:root {
  --bg: #fbf8f4;
  --panel: #ffffff;
  --ink: #1d1a26;
  --soft: #5d5670;
  --faint: #8b839c;
  --line: #e3dcd2;
  --warm: #b8722a;
  --warm-bg: #fdf2e3;
  --her: #f4eee6;
  --you: #eceaf4;
  --alarm: #9a2f2f;
  --alarm-bg: #fbeeee;
  --radius: 12px;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --serif: Georgia, "Iowan Old Style", "Times New Roman", serif;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

[data-theme="dark"] {
  --bg: #14121c;
  --panel: #1c1926;
  --ink: #efe9e2;
  --soft: #b7aec6;
  --faint: #837a96;
  --line: #2e2a3c;
  --warm: #f0b46a;
  --warm-bg: #2a2130;
  --her: #241f30;
  --you: #1f2130;
  --alarm: #f0908c;
  --alarm-bg: #2e1e22;
}

* { box-sizing: border-box; }

/* THIS RULE IS LOAD-BEARING. Every panel in this app is shown and hidden by
 * toggling the `hidden` attribute, which the user-agent implements as a plain
 * `display: none` — so ANY author rule that sets `display` on the same element
 * silently wins and the panel never hides. Two shipped that way: `.progress`
 * and `.composer` are both `display: flex`, so the four-stage progress tracker
 * sat visible through an entire conversation with nothing in flight, and the
 * Send box stayed on screen after the evening had ended. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.62 var(--sans);
  -webkit-text-size-adjust: 100%;
}

a { color: var(--warm); }

h1, h2, h3 { font-family: var(--serif); font-weight: 700; line-height: 1.22; }
h1 { font-size: clamp(1.7rem, 4.2vw, 2.6rem); margin: 0 0 .7rem; }
h2 { font-size: clamp(1.2rem, 2.6vw, 1.55rem); margin: 0 0 .6rem; }
h3 { font-size: 1.05rem; margin: 0 0 .4rem; }

p { margin: 0 0 .85rem; }

.skip {
  position: absolute; left: -9999px; top: 0; background: var(--panel);
  padding: .5rem .8rem; z-index: 40;
}
.skip:focus { left: .5rem; top: .5rem; }

.vis-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

.bar {
  position: sticky; top: 0; z-index: 20;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}
.bar-in {
  max-width: 1080px; margin: 0 auto; padding: .55rem 1rem;
  display: flex; align-items: center; gap: .55rem; flex-wrap: wrap;
}
.back { text-decoration: none; font-size: .9rem; }
.sep { color: var(--faint); }
.brand { font-family: var(--serif); font-weight: 700; }
.grow { flex: 1 1 auto; }
.credits { font: 600 .82rem/1 var(--mono); color: var(--soft); white-space: nowrap; }
.linkish { font-size: .85rem; }

main { max-width: 1080px; margin: 0 auto; padding: 1.4rem 1rem 2rem; }

.hero { margin-bottom: 1.6rem; }
.intro { margin: 0 0 1rem; }
.intro h1 { margin-bottom: .25rem; }
.lede { font-size: 1.07rem; color: var(--ink); }
.quiet { color: var(--soft); }
.tiny { font-size: .82rem; color: var(--faint); margin: .3rem 0 .6rem; }
.err { color: var(--alarm); font-size: .9rem; }

.row { display: flex; gap: .55rem; align-items: center; flex-wrap: wrap; margin: .8rem 0 0; }

.btn {
  font: 600 .92rem/1 var(--sans);
  padding: .62rem .95rem;
  border-radius: 9px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--ink);
  cursor: pointer;
}
.btn:hover:not(:disabled) { border-color: var(--warm); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn.primary { background: var(--warm); border-color: var(--warm); color: #1d1a26; }
.btn.small { font-size: .82rem; padding: .42rem .7rem; }
.btn.ghost { background: transparent; }
.btn.link {
  background: none; border: 0; padding: 0 0 0 .1rem;
  color: var(--warm); text-decoration: underline; font-size: inherit;
}

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.1rem 1.15rem;
  margin: 0 0 1.3rem;
}

.rules { margin: .6rem 0 0; padding-left: 1.1rem; color: var(--soft); }
.rules li { margin-bottom: .45rem; }
.rules strong { color: var(--ink); }

/* ---- the roll ----
 * The four rolled evenings are the first control on the page: a pick is one
 * click and needs no explanation, while the code box beside them stays there
 * for anyone who wants a particular character back. */
.setup { margin: 0 0 1.3rem; }

.picks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .6rem; }
@media (min-width: 700px) { .picks { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.pick {
  display: flex; flex-direction: column; gap: .3rem;
  text-align: left; cursor: pointer;
  padding: .75rem .8rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); color: var(--ink);
  font: inherit;
}
.pick:hover { border-color: var(--warm); }
.pick:focus-visible { outline: 2px solid var(--warm); outline-offset: 1px; }
.pick.on { border-color: var(--warm); background: var(--her); box-shadow: inset 3px 0 0 var(--warm); }
.pick-name { font-family: var(--serif); font-weight: 700; font-size: 1.02rem; }
.pick-mid {
  font-size: .84rem; color: var(--soft); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.pick-att { font: .74rem/1 var(--mono); color: var(--warm); margin-top: auto; padding-top: .3rem; }

/* The grid and the profile card are both filled by app.js, and on a cold edge
 * that is several seconds after the markup paints. Reserve the space rather
 * than letting the run button jump down the page when the roll arrives, and do
 * not draw an empty bordered box where a character will be. */
.picks:empty {
  min-height: 7.5rem; border: 1px dashed var(--line); border-radius: var(--radius);
}
.hercard:empty { display: none; }

.pickbar { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin-top: .7rem; }

.seedrow { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin-top: .8rem; }
.seedlab { font-size: .82rem; color: var(--faint); text-transform: uppercase; letter-spacing: .07em; }
.seedbox {
  font: 700 1.05rem/1 var(--mono);
  letter-spacing: .18em;
  padding: .55rem .7rem;
  width: 11ch;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--bg);
  color: var(--ink);
  text-transform: uppercase;
}
.seedbox:focus { outline: 2px solid var(--warm); outline-offset: 1px; }

.hercard {
  margin: 1rem 0 .3rem;
  border: 1px solid var(--line);
  border-left: 4px solid var(--warm);
  border-radius: var(--radius);
  padding: .95rem 1rem;
  background: var(--her);
}
.hercard h3 { font-size: 1.3rem; margin-bottom: .5rem; }
.hercard dl { margin: 0; display: grid; grid-template-columns: minmax(9rem, auto) 1fr; gap: .3rem .9rem; }
.hercard dt { font-size: .76rem; text-transform: uppercase; letter-spacing: .06em; color: var(--faint); padding-top: .2rem; }
.hercard dd { margin: 0; }
.hercard .boundary { color: var(--warm); }

/* The age tick and the run button sit on one line so the gate is read at the
 * point of action rather than as small print somewhere above it. */
.gate {
  margin-top: 1rem; padding-top: .9rem; border-top: 1px solid var(--line);
  display: flex; gap: .8rem; align-items: center; flex-wrap: wrap;
}
.check { display: flex; gap: .45rem; align-items: center; font-weight: 600; white-space: nowrap; }
.check input { margin: 0; }

.meter { font: .84rem/1.4 var(--mono); color: var(--soft); }

/* ---- conversation ---- */
.convo { margin-bottom: 1.3rem; }
/* The framing travels with the conversation. It was previously only on the
 * landing page, which is the one place a person in the middle of an evening is
 * not looking. */
.fiction {
  font-size: .86rem; color: var(--soft); margin: 0 0 .9rem;
  padding: .55rem .75rem; border-left: 3px solid var(--line); background: var(--panel);
  border-radius: 0 8px 8px 0;
}
.fiction strong { color: var(--ink); }

/* One bordered card: framing strip, an internally scrolling transcript, and a
 * composer pinned to its bottom edge. The cap is viewport-relative so the
 * composer never leaves the screen however long the evening runs. */
.chat {
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); overflow: hidden;
}
.chat .fiction {
  margin: 0; border: 0; border-radius: 0; background: var(--her);
  border-bottom: 1px solid var(--line); padding: .6rem .9rem;
}
.convo-grid { display: grid; grid-template-columns: 1fr; gap: 1.1rem; }
@media (min-width: 900px) { .convo-grid { grid-template-columns: 1fr 20rem; } }

