/* magnoon.nl — the base layer every app page starts from: the box-sizing reset,
   the scrollbar-gutter rule, the inherited control font, and the boot-failure
   notice.

   Split out because these were transcribed into all four app stylesheets and had
   started to disagree. `.bootfail` was the clearest case — the same notice, with
   the same 4s reveal animation and the same @keyframes name, written three times
   with three border colours (var(--cor), #a96969, #d17374), two radii and three
   different revealed margins. Nothing chose those differences; they are what
   happens when a rule is copied and then edited in one place. Now there is one.

   Load order matters and is the reason this is a separate file rather than more
   of chrome.css: this must come FIRST so an app can override it, and the
   self-contained loot-filter page injects chrome.css at the END of its stylesheet
   (the `__CHROME__` marker), where a reset would win against the app instead of
   losing to it. This file goes in at `__BASE__`, right after the palette.

   Depends on the custom properties in site/tokens.css, so it is linked after it.

   Deliberately NOT here: `body`. The four pages legitimately differ on
   typography and background — the loot-filter workbench is 14px/1.35 with a flat
   ground, the other three are 16px/1.5 and two of them carry a radial wash — and
   folding that into a shared rule would mean three overrides immediately, which
   is the duplication again with an extra indirection. Same for the per-app
   palette aliases (--line vs --border for the same --edge): renaming those
   touches thousands of declarations across two large stylesheets for no
   behavioural gain, so they stay, documented, in each app. */

* {
  box-sizing: border-box;
}

/* Keep the scrollbar present at all times so a page that grows past the viewport
   never shifts horizontally when the bar appears.

   This was `scrollbar-gutter: stable both-edges`, which reserved the gutter on
   *both* sides — and a gutter is outside the html content box, so every
   full-width element was inset by a scrollbar's width at each end. That is
   invisible on the page body, which is centred and narrower anyway, but the site
   rail is full-bleed: it left a strip of page background at both ends of the
   bar, so the bar appeared to stop short of the window. `overflow-y: scroll`
   gives the same no-shift guarantee with no gutter to leave a strip in. */
html {
  overflow-y: scroll;
}

/* Controls inherit page typography unless an app restyles them outright. */
button,
input,
select,
textarea {
  font: inherit;
}

/* ---- boot-failure notice ----
   Every app page carries a static <p class="bootfail"> that its module removes as
   its very first act, so it never shows on a working page. If the module does not
   run at all — a CSP that blocks it, a misnamed bundle, a failed download — the
   page is otherwise a silent static shell, and this reveals the notice after four
   seconds instead.

   Pure CSS on purpose: the site-wide CSP allows no inline script, so there is no
   timer to schedule this with. The zero-duration animation is a delayed toggle
   rather than a fade — at 4s the `to` frame applies and stays (forwards). */
.bootfail {
  max-height: 0;
  margin: 0;
  padding: 0 14px;
  overflow: hidden;
  opacity: 0;
  border: 0 solid var(--danger);
  border-radius: var(--radius-md);
  background: var(--panel);
  color: var(--ink);
  animation: bootfail-reveal 0s linear 4s forwards;
}

@keyframes bootfail-reveal {
  to {
    max-height: 8em;
    margin: 16px 0;
    padding: 12px 14px;
    opacity: 1;
    border-width: 1px;
  }
}

/* The key names in that notice. Only .bootfail carries them, but the rule is
   here rather than in one app's stylesheet for the same reason the notice is. */
.bootfail kbd {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: var(--fs-sm);
  padding: 0 4px;
  border: 1px solid var(--edge-soft);
  border-radius: var(--radius-sm);
  background: var(--chip-bg);
}

/* ---- no-script notice ----
   The same notice as .bootfail for the other way a page can end up inert, so it
   gets the same box: three apps had transcribed it into their own stylesheets
   with three border colours (var(--cor), var(--danger), #d17374 — all the same
   colour under different names), three radii and three margins. */
.noscript {
  margin: 16px 0;
  padding: 12px 14px;
  border: 1px solid var(--danger);
  border-radius: var(--radius-md);
  background: var(--panel);
  color: var(--ink);
}

/* ---- "pick something first" placeholder ----
   Both tools with pickers put this where their results go when a selection is
   missing: Prism Crafting in place of the six prism cards, the Atlas in place of
   the checklist and the outcome pool. It is a panel the size of the cards it
   replaces, not a warning, so it takes --panel and --muted rather than the
   --danger box above.

   `grid-column` because every one of those containers is a grid: without it the
   prompt takes one auto-fit column and reads as an empty first card. It is inert
   in a non-grid parent, so it costs the other uses nothing. */
.selection-prompt {
  grid-column: 1/-1;
  margin: 0;
  padding: 18px 20px;
  border: 1px solid var(--edge-soft);
  border-radius: var(--radius-md);
  background: var(--panel);
  color: var(--muted);
}
