/* OutSec shared design system.
   Canonical source: this file, in the outsec-design-system repo.
   Lifted 2026-09-24 from HOKOKU's templates/konseki_report.html (the
   KONSEKI client report) -- the most mature of HOKOKU's three
   previously-divergent CSS systems, chosen as the one both apps
   converge onto. Generalised from report-specific naming
   (.report-body/.report-section/.report-cover) to .page-* equivalents
   since KANCHO's pages aren't reports.

   Consuming apps (HOKOKU, KANCHO) vendor a literal copy of this file
   under their own static/ directory, each with a header comment naming
   the source commit. Edit here, then re-copy -- do not diverge the
   vendored copies. See README.md for the update procedure. */

:root {
  --ink: #14151A;
  --paper: #F7F6F2;
  --signal: #2A46FF;
  --ember: #FF5A1F;
  --muted: #6B6D76;
  --muted-on-dark: #9A9CA8;
  --paper-on-dark: rgba(247, 246, 242, 0.7);
  --paper-on-dark-dim: rgba(247, 246, 242, 0.5);
  --border-light: rgba(20, 21, 26, 0.1);
  --border-light-2: rgba(20, 21, 26, 0.12);
  --card-on-paper: rgba(20, 21, 26, 0.03);
  --tag-bg: rgba(20, 21, 26, 0.06);

  /* Status colours -- pass/high/low/info reuse existing brand tokens
     where the fit is natural (ember already reads as "urgent", signal
     as the brand's own accent). Green/amber/purple are the three
     additions, picked to match signal/ember's richness (fully
     saturated, ~55-60% lightness) rather than pastel, so the badge set
     reads as one deliberate family, not a mismatched traffic light. */
  --status-pass: #1B8A5A;
  --status-high: #FF5A1F;   /* = --ember */
  --status-medium: #C9820F;
  --status-low: #2A46FF;    /* = --signal */
  --status-info: #0F8B8D;   /* teal, distinct from --status-low so Observation/Info don't read as Low */
  --status-nd: #6D4FC4;

  /* Destructive-UI-action token, distinct from --status-high/--ember on
     purpose (2026-09-24): "this finding is high severity" and "this
     button deletes something" are different concepts and shouldn't
     share one visual signal just because both happen to read as
     urgent/red-ish. Chosen a true red rather than reusing ember's
     orange so the two never get confused at a glance. */
  --danger: #D1293D;
  --danger-bg: rgba(209, 41, 61, 0.1);

  --font-display: 'Bricolage Grotesque', sans-serif;
  --font-body: 'IBM Plex Sans', sans-serif;
  --font-mono: 'IBM Plex Mono', monospace;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: var(--font-body); font-size: 10.5pt; color: var(--ink); line-height: 1.6; background: var(--paper); -webkit-font-smoothing: antialiased; }

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

@page { size: A4; margin: 0 1.6cm 1.8cm; }
@media print {
  .no-print { display: none !important; }
  .page-cover { break-after: page; page-break-after: always; margin: 0 -1.6cm; padding: 3cm 1.6cm 2.4cm; }
  .page-body { padding: 0; }
  .page-section { break-inside: avoid-page; }
  thead { display: table-header-group; }
  tr { break-inside: avoid; page-break-inside: avoid; }
}
@media screen {
  body { max-width: 960px; margin: 0 auto; }
  .page-cover { border-radius: 0 0 20px 20px; }
}

