/* QIMS 9000 — components
 *
 * Specified in `design/14-design-system.md`. Requires `tokens.css`.
 *
 * Plain CSS on semantic HTML, no framework, because the front-end stack is not
 * decided. Every class here is a component in the specification; a class that
 * is not in the spec does not belong in this file.
 *
 * Two rules that come from D-62 and are not style preferences:
 *   - focus is never removed, only restyled, and is 3:1 against its surface;
 *   - status is never colour alone. Every badge and banner carries its own
 *     text, and the colour is redundant with it rather than load-bearing.
 */

/* ---------------------------------------------------------------- shell */

.qims-app {
  font-family: var(--qims-font);
  font-size: var(--qims-text-base);
  line-height: var(--qims-leading-normal);
  color: var(--qims-text);
  background: var(--qims-surface-sunken);
  min-height: 100vh;
}

.qims-header {
  display: flex;
  align-items: center;
  gap: var(--qims-space-4);
  padding: var(--qims-space-3) var(--qims-space-6);
  background: var(--qims-surface);
  border-bottom: 1px solid var(--qims-border);
}

/* The deck puts the logo top right on every page. It is TJ4's mark, not the
   customer's -- see D-61 -- and the slot is fixed height so a revised file
   drops in without moving anything. */
.qims-header__logo {
  margin-left: auto;
  height: 2.5rem;
  display: block;
}

.qims-nav {
  display: flex;
  gap: var(--qims-space-1);
  padding: 0 var(--qims-space-6);
  background: var(--qims-surface);
  border-bottom: 1px solid var(--qims-border);
  overflow-x: auto;
}

.qims-nav__item {
  padding: var(--qims-space-3) var(--qims-space-4);
  color: var(--qims-text-secondary);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  font-size: var(--qims-text-sm);
  font-weight: var(--qims-weight-medium);
}

.qims-nav__item:hover { color: var(--qims-text); }

.qims-nav__item[aria-current="page"] {
  color: var(--qims-text-link);
  border-bottom-color: var(--qims-border-brand);
}

.qims-main { padding: var(--qims-space-6); }

/* ---------------------------------------------------------------- focus */

.qims-app :focus-visible {
  outline: var(--qims-focus-width) solid var(--qims-focus-ring);
  outline-offset: var(--qims-focus-offset);
  border-radius: var(--qims-radius-sm);
}

/* ---------------------------------------------------------------- type */

.qims-title {
  font-size: var(--qims-text-2xl);
  line-height: var(--qims-leading-tight);
  font-weight: var(--qims-weight-bold);
  margin: 0 0 var(--qims-space-2);
}

.qims-subtitle {
  font-size: var(--qims-text-sm);
  color: var(--qims-text-secondary);
  margin: 0 0 var(--qims-space-6);
}

/* A standalone heading above a group that is not a .qims-section -- a chart
   card, a sign-in panel. Written as a real heading element for the same reason
   .qims-section__title is. */
.qims-section-title {
  font-size: var(--qims-text-xl);
  line-height: var(--qims-leading-tight);
  font-weight: var(--qims-weight-medium);
  margin: 0 0 var(--qims-space-4);
}

.qims-link {
  color: var(--qims-text-link);
  /* 2.5.8 target size. An inline element's client rect is its font box, not
     its line box, so a link in 14px help text measured 21px and a link alone
     in a table cell measured 19px. WCAG exempts a target "in a sentence",
     but a link that is the whole content of a cell is not in one -- and the
     rule cannot tell the two apart, so every link clears the bar instead.
     In 16px body text the line box is already 24px, so nothing moves.
     Found by composing the system into screens: .qims-link appeared nowhere
     in preview.html, so neither check could see it. */
  display: inline-block;
  min-height: var(--qims-tap-min);
}

/* ---------------------------------------------------------------- card */

.qims-card {
  background: var(--qims-surface);
  border: 1px solid var(--qims-border);
  border-radius: var(--qims-radius-md);
  box-shadow: var(--qims-shadow-1);
}

.qims-card__header {
  display: flex;
  align-items: center;
  gap: var(--qims-space-3);
  padding: var(--qims-space-4) var(--qims-space-5);
  border-bottom: 1px solid var(--qims-border);
}

.qims-card__title {
  font-size: var(--qims-text-lg);
  font-weight: var(--qims-weight-medium);
  margin: 0;
}

.qims-card__body { padding: var(--qims-space-5); }

.qims-card__footer {
  display: flex;
  gap: var(--qims-space-2);
  justify-content: flex-end;
  padding: var(--qims-space-4) var(--qims-space-5);
  border-top: 1px solid var(--qims-border);
  background: var(--qims-surface-raised);
}

/* ---------------------------------------------------------------- button */

.qims-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--qims-space-2);
  min-height: var(--qims-control-height);
  min-width: var(--qims-tap-min);
  padding: 0 var(--qims-space-4);
  font: inherit;
  font-size: var(--qims-text-sm);
  font-weight: var(--qims-weight-medium);
  border-radius: var(--qims-radius-md);
  border: 1px solid transparent;
  cursor: pointer;
  background: var(--qims-surface);
  color: var(--qims-text);
  border-color: var(--qims-border-strong);
  /* A button is sometimes an anchor -- an Open that navigates rather than
     submits. Without this it inherits the link underline and reads as neither. */
  text-decoration: none;
}

.qims-btn:hover { background: var(--qims-surface-raised); }
.qims-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.qims-btn--primary {
  background: var(--qims-surface-brand);
  color: var(--qims-text-on-brand);
  border-color: var(--qims-surface-brand);
}
.qims-btn--primary:hover { background: var(--qims-blue-700); border-color: var(--qims-blue-700); }

