/* ============================================================
   THEME — palette + typography
   Default: dark (warm-peach accent on near-black, Hex-inspired).
   Light theme is opt-in via [data-theme="light"] on <html>.
   View Transitions API (browser-supported) gives a circular reveal
   when toggling — set up automatically by app.js.
   ============================================================ */

:root,
:root[data-theme="dark"] {
  --bg:           #0d0d0d;
  --panel:        #161616;
  --panel-2:      #1d1d1d;
  --border:       #2a2a2a;
  --border-soft:  #1f1f1f;
  --fg:           #f5e9d8;          /* warm off-white, not cold #fff */
  --fg-2:         #b9b1a3;
  --muted:        #8a8378;
  --accent:       #ff9a6b;          /* peach/coral — the brand */
  --accent-hover: #ffb088;
  --accent-soft:  rgba(255, 154, 107, 0.14);
  --accent-line:  rgba(255, 154, 107, 0.30);
  --good:         #7cc69a;
  --good-soft:    rgba(124, 198, 154, 0.14);
  --warning:      #f4b266;
  --warning-soft: rgba(244, 178, 102, 0.14);
  --danger:       #e56b6f;
  --danger-soft:  rgba(229, 107, 111, 0.14);

  /* shadows — soft, no harsh outlines */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-2: 0 4px 16px rgba(0, 0, 0, 0.5);

  /* selection */
  --selection-bg: rgba(255, 154, 107, 0.28);
  --selection-fg: var(--fg);
}

:root[data-theme="light"] {
  /* Pure white, Linear/Vercel/Apple-style minimalism.
     Card surfaces have subtle gray (not warm) to keep things crisp.
     Accents stay coral (brand) but pop punchier against white. */
  --bg:           #ffffff;
  --panel:        #ffffff;
  --panel-2:      #f7f7f8;          /* near-white for cards, no warmth */
  --border:       #e5e5e7;          /* Apple-style hairline */
  --border-soft:  #ebebed;
  --fg:           #0a0a0a;          /* near-black — max contrast */
  --fg-2:         #424245;          /* iOS-secondary gray */
  --muted:        #6e6e73;          /* iOS-tertiary */
  --accent:       #ff5722;          /* punchier coral on white */
  --accent-hover: #e6491a;
  --accent-soft:  rgba(255, 87, 34, 0.08);
  --accent-line:  rgba(255, 87, 34, 0.30);
  --good:         #0a8e57;          /* clean green, no olive */
  --good-soft:    rgba(10, 142, 87, 0.09);
  --warning:      #b86e00;          /* amber, not muddy */
  --warning-soft: rgba(184, 110, 0, 0.10);
  --danger:       #d92020;          /* clean red */
  --danger-soft:  rgba(217, 32, 32, 0.08);

  /* Slightly stronger shadows on white surfaces — needed for card depth */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-2: 0 6px 24px rgba(0, 0, 0, 0.06), 0 2px 6px rgba(0, 0, 0, 0.04);

  --selection-bg: rgba(255, 87, 34, 0.18);
  --selection-fg: var(--fg);
}

::selection { background: var(--selection-bg); color: var(--selection-fg); }

/* ============================================================
   TYPOGRAPHY — three-font system
   - Display (headlines):  Manrope ExtraBold/Black
   - Body (UI, prose):     Inter
   - Mono (line numbers,
     code-like content):   JetBrains Mono
   ============================================================ */

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family:
    'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI',
    'SF Pro Text', 'Helvetica Neue', Arial, sans-serif;
  background: var(--bg);
  color: var(--fg);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: 'cv11' on, 'ss01' on;  /* Inter: better Russian + alt 'a' */
  transition: background-color 200ms ease, color 200ms ease;
}

.font-display {
  font-family: 'Manrope', 'Inter', -apple-system, sans-serif;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.font-mono {
  font-family: 'JetBrains Mono', 'SF Mono', 'Consolas', ui-monospace, monospace;
  font-feature-settings: 'zero' on;
}

/* Scrollbars — subtle, not contrasty */
* { scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 10px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--muted); background-clip: padding-box; border: 2px solid transparent; }
*::-webkit-scrollbar-corner { background: transparent; }
#app { display: flex; flex-direction: column; height: 100vh; }
/* The auth-gate wrapper added around the cabinet content must be
   layout-transparent — otherwise it eats #app's flex chain, <main>
   collapses to its intrinsic height, and the independent left/right
   scroll panes never overflow (so overflow-y: auto never activates).
   `display: contents` makes the wrapper vanish from layout while
   keeping the element addressable for the JS show/hide toggle.
   `display: none` on the inline style still wins (= cabinet hidden
   for anonymous users, until AUTH._renderGate flips it). */
#cabinet-app { display: contents; }

header {
  position: relative;
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--panel);
  overflow: hidden;
}
/* Soft animated gradient line under the header — accent-colored, subtle */
header::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--accent-line) 50%,
    transparent 100%
  );
  background-size: 200% 100%;
  animation: drift 11s linear infinite;
  opacity: 0.55;
  pointer-events: none;
}
@keyframes drift {
  0%   { background-position: -100% 0; }
  100% { background-position: 100% 0; }
}

.brand {
  display: inline-flex; align-items: center; gap: 12px;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.018em;
  color: var(--fg);
  text-transform: none;
}
.brand::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--good);
  box-shadow: 0 0 0 0 var(--good-soft);
  animation: breathe 2.6s ease-in-out infinite;
}
@keyframes breathe {
  0%, 100% { box-shadow: 0 0 0 0 var(--good-soft); opacity: 1; }
  50%      { box-shadow: 0 0 0 7px transparent; opacity: 0.55; }
}
body.busy .brand::before {
  background: var(--accent);
  animation: busybreathe 1s ease-in-out infinite;
}
@keyframes busybreathe {
  0%, 100% { box-shadow: 0 0 0 0 var(--accent-line); }
  50%      { box-shadow: 0 0 0 7px transparent; }
}

.actions { display: flex; gap: 8px; align-items: center; }

main {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(320px, 1fr) minmax(520px, 1.2fr);
  gap: 1px;
  background: var(--border);
  overflow: hidden;
}
#left, #right {
  background: var(--bg);
  overflow-y: auto;
  overflow-x: hidden;       /* sticky tabs' negative margins create a ~10px
                               sub-pixel overflow on the right pane; we
                               never put real content past the edge so
                               clipping it is safe. */
  padding: 20px 24px;
}

.drop {
  border: 1.5px dashed var(--border);
  border-radius: 14px;
  padding: 72px 30px;
  text-align: center;
  color: var(--muted);
  background:
    radial-gradient(ellipse at top, var(--accent-soft), transparent 60%),
    var(--panel);
  transition: border-color 0.25s ease, background 0.25s ease, color 0.25s ease;
  position: relative;
  overflow: hidden;
  font-size: 14px;
}
.drop::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 120%, var(--accent-soft), transparent 55%);
  opacity: 0;
  transition: opacity 0.35s ease;
  pointer-events: none;
}
.drop:hover::before, .drop.dragover::before { opacity: 1; }
.drop.dragover { border-color: var(--accent); background: var(--panel-2); color: var(--fg); }
.drop p { margin: 6px 0; }
.link { color: var(--accent); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }

.article-structure {
  margin-top: 8px;
  font-size: 12px;
  color: var(--fg-2);
  letter-spacing: -0.005em;
  line-height: 1.7;
}
.article-structure .struct-part {
  display: inline-block;
}
.article-structure .struct-part-skip {
  color: var(--muted);
  text-decoration: line-through;
  text-decoration-color: var(--muted);
  text-decoration-thickness: 1px;
}
.article-structure .struct-skip {
  display: inline-block;
  margin-left: 4px;
  padding: 1px 7px;
  border-radius: 4px;
  background: var(--panel-2);
  color: var(--muted);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0;
  text-decoration: none;
  vertical-align: middle;
}

.article-stats {
  font-size: 11.5px;
  color: var(--muted);
  letter-spacing: -0.005em;
  margin-bottom: 12px;
  padding: 0 2px;
}
.article {
  white-space: pre-wrap;
  font-size: 12.5px;
  color: var(--fg);
  border: 1px solid var(--border);
  padding: 16px;
  border-radius: 4px;
  background: var(--panel);
  tab-size: 2;
}
.article .hl { background: var(--accent-soft); border-radius: 2px; }

.muted { color: var(--muted); }
.center { text-align: center; margin-top: 80px; }

.toolbar { display: flex; gap: 8px; flex-wrap: wrap; margin: 18px 0 24px; }

