/*
 * Job Radar — hand-authored CSS. No framework, no component library (§2).
 *
 * One token layer, then plain selectors using modern CSS: custom properties,
 * nesting, color-mix, container queries. The visual system has one job beyond
 * legibility: make a derived value look unmistakably different from a
 * source-asserted one (§5). That is the `.derived` treatment below, and it is
 * load-bearing rather than decorative.
 */

/* ---------------------------------------------------------------- tokens -- */

:root {
  color-scheme: light dark;

  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --step--1: clamp(0.78rem, 0.76rem + 0.1vw, 0.83rem);
  --step-0: clamp(0.94rem, 0.92rem + 0.12vw, 1rem);
  --step-1: clamp(1.1rem, 1.05rem + 0.25vw, 1.25rem);
  --step-2: clamp(1.35rem, 1.25rem + 0.5vw, 1.65rem);
  --step-3: clamp(1.7rem, 1.5rem + 0.9vw, 2.2rem);

  --space-3xs: 0.125rem;
  --space-2xs: 0.25rem;
  --space-xs: 0.5rem;
  --space-s: 0.75rem;
  --space-m: 1rem;
  --space-l: 1.5rem;
  --space-xl: 2.25rem;
  --space-2xl: 3.5rem;

  --radius: 6px;
  --radius-s: 4px;
  --border-width: 1px;

  --measure: 68ch;
  --page-max: 78rem;

  /* Light theme. Dark overrides live in the media query below. */
  --bg: hsl(40 20% 98%);
  --bg-raised: hsl(0 0% 100%);
  --bg-sunken: hsl(40 14% 94%);
  --ink: hsl(220 20% 14%);
  --ink-muted: hsl(220 10% 42%);
  --ink-faint: hsl(220 8% 56%);
  --rule: hsl(220 14% 87%);
  --rule-strong: hsl(220 14% 76%);

  --accent: hsl(214 78% 42%);
  --accent-ink: hsl(214 82% 32%);
  --accent-bg: hsl(214 78% 96%);

  /* Derived / guessed values. Deliberately a different hue from everything
     that carries information the source actually asserted. */
  --derived: hsl(276 34% 44%);
  --derived-bg: hsl(276 40% 96%);

  --ok: hsl(150 52% 30%);
  --ok-bg: hsl(150 45% 95%);
  --warn: hsl(35 78% 34%);
  --warn-bg: hsl(40 85% 94%);
  --danger: hsl(2 62% 44%);
  --danger-bg: hsl(2 70% 96%);

  --shadow: 0 1px 2px hsl(220 20% 14% / 0.05), 0 2px 8px hsl(220 20% 14% / 0.04);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: hsl(222 18% 11%);
    --bg-raised: hsl(222 16% 15%);
    --bg-sunken: hsl(222 20% 8%);
    --ink: hsl(220 16% 92%);
    --ink-muted: hsl(220 10% 68%);
    --ink-faint: hsl(220 8% 54%);
    --rule: hsl(222 12% 25%);
    --rule-strong: hsl(222 10% 36%);

    --accent: hsl(210 82% 68%);
    --accent-ink: hsl(210 84% 76%);
    --accent-bg: hsl(214 40% 20%);

    --derived: hsl(276 62% 76%);
    --derived-bg: hsl(276 28% 22%);

    --ok: hsl(150 48% 64%);
    --ok-bg: hsl(150 28% 18%);
    --warn: hsl(40 80% 66%);
    --warn-bg: hsl(38 32% 20%);
    --danger: hsl(2 76% 70%);
    --danger-bg: hsl(2 32% 22%);

    --shadow: 0 1px 2px hsl(0 0% 0% / 0.3), 0 2px 8px hsl(0 0% 0% / 0.25);
  }
}

/* ---------------------------------------------------------------- base ---- */

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

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

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.55;
  color: var(--ink);
  background: var(--bg);
  text-underline-offset: 0.15em;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  line-height: 1.2;
  font-weight: 620;
  text-wrap: balance;
}

h1 {
  font-size: var(--step-3);
}
h2 {
  font-size: var(--step-2);
}
h3 {
  font-size: var(--step-1);
}
h4 {
  font-size: var(--step-0);
}