.qims-btn--danger {
  background: var(--qims-danger-600);
  color: #FFFFFF;
  border-color: var(--qims-danger-600);
}
.qims-btn--danger:hover { background: var(--qims-danger-700); border-color: var(--qims-danger-700); }

.qims-btn--ghost { background: transparent; border-color: transparent; color: var(--qims-text-link); }
.qims-btn--ghost:hover { background: var(--qims-surface-brand-subtle); }

.qims-btn--sm { min-height: var(--qims-control-height-sm); font-size: var(--qims-text-xs); padding: 0 var(--qims-space-3); }

/* ---------------------------------------------------------------- fields */

.qims-field { display: flex; flex-direction: column; gap: var(--qims-space-1); margin-bottom: var(--qims-space-4); }

.qims-label {
  font-size: var(--qims-text-sm);
  font-weight: var(--qims-weight-medium);
  color: var(--qims-text);
}

/* Required is marked in words as well as a glyph: an asterisk alone is a
   colour-and-symbol convention screen readers announce inconsistently. */
.qims-label__required { color: var(--qims-danger-text); font-weight: var(--qims-weight-normal); }

.qims-input,
.qims-select,
.qims-textarea {
  font: inherit;
  font-size: var(--qims-text-base);
  color: var(--qims-text);
  background: var(--qims-surface);
  border: 1px solid var(--qims-border-strong);
  border-radius: var(--qims-radius-md);
  padding: 0 var(--qims-space-3);
  min-height: var(--qims-control-height);
  width: 100%;
  box-sizing: border-box;
}

.qims-textarea { padding: var(--qims-space-2) var(--qims-space-3); min-height: 6rem; resize: vertical; line-height: var(--qims-leading-normal); }

.qims-input:disabled,
.qims-select:disabled,
.qims-textarea:disabled { background: var(--qims-surface-sunken); color: var(--qims-text-secondary); }

.qims-input[aria-invalid="true"],
.qims-textarea[aria-invalid="true"] { border-color: var(--qims-danger-600); }

.qims-help { font-size: var(--qims-text-xs); color: var(--qims-text-secondary); }

/* Errors lead with a word, never a colour. */
.qims-error { font-size: var(--qims-text-xs); color: var(--qims-danger-text); font-weight: var(--qims-weight-medium); }

.qims-counter { font-size: var(--qims-text-xs); color: var(--qims-text-secondary); text-align: right; font-variant-numeric: tabular-nums; }
.qims-counter--over { color: var(--qims-danger-text); font-weight: var(--qims-weight-medium); }

/* Y / N / NA. Three of the eight inspection forms carry a tri-state and the
   deck writes it four different ways -- see D-12. One control, one vocabulary. */
.qims-tristate { display: inline-flex; border: 1px solid var(--qims-border-strong); border-radius: var(--qims-radius-md); overflow: hidden; }

.qims-tristate__option { position: relative; }
.qims-tristate__option input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }

.qims-tristate__option span {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--qims-control-height);
  min-width: 3rem;
  padding: 0 var(--qims-space-3);
  font-size: var(--qims-text-sm);
  border-left: 1px solid var(--qims-border-strong);
  background: var(--qims-surface);
}

.qims-tristate__option:first-child span { border-left: none; }
.qims-tristate__option input:checked + span { background: var(--qims-surface-brand); color: var(--qims-text-on-brand); font-weight: var(--qims-weight-medium); }
.qims-tristate__option input:focus-visible + span { outline: var(--qims-focus-width) solid var(--qims-focus-ring); outline-offset: calc(-1 * var(--qims-focus-width)); }

.qims-check { display: flex; align-items: center; gap: var(--qims-space-2); min-height: var(--qims-tap-min); font-size: var(--qims-text-sm); }
.qims-check input { width: 1rem; height: 1rem; accent-color: var(--qims-blue-600); }

/* ---------------------------------------------------------------- badge */

/* The dot is decoration. The text is the state. Removing the colour must leave
   the meaning intact -- that is the D-62 rule, and it is why there is no
   `.qims-badge` variant that renders an empty pill. */
.qims-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--qims-space-2);
  padding: 0 var(--qims-space-3);
  min-height: 1.5rem;
  border-radius: var(--qims-radius-pill);
  font-size: var(--qims-text-xs);
  font-weight: var(--qims-weight-medium);
  background: var(--qims-neutral-fill);
  color: var(--qims-neutral-text);
  white-space: nowrap;
}

.qims-badge::before { content: ""; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: currentColor; flex: none; }

/* Generic state. Use these wherever the meaning is success/warning/danger in
   the ordinary sense. The document-status variants below are separate on
   purpose: they name a document lifecycle state, and reaching for one to mean
   "pass" borrows a vocabulary that does not fit and will read wrong the moment
   D-12 settles what an inspection result is. */
.qims-badge--info { background: var(--qims-info-fill); color: var(--qims-info-text); }
.qims-badge--success { background: var(--qims-success-fill); color: var(--qims-success-text); }
.qims-badge--warning { background: var(--qims-warning-fill); color: var(--qims-warning-text); }
.qims-badge--danger { background: var(--qims-danger-fill); color: var(--qims-danger-text); }

