@import url('https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400;14..32,500;14..32,600&display=swap');

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --bg:        #F5F7FA;
  --surface:   #FFFFFF;
  --surface-2: #F1F3F7;
  --border:    #E4E2DC;
  --text:      #111827;
  --muted:     #6B7280;
  --accent:    #1652A8;
  --accent-h:  #0F3D82;
  --accent-bg: #EBF2FF;
  --success:   #166534;
  --danger:    #991B1B;
  --ins-bg:    #DCFCE7;
  --del-bg:    #FEE2E2;
  --pin-pending:  #B45309;   /* a proposal waiting on a decision — the loud state */
  --pin-resolved: #9CA3AF;   /* decided (accepted / reverted / edited) — quiet but perceptible */
  --header-h:  48px;   /* nav height; sticky headers + the job modal seat themselves below it */
  --radius:    5px;
  --shadow:    0 1px 2px rgba(0,0,0,.06);
}

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 14px;
  font-feature-settings: "cv02", "cv03", "cv11";
  line-height: 1.6;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}

/* ── Header ── */
header {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 100;
}
/* Anchors the overflow menu, which hangs below the bar. */
nav { position: relative; }

nav {
  display: flex;
  align-items: center;
  height: 48px;
  padding: 0 1rem;
  gap: 0.25rem;
}

.app-logo {
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--text);
  margin-right: 0.5rem;
  flex-shrink: 0;
  letter-spacing: -.01em;
}

.nav-links {
  display: flex;
  gap: 2px;
  flex: 1;
  min-width: 100px;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.nav-links::-webkit-scrollbar { display: none; }

.nav-btn {
  background: none;
  border: none;
  padding: 0.375rem 0.75rem;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 0.875rem;
  font-family: inherit;
  color: var(--muted);
  transition: background 0.1s, color 0.1s;
  min-height: 34px;
  white-space: nowrap;
  flex-shrink: 0;
}

.nav-btn:hover { background: var(--bg); color: var(--text); }
.nav-btn.active { background: var(--text); color: #fff; }

.user-pill {
  background: none;
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 0.25rem 0.75rem;
  font-size: 0.78rem;
  font-family: inherit;
  color: var(--muted);
  cursor: pointer;
  margin-left: auto;
  flex-shrink: 0;
  transition: background 0.1s;
}

.user-pill:hover { background: var(--bg); }

/* Narrow phones: the logo/user-pill text plus the tab bar don't all fit on one row.
   Drop to icon-only chrome so the tab bar always keeps real, scrollable width
   instead of being squeezed to nothing by flex-shrink:0 siblings. */
@media (max-width: 480px) {
  .app-logo-text { display: none; }
  .user-pill-text { display: none; }
  .user-pill { padding: 0.375rem; }
}

/* Overflow menu under the 👤 pill: holds the views that don't earn a permanent tab. */
.settings-panel {
  position: absolute;
  top: var(--header-h);
  right: 0.75rem;
  z-index: 400;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.15rem;
  min-width: 190px;
  padding: 0.4rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 28px rgba(0,0,0,.16);
  font-size: 0.8rem;
  color: var(--muted);
}
.settings-panel .menu-item { text-align: left; }
.menu-sep { border-top: 1px solid var(--border); margin: 0.3rem 0; }

.settings-panel input {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.25rem 0.5rem;
  font-size: 0.8rem;
  font-family: inherit;
  width: 200px;
}

/* ── Layout ── */
main {
  width: 100%;
  max-width: 1440px;
  margin: 0 auto;
  padding: 1.25rem clamp(1rem, 2vw, 2rem) 3rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.view { display: flex; flex-direction: column; gap: 0.75rem; }
.view.hidden { display: none; }

/* ── Cards ── */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
  box-shadow: var(--shadow);
}

/* ── Section labels ── */
.section-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 1rem;
}

.document-header-sticky {
  position: sticky;
  top: 48px;
  z-index: 20;
  background: var(--surface);
  padding: .5rem 0;
}

.section-n {
  background: var(--accent-bg);
  color: var(--accent);
  border: 1px solid rgba(22,82,168,.15);
  border-radius: 4px;
  padding: 0.05em 0.4em;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.7;
}

.sec-badge {
  background: #EEF2FF;
  color: #4338CA;
  border-radius: 100px;
  padding: 0.1em 0.55em;
  font-size: 0.68rem;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
}

.sec-timing {
  color: var(--muted);
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.78rem;
}

.section-controls {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  /* Must wrap: this row carries a long base-doc note, 2-3 chips and the 5-button
     review toolbar. Without wrapping its min-content width (~650px) overflows the
     card on a phone and drags the whole page into horizontal scroll. */
  flex-wrap: wrap;
  min-width: 0;
}

.control-note {
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--muted);
  /* Truncate rather than either forcing width or collapsing to one word per line. */
  min-width: 0;
  max-width: 28rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.base-letter-indicator {
  max-width: 28rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Inputs ── */
.input-group { margin-bottom: 0.625rem; }

input[type="url"],
input[type="text"],
input[type="search"],
input[type="password"],
textarea {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.6rem 0.75rem;
  font-size: 0.9rem;
  font-family: inherit;
  color: var(--text);
  background: var(--surface);
  transition: border-color 0.15s, box-shadow 0.15s;
  min-height: 44px;
}

input:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(31,92,230,.1);
}

textarea { resize: vertical; min-height: 110px; }

.lang-warning {
  background: #FFFBEB;
  border: 1px solid #FDE68A;
  border-radius: var(--radius);
  padding: 0.5rem 0.75rem;
  font-size: 0.85rem;
  margin-bottom: 0.5rem;
}

/* ── Buttons ── */
.btn-primary {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: var(--radius);
  padding: 0.55rem 1.25rem;
  font-size: 0.875rem;
  font-family: inherit;
  font-weight: 500;
  cursor: pointer;
  min-height: 38px;
  width: auto;
  margin-top: 0.5rem;
  transition: background 0.15s;
  letter-spacing: 0.01em;
}

.btn-primary:hover { background: var(--accent-h); }
.btn-primary:disabled { background: var(--border); color: var(--muted); cursor: default; }

#input-card .btn-primary { width: 100%; }

.btn-ghost {
  background: none;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.4rem 0.875rem;
  font-size: 0.85rem;
  font-family: inherit;
  cursor: pointer;
  min-height: 36px;
  transition: background 0.1s;
}

.btn-ghost:hover { background: var(--bg); }
/* Base look for a standalone small button (credential row Save/Remove) — same shape as
   .btn-ghost.btn-sm below, but usable without also adding .btn-ghost. */
.btn-sm {
  background: none;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.25rem 0.6rem;
  font-size: 0.78rem;
  font-family: inherit;
  cursor: pointer;
  min-height: 28px;
  transition: background 0.1s;
}
.btn-sm:hover { background: var(--bg); }
.btn-ghost.btn-sm { padding: 0.25rem 0.6rem; font-size: 0.78rem; min-height: 28px; }
.btn-danger { color: var(--danger); border-color: var(--danger); }
.btn-danger:hover { background: var(--del-bg); }

/* Copy-button confirmation flash */
.btn-ghost.copied {
  background: #DCFCE7;
  color: var(--success);
  border-color: var(--success);
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.btn-ghost.copy-failed {
  background: #FEE2E2;
  color: #991B1B;
  border-color: #991B1B;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.btn-chip {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 0.15rem 0.65rem;
  font-size: 0.73rem;
  font-family: inherit;
  font-weight: 500;
  cursor: pointer;
  min-height: 24px;
  text-transform: none;
  letter-spacing: 0;
  transition: background 0.1s;
}

.btn-chip:hover { background: var(--border); }
.btn-chip.diff-off { color: var(--muted); }

/* ── Progress steps ── */
.progress-steps {
  margin-top: 0.875rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.step {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.85rem;
  color: var(--muted);
}

.step-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid var(--border);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0;
  transition: border-color 0.2s, background 0.2s;
}

.step.active .step-dot {
  border-color: var(--accent);
  border-top-color: transparent;
  animation: spin 0.7s linear infinite;
}
.step.active .step-text { color: var(--text); font-weight: 500; }

.step.done .step-dot {
  background: var(--success);
  border-color: var(--success);
  font-size: 0.55rem;
  color: #fff;
}
.step.done .step-dot::after { content: '✓'; }
.step.done .step-text { color: var(--text); }

.step.error .step-dot {
  background: var(--danger);
  border-color: var(--danger);
  font-size: 0.55rem;
  color: #fff;
}
.step.error .step-dot::after { content: '✗'; }
/* The failure reason is set as a `title` tooltip on the chip — signal it's hoverable. */
.step.error { cursor: help; }
.step.error .step-text {
  color: var(--danger);
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}

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

/* ── Smoke test ── */

.smoke-result {
  font-size: 0.78rem;
  font-weight: 500;
}
.smoke-result.ok   { color: var(--success); }
.smoke-result.fail { color: var(--danger); }
.smoke-result.wait { color: var(--muted); }

.hidden { display: none !important; }

/* ── Research grid ── */
.research-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.research-cell {
  background: #FAFBFD;
  padding: 0.75rem;
}

.cell-hd {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.4rem;
}

.cell-bd {
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--text);
}

/* Skeleton shimmer */
.sk {
  height: 9px;
  border-radius: 3px;
  margin-bottom: 5px;
  background: linear-gradient(90deg, var(--border) 25%, var(--surface-2) 50%, var(--border) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
}
.sk.s { width: 55%; }
.sk.m { width: 78%; }

@keyframes shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Research cell content */
.cell-bd ul { padding-left: 1rem; }
.cell-bd li { margin-bottom: 0.15rem; }

.want-row { display: flex; gap: 0.35rem; margin-bottom: 0.25rem; }
.want-need { font-weight: 500; min-width: 110px; }
.want-evidence { color: var(--muted); }

.news-item { margin-bottom: 0.3rem; }
.news-src { color: var(--accent); font-size: 0.78rem; margin-left: 0.25rem; }

.fit-ok  { color: var(--success); }
.fit-warn { color: var(--danger); }

.prep-lbl { font-size: 0.7rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; margin-top: 0.4rem; margin-bottom: 0.2rem; }

/* ── Actions row ── */
.actions-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.25rem 0;
}

.actions-save {
  width: auto !important;
  margin-top: 0 !important;
  margin-left: auto;
}

.save-status {
  margin-left: auto;
  font-size: 0.78rem;
  color: var(--muted);
  white-space: nowrap;
}

.actions-applied {
  width: auto !important;
  margin-top: 0 !important;
}

/* ── Application status badges (history list) ── */
.h-status {
  font-size: 0.7rem;
  font-weight: 600;
  border-radius: 4px;
  padding: 0.1em 0.5em;
  flex-shrink: 0;
  white-space: nowrap;
}
.h-status-draft   { color: var(--muted);   background: #F3F4F6; }
.h-status-saved   { color: var(--accent);  background: var(--accent-bg); }
.h-status-applied { color: var(--success); background: #DCFCE7; }

.h-applied {
  flex-shrink: 0;
  border: 1px solid var(--border);
  background: none;
  color: var(--muted);
  font-size: 0.72rem;
  line-height: 1;
  padding: 0.3em 0.5em;
  border-radius: 4px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s, color 0.15s, border-color 0.15s;
}
.history-row:hover .h-applied { opacity: 1; }
.h-applied:hover { color: var(--success); border-color: var(--success); }

/* ── Doc content ── */
.doc-content {
  font-size: 0.875rem;
  line-height: 1.75;
  white-space: pre-wrap;
  word-break: break-word;
}

/* No diff highlighting: a review unit is marked by its pin, not by tinting its text — tinted
   text does not read as a CV. Visibility is driven entirely by the data-status rules below. */
.doc-content ins { text-decoration: none; }
.doc-content p { margin: 0 0 0.85em; position: relative; }
.doc-content p:last-child { margin-bottom: 0; }
.change-marker { cursor: pointer; }

/* Per-paragraph copy button (accept this paragraph's changes + copy) */
.para-copy-btn {
  position: absolute;
  top: 0;
  right: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 22px;
  padding: 0;
  font-size: 0.8rem;
  line-height: 1;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  opacity: 0;
  transition: opacity .12s ease;
  -webkit-user-select: none;
  user-select: none;
}
.doc-content p:hover .para-copy-btn,
.para-copy-btn:focus-visible { opacity: 1; }
.para-copy-btn:hover { color: var(--text); background: var(--bg); }
.para-copy-btn.copied { color: #16a34a; border-color: #16a34a; opacity: 1; }
.para-copy-btn.copy-failed { color: #dc2626; border-color: #dc2626; opacity: 1; }

/* Change pin — one per review unit, sits inline at the end of the unit's last line and
   carries its state. No button chrome; it must not disturb line height. */
.unit-pin {
  border: 0;
  background: none;
  padding: 0;
  margin: 0 0 0 3px;
  font-size: 0.6em;
  line-height: 1;
  vertical-align: 0.15em;
  cursor: pointer;
  color: var(--pin-pending);
  -webkit-user-select: none;
  user-select: none;
  transition: color .12s ease;
}
.unit-pin:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }
.unit-pin[data-unit-state="pending"] { color: var(--pin-pending); }
.unit-pin[data-unit-state="accepted"],
.unit-pin[data-unit-state="reverted"],
.unit-pin[data-unit-state="edited"] { color: var(--pin-resolved); }

/* Reorder marker — the model moved this line for this ad instead of rewording it. Not a
   review decision: a move has already happened, there is nothing to accept or revert, so it
   is a mark and not a pin. Drawn with ::after so it never enters textContent, which is what
   _resolveDiffNodes and the export read. The provenance panel lists what moved. */
.doc-content [data-moved]::after {
  content: "\21c5";
  margin-left: 3px;
  font-size: 0.72em;
  vertical-align: 0.1em;
  color: var(--pin-resolved);
  -webkit-user-select: none;
  user-select: none;
}

/* ── Provenance popover ── */
.popover {
  position: fixed;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 4px 20px rgba(0,0,0,.12);
  padding: 1rem;
  max-width: min(400px, calc(100vw - 2rem));
  width: 100%;
  z-index: 200;
  font-size: 0.85rem;
}

.popover-close {
  position: absolute;
  top: 0.5rem; right: 0.75rem;
  background: none; border: none;
  font-size: 1.2rem; cursor: pointer;
  color: var(--muted);
  min-height: 32px; min-width: 32px;
}

#prov-detail dt { font-weight: 600; margin-top: 0.4rem; color: var(--muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: .05em; }
#prov-detail dd { margin-left: 0; margin-bottom: 0.15rem; }

.unsupported-item { color: var(--danger); font-size: 0.875rem; padding: 0.25rem 0; }
.unsupported-why { color: var(--muted); font-size: 0.8rem; margin: 0.1rem 0 0 1.1rem; line-height: 1.35; }
.all-clear { color: var(--success); font-weight: 500; font-size: 0.875rem; }

/* ── Profile ── */
.profile-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.profile-hd-left { display: flex; align-items: baseline; gap: 0.5rem; flex-wrap: wrap; }

.profile-title { font-size: 1rem; font-weight: 600; }

.corpus-badge { font-size: 0.8rem; color: var(--success); font-weight: 500; }
.corpus-stats { font-size: 0.78rem; color: var(--muted); }
.corpus-msg { font-size: 0.85rem; color: var(--muted); margin-top: 0.5rem; }

.profile-sec-label {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 0.875rem;
}

.dim-tag { font-weight: 400; text-transform: none; letter-spacing: 0; }

.profile-job {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border);
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.875rem;
}
.profile-job:last-child { border-bottom: none; }
.job-role { font-weight: 500; }
.job-company { color: var(--muted); }
.job-dates { color: var(--muted); font-size: 0.8rem; flex-shrink: 0; }

.family-row {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.875rem;
  flex-wrap: wrap;
}
.family-row:last-child { border-bottom: none; }
.family-name { font-weight: 500; min-width: 180px; }
.family-meta { color: var(--muted); font-size: 0.8rem; }
.family-arr { margin-left: auto; color: var(--muted); font-size: 0.8rem; }

.tag {
  display: inline-block;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.1rem 0.4rem;
  font-size: 0.78rem;
  margin: 0.1rem 0.1rem 0.1rem 0;
}

/* ── History ── */
.history-hd {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.875rem;
  flex-wrap: wrap;
}

.history-title { font-size: 1rem; font-weight: 600; }

/* Pushes a control to the far right of a card header (e.g. the Jobs bookmarks toggle). */
.hd-right { margin-left: auto; }

.history-hd input[type="search"] {
  max-width: 220px;
  min-height: 34px;
  font-size: 0.85rem;
  padding: 0.35rem 0.65rem;
}

.filter-chips {
  display: flex;
  gap: 0.375rem;
  flex-wrap: wrap;
  margin-bottom: 0.875rem;
}

.chip {
  background: none;
  border: 1px solid var(--border);
  border-radius: 100px;
  padding: 0.2rem 0.7rem;
  font-size: 0.78rem;
  font-family: inherit;
  cursor: pointer;
  color: var(--muted);
  transition: background 0.1s, color 0.1s, border-color 0.1s;
  line-height: 1.5;
}

.chip:hover { background: var(--bg); color: var(--text); }
.chip.active { background: var(--text); color: #fff; border-color: var(--text); }

.history-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0;
  border-top: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.1s;
}

.history-row:hover {
  background: var(--bg);
  margin: 0 -1.25rem;
  padding-left: 1.25rem;
  padding-right: 1.25rem;
}

.h-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--surface-2);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text);
  flex-shrink: 0;
}

