/* KAS v3 — the visual system.
   Every value here comes from docs/design-guidelines.md §6.
   One light look. No dark mode: this is read in a bright workshop. */

:root {
  --ground:      #f6f5f2;
  --card:        #ffffff;
  --ink:         #1d1d1f;
  --muted:       #7a7a82;
  --line:        #e9e7e2;
  --gold:        #b8893b;
  --gold-soft:   #f4ead7;
  --ok:          #1f9e6e;
  --ok-soft:     #e2f4ec;
  --check:       #c47a1a;
  --check-soft:  #fbefdd;
  --stop:        #cc4444;
  --stop-soft:   #fbe9e9;
  --computed:    #eaf1f8;
  --typed:       #ffffff;

  /* 8 px grid */
  --s1: 8px; --s2: 16px; --s3: 24px; --s4: 32px;
  --radius: 12px;

  /* the floor for anything a thumb has to hit (guidelines section 6) */
  --touch: 44px;

  --font: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
          Roboto, system-ui, sans-serif;
}

* { box-sizing: border-box; }

/* Anything marked hidden really is hidden. Without this line a rule that sets
   display: flex quietly beats the hidden attribute, and every screen shows at
   once. Caught on the first run of these screens. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  overflow-x: hidden;          /* the page never scrolls sideways */
}

/* The four tabs are pinned to the bottom of the screen, so anything the browser
   scrolls to can be parked UNDERNEATH them — and a tap then lands on a tab
   instead of the button the thumb was aiming at. This keeps that much of the
   screen clear whenever the browser scrolls something into view, which it does
   when a box is focused as well as when a script asks it to.
   Found by the job 04 prove script: its tap on "Add another line" was landing
   on the tab bar. */
html { scroll-padding-bottom: 84px; }

body {
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.45;
  -webkit-text-size-adjust: 100%;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* every number is tabular, everywhere */
time, .num { font-variant-numeric: tabular-nums; }

/* ---------- header ---------- */

.bar {
  background: var(--card);
  border-bottom: 1px solid var(--line);
  padding: var(--s2);
  padding-top: calc(var(--s2) + env(safe-area-inset-top));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s1);
  flex-wrap: wrap;             /* header content wraps, never overflows */
}

.bar-title { min-width: 0; }

.bar h1 {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.bar .sub { margin: 0; }

/* The name at the top. A long name wraps inside this button and makes it
   taller; it never makes it wider. That is what keeps the version 2 bug
   (a header button pushed off a 360 px screen) from coming back. */
.who {
  display: flex;
  align-items: center;
  gap: var(--s1);
  min-height: var(--touch);
  max-width: 100%;
  padding: 6px var(--s1) 6px 6px;
  background: var(--gold-soft);
  border: 1px solid var(--gold);
  border-radius: 999px;
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}

.who-name {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* ---------- text ---------- */

.sub {
  font-size: 13px;
  color: var(--muted);
}

.whisper { text-align: center; }

.eyebrow {
  margin: 0 0 var(--s1);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.eyebrow.is-ok   { color: var(--ok); }
.eyebrow.is-stop { color: var(--stop); }

h2 {
  margin: 0 0 var(--s1);
  font-size: 22px;
  font-weight: 700;
}

.lead { margin-bottom: var(--s1); }
.lead .sub { margin: 0; }

.say {
  margin: var(--s2) 0 0;
  font-size: 15px;
  font-weight: 500;
}
.say-stop { color: var(--stop); }

/* ---------- layout ---------- */

main {
  flex: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
}

.screen {
  flex: 1;
  padding: var(--s2);
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s2);
}

.card.is-stop { background: var(--stop-soft); border-color: var(--stop); }
.card p { margin: 0 0 var(--s1); }
.card p:last-child { margin-bottom: 0; }

.line {
  border: 0;
  border-top: 1px solid var(--line);
  margin: var(--s2) 0;
}

/* A figure the system worked out sits on pale blue; a figure a person typed
   sits on white inside a rule. Background, not text colour, so it survives
   glare and colour-blindness. No figures on these screens yet: the tokens
   stay defined so no later screen invents its own. */
.computed {
  background: var(--computed);
  border-radius: 6px;
  padding: 2px 6px;
}
.typed {
  background: var(--typed);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 2px 6px;
}

/* ---------- the code ---------- */

.dots {
  display: flex;
  gap: 14px;
  margin-top: var(--s3);
}

.dots span {
  width: 18px;
  height: 18px;
  border-radius: 999px;
  border: 2px solid var(--gold);
  background: transparent;
}

.dots span.on { background: var(--gold); }

.dots.wrong { animation: shake 0.4s; }

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-9px); }
  40%      { transform: translateX(9px); }
  60%      { transform: translateX(-6px); }
  80%      { transform: translateX(6px); }
}

