/*
  Resume Tailor — tool chrome ("Spread" direction).

  Independent from the resume PDF's own stylesheet (print_resume.css) and
  hand-authored from scratch — no Tailwind, no build step, no shared classes
  with the PDF template. See REDESIGN plan for the full rationale.

  Signature idea: the app is shaped like an open two-page spread from step
  one. The tailored/final side is the lit page (bright white); anything
  provisional or original sits on a recessed warm grey. Colour is spent in
  exactly one place — changed text, the active step, focus — not sprayed
  across the chrome.

  Palette/type/radius tokens below are ported from jobrhyme's brand seed
  (bronze/amber, hue 38 / chroma 0.16 / lightness 0.55, radius 0.5rem, Inter) —
  same oklch() math, literal values instead of jobrhyme's live calc() ramp
  since this is a single fixed (light-only) theme, not a seed to re-derive.
  `--added`/`--added-wash` (diff "addition" green) and the danger/added
  border+text companions below have no jobrhyme equivalent (it has no diff
  view) — picked to read as warm-neutral against the bronze accent, not
  literally ported. `--font-read` (Newsreader) and `--font-mono` (JetBrains
  Mono) are also kept rather than flattened to Inter: they're content-type
  choices (serif for resume prose, mono for dates/meta) jobrhyme never had to
  make, not brand identity.
*/

/* ---------- Tokens ---------- */
:root {
  --page-recto: oklch(1 0.002 38);      /* the lit page: tailored content, primary surfaces */
  --page-verso: oklch(0.96 0.006 38);   /* the recessed page: original content, secondary surfaces */
  --ink: oklch(0.18 0.01 38);
  --dim: oklch(0.5 0.02 38);
  --line: oklch(0.9 0.008 38);
  --accent: oklch(0.47 0.16 38);        /* jobrhyme brand-600 */
  --accent-hover: oklch(0.39 0.144 38); /* jobrhyme brand-700 */
  /* Wash tones below are hand-softened, not jobrhyme's literal brand-100/200
     (chroma 0.064/0.096) — at this hue (~38, orange/amber) that chroma reads
     as a bold salmon at large-panel size (.notes, .message-*), noticeably
     more saturated than the pale indigo wash it replaces. Chroma dialed down
     until sampled rgb() spread matched the original wash/border pairs'
     spread; --accent itself and small-badge uses stay at jobrhyme's literal
     values. */
  --accent-wash: oklch(0.96 0.02 38);
  --accent-wash-line: oklch(0.89 0.04 38);
  --accent-wash-ink: oklch(0.32 0.1 38);
  --success: oklch(0.55 0.13 150);       /* applied / in progress (#109) */
  --success-wash: oklch(0.96 0.03 150);
  --danger: oklch(0.577 0.245 27.325);  /* jobrhyme's own --destructive */
  --danger-wash: oklch(0.96 0.018 27.325);
  --danger-wash-line: oklch(0.88 0.045 27.325);
  --danger-wash-ink: oklch(0.35 0.14 27.325);
  --added: oklch(0.5 0.13 155);         /* not a jobrhyme token — see file header */
  --added-wash: oklch(0.95 0.02 155);
  --added-wash-line: oklch(0.86 0.06 155);
  --added-wash-ink: oklch(0.32 0.09 155);

  --font-ui: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-read: "Newsreader", Georgia, serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Consolas, monospace;

  --radius: 0.5rem;
  --radius-sm: 0.375rem;
  --shadow-card: 0 1px 2px oklch(0.2 0.03 38 / 0.06), 0 8px 24px -12px oklch(0.2 0.04 38 / 0.14);
  --content-width: 46rem;
  --content-width-wide: 76rem;
}

@media (prefers-color-scheme: dark) {
  /* Single-user internal tool, always used in daylight-adjacent contexts
     (reading resume text) — deliberately no dark theme. Explicit no-op
     block so it reads as a decision, not an oversight. */
}

/* ---------- Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--page-verso);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 15.5px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.25; }
p { margin: 0 0 0.75em; }
p:last-child { margin-bottom: 0; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 0.15em; }
a:hover { text-decoration-thickness: 2px; }
ul, ol { margin: 0; padding: 0; list-style: none; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---------- Shell ---------- */
.site-nav {
  background: var(--page-recto);
  border-bottom: 1px solid var(--line);
  /* Its own stacking level above the page's sticky bars (the wizard's
     stepper and the editor's status bar sit at 15-20), so open menus -
     the phone menu, the client switcher - are never painted
     behind them (#106). */
  position: relative;
  z-index: 40;
}
.site-nav-inner {
  max-width: var(--content-width-wide);
  margin: 0 auto;
  padding: 0.9rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: relative; /* anchors .nav-links's dropdown positioning below */
}
.site-brand {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ink);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
/* Candidate logo (base.html, logo test): the lockup, or just the square
   mark below 400px - same height either way. */
.site-brand picture { display: flex; }
.site-brand-logo { display: block; height: 32px; width: auto; }
.beta-badge {
  font-family: var(--font-ui);
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-wash);
  border: 1px solid var(--accent-wash-line);
  border-radius: 999px;
  padding: 0.12rem 0.5rem;
}
.nav-links { display: flex; align-items: center; gap: 1rem; }

/* Hamburger button — hidden by default, shown only under the breakpoint
   below where .nav-links itself switches from an inline row to a
   dropdown. Three-line icon drawn with the button's own border-box
   (a middle bar plus a ::before/::after pair) rather than an inline SVG —
   nothing else in this app's chrome uses icons, so one three-line CSS
   shape is simpler than adding an icon dependency for a single glyph. */
.nav-menu-toggle {
  display: none;
  background: none;
  border: none;
  padding: 0.5rem;
  margin: -0.5rem 0 -0.5rem -0.5rem;
  cursor: pointer;
}
.nav-menu-icon {
  position: relative;
  display: block;
  width: 1.15rem;
  height: 2px;
  background: var(--ink);
  border-radius: 1px;
}
.nav-menu-icon::before, .nav-menu-icon::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  background: var(--ink);
  border-radius: 1px;
}
.nav-menu-icon::before { top: -6px; }
.nav-menu-icon::after { top: 6px; }

@media (max-width: 640px) {
  .nav-menu-toggle { display: inline-flex; align-items: center; justify-content: center; order: 1; }
  .nav-links {
    display: none;
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    z-index: 20;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    min-width: 10rem;
    background: var(--page-recto);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
    padding: 0.4rem;
  }
  .nav-links.is-open { display: flex; }
  .nav-links a, .nav-links .nav-logout-form, .nav-links button.nav-logout {
    width: 100%;
    text-align: left;
    padding: 0.6rem 0.65rem;
    border-radius: var(--radius-sm);
  }
  .nav-links a:hover, .nav-links button.nav-logout:hover { background: var(--page-verso); color: var(--accent); }
}
.nav-logout {
  font-size: 0.82rem;
  color: var(--dim);
  text-decoration: none;
}
.nav-logout:hover { color: var(--accent); }
.nav-profile-link { display: inline-flex; align-items: center; gap: 0.35rem; }
.nav-profile-icon { width: 1.05em; height: 1.05em; flex-shrink: 0; }
/* "Log out" is a form button now (Django's LogoutView needs POST), not a
   plain <a> — reset button chrome so it still reads as the same plain-text
   link the "Log in" <a> next to it is. */
.nav-logout-form { display: inline-flex; }
button.nav-logout {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
}

.page-main {
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 2.25rem 1.5rem 4rem;
}
.page-main.wide { max-width: var(--content-width-wide); }

.pending-approval-banner {
  background: var(--accent-wash);
  border-bottom: 1px solid var(--accent-wash-line);
}
.pending-approval-banner-inner {
  max-width: var(--content-width-wide);
  margin: 0 auto;
  padding: 0.6rem 1.5rem;
  font-size: 0.85rem;
  color: var(--accent-wash-ink);
  text-align: center;
}

.page-eyebrow {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 0.5rem;
}
.page-title {
  font-family: var(--font-ui);
  font-size: 1.85rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.page-lede {
  font-size: 1rem;
  color: var(--dim);
  max-width: 38rem;
  margin-top: 0.6rem;
}
.page-section-heading {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 0.9rem;
}

/* ---------- Messages ---------- */
.messages { margin: 1.25rem 0 0; display: flex; flex-direction: column; gap: 0.5rem; }
.message {
  padding: 0.7rem 1rem;
  border-radius: var(--radius);
  font-size: 0.87rem;
  line-height: 1.5;
  border: 1px solid transparent;
}
.message-success { background: var(--added-wash); border-color: var(--added-wash-line); color: var(--added-wash-ink); }
.message-info { background: var(--accent-wash); border-color: var(--accent-wash-line); color: var(--accent-wash-ink); }
.message-error, .message-warning { background: var(--danger-wash); border-color: var(--danger-wash-line); color: var(--danger-wash-ink); }

/* ---------- Stepper ---------- */
/* Step tabs (see templatetags/wizard_tags.py). Sticky so they stay in
   reach the whole way down a long result page - the point is that moving
   between steps never needs the browser's Back button. The bar paints the
   page background behind itself so content scrolls under it cleanly. */
.stepper-bar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--page-verso);
  margin: -0.75rem 0 2rem;
  padding-top: 0.75rem;
}
.stepper {
  display: flex;
  margin: 0;
  padding: 0;
  border-bottom: 1px solid var(--line);
}
.stepper-step {
  flex: 1;
  min-width: 0;
  color: var(--dim);
  font-size: 0.82rem;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.stepper-link {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.75rem 0.7rem;
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
a.stepper-link:hover { background: var(--page-recto); }
a.stepper-link:hover .stepper-label { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.15em; }
.stepper-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  border: 1px solid var(--line);
  background: var(--page-recto);
  flex-shrink: 0;
}
.stepper-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.stepper-label { white-space: nowrap; font-weight: 600; }
.stepper-detail {
  font-size: 0.74rem; color: var(--dim); font-weight: 400;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.stepper-step.is-current { color: var(--ink); border-bottom-color: var(--accent); }
.stepper-step.is-current .stepper-link { background: var(--page-recto); }
.stepper-step.is-current .stepper-num { background: var(--accent); border-color: var(--accent); color: #fff; }
.stepper-step.is-done { color: var(--ink); }
.stepper-step.is-done .stepper-num { background: var(--added-wash); border-color: var(--added); color: var(--added); }
.stepper-step.is-available { color: var(--ink); }
.stepper-step.is-available .stepper-num { border-color: var(--accent-wash-line); color: var(--accent); }

/* Phone width: number stacked over a short label on every tab (a row of
   bare checkmarks gives no clue which step is which); the status line
   drops out, still available as the link's title. */
@media (max-width: 640px) {
  .stepper-link { flex-direction: column; gap: 0.25rem; padding: 0.45rem 0.2rem 0.55rem; text-align: center; }
  .stepper-text { align-items: center; }
  .stepper-label { font-size: 0.7rem; }
  .stepper-detail { display: none; }
}

/* ---------- Cards & forms ---------- */
.card {
  background: var(--page-recto);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 1.75rem;
}
.card + .card { margin-top: 1.25rem; }

.field { margin-top: 1.25rem; }
.field:first-child { margin-top: 0; }
.field label {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 0.4rem;
}
.field .hint { font-size: 0.78rem; color: var(--dim); margin-top: 0.4rem; }

/* Styled stand-in for the raw OS file-picker button — pairs with a
   visually-hidden <input type="file"> (see forms.py/step_resume.html);
   the previous bare native button looked visually jarring next to every
   other button in the app. */
.file-upload-row { display: flex; align-items: center; gap: 0.85rem; flex-wrap: wrap; }
.file-upload-btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0.55rem 1.1rem;
  background: var(--page-recto); color: var(--ink); border: 1px solid var(--line);
  border-radius: var(--radius-sm); font-size: 0.85rem; font-weight: 600;
  cursor: pointer; transition: border-color 0.15s, color 0.15s;
}
.file-upload-btn:hover { border-color: var(--accent); color: var(--accent); }
.file-upload-name { font-size: 0.85rem; color: var(--dim); }

.field input[type="text"], .field input[type="url"], .field input[type="password"],
.field input[type="email"], .field textarea, .field select {
  width: 100%;
  box-sizing: border-box;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 0.92rem;
  background: var(--page-recto);
  color: var(--ink);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.field textarea { resize: vertical; }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-wash);
}
textarea#id_resume_yaml {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1.6;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.65rem 1.4rem;
  background: var(--accent);
  color: #fff;
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, opacity 0.15s;
}
.btn:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
a.btn { text-decoration: none; }  /* a link styled as a button isn't underlined */
.btn:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-secondary { background: var(--page-recto); color: var(--ink); border-color: var(--line); }
.btn-secondary:hover { border-color: var(--accent); color: var(--accent); background: var(--page-recto); }
.btn-ghost {
  background: transparent; color: var(--dim); border: none; padding: 0.4rem 0.1rem;
  font-size: 0.82rem; text-decoration: underline; text-underline-offset: 0.2em; cursor: pointer;
}
.btn-ghost:hover { color: var(--accent); }
/* Review step (review.html): "Looks good" + Save, above and below the diff. */
.review-next { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; margin: 1.25rem 0 1.5rem; }
.review-next form { margin: 0; }
.review-next-bottom { margin-top: 2rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }
/* Result step: the resume itself, full width, in a card frame. Three
   classes, to outrank .resume-pdf-preview.is-expanded's 32rem (defined
   later in this file). */
