:root {
  /* Dark theme, Winterberry Group accent (the coral-red from the "wg" mark).
     Backgrounds sit near-black and neutral so the accent can be used sparingly
     and still read -- the same reason Neon's console feels calm with one bright
     green. --dim is the quietest step, for inactive icons and column labels. */
  --text: #ececec;
  --muted: #9a9fa6;
  --dim: #6b7078;
  --border: #23272e;
  --border-strong: #2b3039;
  --bg: #0e1014;
  --bg-alt: #101216;
  --bg-raised: #191c22;
  --accent: #e8542f;
  --accent-contrast: #ffffff;
  --badge-bg: rgba(232, 84, 47, 0.16);
  --badge-text: #ff9a78;
  --category-badge-bg: rgba(45, 190, 165, 0.14);
  --category-badge-text: #5fd6c4;
  --error: #ff6b6b;
  --flash-bg: rgba(232, 84, 47, 0.12);
  --flash-border: rgba(232, 84, 47, 0.4);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  color: var(--text);
  background: var(--bg);
  line-height: 1.5;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Accent restraint: titles in lists and cards are the highest-volume links in the
   app, and leaving them all accent-colored is what made every page read as mostly
   orange. They're primary content, so they get --text and reveal the accent on
   hover; the accent stays for genuine "go somewhere else" links (back-links,
   inline prose links), where it actually signals something. */
.card-title a,
.archive-list a,
.recent-list a,
.project-list-name,
.search-result-title a {
  color: var(--text);
}
.card-title a:hover,
.archive-list a:hover,
.recent-list a:hover,
.project-list-name:hover,
.search-result-title a:hover {
  color: var(--accent);
  text-decoration: none;
}

/* --- App shell: fixed-width sidebar + content column ------------------------- */

.app-shell {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  width: 218px;
  flex-shrink: 0;
  background: var(--bg-alt);
  border-right: 1px solid var(--border);
  padding: 0.9rem 0.6rem 1rem;
  display: flex;
  flex-direction: column;
}
.sidebar-brand {
  display: block;
  padding: 0 0.45rem 0.9rem;
}
.sidebar-brand:hover { text-decoration: none; }

.sidebar-label {
  font-size: 0.68rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--dim);
  padding: 0 0.5rem 0.45rem;
}

.sidebar-nav { display: flex; flex-direction: column; gap: 0.1rem; }
.sidebar-nav a {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.45rem 0.5rem;
  border-radius: 6px;
  font-size: 0.85rem;
  color: var(--muted);
  border: 1px solid transparent;
}
.sidebar-nav a:hover {
  text-decoration: none;
  background: var(--bg-raised);
  color: var(--text);
}
/* Only the active item gets the accent -- the whole point of the sidebar is that
   one thing is highlighted at a time, instead of every nav item shouting. */
.sidebar-nav a.is-active {
  background: var(--bg-raised);
  border-color: var(--border-strong);
  color: var(--text);
  font-weight: 600;
}
.sidebar-nav .icon { width: 17px; height: 17px; flex-shrink: 0; color: var(--dim); }
.sidebar-nav a:hover .icon { color: var(--muted); }
.sidebar-nav a.is-active .icon { color: var(--accent); }

/* Nested project links. The left rule plus the indent is what marks them as
   children of the Projects item above, now that they have no heading of their
   own -- indentation alone read as accidental. */
.sidebar-children {
  display: flex;
  flex-direction: column;
  margin: 0.15rem 0 0.15rem 1.35rem;
  padding-left: 0.5rem;
  border-left: 1px solid var(--border);
}
.sidebar-children a {
  display: block;
  padding: 0.3rem 0.5rem;
  border-radius: 6px;
  font-size: 0.8rem;
  color: var(--muted);
}
.sidebar-children a:hover {
  text-decoration: none;
  background: var(--bg-raised);
  color: var(--text);
}
.sidebar-children a.is-active {
  background: var(--bg-raised);
  color: var(--text);
  font-weight: 600;
}

.app-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* Sticky so the search box and the account controls stay reachable on a long
   archive page -- that's the whole reason Sign out moved up here out of the
   sidebar foot. Needs an opaque background (it has one) or content scrolls
   through it. */
.topbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem 1.5rem;
  border-bottom: 1px solid var(--border);
  background: var(--bg-alt);
  min-height: 46px;
  position: sticky;
  top: 0;
  z-index: 20;
}

/* margin-left:auto rather than justify-content on .topbar, so the search box
   stays left-aligned whether or not this block is present (it's absent when
   REQUIRE_LOGIN is off). */
.topbar-account {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-shrink: 0;
}
.topbar-user {
  font-size: 0.8rem;
  color: var(--muted);
  white-space: nowrap;
}

/* Quieter than a default .auth-btn: in the top bar it sits next to the search
   field permanently, and a full-weight button there pulls the eye away from the
   page content every time. */
.auth-btn-quiet {
  font-weight: 500;
  font-size: 0.8rem;
  padding: 0.3rem 0.7rem;
  border-radius: 6px;
  color: var(--muted);
}
.auth-btn-quiet:hover {
  color: var(--text);
  filter: none;
  border-color: var(--dim);
}

.site-title { display: flex; align-items: center; }
.site-title:hover { text-decoration: none; }

.site-logo {
  height: 34px;
  width: auto;
  display: block;
}

/* The border lives on this wrapper, not the input, so the magnifier sits inside
   the field. Border and icon are deliberately the full text white rather than a
   muted grey -- this is the one control that has to be findable at a glance, and
   every subtler shade got lost against the top bar. */
.site-search-field {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  background: var(--bg);
  border: 1px solid var(--text);
  border-radius: 6px;
  padding: 0.3rem 0.65rem;
  width: 260px;
  transition: border-color 0.12s ease;
}
.site-search-field:focus-within { border-color: var(--accent); }
.site-search-field .icon {
  width: 15px;
  height: 15px;
  color: var(--text);
  flex-shrink: 0;
}
.site-search-field input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  padding: 0;
  color: var(--text);
  font-size: 0.85rem;
}
.site-search-field input:focus { outline: none; }
.site-search-field input::placeholder { color: var(--dim); }

.auth-area { display: flex; align-items: center; gap: 0.7rem; }
.auth-user { color: var(--muted); font-size: 0.9rem; }
.auth-btn {
  background: var(--bg-raised);
  color: var(--text);
  border: 1px solid var(--border);
  font-weight: 600;
  font-size: 0.85rem;
  padding: 0.45rem 0.9rem;
  border-radius: 8px;
  cursor: pointer;
}
.auth-btn:hover { filter: brightness(1.15); }
.auth-btn:disabled { opacity: 0.6; cursor: default; }
.auth-btn-primary {
  background: var(--accent);
  color: var(--accent-contrast);
  border-color: var(--accent);
}

/* Centred on the same column as .site-main below, so a flash lines up with the
   content it refers to rather than hugging the sidebar. */
.flash-messages { max-width: 1180px; margin: 1rem auto 0; width: 100%; padding: 0 1.75rem; }
.flash {
  background: var(--flash-bg);
  border: 1px solid var(--flash-border);
  color: var(--text);
  padding: 0.6rem 0.9rem;
  border-radius: 6px;
  font-size: 0.9rem;
}

.toast-container {
  position: fixed;
  bottom: 1.5rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  z-index: 1000;
  pointer-events: none;
}
.toast {
  background: var(--bg-raised);
  border: 1px solid var(--accent);
  color: var(--text);
  padding: 0.65rem 1.1rem;
  border-radius: 8px;
  font-size: 0.9rem;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
  animation: toast-in-out 3.5s ease forwards;
}
@keyframes toast-in-out {
  0% { opacity: 0; transform: translateY(8px); }
  8% { opacity: 1; transform: translateY(0); }
  88% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(8px); }
}

/* Wider than the old 900px cap so tables have room, but still capped: article
   summaries are prose, and full-viewport line lengths are hard to read. The auto
   side margins centre that capped column in the space beside the sidebar --
   without them the content pins left and all the slack piles up on the right. */
.site-main {
  max-width: 1180px;
  margin: 0 auto;
  width: 100%;
  padding: 1.5rem 1.75rem 4rem;
}

h2 { font-size: 1.4rem; margin: 0 0 1rem; }
h3.category-heading {
  font-size: 1.05rem;
  margin: 2rem 0 0.75rem;
  padding-bottom: 0.35rem;
  border-bottom: 2px solid var(--border);
}

