  @font-face { font-family: 'Literata'; src: url('fonts/Literata-Black.ttf') format('truetype'); font-weight: 900; font-display: swap; }
  /* the reading face: Literata's upright variable font (weights 200 to 900), under its own name so the Black file above stays
     the display face. There is no italic file, so nothing in this game is set in italic. Licence: fonts/Literata-OFL.txt.
     955 KB: subset it before any deploy. */
  @font-face { font-family: 'Literata Text'; src: url('fonts/Literata-Variable.ttf') format('truetype'); font-weight: 200 900; font-style: normal; font-display: swap; }
  /* Brother James family tokens (design/brotherjames-tokens.css). The prints are always on cream paper;
     only the table they lie on changes with the theme. */
  :root {
    color-scheme: light dark;
    --cream: #FDF4E5; --paper: #fff9f0; --slate: #545E68; --char: #332e2a; --oxblood: #853D3E; --sage: #606C59; --ochre: #9F7A4E; --brown: #a26e47;
    --table: #FDF4E5; --on-table: #332e2a; --on-table-soft: #545E68; --table-line: rgba(84, 94, 104, 0.28);
    --ink: #332e2a; --ink-soft: #545E68; --rule: rgba(51, 46, 42, 0.22); --focus: #1d4f91;
    --radius: 4px; --gap: 18px; --edge: #332e2a;
    --display: 'Literata', Georgia, 'Times New Roman', serif;
    --ui: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --shadow: 0 1px 0 rgba(51, 46, 42, 0.10), 0 6px 18px rgba(51, 46, 42, 0.08);
    --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n' x='0' y='0' width='1' height='1'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .2  0 0 0 0 .18  0 0 0 0 .16  0 0 0 .09 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) { --table: #24282d; --on-table: #FDF4E5; --on-table-soft: #c9c2b4; --table-line: rgba(253, 244, 229, 0.25); --focus: #9cc2f5; --edge: #0d0f11;
      --shadow: 0 1px 0 rgba(0, 0, 0, 0.4), 0 8px 22px rgba(0, 0, 0, 0.35); }
  }
  :root[data-theme="dark"] { --table: #24282d; --on-table: #FDF4E5; --on-table-soft: #c9c2b4; --table-line: rgba(253, 244, 229, 0.25); --focus: #9cc2f5; --edge: #0d0f11;
    --shadow: 0 1px 0 rgba(0, 0, 0, 0.4), 0 8px 22px rgba(0, 0, 0, 0.35); }

  * { box-sizing: border-box; }
  html, body { margin: 0; background: var(--table); color: var(--on-table); }
  body { font: 16px/1.45 var(--ui); min-height: 100svh; touch-action: manipulation; overflow-x: clip;
    padding: max(8px, env(safe-area-inset-top)) 14px max(14px, env(safe-area-inset-bottom)); }
  main { max-width: 27rem; margin: 0 auto; display: flex; flex-direction: column; gap: 10px; }
  header { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
  h1 { font: 900 1.5rem/1 var(--display); margin: 0; letter-spacing: .01em; }
  .meta { color: var(--on-table-soft); font-size: .8125rem; font-variant-numeric: tabular-nums; }
  button { font: inherit; color: inherit; cursor: pointer; }
  button:focus-visible, input:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
  .linkish { background: none; border: 0; min-height: 44px; padding: 6px 4px; color: var(--on-table-soft); text-decoration: underline; font-size: .875rem; }
  .line { color: var(--on-table-soft); font-size: .875rem; margin: 0; }
  .line:empty { display: none; }

  /* every printed thing: cream paper, dark ink, a little grain, square as a cut sheet */
  .print { background-color: var(--cream); background-image: var(--grain); color: var(--ink); border-radius: 4px; box-shadow: var(--shadow); }

  /* the garden plate: the one bold thing */
  #scene { position: relative; overflow: hidden; aspect-ratio: 360 / 220; max-height: 33svh; width: 100%; }
  #plate { width: 100%; height: 100%; }
  #scene svg { display: block; width: 100%; height: 100%; }
  #scene .cap { position: absolute; left: 14px; top: 10px; font: 900 .8125rem/1 var(--display); letter-spacing: .08em; text-transform: uppercase; color: var(--ink); }
  #scene .wash { transition: opacity .9s linear; }
  #scene .sun { transition: transform .5s cubic-bezier(.2, 0, 0, 1), opacity .6s linear; }
  #scene .wheel { transition: transform .45s cubic-bezier(.34, 1.3, .64, 1); transform-box: fill-box; transform-origin: center; }
  #scene .rain { transition: opacity .8s linear; }
  #scene .tint { mix-blend-mode: multiply; }
  #scene .key * { fill: none; stroke: #332e2a; stroke-width: 1.3px; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
  #scene .key .pip { stroke: none; }
  #scene .grow .st { stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw .5s ease-out forwards; animation-delay: calc(var(--d) * 220ms); }
  #scene .grow .lf { transform-box: fill-box; transform-origin: 0% 50%; transform: scale(0); animation: pop .3s cubic-bezier(.3, 1.5, .5, 1) forwards; animation-delay: calc(var(--d) * 220ms + .3s + var(--i) * 24ms); }
  #scene .creep { opacity: 0; animation: fade .5s ease-out forwards; animation-delay: calc(var(--d) * 260ms + .5s); }
  @keyframes draw { to { stroke-dashoffset: 0; } } @keyframes pop { to { transform: scale(1); } } @keyframes fade { to { opacity: 1; } }

  /* the card: a seed packet. A band of one ink names the kind of job; the helper's words sit on their own plate. */
  #stage { position: relative; }
  .card { padding: 0; border: 2px solid var(--char); overflow: hidden; }
  .card.enter { animation: enter .2s cubic-bezier(.05, .7, .1, 1); }
  .ghost { position: absolute; left: 0; right: 0; top: 0; pointer-events: none; animation: leave .2s cubic-bezier(.3, 0, 1, 1) forwards; z-index: 2; }
  .ghost.lift { animation-name: lift; }
  @keyframes enter { from { transform: translateY(14px); opacity: 0; } }
  @keyframes leave { to { transform: translateX(105%) rotate(5deg); opacity: 0; } }
  @keyframes lift { to { transform: translateY(-36px) rotate(-2deg); opacity: 0; } }
  .band { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 7px 14px; color: var(--cream); font: 900 .8125rem/1.2 var(--display); letter-spacing: .09em; text-transform: uppercase; }
  .band.words { background: var(--slate); } .band.numbers { background: var(--char); } .band.answers { background: var(--sage); } .band.people { background: var(--oxblood); }
  .band .k { display: inline-flex; align-items: center; gap: 7px; } .band svg { width: 16px; height: 16px; }
  .seeds { display: inline-flex; gap: 4px; vertical-align: middle; margin-left: 6px; }
  .seeds i { width: 10px; height: 14px; border-radius: 50% 50% 50% 50% / 62% 62% 38% 38%; border: 1.5px solid currentColor; display: inline-block; }
  .seeds i.on { background: currentColor; }
  .body { padding: 12px 14px 14px; }
  .job { font: 900 1.3rem/1.22 var(--display); margin: 0 0 2px; color: var(--ink); }
  .who { color: var(--ink-soft); font-size: .875rem; margin: 0 0 12px; }
  .lab { display: flex; align-items: center; gap: 6px; font-size: .6875rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 4px; }
  .lab svg { width: 14px; height: 14px; }
  /* two plates: the oxblood tint is laid a little off its key line on every card alike. A look pulls it into register. */
  .plate { position: relative; isolation: isolate; border: 1.5px solid var(--char); padding: 9px 11px 10px; margin-right: 6px; margin-bottom: 5px; }
  .plate::before { content: ''; position: absolute; inset: 0; z-index: -1; background: rgba(133, 61, 62, .15); transform: translate(6px, 5px); transition: transform .3s cubic-bezier(.34, 1.56, .64, 1); }
  .plate.reg::before { transform: none; }
  .answer { margin: 0; font-size: 1.0625rem; line-height: 1.5; color: var(--ink); }
  .answer .hit { background: rgba(159, 122, 78, .32); box-shadow: inset 0 -2px 0 var(--char); }
  .parts, .opts { display: grid; gap: 9px; margin: 0; padding: 0; list-style: none; }
  .parts li { margin-right: 6px; }
  .parts button, .opts button { position: relative; isolation: isolate; width: 100%; text-align: left; min-height: 48px; padding: 9px 11px; background: transparent; color: var(--ink); border: 1.5px solid var(--char); border-radius: 0; font-size: 1.0625rem; }
  .parts button::before { content: ''; position: absolute; inset: 0; z-index: -1; background: rgba(133, 61, 62, .15); transform: translate(6px, 5px); transition: transform .14s cubic-bezier(.2, 0, 0, 1); }
  .parts button[aria-selected="true"]::before { transform: none; background: rgba(159, 122, 78, .32); }
  .parts button[aria-selected="true"], .opts button[aria-selected="true"] { box-shadow: inset 0 0 0 1.5px var(--char); }
  .opts button { background: var(--paper); }
  .opts button[aria-pressed="true"] { background: var(--sage); color: var(--cream); }
  .hint { color: var(--ink-soft); font-size: .875rem; margin: 12px 0 0; }
  .result { margin: 12px 0 0; padding: 8px 11px; border-left: 5px solid var(--char); background: var(--paper); }
  .tag { display: block; font: 900 .6875rem/1.3 var(--display); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
  .result small, .list small { display: block; color: var(--ink-soft); margin-top: 2px; font-size: .875rem; }
  .sheetcard { padding: 14px 16px 16px; }
  .sheetcard h2 { font: 900 1.3rem/1.2 var(--display); margin: 0 0 8px; }
  .sheetcard p { margin: 0 0 8px; }
  .list { margin: 0 0 10px; padding: 0; list-style: none; display: grid; gap: 8px; }
  .list li { padding: 8px 11px; background: var(--paper); border-left: 5px solid var(--char); animation: enter .28s cubic-bezier(.05, .7, .1, 1) backwards; animation-delay: calc(var(--n) * 320ms + .7s); }
  .counts { font-weight: 650; }
  .counts.late { animation: fade .3s ease-out backwards; animation-delay: calc(var(--n) * 320ms + .8s); }
  .note { color: var(--ink-soft); font-size: .875rem; }
  .src { font-size: .75rem; letter-spacing: .04em; color: var(--ink-soft); }
  label { display: block; font-size: .875rem; color: var(--ink-soft); margin: 8px 0 2px; }
  input[type=text] { width: 100%; font: inherit; font-size: 1rem; padding: 10px 12px; border: 1.5px solid var(--char); border-radius: 0; background: var(--paper); color: var(--ink); }
  textarea { width: 100%; min-height: 6rem; font: .8125rem/1.4 ui-monospace, Menlo, monospace; background: var(--paper); color: var(--ink); border: 1px solid var(--char); border-radius: 0; padding: 8px; }

  /* the hours you have, and what you have done by hand */
  .row { display: flex; justify-content: space-between; align-items: center; gap: 8px; min-height: 30px; }
  .suns { display: inline-flex; gap: 5px; align-items: center; color: var(--on-table); }
  .suns svg { width: 22px; height: 22px; }
  .suns svg.pop { animation: spend .3s cubic-bezier(.3, 1.5, .5, 1); }
  @keyframes spend { from { transform: scale(1.5); } }
  .practice { display: inline-flex; gap: 6px; align-items: center; font-size: .75rem; color: var(--on-table-soft); }
  .practice svg { width: 18px; height: 18px; opacity: .32; } .practice svg.on { opacity: 1; color: var(--on-table); }

  /* buttons are cut blocks: square, keyed, with a hard edge that goes down when pressed. Look and Send weigh the same. */
  .bar { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding-bottom: 4px; }
  .bar.three { grid-template-columns: 1fr 1fr 1fr; } .bar.one { grid-template-columns: 1fr; }
  .big { min-height: 54px; border-radius: 4px; border: 2px solid var(--char); background: var(--cream); color: var(--char); font-weight: 650; font-size: 1.0625rem;
    display: flex; align-items: center; justify-content: center; gap: 8px; padding: 6px 8px; box-shadow: 0 3px 0 var(--edge); transition: transform .06s, box-shadow .06s; }
  .big:active { transform: translateY(3px); box-shadow: 0 0 0 var(--edge); }
  .big svg { width: 22px; height: 22px; flex: none; }
  .big.primary { background: var(--sage); color: var(--cream); }
  .big[disabled] { opacity: .45; cursor: default; box-shadow: none; transform: translateY(3px); }
  .key { font: 500 .75rem/1 ui-monospace, Menlo, monospace; border: 1px solid currentColor; border-radius: 3px; padding: 2px 5px; opacity: .7; }
  @media (hover: none), (pointer: coarse) { .key, #keys { display: none; } }

  .overlay { position: fixed; inset: 0; background: rgba(36, 40, 45, .6); display: flex; align-items: center; justify-content: center; padding: 16px; z-index: 5; }
  .overlay[hidden] { display: none; }
  .sheet { padding: 18px; max-width: 25rem; width: 100%; max-height: 90svh; overflow: auto; display: grid; gap: 10px; border: 2px solid var(--char); }
  .sheet h2 { font: 900 1.3rem/1.2 var(--display); margin: 0; } .sheet p { margin: 0; color: var(--ink-soft); font-size: .875rem; }
  .toast { position: fixed; left: 50%; bottom: max(18px, env(safe-area-inset-bottom)); transform: translateX(-50%); background: var(--char); color: var(--cream); border: 1.5px solid var(--cream);
    padding: 8px 14px; border-radius: 4px; font-size: .875rem; pointer-events: none; opacity: 0; transition: opacity .2s; max-width: 90vw; text-align: center; z-index: 6; }
  .toast.show { opacity: 1; }
  .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  @media (prefers-reduced-motion: reduce) {
    .card.enter, .ghost, .list li, .counts.late, .suns svg.pop { animation: none; }
    .ghost { display: none; }
    #scene .sun, #scene .wheel { transition: none; }
    #scene .grow .st, #scene .grow .lf, #scene .creep { animation: none; stroke-dashoffset: 0; transform: none; opacity: 1; }
    .plate::before, .parts button::before { transition: none; }
  }

  /* ---- the opening: did it happen, and how sure? ---- */
  .event { font: 900 1.25rem/1.3 var(--display); margin: 2px 0 10px; color: var(--ink); }
  .ask { color: var(--ink-soft); font-size: .9375rem; margin: 0; }
  .band.plain { background: var(--char); }
  .picked { margin: 12px 0 0; padding: 8px 11px; border: 1.5px dashed var(--char); font-size: .9375rem; }
  .reveal { margin: 12px 0 0; padding: 9px 11px; border-left: 5px solid var(--char); background: var(--paper); }
  .reveal .src { display: block; margin-top: 4px; }
  #scene .codetag { text-align: left; cursor: pointer; border-radius: 0; position: absolute; right: 11px; top: 9px; max-width: 46%; padding: 3px 8px 4px; background: var(--cream); border: 1.5px solid var(--char);
    font: 900 .75rem/1.2 var(--display); letter-spacing: .04em; color: var(--ink); transform: rotate(-3deg); box-shadow: 0 2px 0 var(--char); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #scene .codetag small { display: block; font: 600 .5625rem/1.2 var(--ui); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); }
  .tally { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 0 0 10px; }
  .tally dt { font: 900 1.2rem/1.2 var(--display); text-align: right; } .tally dd { margin: 0; align-self: center; }
  .foot { color: var(--on-table-soft); font-size: .8125rem; margin: 0; }
  .foot:empty { display: none; }
  #scene .codetag[hidden] { display: none; }
  #scene .codetag:disabled { cursor: default; opacity: 1; }
  #scene .codetag::after { content: ''; position: absolute; inset: -12px; } /* a 44px touch target round a small tag */
  a.linkish { display: inline-flex; align-items: center; }
  /* a tale, once revealed: the statement is struck through in oxblood, and the band changes ink */
  .card.tale .band { background: var(--oxblood); }
  .card.tale .event { text-decoration: line-through; text-decoration-color: var(--oxblood); text-decoration-thickness: 2px; color: var(--ink-soft); }
  .reveal .tag { color: var(--ink); }

  /* ---- the menu: a printed plate. Masthead, cut blocks, then the colophon set in a book face. ---- */
  :root { --serif: 'Literata Text', 'Iowan Old Style', 'Palatino Linotype', Palatino, 'Book Antiqua', Georgia, serif; }
  .sheet.menu { padding: 0; gap: 0; display: block; }
  .mhead { display: flex; align-items: center; gap: 12px; padding: 16px 18px 13px; border-bottom: 2px solid var(--char); }
  .mmark { flex: none; width: 40px; height: 40px; color: var(--char); display: block; background: rgba(159, 122, 78, .32); border-radius: 50%; box-shadow: 3px 2px 0 rgba(133, 61, 62, .22); }
  .mmark svg { width: 100%; height: 100%; display: block; }
  .sheet.menu .mhead h2 { font: 900 1.75rem/1 var(--display); letter-spacing: .01em; margin: 0 0 4px; color: var(--ink); }
  .sheet.menu .mwhat { font: 1rem/1.35 var(--serif); color: var(--ink); margin: 0; }
  .mctl { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 14px 18px 16px; }
  .mctl .wide { grid-column: 1 / -1; }
  .mctl .big { min-height: 48px; font-size: 1rem; }
  .mband { margin: 0; justify-content: flex-start; font-size: .8125rem; }
  .colophon { margin: 0; padding: 14px 18px 20px; display: grid; gap: 13px; }
  .colophon dt { font: 900 .75rem/1.2 var(--display); letter-spacing: .1em; text-transform: uppercase; color: var(--oxblood); margin: 0 0 2px; }
  .colophon dd { margin: 0; font: 1rem/1.5 var(--serif); color: var(--ink); }
  .colophon .stance { margin: 2px 6px 5px 0; padding: 10px 12px 11px; }
  .colophon .stance::before { transform: translate(6px, 5px); }
  .colophon .stance dt { color: var(--ink); }
  .colophon .stance dd { font: 900 1.0625rem/1.35 var(--display); }

  /* ---- guess the number: three answers, written low to high, each a cut block ---- */
  .answers { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 8px; }
  .ans { width: 100%; min-height: 48px; display: flex; align-items: center; justify-content: space-between; gap: 10px; text-align: left; padding: 9px 12px;
    border: 2px solid var(--char); border-radius: 4px; background: var(--paper); color: var(--ink); font-weight: 650; font-size: 1.0625rem; }
  button.ans { box-shadow: 0 3px 0 var(--char); transition: transform .06s, box-shadow .06s; }
  button.ans:active { transform: translateY(3px); box-shadow: 0 0 0 var(--char); }
  button.ans[aria-pressed="true"] { background: var(--char); color: var(--cream); transform: translateY(3px); box-shadow: 0 0 0 var(--char); }
  button.ans[aria-pressed="false"] { box-shadow: none; transform: translateY(3px); border-style: dashed; border-width: 1.5px; }
  div.ans { font-weight: 500; border-width: 1.5px; border-style: dashed; color: var(--ink-soft); }
  div.ans.true { border-style: solid; border-width: 2px; background: var(--sage); color: var(--cream); font-weight: 650; }
  div.ans.mine:not(.true) { border-style: solid; color: var(--ink); }
  .amark { flex: none; font: 900 .6875rem/1 var(--display); letter-spacing: .1em; text-transform: uppercase; }
  .card.answered .event { font-size: 1.0625rem; color: var(--ink-soft); margin-bottom: 8px; }
  .card.answered .band { background: var(--sage); }
  .hint.out { font-weight: 650; color: var(--ink); }
  .picked { text-align: center; border: 0; padding: 4px 0 0; font-weight: 650; }
  .bar.none { display: none; }
  .setup { margin: 0 0 8px; font: 1.0625rem/1.45 var(--serif); color: var(--ink); }
  .card.answered .setup { font-size: .9375rem; color: var(--ink-soft); margin-bottom: 4px; }

  /* ---- one new thing a round: the acorn, the measuring stick, the watering can ---- */
  #scene.noon .wash { opacity: .15 !important; fill: #9F7A4E; }
  .acorn { display: inline-flex; width: 20px; height: 20px; color: var(--cream); }
  .acorn svg { width: 100%; height: 100%; }
  .acorn.noon .nut { fill: var(--ochre); }
  .acorn.spent .nut { fill: currentColor; }
  .acorn.spent { opacity: .55; }
  .stick { margin: 6px 0 2px; }
  .stickread { margin: 0 0 2px; font-size: .9375rem; color: var(--ink-soft); text-align: center; }
  .stickread output { font: 900 2rem/1 var(--display); color: var(--ink); font-variant-numeric: tabular-nums; }
  input[type=range] { -webkit-appearance: none; appearance: none; width: 100%; height: 44px; margin: 0; background: transparent; cursor: pointer; touch-action: pan-y; }
  input[type=range]::-webkit-slider-runnable-track { height: 10px; border: 2px solid var(--char); background: repeating-linear-gradient(90deg, var(--char) 0 1.5px, var(--paper) 1.5px 10%); }
  input[type=range]::-moz-range-track { height: 6px; border: 2px solid var(--char); background: var(--paper); }
  input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 22px; height: 34px; margin-top: -14px; border: 2px solid var(--char); border-radius: 3px; background: var(--oxblood); box-shadow: 0 3px 0 var(--char); }
  input[type=range]::-moz-range-thumb { width: 18px; height: 30px; border: 2px solid var(--char); border-radius: 3px; background: var(--oxblood); }
  .stickends { display: flex; justify-content: space-between; margin: 0; font-size: .75rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
  .track { position: relative; height: 62px; margin: 6px 14px 4px; }
  .track::before { content: ''; position: absolute; left: -14px; right: -14px; top: 28px; height: 6px; border: 2px solid var(--char); background: var(--paper); }
  .mk { position: absolute; transform: translateX(-50%); white-space: nowrap; font: 900 .75rem/1 var(--display); letter-spacing: .06em; text-transform: uppercase; color: var(--ink); }
  .tick { position: absolute; width: 3px; height: 16px; margin-left: -1.5px; background: var(--char); }
  .tick.you { top: 14px; } .tick.real { top: 30px; width: 5px; margin-left: -2.5px; background: var(--sage); }
  .mk.you { top: 0; } .mk.real { top: 50px; color: var(--sage); }
  .bar.three .big { font-size: .9375rem; padding: 6px 4px; flex-direction: column; gap: 3px; }
  .canitem small { display: block; font-size: .8125rem; line-height: 1.35; color: var(--ink-soft); margin-bottom: 3px; }
  .canitem span { font-weight: 650; }

  /* ---- ruling 12: the guide link, and three things done away from the screen ---- */
  .guide { margin: 4px 0 10px; padding: 9px 11px; border: 1.5px solid var(--char); background: var(--paper); }
  .guide a { display: block; margin-top: 2px; font: 900 1.0625rem/1.3 var(--display); color: var(--oxblood); text-decoration-thickness: 2px; text-underline-offset: 3px; min-height: 30px; }
  .guide .src, .sheetcard .guide .src { display: block; margin: 4px 0 0; }
  .note.warn, .sheetcard .note.warn { display: block; margin: 6px 0 0; }
  .checks { list-style: none; margin: 4px 0 4px; padding: 0; display: grid; gap: 10px; }
  .checks li { display: grid; gap: 6px; padding: 9px 11px 10px; border: 1.5px solid var(--char); background: var(--paper); }
  .checks li.on { box-shadow: inset 0 0 0 1.5px var(--char); }
  .checks .what { font-weight: 650; font-size: 1.0625rem; color: var(--ink); }
  .checks .two { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .checks button { min-height: 44px; border: 2px solid var(--char); border-radius: 4px; background: var(--cream); color: var(--char); font-weight: 650; box-shadow: 0 3px 0 var(--char); }
  .checks button[aria-pressed="true"] { background: var(--char); color: var(--cream); transform: translateY(3px); box-shadow: none; }
  .checks .earned { font: 900 .9375rem/1.3 var(--display); color: var(--oxblood); }
  #scene .codetag { white-space: normal; text-align: left; line-height: 1.15; }

  /* ================= the design round (2026-10-02): one thing to know on every pane ================= */
  /* The stamp: that one thing, pressed. A solid ink block, Literata Black reversed out of it, and the oxblood plate laid
     a little off beneath, as on every print in this game. It is the largest type on its pane. */
  .stamp { position: relative; isolation: isolate; margin: 10px 7px 13px 0; padding: 11px 14px 12px; font: 900 1.4375rem/1.18 var(--display); letter-spacing: .005em; text-wrap: balance; }
  .stamp::before { content: ''; position: absolute; inset: 0; z-index: -2; background: var(--oxblood); transform: translate(7px, 6px); }
  .stamp::after { content: ''; position: absolute; inset: 0; z-index: -1; }
  .stamp.ink { color: var(--cream); } .stamp.ink::after { background: var(--char); }
  .stamp.true { color: var(--cream); } .stamp.true::after { background: var(--sage); } .stamp.true::before { background: var(--char); }
  .stamp.paper { color: var(--ink); } .stamp.paper::after { background: var(--cream); box-shadow: inset 0 0 0 2px var(--char); } .stamp.paper::before { background: rgba(133, 61, 62, .45); }
  .stamp small { display: block; margin-top: 4px; font: 600 .8125rem/1.3 var(--ui); letter-spacing: .02em; }
  .sheetcard .stamp { margin-top: 4px; }

  /* what supports it: the figure in the book face, the source small, how the player did last */
  .figure { margin: 0 0 4px; font: 1.0625rem/1.45 var(--serif); color: var(--ink); }
  .sheetcard p.figure { margin-bottom: 4px; }
  .asked { margin: 0 0 2px; font: .9375rem/1.35 var(--serif); color: var(--ink-soft); }
  .yousaid { margin: 0 0 6px; font-size: .875rem; color: var(--ink-soft); }
  .body .src { display: block; margin: 0 0 8px; }
  .hint.out { margin: 6px 0 0; padding-top: 7px; border-top: 1.5px dashed var(--rule); }
  .linkish.change { color: var(--ink-soft); display: block; margin: 0 auto; min-height: 40px; }

  /* the question is the peak of a card; the setup reads first and sits quieter */
  .event { font-size: 1.4375rem; line-height: 1.2; text-wrap: balance; margin: 2px 0 12px; }
  .setup { font-size: 1rem; margin-bottom: 7px; }

  /* three short answers are a scale: side by side, low to high, a notch joining them, under the Left, Down, Right keys */
  .answers.scale { grid-template-columns: 1fr 1fr 1fr; gap: 0; position: relative; }
  .answers.scale li + li .ans { border-left-width: 0; }
  .answers.scale .ans { flex-direction: column; justify-content: center; text-align: center; gap: 5px; min-height: 68px; padding: 8px 4px; border-radius: 0; font: 900 1.125rem/1.15 var(--display); }
  .answers.scale li:first-child .ans { border-radius: 4px 0 0 4px; } .answers.scale li:last-child .ans { border-radius: 0 4px 4px 0; }
  .answers.scale .key { font-family: var(--ui); }

  /* the tally reads as a ledger under its line */
  .tally { border-top: 2px solid var(--char); padding-top: 8px; }

  /* the plate folds to its beds on a short screen while there is something to read */
  @media (max-height: 740px) { #scene.compact { aspect-ratio: 360 / 138; } #scene.compact .cap { display: none; } #scene.compact .codetag { display: none; } }

  /* guided reading: a new pane's parts arrive once, in reading order */
  /* parts start faint, never invisible: if a browser stalls the animation (a hidden tab), the words can still be read */
  @keyframes rise { from { opacity: .22; transform: translateY(9px); } }
  @keyframes press { 0% { opacity: .22; transform: translateY(-9px) scale(1.07) rotate(-1.4deg); } 70% { opacity: 1; transform: translateY(1px) scale(.995) rotate(0deg); } 100% { transform: none; } }
  @keyframes register { from { transform: translate(0, 0); } }
  #stage.staged .card.enter { animation: none; }
  #stage.staged .body > *, #stage.staged .sheetcard > * { animation: rise .2s cubic-bezier(.2, .7, .2, 1) backwards; }
  #stage.staged .body > :nth-child(1), #stage.staged .sheetcard > :nth-child(1) { animation-delay: 0s; }
  #stage.staged .body > :nth-child(2), #stage.staged .sheetcard > :nth-child(2) { animation-delay: .09s; }
  #stage.staged .body > :nth-child(3), #stage.staged .sheetcard > :nth-child(3) { animation-delay: .18s; }
  #stage.staged .body > :nth-child(4), #stage.staged .sheetcard > :nth-child(4) { animation-delay: .25s; }
  #stage.staged .body > :nth-child(n+5), #stage.staged .sheetcard > :nth-child(n+5) { animation-delay: .31s; }
  #stage.staged .stamp { animation-name: press; animation-duration: .26s; animation-timing-function: cubic-bezier(.3, 1.4, .5, 1); }
  #stage.staged .stamp::before { animation: register .22s cubic-bezier(.34, 1.56, .64, 1) backwards; animation-delay: .34s; }
  #stage.staged .answers li { animation: rise .18s cubic-bezier(.2, .7, .2, 1) backwards; }
  #stage.staged .answers li:nth-child(1) { animation-delay: .2s; } #stage.staged .answers li:nth-child(2) { animation-delay: .27s; } #stage.staged .answers li:nth-child(3) { animation-delay: .34s; }
  #stage.settled *, #stage.settled *::before { animation: none !important; }
  @media (prefers-reduced-motion: reduce) { #stage * , #stage *::before { animation: none !important; } }
  /* where a stamp follows a sheet's title, the title steps back to a label so the stamp is read first */
  .sheetcard h2:has(+ .stamp) { font: 900 .8125rem/1.2 var(--display); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 2px; }

  /* ---- after the critic's read of the screenshots (2026-10-02) ---- */
  /* "How sure?" is what that pane asks, so it is the largest thing on it; the answer picked sits above it at full width */
  .howsure { margin: 12px 0 0; font: 900 1.625rem/1.1 var(--display); text-align: center; color: var(--ink); }
  .card.asking .event { font-size: 1.0625rem; line-height: 1.3; color: var(--ink-soft); margin-bottom: 8px; }
  .card.asking .setup { display: none; }
  .card.asking .answers.scale { grid-template-columns: 1fr; }
  .card.asking .answers.scale .ans { border-radius: 4px; min-height: 52px; }
  /* how the player did is the pay-off of a result: a line of the display face, not a footnote */
  .hint.out { font: 900 1.0625rem/1.25 var(--display); color: var(--ink); }
  /* room inside the three cells of a scale */
  .answers.scale .ans { font-size: 1.0625rem; padding: 9px 6px; }
  /* ideas for a real safe word are examples to read, not things to tap */
  .ideas { margin: 0 0 10px; padding: 0 0 0 1.1em; font: 1rem/1.4 var(--serif); color: var(--ink); }
  .ideas li { margin: 0 0 2px; }
  /* a ticked row says so with a mark; "Not yet" stays plain, because it is a full answer and not a warning */
  .checks button[aria-pressed="true"]::before { content: '\2713\00a0'; }
  .checks button[data-k^="notyet"][aria-pressed="true"] { background: var(--paper); color: var(--ink); border-style: dashed; box-shadow: none; }
  .checks button[data-k^="notyet"][aria-pressed="true"]::before { content: ''; }
  .checks button[data-k^="done"][aria-pressed="true"] { background: var(--sage); color: var(--cream); }
  /* a card to try again shows that it opens */
  .canitem { position: relative; padding-right: 34px !important; }
  .canitem::after { content: '\2192'; position: absolute; right: 11px; top: 50%; transform: translateY(-50%); font-size: 1.25rem; color: var(--ink); }
  .big.wide { width: 100%; }
  /* on a pane whose content is a list of things to do, the title is a label and the things are the largest type */
  .sheetcard.quiet h2 { font: 900 .8125rem/1.2 var(--display); letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 4px; }
  .checks .what { font: 900 1.1875rem/1.2 var(--display); }
  .canitem span { font: 900 1.125rem/1.2 var(--display); display: block; }

  /* one family (third critic: the sans buttons and captions read as a second hand). Everything that is not the display
     face is set in Literata's text weights; the system sans stays only as the fallback while the font loads. */
  :root { --ui: 'Literata Text', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; }
  .opts button { font-family: var(--serif); line-height: 1.4; }

  /* ---- Justin's notes, 2026-10-02 evening ---- */
  /* the game's one description, under the plate on the first screen: set as a line of the book, not a caption */
  #intro.what { margin: 14px 2px 8px; font: 500 1.125rem/1.4 var(--serif); color: var(--on-table); text-wrap: balance; }
  #intro.what::before { content: ''; display: block; width: 36px; height: 3px; margin: 0 0 9px; background: var(--on-table); }
  #intro.what:empty { display: none; }
  /* more air between the paragraphs of a sheet (the safe-word screen most of all) */
  .sheetcard p { margin: 0 0 12px; }
  .sheetcard p.figure { margin-bottom: 12px; }
  .sheetcard .src { margin: -6px 0 16px; }
  .sheetcard .note { margin-bottom: 8px; }
  .ideas { margin: 4px 0 18px; }
  .ideas li { margin: 0 0 6px; }
  .sheetcard label { margin: 6px 0 6px; }
  .sheetcard .stamp { margin-bottom: 18px; }

  /* ---- the start guide: two toy cards and a key, before round 1 ---- */
  .legend { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 8px 0; }
  .gfig { display: grid; gap: 4px; justify-items: center; text-align: center; padding: 8px 6px 9px; border: 1.5px solid var(--char); background: var(--paper); font-weight: 650; font-size: .875rem; line-height: 1.25; color: var(--ink); }
  .gfig svg { display: block; width: 58px; height: 76px; }
  .gfig.outline { border-style: dashed; }
  .gfig.outline svg * { fill: none !important; stroke: #332e2a; stroke-width: 1.3px; }
  .gfig b, .gkey .pts { font: 900 1.25rem/1 var(--display); }
  .gkey { list-style: none; margin: 2px 0 10px; padding: 0; display: grid; gap: 6px; }
  .gkey li { display: grid; grid-template-columns: 30px 1fr auto; align-items: center; gap: 10px; padding: 2px 12px 2px 8px; border: 1.5px solid var(--char); background: var(--paper); }
  .gkey svg { display: block; width: 28px; height: 36px; }
  .gmore { margin: 0; }
  @media (max-height: 740px) { .gmore { display: none; } }
  .gkey .klab { font-weight: 650; font-size: 1.0625rem; }

  /* The first slide (his words, 2026-10-03: "I want the start of the game to stand out and feel a bit different before
     getting into the feel of the normal game"). One dark block in the same inks: a ringing mark, the scene in cream, the
     question as the largest type. No garden yet; the plate arrives with the reveal. */
  #app[data-mode="call"] #scene { display: none; }
  .card.callcard { background: var(--char); color: var(--cream); border-color: var(--char); overflow: visible; margin: 2px 8px 12px 0;
    box-shadow: 8px 8px 0 var(--oxblood); min-height: min(52svh, 25rem); display: flex; flex-direction: column; }
  .card.callcard::before, .card.callcard::after { display: none; }
  .callcard .band { display: none; }
  .callcard .ringer { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 26px 16px 4px; }
  .callcard .ringer svg { width: 132px; height: 70px; display: block; }
  .callcard .arcs path { stroke: var(--cream); stroke-width: 4; }
  .callcard .dot { fill: var(--ochre); stroke: var(--cream); stroke-width: 3; }
  .callcard .ringlab { font: 900 .8125rem/1 var(--display); letter-spacing: .14em; text-transform: uppercase; color: var(--cream); }
  .callcard .body { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; padding: 18px 20px 24px; }
  .callcard .setup { color: var(--cream); font-size: 1.25rem; line-height: 1.4; margin: 0 0 14px; text-wrap: balance; }
  .callcard .event { color: var(--cream); font-size: clamp(2.125rem, 9.5vw, 2.75rem); line-height: 1.05; margin: 0; text-wrap: balance; }
  .callcard .arcs path { animation: ringout 1.8s ease-in-out infinite; }
  .callcard .arcs .a2 { animation-delay: .18s; } .callcard .arcs .a3 { animation-delay: .36s; }
  .callcard .dot { transform-box: fill-box; transform-origin: center; animation: ringdot 1.8s ease-in-out infinite; }
  @keyframes ringout { 0%, 55%, 100% { opacity: .28; } 18% { opacity: 1; } }
  @keyframes ringdot { 0%, 55%, 100% { transform: scale(1); } 12% { transform: scale(1.18); } }
  #stage.staged .callcard .ringer { animation: rise .2s cubic-bezier(.2, .7, .2, 1) backwards; }
  @media (prefers-reduced-motion: reduce) { .callcard .arcs path, .callcard .dot { animation: none !important; opacity: 1; } }

  /* Typed text: the sentence is whole in the page; the part not yet typed is transparent. Answers wait for the words. */
  .untyped { color: transparent; }
  #app.typing #card .answers, #app.typing #card .stick, #app.typing #bar { opacity: 0; pointer-events: none; }
  #card .answers, #card .stick, #bar { transition: opacity .18s ease-out; }
  @media (prefers-reduced-motion: reduce) { #card .answers, #card .stick, #bar { transition: none; } }
  /* The setup line is the first thing to read on a card (his words, 2026-10-03: "This text is too small in the cards ...
     let's make this still stand out a bit more, so the user is directed to read it"). The question stays the larger. */
  .card:not(.answered):not(.asking):not(.callcard) .setup { font-size: 1.1875rem; line-height: 1.4; font-weight: 520; color: var(--ink); margin-bottom: 10px;
    padding-left: 11px; border-left: 3px solid var(--oxblood); }

  /* The menu, organised: Resume in sage (the way back), two labelled groups, Restart in oxblood (the one that cannot be undone). */
  .mctl { row-gap: 10px; }
  .mctl .mlab { margin: 8px 0 -4px; font: 900 .75rem/1 var(--display); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
  .mctl .big.primary { min-height: 54px; font-size: 1.0625rem; }
  .mctl .big.danger { background: var(--oxblood); color: var(--cream); }
  .mctl .mnote { margin: -2px 0 0; font-size: .8125rem; line-height: 1.35; color: var(--ink-soft); }

  /* Going back and forth. A rail under the title: a way back, and one dot for each card of the round (filled = answered,
     and tappable to see that answer again; ringed = the card in hand). A page from the trail wears an oxblood band and a
     dashed edge, so it can never be mistaken for the game in hand. */
  .rail { display: flex; align-items: center; gap: 10px; min-height: 0; margin: -4px 0 -4px; }
  .railback { min-height: 40px; padding: 4px 8px 4px 0; font-weight: 650; font-size: .9375rem; color: var(--on-table); text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
  .dots { display: flex; align-items: center; gap: 9px; margin: 0 0 0 auto; padding: 8px 2px; list-style: none; }
  .dots li { display: flex; }
  .dot { display: block; width: 14px; height: 14px; padding: 0; border-radius: 50%; border: 2px solid var(--on-table); background: transparent; }
  button.dot.done { background: var(--on-table); position: relative; }
  button.dot.done::after { content: ''; position: absolute; inset: -12px -5px; }
  .dot.now { box-shadow: 0 0 0 2px var(--table), 0 0 0 4px var(--oxblood); }
  button.dot.at { background: var(--oxblood); border-color: var(--oxblood); box-shadow: 0 0 0 2px var(--table), 0 0 0 4px var(--oxblood); }
  .card.looking { outline: 3px dashed var(--oxblood); outline-offset: 3px; }
  .card.looking .band { background: var(--oxblood); }
  button.ans.hi { outline: 3px solid var(--focus); outline-offset: 2px; }
  .bar.arming .big { animation: arm .65s linear; }
  @keyframes arm { 0%, 99% { opacity: .5; } 100% { opacity: 1; } }

  /* Typed pages: a line that has not begun is not there yet (its bullet or its block would give it away); controls wait. */
  .pending { opacity: 0; }
  #app.typing #card input, #app.typing #card .legend, #app.typing #card .gkey, #app.typing #card .change { opacity: 0; pointer-events: none; }

  /* Mobile round (his words via Geese Games, 2026-10-03: "mobile optimize all pages and games"). */
  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
  body { padding-left: max(14px, env(safe-area-inset-left)); padding-right: max(14px, env(safe-area-inset-right)); }
  button, .big, .ans, .linkish, .dot, .band, .key { -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
  .railback, .linkish.change { min-height: 44px; }
  .guide a { min-height: 44px; display: flex; align-items: center; }
  .dots { gap: 14px; }
  button.dot.done::after { inset: -15px -7px; }
  .sheet { max-height: 90dvh; overscroll-behavior: contain; }
  .toast { max-width: calc(100vw - 32px); }
  input[type=text] { font-size: max(16px, 1rem); min-height: 48px; }
  @media (prefers-reduced-motion: reduce) { .bar.arming .big { animation: none; } }
  /* a phone on its side: the first slide lays its mark beside its words, and the plate gives way to the reading */
  @media (orientation: landscape) and (max-height: 480px) {
    .card.callcard { min-height: 0; flex-direction: row; align-items: center; }
    .callcard .ringer { padding: 14px 6px 14px 18px; }
    .callcard .ringer svg { width: 96px; height: 52px; }
    .callcard .body { padding: 14px 18px; justify-content: center; }
    .callcard .event { font-size: 1.875rem; }
    #scene { max-height: 26svh; }
  }

  /* a short phone (an SE is 667 tall): the plate folds further and the card tightens, so a question and its three answers
     fit without a scroll now that the setup line is larger; the guide's key screen loses a little air */
  @media (max-height: 700px) {
    #scene.compact { aspect-ratio: 360 / 96; }
    .card:not(.answered):not(.asking):not(.callcard) .setup { font-size: 1.0625rem; margin-bottom: 7px; }
    .card:not(.callcard) .event { font-size: 1.3125rem; margin-bottom: 9px; }
    .gkey li { padding-top: 0; padding-bottom: 0; }
    .rail { margin-top: -8px; margin-bottom: -8px; }
  }

  /* the dots: 44 tall to the thumb, and spaced so two hit areas never touch */
  .dots { gap: 18px; }
  button.dot.done::after { inset: -17px -11px; }
  /* a phone on its side has width to spare: use it, so less sits below the fold */
  @media (orientation: landscape) and (max-height: 480px) {
    main { max-width: 42rem; }
    #intro.what { margin: 6px 2px 4px; font-size: 1rem; }
    #intro.what::before { display: none; }
    .callcard .setup { font-size: 1.0625rem; margin-bottom: 8px; }
  }
  /* on the dark table the first slide's charcoal block needs an edge of its own */
  @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .card.callcard { border-color: var(--cream); } }
  :root[data-theme="dark"] .card.callcard { border-color: var(--cream); }

  /* The first slide's call: a wave drawn in code that uncovers as the made-up lines type. No sound. */
  .callcard .calltalk { margin: 0 0 14px; padding: 10px 12px 9px; border: 1.5px solid rgba(253, 244, 229, .45); border-radius: 3px; }
  .callcard .wave { height: 34px; clip-path: inset(0 calc((1 - var(--p, 1)) * 100%) 0 0); }
  .callcard .wave svg { display: block; width: 100%; height: 100%; }
  .callcard .wave rect { fill: var(--cream); }
  .callcard .talklab { margin: 6px 0 4px; font: 900 .6875rem/1 var(--display); letter-spacing: .12em; text-transform: uppercase; color: var(--cream); opacity: .8; }
  .callcard .talklines { margin: 0; padding: 0; list-style: none; font: 1.0625rem/1.4 var(--serif); color: var(--cream); }
  .callcard .talklines li { margin: 0; }
  @media (max-height: 700px) { .callcard .ringer { padding-top: 14px; } .callcard .ringer svg { width: 96px; height: 52px; } .callcard .calltalk { margin-bottom: 10px; } .callcard .setup { font-size: 1.125rem; margin-bottom: 10px; } }
  @media (orientation: landscape) and (max-height: 480px) { .callcard .calltalk { margin-bottom: 6px; padding: 6px 10px; } .callcard .wave { height: 20px; } .callcard .talklines { font-size: .9375rem; } }

  /* with the made-up call on the slide, the ringing mark sits in a row with its label, so the buttons stay on screen */
  .callcard .ringer { flex-direction: row; justify-content: flex-start; gap: 12px; padding: 18px 20px 0; }
  .callcard .ringer svg { width: 76px; height: 40px; flex: none; }
  .callcard .body { justify-content: flex-start; padding-top: 14px; }
  .card.callcard { min-height: 0; }
  @media (max-height: 700px) {
    .callcard .ringer { padding-top: 12px; } .callcard .ringer svg { width: 60px; height: 32px; }
    .callcard .body { padding: 10px 16px 16px; }
    .callcard .setup { font-size: 1.0625rem; margin-bottom: 8px; }
    .callcard .calltalk { padding: 7px 10px; margin-bottom: 8px; } .callcard .wave { height: 26px; }
    .callcard .talklines { font-size: .9375rem; line-height: 1.35; }
    .callcard .event { font-size: 1.875rem; }
    #app[data-mode="call"] #intro.what { font-size: 1rem; margin: 6px 2px 4px; }
    #app[data-mode="call"] #intro.what::before { margin-bottom: 5px; }
    #app[data-mode="call"] #keys { display: none; }
  }
