/* Layout and components. No raw hex here — tokens only (TEST-AC-201/202). */

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

body {
  margin: 0;
  font-family: var(--font-stack);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.25;
  color: var(--color-body);
  background: var(--color-canvas);
}

a { color: var(--color-link); text-decoration: none; }
a:hover { color: var(--color-link-active); }

/* ---- top nav (64px, white, never inverted) ---- */
.topnav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  height: 64px;
  padding: 0 max(var(--space-lg), calc((100% - var(--layout-max)) / 2 + var(--space-xxl)));
  border-bottom: 1px solid var(--color-surface-strong);
  background: var(--color-canvas);
}
.brand { display: inline-flex; align-items: center; color: var(--color-ink); }
.brand-mark { display: block; height: 26px; width: auto; fill: currentColor; }
.navlinks { display: flex; align-items: center; gap: var(--space-md); }
.navlinks a { font-size: 14px; color: var(--color-ink); }
.navlinks a:hover { color: var(--color-muted); }
.navlinks a[aria-current="page"] { font-weight: 500; border-bottom: 2px solid var(--color-ink); }

/* ---- layout ---- */
.container {
  max-width: var(--layout-max);
  margin: 0 auto;
  padding: var(--space-xl) var(--space-xxl);
}
@media (max-width: 1024px) { .container { padding: var(--space-xl) var(--space-lg); } }
@media (max-width: 768px)  { .container { padding: var(--space-lg) var(--space-md); } }

.page-title { font-size: 32px; font-weight: 400; line-height: 1.2; color: var(--color-ink); margin: 0 0 var(--space-xs); }
@media (max-width: 768px) { .page-title { font-size: 24px; } }
.page-sub { font-size: 14px; color: var(--color-muted); margin: 0 0 var(--space-lg); }

/* ---- source label (TEST-AC-051) ---- */
.source-label {
  display: inline-block;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: 0.16px;
  text-transform: uppercase;
  color: var(--color-muted);
  border: 1px solid var(--color-surface-strong);
  border-radius: var(--radius-sm);
  padding: var(--space-xxs) var(--space-xs);
  margin-bottom: var(--space-md);
}

/* ---- article cards: no thumbnails, category + title only ---- */
.card-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-lg);
}
@media (max-width: 1024px) { .card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 768px)  { .card-grid { grid-template-columns: 1fr; } }

.card {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-md);
  border: 1px solid var(--color-surface-strong);   /* soft rule: 1.30:1 */
  border-radius: var(--radius-md);
  background: var(--color-canvas);
  color: var(--color-ink);
  min-height: var(--touch-min);
  cursor: pointer;
  text-decoration: none;
  transition: background-color 120ms ease;
}
.card:hover { background: var(--color-surface-soft); }

.card-eyebrow {
  display: flex;
  flex-wrap: nowrap;
  align-items: baseline;
  gap: 0 var(--space-xs);
  min-width: 0;
  overflow: hidden;
}
.card-category {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: 0.16px;
  text-transform: uppercase;
  color: var(--color-muted);
  white-space: nowrap;
}
/* The raw MIND taxonomy value. Displayed because the accepted criterion asks
   for it, but demoted: it is an identifier, not something a reader parses. */
.card-sub {
  font-size: 14px;
  font-weight: 400;
  line-height: 1.35;
  color: var(--color-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  opacity: 0.75;
}
.card-title {
  font-size: 18px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--color-ink);
  margin: 0;
  /* No clamp: cutting a news headline mid-phrase is data loss, and half the
     cards would be truncated at 2 lines. Reserving three lines instead was
     tried and reverted: it moved the slack between the headline and the
     abstract, which reads as a mistake, whereas slack above the footer reads
     as a normal bottom-aligned card. */
}
.card-abstract {
  font-size: 14px;
  line-height: 1.5;
  color: var(--color-body);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0;
  /* Reserve two lines whether or not the abstract fills them, so cards in a
     row end on one line. A minimum, not a fixed height: a single long word
     can still take three. */
  min-height: calc(2 * 1.5 * 14px);
}
.card-meta {
  /* Footer sits at the bottom edge, right-aligned: it is reference data, not
     something to read first. */
  margin-top: auto;
  padding-top: var(--space-xs);
  display: flex;
  flex-wrap: nowrap;
  justify-content: flex-end;
  align-items: baseline;
  gap: 0 var(--space-xs);
  overflow: hidden;
  font-size: 12px;
  line-height: 1.3;
  color: var(--color-muted);
}
.card-meta > span { white-space: nowrap; }
/* Counts run one step below body text. At 12px they read as a footnote and
   stop competing with the headline and the abstract; the extra opacity drop
   keeps the numbers available but visually quiet (user request, 2026-10-22). */
