/* ============================================================================
   The built-in ISO 9001 guide
   ============================================================================

   The guide is prose, and prose has different needs from the rest of the app:
   a measure that does not run to 1400px on a monitor, generous line height,
   and headings that separate the eight fixed parts of an article clearly
   enough that a reader learns where to look (§6.3).

   Everything here uses the semantic tokens from css/tokens.css, so both
   themes come for free. The print rules at the end are the "hand it to a new
   hire" path (§6.4).
   ========================================================================== */

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

.guide-hero {
  max-width: 70ch;
}

.guide-disclaimer {
  font-size: var(--text-sm);
  color: var(--text-muted);
  border-left: 3px solid var(--border-strong);
  padding-left: var(--space-md, 1rem);
  margin: var(--space-md, 1rem) 0;
}

.guide-progress {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.guide-categories {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-md, 1rem);
  margin-top: var(--space-lg, 1.5rem);
}

.guide-category {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  padding: var(--space-md, 1rem);
  background: var(--surface-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg, 12px);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, transform 0.15s ease;
  /* 44px minimum touch target is satisfied by the padding + two text lines. */
  min-height: 44px;
}

.guide-category:hover,
.guide-category:focus-visible {
  border-color: var(--interactive);
  transform: translateY(-1px);
}

.guide-category-icon {
  font-size: 1.5rem;
  line-height: 1;
  flex: 0 0 auto;
}

.guide-category-body {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}

.guide-category-body strong {
  color: var(--text-primary);
}

.guide-category-blurb {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: 1.45;
}

.guide-category-count {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

/* -------------------------------------------------------------- list views */

.guide-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.guide-list > li {
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--border-subtle);
}

.guide-list > li:last-child {
  border-bottom: 0;
}

.guide-list a {
  color: var(--interactive);
  font-weight: 500;
}

.guide-list-blurb {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin-top: 0.15rem;
  line-height: 1.5;
}

/* ----------------------------------------------------------------- article */

.guide-article {
  /* A comfortable measure. Long-form text set the full width of a desktop
     window is measurably harder to read, and this app is used on 27" screens. */
  max-width: 72ch;
  line-height: 1.65;
}

.guide-article-head {
  border-bottom: 1px solid var(--border-subtle);
  padding-bottom: var(--space-md, 1rem);
  margin-bottom: var(--space-md, 1rem);
}

.guide-one-sentence {
  font-size: var(--text-lg, 1.125rem);
  color: var(--text-primary);
  font-weight: 500;
  line-height: 1.55;
  border-left: 3px solid var(--interactive);
  padding-left: var(--space-md, 1rem);
  margin-bottom: var(--space-lg, 1.5rem);
}

.guide-article h3 {
  font-size: var(--text-base, 1rem);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  margin-top: var(--space-lg, 1.5rem);
  margin-bottom: 0.4rem;
}

.guide-article p {
  color: var(--text-secondary);
  margin-bottom: 0.85rem;
}

.guide-steps,
.guide-evidence,
.guide-mistakes {
  color: var(--text-secondary);
  padding-left: 1.25rem;
  margin-bottom: 0.5rem;
}

.guide-steps > li,
.guide-evidence > li,
.guide-mistakes > li {
  margin-bottom: 0.5rem;
  line-height: 1.6;
}

/* The three evidence lists are colour-coded, but colour is never the only
   signal: the heading above each one already names what it is, and the marker
   glyph differs. That keeps them readable with any form of colour blindness
   and in forced-colors mode. */
.guide-evidence {
  list-style: none;
  padding-left: 0;
}

.guide-evidence > li::before {
  content: '✓';
  color: var(--status-success-fg);
  font-weight: 700;
  margin-right: 0.5rem;
}

.guide-mistakes {
  list-style: none;
  padding-left: 0;
}

.guide-mistakes > li::before {
  content: '✕';
  color: var(--status-danger-fg);
  font-weight: 700;
  margin-right: 0.5rem;
}

.guide-step-link {
  color: var(--interactive);
  white-space: nowrap;
  font-size: var(--text-sm);
}

.guide-step-link::after {
  content: ' →';
}

.guide-article-foot {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: var(--space-xl, 2rem);
  padding-top: var(--space-md, 1rem);
  border-top: 1px solid var(--border-subtle);
}

/* --------------------------------------------------------------- glossary */

.glossary {
  margin: 0;
}

/* The glossary card is full width, so its intro needs its own measure — set
   across a 27" monitor it was running to about 130 characters a line. */
.glossary-intro {
  max-width: 42rem;
}

.glossary-entry {
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--border-subtle);
}

.glossary-entry:last-child {
  border-bottom: 0;
}

.glossary dt {
  font-weight: 600;
  color: var(--text-primary);
}

.glossary dd {
  margin: 0.25rem 0 0;
  color: var(--text-secondary);
  line-height: 1.6;
  max-width: 42rem;
}

/* The everyday phrase alongside the formal term (§6.1) — an auditor says
   "objective evidence", the shop says "the paperwork that shows it happened",
   and both need to find the entry. */