.resume-pdf-preview.result-preview.is-expanded {
  height: 44rem; margin: 1.25rem 0 1.5rem;
  border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-card);
}
@media (max-width: 760px) { .resume-pdf-preview.result-preview.is-expanded { height: 30rem; } }
/* Where a framed PDF won't show (most phones): the first page as an image. */
.resume-pdf-preview.result-preview.is-expanded.is-image { height: auto; min-height: 12rem; }
.result-preview-image { display: block; position: relative; text-decoration: none; }
.result-preview-image[hidden] { display: none; }
/* No JS: no frame or image is loaded, so the loader is replaced by a link. */
.result-preview-noscript { position: absolute; inset: auto 0 45% 0; width: max-content; margin: 0 auto; z-index: 2; }
.result-preview-image img { display: block; width: 100%; height: auto; }
.result-preview-open {
  position: absolute; right: 0.6rem; bottom: 0.6rem;
  padding: 0.35rem 0.7rem; border-radius: 999px;
  background: var(--ink); color: var(--page-recto); font-size: 0.78rem; font-weight: 600;
}
.actions { margin-top: 1.75rem; display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
/* Groups controls into their own line within .actions (result.html's
   export cluster vs. save/navigation cluster) without changing .actions
   itself — that's still a plain single-row flex container everywhere
   else it's used (step_resume.html's upload/YAML-form button groups).
   flex: 1 1 100% claims the full row width, so .actions's own flex-wrap
   pushes the next .actions-row onto a new line on its own. */
.actions-row { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; flex: 1 1 100%; }
.actions-row-secondary { margin-top: 0.1rem; }
.pdf-actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }

/* Compact <select>, sized to sit inline next to .btn/.btn-ghost in a
   .resume-row-actions row — .field select (the form-field version) is
   width:100% and meant for a block-level container, wrong fit here. */
.theme-select-inline {
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 0.82rem;
  background: var(--page-recto);
  color: var(--ink);
}
.theme-select-inline:focus { outline: none; border-color: var(--accent); }
.application-status-select { margin-top: 0.5rem; }
.pdf-actions select {
  padding: 0.6rem 2rem 0.6rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 0.85rem;
  background: var(--page-recto);
  color: var(--ink);
}
.pdf-actions select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-wash); }

.errorlist { list-style: none; padding: 0; margin: 0.75rem 0 0; }
.errorlist li {
  background: var(--danger-wash); border: 1px solid var(--danger-wash-line); color: var(--danger-wash-ink);
  padding: 0.65rem 0.9rem; border-radius: var(--radius-sm); font-size: 0.85rem; margin-bottom: 0.5rem;
}
.notes {
  background: var(--accent-wash); border: 1px solid var(--accent-wash-line); color: var(--accent-wash-ink);
  padding: 1rem 1.1rem; border-radius: var(--radius); margin-top: 1rem; font-size: 0.87rem; line-height: 1.55;
}
.notes strong { display: block; margin-bottom: 0.15rem; }
.notes-danger {
  background: var(--danger-wash); border-color: var(--danger-wash-line); color: var(--danger-wash-ink);
}
.gap-list { list-style: none; padding: 0; margin: 0.5rem 0 0; display: flex; flex-direction: column; gap: 0.4rem; }
.gap-item { font-size: 0.87rem; line-height: 1.5; }
.gap-priority {
  display: inline-block; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase;
  padding: 0.1rem 0.45rem; border-radius: 999px; margin-right: 0.4rem; vertical-align: middle;
}
.gap-priority-required { background: var(--danger-wash); color: var(--danger-wash-ink); }
.gap-priority-nice_to_have { background: var(--page-verso); border: 1px solid var(--line); color: var(--dim); }
.gap-count-badge {
  display: inline-block; font-family: var(--font-mono); font-size: 0.78rem; font-weight: 600;
  background: var(--accent-wash); color: var(--accent-wash-ink); padding: 0.05rem 0.45rem;
  border-radius: var(--radius-sm); margin-right: 0.5rem; vertical-align: middle;
}
.gap-item-meta { display: block; font-size: 0.78rem; color: var(--dim); margin-top: 0.1rem; }

/* Recurring-gaps chips on /resumes/ — a grid of small chips rather than
   the plain .gap-list/.gap-item stack above (kept as-is: still used by
   result.html's per-result gaps and landing.html's illustrative preview,
   both fine as a plain list in their own single-column context). A
   chip's small footprint suits this page's dashboard-of-cards language
   better than a tall vertical list would once there are several gaps.

   Shape/color vary with what the data says, not for decoration's own
   sake — see resume_library.html's comment above the loop. Badge sizing
   (2.25rem, mono) matches landing.html's .step-num; the hexagon clip-path
   is new, but only applied to the badge — a short, fixed "N×" string,
   never the variable-length requirement text next to it, which stays in
   a plain rectangular card so it can wrap normally at any length. */
.gap-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.6rem;
  margin-top: 0.5rem;
}
.gap-chip {
  border-radius: var(--radius);
  padding: 0.85rem 1rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
}
.gap-chip-required { background: var(--danger-wash); border: 1px solid var(--danger-wash-line); }
.gap-chip-nice { background: var(--accent-wash); border: 1px solid var(--accent-wash-line); }
.gap-chip-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.25rem; height: 2.25rem;
  clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
  color: #fff; font-family: var(--font-mono);
  font-size: 0.82rem; font-weight: 600; flex-shrink: 0;
}
/* The wash tint above is real but too pale to actually read as two
   colors (both ~96% lightness, ~0.02 chroma) — checked computed styles
   directly to confirm. The badge is where the required/nice-to-have
   distinction needs to actually be visible: solid --danger/--accent,
   both verified against white text (4.76:1 / 7.35:1 — WCAG AA is 4.5:1
   for normal text), not just eyeballed. */
.gap-chip-required .gap-chip-badge { background: var(--danger); }
.gap-chip-nice .gap-chip-badge { background: var(--accent); }
.gap-chip-requirement { font-weight: 600; font-size: 0.87rem; color: var(--ink); }
.gap-chip .gap-item-meta { margin-top: -0.15rem; }

/* The single most-recurring gap (gap_summary's first entry, already
   sorted by count descending) gets more room and a bigger badge instead
   of competing at the same weight as every other chip. */
.gap-chip-featured {
  grid-column: span 2;
  padding: 1.1rem 1.25rem;
}
.gap-chip-featured .gap-chip-badge { width: 2.75rem; height: 2.75rem; font-size: 0.95rem; }
.gap-chip-featured .gap-chip-requirement { font-size: 1.05rem; }
@media (max-width: 460px) {
  .gap-chip-featured { grid-column: span 1; }
}

details.advanced { margin-top: 1.5rem; }
details.advanced > summary {
  cursor: pointer; font-size: 0.82rem; font-weight: 600; color: var(--dim);
  list-style: none; display: inline-flex; align-items: center; gap: 0.35rem;
}
details.advanced > summary::-webkit-details-marker { display: none; }
/* A CSS-drawn triangle, not the Unicode "▸"/"▾" glyphs this used to be —
   those rendered as a bare "·" in real testing (Chrome/macOS), reading as
   a stray, broken bullet with nothing before it. Border-trick triangle
   has no font/glyph dependency at all, so there's nothing left to fail to
   render; rotating the same shape 90° for the open state also means only
   one shape to draw instead of two separate glyphs to keep in sync. */
details.advanced > summary::before {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 3.5px 0 3.5px 5px;
  border-color: transparent transparent transparent currentColor;
  transition: transform 0.15s;
}
details.advanced[open] > summary::before { transform: rotate(90deg); }
details.advanced > summary:hover { color: var(--accent); }
details.advanced .field { margin-top: 1rem; }
details.advanced-body-pad { padding-top: 1rem; }

.upload-panel {
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  padding: 1.5rem;
  background: var(--page-verso);
}
.confirm-row { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-top: 0.5rem; }

/* ---------- Working / progress panel ---------- */
.working {
  margin-top: 1.5rem;
  padding: 1.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--page-recto);
  text-align: center;
}
.working[hidden] { display: none; }
.working .echo-loader { margin: 0 auto 0.9rem; }
.working-label { font-size: 0.9rem; color: var(--ink); font-weight: 500; }
.working-sub { font-size: 0.8rem; color: var(--dim); margin-top: 0.35rem; }

/* Echo loader: see echo-loader.css. */

/* Waiting states that use it: a style thumbnail or PDF preview while it
   renders, and a job's panel while it loads. The loader sits centered
   over the box and fades once the content is in. */
.is-loading-box { position: relative; }
.is-loading-box > .echo-loader-overlay {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.5rem;
  background: var(--page-verso); transition: opacity 0.35s ease; z-index: 1; pointer-events: none;
}
.is-loading-box.is-loaded > .echo-loader-overlay { opacity: 0; }
/* Stop a faded-out loader's animations (they'd keep running, and the JR
   ones repaint every frame). */
.is-loading-box.is-loaded > .echo-loader-overlay * { animation: none; }
.echo-loader-caption { font-size: 0.78rem; color: var(--dim); }
.job-detail-loading { display: flex; flex-direction: column; align-items: center; gap: 0.6rem; padding: 2.5rem 1rem; }

/* ---------- Result header / spread ---------- */
.result-header { margin-bottom: 1.75rem; }
.result-header h1 { font-size: 1.5rem; }
.result-posting-link { font-size: 0.85em; text-decoration: none; }
.result-meta { color: var(--dim); font-size: 0.88rem; margin-top: 0.3rem; }

.stats-bar {
  display: flex; flex-wrap: wrap; gap: 1.5rem;
  padding: 1rem 1.25rem; margin: 1.5rem 0;
  background: var(--page-recto); border: 1px solid var(--line); border-radius: var(--radius);
}
.stat { display: flex; flex-direction: column; }
.stat-value { font-family: var(--font-mono); font-size: 1.1rem; font-weight: 500; }
.stat-label { font-size: 0.72rem; color: var(--dim); text-transform: uppercase; letter-spacing: 0.05em; }

.untouched-note {
  font-size: 0.82rem; color: var(--dim); margin: 0.75rem 0 1.75rem;
  padding: 0.75rem 1rem; border-left: 2px solid var(--line);
}

/* The spread itself: verso (original) recessed, recto (tailored) lit. */
.spread-head {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: var(--radius) var(--radius) 0 0; overflow: hidden;
}
.spread-head > div {
  padding: 0.6rem 1.25rem; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
}
.spread-head .col-original { background: var(--page-verso); color: var(--dim); }
.spread-head .col-tailored { background: var(--page-recto); color: var(--accent); }

.diff-summary {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-top: none; border-radius: 0 0 var(--radius) var(--radius);
  margin-bottom: 1.75rem; font-family: var(--font-read); font-size: 1rem; line-height: 1.65;
}
.diff-summary > div { padding: 1.25rem; }
.diff-summary .col-original { background: var(--page-verso); color: var(--dim); }
.diff-summary .col-tailored { background: var(--page-recto); }

/* ---------- Diff entries ---------- */
.diff-entry {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-bottom: 1rem;
  background: var(--page-recto);
  overflow: hidden;
}
.diff-entry > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.25rem;
  background: var(--page-verso);
}
.diff-entry > summary::-webkit-details-marker { display: none; }
.diff-entry-title { display: flex; flex-direction: column; gap: 0.1rem; }
.diff-entry-role { font-weight: 600; }
.diff-entry-company { font-size: 0.82rem; color: var(--dim); }
.diff-entry-meta { display: flex; align-items: center; gap: 0.75rem; flex-shrink: 0; }
.diff-entry-dates { font-size: 0.78rem; color: var(--dim); font-family: var(--font-mono); white-space: nowrap; }

