/* Foundation layer: fonts, material, reset, and reusable primitives.
   Loaded AFTER tokens.brand.css + tokens.product.css and BEFORE app.css.
   Values come only from var(--token); no literal hex/radius here. */

/* --- Fonts (self-hosted, English/Latin subset) --- */
@font-face {
  font-family: "Onest Variable";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/onest-latin-wght-normal.d5c8e706f54e.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/ibm-plex-mono-latin-400-normal.79936b18df9f.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/ibm-plex-mono-latin-500-normal.b1c8a895f5fd.woff2") format("woff2");
}

/* --- Base document typography (owns html/body; app.css must not redeclare) --- */
html {
  background: var(--paper);
}
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "Onest Variable", "Onest", -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: var(--text-base);
  line-height: 1.55;
  text-rendering: optimizeLegibility;
}

/* --- Paper texture: one fixed, pointer-events-none overlay (no scroll repaint) --- */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  background: url("textures/notebook-paper.648c51d93dc8.webp") center / 560px repeat;
  mix-blend-mode: multiply;
  opacity: var(--texture-opacity);
}
:root[data-theme="dark"] body::before {
  mix-blend-mode: soft-light;
  filter: grayscale(1) invert(1);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body::before {
    mix-blend-mode: soft-light;
    filter: grayscale(1) invert(1);
  }
}

/* --- Accessibility / focus primitive --- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 3px;
}
::selection { background: var(--blue-soft); color: var(--ink); }

/* --- Typography scale primitive --- */
h1, h2, h3 { margin: 0; font-weight: 650; letter-spacing: -0.02em; line-height: 1.2; }
h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); }
h3 { font-size: var(--text-title); }

/* --- Button primitive (9px radius, never a full pill) --- */
.button {
  min-height: 40px;
  padding: 0 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-small);
  font: inherit;
  font-weight: 620;
  cursor: pointer;
  white-space: nowrap;
  transition: transform .2s var(--ease), background .2s var(--ease), border-color .2s var(--ease);
}
.button:active { transform: translateY(1px) scale(.985); }
/* A disabled button used to be pixel-identical to a live one, so "Promote"
   (disabled until an area is picked) read as broken rather than as waiting.
   Dimming alone would drop it under 4.5:1, so the cursor and the dropped hover
   carry the message too — and :disabled is exposed to assistive tech anyway. */
.button:disabled { opacity: .55; cursor: not-allowed; }
.button:disabled:hover { transform: none; }
/* .button sets metrics only -- no colour, no text-decoration. On a <button>
   the UA supplies a background and the element inherits colour, but an
   <a class="button"> keeps the browser's blue AND its underline, so it renders
   as a raw link wearing button padding. That shipped on Home's connect panel
   and is still live on the OAuth consent screen's Cancel. This is the same fix
   a.btn already carries a few hundred lines into app.css; .button itself stays
   untouched for the <button> case. */
a.button { text-decoration: none; }
/* The colour reset is a FLOOR, not a ceiling, so it goes through :where() --
   which contributes no specificity, leaving this at plain `a` (0,0,1). Written
   as `a.button { color: inherit }` (0,1,1) it out-specified
   `.button-primary { color: var(--paper-solid) }` (0,1,0) and repainted the
   primary CTA's label in whatever muted colour surrounded it. */
a:where(.button) { color: inherit; }
.button-small { min-height: 34px; padding: 0 12px; font-size: 14px; }
.button-primary { background: var(--blue-strong); color: var(--paper-solid); border-color: var(--blue-strong); }
.button-primary:hover { background: var(--blue); border-color: var(--blue); transform: translateY(-1px); }

/* --- Form-control focus primitive --- */
/* Text-entry controls hold a 14px readability floor above the dense 13px body. */
input, textarea, select { font: inherit; font-size: var(--text-md); }
/* A border-colour swap alone is NOT a focus indicator: on a 1px edge it is easy
   to miss and disappears entirely for anyone who cannot resolve the hue change.
   Keep the ring (WCAG 2.4.7) and let the border tint ride along with it. */
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 1px;
  border-color: var(--blue);
}

/* --- Skip link: 13 of 18 focusable elements on a page are sidebar chrome, so
   without this every keyboard user re-tabs the whole nav on every page. --- */
.skip-link {
  position: absolute;
  left: 8px;
  top: -100px;
  z-index: 100;
  padding: 10px 14px;
  background: var(--paper-raised);
  color: var(--ink);
  border: 1px solid var(--blue);
  border-radius: var(--radius-small);
  font-weight: 620;
  text-decoration: none;
  transition: top .15s var(--ease);
}
.skip-link:focus { top: 8px; }

/* --- Brand artwork ---
   Supplied PNG with alpha, so it cannot follow currentColor the way an inline
   SVG would: the theme change is a file swap. Sizes set width only — height
   follows the artwork's own ratio (symbol 253x230, wordmark 586x168). */
.brand-art { display: inline-flex; align-items: center; gap: 9px; line-height: 0; }
.brand-art img { display: block; width: 100%; height: auto; }
.brand-art-mark { display: block; width: 24px; }
.brand-art-word { display: block; width: 66px; }
.brand-art .art-dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .brand-art .art-light { display: none; }
  :root:not([data-theme="light"]) .brand-art .art-dark { display: block; }
}
:root[data-theme="dark"] .brand-art .art-light { display: none; }
:root[data-theme="dark"] .brand-art .art-dark { display: block; }