.card-readers {
  display: flex;
  flex-wrap: nowrap;
  align-items: baseline;
  justify-content: flex-end;
  gap: 0 var(--space-xs);
  font-size: 12px;
  line-height: 1.3;
  color: var(--color-muted);
  opacity: 0.65;
}
.card-readers > span { white-space: nowrap; }

/* ---- persona picker ----
   A scrollable list of dataset users for the passwordless demo login. The
   list scrolls inside a fixed height so the submit button stays reachable
   with 50 rows on a laptop screen. */
.picker-card {
  max-width: 560px;
  margin: var(--space-xxl) auto;
  padding: var(--space-xl);
  border: 1px solid var(--color-surface-strong);
  border-radius: var(--radius-lg);
}
.picker-note { font-size: 16px; color: var(--color-muted); margin: 0 0 var(--space-md); }
.picker-list {
  max-height: 340px;
  overflow-y: auto;
  border: 1px solid var(--color-surface-strong);
  border-radius: var(--radius-sm);
  background: var(--color-canvas);
  /* Overlay scrollbars on Linux/Chrome are ~2px and read as "the list is cut
     off" rather than "the list scrolls". Ask for a visible, thin one. */
  scrollbar-width: thin;
  scrollbar-color: var(--color-muted) transparent;
  overscroll-behavior: contain;
}
.picker-list::-webkit-scrollbar { width: 10px; }
.picker-list::-webkit-scrollbar-track { background: var(--color-surface-soft); }
.picker-list::-webkit-scrollbar-thumb {
  background: var(--color-muted);
  border-radius: 5px;
  border: 2px solid var(--color-surface-soft);
}
.picker-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-surface-strong);
  cursor: pointer;
  margin: 0;
  font-weight: 400;
}
.picker-row:last-child { border-bottom: 0; }
.picker-row:hover { background: var(--color-surface-soft); }
.picker-row input[type="radio"] {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--color-primary);
}
.picker-row:has(input:checked) { background: var(--color-surface-soft); }
.picker-row:focus-within { outline: 2px solid var(--color-info-border); outline-offset: -2px; }
.picker-id {
  font-size: 16px;
  line-height: 1.4;
  color: var(--color-ink);
  font-variant-numeric: tabular-nums;
}
.picker-meta { font-size: 14px; color: var(--color-muted); }

/* ---- history list ----
   A record of what was read, not a feed to browse: one line per article, the
   title carrying the row, so nothing is stretched to a neighbour's height
   (which left blank bands and forced the abstract out). */
.history-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--color-surface-strong);
}
.history-row {
  display: grid;
  /* Title takes the slack; metadata columns are fixed so a row with only
     "1× via web" does not shrink the last column and shift category/time
     leftwards relative to rows that carry both counts. 220px fits
     "4257× via MIND · 8× via web" at 14px with room to spare. */
  grid-template-columns: minmax(0, 1fr) 120px 210px 220px;
  align-items: baseline;
  gap: var(--space-md);
  padding: var(--space-sm) 0;
  border-bottom: 1px solid var(--color-surface-strong);
}
.history-row a {
  color: var(--color-ink);
  text-decoration: none;
  font-size: 16px;
  line-height: 1.4;
}
.history-row a:hover { color: var(--color-link-active); }  /* D27: token-only */
.history-cat {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: 0.16px;
  text-transform: uppercase;
  color: var(--color-muted);
}
.history-time { font-size: 14px; color: var(--color-muted); text-align: right; white-space: nowrap; }
.history-readers { font-size: 14px; color: var(--color-muted); text-align: right; white-space: nowrap; opacity: 0.65; }
.history-readers > span { white-space: nowrap; }
@media (max-width: 768px) {
  .history-row { grid-template-columns: minmax(0, 1fr); gap: var(--space-xxs); }
  .history-time { text-align: left; }
}