.qims-badge--draft { background: var(--qims-doc-draft-fill); color: var(--qims-doc-draft-text); }
.qims-badge--current { background: var(--qims-doc-current-fill); color: var(--qims-doc-current-text); }
.qims-badge--due { background: var(--qims-doc-due-fill); color: var(--qims-doc-due-text); }
.qims-badge--overdue { background: var(--qims-doc-overdue-fill); color: var(--qims-doc-overdue-text); }
.qims-badge--obsolete { background: var(--qims-doc-obsolete-fill); color: var(--qims-doc-obsolete-text); }

/* ---------------------------------------------------------------- banner */

.qims-banner {
  display: flex;
  gap: var(--qims-space-3);
  padding: var(--qims-space-3) var(--qims-space-4);
  border-radius: var(--qims-radius-md);
  border-left: 3px solid currentColor;
  font-size: var(--qims-text-sm);
  background: var(--qims-info-fill);
  color: var(--qims-info-text);
  margin-bottom: var(--qims-space-4);
}

.qims-banner__title { font-weight: var(--qims-weight-bold); }
.qims-banner__body { color: var(--qims-text); }
.qims-banner--success { background: var(--qims-success-fill); color: var(--qims-success-text); }
.qims-banner--warning { background: var(--qims-warning-fill); color: var(--qims-warning-text); }
.qims-banner--danger { background: var(--qims-danger-fill); color: var(--qims-danger-text); }

/* ---------------------------------------------------------------- table */

.qims-table { width: 100%; border-collapse: collapse; font-size: var(--qims-text-sm); background: var(--qims-surface); }

.qims-table th {
  text-align: left;
  font-weight: var(--qims-weight-medium);
  color: var(--qims-text-secondary);
  font-size: var(--qims-text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: var(--qims-space-3) var(--qims-space-4);
  border-bottom: 1px solid var(--qims-border);
  white-space: nowrap;
}

.qims-table td { padding: var(--qims-space-3) var(--qims-space-4); border-bottom: 1px solid var(--qims-neutral-100); vertical-align: middle; }
.qims-table tbody tr:hover { background: var(--qims-surface-raised); }
.qims-table__num { text-align: right; font-variant-numeric: tabular-nums; }

/* Inspections are a flat list grouped by year -- see 07-modules.md §7.4. */
.qims-table__group th {
  background: var(--qims-surface-sunken);
  color: var(--qims-text);
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--qims-text-sm);
}

.qims-table__wrap { overflow-x: auto; border: 1px solid var(--qims-border); border-radius: var(--qims-radius-md); }

/* ---------------------------------------------------------------- tabs */

.qims-tabs { display: flex; gap: var(--qims-space-1); border-bottom: 1px solid var(--qims-border); margin-bottom: var(--qims-space-5); }

.qims-tab {
  appearance: none;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  font: inherit;
  font-size: var(--qims-text-sm);
  font-weight: var(--qims-weight-medium);
  color: var(--qims-text-secondary);
  padding: var(--qims-space-3) var(--qims-space-4);
  min-height: var(--qims-control-height);
  cursor: pointer;
}

.qims-tab[aria-selected="true"] { color: var(--qims-text-link); border-bottom-color: var(--qims-border-brand); }
.qims-tab:disabled { color: var(--qims-neutral-400); cursor: not-allowed; }

/* ---------------------------------------------------------------- task row */

/* The Home task list. D-42 made this a real store rather than a view, and its
   rows can be withdrawn, so the row carries a state that is not "done". */
.qims-task {
  display: flex;
  align-items: center;
  gap: var(--qims-space-3);
  padding: var(--qims-space-3) var(--qims-space-4);
  border-bottom: 1px solid var(--qims-neutral-100);
}

.qims-task__body { flex: 1; min-width: 0; }
.qims-task__title { font-size: var(--qims-text-sm); font-weight: var(--qims-weight-medium); }
.qims-task__meta { font-size: var(--qims-text-xs); color: var(--qims-text-secondary); }
.qims-task--withdrawn .qims-task__title { text-decoration: line-through; color: var(--qims-text-secondary); }

/* ---------------------------------------------------------------- matrix */

/* PEAR. D-18: the score is derived from two axis bands and both are stored, so
   the control selects a cell rather than typing a number. The band labels are
   our own wording -- D-02 forbids shipping AS9101's. */
.qims-matrix { border-collapse: collapse; font-size: var(--qims-text-sm); }
.qims-matrix th { padding: var(--qims-space-2) var(--qims-space-3); font-weight: var(--qims-weight-medium); color: var(--qims-text-secondary); text-align: left; }
.qims-matrix td { padding: 0; border: 1px solid var(--qims-border); }

.qims-matrix__cell { position: relative; }
.qims-matrix__cell input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }

.qims-matrix__cell span {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 3.5rem;
  min-height: 3rem;
  font-weight: var(--qims-weight-medium);
  background: var(--qims-surface);
}

.qims-matrix__cell input:checked + span { background: var(--qims-surface-brand); color: var(--qims-text-on-brand); }
.qims-matrix__cell input:focus-visible + span { outline: var(--qims-focus-width) solid var(--qims-focus-ring); outline-offset: calc(-1 * var(--qims-focus-width)); }

/* ---------------------------------------------------------------- utility */

.qims-stack > * + * { margin-top: var(--qims-space-4); }
.qims-row { display: flex; gap: var(--qims-space-3); align-items: center; flex-wrap: wrap; }
.qims-muted { color: var(--qims-text-secondary); }
.qims-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;
}

/* ================================================================= screens
 *
 * Everything above is a control. Everything below is the furniture a screen
 * is built from, and it exists because composing screens out of controls
 * alone produced a form dump on a grey background: every field the same
 * weight, no identity, and nothing to read before the fields.
 *
 * 14.1 had scoped the system to "tokens and components, not screens", which
 * was right while nothing consumed it. The mock-up consumed it and the gap
 * showed at once, so the patterns live here rather than in the mock-up's own
 * stylesheet: a second private stylesheet is how the two quietly diverge.
 */

