/* Axis documentation: the website's look on Material, then layout, overflow
 * and diagrams. */

/* ---------------------------------------------------------------------------
 * Type: Inter Variable, vendored
 *
 * The product and the website bundle Inter rather than fetching it, and so do
 * the docs: the same two subsets (latin, latin-ext), from assets/fonts.
 * `--md-text-font` is the hook Material reads into its font stack, so setting
 * it is the whole change; `theme.font` stays false, which would otherwise
 * fetch Roboto from Google.
 * ------------------------------------------------------------------------ */
@font-face {
  font-family: 'Inter Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('../assets/fonts/inter-latin-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Inter Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('../assets/fonts/inter-latin-ext-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
:root {
  --md-text-font: 'Inter Variable';
}
/* The alternate 1 and open digits, as the app sets them, and tabular figures
 * wherever numbers stand in a column. */
.md-typeset {
  font-feature-settings: 'cv05', 'cv08';
}
.md-typeset table {
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------
 * Colour: the product's tokens
 *
 * The --ax-* values are web/src/app.css's roles, light and dark, plus the
 * axis grey the website adds. scripts/tests/test_docs_site.py holds them to
 * that file, so a colour changed in the app and left here is reported.
 * Material's own variables are then set from them: monochrome ink, the link
 * blue for links and focus, and hue for status alone.
 * ------------------------------------------------------------------------ */
[data-md-color-scheme="default"] {
  --ax-bg: #ffffff;
  --ax-surface: #f9fafb;
  --ax-card: #f3f4f6;
  --ax-border: #e6e7e9;
  --ax-text: #111315;
  --ax-muted: #5b6270;
  --ax-link: #1a56db;
  --ax-emerald: #067647;
  --ax-amber: #b54708;
  --ax-axis-rule: #6b7280;
}
[data-md-color-scheme="slate"] {
  --ax-bg: #0d0f12;
  --ax-surface: #141719;
  --ax-card: #17191d;
  --ax-border: #262a30;
  --ax-text: #e8eaed;
  --ax-muted: #969ba4;
  --ax-link: #6aa9ff;
  --ax-emerald: #4ade80;
  --ax-amber: #fbbf24;
  --ax-axis-rule: #9aa1ab;
  --md-hue: 220;
}
[data-md-color-scheme="default"],
[data-md-color-scheme="slate"] {
  --md-default-bg-color: var(--ax-bg);
  --md-default-bg-color--light: var(--ax-surface);
  --md-default-bg-color--lighter: var(--ax-card);
  --md-default-bg-color--lightest: var(--ax-border);
  --md-default-fg-color: var(--ax-text);
  --md-default-fg-color--light: var(--ax-muted);
  --md-default-fg-color--lighter: var(--ax-axis-rule);
  --md-default-fg-color--lightest: var(--ax-border);

  --md-primary-fg-color: var(--ax-bg);
  --md-primary-fg-color--light: var(--ax-surface);
  --md-primary-fg-color--dark: var(--ax-card);
  --md-primary-bg-color: var(--ax-text);
  --md-primary-bg-color--light: var(--ax-muted);

  --md-accent-fg-color: var(--ax-link);
  --md-accent-fg-color--transparent: color-mix(in srgb, var(--ax-link) 10%, transparent);
  --md-accent-bg-color: var(--ax-bg);
  --md-accent-bg-color--light: var(--ax-surface);

  --md-typeset-color: var(--ax-text);
  --md-typeset-a-color: var(--ax-link);
  --md-typeset-mark-color: color-mix(in srgb, var(--ax-amber) 20%, transparent);
  --md-typeset-table-color: var(--ax-border);
  --md-typeset-table-color--light: var(--ax-surface);
  --md-code-bg-color: var(--ax-card);
  --md-code-fg-color: var(--ax-text);
  --md-admonition-bg-color: var(--ax-surface);
  --md-admonition-fg-color: var(--ax-text);
  --md-footer-bg-color: var(--ax-surface);
  --md-footer-bg-color--dark: var(--ax-surface);
  --md-footer-fg-color: var(--ax-text);
  --md-footer-fg-color--light: var(--ax-muted);
  --md-footer-fg-color--lighter: var(--ax-muted);

  /* No shadows anywhere: separation comes from the border. */
  --md-shadow-z1: none;
  --md-shadow-z2: none;
  --md-shadow-z3: none;
}

/* Links in running text are underlined, as the website's prose links are, so
 * a link is told from its sentence by more than its colour. */
.md-typeset p a:not(.ax-seat),
.md-typeset li a,
.md-typeset td a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
.md-typeset .grid.cards a,
.md-typeset a.headerlink {
  text-decoration: none;
}

/* The focus ring the website uses: 2px of the link colour, offset 2px. */
.md-typeset a:focus-visible,
.md-header a:focus-visible,
.md-footer a:focus-visible,
.md-nav__link:focus-visible,
.md-header__button:focus-visible {
  outline: 2px solid var(--ax-link);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
 * The wordmark: both inks in the page, one shown
 *
 * Material's own `.md-logo img{display:block}` ties a same-specificity rule on
 * cascade order alone, so the show-and-hide half is important.
 * ------------------------------------------------------------------------ */
img.ax-logo {
  height: 1.7rem;
  width: auto;
}
img.ax-logo--dark,
img.ax-mm--dark {
  display: none !important;
}
[data-md-color-scheme="slate"] img.ax-logo--light,
[data-md-color-scheme="slate"] img.ax-mm--light {
  display: none !important;
}
[data-md-color-scheme="slate"] img.ax-logo--dark,
[data-md-color-scheme="slate"] img.ax-mm--dark {
  display: block !important;
}

/* ---------------------------------------------------------------------------
 * Header, after the website's SiteHeader
 * ------------------------------------------------------------------------ */
/* Solid rather than the website's 92%: a docs page scrolls tables and code
 * under the bar, and text showing through it competes with the links. */
.md-header.ax-header {
  background-color: var(--ax-bg);
  border-bottom: 1px solid var(--ax-border);
  box-shadow: none;
  color: var(--ax-text);
}
.ax-header .md-header__inner {
  align-items: center;
  gap: 0.4rem;
  height: 3.2rem;
  padding: 0 0.6rem;
}
.ax-header__home {
  align-items: center;
  display: inline-flex;
  min-height: 2.2rem;
}
.ax-header__docs {
  border-left: 1px solid var(--ax-border);
  color: var(--ax-text);
  font-size: 0.75rem;
  font-weight: 600;
  margin-left: 0.4rem;
  padding-left: 0.8rem;
  white-space: nowrap;
}
.ax-header__links {
  display: none;
  gap: 0.2rem;
  list-style: none;
  margin: 0 0 0 1rem;
  padding: 0;
}
.ax-header__links a,
.ax-header__app {
  border-radius: 0.4rem;
  color: var(--ax-muted);
  display: inline-flex;
  font-size: 0.7rem;
  font-weight: 500;
  min-height: 2.2rem;
  align-items: center;
  padding: 0 0.6rem;
  white-space: nowrap;
}
.ax-header__links a:hover,
.ax-header__app:hover {
  color: var(--ax-text);
}
.ax-header__tools {
  align-items: center;
  display: flex;
  gap: 0.2rem;
  margin-left: auto;
}
/* A quiet text link, as the docs plan settled: the route to contact without
 * selling to someone in the middle of a task. */
.ax-header__cta {
  border: 1px solid var(--ax-border);
  border-radius: 0.4rem;
  color: var(--ax-text);
  display: none;
  font-size: 0.7rem;
  font-weight: 600;
  min-height: 2.2rem;
  align-items: center;
  padding: 0 0.7rem;
  white-space: nowrap;
}
.ax-header__app {
  display: none;
}
@media screen and (min-width: 60em) {
  .ax-header__app,
  .ax-header__cta {
    display: inline-flex;
  }
}
/* The website's four links join the bar at 76.25em, where the drawer goes.
 * From there to 82em the bar is full, so the walkthrough link shortens to the
 * word the website's own header uses when it is narrow. The header test in
 * scripts/tests/test_docs_site.py walks the widths and fails on any item
 * that runs past the bar. */
.ax-header__cta-short {
  display: none;
}
@media screen and (min-width: 76.25em) {
  .ax-header__links {
    display: flex;
  }
  /* The drawer opens the navigation on a narrow screen; on a wide one the
   * navigation is beside the page already. */
  .ax-header__drawer {
    display: none;
  }
}
@media screen and (min-width: 76.25em) and (max-width: 81.99em) {
  .ax-header__cta-full {
    display: none;
  }
  .ax-header__cta-short {
    display: inline;
  }
}
/* An open search widens to 23.4rem, then 34.4rem, and Material assumes the
 * bar is otherwise empty. Here the bar is full, so while a reader searches
 * the website's links and the two calls to action step aside; they return
 * when the search closes. Material folds the theme control to no width at
 * the same moment and leaves its button hanging past the bar, invisible;
 * taking it out of the layout keeps the page from scrolling sideways. */
[data-md-toggle="search"]:checked ~ .md-header .md-header__option,
[data-md-toggle="search"]:checked ~ .md-header .ax-header__links,
[data-md-toggle="search"]:checked ~ .md-header .ax-header__app,
[data-md-toggle="search"]:checked ~ .md-header .ax-header__cta {
  display: none;
}
/* A phone has room for the drawer, the wordmark, Documentation, search and
 * the theme, with a few pixels to spare; a desktop window that narrow also
 * spends 15px on its scrollbar, so the gaps tighten. */
@media screen and (max-width: 29.99em) {
  .ax-header .md-header__inner {
    gap: 0.2rem;
    padding: 0 0.4rem;
  }
  .ax-header__docs {
    margin-left: 0.2rem;
    padding-left: 0.5rem;
  }
}
.ax-header .md-header__button {
  color: var(--ax-text);
  margin: 0;
}
.ax-header .md-search__form {
  background-color: var(--ax-card);
}

/* ---------------------------------------------------------------------------
 * Type and the axis line
 *
 * The kicker above the H1, then the H1, then the dashed axis rule drawn once
 * on first paint: 12 on, 6 off, in the axis grey, the website's motif. Each
 * H2 opens with the same rule, so the line divides one task from the next.
 * The rule is decorative and drawn in CSS, so it is absent from the
 * accessibility tree.
 * ------------------------------------------------------------------------ */
.md-typeset {
  font-size: 0.85rem;
  line-height: 1.6;
}
.ax-kicker {
  color: var(--ax-muted);
  font-size: 0.65rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  line-height: 1.3;
  margin: 0 0 0.4rem;
  text-transform: uppercase;
}
.md-typeset .ax-kicker--page {
  margin-bottom: 0.2rem;
}
.md-typeset .ax-kicker--page + h1 {
  margin-top: 0;
}
.md-typeset h1 {
  color: var(--ax-text);
  font-weight: 650;
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin-bottom: 1.2em;
}
.md-typeset h1::after,
.md-typeset h2::before,
.md-typeset hr {
  background-image: repeating-linear-gradient(90deg, var(--ax-axis-rule) 0 12px, transparent 12px 18px);
  background-repeat: no-repeat;
  background-size: 100% 2px;
  border: 0;
  content: "";
  display: block;
  height: 2px;
}
.md-typeset h1::after {
  margin-top: 0.5em;
}
.md-typeset h2 {
  font-weight: 600;
  letter-spacing: -0.02em;
  margin-top: 2.4em;
}
.md-typeset h2::before {
  margin-bottom: 1.4em;
}
.md-typeset h3 {
  font-weight: 600;
  letter-spacing: -0.01em;
}
@media (prefers-reduced-motion: no-preference) {
  .md-typeset h1::after {
    animation: ax-draw-rule 0.6s cubic-bezier(0.65, 0, 0.35, 1) both;
  }
}
@keyframes ax-draw-rule {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}
@media (forced-colors: active) {
  .md-typeset h1::after,
  .md-typeset h2::before,
  .md-typeset hr {
    background: CanvasText;
  }
}

/* The H1's rule starts from the logo's origin square: solid ink, four times
 * the rule's thickness as the logo's square is to its lines, centred on the
 * rule, with the dashes stopping one rule-width short of it. The square opens
 * out from its centre as the rule sets off, so the line is drawn out of it;
 * under reduced motion it is simply there. */
.md-typeset h1 {
  position: relative;
}
.md-typeset h1::after {
  background-position: 10px 0;
}
.md-typeset h1::before {
  background: var(--ax-text);
  bottom: -3px;
  content: "";
  height: 8px;
  left: 0;
  position: absolute;
  width: 8px;
}
@media (prefers-reduced-motion: no-preference) {
  .md-typeset h1::before {
    animation: ax-open-origin 0.24s cubic-bezier(0.25, 1, 0.5, 1) both;
  }
}
@keyframes ax-open-origin {
  from { clip-path: inset(50% 50% 50% 50%); }
  to { clip-path: inset(0 0 0 0); }
}
@media (forced-colors: active) {
  .md-typeset h1::before {
    background: CanvasText;
  }
}

/* A page still being written says so, quietly, above its title. */
.md-typeset .ax-stub-note {
  border: 1px solid var(--ax-border);
  border-radius: 8px;
  color: var(--ax-muted);
  font-size: 0.7rem;
  padding: 0.3rem 0.6rem;
  width: fit-content;
}

/* ---------------------------------------------------------------------------
 * The writers' blocks (docs/CONTRIBUTING-DOCS.md names each one)
 * ------------------------------------------------------------------------ */

/* Admonitions: monochrome panels, 8px radius, a 1px border. Hue only where
 * it means a status: emerald for what you see when it worked, amber for work
 * that waits for approval. */
.md-typeset .admonition,
.md-typeset details {
  background-color: var(--ax-surface);
  border: 1px solid var(--ax-border);
  border-radius: 8px;
  box-shadow: none;
  font-size: 0.8rem;
}
.md-typeset .admonition > .admonition-title,
.md-typeset details > summary {
  background-color: transparent;
  font-weight: 600;
}
.md-typeset .admonition > .admonition-title::before,
.md-typeset details > summary::before {
  background-color: var(--ax-text);
}
.md-typeset details > summary::after {
  color: var(--ax-muted);
}
.md-typeset .admonition.check,
.md-typeset details.check {
  border-left: 3px solid var(--ax-emerald);
}
.md-typeset .check > .admonition-title::before,
.md-typeset .check > summary::before {
  background-color: var(--ax-emerald);
}
:root {
  --md-admonition-icon--waits: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 20a8 8 0 1 0 0-16 8 8 0 0 0 0 16m0-18a10 10 0 1 1 0 20 10 10 0 0 1 0-20m.5 5v5.25l4.5 2.67-.75 1.23L11 13V7z"/></svg>');
}
.md-typeset .admonition.waits,
.md-typeset details.waits {
  border-left: 3px solid var(--ax-amber);
}
.md-typeset .waits > .admonition-title::before,
.md-typeset .waits > summary::before {
  background-color: var(--ax-amber);
  -webkit-mask-image: var(--md-admonition-icon--waits);
  mask-image: var(--md-admonition-icon--waits);
}
.md-typeset .admonition.failure,
.md-typeset details.failure,
.md-typeset details.question {
  border-color: var(--ax-border);
}

/* The prompt: what a reader says to the assistant, as a chat bubble. Written
 * `!!! prompt ""`, so it carries no title. */
.md-typeset .admonition.prompt {
  background-color: var(--ax-card);
  border: 0;
  border-radius: 12px 12px 12px 4px;
  font-size: 0.85rem;
  max-width: 34rem;
  padding: 0.6rem 0.9rem;
}
.md-typeset .admonition.prompt > p {
  margin: 0;
}

/* The placeholder poster: a branded 16:10 box that names the task and lists
 * its steps, so the page teaches before the clip exists. Written
 * `!!! video DCL-06 "Compare quotations"` with the steps as its body; the
 * media tool later swaps the whole block for the clip, keyed by the ID. */
.md-typeset .admonition.video {
  aspect-ratio: 16 / 10;
  background-color: var(--ax-bg);
  border: 1px solid var(--ax-border);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: 40rem;
  overflow: auto;
  padding: 1.2rem 1.6rem 1.6rem;
  position: relative;
}
.md-typeset .admonition.video > .admonition-title {
  font-size: 1.05rem;
  letter-spacing: -0.02em;
  margin: 0 0 0.6rem;
  padding: 0;
}
.md-typeset .admonition.video > .admonition-title::before {
  background: none;
  color: var(--ax-muted);
  content: "Video coming";
  display: block;
  font-size: 0.6rem;
  font-weight: 500;
  height: auto;
  letter-spacing: 0.12em;
  -webkit-mask-image: none;
  mask-image: none;
  margin-bottom: 0.4rem;
  position: static;
  text-transform: uppercase;
  width: auto;
}
.md-typeset .admonition.video::after {
  background-image: repeating-linear-gradient(90deg, var(--ax-axis-rule) 0 12px, transparent 12px 18px);
  bottom: 1rem;
  content: "";
  height: 2px;
  left: 1.6rem;
  position: absolute;
  right: 1.6rem;
}
.md-typeset .admonition.video ol {
  color: var(--ax-text);
  font-size: 0.8rem;
  margin-top: 0;
}

/* A slot with an image (tools/docs/hooks.py adds it): the poster or the
 * thumbnail across the top, at its own ratio, then the title and the steps
 * under it, so the box grows to hold them rather than holding a ratio. */
.md-typeset .admonition.video.ax-video--clip,
.md-typeset .admonition.video.ax-video--poster,
.md-typeset .admonition.video.ax-video--thumbnail {
  aspect-ratio: auto;
  justify-content: flex-start;
  overflow: visible;
  padding-top: 0;
}
.md-typeset .admonition.video .ax-video__image {
  border-bottom: 1px solid var(--ax-border);
  margin: 0 -1.6rem 1rem;
}
.md-typeset .admonition.video .ax-video__image img,
.md-typeset .admonition.video .ax-video__image video {
  border-radius: 11px 11px 0 0;
  display: block;
  height: auto;
  width: 100%;
}

/* A screenshot slot with its capture (tools/docs/hooks.py): the same product
 * frame as the placeholder, holding the image at its own ratio. */
.md-typeset figure.ax-shot {
  border: 1px solid var(--ax-border);
  border-radius: 12px;
  margin: 1.2rem 0;
  max-width: 40rem;
  overflow: hidden;
}
.md-typeset figure.ax-shot img {
  display: block;
  height: auto;
  width: 100%;
}

/* A slot that plays its clip has its video, so its kicker drops "coming".
 * A poster or a thumbnail still stands in for one that is to come. */
.md-typeset .admonition.video.ax-video--clip > .admonition-title::before {
  content: "Video";
}

/* One take per theme, for a player and an image alike. Each selector names
 * the frame that sizes its media (.ax-video__image, figure.ax-shot), so it
 * outranks that frame's own `display: block` rule above it: a selector any
 * less specific loses to it, and both takes show on the light ground.
 * scripts/tests/test_docs_site.py reads what each theme renders. */
.md-typeset .admonition.video .ax-video__image .ax-media--dark,
.md-typeset figure.ax-shot .ax-media--dark,
[data-md-color-scheme="slate"] .md-typeset .admonition.video .ax-video__image .ax-media--light,
[data-md-color-scheme="slate"] .md-typeset figure.ax-shot .ax-media--light {
  display: none;
}
[data-md-color-scheme="slate"] .md-typeset .admonition.video .ax-video__image .ax-media--dark,
[data-md-color-scheme="slate"] .md-typeset figure.ax-shot .ax-media--dark {
  display: block;
}

/* The screenshot slot: the product frame (1px border, 12px radius, 16:10),
 * holding the shot's description until the capture lands. Written
 * `!!! shot SH-09 "What the screenshot shows"`. */
.md-typeset .admonition.shot {
  align-items: center;
  aspect-ratio: 16 / 10;
  background-color: var(--ax-card);
  border: 1px solid var(--ax-border);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: 40rem;
  padding: 1rem 1.6rem;
  text-align: center;
}
.md-typeset .admonition.shot > .admonition-title {
  color: var(--ax-muted);
  font-weight: 500;
  padding: 0;
}
.md-typeset .admonition.shot > .admonition-title::before {
  background: none;
  content: "Screenshot coming";
  display: block;
  font-size: 0.6rem;
  height: auto;
  letter-spacing: 0.12em;
  -webkit-mask-image: none;
  mask-image: none;
  margin-bottom: 0.3rem;
  position: static;
  text-transform: uppercase;
  width: auto;
}
@media screen and (max-width: 44.9375em) {
  .md-typeset .admonition.video,
  .md-typeset .admonition.shot {
    aspect-ratio: auto;
    min-height: 12rem;
  }
}

/* Seat chips: links to the seat's tab on Roles and seats. */
.md-typeset a.ax-seat {
  border: 1px solid var(--ax-border);
  border-radius: 999px;
  color: var(--ax-text);
  display: inline-block;
  font-size: 0.65rem;
  font-weight: 500;
  margin: 0 0.2rem 0.2rem 0;
  padding: 0.1rem 0.6rem;
}
.md-typeset a.ax-seat:hover {
  border-color: var(--ax-text);
}

/* The Goal line of a stage, and the Next line of a task. */
.md-typeset .ax-goal {
  font-size: 0.95rem;
}
.md-typeset .ax-next-line {
  border-top: 1px solid var(--ax-border);
  color: var(--ax-muted);
  padding-top: 0.6rem;
}

/* The four ticks on Home: Describe · Prepare · Approve · Recorded. */
.md-typeset .ax-ticks {
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* A module's generated facts line, quiet under its heading. */
.md-typeset .module-facts {
  color: var(--ax-muted);
  font-size: 0.75rem;
}

/* Grid cards on Home: the product's card, 8px radius, a border, no shadow. */
.md-typeset .grid.cards > ul > li,
.md-typeset .grid.cards > ol > li {
  border: 1px solid var(--ax-border);
  border-radius: 8px;
  box-shadow: none;
}
.md-typeset .grid.cards > ul > li:hover {
  border-color: var(--ax-text);
  box-shadow: none;
}

/* Content tabs: the active tab underlined in ink rather than a hue. */
.md-typeset .tabbed-labels > label {
  font-size: 0.75rem;
}
.md-typeset .tabbed-labels::before {
  background: var(--ax-text);
}

/* ---------------------------------------------------------------------------
 * Footer, after the website's SiteFooter
 * ------------------------------------------------------------------------ */
.ax-footer {
  border-top: 1px solid var(--ax-border);
}
.ax-footer .md-footer__inner {
  border-bottom: 1px solid var(--ax-border);
}
.ax-footer__body {
  display: grid;
  gap: 2rem;
  padding: 2.4rem 0.8rem 1.6rem;
}
@media screen and (min-width: 60em) {
  .ax-footer__body {
    grid-template-columns: 1fr 2fr;
  }
}
.ax-footer__tagline {
  color: var(--ax-muted);
  font-size: 0.75rem;
  margin-top: 0.6rem;
}
.ax-footer__columns {
  display: grid;
  gap: 1.6rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media screen and (min-width: 45em) {
  .ax-footer__columns {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
.ax-footer__heading {
  color: var(--ax-text);
  font-size: 0.75rem;
  font-weight: 600;
  margin: 0 0 0.6rem;
}
.ax-footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.ax-footer li a {
  color: var(--ax-muted);
  display: inline-flex;
  font-size: 0.75rem;
  min-height: 1.6rem;
  align-items: center;
}
.ax-footer li a:hover {
  color: var(--ax-text);
}
/* BUILT BY sits under the tagline, its mark directly beneath it. */
.ax-footer__builder {
  align-items: flex-start;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 1.6rem;
}
.ax-footer__builder .ax-kicker {
  margin: 0;
}
.ax-footer__builder img {
  height: 1.4rem;
  width: auto;
}
/* The copyright closes the same section, under both columns. */
.ax-footer__legal {
  border-top: 1px solid var(--ax-border);
  grid-column: 1 / -1;
  padding-top: 1.2rem;
}
.ax-footer .md-copyright {
  color: var(--ax-muted);
  font-size: 0.7rem;
  margin: 0;
  width: auto;
}
.ax-footer .md-copyright__highlight {
  color: var(--ax-muted);
}

/* ---------------------------------------------------------------------------
 * Content width
 *
 * Material caps every grid row at 61rem, which on a 1440px display leaves a
 * narrow column of prose with more empty space either side of it than text in
 * it. The cap is raised to 72rem, which is 1440px -- the website's own
 * widest layout -- at the 20px root Material sets below 100em. In rem, as
 * Material's own cap is, because from 100em Material enlarges the root to 22px
 * and then 24px: a cap in pixels stays put while everything in the header
 * grows, and the last item in the bar is pushed past its edge.
 * ------------------------------------------------------------------------ */
.md-grid {
  max-width: 72rem;
}

/* The extra width is for tables, code and diagrams, not for lines of prose,
 * which at the full column would run past 120 characters and be a chore to
 * read. Running text keeps the measure Material always gave it, about 690px,
 * and the width won above goes to headings, code, tables and diagrams. In rem,
 * so the measure follows the font as Material scales it up on wide screens. */
.md-typeset p,
.md-typeset ul,
.md-typeset ol,
.md-typeset dl,
.md-typeset blockquote {
  max-width: 34rem;
}

/* ---------------------------------------------------------------------------
 * Overflow containment
 *
 * One unbreakable line — a pipeline drawn in a code fence, a wide table, a
 * diagram — must move a scrollbar of its own and never the page's. Material
 * already hides overflow on <html>, so anything that escapes its container is
 * not merely awkward but unreachable: it is clipped at the viewport edge with
 * no way to scroll to it. Each container that can hold wide content is given
 * the overflow explicitly.
 * ------------------------------------------------------------------------ */
.md-typeset pre,
.md-typeset pre > code,
.md-typeset__scrollwrap,
.md-typeset__table {
  overflow-x: auto;
}

/* Images and inline SVG shrink to the column rather than push past it. */
.md-typeset img,
.md-typeset svg {
  max-width: 100%;
}

/* Long identifiers — action names, environment variables, URLs — are the one
 * kind of prose that cannot be broken at a space, so they break anywhere
 * rather than run off the edge. */
.md-typeset p > code,
.md-typeset li > code,
.md-typeset td > code {
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------------------
 * Diagrams
 *
 * A ```mermaid fence arrives as div.axis-diagram holding its own source, and
 * docs/javascripts/diagrams.js replaces that text with rendered SVG. The
 * source is only hidden where that script is running, so a reader without it
 * still gets something to read instead of a gap.
 * ------------------------------------------------------------------------ */
.md-typeset .axis-diagram {
  margin: 1.2em 0;
}

.md-typeset .axis-diagram:not([data-rendered]) {
  color: var(--md-default-fg-color--light);
  font-family: var(--md-code-font-family);
  font-size: 0.7rem;
  white-space: pre-wrap;
}

.axis-diagrams-js .md-typeset .axis-diagram:not([data-rendered]) {
  visibility: hidden;
}

.axis-diagram__frame {
  background-color: var(--md-default-bg-color);
  position: relative;
}

.axis-diagram__canvas {
  overflow-x: auto;
  overscroll-behavior: contain;
  text-align: center;
}

.axis-diagram__canvas svg {
  height: auto;
  max-width: 100%;
}

/* mermaid draws edge labels on an opaque chip in a shade of its own choosing,
 * a light grey that sits oddly on the slate page. The SVG is in the light DOM,
 * so the page's colours can reach it, but mermaid scopes its generated rules
 * with the SVG's own id and an id outranks any selector worth writing — hence
 * the important. These are Material's variables, so the chip follows the
 * palette on its own. */
.axis-diagram__canvas .edgeLabel,
.axis-diagram__canvas .edgeLabel p,
.axis-diagram__canvas .edgeLabel span {
  background-color: var(--md-default-bg-color) !important;
  color: var(--md-default-fg-color) !important;
}

.axis-diagram__canvas .edgeLabel rect {
  fill: var(--md-default-bg-color) !important;
  opacity: 1 !important;
}

.axis-diagram__source {
  white-space: pre-wrap;
}

/* The control sits over the top-right corner of the diagram, quiet until it is
 * pointed at or focused, and always visible to the keyboard. */
.axis-diagram__toggle {
  background-color: var(--md-default-bg-color);
  border: 0.05rem solid var(--md-default-fg-color--lightest);
  border-radius: 0.1rem;
  color: var(--md-default-fg-color--light);
  cursor: pointer;
  display: flex;
  opacity: 0.5;
  padding: 0.25rem;
  position: absolute;
  right: 0.2rem;
  top: 0.2rem;
  transition: opacity 125ms, color 125ms;
  z-index: 1;
}

.axis-diagram__toggle svg {
  fill: currentcolor;
  height: 0.8rem;
  width: 0.8rem;
}

.axis-diagram__frame:hover .axis-diagram__toggle,
.axis-diagram__toggle:focus,
.axis-diagram__toggle:hover {
  color: var(--md-accent-fg-color);
  opacity: 1;
}

.axis-diagram__toggle:focus-visible {
  outline: 0.1rem solid var(--md-accent-fg-color);
  outline-offset: 0.1rem;
}

/* Fullscreen. The frame is fixed to the viewport and the script pins the
 * height its host had, so the page underneath keeps its shape and the reader
 * comes back to the scroll position they left. Material's own layers stop at
 * z-index 10. */
.axis-diagram__frame--fullscreen {
  bottom: 0;
  display: flex;
  flex-direction: column;
  left: 0;
  padding: 1.2rem;
  position: fixed;
  right: 0;
  top: 0;
  z-index: 20;
}

.axis-diagram__frame--fullscreen .axis-diagram__canvas {
  align-items: center;
  display: flex;
  flex: 1;
  justify-content: center;
  overflow: auto;
}

/* mermaid writes a pixel max-width onto the SVG it produces, so filling the
 * viewport takes an important to outrank that inline style. */
.axis-diagram__frame--fullscreen .axis-diagram__canvas svg {
  max-height: 100%;
  max-width: 100% !important;
  width: auto;
}

/* Held on <html> while a diagram is open, so the page behind the overlay stays
 * where it was. Material gives html an overflow of its own, and the viewport
 * scrolls from the root element once that is set, so a lock on body is read
 * and ignored. */
.axis-diagram-lock {
  overflow: hidden;
}