/* ---- article body (D26) ---- */
.article-body {
  font-size: var(--type-article-size);
  line-height: var(--type-article-leading);
  max-width: 70ch;
  color: var(--color-body);
}
.article-headline { font-size: 40px; font-weight: 400; line-height: 1.2; color: var(--color-ink); margin: 0 0 var(--space-sm); }
@media (max-width: 768px) { .article-headline { font-size: 32px; } }

/* ---- forms ---- */
.form-card {
  max-width: 420px;
  margin: var(--space-xxl) auto;
  padding: var(--space-xl);
  border: 1px solid var(--color-muted);
  border-radius: var(--radius-lg);
}
label { display: block; font-size: 14px; font-weight: 500; color: var(--color-ink); margin: var(--space-md) 0 var(--space-xs); }

input[type="text"], input[type="email"], input[type="password"] {
  width: 100%;
  height: var(--touch-min);
  padding: var(--space-sm) var(--space-md);
  font-family: var(--font-stack);
  font-size: 14px;
  color: var(--color-ink);
  background: var(--color-canvas);
  border: 1px solid var(--color-muted);
  border-radius: var(--radius-sm);
}
input:focus-visible {
  outline: 2px solid var(--color-info-border);
  outline-offset: 2px;
  border-color: var(--color-info-border);
}

/* ---- buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: var(--space-md) var(--space-lg);
  font-family: var(--font-stack);
  font-size: 16px;
  font-weight: 500;
  border-radius: var(--radius-lg);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 120ms ease;
}
.btn-primary { background: var(--color-primary); color: var(--color-on-primary); }
.btn-primary:hover { background: var(--color-primary-active); }
.btn-secondary { background: var(--color-canvas); color: var(--color-ink); border-color: var(--color-muted); }
.btn-secondary:hover { background: var(--color-surface-soft); }
.btn:focus-visible { outline: 2px solid var(--color-info-border); outline-offset: 2px; }

/* ---- states ---- */
.error-text { color: var(--color-error); font-size: 14px; margin: var(--space-xs) 0; }
.field-error { border-color: var(--color-error) !important; }
.callout {
  padding: var(--space-lg);
  border-radius: var(--radius-md);
  background: var(--color-signature-cream);
  color: var(--color-ink);
}
.callout-error {
  padding: var(--space-lg);
  border-radius: var(--radius-lg);
  background: var(--color-signature-coral);
  color: var(--color-on-primary);
}
.callout-error a { color: var(--color-on-primary); text-decoration: underline; }

.skeleton {
  height: 96px;
  border-radius: var(--radius-md);
  background: var(--color-surface-soft);
  animation: pulse 1.6s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }

.meta-row {
  font-size: 14px;
  line-height: 1.25;
  color: var(--color-muted);
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}
.meta-row > span + span::before {
  content: "·";
  margin-right: var(--space-sm);
  color: var(--color-surface-strong);
}
.section-title { font-size: 24px; font-weight: 400; color: var(--color-ink); margin: var(--space-xxl) 0 var(--space-md); }

/* error page heading sits on the coral surface */
.error-headline { color: var(--color-on-primary); }

/* ---- disabled states (TEST-AC-233, TEST-AC-243) ---- */
input:disabled, button:disabled, .btn:disabled {
  border-color: var(--color-border-strong); /* disabled */
  color: var(--color-muted);
  cursor: not-allowed;
  opacity: 0.7;
}

/* ---- breadcrumbs ---- */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-sm);
  font-size: 14px;
  color: var(--color-muted);
}
.breadcrumb li + li::before {
  content: "/";
  margin-right: var(--space-xs);
  color: var(--color-surface-strong);
}
.breadcrumb a { color: var(--color-link); }
.breadcrumb a:hover { color: var(--color-link-active); }

