/* ============================================================================
 * site.css — ReactorDynamics.com public site (landing / about / privacy /
 * legal / changelog).
 *
 * Same quiet-board palette as ui/shell.css so stepping from the site into the
 * control room doesn't feel like a site change. The site pages scroll (unlike
 * the shell); color is still spent only where it means something — green for
 * "live", amber for "coming soon" / alpha, red never (reserved for the board).
 * ========================================================================== */

:root {
  --bg: #070A0C;
  --bg-panel: #0E1216;
  --bg-elevated: #161B21;
  --border: #232931;
  --text: #E4E9EE;
  --text-2: #98A3AF;
  --muted: #69757F;
  --normal: #5BB3C4;
  --caution: #D9A441;
  --running: #46A35E;
  --core-glow: #00C4FF;
  --radius: 6px;
  --content: 980px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: ui-sans-serif, "Segoe UI", Roboto, system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.6;
}
.mono { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; }

a { color: var(--normal); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ================================================================== header */
.site-header {
  position: sticky; top: 0; z-index: 10;
  background: rgba(7, 10, 12, 0.92);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--border);
}
.site-header .bar {
  max-width: var(--content); margin: 0 auto; padding: 12px 20px;
  display: flex; align-items: center; gap: 16px;
}
.brand {
  font-weight: 700; font-size: 18px; color: var(--text); letter-spacing: 0.2px;
  white-space: nowrap;
}
.brand:hover { text-decoration: none; }
.brand-alpha {
  border: 1px solid var(--caution); color: var(--caution); border-radius: 999px;
  padding: 2px 9px; font-size: 11px; font-weight: 700; letter-spacing: 1.4px;
  line-height: 1.4; white-space: nowrap;
}
/* Release number beside the ALPHA badge. Deliberately QUIETER than the badge — no border,
   muted colour — because ALPHA is the warning and the version is only the reference you
   quote in a bug report. Filled by site/nav.js from RD_RELEASE; empty when there is no
   version to show, and an empty inline span occupies nothing, so the header is unchanged. */