/* ------------------------------------------------------------------ shell */

/* Modules run down the side rather than across the top. That is D-63 and it is
 * a proposal, not a specification: the deck draws a tab strip. It is here
 * because the deck's own strip already wraps to two lines on its slides, and an
 * overflowing nav hides exactly what D-40 says every user must be able to see.
 * Reversing it is this grid and the rail's flex direction, nothing more.
 * The logo stays top right, which is the deck's one instruction about the page.
 */
.qims-shell {
  display: grid;
  grid-template-columns: 15rem 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas: "top top" "side main";
  min-height: 100vh;
  background: var(--qims-surface-sunken);
}

.qims-topbar {
  grid-area: top;
  display: flex;
  align-items: center;
  gap: var(--qims-space-4);
  padding: var(--qims-space-3) var(--qims-space-5);
  background: var(--qims-surface);
  border-bottom: 1px solid var(--qims-border);
}
.qims-topbar__org { font-weight: var(--qims-weight-bold); }
.qims-topbar__find { position: relative; display: flex; align-items: center;
  flex: 0 1 22rem; }
.qims-topbar__find > .qims-icon {
  position: absolute;
  left: var(--qims-space-3);
  color: var(--qims-text-secondary);
  pointer-events: none;
}
.qims-topbar__search { width: 100%; padding-left: var(--qims-space-8); }

/* Resources, Help and a route to TJ4 sit beside the mark, which is where the
 * deck draws them: a callout on the home-page slide, next to the logo.
 */
.qims-topbar__util {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--qims-space-1);
}
.qims-topbar__logo { margin-left: var(--qims-space-4); height: 2.25rem; display: block; }

.qims-sidenav {
  grid-area: side;
  background: var(--qims-surface);
  border-right: 1px solid var(--qims-border);
  padding: var(--qims-space-4) var(--qims-space-3);
}
.qims-sidenav__label {
  padding: 0 var(--qims-space-3) var(--qims-space-2);
  font-size: var(--qims-text-xs);
  font-weight: var(--qims-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--qims-text-secondary);
}
.qims-sidenav__item {
  display: flex;
  align-items: center;
  gap: var(--qims-space-3);
  width: 100%;
  padding: var(--qims-space-2) var(--qims-space-3);
  margin-bottom: 2px;
  border: 0;
  border-radius: var(--qims-radius-md);
  background: none;
  font: inherit;
  font-size: var(--qims-text-sm);
  font-weight: var(--qims-weight-medium);
  color: var(--qims-text-secondary);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  min-height: var(--qims-tap-min);
}
.qims-sidenav__item:hover { background: var(--qims-surface-raised); color: var(--qims-text); }
.qims-sidenav__item[aria-current="page"] {
  background: var(--qims-surface-brand-subtle);
  color: var(--qims-text-link);
}
.qims-sidenav__list, .qims-sidenav__sub {
  list-style: none;
  margin: 0;
  padding: 0;
}
.qims-sidenav__group {
  display: block;
  padding: var(--qims-space-4) var(--qims-space-3) var(--qims-space-1);
  font-size: var(--qims-text-xs);
  font-weight: var(--qims-weight-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--qims-text);
}
/* Grouping is carried by a tint, not by indentation: indenting the two
 * children pushed their icons out of the column every other item's icon
 * sits in, and a rail whose icons do not line up looks broken before it
 * looks nested. */
.qims-sidenav__sub {
  background: var(--qims-surface-sunken);
  border-radius: var(--qims-radius-md);
  padding: 2px 0;
}

/* Administration sits below a rule rather than second in the running order. */
.qims-sidenav__foot {
  margin-top: var(--qims-space-4);
  padding-top: var(--qims-space-3);
  border-top: 1px solid var(--qims-border);
}

.qims-sidenav__count {
  margin-left: auto;
  font-size: var(--qims-text-xs);
  color: var(--qims-text-secondary);
}

.qims-content { grid-area: main; padding: var(--qims-space-6); min-width: 0; }

@media (max-width: 60rem) {
  .qims-shell {
    grid-template-columns: 1fr;
    grid-template-areas: "top" "side" "main";
  }
  .qims-sidenav {
    display: flex;
    gap: var(--qims-space-1);
    overflow-x: auto;
    border-right: 0;
    border-bottom: 1px solid var(--qims-border);
  }
  .qims-sidenav__label { display: none; }
  .qims-sidenav__list, .qims-sidenav__sub, .qims-sidenav li {
    display: flex;
    align-items: center;
    gap: var(--qims-space-1);
  }
  .qims-sidenav__group {
    padding: 0 var(--qims-space-2) 0 var(--qims-space-3);
    white-space: nowrap;
  }
  .qims-sidenav__item { width: auto; white-space: nowrap; }
  .qims-sidenav__sub { background: none; padding: 0; }
  .qims-sidenav__foot {
    margin: 0 0 0 var(--qims-space-2);
    padding: 0 0 0 var(--qims-space-2);
    border-top: 0;
    border-left: 1px solid var(--qims-border);
  }
}

/* ------------------------------------------------------------------- page */