/* ---- skip link ---- */
.skip-link {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.skip-link:focus-visible {
  position: fixed;
  top: var(--space-md);
  left: var(--space-md);
  width: auto;
  height: auto;
  padding: var(--space-sm) var(--space-md);
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-radius: var(--radius-sm);
  z-index: 1000;
  clip: auto;
  white-space: normal;
  outline: 2px solid var(--color-info-border);
  outline-offset: 2px;
}

/* ---- spacing utilities ---- */
.mt-xs { margin-top: var(--space-xs); }
.mt-sm { margin-top: var(--space-sm); }
.mt-md { margin-top: var(--space-md); }
.mt-lg { margin-top: var(--space-lg); }
.mt-xl { margin-top: var(--space-xl); }
.mb-xs { margin-bottom: var(--space-xs); }
.mb-sm { margin-bottom: var(--space-sm); }
.mb-md { margin-bottom: var(--space-md); }
.mb-lg { margin-bottom: var(--space-lg); }
.w-full { width: 100%; }
.m-0 { margin: 0; }

/* ---- site footer ---- */
.site-footer {
  border-top: 1px solid var(--color-surface-strong);
  background: var(--color-canvas);
  padding: var(--space-xxl) max(var(--space-lg), calc((100% - var(--layout-max)) / 2 + var(--space-xxl)));
  margin-top: var(--space-section);
}
.footer-content {
  max-width: var(--layout-max);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  font-size: 14px;
  color: var(--color-muted);
  flex-wrap: wrap;
}

/* ---- landing hero section ---- */
.hero-section {
  text-align: center;
  padding: var(--space-section) var(--space-lg);
  max-width: 680px;
  margin: 0 auto;
}
.hero-headline {
  font-size: 40px;
  font-weight: 400;
  line-height: 1.2;
  color: var(--color-ink);
  margin: 0 0 var(--space-md);
}
@media (max-width: 768px) {
  .hero-headline { font-size: 32px; }
  .hero-section { padding: var(--space-xl) var(--space-md); }
}
.hero-sub {
  font-size: 16px;
  line-height: 1.5;
  color: var(--color-muted);
  margin: 0 0 var(--space-xl);
}
.hero-actions {
  display: flex;
  justify-content: center;
  gap: var(--space-md);
  flex-wrap: wrap;
}

/* ---- collapsible nav (TEST-AC-242: collapses below 768px) ---- */
.navmenu { display: contents; }
.navmenu > summary { display: none; }
.navmenu > summary::-webkit-details-marker { display: none; }

/* Chrome renders a closed <details> through a ::details-content box that is
   content-visibility:hidden by default. display:contents on the parent does
   not reach inside it, so the desktop links stayed invisible until here
   (measured: links laid out at 44px tall, zero paint, Chrome 155). */
.navmenu::details-content { content-visibility: visible; display: contents; }

.navburger, .navburger::before, .navburger::after {
  display: block; width: 20px; height: 2px;
  background: var(--color-ink); content: "";
}
.navburger { position: relative; }
.navburger::before { position: absolute; top: -6px; }
.navburger::after  { position: absolute; top: 6px; }

.btn-compact { min-height: 44px; padding: var(--space-xs) var(--space-md); }

@media (max-width: 767px) {
  .navmenu { display: block; position: relative; }
  .navmenu > summary {
    display: flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; cursor: pointer;
    border: 1px solid var(--color-muted); border-radius: var(--radius-sm);
  }
  .navmenu > summary:focus-visible {
    outline: 2px solid var(--color-info-border); outline-offset: 2px;
  }
  .navlinks {
    display: none;
    position: absolute; right: 0; top: calc(100% + var(--space-xs));
    min-width: 200px; padding: var(--space-md);
    flex-direction: column; align-items: stretch; gap: var(--space-sm);
    background: var(--color-canvas);
    border: 1px solid var(--color-muted);
    border-radius: var(--radius-md);
    z-index: 10;
  }
  .navmenu[open] > .navlinks { display: flex; }
  .navlinks a { padding: var(--space-xs) 0; }
}
