/* ============================================================
   ClariAz theme tokens.

   Brand: orange on near-black with silver/grey supporting tones, per the
   ClariAz identity (shield mark, "Identify. Resolve. Monitor.").

   Dark is the default and carries the brand. Light is opt-in via
   data-theme="light" on <html>, set before first paint by the inline script
   in _Layout so the page never flashes the wrong theme. Every colour below
   has a counterpart in the light block — nothing in this stylesheet should
   hardcode a hex value, or it will break in one of the two themes.
   ============================================================ */

:root {
  color-scheme: dark;

  /* Typefaces are tokens, not repeated stacks: a headline face that is named in
     twenty places is a headline face that gets changed in nineteen. */
  --font-heading: 'Space Grotesk', 'Inter', sans-serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --bg: #08090c;
  --panel: #101216;
  --panel-rgb: 16, 18, 22;
  --panel-raised: #171a20;
  --border: #262a32;
  --border-strong: #363b45;
  --text: #f0f2f5;
  /* Secondary text sits at ~7:1 against the panel so 10-12px labels stay
     legible — a dimmer value fails at small sizes. */
  --muted: #a3aab6;
  /* Dimmer than --muted so a hint never reads as a filled value. */
  --placeholder: #6b7280;

  /* ClariAz orange is the single accent; silver and steel support it. */
  /* A deep burnt copper rather than the logo's bright orange: the same hue family, heavier
     and quieter, so the accent reads as considered rather than loud across a whole page. */
  --accent: #4fb8a8;
  --accent-2: #b8bfc9;
  --accent-3: #2f9e8f;
  --accent-text: #7fd6c8;
  --accent-2-text: #cfd5dd;
  --accent-3-text: #6fd1c0;
  --on-accent: #ffffff;
  /* The filled-button surface. Separate from --accent because a solid button has
     to carry legible label text, and the brand orange only clears 4.5:1 against
     one of the two themes' label colours — see the light block. */
  /* White on #b5541a is 4.9:1; hover darkens (6.3:1) rather than lightening, as in the
     light block, so the label never loses contrast under the pointer. */
  --accent-solid: #1b5c5f;
  --accent-solid-hover: #123638;
  /* Solid alert surface for the unread badge. One value for both themes: an
     alert that changes colour with the theme stops reading as the same signal,
     and white on this red clears 5.8:1 either way. */
  --alert-solid: #c02b22;
  --on-alert: #ffffff;

  /* Semantic status colours: -text is what sits on -bg. */
  --danger: #ff4d4f;
  --danger-text: #ff8a8c;
  --danger-bg: color-mix(in srgb, #ff4d4f 16%, transparent);
  --critical-text: #ff9295;
  --critical-bg: #5c0910;
  --warning: #f5a623;
  --warning-text: #f5b64a;
  --warning-bg: color-mix(in srgb, #f5a623 18%, transparent);
  /* The development banner is fixed in both themes, like the brand plate: graphite edged
     in the brand orange, read as an environment marker rather than an alarm. */
  --dev-banner-bg: #151920;
  --dev-banner-fg: #c9ced6;
  --dev-banner-accent: #d0631c;
  --dev-banner-accent-text: #eb8f55;
  /* The account avatar's silhouette, white on the brand-orange gradient in both themes. */
  --avatar-fg: #ffffff;
  /* Dashboard chart colours, each checked with the dataviz palette validator against
     --panel. The trend pair passes every categorical check (normal-vision ΔE 32). The
     level fills are a status scale — Low to Critical — and clear CVD separation, the
     normal-vision floor and 3:1; they always sit beside their names and counts. Actions
     are ordinal: one hue stepping darker towards done. */
  --chart-identified: #d0631c;
  --chart-closed: #3987e5;
  --chart-grid: #1c2028;
  --chart-baseline: #363b45;
  --level-low-fill: #1aa37f;
  --level-medium-fill: #e0ad1c;
  --level-high-fill: #ee6a2a;
  --level-critical-fill: #c91c64;
  --action-planned-fill: color-mix(in srgb, #3987e5 38%, #101216);
  --action-inprogress-fill: color-mix(in srgb, #3987e5 68%, #101216);
  --action-done-fill: #3987e5;
  --success: #14b8a6;
  --success-text: #3fe0cd;
  --success-bg: color-mix(in srgb, #14b8a6 16%, transparent);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 24px rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.55);
  --overlay: rgba(2, 2, 4, 0.7);

  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-lg: 18px;
}

:root[data-theme="light"] {
  color-scheme: light;

  --bg: #f5f6f8;
  --panel: #ffffff;
  --panel-rgb: 255, 255, 255;
  --panel-raised: #eef0f4;
  --border: #e0e3e9;
  --border-strong: #c9ced8;
  --text: #12151c;
  --muted: #5c6474;
  --placeholder: #98a0ae;

  --accent: #2f9e8f;
  --accent-2: #5c6474;
  --accent-3: #123638;
  /* Darkened again from the copper accent so text on white clears 4.5:1 with room to
     spare (7.8:1). */
  --accent-text: #1f6f65;
  --accent-2-text: #4a5160;
  --accent-3-text: #123638;
  --on-accent: #ffffff;
  /* White on the brand orange is 3.5:1 — below AA for a 14px label. The filled
     button therefore darkens here (5.2:1), and darkens further on hover rather
     than lightening: lightening an orange under white text loses contrast at
     the exact moment the pointer is on it. */
  --accent-solid: #123638;
  --accent-solid-hover: #1b4d50;
  --alert-solid: #c02b22;
  --on-alert: #ffffff;

  /* Semantic status colours: -text is what sits on -bg. */
  --danger: #d92d20;
  --danger-text: #b42318;
  --danger-bg: color-mix(in srgb, #d92d20 12%, transparent);
  --critical-text: #8f1a12;
  --critical-bg: color-mix(in srgb, #d92d20 20%, transparent);
  --warning: #d78100;
  --warning-text: #9a5c00;
  --warning-bg: color-mix(in srgb, #d78100 16%, transparent);
  --success: #0d9488;
  --success-text: #0b7a70;
  --success-bg: color-mix(in srgb, #0d9488 14%, transparent);

  /* Chart colours re-stepped for the white panel, validated there (see the dark block). */
  --chart-identified: #b4520f;
  --chart-closed: #2a78d6;
  --chart-grid: #eceef2;
  --chart-baseline: #c9ced8;
  --level-low-fill: #0d9488;
  --level-medium-fill: #cc9f12;
  --level-high-fill: #d6491c;
  --level-critical-fill: #a3123f;
  --action-planned-fill: color-mix(in srgb, #2a78d6 32%, #ffffff);
  --action-inprogress-fill: color-mix(in srgb, #2a78d6 64%, #ffffff);
  --action-done-fill: #2a78d6;

  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.08);
  --shadow-md: 0 4px 12px rgba(16, 24, 40, 0.08), 0 12px 28px rgba(16, 24, 40, 0.06);
  --shadow-lg: 0 12px 32px rgba(16, 24, 40, 0.14);
  --overlay: rgba(18, 21, 28, 0.45);

  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-lg: 18px;
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html, body {
  margin: 0;
  min-height: 100%;
}

body {
  font-family: var(--font-body);
  letter-spacing: -0.01em;
  background: var(--bg);
  color: var(--text);
  -webkit-text-size-adjust: 100%;
  overflow-x: hidden;
}

button, input, select, textarea {
  font: inherit;
  color: inherit;
}

/* The ambient layer is atmosphere, not content. It stays far enough back that
   text never renders over a moving gradient — the login screen can afford more
   of it than a dense data page (see .app-shell override below). */
.blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(110px);
  opacity: 0.14;
  will-change: transform;
}

@keyframes blob-drift-a {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(6vmax, 8vmax) scale(1.1); }
}

@keyframes blob-drift-b {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-8vmax, 6vmax) scale(1.08); }
}

@keyframes blob-drift-c {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(5vmax, -6vmax) scale(1.12); }
}

body:has(.app-shell) .blob {
  opacity: 0.16;
}

/* The login screen is the brand moment, so the ambience is pushed well
   forward here. Inside the app it stays subdued — dense tables and reports
   need the contrast more than they need atmosphere. */
body:has(.auth-shell) .blob {
  opacity: 0.3;
}

:root[data-theme="light"] body:has(.auth-shell) .blob {
  opacity: 0.16;
}

/* On a light background the same effects read as smudges rather than depth,
   so they are pulled back much further than in dark. */
:root[data-theme="light"] .blob {
  opacity: 0.09;
}

:root[data-theme="light"] body:has(.app-shell) .blob {
  opacity: 0.05;
}

@media (prefers-reduced-motion: reduce) {
  .blob { animation: none; }
}

/* ---------- Surfaces ---------- */

/* Opaque by design. Translucency over an animated backdrop is what made body
   text hard to read; content surfaces are now solid and the depth comes from
   the border and shadow instead. */
.glass-card {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

/* ---------- Page structure & typography ---------- */

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.page-title {
  font-family: var(--font-heading);
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: 0;
  color: var(--text);
}

.page-subtitle {
  font-size: 13px;
  color: var(--muted);
  margin: 5px 0 0;
}

/* The same voice one level down: the note under a card's own heading. Settings
   used .page-subtitle for this with two different inline bottom margins, so the
   page-header class was doing double duty at two different rhythms. */
.card-subtitle {
  font-size: 13px;
  color: var(--muted);
  margin: 0 0 16px;
}

.page-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

.section-title {
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 700;
  margin: 0 0 12px;
  color: var(--text);
}

/* Definition-style detail grid used on every Details screen. */
.detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px 24px;
}

.detail-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.detail-label {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.detail-value {
  font-size: 14px;
  color: var(--text);
  overflow-wrap: anywhere;
}

.card-pad {
  padding: 22px;
}

/* The standard gap between stacked cards on a page. It was written inline as
   style="margin-top:18px" on a dozen cards across six views. */
.card-gap {
  margin-top: 18px;
}

.stack-md {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.form-card {
  max-width: 680px;
  padding: 22px;
}

.form-error {
  color: var(--danger-text);
  font-size: 12.5px;
  margin-top: 4px;
  display: block;
}

.form-hint {
  font-size: 11.5px;
  color: var(--muted);
  margin-top: 4px;
  display: block;
}

.form-actions {
  display: flex;
  gap: 12px;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

.alert {
  padding: 12px 15px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 16px;
  border: 1px solid var(--border);
}

.alert-success {
  color: var(--success-text);
  background: var(--success-bg);
  border-color: var(--success-bg);
}

/* Login stacks the mark above the wordmark instead of beside it. *//* A slow scanning halo behind the shield — reads as "actively monitoring"
   without moving anything the eye needs to read. */@keyframes brand-scan {
  0% { transform: scale(0.62); opacity: 0; }
  22% { opacity: 0.55; }
  100% { transform: scale(1.85); opacity: 0; }
}

.btn-block {
  width: 100%;
  justify-content: center;
}

/* A single-button form sitting in a .row-actions / .page-actions line. Written
   inline as style="display:inline" on eight forms across five views. */
.inline-form {
  display: inline;
}

/* Bottom counterpart of .card-gap, for a block that introduces the card below
   it. The views carried 14, 16, 18 and 20px versions of the same idea. */
.card-gap-bottom {
  margin-bottom: 18px;
}

/* ---------- Static content pages ---------- */

.prose {
  max-width: 780px;
  font-size: 14.5px;
  line-height: 1.75;
  color: var(--text);
}

.prose h3 {
  font-family: var(--font-heading);
  font-size: 16px;
  font-weight: 700;
  margin: 28px 0 10px;
  color: var(--text);
}

.prose h3:first-child {
  margin-top: 0;
}

.prose p {
  margin: 0 0 14px;
  color: var(--muted);
}

.prose ul {
  margin: 0 0 16px;
  padding-left: 20px;
  color: var(--muted);
}

.prose li {
  margin-bottom: 7px;
}

.prose strong {
  color: var(--text);
  font-weight: 600;
}

/* Same measure as .prose. The FAQ used to cap its whole card at 820px inline
   while Privacy and Terms used a full-width card with 780px of text inside, so
   the three Help pages were laid out two different ways. */
.faq-item {
  max-width: 780px;
  border-bottom: 1px solid var(--border);
  padding: 18px 0;
}

.faq-item:first-of-type {
  padding-top: 0;
}

.faq-item:last-of-type {
  border-bottom: none;
  padding-bottom: 0;
}

.faq-question {
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  margin: 0 0 8px;
}

.faq-answer {
  font-size: 14px;
  line-height: 1.7;
  color: var(--muted);
  margin: 0;
}

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

.app {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  max-width: 680px;
  margin: 0 auto;
}

/* Wordmark: the "a" carries the brand orange, as in the ClariAz logo.
   These use element+class selectors so they outrank the generic
   `.auth-brand strong` / `.auth-brand span` rules those blocks still need
   for their non-brand headings. */
/* Text is authored already-uppercase rather than transformed: the page is
   lang="az", where text-transform turns an English "i" into "İ" and renders
   the tagline as "IDENTİFY. MONİTOR.". *//* The accent letter must inherit everything but colour. `.auth-brand span` is
   a generic rule for that block's subtitle and would otherwise turn this into
   a 12px block, shrinking the "A" and breaking the wordmark onto two lines. */.brand h1 {
  font-family: var(--font-heading);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
  line-height: 1.3;
  background: linear-gradient(90deg, var(--text), var(--text) 60%, var(--accent));
  -webkit-background-clip: text;
  background-clip: text;
}

.brand p {
  font-size: 12px;
  margin: 0;
  color: var(--muted);
}

.ai-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 6px 12px;
  border-radius: 999px;
  color: var(--text);
  background: color-mix(in srgb, var(--panel) 60%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 8%, transparent), 0 4px 14px color-mix(in srgb, var(--accent) 16%, transparent);
  white-space: nowrap;
}

.ai-pill-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 80%, transparent);
  animation: atom-pulse 1.6s ease-in-out infinite;
}

.report-header .ai-pill {
  margin-left: 0;
  margin-bottom: 10px;
}

/* ---------- Stepper ---------- */.step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  min-width: 56px;
}

/* ---------- Step panels & fields ---------- */

.wizard-card {
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.checkbox-item {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  background: color-mix(in srgb, var(--panel) 55%, transparent);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 7px 13px 7px 10px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.checkbox-item:has(input:checked) {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent-text);
}

.checkbox-item input {
  accent-color: var(--accent);
  width: 15px;
  height: 15px;
  cursor: pointer;
}

.form-section-label {
  font-family: var(--font-heading);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent-text);
  margin: 10px 0 -4px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

.form-section-label:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;   /* a long option text must not widen the grid column past the screen */
}

.field-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 14px;
}

/* Three across, for the risk manage row (owner / priority / reminder cadence). Collapses
   with .field-row at the same breakpoints — it is a modifier, not a second component. */
.field-row-3 {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
}

@media (max-width: 480px) {
  .field-row,
  .field-row-3 {
    grid-template-columns: 1fr;
  }
}

.field label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

/* The required marker. Standalone, not `.field label .req`: dialogs label their
   fields with .form-label rather than a .field wrapper, and each of those five
   asterisks carried its own inline colour — a different one from the thirty-one
   elsewhere in the app. */
.req {
  color: var(--accent-text);
}

.field-label-row {
  display: flex;
  align-items: center;
  gap: 7px;
}

.field-info-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 21px;
  height: 21px;
  border-radius: 50%;
  border: none;
  background: linear-gradient(135deg, var(--accent), var(--accent-3));
  color: var(--on-accent);
  font-size: 12px;
  font-weight: 800;
  font-style: italic;
  font-family: Georgia, 'Times New Roman', serif;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent);
  animation: field-info-pulse 2.4s ease-in-out infinite;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.field-info-btn:hover,
.field-info-btn:focus-visible,
.field-info-btn.active {
  outline: none;
  transform: scale(1.16);
  animation-play-state: paused;
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 30%, transparent);
}

@keyframes field-info-pulse {
  0%, 100% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent);
  }
  50% {
    box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent) 0%, transparent);
  }
}