.qims-page {
  display: flex;
  align-items: flex-start;
  gap: var(--qims-space-4);
  margin-bottom: var(--qims-space-5);
}
.qims-page__main { flex: 1 1 auto; min-width: 0; }
.qims-page__title {
  margin: 0;
  font-size: var(--qims-text-2xl);
  font-weight: var(--qims-weight-bold);
  line-height: var(--qims-leading-tight);
}
.qims-page__sub {
  margin: var(--qims-space-1) 0 0;
  color: var(--qims-text-secondary);
  font-size: var(--qims-text-sm);
}
.qims-page__actions { display: flex; gap: var(--qims-space-2); flex-wrap: wrap; }

/* ----------------------------------------------------------------- record */

/* What a record is, before what it contains: identity, state, and the three
 * or four facts somebody checks before reading a single field.
 */
.qims-record {
  background: var(--qims-surface);
  border: 1px solid var(--qims-border);
  border-radius: var(--qims-radius-lg);
  box-shadow: var(--qims-shadow-1);
  margin-bottom: var(--qims-space-5);
}
.qims-record__head {
  display: flex;
  align-items: center;
  gap: var(--qims-space-3);
  padding: var(--qims-space-4) var(--qims-space-5);
  flex-wrap: wrap;
}
.qims-record__id {
  font-family: var(--qims-font-mono);
  font-size: var(--qims-text-sm);
  color: var(--qims-text-secondary);
  padding: 2px var(--qims-space-2);
  border: 1px solid var(--qims-border);
  border-radius: var(--qims-radius-sm);
}
/* A real heading, not text that looks like one. A record title and a section
   title are siblings under the page title, so both are h2: the outline was
   twenty h1s and no h2 at all, which is 1.3.1 -- structure conveyed visually
   and not programmatically -- and below the AA bar D-62 adopts. */
.qims-record__title {
  font-size: var(--qims-text-lg);
  font-weight: var(--qims-weight-bold);
  margin: 0;
}
.qims-record__spacer { flex: 1 1 auto; }
.qims-record__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--qims-space-8);
  padding: var(--qims-space-3) var(--qims-space-5);
  border-top: 1px solid var(--qims-border);
  background: var(--qims-surface-raised);
  border-radius: 0 0 var(--qims-radius-lg) var(--qims-radius-lg);
}

/* Key and value: the read-only counterpart of a field. */
.qims-kv { padding: var(--qims-space-1) 0; }
.qims-kv__k { display: block; font-size: var(--qims-text-xs); color: var(--qims-text-secondary); }
.qims-kv__v { display: block; font-size: var(--qims-text-sm); font-weight: var(--qims-weight-medium); }

/* ---------------------------------------------------------------- section */

/* A form is a sequence of meanings, not a grid of inputs. */
.qims-section {
  background: var(--qims-surface);
  border: 1px solid var(--qims-border);
  border-radius: var(--qims-radius-lg);
  margin-bottom: var(--qims-space-5);
  overflow: hidden;
}
.qims-section__head {
  display: flex;
  align-items: baseline;
  gap: var(--qims-space-3);
  padding: var(--qims-space-3) var(--qims-space-5);
  border-bottom: 1px solid var(--qims-border);
}
.qims-section__title {
  font-size: var(--qims-text-base);
  font-weight: var(--qims-weight-bold);
  margin: 0;
}
.qims-section__note { font-size: var(--qims-text-sm); color: var(--qims-text-secondary); }
.qims-section__body { padding: var(--qims-space-5); }

/* A tab panel is a section whose title is the tab. Without a surface of its
   own, the fields inside one sit loose on the page background while the fields
   on a non-tabbed screen sit on white -- the same form, two different
   treatments, decided by whether the screen happened to use tabs. */
.qims-panel {
  background: var(--qims-surface);
  border: 1px solid var(--qims-border);
  border-radius: 0 var(--qims-radius-lg) var(--qims-radius-lg) var(--qims-radius-lg);
  padding: var(--qims-space-5);
  margin-bottom: var(--qims-space-5);
}
.qims-panel > .qims-field:last-child,
.qims-panel > .qims-grid:last-child > .qims-field:last-child { margin-bottom: 0; }

/* Two columns on a desk, one on a tablet; a field claims the full width when
 * its content is prose rather than a value.
 *
 * The column count is stated rather than fitted. auto-fit gives every row in
 * the group the same count, so a six-field group on a wide screen lands as
 * four then two and the second row does not line up under the first. A form
 * that reads as two tidy columns everywhere beats one that packs tightest.
 */
.qims-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 var(--qims-space-6);
}
.qims-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.qims-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.qims-grid__wide { grid-column: 1 / -1; }

@media (max-width: 60rem) {
  .qims-grid--3, .qims-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 40rem) {
  .qims-grid, .qims-grid--3, .qims-grid--4 { grid-template-columns: minmax(0, 1fr); }
}

/* ---------------------------------------------------------------- toolbar */

.qims-toolbar {
  display: flex;
  align-items: center;
  gap: var(--qims-space-3);
  padding-bottom: var(--qims-space-4);
  flex-wrap: wrap;
}
.qims-toolbar__spacer { flex: 1 1 auto; }

/* Actions that must not scroll away on a long record. */
.qims-actionbar {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: var(--qims-space-3);
  padding: var(--qims-space-3) var(--qims-space-5);
  background: var(--qims-surface);
  border: 1px solid var(--qims-border);
  border-radius: var(--qims-radius-lg);
  box-shadow: var(--qims-shadow-2);
  margin-top: var(--qims-space-5);
}
.qims-actionbar__spacer { flex: 1 1 auto; }

/* ------------------------------------------------------------ empty state */