button, .ghost, select, input[type="text"], textarea {
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--fg);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 14px;
  letter-spacing: -0.005em;
}
button { cursor: pointer; transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease; }
button:hover, .ghost:hover { background: var(--panel-2); border-color: var(--accent-line); color: var(--accent); }
button.primary {
  background: var(--accent); border-color: var(--accent); color: #ffffff;
  position: relative;
  transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.25s ease, transform 0.06s ease;
}
button.primary:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  color: #ffffff;
  box-shadow: 0 8px 22px -12px var(--accent), 0 2px 6px -3px var(--accent-line);
}
button.primary:active { transform: translateY(1px); }
button:disabled { opacity: 0.5; cursor: wait; }
a.ghost { text-decoration: none; display: inline-block; }

select { min-width: 140px; }
input[type="text"], textarea {
  width: 100%; padding: 10px 12px;
  border-radius: 8px;
  font-weight: 400;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
input[type="text"]:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
textarea { resize: vertical; font-size: 12.5px; line-height: 1.55; }
.title-input { font-size: 14px; }

.title-row { margin-bottom: 10px; }
.lbl, .subrow label {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--fg-2);
  margin-bottom: 8px;
  letter-spacing: -0.005em;
}
.subrow { margin-bottom: 18px; }
.row { display: flex; gap: 14px; }
.row .grow { flex: 1; }

.panel {
  border: 1px solid var(--border);
  background: var(--panel);
  border-radius: 14px;
  padding: 24px 26px;
  margin-bottom: 22px;
  box-shadow: var(--shadow-1);
  animation: fadeIn 0.35s ease-out both;
}
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(3px); }
  to   { opacity: 1; transform: translateY(0); }
}
.panel-title {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--fg);
  margin-bottom: 18px;
  line-height: 1.3;
}
.panel.warning { border-color: var(--warning); background: var(--warning-soft); }
.panel.warning .panel-title { color: var(--warning); }

.section-block {
  margin-bottom: 22px;
  /* No overflow: hidden — would clip the criterion behind-glow + the
     ⓘ tooltip. Border-radius is applied separately to head & body. */
  box-shadow: var(--shadow-1);
  border-radius: 14px;
}
/* Wrapper for the right-side cluster: price hint + «Оценить секцию».
   Without this the price chip sat too close to the button. */
.section-head-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}
.section-rescore-price {
  font-size: 12px;
  color: var(--muted);
  letter-spacing: -0.005em;
  white-space: nowrap;
}
.section-rescore-price:empty { display: none; }

.section-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 22px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: 14px 14px 0 0;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.012em;
  color: var(--fg);
}
.section-body {
  border: 1px solid var(--border);
  border-top: none;
  border-radius: 0 0 14px 14px;
  background: var(--panel);
}

.criterion {
  position: relative;
  padding: 18px 22px;
  border-top: 1px solid var(--border-soft);
  animation: slideIn 0.28s ease-out both;
  transition: box-shadow 0.18s ease, border-top-color 0.18s ease;
}
.criterion:first-child { border-top: none; }
/* Hover: the criterion's frame highlights subtly — top separator goes
   accent-line, plus a 2px accent stripe on the left via inset shadow
   (no layout shift). No glow, no fill — just a clean frame cue. */
.criterion:hover {
  border-top-color: var(--accent-line);
  box-shadow: inset 2px 0 0 var(--accent);
}
.criterion:hover + .criterion { border-top-color: var(--accent-line); }
@keyframes slideIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.criterion-head {
  display: flex; align-items: flex-start; gap: 14px; justify-content: space-between;
  margin-bottom: 8px;
}
.criterion-text {
  color: var(--fg);
  font-size: 13.5px;
  line-height: 1.5;
  flex: 1;
  font-weight: 450;
}
.criterion-meta {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-shrink: 0;
}

/* Score pill — replaces the old 6-button row; AI output is read-only.
   Color tints by score class (added in JS as score-poor / score-good / etc.) */
.score-pill {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: -0.005em;
  padding: 4px 12px;
  border-radius: 7px;
  white-space: nowrap;
  user-select: none;
  transition: background 0.15s ease;
}
.score-pill.score-poor,
.score-pill.score-fair      { background: var(--danger-soft);  color: var(--danger); }
.score-pill.score-average   { background: var(--panel-2);      color: var(--fg-2); }
.score-pill.score-good,
.score-pill.score-excellent { background: var(--good-soft);    color: var(--good); }
.score-pill.score-not       { background: var(--panel-2);      color: var(--muted); }
.score-pill.score-empty     { background: var(--panel-2);      color: var(--muted); font-style: italic; }

/* Read-only rationale — prose paragraph, not a textarea */
.criterion-rationale {
  margin-top: 14px;
  font-size: 13px;
  line-height: 1.62;
  color: var(--fg-2);
  white-space: pre-wrap;
  letter-spacing: -0.003em;
}

.verif-badge {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: -0.005em;
  padding: 5px 12px;
  border-radius: 7px;
  white-space: nowrap;
  cursor: default;
  user-select: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.verif-badge.watch {
  background: var(--warning-soft);
  color: var(--warning);
  border: 1px solid var(--warning);
}
.verif-badge.flag {
  background: var(--danger-soft);
  color: var(--danger);
  border: 1.5px solid var(--danger);
  font-size: 12.5px;
  padding: 6px 14px;
  box-shadow: 0 0 0 0 var(--danger);
  animation: pulseDanger 1.8s ease-in-out infinite;
}

.verif-details {
  margin-top: 8px;
  padding: 8px 10px;
  background: rgba(229,107,111,0.05);
  border-left: 2px solid var(--danger);
  border-radius: 0 3px 3px 0;
  font-size: 11.5px;
}
.verif-item { color: var(--fg-2); margin: 3px 0; }
.verif-item.watch { color: var(--warning); }
.verif-item.flag  { color: var(--danger); }
.verif-kind {
  display: inline-block;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--muted);
  margin-right: 8px;
  padding: 2px 8px;
  background: var(--panel-2);
  border-radius: 5px;
}
.score-row { display: flex; gap: 6px; margin-bottom: 14px; flex-wrap: wrap; }
.score-btn {
  padding: 6px 14px;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  letter-spacing: -0.005em;
  transition: color 0.18s ease, background 0.18s ease, border-color 0.18s ease, transform 0.08s ease;
}
.score-btn:hover { color: var(--fg); border-color: var(--border); }
.score-btn:active { transform: scale(0.96); }
.score-btn.selected { animation: pop 0.22s ease-out; }
@keyframes pop {
  0%   { transform: scale(0.9); }
  60%  { transform: scale(1.05); }
  100% { transform: scale(1); }
}
.score-btn.selected { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }
.score-btn.selected.poor, .score-btn.selected.fair { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.score-btn.selected.good, .score-btn.selected.excellent { background: var(--good-soft); border-color: var(--good); color: var(--good); }

.rationale { font-size: 12px; color: var(--fg-2); background: var(--bg); border: 1px solid var(--border); border-radius: 3px; padding: 10px; margin-bottom: 8px; white-space: pre-wrap; }
.rationale textarea { min-height: 72px; }
.evidence {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px dashed var(--border-soft);
  font-size: 12px;
  color: var(--muted);
  line-height: 1.6;
}
.evidence .q { color: var(--fg-2); cursor: pointer; transition: color 0.15s ease; }
.evidence .q:hover { color: var(--accent); }
.evidence .q:hover { text-decoration: underline; }

.toast {
  position: fixed; bottom: 24px; right: 24px;
  background: var(--panel-2); border: 1px solid var(--border);
  padding: 12px 18px; border-radius: 10px;
  opacity: 0; transition: opacity 0.2s ease, transform 0.2s ease;
  pointer-events: none; z-index: 100;
  font-size: 13px;
  box-shadow: var(--shadow-2);
}
.toast.show { opacity: 1; pointer-events: auto; cursor: pointer; }
.toast.sticky::after { content: " ×"; color: var(--muted); }
.toast.err { border-color: var(--danger); color: var(--danger); }

#factcheck-list .issue {
  border-top: 1px solid var(--border);
  padding: 10px 0;
  font-size: 12px;
  animation: slideIn 0.25s ease-out both;
}
#factcheck-list .issue:first-child { border-top: none; }
.issue-head { display: flex; gap: 8px; align-items: center; margin-bottom: 6px; }
.issue .sev-high { color: var(--danger); font-weight: 500; }
.issue .sev-medium { color: var(--warning); font-weight: 500; }
.issue .sev-low { color: var(--muted); font-weight: 500; }
.issue-kind {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: -0.005em;
  padding: 2px 8px;
  border-radius: 5px;
  background: var(--panel-2);
  color: var(--muted);
}
.issue .quote-line { margin-top: 4px; font-style: italic; }
.issue .truth-line { margin-top: 4px; color: var(--good); font-size: 11.5px; }