p {
  margin: 0;
}

a {
  color: var(--accent);

  &:hover {
    color: var(--accent-ink);
  }

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

code,
kbd,
pre {
  font-family: var(--font-mono);
  font-size: 0.92em;
}

/* -------------------------------------------------------------- layout ---- */

.masthead {
  border-bottom: var(--border-width) solid var(--rule);
  background: var(--bg-raised);

  & .masthead-inner {
    max-width: var(--page-max);
    margin-inline: auto;
    padding: var(--space-s) var(--space-m);
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-m);
  }

  & .wordmark {
    font-size: var(--step-1);
    font-weight: 680;
    letter-spacing: -0.015em;
    color: var(--ink);
    text-decoration: none;
  }

  & nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-m);
    margin-inline-end: auto;
  }

  & nav a {
    text-decoration: none;
    color: var(--ink-muted);
    font-size: var(--step--1);
    padding-block: var(--space-2xs);
    border-bottom: 2px solid transparent;

    &:hover {
      color: var(--ink);
    }

    &[aria-current="page"] {
      color: var(--ink);
      border-bottom-color: var(--accent);
    }
  }
}

main {
  max-width: var(--page-max);
  margin-inline: auto;
  padding: var(--space-l) var(--space-m) var(--space-2xl);
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
}

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: var(--space-m);

  & .lede {
    color: var(--ink-muted);
    max-width: var(--measure);
    margin-top: var(--space-2xs);
  }
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: center;
}

/* --------------------------------------------------------------- panels --- */

.panel {
  background: var(--bg-raised);
  border: var(--border-width) solid var(--rule);
  border-radius: var(--radius);
  padding: var(--space-m);
  box-shadow: var(--shadow);

  & > header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-s);
    margin-bottom: var(--space-s);
  }

  & > header h2,
  & > header h3 {
    font-size: var(--step-1);
  }
}

.panel-note {
  color: var(--ink-muted);
  font-size: var(--step--1);
  max-width: var(--measure);
}

.grid {
  display: grid;
  gap: var(--space-m);
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
}

.metrics {
  display: grid;
  gap: var(--space-s);
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));

  & .metric {
    background: var(--bg-sunken);
    border-radius: var(--radius-s);
    padding: var(--space-s);
  }

  & .metric-value {
    font-size: var(--step-2);
    font-weight: 640;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
  }

  & .metric-label {
    font-size: var(--step--1);
    color: var(--ink-muted);
  }
}

/* --------------------------------------------------------------- tables --- */

.table-scroll {
  overflow-x: auto;
  margin-inline: calc(var(--space-m) * -1);
  padding-inline: var(--space-m);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step--1);

  & th,
  & td {
    text-align: left;
    padding: var(--space-xs) var(--space-s);
    border-bottom: var(--border-width) solid var(--rule);
    vertical-align: top;
  }

  & th {
    font-weight: 620;
    color: var(--ink-muted);
    white-space: nowrap;
    border-bottom-color: var(--rule-strong);
  }

  & tbody tr:last-child td {
    border-bottom: none;
  }

  & tbody tr:hover {
    background: var(--bg-sunken);
  }

  & td.numeric,
  & th.numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
  }
}

/* -------------------------------------------------- asserted vs derived --- */

/*
 * The distinction the whole data model turns on (§5). A derived value never
 * looks like a fact the source stated: different hue, dotted underline, and a
 * marker that survives being read aloud by a screen reader.
 */
.derived {
  color: var(--derived);
  border-bottom: 1px dotted currentColor;
  cursor: help;

  &::after {
    content: "·derived";
    font-size: 0.75em;
    vertical-align: super;
    opacity: 0.75;
    margin-inline-start: 0.15em;
    border-bottom: none;
  }
}

.asserted {
  color: var(--ink);
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  font-size: var(--step--1);
  color: var(--ink-muted);
}

.provenance {
  font-size: var(--step--1);
  color: var(--ink-faint);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-m);

  & dt {
    font-weight: 620;
    display: inline;
    margin-inline-end: var(--space-2xs);
  }

  & dd {
    display: inline;
    margin: 0;
  }

  & > div {
    display: flex;
    gap: var(--space-2xs);
  }
}

