/* ==========================================================================
   projects.wopr.ltd — theme overrides for MkDocs Material
   --------------------------------------------------------------------------
   Balance: apalrd's dense, ISO-dated, tag-marked project list and first-person
   technical voice, on chadtimbl.in's calmer page: off-white paper, one accent,
   generous line-height, a short personal intro before the list.

   Sections
     1. Fonts            (system stacks; self-hosted @font-face is opt-in)
     2. Colour tokens    (light, then dark)
     3. Flat header      (no coloured bar)
     4. Long-form type   (measure, size, rhythm for 4–8k word pages)
     5. Inline code      (commit hashes in backticks must be quiet)
     6. Tables           (facts blocks, feature catalogues)
     7. Admonitions      (toned down)
     8. Home page        (project cards + meta line)
     9. Small things     (footer, TOC, nav, status badges)
   ========================================================================== */


/* 1. Fonts ----------------------------------------------------------------
   Material sets no font when `font: false`; it falls back to its own system
   stack. We name the stacks explicitly so both schemes and all platforms
   agree. Nothing here makes a network request.

   To self-host a typeface instead, drop .woff2 files in docs/fonts/ and
   uncomment the @font-face block below; the stacks then fall through to it.
   Suggested pairings (all OFL-licensed, so redistribution is fine):
     text  — "Inter", or "IBM Plex Sans", or "Source Serif 4" for a bookish feel
     mono  — "JetBrains Mono", or "IBM Plex Mono", or "Iosevka"
*/

/*
@font-face {
  font-family: "WOPR Text";
  src: url("../fonts/text-regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "WOPR Text";
  src: url("../fonts/text-bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "WOPR Text";
  src: url("../fonts/text-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "WOPR Mono";
  src: url("../fonts/mono-regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
*/

:root {
  /* Put "WOPR Text", / "WOPR Mono", at the front of these when self-hosting. */
  --md-text-font-family:
    system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    "Noto Sans", "Liberation Sans", Arial, sans-serif;
  --md-code-font-family:
    ui-monospace, "SF Mono", Menlo, Consolas, "DejaVu Sans Mono",
    "Liberation Mono", monospace;

  /* Material reads these two; the `-family` names above are ours. */
  --md-text-font: var(--md-text-font-family);
  --md-code-font: var(--md-code-font-family);
}


/* 2. Colour tokens --------------------------------------------------------
   One accent (amber), warm neutrals, no blue-grey slate. Contrast on body
   text is ≥ 12:1 in both schemes; on the accent used as link text ≥ 4.5:1 (light 5.0, dark 8.2).
*/

/* Light: paper and ink. */
[data-md-color-scheme="default"] {
  --wopr-paper:        #faf8f3;
  --wopr-paper-2:      #f1eee6;   /* code, table stripes, cards */
  --wopr-rule:         #d9d4c7;
  --wopr-ink:          #1f2023;
  --wopr-ink-2:        #55575c;   /* metadata, captions */
  --wopr-ink-3:        #8a8c92;   /* rules, disabled */
  --wopr-accent:       #94600c;   /* amber; 5.0:1 on paper, 4.6:1 on paper-2 */
  --wopr-accent-soft:  #f3e4c4;

  --md-default-bg-color:           var(--wopr-paper);
  --md-default-fg-color:           var(--wopr-ink);
  --md-default-fg-color--light:    var(--wopr-ink-2);
  --md-default-fg-color--lighter:  var(--wopr-ink-3);
  --md-default-fg-color--lightest: var(--wopr-rule);

  --md-primary-fg-color:           var(--wopr-paper);
  --md-primary-bg-color:           var(--wopr-ink);
  --md-primary-bg-color--light:    var(--wopr-ink-2);
  --md-accent-fg-color:            var(--wopr-accent);
  --md-accent-fg-color--transparent: var(--wopr-accent-soft);

  --md-typeset-color:              var(--wopr-ink);
  --md-typeset-a-color:            var(--wopr-accent);
  --md-code-bg-color:              var(--wopr-paper-2);
  --md-code-fg-color:              #3b3d42;
  --md-typeset-table-color:        var(--wopr-rule);
  --md-typeset-table-color--light: var(--wopr-paper-2);
  --md-footer-bg-color:            var(--wopr-paper-2);
  --md-footer-bg-color--dark:      var(--wopr-paper-2);
  --md-footer-fg-color:            var(--wopr-ink);
  --md-footer-fg-color--light:     var(--wopr-ink-2);
  --md-footer-fg-color--lighter:   var(--wopr-ink-3);
}

