/* ==========================================================================
   Vaporsoft palette for Material for MkDocs.

   Every value here is lifted from src/Nfty.App/Themes/Tokens.axaml, which is itself a verbatim port
   of the locked token block in docs/design/mockups/explorer.html. That file is the source of truth:
   do not invent a hex here, and if a token changes there, change it here too.

   Two notes on the translation:

   - Avalonia writes 8-digit hex alpha-FIRST (#AARRGGBB); CSS writes it alpha-LAST. Rather than
     re-rotate the digits and risk the exact bug Tokens.axaml warns about, every translucent value
     is written here as rgb() with a decimal alpha, and the Avalonia byte it came from is in the
     comment beside it.
   - Material names its header colours backwards from what you would guess: --md-primary-fg-color is
     the header's BACKGROUND and --md-primary-bg-color is its TEXT. The app's titlebar is a quiet
     panel with an accent wordmark, not a slab of red, so primary is the panel colour here.
   ========================================================================== */

/* THE TYPEFACE, served from this site.
   The same superfamily the app embeds (src/Nfty.App/Assets/Fonts), so the manual's prose
   matches its own screenshots. Self-hosted rather than pulled from a font CDN because
   mkdocs.yml sets `font: false` - this site asks no third party for a typeface, and that
   promise would be worth nothing if the stylesheet then did.
   Eight files rather than a variable font because the app ships these exact four weights of
   each, and a manual that renders a weight the product cannot draw is quietly unlike it.
   font-display: swap - the page stays readable in a fallback while these arrive, which
   matters more here than avoiding one reflow. */
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/IBMPlexSans-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../assets/fonts/IBMPlexSans-Medium.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../assets/fonts/IBMPlexSans-SemiBold.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../assets/fonts/IBMPlexSans-Bold.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/IBMPlexMono-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../assets/fonts/IBMPlexMono-Medium.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../assets/fonts/IBMPlexMono-SemiBold.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../assets/fonts/IBMPlexMono-Bold.woff2") format("woff2");
}

:root {
  /* Named here because theme.font is off: with `font: false` Material keeps its own system stack,
     so the faces declared above have to be asked for. The fallbacks stay for the moment before the
     woff2 lands, and for a reader who blocks web fonts.
     These are CSS stacks, where `-apple-system` is a real keyword - unlike the Avalonia tokens they
     mirror, where it named nothing at all and silently resolved to a system fallback. */
  --md-text-font-family: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  --md-code-font-family: "IBM Plex Mono", "SF Mono", "Cascadia Code", ui-monospace, Menlo, Consolas, monospace;

  /* Shared across both schemes: the accent is one colour in the app, and only the text form of it
     shifts per theme for contrast. */
  --vs-accent: #a11f31;
  --vs-on-accent: #f7f2ec;
}

/* ---------------------------------------------------------------- light --- */
[data-md-color-scheme="default"] {
  --vs-bg: #f4efe8;
  --vs-bg-alt: #f1ece4;
  --vs-bg-alt2: #ede7df;
  --vs-panel: #f8f3ed;
  --vs-tile: #ece5db;
  --vs-fg: #121318;
  --vs-fg-muted: rgb(18 20 24 / 0.72);      /* Avalonia #b8121418 */
  --vs-line: rgb(18 20 24 / 0.12);          /* #1f121418 */
  --vs-line-strong: rgb(18 20 24 / 0.20);   /* #33121418 */
  --vs-accent-text: #97192a;
  --vs-accent-hover: #b92f44;
  --vs-accent-wash: rgb(161 31 49 / 0.08);  /* #14a11f31 */
  --vs-accent-line: rgb(161 31 49 / 0.25);  /* #40a11f31 */
  --vs-success: #3d6b52;
  --vs-warning: #6a4a25;
  --vs-info: #3b5b6f;                       /* the Dynamic kind colour */
  --vs-custom: #6d4f9c;                     /* the Custom kind colour */
  --vs-shadow: 0 1px 2px rgb(18 20 24 / 0.06), 0 18px 48px -24px rgb(18 20 24 / 0.20);

  color-scheme: light;
}

