/* zewbie LAYOUT PRIMITIVES -- P7.1
   =================================================================================
   This file holds ONLY what is above the component sheet: the document reset, the
   global header and nav, the footer, and four composition primitives that every
   page in P7.2..P7.6 is expected to use instead of inventing spacing.

   It is deliberately the ONLY css file P7.1 adds. `tokens.css` is the P4.1 winner
   VERBATIM (sha256 6dc0b987...f99ef) and `components.css` is the P4.3 component
   sheet VERBATIM (sha256 ca1a4ac7...1c909). Neither was edited to make this file
   work; if a primitive needed a new token the answer was to compose existing ones.

   WHY NO NEW COMPONENTS HERE: `skeleton.html`'s own comment says "do not build a
   second design system here". A nav bar is a layout host, not a component family,
   and the eleven component families are P4.3's and stay there.

   Cascade order is load order, and it matters:
       tokens.css  ->  layout.css  ->  components.css
   layout.css sets element-level defaults (`a`, `table`, `img`); components.css
   sets class-level rules that must win over them. `base.html` links them in that
   order and nothing else may reorder them.

   EVERY policed length in here is a token or an allowlisted literal (P4.2 gate 1,
   rules R1-R5). The four pinned breakpoints are 480/768/1024/1280 and this file
   uses two of them.
   ================================================================================= */

/* ------------------------------------------------------------------ 0. reset */

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

html {
  /* The two SC 1.4.12 test values live on the root so a page cannot forget them. */
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: var(--sp-0);
  background-color: var(--c-bg);
  color: var(--c-text);
  font-family: var(--font);
  font-size: var(--fs-base);
  font-weight: var(--fw-regular);
  line-height: var(--lh-base);
  /* The single most load-bearing declaration in this file for the 360px gate: a
     page is allowed to scroll DOWN, never SIDEWAYS. This does not hide an
     overflow -- `tools/check_viewport.js` measures the widest ELEMENT as well as
     the document, so a box that sticks out is still caught and named. */
  overflow-x: hidden;
}

/* An image or an embed is the classic 360px overflow. Cap them once, here. */
img,
svg,
video,
iframe {
  max-width: 100%;
  height: auto;
}

/* A long report number, a lab URL or a 40-character shape name must wrap rather
   than push the viewport. */
body {
  overflow-wrap: break-word;
}

a {
  color: var(--c-accent);
}

/* ------------------------------------------------- 1. the skip link (SC 2.4.1) */

/* Off-screen until focused. It is the first focusable thing in the document and
   it is the reason `<main id="main">` carries that id in base.html. */
.skip-link {
  position: absolute;
  left: var(--sp-0);
  top: var(--sp-0);
  z-index: 100;
  background-color: var(--c-accent);
  color: var(--c-accent-fg);
  padding-block: var(--sp-2);
  padding-inline: var(--sp-4);
  border-radius: var(--radius);
  font-weight: var(--fw-semibold);
  /* `transform` is not a policed property: this is how it hides without
     `display:none`, which would take it out of the tab order entirely. */
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: translateY(var(--sp-0));
}

/* ------------------------------------------------------------- 2. the container */

/* The one horizontal measure in the product. Everything that is not a
   full-bleed band sits in one of these. */
.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--sp-4);
}

@media (min-width: 768px) {
  .container {
    padding-inline: var(--sp-5);
  }
}

/* ---------------------------------------------------------- 3. the site header */

.site-header {
  background-color: var(--c-surface);
  /* A structural divider is decorative, so `--c-border` is the correct token and
     R5 permits it: `.site-header` is not an interactive selector. */
  border-block-end: var(--border-w) solid var(--c-border);
}

.site-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  padding-block: var(--sp-3);
}

.brand {
  color: var(--c-text);
  font-size: var(--fs-lg);
  line-height: var(--lh-lg);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  /* Pushes the nav to the far edge on one line without a spacer element. */
  margin-inline-end: auto;
}

.brand:hover {
  text-decoration: underline;
}

.site-nav__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1);
  margin: var(--sp-0);
  padding: var(--sp-0);
  list-style: none;
}

/* A nav link is a control, so it gets the 40px target from `--control-min-h`
   (clears SC 2.5.8's 24px without needing the spacing exception) and NO
   `--c-border`: see R5. Its resting state is text, its focus state is the
   shared focus ring below. */
.site-nav__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-min-h);
  padding-inline: var(--sp-3);
  border-radius: var(--radius);
  color: var(--c-text);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  text-decoration: none;
}

.site-nav__link:hover {
  background-color: var(--c-bg);
  text-decoration: underline;
}

