/* Margin Call: the trading floor's colours (same family as the crash game), one dark look on purpose. */
:root {
  --bg: #0a1c26; --panel: #10293a; --panel-2: #153447; --line: #22495c; --deep: #071219;
  --fg: #e9f4f1; --soft: #bfd8d5; --muted: #8eb0b4;
  --accent: #ffb547; --accent-ink: #2a1700; --up: #52d38f; --down: #ff5d52; --even: #7cc4ff; --sl: #ff8f6b;
  --f-display: "Rubik Mono One", "Rubik", system-ui, sans-serif;
  --f-body: "Rubik", system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-mono: "JetBrains Mono", ui-monospace, Menlo, Consolas, monospace;
  color-scheme: dark;
}
[hidden] { display: none !important; }
html, body { background: var(--bg); color: var(--fg); margin: 0; }
body { font: 15px/1.45 var(--f-body); }
button, input { font: inherit; color: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 2px solid var(--even); outline-offset: 2px; }
h1, h2, h3, p { margin: 0; }

.app {
  max-width: 1640px; margin: 0 auto; padding: 12px 16px 32px; display: grid; gap: 14px; align-items: start;
  grid-template-columns: 384px minmax(0, 1fr) 340px;
  grid-template-areas: "top top top" "bank market side" "bank lower side";
  grid-template-rows: auto auto 1fr; /* the tall side columns stretch the last row, never the chart's */
}
.top { grid-area: top; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.market { grid-area: market; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.side { grid-area: side; min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.lower { grid-area: lower; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.lower > .score { margin-top: 12px; } /* the review card under the closed trades, on a wide screen (main.js) */
.bank { grid-area: bank; min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 14px; display: flex; flex-direction: column; gap: 10px; min-width: 0; }

/* header */
h1 { font: 400 clamp(20px, 2.6vw, 23px)/1 var(--f-display); letter-spacing: .02em; }
h1 span { color: var(--accent); }
.where { color: var(--muted); font-size: 13px; }
.where b { color: var(--fg); font-weight: 600; }
.money { display: flex; gap: 6px; margin-left: auto; flex-wrap: wrap; }
.money > div { background: var(--panel); border: 1px solid var(--line); border-radius: 999px; padding: 5px 11px; display: flex; gap: 8px; align-items: baseline; }
.lbl { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.money b { font: 600 16px var(--f-mono); font-variant-numeric: tabular-nums; }
.pill { background: none; border: 1px solid var(--line); border-radius: 999px; padding: 6px 14px; color: var(--soft); font-size: 13px; }
.pill:hover { border-color: var(--muted); color: var(--fg); }
.pill.icon { padding: 6px 10px; display: inline-flex; align-items: center; }
.pill.save { border-color: var(--accent); color: var(--fg); }
.pill.mood { text-decoration: none; display: inline-flex; gap: 6px; align-items: baseline; }
.pill.mood b { font: 700 12px var(--f-mono); color: var(--fg); background: var(--panel-2); border-radius: 999px; padding: 1px 7px; }
.pill.mood.fear b { color: var(--down); } .pill.mood.greed b { color: var(--up); }
.pill.mood .fg-words { color: var(--muted); font-size: 12px; }
/* the pixel newspaper stands for the word "Journal" on a phone only (the 760px block below); 14px, one pixel a square */
.pill.mood .np { display: none; flex: none; align-self: center; width: 14px; height: 14px; shape-rendering: crispEdges; }
.pill.icon svg { width: 16px; height: 16px; shape-rendering: crispEdges; }
/* THE RANK AS A BADGE (owner, 2026-10-28, phones; 2026-10-29 on a wide screen too): a pill like the Journal and the sound button beside it, in its floor's tier, the
   way a game's achievements go up (main.js RANK_TIERS): wood at the junior desk, bronze for a trader, silver for a senior,
   gold for the head of desk. A metal plate's light: a bright pixel line on top, a dark one below. "Hyper Bank" stays
   before it while the line has room (main.js fitMood takes it out first, .bare, so the Fear & Greed words can stay; owner 2026-10-29) */
.where .where-dot { display: none; }
#rank { flex: none; padding: 6px 10px; border: 1px solid var(--edge); border-radius: 999px; color: var(--ink); font-size: 12px; line-height: 18px; font-weight: 600;
  background: linear-gradient(180deg, var(--hi), var(--lo)); box-shadow: inset 0 1px 0 var(--shine), inset 0 -1px 0 rgba(0, 0, 0, .35); }
#rank, #rank[data-tier="wood"] { --edge: #84593a; --ink: #e8c9a0; --hi: #3b2818; --lo: #281a0e; --shine: rgba(255, 220, 175, .14); }
#rank[data-tier="wood"], #rank:not([data-tier]) { background: repeating-linear-gradient(180deg, transparent 0 5px, rgba(0, 0, 0, .14) 5px 6px), linear-gradient(180deg, var(--hi), var(--lo)); } /* the grain */
#rank[data-tier="bronze"] { --edge: #cd7f3e; --ink: #ffad74; --hi: #522b11; --lo: #341805; --shine: rgba(255, 190, 140, .32); }
#rank[data-tier="silver"] { --edge: #b4c0cc; --ink: #f2f6fa; --hi: #3c4854; --lo: #252f39; --shine: rgba(255, 255, 255, .34); }
#rank[data-tier="gold"] { --edge: #f2b230; --ink: #ffd96b; --hi: #4f3908; --lo: #322303; --shine: rgba(255, 233, 160, .4); }
/* THE WIDE SCREEN'S HEADER (owner, 2026-10-29): one row. The name beside the rank badge, the return inside the equity pill
   in green or red (its own pill goes); a guest's "Save your desk" right after the name, as on a phone; then free cash, the
   Journal, language, sound. Phones keep their three boxes */
.where { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.eq-ret { display: none; }
@media (min-width: 761px) {
  .top h1 { order: 1; } .where { order: 2; } #nameBtn { order: 3; } #saveBtn { order: 4; } .money { order: 5; } #moodChip { order: 6; }
  .lang-wrap { order: 7; } #soundBtn { order: 8; }
  .top { column-gap: 10px; }
  /* the Journal as the pixel newspaper, as on a phone, then Fear & Greed and the number */
  .pill.mood { gap: 6px; } .pill.mood .np { display: block; } .pill.mood .mood-word { display: none; }
  .where.bare .where-bank, .pill.mood.tight .fg-words { display: none; } /* main.js fitMood, when the row is short of room */
  .top.snug .money > div { padding: 5px 9px; gap: 6px; } .top.snug .money b { font-size: 14px; } .top.snug .pill { padding-left: 11px; padding-right: 11px; }
  .money .m-ret { display: none; }
  .eq-ret { display: inline; font: 600 13px var(--f-mono); font-variant-numeric: tabular-nums; color: var(--muted); }
  /* the market tabs in one row that scrolls sideways; a fade on the side where more markets wait (main.js tabsEdges) */
  .tabs.more-end { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent); }
  .tabs.more-start { -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 56px), transparent); }
  .tabs.more-start.more-end { -webkit-mask-image: linear-gradient(to right, transparent, #000 56px, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(to right, transparent, #000 56px, #000 calc(100% - 56px), transparent); }
  [dir=rtl] .tabs.more-end:not(.more-start) { -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 56px), transparent); }
  [dir=rtl] .tabs.more-start:not(.more-end) { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 56px), transparent); }
}
#soundBtn[aria-pressed="true"] .off, #soundBtn[aria-pressed="false"] .on { display: none; }
/* the language: a short code (a pixel globe and EN) with the full select laid over it, invisible, so a tap or a click still
   opens the full list of languages (owner, 2026-10-28 phones; 2026-10-29 wide screens too, so the header fits one row) */