/* Labelled-paragraph editor for strengths / areas */
.labelled-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 8px; }
.labelled-item {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 10px 12px;
  background: var(--bg);
  position: relative;
  animation: slideIn 0.22s ease-out both;
}
.labelled-item input.topic {
  width: 100%;
  font-weight: 500;
  font-size: 12.5px;
  background: transparent;
  border: none;
  border-bottom: 1px dashed var(--border);
  padding: 4px 0;
  margin-bottom: 6px;
  color: var(--fg);
}
.labelled-item input.topic:focus { outline: none; border-bottom-color: var(--accent); }
.labelled-item textarea.body, .labelled-item textarea.recommendation {
  width: 100%;
  background: transparent;
  border: none;
  padding: 4px 0;
  font-size: 12px;
  resize: vertical;
  color: var(--fg);
  min-height: 50px;
}
.labelled-item textarea.recommendation {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
  color: var(--fg-2);
  font-style: italic;
  min-height: 36px;
}
.labelled-item textarea:focus { outline: none; }
.labelled-item .li-rm {
  position: absolute; top: 6px; right: 8px;
  background: transparent; border: none;
  color: var(--muted); font-size: 14px; cursor: pointer;
  padding: 2px 6px; border-radius: 3px;
  opacity: 0; transition: opacity 0.15s ease, color 0.15s ease;
}
.labelled-item:hover .li-rm { opacity: 1; }
.labelled-item .li-rm:hover { color: var(--danger); background: var(--danger-soft); }
.ghost.small { padding: 4px 10px; font-size: 11px; }

/* One-page summary — same shell as .review-output (the .summary-output
   modifier just lets us add summary-only tweaks later without touching
   .review-output). Bullet lists below get accent-coloured markers per
   kind (valuable/questionable) so the user can scan severity at a
   glance without reading the section title. */
.summary-output { /* inherits .review-output card styling */ }

.summary-list {
  margin: 0;
  padding-left: 22px;
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--fg);
}
.summary-list .summary-li { margin: 6px 0; padding-left: 4px; }
.summary-list.valuable     .summary-li::marker { color: var(--good);    font-size: 1.1em; }
.summary-list.questionable .summary-li::marker { color: var(--warning); font-size: 1.1em; }
.summary-list.neutral      .summary-li::marker { color: var(--accent);  font-size: 1.1em; }

.summary-takeaway-card {
  display: block;
  margin-top: 8px;
  padding: 18px 22px;
  background:
    radial-gradient(ellipse at top right, var(--accent-soft), transparent 60%),
    var(--panel-2);
  border: 1px solid var(--accent-line);
  border-radius: 12px;
  position: relative;
  overflow: hidden;
}
.summary-takeaway-card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; bottom: 0; width: 3px;
  background: var(--accent);
}
.summary-takeaway-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 8px;
}
.summary-takeaway-body {
  font-family: 'Iowan Old Style', 'Georgia', 'Cambria', serif;
  font-style: italic;
  font-size: 16px;
  line-height: 1.55;
  color: var(--fg);
}

/* ============================================================
   TRAINER — slider-style selectors + practice card
   ============================================================ */

.trainer-setup-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 14px;
}
.trainer-setup-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Slider — same affordance as .profile-picker but with finer hint text. */
.trainer-slider {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 4px;
}
.trainer-slider-compact {
  grid-template-columns: repeat(3, 1fr);
}
.trainer-slider-opt {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 10px 8px;
  border-radius: 9px;
  cursor: pointer;
  text-align: center;
  transition: background-color 140ms ease, color 140ms ease;
  user-select: none;
}
.trainer-slider-opt:hover { background: var(--panel); }
.trainer-slider-opt input { position: absolute; opacity: 0; pointer-events: none; }
.trainer-slider-opt.active,
.trainer-slider-opt:has(input:checked) {
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}
.trainer-slider-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--fg);
}
.trainer-slider-opt.active .trainer-slider-label,
.trainer-slider-opt:has(input:checked) .trainer-slider-label { color: var(--accent); }
.trainer-slider-hint {
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.005em;
}
.trainer-slider-opt[data-free="1"] .trainer-slider-hint {
  color: var(--good);
  font-weight: 700;
}

/* Note shown beneath the count slider — pricing context (free pack
   eligibility, balance shortfall, etc.) populated by TRAINER._refreshQuote(). */
.trainer-quote-note {
  margin-top: 10px;
  font-size: 12px;
  color: var(--muted);
  line-height: 1.45;
}
.trainer-quote-note[data-state="freebie"] {
  color: var(--good);
}
.trainer-quote-note[data-state="shortfall"] {
  color: var(--warning);
}

/* Practice session ── one-question card flow. */
.trainer-session-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-soft);
}
.trainer-session-progress {
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-feature-settings: 'tnum' 1;
}
.trainer-session-level {
  font-size: 12px;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 3px 8px;
  border-radius: 6px;
  letter-spacing: 0.02em;
}
.trainer-session-head .ghost.small {
  margin-left: auto;
}

.trainer-card {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 24px 26px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.trainer-question {
  font-family: 'Manrope', 'Inter', sans-serif;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.4;
  color: var(--fg);
}
.trainer-quote {
  padding: 10px 14px;
  border-left: 2px solid var(--accent-line);
  background: var(--accent-soft);
  border-radius: 0 8px 8px 0;
  font-size: 13px;
  color: var(--fg-2);
  font-style: italic;
}
.trainer-quote .trainer-quote-line {
  font-style: normal;
  font-weight: 700;
  color: var(--accent);
  margin-right: 6px;
  font-feature-settings: 'tnum' 1;
}

.trainer-attempts {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.trainer-attempts-dots {
  display: inline-flex;
  gap: 4px;
}
.trainer-attempts-dots .trainer-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--border);
}
.trainer-attempts-dots .trainer-dot.used { background: var(--warning); }
.trainer-attempts-dots .trainer-dot.current {
  background: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}

.trainer-answer {
  width: 100%;
  resize: vertical;
  min-height: 110px;
  padding: 12px 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-family: inherit;
  font-size: 14px;
  line-height: 1.55;
  color: var(--fg);
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.trainer-answer:focus {
  outline: none;
  border-color: var(--accent-line);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.trainer-action-row {
  display: flex;
  gap: 10px;
  align-items: center;
}
.trainer-action-row .ghost { margin-left: auto; }

.trainer-hints {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.trainer-hint {
  padding: 10px 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-left: 3px solid var(--warning);
  border-radius: 0 8px 8px 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--fg);
  animation: hintIn 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.trainer-hint .trainer-hint-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--warning);
  margin-right: 8px;
}
.trainer-hint.verdict-correct {
  border-left-color: var(--good);
  background: var(--good-soft);
}
.trainer-hint.verdict-correct .trainer-hint-label {
  color: var(--good);
}
.trainer-hint.verdict-close {
  border-left-color: var(--warning);
  background: var(--warning-soft);
}
.trainer-hint.verdict-close .trainer-hint-label {
  color: var(--warning);
}
.trainer-hint.verdict-wrong {
  border-left-color: var(--danger);
  background: var(--danger-soft);
}
.trainer-hint.verdict-wrong .trainer-hint-label {
  color: var(--danger);
}
@keyframes hintIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.trainer-reveal {
  margin-top: 4px;
  padding: 18px 20px;
  background:
    radial-gradient(ellipse at top right, var(--accent-soft), transparent 60%),
    var(--panel);
  border: 1px solid var(--accent-line);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.trainer-reveal-headline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.trainer-reveal-head {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.trainer-reveal-body {
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--fg);
}
.trainer-reveal-warn {
  padding: 10px 12px;
  background: var(--warning-soft);
  border-left: 2px solid var(--warning);
  border-radius: 0 6px 6px 0;
  font-size: 13px;
  color: var(--fg-2);
}
.trainer-reveal-warn::before {
  content: "Чего избегать · ";
  color: var(--warning);
  font-weight: 700;
}
.trainer-reveal-rubric-head {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--fg-2);
  margin-top: 4px;
}
.trainer-reveal-rubric {
  margin: 0;
  padding-left: 22px;
  font-size: 13.5px;
  color: var(--fg);
  line-height: 1.55;
}
.trainer-reveal-rubric li { margin: 3px 0; }
.trainer-reveal-rubric li::marker { color: var(--accent); }

/* Attention points — follow-up risks to be ready for. Visually distinct
   from the rubric: warning-coloured headers, danger marker on each item.
   The wording «осторожно — могут зацепиться» is a friendly framing of
   what's basically «а вот тут вас могут поджарить», so the user reads
   it as a useful prep list, not a scary list. */
.trainer-reveal-attention-head {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--warning);
  margin-top: 6px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.trainer-reveal-attention-head::before {
  content: "⚐";
  font-size: 14px;
  color: var(--warning);
  filter: saturate(1.2);
}
.trainer-reveal-attention {
  margin: 0;
  padding-left: 22px;
  font-size: 13.5px;
  color: var(--fg);
  line-height: 1.55;
}
.trainer-reveal-attention li {
  margin: 6px 0;
  padding-left: 4px;
}
.trainer-reveal-attention li::marker {
  color: var(--warning);
  font-size: 1.1em;
}

.trainer-next-row {
  display: flex;
  justify-content: flex-end;
}

.trainer-session-foot {
  margin-top: 18px;
  padding: 22px;
  text-align: center;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  align-items: center;
}
.trainer-done-msg {
  font-family: 'Manrope', 'Inter', sans-serif;
  font-weight: 600;
  font-size: 15px;
  color: var(--fg);
}

/* ============================================================
   BUSY-STRIP — inline progress indicator for slow LLM calls.
   Lives inside any tab panel; toggled by the BUSY module in app.js.
   Visible while a long call is in flight: spinner + label/hint +
   live elapsed counter + indeterminate bar (so the user sees motion
   even when the LLM is silent for 60+ seconds).
   ============================================================ */
.busy-strip {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  margin: 12px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  position: relative;
  overflow: hidden;
}
.busy-spinner {
  flex-shrink: 0;
  width: 18px; height: 18px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: busy-spin 0.85s linear infinite;
}
@keyframes busy-spin {
  to { transform: rotate(360deg); }
}
.busy-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.busy-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--fg);
}
.busy-hint {
  font-size: 11.5px;
  color: var(--muted);
  letter-spacing: 0.005em;
}
.busy-elapsed {
  font-feature-settings: 'tnum' 1;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
  min-width: 38px;
  text-align: right;
}
/* Indeterminate bar at the bottom of the strip — pure CSS animation
   so we don't have to drive it from JS. Two phases: a slow drift
   left-to-right, then a fast catch-up right-to-left, repeating. */