.glossary-alias {
  font-weight: 400;
  font-size: var(--text-sm);
  color: var(--text-muted);
  font-style: italic;
}

/* ---------------------------------------------- contextual entry points */

/* The "? What is this?" link on every generated screen (§6.4). Deliberately
   quiet: it must be findable at the moment of confusion without competing
   with the screen's own actions. */
.guide-inline-link {
  font-size: var(--text-sm);
  color: var(--interactive);
  text-decoration: none;
  white-space: nowrap;
  padding: 0.25rem 0.4rem;
  border-radius: var(--radius-sm, 6px);
}

.guide-inline-link:hover,
.guide-inline-link:focus-visible {
  background: var(--interactive-subtle);
  text-decoration: underline;
}

.search-group-heading {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  padding: 0.5rem var(--space-sm, 0.5rem) 0.25rem;
  border-top: 1px solid var(--border-subtle);
  margin-top: 0.25rem;
}

/* ------------------------------------------------------------ phone layout */

@media (max-width: 767px) {
  .guide-categories {
    grid-template-columns: 1fr;
  }

  .guide-article,
  .guide-hero {
    max-width: none;
  }

  .guide-article-foot .btn {
    flex: 1 1 auto;
  }
}

/* ------------------------------------------------------------------ print */

/* Printing an article is the "hand it to a new hire" path (§6.4). The app
   chrome is not part of the document, so it is removed rather than hidden
   behind a background-graphics setting the user may not have on. */
@media print {
  .sidebar,
  .topbar,
  .bottom-nav,
  .mobile-nav-toggle,
  .toast-container,
  .modal-overlay,
  .auth-overlay,
  .syncing-overlay,
  .skip-link,
  .breadcrumb,
  .guide-article-foot,
  #search-results {
    display: none !important;
  }

  .app-layout,
  .main-area,
  .content {
    display: block;
    margin: 0;
    padding: 0;
    overflow: visible;
    height: auto;
  }

  .card,
  .guide-article {
    border: 0;
    box-shadow: none;
    background: transparent;
    max-width: none;
    padding: 0;
  }

  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
  }

  .guide-article h3 {
    color: #000;
    page-break-after: avoid;
  }

  .guide-article p,
  .guide-list > li,
  .guide-steps > li,
  .guide-evidence > li,
  .guide-mistakes > li,
  .glossary-entry {
    color: #000;
    page-break-inside: avoid;
  }

  .guide-one-sentence {
    border-left: 2pt solid #000;
    color: #000;
  }

  /* A printed deep link is useless as a link, so print where it goes. The
     app uses hash routing, so the fragment is the whole address. */
  .guide-step-link::after {
    content: ' (' attr(href) ')';
    font-size: 9pt;
  }

  .guide-evidence > li::before,
  .guide-mistakes > li::before {
    color: #000;
  }
}

/* ============================================================================
   My Work and compliance readiness (§7.1, §5.2)
   ========================================================================== */

/* The count on a filter chip. Tabular figures so the three tabs do not shift
   width as the queue changes under them. */
.chip-count {
  font-variant-numeric: tabular-nums;
  opacity: 0.75;
  margin-left: 0.25rem;
}

/* The whole row opens the record; the title is the anchor that does it, so it
   has to look like the way through rather than like a caption. */
.task-row { cursor: pointer; }
.task-row:hover { background: var(--surface-sunken, var(--bg-tertiary)); }
/* The row is not focusable — the title link is — so the focus ring has to be
   drawn for the row that contains the focused link, or keyboard users get a
   ring around a few words with no indication of which row they are in. */
.task-row:focus-within { background: var(--surface-sunken, var(--bg-tertiary)); }

.task-link {
  font-weight: 600;
  color: var(--text-primary);
  text-decoration: none;
}
.task-link:hover,
.task-link:focus-visible { text-decoration: underline; }

/* Tasks whose action is not "open this record" are buttons; they should still
   read as the way through, so they shed the button chrome. */