/* ---------------------------------------------------------------- chips --- */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: 0.1em 0.55em;
  border-radius: 999px;
  font-size: var(--step--1);
  font-weight: 560;
  line-height: 1.5;
  white-space: nowrap;
  background: var(--bg-sunken);
  color: var(--ink-muted);

  &.ok {
    background: var(--ok-bg);
    color: var(--ok);
  }
  &.warn {
    background: var(--warn-bg);
    color: var(--warn);
  }
  &.danger {
    background: var(--danger-bg);
    color: var(--danger);
  }
  &.accent {
    background: var(--accent-bg);
    color: var(--accent-ink);
  }
  &.guess {
    background: var(--derived-bg);
    color: var(--derived);
    border: 1px dotted color-mix(in oklab, var(--derived) 55%, transparent);
  }
  &.muted {
    opacity: 0.75;
  }
}

.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* --------------------------------------------------------------- forms ---- */

form.stack {
  gap: var(--space-s);
}

label {
  display: block;
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--ink-muted);
  margin-bottom: var(--space-3xs);
}

.field-hint {
  font-size: var(--step--1);
  color: var(--ink-faint);
  font-weight: 400;
  margin-top: var(--space-3xs);
}

input[type="text"],
input[type="search"],
input[type="password"],
select,
textarea {
  width: 100%;
  font: inherit;
  font-size: var(--step-0);
  color: var(--ink);
  background: var(--bg);
  border: var(--border-width) solid var(--rule-strong);
  border-radius: var(--radius-s);
  padding: var(--space-xs) var(--space-s);

  &:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
  }
}

textarea {
  min-height: 5lh;
  resize: vertical;
  line-height: 1.5;
}

.field-row {
  display: grid;
  gap: var(--space-s);
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
  align-items: end;
}

.checkbox {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--step--1);
  color: var(--ink-muted);
  font-weight: 600;

  & input {
    inline-size: 1rem;
    block-size: 1rem;
    accent-color: var(--accent);
  }
}

button,
.button {
  font: inherit;
  font-size: var(--step--1);
  font-weight: 620;
  line-height: 1.4;
  padding: var(--space-xs) var(--space-m);
  border-radius: var(--radius-s);
  border: var(--border-width) solid var(--rule-strong);
  background: var(--bg-raised);
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);

  &:hover {
    background: var(--bg-sunken);
  }

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

  &.primary {
    background: var(--accent);
    border-color: var(--accent);
    color: hsl(0 0% 100%);

    &:hover {
      background: var(--accent-ink);
      border-color: var(--accent-ink);
    }
  }

  &.quiet {
    border-color: transparent;
    background: transparent;
    color: var(--ink-muted);
    padding-inline: var(--space-xs);

    &:hover {
      background: var(--bg-sunken);
      color: var(--ink);
    }
  }

  &.danger {
    color: var(--danger);
    border-color: color-mix(in oklab, var(--danger) 40%, transparent);

    &:hover {
      background: var(--danger-bg);
    }
  }
}

@media (prefers-color-scheme: dark) {
  button.primary,
  .button.primary {
    color: hsl(222 20% 10%);
  }
}

.inline-form {
  display: inline;
}

/* --------------------------------------------------------------- notes ---- */

.notice {
  border: var(--border-width) solid var(--rule);
  border-inline-start: 3px solid var(--ink-faint);
  border-radius: var(--radius-s);
  padding: var(--space-s) var(--space-m);
  font-size: var(--step--1);
  background: var(--bg-raised);

  &.error {
    border-inline-start-color: var(--danger);
    background: var(--danger-bg);
    color: var(--danger);
  }
  &.ok {
    border-inline-start-color: var(--ok);
    background: var(--ok-bg);
    color: var(--ok);
  }
  &.warn {
    border-inline-start-color: var(--warn);
    background: var(--warn-bg);
    color: var(--warn);
  }
}

.empty {
  color: var(--ink-muted);
  font-size: var(--step--1);
  padding: var(--space-m);
  text-align: center;
  background: var(--bg-sunken);
  border-radius: var(--radius-s);
}

/* ---------------------------------------------------------------- login --- */

.login-shell {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: var(--space-m);

  & .panel {
    width: min(24rem, 100%);
  }
}