.busy-bar {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--border);
  overflow: hidden;
}
.busy-bar-fill {
  position: absolute;
  top: 0; bottom: 0;
  left: 0;
  width: 30%;
  background: linear-gradient(
    90deg,
    transparent,
    var(--accent),
    transparent
  );
  animation: busy-bar-drift 1.6s ease-in-out infinite;
}
@keyframes busy-bar-drift {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(400%); }
}

/* ============================================================
   TITLE-CONFIRM MODAL — runs once after every upload
   Reuses .cabinet-modal shell; just tweaks card width + body.
   ============================================================ */
.title-confirm-card {
  width: min(520px, calc(100vw - 32px));
}
.title-confirm-body {
  padding: 22px 24px 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.title-confirm-note {
  margin: 0;
  font-size: 13px;
  color: var(--fg-2);
  line-height: 1.55;
}
.title-confirm-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 4px;
}
.title-confirm-input {
  width: 100%;
  resize: vertical;
  min-height: 70px;
  padding: 12px 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--fg);
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.title-confirm-input:focus {
  outline: none;
  border-color: var(--accent-line);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.title-confirm-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11px;
  letter-spacing: 0.005em;
}
.title-confirm-source {
  color: var(--muted);
  font-style: italic;
}
.title-confirm-counter {
  color: var(--muted);
  font-feature-settings: 'tnum' 1;
}
.title-confirm-foot {
  display: flex;
  justify-content: flex-end;
  padding: 12px 24px 22px;
  border-top: 1px solid var(--border-soft);
}
.title-confirm-foot .primary { min-width: 200px; }

.metaphor-card {
  margin-top: 18px;
  padding: 20px 24px;
  background:
    radial-gradient(ellipse at top left, var(--accent-soft), transparent 60%),
    linear-gradient(135deg, var(--panel-2), var(--panel));
  border: 1px solid var(--accent-line);
  border-radius: 6px;
  position: relative;
  overflow: hidden;
  animation: fadeIn 0.5s ease-out both;
}
.metaphor-card::before {
  content: "";
  position: absolute; top: 0; left: -40%; right: -40%; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent-line), transparent);
  background-size: 200% 100%;
  animation: drift 9s linear infinite;
}
.metaphor-card::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle at 80% 120%, var(--accent-soft), transparent 55%);
  pointer-events: none;
}
.metaphor-label {
  font-size: 12px; font-weight: 600; letter-spacing: -0.005em;
  color: var(--accent); margin-bottom: 12px;
}
.metaphor-text {
  font-family: 'Iowan Old Style', 'Georgia', 'Cambria', serif;
  font-style: italic;
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--fg);
  letter-spacing: 0.005em;
}

/* Review integrity panel */
.health-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
@media (max-width: 900px) { .health-grid { grid-template-columns: 1fr; } }
.health-col {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
  background: var(--bg);
}
.health-col-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px; font-weight: 600; letter-spacing: -0.01em;
  color: var(--fg); margin-bottom: 12px;
}
.health-col-head .ghost.small { padding: 3px 10px; font-size: 10.5px; }
.health-row {
  display: grid;
  grid-template-columns: 12px 1fr auto;
  gap: 8px 10px;
  padding: 7px 0;
  border-top: 1px solid var(--border);
  align-items: start;
}
.health-row:first-child { border-top: none; }
.health-dot {
  width: 8px; height: 8px; border-radius: 50%; margin-top: 5px;
}
.health-dot.ok { background: var(--good); box-shadow: 0 0 6px -1px rgba(124,198,154,0.6); }
.health-dot.watch { background: var(--warning); }
.health-dot.flag { background: var(--danger); animation: pulseDanger 2s ease-in-out infinite; }
.health-main .lbl-inline { font-size: 11.5px; color: var(--fg); }
.health-main .val { font-size: 11px; color: var(--muted); margin-top: 2px; }
.health-sev {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted);
}
.health-sev.ok { color: var(--good); }
.health-sev.watch { color: var(--warning); }
.health-sev.flag { color: var(--danger); }
.health-empty { font-size: 11.5px; color: var(--muted); padding: 12px 0; text-align: center; }
.health-score {
  float: right;
  font-size: 11.5px; font-weight: 500; letter-spacing: -0.005em;
  padding: 3px 10px; border-radius: 6px;
  background: var(--panel-2); color: var(--muted);
}
.health-score.all-green { background: var(--good-soft); color: var(--good); }
.health-score.has-issues { background: var(--warning-soft); color: var(--warning); }

/* Authenticity panel */
.auth-row {
  display: grid;
  grid-template-columns: 14px 1fr auto;
  gap: 10px 12px;
  padding: 10px 0;
  border-top: 1px solid var(--border);
  align-items: start;
  animation: slideIn 0.25s ease-out both;
}
.auth-row:first-child { border-top: none; }
.auth-dot {
  width: 8px; height: 8px; border-radius: 50%;
  margin-top: 6px;
}
.auth-dot.ok   { background: var(--good);    box-shadow: 0 0 8px -1px rgba(124,198,154,0.6); }
.auth-dot.watch{ background: var(--warning); box-shadow: 0 0 8px -1px rgba(244,178,102,0.6); }
.auth-dot.flag { background: var(--danger);  box-shadow: 0 0 8px -1px rgba(229,107,111,0.7); animation: pulseDanger 1.8s ease-in-out infinite; }
@keyframes pulseDanger {
  0%, 100% {
    box-shadow:
      0 0 0 0 var(--danger-soft),
      0 0 8px -1px var(--danger-soft);
  }
  50% {
    box-shadow:
      0 0 0 6px transparent,
      0 0 16px 0 var(--danger-soft);
  }
}
.auth-main .lbl-inline { font-size: 12px; color: var(--fg); font-weight: 500; }
.auth-main .val { font-size: 12px; color: var(--muted); margin-top: 2px; }
.auth-main .detail { font-size: 11.5px; color: var(--muted); margin-top: 4px; font-style: italic; }
.auth-sev { font-size: 11.5px; font-weight: 500; letter-spacing: -0.005em; color: var(--muted); }
.auth-sev.ok    { color: var(--good); }
.auth-sev.watch { color: var(--warning); }
.auth-sev.flag  { color: var(--danger); }

/* Questions panel */
.chip-row { display: flex; gap: 8px; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: var(--panel-2);
  font-size: 11.5px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.chip:hover { border-color: var(--accent-line); }
.chip input { margin: 0; }
.chip input:checked ~ * { color: var(--accent); }

.question {
  padding: 14px 0;
  border-top: 1px solid var(--border);
  animation: slideIn 0.3s ease-out both;
}
.question:first-child { border-top: none; }
.question .q-meta { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; }
.question .q-level {
  font-size: 11.5px; font-weight: 500; letter-spacing: -0.005em;
  padding: 3px 10px; border-radius: 6px;
}
.q-level.protocol    { background: var(--good-soft);    color: var(--good); }
.q-level.substantive { background: var(--accent-soft);  color: var(--accent); }
.q-level.challenging { background: var(--danger-soft);  color: var(--danger); }
.question .q-text { font-size: 13px; color: var(--fg); line-height: 1.6; margin-bottom: 8px; font-weight: 500; }
.question .q-where { font-size: 11.5px; color: var(--muted); margin-bottom: 8px; }
.question .q-where .q { color: var(--good); cursor: pointer; }
.question .q-where .q:hover { text-decoration: underline; }
.question .q-expect { font-size: 12px; color: var(--fg-2); margin-bottom: 6px; }
.question .q-warn { font-size: 11.5px; color: var(--warning); }
.question .q-expect strong, .question .q-warn strong {
  display: inline-block; min-width: 120px;
  font-weight: 500; color: var(--muted);
  letter-spacing: -0.005em; font-size: 12px;
}

.spinner {
  display: inline-block;
  width: 10px; height: 10px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
  margin-right: 6px;
  vertical-align: -1px;
}
@keyframes spin { to { transform: rotate(360deg); } }


/* ============================================================
   Theme + pronoun toggles in header
   ============================================================ */

.theme-toggle,
.pronoun-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0;
  padding: 6px 10px;
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  line-height: 1;
}