.pill {
  display: inline-block; font-size: 0.68rem; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; padding: 0.15rem 0.55rem; border-radius: 999px;
}
.pill-unchanged { background: var(--line); color: var(--dim); }
.pill-changed { background: var(--accent-wash); color: var(--accent); }

.diff-entry-body { padding: 1rem 1.25rem 1.25rem; }
.diff-rationale {
  font-size: 0.85rem; color: var(--accent-wash-ink); background: var(--accent-wash);
  border-radius: var(--radius-sm); padding: 0.6rem 0.85rem; margin-bottom: 1rem;
}
.diff-rationale::before { content: "Why: "; font-weight: 600; }

.diff-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0;
  border-top: 1px solid var(--line);
  font-family: var(--font-read); font-size: 0.95rem; line-height: 1.6;
}
.diff-row:first-child { border-top: none; }
.diff-cell { padding: 0.6rem 1rem; }
.diff-cell.diff-original { background: var(--page-verso); color: var(--dim); }
.diff-empty { color: var(--line); }

.diff-row.diff-added .diff-cell.diff-original,
.diff-row.diff-removed .diff-cell.diff-tailored { background: repeating-linear-gradient(45deg, var(--page-verso), var(--page-verso) 6px, oklch(0.93 0.008 38) 6px, oklch(0.93 0.008 38) 7px); }

.tk-equal { color: inherit; }
.tk-del { color: var(--danger); text-decoration: line-through; text-decoration-thickness: 1px; background: var(--danger-wash); }
.tk-ins { color: var(--added); background: var(--added-wash); border-radius: 2px; }

.flag-badge {
  display: inline-flex; align-items: center; gap: 0.3rem; margin-left: 0.5rem;
  font-size: 0.7rem; font-family: var(--font-mono); color: var(--dim); vertical-align: middle;
}

/* ---------- Small buttons ---------- */
.btn-tiny {
  padding: 0.3rem 0.75rem; font-size: 0.78rem; font-weight: 600; border-radius: var(--radius-sm);
  background: var(--accent); color: #fff; border: 1px solid var(--accent); cursor: pointer;
}
.btn-tiny:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-tiny:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-tiny-ghost { background: transparent; color: var(--dim); border-color: var(--line); }
.btn-tiny-ghost:hover { color: var(--accent); border-color: var(--accent); background: transparent; }

/* align-items: start — without it, grid stretches the shorter tag-list to
   match the taller (wrapped) one, and flex-wrap's default align-content:
   stretch then inflates that single line of pills into tall ellipses. Only
   shows up once the two sides' tag counts wrap to a different number of
   lines, which real tag lists do but small fixture data may not. */
.diff-tags { padding: 0.85rem 1.25rem; border-top: 1px solid var(--line); display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; align-items: start; }
.tag-list { display: flex; flex-wrap: wrap; align-content: flex-start; gap: 0.4rem; }
.tag {
  font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em; padding: 0.2rem 0.55rem;
  border-radius: 999px; background: var(--line); color: var(--dim);
}
.tag.tk-del { text-decoration: line-through; background: var(--danger-wash); color: var(--danger); }
.tag.tk-ins { background: var(--added-wash); color: var(--added); }

/* ---------- Mobile: stack the spread ---------- */
/* No-JS "show original too" toggle: a checkbox immediately preceding
   .diff-view in the DOM (see result.html), targeted via the general
   sibling combinator. Unchecked (default) = tailored-only reading view. */
#show-original { position: absolute; opacity: 0; pointer-events: none; }
.view-toggle-label {
  display: none;
  align-items: center; gap: 0.5rem; font-size: 0.85rem; cursor: pointer;
  padding: 0.5rem 0.9rem; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--page-recto); width: fit-content; margin: 1.5rem 0;
}

@media (max-width: 780px) {
  .view-toggle-label { display: inline-flex; }

  .spread-head, .diff-summary, .diff-row, .diff-tags { grid-template-columns: 1fr; }
  .spread-head .col-original, .diff-summary .col-original { display: none; }
  .diff-row .diff-cell.diff-original { display: none; }
  .diff-row .diff-cell.diff-tailored::before {
    content: attr(data-label); display: block; font-size: 0.68rem; color: var(--dim);
    text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.2rem; font-family: var(--font-ui);
  }
  .diff-tags > div:first-child { display: none; }

  #show-original:checked ~ .diff-view .spread-head,
  #show-original:checked ~ .diff-view .diff-summary,
  #show-original:checked ~ .diff-view .diff-row,
  #show-original:checked ~ .diff-view .diff-tags { grid-template-columns: 1fr 1fr; }
  #show-original:checked ~ .diff-view .spread-head .col-original,
  #show-original:checked ~ .diff-view .diff-summary .col-original,
  #show-original:checked ~ .diff-view .diff-row .diff-cell.diff-original,
  #show-original:checked ~ .diff-view .diff-tags > div:first-child { display: block; }
}

/* ==========================================================================
   Marketing / landing page (tailor/landing.html) — the one public,
   unauthenticated page in the app. Reuses every token above (same nav,
   same accent, same fonts) so it reads as one product, not a bolted-on
   microsite. New component classes below; nothing here changes how the
   gated wizard renders.
   ========================================================================== */

.marketing-section { padding: 4.5rem 1.5rem; border-bottom: 1px solid var(--line); }
.marketing-section.is-verso { background: var(--page-verso); }
.marketing-inner { max-width: var(--content-width-wide); margin: 0 auto; }
.marketing-inner.is-narrow { max-width: 42rem; }
.marketing-eyebrow {
  font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 0.75rem; text-align: center;
}
.marketing-heading {
  font-family: var(--font-ui); font-weight: 700; letter-spacing: -0.015em; color: var(--ink);
  text-align: center; font-size: 1.9rem; line-height: 1.15; margin: 0 auto 0.75rem; max-width: 40rem;
}
.marketing-lede {
  text-align: center; color: var(--dim); font-size: 1.05rem; line-height: 1.6;
  max-width: 38rem; margin: 0 auto 2.5rem;
}

/* ---------- Hero ---------- */
.hero { padding: 5.5rem 1.5rem 4.5rem; text-align: center; }
.hero-heading {
  font-family: var(--font-ui); font-weight: 750; letter-spacing: -0.02em; color: var(--ink);
  font-size: 2.6rem; line-height: 1.08; margin: 0 auto 1.1rem; max-width: 42rem;
}
.hero-heading em { color: var(--accent); font-style: normal; }
.hero-lede { color: var(--dim); font-size: 1.15rem; line-height: 1.6; max-width: 36rem; margin: 0 auto 2.25rem; }
@media (min-width: 640px) { .hero-heading { font-size: 3.4rem; } }

/* ---------- Waitlist form (hero + bottom CTA band both use this) ---------- */
.hero-actions { display: flex; gap: 0.6rem; justify-content: center; flex-wrap: wrap; }
.waitlist-form { display: flex; gap: 0.6rem; justify-content: center; flex-wrap: wrap; max-width: 30rem; margin: 0 auto; }
.waitlist-form input[type="email"] {
  flex: 1; min-width: 14rem; padding: 0.7rem 1rem; border: 1px solid var(--line); border-radius: var(--radius-sm);
  font-family: inherit; font-size: 0.95rem; background: var(--page-recto); color: var(--ink);
}
.waitlist-form input[type="email"]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-wash); }
.waitlist-note { text-align: center; font-size: 0.8rem; color: var(--dim); margin-top: 0.75rem; }
.cta-band .waitlist-note { color: oklch(0.75 0.02 38); }

/* ---------- How it works ---------- */
.steps-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.75rem; counter-reset: step; }
.step-card { text-align: center; }
.step-num {
  display: inline-flex; align-items: center; justify-content: center; width: 2.25rem; height: 2.25rem;
  border-radius: 50%; background: var(--accent); color: #fff; font-family: var(--font-mono);
  font-size: 0.9rem; font-weight: 600; margin-bottom: 0.9rem;
}
.step-title { font-weight: 600; color: var(--ink); margin-bottom: 0.35rem; }
.step-body { font-size: 0.88rem; color: var(--dim); line-height: 1.55; }
@media (max-width: 780px) { .steps-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .steps-grid { grid-template-columns: 1fr; } }

/* ---------- Capabilities ---------- */
.feature-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.25rem; }
.feature-card { background: var(--page-recto); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-card); padding: 1.5rem; }
.feature-title { font-weight: 600; color: var(--ink); margin-bottom: 0.4rem; }
.feature-body { font-size: 0.9rem; color: var(--dim); line-height: 1.6; }
@media (max-width: 640px) { .feature-grid { grid-template-columns: 1fr; } }

/* ---------- Approach ---------- */
.approach-list { display: flex; flex-direction: column; gap: 1.5rem; max-width: 40rem; margin: 0 auto; }
.approach-item { display: flex; gap: 1rem; }
.approach-mark { color: var(--accent); font-family: var(--font-mono); font-size: 0.9rem; flex-shrink: 0; padding-top: 0.15rem; }
.approach-title { font-weight: 600; color: var(--ink); margin-bottom: 0.25rem; }
.approach-body { font-size: 0.9rem; color: var(--dim); line-height: 1.6; }