/* `aria-current="page"`, not a `.is-active` class: the accessible state and the
   visual state are the same attribute, so they cannot drift apart. Three
   signals, never colour alone -- weight, fill and a 3:1 edge. */
.site-nav__link[aria-current="page"] {
  background-color: var(--c-bg);
  border: var(--border-w) solid var(--c-border-strong);
  font-weight: var(--fw-semibold);
}

/* NOT YET BUILT (`services/navigation.py`). TWO signals, because colour alone
   would fail SC 1.4.1: muted text AND a dotted underline. It keeps its tab stop
   and its `title`/`aria-describedby` reason -- see `_header.html`. When P7.2..P7.6
   register their endpoints this selector simply stops matching; nothing here
   needs editing. `--c-text-muted` on `--c-surface` is 7.3:1 in the P4.2 audit,
   so "muted" is not "low contrast". */
.site-nav__link[aria-disabled="true"] {
  color: var(--c-text-muted);
  text-decoration: underline dotted;
  cursor: default;
}

.site-nav__link[aria-disabled="true"]:hover {
  background-color: transparent;
  text-decoration: underline dotted;
}

/* The shortlist tray count. Tabular so 1 -> 2 does not shift the nav. */
.site-nav__count {
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-semibold);
}

/* ---------------------------------------------------------- 4. the site footer */

.site-footer {
  margin-block-start: var(--sp-8);
  background-color: var(--c-surface);
  border-block-start: var(--border-w) solid var(--c-border);
  color: var(--c-text-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
}

.site-footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
  padding-block: var(--sp-6);
}

.site-footer__col {
  flex-basis: var(--card-min);
  flex-grow: 1;
}

.site-footer__heading {
  margin: var(--sp-0);
  margin-block-end: var(--sp-2);
  color: var(--c-text);
  font-size: var(--fs-sm);
  line-height: var(--lh-sm);
  font-weight: var(--fw-semibold);
}

.site-footer__list {
  margin: var(--sp-0);
  padding: var(--sp-0);
  list-style: none;
}

.site-footer__list li + li {
  margin-block-start: var(--sp-1);
}

/* A footer destination that this build does not have. It is NOT an anchor: in
   the footer there is no tray count or state to preserve, so the honest render
   is plain text plus the sr-only reason -- an `aria-disabled` link here would
   add a tab stop that leads nowhere. */
.site-footer__unbuilt {
  color: var(--c-text-muted);
  text-decoration: underline dotted;
}

.site-footer__note {
  margin-block-start: var(--sp-2);
  margin-block-end: var(--sp-0);
  max-width: var(--measure);
}

/* ------------------------------------------------- 5. composition primitives */

/* `.page` -- the main content column of any page. */
.page {
  padding-block: var(--sp-6);
}

.page__header {
  margin-block-end: var(--sp-5);
}

.page__title {
  margin: var(--sp-0);
  font-size: var(--fs-2xl);
  line-height: var(--lh-2xl);
  font-weight: var(--fw-semibold);
}

.page__lede {
  margin-block-start: var(--sp-2);
  margin-block-end: var(--sp-0);
  max-width: var(--measure);
  color: var(--c-text-muted);
  font-size: var(--fs-lg);
  line-height: var(--lh-lg);
}

/* `.stack` -- vertical rhythm via the owl selector, so a page never sets a
   margin on a component and components stay position-independent. */
.stack > * + * {
  margin-block-start: var(--sp-4);
}

.stack--tight > * + * {
  margin-block-start: var(--sp-2);
}

.stack--loose > * + * {
  margin-block-start: var(--sp-6);
}

/* `.cluster` -- a wrapping row of things of unequal size: chips, button rows,
   a label next to a count. */
.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}

.cluster--tight {
  gap: var(--sp-2);
}

/* `.prose` -- a readable measure for anything that is sentences. */
.prose {
  max-width: var(--measure);
}

.prose h2 {
  margin-block-start: var(--sp-6);
  margin-block-end: var(--sp-2);
  font-size: var(--fs-xl);
  line-height: var(--lh-xl);
  font-weight: var(--fw-semibold);
}

.prose p {
  margin-block-start: var(--sp-0);
  margin-block-end: var(--sp-4);
}

/* ------------------------------------------------------------ 6. the focus ring */

/* components.css scopes its focus ring to a `:where()` list of the eleven
   component families' controls, which by construction cannot name anything
   P7.1 adds. These are layout.css's own controls and they get the identical
   ring from the identical tokens -- NOT a second, slightly different one. */
:where(.skip-link, .brand, .site-nav__link, .site-footer__list a):focus-visible {
  outline: var(--focus-w) solid var(--c-accent);
  outline-offset: var(--focus-off);
}
