/* ============================================================
   THE CENSUS ARCHIVE

   Structure ported from the live results page, restyled onto the redesign's
   scale and palette. Tokens come from juq.css and system.css; nothing here
   redefines a colour or a step.

   EVERY CLASS IS PREFIXED, INCLUDING THE ONES INSIDE A ROW. An earlier version
   used bare `.lab` for the answer label, and juq.css turns out to own a global
   `.lab` (the lab component) carrying a dashed border, generous padding and a
   top margin. Every answer label silently inherited all three, which is what
   made the rows tall and dropped the label below the bar it was supposed to
   sit beside. Nothing here may use a bare class name, however local it looks.
   See juq.css for the rule this collided with.

   The mockup's `.cs-theme` pills became rows, so 31% and 4% no longer look
   alike. Its trends section is gone for now: with one edition there is nothing
   to chart, and an empty state explaining that was taking up more room than it
   was worth.
   ============================================================ */

/* ---------- editions + the meta line ---------- */
.cs-eds { display:flex; gap:var(--s-2); flex-wrap:wrap; margin:var(--s-6) 0 var(--s-3); }
.cs-ed {
  display:flex; flex-direction:column; gap:1px; align-items:flex-start;
  padding:var(--s-2) var(--s-4); cursor:pointer; font:inherit; text-align:left;
  border:var(--bw) solid var(--line-strong); border-radius:var(--radius);
  background:var(--surface); color:var(--ink);
}
.cs-ed b { font-size:var(--t-sm); font-weight:800; font-style:italic; text-transform:uppercase; }
.cs-ed span { font-family:var(--f-mono); font-size:var(--t-label); letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
.cs-ed[aria-pressed="true"] { background:var(--accent); border-color:var(--accent); color:var(--accent-ink); }
.cs-ed[aria-pressed="true"] span { color:var(--accent-ink); opacity:.75; }
.cs-ed:disabled { cursor:default; opacity:.5; }
/* The one that is actually running. It is a link, not a filter, so it is marked
   rather than pressed: everything else on this row changes the page below, this
   one leaves it. */
.cs-ed-live { text-decoration:none; border-color:var(--accent); color:var(--accent); }
.cs-ed-live span { color:var(--accent); }
.cs-ed-live:hover { background:var(--accent); border-color:var(--accent); color:var(--accent-ink); }
.cs-ed-live:hover span { color:var(--accent-ink); opacity:.75; }

.cs-heads { display:flex; flex-wrap:wrap; gap:var(--s-5); margin-bottom:var(--s-5); }
.cs-heads span { font-family:var(--f-mono); font-size:var(--t-label); letter-spacing:.12em; text-transform:uppercase; color:var(--muted); }

/* ---------- the quick stats ----------
   Eight cards on a FIXED four-column grid, so they read as two rows of four
   the way the live page does. auto-fit was wrong here: on a wide screen it
   spread seven across one line and orphaned the eighth. */
.cs-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s-3); margin-bottom:var(--s-7); }
.cs-stat {
  display:flex; flex-direction:column; gap:var(--s-2); align-items:flex-start;
  padding:var(--s-4) var(--s-5); font:inherit; text-align:left;
  border:var(--bw) solid var(--line-strong); border-radius:var(--radius);
  background:var(--surface); color:var(--ink);
}
/* A streamer name or a game title is far longer than "126", so the value steps
   down the scale rather than overflowing. Same idea as the live page. */
.cs-stat b { font-family:var(--f-mono); font-size:var(--t-h1); font-weight:800; line-height:1; letter-spacing:-.02em; font-variant-numeric:tabular-nums; color:var(--accent); overflow-wrap:anywhere; }
.cs-stat b.cs-stat-md { font-size:var(--t-h2); }
.cs-stat b.cs-stat-sm { font-size:var(--t-lg); line-height:1.2; }
.cs-stat span { font-family:var(--f-mono); font-size:var(--t-label); letter-spacing:.12em; text-transform:uppercase; color:var(--muted); }
.cs-stat-link { cursor:pointer; }
.cs-stat-link:hover { border-color:var(--accent); }
.cs-stat:disabled { cursor:default; }

@media (max-width: 900px) { .cs-stats { grid-template-columns:repeat(2,1fr); } }

