/* NETRUN TRACKERATOR
   Mobile-first. Assume a phone in portrait, one thumb, bad lighting, flaky
   venue wifi, and a distracted reader.

   Accessibility is not negotiable here (CLAUDE.md): pinch-zoom stays enabled,
   a real text-size control ships, and the camouflage on the agreement page is
   done with a scroll box rather than tiny type. */

:root {
  --scale: 1;
  --bg: #0a0c0f;
  --panel: #11151b;
  --panel-2: #161c24;
  --line: #24303d;
  --fg: #d6e2ea;
  --dim: #7d8ea0;
  --accent: #35e08a;
  --accent-dim: #1c6b45;
  --warn: #ffb648;
  --alert: #ff4f6d;
  --link: #5ad1ff;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

html {
  font-size: calc(16px * var(--scale));
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--mono);
  line-height: 1.55;
  padding: 0 0 5rem;
  overflow-x: hidden;
}

.wrap { max-width: 44rem; margin: 0 auto; padding: 0 1rem; }

/* Pages carrying a sidebar rail get a wider container -- masthead and footer
   included, so the page doesn't step in and out at different widths. */
body.has-rail .wrap { max-width: 62rem; }

.layout { display: block; }
.layout-main { min-width: 0; }

/* The rail is part of the normal flow on a phone (it just reads as one more ad
   near the bottom) and only becomes a sidebar when there's genuinely room.
   Mobile-first means no slot may vanish in portrait. */
.ad-rail { margin-top: 1.5rem; }
.ad-rail .ad-rail-label {
  font-size: .6rem; letter-spacing: .2em; color: var(--dim);
  text-transform: uppercase; margin-bottom: .4rem;
}

@media (min-width: 62rem) {
  body.has-rail .layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 15rem;
    gap: 2rem;
    align-items: start;
  }
  .ad-rail { margin-top: 0; position: sticky; top: 1rem; }
}

/* ---- masthead ---------------------------------------------------------- */
header.masthead {
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, #0d1117, #0a0c0f);
  padding: .85rem 0;
  margin-bottom: 1.25rem;
}
.masthead .wrap { display: flex; align-items: center; gap: .75rem; }
.masthead .brand {
  font-weight: 700; letter-spacing: .12em; font-size: .95rem;
  color: var(--accent); text-decoration: none; white-space: nowrap;
}
.masthead .brand span { color: var(--dim); }
.masthead .spacer { flex: 1; }

/* Text-size control. Real, working, and always reachable. */
.textsize { display: flex; gap: .25rem; }
.textsize button {
  font-family: var(--mono); background: var(--panel-2); color: var(--dim);
  border: 1px solid var(--line); border-radius: 4px;
  min-width: 2.25rem; min-height: 2.25rem; cursor: pointer; font-size: .8rem;
}
.textsize button[aria-pressed="true"] { color: var(--accent); border-color: var(--accent-dim); }

/* ---- type -------------------------------------------------------------- */
h1, h2, h3 { line-height: 1.25; letter-spacing: .04em; }
h1 { font-size: 1.5rem; margin: 0 0 .5rem; }
h2 { font-size: 1.1rem; margin: 2rem 0 .6rem; color: var(--accent); }
h3 { font-size: .95rem; margin: 1.25rem 0 .4rem; }
p { margin: 0 0 1rem; }
a { color: var(--link); }
.dim { color: var(--dim); }
.small { font-size: .85rem; }
.tiny { font-size: .78rem; }
.alert { color: var(--alert); }
.warn { color: var(--warn); }
.ok { color: var(--accent); }

.kicker {
  color: var(--dim); letter-spacing: .22em; font-size: .72rem;
  text-transform: uppercase; margin: 0 0 .35rem;
}

/* ---- panels ------------------------------------------------------------ */
.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 8px; padding: 1rem; margin: 0 0 1rem;
}
.panel.tight { padding: .75rem; }
.panel.hot { border-color: var(--alert); }
.panel.good { border-color: var(--accent-dim); }

.rule { border: 0; border-top: 1px dashed var(--line); margin: 1.25rem 0; }

/* ---- forms ------------------------------------------------------------- */
label { display: block; }
.field { margin: 0 0 1.5rem; }
.field > .q { font-weight: 700; margin: 0 0 .6rem; }