/* Dark: near-black, warm, not blue. */
[data-md-color-scheme="slate"] {
  --wopr-paper:        #17181a;
  --wopr-paper-2:      #202225;
  --wopr-rule:         #33363b;
  --wopr-ink:          #dcd9d1;
  --wopr-ink-2:        #a09d95;
  --wopr-ink-3:        #6f6d67;
  --wopr-accent:       #e0a63a;
  --wopr-accent-soft:  #3a2f16;

  --md-default-bg-color:           var(--wopr-paper);
  --md-default-fg-color:           var(--wopr-ink);
  --md-default-fg-color--light:    var(--wopr-ink-2);
  --md-default-fg-color--lighter:  var(--wopr-ink-3);
  --md-default-fg-color--lightest: var(--wopr-rule);

  --md-primary-fg-color:           var(--wopr-paper);
  --md-primary-bg-color:           var(--wopr-ink);
  --md-primary-bg-color--light:    var(--wopr-ink-2);
  --md-accent-fg-color:            var(--wopr-accent);
  --md-accent-fg-color--transparent: var(--wopr-accent-soft);

  --md-typeset-color:              var(--wopr-ink);
  --md-typeset-a-color:            var(--wopr-accent);
  --md-code-bg-color:              var(--wopr-paper-2);
  --md-code-fg-color:              #cfccc4;
  --md-typeset-table-color:        var(--wopr-rule);
  --md-typeset-table-color--light: var(--wopr-paper-2);
  --md-footer-bg-color:            var(--wopr-paper-2);
  --md-footer-bg-color--dark:      var(--wopr-paper-2);
  --md-footer-fg-color:            var(--wopr-ink);
  --md-footer-fg-color--light:     var(--wopr-ink-2);
  --md-footer-fg-color--lighter:   var(--wopr-ink-3);

  /* Slate's syntax colours are fine; its selection colour is too blue. */
  --md-typeset-mark-color:         var(--wopr-accent-soft);
}


/* 3. Flat header -----------------------------------------------------------
   Neither reference site has a coloured bar. The header takes the page
   colour and is separated by a hairline. Search box picks up paper-2.
*/
.md-header {
  color: var(--md-default-fg-color);
  background-color: var(--md-default-bg-color);
  border-bottom: 1px solid var(--wopr-rule);
  box-shadow: none;
}
.md-header--shadow { box-shadow: none; }
.md-header__title { font-weight: 600; letter-spacing: -0.01em; }
.md-header__button.md-logo svg { fill: var(--wopr-accent); }
.md-search__form { background-color: var(--wopr-paper-2); }
.md-search__input::placeholder,
.md-search__input + .md-search__icon { color: var(--wopr-ink-2); }
.md-search__input { color: var(--wopr-ink); }
[data-md-toggle="search"]:checked ~ .md-header .md-search__form {
  background-color: var(--md-default-bg-color);
}
.md-tabs { background-color: var(--md-default-bg-color); color: var(--wopr-ink); }


/* 4. Long-form type -------------------------------------------------------
   Material's default is 16px on a 61rem grid, which reads wide for 8,000
   words. We go slightly larger, hold the measure near 70 characters, and
   open up the leading. Headings are weight-600 and tight; ### stage headings
   get a hairline above so a long timeline has visible seams.
*/
.md-grid { max-width: 64rem; }