.section-heading {
  font-size: 0.95rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin: 0 0 0.5rem;
}

.page-intro {
  color: var(--muted);
  font-size: 0.9rem;
  max-width: 65ch;
  margin: -0.5rem 0 1rem;
}

/* --- Landing page ------------------------------------------------------- */

.landing-hero { margin-bottom: 1.5rem; }

/* Signed-out sign-in page: pitch on the left, sign-in card on the right. */
.signin-split {
  display: grid;
  grid-template-columns: 1fr 280px;
  gap: 2.5rem;
  align-items: center;
  margin: 0;
  /* Fills the viewport below the header so the content sits vertically centered
     rather than stranded at the top of an otherwise empty page. The subtraction
     covers the header plus .site-main's own vertical padding. */
  min-height: calc(100vh - 12rem);
}
.signin-pitch h2 {
  font-size: 1.6rem;
  line-height: 1.25;
  margin: 0 0 1.1rem;
}
.signin-features {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.signin-features li {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.5;
}
.signin-features .icon {
  width: 18px;
  height: 18px;
  color: var(--accent);
  flex-shrink: 0;
  margin-top: 0.15rem;
}

.signin-card {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.6rem 1.4rem;
}
.signin-card h3 { margin: 0 0 1rem; font-size: 1.05rem; }

/* White with a dark label, per Google's own sign-in button convention -- a themed
   accent-colored version reads as "some button" rather than "Google sign-in". */
.google-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  background: #ffffff;
  color: #1f1f1f;
  border: none;
  border-radius: 8px;
  padding: 0.65rem 0.9rem;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}
.google-btn .icon { width: 18px; height: 18px; }
.google-btn:hover:not(:disabled) { filter: brightness(0.94); }
.google-btn:disabled { opacity: 0.6; cursor: default; }

.signin-error {
  margin: 0.8rem 0 0;
  color: var(--error);
  font-size: 0.82rem;
  line-height: 1.5;
}
.signin-note {
  margin: 0.9rem 0 0;
  color: var(--muted);
  font-size: 0.75rem;
  text-align: center;
}

@media (max-width: 620px) {
  .signin-split { grid-template-columns: 1fr; gap: 1.75rem; }
}

.aotd-section {
  margin-bottom: 2rem;
  padding: 1.1rem 1.2rem 0.2rem;
  border: 1px solid var(--accent);
  border-radius: 10px;
  background: var(--badge-bg);
}
.aotd-section .section-heading {
  color: var(--accent);
  font-weight: 700;
}
.aotd-section .card {
  border: none;
  background: none;
  padding: 0;
  margin-bottom: 0.9rem;
}

.landing-cards {
  display: grid;
  /* Three columns so the Document Sourcing hero can span the full row above the
     other three -- it's the app's primary feature, so it gets the weight. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
  margin-bottom: 2.5rem;
}

.landing-card {
  display: block;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.5rem;
  color: var(--text);
  background: var(--bg);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.landing-card:hover {
  text-decoration: none;
  border-color: var(--accent);
  box-shadow: 0 2px 14px rgba(232, 84, 47, 0.18);
  background: var(--bg-raised);
}
/* Line icons replaced the emoji here -- sized in CSS since _icons.html leaves the
   SVG dimensionless, and colored via currentColor by the rules below. */
.landing-card-icon { display: inline-flex; color: var(--muted); }
.landing-card-icon .icon { width: 22px; height: 22px; }
.landing-card-hero .landing-card-icon { color: var(--accent); }
.landing-card-hero .landing-card-icon .icon { width: 26px; height: 26px; }
.landing-card h3 { margin: 0.5rem 0 0.4rem; font-size: 1.15rem; }
.landing-card p { margin: 0; color: var(--muted); font-size: 0.9rem; }

/* Hero modifier must come AFTER the .landing-card base rules above: both are
   single-class selectors, so at equal specificity source order decides which
   background/border wins. Declared earlier, these were silently overridden. */
.landing-card-hero {
  grid-column: 1 / -1;
  background: var(--bg-raised);
  border-color: var(--accent);
  padding: 1.6rem 1.75rem;
}
.landing-card-hero h3 { font-size: 1.4rem; }
.landing-card-hero p { font-size: 0.95rem; max-width: 78%; }

.landing-hero-top {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.landing-hero-tag {
  background: var(--badge-bg);
  color: var(--badge-text);
  font-size: 0.75rem;
  padding: 0.15rem 0.6rem;
  border-radius: 8px;
}

@media (max-width: 620px) {
  .landing-cards { grid-template-columns: 1fr; }
  .landing-card-hero p { max-width: none; }
}

.recent-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
}
@media (max-width: 640px) {
  .recent-columns { grid-template-columns: 1fr; }
}

.recent-list { list-style: none; padding: 0; margin: 0; }
.recent-list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.9rem;
}

