@layer base, page, kit;
@layer base {
/* sojo: one stylesheet for the frame sheet, the popup and the hub. Tokens from the Paper file (Style guide, docs/design.md). */
/* Self-hosted Rysana Sans and Rysana Mono (licensed to sojo; subset woff2 in assets/fonts/). Nothing loads from a third party. */
@font-face { font-family: "Rysana Sans"; font-style: normal; font-weight: 800; font-display: swap; src: url(/fonts/rysana-sans-800.woff2?v=746d694bc5) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2190-21FF, U+2212, U+2713, U+2715, U+2500-259F, U+FEFF, U+FFFD; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/rysana-mono-400.woff2?v=9d5089629e) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2190-21FF, U+2212, U+2713, U+2715, U+2500-259F, U+FEFF, U+FFFD; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url(/fonts/rysana-mono-500.woff2?v=a417c995b9) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2190-21FF, U+2212, U+2713, U+2715, U+2500-259F, U+FEFF, U+FFFD; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 700; font-display: swap; src: url(/fonts/rysana-mono-700.woff2?v=22d84f0d6e) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2190-21FF, U+2212, U+2713, U+2715, U+2500-259F, U+FEFF, U+FFFD; }

/* Per-script subsets: a browser fetches one only when the page shows a character in its range. Han has no Rysana glyphs,
 * so kanji and Chinese use system fonts. Made from the owner's TTFs (~/Library/Fonts; SIL OFL 1.1) with fonttools:
 * pyftsubset RysanaMono-Regular.ttf --unicodes="<range below>" --layout-features='*' --flavor=woff2 --output-file=rysana-mono-400-<script>.woff2
 * (Medium 500, Bold 700, RysanaSans-ExtraBold 800). Hangul: hangul1 is the 2,350 KS X 1001 syllables + jamo (--unicodes-file),
 * hangul2 the other 8,822; both declare the syllable block, and hangul1 (declared last) is tried first. */