input[type="text"] {
  width: 100%; font-family: var(--mono); font-size: 1rem;
  padding: .8rem .75rem; background: var(--panel-2); color: var(--fg);
  border: 1px solid var(--line); border-radius: 6px;
}
input[type="text"]:focus, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* Radio options as full-width thumb targets. */
.opt {
  display: flex; align-items: flex-start; gap: .65rem;
  padding: .7rem .75rem; margin: 0 0 .4rem;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 6px; cursor: pointer; min-height: 2.75rem;
}
.opt input { margin-top: .2rem; width: 1.15rem; height: 1.15rem; flex: none; }
.opt:has(input:checked) { border-color: var(--accent); background: #12241b; }

.btn {
  display: inline-block; width: 100%; text-align: center;
  font-family: var(--mono); font-size: 1rem; font-weight: 700;
  letter-spacing: .06em; padding: .95rem 1rem; min-height: 3rem;
  background: var(--accent); color: #051009; border: 0; border-radius: 6px;
  cursor: pointer; text-decoration: none;
}
.btn.ghost { background: transparent; color: var(--fg); border: 1px solid var(--line); }
.btn.danger { background: var(--alert); color: #1a0308; }
.btn + .btn { margin-top: .5rem; }

.errors { border-left: 3px solid var(--alert); padding-left: .75rem; }
.errors li { color: var(--alert); }

/* ---- the pre-checked consent box --------------------------------------
   Smaller type, muted, sits below the submit button's visual weight. It is
   unambiguous on careful reading and invisible to a two-second read. It is NOT
   undecidable -- an undecidable prompt rewards a coin flip and teaches nothing. */
.consent-strip {
  margin-top: 1.75rem; padding-top: .9rem;
  border-top: 1px solid var(--line); color: var(--dim);
}
.consent-strip label {
  display: flex; gap: .5rem; align-items: flex-start;
  font-size: .76rem; line-height: 1.45;
}
.consent-strip input { margin-top: .15rem; width: 1rem; height: 1rem; flex: none; }
.consent-strip .prefs-link { color: var(--dim); text-decoration: none; }
.consent-strip .prefs-link:hover { text-decoration: underline; }

/* ---- agreement --------------------------------------------------------
   200px fixed-height scroll box: more authentic than tiny type, same
   sliver-of-a-scrollbar effect, and it does not lock out anyone with a vision
   impairment. The camouflage does the work, not the point size. */
.agreement-box {
  height: 200px; overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: #0d1116; border: 1px solid var(--line); border-radius: 6px;
  padding: .85rem; font-size: .8rem; line-height: 1.5;
}
.agreement-box h2 { font-size: .85rem; color: var(--fg); margin: 1.1rem 0 .35rem; }
.agreement-box h3 { font-size: .8rem; color: var(--fg); margin: .9rem 0 .3rem; }
.agreement-box p { margin: 0 0 .65rem; }

/* Links inside the agreement read as body text: same colour, same weight,
   hover-underline only (a no-op on touch). Present and functional, invisible
   to skimming. */
.agreement-box a { color: inherit; text-decoration: none; font-weight: inherit; }
.agreement-box a:hover { text-decoration: underline; }
.agreement-box a:focus-visible { outline: 2px solid var(--accent); }

.scrollmeter {
  display: flex; justify-content: space-between; align-items: center;
  font-size: .72rem; color: var(--dim); margin-top: .35rem;
}

/* ---- toggles ----------------------------------------------------------- */
.toggle {
  display: flex; align-items: flex-start; gap: .7rem;
  padding: .8rem .25rem; border-bottom: 1px solid var(--line);
  min-height: 3rem; cursor: pointer;
}
.toggle input { margin-top: .25rem; width: 1.2rem; height: 1.2rem; flex: none; }
.toggle .t-label { font-size: .9rem; }
.toggle .t-note { font-size: .76rem; color: var(--dim); margin-top: .15rem; }
.toggle .t-num { color: var(--dim); font-size: .72rem; min-width: 1.5rem; }

/* ---- ads --------------------------------------------------------------
   Styled to read as an ad slot rather than as part of the app: warmer, boxier,
   slightly too eager. It should feel like something wedged into the page,
   because that is what it is. */
.ad {
  border: 1px solid var(--line); border-left: 3px solid var(--warn);
  border-radius: 6px; padding: .85rem; margin: 0 0 1rem;
  background: #15181d;
}
a.ad { display: block; text-decoration: none; color: inherit; }
a.ad:hover, a.ad:focus-visible { border-color: var(--warn); }
.ad.pinned { border-left-width: 5px; }
.ad.pinned .ad-tag { color: var(--warn); }

/* Dismissible pop-over. The close control is deliberately full-size and first
   in the tab order -- the joke is the volume of ads, not trapping anyone. */
.ad-overlay {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(4, 6, 9, .82);
  display: flex; align-items: center; justify-content: center; padding: 1rem;
}
.ad-overlay-card {
  background: #15181d; border: 1px solid var(--warn); border-radius: 8px;
  padding: 1rem; max-width: 26rem; width: 100%;
  max-height: 88vh; overflow-y: auto;
}
.ad-close {
  display: block; width: 100%; min-height: 2.75rem; margin: 0 0 .75rem;
  font-family: var(--mono); font-size: .78rem; letter-spacing: .14em;
  background: var(--panel-2); color: var(--fg);
  border: 1px solid var(--line); border-radius: 6px; cursor: pointer;
}
.ad-close:hover { border-color: var(--accent); color: var(--accent); }

.ad-tag {
  font-size: .58rem; letter-spacing: .22em; color: var(--dim);
  text-transform: uppercase; margin-bottom: .4rem;
}
.ad-brand {
  font-size: .68rem; letter-spacing: .16em; color: var(--warn);
  text-transform: uppercase; margin-bottom: .3rem;
}
.ad-headline { font-size: 1rem; font-weight: 700; line-height: 1.3; margin-bottom: .3rem; }
.ad-body { font-size: .82rem; color: var(--dim); margin: 0 0 .55rem; }
.ad-cta {
  display: inline-block; font-size: .72rem; letter-spacing: .12em;
  color: var(--warn); border: 1px solid var(--accent-dim);
  border-radius: 4px; padding: .4rem .6rem;
}

/* The dossier's attribution card: same ad, now with its sourcing attached. */
.ad-why {
  border-top: 1px dashed var(--line); margin-top: .6rem; padding-top: .5rem;
  font-size: .76rem; color: var(--dim);
}
/* Source tiers. Same colours mid-run and on the dossier: during the run they
   mean nothing to the player, which is the point -- the eye learns a
   distinction it can't name, and the dossier cashes it in at the end.

   Colour is the only cue mid-run, and that's fine: nothing actionable rides on
   it, so missing it costs a player nothing. On the dossier, where it does
   matter, the section headings and the SPONSORED — ... labels carry the meaning
   in text. */
.ad.ad-s1 { border-left-color: var(--warn); }      /* you told us */
.ad.ad-s1 .ad-why { color: var(--dim); }
.ad.ad-s2 { border-left-color: var(--link); }      /* where you went */
.ad.ad-s2 .ad-why { color: var(--link); }
.ad.ad-s3 { border-left-color: var(--alert); }     /* someone near you told us */
.ad.ad-s3 .ad-why { color: var(--alert); }

.ad-overlay-card.ad-s1 { border-color: var(--warn); }
.ad-overlay-card.ad-s2 { border-color: var(--link); }
.ad-overlay-card.ad-s3 { border-color: var(--alert); }

/* ---- receipt ----------------------------------------------------------- */
.receipt {
  background: #0d1116; border: 1px dashed var(--line); border-radius: 6px;
  padding: .9rem; font-size: .82rem; white-space: pre-wrap; overflow-x: auto;
}
.receipt .sold { color: var(--warn); }
.receipt .supp { color: var(--accent); }

table { width: 100%; border-collapse: collapse; font-size: .82rem; }
th, td { text-align: left; padding: .5rem .4rem; border-bottom: 1px solid var(--line); }
th { color: var(--dim); font-weight: 400; text-transform: uppercase; font-size: .7rem;
     letter-spacing: .1em; }
.table-scroll { overflow-x: auto; }

.flag {
  display: block; background: #12241b; border: 1px solid var(--accent-dim);
  border-radius: 6px; padding: .7rem; color: var(--accent);
  font-size: .9rem; word-break: break-all; margin: .5rem 0;
}

.confidence { color: var(--dim); }
.bar { height: 3px; background: var(--line); border-radius: 2px; overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--accent-dim); }

/* The debrief. The one place the app speaks as itself rather than as the
   character, so it gets ordinary prose measure instead of terminal styling. */
.debrief h2 { color: var(--accent); font-size: 1.05rem; margin: 1.75rem 0 .5rem; }
.debrief h2:first-child { margin-top: 0; }
.debrief p, .debrief li { font-size: .9rem; line-height: 1.65; }
.debrief ul { padding-left: 1.1rem; }
.debrief li { margin-bottom: .6rem; }
.debrief strong { color: var(--fg); }

footer.foot {
  margin-top: 3rem; padding-top: 1rem; border-top: 1px solid var(--line);
  color: var(--dim); font-size: .76rem;
}
footer.foot a { color: var(--dim); }
/* Anonymous-mode note. Lives in the footer rather than the masthead: a badge on
   every screen reads as a surveillance indicator, which is the opposite of the
   reassurance this mode is supposed to provide. Quiet, but always present so
   nobody is in the state without knowing, and the way out is one tap. */
.anonnote { color: var(--dim); }

@media print {
  body { background: #fff; color: #000; }
  .noprint { display: none !important; }
}