.history-main {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  min-width: 0;
}

.delete-form { flex-shrink: 0; }
.delete-btn {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.15rem 0.4rem;
  border-radius: 4px;
}
.delete-btn:hover {
  color: var(--error);
  background: rgba(255, 107, 107, 0.12);
}

/* --- Generation progress -------------------------------------------------- */

/* --- Generation progress -------------------------------------------------- */
/* This page has nothing on it but the bar, so it gets centered in the viewport
   rather than hugging the top of a mostly-empty screen -- at 520px wide and
   top-aligned it read as a stray fragment on a wide monitor. Still a bounded
   column: a progress bar spanning 1180px looks like a page element, not an
   instrument. */
.progress-panel {
  max-width: 680px;
  margin: 0 auto;
  min-height: 60vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.progress-heading {
  margin: 0 0 1.8rem;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.progress-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.65rem;
}
.progress-stage { font-size: 1.05rem; color: var(--text); }
.progress-percent {
  font-family: ui-monospace, "Cascadia Mono", Menlo, Consolas, monospace;
  font-size: 1.05rem;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.progress-track {
  width: 100%;
  height: 6px;
  background: var(--border);
  border-radius: 999px;
  overflow: hidden;
}
.progress-fill {
  position: relative;
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
  transition: width 0.45s ease;
  overflow: hidden;
}
/* The bar can hold one percentage for 20+ seconds during a long stage, which
   reads as hung. A highlight sweeping the filled portion is the only thing on
   the page that proves otherwise. Stops once the job settles -- a shimmer under
   an error message looks like it's still trying. */
.progress-shimmer {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 42%;
  background: rgba(255, 255, 255, 0.3);
  animation: progress-sweep 1.9s linear infinite;
}
@keyframes progress-sweep {
  from { transform: translateX(-110%); }
  to { transform: translateX(340%); }
}
.progress-panel.is-settled .progress-shimmer { display: none; }
.progress-panel.has-error .progress-fill { background: var(--error); }
.progress-panel.has-error .progress-percent { color: var(--error); }

.progress-telemetry {
  display: flex;
  gap: 1.2rem;
  margin-top: 0.85rem;
  font-size: 0.8rem;
  color: var(--dim);
}
.progress-telemetry b {
  color: var(--muted);
  font-weight: 500;
  font-family: ui-monospace, "Cascadia Mono", Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
}

.progress-error {
  margin: 1.3rem 0 0;
  font-size: 0.92rem;
  color: var(--error);
}
.progress-cancel { margin-top: 2rem; font-size: 0.9rem; }

@media (prefers-reduced-motion: reduce) {
  .progress-shimmer { animation: none; opacity: 0.18; }
}

/* --- Newsletter view ----------------------------------------------------- */

.newsletter-banner {
  border-bottom: 3px double var(--border);
  padding-bottom: 1rem;
  margin-bottom: 1rem;
}
.newsletter-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  color: var(--dim);
  font-weight: 600;
  margin: 0 0 0.25rem;
}
.newsletter-banner h2 { margin: 0; }

/* Neutral panel with a hairline border rather than an orange wash: the wash was
   tuned against the old lighter background and reads muddy on the near-black one,
   and a whole tinted block is the opposite of using the accent sparingly. */
/* "Standing" marker on a feedback note -- a note that is fed to every future
   generation as a constraint rather than ageing out of the rolling window.
   Deliberately quiet: it's a rarely-used option, not a call to action. */
.standing-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.75rem;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
}
.standing-toggle input { cursor: pointer; margin: 0; accent-color: var(--accent); }
.standing-toggle:hover { color: var(--text); }

/* A retired note is kept on the page as a record but is no longer acting, so it
   reads as struck-through and dimmed rather than disappearing. */
