/* Documentation: the SRS and the traceability matrix.
   Denser than the rest of the app on purpose — a specification is read in long
   passes and scanned for a field or a rule, so tables get tighter rows and the
   prose gets a measured column rather than the full page width. */

.doc-lede { color: var(--muted); max-width: 68ch; margin: 0 0 18px; }

/* --- index ------------------------------------------------------------- */

.doc-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 14px; }
.doc-card {
  display: block; padding: 18px 20px; text-decoration: none; color: inherit;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
}
.doc-card:hover { border-color: var(--primary); }
.doc-card h3 { margin: 6px 0 10px; font-size: 17px; }
.doc-card p { margin: 10px 0 0; color: var(--muted); font-size: 13px; line-height: 1.5; }
.doc-card-kind {
  font-size: 10px; font-weight: 700; letter-spacing: .1em; color: var(--primary);
}
.doc-card-meta { display: flex; gap: 10px; align-items: center; font-size: 12px; color: var(--muted); }
.doc-note { margin-top: 16px; font-size: 13px; color: var(--muted); }
.doc-note strong { color: var(--text); }

/* --- document furniture ------------------------------------------------ */

.doc-head {
  display: flex; flex-wrap: wrap; gap: 28px;
}
.doc-head > div { display: flex; flex-direction: column; gap: 3px; }
.doc-label { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }

.doc-stamp {
  margin: 14px 0 20px; padding: 9px 13px; font-size: 12px; color: var(--muted);
  border: 1px solid var(--border); border-left: 3px solid var(--primary);
  border-radius: var(--radius); background: var(--surface-alt);
}
.doc-stamp code { color: var(--primary); }

.doc-toc {
  display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 16px 0;
  padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); font-size: 12.5px;
}
.doc-toc a { color: var(--muted); text-decoration: none; }
.doc-toc a:hover { color: var(--primary); }

.doc-section {
  margin: 26px 0; padding: 20px 22px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
}
.doc-section > h3 { margin: 0 0 16px; font-size: 17px; display: flex; align-items: baseline; gap: 10px; }
.doc-num {
  font-size: 12px; color: var(--primary); font-variant-numeric: tabular-nums;
  border: 1px solid var(--border); border-radius: 4px; padding: 1px 7px;
}
.doc-section p { max-width: 78ch; line-height: 1.6; }
.doc-subhead { margin: 22px 0 10px; font-size: 14px; color: var(--text); }
.doc-empty { color: var(--muted); font-style: italic; }
.doc-dim { color: var(--muted); }
.doc-hint { font-size: 12px; margin-bottom: 6px; }

/* --- tables ------------------------------------------------------------ */

.doc-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.doc-table caption {
  text-align: left; font-size: 10px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--muted); padding-bottom: 6px;
}
.doc-table th, .doc-table td {
  text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--border); vertical-align: top;
}
.doc-table thead th {
  font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); font-weight: 600; white-space: nowrap;
}
.doc-table td.num, .doc-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.doc-table .mono { font-family: ui-monospace, Consolas, monospace; font-size: 11.5px; }
.doc-kv th { width: 42%; font-weight: 500; color: var(--muted); }
.req-star { color: var(--danger); margin-left: 2px; }

/* Wide generated tables scroll themselves rather than the page. */
.doc-section { overflow-x: auto; }

.doc-tag {
  display: inline-block; margin: 1px 3px 1px 0; padding: 1px 6px;
  font-size: 10.5px; border-radius: 3px;
  border: 1px solid var(--border); color: var(--muted); background: var(--surface-alt);
}
.doc-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.doc-chip {
  padding: 3px 9px; font-size: 11.5px; border-radius: 4px;
  border: 1px solid var(--border); background: var(--surface-alt);
}
.doc-chip i { color: var(--muted); font-style: normal; margin-left: 6px; font-size: 10.5px; }

.doc-split { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; }
.doc-entity { margin: 18px 0 26px; }
.doc-entity h4 { margin: 0 0 8px; font-size: 13.5px; }
.doc-touch { font-size: 12px; margin: 0 0 8px; }
.doc-refs a { color: var(--primary); text-decoration: none; margin-right: 6px; }
.doc-link { color: var(--primary); text-decoration: none; font-weight: 600; }
.doc-op { margin: 12px 0; }
.doc-op-name {
  font-family: ui-monospace, Consolas, monospace; font-size: 11.5px;
  color: var(--primary); margin-bottom: 4px;
}

/* --- requirements ------------------------------------------------------ */

.doc-reqid {
  font-family: ui-monospace, Consolas, monospace; font-size: 11.5px;
  color: var(--primary); text-decoration: none; white-space: nowrap; font-weight: 600;
}
.doc-req-title { font-weight: 600; margin-bottom: 3px; }
.doc-req-statement { font-size: 12px; line-height: 1.5; max-width: 90ch; }
.doc-jira {
  font-family: ui-monospace, Consolas, monospace; font-size: 11.5px;
  color: var(--primary); text-decoration: none; font-weight: 600;
}
.doc-jira:hover { text-decoration: underline; }