/* The keypad sits at the bottom of the screen, where a thumb reaches. */
.screen-fill .pad { margin-top: auto; }

.pad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s1);
}

.key {
  min-height: 56px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  font-size: 24px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.key:active { background: var(--gold-soft); }
.key-quiet { color: var(--muted); font-size: 20px; }
.key-gap { background: transparent; border: 0; }

/* ---------- the name grid ---------- */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--s2);
}

.name-tile {
  min-height: 96px;            /* the ticket asks for 64 px or more */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s1);
  padding: var(--s2) var(--s1);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
  font-weight: 500;
  text-align: center;
  cursor: pointer;
}

.name-tile:active { background: var(--gold-soft); }
.name-tile .name { overflow-wrap: anywhere; }

.tile {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 999px;
  background: var(--gold-soft);
  color: var(--gold);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.02em;
  flex: none;
}

.tile-sm { width: 32px; height: 32px; font-size: 13px; }

.tile-skeleton {
  min-height: 96px;
  border-radius: var(--radius);
  background: var(--line);
  animation: pulse 1.2s ease-in-out infinite;
}

/* ---------- buttons ---------- */

.btn {
  min-height: 48px;
  padding: 0 var(--s2);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
}

.btn-gold { background: var(--gold-soft); border-color: var(--gold); }
.btn-quiet { color: var(--muted); }
.btn-wide { width: 100%; }
.btn-small { min-height: var(--touch); font-size: 15px; padding: 0 12px; }
.btn:active { background: var(--gold-soft); }

/* ---------- settings: the name rows ---------- */

.rows { list-style: none; margin: 0; padding: 0; }

.rows li {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s1);
  padding: var(--s1) 0;
  border-top: 1px solid var(--line);
}

.rows li:first-child { border-top: 0; }

.row-name {
  flex: 1 1 120px;
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: 500;
}

.row-name.is-gone { color: var(--muted); font-weight: 400; }

/* The buttons always take a row of their own, so a long name never leaves
   Rename on one line and Remove on the next. */
.row-acts {
  flex: 1 1 100%;
  display: flex;
  gap: var(--s1);
}
.row-acts .btn { flex: 1 1 0; }

.field {
  flex: 1 1 140px;
  min-width: 0;
  min-height: 48px;
  padding: 0 12px;
  background: var(--typed);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  font-size: 16px;
}

.field:focus { outline: 2px solid var(--gold); outline-offset: 1px; }

.add { margin-top: var(--s2); padding-top: var(--s2); border-top: 1px solid var(--line); }
.add-label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.add-line { display: flex; flex-wrap: wrap; gap: var(--s1); }

/* ---------- the sheet behind the name at the top ---------- */

.veil {
  position: fixed;
  inset: 0;
  background: rgba(29, 29, 31, 0.35);
  z-index: 1;
}

.sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--s1);
  padding: var(--s2);
  padding-bottom: calc(var(--s2) + env(safe-area-inset-bottom));
  background: var(--card);
  border-top: 1px solid var(--line);
  border-radius: var(--radius) var(--radius) 0 0;

  /* A sheet grows upward from the bottom of the screen. Without a ceiling it
     grows straight off the TOP of the screen and takes its own heading with
     it — which is the sentence saying why the sheet is there at all. Found by
     opening the agree-the-gap sheet with three names in it. */
  max-height: 86vh;
  overflow-y: auto;
}

/* ---------- the loading skeleton: never a blank screen ---------- */

.skeleton {
  background: var(--line);
  border-radius: 6px;
  height: 14px;
  animation: pulse 1.2s ease-in-out infinite;
}
.skeleton + .skeleton { margin-top: var(--s1); }
.skeleton.w-40 { width: 40%; }
.skeleton.w-70 { width: 70%; }
.skeleton.w-90 { width: 90%; }
.skeleton.tall { height: 22px; }

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }

@media (prefers-reduced-motion: reduce) {
  .skeleton, .tile-skeleton { animation: none; }
  .dots.wrong { animation: none; }
  * { transition: none !important; }
}

/* ---------- the doorway from the Inbox to Gold on hand ---------- */

/* When the bottom bar arrives with job 04 this becomes the Gold tab. Until
   then it is one button, carrying the figure so reading it costs no tap. */