/* ---------- sections ----------
   ANYTHING SCROLLED TO HAS TO CLEAR THE NAVBAR. juq.css sets .nav to
   position:sticky with a 62px bar, so scrollIntoView({block:'start'}) parks
   the target's top at the viewport top, which is UNDERNEATH the navbar: the
   question title and its first rows end up hidden behind it. That is why
   closing a long list kept landing a smidge low, and the quick-stat jump links
   had the same problem more quietly. 62px is the bar, the rest is breathing
   room so the heading is not flush against it. */
:root { --cs-anchor: calc(62px + var(--s-7)); }
.cs-sec { margin-bottom:var(--s-8); scroll-margin-top:var(--cs-anchor); }
.cs-q { scroll-margin-top:var(--cs-anchor); }
.cs-sech { display:flex; align-items:center; gap:var(--s-4); margin-bottom:var(--s-4); }
.cs-sech h2 { margin:0; font-size:var(--t-h2); font-weight:800; font-style:italic; text-transform:uppercase; letter-spacing:-.02em; }
.cs-sech::after { content:''; flex:1; height:2px; background:var(--line-strong); }

/* ONE QUESTION PER ROW, NOT A GRID. A narrow column is fine for a five-option
   question and unreadable for a hundred-option one. */
.cs-qs { display:flex; flex-direction:column; gap:var(--s-3); }
.cs-q { padding:var(--s-4) var(--s-5) var(--s-5); border:var(--bw) solid var(--line-strong); border-radius:var(--radius); background:var(--surface); }
/* Closing a list moves nothing, so the question needs to say where it is.
   Border colour only: a glow or a lift would be one more thing sliding
   around, which is the exact problem this replaced. */
@keyframes csFound {
  from { border-color:var(--accent); }
  to   { border-color:var(--line-strong); }
}
.cs-found { animation:csFound 1.1s ease-out; }
@media (prefers-reduced-motion: reduce) { .cs-found { animation:none; } }
.cs-qh { display:flex; align-items:baseline; gap:var(--s-4); margin-bottom:var(--s-3); }
.cs-qh h3 { margin:0; font-size:var(--t-md); font-weight:800; }
.cs-qn { margin-left:auto; font-family:var(--f-mono); font-size:var(--t-label); letter-spacing:.1em; text-transform:uppercase; color:var(--muted); white-space:nowrap; }

/* ---------- the bars ----------
   One series, so no legend and no palette: a second hue would imply a
   distinction that does not exist. Every row is the same measurement. */
.cs-rows { display:flex; flex-direction:column; }
.cs-row {
  display:grid; grid-template-columns:minmax(96px,200px) 1fr auto;
  gap:var(--s-4); align-items:center;
  padding:3px var(--s-3); border-radius:var(--radius);
  color:inherit; text-decoration:none; min-height:26px;
}
/* Alternating rows, which is what makes a long list scannable across its
   width. Computed in JS rather than :nth-child so the striping keeps running
   across the fold boundary instead of restarting when it opens. */
.cs-row.cs-alt { background:var(--surface-2); }
/* THE LIFT IS NOT OPTIONAL. An outline is painted outside the box and does not
   take up space, so the next row in the list paints its own background right
   over the bottom edge and the highlight looks like it is missing a side.
   Raising the hovered row puts its outline above its neighbours. */
a.cs-row:hover { outline:var(--bw) solid var(--accent); position:relative; z-index:1; }
.cs-lab { display:flex; align-items:center; gap:var(--s-3); font-size:var(--t-md); line-height:1.3; min-width:0; }
/* ONE LINE, ALWAYS. A movie title can run to a full sentence of Japanese, and
   letting it wrap made that single row four times the height of its
   neighbours and broke the alternating rhythm down the whole card. The full
   text is on the tooltip. */