.doc-status {
  display: inline-block; padding: 2px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;
  border: 1px solid var(--border); color: var(--muted);
}
.doc-status-draft { color: var(--muted); }
.doc-status-approved { color: var(--info); border-color: rgba(96, 165, 250, .35); }
.doc-status-implemented { color: var(--primary); border-color: rgba(108, 140, 255, .35); }
.doc-status-verified { color: var(--success); border-color: rgba(74, 222, 128, .35); }
.doc-status-withdrawn { color: var(--muted); text-decoration: line-through; }

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

.rtm-stats { margin-bottom: 16px; }
.stat-sub { font-size: 11px; color: var(--muted); margin-top: 2px; }

.rtm-table td { padding: 10px; }
.rtm-summary { font-size: 12px; margin: 3px 0; max-width: 52ch; }
.rtm-meta { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; font-size: 11px; }
.rtm-case { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 5px; font-size: 12px; }
.rtm-case a { color: var(--text); text-decoration: none; }
.rtm-case a:hover { color: var(--primary); }
.rtm-run { color: var(--muted) !important; font-size: 11px; }

/* A row's coverage is carried on the left edge as well as in the column, so
   the shape of the release reads before any of the text does. */
.rtm-row td:first-child { border-left: 3px solid transparent; }
.rtm-verified  td:first-child { border-left-color: var(--success); }
.rtm-partial   td:first-child { border-left-color: var(--warning); }
.rtm-failed    td:first-child { border-left-color: var(--danger); }
.rtm-untested  td:first-child { border-left-color: var(--border); }

.cov { display: inline-block; padding: 2px 9px; border-radius: 3px; font-size: 11px; font-weight: 700; }
.cov-verified { color: var(--success); background: rgba(74, 222, 128, .12); }
.cov-partial  { color: var(--warning); background: rgba(251, 191, 36, .12); }
.cov-failed   { color: var(--danger);  background: rgba(248, 113, 113, .12); }
.cov-untested { color: var(--muted);   background: var(--surface-alt); }

.doc-gap { color: var(--muted); font-style: italic; font-size: 12px; }
.rtm-gaps { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; }
.rtm-gap h4 { margin: 0 0 8px; font-size: 13px; display: flex; gap: 8px; align-items: center; }
.rtm-gap ul { margin: 0; padding-left: 18px; font-size: 12px; line-height: 1.7; }
.rtm-gap a { color: var(--primary); text-decoration: none; }

/* --- diagrams ---------------------------------------------------------- */

.doc-figure {
  margin: 12px 0 20px; padding: 14px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface-alt);
  overflow-x: auto;
}
.dfd { width: 100%; height: auto; min-width: 640px; }
.dfd text { font-family: inherit; font-size: 12px; fill: var(--text); }
.dfd .dfd-note { font-size: 10px; fill: var(--muted); }
.dfd .dfd-label { font-size: 8.5px; fill: var(--muted); letter-spacing: .08em; }
.dfd .dfd-id { font-size: 11px; fill: var(--primary); font-weight: 700; }
.dfd .dfd-title { font-size: 12.5px; font-weight: 600; }
.dfd .dfd-store { font-size: 10px; fill: var(--primary); }

.dfd-proc-0 ellipse { fill: var(--surface); stroke: var(--primary); stroke-width: 2; }
.dfd-proc-0 text { font-weight: 700; font-size: 15px; }
.dfd-ext rect { fill: var(--surface); stroke: var(--border); stroke-width: 1.5; }
.dfd-proc rect { fill: var(--surface); stroke: var(--border); stroke-width: 1.5; }
.dfd-proc:hover rect { stroke: var(--primary); }


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