.qims-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--qims-space-2);
  padding: var(--qims-space-8) var(--qims-space-5);
  text-align: center;
  color: var(--qims-text-secondary);
  background: var(--qims-surface-raised);
  border: 1px dashed var(--qims-border-strong);
  border-radius: var(--qims-radius-md);
}
.qims-empty__title { font-weight: var(--qims-weight-medium); color: var(--qims-text); }

/* ------------------------------------------------------------------ icons */

/* Stroke icons drawn on currentColor, so an icon inherits the state of
 * whatever it sits in and never needs a colour of its own. Decorative by
 * default: each one sits beside its own label and is aria-hidden, so the
 * label carries the meaning -- the same rule D-62 applies to colour.
 */
.qims-icon {
  width: 1.125rem;
  height: 1.125rem;
  flex: 0 0 auto;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.qims-icon--sm { width: 1rem; height: 1rem; }

/* ------------------------------------------------------------ dense table */

.qims-table--dense th,
.qims-table--dense td { padding: var(--qims-space-2) var(--qims-space-3); }
.qims-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--qims-surface);
}
.qims-table tbody tr:hover { background: var(--qims-surface-raised); }

/* Sign-in and anything else shown before a tenant is known: no topbar, no
   module nav, so the grid must collapse rather than leave the column empty. */
/* Before a tenant is known there is no module nav and nothing to say about the
   organisation -- but there is still a product, and sign-in is the screen where
   its mark matters most. So the topbar stays and sheds its tenant content. */
.qims-shell.is-bare {
  /* Two areas, not three. Naming "side" left its row in the template while
     `display: none` removed the element from it, and the empty row inherited
     the 1fr from grid-template-rows -- so it grew to fill the viewport and
     pushed the content half a screen down. A row that holds nothing should not
     be in the template at all. */
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas: "top" "main";
}
.qims-shell.is-bare .qims-topbar__org,
.qims-shell.is-bare .qims-topbar__search { display: none; }
.qims-shell.is-bare .qims-topbar { justify-content: center; }
.qims-shell.is-bare .qims-topbar__logo { margin: 0; height: 2.75rem; }
.qims-shell.is-bare .qims-content { max-width: 60rem; margin: 0 auto; width: 100%; }

/* ================================================== data, state and history
 *
 * Section 14.8. The pieces above make a screen legible; these make it a
 * quality system. Each answers a question a quality manager asks daily and the
 * earlier vocabulary could not express:
 *
 *   how are we doing            -> metric, meter
 *   where is this record        -> stepper
 *   what happened to it         -> timeline
 *   who did it                  -> avatar
 *   how do I find the one I want -> filters, chip
 *   how bad is it               -> badge--loud
 *   where am I                  -> crumbs
 */

/* ----------------------------------------------------------------- metric */

/* A number with its meaning attached. The bare figure the first draft used
   said "6" and left the reader to guess whether that was good. */
.qims-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--qims-space-4);
  margin-bottom: var(--qims-space-5);
}
.qims-metric {
  background: var(--qims-surface);
  border: 1px solid var(--qims-border);
  border-radius: var(--qims-radius-lg);
  padding: var(--qims-space-4);
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.qims-metric__label {
  font-size: var(--qims-text-xs);
  font-weight: var(--qims-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--qims-text-secondary);
}
.qims-metric__value {
  font-size: var(--qims-text-3xl);
  line-height: 1.1;
  font-weight: var(--qims-weight-bold);
  /* Tabular figures so a column of numbers lines up and a changing value does
     not shuffle the digits beside it. */
  font-variant-numeric: tabular-nums;
}
.qims-metric__unit { font-size: var(--qims-text-lg); font-weight: var(--qims-weight-medium); }
.qims-metric__note { font-size: var(--qims-text-sm); color: var(--qims-text-secondary); }

/* State is carried by a rule down the leading edge, never by the number's
   colour: a red 3 and a black 3 are the same number, and colour alone is D-62. */
.qims-metric--good    { border-left: 3px solid var(--qims-success-600); }
.qims-metric--warning { border-left: 3px solid var(--qims-warning-600); }
.qims-metric--danger  { border-left: 3px solid var(--qims-danger-600); }

/* ------------------------------------------------------------------ meter */

/* Coverage and progress: clauses assessed, milestones done. Always labelled;
   the bar repeats the number rather than replacing it. */
.qims-meter {
  height: 6px;
  border-radius: var(--qims-radius-pill);
  background: var(--qims-surface-sunken);
  overflow: hidden;
  margin-top: var(--qims-space-2);
}
.qims-meter__fill { height: 100%; background: var(--qims-blue-600); border-radius: inherit; }
.qims-meter__fill--good { background: var(--qims-success-600); }
.qims-meter__fill--warning { background: var(--qims-warning-600); }

/* ---------------------------------------------------------------- stepper */

/* Where a record has got to. The single most valuable thing a record screen
   can say and the one the earlier vocabulary had no way to express: a badge
   reading "In progress" does not tell an approver whether anyone has reviewed
   it yet. Steps come from the tenant's workflow -- D-05 -- so the component
   takes any number of them. */
.qims-stepper {
  display: flex;
  align-items: flex-start;
  gap: var(--qims-space-2);
  padding: var(--qims-space-4) var(--qims-space-5);
  border-top: 1px solid var(--qims-border);
  overflow-x: auto;
}
.qims-step {
  display: flex;
  align-items: flex-start;
  gap: var(--qims-space-2);
  flex: 1 1 0;
  min-width: 9rem;
  position: relative;
}
.qims-step__mark {
  flex: 0 0 auto;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: var(--qims-radius-pill);
  border: 1.5px solid var(--qims-border-strong);
  background: var(--qims-surface);
  color: var(--qims-text-secondary);
  font-size: var(--qims-text-xs);
  font-weight: var(--qims-weight-bold);
  display: flex;
  align-items: center;
  justify-content: center;
  font-variant-numeric: tabular-nums;
}
.qims-step__body { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.qims-step__name {
  display: block;
  font-size: var(--qims-text-sm);
  font-weight: var(--qims-weight-medium);
  line-height: var(--qims-leading-tight);
}
.qims-step__meta {
  display: block;
  font-size: var(--qims-text-xs);
  color: var(--qims-text-secondary);
  line-height: var(--qims-leading-tight);
}

/* The connector is drawn from the step, not between steps, so a workflow of
   any length needs no extra markup. */
.qims-step + .qims-step::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--qims-space-2));
  top: 0.75rem;
  width: var(--qims-space-2);
  height: 1.5px;
  background: var(--qims-border-strong);
}

