/* ==========================================================================
   refine-ai-job-search — dashboard UI

   One stylesheet, no framework, no build step. Design direction follows the
   Nixtio / Bogdan Nikitin HR-dashboard look: a warm off-white ground, white
   cards with a generous radius, near-black type, an acid-lime accent used
   sparingly, and pill controls.

   Every colour is a token on :root and redefined for dark mode, so nothing
   below hard-codes a hex value. Adding a theme means editing one block.
   ========================================================================== */

:root {
  /* The page behind the app shell: a cool grey the warm shell sits on. */
  --page:          #e9e9ee;

  --bg:            #fdfcf5;   /* the shell itself - warm ivory */
  --surface:       #ffffff;
  --surface-2:     #fbfaf2;
  --surface-sunk:  #f4f2e6;
  --ink:           #1a1a18;
  --ink-2:         #45443e;
  --muted:         #8b897e;
  --line:          #eceadd;
  --line-strong:   #ded9c6;

  --accent:        #f5ce3e;   /* amber - highlights, never body text */
  --accent-ink:    #1a1a18;   /* type that sits on the amber */
  --accent-soft:   #fdf3cd;
  --accent-warm:   #ffe89b;   /* the gradient wash in the top-right */

  --contrast:      #1c1c1a;   /* the near-black pills and feature cards */
  --contrast-ink:  #fdfcf5;

  --lilac:         #e8e3fb;
  --peach:         #ffe0c4;
  --mint:          #d5f0d9;
  --sky:           #d9e8fb;
  --rose:          #ffdde1;

  --ok:            #2f7d4f;
  --warn:          #9a6212;
  --danger:        #b3261e;
  --danger-soft:   #fdecea;

  --r-xl: 34px;
  --r-lg: 26px;
  --r-md: 16px;
  --r-sm: 10px;

  --shadow:    0 1px 2px rgba(26,26,24,.03), 0 6px 20px rgba(26,26,24,.045);
  --shadow-lg: 0 2px 4px rgba(26,26,24,.04), 0 20px 48px rgba(26,26,24,.09);

  --sidebar-w: 252px;
  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Inter, Roboto,
          "Helvetica Neue", Arial, sans-serif;
}

/* Dark is opt-in, never automatic. Following prefers-color-scheme would mean a
   machine in dark mode never sees the design this app was actually drawn in.
   The toggle in the topbar sets data-theme and remembers the choice. */
:root[data-theme="dark"] {
  --page:         #08080a;
  --bg:           #121214;
  --surface:      #1a1a1d;
  --surface-2:    #202024;
  --surface-sunk: #17171a;
  --ink:          #f6f5ef;
  --ink-2:        #c6c4ba;
  --muted:        #86847b;
  --line:         #2a2a30;
  --line-strong:  #383840;

  --accent-soft:  #3a3010;
  --accent-warm:  #2c2410;

  --contrast:     #f5ce3e;
  --contrast-ink: #1a1a18;

  --lilac:        #2a2545;
  --peach:        #3c2a1a;
  --mint:         #16341f;
  --sky:          #16283f;
  --rose:         #3a1f26;

  --ok:           #57cf94;
  --warn:         #e2b062;
  --danger:       #ff8a80;
  --danger-soft:  #37191a;

  --shadow:    0 1px 2px rgba(0,0,0,.5), 0 8px 24px rgba(0,0,0,.35);
  --shadow-lg: 0 2px 4px rgba(0,0,0,.5), 0 20px 48px rgba(0,0,0,.5);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

/* ==========================================================================
   App shell — fixed sidebar, scrolling main column
   ========================================================================== */

/* The whole app is one rounded card inset from the page edge, with a warm
   wash bleeding out of the top-right corner. */
/* Only the signed-in shell owns the viewport. The auth pages are their own
   layout and have to be free to scroll on a short window. */
.app-shell { position: fixed; inset: 0; overflow: hidden; }

/* The shell fills the viewport and does not move; the content well inside it
   is what scrolls. `position: sticky` on the sidebar could not work here -
   `overflow: hidden` makes this element the scroll container, and a sticky
   child sticks to a box that never scrolls, so the sidebar rode the page. */
.app {
  display: flex;
  height: calc(100vh - 24px);
  margin: 12px;
  border-radius: var(--r-xl);
  background:
    radial-gradient(120% 90% at 100% 0%, var(--accent-warm) 0%, transparent 55%),
    var(--bg);
  overflow: hidden;
}

.sidebar {
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  background: transparent;
  border-right: 1px solid var(--line);
  padding: 24px 16px;
  display: flex;
  flex-direction: column;
  gap: 26px;
  height: 100%;
  /* The nav itself can outgrow a short window; the app frame never scrolls. */
  overflow-y: auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 8px;
  text-decoration: none;
}

.brand-mark {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -0.04em;
  flex: none;
}

.brand-name { font-weight: 650; letter-spacing: -0.03em; font-size: 15px; }
.brand-sub  { font-size: 11px; color: var(--muted); letter-spacing: .02em; }

.nav { display: flex; flex-direction: column; gap: 2px; }

.nav-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--muted);
  padding: 0 10px;
  margin-bottom: 8px;
}

.nav a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 11px;
  border-radius: var(--r-sm);
  text-decoration: none;
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 500;
  transition: background .13s ease, color .13s ease;
}

.nav a:hover { background: var(--surface-sunk); color: var(--ink); }

.nav a.is-active {
  background: var(--contrast);
  color: var(--contrast-ink);
}
.nav a.is-active .nav-icon { opacity: 1; }

.nav-icon {
  width: 17px; height: 17px;
  flex: none;
  opacity: .65;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.nav-count {
  margin-left: auto;
  font-size: 11px;
  font-weight: 600;
  background: var(--surface-sunk);
  color: var(--muted);
  padding: 2px 7px;
  border-radius: 999px;
}
.nav a.is-active .nav-count { background: rgba(255,255,255,.16); color: inherit; }

.sidebar-foot { margin-top: auto; display: flex; flex-direction: column; gap: 12px; }

.side-note {
  background: var(--surface-sunk);
  border-radius: var(--r-md);
  padding: 13px 14px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted);
}
.side-note strong { color: var(--ink-2); display: block; margin-bottom: 3px; font-size: 12px; }

.main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* The one scrolling box on the page. */
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* ==========================================================================
   Topbar
   ========================================================================== */

.topbar {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 22px 30px 18px;
  background: transparent;
}

.topbar-titles h1 { font-size: 30px; font-weight: 450; letter-spacing: -0.035em; }
.topbar-titles p  { margin: 5px 0 0; font-size: 13.5px; color: var(--muted); }

.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 12px; }

.user-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 6px 5px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  text-decoration: none;
}

.user-chip-name  { font-size: 13px; font-weight: 550; line-height: 1.15; }
.user-chip-email { font-size: 11px; color: var(--muted); line-height: 1.15; }

.avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--contrast);
  color: var(--contrast-ink);
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 650;
  letter-spacing: .02em;
  flex: none;
}
.avatar-lg { width: 46px; height: 46px; font-size: 16px; border-radius: 15px; }

.content { padding: 8px 30px 40px; }

/* ==========================================================================
   Cards & layout primitives
   ========================================================================== */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 24px;
  box-shadow: var(--shadow);
}

.card-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.card-head h2 { font-size: 15px; letter-spacing: -0.01em; }
.card-head .card-action { margin-left: auto; font-size: 13px; color: var(--muted); text-decoration: none; }
.card-head .card-action:hover { color: var(--ink); }

.grid { display: grid; gap: 16px; }
.grid-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-split { grid-template-columns: 1.55fr 1fr; align-items: start; }

/* Stat tiles ------------------------------------------------------------- */

.stat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 20px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: 132px;
}

.stat-top { display: flex; align-items: flex-start; gap: 12px; }
.stat-label { font-size: 13px; color: var(--muted); font-weight: 500; }

.stat-badge {
  margin-left: auto;
  width: 34px; height: 34px;
  border-radius: 11px;
  display: grid;
  place-items: center;
  flex: none;
}
.stat-badge svg { width: 16px; height: 16px; stroke: var(--ink); fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.stat-badge.b-lime  { background: var(--accent); }
.stat-badge.b-lilac { background: var(--lilac); }
.stat-badge.b-peach { background: var(--peach); }
.stat-badge.b-mint  { background: var(--mint); }
.stat-badge.b-sky   { background: var(--sky); }

.stat-value {
  font-size: 42px;
  font-weight: 300;
  letter-spacing: -0.05em;
  line-height: 1;
  margin-top: auto;
  font-variant-numeric: tabular-nums;
}
.stat-foot { font-size: 12px; color: var(--muted); }

/* Highlight tile — the one card allowed to be loud */
.stat.is-feature {
  background: linear-gradient(150deg, var(--accent) 0%, var(--accent-warm) 130%);
  border-color: transparent;
  color: var(--accent-ink);
}
.stat.is-feature .stat-label,
.stat.is-feature .stat-foot { color: rgba(26,26,24,.60); }
.stat.is-feature .stat-badge { background: rgba(26,26,24,.10); }
.stat.is-feature .stat-badge svg { stroke: var(--accent-ink); }

/* ==========================================================================
   Buttons & form controls
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: var(--contrast);
  color: var(--contrast-ink);
  font: inherit;
  font-size: 14px;
  font-weight: 550;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: opacity .13s ease, background .13s ease, border-color .13s ease;
}
.btn:hover { opacity: .88; }
.btn:disabled { opacity: .45; cursor: not-allowed; }

.btn-accent { background: var(--accent); color: var(--accent-ink); }
.btn-ghost  { background: transparent; color: var(--ink); border-color: var(--line-strong); }
.btn-ghost:hover { background: var(--surface-sunk); opacity: 1; }
.btn-sm     { padding: 7px 13px; font-size: 13px; }
.btn-block  { width: 100%; }
.btn-icon   { padding: 8px; width: 34px; height: 34px; border-radius: 50%; }
.btn svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field label { font-size: 12px; font-weight: 550; color: var(--ink-2); }
.field-hint  { font-size: 11px; color: var(--muted); }

input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="search"], select, textarea {
  width: 100%;
  padding: 10px 13px;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  outline: none;
  transition: border-color .13s ease, box-shadow .13s ease;
}

input::placeholder { color: var(--muted); }

input:focus, select:focus {
  border-color: var(--ink);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

select {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2386868c' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 32px;
}

/* Search bar ------------------------------------------------------------- */

.searchbar { display: grid; grid-template-columns: 1.5fr 1.5fr .85fr .85fr auto; gap: 12px; align-items: end; }
.searchbar .btn { height: 40px; }

/* ==========================================================================
   Tables
   ========================================================================== */

.table-wrap { overflow-x: auto; margin: 0 -22px -22px; padding: 0 22px 6px; }

table { width: 100%; border-collapse: collapse; font-size: 14px; }

thead th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--muted);
  padding: 0 12px 10px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

tbody td {
  padding: 13px 12px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--surface-2); }

.cell-title { font-weight: 550; letter-spacing: -0.01em; }
.cell-title a { text-decoration: none; }
.cell-title a:hover { text-decoration: underline; }
.cell-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.cell-muted { color: var(--muted); font-size: 13px; white-space: nowrap; }
/* A location is prose and wraps; a date never is. They shared one class, so
   "Cambridge, England, United Kingdom" was told to stay on one line. */
.cell-place { color: var(--muted); font-size: 13px; }

/* The results table sets its own columns. Auto layout sized them from the
   widest cell, which on a wide window starved the role column - titles broke
   over three lines - and left the right half of every row empty. */
.results { table-layout: fixed; }
.results .col-role    { width: 34%; }
.results .col-company { width: 22%; }
.results .col-place   { width: 22%; }
.results .col-when    { width: 12%; }
.results .col-do      { width: 10%; }
.results .cell-title  { line-height: 1.35; }
/* The company name wraps rather than pushing its column wider. */
.results .company span:last-child { min-width: 0; overflow-wrap: anywhere; }

@media (max-width: 1100px) {
  /* Narrow enough that the date is the first thing worth giving up. */
  .results .col-role    { width: 40%; }
  .results .col-company { width: 26%; }
  .results .col-place   { width: 22%; }
  .results .col-when    { width: 0; }
  .results .col-do      { width: 12%; }
  .results .col-when, .results th:nth-child(4), .results td:nth-child(4) { display: none; }
}
.cell-actions { text-align: right; white-space: nowrap; }

.company {
  display: flex;
  align-items: center;
  gap: 10px;
}
.company-mark {
  width: 30px; height: 30px;
  border-radius: 9px;
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 650;
  background: var(--surface-sunk);
  color: var(--ink-2);
  flex: none;
}

/* ==========================================================================
   Chips, pills, badges
   ========================================================================== */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 550;
  background: var(--surface-sunk);
  color: var(--ink-2);
  white-space: nowrap;
}
.chip-lime  { background: var(--accent); color: var(--accent-ink); }
.chip-lilac { background: var(--lilac); color: var(--ink); }
.chip-mint  { background: var(--mint);  color: var(--ink); }
.chip-peach { background: var(--peach); color: var(--ink); }
.chip-sky   { background: var(--sky);   color: var(--ink); }
.chip-rose  { background: var(--rose);  color: var(--ink); }

.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }

/* ==========================================================================
   Activity chart — bars drawn with divs, no chart library
   ========================================================================== */

