/* maaake brand layer for Docmost
 * Implements brandbook v0.1 (agent-massimo/design-systems/maaake/brandbook.html)
 * over Mantine's CSS variable layer. Loaded after Mantine's sheets, so equal
 * specificity wins on order — no !important needed except where noted.
 *
 * The four rules this file exists to obey:
 *   no colour · no #000 on #fff · one mono typeface · hatch is 45° 1.5/11
 */

:root {
  /* ---- brand tokens (verbatim from the brandbook) ---- */
  --ink:      hsl(0 0% 9%);   /* #171717 primary text, hatch, labels */
  --ink-2:    hsl(0 0% 34%);  /* #575757 secondary — 7.0:1 AA        */
  --ink-3:    hsl(0 0% 56%);  /* #8f8f8f large / non-text only       */
  --hairline: hsl(0 0% 85%);  /* #d9d9d9 rules, dividers             */
  --surface:  hsl(0 0% 96%);  /* #f5f5f5 alternate ground            */
  --paper:    hsl(0 0% 99%);  /* #fcfcfc default ground              */

  --hatch-w: 1.5px;
  --hatch-gap: 11px;
  /* The hatch tracks the text colour, so it stays legible in either scheme.
     Ink lines on a dark ground are invisible — that was the bug. */
  --hatch-color: var(--ink);

  /* Brandbook: ship the system mono stack; swap in a named face later. */
  --maaake-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo,
                 "JetBrains Mono", "Cascadia Mono", "Noto Sans Mono",
                 "Liberation Mono", Consolas, monospace;

  /* DEPARTURE FROM BRANDBOOK v0.1, at Pavel's request. Rule 3 is "One typeface.
     Mono, everywhere." Long-form reading is the one place mono costs you, so
     article body text is sans while every other surface stays mono.
     Noto Sans leads because it is the system default here AND is designed as a
     sibling of Noto Sans Mono — same skeleton, same metrics philosophy — so the
     two sit together without looking like an accident. Worth Massimo's review. */
  --maaake-sans: ui-sans-serif, system-ui, "Inter", "IBM Plex Sans",
                 "Noto Sans", "Open Sans", "Liberation Sans", sans-serif;

  /* ---- type: one voice, everywhere ---- */
  --mantine-font-family: var(--maaake-mono);
  --mantine-font-family-headings: var(--maaake-mono);
  --mantine-font-family-monospace: var(--maaake-mono);
  --mantine-heading-font-weight: 700;

  /* ---- ground & text ----
     NOTE: Mantine ALSO sets body/text/anchor/placeholder/bright/contrast inside
     :root[data-mantine-color-scheme=light], an attribute selector that outranks
     a plain :root. Those six are re-declared in the matching block below or they
     silently lose — measured: body stayed #fff until this was fixed. */
  --mantine-color-body: var(--paper);
  --mantine-color-text: var(--ink);
  --mantine-color-bright: var(--ink);
  --mantine-color-dimmed: var(--ink-2);
  --mantine-color-placeholder: var(--ink-3);
  --mantine-color-white: var(--paper);   /* never true #fff */
  --mantine-color-black: var(--ink);     /* never true #000 */

  --mantine-color-default: var(--paper);
  --mantine-color-default-hover: var(--surface);
  --mantine-color-default-border: var(--hairline);
  --mantine-color-default-color: var(--ink);
  --mantine-color-anchor: var(--ink);

  /* ---- primary: blue is banned, primary is ink ---- */
  --mantine-primary-color-filled: var(--ink);
  --mantine-primary-color-filled-hover: hsl(0 0% 18%);
  --mantine-primary-color-contrast: var(--paper);
  --mantine-primary-color-light: var(--surface);
  --mantine-primary-color-light-hover: hsl(0 0% 92%);
  --mantine-primary-color-light-color: var(--ink);

  /* Docmost's primaryColor is "blue", and components reference the raw scale
     directly, so the whole ramp is remapped to neutral grey. Shades 6-9 are
     all ink because that is where the filled states land. */
  --mantine-color-blue-0: var(--surface);
  --mantine-color-blue-1: hsl(0 0% 92%);
  --mantine-color-blue-2: var(--hairline);
  --mantine-color-blue-3: hsl(0 0% 74%);
  --mantine-color-blue-4: var(--ink-3);
  --mantine-color-blue-5: var(--ink-2);
  --mantine-color-blue-6: var(--ink);
  --mantine-color-blue-7: var(--ink);
  --mantine-color-blue-8: var(--ink);
  --mantine-color-blue-9: var(--ink);
  --mantine-color-blue-filled: var(--ink);
  --mantine-color-blue-filled-hover: hsl(0 0% 18%);
  --mantine-color-blue-light: var(--surface);
  --mantine-color-blue-light-hover: hsl(0 0% 92%);
  --mantine-color-blue-light-color: var(--ink);
  --mantine-color-blue-outline: var(--ink);
  --mantine-color-blue-outline-hover: var(--surface);
  --mantine-color-blue-text: var(--ink);

  /* Neutral the grey ramp too — Mantine's default greys are cooled. */
  --mantine-color-gray-0: var(--paper);
  --mantine-color-gray-1: var(--surface);
  --mantine-color-gray-2: hsl(0 0% 92%);
  --mantine-color-gray-3: var(--hairline);
  --mantine-color-gray-4: hsl(0 0% 74%);
  --mantine-color-gray-5: var(--ink-3);
  --mantine-color-gray-6: hsl(0 0% 45%);
  --mantine-color-gray-7: var(--ink-2);
  --mantine-color-gray-8: hsl(0 0% 22%);
  --mantine-color-gray-9: var(--ink);
}