/* ---------- FAQ (details/summary — matches details.advanced elsewhere) ---------- */
.faq-list { max-width: 42rem; margin: 0 auto; display: flex; flex-direction: column; gap: 0.75rem; }
.faq-item { background: var(--page-recto); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.faq-item > summary {
  cursor: pointer; list-style: none; padding: 1rem 1.25rem; font-weight: 600; color: var(--ink);
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::after { content: "+"; color: var(--dim); font-weight: 400; flex-shrink: 0; }
.faq-item[open] > summary::after { content: "\2212"; }
.faq-item-body { padding: 0 1.25rem 1.1rem; font-size: 0.9rem; color: var(--dim); line-height: 1.6; }

/* ---------- Final CTA band — the one deliberate dark surface on the site.
   Not a "dark mode" (Spread stays light-only everywhere else, see the
   :root comment above); this is a single high-contrast section for
   emphasis, a common landing-page technique. ---------- */
.cta-band { background: var(--ink); border-bottom: none; }
.cta-band .marketing-heading, .cta-band .marketing-eyebrow { color: var(--page-recto); }
.cta-band .marketing-eyebrow { color: oklch(0.72 0.1 38); }
.cta-band .marketing-lede { color: oklch(0.78 0.015 38); }
.cta-band .waitlist-form input[type="email"] { background: oklch(0.24 0.014 38); border-color: oklch(0.32 0.014 38); color: var(--page-recto); }
.cta-band .waitlist-form input[type="email"]::placeholder { color: oklch(0.6 0.015 38); }

/* ---------- Footer ---------- */
.marketing-footer { padding: 2rem 1.5rem; text-align: center; font-size: 0.8rem; color: var(--dim); }
/* base.html's sitewide copyright line — landing.html's own .marketing-footer
   above covers that page; this one reaches every other page (and landing
   too, since it renders outside {% block body %}), so it stays deliberately
   plainer: no border/background of its own, just enough padding to read as
   a distinct footer rather than a trailing line of body text. */
.site-footer { padding: 1.5rem 1.5rem 2.5rem; text-align: center; font-size: 0.78rem; color: var(--dim); }

/* ---------- Saved tailored results list ---------- */
/* .results-list-meta is also reused as a plain small-muted-text utility
   outside this page (step_resume.html, step_posting.html) — kept name and
   rule as-is rather than folding it into the resume-card-* set below. */
.results-list-meta { font-size: 0.82rem; color: var(--dim); margin-top: 0.15rem; }

.badge-default {
  display: inline-block; margin-left: 0.5rem; padding: 0.1rem 0.55rem;
  border-radius: 999px; background: var(--accent-wash); color: var(--accent);
  font-size: 0.72rem; font-weight: 600; vertical-align: middle;
}

/* A grid of cards, not a stacked list of dense rows — each saved item
   gets its own presence instead of competing for space in one long
   horizontal line of controls. auto-fill/minmax rather than a fixed
   column count: however many 15rem-ish cards fit the content width is
   how many show per row, no breakpoint math needed for the common cases. */
.resume-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 1rem;
}
.resume-card {
  background: var(--page-recto);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  overflow: hidden; /* clips resume-card-accent's square corners to the card's own radius */
  display: flex;
  flex-direction: column;
}
/* Thin accent edge instead of a literal photo/icon header — enough to
   give each card a visual anchor without this app's restrained palette
   turning into the source material's much louder, per-card color coding. */
.resume-card-accent { height: 0.3rem; background: var(--accent); flex-shrink: 0; }

/* A live preview of the actual PDF, not a static thumbnail — browsers
   already render PDFs natively inside an iframe, so this costs no new
   dependency (no poppler/pdf2image install on the Mac Mini) and is
   always accurate, never a stale cached snapshot. Small by default;
   .is-expanded (toggled by the click handler in resume_library.html)
   grows it in place rather than opening a new tab — the existing
   "Preview ↗" button still does that, for genuine reading/printing. */
.resume-pdf-preview {
  position: relative;
  height: 9rem;
  overflow: hidden;
  cursor: zoom-in;
  background: var(--page-verso);
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.resume-pdf-preview.is-expanded { height: 32rem; cursor: default; }
.resume-pdf-preview iframe {
  width: 100%;
  height: 100%;
  border: none;
  /* Small/default state is look-don't-touch — scrolling/clicking inside
     the embedded viewer at thumbnail size would fight with the wrapper's
     own click-to-expand handler. Expanded, there's no such conflict (the
     hint badge below is a separate, always-on-top element that keeps
     working as the collapse control), so pointer-events turns back on:
     otherwise "expand" would just mean "bigger but still inert," unable
     to scroll past page 1 to see the rest. */
  pointer-events: none;
}
.resume-pdf-preview.is-expanded iframe { pointer-events: auto; }
.resume-pdf-preview-hint {
  position: absolute;
  bottom: 0.5rem;
  right: 0.5rem;
  background: var(--ink);
  color: var(--page-recto);
  font-size: 0.7rem;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  opacity: 0.85;
  /* Always clickable regardless of the iframe's own pointer-events state
     above — this badge, not the iframe, is what collapse falls back to
     once expanded. */
  pointer-events: auto;
}
.resume-card-body { padding: 1.1rem 1.25rem; flex: 1 1 auto; }
.resume-card-title { font-weight: 600; color: var(--ink); }
.resume-card-footer {
  padding: 0.85rem 1.25rem; border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.6rem;
}
/* View/Delete as plain text links, not full buttons — Preview (inside
   .preview-combo) is the one action people come to this page for; these
   two stay present but visually secondary, matching the source
   inspiration's one-clear-action-plus-small-metadata card footer. */
.resume-card-links { display: flex; align-items: center; gap: 0.85rem; font-size: 0.82rem; }
.resume-card-links a { color: var(--dim); }
.resume-card-links a:hover { color: var(--accent); }
.resume-card-links form { display: inline; }
.resume-card-links button {
  background: none; border: none; padding: 0; font: inherit; font-size: 0.82rem;
  color: var(--dim); cursor: pointer; text-decoration: underline; text-decoration-thickness: 1px;
}
.resume-card-links button:hover { color: var(--accent); }

/* Whole-tile click target for saved results (_result_tile.html):
   .tile-link's ::after covers the card, and every other control on the
   tile is lifted above it so it still gets its own clicks. */
.result-tile { position: relative; cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s; scroll-margin-top: 1.5rem; }
.result-tile:hover { border-color: var(--accent-wash-line); box-shadow: var(--shadow-card), 0 0 0 1px var(--accent-wash-line); }
.result-tile .tile-link::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.result-tile :is(a:not(.tile-link), select, button) { position: relative; z-index: 2; }
.result-tile:has(.tile-link:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Only hide the link's own outline where :has() can draw the card one. */
@supports selector(:has(*)) {
  .result-tile .tile-link:focus-visible { outline: none; }
}
/* The tile a status change / delete redirect lands on (#tr-<pk>). */
.result-tile:target { border-color: var(--accent); }

/* Saved-results carousel on the Jobs tab (saved_jobs.html) - a
   horizontal, center-focused strip of .result-tile cards.
   --carousel-item-width drives both the card width and the spacer math
   below from one place, so the two breakpoints below can't drift apart. */
.tailored-carousel {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.tailored-carousel-track {
  --carousel-item-width: 18rem;
  display: flex;
  align-items: stretch;
  gap: 1.25rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  padding: 0.5rem 0 1rem;
  min-width: 0;
  flex: 1 1 auto;
}
/* Half a card width (minus half the inter-card gap, so the math isn't
   thrown off by the one gap that lands between the spacer and the first/
   last real card) — lets the first and last cards reach true center same
   as any card in the middle, instead of stopping at the scroll edge. */
.tailored-carousel-spacer {
  flex: 1 0 auto;
  width: calc(50% - (var(--carousel-item-width) / 2) - 0.625rem);
}
.tailored-carousel-item {
  flex: 0 0 var(--carousel-item-width);
  width: var(--carousel-item-width);
  scroll-snap-align: center;
  transform-origin: center center;
  transition: transform 0.15s ease-out, opacity 0.15s ease-out, border-color 0.15s, box-shadow 0.15s;
}
.tailored-carousel-nav {
  flex: 0 0 auto;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--page-recto);
  color: var(--ink);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tailored-carousel-nav:hover { border-color: var(--accent); color: var(--accent); }

@media (max-width: 460px) {
  .tailored-carousel-track { --carousel-item-width: 15rem; }
  .tailored-carousel-nav { display: none; }
}


/* Jobs tab status filters (saved_jobs.html). */
.job-filters { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0 0 1.25rem; }
.job-filter {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--page-recto); color: var(--ink);
  font-size: 0.8rem; text-decoration: none;
}
.job-filter:hover { border-color: var(--accent); }
.job-filter.is-active { background: var(--ink); border-color: var(--ink); color: var(--page-recto); }
.job-filter-count { font-family: var(--font-mono); font-size: 0.72rem; opacity: 0.75; }

/* "Tailor a new posting" — its own full-width row above .resume-grid,
   not a tile competing for attention inside it. Solid accent, not the
   dashed-outline/muted treatment this used when it lived in the grid:
   this is the one action most people come to this page to take, so it
   gets the strongest visual weight on the page, not the same weight as
   things already saved. */
.resume-cta-banner {
  display: flex; align-items: center; gap: 1rem;
  background: var(--accent); color: #fff;
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 1.1rem 1.4rem;
  margin-bottom: 1.25rem;
  text-decoration: none;
}
.resume-cta-banner:hover { background: var(--accent-hover); }
.resume-cta-banner-icon {
  width: 2.5rem; height: 2.5rem; border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.4rem; line-height: 1; flex-shrink: 0;
}
.resume-cta-banner-text { flex: 1 1 auto; min-width: 0; }
.resume-cta-banner-title { display: block; font-weight: 700; font-size: 1.02rem; }
.resume-cta-banner-sub { display: block; font-size: 0.82rem; opacity: 0.85; margin-top: 0.1rem; }
.resume-cta-banner-arrow { font-size: 1.3rem; flex-shrink: 0; }
@media (max-width: 460px) {
  .resume-cta-banner-sub { display: none; } /* title + arrow alone still reads fine at phone width */
}

/* Preview: a style picker joined directly to its "Preview" button, one
   visual unit rather than two adjacent controls — the seam is the select's
   missing right border meeting the button's own left one. Kept as the
   first (leftmost/topmost) action in markup order — see resume_library.html
   — since it's the one people actually come to this page to use. */
.preview-combo { display: inline-flex; align-items: stretch; }
.preview-combo-select {
  border-top-right-radius: 0; border-bottom-right-radius: 0;
  border-right: none;
  max-width: 7rem;
  padding-top: 0.6rem; padding-bottom: 0.6rem;
}
.preview-combo-btn {
  border-top-left-radius: 0; border-bottom-left-radius: 0;
  white-space: nowrap;
}

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

/* Gap map (gap_readiness.html) — every gap on one page: a category x
   lane matrix up top, then an expandable row per gap, grouped by category.
   Lane color is semantic (build=accent, mention=a separate amber-ish hue
   so it reads as distinct from both "go" and "skip", skip=dim/neutral)
   rather than reusing --danger, which already means "required" via
   .gap-priority-required and the dot rings on this same page - reusing it
   for lane identity would collide with that meaning. */
[data-kind="build"] { --lane-color: var(--accent); }
[data-kind="mention"] { --lane-color: oklch(0.6 0.1 95); }
[data-kind="skip"] { --lane-color: var(--dim); }
[data-kind="none"] { --lane-color: var(--line); }

.gap-readiness-headline { font-size: 1.05rem; color: var(--ink); max-width: 42rem; }

.gap-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: 0.75rem;
  margin: 1.25rem 0 1.5rem;
}
.gap-stat {
  display: flex; flex-direction: column; gap: 0.15rem;
  background: var(--page-recto);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.8rem 1rem;
  color: var(--ink);
  text-decoration: none;
  min-width: 0;
}
.gap-stat-value { font-size: 1.5rem; font-weight: 600; line-height: 1.15; font-variant-numeric: tabular-nums; }
.gap-stat-label { font-size: 0.76rem; color: var(--dim); }
.gap-stat-top { grid-column: span 2; border-color: var(--accent-wash-line); background: var(--accent-wash); }
.gap-stat-top .gap-stat-value { font-size: 1.1rem; overflow-wrap: anywhere; }
.gap-stat-top:hover { border-color: var(--accent); }
@media (max-width: 560px) {
  .gap-stat-top { grid-column: 1 / -1; }
}

.gap-lane-dot {
  display: inline-block; flex: none;
  width: 0.6rem; height: 0.6rem; border-radius: 50%;
  background: var(--lane-color, var(--line));
}

.gap-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0.75rem; margin-bottom: 1rem;
}
.gap-filter { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.gap-filter-chip, .gap-expand-all {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font: inherit; font-size: 0.8rem;
  padding: 0.3rem 0.75rem;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--page-recto); color: var(--ink);
  cursor: pointer;
}
.gap-filter-chip:hover, .gap-expand-all:hover { border-color: var(--accent); }
.gap-filter-chip[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--page-recto); }
.gap-expand-all { color: var(--dim); }

/* The Gaps page's progress bar while a new synthesis is built
   (gap_readiness.html, #id_gap_building). The fill is set from JS. */
.gap-building { padding: 1rem 1.25rem; margin-bottom: 1.5rem; }
.gap-building-head { display: flex; align-items: center; gap: 0.6rem; }
.gap-building-title { margin: 0; font-weight: 600; }
.gap-building-bar {
  height: 0.5rem; margin: 0.75rem 0 0.6rem;
  background: var(--page-verso); border-radius: 999px; overflow: hidden;
}
.gap-building-fill {
  display: block; height: 100%; width: 0;
  background: var(--accent); border-radius: 999px;
  transition: width 0.2s linear;
}
.gap-building .results-list-meta { margin: 0; }
.gap-building.is-failed .gap-building-fill { background: var(--danger); }
.gap-building.is-failed .echo-loader { display: none; }

/* "Where to start" (#110): one bar per gap, out of all saved postings,
   split into required (--danger, as everywhere on gap UI) and nice to have
   (a light tint of it: lighter = less pressing, and unlike --accent it
   can't be mistaken for red), with a 2px gap between the two parts. Desktop: label | bar |
   value in one line. Phone width: the label on its own line above. */