.chart {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 132px;
  padding-top: 8px;
}
.chart-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 8px; min-width: 0; }
.chart-bar {
  width: 100%;
  border-radius: 6px 6px 3px 3px;
  background: var(--accent);
  min-height: 3px;
  transition: opacity .13s ease;
}
.chart-bar.is-empty { background: var(--surface-sunk); }
.chart-col:hover .chart-bar { opacity: .75; }
.chart-tick {
  font-size: 10px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* ==========================================================================
   Empty & message states
   ========================================================================== */

.empty { text-align: center; padding: 44px 20px; color: var(--muted); }
.empty-mark {
  width: 52px; height: 52px;
  border-radius: 17px;
  background: var(--surface-sunk);
  display: grid;
  place-items: center;
  margin: 0 auto 14px;
}
.empty-mark svg { width: 22px; height: 22px; stroke: var(--muted); fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.empty h3 { font-size: 15px; color: var(--ink); margin-bottom: 5px; }
.empty p  { margin: 0 auto; max-width: 44ch; font-size: 13px; }

.alert {
  display: flex;
  gap: 11px;
  padding: 13px 16px;
  border-radius: var(--r-md);
  font-size: 13.5px;
  margin-bottom: 18px;
  border: 1px solid transparent;
}
.alert-error  { background: var(--danger-soft); color: var(--danger); border-color: color-mix(in srgb, var(--danger) 22%, transparent); }
.alert-ok     { background: var(--mint); color: var(--ok); border-color: color-mix(in srgb, var(--ok) 22%, transparent); }
.alert code   { font-size: 11px; opacity: .75; }

/* ==========================================================================
   Job detail
   ========================================================================== */

.detail-head { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 20px; }
.detail-head h2 { font-size: 23px; }
.detail-head .company-mark { width: 46px; height: 46px; border-radius: 15px; font-size: 15px; }
.detail-meta { color: var(--muted); font-size: 13.5px; margin-top: 5px; }

.description {
  font-size: 14.5px;
  line-height: 1.68;
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.detail-side { display: flex; flex-direction: column; gap: 16px; }

/* Which resume the score is for. Sits above the number, because changing it
   changes the number. */
.resume-pick {
  display: flex; flex-direction: column; gap: 6px;
  padding-bottom: 14px; margin-bottom: 14px;
  border-bottom: 1px solid var(--line);
}
.resume-pick label {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted);
}
.resume-pick select { font-size: 12.5px; padding: 7px 10px; border-radius: 9px; }

/* The match score --------------------------------------------------------- */

.match { display: flex; align-items: center; gap: 14px; }
.match-title { font-size: 14px; font-weight: 600; }
.ring {
  width: 62px; height: 62px; border-radius: 50%; flex: none;
  display: grid; place-items: center; position: relative;
  /* The arc is the score; the hole in the middle is drawn over it. */
  background: conic-gradient(var(--tone, var(--accent)) var(--pct, 0%), var(--surface-sunk) 0);
}
.ring::after { content: ""; position: absolute; inset: 7px; border-radius: 50%; background: var(--surface); }
.ring b { position: relative; z-index: 1; font-size: 19px; font-weight: 650; font-variant-numeric: tabular-nums; }
.ring.is-good { --tone: var(--ok); }
.ring.is-fair { --tone: var(--warn); }
.ring.is-poor { --tone: var(--danger); }

.bars { display: grid; gap: 5px; margin-top: 14px; }
.bar { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--muted); }
.bar i { flex: none; width: 46px; font-style: normal; }
.bar u { flex: 1; height: 5px; border-radius: 3px; background: var(--surface-sunk); text-decoration: none; }
.bar u b { display: block; height: 100%; border-radius: 3px; background: var(--accent); }

/* The score, broken into the four things it is made of. Same shape as .bars
   on the posting, with the points spelled out - "12/20" answers "where did
   the other eight go" in a way a bar on its own never does. */
.parts { display: grid; gap: 6px; margin-top: 15px; }
.part {
  display: flex; align-items: center; gap: 9px;
  font-size: 11px; color: var(--muted);
}
.part i { flex: none; width: 52px; font-style: normal; }
.part u {
  flex: 1; height: 5px; border-radius: 3px;
  background: var(--surface-sunk); text-decoration: none;
}
.part u b { display: block; height: 100%; border-radius: 3px; background: var(--accent); }
.part em {
  flex: none; width: 34px; text-align: right; font-style: normal;
  font-variant-numeric: tabular-nums; color: var(--ink-2);
}

.chip.is-gap { background: var(--surface); border: 1px dashed var(--line-strong); color: var(--ink-2); }
.match-notes { margin: 14px 0 0; padding-left: 16px; }

/* The resumes list -------------------------------------------------------- */

.version {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface-2);
}
.version + .version { margin-top: 8px; }
.version-score {
  flex: none;
  width: 40px; height: 40px;
  border-radius: 12px;
  display: grid; place-items: center;
  font-size: 14px; font-weight: 650;
  font-variant-numeric: tabular-nums;
  background: var(--surface-sunk);
}
.version-score.is-good { background: #e7f3ec; color: var(--ok); }
.version-score.is-fair { background: var(--accent-soft); color: var(--warn); }
.version-score.is-poor { background: var(--danger-soft); color: var(--danger); }
.version-what { min-width: 0; }
.version-what b { display: block; font-size: 12.5px; font-weight: 600; }
.version-what > span { display: block; font-size: 11.5px; color: var(--muted); line-height: 1.45; }
.version-what .tag {
  display: inline-block; margin-left: 6px;
  font-size: 9.5px; text-transform: uppercase; letter-spacing: .07em;
  padding: 1px 7px; border-radius: 999px;
  background: var(--accent-soft); color: var(--ink-2);
}
.version-acts { margin-left: auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

@media (max-width: 720px) {
  .version { flex-wrap: wrap; }
  .version-acts { margin-left: 0; width: 100%; }
}

/* The tailoring overlay ----------------------------------------------------

   CSS-only: `:target` opens it, a link back to the page closes it. The whole
   app is server-rendered with no JavaScript, and a modal that needed some
   would be the one thing on the site that breaks without it.
   ========================================================================== */

.modal { display: none; }
/* `:has(:target)` as well as `:target`: an action inside the overlay can send
   you back to an anchor *within* it - the end of the conversation, one
   change - and matching only the overlay's own id would close it every time
   that happened. Which is exactly what it did. */
.modal:target,
.modal:has(:target) {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 60;
  overflow-y: auto;
  padding: 28px 20px 40px;
  /* Above the fixed app shell, which owns the viewport. */
  background: rgba(26, 26, 24, .42);
  backdrop-filter: blur(2px);
}
:root[data-theme="dark"] .modal:target { background: rgba(0, 0, 0, .62); }

/* The backdrop is a link, so clicking outside closes it - as a person
   expects, and without a keydown handler to do it. */
.modal-veil { position: fixed; inset: 0; display: block; }

.modal-card {
  position: relative;
  max-width: 1100px;
  margin: 0 auto;
  background: var(--bg);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.modal-head {
  display: flex; align-items: center; gap: 16px;
  padding: 18px 24px;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  position: sticky; top: 0; z-index: 1;
}
.modal-head h2 { font-size: 16px; font-weight: 620; letter-spacing: -.01em; }
.modal-head span { font-size: 12.5px; color: var(--muted); }
.modal-x {
  margin-left: auto;
  width: 32px; height: 32px;
  border: 1px solid var(--line); border-radius: 50%;
  display: grid; place-items: center;
  font-size: 19px; line-height: 1; color: var(--ink-2); text-decoration: none;
}
.modal-x:hover { background: var(--surface-sunk); color: var(--ink); }
.modal-body { padding: 20px 24px 26px; }

@media (max-width: 720px) {
  .modal:target { padding: 0; }
  .modal-card { border-radius: 0; min-height: 100vh; }
}

/* The assistant, beside the document it is talking about ------------------- */

/* The document leads; the score and the chat read alongside it. */
.coach {
  display: grid;
  /* The document is the work; the score and the chat are what you consult
     while doing it. So the document takes the room that is left and the
     column beside it is a fixed sidebar, wide enough to read a paragraph of
     chat and no wider. */
  grid-template-columns: minmax(0, 1fr) 386px;
  gap: var(--gap);
  align-items: start;
  margin-bottom: var(--gap);
}
.coach-side {
  display: flex; flex-direction: column; gap: var(--gap); min-width: 0;
  /* The sheet is a full page tall, so the score and the chat would scroll
     away exactly when you start editing the lines they are about. */
  position: sticky;
  top: 12px;
}

/* What can be typed into, and what the typing did. */
.editing-note {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 10px;
  font-size: 11.5px; color: var(--muted);
}
.editing-note kbd {
  font: inherit; font-size: 10.5px; font-weight: 600;
  border: 1px solid var(--line-strong); border-radius: 4px;
  padding: 1px 5px; background: var(--surface); color: var(--ink-2);
}
.editing-note .said {
  margin-left: auto; font-weight: 600;
  opacity: 0; transition: opacity .15s ease;
}
.editing-note .said.on { opacity: 1; }
.editing-note .said.ok { color: #3f8f5f; }
.editing-note .said.bad { color: var(--danger, #c0392b); }
.coach-talk, .coach-doc, .score-card { margin: 0; }
.traceable { margin: 0 0 var(--gap); }

.score-live { display: flex; align-items: center; gap: 16px; }
.score-live .ring.big { width: 74px; height: 74px; }
.score-live .ring.big b { font-size: 24px; }
.score-line { display: flex; align-items: baseline; gap: 7px; font-size: 12.5px; }
.score-line b { font-size: 14px; font-variant-numeric: tabular-nums; }
.score-line .muted { font-size: 11px; }

.chat {
  display: flex; flex-direction: column; gap: 9px;
  max-height: 300px;
  overflow-y: auto;
  padding-right: 4px;
  margin-bottom: 12px;
}
.turn { max-width: 88%; }
/* A turn carrying a written analysis is a document, not a remark: it gets
   the full width and the chat gets taller to read it in. */
.turn:has(.analysis) { max-width: 100%; }
.chat:has(.analysis) { max-height: 620px; }

.analysis { display: grid; gap: 8px; margin-top: 9px; }
.finding {
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-strong);
  border-radius: 9px;
  background: var(--surface);
  padding: 9px 11px;
}
.finding h4 {
  display: flex; align-items: baseline; gap: 7px;
  margin: 0 0 5px;
  font-size: 12px; font-weight: 650; color: var(--ink);
}
.finding h4 em {
  margin-left: auto; font-style: normal; font-weight: 500;
  font-size: 10.5px; color: var(--muted); white-space: nowrap;
}
.finding .mark { flex: none; width: 7px; height: 7px; border-radius: 50%; }
.finding ul { margin: 0; padding-left: 15px; }
.finding li { font-size: 12px; line-height: 1.55; color: var(--ink-2); margin-bottom: 3px; }
.finding li:last-child { margin-bottom: 0; }

.finding.is-good    { border-left-color: #3f8f5f; }
.finding.is-good    .mark { background: #3f8f5f; }
.finding.is-fix     { border-left-color: var(--accent); }
.finding.is-fix     .mark { background: var(--accent); }
.finding.is-blocked { border-left-color: #c0392b; }
.finding.is-blocked .mark { background: #c0392b; }
.finding.is-note    .mark { background: var(--line-strong); }
.turn p {
  margin: 0;
  padding: 9px 12px;
  border-radius: 14px;
  font-size: 12.5px;
  line-height: 1.55;
  white-space: pre-wrap;
}
/* The opening bubble is written by the template, not by the assistant, so
   it has no line breaks worth keeping - and pre-wrap was printing the
   markup's indentation as if it were part of the sentence. */
.turn.is-hint p { white-space: normal; }
.turn.is-assistant { align-self: flex-start; }
.turn.is-assistant p { background: var(--surface-sunk); color: var(--ink); border-bottom-left-radius: 5px; }
.turn.is-user { align-self: flex-end; }
.turn.is-user p { background: var(--accent-soft); border: 1px solid var(--accent); border-bottom-right-radius: 5px; }
.turn.is-failed p { background: var(--danger-soft); color: var(--danger); }
.turn.is-waiting p { color: var(--muted); }
.turn-note { display: block; font-size: 10.5px; color: var(--muted); margin: 4px 0 0 12px; }
/* A turn that changed nothing has to read as a warning, not as a footnote. */
.turn-note.is-blocked { color: var(--danger); font-weight: 600; }
/* The anchor the answer lands on. Given a little height so bringing it into
   view actually shows the turn above it rather than clipping to its top. */
.chat-end { display: block; height: 1px; scroll-margin-top: 200px; }

/* The assistant heard you claim a skill and wants your word on it before it
   goes into the profile. Sits between the conversation and the composer,
   where the answer that raised it just landed. */
.claim-offer {
  margin: 12px 0;
  padding: 11px 13px;
  border-radius: 12px;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
}
.claim-offer p {
  margin: 0 0 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-2);
}
.claim-offer b { color: var(--ink); }

.composer { display: flex; gap: 8px; align-items: flex-end; }
.composer textarea { flex: 1; min-height: 44px; }
.prompts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.prompts .chip {
  border: 1px dashed var(--line-strong);
  background: var(--surface);
  cursor: pointer;
  font: inherit; font-size: 11px; font-weight: 500;
  color: var(--ink-2);
  padding: 4px 10px;
}
.prompts .chip:hover { background: var(--surface-sunk); border-style: solid; }

/* The preview is the print view itself, scaled - a preview that is not the
   document can lie about it. */
.preview-frame {
  position: relative;
  height: 300px;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: #fff;
}
.preview-frame iframe {
  position: absolute;
  top: 0; left: 0;
  width: 200%; height: 200%;
  border: 0;
  transform: scale(.5);
  transform-origin: 0 0;
}
/* The document as the main column: the whole sheet, as large as the column
   allows and never larger than life.

   A4 is 210x297mm - 794x1123px at 96dpi - so the frame carries the sheet's
   own proportions and the page is scaled to fit its width. The two agree
   exactly: at a frame width W the scale is W/794, which makes the iframe
   794px wide and 1123px tall, whatever W is. Nothing is cropped, and the
   text is at 100% once the column is wide enough to hold a real page. */
.preview-frame.tall {
  width: 100%;
  max-width: 794px;
  margin-inline: auto;
  height: auto;
  aspect-ratio: 210 / 297;
  border-radius: 10px;
}
.preview-frame.tall iframe {
  --s: var(--preview-scale, 1);
  width: calc(100% / var(--s));
  height: calc(100% / var(--s));
  transform: scale(var(--s));
  transform-origin: 0 0;
}
/* Without the script the scale stays 1, which is right at full width and
   clips on a narrow one. These keep that from looking broken in between. */
@media (max-width: 1240px) {
  .preview-frame.tall { --preview-scale: .82; }
}
@media (max-width: 1040px) {
  .preview-frame.tall { --preview-scale: .68; }
}

.preview-foot { display: flex; align-items: center; gap: 12px; margin-top: 12px; }
.preview-foot > span:last-child { display: flex; flex-direction: column; gap: 2px; }
.preview-foot b { font-size: 12.5px; }
.preview-foot .muted { font-size: 11px; }

@media (max-width: 1180px) {
  .coach { grid-template-columns: minmax(0, 1fr) 330px; }
}
@media (max-width: 940px) {
  .coach { grid-template-columns: 1fr; }
  .preview-frame.tall { --preview-scale: 1; }
}

/* Tailoring, on the posting it belongs to ---------------------------------- */

.tailor { margin-top: 0; }
.tailor-bar {
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  padding: 15px 20px;
  border: 1px solid var(--accent);
  border-radius: var(--r-lg);
  background: var(--accent-soft);
}
.tailor-bar b { display: block; font-size: 13.5px; }
.tailor-bar span { font-size: 12px; color: var(--ink-2); line-height: 1.5; }
.tailor-score { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.tailor-score .ring { width: 52px; height: 52px; }
.tailor-score .ring::after { background: var(--accent-soft); }
.tailor-score .ring b { font-size: 16px; }
.tailor-score .ring.small { width: 42px; height: 42px; }
.tailor-score .ring.small b { font-size: 13px; }
.tailor-score .arrow { color: var(--muted); }
.lift { font-size: 13px; font-weight: 650; }
.lift.up { color: var(--ok); }

.change {
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 13px 15px;
  background: var(--surface-2);
  scroll-margin-top: 20px;
}
.change + .change { margin-top: 10px; }
/* An undone change stays on the page - you are choosing, not deleting - but
   it stops looking like part of the resume. */
.change.is-out { opacity: .55; }
.change.is-out .now { text-decoration: line-through; color: var(--muted); }
.change.is-out .was { text-decoration: none; color: var(--ink-2); }
.change .was { font-size: 12px; color: var(--muted); text-decoration: line-through; margin-bottom: 6px; }
.change .now { font-size: 13px; color: var(--ink); line-height: 1.55; }
.change-foot { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.change-foot .why { font-size: 11.5px; color: var(--muted); line-height: 1.45; }
.change-foot form { margin-left: auto; }

/* A rewrite shown inside the answer that proposed it: the line it replaces,
   the line it proposes, and the button that applies it. Narrower than the
   review list's cards because the chat column is. */
.offers { margin-top: 10px; display: flex; flex-direction: column; gap: 9px; }
.offer { padding: 11px 13px; border-radius: 12px; background: var(--surface); }
.offer .was { font-size: 11.5px; margin-bottom: 8px; }
.offer .now { font-size: 12.5px; }
.offer-label {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted);
  margin-bottom: 3px;
}
/* An offer waiting to be accepted is the live thing on the card, so it is the
   one that stands out. Once it is on the resume it stops asking to be read. */
.offer { border: 1px solid var(--accent); background: var(--accent-soft); }
.offer .now { text-decoration: none; color: var(--ink); }
.offer.is-taken { border-color: var(--line); background: var(--surface-2); }
.offer.is-taken .offer-label { color: var(--ok); }
.offer .change-foot { margin-top: 9px; }
/* What taking this suggestion costs the page. Stated plainly: a line coming
   off is the user's to weigh, and it used to happen silently. */
.offer-cost {
  margin-top: 9px;
  padding: 8px 10px;
  border-radius: 9px;
  background: var(--surface-sunk);
  font-size: 11px;
  line-height: 1.45;
  color: var(--ink-2);
}
.offer-cost b { display: block; font-weight: 600; margin-bottom: 4px; color: var(--warn); }
.offer-cost ul { margin: 0; padding-left: 15px; }
.offer-cost li { margin-bottom: 2px; }

.offer-warn {
  margin-top: 8px;
  font-size: 11px;
  line-height: 1.45;
  color: var(--danger);
}

.kept-out {
  display: flex; align-items: baseline; gap: 10px;
  padding: 8px 0; border-bottom: 1px solid var(--line);
}
.kept-out:last-child { border-bottom: 0; }
.kept-out b { font-size: 12.5px; font-weight: 600; }
.kept-out span { margin-left: auto; font-size: 11px; color: var(--muted); text-align: right; }

/* The route to the target score, stated before the gaps it is made of. */
.route {
  padding: 11px 13px;
  margin-bottom: 12px;
  border-radius: 12px;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-2);
}
.route b { display: block; font-size: 13px; color: var(--ink); margin-bottom: 2px; }

/* A gap you can close: tick it and it joins your profile. */
.kept-out.claimable { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
.kept-out.claimable:hover { background: var(--surface-sunk); border-radius: 8px; }
.kept-out.claimable input { margin: 3px 0 0; flex: none; accent-color: var(--accent); }
.kept-out.claimable span { margin-left: 0; text-align: left; display: block; }
.kept-out.claimable b { display: block; }
.kept-out.claimable em {
  display: block; font-style: normal; font-size: 11px; color: var(--muted); line-height: 1.45;
}
.match-notes li { font-size: 11.5px; color: var(--muted); margin-bottom: 4px; line-height: 1.5; }

.kv { display: flex; flex-direction: column; gap: 12px; }
.kv-row { display: flex; gap: 12px; font-size: 13.5px; }
.kv-row dt { color: var(--muted); flex: 0 0 92px; }
.kv-row dd { margin: 0; font-weight: 500; }

/* ==========================================================================
   Auth pages — split screen, no app shell
   ========================================================================== */

.auth { display: flex; min-height: 100vh; }

.auth-aside {
  flex: 0 0 44%;
  background: var(--contrast);
  color: var(--contrast-ink);
  padding: 40px;
  display: flex;
  flex-direction: column;
  gap: 30px;
}
.auth-aside .brand-name { color: var(--contrast-ink); }
.auth-aside .brand-sub  { color: rgba(255,255,255,.5); }

.auth-pitch { margin-top: auto; }
.auth-pitch h2 {
  font-size: 33px;
  letter-spacing: -0.035em;
  line-height: 1.12;
  margin-bottom: 14px;
  max-width: 15ch;
}
.auth-pitch .lime { color: var(--accent); }
.auth { background: var(--bg); }
.auth-pitch p { color: rgba(255,255,255,.62); font-size: 14.5px; max-width: 42ch; margin: 0; }

.auth-points { display: flex; flex-direction: column; gap: 12px; margin-top: 26px; }
.auth-point { display: flex; gap: 11px; align-items: flex-start; font-size: 13.5px; color: rgba(255,255,255,.78); }
.auth-point svg { width: 17px; height: 17px; flex: none; margin-top: 1px; stroke: var(--accent); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

.auth-main { flex: 1; display: grid; place-items: center; padding: 40px 24px; }
.auth-card { width: 100%; max-width: 384px; }
.auth-card h1 { font-size: 26px; margin-bottom: 6px; }
.auth-card .lede { color: var(--muted); font-size: 14px; margin: 0 0 26px; }
.auth-form { display: flex; flex-direction: column; gap: 15px; }
.auth-alt { margin-top: 22px; font-size: 13.5px; color: var(--muted); text-align: center; }
.auth-alt a { font-weight: 550; color: var(--ink); }

.auth-foot { font-size: 11.5px; color: var(--muted); text-align: center; margin-top: 26px; line-height: 1.5; }

/* ==========================================================================
   Utilities & responsive
   ========================================================================== */

.muted     { color: var(--muted); }
.nowrap    { white-space: nowrap; }
.stack     { display: flex; flex-direction: column; gap: 16px; }
.row       { display: flex; align-items: center; gap: 10px; }
.push      { margin-left: auto; }
.mt-0      { margin-top: 0; }
.tabular   { font-variant-numeric: tabular-nums; }
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 1180px) {
  .grid-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-split { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .searchbar { grid-template-columns: 1fr 1fr; }
  .searchbar .btn { grid-column: 1 / -1; }
  .auth-aside { display: none; }
}

@media (max-width: 720px) {
  .app { flex-direction: column; }
  .sidebar {
    width: 100%; flex: none; height: auto; position: static;
    border-right: none; border-bottom: 1px solid var(--line);
    flex-direction: row; align-items: center; gap: 14px;
    padding: 12px 16px; overflow-x: auto;
  }
  .nav { flex-direction: row; }
  .nav-label, .sidebar-foot { display: none; }
  .content, .topbar { padding-left: 16px; padding-right: 16px; }
  .grid-stats { grid-template-columns: 1fr; }
  .user-chip-name, .user-chip-email { display: none; }
  .user-chip { padding: 4px; border-color: transparent; }
}

/* ==========================================================================
   Theme toggle
   ========================================================================== */

.theme-toggle { position: relative; }
/* Only the icon for the theme you would switch *to* is shown. */
.theme-toggle .icon-moon { display: block; }
.theme-toggle .icon-sun  { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun  { display: block; }

@media (max-width: 720px) {
  .app { margin: 0; border-radius: 0; min-height: 100vh; }
}


/* ==========================================================================
   Profile — one page: the record, the resume that produced it, the targeting

   Left column reads; right rail acts. Editing is per card - a card swaps its
   body for a form - so there is no page-wide form to scroll past.

   Tighter than the rest of the app on purpose, and scoped to .profile-page
   so the dashboard and the job tables keep the proportions they were drawn
   to: this page is a record to be read, and 26px radii with 24px padding put
   four words on a line.
   ========================================================================== */

textarea {
  min-height: 74px;
  resize: vertical;
  line-height: 1.5;
}

.profile-page { --pad: 20px; --radius: 20px; --gap: 14px; }
.profile-page .card { padding: var(--pad); border-radius: var(--radius); }
.profile-page .field label { font-size: 11.5px; }
.profile-page input[type="text"],
.profile-page select,
.profile-page textarea {
  padding: 8px 11px;
  font-size: 13px;
  border-radius: 9px;
}

/* Identity ---------------------------------------------------------------- */

.identity {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-bottom: var(--gap);
}
.identity-avatar {
  flex: none;
  width: 56px; height: 56px;
  border-radius: 18px;
  background: var(--accent);
  color: var(--accent-ink);
  display: grid; place-items: center;
  font-size: 18px; font-weight: 640;
}
.identity-id { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.identity-name { font-size: 20px; font-weight: 620; letter-spacing: -.02em; }
.identity-sub { font-size: 13px; color: var(--ink-2); }
.identity-edit { margin-left: auto; align-self: flex-start; }
/* In edit mode the card holds a form, not a row. */
.identity:has(form) { display: block; }

/* The page ---------------------------------------------------------------- */

.profile-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--gap);
  align-items: start;
}
.profile-main, .profile-rail { display: flex; flex-direction: column; gap: var(--gap); min-width: 0; }
.profile-page .card + .card { margin-top: 0; }

.panel-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--gap);
  align-items: start;
}

.panel-head {
  display: flex; align-items: center; gap: 9px;
  margin-bottom: 14px;
}
.panel-head h2 { font-size: 14px; font-weight: 600; letter-spacing: -.005em; }
.panel-head .count { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.panel-head .btn { margin-left: auto; }

/* Tech stack -------------------------------------------------------------- */

.stack-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 14px 20px;
}
.stack-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--muted);
  margin-bottom: 7px;
}
.cloud { display: flex; flex-wrap: wrap; gap: 6px; }
.cloud .chip {
  background: var(--surface-sunk);
  border: 1px solid var(--line);
  font-size: 11.5px;
  padding: 3px 10px;
}
.cloud a.chip { text-decoration: none; }
.cloud a.chip:hover { border-color: var(--line-strong); }
.cloud .chip.is-key { background: var(--accent-soft); border-color: var(--accent); }

/* Experience -------------------------------------------------------------- */

.timeline { position: relative; padding-left: 20px; margin-left: 4px; }
.timeline::before {
  content: "";
  position: absolute;
  left: 0; top: 6px; bottom: 6px;
  width: 1.5px;
  background: var(--line);
}
.tl-item { position: relative; padding-bottom: 16px; }
.tl-item:last-child { padding-bottom: 0; }
.tl-item::before {
  content: "";
  position: absolute;
  left: -24px; top: 4px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--line-strong);
}
.tl-item.is-current::before { background: var(--accent); border-color: var(--accent); }
.tl-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.tl-head h3 { font-size: 13.5px; font-weight: 600; }
.tl-where { font-size: 12.5px; color: var(--ink-2); }
.tl-when {
  margin-left: auto;
  font-size: 11.5px; color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.tl-item p { font-size: 12.5px; color: var(--ink-2); margin: 6px 0 0; }
.tl-item ul { margin: 7px 0 0; padding-left: 16px; }
.tl-item li { font-size: 12.5px; color: var(--ink-2); margin-bottom: 4px; line-height: 1.5; }
.tl-item .cloud { margin-top: 8px; }

/* Small records ----------------------------------------------------------- */

.records { display: grid; gap: 8px; }
.records.two { grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); }
.record {
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 12px 14px;
  background: var(--surface-2);
}
.record h3 { font-size: 12.5px; font-weight: 600; margin-bottom: 2px; line-height: 1.35; }
.record p { font-size: 11.5px; color: var(--muted); margin: 0; line-height: 1.45; }
.record .cloud { margin-top: 8px; }
.record a { font-size: 11.5px; }

/* The rail ---------------------------------------------------------------- */

.file-row {
  display: flex; align-items: center; gap: 11px;
  padding: 12px 13px;
  border: 1px solid var(--line);
  border-radius: 15px;
  background: var(--surface-2);
}
.file-mark {
  flex: none;
  width: 34px; height: 34px;
  border-radius: 11px;
  display: grid; place-items: center;
  background: var(--accent-soft);
}
.file-mark svg { width: 17px; height: 17px; stroke: var(--ink); fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.file-name { display: block; font-size: 12.5px; font-weight: 600; word-break: break-all; }
.file-sub { display: block; font-size: 11px; color: var(--muted); }

/* The extracted text, folded away: it is long, and it is only wanted when a
   parse looks wrong. */
.text-peek > summary { list-style: none; cursor: pointer; }
.text-peek > summary::-webkit-details-marker { display: none; }
.text-peek pre {
  margin: 11px 0 0;
  padding: 12px 13px;
  max-height: 260px;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface-2);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  line-height: 1.65;
  color: var(--ink-2);
  white-space: pre-wrap;
  word-break: break-word;
}

.tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-top: 13px;
}
.tiles > div {
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 11px 13px;
  background: var(--surface-2);
}
.tiles b { display: block; font-size: 17px; font-weight: 640; font-variant-numeric: tabular-nums; }
.tiles span { font-size: 11px; color: var(--muted); }

.drop {
  border: 1.5px dashed var(--line-strong);
  border-radius: 15px;
  padding: 16px;
  text-align: center;
  background: var(--surface-2);
  transition: border-color .15s ease, background .15s ease;
}
.drop:hover { border-color: var(--accent); background: var(--accent-soft); }
.drop input[type="file"] { width: 100%; font-size: 11.5px; color: var(--ink-2); }
.drop input[type="file"]::file-selector-button {
  font: inherit; font-size: 11.5px; font-weight: 550;
  margin-right: 9px;
  padding: 6px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
}
.drop input[type="file"]::file-selector-button:hover { background: var(--surface-sunk); }

/* Review bar and the edit forms ------------------------------------------- */

.review-bar {
  display: flex; align-items: center; gap: 12px;
  padding: 13px 18px;
  margin-bottom: var(--gap);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  background: var(--accent-soft);
  font-size: 13px;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 11px 14px;
}
.form-grid.two { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.form-grid .span-all { grid-column: 1 / -1; }

.edit-row + .edit-row,
.edit-group + .edit-group {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.edit-group > h3 {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--muted);
  margin-bottom: 11px;
}
.edit-row-note { margin: 7px 0 0; }
.edit-actions {
  display: flex; align-items: center; gap: 9px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}

.steps { margin: 0; padding-left: 18px; }
.steps li { font-size: 13px; color: var(--ink-2); margin-bottom: 7px; line-height: 1.55; }
.steps code, .field-hint code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--surface-sunk);
}

@media (max-width: 1080px) {
  .profile-grid { grid-template-columns: 1fr; }
}
@media (max-width: 620px) {
  .form-grid, .form-grid.two { grid-template-columns: 1fr; }
  .identity { flex-wrap: wrap; }
}


/* ==========================================================================
   Job sources — which portals a search asks, and how each one did

   All of it sits *under* the search rather than in it: which portals to ask
   is a setting changed now and then, and eleven tick boxes above the results
   would be the search page's plumbing made into the search page.
   ========================================================================== */

.portals { margin-top: 14px; border-top: 1px solid var(--line); }
/* The form is a plain block wrapping both rows; the grid is the top row. */
.searchbar + .portals { margin-top: 16px; }

.portals summary {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  padding: 11px 2px 0;
  list-style: none;
  font-size: 12px;
  color: var(--muted);
}
.portals summary::-webkit-details-marker { display: none; }
.portals-at { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portals-toggle {
  margin-left: auto;
  flex: none;
  font-weight: 600;
  color: var(--ink-2);
}
.portals summary:hover .portals-toggle { color: var(--ink); }
.portals[open] .portals-toggle::after { content: " ▴"; }
.portals:not([open]) .portals-toggle::after { content: " ▾"; }

.portal-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin: 12px 0 0;
}
/* Pills rather than cards: eleven boxes on a grid read as a form to fill in,
   and this is a row of switches. */
.portal {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 11px 6px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  user-select: none;
}
.portal:hover { border-color: var(--line-strong); }
.portal input { margin: 0; flex: none; accent-color: var(--accent); }
.portal:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.portal-name { font-weight: 500; }
/* Shown, never hidden: knowing a portal exists and what it wants is the only
   way anyone turns it on. */
.portal.is-off { opacity: .55; cursor: default; background: var(--surface-sunk); }
.portal-why { font-size: 10px; color: var(--muted); }

.portal-hint {
  margin: 10px 0 2px;
  font-size: 11px;
  line-height: 1.5;
  color: var(--muted);
}
.portal-hint code {
  font-size: 10.5px;
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--surface-sunk);
}

/* What each portal returned, as one line above the table. */
.report {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
  margin: -4px 0 16px;
  font-size: 11.5px;
  color: var(--muted);
}
.report-hit b { color: var(--ink-2); font-weight: 600; margin-right: 5px; }
.report-hit.is-none { font-style: italic; }
/* The portals that did nothing: one phrase, with the detail on hover. A chip
   each for five that sat out is five chips saying nothing happened. */
.report-note { color: var(--muted); cursor: help; border-bottom: 1px dotted var(--line-strong); }
.report-note.is-bad { color: var(--warn); border-bottom-color: currentColor; }

/* Which portal a result came from — only rendered when more than one did.
   Inline with the title and unbreakable, so it never becomes a second line
   under a title that already wrapped. */
.from {
  display: inline-block;
  font-size: 9.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--muted);
  background: var(--surface-sunk);
  padding: 1px 6px;
  border-radius: 5px;
  margin-left: 8px;
  white-space: nowrap;
  vertical-align: 1px;
}

/* Paging forward through results no portal will give a total for. */
.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.pager-at { font-size: 12px; color: var(--muted); }

@media (max-width: 900px) {
  .portals summary { flex-wrap: wrap; }
}

/* An application's history: what happened, oldest first. A list rather than
   a table - four events with two lines each is a story, not data. */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li {
  padding: 9px 0 9px 14px; border-left: 2px solid var(--line);
  position: relative; font-size: 13px;
}
.timeline li::before {
  content: ""; position: absolute; left: -5px; top: 15px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--line-strong);
}
.timeline li:last-child::before { background: var(--accent, var(--line-strong)); }
.timeline li b { margin-right: 6px; }
/* The same list inside a table cell, where the row already has the padding. */
.timeline-tight li { padding: 3px 0 3px 12px; font-size: 12.5px; }
.timeline-tight li::before { top: 9px; width: 6px; height: 6px; left: -4px; }