/* Light scheme — must match Mantine's own selector to win.
   These are the six it hardcodes; without this block the page keeps #fff/#000,
   which is the one pairing the brandbook explicitly bans. */
:root[data-mantine-color-scheme="light"],
:host([data-mantine-color-scheme="light"]) {
  --mantine-color-body: var(--paper);
  --mantine-color-text: var(--ink);
  --mantine-color-bright: var(--ink);
  --mantine-color-placeholder: var(--ink-3);
  --mantine-color-anchor: var(--ink);
  --mantine-primary-color-contrast: var(--paper);
  /* Errors keep their meaning but drop their hue — the one semantic exception,
     expressed as weight rather than colour. */
  --mantine-color-error: var(--ink);
}

/* Dark scheme: invert ground and ink, keep the greys neutral. The brandbook is
   a light system; this exists so the app stays coherent if a user flips it. */
:root[data-mantine-color-scheme="dark"],
:host([data-mantine-color-scheme="dark"]) {
  --mantine-color-body: var(--ink);
  --mantine-color-text: var(--paper);
  --mantine-color-bright: var(--paper);
  --mantine-color-dimmed: var(--ink-3);
  --mantine-color-default: hsl(0 0% 14%);
  --mantine-color-default-hover: hsl(0 0% 20%);
  --mantine-color-default-border: hsl(0 0% 26%);
  --mantine-color-default-color: var(--paper);
  --mantine-color-anchor: var(--paper);
  --mantine-primary-color-filled: var(--paper);
  --mantine-primary-color-filled-hover: hsl(0 0% 88%);
  --mantine-primary-color-contrast: var(--ink);
  --hatch-color: var(--paper);

  /* Mantine's dark ramp is blue-tinted. The brandbook wants true neutral grey,
     and Docmost leans on these heavily for dark surfaces. */
  --mantine-color-dark-0: var(--paper);
  --mantine-color-dark-1: hsl(0 0% 88%);
  --mantine-color-dark-2: hsl(0 0% 76%);
  --mantine-color-dark-3: var(--ink-3);
  --mantine-color-dark-4: hsl(0 0% 36%);
  --mantine-color-dark-5: hsl(0 0% 26%);
  --mantine-color-dark-6: hsl(0 0% 18%);
  --mantine-color-dark-7: var(--ink);
  --mantine-color-dark-8: var(--ink);
  --mantine-color-dark-9: hsl(0 0% 6%);
}