.h-main { flex: 1; min-width: 0; }
.h-role { font-weight: 500; font-size: 0.875rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.h-role-sub { font-size:.8rem; font-weight:600; color:var(--text); margin-top:.08rem; }
.h-meta { font-size: 0.78rem; color: var(--muted); }
.h-tag { font-size: 0.72rem; color: var(--muted); border: 1px solid var(--border); border-radius: 4px; padding: 0.1em 0.45em; flex-shrink: 0; white-space: nowrap; }
.h-tags { display:flex; flex-wrap:wrap; gap:.25rem; margin-top:.28rem; }
.h-tag-chip { background:var(--surface-2); color:var(--text); border-color:var(--border); }
.history-historical .h-tag-chip { background:#eef2ff; color:#3730a3; border-color:#c7d2fe; }
.hist-tags { margin-top:.4rem; }
.h-arr { color: var(--muted); font-size: 0.8rem; flex-shrink: 0; }
.h-del {
  flex-shrink: 0;
  border: none;
  background: none;
  color: var(--muted);
  font-size: 0.85rem;
  line-height: 1;
  padding: 0.25em 0.4em;
  border-radius: 4px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s, color 0.15s, background 0.15s;
}
.history-row:hover .h-del { opacity: 1; }
.h-del:hover { color: var(--danger); background: var(--del-bg); }

/* ── CV panel split ── */
.cv-panel-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 360px);
  gap: 1.25rem;
  align-items: flex-start;
}
.cv-panel-split .doc-content {
  min-width: 0;
}
.review-panel {
  min-width: 0;
  border-left: 1px solid var(--border);
  padding-left: 1rem;
  font-size: .83rem;
  display: flex;
  flex-direction: column;
  gap: .6rem;
  position: sticky;
  top: calc(48px + 3.5rem);
  max-height: calc(100vh - 48px - 3.5rem);
  overflow: auto;
}

/* ── Review toolbar ── */
.review-toolbar {
  display: inline-flex;
  align-items: center;
  gap: .2rem;
  margin-left: .35rem;
}
#review-counter {
  font-size: .78rem;
  font-weight: 600;
  color: var(--text);
  min-width: 52px;
  text-align: center;
}

/* ── Review unit visibility ──
   Exactly one version of every line is on screen, and it is what will be exported. A node is
   shown iff _resolveDiffNodes would include it in the output — with ONE exception, a pending
   pure addition, shown faint because it has no base wording to stand in for it. Nothing is
   ever struck through: the UA stylesheet strikes <del>, so every visible <del> needs an
   explicit text-decoration: none. "not rendered" is display:none, which getOriginalFor's
   previousSibling walk still traverses. */
ins.change-active,
del.change-active,
.unit-pin.change-active {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-radius: 2px;
}

/* Base wording, still up for review — tinted so old and new are told apart at a glance
   without a strikethrough: a light red-tinted background (--del-bg) and de-emphasized
   (--muted) text mark it as the OLD side of a pending decision, still readable, still the
   line you type into: cursor: text. */
del[data-status="pending"] {
  background: var(--del-bg);
  color: var(--muted);
  text-decoration: none;
  cursor: text;
  border-radius: 2px;
}
/* A reverted <del> is a DECIDED unit — the reviewer chose to keep the base wording — so it
   reads as ordinary, resolved prose, not as still-up-for-replacement. */