/* ==========================================================================
   Recorded test questions — a numbered read-back of one sitting
   ========================================================================== */

/* Numbered by the page rather than by an <ol>: `position` is what the test
   itself said ("Question 4 of 20"), and renumbering them 1..n here would
   quietly disagree with the test the questions came from. */
.question { padding: 18px 0; border-bottom: 1px solid var(--line); }
.question:first-child { padding-top: 4px; }
.question:last-child { border-bottom: 0; padding-bottom: 4px; }

.question-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.question-no {
  font-size: 11px; font-weight: 600; color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.question-head .chip { margin-left: auto; }

/* pre-wrap, because a coding question's examples and constraints are laid
   out in lines and collapsing them loses the question. */
.question-prompt {
  font-size: 14px; line-height: 1.65; color: var(--ink);
  white-space: pre-wrap; overflow-wrap: anywhere;
}

/* The choices, as choices - not as an answer. Nothing here says which one
   was right: the page recorded what was asked, not a key it never saw. */
.question-options { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 7px; }
.question-options li {
  display: flex; gap: 9px; align-items: flex-start;
  padding: 8px 11px; border: 1px solid var(--line); border-radius: 9px;
  font-size: 13px; color: var(--ink-2); background: var(--surface-sunk);
}
.question-options li b {
  flex: none; font-size: 11.5px; color: var(--muted); font-weight: 600; line-height: 1.5;
}

/* The option an answer picked, marked in the list rather than only written
   out under it. Reading a question back means reading the options, and
   "which one was it" answered six lines further down is answered in the
   wrong place. */
.question-options li.is-answer {
  border-color: var(--accent, var(--line-strong));
  background: var(--surface);
  color: var(--ink);
}
.question-options li.is-answer b { color: var(--ink); }
.option-mark {
  margin-left: auto; flex: none; align-self: center;
  font-size: 10.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted);
}