@media (prefers-reduced-motion: reduce) {
  .field-info-btn {
    animation: none;
  }
}

.field-info-tip {
  position: fixed;
  z-index: 80;
  width: min(380px, calc(100vw - 32px));
  max-height: min(420px, calc(100vh - 32px));
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text);
  white-space: pre-line;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: translateY(4px);
  pointer-events: none;
  transition: opacity 0.12s ease, transform 0.12s ease;
}

.field-info-tip strong {
  color: var(--accent-text);
  font-weight: 700;
}

.field-info-tip.visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.field input,
.field textarea,
.field select {
  max-width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--panel) 55%, transparent);
  color: var(--text);
  font-size: 16px;
  padding: 11px 13px;
  outline: none;
  resize: vertical;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.field input:focus,
.field textarea:focus,
.field select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

/* Placeholders must read as a hint, not as a filled value — at --muted they
   are easily mistaken for real input. */
.field input::placeholder,
.field textarea::placeholder {
  color: var(--placeholder);
}

/* A field the user cannot change must not look like one they can. The company
   field on Users/Create and Users/Edit is fixed for an Admin, and rendered
   identically to the editable fields beside it, it read as a text box that
   silently refused to take input. */
.field input:disabled,
.field select:disabled,
.field textarea:disabled,
.form-input:disabled {
  background: color-mix(in srgb, var(--panel-raised) 70%, transparent);
  border-style: dashed;
  color: var(--muted);
  cursor: not-allowed;
}

/* ---------- Action bar ---------- */

.action-bar {
  position: sticky;
  bottom: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--bg) 80%, transparent);
  backdrop-filter: blur(14px);
  border-top: 1px solid color-mix(in srgb, var(--text) 6%, transparent);
}

.action-bar-spacer {
  flex: 1;
}

/* Shared button reset. These classes are used on both <button> and <a>, so the
   anchor defaults (underline, inline layout) must be cleared here or every
   link-styled button renders underlined. */
.btn-primary,
.btn-secondary,
.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
  white-space: nowrap;
  font-family: inherit;
}

.btn-primary:hover,
.btn-secondary:hover,
.btn-ghost:hover {
  text-decoration: none;
}

.btn-primary {
  position: relative;
  border: none;
  border-radius: var(--radius-sm);
  padding: 11px 18px;
  min-height: 42px;
  background: var(--accent-solid);
  color: var(--on-accent);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.1s ease;
}

.btn-primary:hover {
  background: var(--accent-solid-hover);
}

.btn-primary:active { transform: scale(0.99); }
/* A disabled control has to say so with the cursor too — "default" reads as
   "this is not a button", which is the wrong message for one that becomes
   live as soon as the form is complete. */
.btn-primary:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.btn-ghost {
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: 10px 16px;
  min-height: 42px;
  background: transparent;
  color: var(--text);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.btn-ghost:hover {
  background: color-mix(in srgb, var(--text) 6%, transparent);
  border-color: var(--muted);
}

.btn-secondary {
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: var(--radius-sm);
  padding: 10px 16px;
  min-height: 42px;
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent-text);
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease;
}

.btn-secondary:hover {
  background: color-mix(in srgb, var(--accent) 30%, transparent);
}

/* ---------- Loading view ---------- */

.loading-center {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 18px;
  min-height: 50vh;
  padding: 40px 20px;
}

.loading-glow {
  position: absolute;
  width: 260px;
  height: 260px;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent) 30%, transparent), transparent 70%);
  filter: blur(20px);
  animation: atom-pulse 2.4s ease-in-out infinite;
  z-index: -1;
}

.loading-label {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  min-height: 22px;
  margin: 0;
}

.loading-elapsed {
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--accent-text);
  margin: 0;
}

.loading-sub {
  font-size: 13px;
  color: var(--muted);
  max-width: 320px;
  margin: 0;
  line-height: 1.5;
}

.atom-loader {
  position: relative;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
}

.atom-loader.lg {
  width: 64px;
  height: 64px;
}

.atom-core {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 7px;
  height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 70%, transparent);
  animation: atom-pulse 1.4s ease-in-out infinite;
  z-index: 2;
}

.atom-loader.lg .atom-core {
  width: 13px;
  height: 13px;
  margin: -6.5px 0 0 -6.5px;
}

.atom-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
}

.atom-ring::before {
  content: '';
  position: absolute;
  top: -2px;
  left: 50%;
  width: 5px;
  height: 5px;
  margin-left: -2.5px;
  border-radius: 50%;
  background: var(--accent-2);
  box-shadow: 0 0 6px var(--accent-2);
}

.atom-loader.lg .atom-ring::before {
  width: 9px;
  height: 9px;
  margin-left: -4.5px;
  top: -4px;
  background: var(--accent-3);
  box-shadow: 0 0 10px var(--accent-3);
}

.atom-ring:nth-child(2) { animation: atom-spin-a 1s linear infinite; }
.atom-ring:nth-child(3) { animation: atom-spin-b 1.5s linear infinite reverse; }
.atom-ring:nth-child(4) { animation: atom-spin-c 2s linear infinite; }

@keyframes atom-spin-a {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes atom-spin-b {
  from { transform: rotate(120deg); }
  to { transform: rotate(480deg); }
}

@keyframes atom-spin-c {
  from { transform: rotate(240deg); }
  to { transform: rotate(600deg); }
}

@keyframes atom-pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.3); opacity: 0.75; }
}

/* ---------- Error view ---------- */

.error-box {
  max-width: 420px;
  margin: 8vh auto 0;
  text-align: center;
  padding: 32px 24px;
  border-color: color-mix(in srgb, var(--danger) 35%, var(--border));
}

.error-box-icon {
  font-size: 30px;
  margin-bottom: 10px;
  color: var(--critical-text);
}