.md-typeset {
  font-size: 0.85rem;            /* 17px */
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
.md-content__inner { padding-top: 1.6rem; }
.md-typeset > p,
.md-typeset > ul,
.md-typeset > ol,
.md-typeset > blockquote,
.md-typeset > .admonition,
.md-typeset > details { max-width: 44em; }   /* ~70ch at 17px */

.md-typeset h1 {
  font-weight: 650;
  letter-spacing: -0.02em;
  color: var(--md-default-fg-color);
  margin-bottom: 0.6em;
}
.md-typeset h2 {
  font-weight: 600;
  letter-spacing: -0.015em;
  margin-top: 2.4em;
  padding-bottom: 0.25em;
  border-bottom: 1px solid var(--wopr-rule);
}
.md-typeset h3 {
  font-weight: 600;
  margin-top: 2em;
}
.md-typeset h4 { font-weight: 600; text-transform: none; letter-spacing: 0; }

/* Dates in stage headings ("### Stage 3 — 2026-08-04 to 2026-08-16, `a1b2c3d`..`d4e5f6a`")
   sit better when the inline code inherits the heading colour. */
.md-typeset h2 code,
.md-typeset h3 code { background: none; padding: 0; color: var(--wopr-ink-2); font-weight: 400; }

.md-typeset a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.15em; }
.md-typeset a:hover { color: var(--wopr-ink); text-decoration-color: var(--wopr-accent); }

.md-typeset blockquote {
  border-left: 3px solid var(--wopr-accent);
  color: var(--wopr-ink-2);
}
/* Corrections go in blockquotes (estate rule); make them look like an
   annotation rather than a quotation. */
.md-typeset blockquote > p:first-child::before { content: none; }

.md-typeset hr { border-bottom: 1px solid var(--wopr-rule); margin: 2.5em 0; }

/* Page status badge and any header meta */
.md-content__button { color: var(--wopr-ink-3); }


/* 5. Inline code ----------------------------------------------------------
   Build logs cite hundreds of commit hashes in backticks. Material's default
   pill is loud; we flatten it: no border, faint background, near-body size,
   slight letter-spacing so hex reads as hex.
*/
.md-typeset code {
  font-size: 0.86em;
  padding: 0.05em 0.3em;
  border-radius: 3px;
  background-color: var(--md-code-bg-color);
  color: var(--md-code-fg-color);
  word-break: normal;
  overflow-wrap: anywhere;
}
.md-typeset a code { color: var(--wopr-accent); }
.md-typeset pre > code {
  font-size: 0.78em;
  line-height: 1.55;
  padding: 0.9em 1.1em;
}
.md-typeset .highlight { border: 1px solid var(--wopr-rule); border-radius: 4px; }
.md-typeset .highlight .filename { background: var(--wopr-paper-2); border-bottom: 1px solid var(--wopr-rule); }
.md-clipboard { color: var(--wopr-ink-3); }
.md-clipboard:hover { color: var(--wopr-accent); }


/* 6. Tables ---------------------------------------------------------------
   Facts blocks (two columns, keys left) and feature catalogues (three or
   four columns with hash citations). Smaller type, tight padding, ruled rows,
   no zebra banding, header set in the meta colour. Tables are allowed the
   full grid width even when paragraphs are held to the measure.
*/
.md-typeset table:not([class]) {
  font-size: 0.72rem;
  border: 0;
  border-top: 2px solid var(--wopr-ink);
  border-bottom: 1px solid var(--wopr-rule);
  border-radius: 0;
  box-shadow: none;
}
.md-typeset table:not([class]) th {
  font-weight: 600;
  color: var(--wopr-ink-2);
  background: none;
  border-bottom: 1px solid var(--wopr-rule);
  padding: 0.6em 0.8em;
  text-align: left;
  vertical-align: bottom;
}
.md-typeset table:not([class]) td {
  padding: 0.55em 0.8em;
  border-top: 1px solid var(--wopr-rule);
  vertical-align: top;
}
.md-typeset table:not([class]) tr:hover { background: var(--wopr-paper-2); box-shadow: none; }
.md-typeset table:not([class]) code { font-size: 0.9em; white-space: nowrap; }
/* First column of a two-column facts block reads as a label. */
.md-typeset table:not([class]) td:first-child { color: var(--wopr-ink-2); }
.md-typeset__scrollwrap { margin: 1.2em -0.8rem; }


