:root {
  --bg: #1b1a17;
  --paper: #23221e;
  --ink: #d8cfb8;
  --ink-dim: #948a74;
  --accent: #b8905a;
  --line: #3a382f;
  --mono: ui-monospace, "Cascadia Mono", "Consolas", "Liberation Mono", "SFMono-Regular", Menlo, monospace;
}

* { box-sizing: border-box; }

/*
 * Font size option: `html`'s font-size is the one source of truth. Every
 * other font-size in this file is in `rem`, i.e. relative to it, so the
 * 3-way toggle in the footer (app.js sets `document.documentElement.style.
 * fontSize`) scales the whole page at once. 15px is the default ("md").
 */
html {
  font-size: 15px;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--mono);
}

body {
  font-size: 1rem;
}

.crt {
  max-width: 760px;
  margin: 0 auto;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
}

/*
 * .layout places the 4 top-level sections (links / weather / football /
 * news) using named grid-area strings -- each string below is literally a
 * sketch of the page: edit it to reorder or reshuffle sections, the actual
 * CSS properties on .links/.weather/.football/.news never need to change.
 *
 * Mobile (default): one column, top-to-bottom as drawn below.
 * Wide screens (see media query further down): weather/football move to
 * side rails flanking a centered links+news column.
 */
.layout {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto auto auto auto auto 1fr;
  grid-template-areas:
    "links"
    "weather"
    "radio"
    "football"
    "laws"
    "news";
}

.links    { grid-area: links; }
.weather  { grid-area: weather; }
.radio    { grid-area: radio; }
.football { grid-area: football; }
.laws     { grid-area: laws; }
.news     { grid-area: news; min-width: 0; }

/* mobile: inert, just makes weather+radio (and football+laws) act like
   plain, separately ordered grid items (see the media query below for
   their wide-screen job) */
.weather-rail,
.scores-rail {
  display: contents;
}

/* on wide screens, give weather+radio and football their own side rails
   instead of stacking everything in one narrow column -- avoids big
   empty margins */
@media (min-width: 1000px) {
  .crt {
    max-width: 1160px;
    border-left: none;
    border-right: none;
  }

  .layout {
    grid-template-columns: 220px minmax(0, 760px) 220px;
    grid-template-rows: auto 1fr;
    column-gap: 24px;
    justify-content: center;
    grid-template-areas:
      "weather links   football"
      "weather news    football";
  }

  /* .weather-rail and .scores-rail each occupy a full-height side column as
     ONE grid item spanning all rows, symmetric with each other -- any
     content that grows inside them (a standings panel, a law's vote
     history, the radio widget) only grows that rail's own flex height and
     never touches the grid's row track sizing. Asymmetric spans here (e.g.
     one rail spanning all rows while the other was split into two
     differently-sized grid items) are what previously caused expanding
     content to inflate unrelated rows and stretch .links -- keep each side
     as a single spanning flex column to avoid that. */
  .weather-rail,
  .scores-rail {
    display: flex;
    flex-direction: column;
    gap: 12px;
    align-self: start;
  }

  .weather-rail {
    grid-area: weather;
  }

  .scores-rail {
    grid-area: football;
  }

  /* .weather/.radio/.football/.laws are flex children of their rail now,
     not grid children of .layout -- keep the flex default (stretch to the
     rail's full width). */
  .weather,
  .radio,
  .football,
  .laws {
    border: 1px solid var(--line);
  }

  /* side by side under the scores instead of stacked */
  .laws {
    flex-direction: row;
  }

  .law-category {
    flex: 1;
    min-width: 0;
  }

  /* only draws a divider when there are two categories side by side --
     currently just Spain, so :only-child skips it until US comes back */
  .law-category:not(:only-child):first-child {
    border-right: 1px solid var(--line);
  }

  .links,
  .news {
    border-left: 1px solid var(--line);
    border-right: 1px solid var(--line);
  }
}

.bar {
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
  letter-spacing: 0.02em;
}