.feedback-comment-list li.is-retired { opacity: 0.5; text-decoration: line-through; }
.retire-form { display: inline; }
.retire-btn {
  background: none;
  border: none;
  color: var(--dim);
  font-size: 0.72rem;
  cursor: pointer;
  padding: 0 0.2rem;
  text-decoration: underline;
}
.retire-btn:hover { color: var(--accent); }

.badge-standing {
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 0.68rem;
}

/* Placeholder while today's pick is still generating. Deliberately a card-shaped
   block rather than a spinner, so the page doesn't visibly reflow when the real
   article replaces it. */
.aotd-pending {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 1rem 1.1rem;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.85rem;
  color: var(--muted);
}
.aotd-pending-bar {
  position: relative;
  flex-shrink: 0;
  width: 52px;
  height: 3px;
  border-radius: 999px;
  background: var(--border);
  overflow: hidden;
}
.aotd-pending-bar::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 40%;
  border-radius: 999px;
  background: var(--accent);
  animation: progress-sweep 1.6s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .aotd-pending-bar::after { animation: none; }
}

.aotd-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.aotd-head .section-heading { margin-bottom: 0.4rem; }
.aotd-refresh {
  background: none;
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.75rem;
  padding: 0.2rem 0.6rem;
  border-radius: 6px;
  cursor: pointer;
}
.aotd-refresh:hover { color: var(--text); border-color: var(--dim); }

/* --- Document Sourcing chat ------------------------------------------------ */

.chat-section {
  margin: 2rem 0 1.5rem;
  padding: 1.1rem 1.25rem;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.chat-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.chat-head .section-heading { margin-bottom: 0.3rem; }
.chat-clear {
  background: none;
  border: none;
  color: var(--dim);
  font-size: 0.75rem;
  cursor: pointer;
  text-decoration: underline;
  padding: 0;
}
.chat-clear:hover { color: var(--accent); }
.chat-intro {
  margin: 0 0 1rem;
  font-size: 0.78rem;
  color: var(--dim);
  line-height: 1.5;
}

.chat-log { display: flex; flex-direction: column; gap: 0.7rem; }
.chat-msg {
  padding: 0.65rem 0.85rem;
  border-radius: 8px;
  font-size: 0.88rem;
  line-height: 1.6;
  /* Replies contain newlines from the model; render them rather than collapsing. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
/* The question is the quieter element: it's short, and the user wrote it. The
   answer is what they came back to read. */
.chat-msg-user {
  align-self: flex-end;
  max-width: 78%;
  background: var(--bg-raised);
  color: var(--muted);
}
.chat-msg-assistant {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
}
.chat-msg.is-pending { color: var(--dim); font-style: italic; }

.chat-error { margin: 0.7rem 0 0; font-size: 0.82rem; color: var(--error); }

.chat-form { display: flex; gap: 0.5rem; margin-top: 0.9rem; }
.chat-form input {
  flex: 1;
  min-width: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.5rem 0.7rem;
  font-size: 0.88rem;
  color: var(--text);
}
.chat-form input:focus { outline: none; border-color: var(--accent); }
.chat-form button {
  background: var(--accent);
  color: var(--accent-contrast);
  border: none;
  border-radius: 6px;
  padding: 0.5rem 1.1rem;
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
}
.chat-form button:disabled { opacity: 0.55; cursor: default; }

/* --- About page ----------------------------------------------------------- */

/* The one accent-colored control in the top bar. An outlined accent pill rather
   than a solid fill: solid orange sat right next to the search field and read as
   the primary action on every page, which it isn't -- it's a help link. Filling
   in on hover gives it the affordance without the constant shouting.
   color-mix keeps the tint tied to --accent, so re-theming needs one change. */
.about-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.8rem;
  font-weight: 500;
  white-space: nowrap;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.about-btn:hover,
.about-btn:focus-visible {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
  text-decoration: none;
}
/* Already filled while you're on the page, so the pill doubles as the nav's
   current-location marker instead of needing a separate active style. */
.about-btn.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}
.about-btn .icon { width: 14px; height: 14px; flex-shrink: 0; }

/* Narrower than the page default: this is prose to be read, and full-width lines
   at 1180px are hard to track back to the left margin. */
.about-page { max-width: 760px; }
.about-page h2 { margin-bottom: 0.2rem; }

.about-section { margin-bottom: 2.2rem; }
.about-section p { line-height: 1.6; color: var(--text); }
.about-section .section-heading { margin-bottom: 0.5rem; }

.about-list { margin: 0; }
.about-list dt {
  font-weight: 600;
  color: var(--text);
  margin-top: 0.9rem;
}
.about-list dd {
  margin: 0.2rem 0 0;
  color: var(--muted);
  line-height: 1.55;
}

.about-steps, .about-bullets {
  margin: 0.4rem 0 0;
  padding-left: 1.2rem;
  color: var(--muted);
}
.about-steps li, .about-bullets li {
  margin-bottom: 0.6rem;
  line-height: 1.55;
}
.about-steps strong, .about-bullets strong { color: var(--text); }

.about-note {
  margin-top: 0.9rem;
  padding: 0.7rem 0.9rem;
  background: var(--bg-alt);
  border-left: 2px solid var(--border);
  border-radius: 0 6px 6px 0;
  font-size: 0.88rem;
  color: var(--muted);
}

/* Sub-headings inside a section, for the longer explanations (the feedback
   section has four). Smaller and less shouty than .section-heading, which is
   already doing the section-level job above it. */
.about-subheading {
  margin: 1.3rem 0 0.4rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text);
}