.task-link-action {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

/* The record type ("Corrective action"). It was the only link in the row and
   is now a label, so it steps back to let the title lead. */
.task-kind {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 0.15rem;
}

.task-title {
  font-size: var(--text-sm);
  color: var(--text-secondary);
  margin-top: 0.15rem;
}

.task-why {
  font-size: var(--text-sm);
  color: var(--status-warning-fg);
  margin-top: 0.15rem;
}

/* "4d late" beside the date. The colour repeats what the date already says,
   so it is reinforcement rather than the only signal. */
.task-age {
  font-size: var(--text-xs);
  font-weight: 600;
  white-space: nowrap;
  margin-left: 0.35rem;
}
.task-age-danger  { color: var(--status-danger-fg); }
.task-age-warning { color: var(--status-warning-fg); }
.task-age-info    { color: var(--text-muted); }

/* The owner cell is the control that changes it: the queue is where you find
   out something has no owner, so it is where fixing that belongs. */
.task-owner-btn {
  background: none;
  border: 1px solid transparent;
  border-radius: var(--radius-sm, 6px);
  padding: 0.2rem 0.4rem;
  margin: -0.2rem -0.4rem;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.task-owner-btn:hover:not(:disabled),
.task-owner-btn:focus-visible { border-color: var(--border-strong); }
.task-owner-btn:disabled { cursor: default; }

/* A name nobody in the register matches will not reach anyone's queue. Saying
   so where the name is shown beats leaving it to be discovered. */
.task-owner-unknown {
  display: block;
  font-size: var(--text-xs);
  color: var(--status-warning-fg);
}

/* Unowned work is the quiet failure mode, so it is named rather than blank —
   an empty cell reads as "not applicable", which is exactly wrong here. */
.task-unowned {
  color: var(--status-warning-fg);
  font-style: italic;
}

.callout {
  border-left: 3px solid var(--border-strong);
  padding: 0.75rem 1rem;
  border-radius: var(--radius-sm, 6px);
  margin: var(--space-md, 1rem) 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.callout-warning {
  border-left-color: var(--status-warning-fg);
  background: var(--status-warning-bg);
}

/* --------------------------------------------------------- notifications */

/* Unread is carried by a rule and a weight, not by colour alone — the dot to
   its left already encodes severity, and two colour signals in one row is one
   too many to read at a glance. */
.notif-item-unread {
  border-left: 3px solid var(--interactive);
}
.notif-item-unread .notif-item-text {
  font-weight: 600;
}

.notif-mine {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--interactive);
  margin-right: 0.25rem;
}

.notif-more {
  display: block;
  padding: 0.6rem 1rem;
  font-size: var(--text-sm);
  color: var(--interactive);
  border-top: 1px solid var(--border-subtle);
}

/* ============================================================================
   Global search (§7.9)
   ============================================================================
   The panel was `position: fixed; right: 200px; width: 400px`, which put it
   off-screen on anything narrower than roughly 700px. It is anchored to the
   search bar now, and becomes a full-width sheet below the topbar on phones.
   ========================================================================== */

.search-bar { position: relative; }

#search-results {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  width: min(28rem, calc(100vw - 2rem));
  max-height: min(28rem, 60vh);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface-1);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg, 12px);
  box-shadow: var(--shadow-lg, 0 12px 32px rgba(0, 0, 0, 0.35));
  z-index: 200;
  padding: 0.35rem;
}

#search-results.hidden { display: none; }

.search-result {
  display: block;
  padding: 0.55rem 0.6rem;
  border-radius: var(--radius-sm, 6px);
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  /* Comfortably past the 44px touch minimum with two lines of content. */
  min-height: 44px;
}

.search-result:hover,
.search-result.is-active {
  background: var(--interactive-subtle);
}

/* The keyboard cursor needs to be visible without hover, and distinguishable
   from it — otherwise arrowing down looks identical to nothing happening. */
.search-result.is-active {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

.search-result-main {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.search-result-label {
  font-size: var(--text-sm);
  color: var(--text-primary);
}

.search-result-meta {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 0.15rem;
}

.search-facets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  padding: 0.35rem 0.25rem 0.5rem;
  border-bottom: 1px solid var(--border-subtle);
  margin-bottom: 0.35rem;
}

.search-empty {
  padding: 1rem;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.search-empty-hint {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 0.35rem;
}

@media (max-width: 767px) {
  /* Full-width sheet: on a phone there is no room to anchor a 28rem panel to
     a control that is itself nearly the width of the screen. */
  #search-results {
    position: fixed;
    top: calc(var(--topbar-height, 3.5rem) + env(safe-area-inset-top));
    left: 0.5rem;
    right: 0.5rem;
    width: auto;
    max-height: calc(100dvh - var(--topbar-height, 3.5rem) - 5rem);
  }
}

/* ============================================================================
   QR label printing (§10.9)
   ============================================================================
   Replaces a `window.open` + `document.write` popup that popup blockers
   stopped, that silently did nothing on iOS Safari, and that carried an
   inline script no CSP could cover. The label is part of this document and
   the print stylesheet hides everything else.
   ========================================================================== */

#print-label { display: none; }

@media print {
  /* When a label is printing, it is the only thing on the page — including
     ahead of the guide's own print rules, which assume an article. */
  body.printing-label > *:not(#print-label) { display: none !important; }

  body.printing-label #print-label {
    display: block;
    text-align: center;
    font-family: system-ui, sans-serif;
    color: #000;
    background: #fff;
  }

  .print-label-sheet { padding: 12mm 8mm; page-break-inside: avoid; }

  .print-label-qr {
    width: 45mm;
    height: 45mm;
    /* Nearest-neighbour: a resampled QR is a QR that does not scan. */
    image-rendering: pixelated;
  }

  .print-label-title { font-size: 14pt; margin: 4mm 0 1mm; }
  .print-label-subtitle { font-size: 10pt; margin: 0 0 1mm; }
  .print-label-code { font-family: ui-monospace, monospace; font-size: 11pt; margin: 0; }
}