/* -------------------------------------------------------------- posting --- */

.posting-body {
  max-width: var(--measure);
  white-space: pre-wrap;
  overflow-wrap: break-word;
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg-sunken);
  border-radius: var(--radius-s);
  padding: var(--space-m);
  max-height: 34rem;
  overflow-y: auto;
}

.posting-title {
  font-weight: 620;
  color: var(--ink);
  text-decoration: none;

  &:hover {
    text-decoration: underline;
  }
}

.meta-line {
  font-size: var(--step--1);
  color: var(--ink-muted);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-s);
  align-items: center;
}

.blind-spots {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-s);

  & li {
    display: grid;
    gap: var(--space-3xs);
    padding-inline-start: var(--space-s);
    border-inline-start: 2px solid var(--rule-strong);
  }

  & .blind-spot-name {
    font-weight: 620;
    font-size: var(--step--1);
  }
  & .blind-spot-reason {
    font-size: var(--step--1);
    color: var(--ink-muted);
    max-width: var(--measure);
  }
}

/*
 * A very small set of spacing utilities. These exist because the CSP forbids
 * inline style attributes as well as inline scripts, so one-off nudges have to
 * be named. Kept deliberately few — if this list grows, the component wants a
 * real class instead.
 */
.gap-above {
  margin-top: var(--space-m);
}
.gap-above-tight {
  margin-top: var(--space-3xs);
}
.chip-inline {
  margin-inline-start: 0.5em;
}
.constrain {
  max-width: 22rem;
}
.title-compact {
  font-size: var(--step-2);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.pagination {
  display: flex;
  gap: var(--space-s);
  align-items: center;
  justify-content: space-between;
  font-size: var(--step--1);
  color: var(--ink-muted);
}

/* ------------------------------------------------------- M3: matching ----- */

/* The profile editor: long-form markdown wants a writing surface, not a
   form field. */
textarea.editor {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  min-height: 16lh;
  line-height: 1.6;
  background: var(--bg-raised);
}

input[type="number"] {
  width: 100%;
  font: inherit;
  font-size: var(--step-0);
  color: var(--ink);
  background: var(--bg);
  border: var(--border-width) solid var(--rule-strong);
  border-radius: var(--radius-s);
  padding: var(--space-xs) var(--space-s);

  &:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
  }
}

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

.filter-row {
  align-items: center;
  margin-block-end: var(--space-m);

  & label {
    margin: 0;
  }

  & select {
    width: auto;
  }
}

/* Match cards. One per posting; the quote is the reasoning (§7). */
.match-card {
  padding-block: var(--space-m);

  & + .match-card {
    border-top: var(--border-width) solid var(--rule);
  }
}

.match-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: start;
  gap: var(--space-s);
}

.match-facets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  justify-content: end;
}

.match-quote {
  margin: var(--space-s) 0 var(--space-2xs);
  padding: var(--space-s) var(--space-m);
  border-inline-start: 3px solid var(--accent);
  background: var(--bg-sunken);
  border-radius: 0 var(--radius-s) var(--radius-s) 0;
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--ink-muted);
  white-space: pre-line;
  max-height: 14lh;
  overflow: hidden;

  &.gap {
    border-inline-start-color: var(--warn);
  }
}

/* The weak bucket collapses; no script needed. */
.panel details {
  & summary {
    cursor: pointer;
    list-style-position: outside;

    & h2 {
      display: inline;
      font-size: var(--step-1);
    }
  }

  &[open] summary {
    margin-block-end: var(--space-s);
  }
}

/* Tuning histogram: server-rendered bars, the one place raw floats live. */
.histogram {
  display: flex;
  align-items: end;
  gap: 2px;
  height: 11rem;
  padding: var(--space-s);
  background: var(--bg-sunken);
  border-radius: var(--radius-s);
}

.histogram-bar {
  flex: 1;
  height: 100%;
  display: flex;
  align-items: end;
}

.histogram-fill {
  width: 100%;
  min-height: 1px;
  border-radius: 2px 2px 0 0;
  background: var(--rule-strong);
}

.histogram-bar.strong .histogram-fill {
  background: var(--ok);
}

.histogram-bar.plausible .histogram-fill {
  background: var(--warn);
}