/* The verbatim prompt block. Monospace and boxed because it's quoted machine text,
   not prose -- and pre-wrapped rather than scrolling, since a horizontal scrollbar
   inside a page of prose is easy to miss entirely. */
.about-prompt {
  margin: 0.5rem 0 0;
  padding: 0.75rem 0.9rem;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: ui-monospace, "Cascadia Mono", Menlo, Consolas, monospace;
  font-size: 0.74rem;
  line-height: 1.55;
  color: var(--muted);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.about-source-group { margin-top: 1.1rem; }
.about-source-group h4 {
  margin: 0 0 0.4rem;
  font-size: 0.85rem;
  color: var(--text);
}
.about-count {
  color: var(--dim);
  font-weight: 400;
  font-size: 0.8rem;
}

/* Columns rather than one long stack -- 45 domains as a single list is a wall. */
.about-domains {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 2;
  column-gap: 1.5rem;
  font-size: 0.85rem;
  color: var(--muted);
}
.about-domains li {
  padding: 0.12rem 0;
  break-inside: avoid;
}

.badge-sourcing-only {
  background: var(--bg-raised);
  color: var(--dim);
  font-size: 0.62rem;
  border: 1px solid var(--border);
}

@media (max-width: 620px) {
  .about-domains { columns: 1; }
}

/* --- Forms / filter bars -------------------------------------------------- */

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: flex-end;
  margin: 1rem 0;
  padding: 0.9rem;
  background: var(--bg-alt);
  border-radius: 8px;
}

.filter-bar label {
  display: flex;
  flex-direction: column;
  font-size: 0.8rem;
  color: var(--muted);
  gap: 0.25rem;
}

.search-input-label { flex: 1 1 220px; }

.filter-bar select,
.filter-bar input,
.filter-bar button {
  font-size: 0.9rem;
  padding: 0.4rem 0.5rem;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
}

.filter-bar button {
  background: var(--accent);
  color: var(--accent-contrast);
  border-color: var(--accent);
  cursor: pointer;
  height: fit-content;
  font-weight: 600;
}
.filter-bar button:hover { filter: brightness(1.1); }

/* --- Result cards ---------------------------------------------------------- */

.card {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem 1.1rem;
  margin-bottom: 0.9rem;
  background: var(--bg);
}

.card-title { margin: 0 0 0.4rem; font-size: 1.05rem; }

.card-meta {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  flex-wrap: wrap;
  font-size: 0.8rem;
  color: var(--muted);
  margin-bottom: 0.5rem;
}

.card-source { font-weight: 600; }

.badge {
  display: inline-block;
  background: var(--badge-bg);
  color: var(--badge-text);
  padding: 0.1rem 0.55rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
}

.badge-category {
  background: var(--category-badge-bg);
  color: var(--category-badge-text);
}

/* Partner-circulated articles. Marked with a left rule and a label rather than
   another pill in the meta row: the meta row already carries category and trend
   badges, and a third would read as one more tag rather than as provenance --
   which is the one thing about these results the reader most needs to see. */
