/* ---------------------------------------------------------------
   Reader page styling.

   Typography, type scale and palette are taken from the work screen in
   index.html (#work) rather than from article.css: Instrument Sans over
   the --p-* tokens, not Source Serif 4 over Paper & Ink. That screen is
   already a numbered list of title / description / meta rows, which is
   the shape of a story list, so the scale transfers directly.

   Values below are copied from index.html verbatim so the two stay
   recognisably the same page. Where this file deviates, it says so.

   This stylesheet is self-contained — the page does not load
   article.css, which would otherwise bring the serif and the old
   palette back in.
   --------------------------------------------------------------- */

/* Instrument Sans is the work screen's face. Both files are variable
   across wght 400-700, declared at the range the files actually carry. */
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal; font-weight: 400 700; font-display: swap;
  src: url('fonts/instrument-sans.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: italic; font-weight: 400 700; font-display: swap;
  src: url('fonts/instrument-sans-italic.woff2') format('woff2-variations');
}
/* code only, where fixed advance width carries meaning */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal; font-weight: 400 700; font-display: swap;
  src: url('fonts/jetbrains-mono-400.woff2') format('woff2');
}

:root {
  color-scheme: light;

  /* The work screen's light-scene tokens — one per role, copied from
     body.light-scene in index.html. */
  --p-ink:    #141a20;
  --p-soft:   #2f3843;
  --p-body:   #39434e;
  --p-meta:   #3f4954;
  --p-accent: #08414a;
  --p-rule:   rgba(20, 26, 32, .2);
  --p-wash:   rgba(8, 65, 74, .08);
  --p-chrome: rgba(255, 255, 255, .55);
  --p-chrome-line: rgba(20, 26, 32, .3);

  /* The ground index.html paints on arrival at #work, standing in for the
     coral canvas until WebGL draws. With no canvas here it is simply the
     page colour. */
  --ground: #d3dae2;

  --sans: 'Instrument Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, monospace;

  --measure: 940px;   /* .portal's max-width */
}

/* A class that sets `display` outranks the UA stylesheet's
   [hidden] { display: none }, so .filters and .controls-row would stay on
   screen while carrying the attribute. Tab switching relies on `hidden`
   meaning hidden, so make it win. */
[hidden] { display: none !important; }

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--ground);
  color: var(--p-body);
  font-family: var(--sans);
  font-size: 17.5px;
  line-height: 1.5;
  -webkit-font-smoothing: auto;
}

.wrap { max-width: var(--measure); margin: 0 auto; padding: 0 24px; }

a { color: var(--p-accent); text-decoration: none; border-bottom: 1px solid rgba(8, 65, 74, .3); }
a:hover { border-bottom-color: var(--p-accent); }
a:focus-visible { outline: 2px solid var(--p-accent); outline-offset: 3px; border-radius: 1px; }

/* ---------- top bar ---------- */

/* The work screen has no bar, only a floating Back control. Its treatment
   — chrome fill, chrome line, 10px/500 at .18em — is what this borrows. */
.topbar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: 13px 24px;
  background: var(--p-chrome);
  border-bottom: 1px solid var(--p-chrome-line);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  font-family: var(--sans); font-size: 10px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
}
.topbar a { color: var(--p-meta); border: 0; }
.topbar a:hover { color: var(--p-accent); }
.topbar .mark { color: var(--p-ink); letter-spacing: .22em; }

/* ---------- head ---------- */

/* .portal's own padding: clamp(80px,14vh,150px) top. Set as a longhand,
   not the `padding` shorthand — the shorthand would zero the 24px side
   gutter .wrap applies to the same element and pull the head out of line
   with the list below it. */
.head { padding-top: clamp(64px, 11vh, 120px); }

.eyebrow {
  font-family: var(--sans); font-size: 10.5px; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase; color: var(--p-accent);
}
h1 {
  font-family: var(--sans); font-weight: 600; color: var(--p-ink);
  font-size: clamp(30px, 5vw, 52px); line-height: 1.06; letter-spacing: -.018em;
  margin: 14px 0 10px; text-wrap: balance;
}
.standfirst {
  font-size: 17.5px; line-height: 1.5; color: var(--p-soft); max-width: 60ch;
}

/* ---------- tabs ---------- */