.error-box h2 {
  margin: 0 0 8px;
  font-size: 18px;
}

.error-box p {
  margin: 0 0 22px;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.55;
}

.error-actions {
  display: flex;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* ---------- Report view ---------- */

.report-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}

.report-title {
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 700;
  margin: 0 0 8px;
  letter-spacing: -0.01em;
  background: linear-gradient(90deg, var(--text), var(--text) 55%, var(--accent));
  -webkit-background-clip: text;
  background-clip: text;
}

.badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.badge {
  font-size: 11.5px;
  font-weight: 600;
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  color: var(--accent-text);
  padding: 3px 10px;
  border-radius: 999px;
}

.risk-summary {
  padding: 16px;
  margin-bottom: 16px;
  font-size: 13.5px;
  line-height: 1.6;
}

.risk-summary-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent-text);
  margin-bottom: 6px;
}

.risk-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.risk-card {
  padding: 16px;
  border-left: 3px solid transparent;
}

.risk-card-critical {
  border-left-color: var(--danger);
  box-shadow: 0 0 0 1px var(--danger-bg), var(--shadow-md);
}

.risk-card-high { border-left-color: var(--danger); }
.risk-card-medium { border-left-color: var(--warning-text); }
.risk-card-low { border-left-color: var(--success); }

.risk-card-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}

.risk-id {
  font-size: 11px;
  color: var(--muted);
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}

.risk-card-title {
  font-size: 15.5px;
  font-weight: 700;
  margin-bottom: 8px;
  line-height: 1.4;
}

.risk-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  font-size: 12.5px;
  color: var(--muted);
  margin-bottom: 10px;
}

.risk-meta strong {
  color: var(--text);
  font-weight: 600;
}

.risk-desc {
  font-size: 13.5px;
  line-height: 1.6;
  margin-bottom: 10px;
}

.risk-residual {
  font-size: 12.5px;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.risk-residual .priority-badge {
  padding: 2px 8px;
  font-size: 10.5px;
}

.risk-mitigation {
  font-size: 13.5px;
  line-height: 1.6;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  border-left: 3px solid var(--accent);
  padding: 10px 12px;
  border-radius: 0 8px 8px 0;
}

.priority-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

.priority-critical {
  background: var(--critical-bg);
  color: var(--critical-text);
}

.priority-high {
  background: var(--danger-bg);
  color: var(--danger-text);
}

.priority-medium {
  background: var(--warning-bg);
  color: var(--warning-text);
}

.priority-low {
  background: var(--success-bg);
  color: var(--success-text);
}

/* ---------- Logs page ---------- */.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  /* Nine columns crushed into 720px wrapped every title onto three lines and broke the
     record numbers mid-token. Scrolling horizontally is the lesser cost: a row you can
     read beats a row that fits. */
  min-width: 960px;
}

.data-table th {
  text-align: left;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
  padding: 13px 16px;
  background: var(--panel-raised);
  border-bottom: 1px solid var(--border-strong);
  white-space: nowrap;
}

.data-table td {
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  line-height: 1.5;
}

.data-table tr:last-child td {
  border-bottom: none;
}

.data-table tbody tr:hover td {
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}

.data-table .row-actions {
  display: flex;
  gap: 8px;
  white-space: nowrap;
}

.data-table .row-actions a,
.data-table .row-actions button {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--accent-text);
  background: none;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  padding: 5px 10px;
  text-decoration: none;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.data-table .row-actions a:hover,
.data-table .row-actions button:hover {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}

.logs-ip {
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  white-space: nowrap;
}

.logs-date {
  white-space: nowrap;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.status-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
}

.status-ok {
  background: var(--success-bg);
  color: var(--success-text);
}

.status-fail {
  background: var(--danger-bg);
  color: var(--danger-text);
}

.status-scope {
  background: var(--warning-bg);
  color: var(--warning-text);
}

/* ---------- Report stats bar ---------- */

.report-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}

.stat-chip {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--panel) 60%, transparent);
  border: 1px solid var(--border);
}

.stat-count {
  font-size: 18px;
  font-weight: 800;
}

.stat-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}

.stat-total {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
}

.stat-total .stat-count {
  background: linear-gradient(90deg, var(--text), var(--accent));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.stat-critical .stat-count { color: var(--critical-text); }
.stat-high .stat-count { color: var(--danger-text); }
.stat-medium .stat-count { color: var(--warning-text); }
.stat-low .stat-count { color: var(--success-text); }

/* ---------- Risk score badge & owner ---------- */

.risk-score-badge {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  background: color-mix(in srgb, var(--text) 8%, transparent);
  color: var(--muted);
  border: 1px solid var(--border);
}

.risk-owner {
  font-size: 13px;
  color: var(--text);
  margin-bottom: 10px;
}

.risk-owner strong {
  color: var(--muted);
  font-weight: 600;
}

/* ---------- Risk matrix heatmap ---------- */

.risk-matrix-card {
  padding: 22px;
  margin-bottom: 16px;
}

.risk-matrix {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  /* Fixed row height rather than aspect-ratio: in a wide container a square
     cell stretches the grid to screen height. A board-ready matrix must read
     at a glance, so the rows stay a constant, compact size. */
  grid-template-rows: repeat(5, 64px);
  gap: 4px;
}

.rm-cell {
  border-radius: 6px;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 2px;
  padding: 4px;
  overflow: hidden;
}

/* Axis-labelled matrix layout: impact runs up the Y axis, likelihood along the X. */
.risk-matrix-layout {
  display: grid;
  grid-template-columns: auto auto 1fr;
  grid-template-rows: 1fr auto auto;
  gap: 6px;
  align-items: center;
}

.rm-axis-y {
  grid-column: 1;
  grid-row: 1;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  text-align: center;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}

.rm-y-labels {
  grid-column: 2;
  grid-row: 1;
  display: grid;
  grid-template-rows: repeat(5, 1fr);
  gap: 4px;
  height: 100%;
}

.rm-y-labels span {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  font-size: 10px;
  color: var(--muted);
  white-space: nowrap;
  padding-right: 4px;
}

.risk-matrix-layout .risk-matrix {
  grid-column: 3;
  grid-row: 1;
}

.rm-x-labels {
  grid-column: 3;
  grid-row: 2;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 4px;
}

.rm-x-labels span {
  text-align: center;
  font-size: 10px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rm-axis-x {
  grid-column: 3;
  grid-row: 3;
  text-align: center;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}

@media (max-width: 640px) {
  .rm-y-labels span,
  .rm-x-labels span {
    font-size: 8.5px;
  }
}

/* Explicit, increasing intensity so the grid reads as a heatmap at a glance
   rather than four similarly-weighted tints. */
.rm-band-low { background: color-mix(in srgb, var(--success) 22%, transparent); }
.rm-band-medium { background: color-mix(in srgb, var(--warning) 30%, transparent); }
.rm-band-high { background: color-mix(in srgb, var(--danger) 32%, transparent); }
.rm-band-critical { background: color-mix(in srgb, var(--danger) 58%, transparent); }

.rm-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 18px;
  padding: 0 4px;
  border-radius: 5px;
  font-size: 9.5px;
  font-weight: 800;
  line-height: 1;
  cursor: default;
}

@media (max-width: 480px) {
  .risk-matrix { grid-template-rows: repeat(5, 44px); }
  .rm-chip { min-width: 18px; height: 15px; font-size: 8px; }
}

/* ---------- Filter bar ---------- */

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  padding: 14px 16px;
  margin-bottom: 16px;
}

.filter-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 150px;
  flex: 1 1 150px;
}

.filter-field.filter-search {
  flex: 2 1 220px;
}

.filter-field label {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}

/* min-height, because a native select and a text input with identical padding
   still resolve to different heights — the register's filter bar sat 2px out of
   line with the candidate lists' sort bar for that reason alone. */
.filter-field select,
.filter-field input {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--panel) 55%, transparent);
  color: var(--text);
  font-size: 13.5px;
  min-height: 36px;
  padding: 8px 10px;
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.filter-field select:focus,
.filter-field input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

.filter-actions {
  display: flex;
  gap: 8px;
  flex: 0 0 auto;
}

/* A single ordering choice, on the candidate lists that have no filters. Same box and same
   .filter-field/.filter-actions children as the filter bar — only the class differs, so
   site.js's mobile collapse (which keys off .filter-bar) leaves it alone. Hiding a lone sort
   select behind a toggle labelled "Filtrlə" would be worse than showing it. The field does
   not stretch: one control across a 1400px register reads as a broken layout. */
.sort-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  padding: 14px 16px;
  margin-bottom: 16px;
}

.sort-bar .filter-field {
  flex: 0 1 220px;
}

/* A control strip is one row of controls, so its button matches its selects.
   The bars' buttons kept the 42px page-button height next to 36px fields, which
   left the Apply button standing a clear 6px proud of everything beside it. */
.filter-bar .btn-primary,
.filter-bar .btn-secondary,
.filter-bar .btn-ghost,
.sort-bar .btn-primary,
.sort-bar .btn-secondary,
.sort-bar .btn-ghost {
  min-height: 36px;
  padding: 7px 14px;
  font-size: 13px;
}

/* One default size, matching the 16px an icon already takes inside a button —
   the sidebar's 17px meant the same glyph was a pixel larger in the nav than in
   the button beside it. Components that need a bigger glyph step up in even
   sizes (18 / 20 / 22 / 28 / 36); the odd 15px, 17px and 19px one-offs that had
   accumulated were snapped onto that. */
.nav-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

@keyframes user-menu-in {
  from {
    opacity: 0;
    transform: translateY(-6px) scale(0.96);
  }
  to {
    opacity: 1;
    transform: none;
  }
}


/* ---------- User menu ---------- *//* ---------- Tabs ---------- */

.tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
}

/* ---------- Decision / overdue badges ---------- */

.decision-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
}

.decision-pending {
  background: var(--warning-bg);
  color: var(--warning-text);
}

.decision-accepted {
  background: var(--success-bg);
  color: var(--success-text);
}

.decision-rejected {
  background: var(--danger-bg);
  color: var(--danger-text);
}

.overdue-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
  background: var(--danger-bg);
  color: var(--danger-text);
}

@keyframes nav-progress-advance {
  0% { width: 0; }
  12% { width: 32%; }
  35% { width: 58%; }
  70% { width: 78%; }
  100% { width: 92%; }
}


/* ---------- Accept / Reject buttons ----------
   Same box as .btn-primary / .btn-secondary / .btn-ghost — only the surface
   colour differs. They used to carry their own padding, font size, weight and
   typeface, which made the two most consequential buttons in the product (accept
   or reject a proposed risk) 33px tall next to 42px neighbours, and the only
   buttons in the app set in the heading face. */

.btn-accept,
.btn-reject {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 16px;
  min-height: 42px;
  border: none;
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: filter 0.15s ease;
}

.btn-accept {
  background: var(--success-bg);
  color: var(--success-text);
}

.btn-reject {
  background: var(--danger-bg);
  color: var(--danger-text);
}