.card-partner {
  border-left: 3px solid var(--accent);
}

.partner-flag {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-bottom: 0.35rem;
  color: var(--accent);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* The send date rides in the flag rather than the meta row below, because it
   belongs to the provenance claim -- "a partner sent this, on this date" -- and
   not to the article's own byline/date/tags. It also has to stand apart from
   published_date: a third of partner articles have no article date at all. */
.partner-sent {
  margin-left: 0.5rem;
  padding-left: 0.5rem;
  border-left: 1px solid currentColor;
  font-weight: 600;
  opacity: 0.75;
  text-transform: none;
  letter-spacing: 0;
}

.partner-flag::before {
  content: "";
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: var(--accent);
}

.card-summary { margin: 0.3rem 0 0; }
.card-summary-error { color: var(--error); font-style: italic; }

.card-companies {
  margin-top: 0.5rem;
  font-size: 0.8rem;
  color: var(--muted);
}

.feedback-form {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
}
.feedback-btn {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.2rem 0.5rem;
  font-size: 0.9rem;
  cursor: pointer;
  line-height: 1.4;
}
.feedback-btn:hover { filter: brightness(1.15); }
.feedback-btn-active { border-color: var(--accent); background: var(--badge-bg); }
.feedback-comment {
  flex: 1;
  min-width: 120px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.25rem 0.5rem;
  font-size: 0.85rem;
  color: var(--text);
}

/* Save-to-project picker on an article card -- its own row under the feedback
   row rather than sharing it, so the careful .feedback-form sizing
   above stays untouched. */
.save-form {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.4rem;
}
.save-select {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.25rem 0.4rem;
  font-size: 0.8rem;
  color: var(--text);
  max-width: 240px;
}
.save-btn {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.25rem 0.7rem;
  font-size: 0.8rem;
  color: var(--text);
  cursor: pointer;
}
.save-btn:hover:not(:disabled) { border-color: var(--accent); }
.save-btn:disabled { opacity: 0.5; cursor: default; }
.save-empty-link {
  display: inline-block;
  margin-top: 0.4rem;
  font-size: 0.8rem;
  color: var(--muted);
}

.project-list { list-style: none; padding: 0; }
.project-list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--border);
}
.project-list-name { font-size: 1.05rem; font-weight: 600; flex: 1; }
.project-list-count { color: var(--muted); font-size: 0.85rem; }
.project-folder-count { color: var(--muted); font-size: 0.85rem; margin-left: 0.5rem; }

.saved-list {
  min-height: 2.5rem;
  border-radius: 8px;
  transition: background 0.1s ease;
}
.saved-list:empty::after {
  content: "Drop articles here";
  display: block;
  color: var(--muted);
  font-size: 0.85rem;
  font-style: italic;
  padding: 0.6rem 0.2rem;
}
.saved-article { cursor: grab; }
.saved-article:active { cursor: grabbing; }
.saved-article.dragging { opacity: 0.4; }
.saved-article-remove { margin: -0.4rem 0 0.9rem; }

.project-drop-zone.drop-target-hover {
  background: var(--badge-bg);
  outline: 2px dashed var(--accent);
  outline-offset: 2px;
}

.stats-note {
  color: var(--muted);
  font-size: 0.85rem;
  margin: 0.75rem 0;
}
.stats-note p { margin: 0.2rem 0; }
.stats-suggestions strong { color: var(--text); }

.general-feedback {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.9rem 1.1rem;
  margin: 1rem 0 1.5rem;
}
.feedback-comment-list { list-style: none; margin: 0 0 0.6rem; padding: 0; font-size: 0.85rem; }
.feedback-comment-list li { padding: 0.25rem 0; border-bottom: 1px solid var(--border); }
.feedback-comment-date { color: var(--muted); font-size: 0.75rem; margin-left: 0.4rem; }
.general-feedback-form { display: flex; gap: 0.5rem; }
.general-feedback-form input[type="text"] {
  flex: 1;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.4rem 0.6rem;
  color: var(--text);
}
.general-feedback-form button {
  background: var(--accent);
  color: var(--accent-contrast);
  border: none;
  border-radius: 6px;
  padding: 0.4rem 0.9rem;
  font-weight: 600;
  cursor: pointer;
}
.general-feedback-form button:hover { filter: brightness(1.1); }