.lang-wrap { position: relative; display: inline-flex; }
.lang-wrap[hidden] { display: none; }
.lang-code { display: inline-flex; align-items: center; gap: 5px; padding: 6px 10px; }
.lang-code b { font: 600 12px var(--f-mono); letter-spacing: .04em; }
.lang-wrap select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.lang-wrap:focus-within .lang-code { border-color: var(--accent); color: var(--fg); }
#soundBtn[aria-pressed="false"] { color: var(--muted); }
.up { color: var(--up) !important; }
.down { color: var(--down) !important; }

/* markets and chart */
.tabs { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: thin; padding-bottom: 2px; }
/* what the market is, folded, right under the market tabs and above the timeframes (owner, 2026-10-28 phones, 2026-10-29 all) */
.market > * { order: 3; }
.market > .tabs { order: 1; }
.market > .about { order: 2; }
/* on a wide screen the tabs wrap to a second row instead of hiding markets behind a scrollbar (ten markets on
   2026-10-27, more every week); a phone or a narrow tablet keeps the one row that scrolls (wrapped there, the tabs
   would take four rows) */
/* one row at every width, scrolling sideways (owner, 2026-10-29: "few markets for now, we will see") */
.tabs button { flex: 0 0 auto; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 7px 12px; display: grid; gap: 1px; text-align: left; min-width: 104px; }
.tabs button[aria-selected="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.tabs b { font: 600 13px var(--f-mono); display: flex; align-items: center; gap: 6px; direction: ltr; }
/* the market's pixel icon before its ticker (owner, 2026-10-28; src/icons.js, 16x16 square pixels). Its size, --mi, is
   set by main.js so every art pixel is a whole number of the screen's dots (crisp): 24px on a 2x screen, 21.3 on a 3x
   phone, 16 on a 1x monitor, never over 26. The margins keep the tab's height as it was (the ticker's line is 17px),
   the icon reaching into the tab's padding */
.tabs .mi { flex: none; width: var(--mi, 24px); height: var(--mi, 24px); margin: calc((17px - var(--mi, 24px)) / 2) 0; }
.tabs .px { font: 12px var(--f-mono); color: var(--soft); font-variant-numeric: tabular-nums; }
.tabs small { font-size: 11px; color: var(--muted); }
.market .bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } /* scoped: another .bar, the house rules list, is a grid further down */
/* the selected market in plain words, folded under the chart */
.about { font-size: 13px; color: var(--soft); line-height: 1.45; }
.about summary { cursor: pointer; color: var(--muted); font: 600 12px var(--f-mono); letter-spacing: .04em; text-transform: uppercase; }
.about summary:hover { color: var(--text); }
.about p { margin: 7px 0 0; }
.about a { color: var(--accent); }
/* the chart's indicators and drawing tools, folded under one word (owner, 2026-10-21: a simple chart first) */
.ctools-row { display: flex; gap: 10px; flex-wrap: wrap; margin: 6px 0 0; }
.ctools-row[hidden] { display: none; }
.cmode { margin-left: 4px; }
/* what a level means, in plain words, under its switch: always open (owner, 2026-10-23) */
.lvl-hint { margin: 5px 0 0; font-size: 12px; line-height: 1.45; color: var(--muted); }
.fold > summary { cursor: pointer; font: 600 12px var(--f-mono); letter-spacing: .04em; text-transform: uppercase; color: var(--muted); padding: 8px 0; }
.fold > summary:hover { color: var(--fg); }
.seg { display: flex; gap: 4px; }
.seg button { background: none; border: 1px solid var(--line); border-radius: 8px; padding: 4px 10px; font: 12px var(--f-mono); color: var(--muted); }
.seg button[aria-checked="true"] { color: var(--fg); border-color: var(--accent); }
.src { margin-left: auto; font-size: 12px; color: var(--muted); }
/* the level line on the left, the price credit with its referral link right above the chart's top right corner */
.chart-meta { display: flex; align-items: flex-end; gap: 4px 14px; flex-wrap: wrap; margin: 0 0 6px; }
.chart-meta .lvl-hint { flex: 1 1 260px; margin: 6px 0 0; }
.chart-meta .src { flex: 0 0 auto; margin-left: auto; white-space: nowrap; }
.src a { color: inherit; }
.ref-tag { font-size: 10px; border: 1px solid var(--line); border-radius: 6px; padding: 0 4px; margin-left: 4px; }
.chart { position: relative; width: 100%; height: 460px; border: 1px solid var(--line); border-radius: 14px; background: var(--deep); overflow: hidden; }
.chart.drawing { cursor: crosshair; }
.chart .legend { position: absolute; left: 10px; top: 8px; z-index: 3; font: 11px var(--f-mono); color: var(--muted); pointer-events: none; font-variant-numeric: tabular-nums; }
.chart .legend b { color: var(--fg); font-weight: 600; margin-right: 6px; }
.chart .hint { position: absolute; left: 50%; top: 8px; transform: translateX(-50%); z-index: 3; font-size: 12px; color: var(--accent); background: rgba(7,18,25,.85); border-radius: 8px; padding: 2px 8px; pointer-events: none; }
.chart .hint:empty { display: none; }
.seg button[aria-pressed="true"] { color: var(--fg); border-color: var(--accent); }