.tabs {
  display: flex; gap: 4px;
  margin-top: 34px;
  border-bottom: 1px solid var(--p-rule);
}
.tab {
  font-family: var(--sans); font-size: 10px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--p-meta); background: transparent;
  border: 0; border-bottom: 2px solid transparent;
  padding: 12px 16px; margin-bottom: -1px; cursor: pointer;
}
.tab:hover { color: var(--p-accent); }
.tab:focus-visible { outline: 2px solid var(--p-accent); outline-offset: -2px; border-radius: 2px; }
.tab[aria-selected="true"] { color: var(--p-ink); border-bottom-color: var(--p-accent); }

/* ---------- controls ---------- */

.controls { padding-top: 20px; }
.controls-row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }

.digest-lede {
  flex: 1 1 320px; min-width: 0;
  font-size: 15.5px; line-height: 1.55; color: var(--p-body); max-width: 52ch;
}

.search {
  flex: 1 1 260px; min-width: 0;
  font-family: var(--sans); font-size: 15.5px; color: var(--p-ink);
  background: var(--p-chrome);
  border: 1px solid var(--p-rule); border-radius: 2px;
  padding: 10px 14px;
}
.search::placeholder { color: var(--p-meta); opacity: .75; }
.search:focus-visible { outline: 2px solid var(--p-accent); outline-offset: 2px; border-color: var(--p-accent); }

.btn {
  font-family: var(--sans); font-size: 10px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--p-ink); background: var(--p-chrome);
  border: 1px solid var(--p-chrome-line); border-radius: 2px;
  padding: 9px 15px 8px; cursor: pointer;
}
.btn:hover:not(:disabled) { color: var(--p-accent); border-color: var(--p-accent); }
.btn:focus-visible { outline: 2px solid var(--p-accent); outline-offset: 3px; }
.btn:disabled { opacity: .5; cursor: default; }

.filters { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; padding: 0; list-style: none; }
.chip {
  font-family: var(--sans); font-size: 10px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--p-meta); background: transparent;
  border: 1px solid var(--p-rule); border-radius: 999px;
  padding: 7px 14px; cursor: pointer;
}
.chip:hover { color: var(--p-accent); border-color: var(--p-accent); }
.chip:focus-visible { outline: 2px solid var(--p-accent); outline-offset: 2px; }
.chip[aria-pressed="true"] { color: #f4f7fa; background: var(--p-accent); border-color: var(--p-accent); }
.chip .n { opacity: .6; margin-left: 6px; }
.chip[aria-pressed="true"] .n { opacity: .75; }
.chip[data-status="error"] { text-decoration: line-through; opacity: .55; }

.status {
  margin-top: 16px;
  font-family: var(--sans); font-size: 10px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--p-meta);
}

/* ---------- story list ---------- */

/* .entries in index.html: rules top and bottom, rows that wash and shift
   right on hover. */
.stories {
  list-style: none; padding: 0;
  margin: 30px 0 0;
  border-top: 1px solid var(--p-rule);
}

/* Denser than index.html's .entries, which pads 24px and sets its title at
   up to 29px. A work screen shows six projects and can afford the air; a
   reader shows seventy stories and is scanned rather than read, so the
   scale steps down and the gaps close. Face, weights, tracking and colour
   are unchanged — this is the same system set tighter, not a second one. */
.story {
  border-bottom: 1px solid var(--p-rule);
  padding: 13px 8px;
  transition: background .25s ease, padding .25s ease;
}
.story:hover { background: var(--p-wash); padding-left: 16px; }
@media (prefers-reduced-motion: reduce) { .story { transition: none; } }

/* .entries .m — 10px/500 at .14em. Kept inside the content column rather
   than in a third grid track: in index.html that track holds a year and is
   dropped on mobile, but a story's source is not disposable. */
.story-meta {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 3px 9px;
  font-family: var(--sans); font-size: 10px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--p-meta);
}
.story-meta .src { color: var(--p-accent); }
.story-meta .dot { opacity: .45; }

/* .entries .t, stepped down. Tracking eases from -.014em to -.011em with
   the size: tight negative tracking that reads as confident at 29px starts
   closing counters at 20px. */
.story-title {
  margin-top: 4px;
  font-family: var(--sans); font-weight: 600;
  font-size: clamp(17px, 1.9vw, 20px); line-height: 1.26; letter-spacing: -.011em;
  color: var(--p-ink); text-wrap: balance;
}
.story-title a { color: inherit; border-bottom: 1px solid transparent; }
.story:hover .story-title a { color: var(--p-accent); }
.story-title a:focus-visible { outline: 2px solid var(--p-accent); outline-offset: 2px; }

/* .entries .d. The measure widens as the size drops — a longer line at
   14.5px costs no legibility and turns a three-line excerpt into two. */