.brand-ver {
  color: var(--muted, #8b96a5); font-size: 11px; font-weight: 600;
  letter-spacing: 0.8px; line-height: 1.4; white-space: nowrap;
  margin-left: -8px;   /* .bar sets gap:16px; pull the version toward the badge so they read as a pair */
}
/* Burger + dropdown (site menu) */
.nav-wrap {
  margin-left: auto;
  position: relative;
  flex: 0 0 auto;
}
.nav-burger {
  display: flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 40px; height: 36px; padding: 8px 9px;
  background: var(--bg-elevated); border: 1px solid var(--border);
  border-radius: var(--radius); cursor: pointer;
  color: var(--text-2);
}
.nav-burger:hover { border-color: var(--normal); color: var(--text); }
.nav-burger span {
  display: block; height: 2px; width: 100%;
  background: currentColor; border-radius: 1px;
  transition: transform 0.15s ease, opacity 0.15s ease;
}
.nav-burger.is-open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-burger.is-open span:nth-child(2) { opacity: 0; }
.nav-burger.is-open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.site-nav {
  display: none;
  position: absolute; top: calc(100% + 8px); right: 0;
  min-width: 200px;
  flex-direction: column; gap: 0;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
  padding: 6px 0;
  z-index: 20;
}
.site-nav.is-open { display: flex; }
.site-nav a {
  display: block; color: var(--text-2); font-size: 14px;
  padding: 10px 16px; text-decoration: none; white-space: nowrap;
}
.site-nav a:hover { color: var(--text); background: rgba(255, 255, 255, 0.04); text-decoration: none; }
.site-nav a.active { color: var(--text); font-weight: 600; }
/* Disabled links: intentional "not yet" (e.g. gated features), not broken links. */
a.disabled { pointer-events: none; cursor: default; opacity: 0.4; text-decoration: none; }

/* ========================================================== TEST BUILD marker
 * dev.reactordynamics.com serves the same pages as the live domain from the
 * `develop` branch, so a visitor has no way to tell them apart without being told.
 * Both markers key off html[data-channel], set in each page's <head> from
 * window.RD_CHANNEL — which site/stamp_version.js stamps at deploy.
 *
 * DEFAULT IS HIDDEN, and the shown-state is opt-in per channel rather than
 * `:not([data-channel="public"])`. That matters: if the attribute is ever missing
 * or misspelled the markers stay OFF on the released site, which is the direction
 * to fail in — a spurious "TEST BUILD" banner on the real site is worse than a
 * missing one on the test site.
 *
 * Two of them, because they do different jobs. The BAR states the situation once,
 * in full, at the top of the page. The PILL rides the sticky header, so the answer
 * to "which of these two tabs am I in?" is on screen after the bar scrolls away.
 * Filled amber, not the tinted outline used by the ALPHA badge and .alpha-note —
 * this has to read as louder than the things around it. (Red stays reserved for
 * the board.) */
.dev-bar, .brand-test { display: none; }

html[data-channel="preview"] .dev-bar,
html[data-channel="dev"] .dev-bar {
  display: block;
  background: var(--caution); color: #17120A;
  text-align: center; padding: 9px 16px;
  font-size: 13px; font-weight: 600; line-height: 1.45;
}
.dev-bar strong { letter-spacing: 1.2px; }
.dev-bar a { color: #17120A; text-decoration: underline; }
.dev-bar a:hover { color: #000; }

html[data-channel="preview"] .brand-test,
html[data-channel="dev"] .brand-test {
  display: inline-block;
  background: var(--caution); color: #17120A;
  border-radius: 999px; padding: 2px 9px;
  font-size: 11px; font-weight: 700; letter-spacing: 1.4px; white-space: nowrap;
}

/* ==================================================================== hero */
.hero { text-align: center; padding: 64px 20px 40px; }
/* Sits BELOW the CTA, not above it (2026-08-06). It was the first thing on the
   page for a month: a visitor's opening handshake was a limitation, before they
   had been told what the thing is or who it is for. It still has to be seen
   before anyone downloads on a phone, so it keeps the caution border and stays
   above the fold — it just no longer leads. */
.alpha-note {
  display: block; width: fit-content; max-width: 100%; margin: 22px auto 0;
  background: rgba(217, 164, 65, 0.10); border: 1px solid var(--caution);
  color: var(--caution); border-radius: var(--radius);
  padding: 8px 16px; font-size: 13px; font-weight: 600; letter-spacing: 0.2px;
}
/* WHO IT IS FOR — the question the copy never answered (2026-08-06). The site's
   own vocabulary (boration, hot standby, xenon) reads as a filter to anyone
   without a nuclear background, and a reader who has to guess whether they are
   the audience leaves. Highest-read slot on the page: under the subhead, above
   the CTA. */
.hero-who {
  max-width: 660px; margin: 0 auto 26px; padding: 12px 18px;
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-2); font-size: 15px; line-height: 1.55;
}
.hero-who strong { color: var(--text); }
.hero h1 {
  font-size: clamp(28px, 5vw, 44px); line-height: 1.15; margin: 0 0 14px;
  letter-spacing: -0.5px;
}
.hero .sub {
  color: var(--text-2); font-size: clamp(15px, 2.2vw, 19px);
  max-width: 640px; margin: 0 auto 28px;
}
.cta {
  display: inline-block;
  background: var(--bg-elevated);
  border: 1px solid var(--normal);
  color: var(--text);
  padding: 13px 30px; border-radius: var(--radius);
  font-size: 17px; font-weight: 600;
  box-shadow: 0 0 24px rgba(0, 196, 255, 0.12);
  transition: box-shadow 0.15s, transform 0.15s;
}
.cta:hover {
  text-decoration: none;
  box-shadow: 0 0 34px rgba(0, 196, 255, 0.28);
  transform: translateY(-1px);
}
/* Full control-room board at site/hero.png; frame collapses if the file is missing. */
.hero-shot {
  max-width: var(--content); margin: 40px auto 0; padding: 0 20px;
}
.hero-shot img {
  width: 100%; display: block; border-radius: var(--radius);
  border: 1px solid var(--border);
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.55);
}
.hero-intro {
  max-width: 640px; margin: 24px auto 0; padding: 0 20px;
  color: var(--text-2); font-size: 15px; line-height: 1.55;
  text-align: center;
}

/* ================================================================ sections */
.section { max-width: var(--content); margin: 0 auto; padding: 48px 20px; }
.section h2 {
  font-size: 13px; font-weight: 600; letter-spacing: 2px;
  text-transform: uppercase; color: var(--muted); margin: 0 0 22px;
}

/* ============================================================= plant cards */
.plants-live { display: block; max-width: 520px; }
.plants-later-label {
  margin: 28px 0 12px; font-size: 12px; font-weight: 600;
  letter-spacing: 1.5px; text-transform: uppercase; color: var(--muted);
}
.plants-later {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
}
@media (max-width: 760px) { .plants-later { grid-template-columns: 1fr; } }
.plant-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px 20px;
  display: flex; flex-direction: column; gap: 8px;
  color: var(--text);
}
.plant-card h3 { margin: 0; font-size: 22px; }
.plant-card .kind { color: var(--normal); font-size: 13px; letter-spacing: 0.5px; }
.plant-card p { margin: 0; color: var(--text-2); font-size: 14px; flex: 1; }
.plant-card .go {
  margin-top: 14px; align-self: flex-start;
  border: 1px solid var(--running); border-radius: var(--radius);
  color: var(--text); padding: 8px 18px; font-size: 14px; font-weight: 600;
}
.plant-card.live { transition: border-color 0.15s, transform 0.15s; }
.plant-card.live:hover {
  text-decoration: none; border-color: var(--running); transform: translateY(-2px);
}
.plant-card.live:hover .go { background: rgba(70, 163, 94, 0.12); }
.plant-card.soon { opacity: 0.48; }
.badge-soon {
  margin-top: 14px; align-self: flex-start;
  border: 1px solid var(--border); border-radius: var(--radius);
  color: var(--muted); padding: 8px 18px;
  font-size: 12px; font-weight: 700; letter-spacing: 1.5px;
}