.empty-category, .empty-state {
  color: var(--muted);
  font-style: italic;
}

.watchlist-companies {
  list-style: none;
  padding: 0;
  margin: 0 0 1rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  min-height: 2.2rem;
  border-radius: 8px;
  transition: background 0.1s ease;
}
.watchlist-companies:empty::after {
  content: "Drop companies here";
  color: var(--muted);
  font-size: 0.85rem;
  font-style: italic;
  align-self: center;
}
.watchlist-companies li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.3rem 0.4rem 0.3rem 0.8rem;
  font-size: 0.9rem;
  cursor: grab;
}
.watchlist-companies li:active { cursor: grabbing; }
.watchlist-companies li.dragging { opacity: 0.4; }
.watchlist-companies .delete-btn { padding: 0 0.3rem; }

.watchlist-check-all { margin: 1.25rem 0; }
.watchlist-check-all button {
  background: var(--accent);
  color: var(--accent-contrast);
  border: none;
  border-radius: 6px;
  padding: 0.5rem 1rem;
  font-weight: 600;
  cursor: pointer;
}
.watchlist-check-all button:hover { filter: brightness(1.1); }

.watchlist-folder {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0 1.1rem;
  margin-bottom: 1rem;
}
.watchlist-folder-header {
  padding: 1rem 0;
  cursor: pointer;
}
.watchlist-folder-header::marker { color: var(--muted); }
.watchlist-folder-name { font-size: 1.05rem; font-weight: 600; }
.watchlist-folder-body {
  display: none;
  padding-bottom: 1rem;
}
.watchlist-folder[open] > .watchlist-folder-body { display: block; }
.watchlist-folder-delete { margin-bottom: 0.6rem; }
.watchlist-text-btn {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.8rem;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
}
.watchlist-text-btn:hover { color: var(--error); }
.watchlist-action-btn {
  background: var(--bg-raised);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.35rem 0.8rem;
  font-size: 0.85rem;
  cursor: pointer;
}
.watchlist-action-btn:hover { filter: brightness(1.15); }

.watchlist-drop-zone.drop-target-hover {
  background: var(--badge-bg);
  outline: 2px dashed var(--accent);
  outline-offset: 2px;
}

.archive-list { list-style: none; padding: 0; }
.archive-list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border);
}
.archive-list .history-main { flex-wrap: wrap; }
.archive-count { color: var(--muted); font-size: 0.85rem; }

.result-count { color: var(--muted); font-size: 0.85rem; }

.partner-status {
  margin: 0.75rem 0 0;
  padding: 0.6rem 0.8rem;
  border-left: 3px solid var(--accent);
  background: var(--badge-bg);
  border-radius: 0 6px 6px 0;
  font-size: 0.85rem;
}

.partner-status-stale { border-left-color: var(--error); }
.partner-status-warn { color: var(--error); font-weight: 600; }

/* The flag as it appears mid-sentence on the About page, where it's being named
   rather than applied to a card. */
.partner-flag-inline {
  color: var(--accent);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Needs .filter-bar in the selector: `.filter-bar label` stacks its children in
   a column (label text above the control), which is right for the text and
   select but puts this checkbox on its own line above its own words. Same class
   count, so the bare .partner-toggle lost on specificity. */
.filter-bar .partner-toggle {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
  padding-bottom: 0.55rem;
  color: var(--text);
  font-size: 0.85rem;
  white-space: nowrap;
  cursor: pointer;
}

.filter-bar .partner-toggle input {
  cursor: pointer;
  margin: 0;
  accent-color: var(--accent);
}

/* The collapsible partner block. The cards inside keep their own left rule and
   flag, so this wrapper stays quiet -- it's a control, not a second frame. */
.partner-group { margin-bottom: 1rem; }

.partner-summary {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.45rem 0.2rem;
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  user-select: none;
}

.partner-summary::marker { color: var(--accent); }
.partner-summary:hover { opacity: 0.85; }

.partner-summary-hint {
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}

/* Collapsed, the summary is the only thing standing in for several cards, so it
   gets the left rule the cards would otherwise have carried. */
.partner-group:not([open]) .partner-summary {
  border-left: 3px solid var(--accent);
  padding-left: 0.6rem;
}
