/* ---- Shared layout and components ----------------------------------------
   The palette and the type/space scale live in `tokens.css`, which every
   template linking this file links first. Nothing here may introduce a colour
   literal: if a component needs a colour that no token names, the token block
   is where that argument gets settled.
   -------------------------------------------------------------------------- */

/* ---- Layout --------------------------------------------------------------- */

body {
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--text);
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--sp-24) var(--sp-16) var(--sp-64);
}

/* The full-bleed body: `body` sets no measure of its own, bands run edge to
   edge and each one centres its own `.page-width`.

   Two shells take it, and they are exactly the two that render
   `partials/site_header.html`. That is the point: the header centres itself,
   and a body that also caps itself would inset it twice and stop its rule
   short of the window. The pre-login surface
   (`public/base.html`) is one; the organization picker is the other, signed
   in but with no tenant chosen and so no application shell. */
body.page-public,
body.page-picker {
  --gutter: var(--sp-20);
  max-width: none;
  padding: 0;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}

.page-width {
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  background: var(--accent);
  color: var(--on-accent);
  padding: var(--sp-8) var(--sp-20);
  border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; }

.site-header {
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--sp-24);
}
.site-header__inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-12) var(--sp-20);
  flex-wrap: wrap;
  padding-block: var(--sp-8);
}
.site-header a { color: inherit; text-decoration: none; }
/* ...except the one that is a filled button. `.site-header a` outranks `.btn`,
   so "Create a workspace" was ink-on-accent: roughly 2.7:1, unreadable. */
.site-header a.btn { color: var(--on-accent); }
.site-header nav {
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  flex-wrap: wrap;
  font-size: var(--fs-small);
}

/* Wordmark: the site icon plus its name, one target. */
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-8);
  font-weight: var(--fw-semibold);
}
.wordmark .brand-mark { width: 2rem; height: 2rem; display: block; flex: none; }

/* The public and workspace footers share only the two linked brand marks. */
.footer-brands {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-16) var(--sp-24);
}
.footer-brands a { color: inherit; text-decoration: none; }
.footer-brands .wordmark { font-size: var(--fs-body); }
.footer-brands__auray { display: inline-flex; align-items: center; }
.footer-brands .auray-logo__svg {
  display: block;
  height: var(--sp-32);
  width: auto;
}

@media (max-width: 30rem) {
  .footer-brands { justify-content: center; }
}

/* The language switcher was an unstyled OS dropdown on every page (UX-001).
   It is chrome, not a form field: it sits in a topbar row of `.btn-small`
   controls, so it keeps this compact rule and stays out of `forms.css`'s
   scopes, exactly like the topbar search. */
.lang-switch select {
  font: inherit;
  font-size: var(--fs-small);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--sp-4) var(--sp-8);
}

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* `animation-delay` is deliberately absent: a delay is a wait, not motion.
   The in-flight bar's `--dur-wait` is what keeps a fast answer from flashing
   it (`primitives.css`), and flattening the delay here would reintroduce
   exactly the flicker this block exists to prevent. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    transition-delay: 0ms !important;
  }
}

h1 { font-size: var(--fs-h1); line-height: var(--lh-h1); font-weight: var(--fw-semibold); }
h2 {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  font-weight: var(--fw-semibold);
  margin: var(--sp-24) 0 var(--sp-8);
}
h3 { font-size: var(--fs-h3); line-height: var(--lh-h3); font-weight: var(--fw-semibold); }

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

/* ---- Assessment workspace ------------------------------------------------- */

.summary-bar {
  display: flex; flex-wrap: wrap; gap: var(--sp-8);
  margin: var(--sp-16) 0;
}

/* The table itself is the primitive in `tables.css`, which `.assessment-table`
   is an alias of until each list is rewritten onto it (style guide 12.1).
   This is the one cell class the older lists still name. */
.req-id { font-family: var(--font-mono); white-space: nowrap; }

.detail-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  padding: var(--sp-16);
  margin: var(--sp-4) 0;
  display: grid;
  gap: var(--sp-12);
}
.detail-panel .zh { color: var(--muted); }
.detail-panel .note { color: var(--muted); font-size: var(--fs-small); }
.guidance {
  background: var(--accent-soft);
  border-radius: var(--radius-sm);
  padding: var(--sp-8) var(--sp-12);
  font-size: var(--fs-ui);
  /* Harvested guidance is one labelled line per checklist column
     (`load_guidance`); without this the four lines run together. */
  white-space: pre-line;
}

.fields-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: var(--sp-8) var(--sp-16);
  font-size: var(--fs-ui);
}
/* The read side's field labels and the edit side's `.field-group` legends are
   one legend (spec 7.1), so a record reads the same whether it is being read
   or written. Sentence case: Chinese has no capitals and takes no tracking. */
.fields-grid dt {
  color: var(--slate);
  font-size: var(--fs-micro);
  font-weight: var(--fw-medium);
}
.fields-grid dd { margin: 0; }

/* The chip and cell vocabulary, the panel, the legend, the notice and the ID
   tag live in `primitives.css`, linked right after this file: they are one
   shared surface-and-status vocabulary rather than page layout (spec 7.1 to
   7.4, 7.9). Every chip class this file used to define survives there as an
   alias of a status. */

/* ---- Forms & buttons ------------------------------------------------------ */