/* ----------------------------------------------------------------- dark --- */
[data-md-color-scheme="slate"] {
  --vs-bg: #07080b;
  --vs-bg-alt: #0a0b10;
  --vs-bg-alt2: #0f1118;
  --vs-panel: #0b0c10;
  --vs-tile: #12141c;
  --vs-fg: #f2ede6;
  --vs-fg-muted: rgb(242 237 230 / 0.78);   /* Avalonia #c7f2ede6 */
  --vs-line: rgb(242 237 230 / 0.14);       /* #24f2ede6 */
  --vs-line-strong: rgb(242 237 230 / 0.20);/* #33f2ede6 */
  --vs-accent-text: #e0788a;
  --vs-accent-hover: #ba3447;
  --vs-accent-wash: rgb(161 31 49 / 0.15);  /* #26a11f31 */
  --vs-accent-line: rgb(161 31 49 / 0.40);  /* #66a11f31 */
  --vs-success: #a6c08a;
  --vs-warning: #e0c28c;
  --vs-info: #7fb0c4;
  --vs-custom: #c3a6ea;
  --vs-shadow: 0 1px 2px rgb(0 0 0 / 0.38), 0 22px 60px -28px rgb(0 0 0 / 1);

  color-scheme: dark;
}

/* ------------------------------------------------- mapped onto Material --- */
[data-md-color-scheme="default"],
[data-md-color-scheme="slate"] {
  --md-default-bg-color: var(--vs-bg);
  --md-default-fg-color: var(--vs-fg);
  --md-default-fg-color--light: var(--vs-fg-muted);
  --md-default-fg-color--lighter: var(--vs-line-strong);
  --md-default-fg-color--lightest: var(--vs-line);

  --md-primary-fg-color: var(--vs-panel);       /* header background */
  --md-primary-fg-color--light: var(--vs-bg-alt);
  --md-primary-fg-color--dark: var(--vs-bg-alt2);
  --md-primary-bg-color: var(--vs-fg);          /* header text */
  --md-primary-bg-color--light: var(--vs-fg-muted);

  --md-accent-fg-color: var(--vs-accent-text);
  --md-accent-fg-color--transparent: var(--vs-accent-wash);
  --md-accent-bg-color: var(--vs-on-accent);

  --md-typeset-color: var(--vs-fg);
  --md-typeset-a-color: var(--vs-accent-text);
  --md-typeset-mark-color: var(--vs-accent-wash);
  --md-typeset-del-color: rgb(161 31 49 / 0.20);
  --md-typeset-ins-color: rgb(61 107 82 / 0.20);
  --md-typeset-table-color: var(--vs-line-strong);

  --md-code-fg-color: var(--vs-fg);
  --md-code-bg-color: var(--vs-tile);
  --md-code-hl-comment-color: var(--vs-fg-muted);
  --md-code-hl-string-color: var(--vs-success);
  --md-code-hl-number-color: var(--vs-custom);
  --md-code-hl-keyword-color: var(--vs-accent-text);
  --md-code-hl-name-color: var(--vs-fg);
  --md-code-hl-operator-color: var(--vs-fg-muted);
  --md-code-hl-punctuation-color: var(--vs-fg-muted);
  --md-code-hl-function-color: var(--vs-info);
  --md-code-hl-constant-color: var(--vs-custom);
  --md-code-hl-variable-color: var(--vs-warning);

  --md-footer-bg-color: var(--vs-bg-alt2);
  --md-footer-bg-color--dark: var(--vs-bg-alt);
  --md-footer-fg-color: var(--vs-fg);
  --md-footer-fg-color--light: var(--vs-fg-muted);
  --md-footer-fg-color--lighter: var(--vs-line-strong);

  --md-shadow-z1: var(--vs-shadow);
  --md-shadow-z2: var(--vs-shadow);
  --md-shadow-z3: var(--vs-shadow);
}

/* ------------------------------------------------------------- chrome ---- */

/* The app's titlebar is a panel with a hairline under it, not a coloured slab. */
.md-header {
  background-color: var(--vs-panel);
  border-bottom: 1px solid var(--vs-line);
  box-shadow: none;
}
.md-header--shadow { box-shadow: var(--vs-shadow); }