.stream { min-width: 0; }
.transcript {
  display: flex; flex-direction: column; gap: .7rem;
  padding: .9rem; margin: 0;
  max-height: 58vh; min-height: 8rem; overflow-y: auto; overscroll-behavior: contain;
}
/* One dim line where a paragraph used to be. It is generated content so it
 * disappears the instant the first turn is appended, with no JS to keep in
 * step with the transcript's own state. */
.transcript:empty::before {
  content: "Her evening is already happening. Say something.";
  color: var(--faint); font-size: .9rem; margin: auto; text-align: center;
}
.chat .support, .chat .refusal, .chat .ended, .chat .progress { margin: 0 .9rem .9rem; }
.chat .progress { margin-top: -.2rem; }
.turn { padding: .7rem .9rem; border-radius: var(--radius); max-width: 46rem; }
.turn.you { background: var(--you); align-self: flex-end; }
.turn.her { background: var(--her); align-self: flex-start; }
.turn .who { font-size: .74rem; text-transform: uppercase; letter-spacing: .07em; color: var(--faint); display: block; margin-bottom: .2rem; }
.turn p { margin: 0 0 .45rem; white-space: pre-wrap; }
.turn p:last-child { margin-bottom: 0; }
.turn .charged { font: .74rem/1 var(--mono); color: var(--faint); display: block; margin-top: .45rem; }
.flags { margin: .5rem 0 0; padding: .5rem .65rem; border-radius: 8px; background: var(--warm-bg); font-size: .84rem; }
.flags b { color: var(--warm); }
.flags ul { margin: .3rem 0 0; padding-left: 1.05rem; }