.foot {
  border-bottom: none;
  border-top: 1px solid var(--line);
  margin-top: auto;
  font-size: 0.8rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* header text (title + joke line) stays centered regardless of how wide
   the surrounding .crt container gets on large screens */
header.bar {
  text-align: center;
}

.prompt-row { display: flex; align-items: baseline; justify-content: center; }

.prompt { color: var(--accent); }

.otd {
  margin-top: 6px;
  font-size: 0.767rem;
  color: var(--ink-dim);
  line-height: 1.4;
  /* no truncation: a long joke just wraps and takes more vertical space */
}

.blink {
  animation: blink 1.1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

.muted { color: var(--ink-dim); }

.links {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--line);
  border-bottom: 1px solid var(--line);
}

.tile {
  background: var(--paper);
  color: var(--ink);
  border: none;
  padding: 18px 16px;
  text-align: left;
  font-family: var(--mono);
  font-size: 0.933rem;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-decoration: none;
}

.tile:hover {
  background: #2a2924;
}

.tile:active {
  background: #1f1e1a;
}

.tile-label {
  color: var(--accent);
  text-transform: lowercase;
  font-weight: 600;
}

.tile-sub {
  color: var(--ink-dim);
  font-size: 0.8rem;
}

.weather {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1px;
  background: var(--line);
  border-bottom: 1px solid var(--line);
}

.wx-tile {
  background: var(--paper);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.wx-city {
  color: var(--accent);
  font-size: 0.867rem;
  text-transform: lowercase;
}

.wx-temp {
  font-size: 1.333rem;
  color: var(--ink);
}

.wx-icon {
  font-size: 1rem;
}

.wx-forecast {
  margin-top: 8px;
  border-top: 1px solid var(--line);
  padding-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.wx-day {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 0.733rem;
  color: var(--ink-dim);
}

.wx-day-name {
  text-transform: lowercase;
  color: var(--ink);
  width: 3em;
  flex-shrink: 0;
}

.wx-day-temp {
  color: var(--ink);
}

.wx-day-icon {
  font-size: 0.867rem;
}

.radio {
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.radio-head {
  display: flex;
  flex-direction: column;
}

.radio-label {
  color: var(--accent);
  font-size: 0.867rem;
  text-transform: lowercase;
}

.radio-sub {
  color: var(--ink-dim);
  font-size: 0.733rem;
}

.radio-player {
  width: 100%;
  height: 32px;
}

.radio-volume-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.radio-volume-icon {
  color: var(--ink-dim);
  font-size: 0.733rem;
  text-transform: lowercase;
}

.radio-volume {
  flex: 1;
  accent-color: var(--accent);
}

.radio-viz {
  display: none;
  width: 100%;
  height: 40px;
  background: var(--bg);
  border: 1px solid var(--line);
}

.radio-viz.active {
  display: block;
}

.football {
  display: flex;
  flex-direction: column;
  border-bottom: 1px solid var(--line);
}

.fb-row {
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  border-top: 1px solid var(--line);
}

.fb-row:first-child {
  border-top: none;
}

.fb-team {
  color: var(--accent);
  font-size: 0.867rem;
  text-transform: lowercase;
}

.fb-score {
  font-size: 0.867rem;
  color: var(--ink);
}

.fb-live {
  color: #c9654b;
  font-weight: 600;
}

.fb-next {
  font-size: 0.767rem;
  color: var(--ink-dim);
}

.fb-team {
  background: none;
  border: none;
  padding: 0;
  font-family: var(--mono);
  cursor: pointer;
  text-align: left;
}

.fb-team:hover {
  color: var(--ink);
}

/* --- laws widget --- */

.laws {
  display: flex;
  flex-direction: column;
  border-bottom: 1px solid var(--line);
}

.law-category {
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  border-top: 1px solid var(--line);
}

.law-category:first-child {
  border-top: none;
}

.law-row {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.law-flag {
  color: var(--accent);
  font-size: 0.733rem;
  text-transform: lowercase;
  letter-spacing: 0.03em;
}

.law-author {
  height: 0.9em;
  width: auto;
  vertical-align: middle;
  margin-right: 6px;
}

.law-author-text {
  display: inline-block;
  font-size: 0.7rem;
  text-transform: lowercase;
  border: 1px solid var(--line);
  border-radius: 2px;
  padding: 0 4px;
  margin-right: 6px;
  vertical-align: middle;
}

.law-name {
  color: var(--ink);
  font-size: 0.867rem;
  text-decoration: none;
  border-bottom: 1px dotted var(--ink-dim);
}

.law-name:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.law-votes {
  display: flex;
  gap: 14px;
  font-size: 0.8rem;
  color: var(--ink);
}

.law-stage {
  font-size: 0.733rem;
}

.law-history {
  margin-top: 4px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
  font-size: 0.8rem;
}

.law-history summary {
  color: var(--accent);
  cursor: pointer;
  text-transform: lowercase;
}

.law-history summary::marker {
  color: var(--accent);
}

.law-history .law-row {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}

.law-history .law-row:first-child {
  margin-top: 10px;
  padding-top: 0;
  border-top: none;
}

.standings-panel {
  display: none;
  margin-top: 8px;
}

.standings-panel.open {
  display: block;
}

.standings-tabs {
  display: flex;
  gap: 1px;
  background: var(--line);
  margin-bottom: 1px;
}

.standings-tab {
  background: var(--bg);
  color: var(--ink-dim);
  border: none;
  font-family: var(--mono);
  font-size: 0.733rem;
  padding: 5px 10px;
  cursor: pointer;
  text-transform: lowercase;
}

.standings-tab.active {
  color: var(--accent);
  background: var(--paper);
}

.standings-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  font-size: 0.733rem;
}

.standings-table th,
.standings-table td {
  text-align: left;
  padding: 4px 6px;
  border-bottom: 1px solid var(--line);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.standings-table th:first-child,
.standings-table td:first-child {
  width: 2.4em;
}

.standings-table th:last-child,
.standings-table td:last-child {
  width: 3.2em;
  text-align: right;
}

.standings-table th {
  color: var(--ink-dim);
  font-weight: normal;
  text-transform: lowercase;
}

.standings-highlight td {
  color: var(--accent);
  font-weight: 600;
}

.news {
  flex: 1;
  padding: 0;
}

.tabs {
  display: flex;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
}

.tab {
  background: none;
  border: none;
  color: var(--ink-dim);
  font-family: var(--mono);
  font-size: 0.867rem;
  padding: 10px 16px;
  cursor: pointer;
  border-right: 1px solid var(--line);
  white-space: nowrap;
}

.tab.active {
  color: var(--accent);
  background: var(--paper);
}

.tab-icon {
  height: 1.1em;
  width: auto;
  vertical-align: middle;
  display: block;
}

/* --- groq summary --- */

.news-tools {
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* the `display: flex` above beats the browser's default `[hidden] {
   display: none }` rule (same specificity, but author styles always win
   over user-agent ones), so without this, setting .hidden = true in app.js
   on the groq report tab silently did nothing. */
.news-tools[hidden] {
  display: none;
}

.summarize-btn {
  align-self: flex-start;
  background: var(--paper);
  color: var(--accent);
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 0.8rem;
  padding: 6px 12px;
  cursor: pointer;
  text-transform: lowercase;
}

.summarize-btn:hover {
  border-color: var(--accent);
}

.summarize-btn:disabled {
  color: var(--ink-dim);
  cursor: default;
  border-color: var(--line);
}

.summary {
  border-left: 2px solid var(--accent);
  padding-left: 10px;
}

.summary-label {
  font-size: 0.733rem;
  text-transform: lowercase;
  margin-bottom: 4px;
}

.summary-text {
  font-size: 0.867rem;
  line-height: 1.5;
  color: var(--ink);
}

.feed {
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* "news generated <time>" line under the feed -- quiet and set apart from
   the story cards so it reads as metadata about the batch, not another
   story. font-size is in rem so it follows the a-/a/a+ controls. */
.news-timestamp {
  padding: 0 16px 16px;
  font-size: 0.733rem;
  text-transform: lowercase;
}

/* same cascade gotcha as .news-tools above -- without this, `hidden` set in
   app.js wouldn't actually hide the line when no valid timestamp is
   available. */
.news-timestamp[hidden] {
  display: none;
}

.story {
  border: 1px solid var(--line);
  background: var(--paper);
  padding: 14px 16px;
}

.story-title {
  color: var(--ink);
  font-size: 0.967rem;
  font-weight: 600;
  margin: 0 0 6px 0;
}

.story-meta {
  color: var(--ink-dim);
  font-size: 0.767rem;
  margin-bottom: 8px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.story-summary {
  font-size: 0.867rem;
  line-height: 1.5;
  margin: 0 0 10px 0;
  color: var(--ink);
}

.story-link {
  font-size: 0.8rem;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent);
}

.story-link:hover { opacity: 0.8; }

/* --- expandable story details (highlights / perspectives / background / timeline) --- */

.story-details {
  margin-top: 10px;
  border-top: 1px solid var(--line);
  padding-top: 10px;
}

.story-details summary {
  color: var(--accent);
  cursor: pointer;
  font-size: 0.8rem;
  text-transform: lowercase;
}

.story-details summary::marker {
  color: var(--accent);
}

.story-section {
  margin-top: 12px;
}

.story-section h3 {
  margin: 0 0 6px 0;
  color: var(--accent);
  font-size: 0.733rem;
  text-transform: lowercase;
  letter-spacing: 0.03em;
}

.story-highlights {
  margin: 0;
  padding-left: 1.1em;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--ink);
}

.story-perspective {
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--ink);
  margin: 0 0 10px 0;
  padding-left: 10px;
  border-left: 2px solid var(--line);
}

.story-perspective:last-child {
  margin-bottom: 0;
}

.story-section > p {
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--ink);
  margin: 0;
}

/* --- timeline --- */

.story-timeline {
  position: relative;
  margin-left: 4px;
  padding-left: 16px;
  border-left: 2px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.timeline-item {
  position: relative;
}

.timeline-item::before {
  content: "";
  position: absolute;
  left: -21px;
  top: 3px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 2px var(--paper);
}

.timeline-date {
  color: var(--accent);
  font-size: 0.733rem;
  font-weight: 600;
  margin-bottom: 2px;
}

.timeline-content {
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--ink);
}

.citation {
  color: var(--ink-dim);
  text-decoration: none;
  font-size: 0.733rem;
  border-bottom: 1px dotted var(--ink-dim);
}

.citation:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.show-more {
  justify-self: start;
  border: 1px solid var(--line);
  padding: 8px 14px;
  align-self: flex-start;
}

.show-more:hover {
  color: var(--accent);
}

.toast {
  position: fixed;
  bottom: 18px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--accent);
  color: var(--bg);
  padding: 8px 14px;
  font-size: 0.8rem;
  font-family: var(--mono);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.toast.show {
  opacity: 1;
}

/* --- font size control (footer) --- */

/* --- boot screen (fake POST sequence on first load) --- */

.boot-screen {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--mono);
  padding: 24px;
  display: flex;
  cursor: pointer;
  transition: opacity 0.3s ease;
}

.boot-screen.boot-done {
  opacity: 0;
  pointer-events: none;
}

.boot-lines {
  margin: 0;
  font-size: 0.867rem;
  line-height: 1.6;
  white-space: pre-wrap;
}

.boot-ok {
  color: var(--accent);
}

/* --- scanline overlay (toggle in footer) --- */

.scanline-overlay {
  position: fixed;
  inset: 0;
  z-index: 9000;
  pointer-events: none;
  display: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.2) 0px,
    rgba(0, 0, 0, 0.2) 1px,
    transparent 1px,
    transparent 3px
  );
}

body.scanlines-on .scanline-overlay {
  display: block;
}

.footer-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

.scanline-toggle {
  background: var(--paper);
  color: var(--ink-dim);
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 0.8rem;
  padding: 4px 8px;
  cursor: pointer;
  text-transform: lowercase;
}

.scanline-toggle.active {
  color: var(--accent);
  border-color: var(--accent);
}

.fontsize {
  display: flex;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

.fontsize button {
  background: var(--paper);
  color: var(--ink-dim);
  border: none;
  font-family: var(--mono);
  font-size: 0.8rem;
  padding: 4px 8px;
  cursor: pointer;
}

.fontsize button.active {
  color: var(--accent);
}

/* the multi-day forecast takes real estate the phone screen doesn't have
   to spare once the laws/scores widgets are also competing for it -- only
   today's conditions show there, the full forecast is a wide-screen thing.
   Placed at the end of the file: same specificity as the unconditional
   .wx-forecast rule above, so source order is what makes this one win. */
@media (max-width: 999px) {
  .wx-forecast {
    display: none;
  }
}

.fontsize button:hover {
  color: var(--ink);
}
