:root {
  --bg: #f6f7f9;
  --surface: #ffffff;
  --text: #1c2430;
  --muted: #6b7686;
  --border: #e3e7ee;
  --line: #eef1f6; /* hairline: dividers inside a surface, quieter than --border */
  --purple: #6a51c7;
  --accent: #ea4c89; /* dribbble pink */
  --accent-dark: #d13d78;
  --green: #1e9e6a;
  --amber: #b57f0f;
  --red: #c94040;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

a { color: inherit; }
.muted { color: var(--muted); font-weight: 400; }

/* ---- top bar ----
   The application shell, identical on every page. Two tiers:
   row 1 = brand, section tabs and the actions that change the feed;
   row 2 = the stat rail (live counts left, scraper health right). */
.topbar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 10;
}
.topbar-inner {
  max-width: 980px;
  margin: 0 auto;
  padding: 0 20px;
}
.topbar-row {
  display: flex;
  align-items: center;
  gap: 18px;
  height: 56px;
}
.nav-sep { width: 1px; height: 22px; background: var(--border); flex-shrink: 0; }

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--text);
  flex-shrink: 0;
}
.brand-mark {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border-radius: 9px;
  background: var(--accent);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.02em;
}
.brand-name { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; white-space: nowrap; }
.brand:hover .brand-name { color: var(--accent-dark); }

/* Tabs are full-height so the active underline sits on the header's own
   bottom edge rather than floating above it. */