@media print {
  /* The document is the deliverable; the application around it is not. */
  .sidebar, .topbar, .page-header button, .doc-toc, #docProseWrap, .toast { display: none !important; }
  body, .app, .content { background: #fff !important; color: #111 !important; }
  .doc-section, .card, .doc-figure {
    background: #fff !important; border-color: #ccc !important;
    break-inside: avoid; page-break-inside: avoid;
  }
  .doc-table th, .doc-table td { border-color: #ddd !important; }
  .doc-entity, .rtm-row { break-inside: avoid; page-break-inside: avoid; }
  a { color: inherit !important; text-decoration: none !important; }
  /* On paper a dashed connector reads as a tentative relationship, and the
     animation means nothing at all. */
  .fdd-edge, .dfd-edge {
    animation: none; stroke-dasharray: none;
    stroke: #6c8cff !important; filter: none;
  }
  .dfd-arrowhead { animation: none; fill: #6c8cff !important; }

  /* The server-side PDF export stamps .pdf-dark on <html>. That file is a copy
     of the document as it is read on screen, so the paper palette above is put
     back; the browser's own print dialog, which does end up on paper, keeps the
     white version. */
  html.pdf-dark body, html.pdf-dark .app, html.pdf-dark .content {
    background: var(--bg) !important; color: var(--text) !important;
  }
  html.pdf-dark .doc-section, html.pdf-dark .card, html.pdf-dark .doc-figure {
    background: var(--surface) !important; border-color: var(--border) !important;
  }
  html.pdf-dark .doc-table th, html.pdf-dark .doc-table td {
    border-color: var(--border) !important;
  }
  @page { size: A4; margin: 14mm 10mm 16mm; }
}

/* The coverage colours are chips elsewhere; on a summary tile only the figure
   should be coloured, or the tinted background stretches the full tile width
   and reads as a progress bar that is not measuring anything. */
.stat-value.cov-verified, .stat-value.cov-partial,
.stat-value.cov-failed, .stat-value.cov-untested { background: none; padding: 0; }

/* --- library CRUD ------------------------------------------------------- */

.doc-card { display: flex; flex-direction: column; padding: 0; }
.doc-card-body { display: block; padding: 18px 20px 14px; text-decoration: none; color: inherit; }
.doc-card-actions {
  display: flex; gap: 6px; justify-content: flex-end;
  padding: 10px 16px; border-top: 1px solid var(--border);
}
.doc-card--archived { opacity: .6; }
.doc-danger { color: var(--danger); }
.doc-archive-toggle {
  display: flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--muted); cursor: pointer;
}
.rtm-suite {
  font-size: 11px; color: var(--muted) !important;
  border: 1px solid var(--border); border-radius: 3px; padding: 0 6px;
}

/* A snapshot taken from an older commit is not an error, but the reader has to
   see it without hunting for the date. */
.doc-stamp--stale { border-left-color: var(--warning); }

/* --- system under test -------------------------------------------------- */

/* 1,183 steps cannot all be open at once; each case is a disclosure so the
   module summary stays scannable and the detail is one click away. */
.sut-case { border: 1px solid var(--border); border-radius: 6px; margin-bottom: 6px; }
.sut-case > summary {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 12px; cursor: pointer; font-size: 12.5px; list-style: none;
}
.sut-case > summary::-webkit-details-marker { display: none; }
.sut-case > summary::before {
  content: '▸'; color: var(--muted); font-size: 11px; transition: transform .12s;
}
.sut-case[open] > summary::before { transform: rotate(90deg); }
.sut-case[open] > summary { border-bottom: 1px solid var(--border); background: var(--surface-alt); }
.sut-case-title { flex: 1; font-weight: 600; min-width: 240px; }
.sut-steps { margin: 0; }
.sut-steps td { padding: 6px 12px; }

.doc-total td { font-weight: 700; border-top: 2px solid var(--border); }

/* --- functional decomposition diagram ----------------------------------- */

/* A real FDD: ranks on the page, parent above children. The earlier indented
   list read as an outline — the notation exists so the shape of the
   decomposition is visible before any label is. */
/* Wraps into bands to fit, so it scales with the figure rather than
   overflowing it. */
.fdd-svg { width: 100%; height: auto; }
/* The connectors carry the structure, so they have to be seen.
   At --border they were #2a313d on a #161a22 surface — a two-step contrast
   that vanished at any distance, leaving boxes that looked unrelated.

   They are drawn as lit wiring with current running through it: a dash pattern
   travelling along the line, and the colour cycling red → green → blue beneath
   it. The movement is what makes a thin line legible against a dark ground —
   the eye follows a moving edge it would otherwise slide over. */
.fdd-edge,
.dfd-edge {
  stroke: var(--primary);
  stroke-width: 1.7;
  fill: none;
  stroke-linecap: round;
  stroke-dasharray: 7 5;
  filter: drop-shadow(0 0 3px rgba(108, 140, 255, 0.5));
  animation: wire-flow 900ms linear infinite, wire-rgb 5s linear infinite;
}
.dfd-arrowhead { fill: var(--primary); animation: wire-rgb-fill 5s linear infinite; }

/* Offset, not position: the dash pattern slides along the path it is already
   on, so the line stays where it is and only the current appears to move. */
@keyframes wire-flow {
  to { stroke-dashoffset: -24; }
}
@keyframes wire-rgb {
  0%   { stroke: #ff5f6d; }
  33%  { stroke: #4ade80; }
  66%  { stroke: #6c8cff; }
  100% { stroke: #ff5f6d; }
}
@keyframes wire-rgb-fill {
  0%   { fill: #ff5f6d; }
  33%  { fill: #4ade80; }
  66%  { fill: #6c8cff; }
  100% { fill: #ff5f6d; }
}

/* Motion is decoration here; the diagram reads without it. Anyone who has
   asked their system for less of it gets a solid line instead. */
@media (prefers-reduced-motion: reduce) {
  .fdd-edge,
  .dfd-edge,
  .dfd-arrowhead { animation: none; stroke-dasharray: none; }
}

.fdd-root rect { fill: var(--surface); stroke: var(--primary); stroke-width: 2; }
.fdd-root text { font-size: 14px; font-weight: 700; fill: var(--text); }

.fdd-branch rect { fill: var(--surface-alt); stroke: var(--border); stroke-width: 1.5; }
.fdd-branch-text { font-size: 12px; font-weight: 600; fill: var(--text); }

.fdd-leaf rect { fill: var(--surface); stroke: var(--border); stroke-width: 1; }
.fdd-leaf-text { font-size: 10.5px; fill: var(--text); }
.fdd-leaf-detail { font-size: 10px; fill: var(--muted); }
/* The decomposition is a figure, not a control surface. It reads as one thing
   at a glance and nothing in it responds to a pointer, so no box invites a
   click it cannot answer. The screen list in section 7 is where the detail
   lives. */
.fdd-svg { pointer-events: none; }

/* The screen a link lands on, so the jump from the diagram is obvious. */
.doc-table tr:target td { background: var(--surface-alt); box-shadow: inset 3px 0 0 var(--primary); }

/* --- full width --------------------------------------------------------- */

/* A specification is mostly wide tables and diagrams, so it drops the 1100px
   reading column.

   Every paragraph runs the full width of its section, not just the authored
   prose. Capping them at a reading measure left each one filling under half of
   a full-width section, which reads as squeezed against the tables and figures
   beside it — and a section's introductory line looked broken in a way the
   table under it did not. Setting them in columns was worse again: a sentence
   ran down the left and resumed at the top of the right. */
body.doc-fullwidth .container { max-width: none; padding: 22px 28px; }
body.doc-fullwidth .doc-section p { max-width: none; }
body.doc-fullwidth .doc-figure { width: 100%; }

/* A section scrolled to from the contents should show its heading, not sit
   flush against the top edge of the viewport. */
.doc-section, .doc-entity, .doc-table tr[id] { scroll-margin-top: 18px; }

/* --- collapsible modules ------------------------------------------------ */

.doc-group-controls {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 12px; font-size: 12.5px;
}
.doc-group-controls .doc-dim { margin-left: 6px; }

.doc-group {
  border: 1px solid var(--border); border-radius: var(--radius);
  margin-bottom: 8px; background: var(--surface-alt);
}
.doc-group > summary {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; cursor: pointer; list-style: none;
}
.doc-group > summary::-webkit-details-marker { display: none; }
.doc-group > summary::before {
  content: '▸'; color: var(--muted); font-size: 11px; transition: transform .12s;
}
.doc-group[open] > summary::before { transform: rotate(90deg); }
.doc-group[open] > summary { border-bottom: 1px solid var(--border); }
.doc-group-name { font-weight: 700; font-size: 13.5px; min-width: 210px; }
.doc-group-body { padding: 10px 14px 12px; }

/* Nested one level down, so the case rows read as belonging to the module
   rather than competing with it. */
.doc-group-body .sut-case { background: var(--surface); }

/* --- sub-numbering ------------------------------------------------------ */

/* Children carry their parent's number, so a screen or a case can be cited
   exactly — "7.3.2" rather than "the third one under Billing". */
.doc-num-sub {
  font-size: 11px; padding: 1px 6px; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.sut-case-no { min-width: 46px; font-size: 10.5px; }
.doc-subhead .doc-num-sub { margin-right: 6px; }

/* A static figure never scrolls: it is scaled to fit its container, so a
   scrollbar here would only ever be a rounding artefact. */
.doc-figure--static { overflow: hidden; }

/* --- suite linkage on the matrix ---------------------------------------- */

.rtm-link-check { display: flex; align-items: center; cursor: pointer; }
.rtm-link-check input { cursor: pointer; }
.rtm-suite-row.is-linked { border-left: 3px solid var(--success); }
.rtm-suite-row > summary { gap: 9px; }

/* --- printing a collapsed document -------------------------------------- */

/* Sections collapse on screen so a long document stays navigable, but a PDF is
   read as a whole: a printed matrix showing only summary rows would omit the
   evidence it exists to carry. Force every disclosure open for print. */
@media print {
  details > *:not(summary) { display: block !important; }
  details > summary { list-style: none; }
  details > summary::before { content: none !important; }
  .doc-group-controls, .sut-controls { display: none !important; }
  .doc-group, .sut-case, .rtm-suite-row { break-inside: avoid; }
}
