/* ============================================================================
   Grosso University — base layer
   Element defaults + the structural guarantees the tokens alone cannot make.
   Load AFTER tokens.css.
   ============================================================================ */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  interpolate-size: allow-keywords;   /* height:auto transitions where supported */
}

body {
  margin: 0;
  font-family: var(--gu-font-text);
  font-size: var(--gu-text-base);
  line-height: var(--gu-leading-body);
  color: var(--gu-fg);
  background-color: var(--gu-bg);
  -webkit-font-smoothing: antialiased;
}

/* ── The no-spill guarantee ──────────────────────────────────────────────────
   The user's standing directive is "no horizontal spill, ever". Fluid type
   minimums get a heading close, but a single long word — a German-length
   compound, a URL, an unbroken product code — can still exceed a 328px content
   box at 360px, and no amount of clamp() tuning prevents it. These three rules
   make it structurally impossible rather than a per-string hope:

     overflow-wrap: break-word  — a word longer than its line breaks instead of
                                  escaping the box. `anywhere` is deliberately
                                  NOT used: it also shrinks the intrinsic min-
                                  content size, which collapses flex/grid tracks.
     min-width: 0 on flex/grid  — the default `min-width:auto` refuses to shrink
                       children     an item below its min-content width, so a
                                  wide child pushes the whole row sideways. This
                                  is the single most common source of spill.
     max-width: 100% on media   — an image with intrinsic width beyond its column
                                  ignores the column without it.
   ---------------------------------------------------------------------------- */
body { overflow-wrap: break-word; }
:where(h1, h2, h3, h4, h5, h6, p, li, dd, dt, figcaption, blockquote, td, th) {
  overflow-wrap: break-word;
}
:where(
  [style*="display:flex"], [style*="display: flex"],
  [style*="display:grid"], [style*="display: grid"]
) > *,
:where(.flex, .grid, .cluster, .row, .stack) > * { min-width: 0; }

:where(img, svg, video, canvas, picture, iframe, object, embed) {
  max-width: 100%;
  height: auto;
}
:where(img, video) { display: block; }

/* ── Typography ─────────────────────────────────────────────────────────── */
:where(h1, h2, h3, h4, h5, h6) {
  margin: 0;
  font-family: var(--gu-font-display);
  font-weight: var(--gu-display-weight);
  text-transform: var(--gu-display-transform);
  letter-spacing: var(--gu-display-tracking);
  line-height: var(--gu-display-leading);
  /* `balance` evens out ragged short headings; capped at 6 lines by spec, which
     is why body copy uses `pretty` instead. */
  text-wrap: balance;
  /* Display type is set in caps at large sizes, so a single long word can be
     wider than a 360px content box on its own — "PROFESSIONALS" measures 390px
     at --gu-text-5xl against a 326px box. Hyphenation breaks it at a syllable
     with a visible hyphen, which reads far better than the hard mid-word chop
     `overflow-wrap: break-word` produces. It needs a `lang` on <html>, which
     every rendered page sets. */
  hyphens: auto;
}
h1 { font-size: var(--gu-text-4xl); }
h2 { font-size: var(--gu-text-3xl); }
h3 { font-size: var(--gu-text-2xl); }
h4 { font-size: var(--gu-text-xl); }
h5 { font-size: var(--gu-text-lg); }
h6 { font-size: var(--gu-text-base); letter-spacing: 0.12em; }

:where(p, li, dd, blockquote) { text-wrap: pretty; }   /* kills orphans */
:where(p, ul, ol, dl, blockquote, figure, pre) { margin-block: 0 var(--gu-space-sm); }
:where(p, li) { max-width: var(--gu-measure); }

/* Hover must be visible on EVERY surface, including the two where color cannot
   change. On [data-surface=blue] white is the contrast ceiling and on
   [data-surface=gold] ink is the floor, so --gu-link-hover equals --gu-link
   there and a color-only hover would be invisible. Thickening the underline is
   the signal that works on all eight plates. */
a {
  color: var(--gu-link);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color var(--gu-dur-fast) var(--gu-ease),
              text-decoration-thickness var(--gu-dur-fast) var(--gu-ease);
}
a:hover {
  color: var(--gu-link-hover);
  text-decoration-thickness: 3px;
}

strong, b { font-weight: 700; }
small { font-size: var(--gu-text-sm); }
code, kbd, samp, pre { font-family: var(--gu-font-mono); font-size: 0.9em; }
pre { overflow-x: auto; }          /* code blocks scroll; they never spill */

hr { border: 0; border-top: 1px solid var(--gu-rule); margin-block: var(--gu-space-lg); }

/* ── Focus ──────────────────────────────────────────────────────────────────
   Visible on every surface because --gu-focus is defined per surface. Never
   removed: `outline: none` without a replacement is an accessibility defect. */
:focus-visible {
  outline: var(--gu-focus-width) solid var(--gu-focus);
  outline-offset: var(--gu-focus-offset);
  border-radius: var(--gu-radius-sm);
}
:focus:not(:focus-visible) { outline: none; }

/* ── Layout primitives ──────────────────────────────────────────────────── */
.gu-wrap {
  max-width: var(--gu-max-width);
  margin-inline: auto;
  padding-inline: var(--gu-gutter);
}
.gu-section { padding-block: var(--gu-section-y); }

/* Wide, irreducible content (data tables, wide diagrams, code) scrolls inside
   its own box. This is the ONLY sanctioned way for content to exceed the
   viewport width. */
.gu-scroll-x {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
}

/* ── Screen-reader-only ─────────────────────────────────────────────────── */
.gu-sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}
.gu-skip-link {
  position: absolute; inset-inline-start: var(--gu-space-sm); top: var(--gu-space-sm);
  z-index: 100; padding: var(--gu-space-2xs) var(--gu-space-sm);
  background: var(--gu-bg); color: var(--gu-fg);
  border: 2px solid var(--gu-focus); border-radius: var(--gu-radius-sm);
  transform: translateY(-200%);
}
.gu-skip-link:focus { transform: none; }

/* ── Motion ─────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}