/* ── Nav (screen only) ──────────────────────────────────────────────────── */
.nav-bar { display: flex; justify-content: space-between; align-items: center; padding: 18px 32px; font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
.nav-bar a { color: var(--muted); text-decoration: none; }
.nav-bar a:hover { color: var(--ink); }
.nav-back { color: var(--signal) !important; }
.nav-pdf-btn { background: var(--signal); color: var(--paper) !important; padding: 9px 18px; border-radius: 8px; font-weight: 500; font-family: var(--font-body); font-size: 13px; }

/* Full app nav -- KANCHO's authenticated shell (a real logo/links/logout
   row, distinct from the report's screen-only cover-strip .nav-bar
   above, though sharing its type/colour vocabulary). */
.app-nav { display: flex; justify-content: space-between; align-items: center; padding: 14px 32px; background: var(--ink); }
.app-nav .wordmark { font-family: var(--font-display); font-weight: 700; font-size: 16px; letter-spacing: -0.01em; color: var(--paper); text-decoration: none; }
.app-nav .wordmark-accent { color: var(--signal); }
.app-nav-links { display: flex; align-items: center; gap: 22px; font-family: var(--font-mono); font-size: 12px; }
.app-nav-links a { color: var(--paper-on-dark); text-decoration: none; padding: 4px 0; border-bottom: 2px solid transparent; }
.app-nav-links a:hover { color: var(--paper); }
.app-nav-links a.active { color: var(--paper); border-bottom-color: var(--signal); }
.app-nav-logout { background: none; border: none; color: var(--paper-on-dark); font-family: var(--font-mono); font-size: 12px; cursor: pointer; padding: 0; }
.app-nav-logout:hover { color: var(--paper); }

/* ── Cover (matches trace_sample.html's .page-cover exactly) ─────────── */
.page-cover { position: relative; background: var(--ink); padding: 56px 32px 60px; overflow: hidden; }
.page-cover .logo { display: flex; align-items: center; gap: 12px; margin-bottom: 44px; }
.page-cover .wordmark { font-family: var(--font-display); font-weight: 700; font-size: 16px; letter-spacing: -0.01em; color: var(--paper); }
.page-cover .wordmark-accent { color: var(--signal); }
.page-cover-head { position: relative; display: flex; align-items: center; gap: 28px; }
.page-cover-icon { flex-shrink: 0; }
.page-title-block .card-eyebrow--on-dark { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--signal); margin-bottom: 10px; }
.page-title { font-family: var(--font-display); font-weight: 800; font-size: 38px; letter-spacing: -0.02em; color: var(--paper); line-height: 1.1; }
.page-client { font-family: var(--font-body); font-size: 17px; color: var(--paper-on-dark); margin-top: 8px; }
.page-meta { position: relative; display: flex; gap: 48px; margin-top: 36px; font-family: var(--font-mono); font-size: 12.5px; color: var(--paper-on-dark-dim); flex-wrap: wrap; }
.page-meta .label { color: rgba(247, 246, 242, 0.4); display: block; margin-bottom: 3px; }
.page-meta strong { color: var(--paper-on-dark); font-weight: 500; }
.page-rating { margin-top: 30px; font-family: var(--font-mono); font-size: 13px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--signal); }
.page-rating .label { color: var(--paper-on-dark-dim); text-transform: none; letter-spacing: 0; margin-right: 8px; }
.cover-footer { position: relative; margin-top: 44px; padding-top: 20px; border-top: 1px solid var(--border-dark, rgba(247,246,242,0.16)); font-family: var(--font-mono); font-size: 10.5px; color: var(--paper-on-dark-dim); line-height: 1.6; }

/* ── Body / sections (matches .page-body / .page-section) ──────────── */
.page-body { max-width: 900px; margin: 0 auto; padding: 0 32px; }
.page-section { padding: 44px 0; border-bottom: 1px solid var(--border-light); }
.page-section:last-of-type { border-bottom: none; }
.page-section h2 { font-family: var(--font-display); font-weight: 700; font-size: 22px; color: var(--ink); margin-bottom: 14px; }
.page-section h3 { font-family: var(--font-display); font-weight: 700; font-size: 15.5px; color: var(--ink); margin: 20px 0 10px; }
.page-section h4 { font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; margin: 14px 0 8px; }
.page-section > p { font-size: 14.5px; color: var(--muted); line-height: 1.7; max-width: 780px; margin-bottom: 10px; }
.page-section > p:last-child { margin-bottom: 0; }
.page-section a { color: var(--signal); }

/* Narrower content container for app pages (KANCHO) that aren't a
   wide-format report -- same section rhythm, tighter max-width. */
.page-body-app { max-width: 1100px; margin: 0 auto; padding: 24px 32px; }

/* ── Section label (eyebrow + note, matches site's .section-label) ─────── */
.section-label { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 18px; flex-wrap: wrap; }
.section-label .eyebrow { font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.1em; color: var(--muted); text-transform: uppercase; }
.section-note { font-family: var(--font-mono); font-size: 10.5px; color: var(--muted); }

/* ── Stat strip (matches site's .stat-strip / .stat-figure) ────────────── */
.stat-strip { display: flex; gap: 40px; flex-wrap: wrap; align-items: flex-start; margin: 4px 0 18px; }
.stat-figure { font-family: var(--font-display); font-weight: 800; font-size: 32px; color: var(--ink); line-height: 1; }
.stat-figure.status-high   { color: var(--status-high); }
.stat-figure.status-medium { color: var(--status-medium); }
.stat-figure.status-low    { color: var(--status-low); }
.stat-figure.status-info   { color: var(--status-info); }
.stat-figure.status-nd     { color: var(--status-nd); }
.stat-label { font-family: var(--font-mono); font-size: 11px; color: var(--muted); text-transform: uppercase; margin-top: 4px; }