.tabs {
  display: flex;
  align-items: stretch;
  gap: 4px;
  height: 56px;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 0 10px;
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.tab svg { flex-shrink: 0; }
.tab:hover { color: var(--text); border-bottom-color: var(--border); }
.tab.is-active { color: var(--text); border-bottom-color: var(--accent); }
.tab.is-active svg { color: var(--accent); }

.count-badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0 6px;
  color: var(--muted);
}
.count-badge.warn { background: #fdf6e7; border-color: #eedcae; color: var(--amber); }
/* count badges drop out at zero; the element stays so htmx can swap it back */
[hidden] { display: none !important; }

.topbar-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; }
.topbar-actions .btn { font-size: 13.5px; font-weight: 600; padding: 7px 12px; white-space: nowrap; }
.topbar-actions .btn.primary { padding: 8px 14px; box-shadow: 0 1px 2px rgba(209, 61, 120, 0.35); }
.classify-star { color: var(--purple); }
.btn.classify:hover { border-color: #d8d0f2; background: #faf9fe; color: var(--purple); }

/* Account menu: a disclosure, so it opens with no JS and closes on Escape. */
.usermenu { position: relative; }
.usermenu > summary {
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 5px;
  border-radius: 999px;
  padding: 2px 6px 2px 2px;
  list-style: none;
}
.usermenu > summary::-webkit-details-marker { display: none; }
.usermenu > summary svg { color: var(--muted); }
.usermenu > summary:hover, .usermenu[open] > summary { background: var(--bg); }
.usermenu .avatar { width: 28px; height: 28px; font-size: 12px; }
.usermenu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  width: 236px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 10px 28px rgba(28, 36, 48, 0.12);
  padding: 6px;
  z-index: 30;
}
.usermenu-id {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 10px 10px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 6px;
}
.usermenu-id .identity-mail { font-size: 13px; }
.usermenu-id .chip {
  align-self: flex-start;
  padding: 1px 8px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.usermenu-items { display: flex; flex-direction: column; gap: 2px; }
.usermenu-items form { margin: 0; }
.usermenu-items a, .usermenu-items button {
  width: 100%;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
}
.usermenu-items a svg { color: var(--muted); }
.usermenu-items a:hover, .usermenu-items button:hover { background: var(--bg); }
.usermenu-items .usermenu-danger { color: var(--red); }
.usermenu-items .usermenu-danger:hover { background: #fdecec; }

/* ---- stat rail (second tier of the top bar) ---- */
.topbar-row.statrail {
  height: auto;
  gap: 14px;
  flex-wrap: wrap;
  border-top: 1px solid var(--line);
  padding: 9px 0 10px;
}
.statgroup { display: flex; align-items: center; flex-wrap: wrap; }
.stat {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 0 16px;
  border-left: 1px solid var(--line);
  white-space: nowrap;
  text-decoration: none;
}
.statgroup > .stat:first-child { padding-left: 0; border-left: 0; }
.statgroup > .stat:last-child { padding-right: 0; }
.stat strong {
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.stat .num-new { color: var(--accent-dark); }
.stat .num-todo { color: var(--amber); }
.stat-label { font-size: 12px; color: var(--muted); }
.stat-link svg { align-self: center; color: #b6bfcc; }
.stat-link:hover .stat-label, .stat-link:hover svg { color: var(--accent-dark); }

.statmeta { display: flex; align-items: center; gap: 10px; margin-left: auto; flex-wrap: wrap; }
.scrape-note { font-size: 12px; color: var(--muted); white-space: nowrap; }

/* ---- page heading (sections that are not the board) ---- */
.pagehead {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0 2px 14px;
}
.pagehead h1 { font-size: 18px; margin: 0; }
.pagehead .muted { font-size: 13px; }
.backlink { font-size: 13.5px; font-weight: 600; color: var(--muted); text-decoration: none; }
.backlink:hover { color: var(--accent-dark); }

/* poll-health pill: dot + tinted background, colored by outcome */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: 999px;
  padding: 3px 11px;
  font-size: 12px;
  font-weight: 600;
  border: 1px solid var(--border);
  background: var(--bg);
  white-space: nowrap;
}
.pill::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}
.pill-muted { color: var(--muted); }
.pill.poll-ok { color: var(--green); background: #e7f6ef; border-color: #bfe6d4; }
.pill.poll-blocked, .pill.poll-error, .pill.poll-network_error {
  color: var(--red); background: #fdecec; border-color: #f3c2c2;
}
.pill.poll-not_modified { color: var(--muted); }
.pill.poll-robots_denied { color: var(--muted); background: #f3f3f3; }

/* The poll pill is a disclosure: summary holds the pill, the panel is swapped
   in by /status/sources on each open. It floats like .usermenu-panel rather
   than sitting in flow: .statmeta lives in the sticky .topbar, so up to three
   sources' worth of history would grow the rail and push the board down.
   Anchored right (not left) because .statmeta is pushed to the end of the rail
   by margin-left:auto — hanging the panel leftward from the pill's right edge
   is the direction with room. */
.poll-detail { position: relative; }
.poll-detail > summary {
  list-style: none;
  cursor: pointer;
}
.poll-detail > summary::-webkit-details-marker { display: none; }
.poll-sources {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  min-width: 260px;
  max-width: min(420px, calc(100vw - 24px));
  /* history scrolls inside the panel instead of growing it */
  max-height: 60vh;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 10px 28px rgba(28, 36, 48, 0.12);
  padding: 4px 12px;
  /* remote error strings arrive unbroken and must not widen the panel */
  overflow-wrap: anywhere;
  z-index: 30;
}
/* empty until the fetch lands — no bordered flash while it is in flight */
.poll-sources:empty { display: none; }
.poll-source { padding: .4rem 0; border-top: 1px solid var(--line); }
.poll-source:first-child { border-top: 0; }
.poll-source-head { display: flex; align-items: center; gap: .4rem; }
.poll-source-label { font-weight: 600; }
.poll-source-when, .poll-attempt-when { color: var(--muted); font-size: .85em; }
.poll-source-detail { margin: .2rem 0 0; font-size: .9em; }
.poll-attempts { list-style: none; margin: .3rem 0 0; padding: 0; }
.poll-attempt {
  display: flex; gap: .4rem; align-items: baseline;
  font-size: .82em; padding: .1rem 0;
}
/* The when/outcome pair is the column you scan down, so it keeps its width;
   only the detail absorbs the panel's overflow-wrap, or a long remote error
   squeezes its neighbours to one character per line. */
.poll-attempt-when, .poll-attempt-outcome { flex-shrink: 0; white-space: nowrap; }
.poll-attempt-detail { color: var(--muted); min-width: 0; }
/* History outcomes carry the same colour language as the pills, but the pill
   rules are all qualified on .pill (tinted background + dot), so these need
   their own. Scoped to .poll-attempt-outcome so they cannot bleed back. */
.poll-attempt-outcome { font-weight: 600; }
.poll-attempt-outcome.poll-ok { color: var(--green); }
.poll-attempt-outcome.poll-blocked,
.poll-attempt-outcome.poll-network_error,
.poll-attempt-outcome.poll-error { color: var(--red); }
.poll-attempt-outcome.poll-not_modified,
.poll-attempt-outcome.poll-robots_denied { color: var(--muted); }
.poll-source-list { list-style: none; margin: 0; padding: 0; }
.poll-empty { color: var(--muted); margin: .4rem 0 0; }

/* Narrow screens strip the header back one layer at a time, and the labels
   go to the accessibility tree rather than away — the icons stay named. */
@media (max-width: 900px) {
  /* the mark still identifies the app; the wordmark is what the tabs need */
  .brand-name, .nav-sep { display: none; }
  .topbar-row { gap: 12px; }
}
@media (max-width: 760px) {
  .btn-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .topbar-actions .btn, .topbar-actions .btn.primary { padding: 8px 10px; }
}
@media (max-width: 620px) {
  .tab-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .filter-sep { display: none; }
  /* Narrow enough that .statmeta wraps and the pill is no longer at the right
     edge, so hanging a 260px panel off it puts one side off-screen whichever
     edge it is anchored to. Dropping .poll-detail out of the positioned chain
     promotes the rail to containing block, so the panel spans the rail's width
     and still opens directly beneath it. */
  .topbar-row.statrail { position: relative; }
  .poll-detail { position: static; }
  .poll-sources {
    left: 0;
    right: 0;
    min-width: 0;
    max-width: none;
  }
}

.btn {
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 9px;
  padding: 7px 14px;
  font-size: 14px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.btn:hover { border-color: #d5dbe6; }
.btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}
.btn.primary:hover { background: var(--accent-dark); }
.btn:disabled { opacity: 0.6; cursor: wait; }

.spinner {
  width: 12px; height: 12px;
  border: 2px solid rgba(255,255,255,0.4);
  border-top-color: #fff;
  border-radius: 50%;
  display: none;
}
.htmx-request .spinner, .spinner.htmx-request { display: inline-block; animation: spin 0.7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- layout ---- */
main { max-width: 980px; margin: 0 auto; padding: 18px 20px 60px; }

/* ---- filters ----
   One panel rather than loose controls: the filter bar is a single object
   that owns the list below it. */
.filters {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 10px;
  margin-bottom: 12px;
}
.filters .search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 240px;
  min-width: 200px;
}
.filters .search > svg { position: absolute; left: 11px; color: #9aa4b2; pointer-events: none; }
.filters input, .filters select {
  border: 1px solid var(--border);
  background: #fbfcfd;
  border-radius: 9px;
  padding: 7px 9px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text);
}
.filters input[type="search"] { width: 100%; padding: 8px 12px 8px 34px; }
.filters input:focus, .filters select:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
  box-shadow: 0 0 0 3px rgba(234, 76, 137, 0.15);
}
/* sort is not a filter — it reorders what the filters already chose */
.filters .sort { background: var(--surface); font-weight: 600; }
.filter-sep { width: 1px; height: 22px; background: var(--line); }
.filters .check {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13.5px;
  font-weight: 500;
  white-space: nowrap;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--muted);
  border-radius: 999px;
  padding: 6px 12px;
  cursor: pointer;
}
.filters .check input { accent-color: var(--accent); margin: 0; }
.filters .check:has(input:checked) {
  border-color: #f6c6dc;
  background: #fdeef5;
  color: var(--accent-dark);
}

.count { margin: 4px 2px 10px; font-size: 13px; }
.resultbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin: 2px 2px 12px;
}
.resultbar .count { margin: 0; color: var(--muted); }
.resultbar .count strong { color: var(--text); font-variant-numeric: tabular-nums; }
.result-summary { font-size: 12px; color: #9aa4b2; }

/* ---- cards ---- */
.cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* minmax(0, …) stops one card's unbreakable string (long URLs in scraped
     descriptions) from inflating the shared track and forcing page-wide
     horizontal scroll */
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  min-width: 0;
  overflow-wrap: break-word;
}
.card.uiux { border-left: 3px solid var(--accent); }

/* wraps rather than squeezes: on a narrow card the title takes its own line
   and the score, budget and age keep their intrinsic widths */
.card-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.card-head h2 { font-size: 16px; margin: 0; flex: 1 1 240px; min-width: 0; }
.card-head h2 a { text-decoration: none; }
.card-head h2 a:hover { text-decoration: underline; color: var(--accent-dark); }

.platform {
  display: inline-flex;
  align-items: center;
  align-self: center;
  flex-shrink: 0;
}
.platform-dribbble { color: var(--accent); }
.platform-behance { color: #1769ff; }
.platform-unknown { color: var(--muted); font-size: 12px; }

.relevance {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 700;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 2px 7px;
  color: var(--muted);
  min-width: 30px;
  text-align: center;
}
.budget { font-weight: 700; color: var(--green); white-space: nowrap; }

/* age sits at the end of the card head, where the eye lands last; leads from
   the current day carry the accent so a scan finds them without reading */
.age {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  align-self: center;
  flex-shrink: 0;
  border-radius: 999px;
  padding: 3px 9px;
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--muted);
}
.age svg { flex-shrink: 0; }
.age.is-fresh {
  background: #fdeef5;
  border-color: #f6c6dc;
  color: var(--accent-dark);
  font-weight: 700;
}

.card-meta {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 8px;
  font-size: 13px;
}
.chip {
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 12px;
  font-weight: 600;
  background: var(--bg);
  border: 1px solid var(--border);
}
.chip.category { color: var(--text); }
.chip.kind-brief { background: #f0edfb; border-color: #d8d0f2; color: #6a51c7; }
.chip.kind-job   { background: #e8f4f0; border-color: #c2e2d6; color: var(--green); }
.company { font-weight: 600; }
.chip.uiux-chip { background: #fdeef5; border-color: #f6c6dc; color: var(--accent-dark); }
.trust-returning { background: #e7f6ef; border-color: #bfe6d4; color: var(--green); }
.trust-verified  { background: #eaf3fd; border-color: #c5dcf5; color: #2f6db5; }
.trust-promising { background: #fdf6e7; border-color: #eedcae; color: var(--amber); }
.trust-unverified { color: var(--muted); }
.meta-item { color: var(--muted); }

.desc { margin: 10px 0 0; font-size: 14px; color: #3c4656; }
details.desc summary { cursor: pointer; list-style: none; }
details.desc summary::after { content: " show more"; color: var(--accent-dark); font-size: 13px; }
details.desc[open] summary { display: none; }
details.desc p { margin: 0; white-space: pre-line; }

.empty {
  text-align: center;
  padding: 60px 0;
  color: var(--muted);
}

.load-more {
  text-align: center;
  padding: 14px;
  color: var(--muted);
  font-size: 14px;
}
.load-more .spinner { display: inline-block; animation: spin 0.7s linear infinite; vertical-align: -1px; }

/* ---- navigation & applications ---- */
.nav { display: flex; align-items: center; gap: 10px; }
.navlink {
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 12px;
  background: var(--surface);
}
.navlink:hover { border-color: var(--accent); color: var(--accent-dark); }

.card-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.btn.small.applied { border-color: #bfe6d4; color: var(--green); }
.btn.small.applied:hover { background: #e7f6ef; }
.btn.small.danger { border-color: #f3c2c2; color: var(--red); }
.btn.small.danger:hover { background: #fdecec; }

.app-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0 8px;
}
.app-row td {
  background: var(--surface);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 12px 10px;
  vertical-align: middle;
  font-size: 14px;
}
.app-row td:first-child { border-left: 1px solid var(--border); border-radius: 12px 0 0 12px; }
.app-row td:last-child  { border-right: 1px solid var(--border); border-radius: 0 12px 12px 0; }
.app-row.status-won  td { background: #f2fbf7; }
.app-row.status-lost td { opacity: 0.65; }
.app-icon { width: 30px; }
.app-title { width: 40%; }
.app-table { table-layout: fixed; }
.app-table td { overflow-wrap: break-word; }
.app-title a { text-decoration: none; font-weight: 600; }
.app-title a:hover { text-decoration: underline; color: var(--accent-dark); }
.app-sub { margin-top: 4px; font-size: 12.5px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.status-select {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 5px 8px;
  font-size: 13.5px;
  font-weight: 600;
  background: var(--surface);
}
.status-select.status-applied   { color: #2f6db5; }
.status-select.status-replied   { color: var(--amber); }
.status-select.status-interview { color: #6a51c7; }
.status-select.status-won       { color: var(--green); }
.status-select.status-lost      { color: var(--muted); }
.app-row .btn.small { margin-top: 0; }
.app-title .external-link {
  margin-left: 6px;
  font-weight: 700;
  color: var(--muted);
  text-decoration: none;
}
.app-title .external-link:hover { color: var(--accent-dark); }

/* ---- application detail page ---- */
.detail { max-width: 860px; margin: 0 auto; }
.detail-track {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 14px;
  padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 13.5px;
}
.detail-track .btn.external { margin-left: auto; text-decoration: none; }
.detail-heading { margin: 18px 0 6px; font-size: 15px; }
.detail-desc { white-space: pre-line; }

/* ---- AI classification & workflows ---- */
.ai-fit-strong  { background: #e7f6ef; border-color: #bfe6d4; color: var(--green); }
.ai-fit-partial { background: #fdf6e7; border-color: #eedcae; color: var(--amber); }
.ai-fit-poor    { background: #f2f3f5; border-color: var(--border); color: var(--muted); }
.chip.ai-cat  { background: #f0edfb; border-color: #d8d0f2; color: #6a51c7; font-weight: 500; }
.chip.ai-flag { background: #fdecec; border-color: #f3c2c2; color: var(--red); }

/* how the template was chosen: deterministic rules, a model tie-break, or a
   human override — worth distinguishing, since only one of them is repeatable */
.chip.select-rules  { background: #e7f6ef; border-color: #bfe6d4; color: var(--green); }
.chip.select-model  { background: #f0edfb; border-color: #d8d0f2; color: var(--purple); }
.chip.select-manual { background: #fdf6e7; border-color: #eedcae; color: var(--amber); }

.btn.small { font-size: 13px; padding: 5px 11px; margin-top: 10px; }
.btn.small.htmx-request { opacity: 0.6; cursor: wait; }
.spinner.dark { border-color: rgba(0,0,0,0.15); border-top-color: var(--muted); }

/* the manual override: a template picker plus its submit button, laid out
   like the rest of the field/button pairs on this page */
.regen { display: flex; gap: 12px; align-items: end; margin-top: 14px; }
.regen .field { min-width: 220px; }

.analysis {
  margin-top: 12px;
  border-top: 1px dashed var(--border);
  padding-top: 12px;
  font-size: 13.5px;
  display: grid;
  gap: 8px;
}
.analysis.error { color: var(--red); }
.analysis-head { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.analysis-row { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.analysis-label {
  flex-shrink: 0;
  min-width: 130px;
  font-weight: 600;
  color: var(--muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.analysis-list { margin: 0; padding-left: 18px; }
.kw {
  display: inline-block;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 1px 8px;
  margin: 2px 4px 2px 0;
  font-size: 12.5px;
}
.kw-client { background: #fdeef5; border-color: #f6c6dc; color: var(--accent-dark); font-weight: 600; }
.draft {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  font: 13.5px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: var(--text);
  background: #fbfcfd;
  resize: vertical;
}

/* ---- users admin ----
   Same surface/pill vocabulary as the board; the table is the page, so the
   create form sits above it in its own panel rather than in a filter bar. */
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px;
  margin-bottom: 20px;
}
.panel-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.panel-head h2 { font-size: 15px; margin: 0; }
.panel-head .muted { font-size: 13px; }

.user-form {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1.5fr) minmax(0, 1.2fr) auto;
  gap: 10px;
  align-items: end;
}
@media (max-width: 720px) { .user-form { grid-template-columns: minmax(0, 1fr); } }

/* the users form has 3 fields plus a submit button, so fixed columns make
   sense; the templates form has 16 fields, so it needs a flow grid that
   wraps to as many rows as the field count demands instead of forcing
   everything into one ragged row. Additive: layered on .user-form, never
   replacing it. */
.template-form {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
  align-items: end;
}
.template-form .field-wide { grid-column: 1 / -1; }
.template-form .btn { height: 36px; justify-self: start; }
@media (max-width: 720px) { .template-form { grid-template-columns: minmax(0, 1fr); } }

.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field > span {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.field input, .field select {
  width: 100%;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 14px;
  color: var(--text);
}
.field input:focus, .field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(234, 76, 137, 0.15);
}
.user-form .btn { height: 36px; }

/* narrow screens keep the row readable by scrolling the table, not the page */
.table-wrap { overflow-x: auto; }
/* fixed layout so a long email ellipsises inside its cell instead of
   stretching the table past the columns that follow it */
.user-table {
  width: 100%;
  min-width: 860px;
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 0 8px;
}
.user-table thead th {
  text-align: left;
  padding: 0 12px 2px;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}
.col-role, .col-status { width: 105px; }
.col-login { width: 100px; }
.col-actions { width: 255px; }
.user-table .chip, .user-table .pill { white-space: nowrap; }
/* the rules cell can hold two chips ("100-160 words", "needs a question"),
   wider than the users page's single-chip col-role; let them wrap inside
   this column only rather than loosening the shared nowrap rule above. */
.col-rules { width: 165px; }
.user-table td.col-rules .chip { white-space: normal; }
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.user-row td {
  background: var(--surface);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 10px 12px;
  vertical-align: middle;
  font-size: 14px;
}
.user-row td:first-child { border-left: 1px solid var(--border); border-radius: 12px 0 0 12px; }
.user-row td:last-child  { border-right: 1px solid var(--border); border-radius: 0 12px 12px 0; text-align: right; }
/* recede the record without opacity — that would dim the whole cell,
   including the button that brings the account back */
.user-row.is-disabled td { background: #fbfcfd; }
.user-row.is-disabled .identity-mail { font-weight: 500; color: var(--muted); }
.user-row.is-disabled .avatar { color: #9aa4b2; }
/* an open reset form makes the row tall — top-align so the account stays
   level with the control that opened it */
.user-row:has(.reset[open]) td { vertical-align: top; }

.identity { display: flex; align-items: center; gap: 10px; min-width: 0; }
.avatar {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
}
.avatar-admin { background: #fdeef5; border-color: #f6c6dc; color: var(--accent-dark); }
.identity-mail {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tag-you {
  flex-shrink: 0;
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--muted);
}
.chip.role-admin { background: #fdeef5; border-color: #f6c6dc; color: var(--accent-dark); }
.chip.role-lead  { background: var(--bg); color: var(--muted); }
.pill.state-active   { color: var(--green); background: #e7f6ef; border-color: #bfe6d4; }
.pill.state-disabled { color: var(--muted); }
.last-login { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

.row-actions {
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 8px;
}
.row-actions .btn.small { margin-top: 0; white-space: nowrap; }

/* password reset: a disclosure so the field only exists once asked for,
   and still submits without JS. It expands in place rather than floating —
   .table-wrap scrolls, and a positioned panel would be clipped by it. */
.reset { display: inline-block; text-align: left; }
.reset > summary { list-style: none; user-select: none; }
.reset > summary::-webkit-details-marker { display: none; }
.reset[open] > summary { border-color: var(--accent); color: var(--accent-dark); }
/* open, the disclosure claims the full column so it reads as one block
   under the row's other action instead of a stray wrapped button */
.reset[open] { width: 100%; }
.reset[open] .reset-panel { width: 100%; }
.reset-panel {
  width: 230px;
  margin-top: 8px;
  padding: 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.reset-panel form { display: flex; flex-direction: column; gap: 10px; }
.reset-panel .btn.small { margin-top: 0; justify-content: center; }
.reset-hint { margin: 0; font-size: 12px; color: var(--muted); }

/* ---- login ---- */
.login-page { display: flex; justify-content: center; padding-top: 12vh; }
.login-card { display: flex; flex-direction: column; gap: 14px; width: 320px;
              background: var(--surface); border: 1px solid var(--border);
              border-radius: 10px; padding: 28px; }
.login-card h1 { font-size: 18px; margin: 0 0 6px; }
.login-card label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; }
.login-card input { padding: 8px 10px; border: 1px solid var(--border);
                    border-radius: 6px; font-size: 14px; }
.login-error { color: var(--red); font-size: 13px; margin: 0; }
.form-error { color: var(--red); font-size: 13px; margin: 6px 0 0; }