/* ---- the 45° hatch ----
   Removed at Pavel's request 2026-08-22: the trim band across the top is off
   "for now". The full implementation — 16px band, 8px gap, and the four
   viewport-height rules that had to be corrected to make room for it — is in
   commit 3274e22 and documented in README.md. Restoring it is a revert of that
   hunk, not a rewrite.

   The --hatch-w / --hatch-gap / --hatch-color tokens stay: they are brandbook
   geometry, and any future hatch surface (a callout, a cover, an OG card)
   should be driven from them rather than re-deriving 1.5px/11px by hand. */

/* ---- one ground, not two ----
   Docmost hardcodes the header, navbar and aside to #f6f7f9 (a cool grey, which
   the brandbook's neutral-grey rule forbids anyway) with a dark-8 variant. That
   is what made the chrome and the content read as two different surfaces.
   Matched by class *prefix* rather than the full CSS-module hash, because the
   hash changes on every Docmost build. !important is needed to beat the
   scheme-scoped rule and any inline style. */
:root [class*="_header_"],
:root [class*="_navbar_"],
:root [class*="_aside_"] {
  background-color: var(--mantine-color-body) !important;
}

/* ---- residual colour ----
   A few components carry hue that never passes through the variable layer:
   Badge takes the primary fill, Avatar derives a colour from the name (that is
   where the red "GE" came from). Mantine writes both as inline custom
   properties, so these need !important. */
.mantine-Badge-root {
  --badge-bg: var(--mantine-color-default-hover) !important;
  --badge-color: var(--mantine-color-text) !important;
  --badge-bd: 1px solid var(--mantine-color-default-border) !important;
}
.mantine-Avatar-root {
  --avatar-bg: var(--mantine-color-default-hover) !important;
  --avatar-color: var(--mantine-color-text) !important;
}

/* ---- the mark, legible on either ground ----
   The identity mark is a solid ink tile, which disappears against a dark
   surface. The mark is pure greyscale, so inverting it in dark mode yields the
   paper-tile/ink-glyph variant exactly. */
[data-mantine-color-scheme="dark"] img[src*="favicon"],
[data-mantine-color-scheme="dark"] .mantine-Avatar-root img {
  filter: invert(1);
}

/* The header wordmark inherits its colour from a link set to `inherit`, which
   lands on the wrong end of the scale in dark mode. */
[class*="_brand_"],
[class*="_brand_"] * {
  color: var(--mantine-color-text);
}

/* ---- article body: sans for reading, mono for everything structural ----
   Only the prose inside the editor changes face. Navigation, sidebar, search,
   buttons and every other chrome surface stay mono because they are governed by
   --mantine-font-family above and are untouched here. */
.ProseMirror {
  font-family: var(--maaake-sans);
}

/* Structure stays in the mono voice, even inside an article. */
.ProseMirror :where(table, table *),
.ProseMirror :where(code, pre, pre *, kbd, samp),
.ProseMirror :where(a) {
  font-family: var(--maaake-mono);
}

/* Weight floor is 400 — never lighter. De-emphasis is colour or size. */
.ProseMirror :where(p, li, span) {
  font-weight: 400;
}

/* Headings stay MONO — they are structure, not prose. This is the compromise
   that keeps the departure above honest: the mono voice still opens every
   section and still sets the page's rhythm, and only the running text (where
   mono actually costs reading speed) changes face. It also gives the article a
   clear two-voice hierarchy instead of one undifferentiated sans block.
   -0.03em is the brandbook's display tracking, which mono needs to close up its
   naturally wide default. */
.ProseMirror :where(h1, h2, h3, h4, h5, h6),
.ProseMirror :where(h1, h2, h3, h4, h5, h6) * {
  font-family: var(--maaake-mono);
  letter-spacing: -0.03em;
  font-weight: 700;
}

/* ---- links: affordance without hue ----
   The brandbook bans colour outright, so a link cannot be "the blue one". It
   earns its affordance from the underline instead. Broad on purpose: several
   components ship a hardcoded blue that the variable layer never reaches.
   These must resolve through --mantine-color-text, NOT --ink: hardcoding ink
   here painted every link #171717 on a #171717 ground in dark mode. */