/* Both tints are translucent over a dark or light panel, so "more of the tint"
   is the hover cue that works in either theme — brightness() darkened the button
   in dark mode, which reads as pressed rather than hovered. */
.btn-accept:hover { background: color-mix(in srgb, var(--success) 28%, transparent); }
.btn-reject:hover { background: color-mix(in srgb, var(--danger) 28%, transparent); }

/* The small modifier has to shrink the box, not just the padding: every full
   size button carries min-height 42px, so .btn-sm on a ghost stayed 42px tall
   while .btn-sm on an accept button (which had no min-height) became 28px —
   the same modifier producing two different buttons. */
.btn-sm {
  min-height: 32px;
  padding: 5px 12px;
  font-size: 12px;
}

/* ---------- Icon-only filter button ---------- */

.btn-icon-only {
  padding: 8px 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.btn-icon-only .nav-icon {
  width: 16px;
  height: 16px;
}

/* ---------- Risk card actions ---------- */

.risk-card-actions {
  display: flex;
  gap: 10px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}

.risk-decision-note {
  margin-top: 8px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  background: var(--panel-raised);
  font-size: 13px;
  color: var(--muted);
}

/* ---------- Table actions column ---------- */

.table-actions {
  display: flex;
  gap: 6px;
  white-space: nowrap;
}

.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* ---------- Modal ----------
   Hidden by default and opened either by adding .open or by an inline
   display:flex — the views do the latter. There used to be a second
   .modal-overlay block earlier in this file whose display:none this one
   overrode, which left every dialog relying on an inline style="display:none"
   in the markup to stay shut: a view that forgot it shipped an always-open
   dialog. The scrim is --overlay so the light theme gets its own, rather than
   a hardcoded black that only suits dark. */

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--overlay);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: modal-fade-in 0.2s ease;
}

.modal-overlay.open {
  display: flex;
}

@keyframes modal-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes modal-slide-up {
  from { opacity: 0; transform: translateY(16px) scale(0.97); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.modal-card {
  width: 100%;
  max-width: 480px;
  max-height: 90vh;
  overflow-y: auto;
  margin: 16px;
  padding: 0;
  border-radius: var(--radius-lg);
  background: var(--panel);
  border: 1px solid var(--border);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.2), 0 8px 24px rgba(0, 0, 0, 0.1);
  animation: modal-slide-up 0.25s ease;
  overflow: hidden;
}

.modal-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 22px 28px 0;
}

.modal-header-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: var(--danger-bg);
  color: var(--danger-text);
  flex-shrink: 0;
}

/* Tone modifiers, so a dialog's icon tile is not a colour pair pasted inline
   into each view. Accent text rather than raw --accent: at 11-13px on the light
   theme's tint the brand orange is below 4.5:1. */
.modal-header-icon-success {
  background: var(--success-bg);
  color: var(--success-text);
}

.modal-header-icon-accent {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent-text);
}

.modal-header-icon svg {
  width: 20px;
  height: 20px;
}

.modal-header-text h3 {
  font-family: var(--font-heading);
  font-size: 17px;
  font-weight: 700;
  margin: 0;
  color: var(--text);
}

.modal-header-text p {
  font-size: 13px;
  color: var(--muted);
  margin: 2px 0 0;
}

.modal-body {
  padding: 20px 28px;
}

.modal-body .form-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin: 0 0 8px;
  display: block;
  letter-spacing: 0.01em;
}

.modal-body .form-hint {
  font-size: 12px;
  color: var(--muted);
  margin-top: 6px;
}

/* The same box as `.field input` — they are the same control, and the app had
   been carrying two: 12px/14px padding at 14px on a solid --bg with a 1.5px
   border here, against 11px/13px at 16px on a translucent panel with a 1px
   border there, so a dialog's fields were visibly a different shape and size
   from a page's. 16px is not cosmetic: iOS zooms the viewport on focusing an
   input below 16px, which the 14px value did on every modal. */
.form-input {
  display: block;
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--panel) 55%, transparent);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
  box-sizing: border-box;
}

.form-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

.form-input::placeholder {
  color: var(--placeholder);
}

textarea.form-input {
  resize: vertical;
  min-height: 96px;
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 0 28px 22px;
}

.modal-footer .btn-ghost {
  padding: 9px 20px;
}

.modal-footer .btn-reject {
  padding: 9px 20px;
}

.modal-risk-title {
  font-size: 13px;
  color: var(--muted);
  margin: 2px 0 0;
  font-style: italic;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 320px;
}

.modal-confirm-text {
  font-size: 14px;
  color: var(--text);
  line-height: 1.6;
  margin: 0;
}

/* ---------- Alert danger ---------- */

.alert-danger {
  padding: 12px 18px;
  border-radius: var(--radius-sm);
  background: var(--danger-bg);
  color: var(--danger-text);
  font-size: 13px;
  font-weight: 500;
  margin-bottom: 16px;
}

/* ---------- Text muted helper ---------- */

.text-muted {
  color: var(--muted);
}

/* ---------- Risk lifecycle ---------- */

.status-inprogress {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  /* --accent-text, not --accent: the badge is 11px, and the raw brand orange is
     only 3.5:1 on the light theme's near-white tint. */
  color: var(--accent-text);
}

.status-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.progress-bar {
  position: relative;
  width: 90px;
  height: 6px;
  border-radius: 999px;
  background: var(--border);
  overflow: hidden;
}

.progress-bar span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-3));
  transition: width 0.2s ease;
}

.checkbox-inline {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}

.checkbox-inline input {
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
  cursor: pointer;
}

.filter-check {
  display: flex;
  align-items: flex-end;
  padding-bottom: 2px;
}

.form-range {
  width: 100%;
  accent-color: var(--accent);
  cursor: pointer;
}

/* ---------- Attachments ---------- */

.attachment-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
}

.attachment-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel-raised);
}

.attachment-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  flex-shrink: 0;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
}

.attachment-icon svg {
  width: 16px;
  height: 16px;
}

.attachment-meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}

.attachment-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.attachment-name:hover {
  color: var(--accent);
  text-decoration: underline;
}

.attachment-sub {
  font-size: 11.5px;
  color: var(--muted);
}

.upload-row {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

.upload-row input[type="file"] {
  flex: 1;
  min-width: 200px;
  font-size: 13px;
  padding: 8px 10px;
  cursor: pointer;
}

/* The browser's own "Choose File" button is a grey OS control sitting inside an
   otherwise themed field — the one piece of unstyled chrome left on the risk
   page. It is the same shape as .btn-ghost so the row reads as one control. */
.upload-row input[type="file"]::file-selector-button {
  margin-right: 12px;
  padding: 6px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--panel-raised);
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.upload-row input[type="file"]:hover::file-selector-button {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--panel-raised));
}

/* ---------- Notes ---------- */

.note-form {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.note-form textarea {
  flex: 1;
  resize: vertical;
}

.note-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 16px;
}

.note-item {
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: var(--panel-raised);
  border: 1px solid var(--border);
}

.note-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}

.note-author {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--text);
}

.note-date {
  font-size: 11.5px;
  color: var(--muted);
}

.note-delete {
  border: none;
  background: none;
  color: var(--muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}

.note-delete:hover {
  color: var(--danger-text);
}

.note-body {
  font-size: 13.5px;
  color: var(--text);
  line-height: 1.6;
  white-space: pre-wrap;
}

@media (max-width: 640px) {
  .note-form,
  .upload-row {
    flex-direction: column;
    align-items: stretch;
  }
}


@keyframes chart-rise { from { transform: scaleY(0); } }
@keyframes chart-grow { from { transform: scaleX(0); } }
@keyframes donut-in { from { opacity: 0; transform: rotate(-90deg) scale(0.9); } }

/* Heatmap: the risk matrix's own band tints, a count in each occupied cell. */
.heatmap {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 6px 10px;
}


.card-empty {
  flex: 1;
  display: grid;
  place-items: center;
  min-height: 92px;
  margin: 0;
  padding: 12px 8px;
  text-align: center;
  font-size: 13px;
  color: var(--muted);
}

.text-danger {
  color: var(--danger-text);
}

/* ---------- Analysis in progress ---------- */

.processing-box {
  text-align: center;
  padding: 40px 28px;
}

.processing-box h3 {
  font-family: var(--font-heading);
  font-size: 17px;
  font-weight: 700;
  margin: 18px 0 8px;
  color: var(--text);
}

.processing-box p {
  margin: 0 auto;
  max-width: 460px;
}

.processing-box .form-hint {
  margin-top: 14px;
}

.processing-spinner {
  width: 40px;
  height: 40px;
  margin: 0 auto;
  border-radius: 50%;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  animation: processing-spin 0.9s linear infinite;
}

@keyframes processing-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .processing-spinner { animation-duration: 3s; }
}

/* ---------- Notification list ---------- */

.notification-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.notification-form {
  display: block;
}

.notification-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--panel);
  cursor: pointer;
  text-align: left;
  font: inherit;
  transition: border-color 0.15s ease;
}

.notification-row:hover {
  border-color: var(--accent);
}

.notification-row.is-unread {
  background: color-mix(in srgb, var(--accent) 6%, var(--panel));
}

.notification-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-top: 6px;
  flex-shrink: 0;
  background: transparent;
}

.notification-row.is-unread .notification-dot {
  background: var(--accent);
}

.notification-content {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
  min-width: 0;
}

.notification-title {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text);
}

.notification-body {
  font-size: 12.5px;
  color: var(--muted);
  line-height: 1.5;
}

.notification-time {
  font-size: 11.5px;
  color: var(--muted);
  white-space: nowrap;
  flex-shrink: 0;
}

@media (max-width: 640px) {

  .notification-time {
    display: none;
  }
}

/* ---------- Responsive ---------- */


/* Below this the sidebar stops holding a column and becomes an overlay drawer.
   The drawer has its own state (data-drawer) rather than reusing the desktop
   collapse flag — they mean opposite things, so sharing one attribute made a
   desktop-collapsed sidebar open the mobile drawer by default. */
@media (max-width: 900px) {

  .page-head {
    margin-bottom: 16px;
  }
}

