/* ===========================================================================
   BASE — the document, the icon contract, and the handful of globals that
   every component below assumes is already true.

   Load after tokens.css and before components.css.
   =========================================================================== */

/* ------------------------------------------------------------------ icons --
   The icon builder returns an <svg> with no size, no colour and no style
   attribute, so size comes from here and colour from `currentColor` — an icon
   follows the text beside it through every hover and state class without one
   extra rule. */
.icon {
  width: var(--icon-size);
  height: var(--icon-size);
  flex: 0 0 auto;          /* never squashed by a flex row */
  display: block;          /* no inline baseline gap */
}

/* The three sizes to use. A fourth is a smell — check whether the component
   beside it should be resizing instead. */
.icon-sm { --icon-size: var(--icon-size-sm); }
.icon-lg { --icon-size: var(--icon-size-lg); }

/* An ICON SLOT: an empty element the page fills with a glyph. Grid rather than
   the browser's default inline, for two reasons — the svg centres in whatever
   box the slot ends up with, and an inline parent would give a block child a
   baseline descender gap, which is a two-pixel misalignment that only shows up
   next to text and is maddening to chase.

   Declared once here rather than per component. Several components below still
   restate it, which is harmless; what matters is that a new component that
   forgets to is right anyway. */
[data-icon] { display: grid; place-items: center; }

/* Icons carrying a state colour rather than inheriting one. */
.icon-danger { color: var(--error); }
.icon-warn   { color: var(--warn); }
.icon-dim    { color: var(--dim); }

/* Motion is a preference, not a decoration. Honoured globally so no component
   has to remember it. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}

* { box-sizing: border-box; }

/* `hidden` is semantic, and every `display` in a component file outranks it —
   which is not a nuisance, it is a security bug waiting to happen. An app
   that hides what a user may not reach does it by setting this attribute, and
   a component rule with `display: flex` silently un-hides it.

   `!important` is right here for the reason it is usually wrong: nothing
   should ever out-rank this. */
[hidden] { display: none !important; }

::selection { background: var(--primary-cont); color: var(--on); }

body {
  margin: 0;
  background: var(--surface);
  color: var(--on);
  font-family: var(--font);
  font-size: var(--text-8);
  line-height: 1.5;
}

/* An app shell that owns the viewport. Drop this class for an ordinary
   scrolling document. */
body.app-shell {
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Four columns means up to four scroll containers side by side, and a
   browser's default bar is a bright band down each of the seams. Thin and in
   the palette instead — still visible, still draggable, no longer the loudest
   vertical line on the screen. */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--surface-est) transparent;
}
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--surface-est);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--radius-pill);
}
::-webkit-scrollbar-thumb:hover {
  background: color-mix(in srgb, var(--surface-est) 60%, var(--dim));
  background-clip: content-box;
}
::-webkit-scrollbar-corner { background: transparent; }

/* 500 rather than 600, which is what every named title in this system uses.
   A bare <h3> reading heavier than the styled heading beside it is the
   commonest way a page loses its rhythm. */
h1, h2, h3 { margin: 0; font-family: var(--font-display); font-weight: 500; letter-spacing: -0.01em; }
h1 { font-size: var(--text-9); }
h2 { font-size: var(--text-11); }
h3 { font-size: var(--text-10); }
p { margin: 0 0 var(--space-2); }
code { font-family: var(--mono); font-size: 0.92em; color: var(--outline); }

.muted { color: var(--dim); }
.warn-ink { color: var(--warn); }
.small { font-size: var(--text-5); }

/* Present, and holding its space, but neither seen nor reachable: hidden this
   way an element keeps its box, and `visibility` takes it out of the tab
   order and the accessibility tree exactly as `hidden` would. Use it so a
   control that comes and goes does not move the controls beside it. */
.is-reserved { visibility: hidden; }