@font-face { font-family: "Rysana Sans"; font-style: normal; font-weight: 800; font-display: swap; src: url(/fonts/rysana-sans-800-latinx.woff2?v=2506ccd994) format("woff2"); unicode-range: U+0100-0130, U+0132-0151, U+0154-024F, U+0300-036F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF; }
@font-face { font-family: "Rysana Sans"; font-style: normal; font-weight: 800; font-display: swap; src: url(/fonts/rysana-sans-800-kana.woff2?v=d9343c79d3) format("woff2"); unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF, U+FF01-FF60, U+FF65-FF9F; }
@font-face { font-family: "Rysana Sans"; font-style: normal; font-weight: 800; font-display: swap; src: url(/fonts/rysana-sans-800-arab.woff2?v=0ac51bb377) format("woff2"); unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFE; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/rysana-mono-400-latinx.woff2?v=132a635b45) format("woff2"); unicode-range: U+0100-0130, U+0132-0151, U+0154-024F, U+0300-036F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/rysana-mono-400-kana.woff2?v=501cb52869) format("woff2"); unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF, U+FF01-FF60, U+FF65-FF9F; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/rysana-mono-400-arab.woff2?v=668974adbe) format("woff2"); unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFE; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url(/fonts/rysana-mono-500-latinx.woff2?v=db481a1e22) format("woff2"); unicode-range: U+0100-0130, U+0132-0151, U+0154-024F, U+0300-036F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url(/fonts/rysana-mono-500-kana.woff2?v=c6a2e21e03) format("woff2"); unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF, U+FF01-FF60, U+FF65-FF9F; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url(/fonts/rysana-mono-500-arab.woff2?v=b47957a82f) format("woff2"); unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFE; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 700; font-display: swap; src: url(/fonts/rysana-mono-700-latinx.woff2?v=870f33d9d5) format("woff2"); unicode-range: U+0100-0130, U+0132-0151, U+0154-024F, U+0300-036F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 700; font-display: swap; src: url(/fonts/rysana-mono-700-kana.woff2?v=9665717479) format("woff2"); unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF, U+FF01-FF60, U+FF65-FF9F; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 700; font-display: swap; src: url(/fonts/rysana-mono-700-arab.woff2?v=b57837b780) format("woff2"); unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFE; }
@font-face { font-family: "Rysana Sans"; font-style: normal; font-weight: 800; font-display: swap; src: url(/fonts/rysana-sans-800-thai.woff2?v=0c987ec63c) format("woff2"); unicode-range: U+0E00-0E7F; }
@font-face { font-family: "Rysana Sans"; font-style: normal; font-weight: 800; font-display: swap; src: url(/fonts/rysana-sans-800-hangul2.woff2?v=4726f4d132) format("woff2"); unicode-range: U+AC00-D7A3; }
@font-face { font-family: "Rysana Sans"; font-style: normal; font-weight: 800; font-display: swap; src: url(/fonts/rysana-sans-800-hangul1.woff2?v=6ba252df91) format("woff2"); unicode-range: U+1100-11FF, U+3130-318F, U+AC00-D7A3; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/rysana-mono-400-thai.woff2?v=74dfbaa9ee) format("woff2"); unicode-range: U+0E00-0E7F; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/rysana-mono-400-hangul2.woff2?v=c93f6dc123) format("woff2"); unicode-range: U+AC00-D7A3; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url(/fonts/rysana-mono-400-hangul1.woff2?v=234cdd87a4) format("woff2"); unicode-range: U+1100-11FF, U+3130-318F, U+AC00-D7A3; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url(/fonts/rysana-mono-500-thai.woff2?v=eeb3ffaf8f) format("woff2"); unicode-range: U+0E00-0E7F; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url(/fonts/rysana-mono-500-hangul2.woff2?v=051f6a3adf) format("woff2"); unicode-range: U+AC00-D7A3; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 500; font-display: swap; src: url(/fonts/rysana-mono-500-hangul1.woff2?v=b246e45e47) format("woff2"); unicode-range: U+1100-11FF, U+3130-318F, U+AC00-D7A3; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 700; font-display: swap; src: url(/fonts/rysana-mono-700-thai.woff2?v=1f31dfde2f) format("woff2"); unicode-range: U+0E00-0E7F; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 700; font-display: swap; src: url(/fonts/rysana-mono-700-hangul2.woff2?v=d9f0ec18aa) format("woff2"); unicode-range: U+AC00-D7A3; }
@font-face { font-family: "Rysana Mono"; font-style: normal; font-weight: 700; font-display: swap; src: url(/fonts/rysana-mono-700-hangul1.woff2?v=16fe9b6a23) format("woff2"); unicode-range: U+1100-11FF, U+3130-318F, U+AC00-D7A3; }
:root {
  /* Direction A tokens (Paper Style guide, docs/design.md). Dark is the default; sojo.gg pages follow the system. */
  --ground: #0D0D0B; --surface: #161613; --line: #2B2A25; --line-strong: #3A3932; --text: #EDE7D9; --muted: #8F8A7D;
  --plate: rgb(13 13 11 / 92%); --green: #00DC40; --green-ink: #007A24; --on-green: #0D0D0B; --royal: #3862F5; --red: #E5484D; --test: #FFD23F; --on-test: #0D0D0B; --chart: #7D9BFF;
  --ok: var(--green); --scrim: rgb(13 13 11 / 55%);
  --sans: "Rysana Sans", system-ui, sans-serif; --mono: "Rysana Mono", ui-monospace, monospace;
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px; --sp-12: 48px; --sp-16: 64px; --sp-20: 80px;
  --radius: 0; --sheet-w: 448px; --page-w: 720px;
  /* Legacy names, kept so older rules read the new palette. Prefer the names above in new code. */
  --ink: var(--text); --slate: var(--muted); --hair: var(--line); --mist: var(--line-strong); --sky: var(--surface); --chip: var(--surface);
  --sojo: var(--text); --deep: var(--text); --night: var(--text);
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root:not(.dark) { --ground: #F5F4F0; --surface: #FFFFFF; --line: #DAD7CE; --line-strong: #C9C5BA; --text: #12110E; --muted: #6E6A60;
    --plate: rgb(245 244 240 / 92%); --ok: var(--green-ink); --scrim: rgb(18 17 14 / 45%); color-scheme: light; }
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; }
body { -webkit-font-smoothing: antialiased; font-synthesis: none; }
button { font: inherit; cursor: pointer; }
a { color: inherit; }
.small { font-size: 12px; }


}
@layer base {
/* ---------- frame: transparent until the sheet opens ---------- */
html:has(body.frame), body.frame { overflow: hidden; }
/* An archived or suspended game (frame.ts notice): the game isn't live, so the line covers it. */
.fr-off { position: fixed; inset: 0; margin: 0; padding: 24px; display: grid; place-items: center; text-align: center; text-wrap: balance; background: var(--ground); color: var(--text); }

/* ---------- sheet (frame overlay, popup page, hub modal) ---------- */
.sj-ov { position: fixed; inset: 0; z-index: 2147483647; display: flex; align-items: center; justify-content: center; padding: 16px;
  overflow: hidden; }
/* The scrim is its own layer so it fades apart from the card (ui.js Motion). */
.sj-scrim { position: absolute; inset: 0; background: var(--scrim); }
.sj-ov.sj-page { overflow: visible; }
.sj-page .sj-scrim { display: none; }
.sj-ov.sj-out { pointer-events: none; }
/* Waiting for the frame to have room (ui.js whenSized): laid out but never painted and never takes a tap. */
.sj-ov.sj-wait { visibility: hidden; pointer-events: none; }
.sj-ov { overscroll-behavior: contain; }
/* The card sizes to its content. It never grows past the viewport minus a margin; past that, only its body scrolls,
   and the scrollbar stays inside the rounded clip. */
.sj-card { width: 100%; overflow: hidden; display: flex; flex-direction: column; position: relative; max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); }
.sj-body { position: relative; display: flex; flex-direction: column; gap: 16px; overflow-y: auto; min-height: 0; overscroll-behavior: contain; }
.sj-body > * { flex-shrink: 0; } /* scroll, never squash (Stripe's iframes overlapped the button) */
/* Narrow screens: a bottom sheet (not the popup page, which is the whole window). */
@media (max-width: 440px) {
  .sj-ov:not(.sj-page) { align-items: flex-end; padding: 8px 0 0; }
  .sj-ov:not(.sj-page) .sj-card { max-width: none; max-height: calc(100vh - 8px); max-height: calc(100dvh - 8px); }
}
.sj-card.sj-sizing > .sj-body { overflow: hidden; } /* while the height eases: no scrollbar flash */
/* Ghosts: old content fading out where it was during a step change. Never takes clicks. */
.sj-ghost { position: absolute !important; margin: 0 !important; pointer-events: none !important; z-index: 1; box-sizing: border-box; }
/* Rolling numbers (SojoUI.roll): one clipped column per digit, solid while it slides; rest on the middle 0–9 */
.sj-vh { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.sj-roll { position: relative; display: inline-flex; direction: ltr; unicode-bidi: isolate; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sj-rv { display: inline-flex; }
.sj-rc { position: relative; display: inline-block; flex: 0 0 auto; overflow: hidden; }
.sj-rd::before { content: "0"; visibility: hidden; }
.sj-rs { position: absolute; left: 0; top: 0; width: 100%; text-align: center; }
.sj-rs > span { display: block; }
.sj-rs[data-d="0"] { transform: translateY(-33.3333%); } .sj-rs[data-d="1"] { transform: translateY(-36.6667%); }
.sj-rs[data-d="2"] { transform: translateY(-40.0000%); } .sj-rs[data-d="3"] { transform: translateY(-43.3333%); }
.sj-rs[data-d="4"] { transform: translateY(-46.6667%); } .sj-rs[data-d="5"] { transform: translateY(-50.0000%); }
.sj-rs[data-d="6"] { transform: translateY(-53.3333%); } .sj-rs[data-d="7"] { transform: translateY(-56.6667%); }
.sj-rs[data-d="8"] { transform: translateY(-60.0000%); } .sj-rs[data-d="9"] { transform: translateY(-63.3333%); }
.sj-hd { display: flex; align-items: center; justify-content: space-between; height: 32px; }
.sj-brand { display: flex; align-items: center; gap: 8px; font-size: 19px; }
.sj-brand img { width: 28px; height: 28px; }
.sj-x { border: 0; background: none; padding: 6px; margin: -6px; display: flex; }

.sj-lead { display: flex; align-items: center; gap: 16px; padding-top: 2px; }
.sj-lead-t { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sj-art { width: 60px; height: 60px; flex-shrink: 0; object-fit: cover; background: var(--sky); }
.sj-title { overflow-wrap: anywhere; }
.sj-sub { font-size: 15px; line-height: 21px; }
.sj-mono { font-size: 14px; line-height: 20px; }
/* secondary actions (3DS 2: Reopen the tab, Cancel) */
.sj-btn.sm { flex-shrink: 0; }
.sj-row { display: flex; gap: 10px; }
.sj-in { flex: 1; min-width: 0; }
.sj-err:empty { display: none; }
.sj-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.sj-foot.mid { justify-content: center; }
.sj-note { font-size: 13px; line-height: 18px; }
.sj-link { border: 0; background: none; padding: 0; }
.sj-foot .sj-link { flex-shrink: 0; white-space: nowrap; }

.sj-legal { font-size: 12px; line-height: 17px; text-align: center; margin-top: -6px; }
.sj-legal a { text-decoration: underline; text-underline-offset: 2px; }


}
@layer page {
/* ---------- popup ---------- */
body.popup { min-height: 100vh; }
/* /pay: the bank check tab. Who and what on the left, the check on the right. */
.pp { min-height: 100vh; display: flex; align-items: flex-start; justify-content: center; gap: 72px; padding: 64px 80px; }
.pp-l { width: 380px; flex-shrink: 0; display: flex; flex-direction: column; gap: 28px; }
.pp-brand { display: flex; align-items: center; gap: 10px; }
.pp-titles { display: flex; flex-direction: column; gap: 10px; }
.pp-h { margin: 0; }
.pp-sub { white-space: pre-line; }
.pp-sum { border-top: 1px solid var(--hair); padding-top: 20px; display: flex; flex-direction: column; gap: 14px; }
.pp-who { display: flex; align-items: center; gap: 12px; }
.pp-av { width: 36px; height: 36px; object-fit: cover; flex-shrink: 0; background: var(--sky); }
.pp-who-t { display: flex; flex-direction: column; min-width: 0; }
.pp-handle { font-size: 15px; line-height: 20px; }
.pp-for { font-size: 12px; line-height: 17px; }
.pp-item { display: flex; align-items: flex-start; justify-content: space-between; }
.pp-gems { display: flex; align-items: center; gap: 10px; font-size: 17px; line-height: 26px; }
.pp-price { display: flex; flex-direction: column; align-items: flex-end; }
.pp-p { font-size: 17px; line-height: 26px; }
.pp-fee { font-size: 12px; line-height: 17px; }
.pp-card { width: 440px; flex-shrink: 0; display: flex; flex-direction: column; gap: 18px; }
.pp-ct { display: flex; flex-direction: column; gap: 6px; }
.pp-cs { font-size: 14px; line-height: 20px; }
.pp-hr { height: 1px; }
.pp-foot { font-size: 12px; line-height: 17px; text-align: center; }
@media (max-width: 960px) { .pp { flex-direction: column; align-items: center; gap: 32px; padding: 32px 20px; } .pp-l, .pp-card { width: 100%; max-width: 440px; }}
.pop-msg { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; text-align: center; }


}
@layer page {
/* ---------- gems and payments (web/pay.ts): docked to the bottom of the game, 16px in ---------- */
.sj-ov.pg { align-items: flex-end; padding: 16px; }
.pg .sj-card { max-width: 448px; border-radius: 0; box-shadow: none; }
.pg .sj-body { padding: 20px 22px 22px; }
@media (max-width: 440px) { .sj-ov.pg { padding: 8px 8px 0; } .pg .sj-card { border-radius: 0; } }
.pg-hdr { display: flex; align-items: center; gap: 16px; }
.pg-pill { display: flex; align-items: center; gap: 8px; padding-block: 8px; padding-inline: 11px 15px; border-radius: 0; background: var(--sky); }
.pg-pill-n { font-family: var(--mono); font-size: 15px; line-height: 21px; font-weight: 500; color: var(--night); font-variant-numeric: tabular-nums; }
.pg-gem { flex-shrink: 0; display: block; }
.pg-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.pg-pack { border-radius: 0; box-shadow: inset 0 0 0 1.5px var(--hair); padding: 14px 16px; display: flex; flex-direction: column; gap: 6px; cursor: pointer; user-select: none; }
.pg-pack.on { background: var(--sky); box-shadow: inset 0 0 0 2px var(--sojo); cursor: default; }
.pg-pack:focus-visible, .pg-mini:focus-visible { outline: 2px solid var(--sojo); outline-offset: 2px; }
.pg-pack-t, .pg-pack-b { display: flex; align-items: center; justify-content: space-between; }
.pg-pack-b { height: 28px; }
.pg-pack-g { display: flex; align-items: center; gap: 8px; font-family: var(--mono); font-size: 21px; line-height: 29px; font-weight: 500; }
.pg-price { font-family: var(--mono); font-size: 15px; line-height: 21px; font-weight: 500; color: var(--slate); }
.pg-bonus { padding: 2px 8px; border-radius: 0; background: var(--sky); color: var(--night); font-family: var(--mono); font-size: 13px; line-height: 18px; font-weight: 500; }
.pg-pack.on .pg-bonus, .pg-mini.on .pg-bonus { background: var(--surface); }
.pg-foot { display: flex; align-items: center; gap: 16px; } /* a long fee + tax line wraps; the button keeps its size */
.pg-q { font-family: var(--mono); font-size: 15px; line-height: 20px; font-weight: 500; color: var(--slate); }
.pg-q.wait { opacity: .5; }
.pg-foot .pg-pay { flex: 1 0 auto; }
.pg-pay { font-size: 17px; font-weight: 500; }
.pg-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 34px; height: 22px; padding: 0 5px; border-radius: 0; background: #1a1f71; color: #fff;
  font-size: 10px; font-weight: 800; font-style: italic; letter-spacing: .02em; }
.pg-badge.mastercard { background: #252525; } .pg-badge.amex { background: #2e77bb; } .pg-badge.link { background: #00d66f; color: #0f1729; font-style: normal; }
.pg-ece:empty { display: none; }
.pg-or { display: flex; align-items: center; gap: 12px; color: var(--slate); font-size: 13px; font-weight: 500; }
.pg-or::before, .pg-or::after { content: ""; flex: 1; height: 1px; background: var(--hair); }
.pg-pe { min-height: 120px; }
.pg-wait { padding: 2px 0; }
.pg-spin { flex-shrink: 0; display: block; animation: pg-spin 800ms linear infinite; }
@keyframes pg-spin { to { transform: rotate(360deg); } }
.pg-titles { display: flex; flex-direction: column; gap: 2px; }
/* Any button that states a gem amount: black, the gem icon, the amount in mono. */
/* Narrow sheets (390 px games): packs and minis shrink to their columns instead of running past the card */
@media (max-width: 440px) {
  .pg-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .pg-pack { padding: 12px; }
  .pg-pack-g { font-size: 18px; gap: 6px; }
}
.pg-mini { border: 0; border-radius: 0; background: var(--surface); box-shadow: inset 0 0 0 1.5px var(--hair); padding: 10px 12px; display: flex; flex-direction: column; gap: 4px; text-align: start; color: var(--ink); }
.pg-mini.on { background: var(--sky); box-shadow: inset 0 0 0 2px var(--sojo); }
.pg-load { height: 120px; }
/* Gems received: a full-size overlay that never takes clicks. */
.pg-probe { position: fixed; inset: 0; pointer-events: none; }
.pg-rcv { position: fixed; inset: 0; pointer-events: none; z-index: 2147483647; overflow: hidden; }
.pg-fade { position: absolute; left: 0; right: 0; top: 0; height: 120px; background: linear-gradient(rgb(15 23 41 / 45%), rgb(15 23 41 / 0%)); }
.pg-fly { position: absolute; left: 50%; top: 16px; width: max-content; transform: translateX(-50%); }
.pg-fly-pill { padding-block: 6px; padding-inline: 10px 14px; background: var(--surface); box-shadow: none; }
.pg-fly-pill .pg-pill-n { color: var(--night); }
.pg-bit { position: absolute; left: 0; top: 0; transform-origin: 0 0; } /* scale and spin around the gem's centre, so it lands on the pill's gem */
.pg-bit .pg-gem { transform: translate(-50%,-50%); filter: drop-shadow(0 3px 3px rgb(15 23 41 / 40%)); }
.pg-clock { position: absolute; width: 0; height: 0; }
/* ---------- supporter (web/pay.ts): Subscribe sheets, the −500 in the pill, toasts ---------- */
.pg .sj-body:has(> .pg-sup) { gap: 18px; }
.pg-sup { display: flex; flex-direction: column; gap: 4px; }
.pg-sup-s { padding-inline-start: 37px; font-family: var(--mono); font-size: 14px; line-height: 20px; color: var(--slate); }
.pg-crow { display: flex; align-items: center; gap: 12px; padding: 13px 16px; border-radius: 0; background: var(--sky); }
.pg-crow .pg-badge { min-width: 36px; height: 24px; font-size: 11px; }
.pg-crow-n { flex: 1; min-width: 0; font-family: var(--mono); font-size: 15px; line-height: 21px; font-weight: 500; }
.pg-crow-c { border: 0; background: none; padding: 0; color: var(--deep); font: inherit; font-size: 16px; line-height: 20px; font-weight: 500; cursor: pointer; }
.pg-crow-c:hover { color: var(--night); }
/* Pay · Choose a card (web/pay.ts chooseCard) */
.pg-cc-list { display: flex; flex-direction: column; gap: 8px; }
.pg-cc { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 0 16px; border: 0; border-radius: 0; background: var(--surface); box-shadow: inset 0 0 0 1.5px var(--hair);
  color: var(--ink); text-align: start; font: inherit; cursor: pointer; }
.pg-cc:hover { background: var(--chip); }
.pg-cc.on { background: var(--sky); box-shadow: inset 0 0 0 2px var(--sojo); }
.pg-cc:focus-visible { outline: 2px solid var(--sojo); outline-offset: 2px; }
.pg-cc .pg-badge { width: 46px; height: 24px; padding: 0; font-size: 11px; } /* one width, so the names line up */
.pg-cc-n { flex: 1; min-width: 0; font-family: var(--mono); font-size: 15px; line-height: 21px; font-weight: 500; }
.pg-cc-e { font-family: var(--mono); font-size: 13px; line-height: 18px; font-weight: 500; color: var(--slate); font-variant-numeric: tabular-nums; }
.pg-cc-ok { width: 18px; height: 18px; flex-shrink: 0; color: var(--sojo); }
.pg-cc-add .pg-cc-n { font-family: var(--mono); color: var(--deep); }
.pg-cc-plus { width: 46px; flex-shrink: 0; height: 24px; border-radius: 0; background: var(--chip); color: var(--deep); display: flex; align-items: center; justify-content: center; }
.pg-subw { display: flex; flex-direction: column; gap: 12px; } .pg-subw.short { gap: 10px; }
/* No saved card: the pay button and its lines dock to the bottom while the body scrolls; a fade shows there's more above. */
.pg .sj-body:has(> .pg-dock) { padding-bottom: 0; }
.pg-dock { position: sticky; bottom: 0; z-index: 1; margin: 0 -22px; padding: 0 22px 22px; background: var(--surface); }
.pg-dock::before { content: ""; position: absolute; left: 0; right: 0; top: -18px; height: 18px; background: linear-gradient(rgb(255 255 255 / 0), #fff); pointer-events: none; }
.pg-quiet { padding: 0 8px; text-align: center; font-size: 13px; line-height: 18px; font-weight: 500; color: var(--slate); text-wrap: pretty; }
/* EU/EEA/UK only: one quiet line right above the pay button (gems and Supporter). */
.pg-eu { padding: 0 8px; text-align: center; font-size: 13px; line-height: 18px; font-weight: 500; color: var(--slate); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pg-tw { position: fixed; inset: auto 0 24px 0; display: flex; justify-content: center; pointer-events: none; z-index: 2147483647; }
.pg-tw-a { position: absolute; }
.pg-toast { display: flex; align-items: center; gap: 10px; padding-block: 8px; padding-inline: 8px 18px; border: 0; border-radius: 0; background: var(--surface); white-space: nowrap;
  box-shadow: none; font: inherit; font-size: 16px; line-height: 20px; color: var(--slate); }
.pg-toast img { width: 28px; height: 28px; border-radius: 0; flex-shrink: 0; }
.pg-toast b { font-weight: 500; color: var(--ink); }
.pg-toast-b { pointer-events: auto; cursor: pointer; padding-inline-end: 16px; color: var(--deep); }
.pg-toast-b:hover .pg-toast-l { text-decoration: underline; }
.pg-toast-l { font-weight: 500; }
/* ---------- spend in place (web/pay.ts confirmInPlace): sojo's Confirm over the game's spend button ---------- */
/* The one green gem button (every other one is black). White on each shade: go 5.02:1, hover 4.69:1, press 6.35:1.
   It's final from its first frame; the 600 ms arm (web/pay.ts ARM_MS) is enforced but never drawn. */
.pg-sp { position: fixed; inset: 0; pointer-events: none; z-index: 2147483647; overflow: hidden;
  --go: #16a34a; --go-hover: #19ab4f; --go-press: #12883d; } /* lighter, friendlier green (owner, 2026-10-16) */
.pg-sp-btn { position: absolute; display: flex; align-items: center; justify-content: center; gap: 8px; width: max-content; height: 44px; padding: 0 16px; border: 0;
  border-radius: 0; background: var(--go); color: #fff; box-shadow: none; pointer-events: auto; white-space: nowrap; touch-action: manipulation;
  overflow: hidden; }
.pg-sp-btn:hover { background: var(--go-hover); } .pg-sp-btn:active { background: var(--go-press); }
.pg-sp-btn.busy { cursor: default; background: var(--go); }
/* Confirming: a small white spinner to the left of "Confirm" until the server answers. Collapsed until then; it eases
   open (the content stays centred) so nothing jumps. Reduced motion: a still ring. */
.pg-sp-spin { flex-shrink: 0; display: block; width: 0; margin-inline-end: -8px; opacity: 0; animation: none;
  transition: width 200ms cubic-bezier(.4,0,.2,1), margin-inline-end 200ms cubic-bezier(.4,0,.2,1), opacity 120ms linear; }
.pg-sp-btn.busy .pg-sp-spin { width: 16px; margin-inline-end: 0; opacity: 1; animation: pg-spin 800ms linear infinite; }
.pg-sp-btn.busy.done .pg-sp-spin { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .pg-sp-spin { transition: none; } .pg-sp-btn.busy .pg-sp-spin { animation: none; } }
.pg-sp-btn:focus-visible { outline: 2px solid var(--sojo); outline-offset: 2px; }
.pg-sp-l { display: inline-block; overflow: hidden; font-family: var(--mono); font-size: 15px; line-height: 20px; font-weight: 500; }
.pg-sp-n { font-family: var(--mono); font-size: 15px; line-height: 20px; font-weight: 500; font-variant-numeric: tabular-nums; }
.pg-sp-pill { position: absolute; left: 50%; top: 12px; transform: translate(-50%,-72px); background: var(--surface); box-shadow: none; }
.pg-sp-pill .pg-pill-n { color: var(--ink); }

}
@layer kit {
/* ---------- kit layer: the button, the input, the icon-button (the "copy box") — the only building blocks a page may
   never restyle. See web/css/10-base.css for everything else (resets, typography, links, cards, chips, pay-sheet decor). ---------- */
/* ---------- buttons (board 5.1): [ bracketed ] labels, square, no shadows ---------- */
/* align-items/justify-content (content centering) live in base (10-base.css, "kit layout") so a page can still refine them. */
.sj-btn { display: inline-flex; gap: 8px; height: 36px; padding: 0 18px; border: 1px solid var(--line-strong);
  border-radius: 0; background: transparent; color: var(--text); box-shadow: none; font-family: var(--mono); font-size: 15px; line-height: 18px; font-weight: 500;
  text-decoration: none; white-space: nowrap; }
.sj-btn::before { content: "[\00a0"; } .sj-btn::after { content: "\00a0]"; }
.sj-btn:hover { background: var(--surface); border-color: var(--muted); }
.sj-btn.sm, .sj-btn.small { height: 28px; padding: 0 12px; font-size: 13px; line-height: 16px; }
.sj-row .sj-btn.sm { height: 40px; padding: 0 18px; font-size: 15px; } /* beside a 40 px input */
.sj-btn.ghost { border-color: transparent; background: transparent; color: var(--muted); box-shadow: none; }
.sj-btn.ghost:hover { color: var(--text); background: transparent; border-color: var(--line); }
/* Pay: green fill, ink label, 40 high. One per screen, pay actions only. */
.sj-btn.pay, .sj-btn.pg-pay { height: 40px; padding: 0 20px; border-color: var(--green); background: var(--green); color: var(--on-green); }
.sj-btn.pay:hover, .sj-btn.pg-pay:hover { background: #1AE556; border-color: #1AE556; }
.sj-btn.royal { height: 40px; padding: 0 20px; border-color: var(--royal); background: var(--royal); color: #fff; }
.sj-btn.royal:hover { background: #4C72F7; border-color: #4C72F7; }
/* Primary: the page's one main action, filled with the text color. */
.sj-btn.primary { height: 40px; padding: 0 20px; border-color: var(--text); background: var(--text); color: var(--ground); }
.sj-btn.primary:hover { background: var(--muted); border-color: var(--muted); }
.sj-btn.primary:disabled, .sj-btn.primary.wait { background: var(--text); border-color: var(--text); }
.sj-btn:disabled, .sj-btn.wait { opacity: .6; cursor: default; } /* a swap from .6 reads as a cross-fade */
.sj-btn.pay:disabled, .sj-btn.pg-pay:disabled { background: var(--green); }
/* Busy: the spinner (round, the one exception) sits left of the bracket. */
.spin, .pg-spin { border-radius: 50%; }
.sj-btn .pg-spin, .sj-btn .spin { order: -1; }
/* width/flex-shrink moved to base (10-base.css, "kit layout"). */
.spin { display: block; height: 14px; border: 2px solid currentColor; border-right-color: transparent; animation: pg-spin 800ms linear infinite; }
@media (prefers-reduced-motion: reduce) { .spin { animation: none; } }

/* ---------- inputs and code boxes (board 5.2) ---------- */
.sj-in { height: 40px; border: 1px solid var(--line-strong); border-radius: 0; background: var(--surface); color: var(--text); padding: 0 14px;
  font-family: var(--mono); font-size: 16px; line-height: 20px; font-weight: 400; } /* 16px: iOS zooms the page on focus under that (fb_ma9tuxhm2md4ahys); never maximum-scale instead, it would block pinch zoom too */
.sj-in:focus { outline: none; border-color: var(--text); }
.sj-in::placeholder { color: var(--muted); }
/* min-width/flex/width/max-width moved to base (10-base.css, "kit layout"). */
.em-box { text-align: center; padding: 0; height: 48px; border: 1px solid var(--line-strong);
  border-radius: 0; background: var(--surface); color: var(--text); font-family: var(--mono); font-size: 20px; font-weight: 500; }
.em-box:focus { outline: none; border-color: var(--text); }

/* ---------- the copy box: square icon buttons (the landing's Copy bar, the simulator's test cards) ---------- */
/* align-items/justify-content/flex-shrink/margin moved to base (10-base.css, "kit layout"). */
.ib { display: flex; box-sizing: border-box; padding: 0;
  background: var(--surface); border: 1px solid var(--line-strong); color: var(--text); border-radius: 0; text-decoration: none; }
.ib-clip { fill: var(--surface); }
.ib:active { background: var(--ground); }
.ib:active .ib-clip { fill: var(--ground); }
.ib:active > * { transform: translateY(1px); }
.ib:focus-visible { outline: 2px solid #7D9BFF; outline-offset: 2px; }
.ib:focus:not(:focus-visible) { outline: none; }
.cbox { background: var(--surface); border: 1px solid var(--line-strong); }
/* width/flex-shrink moved to base (10-base.css, "kit layout"). */
.em-dash { height: 2px; background: var(--line-strong); border-radius: 0; }

}
@layer base {
/* ===================================================================================
   Direction A foundation (Paper Style guide boards 2 to 5; docs/design.md). Later rules win over the
   legacy rules above. New screens use these classes and tokens; square corners everywhere but the spinner.
   ========================================================================================== */
html { background: var(--ground); }
body { font-family: var(--mono); font-size: 16px; line-height: 24px; font-weight: 400; color: var(--text); font-variant-numeric: tabular-nums; }
body.hub, body.popup, body.pay { background: var(--ground); }
html:has(body.frame), body.frame { background: transparent; }
/* The frame: dark tokens, but the root color-scheme matches the iframe's (light), or the game sees an opaque box. */
html.dark { color-scheme: light; } html.dark body { color-scheme: dark; }
.mono { font-family: var(--mono); font-weight: 400; }
.dim { color: var(--muted); }
::selection { background: var(--royal); color: #fff; }
:focus-visible { outline: 1px solid var(--text); outline-offset: 2px; }

/* ---------- type (board 3) ---------- */
.t-display { font-family: var(--sans); font-size: 96px; line-height: 88px; font-weight: 800; letter-spacing: -0.045em; }
.t-h1, .hero h1, .prof-h, .pp-h, .legal h1, .gm-h { font-family: var(--sans); font-size: 48px; line-height: 52px; font-weight: 800; letter-spacing: -0.03em; }
.t-h2, .legal h2, .sj-title, .hd-brand, .sj-brand, .pp-brand { font-family: var(--sans); font-weight: 800; letter-spacing: -0.02em; }
.t-h2, .legal h2 { font-size: 28px; line-height: 32px; }
.sj-title { font-size: 24px; line-height: 32px; }
.t-figure, .bal-n, .stat-n { font-family: var(--mono); font-size: 24px; line-height: 32px; font-weight: 500; font-variant-numeric: tabular-nums; }
.t-body { font-size: 16px; line-height: 24px; font-weight: 400; }
.t-row { font-size: 14px; line-height: 20px; font-weight: 400; }
.t-label, .label, .em-step, .tr.th { font-family: var(--mono); font-size: 12px; line-height: 16px; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.num { font-variant-numeric: tabular-nums; text-align: end; }
@media (max-width: 600px) { .t-h1, .hero h1, .prof-h, .pp-h, .legal h1, .gm-h { font-size: 36px; line-height: 40px; } .t-display { font-size: 64px; line-height: 60px; } }

/* ---------- ┌─ section heading: a small label above a Sans heading ---------- */
.kicker, .block > .label { display: flex; align-items: center; gap: 8px; }
.kicker::before, .block > .label::before { content: "\250C\2500"; color: var(--muted); letter-spacing: 0; }
.kicker { font-size: 12px; line-height: 16px; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }


/* ---------- links ---------- */
.sj-link, .link { color: var(--text); font-family: var(--mono); font-size: 14px; line-height: 20px; font-weight: 400; text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 3px; }
.sj-link:hover, .link:hover { text-decoration-color: var(--text); }
.sj-link.quiet, .link.quiet { color: var(--muted); text-decoration: none; font-weight: 400; }
.sj-link.quiet:hover, .link.quiet:hover { color: var(--text); }

.sj-err, .err { font-family: var(--mono); font-size: 14px; line-height: 20px; font-weight: 400; color: var(--red); }
.sj-note, .sj-legal, .pp-foot, .pp-for, .pp-fee { font-family: var(--mono); font-weight: 400; color: var(--muted); }
.sj-legal a { color: var(--muted); }

/* ---------- rows and tables (board 5.3): 48 px rows, 1 px lines, numbers right aligned ---------- */
.row, .tr, .sj-r { border-top: 0; border-bottom: 1px solid var(--line); font-size: 14px; line-height: 20px; min-height: 48px; }
.sj-r { display: flex; align-items: center; gap: 16px; }
.sj-r .num, .tr .num, .amt { margin-inline-start: auto; text-align: end; font-variant-numeric: tabular-nums; font-weight: 400; }
.row-main { flex: 1; min-width: 0; overflow-wrap: anywhere; font-weight: 400; }
.game-row:hover .row-main { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.tr.th { min-height: 32px; }
/* a wide table scrolls inside its own box, never the page; its columns never squeeze below their content */
.tscroll { overflow-x: auto; max-width: 100%; }
.tscroll > * { min-width: var(--tmin, max-content); }

/* ---------- cards (surface + 1 px line, square) ---------- */
.card, .box, .bal, .pp-card { background: var(--surface); border: 1px solid var(--line); border-radius: 0; box-shadow: none; }
.box-title { font-weight: 500; }
.legal code, .lookup { background: var(--surface); border: 1px solid var(--line); border-radius: 0; }

/* ---------- sheets (board 5.4): 480 frame, 448 sheet, 24 padding, square, no shadow ---------- */
.sj-card, .pg .sj-card { max-width: var(--sheet-w); background: var(--surface); border: 1px solid var(--line); border-radius: 0; box-shadow: none; }
.sj-body { padding: 24px; }
@media (max-width: 440px) { .sj-ov:not(.sj-page) .sj-card, .pg .sj-card { border-radius: 0; border-bottom: 0; } .sj-ov:not(.sj-page) .sj-body { padding-bottom: calc(24px + env(safe-area-inset-bottom)); } }
.sj-ov.sj-page { background: var(--ground); }
.sj-x { color: var(--muted); border-radius: 0; } .sj-x:hover { background: transparent; color: var(--text); }
.sj-art, .pp-av, .prof-av, .hd-av img, .sj-brand img, .pp-brand img, .hd-brand img, .pg-toast img { border-radius: 0; }
.sj-sub, .sj-mono, .pp-sub, .pp-cs { font-family: var(--mono); font-weight: 400; color: var(--muted); }
.pp-hr, .sj-pl-hr { background: var(--line); }
.pp-sum { border-top-color: var(--line); }

/* ---------- pay sheet parts: selection is a 1 px text-colored line, never a fill ---------- */
.pg-pill, .pg-crow, .pg-nudge { background: transparent; border: 1px solid var(--line); color: var(--text); }
.pg-pill-n { color: var(--text); font-weight: 500; }
.pg-pack, .pg-mini, .pg-cc { background: transparent; box-shadow: inset 0 0 0 1px var(--line); }
.pg-mini:hover, .pg-cc:hover { box-shadow: inset 0 0 0 1px var(--line-strong); }
.pg-pack.on, .pg-mini.on, .pg-cc.on { background: transparent; box-shadow: inset 0 0 0 1px var(--text); }
.pg-bonus, .pg-pack.on .pg-bonus, .pg-mini.on .pg-bonus { background: transparent; border: 1px solid var(--line-strong); color: var(--text); }
.pg-cc-plus { background: transparent; border: 1px solid var(--line); color: var(--text); }
.pg-crow-c, .pg-cc-add .pg-cc-n { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.pg-badge { border-radius: 0; }
.pg-dock { background: var(--surface); }
.pg-dock::before { background: linear-gradient(transparent, var(--surface)); }
.pg-fade { background: linear-gradient(rgb(13 13 11 / 45%), rgb(13 13 11 / 0%)); }
.pg-fly-pill { background: var(--plate); box-shadow: inset 0 0 0 1px var(--line-strong); }
.pg-bit .pg-gem { filter: none; }

/* Confirm (spend in place): the plain green button with a [ bracketed ] label; spinner left of it. */
.pg-sp { --go: var(--green); --go-hover: #1AE556; --go-press: #00C239; }
.pg-sp-btn { height: 40px; padding: 0 20px; border-radius: 0; color: var(--on-green); box-shadow: none; font-family: var(--mono); }
.pg-sp-btn::before { content: "[\00a0"; order: -1; } .pg-sp-btn::after { content: "\00a0]"; }
.pg-sp-btn .pg-sp-spin { order: -2; }
.pg-sp-l, .pg-sp-n { font-family: var(--mono); font-weight: 500; }
.pg-sp-btn:focus-visible { outline-color: var(--text); }
.pg-sp-pill { background: var(--plate); box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--text); }

/* ---------- the pill and its menu (board 5.4): ground at 92 %, 1 px ring, square ---------- */
.sj-pl { position: fixed; inset: 0; pointer-events: none; z-index: 2147483646; }
.sj-pl-bd { position: absolute; inset: 0; pointer-events: auto; }
.sj-pl-b.off { visibility: hidden; pointer-events: none; }
.sj-pl-b:focus-visible { outline: 2px solid var(--sojo); outline-offset: 2px; }
/* a Top up label too long to sit beside the balance (de, fr, ja…) drops under it instead of running into the padding */
.sj-pl-g { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; padding-block: 8px 12px; padding-inline: 10px 8px; }
.sj-pl-v { display: flex; align-items: center; min-height: 28px; }
.sj-pl-up:focus-visible, .sj-pl-a:focus-visible { outline: 2px solid var(--sojo); outline-offset: 2px; }
.sj-pl-hr { height: 1px; margin: 0 6px; flex-shrink: 0; }
.sj-pl-a svg { color: var(--slate); flex-shrink: 0; }
.pg-nudge { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 0 6px 0 14px; border-radius: 0; }
.pg-nudge-t { flex: 1 1 auto; min-width: 0; font-family: var(--mono); font-size: 13px; line-height: 18px; font-weight: 500; color: var(--slate); }
.pg-nudge-a { flex-shrink: 0; font-size: 14px; line-height: 19px; white-space: nowrap; }
.sj-pl-b { position: absolute; display: flex; align-items: center; gap: 10px; width: max-content; max-width: 240px; height: 44px; padding-block: 0; padding-inline: 0 16px; border: 0;
  pointer-events: auto; white-space: nowrap; touch-action: manipulation; -webkit-tap-highlight-color: transparent; border-radius: 0; background: var(--plate);
  color: var(--text); box-shadow: inset 0 0 0 1px var(--line-strong); font-family: var(--mono); }
.sj-pl-b.on { box-shadow: inset 0 0 0 1px var(--text); }
.sj-pl-b:focus-visible, .sj-pl-up:focus-visible, .sj-pl-a:focus-visible { outline-color: var(--text); }
.sj-pl-av { width: 44px; height: 44px; flex-shrink: 0; object-fit: cover; display: block; border-radius: 0; background: var(--surface); }
.sj-pl-h { min-width: 0; direction: ltr; unicode-bidi: isolate; overflow: hidden; text-overflow: ellipsis; font-size: 14px; line-height: 20px; font-weight: 500; }
.sj-pl-m { position: absolute; width: 264px; max-width: calc(100vw - 24px); display: flex; flex-direction: column; padding: 8px; pointer-events: auto; border-radius: 0;
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); }
.sj-pl-n { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 20px; line-height: 28px; font-weight: 500; color: var(--text); }
.sj-pl-up { flex-shrink: 0; border-radius: 0; height: 28px; padding: 0 12px; border: 1px solid var(--line-strong); background: transparent; color: var(--text);
  font-family: var(--mono); font-size: 13px; line-height: 16px; font-weight: 500; }
.sj-pl-up::before { content: "[\00a0"; } .sj-pl-up::after { content: "\00a0]"; }
.sj-pl-up:hover { background: var(--line); }
.sj-pl-a { display: flex; align-items: center; justify-content: space-between; height: 44px; margin-top: 4px; padding: 0 10px; text-decoration: none; border-radius: 0;
  font-family: var(--mono); font-size: 14px; line-height: 20px; font-weight: 400; color: var(--text); }
.sj-pl-a:hover { background: var(--line); color: var(--text); }
.sj-pl-rp { width: 100%; border: 0; background: transparent; text-align: start; cursor: pointer; }

/* ---------- toasts (board 5.5): surface, 1 px ring, square tile ---------- */
.pg-toast { border-radius: 0; background: var(--surface); box-shadow: inset 0 0 0 1px var(--line-strong); font-family: var(--mono); font-size: 14px; line-height: 20px; color: var(--muted); }
.pg-toast b { font-weight: 500; color: var(--text); }
.pg-toast-l { font-weight: 400; }

/* ---------- chips and the Report flag (board 5.5): 28 high, 1 px line ---------- */
.chip { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 8px; border: 1px solid var(--line-strong); background: transparent; color: var(--text);
  font-family: var(--mono); font-size: 13px; line-height: 16px; font-weight: 400; white-space: nowrap; }
.chip.ok { border-color: var(--ok); color: var(--ok); }
.chip.bad { border-color: var(--red); color: var(--red); }
.chip.flag { width: 32px; height: 32px; padding: 0; justify-content: center; }
.pill, .crd-d { border-radius: 0; background: transparent; border: 1px solid var(--line-strong); color: var(--text); font-weight: 400; }

/* ---------- the ROYAL badge (board 5.5): a plain blue block, the word only ---------- */
.royal-badge { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; box-sizing: border-box; background: var(--royal); color: #fff;
  font-family: var(--mono); font-weight: 700; text-transform: uppercase; letter-spacing: 0.14em; white-space: nowrap;
  height: 28px; padding: 2px 8px 0 11px; font-size: 13px; line-height: 16px; }
.royal-badge.md { height: 18px; padding: 2px 6px 0 7px; font-size: 10px; line-height: 12px; }
.royal-badge.sm { height: 12px; padding: 0 4px 0 6px; font-size: 8px; line-height: 10px; }

/* ---------- kit layout (05-kit.css moved these properties here on purpose: a page may still refine where a
   button/input/icon-button sits, even though their look is locked). ---------- */
.sj-btn { align-items: center; justify-content: center; }
.spin { width: 14px; flex-shrink: 0; }
.em-box { min-width: 0; flex: 0 0 40px; width: 40px; max-width: none; }
.ib { align-items: center; justify-content: center; flex-shrink: 0; margin: 0; }
.em-dash { width: 10px; flex-shrink: 0; }

/* ---------- the gem with text (board 5.6): SVG sized to its box (496:478), centered on the line box ---------- */
.pg-gem, .gem { display: block; flex-shrink: 0; overflow: visible; }
.gem-t { display: inline-flex; align-items: center; gap: 4px; font-variant-numeric: tabular-nums; }
.t-figure .gem-t, .gem-t.lg { gap: 6px; }
.gem-t.sj-pl-v { gap: 8px; } /* the pill menu balance: a 20 px gem */


/* ---------- a tip chip over what was pressed (UI.tip): the landing's Copied!, the simulator's Copy issue ---------- */
.tip { position: absolute; height: 24px; padding: 0 8px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; white-space: nowrap;
  background: var(--text); color: var(--ground); font-family: var(--mono); font-weight: 500; font-size: 13px; line-height: 16px; opacity: 0; visibility: hidden; pointer-events: none; }
.tip.on { visibility: visible; }


}
@layer page {
/* ---------- hub chrome ---------- */
.hd { border-bottom: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; }
.hd nav a { text-decoration: none; font-family: var(--mono); color: var(--muted); }
.hd nav a.on { color: var(--text); }
.ft { margin: 0 auto; display: flex; font-family: var(--mono); color: var(--muted); }
.legal p, .legal li { color: var(--text); }
.legal a { color: var(--text); }
.sess.warn, .flag { color: var(--red); }

/* ---------- Royal (royal branch; functional only, wave 2 restyles). Uses the foundation's .royal-badge, .pg-pay and .card. ---------- */
.pg-royal-pin { display: flex; align-items: flex-start; gap: 10px; margin-top: 8px; padding: 12px 14px; font-size: 14px; line-height: 20px; }
.pg-royal-pin b { font-weight: 500; }
.pg-sup:has(.pg-royal-pin) .pg-sup-s { padding-inline-start: 0; }
.sup-dot { display: inline-block; background: var(--red); } /* Paused: the red indicator */
.sup-red { color: var(--red); }
.sup-spin { display: inline-block; vertical-align: -2px; margin-inline-end: 6px; }

/* ---------- Connect your X in games (web/ui.js postPaste connect states). Board: Sign-in · Connect your X · *.
   Per-screen rules after the Direction A block: tokens only, square corners, 1 px lines. ---------- */
.xg-rows { display: flex; flex-direction: column; gap: 10px; padding-top: var(--sp-4); border-top: 1px solid var(--line); }
.xg-row { display: flex; justify-content: space-between; gap: var(--sp-3); font-family: var(--mono); font-size: 14px; line-height: 20px; color: var(--muted); }
.xg-k { min-width: 0; overflow-wrap: anywhere; }
.xg-v { flex-shrink: 0; }
.xg-v.on { color: var(--text); }
.xg-prog { display: flex; flex-direction: column; gap: var(--sp-2); }
.xg-bar { display: block; height: 4px; background: var(--line); }
.xg-fill { display: block; height: 4px; width: 0; background: var(--green); }
.xg-fill[data-n="1"] { width: 10%; } .xg-fill[data-n="2"] { width: 20%; } .xg-fill[data-n="3"] { width: 30%; } .xg-fill[data-n="4"] { width: 40%; } .xg-fill[data-n="5"] { width: 50%; }
.xg-fill[data-n="6"] { width: 60%; } .xg-fill[data-n="7"] { width: 70%; } .xg-fill[data-n="8"] { width: 80%; } .xg-fill[data-n="9"] { width: 90%; } .xg-fill[data-n="10"] { width: 100%; }
.xg-who { display: flex; align-items: center; gap: var(--sp-3); padding-top: var(--sp-4); border-top: 1px solid var(--line); }
.xg-av { width: 32px; height: 32px; flex-shrink: 0; object-fit: cover; background: var(--surface); }
.xg-who-t { display: flex; flex-direction: column; min-width: 0; }
.xg-name { font-family: var(--mono); font-size: 14px; line-height: 20px; font-weight: 400; color: var(--text); overflow-wrap: anywhere; }
.xg-who .sj-mono { font-size: 13px; line-height: 16px; }
.xg-h { font-weight: 400; color: var(--muted); }
/* the popup's last page (id.sojo.gg/x/callback, game flow), no script */
body.xg-done { display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: var(--ground); color: var(--text); text-align: center; }
body.xg-done h1 { font-family: var(--sans); font-weight: 800; font-size: 28px; line-height: 32px; letter-spacing: -0.02em; margin: 0 0 var(--sp-2); }
body.xg-done p { font-family: var(--mono); font-size: 14px; line-height: 20px; color: var(--muted); margin: 0; }

/* ---------- Sojo Ads: the report sheet in the frame (Paper "Ads · Reports"); frame-ui restyles later ---------- */
/* restyled in "Wave 2 · sheets · Ad report" below */


}
@layer page {
/* ============================================================================   Wave 2 · hub (Paper "Hub" and "Account" boards; Style guide 6.3, 6.5, 7.5). sojo.gg pages only.
   ========================================================================================== */
body.hub { display: flex; flex-direction: column; min-height: 100vh; margin: 0; }
.hero h1 { margin: 0; }
.sj-btn.ghost { flex-shrink: 0; }
body.signed-in .only-out { display: none; }
.label { padding-bottom: 8px; }
.row { display: flex; align-items: center; gap: 16px; text-decoration: none; }
.link { border: 0; background: none; padding: 0; }
.link:hover { color: var(--ink); }
.empty { padding: 14px 0; border-bottom: 1px solid var(--hair); margin: 0; font-size: 13px; }
.prof .mono { font-size: 14px; }
.pill { padding: 2px 8px; font-family: var(--mono); font-size: 11px; line-height: 16px; white-space: nowrap; }
.amt { width: 96px; flex-shrink: 0; font-size: 14px; line-height: 20px; }
.bal-n svg { display: block; flex-shrink: 0; }
.sec .label { padding-bottom: 8px; }
.sup { padding: 14px 0; gap: 14px; }
.em-t { display: flex; flex-direction: column; gap: 4px; }
.sj-body > .sj-in { flex: none; } /* a field on its own line (not in .sj-row) keeps its height */
.em-code { display: flex; align-items: center; gap: 8px; }
.em-foot { display: flex; align-items: center; gap: 8px; }
.em-foot .sj-link { font-family: var(--mono); font-size: 13px; line-height: 18px; }
.em-rs:disabled { cursor: default; color: var(--slate); }
.rcpt { cursor: pointer; }
.box-t { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.sess-list { display: flex; flex-direction: column; gap: 2px; padding-top: 8px; }
.ft a { color: var(--slate); text-decoration: none; }
.ft a:hover, .ft a:focus-visible { color: var(--ink); }
.legal h3, .legal h4 { font-size: 16px; font-weight: 500; margin: 24px 0 6px; }
.legal code { font-family: var(--mono); font-size: 13px; padding: 1px 5px; }
.legal table { border-collapse: collapse; margin: 12px 0; font-size: 14px; }
.legal th, .legal td { border-bottom: 1px solid var(--hair); padding: 8px 12px 8px 0; text-align: left; vertical-align: top; }
.legal blockquote { margin: 12px 0; padding-left: 14px; border-left: 3px solid var(--hair); color: var(--slate); }
.legal hr { border: 0; border-top: 1px solid var(--hair); margin: 28px 0; }
.tbl { display: flex; flex-direction: column; font-size: 14px; }
.tr.off { opacity: .55; }
.lookup { white-space: pre-wrap; font-size: 12px; max-height: 420px; overflow: auto; padding: 12px; margin: 8px 0 0; }
.lookup:empty { display: none; }
.tail { display: flex; flex-direction: column; gap: 2px; font-size: 12px; max-height: 480px; overflow: auto; }
.ev { color: var(--slate); }
.steps { margin: 4px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 4px; color: var(--slate); }
.ev.trusted { color: var(--ink); }
/* the shared gutter (header, page, footer, landing): 20 px on phones, 24 px between, a 1200 px column on wide screens.
   Percentages resolve where it's used (full-width blocks), so it's measured inside the scrollbar gutter, never 100vw. */
:root { --gl: max(24px, round(down, (100% - 1200px) / 2, 1px)); --gr: max(24px, round(up, (100% - 1200px) / 2, 1px)); }
.hd { position: relative; z-index: 1; height: 72px; padding: 0 var(--gr) 0 var(--gl); background: var(--ground); }
.hd-brand { display: flex; align-items: center; text-decoration: none; gap: 10px; font-size: 26px; line-height: 32px; letter-spacing: -0.04em; color: var(--text); }
.hd-brand img { width: 28px; height: 28px; }
.hd nav { display: flex; align-items: center; gap: 36px; }
.hd nav a { font-size: 15px; line-height: 18px; font-weight: 400; }
.hd nav a:hover { color: var(--text); }
.hd nav a.on { font-weight: 400; }
.hd-av img { display: block; object-fit: cover; width: 32px; height: 32px; image-rendering: pixelated; }
body.signed-out .in-only { display: none; }
/* 6.5: the dither horizon under the header, the same art flipped as ground at the foot. Static, never behind text. */
.hz { position: relative; z-index: 1; flex-shrink: 0; height: 64px; pointer-events: none; background: url(/art/horizon.png) center bottom / 1320px 160px repeat-x; image-rendering: pixelated; }
.hz.gd { transform: scaleY(-1); margin-top: auto; }
.page { margin: 0 auto; display: flex; flex-direction: column; position: relative; z-index: 1; width: 100%; max-width: 1248px; box-sizing: border-box; flex: 1 0 auto;
  padding: 56px var(--gr) 80px var(--gl); max-width: none; gap: 96px; }
.ft { position: relative; z-index: 1; width: 100%; max-width: none; box-sizing: border-box; padding: 40px var(--gr) 48px var(--gl); gap: 12px; font-size: 13px; line-height: 16px; }
/* footer: 相乗 as a dictionary entry (the logo is 乗), the links at the right of its first line or below it when narrow */
.ft { flex-wrap: wrap; justify-content: space-between; align-items: flex-start; row-gap: 24px; }
.ft-def { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.ft-hw { margin: 0; display: flex; align-items: center; gap: 12px; color: var(--text); font-size: 14px; line-height: 20px; font-weight: 500; }
.ft-mark { display: block; flex-shrink: 0; width: 54px; height: 26px; image-rendering: pixelated; }
.ft-sense { margin: 0; color: var(--muted); }
.ft-l { display: flex; align-items: center; gap: 12px; height: 26px; }
/* social icons: 24 px from Privacy, 16 px apart; each link pads to a 32 px tap target that its negative margin keeps out of the layout */
.ft-so { display: flex; align-items: center; gap: 16px; margin-left: 12px; }
.ft-so a { display: block; padding: 8px; margin: -8px; }
.ft-so svg { display: block; }
/* 6.3: the background canvas. Under everything at rest; over the page only while the page wave dissolves it. */
canvas.bg { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
canvas.bg.top { z-index: 2147483000; }
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 160ms; animation-timing-function: ease-out; }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } canvas.bg { display: none; } }
/* bgfix: the header never moves or flashes on a page change: its own snapshot, the new one shown at once, never crossfaded. */
.hd { view-transition-name: sojo-hd; }
::view-transition-group(sojo-hd), ::view-transition-new(sojo-hd) { animation: none; }
::view-transition-old(sojo-hd) { display: none; }
/* adsshell: signed-out-only content (the home hero) never paints for a visitor the last visit knew (web/hd.ts), nor
   while a cookieless page waits for /v1/me. */
html.hd-in .only-out { display: none; }
html.hd-wait .only-out { visibility: hidden; }
/* No width shift between a page with a scrollbar and one without: the gutter is always kept (sojo.gg pages only, never
   the frame, /pay or /connect). scrollbar-gutter alone isn't kept on the root in Chrome, so overflow-y: scroll keeps it;
   the track is transparent (the gutter shows the ground) and only a quiet thumb shows on a long page. */
html[data-hub] { overflow-y: scroll; scrollbar-gutter: stable; scrollbar-color: var(--line-strong) transparent; }

/* home */
.hero { display: flex; flex-direction: column; align-items: flex-start; gap: 28px; padding: 0; }
.hero h1, .hub .hero .t-display { font-family: var(--sans); font-size: 96px; line-height: 92px; letter-spacing: -0.04em; }
.hero p { margin: 0; font-size: 15px; line-height: 22px; }
.block { display: flex; flex-direction: column; gap: 8px; max-width: 640px; }
.block.wide { max-width: none; }
.block > .label, .sec > .label, .kick { display: flex; align-items: center; gap: 10px; padding-bottom: 0; min-height: 32px; }
.block > .label::before, .sec > .label::before, .kick::before { content: "\250C\2500"; color: var(--ok); letter-spacing: 0; }
.block > .label::after, .sec > .label::after, .kick::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.sec > .label:has(+ .card)::after { display: none; } /* a card under a label: its border is the one line */
.game-row { height: 64px; justify-content: space-between; color: var(--text); font-size: 15px; line-height: 18px; }
.game-row .dim { font-size: 13px; line-height: 16px; }
@media (max-width: 600px) { .hero h1 { font-size: 56px; line-height: 56px; } .page { gap: 64px; padding-top: 40px; } }
@media (max-width: 600px) { :root { --gl: 20px; --gr: 20px; } }
/* nav links: a 44 px tall hit area, same look */
.hd nav a { padding: 13px 0; margin: -13px 0; }
@media (max-width: 600px) { .hd-brand { font-size: 22px; gap: 8px; } .hd-brand img { width: 24px; height: 24px; } .hd nav { gap: 12px; } .hd nav a { font-size: 14px; white-space: nowrap; }
  .hd nav:has(.hd-av:not([hidden])) > a[href="/account"]:not(.hd-av) { display: none; } /* the avatar is the Account link */ }

/* account */
.prof-top { display: flex; justify-content: space-between; flex-wrap: wrap; align-items: center; gap: 32px; }
.prof { display: flex; align-items: center; gap: 32px; min-width: 0; }
.prof-av { object-fit: cover; flex-shrink: 0; width: 120px; height: 120px; image-rendering: pixelated; background: var(--surface); }
.prof-n { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.prof-h { overflow-wrap: anywhere; margin: 0; font-size: 64px; line-height: 72px; letter-spacing: -0.04em; }
.prof-s { margin-top: 8px; font-size: 15px; line-height: 20px; }
/* the card grows to fit its row (gem, number, Top up); narrow screens wrap Top up under the number */
.bal { width: auto; min-width: 420px; max-width: 100%; box-sizing: border-box; padding: 28px; display: flex; flex-direction: column; align-items: stretch; gap: 12px; }
.bal-r { display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap; row-gap: 16px; }
.bal-n { display: flex; align-items: center; gap: 12px; font-family: var(--sans); font-size: 56px; line-height: 60px; font-weight: 800; letter-spacing: -0.04em; color: var(--text); }
.bal .sj-btn { flex-shrink: 0; }
.cols { display: flex; align-items: flex-start; gap: 96px; }
.col { display: flex; flex-direction: column; min-width: 0; flex: 0 0 520px; gap: 48px; }
.col.wide { flex: 1; gap: 0; }
.sec { display: flex; flex-direction: column; gap: 8px; padding-bottom: 0; }
.rbox { padding: 28px; display: flex; flex-direction: column; gap: 12px; }
.rbox-h { display: flex; align-items: center; gap: 14px; min-height: 28px; flex-wrap: wrap; }
.rbox-h b { font-weight: 500; color: var(--text); }
.rbox-h .grow { flex: 1; }
.rbox-l { display: flex; flex-direction: column; gap: 4px; font-size: 15px; line-height: 24px; }
.rbox-l .first { color: var(--text); }
.rbox-a { display: flex; align-items: center; gap: 20px; }
.rbox-a .link.quiet, .rbox-h .link.quiet { font-size: 15px; }
.sup-dot { width: 8px; height: 8px; margin: 0; flex-shrink: 0; }
.crd { height: 64px; gap: 16px; }
.crd .pg-badge { flex: 0 0 38px; height: 22px; display: flex; align-items: center; justify-content: center; font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: 0.04em; color: #fff; background: var(--line-strong); }
.crd .pg-badge.visa { background: #1A1F71; }
.crd-n { flex-shrink: 0; line-height: 21px; width: 130px; font-size: 15px; font-weight: 400; }
.crd-e { white-space: nowrap; flex: 1; font-size: 15px; }
.crd-d { font-family: var(--mono); line-height: 17px; height: 22px; padding: 0 8px; display: inline-flex; align-items: center; font-size: 12px; border-color: var(--ok);
  color: var(--ok); }
.rm { text-align: right; flex-shrink: 0; min-width: 64px; font-size: 15px; }
.sv { display: flex; align-items: center; justify-content: space-between; padding-top: 16px; }
.sv-s { line-height: 17px; font-size: 13px; }
.emr { height: 64px; display: flex; align-items: center; gap: 16px; border-bottom: 1px solid var(--line); font-size: 15px; }
.emr .at { width: 36px; flex-shrink: 0; color: var(--muted); }
.emr .grow { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.emr .chip { height: 22px; font-size: 12px; }
.em-note { padding-top: 16px; font-size: 13px; line-height: 16px; }
.emcard { padding: 28px; display: grid; gap: 16px; flex-shrink: 0; min-height: min-content; }
.emcard > * { min-width: 0; }
.emcard .em-t .sj-title { font-size: 20px; line-height: 28px; }
.emcard > .sj-btn { justify-self: start; }
.emcard .em-code { gap: 8px; }
.buy { height: 64px; gap: 24px; font-size: 15px; line-height: 20px; color: var(--text); }
.buy .date { flex-shrink: 0; width: 72px; font-size: 15px; }
.buy .row-main { line-height: 20px; font-size: 15px; font-weight: 400; }
.buy .gm { width: 130px; flex-shrink: 0; font-size: 13px; }
.buy .amt { width: auto; min-width: 72px; display: flex; justify-content: flex-end; font-size: 15px; }
.rcpt:hover .row-main { color: var(--deep); text-decoration: underline; text-underline-offset: 3px; }
.sec-foot { padding-top: 24px; font-size: 13px; line-height: 16px; }
.buy-list.clip { overflow: hidden; }
.pager { display: flex; align-items: center; justify-content: space-between; gap: 16px; height: 64px; border-bottom: 1px solid var(--line); }
.pager-r { font-size: 13px; line-height: 16px; }
.pager-b { display: flex; gap: 8px; margin-right: -12px; }
.pager .sj-btn[aria-disabled="true"] { opacity: .4; cursor: default; }
.box { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 32px; }
.box-title { font-size: 17px; line-height: 24px; }
.box .mono { font-size: 15px; }
.sess { font-size: 13px !important; }
.foot { display: flex; align-items: center; justify-content: space-between; border-top: 0; padding: 0; font-size: 15px; }
.foot .link.quiet { color: var(--text); font-size: 15px; }
.foot .small { font-size: 15px; }
@media (max-width: 1100px) { .col { flex: 0 0 440px; } .cols { gap: 56px; } }
@media (max-width: 860px) { .prof-h { font-size: 40px; line-height: 44px; } .prof-av { width: 80px; height: 80px; } .bal { width: 100%; min-width: 0; }
  .buy .gm { display: none; } .bal-n { font-size: 44px; line-height: 48px; } .cols { flex-direction: column; } .col { width: 100%; }
  .box { flex-direction: column; align-items: flex-start; } .tr > :nth-child(n+5):not(:last-child) { display: none; } }

/* admin: a readable lookup card; .stat* also serve web/dev.ts */
.stats { flex-wrap: wrap; display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.stat { display: flex; flex-direction: column-reverse; gap: 8px; }
.stat .label { font-size: 13px; letter-spacing: 0; text-transform: none; font-weight: 400; }
.stat-n { font-family: var(--sans); font-size: 44px; line-height: 48px; font-weight: 800; letter-spacing: -0.04em; color: var(--text); }
.lk { padding: 24px; display: flex; flex-direction: column; margin-top: 12px; }
.lk-h { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; padding-bottom: 12px; }
.lk-h b { font-family: var(--sans); font-size: 28px; line-height: 32px; font-weight: 800; letter-spacing: -0.02em; overflow-wrap: anywhere; }
.lk-r { display: grid; grid-template-columns: 110px 1fr auto; gap: 12px; align-items: start; padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 14px; line-height: 20px; }
.lk-r > :first-child { color: var(--muted); }
.lk-r > :last-child { color: var(--muted); text-align: right; }
.lk-v { display: flex; flex-direction: column; min-width: 0; overflow-wrap: anywhere; }
.lk-m { padding-top: 12px; }
.adm-links { display: flex; gap: 24px; }
.tr { display: grid; gap: 12px; align-items: center; grid-template-columns: 2.2fr 1fr 1fr 1fr 1fr 1fr 1.4fr .8fr; }
.tr .num { text-align: right; }
.stats.adm-sum { grid-template-columns: repeat(8, 1fr); }
.aa-tabs { overflow-x: auto; scrollbar-width: none; } /* /admin/ads tabs scroll in their own row at 390 */
.aa-tab { flex-shrink: 0; }
.adm-sum .stat-n { font-size: 32px; line-height: 40px; }
.adm-test { margin: 0; font-size: 13px; line-height: 16px; padding-top: 8px; }
@media (max-width: 1100px) { .stats.adm-sum { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 860px) { .stats, .stats.adm-sum { grid-template-columns: 1fr 1fr; } }

/* admin: sign-in funnel */
.sf-tabs { display: flex; gap: 16px; }
.sf-tabs .link.on { color: var(--text); }
.sf-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.sf-col { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.sf-tbl .tr { grid-template-columns: 1fr auto auto; gap: 12px; font-size: 13px; }
.sf-bails, .sf-wrong, .sf-cost, .sf-past { margin: 0; font-size: 13px; line-height: 20px; }
.sf-cost { padding-top: 4px; }
.sf-past { padding-top: 4px; }
@media (max-width: 860px) { .sf-cols { grid-template-columns: 1fr; } }

/* legal */
.legal { max-width: 720px; font-size: 15px; line-height: 24px; }
.legal h1 { font-size: 64px; line-height: 68px; letter-spacing: -0.04em; margin: 0 0 24px; }
.legal h2 { margin: 48px 0 12px; }

/* /connect and /pay on id.sojo.gg: ground, the sheet centered, square */
body.popup .sj-ov.sj-page { background: var(--ground); }
.pp-card { padding: 28px; }
.pp-cti { font-family: var(--sans); font-weight: 800; font-size: 24px; line-height: 32px; letter-spacing: -0.02em; }
.pp-handle, .pp-gems, .pp-p { font-family: var(--mono); font-weight: 400; }
.pp-h { font-size: 64px; line-height: 68px; letter-spacing: -0.04em; }
.pp-sub { font-size: 15px; line-height: 22px; }
.pp-brand { font-size: 26px; line-height: 32px; letter-spacing: -0.04em; }
.pp-brand img { width: 28px; height: 28px; }
.emcard.in > * { animation: hub-in 200ms ease-out; }
@keyframes hub-in { from { opacity: 0; } to { opacity: 1; } }
.kick-s { margin-left: 8px; }
@media (prefers-reduced-motion: reduce) { .emcard.in > * { animation: none; } }

/* Connect popup (id.sojo.gg/connect), Hub board "Connect popup": corner mark, "Sign in to <game>", game icon */
.cn-hd { gap: 12px; }
.cn-t { display: flex; align-items: center; gap: 10px; min-width: 0; font-family: var(--mono); font-size: 15px; color: var(--text); }
.cn-t span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cn-mk { width: 12px; height: 12px; flex-shrink: 0; margin-top: 6px; border-left: 2px solid var(--green); border-top: 2px solid var(--green); }
.cn-r { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.cn-ic { width: 20px; height: 20px; border-radius: 0; object-fit: cover; image-rendering: pixelated; }
.cn-av { width: 48px; height: 48px; border-radius: 0; flex-shrink: 0; object-fit: cover; image-rendering: pixelated; background: var(--line); }
.cn-h { font-family: var(--mono); font-size: 15px; color: var(--text); }
.cn-not { align-self: flex-start; }

}
@layer page {
/* ---------- Wave 2 · ads buy (web/ads-buy.ts: sojo.gg/ads and /ads/new; Paper "Ads · Buy"). Tokens only, square, 1 px lines. ---------- */
.ab-hero { display: grid; grid-template-columns: minmax(0, 560px) minmax(0, 560px); justify-content: space-between; gap: var(--sp-10); align-items: center; }
.ab-hero-t { display: flex; flex-direction: column; gap: var(--sp-4); align-items: flex-start; }
.ab-from { display: flex; align-items: baseline; gap: var(--sp-2); }
.ab-cta { display: flex; gap: var(--sp-3); align-items: center; margin-top: var(--sp-2); }
.ab-art { position: relative; width: 100%; aspect-ratio: 7 / 6; border: 1px solid var(--line); background: var(--surface); overflow: hidden; }
.ab-wall { display: block; width: 100%; height: 100%; object-fit: cover; image-rendering: pixelated; }
.ab-sp { position: absolute; left: var(--sp-4); bottom: var(--sp-4); background: var(--surface); height: 22px; font-size: 12px; }
.ab-game { gap: var(--sp-6); }
.ab-game-t { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: var(--sp-3) 0; }
.ab-game-f { display: flex; flex-direction: column; gap: 2px; width: 160px; }
.ab-soon { color: var(--muted); }
.ab-note { margin-top: var(--sp-2); }
.ab-signin { display: flex; flex-direction: column; gap: var(--sp-3); align-items: flex-start; max-width: 448px; padding: var(--sp-6) 0; }

.ab-flow { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: var(--sp-12); align-items: start; }
.ab-side { position: sticky; top: var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-2); }
.ab-rail { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.ab-st { display: flex; align-items: center; gap: var(--sp-3); height: 40px; font-family: var(--mono); font-size: 14px; color: var(--muted); }
.ab-st.go { cursor: pointer; }
.ab-st.go:hover, .ab-st.ok { color: var(--text); }
.ab-st.on { color: var(--text); font-weight: 500; }
.ab-n { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: 1px solid var(--line-strong); font-size: 12px; flex-shrink: 0; }
.ab-st.on .ab-n { border-color: var(--text); background: var(--text); color: var(--ground); }
.ab-st.ok .ab-n { border-color: var(--text); }
.ab-body { min-width: 0; }
.ab-step { display: flex; flex-direction: column; gap: var(--sp-3); max-width: 640px; }
.ab-of { padding-bottom: 0; }
.ab-lead { margin: 0 0 var(--sp-4); }
.ab-kids { display: flex; flex-direction: column; gap: var(--sp-5); }
.ab-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); margin-top: var(--sp-6); padding-top: var(--sp-5); border-top: 1px solid var(--line); }
.ab-foot-r { display: flex; align-items: center; gap: var(--sp-4); }
.ab-top { display: flex; align-items: center; justify-content: space-between; min-height: 16px; }
.ab-top .sj-back { height: 36px; margin: -10px -12px -10px 0; } /* the one Back (UI.head look): top right, 36 px hit area */
.ab-f { display: flex; flex-direction: column; gap: var(--sp-2); }
.ab-fl { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); }
.ab-fl .label { padding-bottom: 0; }
.ab-count, .ab-fn { font-size: 12px; line-height: 16px; }
.ab-two { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.ab-sel { appearance: auto; width: 100%; }
.ab-f .sj-in { flex: none; width: 100%; box-sizing: border-box; } /* 01-sheet.css gives .sj-in flex: 1, which collapses it in a column */
.ab-tick { display: flex; align-items: flex-start; gap: var(--sp-3); cursor: pointer; }
.ab-tick-t { display: flex; flex-direction: column; gap: 2px; }
.ab-check { width: 18px; height: 18px; margin: 2px 0 0; accent-color: var(--text); flex-shrink: 0; }
.ab-biz { display: flex; flex-direction: column; gap: var(--sp-4); padding: var(--sp-5); border: 1px solid var(--line); background: var(--surface); }
.ab-biz[hidden] { display: none; }
.ab-sec { display: flex; flex-direction: column; gap: var(--sp-3); }

.ab-ad { display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: var(--sp-6); align-items: start; }
.ab-ad-img { display: flex; flex-direction: column; gap: var(--sp-2); }
.ab-ad-f { display: flex; flex-direction: column; gap: var(--sp-5); }
.ab-file { display: none; }
.ab-drop { width: 100%; aspect-ratio: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-2); padding: var(--sp-4); border: 1px dashed var(--line-strong); background: var(--surface); color: var(--text); cursor: pointer; text-align: center; }
.ab-drop:hover { border-color: var(--text); }
.ab-crop { position: relative; width: 100%; aspect-ratio: 1; background: var(--surface); border: 1px solid var(--line); overflow: hidden; touch-action: none; }
.ab-crop img { position: absolute; user-select: none; pointer-events: none; }
.ab-sq { position: absolute; box-sizing: border-box; border: 1px solid var(--text); outline: 2000px solid color-mix(in srgb, var(--ground) 60%, transparent); cursor: move; }
.ab-crop-b { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-top: var(--sp-2); }
.ab-checked { margin-top: var(--sp-2); }

.ab-tool { min-height: 320px; }
.ab-frame { display: block; width: 100%; height: 520px; border: 1px solid var(--line); background: var(--surface); }
/* Where it runs: the ad in its format, with Edit. The format editor sheet: size tabs, the grid, the colors. */
.ab-fp { display: flex; align-items: center; gap: var(--sp-4); }
.ab-fp-cv { display: block; width: 80px; height: 80px; flex-shrink: 0; image-rendering: pixelated; border: 1px solid var(--line); }
.ab-fp-t { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.ab-wide .sj-card { max-width: 720px; }
.ab-sz { display: flex; gap: var(--sp-2); }
.ab-sz .chip { cursor: pointer; }
.ab-sz .chip.on { border-color: var(--text); }
.ab-grid-w { display: flex; justify-content: center; }
.ab-grid { display: block; width: 100%; max-width: 384px; height: auto; aspect-ratio: 1; image-rendering: pixelated; border: 1px solid var(--line); touch-action: none; cursor: crosshair; }
.ab-sw { display: grid; grid-template-columns: repeat(8, 1fr); gap: var(--sp-1); }
.ab-sw-c { height: 28px; padding: 0; border: 1px solid var(--line); border-radius: 0; cursor: pointer; }
.ab-sw-c.on { outline: 1px solid var(--text); outline-offset: 1px; }
.sj-body > .ab-rep-l { align-self: flex-end; font-size: 13px; line-height: 18px; }
.ab-rep-in { height: auto; padding: 10px 14px; resize: vertical; }
.ab-tool-x { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-3); padding: var(--sp-6); border: 1px solid var(--line); }
.ab-px { display: block; image-rendering: pixelated; border: 1px solid var(--line); }
.ab-px.lg { width: 192px; height: 192px; }

.ab-games { display: flex; flex-direction: column; }
.ab-g { gap: var(--sp-3); }
.ab-box { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border: 1px solid var(--line-strong); font-size: 12px; flex-shrink: 0; }
.ab-g.on .ab-box { border-color: var(--text); }
.ab-opts { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.ab-opt { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: var(--sp-3) var(--sp-4); border: 1px solid var(--line); background: var(--surface); color: var(--text); cursor: pointer; text-align: left; }
.ab-opt.on { border-color: var(--text); box-shadow: inset 0 0 0 1px var(--text); }
.ab-area { display: flex; flex-direction: column; gap: var(--sp-3); }
.ab-map { position: relative; width: 100%; max-width: 440px; aspect-ratio: 1; border: 1px solid var(--line); background: var(--surface); }
.ab-plot { position: absolute; box-sizing: border-box; padding: 0; border: 1px solid var(--line-strong); background: transparent; cursor: pointer; }
.ab-plot.on { background: var(--text); border-color: var(--text); box-shadow: inset 0 0 0 2px var(--surface); }
.ab-plot:hover, .ab-plot:focus-visible { outline: 1px solid var(--text); outline-offset: 2px; }
.ab-hover { min-height: 20px; }
.ab-cap { display: flex; justify-content: space-between; max-width: 440px; }
.ab-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.ab-large { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-5); border: 1px solid var(--line); background: var(--surface); }
.ab-lines { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-1); }
.ab-lines li::before { content: "\2500\00a0"; color: var(--muted); }

.ab-stp { display: flex; gap: var(--sp-2); max-width: 320px; }
.ab-stp-btn { width: 40px; height: 40px; }
.ab-num { flex: 1; min-width: 0; text-align: center; font-variant-numeric: tabular-nums; }
.ab-est { display: flex; flex-direction: column; gap: var(--sp-1); padding: var(--sp-5); border: 1px solid var(--line); background: var(--surface); }
.ab-est .label { padding-bottom: 0; }
.ab-floor { display: flex; align-items: center; gap: var(--sp-2); color: var(--red); }
.ab-floor:empty { display: none; }
.ab-bang { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border: 1px solid var(--red); font-family: var(--mono); font-size: 12px; }

.ab-card { display: flex; align-items: center; gap: var(--sp-3); min-height: 56px; padding: 0 var(--sp-4); border: 1px solid var(--line); background: var(--surface); }
.ab-tag { display: inline-flex; align-items: center; height: 20px; padding: 0 6px; border: 1px solid var(--line-strong); font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: 0.08em; }
.ab-cardv { display: inline-flex; align-items: center; gap: var(--sp-2); }
.ab-sr { justify-content: space-between; }
.ab-sr.due { border-bottom: 0; }
.ab-sum { gap: var(--sp-4); padding: var(--sp-3) 0; }
.ab-sum-t { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ab-thumb { width: 48px; height: 48px; image-rendering: pixelated; border: 1px solid var(--line); flex-shrink: 0; }
.ab-bill { display: flex; flex-direction: column; }

.ab-res { display: flex; flex-direction: column; gap: var(--sp-3); align-items: flex-start; max-width: 560px; }
.ab-res .ab-sec { width: 100%; margin: var(--sp-3) 0; }
.ab-ck { gap: var(--sp-3); padding: var(--sp-3) 0; }
.ab-ck-t { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ab-mk { width: 16px; text-align: center; font-family: var(--mono); color: var(--ok); }
.ab-ck.bad .ab-mk { color: var(--red); }
.ab-live { position: relative; margin: var(--sp-3) 0; }
.ab-live .ab-sp { position: static; margin-top: var(--sp-2); }
.ab-acts { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.ab-note-in { height: auto; min-height: 80px; padding: var(--sp-2) 14px; resize: vertical; font-family: var(--mono); width: 100%; box-sizing: border-box; }

@media (max-width: 860px) {
  .ab-hero { grid-template-columns: 1fr; }
  .ab-flow { grid-template-columns: 1fr; gap: var(--sp-4); }
  .ab-side { display: none; }
  .ab-ad { grid-template-columns: 1fr; }
}
@media (max-width: 480px) {
  .ab-two, .ab-opts { grid-template-columns: 1fr; }
  .ab-game { flex-wrap: wrap; gap: var(--sp-2); }
  .ab-game-f { width: auto; }
  .ab-foot { flex-wrap: wrap; }
  .ab-foot-r { flex-direction: column-reverse; align-items: stretch; width: 100%; }
  .ab-foot-r .sj-btn { width: 100%; }
  .ab-frame { height: 480px; }
}

}
@layer page {
/* ---------- Wave 2 · sheets (in-game sheets, Paper Payments / Gems / Royal / Sign-in / Ads · Reports).
   Per-screen rules after the Direction A block: tokens only, square corners, 1 px lines. ---------- */
.pg .sj-card { background: var(--ground); border-color: var(--line-strong); }
.pg .sj-body { padding: 24px; gap: 12px; }
.pg-hd { height: 24px; }
.pg-hd-l { display: flex; align-items: center; gap: 10px; min-width: 0; }
.pg-kick { font-family: var(--mono); font-size: 15px; line-height: 19px; color: var(--green); }
[dir="rtl"] .pg-kick { display: inline-block; transform: scaleX(-1); }
.pg-bonus { direction: ltr; unicode-bidi: isolate; }
.pg-hd-t { font-family: var(--mono); font-size: 17px; line-height: 20px; font-weight: 500; color: var(--text); overflow-wrap: anywhere; }
.pg-hd .sj-x { width: 24px; height: 24px; margin-inline-end: -4px; padding: 0; }
.pg-hd .sj-x svg { width: 12px; height: 12px; }
/* Store packs (board Gems · Store): surface, 1 px line; the selected one a green line on a faint green */
.pg-grid { gap: 8px; }
.pg-pack { background: var(--surface); box-shadow: inset 0 0 0 1px var(--line); padding: 14px; gap: 10px; }
.pg-pack.on { background: rgb(139 240 160 / 7%); box-shadow: inset 0 0 0 1px var(--green); cursor: pointer; }
.pg-pack-g { font-family: var(--mono); font-size: 20px; line-height: 24px; font-weight: 700; gap: 4px; }
.pg-pack-g .pg-gem { width: 20px; height: 19px; }
.pg-pack-b { height: 28px; }
.pg-pack .pg-bonus { padding: 0; border: 0; background: none; font-size: 12px; line-height: 16px; font-weight: 400; color: var(--muted); }
.pg-pack.on .pg-bonus { border: 0; background: none; color: var(--ok); }
.pg-pack .pg-price { font-size: 14px; line-height: 18px; font-weight: 400; color: var(--muted); }
.pg-pack.on .pg-price { color: var(--text); }
/* store controls: tapping a pack adds one; only the picked one shows − count at its bottom right (× at 1), fading in
   over space the pack always keeps. 28 px squares, 1 px lines, neutral (green stays on Pay). No hover states; a press
   shows a 2 px inset line while held. The numbers roll (SojoUI.roll). */
.pg-pack.down { box-shadow: inset 0 0 0 2px var(--line-strong); }
.pg-pack.on.down { box-shadow: inset 0 0 0 2px var(--green); }
.pg-pack[aria-disabled="true"] { cursor: default; }
.pg-pack:focus-visible { outline: 1px solid var(--text); outline-offset: 2px; }
.pg-cell { position: relative; display: flex; flex-direction: column; min-width: 0; }
.pg-cell > .pg-pack { flex: 1 1 auto; }
.pg-st { position: absolute; inset-inline-end: 14px; bottom: 14px; display: flex; align-items: center; opacity: 0; visibility: hidden; transition: opacity 120ms ease-out, visibility 0s linear 120ms; }
.pg-pack.on + .pg-st { opacity: 1; visibility: visible; transition: opacity 120ms ease-out, visibility 0s; }
.pg-st-b { position: relative; display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: 1px solid var(--line-strong); border-radius: 0; background: transparent; color: var(--text); cursor: pointer; }
.pg-st-b:focus-visible { outline: 1px solid var(--text); outline-offset: 2px; z-index: 1; }
.pg-st-i { display: block; position: absolute; inset-inline-start: 8px; top: 8px; transition: opacity 120ms ease-out; }
.pg-st-rm, .pg-pack.one + .pg-st .pg-st-less { opacity: 0; }
.pg-pack.one + .pg-st .pg-st-rm { opacity: 1; }
.pg-st-n { display: flex; align-items: center; justify-content: center; width: 26px; height: 28px; border: 1px solid var(--line-strong); border-inline-start: 0; font-family: var(--mono); font-size: 13px; line-height: 26px; font-weight: 500; color: var(--text); }
/* the fee line keeps its line box when empty (no pack), so its old text fades where it was */
.pg-foot .pg-q.pg-fee { min-height: 18px; }
@media (max-width: 420px) { .pg-pack .pg-price { font-size: 13px; } .pg-st-n { width: 22px; } }
@media (prefers-reduced-motion: reduce) { .pg-st, .pg-pack.on + .pg-st, .pg-st-i { transition: none; } }
/* the saved card row and Change */
.pg-crow { gap: 12px; height: 44px; padding: 0 12px; background: transparent; border: 1px solid var(--line); }
.pg-crow-n { font-size: 14px; line-height: 18px; font-weight: 400; }
.pg-crow-c { font-family: var(--mono); font-size: 14px; line-height: 18px; font-weight: 400; color: var(--muted); text-decoration: none; }
.pg-crow-c:hover { color: var(--text); }
/* footer: the extras line at left, Pay at right */
/* a fee part too wide to sit beside the button (its words are held together) takes its own line; the button stays at the end */
.pg-foot { flex-wrap: wrap; justify-content: space-between; gap: 8px 12px; margin-top: 4px; }
.pg-foot > :last-child { margin-inline-start: auto; }
.pg-fee { flex: 1 1 0; min-width: min-content; word-break: keep-all; padding: 0; font-size: 13px; line-height: 18px; font-weight: 400; color: var(--muted); }
.pg-foot .pg-pay { flex: 0 0 auto; min-width: 168px; }
.pg-eu { padding: 0; text-align: start; font-size: 13px; line-height: 18px; font-weight: 400; color: var(--muted); }
/* Choose a card (board Pay · Choose a card): 44 rows, the current one a green line, expiry at right; Add a card dashed */
.pg-cc-list { gap: 8px; }
.pg-cc { min-height: 44px; height: 44px; padding: 0 12px; gap: 12px; background: transparent; box-shadow: inset 0 0 0 1px var(--line); }
.pg-cc.on { background: rgb(139 240 160 / 7%); box-shadow: inset 0 0 0 1px var(--green); }
.pg-cc:focus-visible { outline: 1px solid var(--text); outline-offset: 2px; }
.pg-cc .pg-badge { width: 34px; height: 20px; font-size: 9px; }
.pg-cc-n { font-size: 14px; line-height: 18px; font-weight: 400; color: var(--text); }
.pg-cc-e { margin-inline-start: auto; font-size: 14px; line-height: 18px; font-weight: 400; color: var(--muted); }
.pg-cc.on .pg-cc-e { color: var(--ok); }
.pg-cc-add { box-shadow: none; border: 1px dashed var(--line-strong); }
.pg-cc-add:hover { box-shadow: none; border-color: var(--muted); }
.pg-cc-add .pg-cc-n { color: var(--text); text-decoration: none; }
.pg-cc-plus { width: 34px; height: 20px; border: 1px solid var(--line-strong); background: transparent; color: var(--text); font-family: var(--mono); font-size: 14px; line-height: 18px; }

/* ---------- Wave 2 · sheets · Sign-in (Paper Sign-in: Guest verify 1 · Post it, 2 · Connect your X and its states, Pop-up blocked).
   web/ui.js postPaste adds .si to the sheet root. Title row is the shared .pg-hd; the Connect states reuse the xg- block above. ---------- */
.si .sj-card { background: var(--ground); border-color: var(--line-strong); }
.si .sj-body { gap: 16px; }
.si-steps { display: flex; gap: 16px; }
.si-step { border: 0; background: none; padding: 0; font-family: var(--mono); font-size: 13px; line-height: 16px; font-weight: 400; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); cursor: default; }
.si-step:disabled { opacity: 1; }
.si-step.on { color: var(--text); }
.si-p { font-family: var(--mono); font-size: 14px; line-height: 20px; font-weight: 400; color: var(--text); overflow-wrap: anywhere; }
.si-p.si-m { color: var(--muted); }
.si .si-note { font-size: 14px; line-height: 20px; }
/* The found-post step's preview (px.foundTitle): the player's own post, shown only to them, plain text, about 2
   lines, never a link. */
.px-preview { font-size: 14px; line-height: 20px; color: var(--muted); overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.si .sj-legal { text-align: start; margin-top: -8px; }
.si .sj-body > .sj-link { align-self: flex-start; text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 3px; }
.si .sj-body > .sj-link:hover { text-decoration-color: var(--text); }

/* ---------- Wave 2 · sheets · Ad report (Paper Ads · Reports 22, 22b, 22c; web/frame.ts adReport). Uses .si from Sign-in. ---------- */
.si .sj-body:has(> .rp-t) { gap: 14px; }
.rp-t { min-height: 22px; }
.rp-line { display: flex; align-items: center; gap: 12px; min-width: 0; }
.rp-th { width: 36px; height: 36px; flex-shrink: 0; object-fit: cover; image-rendering: pixelated; background: var(--surface); }
.rp-lbl { flex: 1; min-width: 0; font-family: var(--mono); font-size: 13px; line-height: 18px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rp-line .rp-whyl { flex-shrink: 0; font-size: 13px; line-height: 18px; text-decoration: underline; text-decoration-color: currentColor; text-underline-offset: 3px; }
.ch-rs { display: flex; flex-direction: column; border: 1px solid var(--line); }
.ch-r { display: flex; align-items: center; gap: 12px; height: 36px; padding: 0 14px; border: 0; border-top: 1px solid var(--line); background: transparent; color: var(--muted); font-family: var(--mono); font-size: 14px; line-height: 20px; font-weight: 400; text-align: start; cursor: pointer; }
.ch-r:first-child { border-top: 0; }
.ch-r:hover { color: var(--text); }
.ch-r.on { background: var(--surface); color: var(--text); font-weight: 500; }
.ch-r:focus-visible { outline: 1px solid var(--text); outline-offset: -1px; }
.ch-box { display: flex; align-items: center; justify-content: center; width: 14px; height: 14px; flex-shrink: 0; border: 1px solid var(--line-strong); }
.ch-box::after { content: ""; width: 6px; height: 6px; background: var(--text); opacity: 0; }
.ch-r.on .ch-box { border-color: var(--text); }
.ch-r.on .ch-box::after { opacity: 1; }
.rp-fs { display: flex; flex-direction: column; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.rp-f { display: flex; justify-content: space-between; align-items: center; gap: 12px; height: 40px; }
.rp-f + .rp-f { border-top: 1px solid var(--line); }
.rp-fk { font-family: var(--mono); font-size: 13px; line-height: 18px; color: var(--muted); }
.rp-fv { font-family: var(--mono); font-size: 14px; line-height: 20px; font-weight: 500; color: var(--text); overflow-wrap: anywhere; text-align: end; }
.si .rp-n { font-size: 13px; line-height: 18px; }
/* Paste the link: Verify keeps one width while it reads "Checking…", so the label cross-fades in place */
.si .sj-row .sj-btn.sm { flex: 0 0 auto; width: 176px; }
.sj-paste { display: flex; flex-direction: column; gap: 8px; } /* the Paste button above the field + Verify fallback */
.sj-paste .sj-btn.primary { width: 100%; }

/* ---------- Wave 2 · sheets · Payments (board Pay · Buy with no saved card, 3DS, Bank said no, Card saved, Save a card).
   The card form: the price under the title, wallets, "or card", Stripe's form (its final height reserved), extras + Pay. ---------- */
.pg-sub { margin-top: -6px; font-family: var(--mono); font-size: 13px; line-height: 17px; font-weight: 400; color: var(--muted); }
.pg .pg-or { gap: 10px; font-family: var(--mono); font-size: 12px; line-height: 16px; font-weight: 400; color: var(--muted); }
.pg .pg-or::before, .pg .pg-or::after { background: var(--line); }
.pg-foot .pg-fee:empty { visibility: hidden; }
/* The 2.5 px step: Stripe sizes its wrapper (inline height, with its own transition) ~6 px past the iframe, then eases it
   back. The wrapper follows the iframe instead, and the form's final height (US: number, expiry + CVC, ZIP) is reserved
   before it mounts, so the sheet doesn't move when Stripe loads. */
.pg .pg-pe { min-height: 194px; }
.pg .pg-pe > .__PrivateStripeElement { height: auto !important; transition: none !important; }
/* 3DS (boards Pay · 3DS 1, 2, 4, Bank said no): a 15 px line and a muted one; Continue is the blue 40 button, the rest 36 outline at right */
.pg-3t { font-family: var(--mono); font-size: 15px; line-height: 20px; font-weight: 500; color: var(--text); }
.pg-3s { font-family: var(--mono); font-size: 13px; line-height: 17px; font-weight: 400; color: var(--muted); }
.pg-foot .pg-go { flex: 0 0 auto; min-width: 146px; }
.pg .pg-wait { display: flex; align-items: center; gap: 14px; padding: 0; }
.pg-bars { display: flex; gap: 3px; flex-shrink: 0; }
.pg-bars i { width: 5px; height: 9px; background: var(--green); opacity: .25; animation: pg-bar 1000ms linear infinite; }
.pg-bars i:nth-child(2) { animation-delay: 200ms; } .pg-bars i:nth-child(3) { animation-delay: 400ms; }
.pg-bars i:nth-child(4) { animation-delay: 600ms; } .pg-bars i:nth-child(5) { animation-delay: 800ms; }
@keyframes pg-bar { 0%, 60% { opacity: 1; } 61%, 100% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .pg-bars i { animation: none; opacity: 1; } }
.pg-wn { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }
.pg-wn .sj-btn { flex: 0 0 auto; min-width: 140px; }
/* Confirmations (boards Card saved, Email added): a 36 tile with a green line and check, then one line */
.pg-ok { display: flex; align-items: center; gap: 12px; }
.pg-ok-t { width: 36px; height: 36px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; border: 1px solid var(--green); color: var(--green); }
.pg-ok-t svg { display: block; }
.pg-ok-n { font-family: var(--mono); font-size: 14px; line-height: 18px; color: var(--text); overflow-wrap: anywhere; }
/* ---------- Wave 2 · sheets · Gems + Royal (boards Gems · Not enough gems, Negative balance, email nudge; Royal · Subscribe). ---------- */
.pg-need { display: flex; flex-direction: column; gap: 2px; margin-top: -4px; }
.pg-need-a { font-family: var(--mono); font-size: 15px; line-height: 19px; font-weight: 500; color: var(--text); }
.pg-need-b { font-family: var(--mono); font-size: 13px; line-height: 17px; font-weight: 400; color: var(--muted); }
/* the email nudge and the email check in the sheet (boards 6Q8-0, 7CY-0, WK5-0) */
.pg .pg-nudge { min-height: 0; gap: 12px; margin-top: 4px; padding: 12px 0 0; background: transparent; border: 0; border-top: 1px solid var(--line); }
.pg .pg-nudge-t { font-size: 13px; line-height: 18px; font-weight: 400; color: var(--muted); overflow-wrap: anywhere; }
.pg .pg-nudge-a { flex-shrink: 0; }
.pg-hd .sj-back { height: 36px; margin: -6px -12px -6px 0; color: var(--muted); } /* the one Back (UI.head): 36 px hit area in the 24 px row */
.em-bs { margin-top: -4px; font-family: var(--mono); font-size: 13px; line-height: 17px; color: var(--muted); overflow-wrap: anywhere; }
.em-act { display: flex; justify-content: flex-end; }
.em-code-b { display: flex; gap: 10px; justify-content: flex-start; }
.em-bf { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-family: var(--mono); font-size: 13px; line-height: 18px; color: var(--muted); }
/* Royal · Subscribe (boards 4JI-0, 4KV-0, 4M8-0) */
.pg .sj-body:has(> .pg-sup-a) { gap: 12px; }
.pg-sup-a { gap: 12px; }
.pg-sup-a .pg-sup-s { margin-top: -4px; padding: 0; font-size: 16px; line-height: 20px; font-weight: 500; color: var(--text); }
.pg-sup-a .pg-royal-pin { align-items: center; gap: 12px; margin: 0; padding: 12px 16px; background: var(--surface); border: 1px solid var(--line); font-size: 14px; line-height: 18px; color: var(--text); }
.pg-sup-a .pg-royal-pin .pg-gem { flex: 0 0 auto; }
.pg-rp-s { font-size: 13px; line-height: 17px; color: var(--muted); }
.pg-rp-h { display: flex; align-items: center; gap: 8px; font-size: 11px; line-height: 14px; color: var(--muted); }
.pg-rp-h::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--line); }
.pg-rp-l { display: flex; flex-direction: column; gap: 10px; padding: 0 16px; }
.pg-rp { display: flex; align-items: flex-start; gap: 12px; font-family: var(--mono); font-size: 14px; line-height: 18px; color: var(--text); }
.pg-rp-m { flex: 0 0 auto; width: 10px; height: 10px; margin: 4px 3px 0; background: var(--royal); }
/* Royal perks (the pill menu's view) */
.pg-rv-s, .pg-rv-b { display: flex; align-items: center; gap: 8px; }
.pg-rv-none { padding-inline-start: 28px; }
.pg-rv-f { justify-content: flex-end; }
.pg-sup-a ~ .pg-quiet, .pg-subw .pg-quiet { padding: 0; text-align: start; font-size: 12px; line-height: 16px; font-weight: 400; color: var(--muted); }
/* Royal toasts (boards 4OB-0 You're Royal, 4OT-0 Royal paused): red square indicator, two lines, Update card */
.pg-toast-b { align-items: center; gap: 12px; text-align: start; }
.pg-toast-dot { flex: 0 0 auto; width: 8px; height: 8px; background: var(--red); }
.pg-toast-tx { display: flex; flex-direction: column; min-width: 0; }
.pg-toast-b .pg-toast-l { font-size: 13px; line-height: 17px; color: var(--muted); }
.pg-toast-u { flex: 0 0 auto; margin-inline-start: auto; }

/* ---------- Player feedback (web/fb.ts): Request a language, the chats list, a new message, a thread. Uses .si and .ch-*. ---------- */
.si .sj-body > .fb-ask { align-self: flex-start; padding: 0; border: 0; background: none; cursor: pointer; }
.fb-r { justify-content: space-between; }
.fb-r.fb-done { cursor: default; }
.fb-r.fb-done:hover { color: var(--muted); }
.fb-st { font-size: 13px; line-height: 20px; color: var(--muted); }
.fb-other .sj-in { flex: 1; min-width: 0; }
.fb-other[hidden] { display: none; }
.si .fb-ok { min-height: 18px; } /* kept when empty: the bottom sheet mustn't grow and slide a row under the finger that tapped */
.fb-ts { display: flex; flex-direction: column; border: 1px solid var(--line); }
.fb-t { display: flex; flex-direction: column; align-items: stretch; gap: 4px; min-width: 0; padding: 12px; border: 0; border-top: 1px solid var(--line); background: transparent; color: var(--text); text-align: start; cursor: pointer; font-family: var(--mono); }
.fb-t:first-child { border-top: 0; }
.fb-t:hover { background: var(--surface); }
.fb-t:focus-visible { outline: 1px solid var(--text); outline-offset: -1px; }
.fb-th { display: flex; align-items: center; gap: 8px; min-height: 20px; }
.fb-tag { font-size: 12px; line-height: 16px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.fb-dot { width: 8px; height: 8px; flex-shrink: 0; margin-inline-start: auto; background: var(--green); }
.fb-last { min-width: 0; font-size: 14px; line-height: 20px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.si .sj-body > .fb-new { align-self: flex-start; }
.fb-in { height: auto; min-height: 96px; padding: 8px 12px; resize: vertical; white-space: pre-wrap; overflow-wrap: anywhere; }
.si .fb-anon, .si .fb-status { font-size: 13px; line-height: 20px; }
.fb-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.fb-foot > .sj-btn { margin-inline-start: auto; }
.fb-n { font-family: var(--mono); font-size: 13px; line-height: 20px; color: var(--muted); font-variant-numeric: tabular-nums; }
.fb-ms { display: flex; flex-direction: column; gap: 12px; }
.fb-m { display: flex; flex-direction: column; gap: 4px; padding-inline-start: 12px; border-inline-start: 1px solid var(--line-strong); }
.fb-m.me { border-inline-start-color: var(--line); }
.fb-who { font-family: var(--mono); font-size: 12px; line-height: 16px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.fb-body { font-family: var(--mono); font-size: 14px; line-height: 20px; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }
.sj-pl-fn { min-width: 20px; height: 20px; padding: 0 4px; box-sizing: border-box; text-align: center; font-size: 12px; line-height: 20px; font-weight: 500; font-variant-numeric: tabular-nums; background: var(--green); color: var(--on-green); }
.sj-pl-fn[hidden] { display: none; }

/* Game updates: the dot on the pill row (inside the open menu only) and a "New" tag on an entry. */
.sj-pl-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--royal); flex-shrink: 0; margin-inline-start: auto; }
.sj-pl-dot[hidden] { display: none; }
.gu-owner { display: flex; align-items: center; gap: 8px; min-height: 20px; padding: 4px 0 12px; }
.gu-ob { font-size: 13px; line-height: 20px; color: var(--muted); }
.gu-olink { display: flex; align-items: center; gap: 8px; text-decoration: none; color: var(--text); }
.gu-oav { width: 24px; height: 24px; flex-shrink: 0; object-fit: cover; border-radius: 50%; background: var(--surface); }
.gu-oh { font-family: var(--mono); font-size: 13px; line-height: 20px; direction: ltr; unicode-bidi: isolate; }
.gu-es { display: flex; flex-direction: column; gap: 20px; }
.gu-e { display: flex; flex-direction: column; gap: 4px; padding-top: 12px; box-shadow: inset 0 1px 0 0 var(--line); } /* inset, not border-top: a border-top's 1px would break the 4px grid */
.gu-e:first-child { padding-top: 0; box-shadow: none; }
.gu-eh { display: flex; align-items: center; gap: 8px; min-height: 12px; }
.gu-v { font-family: var(--mono); font-size: 12px; line-height: 16px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.gu-dot { margin-inline-start: 0; }
.gu-t { font-size: 14px; line-height: 20px; font-weight: 500; color: var(--text); }
.gu-notes { display: flex; flex-direction: column; gap: 4px; }
.gu-p, .gu-ul { font-size: 14px; line-height: 20px; color: var(--muted); }
.gu-ul { margin: 0; padding-inline-start: 18px; }
.si .sj-body > .gu-more { align-self: flex-start; }

}
@layer page {
/* ---------- Wave 2 · ads manage (web/ads-manage.ts, web/ads-admin.ts). Boards: Ads · Manage 12 to 16c, Ads · Admin 23 to 23d.
   Charts (Style guide board 6): views as #7D9BFF 2×2 dither bars, today solid, spend a day as a text-colored (cream) line. ---------- */
.am-page { gap: var(--sp-10); }
.am-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.am-c { fill: var(--chart); } .am-m { fill: var(--muted); }
.am-k { margin-bottom: var(--sp-6); } .am-k::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.am-k .am-k-r { order: 2; letter-spacing: 0.04em; text-transform: none; font-weight: 400; }
.am-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-6); flex-wrap: wrap; }
.am-h { margin: 0; overflow-wrap: anywhere; }
.am-sub { margin: var(--sp-2) 0 0; font-size: 14px; line-height: 20px; letter-spacing: 0.04em; }
.am-acts { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.am-acts .link { margin-right: var(--sp-3); }
.am-top { display: flex; justify-content: flex-end; }
.am-top .sj-back, .inv-bar .sj-back { height: 36px; margin-right: -12px; } /* the one Back: top right, 36 px */
.am-two { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-12); }
.am-two.w { grid-template-columns: minmax(0, 900fr) minmax(0, 400fr); }
.am-cards { display: grid; gap: var(--sp-4); }
.am-cards.c2 { grid-template-columns: 1fr 1fr; }
.am-cards.c5 { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0; }
.am-cards.c5 .am-card + .am-card { border-left: 0; }
.am-card { padding: var(--sp-6); display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }
.am-fig { font-family: var(--sans); font-weight: 800; font-size: 48px; line-height: 52px; letter-spacing: -0.03em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.am-cards.c5 .am-fig { font-size: 40px; line-height: 44px; }
.am-card-s { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); font-size: 13px; line-height: 18px; letter-spacing: 0.04em; min-height: 18px; }
.am-card-s.barred { justify-content: flex-start; }
.am-bar svg, .am-spark { display: block; flex-shrink: 0; }
.am-bar-fg { fill: var(--muted); }
.am-spark { color: var(--chart); } .am-spark.cream { color: var(--text); }
.am-spark.cream rect:not(:last-child) { opacity: .7; }
/* status: a square dot and a word */
.am-st { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: 14px; line-height: 20px; white-space: nowrap; }
.am-st i { width: 8px; height: 8px; flex-shrink: 0; background: var(--muted); }
.am-st.ok i { background: var(--ok); } .am-st.bad i { background: var(--red); } .am-st.warn i { background: var(--text); }
.am-st.wait, .am-st.off { color: var(--muted); }
.am-st.off i { background: transparent; box-shadow: inset 0 0 0 1px var(--muted); }
/* tables */
.am-tbl { display: flex; flex-direction: column; }
.am-tr { display: grid; align-items: center; gap: var(--sp-4); min-height: 48px; padding: 0; border-bottom: 1px solid var(--line); font-size: 14px; line-height: 20px; color: var(--text); text-decoration: none; }
.am-tr > * { min-width: 0; overflow-wrap: anywhere; }
.am-th { min-height: 32px; font-size: 12px; line-height: 16px; font-weight: 500; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.am-row:hover { background: var(--surface); }
.am-ads .am-tr { grid-template-columns: minmax(0, 440fr) minmax(0, 300fr) 110fr 130fr 150fr 118fr; }
.am-ads .am-row { min-height: 76px; }
.am-where .am-tr { grid-template-columns: minmax(0, 1fr) 140px 160px; min-height: 56px; }
.am-inv .am-tr { grid-template-columns: 140px 140px minmax(0, 1fr) 110px 130px 140px; }
.am-ad { display: flex; align-items: center; gap: var(--sp-4); }
.am-ad-t { display: flex; flex-direction: column; min-width: 0; letter-spacing: 0.04em; }
.am-ad-t .dim { font-size: 13px; line-height: 18px; }
.am-art { width: 48px; height: 48px; flex-shrink: 0; image-rendering: pixelated; background: var(--surface); display: block; }
.am-art.lg { width: 88px; height: 88px; } .am-art.xl { width: 120px; height: 120px; }
.am-art-x { box-shadow: inset 0 0 0 1px var(--line); }
.am-none { margin: 0; padding: var(--sp-4) 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.am-empty { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-4); padding: var(--sp-12) 0; border-top: 1px solid var(--line); }
.am-empty h2, .am-empty p { margin: 0; } .am-empty p { max-width: 520px; font-size: 14px; line-height: 20px; }
/* campaign */
.am-chead { align-items: flex-end; }
.am-ch { display: flex; align-items: flex-end; gap: var(--sp-6); min-width: 0; }
.am-ch .am-st { margin-bottom: var(--sp-2); }
.am-why, .am-ban { display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap; padding: var(--sp-4) var(--sp-6); border: 1px solid var(--line); background: var(--surface); font-size: 14px; line-height: 20px; }
.am-why b, .am-ban b { font-weight: 500; }
.am-ban { border-color: var(--red); justify-content: space-between; }
.am-ban-t { display: flex; flex-direction: column; gap: 2px; }
.am-ban-a { display: flex; gap: var(--sp-3); }
.am-ban-err { flex-basis: 100%; margin: 0; }
.am-note { margin: calc(-1 * var(--sp-6)) 0 0; font-size: 14px; }
.am-nc { position: relative; display: flex; align-items: center; gap: var(--sp-2); margin-top: calc(-1 * var(--sp-6)); font-size: 13px; letter-spacing: 0.04em; }
.am-i { width: 16px; height: 16px; padding: 0; border: 1px solid var(--line-strong); background: transparent; color: var(--muted); font: 500 10px/14px var(--mono); cursor: pointer; }
.am-i:hover, .am-i[aria-expanded="true"] { color: var(--text); border-color: var(--text); }
.am-pop { position: absolute; top: 28px; left: 0; z-index: 5; width: 360px; max-width: calc(100vw - 48px); padding: var(--sp-4); background: var(--surface); border: 1px solid var(--line-strong); font-size: 13px; line-height: 19px; }
.am-pop b { font-weight: 500; } .am-pop p { margin: var(--sp-2) 0 0; color: var(--muted); }
.am-legend { display: flex; gap: var(--sp-6); margin: calc(-1 * var(--sp-2)) 0 var(--sp-6); font-size: 13px; color: var(--muted); }
.am-legend > span { display: inline-flex; align-items: center; gap: var(--sp-2); }
.am-lg-v i { width: 12px; height: 12px; background: var(--chart); } .am-lg-s i { width: 12px; height: 2px; background: var(--text); }
.am-chart { width: 100%; }
.am-svg { display: block; width: 100%; height: 240px; overflow: visible; }
.am-grid { stroke: var(--line-strong); stroke-width: 1; stroke-dasharray: 1 3; }
.am-b.today { fill: var(--chart); }
.am-line { fill: none; stroke: var(--text); stroke-width: 2; }
.am-hit { fill: transparent; }
.am-tip { pointer-events: none; }
.am-tip-bg { fill: var(--surface); stroke: var(--line-strong); stroke-width: 1; }
.am-tip-t { fill: var(--text); font: 400 13px var(--mono); } .am-tip-v { fill: var(--chart); font: 400 13px var(--mono); }
.am-axis { display: flex; margin-top: var(--sp-3); font-size: 12px; color: var(--muted); letter-spacing: 0.04em; }
.am-axis span { flex: 1; text-align: center; white-space: nowrap; } .am-axis span:first-child { text-align: left; } .am-axis span:last-child { text-align: right; }
.am-prev { display: flex; align-items: center; gap: var(--sp-5); }
.am-prev-t { display: flex; flex-direction: column; gap: var(--sp-1); font-size: 15px; } .am-prev-t .dim { font-size: 13px; }
/* sheets: edit and stop */
.am-tabs { display: flex; gap: var(--sp-6); margin: var(--sp-4) 0 var(--sp-5); border-bottom: 1px solid var(--line); }
.am-tab { height: 36px; padding: 0; border: 0; border-bottom: 1px solid transparent; margin-bottom: -1px; background: none; color: var(--muted); font: 500 14px/20px var(--mono); cursor: pointer; }
.am-tab.on { color: var(--text); border-bottom-color: var(--text); }
.am-form { display: flex; flex-direction: column; gap: var(--sp-4); }
.am-f { display: flex; flex-direction: column; gap: var(--sp-2); } .am-f .sj-in { flex: none; width: 100%; box-sizing: border-box; }
.am-f-n { margin: 0; font-size: 13px; line-height: 18px; }
.am-chk { display: flex; align-items: center; gap: var(--sp-3); font-size: 14px; line-height: 20px; }
.am-chk .num { margin-left: auto; }
.am-chk input { accent-color: var(--text); margin: 0; }
.am-plots { display: flex; flex-direction: column; gap: var(--sp-2); padding-left: var(--sp-6); max-height: 220px; overflow: auto; }
.am-sh-p { margin: var(--sp-3) 0 var(--sp-5); font-size: 14px; line-height: 20px; }
.am-sh-a { display: flex; justify-content: flex-end; gap: var(--sp-3); margin-top: var(--sp-6); }
.sj-btn.am-red { border-color: var(--red); color: var(--red); }
.sj-btn.am-red:hover { background: transparent; border-color: var(--red); color: var(--text); }
/* invoice: printable, light like paper whatever the theme */
html:has(body.inv-paper), body.inv-paper { --ground: #F5F4F0; --surface: #FFFFFF; --line: #DAD7CE; --line-strong: #C9C5BA; --text: #12110E; --muted: #6E6A60; --ok: var(--green-ink); color-scheme: light; }
.inv-bar { display: flex; justify-content: space-between; align-items: center; }
.inv { background: var(--surface); border: 1px solid var(--line); padding: var(--sp-12); display: flex; flex-direction: column; gap: var(--sp-10); max-width: 800px; width: 100%; box-sizing: border-box; align-self: center; }
.am-page:has(.inv) { max-width: 848px; }
.inv-h { display: flex; justify-content: space-between; gap: var(--sp-8); flex-wrap: wrap; }
.inv-h h1 { margin: var(--sp-4) 0 0; }
.inv-brand { display: flex; align-items: center; gap: var(--sp-2); font: 800 18px/24px var(--sans); letter-spacing: -0.02em; }
.inv-brand img { width: 24px; height: 24px; }
.inv-meta { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 220px; }
.inv-kv { display: flex; justify-content: space-between; gap: var(--sp-6); font-size: 14px; line-height: 20px; }
.inv-parties { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
.inv-p { display: flex; flex-direction: column; margin-top: var(--sp-2); font-size: 14px; line-height: 20px; } .inv-p b { font-weight: 500; }
.inv-lines .am-tr { grid-template-columns: minmax(0, 1fr) 120px 140px; }
.inv-sum { display: flex; flex-direction: column; align-self: flex-end; width: 320px; max-width: 100%; }
.inv-sr { display: flex; justify-content: space-between; min-height: 36px; align-items: center; border-bottom: 1px solid var(--line); font-size: 14px; }
.inv-sr.tot { font-weight: 500; font-size: 16px; border-bottom: 0; border-top: 1px solid var(--text); }
.inv-paid { margin-top: var(--sp-2); font-size: 13px; text-align: right; }
.inv-note { margin: 0; font-size: 13px; line-height: 19px; }
.inv-f { font-size: 12px; }
@media print {
  body.inv-paper .hd, body.inv-paper .ft, body.inv-paper .hz, body.inv-paper canvas.bg, .no-print { display: none !important; }
  body.inv-paper, html:has(body.inv-paper) { background: #fff; }
  body.inv-paper .page { padding: 0; max-width: none; }
  .inv { border: 0; padding: 0; max-width: none; }
}
/* admin */
.aa-head h1, .aa-head p { margin: 0; } .aa-head p { margin-top: var(--sp-2); font-size: 14px; }
.aa-tabs { display: flex; gap: 28px; border-bottom: 1px solid var(--line); margin-top: calc(-1 * var(--sp-4)); }
.aa-tab { display: inline-flex; align-items: center; gap: var(--sp-2); height: 48px; color: var(--muted); text-decoration: none; font-size: 15px; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.aa-tab:hover { color: var(--text); } .aa-tab.on { color: var(--text); font-weight: 700; border-bottom-color: var(--text); }
.aa-n { min-width: 22px; height: 22px; padding: 0 6px; box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; background: var(--surface); border: 1px solid var(--line); font-size: 11px; color: var(--text); font-weight: 500; }
.aa-body { display: flex; flex-direction: column; gap: var(--sp-12); margin-top: calc(-1 * var(--sp-4)); }
.aa-figs { display: flex; gap: var(--sp-12); flex-wrap: wrap; }
.aa-fig { display: flex; flex-direction: column; }
.aa-fig-n { font: 500 36px/40px var(--mono); font-variant-numeric: tabular-nums; }
.aa-cols { display: grid; grid-template-columns: minmax(0, 708fr) minmax(0, 420fr); gap: var(--sp-16); align-items: start; }
.aa-l { display: block; padding: var(--sp-6) 0 var(--sp-3); border-bottom: 1px solid var(--line); }
.aa-cols .aa-l:first-child, .aa-tools .aa-l { padding-top: 0; }
.aa-need { display: grid; grid-template-columns: 76px minmax(0, 1fr) auto; align-items: center; min-height: 64px; border-bottom: 1px solid var(--line); color: var(--text); text-decoration: none; }
.aa-need-n { font: 500 28px/32px var(--mono); }
.aa-need-t { display: flex; flex-direction: column; font-size: 15px; line-height: 20px; } .aa-need-t b { font-weight: 700; } .aa-need-t .dim { font-size: 13px; }
.aa-open { font-weight: 700; font-size: 15px; }
.aa-need:hover .aa-open { text-decoration: underline; text-underline-offset: 3px; }
.aa-kv { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-4); min-height: 44px; border-bottom: 1px solid var(--line); font-size: 15px; }
.red, .aa-kv .red { color: var(--red); }
/* fr columns would grow past the page at max-content; a fixed width keeps them on the 1200 page and scrolls below it */
.aa-tbl { --tmin: 1152px; }
.aa-tbl[data-cols="g"] .am-tr { grid-template-columns: minmax(0, 2fr) 1fr 1.2fr 1.2fr 1fr 1fr .9fr .9fr 176px; }
.aa-tbl[data-cols="r"] .am-tr { grid-template-columns: minmax(0, 2fr) .7fr 1fr 2fr 1.4fr 1.6fr; }
.aa-tbl[data-cols="e"] .am-tr { grid-template-columns: minmax(0, 1.6fr) .7fr .6fr 1.6fr 2fr 1fr 1fr; }
.aa-tbl[data-cols="a"] .am-tr { grid-template-columns: minmax(0, 2.2fr) .7fr 1fr .6fr .7fr 1.2fr 1fr; }
.aa-tbl .am-tr { min-height: 52px; }
.aa-tbl .am-tr.off { color: var(--muted); }
.aa-acts { display: flex; gap: var(--sp-2); justify-content: flex-end; }
.aa-p { margin: 0; font-size: 14px; }
.aa-q { display: flex; flex-direction: column; gap: var(--sp-4); }
.aa-item { display: grid; grid-template-columns: 120px minmax(0, 1fr) auto; gap: var(--sp-6); padding: var(--sp-6); align-items: start; }
.aa-item-art img { width: 120px; height: 120px; image-rendering: pixelated; display: block; }
.aa-item-m { display: flex; flex-direction: column; gap: var(--sp-2); font-size: 14px; line-height: 20px; min-width: 0; }
.aa-item-m b { font-size: 16px; font-weight: 500; }
.aa-sub { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2) var(--sp-4); padding-top: var(--sp-2); border-top: 1px solid var(--line); overflow-wrap: anywhere; }
.aa-sc { display: inline-flex; gap: var(--sp-1); }
.aa-note { margin: 0; color: var(--muted); }
.aa-item-a { display: flex; flex-direction: column; gap: var(--sp-2); }
.aa-row-a.sj-row .sj-in { flex: 1; min-width: 0; }
.aa-tools { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--sp-10); }
.aa-row-a { padding: var(--sp-3) 0 11px; border-bottom: 1px solid var(--line); } /* 11 + the 1 px line: rows stay on the 4 px grid */
.aa-url { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.aa-tool + .aa-tool { padding-top: var(--sp-6); }
/* a long failing sentence wraps under its label in 24 px lines; 10 + 9 + the line keep each row a multiple of 4 */
.aa-tool .aa-kv { align-items: flex-start; padding: 10px 0 9px; } .aa-tool .aa-kv > :first-child { flex-shrink: 0; } .aa-tool .aa-kv > .num { text-align: right; }
.aa-tool .sj-row { flex-wrap: wrap; gap: var(--sp-2); } .aa-tool .sj-row .sj-in { flex: 1 1 160px; }
@media (max-width: 860px) {
  .am-two, .am-two.w, .am-cards.c2, .aa-cols, .inv-parties { grid-template-columns: 1fr; }
  .am-two { gap: var(--sp-10); }
  .am-cards.c5 { grid-template-columns: 1fr 1fr; gap: var(--sp-3); } .am-cards.c5 .am-card + .am-card { border-left: 1px solid var(--line); }
  .am-fig, .am-cards.c5 .am-fig { font-size: 36px; line-height: 40px; }
  .am-ads .am-tr { grid-template-columns: minmax(0, 1fr) 72px 88px; } .am-ads .am-tr > :nth-child(2) { grid-column: 1 / -1; grid-row: 2; padding-left: 64px; margin-top: -8px; padding-bottom: 12px; }
  .am-ads .am-row { min-height: 0; padding-top: 12px; }
  .hide-s { display: none; }
  .am-inv .am-tr { grid-template-columns: 1fr 1fr 90px 120px; }
  .am-where .am-tr { grid-template-columns: minmax(0, 1fr) 72px 96px; }
  .am-ch { align-items: flex-start; } .am-art.lg { width: 64px; height: 64px; }
  .aa-item { grid-template-columns: 72px minmax(0, 1fr); } .aa-item-art img { width: 72px; height: 72px; } .aa-item-a { grid-column: 1 / -1; flex-direction: row; }
  .inv { padding: var(--sp-6); }
}


}
@layer page {
/* ---------- Wave 2 · spend: the anchored confirm card (Gems · Spend confirm option C), gem flights, the pill (board 5.4) ---------- */
.pg-sp-card { position: absolute; box-sizing: border-box; display: flex; flex-direction: column; gap: 10px; padding: 12px; background: var(--ground);
  border: 1px solid var(--line-strong); pointer-events: auto; font-family: var(--mono); color: var(--text); }
.pg-sp-hd { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 20px; }
.pg-sp-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--sans); font-size: 15px; line-height: 20px; font-weight: 800; color: var(--text); }
.pg-sp-x { flex-shrink: 0; height: 20px; padding: 0; border: 0; background: none; color: var(--muted); font-family: var(--mono); font-size: 13px; line-height: 16px; cursor: pointer; }
.pg-sp-x:hover { color: var(--text); } .pg-sp-x:focus-visible { outline: 1px solid var(--text); outline-offset: 2px; }
.pg-sp-card .pg-sp-btn { position: relative; width: auto; height: 40px; padding: 0 16px; }
/* the spinner sits at the button's left edge, so opening it never moves the label (the card leaves room for it) */
.pg-sp-card .pg-sp-spin { position: absolute; inset-inline-start: 12px; top: 12px; width: 16px; margin-inline-end: 0; transition: opacity 120ms linear; }
.pg-sp-g { gap: 4px; }
.pg-sp-g .pg-gem { display: block; }
.pg-sp-ptr { position: absolute; bottom: -8px; display: block; width: 14px; height: 7px; overflow: visible; }
.pg-sp-card.down .pg-sp-ptr { bottom: auto; top: -8px; transform: rotate(180deg); }
.pg-sp-pf { fill: var(--ground); } .pg-sp-ps { fill: none; stroke: var(--line-strong); stroke-width: 1; stroke-linecap: square; }
.pg-sp-pill { height: 32px; padding: 0 12px; display: flex; align-items: center; }
.pg-sp-pill .pg-pill-n, .pg-fly-pill .pg-pill-n { font-family: var(--mono); font-size: 14px; line-height: 20px; font-weight: 500; color: var(--text); }
/* The pill (board 5.4): 32 high, square, ground at 92 % with a 1 px ring; square avatar; the gem and balance (5.6 rule);
   the ROYAL badge for Royal members. The menu heads with the handle and the badge. */
/* The avatar is the pill's full 32 x 32 at its left edge (owner, 2026-10-20): it paints over the inset ring on its three
   outer sides, so no ring or ground shows between it and the pill's edge, closed or open (.on only recolors the ring). */
.sj-pl-b { height: 32px; gap: 8px; padding-block: 0; padding-inline: 0 10px; max-width: 280px; }
.sj-pl-av { width: 32px; height: 32px; border-radius: 0; }
.sj-pl-bal { gap: 4px; font-family: var(--mono); font-size: 14px; line-height: 20px; font-weight: 500; color: var(--text); }
.sj-pl-bal .pg-gem { display: block; }
.sj-pl-r[hidden] { display: none; }
.sj-pl-r:not(.sm) { overflow: hidden; }
.sj-pl-who { display: flex; align-items: center; gap: 8px; min-width: 0; padding-block: 8px 4px; padding-inline: 10px 8px; }
/* The balance row has no "Gems" label (owner, 2026-10-20): the gem and the number (5.6: 20 x 19, gap 4) on one line with
   Top up, the gem on the handle's and Account settings' left edge, Top up's right edge on the arrow's. */
.sj-pl-g { padding: 8px 10px 12px 10px; }
.sj-pl-v { display: flex; gap: 4px; min-width: 0; min-height: 28px; flex-shrink: 0; }
.sj-pl-who .sj-pl-h { min-width: 0; direction: ltr; unicode-bidi: isolate; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; line-height: 20px; color: var(--text); }
.sj-pl-b.gs { gap: 8px; padding: 0 12px; }
.sj-pl-lc { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; line-height: 20px; font-weight: 500; color: var(--muted); }
.sj-pl-lc svg { color: var(--slate); flex-shrink: 0; }
.sj-pl-si { font-size: 14px; line-height: 20px; font-weight: 500; }
.pg-fly-pill { height: 32px; padding: 0 12px; gap: 8px; }
.pg-fly-pill .gem-t .pg-gem, .pg-sp-pill .gem-t .pg-gem { display: block; }


}
@layer page {
/* ---------- test mode (notes/testmode-plan.md §4): the TEST tag, the Royal switch and Empty ---------- */
.sj-pl-t { background: var(--test); color: var(--on-test); }
.sj-pl-t[hidden], .sj-pl-tb[hidden] { display: none; }
/* The game hid the pill: the tag alone. */
.sj-pl-b.bare { padding: 0 8px; }
.sj-pl-b.bare > :not(.sj-pl-t) { display: none; }
.sj-pl-tb { border: 0; background: transparent; cursor: pointer; text-align: start; }
.sj-pl-k { position: relative; width: 32px; height: 16px; flex-shrink: 0; box-sizing: border-box; box-shadow: inset 0 0 0 1px var(--line-strong); transition: background-color 160ms, box-shadow 160ms; }
.sj-pl-k::after { content: ""; position: absolute; top: 2px; inset-inline-start: 2px; width: 12px; height: 12px; background: var(--muted); transition: transform 160ms cubic-bezier(.22,1,.36,1), background-color 160ms; }
.sj-pl-sw[aria-checked="true"] .sj-pl-k { background: var(--royal); box-shadow: inset 0 0 0 1px var(--royal); }
.sj-pl-sw[aria-checked="true"] .sj-pl-k::after { transform: translateX(16px); background: #fff; }
[dir="rtl"] .sj-pl-sw[aria-checked="true"] .sj-pl-k::after { transform: translateX(-16px); }
@media (prefers-reduced-motion: reduce) { .sj-pl-k, .sj-pl-k::after { transition: none; } }

}
@layer page {
/* The outside developer path: sojo.gg/approve/<code>, /dev (Your games), /dev/<id>, /admin/dev (web/dev.ts). Existing
   components; these lay out the trail, the steps, the key/value rows, the tables and reports. */
.dv-h { margin: 0; overflow-wrap: anywhere; } /* type: .t-h1 */
/* the page's header: trail, title, the steps and next action, close together under the page's wide gap */
.dv-top { display: flex; flex-direction: column; gap: 24px; }
.dv-trail { display: flex; align-items: center; gap: 12px; min-height: 28px; font-size: 13px; line-height: 16px; color: var(--muted); }
.dv-trail ol { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; min-width: 0; }
.dv-trail li { overflow-wrap: anywhere; }
.dv-trail li + li::before { content: "/"; margin-right: 8px; color: var(--line-strong); }
.dv-trail a { color: var(--muted); text-decoration: none; }
.dv-trail a:hover { color: var(--text); }
.dv-trail [aria-current] { color: var(--text); }
.dv-back { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; box-sizing: border-box; border: 1px solid var(--line-strong); }
.dv-trail .dv-back { color: var(--text); }
.dv-title { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px 16px; }
.dv-flow { gap: 16px; max-width: 760px; }
.dv-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, auto); border-top: 1px solid var(--line); border-left: 1px solid var(--line); }
.dv-step { display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 12px; box-sizing: border-box; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  font-size: 14px; line-height: 20px; color: var(--muted); white-space: nowrap; }
.dv-step.current { color: var(--text); outline: 1px solid var(--text); outline-offset: -1px; }
.dv-sn { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; box-sizing: border-box; border: 1px solid var(--line-strong); font: 500 12px/12px var(--mono); }
.dv-step.current .dv-sn { border-color: var(--text); }
.dv-step.done .dv-sn { border-color: var(--ok); color: var(--ok); }
.dv-next { display: flex; align-items: center; justify-content: space-between; gap: 16px 24px; flex-wrap: wrap; }
.dv-nl { display: flex; flex-direction: column; gap: 4px; min-width: 0; font-size: 15px; line-height: 20px; overflow-wrap: anywhere; }
.dv-nl > .mono { font-size: 13px; line-height: 20px; }
.dv-nx { color: var(--muted); }
.dv-nx.on { color: var(--text); }
/* a picker card: its link covers the card; Open simulator sits above the link, not inside it */
.dv-gm { position: relative; }
.dv-gm .gm-a { flex: 1 0 auto; }
.dv-gm .gm-a::after { content: ""; position: absolute; inset: 0; }
.dv-gact { position: relative; z-index: 1; padding: 0 16px 16px; }
/* the plan quote */
.dv-ql { display: flex; align-items: center; gap: 16px; }
.dv-ql .num { margin-left: auto; }
.dv-ql.dv-tot { font-weight: 500; }
.dv-say { margin: 0; font-size: 15px; line-height: 20px; }
.dv-qc { display: flex; align-items: center; gap: 12px; font-size: 14px; line-height: 20px; }
.dv-req, .dv-game { gap: 16px; }
.dv-req { max-width: 640px; }
.dv-rows { display: flex; flex-direction: column; }
.dv-kv { align-items: flex-start; padding: 14px 0; min-height: 0; }
.dv-k { flex: 0 0 120px; font-size: 13px; line-height: 20px; }
.dv-v { display: flex; flex-direction: column; gap: 4px; overflow-wrap: anywhere; }
.dv-list { display: flex; flex-direction: column; gap: 2px; }
.dv-was { display: block; font-size: 12px; }
.dv-err { margin: 0; min-height: 20px; color: var(--red); font-size: 13px; }
.dv-err:empty { min-height: 0; }
.dv-acts { display: flex; flex-wrap: wrap; gap: 12px; }
.dv-stats { gap: 32px 48px; }
.dv-sec { max-width: 760px; }
.dv-tbl .dv-tr { grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr)); }
.dv-tbl .dv-tr > span:not(:first-child) { text-align: right; }
.dv-tbl3 .dv-tr { grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr)); }
.dv-atr { grid-template-columns: 1fr 2fr 1fr 1fr 1.4fr; }
.dv-fb { display: flex; flex-direction: column; gap: 6px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.dv-fb.off { opacity: .55; }
.dv-fb-t { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.dv-fb-b { font-size: 13px; line-height: 19px; white-space: pre-wrap; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden; }
@media (max-width: 600px) {
  .dv-steps { grid-template-columns: 1fr; }
  .dv-next .sj-btn { flex: 1 1 auto; }
  .dv-kv { flex-direction: column; align-items: stretch; gap: 4px; }
  .dv-k { flex: none; }
  .dv-atr { grid-template-columns: 1fr 1fr; }
  .dv-tbl .dv-tr { gap: 8px; font-size: 13px; }
  .dv-tbl .dv-tr.th { align-items: end; padding-bottom: 6px; }
}
.dv-host { display: flex; flex-direction: column; gap: 16px; }
.dv-tbl .dv-vtr { grid-template-columns: 64px 1.4fr 1fr 120px; align-items: center; }
.dv-tbl .dv-vtr > span:not(:first-child) { text-align: left; }
.dv-tbl .dv-vtr > .dv-act { text-align: right; }
.dv-vtr.off { opacity: .55; }
.dv-chips { display: flex; gap: 8px; }
.dv-doms { display: flex; flex-direction: column; }
.dv-dom { display: flex; flex-direction: column; gap: 8px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.dv-recs { display: flex; flex-direction: column; gap: 4px; }
.dv-rec { display: grid; grid-template-columns: 64px 1fr 1fr; gap: 12px; font-size: 13px; line-height: 19px; overflow-wrap: anywhere; }
.dv-card { display: flex; flex-direction: column; gap: 8px; flex: 1; } /* footers line up across a row */
.dv-card .dv-chips { flex-wrap: wrap; align-items: center; }
.dv-fb-r { display: flex; flex-direction: column; gap: 4px; padding-left: 12px; border-left: 2px solid var(--line-strong); }
.dv-fb-in { height: auto; padding: 10px 14px; resize: vertical; font-size: 16px; }
.dv-fb-m { font-size: 13px; line-height: 19px; }
/* the approve page: what the agent can do (checks) and what stays with the human (x's) */
.dv-can { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; font-size: 15px; line-height: 20px; }
.dv-can li { display: flex; align-items: flex-start; gap: 12px; }
.dv-can.no li { color: var(--muted); }
.dv-mk { flex: none; margin-top: 2px; color: var(--muted); }
.dv-mk.ok { color: var(--ok); }
.dv-req > p, .dv-host > p { margin: 0; } /* the block's gap spaces its paragraphs */

}
@layer page {
/* sojo.gg/games, the directory (src/routes/listing.ts), and the listing editor and owner list (web/listing.ts).
   Existing tokens; square corners, 1 px lines, no shadows, no hover states. Image boxes are reserved (no layout shift). */
.gm-page { display: flex; flex-direction: column; gap: 32px; }
.gm-h { margin: 0; } /* type from the shared heading scale (10-base.css) */
.gm-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
.gm { display: flex; flex-direction: column; min-width: 0; background: var(--surface); border: 1px solid var(--line); }
.gm-a { display: flex; flex-direction: column; flex: 1; color: inherit; text-decoration: none; }
.gm-cov { display: block; aspect-ratio: 16 / 9; background: var(--ground); border-bottom: 1px solid var(--line); overflow: hidden; }
.gm-cov img { display: block; width: 100%; height: 100%; object-fit: cover; }
.gm-hd { display: flex; align-items: center; gap: 12px; padding: 16px 16px 0; min-height: 40px; }
.gm-icon { flex: none; width: 40px; height: 40px; display: block; background: var(--ground); outline: 1px solid var(--line); outline-offset: -1px; }
.gm-name { font-family: var(--sans); font-size: 20px; line-height: 24px; font-weight: 800; letter-spacing: -0.01em; overflow-wrap: anywhere; }
.gm-d { padding: 8px 16px 16px; color: var(--muted); font-size: 14px; line-height: 20px; overflow-wrap: anywhere; }
.gm-ft { display: flex; align-items: center; gap: 16px; min-height: 48px; padding: 0 16px; border-top: 1px solid var(--line); font-size: 13px; line-height: 16px; }
.gm-n { color: var(--text); }
.gm-x { margin-left: auto; color: var(--muted); }
/* Fade in once loaded (web/games.ts); without script they simply show. */
.gm-js .gm img { opacity: 0; transition: opacity 220ms ease-out; }
.gm-js .gm img.gm-on { opacity: 1; }
.gm-js .gm img.now { transition: none; }
@media (max-width: 1100px) { .gm-list { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) { .gm-list { grid-template-columns: minmax(0, 1fr); gap: 16px; } .gm-page { gap: 24px; } }
@media (prefers-reduced-motion: reduce) { .gm-js .gm img { transition: none; } }

/* Listing editor (/dev) */
.ls-desc { width: 100%; height: auto; min-height: 76px; padding: 10px 12px; resize: vertical; font: inherit; font-size: 16px; line-height: 20px; box-sizing: border-box; }
.ls-dv { display: flex; flex-direction: column; gap: 4px; width: 100%; }
.ls-under { display: flex; gap: 12px; font-size: 12px; }
.ls-why { font-size: 12px; line-height: 16px; }
.ls-img { display: flex; gap: 16px; align-items: flex-start; }
.ls-img-m { display: flex; flex-direction: column; gap: 6px; font-size: 12px; }
.ls-file { display: none; }
.ls-pv { display: block; flex: none; background: var(--ground); border: 1px solid var(--line); overflow: hidden; }
.ls-pv img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ls-icon { width: 64px; height: 64px; }
.ls-cover { width: 192px; aspect-ratio: 16 / 9; }
.ls-shot { width: 120px; aspect-ratio: 4 / 3; }
.ls-shot img { object-fit: contain; }
.ls-shots { display: flex; flex-direction: column; gap: 12px; }
/* Owner list (/admin) */
.ls-adm { display: flex; flex-direction: column; }
.ls-tr { grid-template-columns: 1.2fr 1fr 1.6fr auto; }
.ls-it { display: flex; align-items: center; gap: 12px; padding: 8px 0 8px 16px; border-bottom: 1px solid var(--line); font-size: 13px; }
.ls-th { width: 64px; height: 36px; object-fit: cover; background: var(--ground); }
.ls-tx { flex: 1; overflow-wrap: anywhere; }

}
@layer page {
/* The simulator, sojo.gg/sim/<id> (web/sim.ts): the game in a mock X post, Go live and the health check on the side (below
   under 900 px), this session's feed under the post. Existing tokens and components; no hover states. */
.sim-page { gap: 32px; }
.sim-top { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px 24px; flex-wrap: wrap; }
.sim-h { margin: 0; overflow-wrap: anywhere; } /* type: .t-h2 */
.sim-ctl { display: flex; gap: 12px; flex-wrap: wrap; }
.sim-seg { display: inline-flex; border: 1px solid var(--line-strong); }
.sim-sb { height: 32px; padding: 0 12px; border: 0; background: transparent; color: var(--muted); font: 500 13px/16px var(--mono); cursor: pointer; }
.sim-sb + .sim-sb { border-left: 1px solid var(--line-strong); }
.sim-sb.on { color: var(--text); box-shadow: inset 0 0 0 1px var(--text); }
.sim-sn { margin-left: 8px; font-size: 11px; font-weight: 400; color: var(--muted); }
.sim-sb:disabled { opacity: .4; cursor: default; }
.sim-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, 440px); gap: 48px; align-items: start; }
.sim-main { display: flex; flex-direction: column; gap: 32px; align-items: flex-start; min-width: 0; }

/* the post: X's shape, Direction A's lines */
.sim-post { width: 100%; max-width: 598px; box-sizing: border-box; padding: 16px; border: 1px solid var(--line); background: var(--surface); display: flex; flex-direction: column; gap: 12px; }
.sim-post.phone { max-width: 390px; }
.sim-ph { display: flex; align-items: center; gap: 12px; }
/* the avatar slot: a filled circle until the image loads, never an empty hole */
.sim-av { flex: none; width: 40px; height: 40px; border-radius: 50%; overflow: hidden; background: var(--line-strong); }
.sim-avi { display: block; width: 100%; height: 100%; object-fit: cover; }
.sim-avi:not([src]) { visibility: hidden; }
.sim-who { display: flex; flex-direction: column; min-width: 0; }
.sim-who > * { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sim-ph > .sj-btn { flex: none; margin-left: auto; }
.sim-nm { font-weight: 700; font-size: 15px; line-height: 20px; }
.sim-txt { margin: 0; min-height: 20px; font-size: 15px; line-height: 20px; overflow-wrap: anywhere; }
.sim-card { border: 1px solid var(--line-strong); display: flex; flex-direction: column; }
.sim-card-f { position: relative; width: 100%; aspect-ratio: 1 / var(--r, 1); background: var(--ground); }
.sim-if { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }
.sim-empty { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 24px; text-align: center; font-size: 13px; }
/* waiting: the kit's spinner and a line; over the card until the game loads */
.sim-wait { display: flex; align-items: center; gap: 10px; min-height: 28px; font-size: 13px; line-height: 20px; }
.sim-load { position: absolute; inset: 0; justify-content: center; background: var(--ground); }
@media (prefers-reduced-motion: reduce) { .sim-wait .spin { display: none; } }
.sim-cap { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-top: 1px solid var(--line); font-size: 13px; line-height: 18px; min-width: 0; }
.sim-cap > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sim-ct { font-weight: 500; }

.sim-sess { width: 100%; max-width: 598px; display: flex; flex-direction: column; gap: 8px; }
.sim-sess > .label { display: flex; align-items: center; gap: 10px; min-height: 32px; }
.sim-fr { min-height: 40px; gap: 16px; }
.sim-ft { flex: 0 0 auto; font-size: 13px; }
.sim-none { margin: 8px 0; font-size: 13px; }

/* the side: Go live, then health */
.sim-side { display: flex; flex-direction: column; gap: 24px; min-width: 0; }
.sim-go { display: flex; flex-direction: column; gap: 16px; border: 1px solid var(--line); background: var(--surface); padding: 24px; box-sizing: border-box; min-width: 0; }
.sim-say { margin: 0; font-size: 15px; line-height: 20px; }
.sim-link { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; }
.sim-url { margin-right: auto; font-size: 14px; line-height: 20px; color: var(--text); overflow-wrap: anywhere; }
.sim-la { display: flex; gap: 8px; }
.sim-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.sim-fails { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 4px; font-size: 13px; line-height: 20px; color: var(--red); }
.sim-why { margin: 0; font-size: 13px; line-height: 20px; }
.sim-go .dv-err:empty { display: none; }
/* Test cards: a label, the number in a copy box (the landing's one-line bar) */
.sim-tg { display: flex; flex-direction: column; gap: 8px; }
.sim-tl { margin: 0; font-size: 13px; line-height: 16px; color: var(--muted); }
.sim-cbox { position: relative; height: 56px; box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 0 9px 0 16px; }
.sim-num { min-width: 0; font-size: 14px; line-height: 20px; white-space: nowrap; color: var(--text); }
.sim-cb { width: 36px; height: 36px; }
.sim-cb svg { display: block; width: 18px; height: 18px; }
.sim-cc { right: 9px; top: -33px; width: 72px; padding: 0; }

/* health */
.sim-health { display: flex; flex-direction: column; gap: 16px; border: 1px solid var(--line); background: var(--surface); padding: 24px; box-sizing: border-box; min-width: 0; }
.sim-tot { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 12px; padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.sim-tot .t-figure { font-size: 18px; line-height: 28px; white-space: nowrap; }
.sim-tot .sj-btn { flex: none; }
.sim-grp { display: flex; flex-direction: column; gap: 4px; }
.sim-grp > .label { min-height: 28px; display: flex; align-items: center; }
.sim-rows { display: flex; flex-direction: column; }
.sim-hr { display: flex; flex-direction: column; gap: 4px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.sim-hr:last-child { border-bottom: 0; }
.sim-hl { display: flex; align-items: center; gap: 10px; }
/* the plain sentence and Copy issue: one line when there's room, the button under the sentence when there isn't */
.sim-fx { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; }
.sim-fx > .sim-dt { flex: 1 1 200px; min-width: 0; }
.sim-fx .sj-btn { flex: none; }
.sim-cp { position: relative; flex: none; display: inline-flex; }
.sim-tip { bottom: calc(100% + 9px); z-index: 2; }
.sim-lb { font-size: 14px; line-height: 20px; }
.sim-st { flex: 0 0 auto; display: inline-flex; align-items: center; height: 20px; padding: 0 6px; border: 1px solid var(--line-strong); font: 500 11px/12px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.sim-st.pass { border-color: var(--ok); color: var(--ok); }
.sim-st.fail { border-color: var(--red); color: var(--red); }
.sim-st.warn { border-color: var(--text); color: var(--text); }
.sim-dt { font-size: 12px; line-height: 17px; overflow-wrap: anywhere; }

@media (max-width: 900px) {
  .sim-grid { grid-template-columns: 1fr; gap: 32px; }
  .sim-health, .sim-go { padding: 16px; }
}

}
@layer page {
/* The simulator's Ad spots (web/sim-spots.ts): under the post, the post's width, no card. Lines are inset shadows, so
   rows stay on the 4 px grid. Per
   format a head line, then one row per spot: the 48 px preview, name and key, size and views a day, Show. */
.sim-spots { width: 100%; max-width: 598px; display: flex; flex-direction: column; gap: 8px; }
.sim-spots > .label { display: flex; align-items: center; gap: 10px; min-height: 32px; }
.sim-spg { display: flex; flex-direction: column; }
.sim-spg + .sim-spg { margin-top: 16px; }
.sim-spf { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; padding-bottom: 12px; box-shadow: inset 0 -1px 0 var(--line); }
.sim-spt { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; gap: 0 8px; font-size: 14px; line-height: 20px; }
.sim-sw { flex: none; display: inline-flex; }
.sim-sw > span { width: 12px; height: 12px; }
.sim-spf > .sj-btn { flex: none; margin-left: auto; }
.sim-spe { margin: 8px 0 0; }
.sim-spe:empty { display: none; }
.sim-spx { margin: 12px 0 0; font-size: 13px; line-height: 20px; color: var(--red); }
.sim-sp { display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; align-items: center; gap: 16px; padding: 12px 0; box-shadow: inset 0 -1px 0 var(--line); }
.sim-pv { display: block; width: 48px; height: 48px; image-rendering: pixelated; }
.sim-pv.none { background: var(--line); }
.sim-spw { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 16px; align-items: center; min-width: 0; }
.sim-spw > * { grid-column: 1; overflow-wrap: anywhere; }
.sim-spn { grid-row: 1; font-size: 14px; line-height: 20px; }
.sim-spk { grid-row: 2; font-size: 12px; line-height: 16px; }
.sim-spc { grid-row: 3; font-size: 12px; line-height: 16px; }
.sim-spw > .sim-spm { grid-column: 2; grid-row: 1 / span 3; font-size: 12px; line-height: 16px; text-align: right; white-space: nowrap; }
/* fixed, so Show and Clear and the Seen mark never move the columns */
.sim-spa { display: flex; align-items: center; justify-content: flex-end; gap: 8px; min-width: 168px; }
.sim-spa > .sj-btn { min-width: 116px; }
.sim-spmore { align-self: flex-start; margin-top: 12px; }

@media (max-width: 600px) {
  .sim-spw { grid-template-columns: minmax(0, 1fr); }
  .sim-spw > .sim-spm { grid-column: 1; grid-row: 2; text-align: left; white-space: normal; }
  .sim-spc { grid-row: 3; }
  .sim-spk { grid-row: 4; }
  .sim-sp { gap: 8px; }
  .sim-spa { min-width: 0; flex-direction: column; align-items: flex-end; }
}

/* ---------- Ad tool (web/sim-tool.ts) ----------
   Under the post: the game's ad tool inline as a sheet card (the post's width, 390 on Phone), the
   size row under it, and two offscreen copies at the ad form's widths that run the checks. */
.sim-tool { width: 100%; max-width: 598px; display: flex; flex-direction: column; gap: 8px; }
.sim-tool > .label { display: flex; align-items: center; gap: 12px; min-height: 32px; }
.sim-tool > .sim-fails:empty { display: none; }
.sim-tc { max-width: 598px; max-height: none; }
.sim-tc.phone { max-width: 390px; }
.sim-tft { flex-wrap: wrap; }
.sim-tsz { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 8px; }
.sim-tsi { display: flex; flex-direction: column; gap: 8px; font-size: 12px; line-height: 16px; }
.sim-tpx { display: flex; }
.sim-tpv { display: block; width: 64px; height: 64px; box-sizing: border-box; border: 1px solid var(--line); image-rendering: pixelated; }
.sim-tpv.none { background: var(--line); }
/* The checks' copies: laid out and painted at full size (a hidden frame may be throttled), never seen or tapped. */
.sim-truns { position: fixed; left: 0; top: 0; width: 0; height: 0; overflow: visible; opacity: 0; pointer-events: none; z-index: -1; }
.sim-trun { position: absolute; left: 0; top: 0; box-sizing: border-box; padding: 24px; }
.sim-trun.w720 { width: 720px; }
.sim-trun.w390 { width: 390px; }
.sim-trun.w390 .ab-frame { height: 480px; }

/* Both sections, between the post and This session (web/sim.ts) */
.sim-ads { width: 100%; display: flex; flex-direction: column; gap: 32px; }
.sim-ads:empty { display: none; }

}
@layer page {
/* scene (web/scene.ts, Style guide 6.5 and 7): the header and footer art come alive on sojo.gg hub pages. Until its canvas
   has drawn, .hz shows the static /art/horizon.png. body.sc: the footer art grows to --scene-h and the page gets the same
   room at its end, so on a short page the footer links stay put and the scene shows as you scroll. */
.hz { overflow: hidden; }
.hz.on { background: none; }
.hz.gd.on { transform: none; }
.hz-cv { position: absolute; left: 0; bottom: 0; image-rendering: pixelated; pointer-events: none; }
.hz.gd .hz-cv { top: 0; bottom: auto; }
body.sc { --scene-h: clamp(240px, 50vh, 640px); min-height: calc(100vh + var(--scene-h) - 64px); }
body.sc .hz.gd { height: var(--scene-h); }


}
@layer page {
/* landing: sojo.gg/ (src/landing.ts; Paper 19TF-0 dark 1440, 19XB-0 light 1440, 1A10-0 390, 1A4G-0, 1BAS-0).
   Under 960: the 390 composition on the shared gutter (from 680 the one-line Copy bar). From 960: the 1440 composition
   on the shared column (1200 max), tiles 2x2; the Copy bar sits beside the headline at every desktop width (960+),
   capped at 520px and narrowing to clear the headline's right edge by 48px+ (owner decision 2026-10-26); where that
   isn't room enough the headline steps down in size (960-1199.98, scripts/landing-crop.ts's H1_SIZE) so it always is
   (checked at every width up to 1920). The fort and the moon are
   never cut: narrower heroes use art with them moved (or the moon left out). The art is full bleed at every width: wide
   art (gen/hero-wide.js, the finals byte-identical in the center) in .lp-art, its center on the stage, so the loop canvas
   and the ground line stay on it. Art is 1 px per cell at exactly 4x on whole px. Every box is sized up front from the
   gutter vars, never the viewport unit. */
.lp-main { position: relative; z-index: 1; flex: 1 0 auto; display: flex; flex-direction: column; }
.lp-main h1, .lp-main h2, .lp-main h3, .lp-main p, .lp-main dl, .lp-main dd { margin: 0; }
.lp-n { display: inline; }
/* hero: the stage holds the text, the loop canvas and the log on the art's whole-pixel origin (stage left = art center) */
/* --lpd: the band's room. The Copy bar (or the subline, the lower) to the dither break (.lp-hb, 40): 48 phone, 100
   desktop. The band centered between the break and the dark hills under it (72 phone, 100 desktop, +0-2 under it: the
   post's height isn't on the grid); the light hills are 32/40 higher, so phones keep them 32+ under the post. Stage y
   (bar bottom, band top, post bottom, light/dark hills): 390 410/570/1026/1060/1100; 680-959 324/484/1020/1052/1092;
   960-1279 548/788/1114/1184/1216; 1280+ 480/720/1082/1152/1184 (the bar is 4px taller: two lines in the box). */
/* The hero is split for the band (games in X posts) between the Copy bar and the loop: .lp-sky is the art's top rows
   (phone 40, desktop 84: transparent sky in every variant, the moon and stars), .lp-art the rest moved down by --lpd
   (the band's room). One png per variant for both, px size and position on whole cells (web/bg.ts reads them). */
.lp-hero { --lps: 160px; --lpd: 644px; --lpb: 456px; position: relative; height: calc(912px + var(--lpd)); overflow: clip; container-type: inline-size; }
.lp-sky, .lp-art { position: absolute; left: calc(var(--gl) - 20px - 576px); width: 1544px; pointer-events: none;
  background: url(/art/landing/hero-mdw.png) 0 0 / 1544px 912px no-repeat; image-rendering: pixelated; }
.lp-sky { top: 0; height: var(--lps); }
.lp-art { top: calc(var(--lps) + var(--lpd)); height: calc(912px - var(--lps)); background-position: 0 calc(0px - var(--lps)); }
.lp-stage { position: absolute; top: 0; left: calc(var(--gl) - 20px); right: 0; height: calc(912px + var(--lpd)); box-sizing: border-box;
  padding: 60px 20px 0; display: flex; flex-direction: column; }
.lp-stage h1 { width: max-content; max-width: 100%; font-family: var(--sans); font-weight: 800; font-size: 48px; line-height: 52px; letter-spacing: -0.04em; color: var(--text); }
.lp-row { display: flex; flex-direction: column; }
.lp-sub { width: min(350px, 100%); box-sizing: border-box; padding-top: 20px; font-size: 15px; line-height: 24px; color: var(--muted); }
.lp-ask { display: flex; flex-direction: column; gap: 12px; padding-top: 32px; }
.lp-lab { font-size: 13px; line-height: 16px; color: var(--muted); }
.lp-bar { position: relative; width: min(350px, 100%); box-sizing: border-box; padding: 16px; display: flex; flex-direction: column; gap: 24px; }
.lp-msg { display: flex; gap: 12px; font-size: 15px; line-height: 22px; color: var(--text); }
.lp-gt { color: var(--muted); }
.lp-bs { display: flex; align-items: center; gap: 8px; }
.lp-b { width: 40px; height: 40px; }
.lp-i { display: flex; }
.lp-i svg { display: block; width: 22px; height: 22px; }
.lp-bot .lp-i svg { width: 24px; height: 24px; } /* head 22 of 24 (the mark's viewBox has a 9.94 margin) */
.lp-copy .lp-i svg { width: 20px; height: 20px; }
/* Copied!: absolutely placed, no layout shift. 390: right of the buttons, centered on them. */
.lp-chip { right: 16px; top: 92px; width: 72px; padding: 0; }
.lp-cv { position: absolute; left: 4px; top: calc(628px + var(--lpd)); width: 384px; height: 144px; image-rendering: pixelated; pointer-events: none; }
.lp-log { position: absolute; left: 20px; top: calc(772px + var(--lpd)); width: min(350px, 100% - 40px); height: 140px; box-sizing: border-box; padding: 16px;
  display: flex; flex-direction: column; gap: 6px; background: var(--surface); border: 1px solid var(--line-strong); }
.lp-ln { display: flex; gap: 8px; height: 22px; font-size: 14px; line-height: 22px; white-space: nowrap; }
.lp-mk { flex-shrink: 0; width: 12px; color: var(--chart); }
.lp-tx { color: var(--text); }
/* the Profit counter: its width reserved for the longest value ("$7,794,849"), so the line never reflows; web/loop.ts ramps it */
.lp-ct { flex-shrink: 0; display: inline-block; width: 10ch; color: var(--muted); font-variant-numeric: tabular-nums; transform-origin: 0 60%; }
.lp-tx.typing::after { content: ""; display: inline-block; width: 7px; height: 14px; margin-left: 1px; vertical-align: -2px; background: var(--text); }
html.js:not(.lp-on) .lp-ln { visibility: hidden; }
@media (prefers-reduced-motion: reduce) { html.js:not(.lp-on) .lp-ln { visibility: visible; } }
/* the band: title and line, then the post (desktop: text left, post right). The post depicts a post on X, so it is a
   deliberate local exception to square corners (docs/design.md): a round avatar, 16 px card and media corners. */
/* the break between the hero and the band: an ordered dither (nested Bayer rows) in the wake's dot color, full bleed
   (the hero clips the margins), its columns on the art's 4 px grid (the stage's content edge is on it) */
.lp-hb { --lph: conic-gradient(from 270deg at 4px 4px, var(--line) 25%, transparent 0); flex-shrink: 0; height: 40px; margin: 48px -4000px 0;
  background: var(--lph) 0 0 / 16px 8px repeat-x, var(--lph) 0 8px / 8px 8px repeat-x, var(--lph) 0 16px / 8px 8px repeat-x,
    var(--lph) 4px 20px / 8px 8px repeat-x, var(--lph) 0 28px / 8px 8px repeat-x, var(--lph) 8px 36px / 16px 8px repeat-x; position: relative; }
/* web/landing.ts: the same rows as cells that scatter under the pointer; room above and below to scatter into */
.lp-hb.on { background: none; }
.lp-hb canvas { position: absolute; top: -32px; height: 104px; pointer-events: none; }
.lp-xb { display: flex; flex-direction: column; height: var(--lpb); margin-top: 72px; }
.lp-xt { display: flex; flex-direction: column; gap: 12px; }
.lp-xt h2 { font-family: var(--sans); font-weight: 800; font-size: 36px; line-height: 38px; letter-spacing: -0.03em; color: var(--text); }
.lp-xt p { width: 400px; max-width: 100%; font-size: 14px; line-height: 20px; color: var(--muted); }
.lp-tl { color: inherit; text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 3px; }
.lp-po { margin-top: auto; width: min(350px, 100%); box-sizing: border-box; display: grid; grid-template-columns: 40px minmax(0, 1fr); column-gap: 10px;
  padding: 12px; background: var(--surface); border: 1px solid var(--line); border-radius: 16px; }
.lp-xav { display: block; width: 40px; height: 40px; border-radius: 50%; }
.lp-xbd { min-width: 0; }
.lp-xu { display: flex; gap: 6px; min-width: 0; font-size: 14px; line-height: 20px; white-space: nowrap; }
.lp-xu b { font-weight: 700; color: var(--text); }
.lp-xu span { overflow: hidden; text-overflow: ellipsis; color: var(--muted); }
.lp-xc { margin-top: 2px; font-size: 14px; line-height: 20px; color: var(--text); }
.lp-pm { position: relative; height: 156px; margin-top: 10px; overflow: hidden; background: var(--ground); border: 1px solid var(--line); border-radius: 16px; }
.lp-sb { position: absolute; left: 0; top: 0; display: block; image-rendering: pixelated; }
.lp-xr { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 10px; height: 20px; }
.lp-xa { display: flex; align-items: center; gap: 6px; font-size: 13px; line-height: 20px; color: var(--muted); }
.lp-xa svg { flex-shrink: 0; display: block; width: 16px; height: 16px; }
.lp-xn { font-variant-numeric: tabular-nums; }
/* pillars: as wide as the column; the art centered on whole px, its ground strip continued (the *-mdw art) */
.lp-pil { display: flex; flex-direction: column; gap: 16px; padding: 64px var(--gr) 64px var(--gl); container-type: inline-size; }
.lp-t { position: relative; height: 360px; box-sizing: border-box; display: flex; flex-direction: column; gap: 6px; padding: 260px 24px 0;
  background: var(--surface) round(down, 50%, 4px) 0 / 992px 360px no-repeat; background-origin: border-box; border: 1px solid var(--line); image-rendering: pixelated; }
.lp-royal { background-image: url(/art/landing/royal-mdw.png); }
.lp-ads { background-image: url(/art/landing/ads-mdw.png); }
.lp-gems { background-image: url(/art/landing/gems-mdw.png); }
.lp-identity { background-image: url(/art/landing/identity-mdw.png); }
.lp-t h3 { font-family: var(--sans); font-weight: 800; font-size: 32px; line-height: 36px; letter-spacing: -0.03em; color: var(--text); }
.lp-t p { width: 300px; max-width: 100%; font-size: 14px; line-height: 20px; color: var(--muted); }
/* pricing (information only: Pro and Studio aren't for sale yet). 390: a block per plan; 1440: the table. */
.lp-price { margin: 0 var(--gr) 0 var(--gl); padding: 64px 0; border-top: 1px solid var(--line); }
.lp-price h2 { font-family: var(--sans); font-weight: 800; font-size: 36px; line-height: 38px; letter-spacing: -0.03em; color: var(--text); }
.lp-tb { display: none; }
.lp-pls { margin-top: 16px; }
.lp-pl { display: flex; flex-direction: column; gap: 16px; padding: 24px 0; border-bottom: 1px solid var(--line); }
.lp-pn { display: flex; align-items: baseline; justify-content: space-between; }
.lp-pn b { font-weight: 500; font-size: 15px; line-height: 22px; color: var(--text); }
.lp-pn span { font-size: 14px; line-height: 20px; color: var(--muted); }
.lp-pl dl { display: grid; grid-template-columns: 175px 1fr; row-gap: 16px; }
.lp-pl dl div { display: flex; flex-direction: column; gap: 2px; }
.lp-pl .lp-wide { grid-column: 1 / -1; } /* Unlimited at 36 px is wider than the second column under 390 */
.lp-pl dt { font-size: 12px; line-height: 16px; color: var(--muted); }
.lp-pl dd { font-family: var(--sans); font-weight: 800; font-size: 36px; line-height: 40px; letter-spacing: -0.03em; color: var(--text); }
.lp-hn { padding: 20px 0; font-size: 14px; line-height: 20px; color: var(--text); }
/* from 680: the one-line Copy bar (1440 sizes) and the desktop post */
@media (min-width: 680px) {
  .lp-bar { width: min(650px, 100%); height: 56px; flex-direction: row; align-items: center; justify-content: space-between; gap: 8px; padding: 0 9px 0 16px; }
  .lp-msg { min-width: 0; font-size: 14px; line-height: 20px; white-space: nowrap; }
  .lp-bs { gap: 4px; }
  .lp-b { width: 36px; height: 36px; }
  .lp-i svg { width: 20px; height: 20px; }
  .lp-copy .lp-i svg { width: 18px; height: 18px; }
  .lp-po { width: 534px; column-gap: 12px; padding: 12px 16px; }
  .lp-xu, .lp-xc { font-size: 15px; }
  .lp-pm { height: 252px; margin-top: 12px; }
  .lp-xr { margin-top: 12px; }
}
@media (min-width: 960px) {
  /* the Copy bar sits beside the headline at every desktop width (960+): capped at 520px, narrowing to
     min(520px, 100% - Xpx) so its left edge clears the headline's right edge by 48px+ (scripts/landing-crop.ts's
     hero(), BAR_MIN); where that isn't enough room the headline steps down (the tiers below, each X matching). */
  .lp-row { flex-direction: row; align-items: flex-start; justify-content: space-between; padding-top: 8px; }
  .lp-ask { width: min(520px, calc(100% - 452px)); padding-top: 0; }
  .lp-bar { width: min(520px, 100%); height: 60px; } /* .lp-bar is inside .lp-ask: its 100% is .lp-ask's already-narrowed width, not the row's */
  .lp-msg { white-space: normal; }
  .lp-chip { right: auto; left: calc(100% - 72px); top: -33px; } /* left set from the pressed button (web/landing.ts) */
  .lp-hero { --lps: 336px; --lpd: 572px; --lpb: 362px; height: calc(1056px + var(--lpd)); }
  .lp-sky, .lp-art { left: calc(var(--gl) - 1320px); width: 3840px; background-image: url(/art/landing/hero-dw.png); background-size: 3840px 1056px; }
  .lp-art { height: calc(1056px - var(--lps)); }
  .lp-stage { left: calc(var(--gl) - 120px); right: calc(var(--gr) - 120px); height: calc(1056px + var(--lpd)); padding: 144px 120px 0; }
  /* line-height = font-size: line 1's descenders clear line 2 (owner 2026-10-22). Steps up from 1016 (the tiers
     below) as the Copy bar gets 452px+ room beside it; H1_SIZE in scripts/landing-crop.ts matches exactly. */
  .lp-stage h1 { max-width: none; font-size: 72px; line-height: 72px; letter-spacing: -0.045em; }
  .lp-sub { width: 400px; padding-top: 28px; font-size: 16px; }
  .lp-cv { left: 120px; top: calc(656px + var(--lpd)); width: 448px; height: 144px; }
  .lp-log { left: 120px; top: calc(800px + var(--lpd)); width: 400px; height: 156px; padding: 20px 24px; }
  .lp-ln { gap: 12px; height: 24px; font-size: 15px; line-height: 24px; }
  .lp-mk { width: 16px; }
  .lp-tx.typing::after { width: 8px; height: 15px; }
  .lp-hb { margin-top: 100px; }
  /* text and post centered as one group; the box an even width so the centering lands on whole px */
  .lp-xb { display: grid; grid-template-columns: minmax(0, max-content) auto; justify-content: center; align-items: center; column-gap: 96px;
    width: round(down, 100%, 2px); margin-top: 100px; }
  .lp-xt { gap: 16px; }
  .lp-xt h2 { font-size: 48px; line-height: 52px; }
  .lp-xt p { font-size: 15px; line-height: 22px; }
  .lp-po { margin-top: 0; }
  /* 2x2: Ads and Gems keep their 384 art; Royal and Identity share the rest (792 at 1200), their art cropped centered */
  .lp-pil { display: grid; grid-template-columns: 384px minmax(0, 1fr) 384px; gap: 24px; padding: 120px var(--gr) 120px var(--gl); }
  .lp-royal { grid-column: 1 / 3; } .lp-ads { grid-column: 3; } .lp-gems { grid-column: 1; grid-row: 2; } .lp-identity { grid-column: 2 / 4; grid-row: 2; }
  .lp-t { height: 440px; justify-content: flex-end; gap: 8px; padding: 32px 32px 20px; background-position: 0 0; }
  /* crops on whole cells: Royal centered (the castle stays whole); Identity so both cuts fall between pines and the
     lodge stays 32+ px inside (u = the art px left of the tile: floor4(A - tile), 0-200; A by the column, below) */
  .lp-royal, .lp-identity { background-size: 792px 440px; background-position: round(down, 50%, 4px) 0; }
  .lp-identity { --lpa: 752px; background-position: clamp(-200px, round(up, 100cqw - 408px - var(--lpa), 4px), 0px) 0; }
  .lp-ads, .lp-gems { background-size: 384px 440px; }
  .lp-royal { background-image: url(/art/landing/royal-d.png); }
  .lp-ads { background-image: url(/art/landing/ads-d.png); }
  .lp-gems { background-image: url(/art/landing/gems-d.png); }
  .lp-identity { background-image: url(/art/landing/identity-d.png); }
  .lp-t h3 { font-size: 40px; line-height: 44px; }
  .lp-t p { width: 320px; font-size: 15px; line-height: 22px; }
  .lp-price { margin: 0; padding: 120px var(--gr) 80px var(--gl); } /* 80 + footer 40 = the 120 rhythm */
  .lp-price h2 { font-size: 48px; line-height: 52px; }
  .lp-pls { display: none; }
  .lp-tb { display: table; width: 100%; margin-top: 64px; border-collapse: collapse; table-layout: fixed; }
  .lp-tb th, .lp-tb td { width: 25%; padding: 32px 0; text-align: left; vertical-align: top; border-bottom: 1px solid var(--line); font-weight: 400; }
  .lp-tb thead th { padding: 0 0 20px; border-bottom-color: var(--line-strong); font-size: 15px; line-height: 22px; color: var(--muted); }
  .lp-tb thead th b, .lp-tb thead th span { display: block; }
  .lp-tb thead th b { font-weight: 500; font-size: 15px; line-height: 22px; color: var(--text); }
  .lp-tb thead th span { margin-top: 8px; font-size: 14px; line-height: 20px; color: var(--muted); }
  .lp-tb tbody th { padding-top: 46px; font-size: 15px; line-height: 22px; color: var(--text); }
  .lp-tb tbody td { font-family: var(--sans); font-weight: 800; font-size: 48px; line-height: 52px; letter-spacing: -0.03em; color: var(--text); }
  .lp-tb .lp-host th, .lp-tb .lp-host td { padding: 28px 0; vertical-align: middle; font-family: var(--mono); font-weight: 400; font-size: 15px; line-height: 22px; letter-spacing: 0; }
}
@media (min-width: 960px) and (max-width: 1119.98px) {
  .lp-hero { --lpb: 326px; }
  .lp-xb { column-gap: 48px; } /* 96 would wrap the title to three lines at 960 */
  .lp-xt h2 { font-size: 38px; line-height: 40px; } /* the text column (470 post, 48 gap) is too narrow for 48px here */
  .lp-po { width: 470px; }
  .lp-pm { height: 216px; }
}
/* the headline's size steps (960's 72px is the base above): each step widens the room beside the Copy bar by the
   same px the headline's X (its width + 48px gap) shrinks, so the box stays min(520px, 100% - Xpx) at every step
   (H1_SIZE and h1w in scripts/landing-crop.ts). --lpd (the art's ground offset) follows the headline's height. */
@media (min-width: 1016px) {
  .lp-stage h1 { font-size: 80px; line-height: 80px; }
  .lp-ask { width: min(520px, calc(100% - 500px)); }
  .lp-hero { --lpd: 588px; }
}
@media (min-width: 1056px) {
  .lp-stage h1 { font-size: 88px; line-height: 88px; }
  .lp-ask { width: min(520px, calc(100% - 544px)); }
  .lp-hero { --lpd: 604px; }
}
@media (min-width: 1100px) {
  .lp-stage h1 { font-size: 96px; line-height: 96px; }
  .lp-ask { width: min(520px, calc(100% - 588px)); }
  .lp-hero { --lpd: 620px; }
}
@media (min-width: 1152px) {
  .lp-stage h1 { font-size: 104px; line-height: 104px; }
  .lp-ask { width: min(520px, calc(100% - 632px)); }
  .lp-hero { --lpd: 636px; }
}
@media (min-width: 1200px) {
  .lp-stage h1 { font-size: 112px; line-height: 112px; }
  .lp-ask { width: min(520px, calc(100% - 676px)); }
  .lp-hero { --lpd: 652px; }
}
@media (min-width: 1120px) and (max-width: 1439.98px) {
  .lp-xt h2 { font-size: 44px; line-height: 48px; } /* the text column (534 post, 96 gap) is still too narrow for 48px up to 1440 */
}
@media (prefers-color-scheme: light) {
  :root:not(.dark) .lp-mk { color: var(--royal); }
  :root:not(.dark) .lp-sky, :root:not(.dark) .lp-art { background-image: url(/art/landing/hero-mlw.png); }
  :root:not(.dark) .lp-royal { background-image: url(/art/landing/royal-mlw.png); }
  :root:not(.dark) .lp-ads { background-image: url(/art/landing/ads-mlw.png); }
  :root:not(.dark) .lp-gems { background-image: url(/art/landing/gems-mlw.png); }
  :root:not(.dark) .lp-identity { background-image: url(/art/landing/identity-mlw.png); }
}
@media (prefers-color-scheme: light) and (min-width: 960px) {
  :root:not(.dark) .lp-sky, :root:not(.dark) .lp-art { background-image: url(/art/landing/hero-lw.png); }
  :root:not(.dark) .lp-royal { background-image: url(/art/landing/royal-l.png); }
  :root:not(.dark) .lp-ads { background-image: url(/art/landing/ads-l.png); }
  :root:not(.dark) .lp-gems { background-image: url(/art/landing/gems-l.png); }
  :root:not(.dark) .lp-identity { background-image: url(/art/landing/identity-l.png); }
}
/* the identity crop's A by the column width (the 2x2 tile is column - 408): left cut in 0-60, 88-96 or 124-200 art px,
   right cut in 688-696, 720-736 or 748-792, at every column 897-1200, checked by tests/landing-crop.test.ts */
@container (max-width: 1096.98px) { .lp-identity { --lpa: 692px; } }
@container (max-width: 1036.98px) { .lp-identity { --lpa: 752px; } }
@container (max-width: 955.98px) { .lp-identity { --lpa: 692px; } }
/* Royal: where the centered crop would slice a pine, shift it a cell or two (the castle stays whole) */
@container (min-width: 1061px) and (max-width: 1067.98px) { .lp-royal { background-position: -64px 0; } }
@container (min-width: 1120px) and (max-width: 1135.98px) { .lp-royal { background-position: -44px 0; } }
/* mid widths: the fort (cols 261-336) and the moon (252-331) whole or not at all. Moved art from a 1028 hero, the 1440
   art from 1256 (fort right edge on screen; hero-wide.js). Under 1036 the moon is left out (moved 32 cells, its glow ends at hero x 1012). */
@media (min-width: 960px) {
  @container (max-width: 1255.98px) { .lp-sky, .lp-art { background-image: url(/art/landing/hero-dn.png); } }
  @container (max-width: 1035.98px) { .lp-sky, .lp-art { background-image: url(/art/landing/hero-dx.png); } }
}
@media (min-width: 960px) and (prefers-color-scheme: light) {
  @container (max-width: 1255.98px) { :root:not(.dark) .lp-sky, :root:not(.dark) .lp-art { background-image: url(/art/landing/hero-ln.png); } }
  @container (max-width: 1035.98px) { :root:not(.dark) .lp-sky, :root:not(.dark) .lp-art { background-image: url(/art/landing/hero-lx.png); } }
}
/* 680-959: a wider subline and log; the post left on the column */
/* 680-719: the bar can't reach 650, so the one-line prompt steps down to fit */
@media (min-width: 680px) and (max-width: 719.98px) { .lp-msg { font-size: 13px; } }
@media (min-width: 680px) and (max-width: 959.98px) {
  .lp-sub { width: min(480px, 100%); }
  .lp-log { width: 400px; }
  .lp-msg .lp-n { display: none; }
  .lp-chip { right: auto; left: 533px; top: -33px; }
  .lp-hero { --lpd: 636px; --lpb: 536px; }
}

}