@media (max-width: 640px) {
  .page-title {
    font-size: 18px;
  }

  /* The AI pill's label is decorative at this width — the dot alone still
     signals "AI-powered" without crowding the two icon buttons beside it. */
  .ai-pill {
    padding: 0;
    width: 32px;
    height: 32px;
    justify-content: center;
    border-radius: 50%;
  }  .page-head {
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .page-actions {
    flex-wrap: wrap;
  }

  .page-actions .btn-primary,
  .page-actions .btn-secondary,
  .page-actions .btn-ghost,
  .page-actions form {
    flex: 1 1 auto;
  }

  .card-pad,
  .form-card {
    padding: 18px;
  }

  .field-row,
  .field-row-3 {
    grid-template-columns: 1fr;
  }

  .form-actions {
    flex-direction: column;
  }

  .form-actions .btn-primary,
  .form-actions .btn-ghost,
  .form-actions .btn-secondary {
    width: 100%;
  }

  .filter-bar,
  .sort-bar {
    padding: 14px;
  }

  .filter-field,
  .filter-field.filter-search {
    flex: 1 1 100%;
    min-width: 0;
  }

  .filter-actions {
    width: 100%;
  }

  .filter-actions .btn-primary,
  .filter-actions .btn-ghost {
    flex: 1;
  }

  .detail-grid {
    grid-template-columns: 1fr;
    gap: 14px;
  }
  .report-header {
    flex-direction: column;
    align-items: stretch;
  }

  .report-header .page-actions,
  .report-header > div:last-child {
    width: 100%;
  }

  /* A 5-column matrix with full-word axis labels cannot be squeezed into 375px
     — it scrolls horizontally instead of truncating into illegibility. The
     matrix keeps its natural size; the card just clips and scrolls it. */
  .risk-matrix-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .risk-matrix-layout {
    width: max-content;
    min-width: 100%;
  }

  .rm-y-labels span {
    font-size: 9px;
  }

  .risk-card-header {
    gap: 6px;
  }

  .risk-card-title {
    font-size: 14px;
  }
}

@media (max-width: 480px) {

  .glass-card.card-pad,
  .glass-card.form-card {
    padding: 16px;
  }

  .stat-chip {
    flex: 1 1 calc(50% - 8px);
  }

  .report-stats {
    gap: 8px;
  }
}

/* In mobile drawer mode the sidebar always shows as expanded — revert icon-only state. */


/* ── Pagination ───────────────────────────────────── */
.pagination-bar {
  display: flex;
  align-items: center;
  gap: 4px;
  justify-content: center;
  flex-wrap: wrap;
  padding: 18px 0 6px;
}
.page-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  height: 34px;
  padding: 0 8px;
  border-radius: 7px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  background: var(--panel-raised);
  border: 1px solid var(--border);
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
  cursor: pointer;
}
.page-btn:hover { background: var(--accent-solid); color: var(--on-accent); border-color: var(--accent-solid); }
.page-btn-active {
  background: var(--accent-solid);
  color: var(--on-accent);
  border-color: var(--accent-solid);
  pointer-events: none;
}
.page-btn-disabled {
  opacity: 0.35;
  pointer-events: none;
}
.page-ellipsis {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  color: var(--muted);
  font-size: 13px;
}
.page-info {
  margin-left: 10px;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
}


/* ── Risk category / subcategory ─────────────────────────────
   A colored dot + plain text, stacked. Every register row already carries level,
   priority and status pills; rendering the taxonomy as two more pills made rows
   unreadable, so the category is text with a hue dot and the subcategory a muted
   second line. Ten distinguishable hues so a register still scans by category at a
   glance. Slugs come from RiskTaxonomy.Slug (ToLowerInvariant — a culture-sensitive
   lower() would emit a dotless 'ı' under Azerbaijani and match none of these rules). */
.category-stack {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  min-width: 0;
}

.category-name {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}

.category-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--muted);
  flex: none;
}

/* The cat-* palette below sets color (+ a pill tint the dot doesn't want);
   the dot takes only the hue. */
.category-dot[class*="cat-"] { background: currentColor; }

.subcategory-name {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--muted);
  padding-left: 15px; /* clears the dot: aligns under the category text */
}

/* Inside registers the taxonomy pair is bounded and allowed to wrap. It used to
   be nowrap on both lines to keep row heights even, but the longest names
   ("Texnologiya və Kibertəhlükəsizlik") held a 245px single line, which pushed
   the register's action column off the right edge of a 1440px screen — the user
   had to scroll the table sideways to reach "Ətraflı" on the most common
   desktop width. A ragged row is cheaper than an unreachable action. */
.data-table .category-stack { max-width: 200px; }
.data-table .category-name,
.data-table .subcategory-name { white-space: normal; }

/* Legacy pill — still the right shape for the guided-flow chips
   (RiskTypes) and role chips (Users). */
.category-badge {
  font-size: 11.5px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  white-space: nowrap;
  color: var(--muted);
  background: color-mix(in srgb, var(--muted) 14%, transparent);
  border: 1px solid transparent;
}

.category-badge[class*="cat-"] { border-color: transparent; }