.gap-chart { padding: 1.1rem 1.25rem 1rem; margin-bottom: 2rem; }
.gap-chart-head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 0.35rem 1rem; margin-bottom: 0.7rem;
}
.gap-chart-head .page-section-heading { margin: 0; }
.gap-chart-legend {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.45rem;
  margin: 0; font-size: 0.74rem; color: var(--dim);
}
.gap-chart-key { display: inline-block; width: 0.8rem; height: 0.55rem; border-radius: 2px; }
.gap-chart-key-required { background: var(--danger); }
.gap-chart { --gap-nice: color-mix(in oklch, var(--danger) 38%, var(--page-recto)); }
.gap-chart-key-nice { background: var(--gap-nice); margin-left: 0.4rem; }
.gap-chart-legend-note { margin-left: 0.4rem; }
.gap-chart-rows { list-style: none; margin: 0; padding: 0; }
.gap-chart-row.is-extra { display: none; }
.gap-chart.is-expanded .gap-chart-row.is-extra,
.gap-chart.is-filtered .gap-chart-row.is-extra { display: block; }
.gap-chart.is-filtered .gap-chart-more { display: none; }
.gap-chart-row.is-dimmed { opacity: 0.25; }
.gap-chart-link {
  display: grid; grid-template-columns: minmax(0, 14rem) minmax(0, 1fr) 7.5rem;
  align-items: center; gap: 0.75rem;
  padding: 0.4rem 0.35rem; margin: 0 -0.35rem;
  border-radius: 6px;
  color: var(--ink); text-decoration: none;
}
.gap-chart-link:hover, .gap-chart-link:focus-visible { background: var(--page-verso); text-decoration: none; }
.gap-chart-label {
  display: flex; align-items: center; gap: 0.45rem; min-width: 0;
  font-size: 0.86rem; line-height: 1.3; overflow-wrap: anywhere;
}
.gap-chart-bar {
  display: flex; gap: 2px; height: 0.7rem;
  background: var(--page-verso); border-radius: 4px; overflow: hidden;
}
/* min-width: a gap asked once out of hundreds rounds to 0% but still shows. */
.gap-chart-seg { display: block; height: 100%; min-width: 3px; }
.gap-chart-seg-required { background: var(--danger); }
.gap-chart-seg-nice { background: var(--gap-nice); }
.gap-chart-seg:last-child { border-radius: 0 4px 4px 0; }
.gap-chart-value {
  font-family: var(--font-mono); font-size: 0.72rem; color: var(--dim);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.gap-chart-req { color: var(--ink); }
.gap-chart-more { margin-top: 0.6rem; }

@media (max-width: 760px) {
  .gap-chart { padding: 0.85rem 1rem; }
  .gap-chart-link { grid-template-columns: minmax(0, 1fr) auto; gap: 0.3rem 0.6rem; }
  .gap-chart-label { grid-column: 1 / -1; }
}

/* The list. */
.gap-list-groups { display: flex; flex-direction: column; gap: 1.75rem; }
.gap-group-heading { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.6rem; }
.gap-group-count { font-family: var(--font-mono); font-weight: 400; letter-spacing: 0; }
.gap-rows {
  background: var(--page-recto);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.gap-row { border-top: 1px solid var(--line); scroll-margin-top: 5rem; }
.gap-row:first-child { border-top: 0; }
.gap-row-summary {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto 9rem;
  align-items: center;
  gap: 0.75rem;
  padding: 0.8rem 1rem;
  cursor: pointer;
  list-style: none;
}
.gap-row-summary::-webkit-details-marker { display: none; }
.gap-row-summary:hover { background: var(--page-verso); }
.gap-row[open] > .gap-row-summary { background: var(--page-verso); }
.gap-row-label { font-weight: 600; font-size: 0.92rem; line-height: 1.3; overflow-wrap: anywhere; }
.gap-row-label::after {
  content: "+"; margin-left: 0.4rem; font-family: var(--font-mono); font-weight: 400; color: var(--dim);
}
.gap-row[open] .gap-row-label::after { content: "−"; }
.gap-row-loose .gap-row-label { font-weight: 500; }
.gap-demand { display: flex; align-items: center; gap: 0.5rem; }
.gap-demand-bar {
  flex: 1; height: 0.4rem; border-radius: 999px; background: var(--line); overflow: hidden;
}
.gap-demand-fill { display: block; height: 100%; border-radius: 999px; background: var(--accent); }
.gap-demand-fill-required { background: var(--danger); }
.gap-demand-text {
  font-family: var(--font-mono); font-size: 0.72rem; color: var(--dim);
  min-width: 2.4rem; text-align: right; font-variant-numeric: tabular-nums;
}

.gap-row-body { padding: 0.25rem 1rem 1.1rem 2.35rem; }
.gap-row-lane { font-size: 0.78rem; font-weight: 600; color: var(--ink); margin-bottom: 0.4rem; }
.gap-row-lane span { font-weight: 400; color: var(--dim); }
.gap-cluster-rec { font-size: 0.88rem; line-height: 1.5; margin: 0 0 0.75rem; max-width: 44rem; }
.gap-row-subhead {
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--dim); margin: 0.75rem 0 0.35rem;
}
.gap-phrasings { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.gap-phrasings li {
  font-size: 0.78rem; padding: 0.1rem 0.55rem;
  border: 1px solid var(--line); border-radius: 999px; background: var(--page-verso);
}
.gap-postings { display: flex; flex-direction: column; }
.gap-posting {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.4rem 0;
  border-top: 1px dashed var(--line);
  font-size: 0.84rem;
}
.gap-posting:first-child { border-top: 0; }
.gap-posting-meta { font-size: 0.74rem; color: var(--dim); }
.gap-posting-links { display: flex; gap: 0.75rem; font-size: 0.8rem; }

@keyframes gap-row-flash { from { background: var(--accent-wash); } to { background: transparent; } }
.gap-row-flash { animation: gap-row-flash 1.6s ease-out; }

@media (max-width: 640px) {
  .gap-row-summary { grid-template-columns: auto minmax(0, 1fr) auto; gap: 0.4rem 0.6rem; padding: 0.75rem 0.85rem; }
  .gap-demand { grid-column: 2 / -1; }
  .gap-row-body { padding: 0.25rem 0.85rem 1rem; }
  .gap-posting { grid-template-columns: minmax(0, 1fr) auto; gap: 0.15rem 0.75rem; }
  .gap-posting-meta { grid-row: 2; }
}

/* Cluster card - no longer used by the gap map itself, but landing.html's
   gap-profile preview still renders one. */
.gap-cluster-card .resume-card-accent { background: var(--lane-color, var(--accent)); }
.gap-cluster-category {
  display: block; font-family: var(--font-mono); font-size: 0.66rem;
  text-transform: uppercase; letter-spacing: 0.04em; color: var(--dim); margin-bottom: 0.5rem;
}
.gap-cluster-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.5rem; margin-bottom: 0.6rem; }
.gap-cluster-label { font-weight: 600; font-size: 0.96rem; line-height: 1.25; }

/* Profile tabs (_profile_tabs.html): Resumes / Jobs / Gaps across the
   three account-home pages. Same underline-tab language as the wizard's
   step tabs, without the numbers - these are peers, not a sequence. */
/* Centered over the centered carousels/cards below. */
.profile-header { margin-bottom: 1rem; text-align: center; }
.profile-header .page-title { display: flex; align-items: center; justify-content: center; gap: 0.6rem; flex-wrap: wrap; }
.profile-tabs {
  display: flex;
  justify-content: center;
  justify-content: safe center; /* never clip the first tab if they overflow */
  gap: 0.25rem;
  border-bottom: 1px solid var(--line);
  margin: 0 0 1.75rem;
  overflow-x: auto;
}
.profile-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.6rem 1rem 0.7rem;
  color: var(--dim);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
.profile-tab:hover { color: var(--ink); background: var(--page-recto); }
.profile-tab.is-active { color: var(--ink); border-bottom-color: var(--accent); background: var(--page-recto); }
.profile-tab-count {
  font-family: var(--font-mono); font-size: 0.7rem; font-weight: 600;
  padding: 0.05rem 0.45rem; border-radius: 999px;
  background: var(--line); color: var(--dim);
}
.profile-tab.is-active .profile-tab-count { background: var(--accent-wash); color: var(--accent); }
@media (max-width: 460px) {
  /* Four tabs on a phone: tighter, and only the active tab keeps its
     count, so the row fits without scrolling sideways. */
  .profile-tabs { gap: 0; }
  .profile-tab { flex: 1 1 auto; justify-content: center; gap: 0.3rem; padding: 0.55rem 0.35rem 0.65rem; font-size: 0.84rem; }
  .profile-tab:not(.is-active) .profile-tab-count { display: none; }
}

/* Gaps tab before there are enough saved results to show a pattern. */
.gap-locked { max-width: 34rem; display: flex; flex-direction: column; gap: 0.75rem; align-items: flex-start; }
.gap-locked-title { font-weight: 600; font-size: 1rem; margin: 0; }
.gap-locked-progress { display: flex; gap: 0.35rem; }
.gap-locked-pip { width: 2.25rem; height: 0.4rem; border-radius: 999px; background: var(--line); }
.gap-locked-pip.is-filled { background: var(--accent); }

/* Profile tab content is centered under the full-width tab bar rather
   than hugging the left edge of the wide layout - with one or two cards
   (the usual Resumes tab) left-aligned content left most of the page
   empty. Fixed-max columns so justify-content has room to center. */
.profile-section { max-width: var(--content-width); margin-left: auto; margin-right: auto; }
.profile-section-wide { max-width: var(--content-width-wide); }
.profile-section .resume-grid { grid-template-columns: repeat(auto-fit, minmax(14rem, 18rem)); justify-content: center; }
.profile-section .job-filters { justify-content: center; }
@media (max-width: 460px) {
  .profile-section .resume-grid { grid-template-columns: 1fr; }
}

/* Jobs tab: the clicked tile's result, read-only, under the carousel
   (_result_detail.html). The open tile gets the same accent border as a
   #tr-<pk> redirect target so it's clear which card the panel belongs to. */
.result-tile.is-open { border-color: var(--accent); box-shadow: var(--shadow-card), 0 0 0 1px var(--accent); }
.job-detail { margin-top: 1rem; }
.tailored-carousel { scroll-margin-top: 0.5rem; }
/* Resumes tab: earlier versions in the same carousel (resume_library.html). */
.badge-earlier {
  margin-left: 0.35rem; padding: 0.05rem 0.45rem; border-radius: 999px;
  font-size: 0.65rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--dim); background: var(--page-verso); border: 1px solid var(--line);
}
.resume-version-card .resume-card-accent { background: var(--line); }
.resume-card-links button.is-armed { color: var(--accent-wash-ink); font-weight: 600; }
.resume-history-note { text-align: center; margin-top: 0.25rem; }
.job-detail[aria-busy="true"]:not(:has(.job-detail-loading)) { opacity: 0.6; }
.job-detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.job-detail-title { font-size: 1.25rem; line-height: 1.3; }
.job-detail-close {
  flex: none; width: 2rem; height: 2rem; border-radius: 50%;
  border: 1px solid var(--line); background: var(--page-recto); color: var(--dim);
  font-size: 1.2rem; line-height: 1; cursor: pointer;
}
.job-detail-close:hover { border-color: var(--accent); color: var(--accent); }
.job-detail-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin-bottom: 1.25rem; }
@media (max-width: 460px) {
  .job-detail { padding: 1.1rem; }
}

/* Match label (services.match_level) on Jobs tiles, the Jobs-tab panel and
   the result page. Strong reuses the "added" green, partial a warm amber,
   stretch the neutral dim - deliberately not --danger, which already means
   "required" on the gap UI and would make a stretch read as an error. */
.match-badge {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.02em;
  padding: 0.12rem 0.55rem; border-radius: 999px; white-space: nowrap; vertical-align: middle;
  background: var(--page-verso); border: 1px solid var(--line); color: var(--ink);
}
.match-dot { width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--dim); }
.match-strong { background: var(--added-wash); border-color: var(--added-wash-line); color: var(--added-wash-ink); }
.match-strong .match-dot { background: var(--added); }
.match-partial { background: oklch(0.96 0.04 85); border-color: oklch(0.88 0.07 85); color: oklch(0.38 0.08 70); }
.match-partial .match-dot { background: oklch(0.7 0.13 80); }
.result-tile-match { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.5rem; margin: 0.35rem 0 0.15rem; }
.result-tile-match .results-list-meta { margin-top: 0; font-size: 0.74rem; }
/* Gap map: per-row dismiss, and the Dismissed section (GapDismissal). */
.gap-dismiss {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem;
  margin-top: 0.9rem; padding-top: 0.75rem; border-top: 1px dashed var(--line);
}
.gap-dismiss-label { font-size: 0.74rem; color: var(--dim); margin-right: 0.15rem; }
.gap-dismissed { margin-top: 2rem; }
.gap-dismissed > summary {
  cursor: pointer; font-size: 0.78rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--dim); display: inline-flex; align-items: center; gap: 0.5rem;
}
.gap-dismissed-list {
  margin-top: 0.6rem;
  background: var(--page-recto); border: 1px solid var(--line); border-radius: var(--radius);
}
.gap-dismissed-item {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 0.75rem;
  padding: 0.55rem 1rem; border-top: 1px solid var(--line); font-size: 0.86rem;
}
.gap-dismissed-item:first-child { border-top: 0; }
.gap-dismissed-label { overflow-wrap: anywhere; color: var(--dim); }
@media (max-width: 460px) {
  .gap-dismissed-item { grid-template-columns: minmax(0, 1fr) auto; }
  .gap-dismissed-item .gap-posting-meta { grid-row: 2; }
}
/* Jobs-tab panel: the candidate's own notes on an application. */
.job-notes { display: flex; flex-direction: column; gap: 0.35rem; margin-bottom: 1.25rem; }
.job-notes-label { font-size: 0.78rem; font-weight: 600; color: var(--ink); }
.job-notes textarea {
  width: 100%; font: inherit; font-size: 0.88rem; line-height: 1.5;
  padding: 0.6rem 0.75rem; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--page-recto); color: var(--ink); resize: vertical;
}
.job-notes textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.job-notes-status { font-size: 0.74rem; color: var(--dim); min-height: 1em; }
.job-notes-foot { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.25rem 1rem; }
.job-notes-dates { font-size: 0.74rem; color: var(--dim); }