a,
a:visited,
.mantine-Anchor-root,
.mantine-Text-root a {
  color: var(--mantine-color-text);
  text-decoration-color: var(--mantine-color-dimmed);
}
a:hover {
  color: var(--mantine-color-text);
  text-decoration: underline;
  text-decoration-color: var(--mantine-color-text);
}

/* ---- semantic highlights: the one sanctioned exception to "no colour" ----
   Comment marks and search hits are the only yellow left in the app, and they
   stay yellow at Pavel's call (2026-08-22). The reasoning is sound: the
   brandbook governs the *brand*, and these two are not brand — they are
   transient UI state about someone else's attention. A grey-on-grey comment
   mark is easy to scroll straight past, which defeats the entire point of
   leaving a comment. Docmost's own washes are used unchanged; the only thing
   added is a dark-scheme variant, because a 14%-alpha yellow over ink is
   invisible.

   Search hits need nothing: Docmost paints them solid #ffff65 and pins the
   text to #212529, so they already read on either ground.

   If this ever needs defending: it is deliberate, it is scoped to one class,
   and nothing about the identity depends on it. */
[data-mantine-color-scheme="dark"] .ProseMirror .comment-mark {
  background: rgb(255 215 0 / 22%);
}

/* Rules and dividers are hairlines, not shadows. */
hr,
.ProseMirror hr {
  border: 0;
  border-top: 1px solid var(--hairline);
}

/* ---- dark-mode filled buttons: fix white-on-white ----
   Mantine's filled Button hardwires its LABEL colour to
   `--button-color: var(--mantine-color-white)` as an INLINE style. The brand maps
   --mantine-color-white to paper, and the dark scheme above also makes the filled
   BACKGROUND paper — so the label went paper-on-paper (white on white, unreadable;
   reported by Pavel 2026-08-25). Force the filled label to ink so it reads on the
   light dark-mode button. Scope carefully: the default (primary) button carries NO
   data-variant attribute, other variants (subtle/outline/default/light) DO — those
   stay light-on-dark and are left alone, so the password eye-toggle etc. are safe.
   !important is required to beat the inline custom property. */
[data-mantine-color-scheme="dark"] .mantine-Button-root:not([data-variant]),
[data-mantine-color-scheme="dark"] .mantine-Button-root[data-variant="filled"] {
  --button-color: var(--ink) !important;
}

/* ---- login: the mark flies above the wordmark ----
   Pavel's ask 2026-08-25. Docmost's login logo is a Mantine Group (_logo_ prefix;
   the full class carries a per-build hash) laid out as a row: [mark] maaake.docs.
   Stack it into a column so the mark sits above the text, enlarge the mark (nginx
   serves the 512 source at that URL, so it upscales cleanly) and give it a gentle,
   reduced-motion-aware float — the "fly". The dark-mode invert() on the mark still
   applies; transform and filter compose fine. */
[class*="_logo_"] {
  flex-direction: column !important;
  gap: 14px !important;
}
[class*="_logo_"] img {
  width: 46px !important;
  height: 46px !important;
  animation: maaake-fly 3.2s ease-in-out infinite;
  will-change: transform;
}
@keyframes maaake-fly {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
@media (prefers-reduced-motion: reduce) {
  [class*="_logo_"] img { animation: none; }
}
/* Keep any in-app header/navbar logo horizontal and static — only the login hero
   flies. (Guards against Docmost reusing the _logo_ component in the top bar.) */
[class*="_header_"] [class*="_logo_"],
[class*="_navbar_"] [class*="_logo_"],
[class*="_aside_"]  [class*="_logo_"] {
  flex-direction: row !important;
  gap: 8px !important;
}
[class*="_header_"] [class*="_logo_"] img,
[class*="_navbar_"] [class*="_logo_"] img,
[class*="_aside_"]  [class*="_logo_"] img {
  width: 22px !important;
  height: 22px !important;
  animation: none !important;
}