.story-summary {
  margin-top: 4px;
  font-size: 14.5px; line-height: 1.45; color: var(--p-body); max-width: 62ch;
}

/* ---------- ranked stories (Summary tab) ---------- */

/* .entries a is a 54px / 1fr / auto grid whose first track holds the entry
   number. The rank sits in that same track, narrowed to 38px along with
   everything else on this page — a two-digit rank needs less room than a
   work screen's entry number. */
.story.ranked { position: relative; padding-left: 38px; }
.story.ranked:hover { padding-left: 44px; }
.story.ranked .rank {
  position: absolute; left: 8px; top: 13px;
  font-family: var(--sans); font-size: 11px; font-weight: 500;
  letter-spacing: .14em; color: var(--p-accent);
  font-variant-numeric: tabular-nums;
}
.story.ranked:hover .rank { left: 14px; }

.badge {
  font-family: var(--sans); font-size: 9.5px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase;
  color: #f4f7fa; background: var(--p-accent);
  border-radius: 2px; padding: 2px 6px;
}

.also {
  margin-top: 6px;
  font-family: var(--sans); font-size: 10px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--p-meta);
}
.also a { color: var(--p-accent); border-bottom-color: rgba(8, 65, 74, .3); }

/* Marks an excerpt a model wrote rather than the publisher. Hidden until
   summaries start arriving as summarySource: 'ai'. */
.tag-ai {
  font-family: var(--sans); font-size: 9.5px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--p-accent);
  border: 1px solid rgba(8, 65, 74, .4); border-radius: 2px; padding: 1px 5px;
}

/* ---------- colophon ---------- */

.foot { padding-top: 64px; padding-bottom: 90px; }   /* longhand, as .head */
.foot .rule { height: 1px; background: var(--p-rule); margin-bottom: 26px; }

.colophon { display: grid; gap: 32px; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); }
.colophon-h {
  font-family: var(--sans); font-size: 10.5px; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase; color: var(--p-accent);
  margin-bottom: 12px;
}
.colophon p { font-size: 15.5px; line-height: 1.55; color: var(--p-body); max-width: 52ch; }
.colophon-back { margin-top: 16px; }
.colophon-back a {
  font-family: var(--sans); font-size: 10px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase;
}

.source-list { list-style: none; padding: 0; font-size: 15.5px; color: var(--p-body); }
.source-list li + li { margin-top: 7px; }
.source-list a { color: var(--p-body); border-bottom-color: rgba(57, 67, 78, .28); }
.source-list a:hover { color: var(--p-accent); border-bottom-color: var(--p-accent); }
.source-down {
  font-family: var(--sans); font-size: 9.5px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--p-accent); opacity: .8;
}

/* ---------- states ---------- */

.note {
  margin-top: 22px; padding: 18px 22px;
  background: var(--p-wash); border: 1px solid var(--p-rule); border-radius: 2px;
  font-size: 15.5px; line-height: 1.55; color: var(--p-body);
}
.note b { color: var(--p-ink); font-weight: 600; }
.note code {
  font-family: var(--mono); font-size: .82em; color: var(--p-accent);
  background: rgba(8, 65, 74, .09); padding: 2px 6px; border-radius: 2px;
}

/* Skeleton rows, so first paint has the shape of the list rather than a
   spinner sitting in empty space. */
.skeleton { padding: 13px 8px; border-bottom: 1px solid var(--p-rule); }
.skeleton span {
  display: block; height: 11px; border-radius: 2px;
  background: linear-gradient(90deg, rgba(20,26,32,.08) 0%, rgba(20,26,32,.16) 50%, rgba(20,26,32,.08) 100%);
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}
.skeleton .s-meta  { width: 32%; }
.skeleton .s-title { width: 88%; height: 16px; margin-top: 8px; }
.skeleton .s-body  { width: 96%; margin-top: 9px; }
.skeleton .s-body2 { width: 64%; margin-top: 6px; }
@keyframes shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) { .skeleton span { animation: none; } }

/* ---------- narrow ---------- */

@media (max-width: 640px) {
  /* index.html narrows the entry number track from 54px to 34px here; this
     page steps its own 38px down in proportion. */
  .story.ranked { padding-left: 30px; }
  .story.ranked:hover { padding-left: 34px; }
  .story.ranked .rank { left: 0; }
  .story.ranked:hover .rank { left: 4px; }
  .colophon { grid-template-columns: 1fr; gap: 28px; }
}