.theme-toggle svg { display: block; color: var(--fg-2); transition: color 150ms; }
.theme-toggle:hover svg { color: var(--accent); }

[data-theme="dark"]  .theme-icon-moon { display: none; }
[data-theme="light"] .theme-icon-sun  { display: none; }

.pronoun-toggle .pronoun-formal,
.pronoun-toggle .pronoun-casual {
  opacity: 0.42;
  transition: opacity 150ms ease, color 150ms ease;
  color: var(--fg-2);
}
.pronoun-toggle .pronoun-sep {
  margin: 0 5px;
  opacity: 0.28;
  color: var(--fg-2);
}
:root[data-pronoun="formal"] .pronoun-toggle .pronoun-formal,
:root[data-pronoun="casual"] .pronoun-toggle .pronoun-casual {
  opacity: 1;
  color: var(--accent);
  font-weight: 600;
}

/* View Transitions API: circular reveal from the click point on theme switch.
   Browsers without support fall back to instant swap (no JS check needed —
   document.startViewTransition just runs the callback synchronously). */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}
::view-transition-new(root) {
  animation: theme-clip 380ms cubic-bezier(0.4, 0, 0.2, 1);
}
::view-transition-old(root) {
  animation: theme-fade 380ms cubic-bezier(0.4, 0, 0.2, 1);
}
@keyframes theme-clip {
  from { clip-path: circle(0 at var(--theme-x, 50%) var(--theme-y, 50%)); }
  to   { clip-path: circle(150% at var(--theme-x, 50%) var(--theme-y, 50%)); }
}
@keyframes theme-fade {
  from { opacity: 1; }
  to   { opacity: 0.85; }
}

/* Info icon on each criterion — surfaces original English wording + source */
.info-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 6px;
  width: 16px;
  height: 16px;
  font-size: 12px;
  line-height: 1;
  color: var(--fg-2);
  border-radius: 50%;
  cursor: help;
  vertical-align: -1px;
  transition: color 120ms ease, background 120ms ease;
  user-select: none;
  outline: none;
}
.info-icon:hover,
.info-icon:focus,
.info-icon:focus-visible {
  color: var(--accent);
  background: var(--accent-soft);
  outline: none;
  box-shadow: none;
}

/* Custom tooltip — shows on hover/focus, no 1-second native delay.
   data-tip = English wording; data-tip-source = standard reference. */
.info-icon::after {
  content: attr(data-tip) "\A\A" "Источник: " attr(data-tip-source);
  white-space: pre-wrap;
  position: absolute;
  z-index: 1000;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(-4px);
  width: max-content;
  max-width: 380px;
  padding: 12px 14px;
  background: var(--panel);              /* fully opaque card surface */
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-family: 'Inter', sans-serif;
  font-size: 12.5px;
  line-height: 1.5;
  text-align: left;
  font-weight: 400;
  box-shadow:
    var(--shadow-2),
    0 0 0 1px var(--border-soft);
  opacity: 0;
  pointer-events: none;
  transition: opacity 120ms ease, transform 120ms ease;
}
.info-icon:hover::after,
.info-icon:focus::after,
.info-icon:focus-visible::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* Edge-of-panel: when the icon is near the right edge, anchor tooltip to right */
.info-icon[data-tip-side="right"]::after {
  left: auto;
  right: 0;
  transform: translateY(-4px);
}
.info-icon[data-tip-side="right"]:hover::after {
  transform: translateY(0);
}

/* ============================================================
   Article view — left rail with line numbers (no [L<n>] brackets)
   ============================================================ */

.article {
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  line-height: 1.62;
}

/* Article view — root container around the rendered .docx */
.article-doc { display: flex; flex-direction: column; gap: 0; }

.article-line {
  display: grid;
  grid-template-columns: 42px 1fr;
  align-items: baseline;
  gap: 14px;
  padding: 2px 0;
  scroll-margin-top: 80px;
  transition: background-color 200ms ease;
  border-radius: 3px;
}
.article-line .line-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10.5px;
  color: var(--muted);
  text-align: right;
  user-select: none;
  padding-top: 0.4em;       /* visually align rail with text baseline */
  letter-spacing: 0;
  transition: color 120ms ease;
}
.article-line:hover .line-num { color: var(--accent); }
.article-line.continuation .line-num { /* empty placeholder for non-marker lines */ }
.article-line .line-content {
  display: block;
  word-wrap: break-word;
  overflow-wrap: break-word;
}

.article-line.hl {
  background: var(--accent-soft);
  animation: hl-fade 2s ease-out;
}
@keyframes hl-fade {
  0%   { background: var(--accent-soft); }
  60%  { background: var(--accent-soft); }
  100% { background: transparent; }
}

/* ---------- headings ---------- */
.article-heading { padding-top: 18px; padding-bottom: 6px; }
.article-heading + .article-heading { padding-top: 8px; }  /* tighter when stacked */
.article-h1 .line-content {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--fg);
  line-height: 1.25;
}
.article-h2 .line-content {
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--fg);
  line-height: 1.3;
}
.article-h3 .line-content {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--fg);
  line-height: 1.35;
}
.article-h4 .line-content,
.article-h5 .line-content,
.article-h6 .line-content {
  font-size: 13px;
  font-weight: 600;
  color: var(--fg-2);
}

/* ---------- paragraphs ---------- */
.article-paragraph { padding: 3px 0; }
.article-paragraph .line-content {
  color: var(--fg);
  line-height: 1.62;
}
.article-paragraph .line-content b { font-weight: 650; color: var(--fg); }
.article-paragraph .line-content i { font-style: italic; }

/* ---------- lists ---------- */
.article-list-item {
  padding: 2px 0;
}
.article-list-item .line-content {
  color: var(--fg);
  line-height: 1.55;
  position: relative;
  padding-left: 16px;
}
.article-list-bullet .line-content::before {
  content: "•";
  position: absolute;
  left: 0;
  color: var(--accent);
  font-weight: 700;
}
.article-list-numbered .line-content::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--muted);
}

/* ---------- tables ---------- */
.article-table {
  margin: 16px 0;
  border-collapse: collapse;
  width: 100%;
  font-size: 12.5px;
  background: var(--panel-2);
  border-radius: 8px;
  overflow: hidden;
}
.article-table tr.article-tr {
  display: grid;
  grid-template-columns: 42px repeat(auto-fit, minmax(80px, 1fr));
  gap: 14px;
  padding: 0;
  background: transparent;
}
.article-table td.line-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10.5px;
  color: var(--muted);
  text-align: right;
  padding: 8px 0;
  user-select: none;
  border: none;
  background: transparent;
}
.article-table td:not(.line-num) {
  padding: 8px 12px;
  color: var(--fg);
  border-top: 1px solid var(--border-soft);
  line-height: 1.5;
}
.article-table tr:first-child td:not(.line-num) {
  border-top: none;
  font-weight: 600;
  color: var(--fg);
  background: var(--panel);
}
.article-table tr.article-tr:hover { background: var(--accent-soft); }
.article-table tr.article-tr:hover td.line-num { color: var(--accent); }

/* Evidence chip line-number badge (replaces [L<n>] brackets) */
.evidence .q-line {
  display: inline-block;
  padding: 1px 6px;
  margin-right: 4px;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 500;
}

/* ============================================================
   TABS — sticky nav inside #right
   Each tab = one analytical action. Underline-style,
   minimalist, with the same drifting gradient we use elsewhere.
   ============================================================ */