.door {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  width: 100%;
  min-height: 48px;
  padding: var(--s2);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.door:active { background: var(--gold-soft); }
.door-name { font-size: 16px; font-weight: 500; }
.door-figure { font-size: 22px; font-weight: 500; }
.door-when { font-size: 13px; color: var(--muted); }

/* ---------- figures: native grams big, fine weight beneath ---------- */

.figures { list-style: none; margin: 0; padding: 0; }

.figures li {
  padding: var(--s2) 0;
  border-top: 1px solid var(--line);
}
.figures li:first-child { border-top: 0; padding-top: 0; }

/* A figure a person typed sits on white inside a rule; a figure the system
   worked out sits on pale blue. Background, not text colour, so it survives
   glare and colour-blindness. This is the first screen where the two meet. */
.figure-big {
  display: inline-block;
  margin: 0;
  font-size: 28px;           /* headline number */
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.figure-under {
  display: inline-block;
  margin: 6px 0 0;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.purity { font-size: 17px; font-weight: 500; color: var(--muted); }

.working { list-style: none; margin: 0 0 var(--s1); padding: 0; font-size: 15px; }
.working li { padding: 4px 0; font-variant-numeric: tabular-nums; }

/* ---------- settings: a rate and its history ---------- */

.rate-name { flex: 1 1 100%; min-width: 0; font-weight: 500; }
.rate-value {
  font-size: 20px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.rate-since { flex: 1 1 100%; font-size: 13px; color: var(--muted); }
.rate-earlier {
  flex: 1 1 100%;
  margin: 0;
  font-size: 13px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.rate-line { display: flex; align-items: baseline; gap: var(--s1); flex: 1 1 auto; }

.change { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: var(--s1); }
.change label { flex: 1 1 100%; font-size: 13px; color: var(--muted); }

/* ============================================================
   Ticket 04 — the spine and the gate
   ============================================================ */

/* ---------- the four tabs ---------- */

/* Rishabh chose the tab bar during job 04, which amends ADR-0014. The Gold on
   hand button became the Gold tab and brought its figure with it, so nothing a
   person could read before has been taken away. */
.tabs {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  display: flex;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  background: var(--card);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}

.tab {
  flex: 1 1 0;
  min-width: 0;                /* four tabs share 360 px without pushing out */
  min-height: 56px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 6px 2px;
  background: transparent;
  border: 0;
  border-top: 3px solid transparent;
  color: var(--muted);
  font: inherit;
  cursor: pointer;
}
.tab:active { background: var(--gold-soft); }
.tab.is-here { color: var(--ink); border-top-color: var(--gold); }

.tab-name { font-size: 13px; font-weight: 500; }
.tab-sub {
  font-size: 11px;
  line-height: 1.2;
  color: var(--muted);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* the computed background is too loud at 11 px inside a tab */
.tab .computed { background: transparent; padding: 0; }

/* Room for the bar, so the last button on any screen is never under it. */
body.has-tabs main { padding-bottom: 72px; }
body.has-tabs .sheet { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }

/* ---------- a draft card on the Inbox ---------- */

.draft {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s2);
  margin-bottom: var(--s1);
}
.draft.is-check { border-color: var(--check); background: var(--check-soft); }

.draft-head { margin: 0 0 4px; font-size: 16px; font-weight: 500; }
.draft-what { list-style: none; margin: 0 0 var(--s1); padding: 0; font-size: 15px; }
.draft-what li { padding: 2px 0; font-variant-numeric: tabular-nums; }
.draft-gap { margin: 0 0 var(--s1); font-size: 15px; }
.draft-gap.is-stop { color: var(--stop); font-weight: 500; }
.draft-why { margin: 0 0 var(--s1); font-size: 13px; color: var(--muted); }
.draft-acts { display: flex; flex-wrap: wrap; gap: var(--s1); }
.draft-acts .btn { flex: 1 1 140px; }

.eyebrow.is-check { color: var(--check); }

/* ---------- one accepted entry on the gate list ---------- */

.entry {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s2);
  margin-bottom: var(--s1);
}
.entry.is-gone { background: var(--ground); border-style: dashed; }
.entry.is-gone .entry-head { color: var(--muted); }
.entry.is-correction { border-color: var(--check); }

.entry-head { margin: 0 0 4px; font-size: 16px; font-weight: 500; }
.entry-who { margin: 0; font-size: 13px; color: var(--muted); }
.entry-who + .entry-who { margin-top: 2px; }

/* ticket 05: the second side. A handover still owing an answer, and one the
   other side did not agree, must not read as quietly as the rest of the row. */
.entry-who.is-waiting { color: var(--check); font-weight: 500; }
.entry-who.is-stop { color: var(--stop); font-weight: 500; }

/* the sheet the second side types its own weight into */
#side-sheet .field { margin-bottom: var(--s2); }
#side-sheet .grid { margin-bottom: var(--s2); }
#side-verdict { margin: 0 0 var(--s2); font-size: 14px; }
#building-says { margin-bottom: 0; }
#building-pick { margin-bottom: var(--s1); }

/* ---------- the direction picker ---------- */

.pick { display: flex; flex-wrap: wrap; gap: var(--s1); margin-bottom: var(--s2); }
.pick-one { flex: 1 1 140px; }
.pick-one.is-picked { background: var(--gold-soft); border-color: var(--gold); font-weight: 700; }

/* ---------- one line of what crossed ---------- */

.what-line { display: flex; flex-wrap: wrap; gap: var(--s1); align-items: center; }
.what-line select.field { flex: 1 1 120px; }
.what-line .what-grams,
.what-line .back-grams,
.what-line #issue-extra-grams { flex: 1 1 90px; }
.what-line .btn-small { flex: 0 0 auto; }

/* ticket 07: the two actions on a job, and the two forms behind them */
#job-acts .btn-wide { margin-top: var(--s1); }
#job-acts .say { margin-top: var(--s1); }
#screen-issue .add-label,
#screen-receive .add-label { margin-top: var(--s2); }
#screen-issue .add-label:first-of-type,
#screen-receive .add-label:first-of-type { margin-top: 0; }
#issue-carried-says,
#receive-out-says { margin-top: var(--s1); }

select.field {
  min-height: var(--touch);
  background: var(--card);
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 32px;
}

/* ---------- the empty photo slot ---------- */

/* An honest empty box. It is not a button, because a button that does nothing
   teaches a person that tapping does nothing — the lesson of ADR-0014. */
.slot {
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  padding: var(--s3) var(--s2);
  text-align: center;
  margin-bottom: var(--s1);
}
.slot .sub { margin: 0; }

/* A field standing on its own inside a card, rather than in a row beside a
   button, fills the card. The flex-basis above only does anything inside a
   flex row, so without this the challan boxes came out half width on a phone —
   found by opening the screen, not by reading the code. */
.card > .field { display: block; width: 100%; }

/* ---------- the agree-the-gap sheet, kept short ---------- */

/* Four figures on four stacked rows pushed the sheet's heading off the screen.
   Label and figure on one line each, so the whole sheet fits a 360 px phone. */
.agree-figures li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s1);
  padding: 6px 0;
}
.agree-figures li p { margin: 0; }
.agree-figures .figure-under { font-size: 17px; }

/* Three name tiles side by side rather than two rows of two. */
#agree-names { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: var(--s1); }
#agree-names .name-tile { padding: var(--s1); }
#agree-names .tile { width: 40px; height: 40px; font-size: 15px; }
#agree-names .name { font-size: 13px; }

/* ---------- ticket 06: the jobs ---------- */

/* A field standing on its own outside a card — the box that finds a job.
   flex: 0 0 auto matters: .field carries flex-grow 1 for the rows it normally
   sits in, and a screen is a flex column, so without this the box grew to fill
   the whole screen. Found by opening it, not by reading the code. */
.field-wide { display: block; width: 100%; flex: 0 0 auto; }
.hunt { margin: 0; }

/* The three lists. Three across at 360 px, each one big enough for a thumb,
   each carrying its own count so a person reads all three without tapping. */
.seg {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s1);
  margin-bottom: var(--s2);
}

.seg-one {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 56px;
  padding: var(--s1) 4px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.seg-one.is-picked {
  background: var(--gold-soft);
  border-color: var(--gold);
  color: var(--ink);
  font-weight: 700;
}
.seg-name { text-align: center; line-height: 1.2; }
.seg-count { font-size: 17px; font-weight: 500; }

/* ---------- chips ---------- */

.chips { display: flex; flex-wrap: wrap; gap: var(--s1); margin-bottom: var(--s2); }
.chips:empty { margin-bottom: 0; }

.chip {
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--card);
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
}
.chip.is-stage { color: var(--ink); background: var(--ground); }
.chip.is-check { color: var(--check); background: var(--check-soft); border-color: var(--check); }
.chip.is-ok    { color: var(--ok);    background: var(--ok-soft);    border-color: var(--ok); }
.chip.is-none  { color: var(--muted); background: var(--ground); }

/* ---------- one job on the list ---------- */

.job {
  display: flex;
  align-items: flex-start;
  gap: var(--s2);
  width: 100%;
  text-align: left;
  padding: var(--s2);
  margin-bottom: var(--s1);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  cursor: pointer;
}
.job:active { background: var(--gold-soft); }
.job.is-check { border-color: var(--check); background: var(--check-soft); }

/* No photo on a job until ticket 20, so a neutral tile carrying the design
   number's own letters — far easier to pick out of a list than one more line
   of text (the version 2 screen review). */
.job-tile {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius);
  background: var(--gold-soft);
  color: var(--gold);
  font-size: 13px;
  font-weight: 700;
}