.histogram-bar.weak .histogram-fill {
  background: var(--rule-strong);
}

/* -------------------------------------------------------- M4: dossier ---- */

.fact-row {
  display: flex;
  justify-content: space-between;
  align-items: start;
  gap: var(--space-m);
  padding-block: var(--space-s);

  & + .fact-row {
    border-top: var(--border-width) solid var(--rule);
  }
}

/* A parent fact and its bullets. Grouping keeps a role and its bullets from
   being separated by the row rules. */
.fact-group + .fact-group {
  border-top: var(--border-width) solid var(--rule);
}

.fact-indent {
  margin-inline-start: var(--space-xl);
}

.fact-retired {
  opacity: 0.55;
}

.fact-main {
  flex: 1;
  min-width: 0;
}

.fact-text {
  margin-block: var(--space-3xs);
  line-height: 1.5;
}

.fact-actions {
  display: flex;
  gap: var(--space-2xs);
  align-items: start;
  flex-shrink: 0;
}

.fact-edit {
  & summary {
    cursor: pointer;
    list-style: none;
  }
}

.fact-edit-body {
  margin-block-start: var(--space-s);
  padding: var(--space-s);
  background: var(--bg-sunken);
  border-radius: var(--radius-s);
}

/* Rewritten wording next to its canonical fact: the original never hides. */
.rewrite-pair {
  display: grid;
  gap: var(--space-xs);
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
}

.rewrite-original {
  color: var(--ink-faint);
  text-decoration: line-through solid color-mix(in srgb, var(--ink-faint) 40%, transparent);
  text-decoration-thickness: 1px;
}

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

/* ------------------------------------------------------ M5: tailoring ----- */

/* A proposed rewrite awaiting review. The flagged treatment is deliberately
   loud: these are where invented specifics show up. */
.proposal {
  padding-block: var(--space-m);

  & + .proposal {
    border-top: var(--border-width) solid var(--rule);
  }
}

.proposal-flagged {
  border-inline-start: 3px solid var(--warn);
  padding-inline-start: var(--space-m);
  margin-inline-start: calc(-1 * var(--space-m));
}

/* Facts a cover-letter paragraph claims to rest on. */
.citation-list {
  list-style: none;
  padding: 0;
  margin: var(--space-2xs) 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);

  & li {
    font-size: var(--step--1);
    line-height: 1.5;
    color: var(--ink-muted);
    padding-inline-start: var(--space-s);
    border-inline-start: 2px solid var(--rule);
  }
}

/* ------------------------------------------------------- M6: pipeline ----- */

/* Fields laid out for copying into someone else's form. Read-only inputs
   rather than plain text so a click-and-select actually grabs the value. */
.copy-grid {
  display: grid;
  gap: var(--space-s);
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
}

.copy-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.copy-label {
  font-size: var(--step--1);
  color: var(--ink-faint);
  font-weight: 600;
}

.copy-value {
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

/* The one-time token reveal. Loud on purpose — it is never shown again. */
.token-reveal {
  font-size: var(--step-0);
  border-color: var(--warn);
  background: var(--warn-bg);
}

.timeline {
  list-style: none;
  padding: 0;
  margin: 0;

  & li {
    padding-block: var(--space-s);
    padding-inline-start: var(--space-m);
    border-inline-start: 2px solid var(--rule);
  }

  & li + li {
    border-top: var(--border-width) solid var(--rule);
  }
}

/* The passkey controls. Hidden in the markup and revealed by script, so the
   layout must not reserve space for something that may never appear. */
.passkey-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);

  & [hidden] {
    display: none;
  }

  & .notice {
    flex-basis: 100%;
    margin: 0;
  }

  & .field-hint {
    flex-basis: 100%;
  }
}

/* "Waiting for you" — the dashboard's first question. Urgent items are marked
   by a rule, not by colour alone. */
.waiting {
  list-style: none;
  padding: 0;
  margin: 0;

  & li {
    padding-block: var(--space-s);
    padding-inline-start: var(--space-m);
    border-inline-start: 2px solid var(--rule);
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
  }

  & li + li {
    border-top: var(--border-width) solid var(--rule);
  }

  & li.urgent {
    border-inline-start-color: var(--warn);
  }
}
