Files
TheLadder/src/ui/styles.css
T
JesseMarkowitzandClaude Opus 5 d84ae495f4 Keep money mattering at the top, and fix the instruments that hid it
Both settings now carry a charge levied by standing itself, which no purchase
ends. Corporate Ladder's steps on money (1200/-60, 2400/-120, 3600/-240): a flat
charge cannot flatten a slope, since late income scales with how well the player
plays, and the flat charge needed to stop an optimiser accumulating put ordinary
archetypes below zero for 44% of a run. Stepped, the balance settles around
$4,250 and ordinary play comes out better than before it existed. The Frontier's
is flat at -4 a run, because its late game never accumulated in the first place.

Found in the first two human sessions of this work:

- A career saved before a pack gained a stat had no path for it, and conditions
  compare numbers only, so every event, option and upkeep entry gated on a new
  stat silently did not exist for that run. Loading now fills those in.
- 'Wrap up my career' sat immediately after the last option in tab order, so one
  Tab too many and Enter read as the game ending at day 31. It goes last, and
  the retrospective says plainly that it is a summary.
- A 181-turn session ran against a stale bundle and the change under test never
  fired. Every logged turn now records app_version and build.
- src/version.js had reported 0.3.0 since 0.3.0, while playtesters were told to
  check the status bar. A test now holds it to package.json.
- 'Put money against the book' was shown locked to a player who owed nothing,
  six times. Options gated on a state the player cannot choose to enter are now
  hidden rather than greyed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RxdJFbLq1rBKsUeticGV1g
2026-09-12 23:07:35 -04:00

341 lines
12 KiB
CSS