.cat-strategic                    { color: #8b7ff5; background: color-mix(in srgb, #8b7ff5 15%, transparent); }
.cat-operational                  { color: #4fa3d9; background: color-mix(in srgb, #4fa3d9 15%, transparent); }
.cat-financial                    { color: #3fb98f; background: color-mix(in srgb, #3fb98f 15%, transparent); }
.cat-compliance-regulatory-legal  { color: #d99b3f; background: color-mix(in srgb, #d99b3f 15%, transparent); }
.cat-technology-cybersecurity     { color: #e0605f; background: color-mix(in srgb, #e0605f 15%, transparent); }
.cat-health-safety                { color: #e07f4f; background: color-mix(in srgb, #e07f4f 15%, transparent); }
.cat-reputational                 { color: #d071b8; background: color-mix(in srgb, #d071b8 15%, transparent); }
.cat-environmental                { color: #5fb85f; background: color-mix(in srgb, #5fb85f 15%, transparent); }
.cat-human-resources-people       { color: #5f8fd9; background: color-mix(in srgb, #5f8fd9 15%, transparent); }
.cat-supply-chain                 { color: #b0894f; background: color-mix(in srgb, #b0894f 15%, transparent); }
.cat-project-change { color: #6fb3c9; background: color-mix(in srgb, #6fb3c9 15%, transparent); }
.cat-geopolitical-country { color: #c47fd0; background: color-mix(in srgb, #c47fd0 15%, transparent); }
.cat-customer-market { color: #4fb8a8; background: color-mix(in srgb, #4fb8a8 15%, transparent); }
.cat-physical-security-assets { color: #cf7a6b; background: color-mix(in srgb, #cf7a6b 15%, transparent); }
.cat-governance-ethics { color: #9a9fd6; background: color-mix(in srgb, #9a9fd6 15%, transparent); }

/* Light theme needs darker text on the same tints to stay legible. */
:root[data-theme="light"] .cat-strategic                   { color: #5b4fd0; }
:root[data-theme="light"] .cat-operational                 { color: #2a6f9e; }
:root[data-theme="light"] .cat-financial                   { color: #1f8060; }
:root[data-theme="light"] .cat-compliance-regulatory-legal { color: #9a6a15; }
:root[data-theme="light"] .cat-technology-cybersecurity    { color: #b03432; }
:root[data-theme="light"] .cat-health-safety               { color: #a85423; }
:root[data-theme="light"] .cat-reputational                { color: #9c4384; }
:root[data-theme="light"] .cat-environmental               { color: #358035; }
:root[data-theme="light"] .cat-human-resources-people      { color: #35619e; }
:root[data-theme="light"] .cat-supply-chain                { color: #7d5c26; }
:root[data-theme="light"] .cat-project-change { color: #2f7f96; }
:root[data-theme="light"] .cat-geopolitical-country { color: #8f4c9c; }
:root[data-theme="light"] .cat-customer-market { color: #1f7f72; }
:root[data-theme="light"] .cat-physical-security-assets { color: #a04c3d; }
:root[data-theme="light"] .cat-governance-ethics { color: #5b60a8; }

/* ── Risk-type guided flow ──────────────────────────────────── */
.rt-step { margin-bottom: 26px; }

/* .form-section-label carries margin-bottom:-4px, which is calibrated for the wizard card
   where a flex gap sits underneath it. Here the label is followed directly by a grid, so
   that negative margin pulls the cards up over the heading. Neutralise it locally rather
   than changing the shared rule, which the intake form still depends on. */
.rt-step .form-section-label {
  margin: 0 0 14px;
  padding-top: 0;
  border-top: none;
}

.rt-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}

.rt-grid-sub { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }

.rt-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
  padding: 16px 18px;
  text-align: left;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  color: var(--text);
  font-family: inherit;
  transition: border-color 0.15s ease, transform 0.12s ease, background 0.15s ease;
}

.rt-card:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
  background: color-mix(in srgb, var(--accent) 6%, var(--panel));
}

.rt-card-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.85;
}

.rt-card-name { font-size: 14px; font-weight: 600; line-height: 1.35; color: var(--text); }
.rt-card-count { font-size: 11px; color: var(--muted); }

/* The category tint colours the dot only, so the card text stays at full contrast. */
.rt-card[class*="cat-"] .rt-card-dot { background: currentColor; }
.rt-card.cat-strategic                   { color: #8b7ff5; }
.rt-card.cat-operational                 { color: #4fa3d9; }
.rt-card.cat-financial                   { color: #3fb98f; }
.rt-card.cat-compliance-regulatory-legal { color: #d99b3f; }
.rt-card.cat-technology-cybersecurity    { color: #e0605f; }
.rt-card.cat-health-safety               { color: #e07f4f; }
.rt-card.cat-reputational                { color: #d071b8; }
.rt-card.cat-environmental               { color: #5fb85f; }
.rt-card.cat-human-resources-people      { color: #5f8fd9; }
.rt-card.cat-supply-chain                { color: #b0894f; }
.rt-card.cat-project-change { color: #6fb3c9; }
.rt-card.cat-geopolitical-country { color: #c47fd0; }
.rt-card.cat-customer-market { color: #4fb8a8; }
.rt-card.cat-physical-security-assets { color: #cf7a6b; }
.rt-card.cat-governance-ethics { color: #9a9fd6; }

.rt-card-sub {
  flex-direction: row;
  align-items: center;
  font-size: 13.5px;
  font-weight: 500;
  padding: 13px 15px;
}

.rt-card-all {
  border-style: dashed;
  color: var(--muted);
  font-weight: 600;
}

.rt-chosen {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.rt-chosen-label {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.rt-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 34px 22px;
}

@media (max-width: 600px) {
  .rt-grid, .rt-grid-sub { grid-template-columns: 1fr; }
}
.lib-link-btn {
  color: var(--muted);
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
  text-decoration: none;
}

.lib-link-btn:hover { color: var(--accent-text); }

/* ── Grouped sidebar navigation ─────────────────────────────── */
.sidebar-group { display: flex; flex-direction: column; }

.sidebar-group + .sidebar-group { margin-top: 4px; }

/* A hairline between sections does the separating work that eleven flat rows could not. */
.sidebar-group:not(.sidebar-group-plain) + .sidebar-group:not(.sidebar-group-plain) {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
}

:root[data-sidebar="collapsed"] .sidebar-group:not(.sidebar-group-plain) + .sidebar-group:not(.sidebar-group-plain) {
  margin-top: 8px;
  padding-top: 8px;
}


/* ── Risk library: accordion ─────────────────────────────────
   Fifteen categories holding 155 subcategories cannot all be open at once and still be
   readable. Rows start closed; the count is what you scan, and search opens only the
   matches. */
.lib-toolbar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}

.lib-search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 260px;
  min-width: 0;
}

.lib-search .nav-icon {
  position: absolute;
  left: 12px;
  width: 16px;
  height: 16px;
  color: var(--muted);
  pointer-events: none;
}

.lib-search input {
  width: 100%;
  min-height: 36px;
  padding: 8px 10px 8px 36px;
  font-size: 13.5px;
  color: var(--text);
  background: color-mix(in srgb, var(--panel) 55%, transparent);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.lib-search input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}

.lib-stats {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  color: var(--muted);
  white-space: nowrap;
}

.lib-stats strong { color: var(--text); font-weight: 700; }
.lib-stat-sep { opacity: 0.5; }

.lib-toolbar-actions { display: flex; gap: 6px; margin-left: auto; }

.lib-accordion { display: flex; flex-direction: column; gap: 8px; }

.lib-row {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: border-color 0.15s ease;
}

.lib-row:hover { border-color: var(--border-strong); }
.lib-row.is-open { border-color: color-mix(in srgb, var(--accent) 40%, var(--border)); }
.lib-row.is-inactive { opacity: 0.6; }

.lib-row-head {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 15px 18px;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
}

.lib-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

.lib-row-titles { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.lib-row-name {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--text);
}

/* The canonical key matters to an administrator but must not compete with the name. */
.lib-row-key {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--muted);
  opacity: 0.75;
}

.lib-row-meta {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.lib-flag {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 3px 8px;
  border-radius: 20px;
  color: var(--muted);
  background: color-mix(in srgb, var(--muted) 14%, transparent);
  cursor: help;
}

.lib-flag-off {
  color: var(--danger-text);
  background: color-mix(in srgb, var(--danger-text) 14%, transparent);
}

.lib-row-count {
  min-width: 26px;
  padding: 3px 8px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 700;
  text-align: center;
  color: var(--text);
  background: color-mix(in srgb, var(--text) 9%, transparent);
}

.lib-chevron {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--muted);
  transition: transform 0.18s ease;
}

.lib-row.is-open .lib-chevron { transform: rotate(180deg); }

.lib-row-body { display: none; padding: 0 18px 16px; }
.lib-row.is-open .lib-row-body { display: block; }

.lib-row-tools {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  padding-bottom: 12px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
}

.lib-row-tools a:last-child { margin-left: auto; }

.lib-sub-table { width: 100%; border-collapse: collapse; }

.lib-sub-table tr { border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent); }
.lib-sub-table tr:last-child { border-bottom: none; }
.lib-sub-table tr.is-inactive { opacity: 0.5; }

.lib-sub-table td { padding: 9px 0; font-size: 13px; vertical-align: middle; }

.lib-sub-name { color: var(--text); }

.lib-sub-key {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  color: var(--muted);
  width: 40%;
}

.lib-sub-tools {
  text-align: right;
  white-space: nowrap;
  font-size: 11.5px;
}

.lib-sub-tools a, .lib-link-btn {
  color: var(--muted);
  background: none;
  border: none;
  padding: 0;
  margin-left: 12px;
  font: inherit;
  cursor: pointer;
  text-decoration: none;
}

.lib-sub-tools a:hover, .lib-link-btn:hover { color: var(--accent-text); }

.lib-sub-empty { margin: 12px 0 0; font-size: 13px; }

.lib-no-results {
  margin-top: 18px;
  text-align: center;
  color: var(--muted);
  font-size: 13.5px;
}

@media (max-width: 640px) {
  .lib-toolbar-actions { margin-left: 0; }
  .lib-sub-key { display: none; }
}

/* ── Empty states ───────────────────────────────────────────── */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 56px 24px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.empty-state-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  margin-bottom: 16px;
  border-radius: 50%;
  color: var(--muted);
  background: color-mix(in srgb, var(--muted) 11%, transparent);
}

.empty-state-icon .nav-icon { width: 22px; height: 22px; }

.empty-state-title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}

.empty-state-desc {
  margin: 7px 0 0;
  max-width: 420px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--muted);
}

.empty-state-action { margin-top: 20px; }

/* ── Tables: one container, sticky head, readable rhythm ─────
   Two patterns had grown up side by side — a flush card and a padded one — so the same
   table looked different depending on which page you reached it from. */
.table-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.table-card > .table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: 0;
}

/* The header stays put while a long register scrolls; without it you lose track of which
   column you are reading within a screen or two. */
.table-card .data-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
}

.table-card .data-table tr:last-child td { border-bottom: none; }

/* ── Keyboard focus ─────────────────────────────────────────
   The stylesheet had exactly one focus-visible rule, so every other control fell back to
   whatever the browser drew — often nothing visible against a dark panel. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The rule above used to also set border-radius: 4px, which every focused
   control inherited — a 10px-radius input visibly changed shape the moment it
   took focus, and the first field of every form does so on load via autofocus.
   Browsers already follow the element's own radius when drawing an outline, so
   only bare inline links need one. */
a:not([class]):focus-visible {
  border-radius: 4px;
}

.sidebar-nav-item:focus-visible,
.lib-row-head:focus-visible,
.rt-card:focus-visible,
.profile-card:focus-visible {
  outline-offset: -2px;
}

/* ── Table cell rhythm ──────────────────────────────────────
   Identifiers, dates, badges and action buttons are atomic — wrapping any of them makes
   the row taller without making it clearer. Only prose columns are allowed to wrap. */
.data-table .risk-id,
.data-table .logs-date,
.data-table .logs-ip,
.data-table td:has(> .priority-badge),
.data-table td:has(> .decision-badge),
.data-table td:has(> .status-badge),
.data-table .row-actions,
.data-table .table-actions {
  white-space: nowrap;
}

/* The title is what the eye lands on, so it gets the room. The explicit class beats
   the old nth-child(2) rule, which pointed at the wrong column whenever a Company
   column was prepended. */
.data-table td strong { font-weight: 600; }
.data-table .cell-title { min-width: 220px; }

.table-card .data-table th:first-child,
.table-card .data-table td:first-child { padding-left: 20px; }

.table-card .data-table th:last-child,
.table-card .data-table td:last-child { padding-right: 20px; }

/* Level and Priority sit side by side and carry the same four words, but they are
   different things — one is the model's assessment, the other a management decision.
   Rendered identically they read as a duplicated column, so priority gets a quieter,
   outlined treatment that is clearly secondary to the assessed level. */
.priority-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}

.priority-chip::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.55;
  flex-shrink: 0;
}

.priority-chip-critical { color: #e0605f; }
.priority-chip-high     { color: #e07f4f; }
.priority-chip-medium   { color: #d99b3f; }
.priority-chip-low      { color: #4fa3d9; }

:root[data-theme="light"] .priority-chip-critical { color: #b03432; }
:root[data-theme="light"] .priority-chip-high     { color: #a85423; }
:root[data-theme="light"] .priority-chip-medium   { color: #9a6a15; }
:root[data-theme="light"] .priority-chip-low      { color: #2a6f9e; }


/* ============================================================
   Edit-analysis banner ("Düzəliş et")
   ============================================================ */

.edit-banner {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 16px 18px;
  margin-bottom: 16px;
  border-left: 3px solid var(--accent);
}

.edit-banner-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent-text);
}

.edit-banner-icon .nav-icon { width: 18px; height: 18px; }

.edit-banner-text strong {
  display: block;
  font-size: 14px;
  margin-bottom: 4px;
}

.edit-banner-text p {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.55;
}

.edit-banner-text .edit-banner-warn {
  margin-top: 6px;
  color: var(--warning-text);
}

/* ============================================================
   Submitted-inputs panel ("Analiz üçün təqdim edilmiş məlumatlar")
   ============================================================ */

.intake-panel {
  margin-bottom: 16px;
  overflow: hidden;
}

.intake-summary {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 15px 18px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.intake-summary::-webkit-details-marker { display: none; }

.intake-summary-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent-2) 16%, transparent);
  color: var(--accent-2-text);
}

.intake-summary-icon .nav-icon { width: 18px; height: 18px; }

.intake-summary-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}

.intake-summary-title {
  font-size: 13.5px;
  font-weight: 700;
}

.intake-summary-hint {
  font-size: 12px;
  color: var(--muted);
}

.intake-chevron {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--muted);
  transition: transform 0.2s ease;
}

details[open] > summary .intake-chevron,
details[open] > summary > .intake-chevron {
  transform: rotate(180deg);
}

.intake-body {
  padding: 4px 18px 18px;
  border-top: 1px solid var(--border);
}

.intake-group { margin-top: 14px; }

.intake-group-title {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent-text);
  margin-bottom: 9px;
}

.intake-group-title .nav-icon { width: 14px; height: 14px; }

.intake-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
  margin: 0;
}

.intake-item {
  background: color-mix(in srgb, var(--panel-raised) 65%, transparent);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  min-width: 0;
}

.intake-item-wide { grid-column: 1 / -1; }

.intake-item dt {
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 4px;
}

.intake-item dd {
  margin: 0;
  font-size: 13px;
  line-height: 1.55;
  overflow-wrap: break-word;
  white-space: pre-line;
}

/* ============================================================
   Risk matrix — explained
   ============================================================ */

.risk-matrix-head { margin-bottom: 14px; }

.risk-matrix-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent-text);
  margin-bottom: 6px;
}

.rm-title-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent-text);
}

.rm-title-icon .nav-icon { width: 16px; height: 16px; }

.risk-matrix-sub {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.6;
  max-width: 70ch;
}

/* The three concepts, always visible above the grid. */
.rm-explain-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}

.rm-explain-card {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: color-mix(in srgb, var(--panel-raised) 55%, transparent);
}

.rm-explain-card strong {
  display: block;
  font-size: 12.5px;
  margin-bottom: 3px;
}

.rm-explain-card p {
  margin: 0;
  font-size: 12px;
  color: var(--muted);
  line-height: 1.55;
}

.rm-explain-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border-radius: 8px;
}

.rm-explain-icon .nav-icon { width: 16px; height: 16px; }

.rm-explain-icon-likelihood {
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  color: var(--accent-text);
}

.rm-explain-icon-impact {
  background: var(--warning-bg);
  color: var(--warning-text);
}

.rm-explain-icon-score {
  background: color-mix(in srgb, var(--accent-2) 16%, transparent);
  color: var(--accent-2-text);
}

/* Scale labels carry their numeric value so "Possible = 3" is explicit. */
.rm-scale-label em {
  font-style: normal;
  font-weight: 800;
  font-size: 9px;
  color: var(--accent-text);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-radius: 4px;
  padding: 1px 4px;
  margin-right: 5px;
}

.rm-y-labels .rm-scale-label { display: flex; align-items: center; justify-content: flex-end; }

.rm-axis-x,
.rm-axis-y {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}

.rm-axis-x svg,
.rm-axis-y svg {
  width: 12px;
  height: 12px;
  color: var(--accent-text);
}

/* The parent is flipped 180° to run bottom-to-top; flip the arrow back upright. */
.rm-axis-y svg { transform: rotate(180deg); }

/* Score in the cell corner: the derivation is visible, not implied. */
.rm-cell {
  position: relative;
  cursor: help;
}

.rm-cell:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.rm-cell-score {
  position: absolute;
  top: 3px;
  right: 5px;
  font-size: 8.5px;
  font-weight: 700;
  color: color-mix(in srgb, var(--text) 55%, transparent);
  pointer-events: none;
}

/* The cell holding the page's current risk. */
.rm-cell-current {
  box-shadow: inset 0 0 0 2px var(--accent), 0 0 12px color-mix(in srgb, var(--accent) 45%, transparent);
}

.rm-chip { text-decoration: none; }

a.rm-chip { cursor: pointer; }

a.rm-chip:hover { filter: brightness(1.2); }

.rm-chip-current {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  animation: rmCurrentPulse 2s ease-in-out infinite;
}

@keyframes rmCurrentPulse {
  0%, 100% { outline-color: var(--accent); }
  50% { outline-color: color-mix(in srgb, var(--accent) 35%, transparent); }
}

@media (prefers-reduced-motion: reduce) {
  .rm-chip-current { animation: none; }
}

/* Legend: band, score range, and what the band demands. */
.rm-legend {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
  margin-top: 16px;
}

.rm-legend-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.rm-legend-swatch {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  border-radius: 5px;
  margin-top: 2px;
}

.rm-legend-item strong { font-size: 12.5px; }

.rm-legend-range {
  font-weight: 600;
  font-size: 11px;
  color: var(--muted);
  margin-left: 4px;
}

.rm-legend-item p {
  margin: 3px 0 0;
  font-size: 12px;
  color: var(--muted);
  line-height: 1.55;
}

/* Why the current risk landed where it did. */
.rm-current-note {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin-top: 16px;
  padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}

.rm-current-marker {
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  margin-top: 5px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 70%, transparent);
}

.rm-current-note p {
  margin: 0;
  font-size: 13px;
  line-height: 1.6;
}

/* Deeper walkthrough, collapsed by default. */
.rm-howto {
  margin-top: 14px;
  border-top: 1px solid var(--border);
  padding-top: 4px;
}

.rm-howto summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 2px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.rm-howto summary::-webkit-details-marker { display: none; }

.rm-howto summary:hover { color: var(--text); }

.rm-howto summary .nav-icon { width: 16px; height: 16px; }

.rm-howto summary .intake-chevron { margin-left: auto; }

.rm-howto-body {
  padding: 4px 2px 10px;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.65;
}

.rm-howto-body p { margin: 0 0 8px; }

.rm-howto-body ul {
  margin: 0 0 8px;
  padding-left: 20px;
}

.rm-howto-body li { margin-bottom: 5px; }

/* Floating tooltip for matrix cells (site.js). */
.matrix-tip {
  position: fixed;
  z-index: 300;
  max-width: 240px;
  padding: 9px 12px;
  border-radius: 9px;
  background: var(--panel-raised);
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-md);
  font-size: 12px;
  line-height: 1.65;
  white-space: pre-line;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s ease;
}

.matrix-tip.visible { opacity: 1; }

/* ============================================================
   Return-to-risk highlight
   ============================================================ */

@keyframes anchorFlashBg {
  0% { background-color: color-mix(in srgb, var(--accent) 22%, transparent); }
  70% { background-color: color-mix(in srgb, var(--accent) 14%, transparent); }
  100% { background-color: transparent; }
}

.anchor-flash:not(tr) {
  animation: anchorFlashBg 2.4s ease forwards;
}

tr.anchor-flash > td {
  animation: anchorFlashBg 2.4s ease forwards;
}

@media (prefers-reduced-motion: reduce) {
  .anchor-flash:not(tr), tr.anchor-flash > td { animation: none; }
}

@keyframes aiDot {
  0%, 60%, 100% { opacity: 0.35; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-3px); }
}


/* Icons inside buttons scale to the button, not the sidebar's 17px default. */
.btn-primary .nav-icon,
.btn-secondary .nav-icon,
.btn-ghost .nav-icon {
  width: 16px;
  height: 16px;
}

.btn-sm .nav-icon {
  width: 14px;
  height: 14px;
}

.error-box-icon .nav-icon {
  width: 36px;
  height: 36px;
}

.note-delete .nav-icon {
  width: 14px;
  height: 14px;
}

.risk-summary-label .nav-icon {
  width: 14px;
  height: 14px;
  vertical-align: -2px;
}

/* ============================================================
   Document-based analysis — dropzone & file list
   ============================================================ */

.doca-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 30px 20px;
  border: 2px dashed var(--border-strong);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--panel-raised) 55%, transparent);
  cursor: pointer;
  text-align: center;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.doca-dropzone:hover,
.doca-dropzone:focus-visible,
.doca-dropzone.dragover {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}

.doca-dropzone-icon .nav-icon {
  width: 28px;
  height: 28px;
  color: var(--accent-text);
}

.doca-dropzone-text {
  font-weight: 600;
  font-size: 13.5px;
}

.doca-file-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 12px 0;
}

.doca-file-list:empty { margin: 0; }

.doca-file {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel-raised);
  font-size: 13px;
}

.doca-file-icon .nav-icon {
  width: 16px;
  height: 16px;
  color: var(--muted);
  display: block;
}

.doca-file-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
  flex: 1;
}

.doca-file-size {
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.doca-file-remove {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  transition: background 0.15s ease, color 0.15s ease;
}

.doca-file-remove .nav-icon {
  width: 16px;
  height: 16px;
}

.doca-file-remove:hover {
  background: color-mix(in srgb, var(--danger-text) 14%, transparent);
  color: var(--danger-text);
}

/* Kept-but-removed rows in edit mode: struck through until restored or submitted. */
.doca-file-removed .doca-file-name,
.doca-file-removed .doca-file-size {
  text-decoration: line-through;
  opacity: 0.55;
}

/* Download links inside the "submitted inputs" panel. */
.intake-file-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--accent-text);
  text-decoration: none;
  font-weight: 600;
}

.intake-file-link:hover { text-decoration: underline; }

.intake-file-link .nav-icon {
  width: 14px;
  height: 14px;
}

/* "No result" is guidance, not an alarm: the model ran and found nothing analyzable,
   so the box drops the red and points the user at refining their inputs. */
.error-box-noresult {
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
}

.error-box-noresult .error-box-icon {
  color: var(--accent-text);
}

/* ── Data tables on small screens ────────────────────────────
   The register is nine columns wide and carries a 960px min-width, so on a phone the
   horizontal scroller hid exactly the columns that matter — level, priority, status and
   the row action. The user saw an identifier and a clipped title and had to guess.

   Below 760px each row becomes a card and each cell carries its column name, taken from
   the `data-label` attribute on the <td>. Cells with no label (the title, the action)
   render full width. This is the standard responsive-table pattern and it removes the
   horizontal scroll entirely rather than decorating it. */
@media (max-width: 900px) {
  .table-card > .table-scroll,
.table-scroll {
    overflow-x: visible;
  }

  .data-table,
  .data-table thead,
  .data-table tbody,
  .data-table tr,
  .data-table td {
    display: block;
    width: auto;
  }

  .data-table {
    min-width: 0;
    font-size: 14px;
  }

  /* The header row is replaced by per-cell labels. */
  .data-table thead {
    display: none;
  }

  .data-table tbody tr {
    padding: 16px;
    border-bottom: 1px solid var(--border);
  }

  .data-table tbody tr:last-child {
    border-bottom: none;
  }

  .data-table tbody tr:hover td {
    background: transparent;
  }

  .data-table td {
    padding: 7px 0;
    border: none;
    display: grid;
    grid-template-columns: minmax(88px, 38%) 1fr;
    gap: 14px;
    align-items: baseline;
    white-space: normal;
    /* Values sit against the right edge opposite their label. Without an explicit
       justify-items the grid stretches each value to the full column, which turned every
       level badge into a full-width block. */
    /* The value box hugs the right edge opposite its label, but text inside it still
       reads left-to-right -- right-aligning the box contents broke multi-line titles and
       split the category dot away from its name. */
    justify-items: end;
    text-align: left;
  }

  /* Category and subcategory are held on one line inside a register row; in a card there
     is no row height to protect, so they wrap instead of being clipped. */
  .data-table .category-name,
  .data-table .subcategory-name {
    white-space: normal;
  }

  .data-table .category-stack {
    align-items: flex-start;
  }

  .data-table td::before {
    content: attr(data-label);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--muted);
    line-height: 1.7;
  }

  /* Cells that carry no label own the full width: the title leads the card, the action
     closes it. */
  .data-table td:not([data-label]),
  .data-table td[data-label=""] {
    display: block;
  }

  .data-table td:not([data-label])::before,
  .data-table td[data-label=""]::before {
    content: none;
  }

  .data-table .cell-title {
    min-width: 0;
    padding-top: 0;
    padding-bottom: 10px;
  }

  .data-table .cell-title strong {
    font-size: 15px;
    line-height: 1.35;
  }

  /* Identifiers and dates may wrap on a phone rather than force a scroller. */
  .data-table .risk-id,
  .data-table .logs-date,
  .data-table .logs-ip,
  .data-table td:has(> .priority-badge),
  .data-table td:has(> .decision-badge),
  .data-table td:has(> .status-badge),
  .data-table .row-actions,
  .data-table .table-actions {
    white-space: normal;
  }

  /* Row actions become full-width targets instead of 28px-tall links. */
  .data-table .row-actions,
  .data-table .table-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding-top: 12px;
  }

  .data-table .row-actions > *,
  .data-table .table-actions > * {
    flex: 1 1 auto;
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* The row action closes the card as a full-width target: a 28px inline link is below
     any reasonable touch minimum, and left-aligned it read as stray text. */
  .data-table tbody td:last-child:not([data-label]) > a,
  .data-table tbody td:last-child:not([data-label]) > button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 44px;
    margin-top: 6px;
  }

  .table-card .data-table th:first-child,
  .table-card .data-table td:first-child,
  .table-card .data-table th:last-child,
  .table-card .data-table td:last-child {
    padding-left: 0;
    padding-right: 0;
  }
}

/* ── Collapsible filters on small screens ───────────────────
   Paired with the toggle built in site.js. The label inside the submit button is hidden
   on desktop, where the icon plus its title is enough, and shown on a phone where an
   unlabelled full-width orange button says nothing about what it does. */
.btn-inline-label { display: none; }

@media (max-width: 900px) {
  .filter-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    min-height: 46px;
    margin-bottom: 12px;
    padding: 12px 16px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    color: var(--text);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
  }

  .filter-toggle::after {
    content: "";
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--muted);
    border-bottom: 2px solid var(--muted);
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform 0.18s ease;
  }

  .filter-toggle[aria-expanded="true"]::after {
    transform: rotate(-135deg) translate(-2px, -2px);
  }

  /* Collapsed by default once the toggle exists; the toggle is only inserted on mobile,
     so a browser with JS disabled keeps the panel open rather than losing it. */
  .filter-toggle + .filter-bar { display: none; }
  .filter-toggle + .filter-bar.filter-bar-open { display: flex; }

  .btn-inline-label { display: inline; margin-left: 8px; }

  /* Icon-only buttons stop being icon-only here, so they need real padding. */
  .filter-actions .btn-icon-only {
    width: auto;
    min-height: 46px;
    padding: 0 18px;
  }
}

/* ── Bare links inside tables ────────────────────────────────
   The stylesheet has no base anchor rule, so a link without a button or ghost class fell
   back to the browser's default blue underline — the request numbers in the candidate
   registers rendered as raw hyperlinks against the dark panel, the one element on the
   page not speaking the design system. Scoped to tables rather than set globally, because
   navigation items, buttons and cards already colour their own anchors and a global rule
   would fight every one of them. */
.data-table a:not([class]) {
  color: var(--accent-text);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.data-table a:not([class]):hover {
  border-bottom-color: currentColor;
}

/* ── Touch comfort on small screens ──────────────────────────
   Measured on a 375px viewport: the candidate Accept/Decline buttons were 28px tall, the
   request-number links 22px, pagination 34px and the sidebar items 33px — all under any
   reasonable touch minimum, and the accept/decline pair are the two most consequential
   controls in the product. Type sizes tuned for a desk monitor were also carried onto the
   phone unchanged; the identifier and subcategory lines were 11px. */
@media (max-width: 900px) {
  .data-table .btn-accept,
  .data-table .btn-reject,
  .data-table .btn-ghost,
  .data-table .btn-sm {
    min-height: 44px;
    padding-left: 16px;
    padding-right: 16px;
  }

  /* A bare link in a table row is a real target, not a word. */
  .data-table a:not([class]) {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
  }

  .page-btn {
    min-width: 44px;
    min-height: 44px;
  }

  /* Readability: nothing on a phone should be under 12px. */
  .data-table .risk-id {
    font-size: 13px;
  }

  .data-table .subcategory-name {
    font-size: 12.5px;
  }

  .data-table td::before {
    font-size: 11px;
  }
}

/* ── Long preview cells in card mode ─────────────────────────
   .logs-msg-preview truncates with nowrap + ellipsis, which the card layout's
   white-space: normal undoes — the submitted intake text then ran for several screens and
   buried every row after it. These classes sit on the <td> itself, so a -webkit-box clamp
   would replace the label/value grid and run the label into the text; the cell stacks
   instead and clips at a fixed height. The full text stays in the title attribute, as it
   is on the desktop table. */

/* ── Matrix and intake controls on small screens ─────────────
   The matrix keeps its own horizontal scroller (.risk-matrix-scroll): a 5×5 board needs
   roughly 450px before the cell chips stop being legible, so unlike the registers it is
   not folded down — squeezing it would make the thing it exists to communicate
   unreadable. Only its height is reduced here, which is what actually hurt on a phone.

   In the intake form the help buttons measured 21px and the data-classification
   checkboxes 15px — the smallest targets in the product, on the screen a new user meets
   first. The checkbox keeps its visual size but its whole row becomes the target. */
@media (max-width: 900px) {
  .risk-matrix {
    grid-template-rows: repeat(5, 54px);
    gap: 3px;
  }

  .risk-matrix-layout {
    gap: 4px;
  }

  .rm-cell {
    padding: 3px;
    border-radius: 5px;
  }

  .rm-cell-score {
    font-size: 10px;
  }

  .field-info-btn {
    width: 32px;
    height: 32px;
  }

  .checkbox-item {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
  }

  .checkbox-item input[type="checkbox"] {
    width: 20px;
    height: 20px;
    flex: none;
  }
}


/* ---------- Risk review prompt ----------
   The dialog a risk owner meets when a review cadence falls due. Deliberately the
   largest surface in the app: it is not a confirmation, it is a briefing — the owner
   is being asked to sign off on a state, so the state, the mitigation and everything
   that moved since the previous review have to fit on it without a scroll-hunt.

   Built from the existing dialog parts (.modal-overlay, .modal-card, the badge and
   progress classes) rather than a second dialog system, so site.js's focus trap,
   Escape handling and scroll lock apply to it with no extra wiring. What is added
   here is the size: about 70% of the viewport, on a heavier blur, with its own
   scrolling body so the header and the decision row never leave the screen. */

/* The dialog arrives a few seconds after the page rather than with it, so it gets a
   slower, softer entrance than the confirm dialogs: the scrim settles first and the
   panel rises into it. An instant appearance after a delay reads as a glitch. */
.review-overlay {
  padding: 0;
  backdrop-filter: blur(16px) saturate(115%);
  -webkit-backdrop-filter: blur(16px) saturate(115%);
  animation: review-scrim-in 0.45s ease both;
}

.review-overlay .review-card {
  animation: review-card-in 0.55s cubic-bezier(0.16, 0.84, 0.3, 1) both;
}

@keyframes review-scrim-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes review-card-in {
  from { opacity: 0; transform: translateY(26px) scale(0.965); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

/* Someone who has asked the system to stop moving things still gets the dialog,
   just without the travel. */
@media (prefers-reduced-motion: reduce) {
  .review-overlay,
  .review-overlay .review-card {
    animation-duration: 0.01ms;
  }
}

/* A fixed height, not a max: the dialog is the same object whether the risk has
   twenty actions or none, and a panel that resizes between two reviews in the same
   queue reads as a different window each time. The body scrolls inside it. */
.review-card {
  width: 70vw;
  max-width: 1120px;
  height: 82vh;
  margin: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 40px 120px rgba(0, 0, 0, 0.45), 0 12px 32px rgba(0, 0, 0, 0.22);
}

/* .review-item sets display:flex, which would otherwise beat the user agent's
   display:none for [hidden] and show the whole queue at once. */
.review-item[hidden] {
  display: none;
}

/* ---- head ---- */

.review-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 22px 28px;
  border-bottom: 1px solid var(--border);
  background: linear-gradient(180deg,
      color-mix(in srgb, var(--accent) 7%, transparent),
      transparent);
  flex-shrink: 0;
}

.review-kicker {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 5px;
}

.review-head-text h3 {
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.25;
  margin: 0;
  color: var(--text);
}

.review-head-text p {
  font-size: 13px;
  color: var(--muted);
  margin: 3px 0 0;
}

.review-counter {
  margin-left: auto;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--muted);
  background: var(--panel-raised);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 6px 12px;
  white-space: nowrap;
  flex-shrink: 0;
}

/* ---- one review ---- */

.review-item {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1;
}

.review-body {
  padding: 24px 28px;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

.review-badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.review-title {
  font-family: var(--font-heading);
  font-size: 20px;
  font-weight: 700;
  line-height: 1.35;
  color: var(--text);
  margin: 14px 0 10px;
}

.review-desc {
  font-size: 14px;
  line-height: 1.65;
  color: var(--muted);
  margin: 14px 0 0;
}

.review-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 16px 22px;
  margin: 18px 0 0;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--panel-raised) 60%, transparent);
}

/* A long label ("Məlumatlandırma dövrü") wraps to two lines while its neighbours do
   not, which left the values in one row sitting at different heights. Stretching the
   cells and pushing the value to the bottom lines them up again. */
.review-fact {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.review-fact-value {
  margin-top: auto;
}

.review-fact-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.review-fact-value {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}

.review-fact-value.is-overdue {
  color: var(--danger-text);
}

.review-note-box {
  margin: 16px 0 0;
  padding: 14px 16px;
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text);
}

/* Titles, descriptions and notes are model- or user-supplied, so one of them will
   eventually be a single unbroken 400-character string. Without this it pushes the
   dialog wider than the screen instead of wrapping. */
.review-title,
.review-desc,
.review-note-box,
.review-quiet,
.review-list-main {
  overflow-wrap: anywhere;
}

/* A note can be an essay; the dialog shows the opening of it and the risk page has
   the rest. The action plan gets more room because it is the plan under review. */
.review-note-text {
  display: -webkit-box;
  -webkit-line-clamp: 6;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.review-list-quote {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.review-note-box strong {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 5px;
}

/* ---- the two blocks: where it stands, what moved ---- */

.review-block {
  margin: 18px 0 0;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.review-block-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.review-block-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text);
}

.review-block-title svg {
  width: 16px;
  height: 16px;
  color: var(--muted);
}

.review-block-meta {
  margin-left: auto;
  font-size: 12px;
  color: var(--muted);
}

.review-quiet {
  font-size: 13px;
  color: var(--muted);
  margin: 0;
}

.review-progress {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.review-progress-label {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
}

.review-progress .progress-bar {
  flex: 1;
}

.review-progress-value {
  font-size: 12px;
  font-weight: 700;
  color: var(--text);
  min-width: 38px;
  text-align: right;
}

.review-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.review-list-item {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--panel-raised) 55%, transparent);
}

.review-list-main {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
  flex: 1;
  min-width: 140px;
}

.review-list-quote {
  font-weight: 500;
  font-style: italic;
}

.review-list-meta {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
}

.review-change-tag {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  white-space: nowrap;
  flex-shrink: 0;
}

.tag-new  { background: var(--success-bg); color: var(--success-text); }
.tag-upd  { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent-text); }
.tag-note { background: var(--panel-raised); color: var(--muted); }
.tag-file { background: var(--warning-bg); color: var(--warning-text); }

/* ---- the decision row ---- */

.review-footer {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 16px 28px;
  border-top: 1px solid var(--border);
  background: var(--panel);
  flex-shrink: 0;
}

.review-hint {
  font-size: 12px;
  color: var(--muted);
  margin: 0;
  flex: 1;
  min-width: 180px;
}

.review-footer-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

.review-footer-actions .btn-accept svg {
  width: 16px;
  height: 16px;
}

.review-more {
  margin: 0;
  padding: 10px 28px 14px;
  font-size: 12px;
  color: var(--muted);
  text-align: center;
  border-top: 1px solid var(--border);
  background: var(--panel);
  flex-shrink: 0;
}

/* A dialog that is 70% of a phone is a letterbox: below the sidebar breakpoint it
   takes the screen instead, and the decision row stacks under the hint. */
@media (max-width: 900px) {
  .review-card {
    width: 100%;
    max-width: none;
    height: 100vh;
    border-radius: 0;
    border: none;
  }

  .review-head,
  .review-body,
  .review-footer {
    padding-left: 18px;
    padding-right: 18px;
  }

  .review-head-text h3 {
    font-size: 18px;
  }

  .review-title {
    font-size: 17px;
  }

  .review-footer-actions {
    width: 100%;
    margin-left: 0;
  }

  .review-footer-actions .btn-secondary,
  .review-footer-actions .btn-accept {
    flex: 1;
    justify-content: center;
  }
}

/* Marks a register row the reader is on as an action assignee rather than as the owner.
   Quiet on purpose: the register's loud elements are level, priority and status, and this
   is context for one reader, not a property of the risk. */
.my-action-chip {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--accent-text);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}