.qims-step--done .qims-step__mark {
  background: var(--qims-success-600);
  border-color: var(--qims-success-600);
  color: #FFFFFF;
}
.qims-step--current .qims-step__mark {
  background: var(--qims-surface-brand);
  border-color: var(--qims-surface-brand);
  color: var(--qims-text-on-brand);
}
.qims-step--current .qims-step__name { font-weight: var(--qims-weight-bold); }
.qims-step--todo .qims-step__name { color: var(--qims-text-secondary); }

/* --------------------------------------------------------------- timeline */

/* The audit trail as something a person reads rather than a table they parse.
   Append-only and retained for the life of the tenant -- D-26. */
.qims-timeline { list-style: none; margin: 0; padding: 0; }
.qims-timeline__event {
  display: grid;
  grid-template-columns: 9rem 1.5rem 1fr;
  gap: 0 var(--qims-space-2);
  padding-bottom: var(--qims-space-4);
  position: relative;
}
.qims-timeline__when {
  font-size: var(--qims-text-xs);
  color: var(--qims-text-secondary);
  padding-top: 3px;
  font-variant-numeric: tabular-nums;
}
.qims-timeline__dot {
  width: 9px;
  height: 9px;
  border-radius: var(--qims-radius-pill);
  background: var(--qims-border-strong);
  margin: 6px auto 0;
}
.qims-timeline__event--now .qims-timeline__dot { background: var(--qims-surface-brand); }
/* The rail is the dot column's own background, so it never outruns the list. */
.qims-timeline__event:not(:last-child)::before {
  content: "";
  position: absolute;
  left: calc(9rem + var(--qims-space-2) + 0.75rem - 0.5px);
  top: 1rem;
  bottom: 0;
  width: 1px;
  background: var(--qims-border);
}
.qims-timeline__what { font-size: var(--qims-text-sm); }
.qims-timeline__who { font-size: var(--qims-text-xs); color: var(--qims-text-secondary); }

/* ----------------------------------------------------------------- avatar */

/* Initials rather than a photograph: nobody uploads one, and a quality record
   is signed by a name. The circle is decorative -- the name sits beside it. */
.qims-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--qims-radius-pill);
  background: var(--qims-surface-sunken);
  border: 1px solid var(--qims-border);
  color: var(--qims-text-secondary);
  font-size: 10px;
  font-weight: var(--qims-weight-bold);
  letter-spacing: 0.02em;
  flex: 0 0 auto;
}
.qims-avatar--me { background: var(--qims-surface-brand-subtle); border-color: var(--qims-blue-300); color: var(--qims-text-link); }
.qims-person { display: inline-flex; align-items: center; gap: var(--qims-space-2); min-width: 0; }

/* ---------------------------------------------------------------- filters */

/* A list of four rows needs no filtering. A list of four hundred is unusable
   without it, and every list in a quality system becomes the second kind. */
.qims-filters {
  display: flex;
  align-items: center;
  gap: var(--qims-space-2);
  padding: var(--qims-space-3);
  background: var(--qims-surface);
  border: 1px solid var(--qims-border);
  border-radius: var(--qims-radius-lg) var(--qims-radius-lg) 0 0;
  border-bottom: 0;
  flex-wrap: wrap;
}
.qims-filters__search { flex: 1 1 16rem; min-width: 10rem; }
.qims-filters__spacer { flex: 1 1 auto; }
.qims-filters__count {
  font-size: var(--qims-text-sm);
  color: var(--qims-text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.qims-filters .qims-select { width: auto; min-width: 8rem; font-size: var(--qims-text-sm); }
/* A filtered table joins the bar above it rather than floating below it. */
.qims-filters + .qims-table__wrap { border-radius: 0 0 var(--qims-radius-lg) var(--qims-radius-lg); }

.qims-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--qims-space-1);
  min-height: var(--qims-tap-min);
  padding: 0 var(--qims-space-2);
  border-radius: var(--qims-radius-sm);
  background: var(--qims-surface-brand-subtle);
  color: var(--qims-text-link);
  border: 1px solid var(--qims-blue-200);
  font-size: var(--qims-text-xs);
  font-weight: var(--qims-weight-medium);
  white-space: nowrap;
}

/* ------------------------------------------------------------- crumbs */

.qims-crumbs {
  display: flex;
  align-items: center;
  gap: var(--qims-space-2);
  font-size: var(--qims-text-sm);
  color: var(--qims-text-secondary);
  margin-bottom: var(--qims-space-2);
  flex-wrap: wrap;
}
.qims-crumbs__sep { color: var(--qims-border-strong); }

/* ------------------------------------------------------------ loud badge */