.tabs {
  position: sticky;
  /* Sticky offsets are measured from the padding-box of the scroll
     container. #right has padding-top: 20px, so top:0 would pin 20px
     below the border edge and let upstream content peek through that
     strip. Using -20px compensates so the tabs sit flush at y=0. */
  top: -20px;
  z-index: 10;
  display: flex;
  gap: 2px;
  margin: -20px -24px 22px;        /* bleed past #right's padding */
  padding: 20px 24px 0;            /* eat the padding zone with bg color */
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.tabs::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: linear-gradient(
    90deg, transparent 0%, var(--accent-line) 50%, transparent 100%);
  background-size: 200% 100%;
  animation: drift 11s linear infinite;
  opacity: 0.45;
  pointer-events: none;
}
.tab {
  background: transparent;
  border: none;
  padding: 10px 14px 12px;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
  border-radius: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  letter-spacing: -0.005em;
  transition: color 0.18s ease, border-color 0.18s ease;
}
.tab:hover {
  color: var(--fg);
  background: transparent;
  border-color: transparent transparent var(--border) transparent;
}
.tab.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.tab-panel { display: none; animation: fadeIn 0.32s ease-out both; }
.tab-panel.active { display: block; }

/* ============================================================
   PROFILE PICKER — two cards, single radio choice
   Sits at the top of the Скоринг tab.
   ============================================================ */
/* Score-tab controls — picker + run-CTA in one horizontal row.
   Picker grows to fill, button keeps its content width. */
.score-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 18px;
}
.score-controls .profile-picker { flex: 1; margin-bottom: 0; }
.score-controls .big-cta        { margin-bottom: 0; flex-shrink: 0; }

.profile-picker {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-bottom: 12px;
}
.profile-option {
  position: relative;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 9px;
  background: var(--panel);
  cursor: pointer;
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
  transition:
    border-color 0.18s ease, background 0.18s ease,
    box-shadow 0.22s ease, transform 0.08s ease;
}
.profile-option:hover { border-color: var(--accent-line); }
.profile-option:active { transform: scale(0.995); }
.profile-option input { position: absolute; opacity: 0; pointer-events: none; }
.profile-option.active,
.profile-option:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: 0 0 0 1px var(--accent-line);
}
.profile-name {
  font-weight: 600; font-size: 12.5px; color: var(--fg);
  letter-spacing: -0.005em;
}
.profile-option.active .profile-name,
.profile-option:has(input:checked) .profile-name { color: var(--accent); }
.profile-desc { font-size: 11px; color: var(--muted); }

/* ============================================================
   BIG CTA — block-level primary button with arrow micro-motion
   ============================================================ */
.big-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;                /* no longer a full-width pill */
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.005em;
  border-radius: 8px;
  margin-bottom: 18px;
}
.big-cta .cta-arrow {
  display: inline-block;
  font-weight: 500;
  font-size: 13.5px;
  transition: transform 0.22s ease;
}
.big-cta:hover .cta-arrow { transform: translate(2px, -2px); }

/* Inline price hint under «Сделать резюме» / «Сгенерировать рецензию».
   Sits below the CTA so the user always sees what a click costs before
   pressing it — without this, single-click tools (4-8 кр) felt «free»
   compared to the «Запустить анализ» modal that surfaces a price up-front. */
.cta-price-hint {
  font-size: 12.5px;
  color: var(--muted);
  letter-spacing: -0.005em;
  /* Sits to the right of the CTA in the flex row — no negative margins
     pulling it under the button anymore. */
}
/* Inline variant for the score-controls row — the «Запустить анализ»
   button shares a flex row with the profile picker, so the hint hangs
   under the button instead of below a centred CTA. */
.cta-price-hint-inline {
  text-align: right;
  margin-top: 6px;
  margin-bottom: 0;
}
/* Shortfall state — caller adds the class when balance < required. */
.cta-price-hint-shortfall {
  color: var(--accent);
  font-weight: 600;
}

.action-row {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-bottom: 18px; align-items: center;
}
.action-row .big-cta { margin: 0; }

/* ============================================================
   ANALYSIS MODAL — appears during scoring (multi-minute wait UX)
   Frosted-glass backdrop + bottom-right card with:
     · Журнал наблюдений (thought log)
     · concrete progress bar (counter + percentage)
     · ETA rounded to minutes
     · constellation animation
   ============================================================ */
.analysis-modal {
  position: fixed; inset: 0; z-index: 200;
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.28s ease, visibility 0.28s ease;
}
.analysis-modal[aria-hidden="false"] {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
}

.analysis-modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(13, 13, 13, 0.34);
  backdrop-filter: blur(8px) saturate(120%);
  -webkit-backdrop-filter: blur(8px) saturate(120%);
}
[data-theme="light"] .analysis-modal-backdrop {
  background: rgba(245, 245, 247, 0.55);
}

.analysis-modal-card {
  position: absolute;
  /* JS sets left/top/width/height each open() and on resize, centered on
     the viewport. Defaults below cover the brief moment before JS runs. */
  left: 50%; top: 50%;
  width: min(820px, 80vw);
  height: min(420px, 68vh);
  transform: translate(-50%, -50%) translateY(24px);
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 20px;
  box-shadow:
    0 32px 80px -24px rgba(0, 0, 0, 0.60),
    0 12px 28px -12px rgba(0, 0, 0, 0.40),
    0 0 0 1px var(--border-soft);
  padding: 22px 24px 18px;
  opacity: 0;
  transition:
    transform 0.42s cubic-bezier(0.2, 0.8, 0.2, 1),
    opacity   0.42s cubic-bezier(0.2, 0.8, 0.2, 1);
}
[data-theme="light"] .analysis-modal-card {
  box-shadow:
    0 32px 80px -24px rgba(0, 0, 0, 0.18),
    0 12px 28px -12px rgba(0, 0, 0, 0.10),
    0 0 0 1px var(--border-soft);
}
.analysis-modal[aria-hidden="false"] .analysis-modal-card {
  transform: translate(-50%, -50%);
  opacity: 1;
}

/* Two-column body: thoughts (left) | progress + constellation (right) */
.analysis-modal-body {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 18px;
  min-height: 0;                   /* let grid children actually shrink */
}
.analysis-modal-right-col {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 0;
}

.analysis-modal-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 14px;
  flex-shrink: 0;
}
.analysis-modal-title {
  font-family: 'Manrope', sans-serif;
  font-size: 16px; font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--fg);
  display: inline-flex; align-items: center; gap: 9px;
}
.analysis-modal-title::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
  animation: busybreathe 1.05s ease-in-out infinite;
}
.analysis-modal-eta {
  font-size: 11.5px; font-weight: 500;
  color: var(--muted);
  letter-spacing: -0.005em;
  font-feature-settings: 'tnum' on;        /* tabular digits — no jitter */
}

/* Foot note — «можно закрыть, пришлём письмо» reassurance.
   Sits below the body so users see it once they've taken in the
   running thoughts + progress + animation. */
.analysis-modal-foot {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid rgba(255,255,255,0.07);
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted);
  text-align: center;
  flex-shrink: 0;
}
[data-theme="light"] .analysis-modal-foot {
  border-top-color: rgba(0,0,0,0.07);
}

/* Журнал наблюдений ------------------------------------------- */
.analysis-thoughts {
  display: flex;
  flex-direction: column;
  border-radius: 12px;
  background: var(--panel-2);
  padding: 12px 14px 8px;
  border: 1px solid var(--border-soft);
  min-height: 0;
}
.analysis-thoughts-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 500;
  color: var(--muted);
  margin-bottom: 8px;
  flex-shrink: 0;
}
.analysis-thoughts-list {
  list-style: none;
  margin: 0; padding: 0;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--fg-2);
  flex: 1;
  min-height: 0;
  overflow: hidden;
  position: relative;
  mask-image: linear-gradient(
    to bottom, #000 0, #000 78%, transparent 100%);
  -webkit-mask-image: linear-gradient(
    to bottom, #000 0, #000 78%, transparent 100%);
}
.analysis-thoughts-list li {
  padding: 3px 0;
  display: flex; gap: 8px; align-items: baseline;
  animation: thoughtIn 0.55s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.analysis-thoughts-list li::before {
  content: "·";
  color: var(--accent);
  font-weight: 700;
  flex-shrink: 0;
}
.analysis-thoughts-list li.fresh { color: var(--fg); }
@keyframes thoughtIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Concrete progress bar ---------------------------------------- */
.analysis-progress { flex-shrink: 0; }
.analysis-progress-meta {
  display: flex; justify-content: space-between;
  font-size: 11.5px; color: var(--muted);
  margin-bottom: 8px;
  letter-spacing: -0.003em;
  font-feature-settings: 'tnum' on;
}
.analysis-progress-meta #analysis-phase-label {
  color: var(--fg-2); font-weight: 500;
}
.analysis-progress-bar {
  height: 6px;
  border-radius: 3px;
  background: var(--panel-2);
  overflow: hidden;
  position: relative;
}
.analysis-progress-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--accent), var(--accent-hover));
  border-radius: 3px;
  position: relative;
  transition: width 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
  box-shadow: 0 0 8px -2px var(--accent);
}
.analysis-progress-fill::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(
    90deg, transparent 20%, rgba(255, 255, 255, 0.28) 50%, transparent 80%);
  animation: shimmer 1.8s linear infinite;
}
@keyframes shimmer {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%);  }
}