/* 7. Admonitions -----------------------------------------------------------
   Sparingly used per the brief. Neutral border, no coloured tint, and the
   title in the meta colour, so a note reads as an aside not an alarm.
*/
.md-typeset .admonition,
.md-typeset details {
  border-width: 0 0 0 3px;
  border-color: var(--wopr-ink-3);
  border-radius: 0 4px 4px 0;
  background: var(--wopr-paper-2);
  box-shadow: none;
  font-size: 0.78rem;
}
.md-typeset .admonition-title,
.md-typeset summary {
  background: none !important;
  color: var(--wopr-ink-2);
  font-weight: 600;
}
.md-typeset .admonition-title::before,
.md-typeset summary::before { background-color: var(--wopr-ink-2) !important; }
.md-typeset .admonition.warning,
.md-typeset .admonition.danger,
.md-typeset .admonition.failure { border-color: var(--wopr-accent); }
.md-typeset .warning > .admonition-title::before,
.md-typeset .danger > .admonition-title::before,
.md-typeset .failure > .admonition-title::before { background-color: var(--wopr-accent) !important; }


/* 8. Home page ------------------------------------------------------------
   Rendered by overrides/home.html from `extra.projects`. The layout is
   apalrd's list (title, ISO date line, hashtag tags, summary, read-more) set
   as cards on chadtimbl.in's calm page. One column under 45rem, two above.
*/
.wopr-home .md-typeset h1 { margin-bottom: 0.3em; }
.wopr-intro { max-width: 44em; }
.wopr-intro p { font-size: 0.95rem; line-height: 1.6; }

.wopr-projects {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  margin: 1.6rem 0 2.4rem;
  padding: 0;
  list-style: none;
}
@media screen and (min-width: 45rem) {
  .wopr-projects { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.wopr-card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.1rem 1.2rem 1rem;
  border: 1px solid var(--wopr-rule);
  border-radius: 6px;
  background: var(--wopr-paper-2);
  transition: border-color 120ms ease;
}
.wopr-card:hover { border-color: var(--wopr-accent); }
.wopr-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
}
.wopr-card__title {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 650;
  letter-spacing: -0.015em;
  font-family: var(--md-code-font);   /* project names are repo names */
}
.wopr-card__title a { color: var(--wopr-ink); text-decoration: none; }
.wopr-card__title a:hover { color: var(--wopr-accent); }

/* The meta line: monospace, ISO dates, middle dots. Same idiom on every
   card and reusable in page bodies via <p class="wopr-meta">. */
.wopr-meta {
  margin: 0;
  font-family: var(--md-code-font);
  font-size: 0.66rem;
  line-height: 1.5;
  color: var(--wopr-ink-2);
  letter-spacing: 0.01em;
}
.wopr-meta b { font-weight: 600; color: var(--wopr-ink); }
.wopr-meta .sep { margin: 0 0.4em; color: var(--wopr-ink-3); }

.wopr-card__summary { margin: 0.1rem 0 0; font-size: 0.78rem; line-height: 1.55; color: var(--wopr-ink); }

.wopr-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.7rem;
  margin: 0.2rem 0 0;
  padding: 0;
  list-style: none;
  font-family: var(--md-code-font);
  font-size: 0.64rem;
  color: var(--wopr-ink-2);
}
.wopr-tags li::before { content: "#"; color: var(--wopr-ink-3); }

.wopr-card__foot {
  margin-top: auto;
  padding-top: 0.6rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.72rem;
}
.wopr-card__foot a { text-decoration: none; }
.wopr-card__foot a::after { content: " →"; }
.wopr-card__foot a:hover { text-decoration: underline; }