/* The Ladder — one stylesheet, no framework.
The look is office stationery: manila, rules, stamped figures. Muted enough
that seventeen scenarios in a row do not tire the eye. */
:root {
--paper: #f2eee4;
--card: #fffdf7;
--ink: #26231d;
--ink-soft: #6b6659;
--ink-faint: #938c7c;
--rule: #ded6c4;
--rule-strong: #c9bfa8;
--accent: #7c5a2c;
--accent-soft: #efe3cd;
--up: #4a6b3d;
--down: #a4402f;
--focus: #2f6f9e;
--radius: 3px;
--sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--serif: Georgia, "Iowan Old Style", "Palatino Linotype", Palatino, serif;
}
@media (prefers-color-scheme: dark) {
:root {
--paper: #1c1a17;
--card: #24211d;
--ink: #e8e3d8;
--ink-soft: #a8a294;
--ink-faint: #7d776a;
--rule: #38342d;
--rule-strong: #4a453b;
--accent: #c9a05e;
--accent-soft: #3a3227;
--up: #85ad72;
--down: #d17a68;
--focus: #6fa8d4;
}
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--paper);
color: var(--ink);
font-family: var(--sans);
font-size: 16px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
.app { max-width: 1080px; margin: 0 auto; padding: 24px 20px 48px; }
/* ---------- status bar ---------- */
.statusbar {
display: flex; flex-wrap: wrap; gap: 8px 16px;
align-items: baseline; justify-content: space-between;
margin-bottom: 18px; padding-bottom: 10px;
border-bottom: 1px solid var(--rule);
font-size: 12px; letter-spacing: 0.04em;
}
.statusbar__what { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }
.statusbar__game { font-weight: 600; color: var(--ink); }
.statusbar__sep { color: var(--rule-strong); }
.statusbar__pack { color: var(--ink-soft); }
.statusbar__title { color: var(--accent); }
.statusbar__version {
font-variant-numeric: tabular-nums; color: var(--ink-faint); font-size: 11px;
}
.booting { color: var(--ink-faint); padding: 48px 20px; text-align: center; }
/* ---------- head-up display ---------- */
.hud {
display: flex;
flex-wrap: wrap;
gap: 20px 32px;
align-items: flex-end;
justify-content: space-between;
padding-bottom: 16px;
border-bottom: 2px solid var(--rule-strong);
}
.hud__stage {
margin: 0;
font-size: 12px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--ink-faint);
}
.hud__day { margin: 2px 0 0; font-size: 26px; font-weight: 600; letter-spacing: -0.01em; }
.hud__detail { margin: 1px 0 0; font-size: 13px; color: var(--ink-soft); }
.diary {
margin: 14px 0 0; padding: 8px 12px;
font-size: 12.5px; color: var(--ink-soft);
background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius);
}
.diary__entry--in { color: var(--up); }
.diary__entry--out { color: var(--ink-soft); }
.stats { display: flex; flex-wrap: wrap; gap: 10px 26px; align-items: flex-end; }
.figure { display: flex; flex-direction: column; gap: 1px; min-width: 92px; }
.figure__label {
font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint);
}
.figure__value { font-family: var(--serif); font-size: 21px; font-variant-numeric: tabular-nums; }
.figure__value--negative { color: var(--down); }
/* ---------- meters ---------- */
.meter { min-width: 150px; }
.meter--compact { min-width: 132px; }
.meter__head {
display: flex; justify-content: space-between; gap: 10px; align-items: baseline;
font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint);
}
.meter__value { font-variant-numeric: tabular-nums; color: var(--ink-soft); }
.meter__track {
margin-top: 4px; height: 5px; background: var(--rule); border-radius: 99px; overflow: hidden;
}
.meter__fill {
height: 100%; background: var(--accent); border-radius: 99px;
transition: width 280ms ease;
}
/* ---------- layout ---------- */
.layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 280px;
gap: 36px;
margin-top: 28px;
align-items: start;
}
@media (max-width: 860px) {
.layout { grid-template-columns: minmax(0, 1fr); gap: 28px; }
}
/* ---------- the scenario ---------- */
.scenario__text, .outcome__text {
font-family: var(--serif);
font-size: 20px;
line-height: 1.55;
margin: 0 0 24px;
}
.options { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.option {
display: flex; flex-direction: column; gap: 3px; width: 100%;
padding: 14px 16px; text-align: left; cursor: pointer;
background: var(--card); color: inherit; font: inherit;
border: 1px solid var(--rule-strong); border-radius: var(--radius);
transition: border-color 120ms ease, transform 120ms ease, background 120ms ease;
}
.option:hover:not(:disabled) { border-color: var(--accent); transform: translateX(2px); }
.option:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.option__label { font-size: 16px; }
.option--locked {
cursor: not-allowed; background: transparent; border-style: dashed;
border-color: var(--rule); color: var(--ink-faint);
}
.option__requirement {
font-size: 12px; letter-spacing: 0.04em; color: var(--ink-faint); font-style: italic;
}
/* ---------- outcome ---------- */
.outcome__chose {
margin: 0 0 10px; font-size: 12px; letter-spacing: 0.12em;
text-transform: uppercase; color: var(--accent);
}
.outcome__ledger {
margin: 26px 0; padding: 18px 20px;
background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius);
}
.outcome__heading {
margin: 0 0 10px; font-size: 11px; letter-spacing: 0.12em;
text-transform: uppercase; color: var(--ink-faint); font-weight: 600;
}
.outcome__upkeep { margin-top: 18px; padding-top: 16px; border-top: 1px dashed var(--rule); }
.changes { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.changes--none { color: var(--ink-faint); font-style: italic; margin: 0; }
.change { display: flex; gap: 10px; align-items: baseline; font-size: 14px; }
.change__label { color: var(--ink-soft); }
.change__delta { font-variant-numeric: tabular-nums; font-weight: 600; margin-left: auto; }
.change--up .change__delta { color: var(--up); }
.change--down .change__delta { color: var(--down); }
.change__note { font-size: 11px; color: var(--ink-faint); font-style: italic; }
.change--note .change__phrase { font-style: italic; }
.change--note.change--up .change__phrase { color: var(--up); }
.change--note.change--down .change__phrase { color: var(--ink-soft); }
.button--next { margin-top: 8px; }
/* ---------- people ---------- */
.people__heading, .retro__heading {
margin: 0 0 12px; font-size: 11px; letter-spacing: 0.12em;
text-transform: uppercase; color: var(--ink-faint); font-weight: 600;
}
.person {
padding: 16px; margin-bottom: 14px;
background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius);
}
.person__name { margin: 0; font-size: 16px; font-weight: 600; }
.person__title {
margin: 1px 0 0; font-size: 11px; letter-spacing: 0.08em;
text-transform: uppercase; color: var(--ink-faint);
}
.person__description {
margin: 10px 0 14px; font-size: 13px; line-height: 1.5; color: var(--ink-soft);
font-family: var(--serif);
}
.person__meters { display: grid; gap: 8px; }
/* ---------- feedback ---------- */
.feedback {
margin: 24px 0; padding: 14px 16px;
border: 1px dashed var(--rule-strong); border-radius: var(--radius);
}
.feedback__row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.feedback__prompt { font-size: 13px; color: var(--ink-soft); }
.feedback__ratings { display: flex; gap: 6px; }
.rating {
padding: 4px 10px; font-size: 16px; line-height: 1.2; cursor: pointer;
background: transparent; border: 1px solid var(--rule); border-radius: var(--radius);
filter: grayscale(1); opacity: 0.65; transition: all 120ms ease;
}
.rating:hover { opacity: 1; filter: none; }
.rating--on { filter: none; opacity: 1; border-color: var(--accent); background: var(--accent-soft); }
.rating:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.feedback__toggle {
margin-left: auto; padding: 0; font: inherit; font-size: 12px; cursor: pointer;
background: none; border: none; color: var(--ink-faint); text-decoration: underline;
}
.feedback__detail { display: grid; gap: 12px; margin-top: 14px; }
.field { display: grid; gap: 4px; }
.field__label { font-size: 12px; color: var(--ink-faint); }
.field__input {
width: 100%; padding: 8px 10px; font: inherit; font-size: 14px; resize: vertical;
background: var(--card); color: inherit;
border: 1px solid var(--rule); border-radius: var(--radius);
}
.field__input:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.feedback__saved { margin: 10px 0 0; font-size: 12px; color: var(--up); }
/* ---------- buttons and controls ---------- */
.controls {
display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
margin-top: 36px; padding-top: 18px; border-top: 1px solid var(--rule);
}
.button {
padding: 9px 15px; font: inherit; font-size: 14px; cursor: pointer;
background: var(--card); color: inherit;
border: 1px solid var(--rule-strong); border-radius: var(--radius);
transition: border-color 120ms ease, background 120ms ease;
}
.button:hover { border-color: var(--accent); }
.button:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.button--primary { background: var(--accent); border-color: var(--accent); color: #fffdf7; }
.button--primary:hover { filter: brightness(1.08); }
.button--quiet { border-color: transparent; background: transparent; color: var(--ink-faint); }
.button--quiet:hover { color: var(--ink); border-color: var(--rule); }
/* ---------- retrospective ---------- */
.retro__head { padding-bottom: 20px; border-bottom: 2px solid var(--rule-strong); }
.retro__eyebrow {
margin: 0; font-size: 11px; letter-spacing: 0.14em;
text-transform: uppercase; color: var(--ink-faint);
}
.retro__title { margin: 6px 0 4px; font-size: 32px; font-weight: 600; letter-spacing: -0.02em; }
.retro__subtitle { margin: 0; color: var(--ink-soft); font-family: var(--serif); font-size: 17px; }
.retro__note { margin: 8px 0 0; color: var(--ink-soft); font-size: 13px; }
.retro__section { margin-top: 34px; }
.retro__people { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
.retro__people .person { margin-bottom: 0; }
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; margin: 0; }
.facts__item {
padding: 12px 14px; background: var(--card);
border: 1px solid var(--rule); border-radius: var(--radius);
}
.facts__label {
font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint);
}
.facts__value { margin: 3px 0 0; font-family: var(--serif); font-size: 16px; }
.moments { margin: 0; padding-left: 22px; display: grid; gap: 7px; }
.moment { font-family: var(--serif); font-size: 16px; }
.moments--none { padding: 0; color: var(--ink-faint); font-style: italic; }
.screen--error { padding: 40px 0; }
.screen--error h1 { font-size: 20px; color: var(--down); }
/* The setting picker. One card per content pack; the pack you are in is
marked rather than hidden, because "keep playing" is the common case. */
.screen--packs { padding: 40px 0; }
.packs__eyebrow {
margin: 0; font-size: 11px; letter-spacing: 0.14em;
text-transform: uppercase; color: var(--ink-faint);
}
.packs__title { margin: 6px 0 6px; font-size: 32px; font-weight: 600; letter-spacing: -0.02em; }
.packs__subtitle {
margin: 0 0 28px; max-width: 52ch;
color: var(--ink-soft); font-family: var(--serif); font-size: 17px;
}
.packs__list {
list-style: none; margin: 0; padding: 0;
display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;
}
.packs__item {
padding: 18px 18px 16px; background: var(--card);
border: 1px solid var(--rule); border-radius: var(--radius);
display: flex; flex-direction: column; gap: 8px;
}
.packs__item--current { border-color: var(--accent); }
.packs__name { margin: 0; font-size: 19px; font-weight: 600; letter-spacing: -0.01em; }
.packs__blurb { margin: 0; color: var(--ink-soft); font-family: var(--serif); font-size: 16px; }
.packs__state {
margin: 0 0 4px; font-size: 12px; letter-spacing: 0.04em; color: var(--ink-faint);
}
.packs__item .button { margin-top: auto; align-self: flex-start; }