/* "What we captured" after a PDF upload (_extraction_check.html). */
.extraction-check { margin: 1rem 0 1.5rem; padding: 0.9rem 1.25rem; }
.extraction-check.has-issues { border-color: oklch(0.88 0.07 85); background: oklch(0.985 0.015 85); }
.extraction-check > summary {
  cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
}
.extraction-check > summary::-webkit-details-marker { display: none; }
.extraction-check-title { font-weight: 600; font-size: 0.92rem; }
.extraction-check-count {
  font-size: 0.72rem; font-weight: 600; padding: 0.1rem 0.55rem; border-radius: 999px;
  background: oklch(0.96 0.04 85); border: 1px solid oklch(0.88 0.07 85); color: oklch(0.38 0.08 70);
}
.extraction-check-items {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: 0.35rem 1.25rem; margin: 0.85rem 0 0;
}
.extraction-check-items li { display: flex; align-items: baseline; gap: 0.45rem; font-size: 0.84rem; min-width: 0; }
.extraction-check-mark { flex: none; width: 1rem; text-align: center; font-weight: 700; color: var(--added); }
.extraction-check-items li.is-missing .extraction-check-mark { color: oklch(0.6 0.13 70); }
.extraction-check-label { font-weight: 600; }
.extraction-check-value { color: var(--dim); overflow-wrap: anywhere; }
.extraction-check-issues { margin: 0.85rem 0 0.6rem; padding-left: 1.1rem; list-style: disc; font-size: 0.86rem; }
.extraction-check-issues li { margin-bottom: 0.25rem; }

/* In-place resume editor (resume_edit.html). Every editable field is a
   contenteditable span that reads like the resume until hovered or
   focused - a dashed outline on hover, a solid accent one while typing -
   and shows its placeholder when empty. */
.ed-statusbar {
  position: sticky; top: 0; z-index: 15;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.5rem 1rem;
  padding: 0.55rem 0; margin-bottom: 0.75rem;
  background: var(--page-verso); border-bottom: 1px solid var(--line); font-size: 0.82rem;
}
.ed-status { color: var(--dim); }
.ed-status.is-error { color: var(--danger-wash-ink); font-weight: 600; }
.ed-statusbar-links { display: flex; gap: 1rem; }
.ed-conflict {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  margin-bottom: 0.75rem; padding: 0.6rem 0.9rem; font-size: 0.86rem;
  background: var(--danger-wash); border: 1px solid var(--danger-wash-line); border-radius: var(--radius-sm); color: var(--danger-wash-ink);
}
/* display:flex above would otherwise beat the [hidden] attribute. */
.ed-conflict[hidden] { display: none; }
.ed-page { padding: 2rem 2.25rem; }
.ed-field {
  display: inline-block; min-width: 2ch; max-width: 100%;
  padding: 0.05rem 0.25rem; margin: 0 -0.25rem;
  border-radius: var(--radius-sm); outline: 1px dashed transparent; outline-offset: 0;
  overflow-wrap: anywhere; cursor: text; transition: outline-color 0.12s, background 0.12s;
}
.ed-field:hover { outline-color: var(--line); }
.ed-field:focus { outline: 2px solid var(--accent); background: var(--page-recto); }
.ed-field:empty::before { content: attr(data-placeholder); color: var(--dim); opacity: 0.7; }
.ed-multiline { display: block; }
.ed-header { display: flex; flex-direction: column; gap: 0.35rem; margin-bottom: 1.5rem; }
.ed-name { font-size: 1.9rem; font-weight: 700; line-height: 1.15; letter-spacing: -0.01em; }
.ed-title { font-size: 1.05rem; color: var(--accent); font-weight: 600; }
.ed-summary { margin-top: 0.6rem; font-size: 0.92rem; line-height: 1.6; color: var(--ink); }
.ed-section { margin-top: 1.75rem; }
.ed-section-title {
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  padding-bottom: 0.35rem; margin-bottom: 0.75rem; border-bottom: 2px solid var(--ink);
}
.ed-entry { padding: 0.75rem 0 0.9rem; border-bottom: 1px dashed var(--line); }
.ed-entry:last-child { border-bottom: 0; }
.ed-entry-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; }
.ed-entry-head > div:first-child { flex: 1; min-width: 0; }
.ed-role { font-weight: 600; font-size: 0.98rem; }
.ed-entry-sub { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.4rem; font-size: 0.86rem; color: var(--accent); }
.ed-sep { color: var(--dim); }
.ed-location { color: var(--dim); }
.ed-dates { flex: none; font-family: var(--font-mono); font-size: 0.78rem; color: var(--dim); white-space: nowrap; }
.ed-list { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; margin-top: 0.5rem; }
.ed-list-bullets { flex-direction: column; align-items: stretch; gap: 0.15rem; }
.ed-item { position: relative; display: flex; align-items: baseline; gap: 0.3rem; font-size: 0.88rem; line-height: 1.5; }
.ed-list-bullets .ed-item { padding-left: 1rem; }
.ed-list-bullets .ed-item::before { content: "•"; position: absolute; left: 0.2rem; color: var(--dim); }
.ed-list-bullets .ed-item .ed-field { flex: 1; }
.ed-list-chips .ed-item {
  padding: 0.05rem 0.2rem 0.05rem 0.5rem; border: 1px solid var(--line); border-radius: 999px;
  background: var(--page-verso); font-size: 0.8rem;
}
.ed-item-hidden { opacity: 0.55; }
.ed-remove {
  flex: none; border: 0; background: none; color: var(--dim); font-size: 1rem; line-height: 1;
  cursor: pointer; padding: 0 0.2rem; opacity: 0; transition: opacity 0.12s;
}
.ed-item:hover .ed-remove, .ed-item:focus-within .ed-remove, .ed-remove:focus-visible { opacity: 1; }
.ed-remove:hover { color: var(--danger); }
.ed-add {
  align-self: flex-start; border: 1px dashed var(--line); background: none; color: var(--dim);
  font: inherit; font-size: 0.76rem; padding: 0.1rem 0.6rem; border-radius: 999px; cursor: pointer;
}
.ed-add:hover { border-color: var(--accent); color: var(--accent); }
.ed-skill-row { display: grid; grid-template-columns: 9rem minmax(0, 1fr); gap: 0.75rem; align-items: baseline; padding: 0.3rem 0; }
.ed-skill-row .ed-list { margin-top: 0; }
.ed-skill-label { font-weight: 600; font-size: 0.86rem; }
@media (hover: none) {
  .ed-remove { opacity: 0.6; }
}
@media (max-width: 560px) {
  .ed-page { padding: 1.25rem 1rem; }
  .ed-entry-head { flex-direction: column; gap: 0.15rem; }
  /* Stacked, the name column would shrink to fit and wrap a short name
     ("CPR and First / Aid") at about half the card's width. */
  .ed-entry-head > div:first-child { align-self: stretch; }
  .ed-skill-row { grid-template-columns: 1fr; gap: 0.2rem; }
  .ed-name { font-size: 1.5rem; }
}
/* Editor: read-only while an add/remove is in flight (resume_edit.html). */
.ed-page.is-busy .ed-field, .ed-page.is-busy button { pointer-events: none; }
.ed-page.is-busy { opacity: 0.75; transition: opacity 0.1s; }

/* Editor 5b: whole-entry controls, bullet reordering, date picker. The
   entry toolbar sits top-right and only shows on hover / keyboard focus
   inside the entry (always shown on touch screens). */
.ed-entry { position: relative; }
/* Sits on the dashed line above its entry rather than over the entry's
   own top row, where it used to cover the dates field and its picker. */
.ed-entry-tools {
  position: absolute; top: -0.95rem; right: 0.5rem; z-index: 2;
  display: flex; gap: 0.2rem; padding: 0.15rem;
  background: var(--page-recto); border: 1px solid var(--line); border-radius: 999px;
  box-shadow: var(--shadow-card);
  opacity: 0; pointer-events: none; transition: opacity 0.12s;
}
.ed-entry:hover > .ed-entry-tools, .ed-entry:focus-within > .ed-entry-tools { opacity: 1; pointer-events: auto; }
.ed-move, .ed-entry-remove {
  border: 0; background: none; cursor: pointer; color: var(--dim);
  font: inherit; font-size: 0.8rem; line-height: 1; padding: 0.25rem 0.45rem; border-radius: 999px;
}
.ed-move:hover:not(:disabled), .ed-entry-remove:hover { background: var(--page-verso); color: var(--accent); }
.ed-move:disabled { opacity: 0.3; cursor: default; }
.ed-entry-remove.is-armed { background: var(--danger-wash); color: var(--danger-wash-ink); font-weight: 600; }
.ed-item-move { display: inline-flex; opacity: 0; transition: opacity 0.12s; }
.ed-item:hover .ed-item-move, .ed-item:focus-within .ed-item-move { opacity: 1; }
.ed-item-move .ed-move { padding: 0 0.2rem; font-size: 0.75rem; }
.ed-add-entry { margin-top: 0.6rem; }
.ed-add-entry-top { margin: 0 0 0.6rem; }
.ed-skill-row.ed-entry { padding: 0.45rem 0; border-bottom: 1px dashed var(--line); }
/* Optional sections: a publication's description line, community
   engagement's roles, and the "Add a section" row under everything. */
.ed-description { display: block; margin-top: 0.35rem; font-size: 0.86rem; color: var(--dim); }
.ed-roles { margin-top: 0.4rem; padding-left: 0.75rem; border-left: 2px solid var(--line); }
.ed-role-row.ed-entry { padding: 0.35rem 0; }
.ed-role-name { font-size: 0.88rem; }
.ed-add-sections {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem;
  margin-top: 1.75rem; padding-top: 0.9rem; border-top: 1px dashed var(--line);
}
.ed-add-sections-label { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--dim); margin-right: 0.25rem; }
.ed-add-sections .ed-add-entry { margin-top: 0; }
/* A section's draft (openDraft inserts it before its button) gets a full
   line of its own under the buttons, instead of squeezing in between them. */
.ed-add-sections .ed-draft-entry { flex: 1 0 100%; order: 1; }
.ed-date-wrap { display: inline-flex; align-items: baseline; gap: 0.2rem; }
.ed-date-btn {
  border: 0; background: none; cursor: pointer; font-size: 0.8rem; line-height: 1; padding: 0.1rem;
  opacity: 0.45; filter: grayscale(1);
}
.ed-date-btn:hover, .ed-date-btn:focus-visible { opacity: 1; filter: none; }
.ed-datepicker {
  position: absolute; z-index: 30; padding: 0.85rem 1rem; width: 19rem; max-width: calc(100vw - 16px);
  display: flex; flex-direction: column; gap: 0.55rem;
}
.ed-datepicker[hidden] { display: none; }
.ed-datepicker-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; font-size: 0.84rem; }
.ed-datepicker-label { width: 2.6rem; font-weight: 600; color: var(--dim); }
.ed-datepicker select, .ed-datepicker input[type="number"] {
  font: inherit; font-size: 0.84rem; padding: 0.25rem 0.4rem;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--page-recto); color: var(--ink);
}
.ed-datepicker input[type="number"] { width: 5rem; }
.ed-datepicker select:disabled, .ed-datepicker input:disabled { opacity: 0.45; }
.ed-datepicker-present { display: inline-flex; align-items: center; gap: 0.3rem; }
.ed-datepicker-actions { display: flex; gap: 0.4rem; justify-content: flex-end; }
@media (hover: none) {
  .ed-entry-tools { position: static; opacity: 1; pointer-events: auto; justify-content: flex-end; width: max-content; margin-left: auto; box-shadow: none; }
  .ed-item-move { opacity: 1; }
}
.ed-datepicker-note { margin: 0; font-size: 0.76rem; color: var(--dim); }
.ed-datepicker-note[hidden] { display: none; }
.ed-datepicker-error { color: var(--danger-wash-ink); font-weight: 600; }
/* A field or draft whose save failed (resume_edit.html's trackSave). */
.ed-field.is-unsaved, .ed-draft.is-unsaved .ed-field { background: var(--danger-wash); box-shadow: inset 0 -2px 0 var(--danger-wash-ink); }
.ed-unreadable {
  margin: 0 0 1rem; padding: 0.6rem 0.8rem; font-size: 0.84rem; border-radius: var(--radius-sm);
  background: var(--danger-wash); border: 1px solid var(--danger-wash-line); color: var(--danger-wash-ink);
}