/* ==========================================================================
   The worked answer under a question
   ========================================================================== */

/* Set in from the question by a rule down its left edge rather than boxed:
   it belongs to the question above it, and a card would read as a second
   thing on the page rather than as this question's answer. */
.answer {
  margin: 14px 0 2px; padding: 12px 0 2px 14px;
  border-left: 2px solid var(--accent, var(--line-strong));
}
/* Written against a reading of the question that has since changed. Still
   shown - a mostly right answer to a partial question is worth having - but
   never as though it answered what is on the page now. */
.answer.is-stale { border-left-style: dashed; border-left-color: var(--line-strong); }

.answer-head { display: flex; align-items: center; gap: 9px; margin-bottom: 9px; }
.answer-tag {
  font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted);
}
.answer-note { margin: 0 0 9px; font-size: 12.5px; color: var(--muted); }

/* The chosen option, written out as well as marked in the list above: the
   letter alone means scrolling back up to find out what it was. */
.answer-choice {
  display: flex; gap: 9px; align-items: baseline; margin: 0 0 9px;
  font-size: 13.5px; color: var(--ink);
}
.answer-choice b { flex: none; font-size: 11.5px; color: var(--muted); }

.answer-text {
  font-size: 13.5px; line-height: 1.65; color: var(--ink);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
/* Code that has been re-wrapped is not an answer any more, so this scrolls
   rather than wraps. */
.answer-code {
  margin: 0; padding: 11px 13px; max-height: 460px; overflow: auto;
  background: var(--surface-sunk); border-radius: 9px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; line-height: 1.6; color: var(--ink);
  white-space: pre;
}
.answer-why {
  margin-top: 10px; font-size: 12.5px; line-height: 1.6; color: var(--ink-2);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.answer-why b {
  display: block; margin-bottom: 3px;
  font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
}
.answer-foot {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px;
}
.answer-foot .muted { margin-right: auto; }

/* The offer, on a question with no answer yet. Quiet: the question is what
   the page is for, and a row of buttons down the page would compete with it. */
.answer-ask { margin-top: 12px; }

/* A test being read right now. Pulsed rather than merely coloured: the whole
   point of the chip is that it means "still happening", and a static chip
   reads as one more status. */
.chip.live::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; animation: live-pulse 1.6s ease-in-out infinite;
}
@keyframes live-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .25 } }
@media (prefers-reduced-motion: reduce) {
  .chip.live::before { animation: none; }
}

/* The raw text of a recorded screen. Shown because "nothing was found" and
   "what was read was a navigation bar" are indistinguishable from a count,
   and only one of them is worth asking a model about again. */
.screen { border-top: 1px solid var(--line); padding: 9px 0; }
.screen summary {
  cursor: pointer; font-size: 12px; color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.screen summary:hover { color: var(--ink-2); }
.screen-text {
  margin: 9px 0 2px; padding: 10px 12px; max-height: 320px; overflow: auto;
  background: var(--surface-sunk); border-radius: 9px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px; line-height: 1.55; color: var(--ink-2);
  white-space: pre-wrap; overflow-wrap: anywhere;
}

/* The rest of a sitting, folded under the screen being shown. Present but
   not in the way: the question in front of you is what you came for, and
   the twelve before it are what you come back for. */
.earlier { margin-top: 18px; border-top: 1px solid var(--line); padding-top: 12px; }
.earlier summary {
  cursor: pointer; font-size: 12.5px; color: var(--muted); font-weight: 550;
}
.earlier summary:hover { color: var(--ink-2); }
.earlier[open] summary { margin-bottom: 6px; }