del[data-status="reverted"] { background: transparent; color: inherit; text-decoration: none; cursor: text; }

/* Resolved: tailored wording in, base wording / cut out. */
del[data-status="accepted"]  { display: none; text-decoration: none; }
ins[data-status="accepted"],
ins[data-status="edited"]    { background: transparent; color: inherit; text-decoration: none; cursor: text; }
/* The reviewer's own wording, typed into the <del> that carried the line. It exports, so it is
   ordinary prose — and it must lose the UA strikethrough like every other visible <del>. */
del[data-status="edited"]    { background: transparent; color: inherit; text-decoration: none; cursor: text; }
ins[data-status="reverted"]  { display: none; }

/* The NEW side of a pending decision — ordinary, fully readable prose, distinguished from the
   old side only by NOT carrying the red-tinted background above. Both a reworded unit's <ins>
   and a pure addition render this way; accepting resolves the unit down to this same look with
   the <del> gone, so nothing visually changes at that moment except the old text disappearing. */
ins[data-ins-kind="change"][data-status="pending"],
ins[data-ins-kind="addition"][data-status="pending"] {
  background: transparent;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

/* Diff: off — the print preview. Resolve to the output state: no faint content, no pins,
   and no reorder marks. */
.diff-hidden .unit-pin { display: none; }
.diff-hidden [data-moved]::after { content: none; }
.diff-hidden ins[data-ins-kind="addition"][data-status="pending"],
.diff-hidden ins[data-ins-kind="change"][data-status="pending"] { display: none; }
/* ...and don't leave a bullet's list marker stranded on an otherwise-empty line. One total
   rule for the class: under Diff off a list item is empty when it has no static prose
   (.doc-text) and none of the ins/del states that render here — a pending or reverted <del>,
   an accepted or edited <ins>. Everything else in it (a pending/change/reverted <ins>, an
   accepted <del>, the pin) is display:none, so the row would show only its marker. Covers a
   pending pure addition, a reverted addition, and an accepted deletion in a legacy diff. */
.diff-hidden li:not(:has(.doc-text)):not(:has(del[data-status="pending"])):not(:has(del[data-status="reverted"])):not(:has(ins[data-status="accepted"])):not(:has(ins[data-status="edited"])) {
  display: none;
}
.diff-hidden ins,
.diff-hidden del {
  background: transparent !important;
  text-decoration: none !important;
  color: inherit !important;
  outline: none !important;
  opacity: 1 !important;
  cursor: default;
}

/* ── Review panel content ── */
.rp-header { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }

.rp-badge {
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .05em;
  padding: .1em .45em;
  border-radius: 3px;
  text-transform: uppercase;
}
.rp-badge-added   { background: var(--ins-bg); color: #166534; }
.rp-badge-removed { background: var(--del-bg); color: #991b1b; }

.rp-conf { font-size: .72rem; color: var(--muted); }

.rp-source {
  font-size: .78rem;
  padding-bottom: .5rem;
  border-bottom: 1px solid var(--border);
  margin-bottom: .1rem;
  display: flex;
  flex-direction: column;
  gap: .15rem;
}
.rp-source-company { font-weight: 600; color: var(--text); }
.rp-source-file { color: var(--muted); font-style: italic; }
.rp-source-type { font-size: .72rem; color: var(--muted); }
.rp-source-spaced { margin-top: .35rem; }

.rp-warning {
  padding: .55rem .65rem;
  border-left: 3px solid #b45309;
  background: #fffbeb;
  color: #78350f;
  font-size: .78rem;
  line-height: 1.45;
}

.rp-field { display: flex; flex-direction: column; gap: .15rem; }
.rp-lbl {
  font-size: .7rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.rp-orig { color: var(--muted); font-style: italic; }
.rp-sugg { font-weight: 500; color: var(--text); }
.rp-source-diff {
  color: var(--text);
  line-height: 1.5;
}
.rp-source-diff ins {
  background: var(--ins-bg);
  text-decoration: none;
  border-radius: 2px;
  padding: 0 1px;
}
.rp-source-diff del {
  background: var(--del-bg);
  border-radius: 2px;
  padding: 0 1px;
}

.rp-why {
  font-size: .78rem;
  color: var(--muted);
  line-height: 1.5;
  border-top: 1px solid var(--border);
  padding-top: .5rem;
}

.rp-actions { display: flex; gap: .35rem; flex-wrap: wrap; margin-top: .1rem; }
.rp-btn { padding: .28rem .65rem !important; font-size: .78rem !important; min-height: 28px !important; margin-top: 0 !important; width: auto !important; }

/* On desktop the panel is a sidebar (`.review-panel { display: flex; flex-direction: column }`,
   see above) whose content length varies a lot between units — a full-paragraph rewrite's
   source diff runs many lines longer than a one-word bullet edit. With Accept/Revert rendered
   last, reviewing a long unit meant scrolling down inside the panel to find them. `order: -1`
   moves them to the visual top with no DOM/JS change (so nothing here touches the phone sheet's
   own bottom-docked .rp-actions rule below); sticky plus a background keeps them pinned there
   even if the panel's own content still needs scrolling. */
@media (min-width: 641px) {
  .rp-actions {
    order: -1;
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--surface);
    padding-bottom: .5rem;
    margin-bottom: .1rem;
    border-bottom: 1px solid var(--border);
  }
}

.rp-edit-ta {
  width: 100%;
  min-height: 60px;
  resize: vertical;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: .4rem .5rem;
  font-size: .83rem;
  font-family: inherit;
}
.rp-edit-ta:focus { outline: none; box-shadow: 0 0 0 3px rgba(31,92,230,.1); }
#letter-review-panel .rp-edit-ta {
  min-height: clamp(220px, calc(100vh - 380px), 700px);
  resize: vertical;
}

/* ── Source link chips ── */
.src-chip {
  display: inline-flex; align-items: center; gap: .2rem;
  padding: .15rem .5rem;
  border: 1px solid var(--border);
  border-radius: 99px;
  font-size: .75rem;
  color: var(--accent);
  text-decoration: none;
  white-space: nowrap;
  margin: .1rem .15rem .1rem 0;
}
.src-chip:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.src-chip.social-linkedin { border-color: #0a66c2; color: #0a66c2; }
.src-chip.social-linkedin:hover { background: #0a66c2; color: #fff; border-color: #0a66c2; }
.src-chip.social-x { border-color: #000; color: #000; }
.src-chip.social-x:hover { background: #000; color: #fff; }
.src-chip.social-instagram { border-color: #e1306c; color: #e1306c; }
.src-chip.social-instagram:hover { background: #e1306c; color: #fff; border-color: #e1306c; }
.src-chip.social-facebook { border-color: #1877f2; color: #1877f2; }
.src-chip.social-facebook:hover { background: #1877f2; color: #fff; border-color: #1877f2; }
.src-chip.social-youtube { border-color: #ff0000; color: #c00; }
.src-chip.social-youtube:hover { background: #ff0000; color: #fff; border-color: #ff0000; }
.src-chip.social-tiktok { border-color: #010101; color: #010101; }
.src-chip.social-tiktok:hover { background: #010101; color: #fff; }

/* ── Research sources footer ── */
.research-sources {
  margin-top: .75rem;
  padding-top: .5rem;
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .1rem;
}
.sources-lbl {
  font-size: .7rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--muted);
  margin-right: .25rem;
  white-space: nowrap;
}

.rp-done { padding: .75rem 0; }
.rp-done-check { font-weight: 600; color: var(--success); margin-bottom: .25rem; }
.rp-done-stats { font-size: .78rem; color: var(--muted); }

/* ── CV typography (Task 30) ── */
#cv-content { white-space: normal; }
.cv-name    { font-size: 1.2rem; font-weight: 700; letter-spacing: -.01em; margin-bottom: .1rem; }
.cv-role    { font-size: .9rem; font-weight: 400; color: var(--muted); margin-bottom: .7rem; }
.cv-section {
  font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text); border-bottom: 1px solid var(--border);
  padding-bottom: .2rem; margin: .875rem 0 .35rem;
}
.cv-list    { padding-left: 1.1rem; margin: .2rem 0 .35rem; }
.cv-list li { margin-bottom: .18rem; line-height: 1.55; }
.cv-para    { margin-bottom: .3rem; line-height: 1.65; }

/* ── Profile section modal ── */
.modal-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.35);
  z-index: 300;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem;
}
.modal-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 32px rgba(0,0,0,.15);
  padding: 1.25rem;
  width: 100%;
  max-width: 560px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  gap: .75rem;
}
.modal-hd { display: flex; align-items: center; justify-content: space-between; }
.modal-hd span { font-weight: 600; font-size: .95rem; }
.modal-ta {
  flex: 1;
  min-height: 220px;
  resize: vertical;
  font-family: 'SF Mono', 'Fira Code', monospace;
  font-size: .8rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .5rem .75rem;
  line-height: 1.5;
}
.modal-ta:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(31,92,230,.1); }
/* The full-screen section editor keeps the code face — it edits raw JSON/markdown. The Settings
   textareas hold prose and lists a person types, so they read in the body face like every other
   field, and they do not need to be 220px tall. */
.settings-form .modal-ta { font-family: inherit; font-size: .88rem; min-height: 5.5rem; }
.modal-ta { background: var(--surface); color: var(--text); }
[data-theme="dark"] .modal-ta { background: var(--bg); }
.modal-actions { display: flex; gap: .5rem; }

/* ── Profile section content ── */
.profile-md-content { font-size: .85rem; line-height: 1.7; color: var(--text); }
.rp-conf { font-size: .72rem; color: var(--muted); }
.rp-header { display: flex; align-items: center; gap: .5rem; margin-bottom: .5rem; }

/* ── Cover-letter signature ── */
.sig-block { display: flex; flex-direction: column; gap: .6rem; align-items: flex-start; }
.sig-thumb { max-width: 240px; max-height: 120px; background: #fff; border: 1px solid var(--border);
             border-radius: 6px; padding: .4rem; }
.sig-empty { font-size: .82rem; color: var(--muted); margin: 0; }
.sig-controls { display: flex; gap: .5rem; }
.sig-upload-label { cursor: pointer; }
.sig-error { font-size: .8rem; color: var(--danger, #c0392b); margin: 0; }
.sig-error:empty { display: none; }

/* ── Responsive ── */
@media (max-width: 640px) {
  .research-grid { grid-template-columns: 1fr 1fr; }
  .actions-save { margin-left: 0; width: 100% !important; }
  .cv-panel-split { grid-template-columns: 1fr; }
  /* Document headers: give the controls their own full-width row instead of
     letting them fight the title for horizontal space. */
  .section-controls { margin-left: 0; width: 100%; }
  .control-note, .base-letter-indicator { max-width: 100%; }
  .review-toolbar { margin-left: 0; }
  /* A wrapped header is several rows tall on a phone; sticking it to the top
     would eat most of the screen the document needs. */
  .document-header-sticky { position: static; }
  .review-panel {
    border-left: none;
    border-top: 1px solid var(--border);
    padding-left: 0;
    padding-top: 1rem;
    position: static;
    max-height: none;
  }
}

@media (max-width: 400px) {
  .research-grid { grid-template-columns: 1fr; }
}

/* ── Inline editing of the active change ── */
/* The suggestion under review is typeable in place, so the document itself
   shows the result. Styled as a field so it reads as editable, not as prose. */
ins[contenteditable="true"],
del[contenteditable="true"] {
  cursor: text;
  background: var(--surface);
  box-shadow: inset 0 -1px 0 var(--accent);
  border-radius: 3px;
  padding: 0 2px;
  text-decoration: none;
}
ins[contenteditable="true"]:focus,
del[contenteditable="true"]:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Unchanged document text is editable too. Deliberately unstyled until focused —
   boxing every paragraph would drown out the diff this view exists to show. */
.doc-text { cursor: text; }
.doc-text[contenteditable="true"] {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-radius: 3px;
}

/* Collapse control: only meaningful for the docked sheet — on desktop the panel
   is a sidebar that isn't in the way. */
.rp-hide { display: none; }

/* ── Review panel docked as a bottom sheet (phones) ── */
@media (max-width: 640px) {
  .review-panel.rp-sheet {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    /* The desktop rule sets `top` for sticky positioning; left in place it
       over-constrains the fixed box and pins the sheet to the top instead. */
    top: auto;
    z-index: 60;
    max-height: 42vh;
    overflow: auto;
    margin: 0;
    padding: .75rem 1rem calc(.75rem + env(safe-area-inset-bottom, 0px));
    background: var(--surface);
    border: none;
    border-top: 1px solid var(--border);
    border-radius: 14px 14px 0 0;
    box-shadow: 0 -6px 24px rgba(0, 0, 0, .18);
  }
  /* The suggestion is right there in the document — repeating it wastes the
     little vertical space the sheet has. */
  .review-panel.rp-sheet .rp-field-sugg { display: none; }
  .review-panel.rp-sheet .rp-actions { position: sticky; bottom: 0; background: var(--surface); padding-top: .4rem; }
  .review-panel.rp-sheet .rp-hide { display: inline-flex; flex: 0 0 auto; }

  /* While typing, the sheet collapses to just its action row. The keyboard already
     owns ~half the screen; a 42vh panel on top of that leaves nothing to read the
     sentence you are editing. */
  body.editing .review-panel.rp-sheet {
    max-height: none;
    overflow: visible;
    padding-top: .4rem;
  }
  body.editing .review-panel.rp-sheet > *:not(.rp-actions) { display: none; }
  body.editing .review-panel.rp-sheet .rp-actions { position: static; }
  body.editing.sheet-open #view-new { padding-bottom: 24vh; }
  /* !important to beat .rp-btn's own !important sizing — these need to be real
     tap targets, not 28px desktop chips. */
  .review-panel.rp-sheet .rp-btn { flex: 1 1 auto; min-height: 40px !important; font-size: .85rem !important; }
  /* Keep the end of the letter reachable above the docked sheet. */
  body.sheet-open #view-new { padding-bottom: 46vh; }
}

/* ── Discover / Jobs shared ── */
.discover-hd   { display:flex; align-items:flex-start; justify-content:space-between; gap:1rem; }
.discover-metrics { display:flex; gap:.75rem; flex-wrap:wrap; margin-top:.3rem; }
.disc-metric   { font-size:.78rem; color:var(--muted); }
.discover-ranking-hint { margin-top:.18rem; color:var(--muted); font-size:.7rem; letter-spacing:.01em; }
.nav-badge { display:inline-block; min-width:1.2em; padding:0 .35em; margin-left:.4em;
  font-size:.72rem; line-height:1.4; text-align:center; border-radius:999px;
  background:var(--accent); color:#fff; font-weight:700; }
.nav-badge.hidden { display:none; }
/* Pulsing dot on the Discover nav while a discovery run is executing (visible from any view). */
.nav-btn.nav-running::after { content:''; display:inline-block; width:7px; height:7px; margin-left:.4em;
  border-radius:999px; background:#16a34a; vertical-align:middle; animation:nav-pulse 1.2s ease-in-out infinite; }
@keyframes nav-pulse { 0%,100% { opacity:1; } 50% { opacity:.3; } }
/* Interrupted-generation banner on the New view (survives reload / shows in other tabs). */
.gen-resume-banner { display:flex; align-items:center; gap:.5rem; justify-content:space-between;
  background:#FFFBEB; border:1px solid #FDE68A; border-radius:var(--radius);
  padding:.5rem .75rem; font-size:.85rem; margin-bottom:.75rem; }
.gen-resume-banner.hidden { display:none; }
.gen-banner-x { border:none; background:transparent; cursor:pointer; font-size:1.1rem;
  line-height:1; color:var(--muted); padding:0 .25rem; }
.gen-banner-x:hover { color:var(--text); }
/* No-key banner — sits above <main>, so it's visible from every view until a usable
   key exists for the active provider. */
.banner { display:flex; align-items:center; gap:.5rem;
  background:#FFFBEB; border:1px solid #FDE68A; border-bottom-width:1px;
  padding:.5rem 1rem; font-size:.85rem; }
.banner.hidden { display:none; }
.banner a { color:var(--accent); text-decoration:underline; cursor:pointer; }
/* Staleness marker on the Profile view — the .banner look, but sitting inside the header card
   above the Re-run button rather than spanning the page. */
.profile-stale { border-radius:var(--radius); margin-bottom:.75rem; }
/* "Finish setting up" checklist on the Profile view (Spec 5 Plan 3 Task 8). */
.setup-checklist-list { margin:.5rem 0 0; padding-left:1.1rem; font-size:.85rem; line-height:1.9; }
.setup-checklist-list a { color:var(--accent); text-decoration:underline; cursor:pointer; }
/* Transient action feedback (credential save/delete) — fixed, auto-dismissing. */
.toast { position:fixed; left:50%; bottom:1.5rem; transform:translateX(-50%);
  background:var(--text); color:var(--surface); padding:.55rem 1rem; border-radius:var(--radius);
  font-size:.85rem; box-shadow:var(--shadow); z-index:500; max-width:min(90vw, 420px); }
.toast.hidden { display:none; }
.discover-hero { margin:.6rem 0 1rem; padding:.7rem 1rem; border-radius:8px;
  background:#fff7ed; border:1px solid #fed7aa; font-size:.95rem; color:#7c2d12; }
.discover-hero.hidden { display:none; }
.job-group { margin:1.2rem 0 .5rem; font-size:.8rem; letter-spacing:.08em;
  text-transform:uppercase; color:var(--muted); }
.job-list      { display:flex; flex-direction:column; gap:.55rem; margin-top:.75rem; }
.job-card {
  display:grid; grid-template-columns:56px minmax(0,1fr) auto; gap:0 1rem;
  background:var(--surface); border:1px solid var(--border);
  border-radius:8px; padding:.7rem .85rem;
  box-shadow:0 1px 2px rgba(15,23,42,.04);
  position:relative; overflow:hidden;
}
.job-card::before { content:""; position:absolute; inset:0 auto 0 0; width:4px; background:#d1d5db; }
.job-card-rel-5::before { background:#16a34a; }
.job-card-rel-4::before { background:#65a30d; }
.job-card-rel-3::before { background:#ca8a04; }
.job-card-rel-2::before { background:#94a3b8; }
.job-card-rel-1::before { background:#cbd5e1; }
.job-card[data-status="dismissed"] { opacity:.45; pointer-events:none; }

/* Fit rail: score numeral + 5-dot meter + one-word verdict, colored by relevance */
.job-fit { display:flex; flex-direction:column; align-items:center; gap:.3rem; padding-top:.1rem; }
.fit-score { font-size:1.35rem; font-weight:800; line-height:1; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; }
.fit-dots  { display:flex; gap:3px; }
.fit-dot   { width:5px; height:5px; border-radius:50%; background:var(--border); }
.fit-dot.on { background:currentColor; }
.fit-label { font-size:.58rem; font-weight:700; text-transform:uppercase; letter-spacing:.07em; opacity:.85; }
.fit-5 { color:#15803d; }
.fit-4 { color:#4d7c0f; }
.fit-3 { color:#a16207; }
.fit-2 { color:#64748b; }
.fit-1 { color:#94a3b8; }
.fit-none { color:var(--muted); }
.fit-none .fit-score { font-weight:600; }

.job-card-main { min-width:0; }
.job-title-row { display:flex; gap:.45rem; align-items:baseline; flex-wrap:wrap; }
.job-card-title  { font-weight:700; font-size:.98rem; color:var(--text); text-decoration:none; }
button.job-card-title { background:none; border:none; padding:0; font-family:inherit;
  text-align:left; cursor:pointer; line-height:inherit; }
.job-card-title:hover { color:var(--accent); text-decoration:underline; }
.job-card-company { color:var(--muted); font-size:.88rem; }
.job-card-company::before { content:"at "; color:var(--muted); }
.job-meta { display:flex; gap:.45rem; align-items:center; flex-wrap:wrap; margin-top:.2rem;
  font-size:.78rem; color:var(--muted); }
.job-reason { font-size:.8rem; color:var(--text); opacity:.85; margin:.4rem 0 0; }
.job-reason q { font-style:italic; color:var(--muted); quotes:"“" "”"; }
.job-excerpt { font-size:.76rem; color:var(--muted); margin:.25rem 0 0;
  display:-webkit-box; -webkit-line-clamp:2; line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }

.job-card-side { display:flex; flex-direction:column; align-items:flex-end;
  justify-content:space-between; gap:.5rem; }
.job-when { font-size:.72rem; color:var(--muted); display:flex; align-items:center; gap:.4rem;
  white-space:nowrap; }
.job-card-actions { display:flex; gap:.35rem; flex-wrap:wrap; justify-content:flex-end; }
@media (max-width: 600px) {
  .job-card { grid-template-columns:44px minmax(0,1fr); }
  .job-card-side { grid-column:1 / -1; flex-direction:row; flex-wrap:wrap; align-items:center; margin-top:.5rem; }
  .job-when { flex:1 1 100%; }
  .job-card-actions { flex:1 1 100%; justify-content:flex-start; }
}

.pill { display:inline-block; font-size:.66rem; font-weight:700; padding:.05em .45em;
  border-radius:6px; margin-right:.35em; vertical-align:middle; }
.pill-new { background:var(--accent); color:#fff; }
.via-tag { font-size:.72rem; color:#6d28d9; margin-left:.4em; font-weight:600; }
.chip.remote-chip { font-size:.7rem; padding:.05em .45em; border-radius:6px;
  background:#eef2ff; color:#3730a3; border-color:#c7d2fe; }
.chip.seniority-chip { font-size:.7rem; padding:.05em .45em; border-radius:6px;
  background:#fef3c7; color:#92400e; border-color:#fde68a; }
.status-chip { display:inline-block; font-size:.66rem; font-weight:700; padding:.08rem .42rem;
  border-radius:6px; text-transform:uppercase; letter-spacing:.02em;
  background:#f1f5f9; color:#475569; }
.status-applied { background:#dcfce7; color:#166534; }
.status-dismissed { background:#fee2e2; color:#991b1b; }
.btn-star { font-size:.9rem; line-height:1; }
.btn-star.on { color:#b45309; }
.status-bookmarked { background:#fef3c7; color:#92400e; }
/* The Jobs header's ★ Bookmarks control is a filter toggle: pressed has to read as "on",
   and the status select it disables has to read as "not yours right now". */
#jobs-bookmarks-toggle[aria-pressed="true"] { background:#fef3c7; border-color:#f59e0b; color:#92400e; }
.filter-row select:disabled { opacity:.55; cursor:default; }
.run-phase { font-weight:600; text-transform:capitalize; }
.run-console { display:flex; flex-direction:column; gap:.65rem; }
.run-console-top { display:flex; justify-content:space-between; gap:1rem; align-items:flex-start; }
.run-title { font-weight:700; color:var(--text); }
.run-subtitle { font-size:.78rem; color:var(--muted); margin-top:.12rem; }
.run-eta { font-size:.78rem; font-weight:700; color:var(--text); white-space:nowrap; }
.run-steps { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:.35rem; }
.run-step { border:1px solid var(--border); border-radius:6px; padding:.35rem .45rem;
  font-size:.72rem; text-align:center; color:var(--muted); background:var(--surface); }
.run-step.done { color:#166534; background:#dcfce7; border-color:#bbf7d0; }
.run-step.active { color:#7c2d12; background:#ffedd5; border-color:#fed7aa; font-weight:700; }
.run-progressbar { height:8px; border-radius:999px; background:var(--surface-2); overflow:hidden; }
.run-progressbar span { display:block; height:100%; min-width:8px; border-radius:999px; background:var(--accent); transition:width .25s ease; }
/* Finished run: the bar goes green with every step, and "✓ Complete" is promoted from a quiet
   ETA caption to the loudest thing in the console — the previous version left an amber step and
   a ~95% blue bar on a successful run, which reads as still-working. */
.run-console.is-done .run-progressbar span { background:#16a34a; }
.run-console.is-done .run-eta { font-size:.95rem; color:#166534; background:#dcfce7;
  border:1px solid #bbf7d0; border-radius:999px; padding:.2rem .6rem; }
[data-theme="dark"] .run-console.is-done .run-progressbar span { background:#22c55e; }
[data-theme="dark"] .run-console.is-done .run-eta { color:#86efac; background:#14331f;
  border-color:#1f4d32; }
.run-counters { display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:.35rem; }
.run-counters span { border:1px solid var(--border); border-radius:6px; padding:.32rem .4rem;
  font-size:.72rem; color:var(--muted); background:var(--surface); text-align:center; }
.run-log-title { font-size:.72rem; font-weight:800; color:var(--text); margin-bottom:.25rem; }
.run-listings, .run-events-wrap { border:1px solid var(--border); border-radius:6px;
  background:var(--surface); padding:.45rem .55rem; }
.run-listings ul, .run-events { max-height:180px; overflow:auto; margin:0; padding-left:1rem; }
.run-listings li, .run-events li { margin:.22rem 0; color:var(--muted); font-size:.74rem; }
.run-listings p { margin:.1rem 0; color:var(--muted); font-size:.74rem; }
.run-listing-row { display:flex; justify-content:space-between; gap:.75rem; align-items:flex-start; }
.run-listing-title { color:var(--accent); font-weight:700; text-decoration:none; }
.run-listing-title:hover { text-decoration:underline; }
.run-listing-open { flex:0 0 auto; border:1px solid var(--border); border-radius:6px; padding:.12rem .45rem;
  color:var(--text); background:var(--surface-2); text-decoration:none; font-weight:700; }
.run-listing-open:hover { border-color:var(--accent); color:var(--accent); }
.run-listings small { display:block; color:var(--muted); margin-top:.05rem; }
.run-activity-row { display:flex; justify-content:space-between; gap:.75rem; align-items:flex-start; }
.run-activity-title { color:var(--accent); font-weight:700; text-decoration:none; }
.run-activity-title:hover { text-decoration:underline; }
.run-activity-open { flex:0 0 auto; border:1px solid var(--border); border-radius:6px; padding:.1rem .42rem;
  color:var(--text); background:var(--surface-2); text-decoration:none; font-weight:700; }
.run-activity-open:hover { border-color:var(--accent); color:var(--accent); }

/* Language chip */
.lang-chip     { display:inline-flex; align-items:center; justify-content:center; text-align:center; text-transform:uppercase; font-size:.68rem; font-weight:600; padding:.1rem .35rem; border-radius:3px; }
.lang-en       { background:#dbeafe; color:#1e40af; }
/* Dutch-required is informational after Plan 2 (a per-user preference, no longer a fixed cap):
   a neutral amber pill in the same family as the other lang chips, normal case since it spells
   out the reason. Distinct from .lang-mixed's yellow but not an alarm-red flag. */
.lang-nl       { background:#ffedd5; color:#9a3412; text-transform:none; }
.lang-mixed    { background:#fef3c7; color:#92400e; }
.lang-unknown  { background:var(--surface-2); color:var(--muted); }

/* Jobs filters */
.jobs-filters  { margin-bottom:.5rem; }
.filter-row    { display:flex; gap:.5rem; flex-wrap:wrap; align-items:center; margin-bottom:.4rem; }
.filter-row select, .filter-row input[type=number], .filter-row input[type=date] {
  padding:.28rem .5rem; border:1px solid var(--border); border-radius:var(--radius);
  font-size:.82rem; background:var(--surface); color:var(--text);
}
/* ── Multi-select filter (button + checkbox popover) ── */
.ms { position:relative; display:inline-block; }
.ms-btn { padding:.28rem 1.4rem .28rem .5rem; border:1px solid var(--border);
  border-radius:var(--radius); font-size:.82rem; background:var(--surface); color:var(--text);
  cursor:pointer; max-width:14rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  text-align:left; }
.ms-btn::after { content:'▾'; position:absolute; right:.5rem; top:50%; transform:translateY(-50%);
  pointer-events:none; color:var(--muted); font-size:.7rem; }
.ms.ms-active .ms-btn { border-color:var(--accent); color:var(--accent); font-weight:600; }
.ms-panel { position:absolute; z-index:40; top:calc(100% + 4px); left:0; min-width:100%;
  width:max-content; max-width:18rem; background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius); box-shadow:0 6px 20px rgba(0,0,0,.14); padding:.35rem; }
.ms-opts { max-height:16rem; overflow-y:auto; }
.ms-opt { display:flex; align-items:center; gap:.45rem; padding:.25rem .4rem; font-size:.82rem;
  border-radius:4px; cursor:pointer; color:var(--text); }
.ms-opt:hover { background:var(--bg); }
.ms-opt input { margin:0; }
.ms-clear { width:100%; margin-top:.3rem; padding:.25rem; font-size:.75rem; cursor:pointer;
  background:none; border:none; border-top:1px solid var(--border); color:var(--muted); }
.ms-clear:hover { color:var(--text); }

.jobs-pagination { display:flex; align-items:center; gap:.75rem; padding:.75rem 0; }
.page-info     { font-size:.82rem; color:var(--muted); }
.empty-msg     { font-size:.875rem; color:var(--muted); padding:.5rem 0; }

/* Runs table */
.runs-table    { width:100%; border-collapse:collapse; font-size:.83rem; margin-top:.5rem; }
.runs-table th { text-align:left; font-size:.7rem; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); padding:.4rem .5rem; border-bottom:1px solid var(--border); }
.runs-table td { padding:.5rem .5rem; border-bottom:1px solid var(--surface-2); }

/* Settings form */
.settings-form    { display:flex; flex-direction:column; gap:1rem; }
.settings-row     { display:flex; flex-direction:column; gap:.3rem; }
.settings-lbl     { font-size:.78rem; font-weight:600; color:var(--muted); text-transform:uppercase; letter-spacing:.04em; }
.settings-sublbl  { display:block; font-size:.72rem; font-weight:600; color:var(--muted); margin:.5rem 0 .15rem; }
.settings-subhead { font-size:.9rem; font-weight:600; color:var(--text); margin-top:.5rem; padding-bottom:.35rem; border-bottom:1px solid var(--border); }
.settings-subhead:first-child { margin-top:0; }
/* background/color were never set, so every Settings and Admin input rendered WHITE in
   dark mode — the one place in the app that ignored the theme. */
.settings-input   { padding:.4rem .65rem; border:1px solid var(--border); border-radius:var(--radius);
  font:inherit; font-size:.88rem; width:100%; max-width:320px;
  background:var(--surface); color:var(--text); }
[data-theme="dark"] .settings-input { background:var(--bg); }
.settings-input::placeholder { color:var(--muted); opacity:.6; }
/* A button in a settings-row is an action, not a field: don't stretch it to the row. */
.settings-row > button { align-self:flex-start; }
.settings-input:focus { outline:none; border-color:var(--accent); box-shadow:0 0 0 3px rgba(31,92,230,.1); }
.settings-hint    { font-size:.75rem; color:var(--muted); }
.settings-sources { display:flex; gap:1rem; flex-wrap:wrap; }
.settings-check   { display:flex; align-items:center; gap:.35rem; font-size:.88rem; cursor:pointer; }
/* Only the source ids are lowercase data needing a capital; everything else is written copy. */
.settings-sources .settings-check { text-transform:capitalize; }
.settings-check input { cursor:pointer; }

.rp-ai-status      { font-size:.8rem; margin:.25rem 0; min-height:1em; }
.rp-ai-status.wait { color:var(--muted); }
.rp-ai-status.fail { color:var(--danger); }

/* ── Historical applications (read-only history) ─────────────────────────────── */
.h-historical { color:var(--accent); border-color:var(--accent); background:var(--accent-bg);
  font-weight:600; letter-spacing:.02em; }
.history-historical { opacity:.92; }
.history-historical:hover { opacity:1; }
.h-src { font-size:.68rem; color:var(--muted); border:1px solid var(--border); border-radius:4px;
  padding:.1em .4em; flex-shrink:0; white-space:nowrap; text-transform:capitalize; }

/* Seated BELOW the sticky header (which is z-index:100): at z-index:50 the top bar painted over
   the modal and clipped its title/close button. Starting at --header-h keeps the nav visible and
   un-dimmed instead of hiding it under the backdrop. */
.hist-overlay { position:fixed; top:var(--header-h); left:0; right:0; bottom:0; z-index:300;
  background:rgba(20,22,28,.45);
  display:flex; align-items:flex-start; justify-content:center; padding:2vh 1rem; overflow:auto; }
.hist-modal { background:var(--surface); border:1px solid var(--border); border-radius:12px;
  max-width:760px; width:100%; padding:1.25rem 1.5rem 1.75rem; box-shadow:0 12px 40px rgba(0,0,0,.18); }
.hist-modal-hd { display:flex; align-items:center; justify-content:space-between; gap:1rem;
  margin-bottom:.5rem; }
.hist-title { font-weight:600; margin:0 .5rem 0 .4rem; }
.hist-company { color:var(--muted); font-size:.9rem; }
.hist-close { border:none; background:none; color:var(--muted); font-size:1.1rem; cursor:pointer;
  line-height:1; padding:.25rem; }
.hist-close:hover { color:var(--text); }
.hist-link { display:inline-block; font-size:.82rem; color:var(--accent); margin:.25rem 0 .75rem; }
.hist-modal h4 { font-size:.72rem; text-transform:uppercase; letter-spacing:.08em; color:var(--muted);
  margin:1.1rem 0 .35rem; }
.hist-file { text-transform:none; letter-spacing:0; color:var(--accent); font-weight:500;
  margin-left:.4em; }
.hist-text { white-space:pre-wrap; font-size:.85rem; line-height:1.5; color:var(--text);
  background:var(--bg); border:1px solid var(--border); border-radius:8px; padding:.7rem .85rem;
  max-height:320px; overflow:auto; }
.hist-none { font-size:.82rem; color:var(--muted); font-style:italic; }

/* ── Job detail modal ── */
.jd-modal { display:flex; flex-direction:column; gap:.55rem; }
.jd-title { font-weight:700; font-size:1.05rem; line-height:1.35; }
.jd-company { color:var(--muted); font-size:.9rem; }
.jd-dates { font-size:.75rem; color:var(--muted); }
.jd-desc { white-space:pre-wrap; font-size:.88rem; line-height:1.6; color:var(--text);
  background:var(--bg); border:1px solid var(--border); border-radius:8px; padding:.8rem .95rem; }
/* Rich (structure-preserving) description: normal flow, styled headings/lists/emphasis. */
.jd-desc-rich { white-space:normal; }
.jd-desc-rich > :first-child { margin-top:0; }
.jd-desc-rich > :last-child { margin-bottom:0; }
.jd-desc-rich p { margin:0 0 .7em; }
.jd-desc-rich h3, .jd-desc-rich h4 { margin:1.1em 0 .4em; line-height:1.35; font-weight:700; }
.jd-desc-rich h3 { font-size:.98rem; }
.jd-desc-rich h4 { font-size:.9rem; }
.jd-desc-rich ul, .jd-desc-rich ol { margin:.4em 0 .8em; padding-left:1.4em; }
.jd-desc-rich li { margin:.25em 0; }
.jd-desc-rich strong { font-weight:700; }
.jd-desc-rich em { font-style:italic; }
.jd-actions { justify-content:flex-end; }
@media (max-width: 600px) {
  /* Full-page reading view: edge-to-edge under the nav, with a thumb-zone sticky action bar. */
  .jd-overlay { padding:0; }
  .jd-overlay .hist-modal { border-radius:0; border:none;
    min-height:calc(100dvh - var(--header-h));
    padding:1rem 1rem calc(4.5rem + env(safe-area-inset-bottom)); }
  .jd-actions { position:fixed; left:0; right:0; bottom:0;
    background:var(--surface); border-top:1px solid var(--border);
    padding:.6rem .85rem calc(.6rem + env(safe-area-inset-bottom));
    justify-content:space-between; }
}

/* ── Role-family chips (shared taxonomy across History, Jobs, Discover) ───────── */
.fam-chip { display:inline-block; font-size:.68rem; font-weight:600; line-height:1.4;
  padding:.08em .5em; border-radius:999px; white-space:nowrap; vertical-align:middle;
  border:1px solid transparent; background:var(--surface-2); color:var(--muted); }
.fam-social-media  { background:#e0f2fe; color:#075985; }
.fam-content-social { background:#ede9fe; color:#5b21b6; }
.fam-marketer      { background:#fef3c7; color:#92400e; }
.fam-influencer    { background:#fce7f3; color:#9d174d; }
.fam-community     { background:#dcfce7; color:#166534; }
.fam-pr-account    { background:#e0e7ff; color:#3730a3; }
.fam-events        { background:#ffedd5; color:#9a3412; }
.fam-recruitment   { background:#ccfbf1; color:#115e59; }
.fam-admin-office  { background:#f1f5f9; color:#334155; }
.fam-hospitality   { background:#fee2e2; color:#991b1b; }
.fam-other         { background:#f3f4f6; color:#6b7280; }

.chip-n { display:inline-block; min-width:1.1em; padding:0 .3em; margin-left:.25em;
  font-size:.7rem; border-radius:999px; background:var(--surface-2); color:var(--muted); }
.chip.active .chip-n { background:rgba(255,255,255,.3); color:#fff; }

.discover-run-controls { display:flex; align-items:center; gap:.5rem; }
.discover-run-controls select { border:1px solid var(--border); border-radius:var(--radius);
  padding:.3rem .5rem; font-size:.8rem; font-family:inherit; background:var(--surface); color:var(--text); }

.family-row { display:flex; align-items:center; gap:.6rem; }
.family-counts { margin-left:auto; display:flex; gap:.4rem; }
.fam-count { font-size:.74rem; font-weight:600; padding:.15em .6em; border-radius:999px;
  border:1px solid var(--border); background:var(--surface); color:var(--accent); cursor:pointer; }
.fam-count:hover:not(:disabled) { background:var(--accent-bg); }
.fam-count.is-zero, .fam-count:disabled { color:var(--muted); cursor:default; opacity:.55; }

.btn-generate-hero {
  width: 100%;
  margin-top: .25rem;
  padding: .85rem 1.25rem;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: .01em;
  border: none;
  border-radius: 12px;
  color: #fff;
  background: linear-gradient(135deg, #6d5efc 0%, #8b5cf6 50%, #ec4899 100%);
  box-shadow: 0 6px 18px rgba(124, 92, 252, .35);
  cursor: pointer;
  transition: transform .08s ease, box-shadow .2s ease, filter .2s ease;
}
.btn-generate-hero:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 9px 26px rgba(124, 92, 252, .45);
  filter: brightness(1.05);
}
.btn-generate-hero:active:not(:disabled) { transform: translateY(0); }
.btn-generate-hero:disabled { opacity: .55; cursor: default; box-shadow: none; }
#run-instruction { width: 100%; }

.fit-block { margin-top: .75rem; }
.fit-hd { font-weight: 600; font-size: .85rem; color: var(--muted); margin-bottom: .35rem; }
.fit-chips { display: flex; flex-wrap: wrap; gap: .35rem; }
.fit-split { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.course-list { display: flex; flex-direction: column; gap: .5rem; }
.course-card { display: flex; flex-direction: column; padding: .6rem .8rem; border: 1px solid var(--border);
  border-radius: 10px; text-decoration: none; color: inherit; transition: border-color .15s ease, transform .08s ease; }
.course-card:hover { border-color: #8b5cf6; transform: translateY(-1px); }
.course-title { font-weight: 600; }
.course-meta { font-size: .8rem; color: var(--muted); }
@media (max-width: 640px) { .fit-split { grid-template-columns: 1fr; } }

/* ════════════════════════════════════════════════════════════════════════
   Dark mode — toggled via [data-theme="dark"] on <html>.
   Structural colors come from the :root variables (overridden below);
   the rest are targeted fixes for hardcoded light values.
   ════════════════════════════════════════════════════════════════════════ */
[data-theme="dark"] {
  --bg:        #0f1115;
  --surface:   #181b21;
  --surface-2: #20242c;
  --border:    #2d323b;
  --text:      #e5e7eb;
  --muted:     #9aa3b2;
  --accent:    #4f8cf7;
  --accent-h:  #6b9bf9;
  --accent-bg: #1b2740;
  --success:   #4ade80;
  --danger:    #f87171;
  --ins-bg:    #14331f;
  --del-bg:    #3a1d1d;
  --pin-pending:  #fbbf24;
  --pin-resolved: #6b7280;
  --shadow:    0 1px 2px rgba(0,0,0,.45);
}

/* The active nav/chip uses --text as a fill with #fff text; in dark --text is
   light, so swap the text back to the dark bg for contrast. */
[data-theme="dark"] .nav-btn.active,
[data-theme="dark"] .chip.active { color: var(--bg); }

/* Theme toggle button */
.theme-toggle {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  border-radius: var(--radius);
  width: 32px; height: 32px;
  font-size: 0.95rem; line-height: 1;
  cursor: pointer; margin-right: .5rem;
  transition: background .15s, border-color .15s;
  flex-shrink: 0;
}
.theme-toggle:hover { background: var(--surface-2); border-color: var(--accent); }

/* ── Targeted surface fixes ── */
[data-theme="dark"] .research-cell { background: var(--surface-2); }
[data-theme="dark"] .job-card::before { background:#3a414d; }

/* Fit-rail colors need extra luminance on dark surfaces */
[data-theme="dark"] .fit-5 { color:#4ade80; }
[data-theme="dark"] .fit-4 { color:#a3e635; }
[data-theme="dark"] .fit-3 { color:#fbbf24; }
[data-theme="dark"] .fit-2 { color:#94a3b8; }
[data-theme="dark"] .fit-1 { color:#64748b; }

/* ── Warning / callout boxes (amber) ── */
[data-theme="dark"] .lang-warning,
[data-theme="dark"] .gen-resume-banner,
[data-theme="dark"] .banner,
[data-theme="dark"] .discover-hero,
[data-theme="dark"] .rp-warning {
  background:#2a2410; border-color:#4d3a16; color:#fcd34d; }
[data-theme="dark"] .rp-warning { border-left-color:#b45309; }

/* ── Indigo/violet pills ── */
[data-theme="dark"] .sec-badge,
[data-theme="dark"] .history-historical .h-tag-chip,
[data-theme="dark"] .h-tag-chip,
[data-theme="dark"] .fam-pr-account { background:#21204a; color:#c4b5fd; border-color:#3a3470; }
[data-theme="dark"] .fam-content-social { background:#241c4a; color:#c4b5fd; }
[data-theme="dark"] .via-tag { color:#c4b5fd; }

/* ── Blue pills ── */
[data-theme="dark"] .lang-en { background:#16284a; color:#93c5fd; }
[data-theme="dark"] .fam-social-media { background:#0e3340; color:#7dd3fc; }

/* ── Green pills ── */
[data-theme="dark"] .btn-ghost.copied,
[data-theme="dark"] .h-status-applied,
[data-theme="dark"] .status-applied,
[data-theme="dark"] .fam-community { background:#14331f; color:#86efac; }
[data-theme="dark"] .run-step.done { background:#14331f; color:#86efac; border-color:#1f4d32; }
[data-theme="dark"] .rp-badge-added { color:#86efac; }

/* ── Red pills ── */
[data-theme="dark"] .btn-ghost.copy-failed,
[data-theme="dark"] .status-dismissed,
[data-theme="dark"] .fam-hospitality { background:#3a1d1d; color:#fca5a5; border-color:#5b2b2b; }
/* Dutch-required is informational now: a neutral amber pill, matching the other lang chips. */
[data-theme="dark"] .lang-nl { background:#3a2410; color:#fdba74; border-color:transparent; }
[data-theme="dark"] .rp-badge-removed { color:#fca5a5; }
[data-theme="dark"] .para-copy-btn.copied { color:#4ade80; border-color:#4ade80; }
[data-theme="dark"] .para-copy-btn.copy-failed { color:#f87171; border-color:#f87171; }

/* ── Amber pills ── */
[data-theme="dark"] .lang-mixed,
[data-theme="dark"] .fam-marketer { background:#3a2e12; color:#fcd34d; }
[data-theme="dark"] .run-step.active { background:#3a2410; color:#fdba74; border-color:#574214; }
[data-theme="dark"] .fam-events { background:#3a2410; color:#fdba74; }

/* ── Pink / teal / slate pills ── */
[data-theme="dark"] .fam-influencer { background:#3a1830; color:#f9a8d4; }
[data-theme="dark"] .fam-recruitment { background:#0f3330; color:#5eead4; }
[data-theme="dark"] .h-status-draft,
[data-theme="dark"] .status-chip,
[data-theme="dark"] .fam-admin-office,
[data-theme="dark"] .fam-other { background:#262b34; color:#cbd5e1; }

[data-theme="dark"] .chip.seniority-chip { background:#3a2c12; color:#fcd34d; border-color:#57430f; }

/* ── Social brand chips that are black (invisible on dark) ── */
[data-theme="dark"] .src-chip.social-x { border-color:#e5e7eb; color:#e5e7eb; }
[data-theme="dark"] .src-chip.social-x:hover { background:#e5e7eb; color:#000; }
[data-theme="dark"] .src-chip.social-tiktok { border-color:#e5e7eb; color:#e5e7eb; }
[data-theme="dark"] .src-chip.social-tiktok:hover { background:#e5e7eb; color:#000; border-color:#e5e7eb; }

[data-theme="dark"] .btn-star.on { color:#fbbf24; }

/* ── Reusable tooltip (see core.js attachTooltip) ─────────────────────────────
   Not the native `title` attribute: that needs ~1s of hover and never fires on touch.
   This is a single shared floating bubble, shown on hover (short delay) or tap. */
.has-tooltip { cursor: help; }
.tooltip-bubble {
  position: fixed;
  transform: translate(-50%, -100%);
  background: var(--text);
  color: var(--surface);
  padding: 0.4rem 0.6rem;
  border-radius: var(--radius);
  font-size: 0.8rem;
  line-height: 1.3;
  max-width: 420px;
  max-height: 40vh;
  overflow-y: auto;
  z-index: 500;
  /* Hoverable and selectable. It was pointer-events:none, so a long failure reason could be read
     only as fast as you could scan it — you could not move onto the bubble, scroll it, or select
     the text to copy, and it vanished the moment the pointer left the anchor. */
  pointer-events: auto;
  user-select: text;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  box-shadow: var(--shadow);
  opacity: 1;
  transition: opacity 0.1s ease;
}
.tooltip-bubble.hidden { opacity: 0; visibility: hidden; pointer-events: none; }
[data-theme="dark"] .status-bookmarked { background:rgba(120,53,15,.35); color:#fbbf24; }
[data-theme="dark"] #jobs-bookmarks-toggle[aria-pressed="true"] {
  background:rgba(120,53,15,.35); border-color:#b45309; color:#fbbf24; }

/* ── Documents component (documents.js: wizard step 1 + Profile Documents panel) ──── */
.doc-panel { display: flex; flex-direction: column; gap: 0.75rem; }
.doc-dropzone {
  border: 1.5px dashed var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
  text-align: center;
  background: var(--bg);
  transition: border-color 0.12s ease, background 0.12s ease;
}
.doc-dropzone.is-dragover { border-color: var(--accent); background: var(--accent-bg); }
.doc-drop-copy { margin: 0 0 0.6rem; color: var(--muted); font-size: 0.875rem; }
.doc-errors { display: flex; flex-direction: column; gap: 0.4rem; }
.doc-errors.hidden { display: none; }
.doc-error {
  background: rgba(153, 27, 27, 0.08);
  border: 1px solid var(--danger);
  color: var(--danger);
  border-radius: var(--radius);
  padding: 0.5rem 0.7rem;
  font-size: 0.85rem;
}
.doc-list { display: flex; flex-direction: column; gap: 0.5rem; }
.doc-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.6rem 0.75rem;
}
.doc-row-pending { opacity: 0.6; }
.doc-row-main { display: flex; flex-direction: column; min-width: 0; flex: 1 1 12rem; }
.doc-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-meta { color: var(--muted); font-size: 0.8rem; }
.doc-kind { padding: 0.25rem 0.4rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.doc-current { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.8rem; color: var(--muted); }

/* ── Structured master-profile editor (profile.js renderMasterEditor) ─────────────── */
.me-editor { display: flex; flex-direction: column; gap: 1.75rem; }
/* Section headings sat at 0.9rem — barely above the field labels beneath them, so the form read
   as one undifferentiated column. A hairline rule does the separating that extra size would
   otherwise have to. */
.me-section > h4 {
  margin: 0 0 0.7rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.82rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.me-cards, .me-lang-rows, .me-contact-rows { display: flex; flex-direction: column; gap: 0.6rem; }
.me-card {
  position: relative;   /* anchors .me-card-remove, below */
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.7rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.8rem 0.85rem 0.85rem;   /* top gutter reserves the Remove button's row */
  background: var(--surface);
}
.me-card-field { display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.78rem; color: var(--muted); }
.me-card-field > span { font-weight: 500; letter-spacing: 0.01em; }
/* A label labels; the example demonstrates. Kept visually subordinate so it never competes. */
.me-hint { font-style: normal; font-weight: 400; color: var(--muted); opacity: 0.75; }
.me-hint::before { content: '· '; }
.me-card-field-wide { grid-column: 1 / -1; }
.me-input, .me-jsonbox, .me-skills, .me-bullets, .me-additional {
  width: 100%;
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
}
[data-theme="dark"] .me-input, [data-theme="dark"] .me-jsonbox,
[data-theme="dark"] .me-skills, [data-theme="dark"] .me-bullets,
[data-theme="dark"] .me-additional { background: var(--bg); }
/* Matches .settings-input:focus — the same focus affordance everywhere in the app. */
.me-input:focus, .me-jsonbox:focus, .me-skills:focus, .me-bullets:focus, .me-additional:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(31, 92, 230, .1);
}
.me-input::placeholder, .me-skills::placeholder, .me-bullets::placeholder,
.me-additional::placeholder { color: var(--muted); opacity: .55; }
/* Monospace belongs to raw JSON, where character alignment carries meaning. Bullets and skills
   are prose typed by a person and were being set in a code face for no reason. */
.me-jsonbox { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.8rem; }
.me-bullets, .me-skills, .me-additional { min-height: 5.25rem; resize: vertical; line-height: 1.5; }
.me-invalid { border-color: var(--danger); background: rgba(153, 27, 27, 0.06); }
.me-lang-row, .me-contact-row {
  display: grid; gap: 0.5rem; align-items: center;
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 0.5rem 0.6rem; background: var(--surface);
}
.me-lang-row { grid-template-columns: 1fr 1fr auto; }
.me-contact-row { grid-template-columns: 1fr 2fr auto; }
/* Remove: quiet until you reach for it. Pinned to the card's top-right rather than sitting on a
   full-width row at the bottom, where two adjacent cards' buttons read as a pair. */
.me-card-remove { position: absolute; top: 0.4rem; right: 0.5rem; }
.me-remove {
  color: var(--muted);
  border-color: transparent;
  transition: color .12s, border-color .12s, background .12s;
}
.me-remove:hover, .me-remove:focus-visible {
  color: var(--danger);
  border-color: var(--danger);
  background: var(--del-bg);
}
.me-save-row { display: flex; align-items: center; gap: 0.75rem; }
.me-save-row.hidden { display: none; }
.me-save-status { font-size: 0.85rem; color: var(--muted); }
.me-empty { color: var(--muted); font-size: 0.875rem; }

/* ── First-run setup wizard (setup.js / view-setup) ─────────────────────────────── */
body.setup-active .nav-links,
body.setup-active #btn-settings,
body.setup-active #btn-theme { display: none; }
.setup-card { max-width: 44rem; margin: 1.5rem auto; }
.setup-rail { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; margin-bottom: 1.25rem; }
.setup-rail-step {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.78rem; color: var(--muted);
}
.setup-rail-step.is-active { color: var(--text); font-weight: 600; }
.setup-rail-dot {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.4rem; height: 1.4rem; border-radius: 50%;
  border: 1px solid var(--border); font-size: 0.72rem;
}
.setup-rail-step.is-active .setup-rail-dot { border-color: var(--accent); color: var(--accent); }
.setup-rail-step.is-done .setup-rail-dot { background: var(--accent-bg); border-color: var(--accent); color: var(--accent); }
.setup-body { min-height: 8rem; }
.setup-step-title { margin: 0 0 0.5rem; }
.setup-step-copy { color: var(--muted); font-size: 0.9rem; margin: 0 0 1rem; }
.setup-hint { color: var(--muted); font-size: 0.82rem; }
.setup-footer { display: flex; align-items: center; gap: 0.6rem; margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.setup-footer-spacer { flex: 1; }
.setup-footer .hidden { display: none; }

/* ── Setup: profile-build screen (a full-screen wait, not a step) ───────────────── */
.setup-card.is-building .setup-rail,
.setup-card.is-building .setup-footer { display: none; }
.setup-building { text-align: center; padding: 0.5rem 0 1rem; }
.setup-build-status { font-size: 0.88rem; color: var(--muted); margin-top: 0.75rem; }
.setup-build-phases { list-style: none; margin: 1.25rem auto 0; padding: 0; max-width: 20rem; text-align: left; }
.setup-build-phases li { display: flex; align-items: center; gap: 0.55rem; padding: 0.28rem 0; font-size: 0.86rem; color: var(--muted); }
.setup-build-phases li.is-done,
.setup-build-phases li.is-active { color: var(--text); }
.setup-build-phases li.is-active { font-weight: 600; }
.setup-phase-mark { flex: none; width: 1rem; height: 1rem; border-radius: 50%; border: 2px solid var(--border); box-sizing: border-box; }
.setup-build-phases li.is-done .setup-phase-mark { background: var(--accent); border-color: var(--accent); }
.setup-build-phases li.is-active .setup-phase-mark { border-color: var(--accent); border-top-color: transparent; animation: spin 0.7s linear infinite; }
.setup-build-phases.is-stalled li.is-active .setup-phase-mark { animation: none; border-color: var(--border); }
.setup-building-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; margin-top: 1.25rem; }

/* ── Rebuild-overwrite dialog ──────────────────────────────────────────────────── */
.rebuild-keep-opts { display: flex; flex-direction: column; gap: 0.4rem; margin: 0.75rem 0; }
.rebuild-keep-opt { display: flex; align-items: center; gap: 0.4rem; font-size: 0.9rem; }

/* ── Setup preferences step ────────────────────────────────────────────────────── */
.setup-pref-group { margin: 1rem 0; padding: 0.9rem; border: 1px solid var(--border); border-radius: var(--radius); }
.setup-pref-group > h4 { margin: 0 0 0.25rem; }
.setup-field { display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.82rem; color: var(--muted); margin: 0.6rem 0; }
.setup-field input, .setup-field textarea { font: inherit; padding: 0.4rem 0.5rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); }
.setup-check { display: flex; align-items: center; gap: 0.4rem; font-size: 0.88rem; margin: 0.5rem 0; }

/* Target-role tag chips: toggle on click, plus a free-add field */
.setup-tag-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; margin: 0.15rem 0 0.25rem; }
.setup-chip { font: inherit; font-size: 0.78rem; padding: 0.2rem 0.55rem; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--text); cursor: pointer; }
.setup-chip:hover { border-color: var(--accent); }
.setup-chip.is-on { background: var(--accent); border-color: var(--accent); color: #fff; }
.setup-chip.is-on:hover { color: #fff; }
.setup-chip-x { margin-left: 0.3rem; opacity: 0.85; }
.setup-chip-add { font: inherit; font-size: 0.78rem; padding: 0.2rem 0.5rem; min-width: 8rem; flex: 1 0 8rem; border: 1px dashed var(--border); border-radius: 999px; background: transparent; color: var(--text); }

/* ── Admin: invites ────────────────────────────────────────────────────────────── */
.admin-invite-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; padding: 0.35rem 0; font-size: 0.85rem; border-bottom: 1px solid var(--border); }
.admin-invite-new { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }
.admin-invite-new input { font: inherit; padding: 0.4rem 0.55rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); min-width: 14rem; }

/* ── Admin: database console ──────────────────────────────────────────────────── */
.admin-db-queries { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.75rem; }

/* ── Profile: sign-out ─────────────────────────────────────────────────────────── */
.profile-signout { margin-top: 1.5rem; text-align: center; }

/* ── Place picker (search location) ── */
/* initPlacePicker wraps the input in .place-field so the dropdown anchors to the input rather
   than to the surrounding label, which also holds the hint line. */
.place-field { position: relative; display: block; }
.place-field > input { width: 100%; }
.place-suggest {
  position: absolute; z-index: 50; left: 0; right: 0; top: 100%;
  margin-top: 2px; max-height: 15rem; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.place-suggest.hidden { display: none; }
.place-opt {
  display: flex; align-items: baseline; justify-content: space-between; gap: .75rem;
  width: 100%; padding: .4rem .6rem; border: none; background: none; cursor: pointer;
  font: inherit; font-size: .84rem; color: var(--text); text-align: left;
}
.place-opt:hover, .place-opt.is-active { background: var(--accent-bg); }
.place-opt-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The whole reason this control exists: an Area geoId is the only way to widen a search, since
   LinkedIn's guest endpoint ignores `distance`. Say so where the choice is made. */
.place-opt-tag {
  flex: none; font-size: .68rem; padding: .05rem .4rem; border-radius: 999px;
  background: var(--accent-bg); color: var(--accent); border: 1px solid var(--accent);
}

/* Place chips (search locations) — same visual language as the target-role tag chips. */
.place-chips { display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.place-chip {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .78rem; padding: .2rem .3rem .2rem .6rem;
  border: 1px solid var(--accent); border-radius: 999px;
  background: var(--accent-bg); color: var(--accent);
}
.place-chip-x {
  border: none; background: none; cursor: pointer; color: inherit;
  font-size: .9rem; line-height: 1; padding: 0 .2rem;
}
.place-chip-add { flex: 1 1 12rem; min-width: 10rem; }

/* ── Preference groups (Settings + the setup wizard) ──────────────────────────
   One component, both views, because the distinction it encodes is the same in both and is the
   thing users most need to see: a SCRAPING setting decides whether an ad is fetched at all, a
   SCORING setting only decides where a fetched ad ranks. Getting the first wrong means never
   seeing the job; getting the second wrong means the job is there, just buried. The left rule
   groups the fields, and the chip names which kind you are looking at. */
.pref-group { border-left: 3px solid var(--border); padding-left: .9rem; margin: 1.4rem 0; }
.pref-group:first-child { margin-top: .2rem; }
.pref-group.is-fetch { border-left-color: var(--accent); }
.pref-group.is-score { border-left-color: var(--success); }
.pref-group-hd { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.pref-group-title { font-size: .95rem; font-weight: 700; color: var(--text); }
.pref-group-tag {
  font-size: .62rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  padding: .1rem .45rem; border-radius: 999px; border: 1px solid currentColor;
}
.pref-group.is-fetch .pref-group-tag { color: var(--accent); }
.pref-group.is-score .pref-group-tag { color: var(--success); }
.pref-group.is-view  .pref-group-tag { color: var(--muted); }
.pref-group-why { font-size: .78rem; color: var(--muted); margin: .25rem 0 .7rem; max-width: 60ch; }
/* A number field is 2-3 characters of content; stretching it to the container reads as a text
   box and invites the wrong kind of input. */
.setup-field input[type="number"], .settings-input[type="number"] { max-width: 9rem; }

/* ── History: generation attempts that produced no application ────────────────
   A failed generation writes no `applications` row, so without a row of its own the attempt is
   invisible in History. Muted by default and only red once it has actually failed — an attempt
   is not an error until it is one. */
.h-attempt { opacity: .92; }
.h-attempt-avatar { background: var(--surface-2); color: var(--muted); }
.h-attempt.is-failed .h-attempt-avatar { background: var(--del-bg); color: var(--danger); }
.h-attempt-state { font-weight: 600; color: var(--muted); }
.h-attempt.is-failed .h-attempt-state { color: var(--danger); }
.h-attempt-why {
  margin-left: .4rem; border: none; background: none; padding: 0;
  font: inherit; font-size: inherit; color: var(--accent);
  text-decoration: underline; text-underline-offset: 2px; cursor: help;
}

/* Admin: model run log */
.admin-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.admin-table th, .admin-table td { text-align: left; padding: 0.3rem 0.5rem; border-bottom: 1px solid var(--border); vertical-align: top; }
.admin-table th { color: var(--muted); font-weight: 600; }
.admin-run-fallback { color: var(--danger); font-weight: 600; }

/* Admin: one card per instance credential, in the order calls try them. */
.admin-cred-row { border: 1px solid var(--border); border-radius: var(--radius); padding: 0.9rem 1rem;
  margin-bottom: 0.75rem; display: flex; flex-direction: column; gap: 0.6rem; background: var(--surface); }
.admin-cred-row.is-first { border-color: var(--accent); }
.admin-cred-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.admin-cred-label { font-weight: 600; }
.admin-cred-badge { font-size: 0.75rem; font-weight: 600; padding: 0.1em 0.6em; border-radius: 999px;
  background: var(--surface-2); color: var(--muted); }
.admin-cred-row.is-first .admin-cred-badge { background: var(--accent-bg); color: var(--accent); }
.admin-cred-spacer { flex: 1 1 auto; }
.admin-cred-meta { display: flex; flex-wrap: wrap; gap: 0.4rem 1.2rem; font-size: 0.85rem; color: var(--muted); }
.admin-cred-masked { font-family: ui-monospace, monospace; color: var(--text); }
.admin-cred-models { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 0.6rem; }
.admin-cred-models label, .admin-add-cred-fields label { display: flex; flex-direction: column; gap: 0.25rem; margin: 0; }
.admin-cred-save { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; }
.admin-add-cred { border: 1px dashed var(--border); border-radius: var(--radius); padding: 0.9rem 1rem;
  display: flex; flex-direction: column; gap: 0.6rem; }
.admin-add-cred-title { font-weight: 600; }
.admin-add-cred-fields { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.6rem; }
.admin-add-cred-fields label:nth-child(2) { flex: 1 1 14rem; }
.admin-add-cred-fields .settings-input { height: 2.4rem; box-sizing: border-box; }
