/*
  The stylesheet for the written pages -- everything under /learn, plus the
  changelog.

  It is a plain file rather than a string inside the generator because it is
  ordinary CSS and deserves ordinary tooling. The build copies it to
  /learn/learn.css and every page links it, so one edit reaches all of them.

  The palette is lifted from the app (apps/web/src/styles.css) and from the
  renderer (apps/web/src/render/palette.ts) rather than re-picked, so a diagram
  of the house on a written page is the same blue and the same red as the house
  a player is looking at while they read it.

  The wordmark is the exception: it is not copied here, it is appended by the
  build from apps/web/brand.css, which the app imports too. Copying it is what
  let the two drift apart last time.
*/

:root {
  --bg: #10161f;
  --panel: #18202b;
  --panel-2: #1f2937;
  --line: #2b3644;
  --text: #e7edf5;
  --muted: #93a3b8;
  --accent: #4a9d6b;
  --accent-bright: #6ab98a;
  --red: #d94141;
  --yellow: #e8b62c;

  /* The sheet, exactly as the game draws it. */
  --ice: #eef4fb;
  --ice-edge: #d6e2f0;
  --ice-line: #8fa6bd;
  --hog: #c0392b;
  --ring12: #aec0fd;
  --ring8: #ffffff;
  --ring4: #ffacac;
  --granite: #6f7378;

  color-scheme: dark;
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.65 ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
}

/* ---- chrome ---- */

.top {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 10px 20px;
  background: rgba(16, 22, 31, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}

.top .brand {
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--text);
  text-decoration: none;
  font-size: 17px;
}

.top nav {
  display: flex;
  gap: 14px;
  margin-left: auto;
  font-size: 14px;
  flex-wrap: wrap;
}

.top nav a { color: var(--muted); text-decoration: none; }
.top nav a:hover { color: var(--text); }
.top nav a.play { color: var(--accent-bright); font-weight: 600; }

main {
  max-width: 48rem;
  margin: 0 auto;
  padding: 0 20px 4rem;
}

/* ---- headings and prose ---- */

.crumbs {
  margin: 1.75rem 0 0;
  font-size: 13px;
  color: var(--muted);
}
.crumbs a { color: var(--muted); }
.crumbs span { opacity: 0.6; padding: 0 0.35rem; }