/* ── Cards (matches site's .card / .card-flat / .card-eyebrow) ─────────── */
.card { background: #ffffff; border: 1px solid var(--border-light-2); border-radius: 14px; padding: 22px 24px; }
.card-flat { background: var(--card-on-paper); border-radius: 14px; padding: 22px 24px; }
.card-eyebrow { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; color: var(--muted); text-transform: uppercase; margin-bottom: 8px; }

/* ── Tags -- one badge per finding (pass / not determined / a severity
   word), colour-coded by status. Base shape matches the site's own
   .tag; each status variant tints the background with its colour at
   low opacity and sets text to the full-strength colour, so it reads
   clearly on both screen and print without needing a legend. Also used
   by KANCHO for role/account-status badges (tag-neutral/tag-muted). ─── */
.tag {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--muted);
  background: var(--tag-bg);
  border-radius: 5px;
  padding: 3px 9px;
  display: inline-block;
  white-space: nowrap;
}
/* Explicit rgba() rather than color-mix() -- WeasyPrint's CSS engine is
   more conservative than a browser's and color-mix() (CSS Color 5) is
   too recent to trust for the PDF path. */
.tag-pass   { color: var(--status-pass);   background: rgba(27, 138, 90, 0.14); }
.tag-high   { color: var(--status-high);   background: rgba(255, 90, 31, 0.14); }
.tag-medium { color: var(--status-medium); background: rgba(201, 130, 15, 0.14); }
.tag-low    { color: var(--status-low);    background: rgba(42, 70, 255, 0.14); }
.tag-info   { color: var(--status-info);   background: rgba(15, 139, 141, 0.14); }
.tag-nd     { color: var(--status-nd);     background: rgba(109, 79, 196, 0.14); }
.tag-danger { color: var(--danger);        background: var(--danger-bg); }
.tag-neutral{ color: var(--ink);           background: var(--card-on-paper); }

/* ── Tables ──────────────────────────────────────────────────────────── */
table { width: 100%; border-collapse: collapse; font-size: 12.5px; margin: 4px 0; }
.findings-table { table-layout: fixed; }
th { text-align: left; padding: 9px 12px; background: var(--card-on-paper); font-family: var(--font-mono); font-weight: 500; color: var(--muted); border-bottom: 1px solid var(--border-light); font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; }
td { padding: 9px 12px; border-bottom: 1px solid var(--border-light); vertical-align: top; color: var(--ink); overflow-wrap: anywhere; }
tr:last-child td { border-bottom: none; }
.mono { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); }

/* Interactive table variant for app list pages (KANCHO) -- row hover +
   horizontal-scroll wrapper for narrow viewports. The report's plain
   `table` above stays print-oriented and un-hovered. */