/* A column, not a run of inline spans. Without the column the name, what is
   being made and the days in stage ran together into one line — "KRG
   1684/726Ring · 18K52 days in CAD/Wax". Found by opening the screen. */
.job-middle { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.job-name { font-size: 16px; font-weight: 500; overflow-wrap: anywhere; }
.job-line { font-size: 13px; color: var(--muted); margin-top: 2px; }
.job-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }

.job-right { flex: 0 0 auto; text-align: right; display: flex;
             flex-direction: column; align-items: flex-end; }
.job-figure { font-size: 17px; font-weight: 500; font-variant-numeric: tabular-nums; }
.job-fine { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------- the stage timeline ---------- */

/* A table wide enough to need scrolling, so it scrolls INSIDE this box and the
   page itself never moves sideways (guidelines section 9). The stage column
   stays put while the weights slide under the thumb, or a person loses track
   of which row they are reading. */
/* No padding and no negative margin here, deliberately. A sticky column sticks
   to the LEFT EDGE OF THE CONTENT BOX, so 16 px of padding left a 16 px strip
   where the dates slid out from under the stage names — seen on screen, and it
   made the table unreadable while scrolling. */
.scroller {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.timeline {
  border-collapse: separate;
  border-spacing: 0;
  width: max-content;
  min-width: 100%;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.timeline th, .timeline td {
  padding: 8px 10px;
  text-align: right;
  white-space: nowrap;
  border-bottom: 1px solid var(--line);
}
.timeline thead th {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  text-align: right;
}

.timeline th.stage-cell, .timeline td.stage-cell {
  position: sticky;
  left: 0;
  z-index: 1;
  text-align: left;
  background: var(--card);
  font-weight: 500;
  box-shadow: 1px 0 0 var(--line);
}
.timeline td.who-cell { text-align: left; }
.timeline td.out-cell { color: var(--check); }
.timeline tbody tr:last-child th, .timeline tbody tr:last-child td { border-bottom: 0; }

/* Worked-out figures keep the workbook's pale blue wherever they appear, even
   inside a table cell (guidelines section 6). */
.timeline td.computed {
  background: var(--computed);
  border-radius: 0;
}
.timeline td.typed {
  background: var(--typed);
  border-width: 0 0 1px 0;
  border-radius: 0;
}

/* Three karats on one row rather than two and a stray. */
#purity-pick { display: grid; grid-template-columns: repeat(3, 1fr); }
#purity-pick .pick-one { flex: none; }

/* ============================================================
   ticket 08 — the three checks
   ============================================================ */

/* Three badges, each its own tap target. A badge is a button because tapping
   one that is not a tick takes a person to the figures it is about, and a
   thumb needs 44 px to land on (guidelines section 6). */
.badges { list-style: none; margin: 0 0 var(--s1); padding: 0; }
.badges li { margin-top: 6px; }
.badges li:first-child { margin-top: 0; }

.badge {
  display: flex;
  align-items: center;
  gap: var(--s1);
  width: 100%;
  min-height: var(--touch);
  padding: var(--s1) 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  font: inherit;
  font-size: 15px;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}

.badge-mark {
  flex: 0 0 auto;
  width: 22px;
  font-size: 17px;
  font-weight: 600;
  text-align: center;
}
.badge-name { flex: 1 1 auto; }
.badge-by {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  font-weight: 500;
}

/* A tick is quiet on purpose. A cross and a dash are the two a person has to
   read, and they must not look alike: a cross is two figures that disagree, a
   dash is nobody having a figure at all. */
.badge.is-tick  { border-color: var(--ok);    background: var(--ok-soft); }
.badge.is-tick  .badge-mark { color: var(--ok); }
.badge.is-cross { border-color: var(--stop);  background: var(--stop-soft); }
.badge.is-cross .badge-mark, .badge.is-cross .badge-by { color: var(--stop); }
.badge.is-dash  { border-color: var(--check); background: var(--check-soft); }
.badge.is-dash  .badge-mark { color: var(--check); }
.badge.is-dash  .badge-name { font-weight: 500; }

/* Where tapping a badge lands. It fades, so the mark never becomes part of the
   furniture. */
.is-pointed {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: var(--radius);
}

/* the two figures the third check is about, and what a card writes */
.draft-gate, .draft-card-says { margin-bottom: var(--s1); font-size: 14px; }

/* which job a challan line brought a casting in for */
.what-job { display: block; margin-top: 6px; }
.what-job .sub { margin: 0 0 4px; }
.what-job select.field { width: 100%; }