/* ticket */
.sides { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.sides button { background: var(--deep); border: 1px solid var(--line); border-radius: 10px; padding: 8px; font-weight: 600; display: grid; gap: 1px; color: var(--soft); }
.sides small { font-weight: 400; font-size: 11px; color: var(--muted); }
#long[aria-checked="true"] { border-color: var(--up); color: var(--up); box-shadow: inset 0 0 0 1px var(--up); }
#short[aria-checked="true"] { border-color: var(--down); color: var(--down); box-shadow: inset 0 0 0 1px var(--down); }
.field { display: grid; gap: 4px; font-size: 12px; color: var(--muted); letter-spacing: .04em; }
.field b { color: var(--fg); font: 600 12px var(--f-mono); }
.field input[type="number"], .field .in, #charSign { background: var(--deep); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; font: 14px var(--f-mono); width: 100%; box-sizing: border-box; min-width: 0; }
.field .in { display: flex; align-items: center; gap: 6px; padding: 0 10px; }
.field .in i { font-style: normal; color: var(--muted); }
.field .in input { border: 0; background: none; padding: 8px 0; outline: none; width: 100%; font: 14px var(--f-mono); }
.field input[type="range"] { width: 100%; accent-color: var(--accent); }
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.pair > div { display: grid; gap: 4px; min-width: 0; align-content: start; } /* the Stop column is taller (the Trail field): the Target's rows do not stretch to match */
.quick { display: flex; gap: 4px; }
.quick button { flex: 1; background: var(--deep); border: 1px solid var(--line); border-radius: 6px; padding: 4px 0; font: 12px var(--f-mono); color: var(--soft); }
.quick.small button { font-size: 11px; padding: 3px 0; }
.quick button:hover { border-color: var(--muted); }
.preview { display: grid; grid-template-columns: auto 1fr; gap: 3px 10px; margin: 0; font-size: 13px; }
.preview dt { color: var(--muted); }
.preview dd { margin: 0; text-align: right; font: 13px var(--f-mono); font-variant-numeric: tabular-nums; }
.go { font: 400 14px var(--f-display); letter-spacing: .02em; background: var(--accent); color: var(--accent-ink); border: 0; border-radius: 10px; padding: 12px; box-shadow: 0 3px 0 #0b0b0b; }
.go:active { transform: translateY(2px); box-shadow: 0 1px 0 #0b0b0b; }
.go.short { background: var(--down); color: #2a0806; }
.go.long { background: var(--up); color: #06210f; }
.go:disabled { background: var(--panel-2); color: var(--muted); cursor: default; }
.ghost { background: none; border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px; color: var(--soft); }
.msg { min-height: 18px; font-size: 13px; color: var(--soft); }
.msg.bad { color: var(--down); }
/* inside Telegram, once: may the bot tell the player how the market closed the trade (main.js askTelegramWrite) */
.tg-ask { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 13px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; }
.tg-ask span { flex: 1 1 100%; }
/* the same card asks at two moments (owner 2026-10-29): on the first visit from Telegram, docked at the bottom of the screen,
   and after a trade opens, in the ticket; each shows its own words */
.tg-ask[data-when="entry"] .tg-ask-trade, .tg-ask[data-when="trade"] .tg-ask-entry { display: none; }
.tg-ask button { border-radius: 8px; padding: 5px 12px; font-size: 13px; }
.tg-ask .tg-yes { background: var(--accent); color: var(--accent-ink); border: 0; font-weight: 600; }
.tg-ask .tg-no { background: none; border: 1px solid var(--line); color: var(--soft); }
.tg-head { display: none; }
/* the first visit's card, DOCKED (owner, 2026-10-29: 116 new players from the Mini App ads in an hour, 5 let the bot write;
   the card sat in the header under the first visit's dialogs): fixed at the bottom of the screen, a phone's width less its
   margins, over the page and Lea's dimmed walk-through (#coach, z-index 40). main.js keeps her bubble above it and lifts
   the floating ticket button by its height (--dock); the toasts go to the top of the screen meanwhile, or above the card
   while her walk-through needs the top (html.toasts-up, main.js placeToasts), so neither they nor the card cover her
   bubble; a dialog open hides it */
.tg-ask.dock { position: fixed; left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); z-index: 46; box-sizing: border-box; max-width: 440px; margin: 0 auto; gap: 10px; padding: 12px 14px 14px; font-size: 14px; line-height: 1.45; background: var(--panel); border: 1px solid var(--accent); border-radius: 14px; box-shadow: 0 3px 0 #0b0b0b, 0 12px 40px rgba(0, 0, 0, .55); }
.tg-ask.dock .tg-head { display: flex; align-items: center; gap: 7px; flex: 1 1 100%; font: 400 11px var(--f-display); letter-spacing: .1em; color: var(--accent); }
.tg-ask.dock .tg-head svg { width: 14px; height: 14px; flex: none; shape-rendering: crispEdges; }
.tg-ask.dock button { padding: 10px 14px; font-size: 14px; border-radius: 10px; }
.tg-ask.dock .tg-yes { flex: 1 1 auto; box-shadow: 0 3px 0 #0b0b0b; }
.tg-ask.dock span { text-wrap: pretty; }
html:has(dialog[open]) .tg-ask.dock { display: none; }
/* while it stands the page ends above it, so its last lines scroll clear of the card, and a target scrolled to the centre
   (Lea's walk-through) is centred in the room above it */
html.docked { scroll-padding-bottom: var(--dock, 0px); }
html.docked body { padding-bottom: var(--dock, 0px); }
/* the toasts above the card (and above the floating ticket button), or at the top of the screen (html.toasts-up). Both ends
   are set on the rule the floating button has (bottom: 70px, below): a top beside that bottom stretched a toast over half
   the screen (review 2026-10-29, 360x640) */
html.docked .toasts { bottom: calc(16px + var(--dock, 0px) + env(safe-area-inset-bottom, 0px)); }
html.docked .to-ticket:not([hidden]) ~ .toasts { bottom: calc(70px + var(--dock, 0px) + env(safe-area-inset-bottom, 0px)); }
html.toasts-up .toasts, html.toasts-up .to-ticket:not([hidden]) ~ .toasts { top: calc(12px + env(safe-area-inset-top, 0px)); bottom: auto; }

/* review */
.score h2, .lower h2, .open-book h2, .closed-book h2, .desk h2 { font: 400 13px var(--f-display); letter-spacing: .06em; color: var(--accent); }
/* the open positions and the closed trades, each with its heading: the top of the book on a wide screen, under the ticket
   on a phone, the closed trades right after the open positions (main.js placeBook) */
.open-book, .closed-book { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
/* the closed trades fold like "What is this market?" (owner 2026-10-29): the heading is the switch, the count beside it;
   open on a wide screen, folded on a phone, the player's own choice kept (prefs.closedOpen, src/main.js) */
.closed-fold > summary { cursor: pointer; color: var(--accent); font-size: 13px; }
.closed-fold > summary h2 { display: inline; margin: 0; }
.closed-n { margin-inline-start: 8px; font: 600 12px var(--f-mono); color: var(--muted); }
.closed-fold[open] > .tbl { margin-top: 8px; }
.desk h3 { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); font-weight: 600; margin-top: 4px; }
.grades { display: flex; gap: 18px; align-items: flex-end; }
.grade { display: grid; gap: 2px; }
.grade b { font: 400 46px/1 var(--f-display); }
.grade small { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.gA, .gB { color: var(--up); } .gC { color: var(--accent); } .gD, .gF { color: var(--down); } .gN { color: var(--muted); }
.prelim { font-size: 12px; color: var(--muted); }
.metrics { display: grid; grid-template-columns: 1fr auto; gap: 3px 10px; font-size: 13px; margin: 0; }
.metrics dt { color: var(--muted); }
.metrics dd { margin: 0; font: 13px var(--f-mono); text-align: right; font-variant-numeric: tabular-nums; }
.voices { display: grid; gap: 8px; }
.voices p { font-size: 13px; color: var(--soft); border-left: 3px solid var(--line); padding-left: 10px; }
.voices b { color: var(--accent); font: 600 11px var(--f-mono); letter-spacing: .06em; display: block; }

/* tables */
.tbl { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); }
.tbl table { border-collapse: collapse; width: 100%; font-size: 13px; }
.tbl th, .tbl td { padding: 7px 10px; text-align: right; white-space: nowrap; border-bottom: 1px solid var(--line); }
.tbl th { font-weight: 600; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); background: var(--panel-2); }
.tbl th:first-child, .tbl td:first-child { text-align: left; }
.tbl tr:last-child td { border-bottom: 0; }
.tbl td { font-family: var(--f-mono); font-variant-numeric: tabular-nums; }
.tbl td.txt { font-family: var(--f-body); }
.tbl .empty { color: var(--muted); font-family: var(--f-body); text-align: left; padding: 12px; }
.tbl input { width: 92px; background: var(--deep); border: 1px solid var(--line); border-radius: 6px; padding: 3px 6px; font: 12px var(--f-mono); }
.tbl button { background: none; border: 1px solid var(--line); border-radius: 6px; padding: 3px 9px; font-size: 12px; color: var(--soft); }
.tbl button.close { border-color: var(--accent); color: var(--accent); }
.tag { font: 600 10px var(--f-body); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); border: 1px solid var(--line); border-radius: 999px; padding: 0 6px; margin-left: 6px; }

/* open positions: one card each */
.positions { display: grid; gap: 8px; }
.pos { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; display: grid; gap: 8px; }
.pos-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.pos-head b { font: 600 15px var(--f-mono); }
.pos-head .sz { color: var(--muted); font: 13px var(--f-mono); }
.pos-head .pl { margin-left: auto; font: 600 15px var(--f-mono); font-variant-numeric: tabular-nums; }
.tag.long { color: var(--up); border-color: var(--up); }
.tag.short { color: var(--down); border-color: var(--down); }
.pos-nums { display: grid; grid-template-columns: repeat(3, auto 1fr); gap: 2px 8px; margin: 0; font-size: 13px; }
.pos-nums dt { color: var(--muted); }
.pos-nums dd { margin: 0; font: 13px var(--f-mono); font-variant-numeric: tabular-nums; }
.pos-orders { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; font-size: 12px; color: var(--muted); }
.pos-orders label { display: flex; align-items: center; gap: 6px; }
.pos-orders input { width: 100px; background: var(--deep); border: 1px solid var(--line); border-radius: 6px; padding: 4px 6px; font: 12px var(--f-mono); }
.pos-orders button { background: none; border: 1px solid var(--line); border-radius: 6px; padding: 4px 10px; font-size: 12px; color: var(--soft); }
.pos-orders button.close { border-color: var(--accent); color: var(--accent); margin-left: auto; }
p.empty.card { color: var(--muted); font-size: 14px; }
@media (max-width: 520px) { .pos-nums { grid-template-columns: auto 1fr; } }

.key-text { background: var(--deep); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; font: 13px var(--f-mono); word-break: break-all; white-space: pre-wrap; user-select: all; margin: 0 0 12px; }

/* the bank */
#building { width: 384px; max-width: 100%; aspect-ratio: 128 / 244; display: block; image-rendering: pixelated; border-radius: 14px; border: 1px solid var(--line); }
.board-row { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto 24px 24px; gap: 6px; align-items: center; font-size: 13px; padding: 3px 0; border-bottom: 1px solid var(--line); }
.board-row:last-child { border-bottom: 0; }
.out { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 10px; font-size: 13px; }
.out a { color: var(--accent); }
.out .link { font-size: 13px; color: var(--muted); }
.syn { display: flex; flex-direction: column; gap: 8px; }
.syn-lead { color: var(--soft); font-size: 13px; }
.syn-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.syn-head b { font-size: 15px; }
.syn-head.big b { font-size: 18px; }
.syn-tag { font: 700 11px var(--f-mono); letter-spacing: .08em; color: #0a1c26; background: var(--c); border-radius: 6px; padding: 2px 6px; }
.syn-members { display: flex; flex-direction: column; }
.syn-m { display: grid; grid-template-columns: minmax(0, 1fr) auto 22px 22px auto; gap: 6px; align-items: center; font-size: 13px; padding: 4px 0; border-bottom: 1px solid var(--line); }
.syn-m:last-child { border-bottom: 0; }
.syn-m.me .nm { color: var(--accent); }
.syn-m .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.syn-m .r { font: 12px var(--f-mono); text-align: right; }
.syn-m .g { font: 700 12px var(--f-mono); text-align: center; }
.syn-invite { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pill-btn { align-self: flex-start; background: var(--accent); color: var(--accent-ink, #2a1700); border: 0; border-radius: 10px; padding: 8px 14px; font: 600 13px var(--f-body); cursor: pointer; }
input.upper { text-transform: uppercase; }
.syn-dlg .field input { background: var(--deep); border: 1px solid var(--line); border-radius: 8px; padding: 9px 10px; font: 15px var(--f-body); width: 100%; box-sizing: border-box; }
.syn-dlg form { display: grid; gap: 12px; }
#synBody .field + .field, #synBody .field + .opt { margin-top: 12px; } /* each label clear of the field above it */
.board-row.me { color: var(--accent); }
.board-row .n { color: var(--muted); font: 12px var(--f-mono); }
.board-row .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board-row .r { font: 12px var(--f-mono); text-align: right; }
.board-row .g { font: 400 12px var(--f-display); text-align: center; }
.bot { display: grid; gap: 2px; font-size: 13px; }
.bot b { color: var(--fg); }
.bot p { color: var(--muted); font-size: 12px; }

/* dialogs and toasts */
dialog { overflow: visible; background: var(--panel); color: var(--fg); border: 1px solid var(--line); border-radius: 16px; padding: 20px; width: min(520px, calc(100vw - 32px)); box-sizing: border-box; }
dialog::backdrop { background: rgba(3, 8, 12, .72); }
.eyebrow { font: 400 11px var(--f-display); letter-spacing: .12em; color: var(--accent); margin-bottom: 12px; }
dialog.intro { width: fit-content; max-width: calc(100vw - 24px); padding: 14px 16px; }
dialog.intro .eyebrow { margin-bottom: 8px; }
/* on a short screen (under about 600px: a landscape phone, a Telegram sheet) the picture gets smaller so the caption and the
   buttons still fit; the caption keeps at least 256px for its words. A taller screen is as before */
#introCanvas { display: block; height: min(58vh, 600px); height: min(58vh, 600px, calc(100dvh - 250px)); aspect-ratio: 128 / 244; max-width: 100%; margin: 0 auto; border-radius: 12px; border: 1px solid var(--line); image-rendering: pixelated; }
#intro .caption { width: calc(min(58vh, 600px) * 128 / 244); width: max(calc(min(58vh, 600px, calc(100dvh - 250px)) * 128 / 244), 256px); max-width: 100%; min-height: 86px; display: grid; align-content: start; gap: 4px; margin: 10px auto 0; }
#intro .who { font: 600 12px var(--f-mono); letter-spacing: .08em; color: var(--accent); min-height: 15px; }
#intro .who.you { color: var(--even); }
#intro .say { font-size: 15px; line-height: 1.45; }
#intro .actions { margin-top: 8px; }
/* week one: the tasks, the house rules in the ticket, the talk with Lea */
.house { display: flex; flex-wrap: wrap; gap: 5px; }
.house .rule { font: 600 11px var(--f-mono); border: 1px solid var(--line); border-radius: 999px; padding: 3px 8px; color: var(--muted); }
.house .rule.ok { color: var(--up); border-color: #2f6b4a; }
.house .rule.no { color: var(--down); border-color: #6b2f2f; }
.cost-hint { flex-basis: 100%; margin-top: 2px; font-size: 11.5px; line-height: 1.4; color: var(--muted); }
.cost-hint.warn { color: var(--down, #ff5d52); }
.story h2 small { font: 500 12px var(--f-mono); color: var(--muted); margin-left: 6px; letter-spacing: 0; }
.story-lead { color: var(--soft); font-size: 13px; }
.tasks { list-style: none; padding: 0; margin: 0; display: grid; gap: 6px; }
.tasks li { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.tasks .tick { flex: none; width: 18px; height: 18px; border-radius: 5px; border: 1px solid var(--line); display: grid; place-items: center; font: 700 12px var(--f-mono); color: var(--up); }
.tasks li.done .txt { color: var(--muted); } /* the tick says done; a strike-through read as cancelled (owner, 2026-10-30) */
.tasks li.done .tick { border-color: #2f6b4a; background: #12301f; }
.tasks .txt { flex: 1; }
.tasks .txt small { color: var(--accent); font: 12px var(--f-mono); margin-left: 4px; }
.tasks li.due .tick { color: var(--accent); border-color: var(--accent); }
.bar { list-style: none; padding: 0; margin: 0 0 4px; display: grid; gap: 4px; font-size: 14px; }
.bar li.ok { color: var(--up); }
.bar li.no { color: var(--down); }
.tasks .pill { flex: none; padding: 4px 10px; font-size: 12px; border-color: var(--accent); color: var(--fg); }
/* THE CHALLENGE CARD (server/story.mjs; main.js challengeCard, owner 2026-10-29): Marco's promotion challenge on the week card,
   ten pips (green by the house rules, amber not, hollow to come; each says so in its title), the profit against the goal, a meter from the 5% limit
   (left) to the goal (right) with zero, the lowest value (a dark red tick) and now (the dot). The pips, the meter and its
   ends run left to right on every page (like the chart); the words follow the page. No fixed widths: at 360px a pip is ~26px */
.ch { display: grid; gap: 8px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2); min-width: 0; }
.ch-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 4px 8px; }
.ch-head h3 { margin: 0; font: 400 13px var(--f-display); letter-spacing: .06em; color: var(--accent); }
.ch-head small { font: 600 12px var(--f-mono); color: var(--soft); }
.ch-pips { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 4px; }
.ch-pips i { height: 8px; border-radius: 3px; border: 1px solid var(--line); }
.ch-pips i.ok { background: var(--up); border-color: var(--up); }
.ch-pips i.no { background: var(--accent); border-color: var(--accent); }
.ch-row { margin: 0; font-size: 13px; line-height: 1.4; color: var(--soft); overflow-wrap: anywhere; }
.ch-row b { font: 600 13px var(--f-mono); color: var(--fg); white-space: nowrap; }
.ch-row b.up { color: var(--up); }
.ch-row b.down { color: var(--down); }
.ch-meter { position: relative; height: 10px; margin: 2px 5px; border-radius: 999px; background: var(--deep); border: 1px solid var(--line); }
.ch-meter > span { position: absolute; top: 0; bottom: 0; }
.ch-meter .ch-zero { width: 1px; background: var(--muted); }
.ch-meter .ch-fill { border-radius: 999px; opacity: .8; }
.ch-meter .ch-low { width: 2px; margin-left: -1px; background: #b3261e; }
.ch-meter .ch-now { top: 50%; bottom: auto; width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%; background: var(--fg); box-shadow: 0 0 0 2px var(--deep); }
.ch-ends { display: flex; justify-content: space-between; gap: 8px; font: 11px var(--f-mono); }
.ch-ends .down { color: var(--down); }
.ch-ends .up { color: var(--up); }
.ch-meta, .ch-how { margin: 0; font-size: 12px; line-height: 1.45; color: var(--muted); overflow-wrap: anywhere; }
.ch-how summary { cursor: pointer; }
.ch-how p { margin: 6px 0 0; }
/* the rules line starts with a green pip, the legend of the pips above (review 2026-10-29: green read as a win); a ✓ once enough */
.ch-rules .pip { display: inline-block; width: 18px; height: 8px; border-radius: 3px; margin-inline-end: 6px; background: var(--up); vertical-align: 1px; }
.ch-rules.met::after { content: " ✓"; color: var(--up); font-weight: 700; }
.tag.ch-tag { color: var(--accent); border-color: var(--accent); text-transform: none; letter-spacing: 0; }
.link { background: none; border: 0; padding: 0; color: var(--muted); font-size: 12px; text-decoration: underline; text-align: left; justify-self: start; }
dialog.talk { width: min(580px, calc(100vw - 24px)); }
dialog.acct { width: min(440px, calc(100vw - 24px)); }
.acct form { display: grid; gap: 12px; }
.acct .eyebrow { margin-bottom: 0; }
.acct-tabs button[aria-selected="true"] { color: var(--fg); border-color: var(--accent); background: var(--panel-2); }
.acct .field input { background: var(--deep); border: 1px solid var(--line); border-radius: 8px; padding: 9px 10px; font: 15px var(--f-body); width: 100%; box-sizing: border-box; }
.acct-line { font-size: 13px; color: var(--soft); margin-top: 12px; overflow-wrap: anywhere; } /* a long address wraps, never widens the file */
.acct-line .link { font-size: 13px; }
.acct-line [data-confirm-send] { margin-inline-end: 10px; } /* "Send the link again" and "Log out", two links, not one; a "Log out" wrapped to the next line starts flush */
.acct-body { display: contents; } /* a wide screen: the account form as one grid; a phone scrolls it (the dialogs on a phone, below) */
.talk-top { display: flex; gap: 14px; align-items: flex-start; }
#talkFace { flex: none; width: 120px; aspect-ratio: 24 / 22; image-rendering: pixelated; border-radius: 10px; border: 1px solid var(--line); }
.talk-text { min-height: 110px; }
.talk .who { font: 600 12px var(--f-mono); letter-spacing: .08em; color: var(--accent); margin-bottom: 6px; }
.talk .say { font-size: 15px; line-height: 1.5; }
.talk-choices { display: grid; gap: 6px; margin-top: 14px; }
.talk-choices button { text-align: left; background: var(--deep); border: 1px solid var(--line); border-radius: 10px; padding: 9px 12px; color: var(--fg); font-size: 14px; }
.talk-choices button:hover { border-color: var(--accent); }
.talk-choices button.asked { color: var(--muted); }
.talk-choices button.go { text-align: center; }
@media (max-width: 560px) { #talkFace { width: 84px; } .talk-text { min-height: 0; } }
/* the personnel file: the look before the hiring scene */
dialog.char { width: min(660px, calc(100vw - 24px)); max-height: calc(100dvh - 24px); overflow: auto; }
.char-lead { color: var(--soft); font-size: 14px; margin: -4px 0 14px; }
.char-body { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 18px; align-items: start; }
#charCanvas { width: 264px; aspect-ratio: 44 / 30; display: block; image-rendering: pixelated; border-radius: 12px; border: 1px solid var(--line); }
.char-pic { position: sticky; top: 0; } /* a wide screen: the picture stays in sight beside the fields */
#charDlg:focus { outline: none; } /* a phone focuses the file itself on opening (main.js showFile), not a field */
/* a wide screen: the fields beside the picture and the account line under both, as one grid (a phone scrolls .char-main) */
.char-main { display: contents; }
.char-main > .acct-line { grid-column: 1 / -1; margin-top: -6px; } /* 12px under the body with the grid's gap */
.char-fields { display: grid; gap: 10px; }
.opt { border: 0; padding: 0; margin: 0; min-width: 0; }
.opt legend { font-size: 12px; color: var(--muted); letter-spacing: .04em; padding: 0; margin-bottom: 5px; }
.pick, .swatches { display: flex; flex-wrap: wrap; gap: 6px; }
.pick button { background: var(--deep); border: 1px solid var(--line); border-radius: 8px; padding: 6px 12px; font-size: 13px; color: var(--soft); }
.pick button[aria-checked="true"] { color: var(--fg); border-color: var(--accent); background: var(--panel-2); }
.swatches button { width: 26px; height: 26px; padding: 0; border-radius: 50%; background: var(--sw); border: 2px solid var(--line); }
.swatches button[aria-checked="true"] { border-color: var(--fg); box-shadow: 0 0 0 2px var(--accent); }
.actions .dice { margin-right: auto; }
#building, #heroBuilding { touch-action: manipulation; }
/* a phone's personnel file: "THE DIALOGS ON A PHONE" at the end of this file */
.actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
.toasts { position: fixed; right: 16px; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); display: grid; gap: 8px; z-index: 50; max-width: min(360px, calc(100vw - 32px)); }
/* phones: the ticket sits two screens under the chart (2026-10-26: 94% of Mini App desks never traded); a floating button takes
   the player to it while it is out of view (main.js toTicket), and goes once the ticket is on screen. Centred by its margins
   between left and right (a `left: 50%` with no width caps a fixed box at half the screen and wraps the label in any language,
   and the press's translateY in .go:active would undo a translateX); the toasts move up above it while it is shown */
.to-ticket { display: none; position: fixed; left: 16px; right: 16px; width: fit-content; margin: 0 auto; bottom: calc(14px + var(--dock, 0px) + env(safe-area-inset-bottom, 0px)); z-index: 45; padding: 12px 22px; box-shadow: 0 3px 0 #0b0b0b, 0 8px 24px rgba(0,0,0,.45); }
@media (max-width: 760px) {
  .to-ticket:not([hidden]) { display: block; }
  .to-ticket:not([hidden]) ~ .toasts { bottom: calc(70px + env(safe-area-inset-bottom, 0px)); }
}
.toast { background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; padding: 10px 14px; font-size: 14px; box-shadow: 0 10px 30px rgba(0, 0, 0, .45); }
.toast.win { border-color: var(--up); }
.toast.loss { border-color: var(--down); }
.toast.lea { border-color: #5bd16b; }

@media (max-width: 1280px) {
  .app { grid-template-columns: minmax(0, 1fr) 340px; grid-template-areas: "top top" "market side" "lower side" "bank bank"; grid-template-rows: auto auto 1fr auto; }
  .bank { flex-direction: row; align-items: flex-start; }
  .bank .desk { flex: 1; }
}
/* phones: a switch shows either the chart or Hyper Bank on top (only one of them fits), the ticket and the book below */
.viewsw { display: none; grid-area: switch; }
.viewsw button { flex: 1; display: flex; align-items: center; justify-content: center; gap: 8px; background: var(--panel); border: 1px solid var(--line); padding: 8px; font-size: 14px; color: var(--muted); }
.viewsw button:first-child { border-radius: 10px 0 0 10px; }
.viewsw button:last-child { border-radius: 0 10px 10px 0; border-left: 0; }
.viewsw button[aria-checked="true"] { color: var(--fg); background: var(--panel-2); box-shadow: inset 0 -2px 0 var(--accent); }
.viewsw svg { width: 14px; height: 14px; shape-rendering: crispEdges; }
@media (max-width: 760px) {
  .app { grid-template-columns: minmax(0, 1fr); grid-template-areas: "top" "switch" "market" "side" "lower" "bank"; grid-template-rows: none; padding: 8px 10px 24px; gap: 10px; }
  .viewsw { display: flex; }
  .app[data-view="chart"] .bank { display: none; }
  .app[data-view="bank"] .market { display: none; }
  .app[data-view="bank"] { grid-template-areas: "top" "switch" "bank" "side" "lower"; }
  /* phones (owner, 2026-10-28): the title, the language and the name on top; the rank with the Journal and sound on
     its right (a guest's save button beside the name), so the row they had of their own goes and the chart starts higher; then the money. ::after breaks the line
     after the name (its negative margin takes back the extra row gap) */
  .top { display: flex; flex-wrap: wrap; gap: 6px 8px; }
  .top h1 { flex: 1 1 auto; }
  #nameBtn { order: 1; } #saveBtn { order: 2; } /* a guest's "Save your desk" beside the name, where there is room */
  .top::after { content: ""; order: 3; flex-basis: 100%; height: 0; margin-top: -6px; }
  /* a guest (owner, 2026-10-29): "Save your desk" wrapped under the name anyway, so the name goes down with it, name first,
     on a row of their own; once the desk is saved the button goes and the name is back on the top row (main.js .guest) */
  .top.guest::before { content: ""; order: 1; flex-basis: 100%; height: 0; margin-top: -6px; }
  .where { order: 4; flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; white-space: nowrap; font-size: 12px; }
  #moodChip { order: 5; } #soundBtn { order: 6; }
  .where.bare .where-bank { display: none; }
  /* a free desk's long name on a narrow phone, once "Hyper Bank" and the Journal's words are gone (fitMood): the badge in
     smaller type (.snug), and as the last step on two lines of the same height (.wrap), every word kept */
  .where.snug #rank { padding: 6px 7px; font-size: 11px; }
  .where.wrap { flex-basis: 0; } /* the line then breaks by the chip and the sound button, the badge takes what is left */
  .where.wrap #rank { flex: 0 1 auto; min-width: 0; white-space: normal; text-align: center; padding: 2px 8px; line-height: 13px; border-radius: 12px; }
  /* the Journal on a phone (owner, 2026-10-28): the pixel newspaper for the word, then "Fear & Greed" and the number; the
     words go (.tight, main.js fitMood) when they would not fit on the rank's line. Right to left, the paper is mirrored too */
  .pill.mood { padding: 6px 10px; gap: 5px; } /* a little narrower than on a wide screen, so the words fit more often */
  .pill.mood .np { display: block; }
  .pill.mood .mood-word, .pill.mood.tight .fg-words { display: none; }
  [dir=rtl] .pill.mood .np { transform: scaleX(-1); }
  .money { order: 7; flex-basis: 100%; margin-left: 0; flex-wrap: nowrap; gap: 6px; }
  .money > div { flex: 1; display: grid; gap: 0; padding: 4px 10px; border-radius: 10px; min-width: 0; }
  .money .lbl { font-size: 9px; }
  .money b { font-size: 13px; }
  .chart { height: 340px; }
  .market .bar { flex-wrap: wrap; gap: 6px; padding-bottom: 2px; } /* the timeframes, then Simple/Advanced if they do not fit in one row */
  .market .bar .seg { flex: 0 0 auto; }
  .market .bar .seg button { white-space: nowrap; padding: 4px 8px; }
  .cmode { margin-left: 0; }
  .ctools-row { gap: 6px; }
  .ctools-row .seg { flex-wrap: wrap; }
  .ctools-row .seg button { padding: 4px 8px; }
  /* the chart's hint and the price credit in one small card (owner, 2026-10-28: one space, every word kept): the credit and
     its referral tag follow the hint inline, in the same type. The refused-socket line (Too many desks from your network...)
     that can stand in the credit's place wraps with the rest instead of widening the page */
  .chart-meta { display: block; margin: 0; padding: 7px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); font-size: 11px; line-height: 1.45; color: var(--muted); }
  .chart-meta .lvl-hint, .chart-meta .src { display: inline; margin: 0; font-size: inherit; line-height: inherit; white-space: normal; }
  .chart-meta .ref-tag { display: inline; margin: 0; padding: 0 3px; border-radius: 5px; font-size: 10px; white-space: nowrap; }
  /* the credit never breaks: "Prices on Hyperliquid" and its tag stay on one line, at the end of the hint or on the next
     line (owner 2026-10-29); only the credit, the refused-socket line in the same place still wraps */
  .chart-meta .credit { white-space: nowrap; }
  .bank { flex-direction: column; }
  #building { width: auto; height: min(calc((100vw - 20px) * 244 / 128), 72vh); max-width: 100%; margin: 0 auto; }
}
@media (prefers-reduced-motion: reduce) { .go { transition: none; } }

/* a desk's card (main.js showDesk): a colleague or a desk on the board, with the book (book.css) */
dialog.desk-dlg { width: min(680px, calc(100vw - 24px)); max-height: calc(100dvh - 32px); overflow: auto; }
.desk-top { display: flex; gap: 14px; align-items: center; }
.desk-top canvas { image-rendering: pixelated; flex: 0 0 auto; }
.desk-head { min-width: 0; }
.desk-head .eyebrow { margin-bottom: 4px; }
.desk-head h2 { margin: 0; font: 600 20px var(--f-body); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.desk-meta { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 6px 0 0; color: var(--muted); font-size: 13px; }
.desk-meta b { font: 600 13px var(--f-mono); color: var(--fg); }
.desk-meta .g { font: 400 12px var(--f-display); margin-left: 4px; font-style: normal; }
.desk-about { color: var(--soft); font-size: 13px; margin: 12px 0 0; }
.desk-sec { margin-top: 14px; }
.desk-sec h2 { margin: 0; font: 600 15px var(--f-body); }
.board-row[data-id] { cursor: pointer; border-radius: 6px; }
.board-row[data-id]:hover { background: var(--panel-2); }
.board-row[data-id]:focus-visible { background: var(--panel-2); outline: 1px solid var(--accent); outline-offset: 1px; }
.bot .link { margin-top: 2px; }
/* two modes (story.mjs): a graduate wears the class line (the free desk sits at the junior desk, with no floor to pick) */
.story-lead.grad { color: var(--accent); font-weight: 600; }
.pill.grad { color: var(--accent); border-color: var(--accent); }

/* the simple ticket (owner, 2026-10-19: beginners pick a market, a side and the risk; the rules set the rest) */
.tmode { margin-bottom: 8px; }
.sblock { display: none; }
.ticket.simple .sblock { display: block; }
.ticket.simple .field, .ticket.simple .pair, .ticket.simple #quickMargin { display: none; }
/* the trailing stop: a toggle on the simple ticket (the stop's own distance), a Trail field under Stop on the full one */
.simple-toggle { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; margin: 8px 0 0; font-size: 13px; color: var(--soft); cursor: pointer; }
.simple-toggle input { accent-color: var(--accent); margin: 0; }
.simple-toggle small { color: var(--muted); font-size: 12px; }
.simple-lead { color: var(--soft); font-size: 13px; margin: 2px 0 6px; }
.simple-sum { color: var(--muted); font-size: 12px; margin: 6px 0 0; line-height: 1.5; }
.simple-sum b { color: var(--fg); font-family: var(--f-mono); font-weight: 600; }
#riskPick button[aria-pressed="true"], #rrPick button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
/* who are you: the level dialog after the hiring scene */
dialog.level { width: min(560px, calc(100vw - 24px)); }
dialog.level h2 { margin: 0 0 14px; font: 600 20px var(--f-body); }
.levels { display: grid; gap: 10px; }
.level-card { text-align: left; background: var(--deep); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; color: var(--fg); display: grid; gap: 4px; cursor: pointer; }
.level-card:hover { border-color: var(--accent); }
.level-card b { font-size: 16px; }
.level-card span { color: var(--soft); font-size: 13px; }
.level-note { color: var(--muted); font-size: 12px; margin: 12px 0 0; }
.level-lead { color: var(--soft); font-size: 14px; margin: -6px 0 14px; }
/* the coach: Lea walks a beginner through the first trade over the real ticket */
.coach { position: fixed; inset: 0; z-index: 40; pointer-events: none; }
.coach-box { position: absolute; border: 2px solid var(--accent); border-radius: 12px; box-shadow: 0 0 0 9999px rgba(3, 8, 12, .55); transition: all .25s; }
.coach-bubble { position: absolute; pointer-events: auto; width: min(360px, calc(100vw - 24px)); box-sizing: border-box; background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px; box-shadow: 0 12px 40px rgba(0,0,0,.5); } /* border-box: the width is the whole bubble, so it ends 12px from the screen's edge (content-box put the padding and the Next button off screen on a 390px phone) */
.coach-bubble .who { font: 400 11px var(--f-display); letter-spacing: .12em; color: var(--accent); margin: 0 0 6px; }
.coach-bubble .say { margin: 0; font-size: 14px; line-height: 1.5; }
.coach-bubble .actions { margin-top: 10px; align-items: center; }
.coach-n { margin-right: auto; color: var(--muted); font: 12px var(--f-mono); }
.quick.risk { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.risk-custom { display: inline-flex; align-items: center; gap: 4px; background: var(--deep); border: 1px solid var(--line); border-radius: 8px; padding: 0 8px; }
.risk-custom i { font-style: normal; color: var(--muted); font-size: 12px; }
.risk-custom input { width: 72px; border: 0; background: none; color: var(--fg); font: 13px var(--f-mono); padding: 5px 0; outline: none; }

@media (max-width: 640px) { .lvl-hint { font-size: 11px; } }

/* Scripts whose letters join or stack (Arabic, Persian, Urdu, Hindi, Bengali, Thai): letter and word spacing pull them
   apart, so it is off in those languages (src/i18n.js sets html lang); English and the other languages look as before. */
:lang(ar), :lang(fa), :lang(ur), :lang(hi), :lang(bn), :lang(th) { letter-spacing: normal !important; word-spacing: normal !important; }

/* ---- Other languages (2026-10-27, after the review of the game in 24 languages): the same font stacks as landing.css, scoped
   to a language (:lang) or to right-to-left pages ([dir=rtl]); English looks as before. ---- */
:root { --f-pixel: "Rubik Mono One", "Rubik", system-ui, sans-serif; }
html:lang(ja) { --f-script: "Hiragino Sans", "Hiragino Kaku Gothic ProN", Meiryo, "Yu Gothic UI", "Noto Sans JP", "Noto Sans CJK JP"; }
html:lang(ko) { --f-script: "Apple SD Gothic Neo", "Malgun Gothic", "Noto Sans KR", "Noto Sans CJK KR"; }
html:lang(zh) { --f-script: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", "Noto Sans CJK SC"; }
html:lang(th) { --f-script: "Leelawadee UI", Thonburi, "Noto Sans Thai", Tahoma; }
html:lang(hi) { --f-script: "Nirmala UI", "Kohinoor Devanagari", "Devanagari Sangam MN", "Noto Sans Devanagari", Mangal; }
html:lang(bn) { --f-script: "Nirmala UI", "Kohinoor Bangla", "Bangla Sangam MN", "Noto Sans Bengali", Vrinda; }
html:lang(ar), html:lang(fa), html:lang(ur) { --f-script: "Segoe UI", Tahoma, "Noto Sans Arabic", "Noto Naskh Arabic", "Geeza Pro"; }
html:is(:lang(ja), :lang(ko), :lang(zh), :lang(th), :lang(hi), :lang(bn), :lang(ar), :lang(fa), :lang(ur)) {
  --f-display: var(--f-script), system-ui, sans-serif;
  --f-body: "Rubik", var(--f-script), system-ui, sans-serif;
  --f-mono: "JetBrains Mono", var(--f-script), ui-monospace, Menlo, Consolas, monospace;
}
html:is(:lang(ru), :lang(uk), :lang(vi)) { --f-display: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; }
/* bold where the pixel face stood; the brand mark, the grades and the ranks (always Latin) keep the pixel face */
html:is(:lang(ja), :lang(ko), :lang(zh), :lang(th), :lang(hi), :lang(bn), :lang(ar), :lang(fa), :lang(ur), :lang(ru), :lang(uk), :lang(vi)) :is(.go, .score h2, .lower h2, .open-book h2, .closed-book h2, .desk h2, .eyebrow, .coach-bubble .who) { font-weight: 700; }
html:is(:lang(ja), :lang(ko), :lang(zh), :lang(th), :lang(hi), :lang(bn), :lang(ar), :lang(fa), :lang(ur), :lang(ru), :lang(uk), :lang(vi)) :is(.top h1, .grade b, .board-row .g, .desk-meta .g) { font-family: var(--f-pixel); font-weight: 400; }
/* Turkish: uppercased in CSS the browser maps i to İ and ı to I for lang=tr; the capitals-only face has both */
html:lang(tr) :is(.go, .score h2, .lower h2, .open-book h2, .closed-book h2, .desk h2, .eyebrow, .coach-bubble .who) { text-transform: uppercase; }
html:lang(tr) .story h2 small { text-transform: none; }
/* right to left: the task's counter (0 of 3) sits after the text, with its gap on the other side */
[dir=rtl] .tasks .txt small { margin-left: 0; margin-right: 4px; }

/* the way-in dialogs scroll on a short screen (a Telegram sheet, a landscape phone) instead of being cut at the bottom */
#modeDlg, #levelDlg { max-height: calc(100dvh - 24px); overflow-y: auto; overscroll-behavior: contain; }

/* ---- THE DIALOGS ON A PHONE (owner, 2026-10-29, on his iPhone: the personnel file "too big and inconvenient, something
   slides, something scrolls in the background", logging in inconvenient; 760px and under, a wide screen as it was) ---- */
/* a dialog open: the page behind stays where it is, no scrolling and no bounce; closing gives the scroll back at the same place */
@media (max-width: 760px), (pointer: coarse) {
  html:has(dialog[open]) { overflow: hidden; overscroll-behavior: none; }
  /* iOS zooms the whole page into a field typed in under 16px and does not zoom back (the "sliding"): 16px in every dialog,
     also on a phone held sideways (wider than 760px, a touch screen) */
  dialog input:not([type=range], [type=checkbox], [type=radio]), :is(#acctDlg, #synDlg, #charDlg) input { font-size: 16px; }
  /* the same on the page itself (owner, 2026-10-29): the ticket's margin, target, stop, trail, the custom risk and R, the open
     positions' stop and target fields, the language list; the boxes keep their size, only the type grows to 16px */
  input:not([type=range], [type=checkbox], [type=radio]), select, textarea { font-size: 16px !important; } /* over the fields' own font rules */
}
@media (max-width: 760px) {
  /* a dialog taller than the screen scrolls inside, and that scrolling never carries on to the page */
  dialog { max-height: calc(100vh - 16px); max-height: calc(100dvh - 16px); overflow-y: auto; overscroll-behavior: contain; }
  /* the dialogs with fields hang from the top of the screen, 8px from its edges: a keyboard rises under them and nothing moves */
  #acctDlg, #synDlg, #charDlg { margin: 8px auto auto; max-width: calc(100vw - 16px); }
  #acctDlg, #synDlg { width: min(440px, calc(100vw - 16px)); }
  #synDlg { padding: 16px; }
  #charDlg { width: min(660px, calc(100vw - 16px)); height: calc(100vh - 16px); height: calc(100dvh - 16px); }
  /* the keyboard up (main.js fitKeyboard): they keep inside the part of the screen above it, the buttons in reach */
  html.kb :is(#acctDlg, #synDlg, #charDlg) { margin-top: calc(var(--vvt) + 8px); max-height: calc(var(--vvh) - 16px); }
  html.kb #charDlg { height: calc(var(--vvh) - 16px); }
  /* Cancel and the main button share the row while their words fit on one line each; when they do not, they take a row each,
     the main button at the bottom (as in the personnel file) */
  :is(#acctDlg, #synDlg) .actions { flex-wrap: wrap; }
  :is(#acctDlg, #synDlg) .actions > button { flex: 1 1 auto; }
  :is(#acctDlg, #synDlg) .actions > .go { flex-grow: 3; } /* on a shared row the main button takes most of the room */

  /* save your desk / log in, and the personnel file: the words and the fields scroll in their own part, the message and the
     buttons stay at the bottom of the sheet */
  #acctDlg, #charDlg { padding: 0; overflow: hidden; }
  #acctDlg[open], #charDlg[open] { display: flex; flex-direction: column; }
  #acctForm, #charForm { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 0; }
  :is(#acctForm, #charForm) > .msg { flex: none; min-height: 0; margin: 0; padding: 8px 16px 0; }
  :is(#acctForm, #charForm) > .msg:empty { padding: 0; }
  :is(#acctForm, #charForm) > .actions { flex: none; margin: 0; padding: 10px 16px 14px; }
  .acct-body { display: grid; gap: 12px; flex: 0 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 16px 16px 4px; }
  /* the two ways in as one clear switch across the dialog, each half a good tap */
  #acctLead { margin: 0; }
  .acct-tabs { display: grid; grid-template-columns: repeat(2, minmax(max-content, 1fr)); } /* halves, or what the longer words need */
  .acct-tabs button { padding: 9px 8px; font-size: 14px; text-align: center; }
  .acct .field input { padding: 10px 12px; }
  #acctForgot { font-size: 14px; padding: 4px 0; }

  /* the personnel file: the title and its line, the picture (smaller, never over the fields), the fields scrolling under it,
     the buttons at the bottom; 561 to 760px keep the picture on the left of the fields */
  #charForm > .eyebrow { margin: 0; padding: 14px 16px 0; }
  #charLead { margin: 4px 0 0; padding: 0 16px; font-size: 13px; }
  .char-body { flex: 1 1 0; min-height: 0; margin-top: 10px; gap: 0; grid-template-rows: minmax(0, 1fr); align-items: stretch; border-bottom: 1px solid var(--line); }
  .char-pic { position: static; align-self: start; padding: 0 0 12px 16px; }
  [dir=rtl] .char-pic { padding: 0 16px 12px 0; }
  .char-main { display: block; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 16px 14px; }
  .char-main > .acct-line { margin-top: 14px; }
  #charForm > .actions { flex-wrap: wrap; }
}
@media (max-width: 560px) {
  .char-body { display: flex; flex-direction: column; }
  .char-pic { flex: none; align-self: stretch; display: flex; justify-content: center; padding: 0 16px 10px; border-bottom: 1px solid var(--line); }
  [dir=rtl] .char-pic { padding: 0 16px 10px; }
  #charCanvas { width: auto; height: clamp(96px, 17vh, 140px); height: clamp(96px, 17dvh, 140px); }
  .char-main { flex: 1 1 0; padding-top: 12px; }
  /* typing the name with the keyboard up: the picture steps aside, the field and the buttons keep their room */
  html.kb #charDlg .char-pic { display: none; }
  /* Surprise me and Cancel side by side, Save (or Sign the file) across the sheet under them: one line each in every language */
  #charForm > .actions .dice { margin: 0; flex: 1 1 auto; }
  #charCancel { flex: 1 1 auto; }
  #charGo { flex: 1 0 100%; }
}
/* a short screen at any width (a phone held sideways is wider than 760px, a small window): every dialog scrolls inside, so
   its buttons stay in reach (Save my desk was under the bottom edge at 844x390, with no way to it) */
@media (max-height: 560px) {
  dialog { max-height: calc(100vh - 16px); max-height: calc(100dvh - 16px); overflow-y: auto; overscroll-behavior: contain; }
}

/* THE EXTRA (server/extra.mjs, index.mjs extraStrip): while the owner's special edition shows, a red strip on top of the landing
   page and the desk links to it in the Journal (owner: "everywhere"). One line on a wide screen; on a phone the stamp and the
   link first, the title on a line of its own, cut short */
.extra-strip { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 4px 12px; padding: 8px 16px; background: #a3241c; color: #f6eedb; text-decoration: none; font: 500 14px/1.35 var(--f-body); }
.extra-strip b { font: 800 12px/1 var(--f-body); letter-spacing: .1em; text-transform: uppercase; background: #f6eedb; color: #a3241c; padding: 5px 8px 4px; white-space: nowrap; }
.extra-strip-title { font-weight: 700; min-width: 0; }
.extra-strip-go { text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
.extra-strip:hover .extra-strip-go { text-decoration-thickness: 2px; }
@media (max-width: 640px) {
  .extra-strip { justify-content: flex-start; font-size: 13px; padding: 7px 16px; }
  .extra-strip-title { order: 3; flex: 1 0 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