/* ================================================================ features */
.features { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
@media (max-width: 760px) { .features { grid-template-columns: 1fr; } }
.feature {
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 18px 20px;
}
.feature h3 { margin: 0 0 6px; font-size: 16px; }
.feature p { margin: 0; color: var(--text-2); font-size: 14px; }

/* ============================================================ content pages */
.page { max-width: 760px; margin: 0 auto; padding: 48px 20px 64px; }
.page h1 { font-size: 32px; margin: 0 0 8px; letter-spacing: -0.5px; }
.page .lede { color: var(--text-2); font-size: 18px; margin: 0 0 32px; }
.page h2 {
  font-size: 20px; margin: 36px 0 10px;
  text-transform: none; letter-spacing: 0; color: var(--text);
}
.page h3 {
  font-size: 16px; margin: 20px 0 8px; font-weight: 600; color: var(--text);
}
.page p, .page li { color: var(--text-2); }
.page strong { color: var(--text); }
.page ul { padding-left: 1.25em; }
.page .page-cta { margin: 24px 0 8px; }
.page .page-cta-bottom { margin: 32px 0 0; }
.page .page-hero { padding: 0; margin: 28px 0 8px; }
.page .page-disclaimer { color: var(--text-2); margin-top: 2rem; }
.notice {
  background: var(--bg-panel); border: 1px solid var(--caution);
  border-radius: var(--radius); padding: 12px 16px;
  color: var(--text-2); font-size: 14px; margin-bottom: 28px;
}
.notice strong { color: var(--caution); }

/* =============================================================== changelog */
/* Entries are <details class="log-entry"><summary class="log-head">. Six releases
   landed in the first three days, so the page was always going to outgrow one
   screen; collapsing everything but the newest keeps the version list itself
   scannable. `display:flex` on the summary suppresses the default disclosure
   triangle in every engine, so the chevron below is drawn by hand — do not
   remove it and leave the flex, or the rows lose their only affordance. */
.log-entry { border-top: 1px solid var(--border); padding-top: 24px; margin-top: 32px; }
.log-entry:first-of-type { border-top: none; padding-top: 0; margin-top: 0; }
.log-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.log-head h2 { margin: 0; border: none; padding: 0; font-size: 20px; }
/* nowrap + a shrinkable h2. The base .log-head wraps, which was invisible while every
   entry was expanded and its head was one line among twenty; collapsed, a long headline
   pushed the date onto a line of its own and the version list read as ragged pairs.
   The headline now wraps INSIDE its own box and the version and date stay on the first
   line, where a scanner is looking for them. Wrapping comes back on a narrow screen. */
summary.log-head { cursor: pointer; list-style: none; flex-wrap: nowrap; }
summary.log-head h2 { flex: 1 1 auto; min-width: 0; }
summary.log-head .log-ver, summary.log-head .log-date { flex: 0 0 auto; }
@media (max-width: 620px) { summary.log-head { flex-wrap: wrap; } }
summary.log-head::-webkit-details-marker { display: none; }
summary.log-head::before {
  content: '▸'; flex: 0 0 auto; color: var(--muted); font-size: 15px; line-height: 1;
  transition: transform 0.12s; transform-origin: 50% 45%;
}
details[open] > summary.log-head::before { transform: rotate(90deg); }
summary.log-head:hover h2 { color: var(--normal); }
summary.log-head:focus-visible { outline: 2px solid var(--normal); outline-offset: 3px; }
.log-note {
  color: var(--muted); font-size: 13px; margin: 0 0 28px;
}
.log-ver {
  font-size: 12px; font-weight: 700; letter-spacing: 0.5px; color: var(--normal);
  border: 1px solid var(--border); border-radius: 999px; padding: 2px 9px; line-height: 1.5;
}
.log-date { color: var(--muted); font-size: 13px; margin-left: auto; }
.log-entry ul { margin: 14px 0 0; padding-left: 0; list-style: none; }
.log-entry li { margin-bottom: 10px; font-size: 15px; line-height: 1.55; }
.log-tag {
  display: inline-block; min-width: 62px; margin-right: 8px;
  font-size: 11px; letter-spacing: 0.6px; text-transform: uppercase;
  text-align: center; padding: 2px 6px; border-radius: 3px;
  border: 1px solid currentColor; vertical-align: 1px;
}
.log-tag.added { color: var(--running); }
.log-tag.changed { color: var(--normal); }
.log-tag.fixed { color: var(--caution); }
.log-empty {
  border: 1px dashed var(--border); border-radius: var(--radius);
  padding: 28px 20px; text-align: center; color: var(--muted); font-size: 15px;
}

/* ================================================================== footer */
.site-footer {
  border-top: 1px solid var(--border);
  margin-top: 32px; padding: 28px 20px 40px;
}
.site-footer .inner {
  max-width: var(--content); margin: 0 auto;
  color: var(--muted); font-size: 13px;
}
.site-footer .links { margin-top: 8px; display: flex; gap: 18px; flex-wrap: wrap; }
.site-footer a { color: var(--text-2); }

/* Download page — the primary action. Deliberately the only button of its size on the
   site: the page exists to do one thing. */
.btn-download {
  display: inline-block; padding: 14px 26px; margin: 8px 0 4px;
  background: var(--accent, #2f81f7); color: #fff; border-radius: 8px;
  font-size: 17px; font-weight: 600; text-decoration: none;
  border: 1px solid rgba(255,255,255,.14);
}
.btn-download:hover { filter: brightness(1.08); text-decoration: none; }
.btn-download .mono { opacity: .72; font-weight: 400; font-size: 14px; }
.dl-note { color: var(--text-2); font-size: 14px; margin-top: 4px; }
/* Version · date · size, filled from download/manifest.js at deploy (2026-08-06).
   Without it "latest.zip" gave a returning visitor no way to tell whether they
   already had this build. Stays hidden until the manifest fills it, so a local
   checkout (download/ is gitignored) shows nothing rather than a row of dashes. */
.dl-meta {
  display: none; margin: 10px 0 0; color: var(--text-2); font-size: 14px;
}
.dl-meta.is-filled { display: block; }
.dl-meta .sep { color: var(--muted); margin: 0 8px; }