/* Constellation ------------------------------------------------ */
.analysis-animation {
  flex: 1;
  min-height: 80px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  /* color drives `currentColor` in the SVG's radialGradient stops so the
     nebula tints to the active accent (and follows theme switches). */
  color: var(--accent);
}
.constellation {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;     /* let halos breathe past the viewBox */
}

/* Nebula glow — a soft radial gradient that breathes behind everything */
.constellation .cnebula {
  transform-origin: center;
  transform-box: view-box;
  animation: nebulaShift 9s ease-in-out infinite;
}
@keyframes nebulaShift {
  0%, 100% { opacity: 0.32; transform: scale(0.94); }
  50%      { opacity: 0.62; transform: scale(1.08); }
}

/* Skeleton lines — bezier curves that draw in once, then breathe softly.
   Opacity-only breathe (no stroke-width) keeps paint cost reasonable when
   ~110 lines all animate simultaneously. */
.constellation .cline {
  stroke: var(--accent-line);
  stroke-width: 0.55;
  fill: none;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  opacity: 0;            /* hidden until our --d delay so unappeared lines stay invisible */
  animation:
    lineDraw    1.1s cubic-bezier(0.2, 0.8, 0.2, 1) var(--d, 0s) forwards,
    lineBreathe 5.4s ease-in-out calc(var(--d, 0s) + 1.6s) infinite;
}
@keyframes lineDraw {
  0%   { opacity: 0; stroke-dashoffset: 100; }
  3%   { opacity: 0.65; }
  100% { opacity: 0.65; stroke-dashoffset: 0; }
}
@keyframes lineBreathe {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 0.95; }
}

/* Halo rings — large soft rings rippling outward from each node, staggered */
.constellation .chalo {
  fill: none;
  stroke: var(--accent);
  stroke-width: 0.9;
  opacity: 0;
  transform-origin: center;
  transform-box: fill-box;
  animation: haloRipple 4.0s ease-out calc(var(--d, 0s) + 3.4s) infinite;
}
@keyframes haloRipple {
  0%   { transform: scale(0.5); opacity: 0;   stroke-width: 1.4; }
  18%  { opacity: 0.55; }
  100% { transform: scale(3.6); opacity: 0;   stroke-width: 0.2; }
}

/* Core dots — the stable structure of the graph */
.constellation .cdot {
  fill: var(--accent);
  opacity: 0;
  filter: drop-shadow(0 0 1.8px var(--accent));
  animation: dotIn 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) var(--d, 0s) forwards;
}
@keyframes dotIn { from { opacity: 0; } to { opacity: 0.85; } }

/* Traveling pulses — bright glowing dots walking along each curve */
.constellation .cpulse {
  fill: var(--accent);
  opacity: 0.95;
  filter:
    drop-shadow(0 0 3px var(--accent))
    drop-shadow(0 0 1.2px var(--accent));
}

/* ============================================================
   CABINET — balance pill + credits modal
   The pill lives in header .actions; the modal is centered
   over the page when opened.
   ============================================================ */

/* Auth pill — «Войти» when anonymous, email when signed in. Lives next
   to the credits pill in the header. */
.auth-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  font-weight: 500;
}
.auth-pill[data-state="signed_in"] {
  color: var(--fg);
}
.auth-pill[data-state="signed_in"]::before {
  content: "•";
  color: var(--good);
  margin-right: 2px;
}

.credits-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 8px;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  font-weight: 600;
  letter-spacing: 0.005em;
}
.credits-pill svg { color: var(--accent); flex-shrink: 0; }
.credits-pill .credits-pill-value { color: var(--fg); }
.credits-pill[data-low="1"] .credits-pill-value { color: var(--warning); }
.credits-pill[data-empty="1"] .credits-pill-value { color: var(--danger); }

/* Modal shell — same hide/show pattern as .analysis-modal (visibility +
   opacity, not display:none). Avoids the "card flows into normal layout
   at the bottom of the page" failure mode if the CSS file is cached
   old or the rule fails to load for any reason. */
.cabinet-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s ease, visibility 0.22s ease;
}
.cabinet-modal[aria-hidden="false"] {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
}

.cabinet-modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  animation: cabBackdropIn 200ms ease-out;
}
:root[data-theme="light"] .cabinet-modal-backdrop {
  background: rgba(20, 20, 25, 0.35);
}
@keyframes cabBackdropIn { from { opacity: 0; } to { opacity: 1; } }

/* ============================================================
   AUTH GATE — full-screen login view shown to anonymous visitors.
   Cabinet UI is hidden until a real user signs in. Reuses the
   .login-* form pieces below for the email input + states.
   ============================================================ */
.auth-gate {
  position: fixed;
  inset: 0;
  background:
    radial-gradient(ellipse at 30% 20%, var(--accent-soft), transparent 55%),
    radial-gradient(ellipse at 80% 80%, var(--accent-soft), transparent 60%),
    var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 16px;
  overflow-y: auto;
  z-index: 1;
}

.auth-gate-card {
  width: min(480px, 100%);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 36px 36px 28px;
  box-shadow: var(--shadow-2);
}
@media (max-width: 480px) {
  .auth-gate-card { padding: 28px 22px 22px; }
}

.auth-gate-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 22px;
  letter-spacing: -0.02em;
  margin-bottom: 8px;
  color: var(--fg);
}
.auth-gate-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  background: var(--accent);
  color: #fff;
  border-radius: 9px;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: -0.04em;
}
.auth-gate-tagline {
  margin: 0 0 24px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--fg-2);
}

.auth-gate-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.auth-gate-submit {
  margin-top: 12px;
  width: 100%;
}
.auth-gate-submit:disabled,
.auth-gate-submit[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
  background: var(--accent);
}

/* 152-ФЗ — explicit consent. Required tick before submit-enable;
   the active acceptance is legally stronger than passive «using
   the site = consent». */
.auth-consent {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 10px 0 4px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--fg-2);
  cursor: pointer;
  user-select: none;
}
.auth-consent-box {
  /* Make the native checkbox a bit bigger and align to the first
     line of the label text. Custom-checkboxed via accent-color
     so it tints peach in modern browsers; falls back to OS chrome
     in older ones. */
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  margin-top: 2px;
  accent-color: var(--accent);
  cursor: pointer;
}
.auth-consent-text a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.auth-consent-text a:hover {
  color: var(--accent-hover);
}

/* OAuth provider buttons (Google / VK) — quick-path above the email
   form. Each provider button is a brand-colored anchor; clicking
   navigates to /api/auth/{provider} which redirects out to consent. */
.oauth-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 14px;
}
.oauth-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  transition: filter 140ms ease, transform 100ms ease;
  user-select: none;
  cursor: pointer;
}
.oauth-btn:hover  { filter: brightness(1.08); }
.oauth-btn:active { transform: scale(0.99); }
.oauth-btn-google {
  background: #fff;
  color: #1f1f1f;
  border: 1px solid #dadce0;
}
:root[data-theme="dark"] .oauth-btn-google { color: #1f1f1f; }
.oauth-btn-vk {
  background: #0077FF;
  color: #fff;
  border: 1px solid #0077FF;
}

.oauth-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 6px 0 12px;
  color: var(--muted);
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.oauth-divider::before,
.oauth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border-soft);
}
.oauth-divider span {
  white-space: nowrap;
}

.auth-gate-disclaimer {
  margin: 24px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--border-soft);
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--muted);
  text-align: center;
}

/* Login-modal styling — magic-link flow. Reuses .cabinet-modal shell. */
.login-card { width: min(440px, calc(100vw - 32px)); }
.login-body {
  padding: 22px 24px 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.login-note {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--fg-2);
}
.login-edu-hint {
  margin: 0;
  padding: 10px 12px;
  font-size: 12.5px;
  background: var(--good-soft);
  border-left: 2px solid var(--good);
  border-radius: 0 8px 8px 0;
  color: var(--fg);
}
.login-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 4px;
}
.login-input {
  width: 100%;
  padding: 12px 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-family: inherit;
  font-size: 15px;
  color: var(--fg);
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.login-input:focus {
  outline: none;
  border-color: var(--accent-line);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.login-error {
  font-size: 13px;
  color: var(--danger);
  padding: 8px 12px;
  background: var(--danger-soft);
  border-radius: 8px;
}
.login-foot {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 24px 22px;
  border-top: 1px solid var(--border-soft);
}
.login-sent-icon {
  font-size: 36px;
  color: var(--accent);
  text-align: center;
  margin-bottom: 4px;
}
.login-sent-title {
  text-align: center;
  font-size: 22px;
  letter-spacing: -0.02em;
  margin: 0 0 6px;
  color: var(--fg);
}

.cabinet-modal-card {
  position: relative;        /* sits above backdrop via z-index */
  z-index: 1;
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow-2);
  transform: translateY(8px) scale(0.98);
  opacity: 0;
  transition: transform 240ms cubic-bezier(0.2, 0.8, 0.2, 1),
              opacity 240ms ease;
}
.cabinet-modal[aria-hidden="false"] .cabinet-modal-card {
  transform: translateY(0) scale(1);
  opacity: 1;
}

.cabinet-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 24px 14px;
  border-bottom: 1px solid var(--border-soft);
}
.cabinet-modal-title {
  font-size: 22px; letter-spacing: -0.02em;
}
.cabinet-modal-close {
  font-size: 22px;
  line-height: 1;
  width: 30px; height: 30px;
  padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px;
}