.table-wrap { overflow-x: auto; }
.table-wrap table { background: #ffffff; border: 1px solid var(--border-light-2); border-radius: 14px; overflow: hidden; }
.table-wrap tbody tr:hover { background: var(--card-on-paper); }
.table-wrap tr[data-href] { cursor: pointer; }

/* ── Findings, per-category (matches .finding-card) ─────────────────────── */
.finding-card { background: #ffffff; border: 1px solid var(--border-light); border-radius: 14px; padding: 20px 24px; margin-bottom: 10px; }
.finding-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.finding-head .card-title { font-family: var(--font-display); font-weight: 700; font-size: 14.5px; color: var(--ink); margin: 0; }
.finding-statement { font-family: var(--font-mono); font-size: 12px; color: var(--ink); line-height: 1.55; margin-bottom: 5px; }
.finding-source { font-size: 11.5px; color: var(--muted); }
.lookalike-note { font-size: 12.5px; color: var(--muted); margin: 0 0 10px; }
.lookalike-note strong { color: var(--ink); }

/* ── Dark callout (matches .callout-dark) ───────────────────────────────── */
.callout-dark { background: var(--ink); border-radius: 16px; padding: 26px 28px; }
.callout-dark .card-eyebrow { color: var(--paper-on-dark-dim); }
.callout-dark p { color: var(--paper); font-size: 13.5px; line-height: 1.65; }

/* ── Buttons ─────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font-family: var(--font-body); font-size: 13.5px; font-weight: 500;
  padding: 9px 16px; border-radius: 8px; border: 1px solid transparent;
  cursor: pointer; text-decoration: none; line-height: 1.2;
}
.btn:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
.btn:disabled, .btn.disabled { cursor: not-allowed; opacity: 0.4; }
.btn-primary { background: var(--signal); color: var(--paper); }
.btn-primary:hover:not(:disabled) { background: #1f37d6; }
.btn-secondary { background: #ffffff; color: var(--ink); border-color: var(--border-light-2); }
.btn-secondary:hover:not(:disabled) { background: var(--card-on-paper); }
.btn-danger { background: var(--danger); color: var(--paper); }
.btn-danger:hover:not(:disabled) { background: #ab2030; }
.btn-sm { padding: 5px 11px; font-size: 12px; }

/* ── Form controls ───────────────────────────────────────────────────── */
.field { margin-bottom: 16px; }
.field-label { display: block; font-family: var(--font-mono); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin-bottom: 6px; }
.field-hint { font-size: 12px; color: var(--muted); margin-top: 4px; }
.field-error { font-size: 12px; color: var(--danger); margin-top: 4px; }
.input, select.input, textarea.input {
  width: 100%; font-family: var(--font-body); font-size: 13.5px; color: var(--ink);
  background: #ffffff; border: 1px solid var(--border-light-2); border-radius: 8px;
  padding: 9px 12px;
}
.input:focus { outline: none; border-color: var(--signal); box-shadow: 0 0 0 3px rgba(42, 70, 255, 0.12); }
.input:disabled { background: var(--card-on-paper); cursor: not-allowed; }

/* Checkbox-driven toggle switch (replaces the peer-checked Tailwind
   pattern KANCHO's old brand.css patched over). Markup:
   <label class="toggle"><input type="checkbox" class="toggle-input">
   <span class="toggle-track"></span></label> */
.toggle { display: inline-flex; align-items: center; cursor: pointer; }
.toggle-input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.toggle-track { width: 36px; height: 20px; background: var(--border-light-2); border-radius: 999px; position: relative; transition: background 0.15s; }
.toggle-track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; background: #fff; border-radius: 50%; transition: transform 0.15s; }
.toggle-input:checked + .toggle-track { background: var(--signal); }
.toggle-input:checked + .toggle-track::after { transform: translateX(16px); }
.toggle-input:focus-visible + .toggle-track { outline: 2px solid var(--signal); outline-offset: 2px; }

/* ── Alerts / flash messages ─────────────────────────────────────────── */
.alert { border-radius: 10px; padding: 12px 16px; font-size: 13.5px; margin-bottom: 16px; border: 1px solid transparent; }
.alert-success { background: rgba(27, 138, 90, 0.1); border-color: rgba(27, 138, 90, 0.3); color: var(--status-pass); }
.alert-error   { background: var(--danger-bg); border-color: rgba(209, 41, 61, 0.3); color: var(--danger); }
.alert-warning { background: rgba(201, 130, 15, 0.1); border-color: rgba(201, 130, 15, 0.3); color: var(--status-medium); }
.alert-info    { background: rgba(15, 139, 141, 0.1); border-color: rgba(15, 139, 141, 0.3); color: var(--status-info); }

/* ── Small utilities ─────────────────────────────────────────────────── */
.hidden { display: none !important; }
.ta-center { text-align: center; }
.ta-right { text-align: right; }
.font-mono-text { font-family: var(--font-mono); }
.text-muted { color: var(--muted); }
.fs-italic { font-style: italic; }
.fs-11 { font-size: 11px; }
.fs-12-5 { font-size: 12.5px; }

.mt-1 { margin-top: 4px; }
.mt-2 { margin-top: 8px; }
.mt-4 { margin-top: 16px; }
.mt-6 { margin-top: 24px; }
.mt-14 { margin-top: 14px; }
.mb-1 { margin-bottom: 4px; }
.mb-2 { margin-bottom: 8px; }
.mb-4 { margin-bottom: 16px; }
.mb-6 { margin-bottom: 24px; }
.pt-2 { padding-top: 8px; }
.pt-4 { padding-top: 16px; }

/* Table column-width hints -- exact percentages used across HOKOKU's
   findings/delta/appendix tables (konseki_report.html), replicating
   current values rather than inventing a new scale. */
.w-16p { width: 16%; }
.w-17p { width: 17%; }
.w-18p { width: 18%; }
.w-22p { width: 22%; }
.w-26p { width: 26%; }
.w-28p { width: 28%; }
.w-33p { width: 33%; }

/* Grid + col-span, replacing KANCHO's dynamic Jinja-interpolated
   `lg:col-span-{{ n }}` -- same interpolation mechanism
   (class="col-span-{{ n }}"), new class names, scoped to the same
   min-width breakpoint Tailwind's `lg:` prefix implied. */
.grid-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
@media (max-width: 1023px) {
  .grid-cols { grid-template-columns: 1fr; }
}
@media (min-width: 1024px) {
  .col-span-1 { grid-column: span 1; }
  .col-span-2 { grid-column: span 2; }
  .col-span-3 { grid-column: span 3; }
}