/* The wordmark, as the app draws it: mono, tight, with the trailing letter in the accent. */
.md-header__title,
.md-nav__title[for="__drawer"] { font-family: var(--md-code-font-family); letter-spacing: -0.01em; }
.md-header__topic:first-child .md-ellipsis { font-weight: 700; }
.md-header__topic:first-child .md-ellipsis::after {
  content: "";
  display: inline-block;
  width: 6px; height: 6px;
  margin-left: 7px;
  border-radius: 2px;
  background: var(--vs-accent);
  vertical-align: 0.08em;
}

/* Search: the app's own search field, not Material's tinted one. */
.md-search__form {
  background-color: var(--vs-bg-alt2);
  border: 1px solid var(--vs-line-strong);
  border-radius: 8px;
  box-shadow: none;
}
.md-search__form:hover { background-color: var(--vs-bg-alt2); border-color: var(--vs-accent-line); }
[data-md-toggle="search"]:checked ~ .md-header .md-search__form { border-color: var(--vs-accent-line); }
.md-search__input { font-family: var(--md-code-font-family); font-size: 0.72rem; }
.md-search__input::placeholder { color: var(--vs-fg-muted); }
.md-search-result__meta,
.md-search-result__article .md-search-result__title { font-family: var(--md-code-font-family); }

/* Section labels in the sidebar read as the app's .plabel: small, spaced, muted, uppercase. */
.md-nav--secondary .md-nav__title,
.md-nav__item--section > .md-nav__link {
  font-family: var(--md-code-font-family);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--vs-fg-muted);
}

/* The selected page carries the app's 2px accent bar, the same one the Explorer tree uses. */
.md-nav__link--active,
.md-nav__link--active code { color: var(--vs-accent-text); }
.md-nav__item .md-nav__link--active {
  box-shadow: inset 2px 0 0 var(--vs-accent);
  padding-left: 0.6rem;
}

/* ------------------------------------------------------------ typeset ---- */

.md-typeset h1,
.md-typeset h2 {
  font-family: var(--md-code-font-family);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--vs-fg);
}
.md-typeset h2 {
  margin-top: 2.2em;
  padding-top: 0.9em;
  border-top: 1px solid var(--vs-line);
}
.md-typeset h1 + h2,
.md-typeset h2:first-child { border-top: 0; padding-top: 0; margin-top: 1.2em; }
.md-typeset h3 { font-weight: 600; }

.md-typeset a:hover { color: var(--vs-accent-hover); }

/* Tables: the app's panel, hairlines, and a mono header row. */
.md-typeset table:not([class]) {
  background-color: var(--vs-panel);
  border: 1px solid var(--vs-line);
  border-radius: 10px;
  box-shadow: none;
  font-size: 0.7rem;
}
.md-typeset table:not([class]) th {
  background-color: var(--vs-bg-alt2);
  font-family: var(--md-code-font-family);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vs-fg-muted);
  border-bottom: 1px solid var(--vs-line);
}
.md-typeset table:not([class]) td { border-top: 1px solid var(--vs-line); }
.md-typeset table:not([class]) tr:first-child td { border-top: 0; }

/* Code blocks sit on the app's tile colour, inside its own hairline. */
.md-typeset pre > code,
.md-typeset .highlight { border-radius: 10px; }
.md-typeset pre > code { border: 1px solid var(--vs-line); }
.md-typeset code { border-radius: 4px; }
.md-typeset a > code { color: var(--vs-accent-text); }

/* Blockquotes are the app's dashed note panel. */
.md-typeset blockquote {
  color: var(--vs-fg-muted);
  border-left: 0;
  border: 1px dashed var(--vs-line-strong);
  border-radius: 8px;
  padding: 0.7em 0.9em;
  background: var(--vs-bg-alt);
}

/* Admonitions borrow the kind colours: info is Dynamic, warning is Static, success is the valid
   pill, and note takes the accent. */
.md-typeset .admonition,
.md-typeset details {
  border-radius: 10px;
  border-width: 1px;
  box-shadow: none;
  background-color: var(--vs-panel);
  font-size: 0.7rem;
}
.md-typeset .admonition-title,
.md-typeset summary { font-family: var(--md-code-font-family); font-size: 0.68rem; }

.md-typeset .note { border-color: var(--vs-accent-line); }
.md-typeset .note > .admonition-title { background-color: var(--vs-accent-wash); }
.md-typeset .note > .admonition-title::before { background-color: var(--vs-accent-text); }