.support, .refusal, .ended {
  border-radius: var(--radius); padding: .9rem 1rem; margin: 0 0 .9rem;
  border: 1px solid var(--line);
}
.support { background: var(--alarm-bg); border-color: var(--alarm); }
.support h3 { color: var(--alarm); }
.refusal { background: var(--warm-bg); border-color: var(--warm); }
.ended { background: var(--her); }

.progress { display: flex; align-items: center; gap: .8rem; margin-bottom: .9rem; flex-wrap: wrap; }
.steps { display: flex; gap: .5rem; margin: 0; padding: 0; list-style: none; flex-wrap: wrap; }
.steps li { font-size: .78rem; color: var(--faint); padding: .22rem .5rem; border: 1px solid var(--line); border-radius: 999px; }
.steps li.on { color: var(--ink); border-color: var(--warm); }
.steps li.done { color: var(--warm); }
.elapsed { font: .8rem/1 var(--mono); color: var(--faint); }

.composer {
  display: flex; flex-direction: column; gap: .5rem;
  border-top: 1px solid var(--line); padding: .7rem .9rem; background: var(--bg);
}
.composer textarea {
  width: 100%; resize: vertical; min-height: 4.4rem;
  font: 1rem/1.55 var(--sans);
  padding: .7rem .8rem;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); color: var(--ink);
}
.composer textarea:focus { outline: 2px solid var(--warm); outline-offset: 1px; }
.composer-foot { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.cost { font: .82rem/1.4 var(--mono); color: var(--soft); }

/* ---- her evening ---- */
.evening {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); padding: .95rem 1rem; align-self: start;
}
@media (min-width: 900px) { .evening { position: sticky; top: 4rem; } }
.evening h3 { font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; color: var(--faint); font-family: var(--sans); }
.evening .att { font: 700 2.1rem/1 var(--serif); color: var(--warm); }
.evening .attlab { font-size: .8rem; color: var(--faint); }
.evening .bar-track { height: 6px; border-radius: 999px; background: var(--line); margin: .5rem 0 .9rem; overflow: hidden; }
.evening .bar-fill { height: 100%; background: var(--warm); }
.evening dl { margin: 0 0 .2rem; }
.evening dt { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--faint); margin-top: .6rem; }
.evening dd { margin: .1rem 0 0; font-size: .92rem; }
.evening .last { margin-top: .8rem; color: var(--alarm); font-weight: 600; font-size: .9rem; }