.cs-labt { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
/* Artwork the answer was picked with: profile pictures, box art, posters,
   7TV emotes. Small on purpose, it identifies the row rather than decorating
   it. Emotes are wider than they are tall, so the box is square and the image
   fits inside it rather than being cropped to it. */
.cs-ico { width:20px; height:20px; flex:0 0 20px; object-fit:contain; border-radius:2px; background:var(--surface-2); }
.cs-val { font-family:var(--f-mono); font-size:var(--t-md); font-weight:800; font-variant-numeric:tabular-nums; text-align:right; white-space:nowrap; }
.cs-cnt { margin-left:var(--s-3); color:var(--muted); font-weight:400; }
.cs-trk { height:8px; background:var(--track); border-radius:var(--radius); overflow:hidden; }
.cs-fill { display:block; height:100%; background:var(--accent); border-radius:0 var(--radius) var(--radius) 0; }

@media (max-width: 560px) {
  .cs-row { grid-template-columns:1fr auto; gap:2px var(--s-4); }
  .cs-trk { grid-column:1 / -1; }
}

/* The fold. Height is animated by census.js and released back to auto, so
   nothing here may set a height. */
.cs-fold[hidden] { display:none; }
.cs-more {
  margin-top:var(--s-5); cursor:pointer; font:inherit;
  font-family:var(--f-mono); font-size:var(--t-label); letter-spacing:.1em; text-transform:uppercase;
  padding:var(--s-2) var(--s-4); border:var(--bw) solid var(--line-strong);
  border-radius:var(--radius); background:transparent; color:var(--muted);
}
.cs-more:hover { border-color:var(--accent); color:var(--ink); }

.cs-detail { margin-top:var(--s-5); padding-top:var(--s-4); border-top:var(--bw) dashed var(--line-strong); }
.cs-detail-h { font-family:var(--f-mono); font-size:var(--t-label); letter-spacing:.14em; text-transform:uppercase; color:var(--muted); margin-bottom:var(--s-3); }
/* One region, its places under it. Grouped so a country and a state inside
   another country never share a ranking. */
.cs-region + .cs-region { margin-top:var(--s-5); }
.cs-region-h { display:flex; align-items:baseline; gap:var(--s-3); font-size:var(--t-md); font-weight:800; margin-bottom:var(--s-2); }
.cs-region-n { margin-left:auto; font-family:var(--f-mono); font-size:var(--t-label); letter-spacing:.1em; color:var(--accent); }

/* A follow-up: the rest of a question, revealed by a particular answer. Inside
   the parent's card and indented off it, so it reads as part of that question
   rather than a new one. */
.cs-sub { margin-top:var(--s-4); padding-left:var(--s-5); border-left:2px solid var(--line-strong); }
.cs-sub-h { display:flex; align-items:baseline; gap:var(--s-3); font-family:var(--f-mono); font-size:var(--t-label); letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin-bottom:var(--s-2); }
.cs-sub-gap { margin-top:var(--s-5); }
.cs-sub-n { margin-left:auto; color:var(--accent); font-weight:700; }
.cs-dim { color:var(--muted); font-family:var(--f-mono); font-size:var(--t-sm); }
.cs-help { font-family:var(--f-mono); font-size:var(--t-mono); line-height:1.6; color:var(--muted); margin:0 0 var(--s-4); }
/* A follow-up whose whole answer is a Read-all button had the button's own
   top margin stacked under the heading's bottom margin, which opened a gap
   wider than the block itself. */
.cs-sub .cs-readall { margin-top:0; }

/* WHO THEY ARE: one bar, four segments. The only place on the page a second
   hue is justified, because these are four different KINDS of person rather
   than one measurement repeated.

   FIXED ACROSS SKINS, on the same argument as higher-lower.css: these four are
   a categorical palette carrying identity, and a category that changes colour
   between themes stops being a category. Derived from Okabe-Ito, then checked
   with the palette validator against the dark surface: worst adjacent pair is
   9.6 deltaE under deuteranopia and 16.9 with normal vision, both clear of the
   floors, and every segment clears 3:1 on contrast.

   Two validator complaints are accepted knowingly. The lightness band wants
   them closer together, but on a dark surface these need to be bright. And the
   grey "reads gray", which is the entire point of it: a lurker is the absence
   of chat, and colouring them like a participant would be the lie. Every
   segment is also directly labelled with its name and share in the legend, so
   colour is never the only thing carrying the meaning. */
:root {
  --cs-seg-lurk:#7f8189;   /* barely there, so barely a colour */
  --cs-seg-live:#56b4e9;   /* talks while he is live */
  --cs-seg-off:#cc79a7;    /* only turns up when he is OFFLINE, the odd one */
  --cs-seg-both:#e69f00;   /* never stops. the hottest, because it is the most */
}
.cs-seg { display:flex; height:14px; border-radius:var(--radius); overflow:hidden; background:var(--track); }
.cs-seg i { display:block; height:100%; }
.cs-seglegend { display:flex; flex-wrap:wrap; gap:var(--s-5); margin-top:var(--s-3); }
.cs-seglegend span { display:inline-flex; align-items:center; gap:var(--s-3); font-family:var(--f-mono); font-size:var(--t-label); letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
.cs-seglegend i { width:12px; height:10px; border-radius:2px; }

/* ---------- height and weight ----------
   Both units render up front and the toggle swaps which shows, so switching
   never needs the data again. */
.cs-units { display:inline-flex; margin-bottom:var(--s-4); border:var(--bw) solid var(--line-strong); border-radius:var(--radius); overflow:hidden; }
.cs-unit {
  cursor:pointer; font:inherit; font-family:var(--f-mono); font-size:var(--t-mono);
  letter-spacing:.08em; text-transform:uppercase; padding:var(--s-2) var(--s-4);
  border:0; background:transparent; color:var(--muted);
}
.cs-unit + .cs-unit { border-left:var(--bw) solid var(--line-strong); }
.cs-unit.on { background:var(--accent); color:var(--accent-ink); }
.cs-mstats { display:flex; flex-wrap:wrap; gap:var(--s-3); }
.cs-mstat { flex:1 1 120px; padding:var(--s-3) var(--s-4); border:var(--bw) solid var(--line-strong); border-radius:var(--radius); background:var(--surface-2); }
.cs-mk { display:block; font-family:var(--f-mono); font-size:var(--t-label); letter-spacing:.12em; text-transform:uppercase; color:var(--muted); margin-bottom:2px; }
.cs-mv { font-family:var(--f-mono); font-size:var(--t-h3); font-weight:800; font-variant-numeric:tabular-nums; color:var(--accent); }

/* ---------- the clock ---------- */
.cs-headline { font-size:var(--t-md); margin-bottom:var(--s-4); }
.cs-headline strong { color:var(--accent); }
.cs-clock { display:flex; align-items:flex-end; gap:2px; height:80px; margin-bottom:var(--s-7); }
.cs-ccol { flex:1; display:flex; flex-direction:column; justify-content:flex-end; align-items:center; height:100%; position:relative; }
.cs-cbar { width:100%; min-height:2px; background:var(--accent); border-radius:var(--radius) var(--radius) 0 0; }
.cs-ctick { position:absolute; bottom:-15px; font-family:var(--f-mono); font-size:var(--t-label); color:var(--muted); white-space:nowrap; }

/* ---------- free text ----------
   The AI reading and the answers themselves are two different kinds of thing,
   so the summary is boxed and labelled and the answers sit outside it. Inside
   the box is a machine's approximation that can be wrong; below it are the
   sentences people actually wrote, which are not. Running them together would
   invite a reader to take the summary for the data. */
.cs-ai { border:var(--bw) solid var(--line-strong); border-left:3px solid var(--accent); border-radius:var(--radius); background:var(--surface-2); padding:var(--s-4) var(--s-5); }
.cs-ai-h { display:flex; align-items:baseline; gap:var(--s-3); margin-bottom:var(--s-3); }
.cs-ai-tag { font-family:var(--f-mono); font-size:var(--t-label); font-weight:700; letter-spacing:.14em; text-transform:uppercase; color:var(--accent); }
.cs-ai-src { font-family:var(--f-mono); font-size:var(--t-label); letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
.cs-ai-note { font-family:var(--f-mono); font-size:var(--t-mono); color:var(--muted); margin:var(--s-3) 0 0; }
.cs-text { font-size:var(--t-md); color:var(--ink); line-height:1.55; margin:0; font-style:italic; }
.cs-themes { margin-top:var(--s-4); }
.cs-fine { margin-top:var(--s-3); font-size:var(--t-sm); }

/* The written answers. Shuffled server-side, so reading two questions cannot
   line up one person's submission. */
.cs-quotes { display:flex; flex-direction:column; gap:var(--s-2); padding-top:var(--s-4); }
.cs-quote {
  margin:0; padding:var(--s-3) var(--s-4); font-size:var(--t-md); line-height:1.5;
  background:var(--surface-2); border-left:2px solid var(--line-strong);
  border-radius:0 var(--radius) var(--radius) 0; overflow-wrap:anywhere;
}
.cs-readall { margin-top:var(--s-4); }

/* A clip row is a button, so it needs the full button reset before it can look
   like the rows either side of it. BACKGROUND IS THE IMPORTANT ONE: without
   it the browser's default button face wins, which on the dark skin painted
   every unstriped clip row white and hid its white label inside it. */
.cs-rowclip { width:100%; font:inherit; color:inherit; border:0; background:transparent; text-align:left; cursor:pointer; }
.cs-rowclip.cs-alt { background:var(--surface-2); }
.cs-rowclip:hover { outline:var(--bw) solid var(--accent); position:relative; z-index:1; }
.cs-rowclip:hover .cs-labt { color:var(--accent); }


/* The clip player inside the shared modal. */
.cs-embed { position:relative; aspect-ratio:16/9; width:100%; background:var(--surface-2); border-radius:var(--radius); overflow:hidden; }
.cs-embed iframe { position:absolute; inset:0; width:100%; height:100%; border:0; }

/* ---------- closing notes ---------- */
.cs-foot { border-top:var(--bw) solid var(--line); padding:var(--s-6) 0 var(--s-10); color:var(--muted); font-size:var(--t-sm); }
.cs-foot b { color:var(--ink); }
.cs-foot p { max-width:78ch; }

/* Every class above that sets `display` beats the browser's own [hidden]
   rule, so hiding one of these with the attribute silently does nothing.
   This has caught this project four separate times. */
.cs-eds[hidden], .cs-heads[hidden], .cs-stats[hidden], .cs-stat[hidden],
.cs-qs[hidden], .cs-rows[hidden], .cs-row[hidden], .cs-mstats[hidden],
.cs-mstat[hidden], .cs-units[hidden], .cs-clock[hidden],
.cs-ed[hidden], .cs-sech[hidden],
.cs-qh[hidden] { display:none; }

/* ---------- insights ----------
   The cross-tabs, last on the page: they mix answers together, so they only
   make sense once each question has been read on its own. */
.cs-readnote {
  font-family: var(--f-mono); font-size: var(--t-mono); line-height: 1.7;
  color: var(--muted); max-width: 78ch; margin: 0 0 var(--s-5);
}
.cs-mblock + .cs-mblock, .cs-mclock + .cs-mclock { margin-top: var(--s-5); }
.cs-mblock .cs-sub-h, .cs-mclock .cs-sub-h { margin-bottom: var(--s-3); }
/* A measured figure carries its own denominator, so the quiet half sits
   beside it rather than under a shared percentage the way an answer count
   does. */
.cs-mblock .cs-val { display: inline-flex; align-items: baseline; gap: var(--s-3); }
.cs-mclock .cs-clock { margin-bottom: var(--s-7); }

/* ---------- the live vs offline scatter ----------
   One dot per measured viewer. Both axes are logarithmic, so the plot area is
   just a box with two rules on it: the quadrant lines sit wherever the data
   says the thresholds fall, positioned inline by census.js. */
.cs-scatter {
  position: relative; height: 230px; margin: var(--s-4) var(--s-4) var(--s-6) var(--s-6);
  border-left: var(--bw) solid var(--line-strong);
  border-bottom: var(--bw) solid var(--line-strong);
}
/* Centred on its coordinate by transform rather than a negative margin of
   half its size, so the dot can be resized without the offset going stale. */
.cs-pt {
  position: absolute; width: 8px; height: 8px; border-radius: 50%;
  transform: translate(-50%, 50%);
  background: var(--accent); opacity: .45; cursor: pointer;
}
.cs-pt:hover { opacity: 1; }
.cs-xline { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line-strong); pointer-events: none; }
.cs-yline { position: absolute; left: 0; right: 0; height: 1px; background: var(--line-strong); pointer-events: none; }
.cs-quad {
  position: absolute; pointer-events: none;
  font-family: var(--f-mono); font-size: var(--t-label); letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); opacity: .75;
}
.cs-q-tl { top: 4px; left: 6px; }
.cs-q-tr { top: 4px; right: 6px; }
.cs-q-bl { bottom: 4px; left: 6px; }
.cs-q-br { bottom: 4px; right: 6px; }