.md-typeset .tip,
.md-typeset .success { border-color: color-mix(in srgb, var(--vs-success) 40%, transparent); }
.md-typeset .tip > .admonition-title,
.md-typeset .success > .admonition-title { background-color: color-mix(in srgb, var(--vs-success) 13%, transparent); }
.md-typeset .tip > .admonition-title::before,
.md-typeset .success > .admonition-title::before { background-color: var(--vs-success); }

.md-typeset .info { border-color: color-mix(in srgb, var(--vs-info) 40%, transparent); }
.md-typeset .info > .admonition-title { background-color: color-mix(in srgb, var(--vs-info) 13%, transparent); }
.md-typeset .info > .admonition-title::before { background-color: var(--vs-info); }

.md-typeset .warning { border-color: color-mix(in srgb, var(--vs-warning) 45%, transparent); }
.md-typeset .warning > .admonition-title { background-color: color-mix(in srgb, var(--vs-warning) 14%, transparent); }
.md-typeset .warning > .admonition-title::before { background-color: var(--vs-warning); }

.md-typeset .danger,
.md-typeset .failure { border-color: var(--vs-accent-line); }
.md-typeset .danger > .admonition-title,
.md-typeset .failure > .admonition-title { background-color: var(--vs-accent-wash); }
.md-typeset .danger > .admonition-title::before,
.md-typeset .failure > .admonition-title::before { background-color: var(--vs-accent); }

/* -------------------------------------------------------------- extras --- */

/* .kind — the letter chip the Explorer puts beside a layer. Written inline as, e.g.,
   [D](#){ .kind .dynamic } is overkill; these are spans in the prose: <span class="kind dynamic">D</span> */
.md-typeset .kind {
  display: inline-block;
  min-width: 1.35em;
  padding: 0 0.3em;
  border-radius: 4px;
  border: 1px solid;
  font-family: var(--md-code-font-family);
  font-size: 0.82em;
  font-weight: 600;
  text-align: center;
}
.md-typeset .kind.dynamic { color: var(--vs-info);    border-color: color-mix(in srgb, var(--vs-info) 28%, transparent);    background: color-mix(in srgb, var(--vs-info) 12%, transparent); }
.md-typeset .kind.static  { color: var(--vs-warning); border-color: color-mix(in srgb, var(--vs-warning) 28%, transparent); background: color-mix(in srgb, var(--vs-warning) 13%, transparent); }
.md-typeset .kind.custom  { color: var(--vs-custom);  border-color: color-mix(in srgb, var(--vs-custom) 28%, transparent);  background: color-mix(in srgb, var(--vs-custom) 13%, transparent); }

/* The landing page's card grid. */
/* Card grids. Material's own `grid cards` rather than a hand-rolled one: it already carries the
   responsive columns, the focus ring and the dark-mode handling, so all that is left here is to
   dress it in the app's panel. */
.md-typeset .grid.cards > ul > li,
.md-typeset .grid > .card {
  border: 1px solid var(--vs-line);
  border-radius: 10px;
  background: var(--vs-panel);
  padding: 0.9rem 1rem;
  transition: border-color 0.12s, background 0.12s;
}
.md-typeset .grid.cards > ul > li:hover,
.md-typeset .grid > .card:hover {
  border-color: var(--vs-accent-line);
  background: var(--vs-accent-wash);
  box-shadow: none;
}
.md-typeset .grid.cards > ul > li > hr {
  margin: 0.5em 0;
  border-bottom-color: var(--vs-line);
}
.md-typeset .grid.cards > ul > li > p:last-child {
  margin-bottom: 0;
  font-size: 0.72rem;
  color: var(--vs-fg-muted);
}
.md-typeset .grid.cards .twemoji,
.md-typeset .grid.cards svg {
  color: var(--vs-accent-text);
}

/* Screenshots. Every figure here is a frame of the running app, so it gets the app's own edge --
   without it a light-theme screenshot bleeds into a light page and loses its boundary. */