/* Not every state deserves the same voice. A document one day overdue and a
   critical CAR three weeks overdue read identically in a tinted badge, so the
   badge that has to interrupt gets a solid fill. Still carries its own words. */
.qims-badge--loud {
  background: var(--qims-danger-600);
  color: #FFFFFF;
  border-color: var(--qims-danger-600);
}
.qims-badge--loud::before { background: #FFFFFF; }

/* -------------------------------------------------------- dense data table */

/* Desk-first: a quality manager reads these all day and wants more rows in
   view, not more air. Figures are tabular and right-aligned so magnitudes
   compare down the column instead of being read one at a time. */
.qims-table { font-size: var(--qims-text-sm); }
.qims-table th, .qims-table td { padding: var(--qims-space-2) var(--qims-space-3); }
.qims-table thead th {
  font-size: var(--qims-text-xs);
  font-weight: var(--qims-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--qims-text-secondary);
  white-space: nowrap;
}
.qims-table__num { text-align: right; font-variant-numeric: tabular-nums; }
.qims-table__date { font-variant-numeric: tabular-nums; white-space: nowrap; }
.qims-table__id {
  font-family: var(--qims-font-mono);
  font-size: var(--qims-text-xs);
  color: var(--qims-text-secondary);
  white-space: nowrap;
}
/* The row is the target; the link inside it is the accessible name. */
.qims-table tbody tr:hover { background: var(--qims-surface-brand-subtle); }
.qims-table tbody tr:hover .qims-link { text-decoration: underline; }

/* ================================================ definitions and authoring
 *
 * Two patterns the deck asks for on nearly every form and the system had no
 * word for.
 */

/* --------------------------------------------------------------- pop-out */

/* The deck attaches a "pop out" definition to roughly twenty field labels and
 * folder names, and Exhibit D is the library of their text. It is an
 * interaction, not a tooltip: several definitions run to a paragraph, and D-44
 * renders a tenant's own words below the shipped ones under a visible label.
 *
 * A native disclosure rather than a hover tooltip. Content revealed on hover
 * has to be dismissable, hoverable and persistent under WCAG 1.4.13, and the
 * cheapest way to satisfy all three is not to use hover at all. <details> is
 * keyboard-operable with no script, so it behaves the same in the fixture, in
 * both mock-up builds, and in a page opened from the filesystem.
 */
.qims-def {
  margin-top: var(--qims-space-2);
  border-left: 2px solid var(--qims-border);
  padding-left: var(--qims-space-3);
}
.qims-def__summary {
  display: flex;
  align-items: center;
  gap: var(--qims-space-2);
  min-height: var(--qims-tap-min);
  font-size: var(--qims-text-sm);
  font-weight: var(--qims-weight-medium);
  color: var(--qims-text-link);
  cursor: pointer;
  list-style: none;
}
.qims-def__summary::-webkit-details-marker { display: none; }
.qims-def__summary::marker { content: ""; }
.qims-def[open] > .qims-def__summary { color: var(--qims-text-secondary); }
.qims-def__body {
  padding-bottom: var(--qims-space-2);
  font-size: var(--qims-text-sm);
  color: var(--qims-text-secondary);
  max-width: 62ch;
}
.qims-def__body > p { margin: 0 0 var(--qims-space-2); }
.qims-def__body > p:last-child { margin-bottom: 0; }

/* D-44: shipped text is never hidden by a tenant's, so the two are stacked and
 * the tenant's is named. A reader can always tell which organization is
 * speaking.
 */
.qims-def__tenant {
  margin-top: var(--qims-space-3);
  padding-top: var(--qims-space-2);
  border-top: 1px dashed var(--qims-border);
}
.qims-def__who {
  display: block;
  font-size: var(--qims-text-xs);
  font-weight: var(--qims-weight-medium);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--qims-text-secondary);
}

/* -------------------------------------------------------------- rich text */

/* Every long field in the deck's examples is a formatting toolbar over a text
 * area -- audit scope, conclusions, PEAR sections, CAR statements. The toolbar
 * is drawn and inert here, like sorting: which marks are permitted inside a
 * controlled record is a specification question nobody has asked.
 */
.qims-richtext {
  border: 1px solid var(--qims-border);
  border-radius: var(--qims-radius-md);
  background: var(--qims-surface);
  overflow: hidden;
}
.qims-richtext__bar {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  padding: var(--qims-space-1);
  background: var(--qims-surface-raised);
  border-bottom: 1px solid var(--qims-border);
}
.qims-richtext__btn {
  min-width: var(--qims-tap-min);
  min-height: var(--qims-tap-min);
  border: 0;
  border-radius: var(--qims-radius-sm);
  background: none;
  font: inherit;
  font-size: var(--qims-text-sm);
  color: var(--qims-text-secondary);
  cursor: pointer;
}
.qims-richtext__btn:hover { background: var(--qims-surface-sunken); color: var(--qims-text); }
.qims-richtext__sep {
  width: 1px;
  margin: var(--qims-space-1) var(--qims-space-2);
  background: var(--qims-border);
}
.qims-richtext > .qims-textarea {
  display: block;
  width: 100%;
  border: 0;
  border-radius: 0;
}

/* The magnifier is the route to the search screen, so it is a link and needs a
 * target big enough to hit. It sits inside the input's padding. */
.qims-topbar__go {
  position: absolute;
  left: var(--qims-space-1);
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--qims-tap-min);
  height: var(--qims-tap-min);
  border-radius: var(--qims-radius-md);
  color: var(--qims-text-secondary);
  text-decoration: none;
}
.qims-topbar__go:hover { color: var(--qims-text); background: var(--qims-surface-raised); }