/* Status dot + word. Colours are the only place the palette widens, and
   they stay muted. */
.wopr-status {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  font-family: var(--md-code-font);
  font-size: 0.64rem;
  color: var(--wopr-ink-2);
  white-space: nowrap;
}
.wopr-status::before {
  content: "";
  width: 0.5em; height: 0.5em;
  border-radius: 50%;
  background: var(--wopr-ink-3);
}
.wopr-status--active::before     { background: #4f9d69; }
.wopr-status--maintained::before { background: var(--wopr-accent); }
.wopr-status--paused::before     { background: var(--wopr-ink-3); }
.wopr-status--retired::before    { background: #b5533c; }

/* Material's own page-status icon (front matter `status:`) picks the same colours */
.md-status--active::after     { color: #4f9d69; }
.md-status--maintained::after { color: var(--wopr-accent); }
.md-status--retired::after    { color: #b5533c; }


/* 9. Small things ---------------------------------------------------------- */

/* Left nav: quieter, section titles in caps, active item in accent. */
.md-nav__title { color: var(--wopr-ink-2); }
.md-nav--primary .md-nav__title { background: none; box-shadow: none; }
.md-nav__item--section > .md-nav__link {
  font-family: var(--md-code-font);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--wopr-ink-2);
}
.md-nav__link--active,
.md-nav__link:hover { color: var(--wopr-accent); }

/* Right TOC: hairline on the left, dates in ### headings kept on one line. */
.md-sidebar--secondary .md-nav__list { border-left: 1px solid var(--wopr-rule); }
.md-sidebar--secondary .md-nav__link { font-size: 0.66rem; line-height: 1.4; }

/* Footer: prev/next kept, colophon in the meta idiom. */
.md-footer { border-top: 1px solid var(--wopr-rule); }
.md-footer-meta { background: var(--wopr-paper-2); }
.md-footer-meta .md-copyright {
  font-family: var(--md-code-font);
  font-size: 0.62rem;
  color: var(--wopr-ink-2);
}
.md-footer__title { font-size: 0.8rem; }

/* Search results and buttons take the accent, not the default indigo. */
.md-search-result__meta { background: var(--wopr-paper-2); color: var(--wopr-ink-2); }
.md-typeset .md-button--primary { background: var(--wopr-accent); border-color: var(--wopr-accent); color: var(--wopr-paper); }

/* Back-to-top */
.md-top { background: var(--wopr-paper-2); color: var(--wopr-ink); border: 1px solid var(--wopr-rule); box-shadow: none; }
.md-top:hover { background: var(--wopr-accent); color: var(--wopr-paper); }

/* Progress bar for navigation.instant */
.md-progress { background: var(--wopr-accent); }

/* Print: drop the chrome, keep the measure honest. */
@media print {
  .md-typeset > p, .md-typeset > ul, .md-typeset > ol { max-width: none; }
  .wopr-card { break-inside: avoid; }
}

/* 8a. Specificity fix (prime agent, 2026-09-27 run): the home template
   renders inside .md-typeset, whose list and heading rules outrank the bare
   class selectors above (cards were indented, bulleted and pushed down by
   the h2 top margin). Same rules, scoped so they win. */
.md-typeset ul.wopr-projects,
.md-typeset ul.wopr-tags { margin-left: 0; padding: 0; list-style: none; }
.md-typeset ul.wopr-projects { margin: 1.6rem 0 2.4rem; }
.md-typeset ul.wopr-projects > li.wopr-card,
.md-typeset ul.wopr-tags > li { margin: 0; list-style: none; }
.md-typeset ul.wopr-tags { display: flex; margin-top: 0.2rem; }
.md-typeset .wopr-card__title { margin: 0; }
.md-typeset .wopr-card p { margin: 0; }
.md-typeset ul.wopr-projects { display: grid; gap: 1rem; }