/* Posting step: "this site can't be read, paste the description" note
   under the URL field (step_posting.html), and the paste box it points to. */
.fetch-hint {
  margin: 0.45rem 0 0; padding: 0.55rem 0.75rem; font-size: 0.84rem; line-height: 1.45;
  border-radius: var(--radius-sm); background: var(--accent-wash);
  border: 1px solid var(--accent-wash-line); color: var(--accent-wash-ink);
}
.fetch-hint[hidden] { display: none; }
textarea.is-needed { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }

/* "Count toward my gaps" (views.set_result_in_gaps): the switch in the Jobs
   tab's detail panel, the tile label, and "Leave out" on the gap map. */
.job-gaps-toggle { display: inline-flex; align-items: center; gap: 0.5rem; margin-left: auto; }
.job-gaps-toggle .results-list-meta { margin: 0; }
.tile-flag { font-weight: 600; color: var(--dim); }
.gap-posting-leave-out { display: inline; }
.gap-posting-leave-out button {
  border: 0; background: none; padding: 0; font: inherit; color: var(--dim); cursor: pointer; text-decoration: underline;
}
.gap-posting-leave-out button:hover { color: var(--accent); }

/* Resume-style carousel (_style_carousel.html): page-1 thumbnails of this
   resume in each style, in the shared .tailored-carousel. */
.style-picker { margin: 1.5rem 0 1rem; }
.style-picker-heading { margin-bottom: 0.25rem; }
.style-carousel .tailored-carousel-track { --carousel-item-width: 13.5rem; }
.style-card {
  background: var(--page-recto); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-card); overflow: hidden; display: flex; flex-direction: column;
}
.style-card.is-selected { border-color: var(--accent); box-shadow: var(--shadow-card), 0 0 0 1px var(--accent); }
.style-card-thumb { display: block; background: var(--page-verso); border-bottom: 1px solid var(--line); aspect-ratio: 210 / 297; }
.style-card-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; }
.style-card-body { padding: 0.65rem 0.8rem 0.8rem; display: flex; flex-direction: column; gap: 0.35rem; }
.style-card-name { font-weight: 600; font-size: 0.92rem; color: var(--ink); }
.style-card-facts { display: flex; flex-wrap: wrap; gap: 0.35rem; font-size: 0.74rem; color: var(--dim); }
.style-card-facts span { padding: 0.05rem 0.45rem; border: 1px solid var(--line); border-radius: 999px; }
.style-fact-ats { color: var(--added-wash-ink); background: var(--added-wash); border-color: var(--added-wash-line) !important; }
.style-fact-muted { font-style: italic; }
.style-card form { margin-top: 0.15rem; }

/* Background tab (background.html, background_review.html, #71). */
.background-lede { text-align: center; max-width: 42rem; margin: 0 auto 0.4rem; }
.background-note { text-align: center; margin-bottom: 1.25rem; }
.background-pending { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.background-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 1rem; margin-bottom: 1.75rem; }
.background-grid .card { display: flex; flex-direction: column; gap: 0.6rem; }
.field-help { font-size: 0.78rem; color: var(--dim); margin-top: 0.25rem; }
.background-count { display: flex; align-items: center; gap: 0.5rem; }
.background-group { margin-bottom: 1.25rem; }
.background-group-title { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--dim); margin: 0 0 0.5rem; }
.background-item { margin-bottom: 0.6rem; padding: 0.85rem 1rem; }
.background-item-context { font-weight: 600; font-size: 0.88rem; margin-bottom: 0.2rem; }
.background-item-text { font-size: 0.92rem; line-height: 1.5; }
.background-item-edit { margin-top: 0.4rem; font-size: 0.84rem; }
.background-item-edit summary { cursor: pointer; color: var(--dim); }
.background-item-edit form, .background-draft-fields { display: flex; flex-direction: column; gap: 0.45rem; margin-top: 0.5rem; }
.background-item-actions { display: flex; gap: 0.5rem; }
.background-clear { margin-top: 1.5rem; font-size: 0.84rem; color: var(--dim); }
.background-clear form { display: flex; align-items: center; gap: 0.75rem; margin-top: 0.5rem; }
.background-empty { text-align: center; }
.background-draft { display: grid; grid-template-columns: auto 1fr; gap: 0.75rem; align-items: start; margin-bottom: 0.6rem; }
.background-draft-fields { margin-top: 0; }
.background-draft-keep { font-size: 0.84rem; white-space: nowrap; }
.background-review-actions { margin-top: 1rem; }
.background-grid textarea, .background-item-edit textarea, .background-draft textarea,
.background-item-edit input[type="text"], .background-draft input[type="text"], .background-grid input[type="text"] {
  font-family: var(--font-ui); font-size: 0.9rem; line-height: 1.45;
}

/* Additions drawn from the Background tab (#71 Phase 2): a badge on the
   diff row, an outline on the tag, and the note on the result page. */
.background-badge {
  display: inline-block; margin-left: 0.4rem; padding: 0.02rem 0.45rem; border-radius: 999px;
  font-size: 0.68rem; font-weight: 600; vertical-align: middle; cursor: help;
  color: var(--accent-wash-ink); background: var(--accent-wash); border: 1px solid var(--accent-wash-line);
}
.tag.tag-from-background { outline: 1px dashed var(--accent); outline-offset: 1px; cursor: help; }
.field-check label { display: flex; align-items: baseline; gap: 0.45rem; font-weight: 500; }

/* "Role at Company" as the link to the posting (result page, job panel):
   reads as the title, with a small arrow and an underline on hover. */
.posting-title-link { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; transition: border-color 0.15s, color 0.15s; }
.posting-title-link:hover, .posting-title-link:focus-visible { color: var(--accent); border-bottom-color: currentColor; }
.posting-title-icon { font-size: 0.6em; margin-left: 0.3em; vertical-align: 0.35em; color: var(--accent); }
.actions-style-note { font-size: 0.8rem; color: var(--dim); align-self: center; }
.tile-preview-btn { align-self: flex-start; }

/* ---------- Clients (#99: professional accounts) ---------- */
.nav-client-switcher { position: relative; font-size: 0.85rem; }
.nav-client-switcher summary { cursor: pointer; list-style: none; padding: 0.3rem 0.6rem; border: 1px solid var(--line); border-radius: 999px; color: var(--dim); white-space: nowrap; }
.nav-client-switcher summary::-webkit-details-marker { display: none; }
.nav-client-switcher summary strong { color: var(--ink); font-weight: 600; }
.nav-client-switcher.is-client summary { border-color: var(--accent); background: var(--accent-wash); }
.nav-client-switcher.is-client summary strong { color: var(--accent); }
.nav-client-menu { position: absolute; right: 0; top: calc(100% + 0.35rem); min-width: 12rem; max-height: 60vh; overflow: auto; z-index: 20; padding: 0.35rem; background: var(--page-recto); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: 0 8px 24px rgb(0 0 0 / 0.12); }
.nav-client-menu form { margin: 0; }
.nav-client-menu button, .nav-client-menu a { display: block; width: 100%; text-align: left; padding: 0.4rem 0.6rem; border: 0; background: none; font: inherit; color: var(--ink); border-radius: calc(var(--radius) - 2px); cursor: pointer; text-decoration: none; }
.nav-client-menu button:hover, .nav-client-menu a:hover { background: var(--accent-wash); color: var(--accent); }
.nav-client-menu button[aria-current="true"] { font-weight: 600; }
.nav-client-menu a { border-top: 1px solid var(--line); margin-top: 0.25rem; color: var(--dim); }
.pill-client { background: var(--accent); color: #fff; }
.profile-client-note { margin-top: 0.35rem; }
.clients-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(16rem, 22rem); gap: 1.25rem; align-items: start; margin-top: 1.25rem; }
.clients-list { display: flex; flex-direction: column; gap: 0.6rem; }
.client-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.9rem 1.1rem; }
.client-row.is-active { border-color: var(--accent); }
.client-row.is-archived { opacity: 0.75; }
.client-row-name { margin: 0; font-weight: 600; }
.client-row-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; justify-content: flex-end; }
.client-row-actions form { margin: 0; }
.clients-archived-heading { margin-top: 1rem; }
.client-form .field-check label { display: flex; gap: 0.5rem; align-items: flex-start; font-weight: 400; line-height: 1.4; }
.client-danger { margin-top: 1.25rem; border-color: var(--danger-wash-line); }
.btn-danger { background: var(--danger); border-color: var(--danger); }
.btn-danger:hover { background: var(--danger); border-color: var(--danger); filter: brightness(0.92); }
.clients-intro-list { margin: 1rem 0 1.5rem; padding-left: 1.2rem; line-height: 1.6; }
.signup-account-type .field-label { display: block; font-weight: 500; margin-bottom: 0.35rem; }
.signup-account-type .radio-row { display: flex; gap: 0.5rem; align-items: center; font-weight: 400; margin-bottom: 0.25rem; }
@media (max-width: 720px) {
  .clients-grid { grid-template-columns: 1fr; }
  .client-row { flex-direction: column; align-items: flex-start; }
  .client-row-actions { justify-content: flex-start; }
  .nav-client-menu { right: auto; left: 0; }
}

/* ---------- Share links and client uploads (#99 Phase 2) ---------- */
.pill-warn { background: var(--danger-wash); color: var(--danger); }
.job-share { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--line); }
.job-share-head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; }
.job-share-create { display: flex; gap: 0.4rem; align-items: center; margin: 0; }
.job-share-create select { font: inherit; font-size: 0.8rem; padding: 0.2rem 0.4rem; }
.job-share-link { margin-top: 0.75rem; padding: 0.6rem 0.75rem; border: 1px solid var(--line); border-radius: var(--radius); }
.job-share-link.is-inactive { opacity: 0.65; }
.job-share-url, .client-upload-link, .client-upload { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; }
.job-share-url form, .client-upload-link form, .client-upload form { margin: 0; }
.job-share-url input, .client-upload-link input { flex: 1 1 14rem; min-width: 0; font-family: var(--font-mono, monospace); font-size: 0.75rem; padding: 0.3rem 0.45rem; border: 1px solid var(--line); border-radius: calc(var(--radius) - 2px); background: var(--page-verso); color: var(--dim); }
.job-share-comment { margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px dashed var(--line); }
.job-share-comment-body { margin: 0.3rem 0 0; white-space: normal; }
.client-upload, .client-upload-link { margin-top: 0.5rem; }
.share-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(16rem, 1fr); gap: 1.25rem; align-items: start; margin-top: 1.25rem; }
.share-preview iframe { width: 100%; height: 75vh; border: 0; border-radius: calc(var(--radius) - 2px); background: #fff; }
.share-downloads { display: flex; gap: 0.5rem; margin: 0.75rem 0 0; }
.share-side { display: flex; flex-direction: column; gap: 1rem; }
.share-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }
.upload-form { max-width: 32rem; margin-top: 1rem; }
@media (max-width: 720px) {
  .share-grid { grid-template-columns: 1fr; }
  .share-preview iframe { height: 60vh; }
}

/* ---------- All clients' jobs (#99) ---------- */
.nav-client-menu a.nav-client-all { color: var(--ink); font-weight: 500; }
.nav-client-menu a.nav-client-all[aria-current="true"] { font-weight: 600; }
.all-jobs-filter { display: flex; gap: 0.5rem; align-items: center; margin: 1rem 0; font-size: 0.85rem; }
.all-jobs { padding: 0; overflow-x: auto; }
.all-jobs table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.all-jobs th, .all-jobs td { text-align: left; padding: 0.6rem 0.9rem; border-bottom: 1px solid var(--line); vertical-align: middle; }
.all-jobs th { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--dim); font-weight: 600; }
.all-jobs tr:last-child td { border-bottom: 0; }
.all-jobs form { margin: 0; }
.all-jobs-group { padding: 0; margin-bottom: 0.9rem; overflow-x: auto; }
.all-jobs-group table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.all-jobs-group th, .all-jobs-group td { text-align: left; padding: 0.55rem 1rem; border-top: 1px solid var(--line); vertical-align: middle; }
.all-jobs-group th { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--dim); font-weight: 600; }
.all-jobs-group form { margin: 0; }
.all-jobs-group-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; padding: 0.8rem 1rem; }
.all-jobs-empty { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.6rem 1rem 0.8rem; border-top: 1px solid var(--line); }