/* A pager is a `.btn-row` whose middle item is a sentence, so it centres on
   the buttons rather than sitting on their top edge. The row itself, and
   every button in it, is `buttons.css`. */
.pager { align-items: center; flex-wrap: wrap; margin-top: var(--sp-12); }

/* Present to a screen reader, absent from the page. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

/* `hidden` must win over any layout rule a component sets on the same
   element (static/js/field-switch.js relies on it to hide the input the
   chosen evidence kind does not use). */
[hidden] { display: none !important; }

.evidence-list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-4); }
.evidence-list li {
  display: flex; justify-content: space-between; gap: var(--sp-12);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: var(--sp-8) var(--sp-12); font-size: var(--fs-ui); background: var(--surface);
}
.evidence-expired { color: var(--crit); }

/* One stored artifact: the link that hands the bytes back, and the digest a
   reader checks them against (templates/partials/evidence_file.html and
   evidence_digest.html). Both break anywhere, because a filename is
   user-supplied and a SHA-256 is 64 unbreakable characters. */
.evidence-file { overflow-wrap: anywhere; }
.evidence-digest {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  color: var(--muted);
  overflow-wrap: anywhere;
}

/* ---- Coverage dashboard (M3) ---------------------------------------------- */

.coverage-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: var(--sp-12);
}
.coverage-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--sp-20);
}
.coverage-card h3 { margin: 0; }
.coverage-card .summary-bar { margin: var(--sp-12) 0; }

.report-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-12);
  font-size: var(--fs-ui);
}
/* Every control that produces a document: the audit pack, the gap CSV, the
   assessment report, the Article 13 view and the effectiveness review. Each
   one carries a language select beside its button
   (`partials/language_select.html`), so they share one row shape. */
.audit-pack-form,
.export-form {
  margin-top: var(--sp-12);
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-8);
}
.audit-pack-form .field,
.export-form .field { margin: 0; }

.article-section { margin-top: var(--sp-32); }
.article-section .assessment-table { margin-top: var(--sp-8); }

.note { color: var(--muted); font-size: var(--fs-small); }
.zh { color: var(--muted); }

/* ---- Case plane (M4) ------------------------------------------------------
   The case is a record page now: its two columns, its rail and the transition
   list live in `record.css`, which every record page will share, and its
   panels are the one `.panel` of `primitives.css`. What is left here is the
   release and advisory dressing below. */

/* ---- Release & advisory panels (M5) --------------------------------------- */

.release-facts {
  list-style: none; margin: var(--sp-8) 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--sp-8);
  font-size: var(--fs-small);
}
.release-facts li {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: var(--sp-4) var(--sp-8);
}
.release-facts .req-id { margin-left: var(--sp-4); }
.fact-ok { background: var(--ok-soft); color: var(--ok); }
.fact-missing { background: var(--crit-soft); color: var(--crit); }

.advisory-banner {
  border-left: 3px solid var(--accent);
  padding: var(--sp-4) 0 var(--sp-4) var(--sp-12);
}

/* The Markdown hint above the advisory's long fields is a grid item in
   `.panel-form`, so its own paragraph margins would stack on the grid gap. */
.advisory-format-hint { margin: 0; }

/* Same reason for the CVSS vector hint in the assessment panel. */
.cvss-vector-hint { margin: 0; }

/* ---- Public report form --------------------------------------------------- */

.public-body { max-width: var(--measure-prose); }
.report-notice {
  border-left: 3px solid var(--accent);
  padding: var(--sp-4) 0 var(--sp-4) var(--sp-12);
  margin-top: var(--sp-24);
}

/* ---- Product cards on workspace home -------------------------------------- */

.card-list { list-style: none; padding: 0; display: grid; gap: var(--sp-12); }
.card-list li {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: var(--sp-20);
}

/* ---- Flash messages (self-service signup, M7b) -----------------------------
   The region itself, only: each message inside it is a `.notice` in its own
   tone (style guide 7.9, `partials/messages.html`). It is rendered whether or
   not it holds anything, so it has no padding of its own to collapse. */

.site-messages { margin-inline: var(--sp-20); display: grid; gap: var(--sp-8); }
/* The vertical space belongs to the messages, not to the region: an empty
   region must take no room at all, and it is never removed from the page. */
.site-messages > .notice:first-child { margin-top: var(--sp-12); }
/* Both full-bleed shells pad through `.page-width`; a second inset double-counts. */
.page-public .site-messages,
.page-picker .site-messages { margin-inline: 0; }

/* ---- Narrowed section notice ---------------------------------------------- */
/* Drawn by every page a dashboard count hands a reader to (the case list, the
   assessment workspace, the monitoring board, the test and review plan), so it
   belongs with the shared components rather than in four page stylesheets.
   It reads as chrome and never as a status: a filter is not a verdict, so the
   accent is right here and a status colour would not be (tokens.css, rule 2).
   The way out sits at the far end of the row, where a reader looking for it
   finds it in the same place on all four pages. */

.filter-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-8) var(--sp-12);
  margin: var(--sp-16) 0;
  padding: var(--sp-8) var(--sp-12);
  background: var(--panel-sunk);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
}
.filter-notice p { margin: 0; }
.filter-notice__label { color: var(--text); }
.filter-notice__n { color: var(--muted); font-size: var(--fs-small); }
.filter-notice__clear { margin-left: auto; }