.md-typeset img[src*="/images/"] {
  border: 1px solid var(--vs-line);
  border-radius: 8px;
}
/* NO `display` here. Material hides the off-theme half of a screenshot pair with
   `[data-md-color-scheme="slate"] img[src$="#only-light"] { display: none }` -- the same specificity
   as the selector above, and this sheet loads after Material's, so setting `display: block` here
   won a tie it should never have entered and both images rendered, one under the other. */
.md-typeset a.glightbox img[src*="/images/"] { cursor: zoom-in; }

/* Glossary tooltips. Every domain word on the site carries one (the abbreviation list is appended
   to every page), which is exactly why the marker has to be quiet -- Material's stock dotted rule is
   a fine cue on a rare term and reads as a page full of spelling errors when six of them appear in
   one paragraph. Faint underline, and none at all where the word is already the subject: a heading,
   a table cell, or a bolded term. The tooltip still works in all of them. */
.md-typeset abbr {
  border-bottom: 1px dotted var(--vs-line-strong);
  text-decoration: none;
  cursor: help;
}
.md-typeset h1 abbr,
.md-typeset h2 abbr,
.md-typeset h3 abbr,
.md-typeset h4 abbr,
.md-typeset table abbr,
.md-typeset strong abbr,
.md-typeset .grid.cards abbr {
  border-bottom: 0;
  cursor: inherit;
}

/* Footer: the copyright is the point, so it gets the app's muted mono. */
.md-footer-meta { background-color: var(--vs-bg-alt2); border-top: 1px solid var(--vs-line); }
.md-copyright { font-family: var(--md-code-font-family); font-size: 0.62rem; }
.md-copyright__highlight { color: var(--vs-fg-muted); }
.md-footer__link { color: var(--vs-fg); }
.md-footer { background-color: var(--vs-bg-alt); }

/* The version/edit affordances Material tints with the accent. */
.md-typeset .md-button--primary {
  background-color: var(--vs-accent);
  border-color: var(--vs-accent);
  color: var(--vs-on-accent);
}
.md-typeset .md-button--primary:hover {
  background-color: var(--vs-accent-hover);
  border-color: var(--vs-accent-hover);
  color: var(--vs-on-accent);
}
.md-typeset .md-button {
  border-radius: 8px;
  border-color: var(--vs-line-strong);
  color: var(--vs-fg);
}
.md-typeset .md-button:hover { border-color: var(--vs-accent-line); color: var(--vs-accent-text); background: var(--vs-accent-wash); }

/* ==========================================================================
   THE TYPEFACE OFFER

   A quiet line, not a call to action. It sits at the foot of a reference page and matters to almost
   nobody, so it is sized and coloured like a footnote and only gains ink on hover — the same
   restraint the app's own ghost buttons use.

   The wording is deliberate and the restraint is not only aesthetic: a web page CANNOT install a
   font. The control says "Get IBM Plex" and goes to IBM's own release, because a button labelled
   "Install" that merely navigates would be the same species of lie as a button wired to nothing,
   which this project has shipped twice and written rules about. It links out rather than serving a
   copy from here: this site is GitHub Pages, and the upstream is the authoritative source anyway.
   ========================================================================== */
.md-typeset .vs-typeface {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin: 2rem 0 0;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--vs-line);
  border-radius: 0.3rem;
  background: var(--vs-bg-alt);
}
.md-typeset .vs-typeface__text {
  flex: 1;
  font-size: 0.68rem;
  line-height: 1.5;
  color: var(--vs-fg-muted);
}
.md-typeset .vs-typeface__text strong {
  display: block;
  font-family: var(--md-code-font-family);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--vs-fg);
}
/* Not .md-button: Material's is a filled slab, and this is a footnote with an action on it. */
.md-typeset a.vs-typeface__get {
  flex: none;
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--vs-line-strong);
  border-radius: 0.3rem;
  font-family: var(--md-code-font-family);
  font-size: 0.66rem;
  font-weight: 600;
  color: var(--vs-fg);
  background: var(--vs-panel);
  text-decoration: none;
  white-space: nowrap;
  transition: background 120ms, border-color 120ms, color 120ms;
}
.md-typeset a.vs-typeface__get:hover,
.md-typeset a.vs-typeface__get:focus-visible {
  border-color: var(--vs-accent);
  color: var(--vs-accent);
  background: var(--vs-panel);
}