/* ---------- Client switcher menu: disabled entries ---------- */
.nav-client-menu button:disabled { color: var(--dim); cursor: not-allowed; opacity: 0.6; }
.nav-client-menu button:disabled:hover { background: none; color: var(--dim); }

/* ---------- Openings (#103 R1) ---------- */
a.opening-row { text-decoration: none; color: inherit; }
a.opening-row:hover { border-color: var(--accent); }
.all-jobs-group-head a[aria-current="true"] { font-weight: 600; color: var(--ink); }
.opening-delete { margin-top: 1.5rem; }
.clients-grid + .opening-delete { margin-top: 1rem; }
.clients-first { border-style: dashed; border-color: var(--accent); }



/* ---------- Feedback category and rating (#111) ---------- */
.feedback-choices .field-label { display: block; font-weight: 500; margin-bottom: 0.4rem; }
.feedback-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
.feedback-chip { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.3rem 0.65rem; border: 1px solid var(--line); border-radius: 999px; font-weight: 400; font-size: 0.85rem; cursor: pointer; }
.feedback-chip:has(input:checked) { border-color: var(--accent); background: var(--accent-wash); color: var(--accent); }
.feedback-chip input { margin: 0; }

/* ---------- Application status on job tiles (#109) ---------- */
.result-tile.status-active { border-color: var(--success); }
.result-tile.status-active .resume-card-accent { background: var(--success); }
.result-tile.status-active .application-status-select { background: var(--success-wash); border-color: var(--success); color: var(--ink); }
.result-tile.status-planned .resume-card-accent { background: var(--accent-wash-line); }
.result-tile.status-closed { opacity: 0.72; }
.result-tile.status-closed .resume-card-accent { background: var(--line); }
.status-dot { display: inline-block; width: 0.55rem; height: 0.55rem; border-radius: 50%; margin-right: 0.4rem; vertical-align: middle; background: var(--line); }
.status-dot.status-active { background: var(--success); }
.status-dot.status-planned { background: var(--accent-wash-line); }

/* ---------- "Add your background" reminder (background_nudge) ---------- */
.background-nudge { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem 1rem; flex-wrap: wrap; margin: 0.75rem 0; padding: 0.75rem 0.9rem; border: 1px dashed var(--accent); border-radius: var(--radius); background: var(--accent-wash); font-size: 0.88rem; line-height: 1.45; }
.background-nudge-text { flex: 1 1 18rem; }
.background-nudge-actions { display: flex; gap: 0.4rem; align-items: center; }
.background-nudge-actions form { margin: 0; }
.background-return { margin: 0 0 1rem; }

/* Billing (billing.html). */
.billing-card { max-width: 34rem; display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem; }
.billing-card form { margin: 0.25rem 0 0; }
.billing-card p { margin: 0; }
.billing-plan { font-size: 1.5rem; font-weight: 700; }
.billing-test-note { max-width: 34rem; }

/* Signed in as a test account (tailor/test_accounts.py). */
.test-account-strip { position: relative; z-index: 35; background: var(--page-verso); border-bottom: 1px solid var(--accent-wash-line); }  /* menu above the sticky stepper (20), under the header (40) */
.test-account-strip-inner {
  max-width: var(--content-width-wide); margin: 0 auto; padding: 0.45rem 1.5rem;
  display: flex; gap: 0.75rem; align-items: center; justify-content: center; flex-wrap: wrap; font-size: 0.85rem;
}
.test-account-strip-inner form { margin: 0; }
.test-account-strip-switch { position: relative; }
.test-account-strip-switch summary { cursor: pointer; color: var(--accent); }
.test-account-strip-menu {
  position: absolute; z-index: 20; top: 1.6rem; left: 0; background: var(--page-recto);
  border: 1px solid var(--accent-wash-line); border-radius: 8px; padding: 0.3rem; min-width: 11rem;
}
.test-account-strip-menu button { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 0.35rem 0.6rem; cursor: pointer; font: inherit; }
.test-account-strip-menu button:hover { background: var(--page-verso); }
.test-accounts-table td { vertical-align: middle; padding: 0.5rem 0.6rem; }
.test-accounts-table form { display: inline; margin: 0; }
.test-accounts-table { width: 100%; border-collapse: collapse; }
.test-accounts-table th { text-align: left; font-size: 0.75rem; color: var(--dim); padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--line); }
.test-accounts-table tr + tr td { border-top: 1px solid var(--line); }
.test-accounts-table button, .test-accounts-table strong { white-space: nowrap; }

/* ---------- Step 4: this job's resume, edited in place ---------- */
.result-editor { margin: 2rem 0; }
.result-editor-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; margin-bottom: 0.5rem; }
.result-editor-head form { margin: 0; }
.result-editor .ed-statusbar { position: static; }  /* the wizard's stepper is the sticky bar here */
.result-save-note { color: var(--accent-wash-ink); }

/* ---------- "Your edits" (Review, a saved job) ---------- */
.own-edits { margin: 1rem 0; padding: 1rem 1.25rem; }
.own-edits-list { list-style: none; margin: 0.5rem 0; padding: 0; display: grid; gap: 0.5rem; }
.own-edits-list li { display: grid; gap: 0.15rem; font-size: 0.9rem; }
.own-edits-list .tk-del { text-decoration: line-through; color: var(--dim); }

/* ---------- Step 4: the editor in the chosen style's look ----------
   The editor (.ed-page) reads these, so on step 4 it takes the chosen
   resume style's fonts and colors (.ed-look-<style>, set by result.html;
   fonts loaded from the style's font_href). Unset on Edit your resume,
   which keeps the app's own look. Layout, spacing and page breaks stay
   the PDF's (the preview beside it); this is only the look. The values
   are taken from each print_resume_*.css: change them together. */
.ed-page { font-family: var(--ed-font-body, inherit); color: var(--ed-ink, var(--ink)); }
.ed-name { font-family: var(--ed-font-name, inherit); color: var(--ed-name-color, inherit); }
.ed-title { font-family: var(--ed-font-heading, inherit); color: var(--ed-accent, var(--accent)); }
.ed-section-title { font-family: var(--ed-font-heading, inherit); color: var(--ed-heading-color, inherit); border-bottom-color: var(--ed-rule, var(--ink)); }
.ed-role, .ed-skill-label { font-family: var(--ed-font-heading, inherit); }
.ed-entry-sub { color: var(--ed-accent, var(--accent)); }
.ed-list-chips .ed-item { background: var(--ed-chip-bg, var(--page-verso)); }
.ed-page[class*="ed-look-"] button { font-family: var(--font-ui); }  /* controls stay the app's */
.ed-page[class*="ed-look-"] .ed-list-bullets .ed-item::before { color: var(--ed-accent); }

.ed-look-classic {
  --ed-font-body: "DM Sans", system-ui, sans-serif; --ed-font-name: "DM Serif Display", Georgia, serif; --ed-font-heading: "DM Sans", sans-serif;
  --ed-ink: #1f2937; --ed-name-color: #0c2340; --ed-heading-color: #0c2340; --ed-accent: #0a7566; --ed-rule: #0c2340; --ed-chip-bg: #e6f2f0;
}
.ed-look-bronze {
  --ed-font-body: "Inter", system-ui, sans-serif; --ed-font-name: "Inter", sans-serif; --ed-font-heading: "Inter", sans-serif;
  --ed-ink: oklch(0.18 0.01 38); --ed-name-color: oklch(0.39 0.144 38); --ed-heading-color: oklch(0.39 0.144 38);
  --ed-accent: oklch(0.47 0.16 38); --ed-rule: oklch(0.39 0.144 38); --ed-chip-bg: oklch(0.93 0.035 38);
}
.ed-look-traditional {
  --ed-font-body: "EB Garamond", Georgia, serif; --ed-font-name: "Jost", "Century Gothic", sans-serif; --ed-font-heading: "Jost", "Century Gothic", sans-serif;
  --ed-ink: #1a1a1a; --ed-name-color: #8a3a1f; --ed-heading-color: #1a1a1a; --ed-accent: #555; --ed-rule: #222; --ed-chip-bg: #f1ede9;
}
.ed-look-jake {
  --ed-font-body: "Source Serif 4", "Times New Roman", serif; --ed-font-name: "Source Serif 4", serif; --ed-font-heading: "Source Serif 4", serif;
  --ed-ink: #111; --ed-name-color: #111; --ed-heading-color: #111; --ed-accent: #333; --ed-rule: #111; --ed-chip-bg: #f2f2f2;
}
.ed-look-mcdowell {
  --ed-font-body: "Crimson Pro", "Times New Roman", serif; --ed-font-name: "Crimson Pro", serif; --ed-font-heading: "Crimson Pro", serif;
  --ed-ink: #111; --ed-name-color: #111; --ed-heading-color: #111; --ed-accent: #333; --ed-rule: #111; --ed-chip-bg: #f2f2f2;
}
.ed-look-awesome {
  --ed-font-body: "Source Sans 3", "Helvetica Neue", Arial, sans-serif; --ed-font-name: "Source Sans 3", sans-serif; --ed-font-heading: "Source Sans 3", sans-serif;
  --ed-ink: #333; --ed-name-color: #111; --ed-heading-color: #c0392b; --ed-accent: #c0392b; --ed-rule: #ccc; --ed-chip-bg: #f7e6e4;
}
.ed-look-sidebar {
  --ed-font-body: "Lato", "Helvetica Neue", Arial, sans-serif; --ed-font-name: "Lato", sans-serif; --ed-font-heading: "Lato", sans-serif;
  --ed-ink: #2b2b2b; --ed-name-color: #1f3a5f; --ed-heading-color: #1f3a5f; --ed-accent: #1f3a5f; --ed-rule: #b9c4d0; --ed-chip-bg: #eef1f4;
}

/* Step 4's editor and preview: each a panel, closed by default, in the
   order you work (editor, styles, preview, downloads). */
.result-panel {
  /* #edit scrolls here: clear of the wizard's sticky stepper. */
  scroll-margin-top: calc(var(--stepper-h, 5rem) + 0.5rem);
  margin: 1.25rem 0; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--page-recto);
}
.result-panel-summary {
  cursor: pointer; list-style: none; display: flex; align-items: baseline; flex-wrap: wrap;
  gap: 0.25rem 0.75rem; padding: 0.9rem 1rem; border-radius: var(--radius);
}
.result-panel-summary::-webkit-details-marker { display: none; }
/* The same CSS triangle as details.advanced (no glyph to fail to render). */
.result-panel-summary::before {
  content: ""; align-self: center; width: 0; height: 0; border-style: solid;
  border-width: 4.5px 0 4.5px 6.5px; border-color: transparent transparent transparent currentColor;
  transition: transform 0.15s;
}
.result-panel[open] > .result-panel-summary::before { transform: rotate(90deg); }
.result-panel-summary:hover { background: var(--page-verso); }
.result-panel-summary:hover .result-panel-title { color: var(--accent); }
.result-panel-title { font-weight: 600; color: var(--ink); }
.result-panel-hint { font-size: 0.82rem; color: var(--dim); }
.result-panel[open] > .result-panel-summary { border-bottom: 1px solid var(--line); border-radius: var(--radius) var(--radius) 0 0; }
/* Inside a panel the frame comes from the panel, not the preview's own card. */
.result-panel .resume-pdf-preview.result-preview.is-expanded { margin: 0; border: 0; border-radius: 0 0 var(--radius) var(--radius); box-shadow: none; }
.result-panel .result-editor { margin: 0; padding: 0.75rem 1rem 1rem; }
/* A style's thumbnail while its preview renders (result.html), under the
   loader, which goes see-through so both show. */
.result-preview-placeholder { display: none; }
.has-placeholder:not(.is-loaded) > .result-preview-placeholder {
  display: block; position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%;
  object-fit: contain; object-position: top center; padding: 0.75rem; background: var(--page-verso);
}
.has-placeholder:not(.is-loaded) > .echo-loader-overlay { background: transparent; }
/* Open, the preview fits the window (with the stepper above it). */
@media (min-width: 761px) {
  .result-panel .resume-pdf-preview.result-preview.is-expanded:not(.is-image) {
    height: min(44rem, calc(100vh - var(--stepper-h, 5rem) - 5rem)); min-height: 24rem;
  }
}
.ed-look-note { margin-top: 0.15rem; }