/* ---- disclosures ----
 * Everything that explains the app rather than running it lives below the
 * controls and closed. None of it is deleted: the cost table, the published
 * guardrail figures and the history are all still in the document, and all
 * still crawlable, they are simply not standing between a visitor and the
 * first click. */
.more { margin: .4rem 0 .9rem; }

.disc {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); margin: 0 0 .6rem; padding: 0 1.05rem;
}
.disc > summary {
  cursor: pointer; padding: .8rem 0; font-weight: 600;
  font-family: var(--serif); font-size: 1.02rem; list-style-position: outside;
}
.disc > summary:hover { color: var(--warm); }
.disc > summary:focus-visible { outline: 2px solid var(--warm); outline-offset: 2px; }
.disc[open] > summary { border-bottom: 1px solid var(--line); margin-bottom: .8rem; }
.disc > *:last-child { margin-bottom: .9rem; }

/* ---- tables, history, numbers ---- */
.costs { width: 100%; border-collapse: collapse; margin: .8rem 0; font-size: .92rem; }
.costs th, .costs td { text-align: left; padding: .42rem .5rem; border-bottom: 1px solid var(--line); }
.costs td:last-child, .costs th:last-child { text-align: right; font-family: var(--mono); white-space: nowrap; }

.history { display: grid; gap: .6rem; margin-top: .9rem; }
.hrec { border: 1px solid var(--line); border-radius: var(--radius); padding: .7rem .85rem; background: var(--bg); }
.hrec .hname { font-family: var(--serif); font-weight: 700; }
.hrec .hmeta { font: .78rem/1.5 var(--mono); color: var(--faint); }
.hrec .hseed { font-family: var(--mono); letter-spacing: .1em; }

.numbers { display: grid; gap: .5rem; margin-top: .9rem; }
.numbers table { width: 100%; border-collapse: collapse; font-size: .88rem; }
.numbers th, .numbers td { text-align: left; padding: .35rem .5rem; border-bottom: 1px solid var(--line); }
.numbers td:not(:first-child), .numbers th:not(:first-child) { text-align: right; font-family: var(--mono); }

.foot {
  max-width: 1080px; margin: 0 auto; padding: 1.4rem 1rem 2.4rem;
  border-top: 1px solid var(--line); color: var(--faint); font-size: .88rem;
}
.foot p { margin: 0 0 .4rem; }

/* ---- docs pages ---- */
.doc { max-width: 900px; }
.doc pre {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: .8rem .9rem; overflow-x: auto; font: .84rem/1.55 var(--mono);
}
.doc code { font: .88em var(--mono); }
.tabs { display: flex; gap: .35rem; flex-wrap: wrap; margin: .8rem 0 .5rem; }
.tab { font: .8rem/1 var(--sans); padding: .38rem .6rem; border: 1px solid var(--line); border-radius: 999px; background: transparent; color: var(--soft); cursor: pointer; }
.tab.on { border-color: var(--warm); color: var(--ink); }
.doc table { width: 100%; border-collapse: collapse; font-size: .9rem; margin: .7rem 0; }
.doc th, .doc td { text-align: left; padding: .4rem .5rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.tokbox { font: .84rem var(--mono); word-break: break-all; background: var(--bg); border: 1px solid var(--line); border-radius: 8px; padding: .55rem .65rem; }