h1 {
  font-size: clamp(1.9rem, 1.3rem + 2.2vw, 2.6rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0.6rem 0 0.5rem;
}

.standfirst {
  font-size: 1.12rem;
  color: var(--muted);
  margin: 0 0 0.75rem;
  max-width: 40rem;
}

.updated {
  font-size: 12.5px;
  color: var(--muted);
  opacity: 0.75;
  margin: 0 0 2.25rem;
  letter-spacing: 0.02em;
}

h2 {
  font-size: 1.4rem;
  letter-spacing: -0.01em;
  margin: 3rem 0 0.75rem;
  padding-top: 0.4rem;
  scroll-margin-top: 4.5rem;
}

h3 {
  font-size: 1.08rem;
  margin: 2rem 0 0.5rem;
  scroll-margin-top: 4.5rem;
}

h2 .anchor, h3 .anchor {
  color: var(--line);
  text-decoration: none;
  margin-left: 0.4rem;
  font-weight: 400;
  opacity: 0;
  transition: opacity 0.12s;
}
h2:hover .anchor, h3:hover .anchor { opacity: 1; }
h2 .anchor:hover, h3 .anchor:hover { color: var(--accent-bright); }

p { margin: 0 0 1.1rem; }

a { color: var(--accent-bright); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: #8ed3ac; }

strong { color: #f4f8fc; font-weight: 650; }

ul, ol { padding-left: 1.35rem; margin: 0 0 1.2rem; }
li { margin: 0.4rem 0; }

code {
  background: var(--panel-2);
  padding: 0.1rem 0.35rem;
  border-radius: 4px;
  font-size: 0.88em;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

pre {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.9rem 1rem;
  overflow-x: auto;
  font-size: 13.5px;
  line-height: 1.55;
}
pre code { background: none; padding: 0; font-size: inherit; }

hr { border: 0; border-top: 1px solid var(--line); margin: 2.5rem 0; }

blockquote {
  margin: 0 0 1.2rem;
  padding-left: 1rem;
  border-left: 2px solid var(--line);
  color: var(--muted);
}

/* ---- tables ---- */

.scroll-x { overflow-x: auto; margin: 0 0 1.4rem; }

table {
  border-collapse: collapse;
  width: 100%;
  font-size: 14.5px;
  font-variant-numeric: tabular-nums;
}

th, td {
  border: 1px solid var(--line);
  padding: 0.42rem 0.7rem;
  text-align: left;
  vertical-align: top;
}

thead th {
  background: var(--panel-2);
  color: var(--muted);
  font-weight: 600;
  white-space: nowrap;
}

tbody tr:nth-child(even) { background: rgba(255, 255, 255, 0.018); }
td.num, th.num { text-align: right; white-space: nowrap; }

/* ---- callouts ---- */

.note, .key {
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  background: var(--panel);
  border-radius: 0 8px 8px 0;
  padding: 0.9rem 1.1rem;
  margin: 0 0 1.4rem;
}
.note > :last-child, .key > :last-child { margin-bottom: 0; }
.key { border-left-color: var(--accent); }
.note .label, .key .label {
  display: block;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.3rem;
}
.key .label { color: var(--accent-bright); }

/* ---- figures ---- */

figure {
  margin: 1.8rem 0;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  overflow: hidden;
}

figure .art {
  display: block;
  padding: 1rem;
  background: radial-gradient(120% 100% at 50% 0%, #1a2431 0%, var(--panel) 70%);
}

figure svg { display: block; width: 100%; height: auto; }

figcaption {
  border-top: 1px solid var(--line);
  padding: 0.7rem 1rem;
  font-size: 13.5px;
  color: var(--muted);
  background: var(--panel-2);
}

/* ---- the card grids on the hub ---- */

.cards {
  list-style: none;
  padding: 0;
  margin: 0 0 1rem;
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}

.cards li { margin: 0; }

.cards a {
  display: block;
  height: 100%;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  padding: 0.9rem 1rem;
  text-decoration: none;
  color: var(--text);
  transition: border-color 0.14s, background 0.14s, transform 0.14s;
}
.cards a:hover {
  border-color: #3d5063;
  background: #1c2531;
  transform: translateY(-1px);
}
.cards .t { display: block; font-weight: 650; margin-bottom: 0.25rem; }
.cards .d { display: block; font-size: 13.5px; color: var(--muted); line-height: 1.5; }

/* ---- prev / next ---- */

.pager {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin: 3rem 0 0;
  border-top: 1px solid var(--line);
  padding-top: 1.5rem;
}
.pager a {
  flex: 1 1 14rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  padding: 0.75rem 1rem;
  text-decoration: none;
  color: var(--text);
}
.pager a:hover { border-color: #3d5063; }
.pager .dir { display: block; font-size: 12px; color: var(--muted); letter-spacing: 0.06em; text-transform: uppercase; }
.pager .next { text-align: right; }

/* ---- footer ---- */

footer.site {
  border-top: 1px solid var(--line);
  margin-top: 3rem;
  padding: 1.5rem 20px 3rem;
  color: var(--muted);
  font-size: 13.5px;
}
footer.site .inner { max-width: 48rem; margin: 0 auto; }
footer.site a { color: var(--muted); }
footer.site a:hover { color: var(--text); }
footer.site .links { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 0.6rem; }
footer.site .made-in { margin-top: 0.6rem; margin-bottom: 0; }

/* ---- interactive diagram controls ---- */

.diagram { margin: 1.8rem 0; }

.diagram .tabs {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.diagram .tabs button {
  font: inherit;
  font-size: 13.5px;
  color: var(--muted);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.3rem 0.85rem;
  cursor: pointer;
  transition: color 0.12s, background 0.12s, border-color 0.12s;
}
.diagram .tabs button:hover { color: var(--text); border-color: #3d5063; }
.diagram .tabs button[aria-pressed='true'] {
  color: #0d1218;
  background: var(--accent-bright);
  border-color: var(--accent-bright);
  font-weight: 650;
}

.diagram .stage {
  display: grid;
  gap: 14px;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
@media (min-width: 46rem) {
  .diagram .stage { grid-template-columns: minmax(0, 1fr) 15rem; }
}

.diagram figure { margin: 0; }

.diagram .readout {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  padding: 0.9rem 1rem;
  min-height: 7rem;
}
.diagram .readout h4 { margin: 0 0 0.35rem; font-size: 1rem; }
.diagram .readout p { margin: 0; font-size: 14px; color: var(--muted); line-height: 1.55; }
.diagram .readout .hint { font-style: italic; opacity: 0.8; }

/*
  Hit targets on the sheet, and the legend beside them.

  The two are the same control seen twice: pointing at either one lights up
  both. That is deliberate rather than clever -- the legend is ordinary text
  that a crawler reads and a screen reader announces, so nothing on these pages
  is only available to a mouse. The highlight is a saturated green at partial
  opacity because it lands on white ice, not on the dark page.
*/

.hot { cursor: pointer; }
.hot .fill { fill: transparent; transition: fill 0.12s; }
.hot .band { fill: none; stroke: transparent; transition: stroke 0.12s; }
.hot .halo { fill: none; stroke: transparent; stroke-width: 0.18; transition: stroke 0.12s; }
.hot .edge { fill: none; stroke: transparent; stroke-width: 0.13; transition: stroke 0.12s; }
.hot:hover .fill, .hot.on .fill { fill: rgba(47, 143, 91, 0.45); }
.hot:hover .band, .hot.on .band { stroke: rgba(47, 143, 91, 0.45); }
.hot:hover .halo, .hot.on .halo { stroke: #2f8f5b; }
.hot:hover .edge, .hot.on .edge { stroke: #2f8f5b; }
.hot:focus { outline: none; }
.hot:focus-visible .halo, .hot:focus-visible .edge { stroke: #1b6b40; stroke-dasharray: 0.3 0.2; }

.legend {
  list-style: none;
  padding: 0;
  margin: 0 0 1.4rem;
  display: grid;
  gap: 2px;
}
.legend li {
  margin: 0;
  padding: 0.42rem 0.7rem;
  border: 1px solid transparent;
  border-radius: 7px;
  transition: background 0.12s, border-color 0.12s;
  font-size: 15px;
}
.legend li.on {
  background: rgba(74, 157, 107, 0.14);
  border-color: rgba(106, 185, 138, 0.45);
}
.legend b { color: #f4f8fc; }
.legend .said { color: var(--muted); }
.legend .n {
  display: inline-block;
  min-width: 1.6em;
  font-variant-numeric: tabular-nums;
  color: var(--accent-bright);
  font-weight: 650;
}

.hint-line {
  font-size: 13px;
  color: var(--muted);
  margin: -0.6rem 0 1.2rem;
  font-style: italic;
}

/* ---- the changelog ---- */

.release { margin: 0 0 2.5rem; }
.release h2 { margin-top: 2.5rem; display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; }
.release .date {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--muted);
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.release ul { margin-bottom: 0; }

/* ---- small print ---- */

.pill {
  display: inline-block;
  font-size: 11.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.1rem 0.55rem;
  vertical-align: 0.1em;
}

.lede-links { display: flex; gap: 10px; flex-wrap: wrap; margin: 0 0 2rem; }
.lede-links a {
  border: 1px solid var(--accent);
  color: var(--accent-bright);
  border-radius: 8px;
  padding: 0.45rem 0.95rem;
  text-decoration: none;
  font-size: 14.5px;
  font-weight: 600;
}
.lede-links a:hover { background: rgba(74, 157, 107, 0.12); }
.lede-links a.plain { border-color: var(--line); color: var(--muted); font-weight: 500; }
.lede-links a.plain:hover { background: var(--panel); color: var(--text); }

/* ================================================================
   Components added with the reference pages
   ================================================================ */

/* ---- on-page contents ----

  Only on the pages long enough to need one. The rule of thumb used here is
  that a page earns a contents list when it is longer than a reader will scroll
  on faith -- roughly eight sections. Below that the list is furniture.
*/

.toc {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  padding: 0.9rem 1.1rem;
  margin: 0 0 2rem;
}
.toc .label {
  display: block;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.5rem;
}
.toc ul {
  list-style: none;
  padding: 0;
  margin: 0;
  columns: 2;
  column-gap: 1.5rem;
  font-size: 14.5px;
}
@media (max-width: 34rem) { .toc ul { columns: 1; } }
.toc li { margin: 0.22rem 0; break-inside: avoid; }

/* ---- sources and outbound links ----

  A source is a claim's receipt and an outbound link is somewhere to go next,
  so they look alike but not identical: sources are numbered-feeling and dense,
  outbound links are spaced like a menu.
*/

.refs, .links-out {
  list-style: none;
  padding: 0;
  margin: 0 0 1.4rem;
}
.refs li, .links-out li {
  margin: 0;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--line);
}
.refs li:last-child, .links-out li:last-child { border-bottom: 0; }
.refs .where { color: var(--muted); font-size: 13.5px; }
.refs .t { color: var(--text); }
.note-line {
  display: block;
  font-size: 13.5px;
  color: var(--muted);
  line-height: 1.5;
  margin-top: 0.15rem;
}
.links-out a { font-weight: 600; }

/* ---- the timeline on the history pages ----

  A left rule with a node per entry. The year is the thing being scanned for,
  so it is the element that is allowed to be wide and monospaced-feeling; the
  prose beside it wraps normally.
*/

.timeline { list-style: none; padding: 0; margin: 0 0 1.6rem; }
.timeline li {
  position: relative;
  margin: 0;
  padding: 0 0 1.1rem 1.4rem;
  border-left: 1px solid var(--line);
}
.timeline li:last-child { border-left-color: transparent; padding-bottom: 0; }
.timeline li::before {
  content: '';
  position: absolute;
  left: -4.5px;
  top: 0.55rem;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--bg);
}
.timeline li.major::before { background: var(--accent-bright); width: 10px; height: 10px; left: -5.5px; }
.timeline .year {
  display: block;
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--accent-bright);
  font-weight: 650;
}
.timeline .what { display: block; }
.timeline .what b { color: #f4f8fc; }

/* ---- the glossary ----

  A definition list that can be filtered. The filter is progressive
  enhancement: with no JavaScript the box is not rendered at all and the list
  is simply a long list, which is a perfectly good glossary.
*/

.gloss-tools { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin: 0 0 1.2rem; }
.gloss-tools input {
  font: inherit;
  font-size: 15px;
  flex: 1 1 14rem;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.5rem 0.8rem;
}
.gloss-tools input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.gloss-count { font-size: 13.5px; color: var(--muted); }

.glossary { margin: 0 0 1.5rem; }
.glossary .letter {
  font-size: 0.95rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-bright);
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.3rem;
  margin: 2rem 0 0.6rem;
}
.glossary dl { margin: 0; }
.glossary dt {
  font-weight: 650;
  color: #f4f8fc;
  margin-top: 0.9rem;
}
.glossary dt .pill { margin-left: 0.4rem; }
.glossary dd { margin: 0.15rem 0 0; color: var(--text); }
.glossary dd .said { color: var(--muted); font-style: italic; }
.glossary .row[hidden] { display: none; }

/* ---- simulators ----

  Sliders on the left, a live sheet on the right, and a table of the same
  numbers underneath. The table is not a fallback -- it is there for the reader
  who wants to read the answer rather than aim at it -- but it does mean the
  page still says everything it has to say with the script removed.
*/

.sim { margin: 1.8rem 0; }
.sim .panel-row {
  display: grid;
  gap: 14px;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
@media (min-width: 46rem) {
  .sim .panel-row { grid-template-columns: 17rem minmax(0, 1fr); }
}
.sim .controls {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  padding: 0.9rem 1rem;
}
.sim .controls > :last-child { margin-bottom: 0; }

.range-row { margin: 0 0 1rem; }
.range-row label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.6rem;
  font-size: 13.5px;
  color: var(--muted);
  margin-bottom: 0.25rem;
}
.range-row label .v {
  color: var(--accent-bright);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.range-row input[type='range'] {
  width: 100%;
  accent-color: var(--accent-bright);
  margin: 0;
}
.range-row .foot { font-size: 12.5px; color: var(--muted); opacity: 0.85; margin-top: 0.2rem; }

.seg { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 1rem; }
.seg button {
  font: inherit;
  font-size: 13px;
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.25rem 0.7rem;
  cursor: pointer;
}
.seg button[aria-pressed='true'] {
  color: #0d1218;
  background: var(--accent-bright);
  border-color: var(--accent-bright);
  font-weight: 650;
}

.sim .verdict {
  border-top: 1px solid var(--line);
  margin-top: 0.9rem;
  padding-top: 0.8rem;
  font-size: 14px;
  color: var(--muted);
  line-height: 1.55;
}
.sim .verdict b { color: var(--text); }

/* ---- numbers worth pulling out of a paragraph ---- */

.stats {
  list-style: none;
  padding: 0;
  margin: 0 0 1.5rem;
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}
.stats li {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  padding: 0.75rem 0.9rem;
}
.stats .n {
  display: block;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent-bright);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.stats .l { display: block; font-size: 13px; color: var(--muted); margin-top: 0.15rem; line-height: 1.45; }

/* ---- the rule / claim comparison used on the physics page ---- */

.theories { list-style: none; padding: 0; margin: 0 0 1.5rem; }
.theories li {
  margin: 0 0 12px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: 0 10px 10px 0;
  background: var(--panel);
  padding: 0.85rem 1rem;
}
.theories .name { display: block; font-weight: 650; color: #f4f8fc; }
.theories .who { display: block; font-size: 13px; color: var(--muted); margin-bottom: 0.4rem; }
.theories p { margin: 0 0 0.5rem; font-size: 14.5px; }
.theories .against { margin: 0; font-size: 14px; color: var(--muted); }
.theories .against b { color: #e8b62c; font-weight: 650; }
.theories li.leading { border-left-color: var(--accent); }

/* ---- the world map ---- */

.map-wrap { margin: 1.8rem 0; }
.map-wrap svg { display: block; width: 100%; height: auto; }
.map-wrap .land { fill: #26303d; stroke: #10161f; stroke-width: 0.4; }
.map-wrap .dot { fill: var(--accent-bright); fill-opacity: 0.85; stroke: #0d1218; stroke-width: 0.5; }
.map-wrap .dot.big { fill: #8ed3ac; }
.nations { font-size: 14.5px; }
.nations td .home { color: var(--muted); }

/*
  What the wordmark looks like, once, for everything that draws it.

  Two stylesheets need these rules and neither owns them: the app's styles.css
  imports this file, and the generator appends it to the written pages'
  learn.css (apps/web/scripts/build-learn.mjs). Both used to carry their own
  copy, which is the same trap the markup was in before brand.mjs -- see the
  comment there.

  What the parts ARE is brand.mjs. This decides what they look like.
*/

:root {
  /*
    The dot in the wordmark, and nothing else.

    Recessed behind --muted so the eye reads "Curl Time" before it reads a
    URL, but it is still text and still has to be readable: 4.65:1 on --panel
    and 5.15:1 on --bg, which are the two grounds the name ever sits on. The
    first draft of this was #55657a, which looked right and was 2.76:1 -- an
    AA failure on the one character in the name that says what the name is.
    apps/web/test/contrast.test.ts measures it so that cannot come back.
  */
  --brand-dot: #7a8a9e;
}

/*
  `CurlTi.me` is a domain hack, and set flat it reads as a URL. Recessing the
  dot and lightening the `me` puts the other reading first -- Curl Time --
  without touching a character of the name.

  The dot goes back further than the `me` does on purpose: that gap is what
  makes the eye jump, and a dot at the same value as the letters around it
  just reads as punctuation again. The recession that does the real work is
  the weight drop, though, not the colour.

  Both stay `display: inline`. An accessible name is computed by walking the
  text nodes, and a block-level or flex child has a space inserted either side
  of it -- which would make the name `CurlTi . me` for a screen reader and for
  every `getByRole('button', { name: BRAND })` in the browser tests.
*/
.brand-dot { color: var(--brand-dot); font-weight: 400; }
.brand-tld { color: var(--muted); font-weight: 400; }