/* Big balance display */
.cabinet-balance {
  text-align: center;
  padding: 28px 24px 22px;
}
.cabinet-balance-num {
  font-size: 56px;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--fg);
  font-feature-settings: 'tnum' 1;
}
.cabinet-balance-label {
  margin-top: 6px;
  color: var(--fg-2);
  font-size: 13px;
  letter-spacing: 0.01em;
}
.cabinet-balance-meta {
  margin-top: 12px;
  font-size: 12px;
  color: var(--muted);
  min-height: 16px;
}
.cabinet-balance-meta a { color: var(--accent); text-decoration: none; }
.cabinet-balance-meta a:hover { text-decoration: underline; }

/* Section blocks */
.cabinet-section {
  padding: 18px 24px;
  border-top: 1px solid var(--border-soft);
}
.cabinet-section-head {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 12px;
}

/* Top-up packages — three vertical cards stacked on narrow widths,
   horizontal at >=420px modal width. */
.cabinet-packages {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
@media (max-width: 520px) {
  .cabinet-packages { grid-template-columns: 1fr; }
}
.cabinet-package {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 12px;
  text-align: center;
  cursor: pointer;
  transition: border-color 140ms ease, transform 100ms ease;
  font-family: inherit;
  color: inherit;
}
.cabinet-package:hover {
  border-color: var(--accent-line);
  transform: translateY(-1px);
}
.cabinet-package[data-discount="1"] {
  border-color: var(--accent-line);
}
.cabinet-package-credits {
  font-family: 'Manrope', 'Inter', sans-serif;
  font-weight: 800;
  font-size: 22px;
  letter-spacing: -0.01em;
  color: var(--fg);
  font-feature-settings: 'tnum' 1;
}
.cabinet-package-suffix {
  font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em;
  margin-top: 2px;
}
.cabinet-package-pages {
  margin-top: 6px;
  font-size: 11px;
  color: var(--muted);
  font-feature-settings: 'tnum' 1;
  letter-spacing: 0.005em;
}
.cabinet-package-price {
  margin-top: 8px;
  font-size: 13px; color: var(--fg-2);
  font-feature-settings: 'tnum' 1;
}

.cabinet-rate-note {
  margin: -4px 0 12px;
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.005em;
}

/* ============================================================
   WORKSPACE STATES — empty / locked actions / review output
   ============================================================ */

/* Hint shown inside #sections when no work is loaded yet — replaces
   the old #empty overlay so the right panel never looks blank. */
.needs-work-hint {
  margin: 18px 12px;
  padding: 16px 18px;
  border: 1px dashed var(--border);
  border-radius: 10px;
  color: var(--fg-2);
  font-size: 13px;
  text-align: center;
  background: var(--panel-2);
}

/* Buttons gated by [data-needs-work]: visually muted while disabled,
   pointer-events suppressed so the hover doesn't pretend they work. */
[data-needs-work][disabled],
[data-needs-work]:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  filter: saturate(0.65);
}

/* Center the primary CTA on tabs that don't have a profile picker beside
   it (Резюме, Рецензия). */
.cta-center {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 18px;          /* breathing room between CTA and inline price hint */
  padding: 22px 0 18px;
}

/* ============================================================
   REVIEW TAB — read-only output + disclaimer + gate notice
   ============================================================ */

/* Gate banner: shown above the «Сгенерировать рецензию» button until
   scoring is complete. Switches to a green «готово» state via
   data-state="ready" applied by app.js. */
.review-gate {
  margin: 12px 12px 18px;
  padding: 12px 16px;
  border-radius: 10px;
  background: var(--warning-soft);
  color: var(--fg);
  font-size: 13px;
  border-left: 3px solid var(--warning);
}
.review-gate[data-state="ready"] {
  background: var(--good-soft);
  border-left-color: var(--good);
}

.review-actions {
  display: flex;
  gap: 8px;
  justify-content: center;
  margin-bottom: 18px;
}

/* Read-only review prose. No textareas — pure display. */
.review-output {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 32px 36px;
  margin: 0 12px 18px;
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--fg);
}
@media (max-width: 720px) {
  .review-output { padding: 22px 18px; }
}
.review-output-head {
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border-soft);
}
.review-output-title {
  font-size: 28px;
  letter-spacing: -0.02em;
  margin: 0 0 6px;
  color: var(--fg);
}
.review-output-meta {
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.review-output-section {
  margin-bottom: 22px;
}
.review-output-section:last-child {
  margin-bottom: 0;
}
.review-section-h {
  font-family: 'Manrope', 'Inter', sans-serif;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.005em;
  color: var(--accent);
  margin: 0 0 10px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border-soft);
}
.review-prose {
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--fg);
}
.review-prose p {
  margin: 0 0 0.75em;
}
.review-prose p:last-child { margin-bottom: 0; }

/* Strengths / areas-of-development blocks: numbered, with optional
   topic header and recommendation footer. */
.review-blocks {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.review-block {
  position: relative;
  padding: 0 0 0 26px;
}
.review-block-num {
  position: absolute;
  left: 0; top: 1px;
  width: 20px;
  text-align: right;
  font-feature-settings: 'tnum' 1;
  color: var(--accent);
  font-weight: 700;
}
.review-block-topic {
  font-weight: 700;
  color: var(--fg);
  margin-bottom: 4px;
}
.review-block-body {
  color: var(--fg);
  line-height: 1.7;
}
.review-block-rec {
  margin-top: 6px;
  padding: 8px 12px;
  border-left: 2px solid var(--accent-line);
  background: var(--accent-soft);
  border-radius: 0 6px 6px 0;
  font-size: 13.5px;
  color: var(--fg-2);
}
.review-block-rec::before {
  content: "Рекомендация · ";
  color: var(--accent);
  font-weight: 700;
}

/* Tactful disclaimer at the bottom of the Review tab. */
.review-disclaimer {
  margin: 20px 12px 18px;
  padding: 18px 20px;
  border-radius: 12px;
  background: var(--panel-2);
  border: 1px solid var(--border-soft);
  font-size: 13px;
  line-height: 1.6;
  color: var(--fg-2);
}
.review-disclaimer-head {
  font-weight: 700;
  color: var(--fg);
  font-size: 13.5px;
  letter-spacing: 0.005em;
  margin-bottom: 8px;
}
.review-disclaimer p {
  margin: 0 0 0.6em;
}
.review-disclaimer p:last-child { margin-bottom: 0; }
.review-disclaimer-soft {
  margin-top: 10px !important;
  padding-top: 10px;
  border-top: 1px dashed var(--border-soft);
  color: var(--muted);
  font-style: italic;
}
.cabinet-package-tag {
  display: inline-block;
  margin-top: 6px;
  padding: 2px 6px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 4px;
}

.cabinet-billing-warn {
  margin-top: 12px;
  padding: 8px 12px;
  font-size: 12px;
  color: var(--warning);
  background: var(--warning-soft);
  border-radius: 8px;
  border-left: 2px solid var(--warning);
}

/* Transaction history list */
.cabinet-history {
  display: flex; flex-direction: column;
  gap: 4px;
}
.cabinet-history-empty {
  color: var(--muted); font-size: 13px; padding: 4px 0;
}
.cabinet-tx {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 10px;
  align-items: baseline;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-soft);
}
.cabinet-tx:last-child { border-bottom: none; }
.cabinet-tx-when {
  font-size: 11px;
  color: var(--muted);
  font-feature-settings: 'tnum' 1;
}
.cabinet-tx-reason {
  font-size: 13px;
  color: var(--fg-2);
}
.cabinet-tx-delta {
  font-weight: 700;
  font-feature-settings: 'tnum' 1;
  font-variant-numeric: tabular-nums;
}
.cabinet-tx-delta[data-sign="+"] { color: var(--good); }
.cabinet-tx-delta[data-sign="-"] { color: var(--danger); }
.cabinet-tx-delta[data-sign="0"] { color: var(--muted); }

/* Insufficient-credits flag on the score button */
.score-needs-topup {
  margin-top: 8px;
  padding: 10px 14px;
  background: var(--warning-soft);
  border: 1px solid var(--warning);
  border-radius: 10px;
  color: var(--fg);
  font-size: 13px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.score-needs-topup a {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}
.score-needs-topup a:hover { text-decoration: underline; }
