/* ============================================================================
   STARFALL — css/trade.css
   ----------------------------------------------------------------------------
   The live desk. Bloomberg density, modern type: a fixed mosaic of small
   windows, every number in a mono face, one amber function bar, and colour
   reserved for the two things it means — up and down.

   01. tokens            05. the mosaic
   02. reset & shell     06. watchlist
   03. top bar           07. chart
   04. function bar      08. ticket · book · tape · blotter
   ========================================================================== */

/* Off-screen text that only assistive technology should reach. The desk page
   loads no other stylesheet, so it cannot borrow the one in terminal.css. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   01. TOKENS
   ========================================================================== */
:root {
  --bg: #05070b;
  --bg-2: #080b11;
  --bg-3: #0b1017;
  --panel: #0a0e14;
  --panel-2: #0d1219;
  --head: linear-gradient(180deg, #131922, #0b0f15);
  --line: rgba(255, 255, 255, 0.075);
  --line-2: rgba(255, 255, 255, 0.14);
  --line-dot: rgba(255, 255, 255, 0.06);
  --ink: #e9effb;
  --ink-2: #b6c3d8;
  /* 4.64:1 on the lightest surface it labels, the #172a2d chart foot the
     large-prints meta line sits on. #7c8ba5 measured 4.35:1 there -- under
     the bar, on a line a reader reads to know how far the tape reaches. */
  --muted: #8290aa;
  /* 4.54:1 on the lightest surface this one labels, and 4.64:1 on #0f141c,
     the study hints. #6b7c99 was 4.37:1 there. Still under --muted (#8290aa,
     6.26:1 on #05070b), so the three-step hierarchy the board is drawn with
     survives. */
  --faint: #6f80a0;
  --accent: #ffbb00;
  --accent-rgb: 255, 187, 0;
  --up: #22d3a5;
  --up-rgb: 34, 211, 165;
  --down: #ff5d73;
  --down-rgb: 255, 93, 115;
  --cyan: #38bdf8;
  --violet: #a78bfa;
  --mono: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --ui: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --r: 6px;
  --bg-soft: rgba(255, 255, 255, 0.022);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ==========================================================================
   02. RESET & SHELL
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body.tdk {
  margin: 0;
  background:
    radial-gradient(120% 80% at 8% -10%, rgba(var(--accent-rgb), 0.05), transparent 55%),
    radial-gradient(90% 70% at 100% 0%, rgba(56, 189, 248, 0.05), transparent 60%),
    var(--bg);
  color: var(--ink);
  font-family: var(--ui);
  font-size: 12.5px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  display: grid;
  /* the column is minmax(0, 1fr) rather than the implicit auto: an auto column
     sizes to the widest thing on the page, so a single long command message or
     a bar full of keys would push the whole desk wider than the window and
     every row with it. Nothing inside can widen the desk now. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto auto minmax(0, 1fr) auto auto;
  height: 100vh;
  overflow: hidden;
}
body.tdk a { color: inherit; text-decoration: none; }
body.tdk button { font-family: inherit; cursor: pointer; }
body.tdk input { font-family: inherit; }
.tdk-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 8px 14px;
  background: var(--accent);
  color: #000;
  font: 700 11px/1 var(--mono);
}
.tdk-skip:focus { left: 8px; top: 8px; }

.tdk-panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}
.tdk-panel__head {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 26px;
  padding: 0 8px 0 0;
  border-bottom: 1px solid var(--line);
  background: var(--head);
}
.tdk-panel__head::before {
  content: '';
  flex: none;
  width: 3px;
  align-self: stretch;
  background: var(--accent);
}
.tdk-panel__title {
  padding-left: 8px;
  font: 700 10px/1 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  white-space: nowrap;
}
.tdk-panel__hint {
  margin-left: auto;
  padding-left: 10px;
  font: 600 9.5px/1 var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ==========================================================================
   03. TOP BAR
   ========================================================================== */
.tdk-top {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 6px 12px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, #0c1017, #070a0f);
  min-height: 40px;
}
.tdk-brand { display: inline-flex; align-items: center; gap: 8px; flex: none; }
.tdk-brand__mark {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(var(--accent-rgb), 0.4);
  border-radius: 7px;
  background: #0d1117;
}
.tdk-brand__mark img { display: block; }
.tdk-brand__txt { display: flex; flex-direction: column; }
.tdk-brand__txt b { font: 800 12px/1 var(--mono); letter-spacing: 0.2em; }
.tdk-brand__txt em { font: 600 8.5px/1.4 var(--mono); letter-spacing: 0.24em; color: var(--accent); font-style: normal; }

.tdk-feed {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.02);
  font: 600 10px/1 var(--mono);
  letter-spacing: 0.07em;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  /* the feed is the one block in the top bar full of nowrap readings: without
     this it cannot shrink, and it pushes the whole page sideways on a laptop */
  flex: 0 1 auto;
  min-width: 0;
}
.tdk-feed b { color: var(--ink); }
.tdk-feed__sep { width: 1px; height: 12px; background: var(--line-2); }
/* Below the width the full reading needs, the decorations go before the page
   does: the separators, then the tick rate, then the venue chips. What is left
   — the state, the venue, the latency — is the part a reader acts on. */
@media (max-width: 1560px) {
  .tdk-feed__sep { display: none; }
  #feedTicks { display: none; }
}
@media (max-width: 1180px) {
  #feedLatency { display: none; }
}

/* ==========================================================================
   07b. SCROLLBARS
   --------------------------------------------------------------------------
   A trading desk scrolls inside its panes all day, so the scrollbars are part
   of the furniture: thin, dark, amber on hover, and never a bright native bar
   sitting across a black terminal. One set of rules covers every scrolling box
   on the page — the watchlist, the ladder, the tape, the blotter, the ticket,
   the drawers and the command history. */
.tdk { scrollbar-width: thin; scrollbar-color: #232b38 transparent; }
.tdk ::-webkit-scrollbar { width: 9px; height: 9px; }
.tdk ::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.03); }
.tdk ::-webkit-scrollbar-thumb {
  border: 2px solid transparent;
  background-clip: padding-box;
  border-radius: 9px;
  background-color: #2a3342;
}
.tdk ::-webkit-scrollbar-thumb:hover { background-color: rgba(var(--accent-rgb), 0.55); }
.tdk ::-webkit-scrollbar-corner { background: transparent; }
/* the watchlist gets the room for a real scrollbar: its row grid keeps its
   columns, so the price column cannot slide under the bar as it appears */
.tdk-board__list { scrollbar-gutter: stable; }
.tdk-board__list::-webkit-scrollbar { width: 11px; }
.tdk-board__list::-webkit-scrollbar-track {
  background: #05070b;
  border-left: 1px solid var(--line);
}
.tdk-board__list::-webkit-scrollbar-thumb {
  border: 3px solid #05070b;
  border-radius: 10px;
  background-color: #2b3546;
  background-clip: padding-box;
}
.tdk-board__list::-webkit-scrollbar-thumb:hover { background-color: var(--accent); }
.tdk-trades__rows, .tdk-blotter__body { scrollbar-gutter: stable; }

/* ---- how lopsided the visible ladder is ---- */
.tdk-book__imb {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-top: 1px solid var(--line);
  background: #050607;
  font: 600 10px/1 var(--mono);
}
.tdk-book__imb-bar {
  flex: 1 1 auto;
  height: 5px;
  border-radius: 3px;
  background: #1a1f27;
  overflow: hidden;
}
.tdk-book__imb-bar i { display: block; height: 100%; }
.tdk-book__imb b { color: var(--muted); font-weight: 600; white-space: nowrap; }
.tdk-book__imb b s { text-decoration: none; }
.tdk-book__imb b s.up { color: var(--up); }
.tdk-book__imb b s.down { color: var(--down); }
.tdk-book__imb b u { text-decoration: none; color: var(--faint); }

/* ---- the tape's own footer: who is doing the lifting ---- */
.tdk-trades__foot {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 6px 10px;
  border-top: 1px solid var(--line);
  background: #050607;
  font: 600 10px/1 var(--mono);
}
.tdk-trades__foot s { text-decoration: none; color: var(--faint); letter-spacing: 0.08em; }
.tdk-trades__foot b { font-weight: 700; }
.tdk-trades__delta { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.tdk-trades__delta-bar {
  display: block;
  width: 54px;
  height: 5px;
  border-radius: 3px;
  background: #1a1f27;
  overflow: hidden;
}
.tdk-trades__delta-bar u { display: block; height: 100%; background: var(--up); }
/* a print several times the median: the blocks a reader is looking for */
.tdk-tr.is-block { box-shadow: inset 2px 0 0 var(--accent); font-weight: 700; }

/* ---- the risk line on the ticket ---- */
.tdk-ticket__risk {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 0 12px 8px;
}
.tdk-ticket__risk label { font: 700 9.5px/1 var(--mono); letter-spacing: 0.12em; color: var(--faint); }
.tdk-ticket__risk input {
  width: 100%;
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: #05070b;
  color: var(--ink);
  font: 600 12px/1 var(--mono);
}
.tdk-ticket__risk button {
  padding: 7px 10px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  font: 700 9.5px/1 var(--mono);
  letter-spacing: 0.1em;
  cursor: pointer;
}
.tdk-ticket__risk button:hover { border-color: var(--accent); color: var(--accent); }
.tdk-led { display: inline-grid; place-items: center; width: 10px; height: 10px; }
.tdk-led i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--faint);
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.03);
}
.tdk-led[data-state="live"] i { background: var(--up); animation: tdkLed 1.8s ease-in-out infinite; }
.tdk-led[data-state="prices"] i { background: var(--accent); }
.tdk-led[data-state="down"] i { background: var(--down); }
@keyframes tdkLed { 50% { opacity: 0.35; } }

.tdk-clocks { display: flex; gap: 12px; margin-left: auto; }
.tdk-clocks span, .tdk-acct span { display: inline-flex; align-items: baseline; gap: 6px; }
.tdk-clocks s, .tdk-acct s {
  text-decoration: none;
  font: 600 9px/1 var(--mono);
  letter-spacing: 0.12em;
  color: var(--faint);
}
/* The value inherits its colour from the label span above it, and that span is
   --faint on purpose. So the account figures -- equity, balance, the numbers a
   trader actually reads at a glance -- were painted in the dimmest colour on
   the board. The label is the caption; the number is the content. */
.tdk-clocks b, .tdk-acct b { font: 700 12px/1 var(--mono); letter-spacing: 0.02em; color: var(--ink); }
.tdk-acct { display: flex; gap: 14px; padding-left: 14px; border-left: 1px solid var(--line); }
.tdk-acct b.up { color: var(--up); }
.tdk-acct b.down { color: var(--down); }
.tdk-acct__tag {
  align-self: center;
  padding: 2px 7px;
  border: 1px solid rgba(var(--accent-rgb), 0.4);
  border-radius: 999px;
  color: var(--accent);
  font: 700 9px/1.6 var(--mono);
  letter-spacing: 0.14em;
}
.tdk-links { display: flex; gap: 12px; padding-left: 14px; border-left: 1px solid var(--line); }
.tdk-links a { font: 700 10px/1 var(--mono); letter-spacing: 0.12em; color: var(--muted); }
.tdk-links a:hover { color: var(--accent); }

/* ==========================================================================
   04. FUNCTION BAR
   ========================================================================== */
.tdk-fn {
  display: flex;
  align-items: stretch;
  gap: 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.5);
  background: linear-gradient(180deg, #f0b100, #d99e00);
  color: #100d04;
  min-height: 34px;
}
/* min-width: 0 is what lets this bar scroll inside itself instead of pushing
   the whole page sideways when there are more function keys than fit */
.tdk-fn__keys { display: flex; flex: 0 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.tdk-fn__keys::-webkit-scrollbar { display: none; }
.tdk-fn__keys button {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  flex: none;
  padding: 0 12px;
  border: 0;
  border-right: 1px solid rgba(0, 0, 0, 0.16);
  background: transparent;
  color: #241c05;
  font: 700 10px/34px var(--mono);
  letter-spacing: 0.1em;
  white-space: nowrap;
}
.tdk-fn__keys button b { font-size: 9px; opacity: 0.62; }
.tdk-fn__keys button:hover { background: rgba(255, 255, 255, 0.26); }
/* SPECIFICITY, and a bug it caused for a while: `.tdk-fn__keys button` is
   (0,1,1) and it sets `align-items: baseline`, which outranked the gear's own
   `align-items: center` (0,1,0). So the glyph sat on the button's top edge and
   the word SETTINGS hung 20px above its floor, in a key that was 35px tall —
   the one key on the bar that looked lifted off it. The rule below is the same
   selector the bar uses, so the gear's own alignment is the one that wins. */
.tdk-fn__keys button.tdk-fn__gear { align-items: center; }
/* A grid rather than a flex row: the prompt, the field, GO, then the message.
   The field's column is minmax(0, 1fr) so the form's own minimum width is the
   three small pieces, and the command line can never widen the page — which,
   with a flex row and a long placeholder, it did. */
.tdk-cmd {
  display: grid;
  /* the last column is the message line: a share of the bar rather than its
     own content, or the sentence inside it decides how wide the desk is */
  grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 38%);
  align-items: center;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
  margin: 3px 4px;
  padding: 0 10px;
  border-radius: 5px;
  background: rgba(0, 0, 0, 0.72);
  color: var(--ink);
  overflow: hidden;
}
.tdk-cmd__prompt { font: 700 10.5px/1 var(--mono); letter-spacing: 0.12em; color: var(--accent); }
.tdk-cmd input {
  width: 100%;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--ink);
  font: 500 11.5px/1 var(--mono);
  letter-spacing: 0.04em;
}
.tdk-cmd input::placeholder { color: rgba(255, 255, 255, 0.28); }

.tdk-cmd button {
  flex: none;
  padding: 0 12px;
  border: 1px solid rgba(var(--accent-rgb), 0.5);
  border-radius: 4px;
  background: rgba(var(--accent-rgb), 0.14);
  color: var(--accent);
  font: 700 10px/22px var(--mono);
  letter-spacing: 0.14em;
}
/* The message line is a whole sentence, and without min-width: 0 its automatic
   minimum size is that sentence — which was enough to push the page 104px wider
   than the window on a laptop. It ellipsises now, and says the whole thing in
   its title. */
.tdk-cmd__msg {
  flex: 0 1 42%;
  min-width: 0;
  font: 600 10px/1 var(--mono);
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tdk-cmd__msg.is-ok { color: var(--up); }
.tdk-cmd__msg.is-bad { color: var(--down); }

/* ==========================================================================
   04b. MOVERS TAPE
   ========================================================================== */
.tdk-tape {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background: #070a0e;
  height: 26px;
}
/* The marquee travels exactly one copy of the list and no further, and how far
   that is in pixels is measured and written as `--shift` by the panel. The old
   `translateX(-50%)` assumed one copy was at least as wide as the strip, which
   is not true of sixteen movers on a wide monitor — the track ran out before the
   loop did and the strip sat empty until the next repaint. */
.tdk-tape__track {
  display: flex;
  align-items: center;
  gap: 0;
  height: 100%;
  width: max-content;
  animation: tdkTape 90s linear infinite;
  animation-duration: var(--dur, 90s);
}
.tdk-tape:hover .tdk-tape__track { animation-play-state: paused; }
@keyframes tdkTape { to { transform: translateX(var(--shift, -50%)); } }
.tdk-tape__cell {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  padding: 0 14px;
  border-right: 1px solid var(--line-dot);
  font: 600 10.5px/26px var(--mono);
  letter-spacing: 0.05em;
  color: var(--ink-2);
  white-space: nowrap;
}
.tdk-tape__cell b { color: var(--ink); font-weight: 700; }
.tdk-tape__cell u { text-decoration: none; }
.tdk-tape__cell i { font-style: normal; }
.tdk-tape__cell.up u { color: var(--up); }
.tdk-tape__cell.down u { color: var(--down); }
.tdk-tape__cell.ref { opacity: 0.62; }
@media (prefers-reduced-motion: reduce) {
  .tdk-tape__track { animation-duration: 220s; }
}

/* ==========================================================================
   05. THE MOSAIC
   ========================================================================== */
/* Three columns and two grips between them. The widths are variables rather
   than literals because the reader drags them: --col-l and --col-r are written
   by the two grips, and set to 0 when a column is hidden, which is the same
   `display: none` written as a width. Nothing below this line ever needs to
   know how wide anything is. */
.tdk-grid {
  --col-l: 244px;
  --col-r: 296px;
  display: grid;
  grid-template-columns: var(--col-l) 7px minmax(0, 1fr) 7px var(--col-r);
  gap: 7px;
  padding: 7px 8px;
  min-height: 0;
  overflow: hidden;
}
/* A hidden column is hidden, not merely squeezed: at 0px the panel's own border
   would still paint a two-pixel stripe. The grip stays, because it is the way
   back. */
.tdk-grid[data-hide-l="1"] > .tdk-board,
.tdk-grid[data-hide-r="1"] > .tdk-side { display: none; }
/* the blotter is a sibling of the grid, not a child, so its switch rides on the
   grid and reaches it with a sibling combinator */
.tdk-grid[data-hide-b="1"] ~ .tdk-blotter { display: none; }

/* ==========================================================================
   05b. GRIPS — a panel is as big as the reader wants it
   ==========================================================================
   Each grip is a button, not a div with a mousedown handler. That is the whole
   of the accessibility story here: it can be tabbed to, its arrows resize the
   panel it belongs to, Enter hides it and Home puts it back, and the label
   says so. A drag is the fast path; the keyboard is a complete one. */
.tdk-grip {
  position: relative;
  align-self: stretch;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: transparent;
  cursor: col-resize;
  touch-action: none;
}
.tdk-grip::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 3px;
  height: 34px;
  transform: translate(-50%, -50%);
  border-radius: 2px;
  background: var(--line-2);
  transition: background 0.15s, height 0.15s;
}
.tdk-grip:hover::before,
.tdk-grip:focus-visible::before { background: var(--accent); height: 62px; }
.tdk-grip:focus-visible { outline: 2px solid var(--accent); outline-offset: -3px; }
.tdk-grip[data-collapsed="true"]::before { background: rgba(var(--accent-rgb), 0.75); }

/* the blotter's grip lies flat: it resizes a height, so it reads sideways */
.tdk-grip--blotter {
  margin: 0 8px;
  height: 7px;
  cursor: row-resize;
}
.tdk-grip--blotter::before {
  width: 34px;
  height: 3px;
  transform: translate(-50%, -50%);
}
.tdk-grip--blotter:hover::before,
.tdk-grip--blotter:focus-visible::before { width: 62px; height: 3px; }

@keyframes tdkGripPulse {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}
/* while a grip is being dragged the pointer belongs to it, so the cursor stays
   right whatever it passes over */
body.tdk-dragging { cursor: col-resize; user-select: none; }
body.tdk-dragging-h { cursor: row-resize; user-select: none; }
/* The right column: the ticket at its own height, then the ladder and the tape.
   The ticket is the tallest thing on the page and it used to be allowed to take
   the whole column, which squashed the other two panes to nothing — a nine-pixel
   order book. So the two market panes have real minimums now, and when the
   window is too short for all three the column scrolls rather than crushes
   anything the reader is trading against. */
.tdk-side {
  display: grid;
  grid-template-rows: minmax(478px, 1.4fr) minmax(190px, 1fr) minmax(165px, 1fr);
  gap: 7px;
  min-height: 0;
  min-width: 0;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: var(--line-2) transparent;
}
/* The blotter is a height, not a share: it is dragged, so it is stored as one.
   --blotter-h is written by its grip, and the body scrolls inside whatever the
   reader left it at. */
.tdk-blotter { margin: 0 8px 6px; height: var(--blotter-h, 24vh); max-height: var(--blotter-h, 24vh); }
/* The body takes the height the reader dragged to rather than sizing to its own
   rows: with a fixed panel height and a content-sized body, a blotter holding
   two fills left a hundred pixels of empty card under them. It still scrolls
   inside whatever height it is given. */
.tdk-blotter__body { overflow: auto; min-height: 0; flex: 1 1 auto; }

/* ==========================================================================
   06. WATCHLIST
   ========================================================================== */
/* One board, two readings. The switch sits in the panel head because it is a
   way of looking at the list, not a control the reader operates. */
.tdk-board__modes { display: inline-flex; gap: 2px; flex: none; margin-left: 2px; }
/* --muted, not --faint: this is a control the reader acts on, and the two
   readings are worth telling apart at a glance */
.tdk-board__modes button {
  padding: 3px 7px;
  border: 1px solid transparent;
  border-radius: 3px;
  background: transparent;
  color: var(--muted);
  font: 700 9px/1.4 var(--mono);
  letter-spacing: 0.14em;
  cursor: pointer;
}
.tdk-board__modes button:hover { border-color: var(--line); color: var(--ink-2); }
.tdk-board__modes button.is-on {
  border-color: rgba(var(--accent-rgb), 0.45);
  background: rgba(var(--accent-rgb), 0.12);
  color: var(--accent);
}
/* The session map: the same ninety rows, ranked by their own 24 h move. Wide
   tiles on a desk, three across on a phone, and never narrower than a price
   fits in — a heat grid you cannot read is just colour. */
.tdk-board__map {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(76px, 1fr));
  align-content: start;
  gap: 3px;
  padding: 6px;
}
/* `display: grid` above is a class rule, so it beats the user agent's own
   `[hidden]` rule — the element carried `hidden` and was painted anyway. Both
   readings of the board were therefore on screen at once, the list and ninety
   tiles under it, which on a phone buried the pane it was supposed to be
   reading. The one line that makes `hidden` mean hidden. */
.tdk-board__map[hidden] { display: none; }
.tdk-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 6px 7px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s var(--ease), background 0.35s var(--ease);
}
.tdk-tile:hover { border-color: var(--line-2); }
.tdk-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.tdk-tile b {
  overflow: hidden;
  font: 700 10.5px/1 var(--mono);
  letter-spacing: 0.03em;
  color: var(--ink);
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Nothing inside a tile may sit lower than --ink-2: the tile is the one place
   on the desk where the background itself moves, and --faint measures 2.5:1 on
   the hottest fills — which is exactly where the price is read most. */
.tdk-tile s, .tdk-tile i { font: 600 9.5px/1 var(--mono); white-space: nowrap; }
.tdk-tile s { color: var(--ink); text-decoration: none; }
.tdk-tile i { font-style: normal; color: var(--ink-2); }
/* the strength of the move, along the bottom edge: the flood alone has to stay
   too pale to read at full range or it takes the tile's own text with it */
.tdk-tile__heat {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
}
.tdk-tile em { position: absolute; top: 3px; right: 4px; font-size: 8px; font-style: normal; color: var(--accent); }
.tdk-tile.is-pinned { border-color: rgba(var(--accent-rgb), 0.3); }
.tdk-tile.is-on { border-color: rgba(var(--accent-rgb), 0.55); outline: 1px solid rgba(var(--accent-rgb), 0.35); outline-offset: -2px; }
.tdk-tile.is-off b { color: var(--muted); }
.tdk-tile.is-off s, .tdk-tile.is-off i { color: var(--muted); }
.tdk-tile.is-stale b { color: var(--warn, #f7a600); }
.tdk-board__map .tdk-empty { grid-column: 1 / -1; margin: 0; padding: 14px 10px; }

.tdk-board__tools {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 6px;
  padding: 7px 8px;
  border-bottom: 1px solid var(--line-dot);
}
.tdk-board__tools .tdk-chips { grid-column: 1 / -1; }
.tdk-board__sort { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.tdk-board__sort span {
  font: 700 9px/1 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
}
.tdk-board__sort select {
  max-width: 108px;
  padding: 6px 6px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #070a0f;
  color: var(--ink-2);
  font: 700 9.5px/1 var(--mono);
  letter-spacing: 0.06em;
  outline: none;
  cursor: pointer;
}
.tdk-board__sort select:focus { border-color: rgba(var(--accent-rgb), 0.5); }
.tdk-board__tools input {
  width: 100%;
  padding: 6px 9px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #070a0f;
  color: var(--ink);
  font: 500 11px/1.2 var(--mono);
  outline: none;
}
.tdk-board__tools input:focus { border-color: rgba(var(--accent-rgb), 0.5); }
.tdk-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.tdk-chips button {
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font: 700 9px/1.4 var(--mono);
  letter-spacing: 0.1em;
}
.tdk-chips button.is-on { border-color: rgba(var(--accent-rgb), 0.5); background: rgba(var(--accent-rgb), 0.12); color: var(--accent); }
.tdk-board__list { overflow: auto; flex: 1 1 auto; min-height: 0; }
.tdk-board__group {
  padding: 5px 9px 3px;
  background: #0b0f15;
  border-top: 1px solid var(--line-dot);
  color: var(--faint);
  font: 700 9px/1 var(--mono);
  letter-spacing: 0.18em;
  position: sticky;
  top: 0;
  z-index: 2;
}
/* a row and its pin: the star holds a column of its own at the right edge, so
   it cannot sit on top of the change reading */
.tdk-board__row { display: grid; grid-template-columns: minmax(0, 1fr) 20px; align-items: stretch; }
.tdk-board__row:hover .tdk-star { opacity: 1; }
.tdk-board__row.is-pinned { background: rgba(var(--accent-rgb), 0.045); }
.tdk-star {
  border: 0;
  border-bottom: 1px dotted var(--line-dot);
  background: transparent;
  color: var(--faint);
  font-size: 11px;
  line-height: 1;
  opacity: 0;
  transition: opacity 0.15s var(--ease), color 0.15s var(--ease);
}
.tdk-star.is-on, .tdk-star:focus-visible { opacity: 1; color: var(--accent); }
.tdk-star:hover { color: var(--accent); }
.tdk-board__group--pinned { color: var(--accent); }
.tdk-board__group b { color: var(--faint); font-weight: 600; }
.tdk-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 8px;
  width: 100%;
  padding: 5px 9px;
  border: 0;
  border-bottom: 1px dotted var(--line-dot);
  background: transparent;
  text-align: left;
  color: var(--ink-2);
  font: 600 11px/1.25 var(--mono);
}
.tdk-row:hover { background: rgba(var(--accent-rgb), 0.06); }
.tdk-row.is-on { background: rgba(var(--accent-rgb), 0.12); box-shadow: inset 2px 0 0 var(--accent); }
.tdk-row__sym { display: flex; align-items: center; gap: 6px; min-width: 0; }
.tdk-row__sym b { color: var(--ink); font-weight: 700; letter-spacing: 0.03em; }
.tdk-row__sym em { color: var(--faint); font-style: normal; font-size: 9px; letter-spacing: 0.08em; }
.tdk-row__px { text-align: right; font-weight: 700; color: var(--ink); }
.tdk-row__sub { display: flex; justify-content: space-between; gap: 8px; font-size: 9.5px; color: var(--faint); }
.tdk-row__chg.up { color: var(--up); }
.tdk-row__chg.down { color: var(--down); }
.tdk-row.is-off .tdk-row__px { color: var(--faint); }
.tdk-row.is-off .tdk-row__chg { color: var(--faint); }
.tdk-tag {
  padding: 0 4px;
  border-radius: 3px;
  border: 1px solid var(--line-2);
  font: 700 8px/1.5 var(--mono);
  letter-spacing: 0.08em;
  color: var(--muted);
}
.tdk-tag--live { border-color: rgba(var(--up-rgb), 0.4); color: var(--up); }
.tdk-row.is-stale .tdk-row__px { color: var(--warn, #f7a600); }
.tdk-row.is-stale .tdk-row__sub { color: rgba(247, 166, 0, 0.75); }
/* the selected row tints its own background, so the secondary line under the
   symbol is read against that tint rather than against the panel: --faint is
   3.7:1 there, which is below the bar for a line naming the instrument */
.tdk-row.is-on .tdk-row__sub { color: var(--ink-2); }
/* The upsell at the foot of the watchlist: one row, gold on hover, and above
   the foot rather than inside it so the count line keeps its own place. It is
   an accent, not a banner -- the desk has to stay a desk. */
.tdk-board__upsell {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex: none;
  padding: 7px 10px;
  border-top: 1px solid var(--line);
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.08), transparent 78%);
  color: var(--muted);
  font: 600 10px/1.4 var(--mono);
  letter-spacing: 0.06em;
  transition: background 0.16s, color 0.16s;
}
.tdk-board__upsell b { color: var(--accent); font-weight: 700; }
.tdk-board__upsell span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tdk-board__upsell u { margin-left: auto; text-decoration: none; color: var(--accent); }
.tdk-board__upsell:hover {
  background: linear-gradient(90deg, rgba(var(--accent-rgb), 0.16), transparent 88%);
  color: var(--ink-2);
}
.tdk-board__upsell:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.tdk-board__foot {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  padding: 5px 9px;
  border-top: 1px solid var(--line);
  background: #070a0f;
  color: var(--faint);
  font: 600 8.5px/1.5 var(--mono);
  letter-spacing: 0.08em;
}
.tdk-board__foot span { display: inline-flex; align-items: center; gap: 5px; }
.tdk-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--faint); }
.tdk-dot--live { background: var(--up); }
.tdk-board__foot #boardCount { margin-left: auto; color: var(--muted); }

/* ==========================================================================
   07. CHART
   ========================================================================== */
.tdk-chart { display: flex; flex-direction: column; min-height: 0; }
.tdk-chart__bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border-bottom: 1px solid var(--line);
  background: var(--head);
  flex-wrap: wrap;
}
.tdk-sym { display: flex; flex-direction: column; margin-right: 4px; }
.tdk-sym b { font: 800 14px/1.1 var(--mono); letter-spacing: 0.06em; }
.tdk-sym em { font: 600 9px/1.3 var(--mono); font-style: normal; color: var(--faint); letter-spacing: 0.1em; text-transform: uppercase; }
.tdk-tfs, .tdk-types, .tdk-ind { display: inline-flex; gap: 2px; }
/* ---- type, then studies --------------------------------------------------
   The candle type and the studies are two different questions — how the bars
   are drawn, and what is drawn on them — and they were one run of chips with
   nothing between them. Each is labelled now, the studies have a rule in front
   of them, and the row is allowed to wrap so a narrow chart bar drops the
   whole studies group onto its own line instead of interleaving the two. */
/* Each group is its own box, so the split is something the eye reads rather
   than something the label asks it to remember: how the bars are drawn on the
   left, what is drawn on them on the right, with real space between the two. */
.tdk-grp {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  padding: 3px 8px 3px 9px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.03);
}
.tdk-grp__lbl {
  font: 700 8.5px/1 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.tdk-grp--ind { border-color: var(--line-2); }
/* eleven periods is more than a narrow chart bar holds, so the period row
   scrolls inside itself the way the function keys do */
.tdk-tfs { flex: 0 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.tdk-tfs::-webkit-scrollbar { display: none; }
.tdk-tfs button { flex: none; }
.tdk-chart__bar { min-width: 0; }
/* the compare picker: one control, because a comparison is one decision */
.tdk-compare { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.tdk-compare span {
  font: 700 9px/1 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--faint);
}
.tdk-compare select {
  max-width: 116px;
  padding: 4px 6px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: #0b0f15;
  color: var(--ink-2);
  font: 700 10px/1 var(--mono);
  letter-spacing: 0.06em;
  outline: none;
  cursor: pointer;
}
.tdk-compare select:focus { border-color: rgba(var(--accent-rgb), 0.5); }
/* the compare reading in the legend, and the way to drop it */
.tdk-ohlc__cmp { display: inline-flex; align-items: center; gap: 6px; color: var(--violet); }
.tdk-ohlc__cmp b { color: inherit; }
.tdk-ohlc__cmp em { font-style: normal; color: var(--faint); }
.tdk-ohlc__cmp em.up { color: var(--up); }
.tdk-ohlc__cmp em.down { color: var(--down); }
.tdk-ohlc__x {
  width: 16px;
  height: 16px;
  padding: 0;
  border: 1px solid var(--line-2);
  border-radius: 3px;
  background: transparent;
  color: var(--faint);
  font: 700 10px/1 var(--mono);
  line-height: 14px;
}
.tdk-ohlc__x:hover { border-color: var(--down); color: var(--down); }
.tdk-chart__bar button {
  padding: 0 8px;
  min-height: 22px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: #0b0f15;
  color: var(--muted);
  font: 700 10px/20px var(--mono);
  letter-spacing: 0.08em;
}
.tdk-chart__bar button:hover { border-color: var(--line-2); color: var(--ink-2); }
.tdk-chart__bar button.is-on { border-color: rgba(var(--accent-rgb), 0.55); background: rgba(var(--accent-rgb), 0.14); color: var(--accent); }
.tdk-chart__btns { display: inline-flex; gap: 2px; margin-left: auto; }

/* ---- the two pickers, which are a phone's controls -----------------------
   The period and the candle type are two chip rows on a desk and two buttons on
   a phone (trade.html carries the reason next to the markup). Outside the
   desk's phone breakpoint they are not drawn at all, so a mouse never gets a
   duplicate control and the chip rows are the only way in. */
.tdk-picks { display: none; }
/* `.tdk-chart__bar button` is (0,1,1) and it sets the chip height and padding;
   the pick is a button in that bar too, so its own rule has to match that
   selector's weight rather than sit under it — a 22px chip with the two lines
   of a pick in it was the first thing this pass got wrong. */
.tdk-chart__bar .tdk-pick {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  align-items: center;
  gap: 1px 8px;
  min-height: 42px;
  padding: 6px 12px;
  border: 1px solid var(--line-2);
  border-radius: 9px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.015));
  color: var(--ink);
  text-align: left;
}
.tdk-chart__bar .tdk-pick s {
  grid-column: 1;
  font: 700 8.5px/1 var(--mono);
  letter-spacing: 0.18em;
  text-decoration: none;
  text-transform: uppercase;
  color: var(--muted);
}
.tdk-chart__bar .tdk-pick b { grid-column: 1; font: 700 15px/1.1 var(--mono); letter-spacing: 0.08em; color: var(--accent); }
/* the chevron, drawn rather than shipped: two strokes, turned by the row it
   sits in, and it turns over while the sheet is open */
.tdk-chart__bar .tdk-pick i {
  grid-row: 1 / span 2;
  grid-column: 2;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--faint);
  border-bottom: 2px solid var(--faint);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 0.18s var(--ease);
}
.tdk-chart__bar .tdk-pick[aria-expanded="true"] { border-color: rgba(var(--accent-rgb), 0.6); }
.tdk-chart__bar .tdk-pick[aria-expanded="true"] i { transform: rotate(-135deg) translate(-2px, -2px); border-color: var(--accent); }
.tdk-chart__bar .tdk-pick:hover { border-color: var(--line-2); background: rgba(255, 255, 255, 0.07); }
.tdk-chart__bar .tdk-pick:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- the sheet both pickers open ----------------------------------------
   A sheet at the bottom of the screen, because that is where a thumb is on a
   phone; rows tall enough to hit without aiming; the choice in force lit in the
   desk's own gold and carrying a line under it that says what it is. */
.tdk-pickbox {
  position: fixed;
  inset: 0;
  z-index: 170;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 10px;
  background: rgba(3, 5, 8, 0.68);
  backdrop-filter: blur(3px);
  animation: tdkPickFade 0.16s var(--ease);
}
.tdk-pickbox__sheet {
  width: min(440px, 100%);
  max-height: min(78vh, 640px);
  max-height: min(78dvh, 640px);
  overflow: auto;
  border: 1px solid var(--line-2);
  border-radius: 16px;
  background: linear-gradient(180deg, #10151d, #0a0e14);
  box-shadow: 0 -18px 50px -22px rgba(0, 0, 0, 0.92), inset 0 1px 0 rgba(255, 255, 255, 0.05);
  animation: tdkPickRise 0.2s var(--ease);
}
.tdk-pickbox__bar { width: 44px; height: 4px; margin: 9px auto 3px; border-radius: 999px; background: var(--line-2); }
.tdk-pickbox header { position: relative; display: grid; gap: 4px; padding: 6px 52px 13px 16px; border-bottom: 1px solid var(--line); }
.tdk-pickbox header b { font: 700 12px/1 var(--mono); letter-spacing: 0.18em; text-transform: uppercase; color: var(--accent); }
.tdk-pickbox header span { font: 500 11px/1.5 var(--ui); color: var(--muted); }
.tdk-pickbox header button {
  position: absolute;
  top: 4px;
  right: 8px;
  width: 34px;
  height: 32px;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  font: 700 15px/1 var(--mono);
}
.tdk-pickbox header button:hover { border-color: var(--accent); color: var(--accent); }
.tdk-pickbox ul { display: grid; gap: 5px; margin: 0; padding: 9px; list-style: none; }
.tdk-pickbox li { margin: 0; }
.tdk-pickbox li button {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 2px 10px;
  width: 100%;
  min-height: 48px;
  padding: 9px 14px;
  border: 1px solid transparent;
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--ink-2);
  text-align: left;
}
.tdk-pickbox li button b { grid-column: 1; font: 700 13px/1.1 var(--mono); letter-spacing: 0.08em; }
.tdk-pickbox li button span { grid-column: 1; font: 500 11px/1.4 var(--ui); color: var(--muted); }
.tdk-pickbox li button i {
  grid-row: 1 / span 2;
  grid-column: 2;
  padding: 4px 8px;
  border-radius: 999px;
  background: var(--accent);
  color: #05070b;
  font: 700 9px/1 var(--mono);
  font-style: normal;
  letter-spacing: 0.14em;
}
.tdk-pickbox li button:hover { border-color: var(--line-2); background: rgba(255, 255, 255, 0.06); }
.tdk-pickbox li button.is-on {
  border-color: rgba(var(--accent-rgb), 0.6);
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.22), rgba(var(--accent-rgb), 0.07));
}
.tdk-pickbox li button.is-on b { color: var(--accent); }
.tdk-pickbox li button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@keyframes tdkPickFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes tdkPickRise { from { transform: translateY(20px); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .tdk-pickbox, .tdk-pickbox__sheet { animation: none; }
}

/* ---- the gear ------------------------------------------------------------
   Settings are one icon in two places — the chart bar and the function keys —
   because "SET" next to "CHART" and "STYLE" and "TYPE" and "PERIOD" was four
   words competing in one strip. The glyph is a stroked gear, so it inherits the
   button's own colour and stays legible when the panel is at 40% opacity. */
.tdk-chart__bar button.tdk-icon-btn svg,
.tdk-fn__gear svg {
  display: block;
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
}
.tdk-chart__bar button.tdk-icon-btn { padding: 0 6px; }
.tdk-fn__gear { padding: 0 10px; }
.tdk-fn__gear:hover { color: var(--accent); }

/* ---- trade auto with AI --------------------------------------------------
   The desk's one gold control, and the only one that is not about the market.
   It is sized and coloured to be found from across the room without stealing
   the accent the whole page is built on: a gold glyph on a near-black slab,
   with the gold arriving as a border and a wash rather than a fill, so the two
   BUY / SELL slabs stay the brightest things on the screen. */
.tdk-ai {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: none;
  margin-left: 8px;
  padding: 0 12px;
  min-height: 30px;
  border: 1px solid rgba(var(--accent-rgb), 0.62);
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.2), rgba(var(--accent-rgb), 0.07));
  color: var(--accent) !important;
  font: 700 9.5px/1 var(--mono) !important;
  letter-spacing: 0.14em;
  white-space: nowrap;
  transition: box-shadow 0.18s var(--ease), transform 0.14s var(--ease), background 0.18s;
  box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.35);
}
/* ---- the same control, inside the chart ----------------------------------
   It used to be the last chip in the chart bar, where it read as one more
   toolbar button. It is the reader's account rather than the market, so it now
   floats in the frame itself, top right, larger than any chip around it: a
   filled gold slab with the glyph at 18px, because it is the only control on
   this page that asks for money and it should not need finding twice. */
.tdk-canvas .tdk-ai {
  position: absolute;
  top: 12px;
  right: 14px;
  z-index: 3;
  margin: 0;
  min-height: 50px;
  /* the left edge carries the lit dot, so the label is inset by its width and
     the dot never sits on a letter */
  padding: 0 22px 0 34px;
  gap: 12px;
  font-size: 13px !important;
  letter-spacing: 0.16em;
  border-width: 1.5px;
  border-color: rgba(var(--accent-rgb), 0.85);
  /* a slab rather than a pill: the frame around it is angular, and a 14px
     radius is the shape the rest of the desk's controls are drawn in */
  border-radius: 14px;
  background:
    radial-gradient(130% 200% at 0% 0%, rgba(var(--accent-rgb), 0.36), transparent 60%),
    linear-gradient(180deg, rgba(var(--accent-rgb), 0.42), rgba(var(--accent-rgb), 0.12));
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
  overflow: hidden;
  box-shadow: 0 16px 38px -22px rgba(var(--accent-rgb), 0.9),
    inset 0 1px 0 rgba(255, 255, 255, 0.14);
}
/* the engine is running: a lit dot on the left edge, breathing slowly, so the
   one control on this page that trades on its own says that it is alive */
.tdk-canvas .tdk-ai::before {
  content: '';
  position: absolute;
  left: 14px;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -4px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #fff 0%, #ffd166 55%, rgba(255, 209, 102, 0.2) 100%);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.18), 0 0 12px 2px rgba(var(--accent-rgb), 0.55);
  animation: tdkAiPulse 2.8s ease-in-out infinite;
}
/* and a slow sheen crossing the slab, which is the difference between a gold
   button and a lit one */
.tdk-canvas .tdk-ai::after {
  content: '';
  position: absolute;
  top: -60%;
  bottom: -60%;
  width: 38%;
  left: -40%;
  background: linear-gradient(100deg, transparent 0%, rgba(255, 255, 255, 0.16) 50%, transparent 100%);
  transform: skewX(-18deg);
  animation: tdkAiSheen 5.4s ease-in-out infinite;
  pointer-events: none;
}
.tdk-canvas .tdk-ai svg { width: 21px; height: 21px; filter: drop-shadow(0 0 8px rgba(var(--accent-rgb), 0.55)); }
@keyframes tdkAiPulse {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.18), 0 0 12px 2px rgba(var(--accent-rgb), 0.55); }
  50% { opacity: 0.72; box-shadow: 0 0 0 6px rgba(var(--accent-rgb), 0.08), 0 0 18px 3px rgba(var(--accent-rgb), 0.35); }
}
@keyframes tdkAiSheen {
  0%, 55% { left: -40%; opacity: 0; }
  62% { opacity: 1; }
  86%, 100% { left: 118%; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .tdk-canvas .tdk-ai::before, .tdk-canvas .tdk-ai::after { animation: none; }
  .tdk-canvas .tdk-ai::after { opacity: 0; }
}
.tdk-ai svg {
  width: 14px;
  height: 14px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.tdk-ai:hover {
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.3), rgba(var(--accent-rgb), 0.14));
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.16), 0 8px 22px -12px rgba(var(--accent-rgb), 1);
  transform: translateY(-1px);
}
.tdk-ai:active { transform: translateY(1px); }
.tdk-ai:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 1340px) {
  /* the label is the first thing a narrow chart bar can do without; the glyph
     and the tooltip still say what it is */
  .tdk-ai span { display: none; }
  .tdk-ai { padding: 0 9px; }
  .tdk-canvas .tdk-ai { padding: 0 14px; min-height: 38px; }
}

/* ---- the print-history control -------------------------------------------
   Sits with the studies, because that is what it feeds, and it is only on the
   page while a study that draws prints is on. The second line states the cost
   before the tap and the coverage after it: a control that fetched 150 KB
   without saying so, or that kept offering a page the venue does not have,
   would be the kind of button this desk tries not to have. */
.tdk-prints {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-left: 4px;
  padding: 0 10px;
  min-height: 22px;
  border: 1px dashed rgba(var(--accent-rgb), 0.45);
  border-radius: 3px;
  background: rgba(var(--accent-rgb), 0.06);
  color: var(--ink-2);
  font: 700 10px/20px var(--mono);
  letter-spacing: 0.08em;
  cursor: pointer;
  white-space: nowrap;
}
.tdk-prints b { color: var(--accent); letter-spacing: 0.12em; }
.tdk-prints span { color: var(--muted); font-weight: 600; letter-spacing: 0.04em; }
.tdk-prints:hover { border-style: solid; border-color: rgba(var(--accent-rgb), 0.75); background: rgba(var(--accent-rgb), 0.14); }
.tdk-prints:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tdk-prints[hidden] { display: none; }
.tdk-prints:disabled { cursor: default; }
.tdk-prints.is-done { border-style: solid; border-color: rgba(var(--up-rgb), 0.45); background: rgba(var(--up-rgb), 0.08); }
.tdk-prints.is-done b { color: var(--up); }
.tdk-prints.is-out { border-color: var(--line-2); background: transparent; }
.tdk-prints.is-out b { color: var(--faint); }
@media (max-width: 900px) {
  /* the coverage line is what a narrow bar can do without; the label stays,
     because a chip with no words is a chip nobody presses */
  .tdk-prints span { display: none; }
}
.tdk-ohlc {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  padding: 5px 10px;
  border-bottom: 1px solid var(--line-dot);
  font: 600 10.5px/1.3 var(--mono);
  color: var(--faint);
  background: #080b11;
}
.tdk-ohlc span { display: inline-flex; align-items: baseline; gap: 5px; }
.tdk-ohlc b { color: var(--ink); font-weight: 700; }
.tdk-ohlc .up { color: var(--up); }
.tdk-ohlc .down { color: var(--down); }
/* The canvas is taken out of flow and pinned to the pane. Left in flow with a
   percentage height it has no definite containing height to resolve against —
   a flex item's own height is auto — so the browser falls back to the
   intrinsic ratio of the bitmap the engine last wrote into it, and the chart
   ends up the shape of the *previous* pane rather than the one it is in. That
   shows up worst on a phone, where the pane changes size on every tab. */
.tdk-canvas { position: relative; flex: 1 1 auto; min-height: 0; }
.tdk-canvas > canvas { position: absolute; inset: 0; }
/* `touch-action: none` is what lets the canvas see a drag at all: with the
   browser's default the first swipe scrolls the page instead and the chart
   never gets the gesture. The tap highlight and the text selection go with it,
   since both fire on a chart you are trying to pan. */
.tdk-canvas canvas {
  display: block;
  width: 100%;
  height: 100%;
  cursor: crosshair;
  touch-action: none;
  -ms-touch-action: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}
.tdk-canvas canvas.is-grabbing { cursor: grabbing; }
.tdk-canvas__msg {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  padding: 20px;
  background: rgba(5, 7, 11, 0.86);
  backdrop-filter: blur(2px);
}
.tdk-canvas__msg.is-on { display: flex; }
.tdk-canvas__msg b { font: 700 12px/1.3 var(--mono); letter-spacing: 0.1em; color: var(--accent); }
.tdk-canvas__msg span { max-width: 46ch; color: var(--muted); font-size: 12px; }/* performance table, the export buttons and the alert arming row */
.tdk-tbl--perf { margin-top: 8px; }
.tdk-tbl tr.is-fired td { color: var(--faint); text-decoration: line-through; }
.tdk-alert-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  background: #070a0f;
  font: 600 9.5px/1.4 var(--mono);
  letter-spacing: 0.07em;
  color: var(--faint);
}
.tdk-alert-form b { color: var(--ink); letter-spacing: 0.1em; }
.tdk-alert-form label { display: inline-flex; align-items: center; gap: 5px; }
.tdk-alert-form input {
  width: 110px;
  padding: 4px 6px;
  border: 1px solid var(--line-2);
  border-radius: 3px;
  background: #0b0f16;
  color: var(--ink);
  font: 600 10px/1 var(--mono);
}
.tdk-alert-dir { display: inline-flex; gap: 3px; }
.tdk-alert-form button, .tdk-actions button {
  padding: 5px 9px;
  border: 1px solid var(--line-2);
  border-radius: 3px;
  background: transparent;
  color: var(--muted);
  font: 600 9.5px/1 var(--mono);
  letter-spacing: 0.08em;
  cursor: pointer;
}
.tdk-alert-form button:hover, .tdk-actions button:hover { color: var(--ink); border-color: var(--accent); }
.tdk-alert-form button.is-on { background: rgba(var(--accent-rgb), 0.16); border-color: var(--accent); color: var(--ink); }
.tdk-actions { display: flex; gap: 6px; padding: 10px; flex-wrap: wrap; }
.tdk-actions button.is-danger:hover { border-color: var(--down); color: var(--down); }
.tdk-note { margin: 8px 10px; color: var(--faint); font: 600 10px/1.5 var(--ui); }
.tdk-foot-type { font-style: normal; color: var(--accent); letter-spacing: 0.08em; }

/* the drawing row: the tools an annotated chart needs, kept to one line so the
   price pane keeps the height */
.tdk-draw {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border-bottom: 1px solid var(--line);
  background: #070a0f;
  font: 600 9px/1 var(--mono);
  letter-spacing: 0.1em;
  color: var(--faint);
  overflow-x: auto;
  scrollbar-width: none;
}
.tdk-draw::-webkit-scrollbar { display: none; }
.tdk-draw__set { display: inline-flex; gap: 3px; }
.tdk-draw__end { display: inline-flex; align-items: center; gap: 5px; margin-left: auto; }
.tdk-draw button {
  padding: 3px 6px;
  border: 1px solid var(--line-2);
  border-radius: 3px;
  background: transparent;
  color: var(--muted);
  font: 600 9px/1 var(--mono);
  letter-spacing: 0.08em;
  cursor: pointer;
}
.tdk-draw button:hover { color: var(--ink); border-color: var(--accent); }
.tdk-draw button.is-on { background: rgba(var(--accent-rgb), 0.16); border-color: var(--accent); color: var(--ink); }
.tdk-draw button[data-tool="cursor"].is-on { background: rgba(255, 255, 255, 0.06); border-color: var(--line-2); }
.tdk-draw #drawCount { min-width: 58px; text-align: right; color: var(--muted); }

/* ---- bar replay: a mode, so it is coloured like one ---- */
.tdk-replay {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(90deg, rgba(232, 121, 249, 0.12), rgba(232, 121, 249, 0.02) 60%, transparent);
  font: 600 9px/1 var(--mono);
  letter-spacing: 0.1em;
  color: var(--faint);
}
.tdk-replay[hidden] { display: none; }
.tdk-replay__lead {
  padding: 2px 6px;
  border: 1px solid rgba(232, 121, 249, 0.55);
  border-radius: 3px;
  color: #e879f9;
}
.tdk-replay button {
  min-height: 24px;
  padding: 3px 8px;
  border: 1px solid var(--line-2);
  border-radius: 3px;
  background: transparent;
  color: var(--muted);
  font: 600 9px/1 var(--mono);
  letter-spacing: 0.08em;
  cursor: pointer;
}
.tdk-replay button:hover { color: var(--ink); border-color: #e879f9; }
.tdk-replay button:disabled { opacity: 0.4; cursor: default; }
.tdk-replay button.is-danger:hover { color: var(--down); border-color: var(--down); }
.tdk-replay #rpSeek {
  flex: 1 1 120px;
  min-width: 90px;
  height: 18px;
  margin: 0 4px;
  accent-color: #e879f9;
  cursor: pointer;
}
.tdk-replay__speed { display: inline-flex; align-items: center; gap: 5px; }
.tdk-replay__speed select {
  padding: 2px 4px;
  border: 1px solid var(--line-2);
  border-radius: 3px;
  background: #0b0f15;
  color: var(--ink-2);
  font: 600 9px/1 var(--mono);
}
.tdk-replay__at { margin-left: auto; color: var(--muted); white-space: nowrap; }
.tdk-relay-badge {
  padding: 1px 6px;
  border: 1px solid rgba(232, 121, 249, 0.5);
  border-radius: 3px;
  color: #e879f9;
}

.tdk-chart__foot { 
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  padding: 5px 10px;
  border-top: 1px solid var(--line);
  background: #070a0f;
  font: 600 10px/1.4 var(--mono);
  color: var(--faint);
}
.tdk-chart__foot b { color: var(--ink-2); }
.tdk-chart__foot .up { color: var(--up); }
.tdk-chart__foot .down { color: var(--down); }
.tdk-chart.is-full {
  position: fixed;
  inset: 0;
  z-index: 120;
  border-radius: 0;
  border-color: var(--accent);
}
body.has-full .tdk-top, body.has-full .tdk-fn, body.has-full .tdk-tape, body.has-full .tdk-blotter,
body.has-full .tdk-grip, body.has-full .tdk-board, body.has-full .tdk-side { display: none; }
body.has-full .tdk-grid { grid-template-columns: minmax(0, 1fr); padding: 0; }

/* ==========================================================================
   08. TICKET · BOOK · TAPE · BLOTTER
   ========================================================================== */
/* the ticket keeps its own scroll as a backstop: if a reader's font or zoom
   makes a row taller, the ticket scrolls rather than quietly hiding its own
   button */
.tdk-ticket { padding-bottom: 8px; overflow-y: auto; scrollbar-width: thin; }
/* What the next press does, stated before it is pressed. It is above the two
   buttons and it has a fixed height, which is the point: the ticket's message
   below it is replaced in place, and a note that grew or shrank used to push
   these two buttons down the panel — a moving target the reader clicks at the
   position the button was, not the position it is. */
.tdk-ticket__do {
  flex: none;
  /* two reserved lines: the sentence is allowed to wrap on a narrow ticket
     instead of being ellipsised, and the fixed height means the wrap cannot
     move the buttons below it */
  height: 30px;
  margin: 4px 9px 0;
  font: 700 9.5px/1.5 var(--mono);
  letter-spacing: 0.07em;
  color: var(--up);
  overflow: hidden;
}
.tdk-ticket__do.is-sell { color: var(--down); }
/* The two sides sit on one row at the foot of the ticket, under the size they
   are sized with: reading top-down you configure the order, set the lot, and
   fire. Each button is a filled action rather than a radio, because a side
   button that only selects leaves the reader hunting for the one that sends.

   SIMPLE AND LOUD. The label is one word and one arrow — the instrument is
   already named in the panel head, and the longer two-line labels this used to
   carry were the reason the buttons had to be squinted at. What is left is a
   large, fully saturated slab with a dark glyph on it, which is the highest
   contrast pairing on the page and the thing the eye lands on first. */
.tdk-ticket__side { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 7px 8px 4px; }
.tdk-ticket__side button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 58px;
  padding: 8px 6px;
  border: 1px solid rgba(0, 0, 0, 0.45);
  border-radius: 10px;
  background: #0b0f15;
  color: var(--muted);
  cursor: pointer;
  transition: filter 0.12s linear, transform 0.12s var(--ease), box-shadow 0.16s var(--ease);
}
.tdk-ticket__side button svg {
  width: 19px;
  height: 19px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.tdk-ticket__side button b {
  font: 800 17px/1 var(--mono);
  letter-spacing: 0.16em;
}
/* The two slabs are the brightest things on the page and they stay that way: a
   lighter top stop behind near-black type, a deeper bottom stop so the shape
   reads as a slab rather than a wash, and a heavier glyph. The two are also
   pulled further apart from each other — the green brighter, the red deeper —
   because the one thing a reader must never do at a ticket is mistake the side.

   The rim is black now, and there is no drop shadow under either slab. The
   light rim and the coloured glow were there to lift the buttons off the panel,
   and what they actually did was put a soft white outline and a coloured haze
   around the two loudest controls on the page — the button stopped at its own
   edge and carried a shadow the rest of the ticket does not have. A 2px black
   rim draws the same boundary on a dark panel, keeps the slab flat against it,
   and leaves the colour to say which side is which. */
.tdk-ticket__side button[data-side="buy"] {
  background: linear-gradient(180deg, #8affdf 0%, #1bdca4 48%, #045c44 100%);
  color: #00150f;
  border: 2px solid #05070b;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.45);
  box-shadow: none;
}
.tdk-ticket__side button[data-side="sell"] {
  background: linear-gradient(180deg, #ffc2ca 0%, #f0455d 48%, #7d0f22 100%);
  color: #1c0207;
  border: 2px solid #05070b;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.45);
  box-shadow: none;
}
/* the glyph takes the same near-black as the word, so the arrow is part of the
   label rather than a decoration beside it */
.tdk-ticket__side button svg { stroke-width: 3; }
.tdk-ticket__side button b { font-size: 18px; }
.tdk-ticket__side button b { text-shadow: inherit; }
.tdk-ticket__side button:hover { filter: brightness(1.08) saturate(1.05); transform: translateY(-1px); }
.tdk-ticket__side button:active { transform: translateY(1px); filter: brightness(0.96); }
.tdk-ticket__side button:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
/* the side the last ticket went out on keeps a ring, so the desk still records
   which way the book was last read without making either button a radio. The
   ring is an outline now, not a shadow: a flat slab with a drawn outline reads
   as a marked button, where a glow under it read as a lit one. */
.tdk-ticket__side button.is-on { outline: 2px solid rgba(255, 255, 255, 0.55); outline-offset: 2px; }
/* the lot row: the size is the one field the whole ticket is built around, so
   it reads larger than the price and target fields above it */
.tdk-ticket__row--lot { padding-top: 6px; }
.tdk-ticket__row--lot input { font-size: 14px; padding: 8px 9px; }
.tdk-ticket__row {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
}
.tdk-ticket__row label, .tdk-ticket__grid label, .tdk-ticket__lev label {
  font: 700 9px/1 var(--mono);
  letter-spacing: 0.14em;
  color: var(--faint);
}
.tdk-ticket__row input, .tdk-ticket__grid input {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #070a0f;
  color: var(--ink);
  font: 700 12px/1.2 var(--mono);
  outline: none;
}
.tdk-ticket__row input:focus, .tdk-ticket__grid input:focus { border-color: rgba(var(--accent-rgb), 0.55); }
.tdk-ticket__px { font: 600 9.5px/1 var(--mono); color: var(--faint); letter-spacing: 0.06em; }
.tdk-ticket__types { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 6px 8px; }
.tdk-ticket__types button {
  min-height: 24px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: #0b0f15;
  color: var(--muted);
  font: 700 9.5px/1 var(--mono);
  letter-spacing: 0.1em;
}
.tdk-ticket__types button.is-on { border-color: rgba(var(--accent-rgb), 0.55); background: rgba(var(--accent-rgb), 0.14); color: var(--accent); }
.tdk-ticket__pcts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; padding: 2px 8px 6px; }
.tdk-ticket__pcts button {
  min-height: 22px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: transparent;
  color: var(--faint);
  font: 700 9px/1 var(--mono);
  letter-spacing: 0.08em;
}
.tdk-ticket__pcts button:hover { border-color: rgba(var(--accent-rgb), 0.45); color: var(--accent); }
.tdk-ticket__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 4px 8px; }
.tdk-ticket__grid div { display: flex; flex-direction: column; gap: 4px; }
.tdk-ticket__lev { display: grid; grid-template-columns: 52px minmax(0, 1fr) 34px; align-items: center; gap: 8px; padding: 8px; }
.tdk-ticket__lev input { accent-color: var(--accent); }
.tdk-ticket__lev b { font: 700 11px/1 var(--mono); text-align: right; }
/* The two things on the ticket that must never be pushed out of view are the
   button and the message under it, so the readings list is the part that gives:
   it takes what is left and scrolls. It is set two to a line, which turns eight
   rows into four and is height the ladder and the tape get to keep. */
.tdk-ticket__math {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin: 4px 0 8px;
  padding: 0;
  flex: 0 1 auto;
  min-height: 30px;
  overflow-y: auto;
}
.tdk-ticket__side, .tdk-ticket__row, .tdk-ticket__types, .tdk-ticket__pcts,
.tdk-ticket__grid, .tdk-ticket__lev, .tdk-ticket__risk,  .tdk-ticket__go, .tdk-ticket__do { flex: none; }
.tdk-ticket__math li {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 9px;
  border-top: 1px dotted var(--line-dot);
  font: 600 10.5px/1.4 var(--mono);
  color: var(--faint);
}
.tdk-ticket__math li:nth-child(2n) { border-left: 1px dotted var(--line-dot); }
.tdk-ticket__math b { color: var(--ink-2); }
.tdk-ticket__go {
  margin: 0 8px;
  min-height: 38px;
  border: 0;
  border-radius: 4px;
  background: linear-gradient(180deg, #27e0af, #14b98d);
  color: #04150f;
  font: 800 12px/1 var(--mono);
  letter-spacing: 0.16em;
}
.tdk-ticket__go.is-sell { background: linear-gradient(180deg, #ff7d8d, #e8475c); color: #1a0508; }
.tdk-ticket__go:hover { filter: brightness(1.08); }

.tdk-book__cols, .tdk-trades__cols {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 6px;
  padding: 4px 9px;
  border-bottom: 1px solid var(--line-dot);
  font: 700 8.5px/1 var(--mono);
  letter-spacing: 0.12em;
  color: var(--faint);
}
.tdk-book__cols s, .tdk-trades__cols s { text-decoration: none; }
.tdk-book__cols s:nth-child(2), .tdk-book__cols s:nth-child(3) { text-align: right; }
.tdk-trades__cols s:nth-child(2), .tdk-trades__cols s:nth-child(3) { text-align: right; }
/* the ladder scrolls inside its pane so the imbalance footer stays on screen */
.tdk-book__side {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow-y: auto;
  flex: 0 1 auto;
  min-height: 0;
  scrollbar-width: none;
}
.tdk-book__side::-webkit-scrollbar { display: none; }
.tdk-book__mid, .tdk-book__cols, .tdk-book__imb { flex: none; }
#bookAsks { justify-content: flex-end; }
#bookBids { justify-content: flex-start; }
.tdk-bk {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 6px;
  padding: 2px 9px;
  position: relative;
  border: 0;
  background: transparent;
  font: 600 10.5px/1.5 var(--mono);
  color: var(--ink-2);
  text-align: left;
}
.tdk-bk u { text-decoration: none; text-align: right; }
.tdk-bk i {
  position: absolute;
  top: 1px;
  bottom: 1px;
  right: 0;
  background: rgba(var(--up-rgb), 0.1);
  pointer-events: none;
}
.tdk-bk.is-ask i { background: rgba(var(--down-rgb), 0.1); }
.tdk-bk:hover { background: rgba(255, 255, 255, 0.05); }
.tdk-bk.is-ask .tdk-bk__p { color: var(--down); }
.tdk-bk:not(.is-ask) .tdk-bk__p { color: var(--up); }
.tdk-bk span, .tdk-bk u { position: relative; z-index: 1; }
.tdk-book__mid {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 9px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: #0b0f15;
}
.tdk-book__mid b { font: 800 14px/1 var(--mono); }
.tdk-book__mid em { font: 600 9.5px/1 var(--mono); font-style: normal; color: var(--faint); letter-spacing: 0.06em; }
.tdk-trades__rows { overflow-y: auto; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.tdk-trades__cols, .tdk-trades__foot { flex: none; }
.tdk-tr {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 6px;
  padding: 2px 9px;
  font: 600 10.5px/1.5 var(--mono);
  color: var(--muted);
  animation: tdkFlash 0.7s var(--ease) both;
}
.tdk-tr u, .tdk-tr s { text-decoration: none; text-align: right; }
.tdk-tr.is-buy u { color: var(--up); }
.tdk-tr.is-sell u { color: var(--down); }
@keyframes tdkFlash { from { background: rgba(255, 255, 255, 0.07); } }

.tdk-tabs { display: flex; gap: 3px; margin-left: 12px; }
.tdk-tabs button {
  padding: 3px 9px;
  border: 1px solid var(--line);
  border-radius: 3px 3px 0 0;
  background: #0b0f15;
  color: var(--muted);
  font: 700 9.5px/1.5 var(--mono);
  letter-spacing: 0.1em;
}
.tdk-tabs button b { color: var(--accent); }
.tdk-tabs button.is-on { border-color: rgba(var(--accent-rgb), 0.5); background: rgba(var(--accent-rgb), 0.13); color: var(--accent); }
.tdk-tbl { width: 100%; border-collapse: collapse; font: 600 11px/1.5 var(--mono); }
.tdk-tbl th, .tdk-tbl td { padding: 5px 9px; border-bottom: 1px dotted var(--line-dot); text-align: right; white-space: nowrap; }
.tdk-tbl th {
  position: sticky;
  top: 0;
  background: #0b0f15;
  color: var(--accent);
  font: 700 9px/1.5 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  z-index: 1;
}
.tdk-tbl th:first-child, .tdk-tbl td:first-child { text-align: left; }
.tdk-tbl tbody tr:hover td { background: rgba(255, 255, 255, 0.03); }
.tdk-tbl .up { color: var(--up); }
.tdk-tbl .down { color: var(--down); }
.tdk-tbl .badge-side { font-weight: 800; }
.tdk-tbl .badge-side.buy { color: var(--up); }
.tdk-tbl .badge-side.sell { color: var(--down); }
.tdk-tbl button {
  padding: 2px 8px;
  border: 1px solid var(--line-2);
  border-radius: 3px;
  background: transparent;
  color: var(--muted);
  font: 700 9px/1.5 var(--mono);
  letter-spacing: 0.08em;
}
.tdk-tbl button:hover { border-color: var(--accent); color: var(--accent); }
.tdk-empty { padding: 18px; color: var(--faint); font: 600 11px/1.6 var(--mono); text-align: center; }
/* The blotter's ACCOUNT tab is a sheet of tiles. It is NOT `.tdk-acct`: that
   name belongs to the header's equity strip, and two rules on one name meant
   the later grid won — which turned the top bar into a 150px-column grid. One
   name, one job. */
.tdk-acctgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1px; background: var(--line-dot); }
.tdk-acctgrid > div { padding: 9px 11px; background: var(--panel); display: flex; flex-direction: column; gap: 5px; }
.tdk-acctgrid span { font: 700 9px/1 var(--mono); letter-spacing: 0.14em; color: var(--faint); text-transform: uppercase; }
.tdk-acctgrid b { font: 700 15px/1 var(--mono); color: var(--ink); }
.tdk-acctgrid b.up { color: var(--up); }
.tdk-acctgrid b.down { color: var(--down); }
.tdk-acctgrid canvas { width: 100%; height: 46px; display: block; }

/* ==========================================================================
   09. FOOT + TOASTS
   ========================================================================== */
.toasts { position: fixed; right: 14px; bottom: 14px; z-index: 150; display: flex; flex-direction: column; gap: 8px; }
.toast {
  display: flex;
  gap: 9px;
  align-items: flex-start;
  min-width: 240px;
  max-width: 340px;
  padding: 10px 12px;
  border: 1px solid var(--line-2);
  border-radius: 6px;
  background: rgba(8, 11, 17, 0.96);
  color: var(--ink-2);
  font: 600 11px/1.5 var(--mono);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.toast.is-in { opacity: 1; transform: none; }
.toast b { color: var(--accent); }
.toast strong { color: var(--ink); }

/* ==========================================================================
   09b. HELP OVERLAY — the key list, on demand
   ========================================================================== */
.tdk-help {
  position: fixed;
  inset: 0;
  z-index: 160;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(3, 5, 8, 0.74);
  backdrop-filter: blur(3px);
}
.tdk-help > header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, #12161d, #0a0e14);
}
.tdk-help > header b { font: 700 11px/1 var(--mono); letter-spacing: 0.16em; color: var(--accent); }
.tdk-help > header button {
  margin-left: auto;
  width: 26px;
  height: 24px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  font: 700 14px/1 var(--mono);
}
.tdk-help__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1px;
  width: min(760px, 100%);
  max-height: min(60vh, 460px);
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--line-dot);
}
.tdk-help section { padding: 12px 14px; background: var(--panel); }
.tdk-help h4 {
  margin: 0 0 8px;
  font: 700 10px/1 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
/* ---- chart settings: the same overlay, with controls in it ---- */
.tdk-set .tdk-help__cols { max-height: min(72vh, 620px); }
.tdk-set__hint { font: 600 10px/1 var(--mono); letter-spacing: 0.1em; color: var(--muted); }
.tdk-set li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 0;
}
.tdk-set li > span:first-child {
  font: 600 11px/1.4 var(--mono);
  color: var(--muted);
  letter-spacing: 0.04em;
}
.tdk-set__seg { display: inline-flex; border: 1px solid var(--line-2); border-radius: 4px; overflow: hidden; }
.tdk-set__seg button,
.tdk-set [data-toggle] {
  min-width: 52px;
  padding: 5px 9px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font: 700 10px/1 var(--mono);
  letter-spacing: 0.08em;
  cursor: pointer;
}
.tdk-set [data-toggle] { border: 1px solid var(--line-2); border-radius: 4px; }
.tdk-set__seg button + button { border-left: 1px solid var(--line-2); }
.tdk-set__seg button.is-on,
.tdk-set [data-toggle].is-on { background: var(--accent); color: #05070b; border-color: var(--accent); }
.tdk-set [data-color] {
  width: 54px;
  height: 24px;
  padding: 0;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  cursor: pointer;
}
.tdk-set__wide { grid-column: 1 / -1; }
.tdk-set__ind {
  display: grid;
  grid-template-columns: minmax(96px, 130px) 1fr auto;
  align-items: center;
  gap: 10px;
}
.tdk-set__fields { display: flex; gap: 6px; min-width: 0; }
.tdk-set__fields input {
  width: 100%;
  min-width: 0;
  padding: 5px 7px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: #05070b;
  color: var(--ink);
  font: 600 10.5px/1 var(--mono);
}
.tdk-set__fields input:focus { outline: 1px solid var(--accent); }
.tdk-set__fields em { color: var(--faint); font: 500 10px/1 var(--mono); }
.tdk-set__num {
  width: 68px;
  padding: 5px 7px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: #05070b;
  color: var(--ink);
  font: 700 10.5px/1.2 var(--mono);
  text-align: right;
}
.tdk-set__num:focus { outline: 1px solid var(--accent); }
.tdk-set__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(760px, 100%);
  margin-top: 10px;
  font: 600 10.5px/1.5 var(--mono);
  color: var(--faint);
}
.tdk-set__foot button {
  padding: 7px 14px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  color: var(--ink);
  font: 700 10px/1 var(--mono);
  letter-spacing: 0.1em;
  cursor: pointer;
}
.tdk-set__foot button[data-set-close] { margin-left: auto; background: var(--accent); color: #05070b; border-color: var(--accent); }

/* --------------------------------------------------------------------------
   09b-2. THE SETTINGS WINDOW — bigger, and two halves
   --------------------------------------------------------------------------
   The dialog used to be one grid of six sections with an eighteen-row studies
   table bolted on the bottom, opened by an unlabelled gear in the function bar.
   It has two tabs now and the studies have their own window: a list of every
   study, whether it is on the frame, and — only while it is on — a gear that
   opens that study's own dialog.

   The frame is wider and taller than the old one because a settings window with
   sliders in it is read, not glanced at, and the rows below need the room. */
.tdk-set--big .tdk-help__cols,
.tdk-set--big .tdk-set__foot { width: min(940px, 100%); }
.tdk-set--big .tdk-help__cols { max-height: min(74vh, 660px); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
/* ---- the two stacks ------------------------------------------------------
   Each column of the Chart & desk pane is a stack of sections, and every
   section in a stack grows to take the leftover height of its column. That is
   what keeps the halves level: a grid of tiles would stretch the short sections
   to the tallest one in their row and leave the reader looking at empty panel
   (see the window's own note in js/trade-panel.js). The 1px gaps are the
   container's background showing through, the same way the grid's gaps were. */
.tdk-set__stack { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.tdk-set__stack > section { flex: 1 1 auto; }

.tdk-set__tabs {
  display: flex;
  gap: 6px;
  width: min(940px, 100%);
  margin-bottom: 9px;
}
.tdk-set__tabs button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid var(--line-2);
  border-radius: 5px;
  background: transparent;
  color: var(--ink-2);
  font: 700 10px/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
}
.tdk-set__tabs button.is-on { border-color: var(--accent); color: var(--accent); background: rgba(255, 187, 0, 0.08); }
.tdk-set__tabs button b {
  padding: 2px 6px;
  border-radius: 999px;
  background: rgba(var(--up-rgb), 0.16);
  color: var(--up);
  font: 700 9.5px/1.4 var(--mono);
}
.tdk-set__pane { width: min(940px, 100%); }
.tdk-set__pane[hidden] { display: none; }
.tdk-set__lead {
  margin: 0 0 10px;
  font: 500 11px/1.6 var(--ui);
  color: var(--muted);
  max-width: 78ch;
}

/* the list of studies. Every row is a name, what it is set to, the way into its
   own settings, and the switch — in that order, so the gear is beside the study
   it belongs to rather than in a column of its own */
.tdk-set__indlist {
  display: grid;
  gap: 1px;
  max-height: min(46vh, 400px);
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--line-dot);
}
.tdk-set__indlist .tdk-set__ind {
  grid-template-columns: minmax(0, 1fr) auto;
  padding: 8px 12px;
  background: var(--panel);
}
.tdk-set__indname { display: grid; gap: 3px; min-width: 0; }
.tdk-set__indname > span,
.tdk-set__indname {
  font: 700 11px/1.2 var(--mono);
  color: var(--ink-2);
  letter-spacing: 0.03em;
}
.tdk-set__ind.is-on .tdk-set__indname { color: var(--ink); }
.tdk-set__indname em {
  font-style: normal;
  font: 500 10px/1.3 var(--mono);
  color: var(--faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tdk-set__indacts { display: inline-flex; align-items: center; gap: 6px; }
.tdk-set__gear {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 9px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}
.tdk-set__gear svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
}
.tdk-set__gear s { text-decoration: none; font: 700 9px/1 var(--mono); letter-spacing: 0.12em; }
.tdk-set__gear:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.tdk-set__gear:disabled { opacity: 0.34; cursor: not-allowed; }
.tdk-set__sw {
  min-width: 46px;
  padding: 5px 9px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  font: 700 9.5px/1 var(--mono);
  letter-spacing: 0.1em;
  cursor: pointer;
}
.tdk-set__sw.is-on { border-color: var(--up); color: var(--up); background: rgba(var(--up-rgb), 0.12); }

/* ---- one study's own dialog ----
   A second window over the first, wider than the settings list and scrolling
   inside itself: a study with three groups of rows is tall, and a dialog that
   grows past the viewport is a dialog with rows nobody can reach. */
.tdk-ip {
  z-index: 165;
  align-content: start;
  overflow: auto;
  padding-top: 14px;
  padding-bottom: 14px;
}
.tdk-ip__head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  width: min(880px, 100%);
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
.tdk-ip__head b { font: 700 13px/1 var(--mono); letter-spacing: 0.14em; color: var(--accent); text-transform: uppercase; }
.tdk-ip__head em { font-style: normal; font: 500 10.5px/1 var(--mono); color: var(--faint); }
.tdk-ip__head button {
  margin-left: auto;
  width: 26px;
  height: 24px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  font: 700 14px/1 var(--mono);
  cursor: pointer;
}
.tdk-ip__switch {
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(880px, 100%);
  padding: 10px 0 2px;
  font: 700 10px/1 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.tdk-ip__body {
  display: grid;
  gap: 1px;
  width: min(880px, 100%);
  margin-top: 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--line-dot);
  overflow: hidden;
}
.tdk-ip__sec { padding: 12px 14px; background: var(--panel); }
.tdk-ip__rows,
.tdk-ip__params { display: grid; gap: 8px; list-style: none; margin: 0; padding: 0; }
.tdk-ip__row,
.tdk-ip__params li {
  display: grid;
  grid-template-columns: minmax(140px, 210px) 1fr;
  align-items: center;
  gap: 12px;
}
.tdk-ip__lbl,
.tdk-ip__params label {
  font: 600 10.5px/1.3 var(--mono);
  color: var(--ink-2);
  letter-spacing: 0.03em;
}
.tdk-ip__params input {
  width: 100%;
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: #05070b;
  color: var(--ink);
  font: 600 11px/1 var(--mono);
}
.tdk-ip__params input:focus { outline: 1px solid var(--accent); }
.tdk-ip__num { display: flex; align-items: center; gap: 10px; }
.tdk-ip__num input[type="range"] {
  flex: 1 1 auto;
  min-width: 0;
  height: 20px;
  accent-color: var(--accent);
}
.tdk-ip__num b {
  min-width: 88px;
  padding: 5px 8px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: #05070b;
  color: var(--ink);
  font: 700 10.5px/1 var(--mono);
  text-align: right;
}
.tdk-ip__col { display: flex; align-items: center; gap: 8px; }
.tdk-ip__col input[type="color"] {
  width: 42px;
  height: 26px;
  padding: 2px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: #05070b;
  cursor: pointer;
}
.tdk-ip__auto {
  padding: 5px 9px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  font: 700 9.5px/1 var(--mono);
  letter-spacing: 0.1em;
  cursor: pointer;
}
.tdk-ip__auto.is-on { border-color: var(--accent); color: var(--accent); background: rgba(255, 187, 0, 0.1); }
.tdk-ip__hex { font: 600 10px/1 var(--mono); color: var(--faint); letter-spacing: 0.04em; }
.tdk-ip__seg { display: inline-flex; border: 1px solid var(--line-2); border-radius: 4px; overflow: hidden; }
.tdk-ip__seg button {
  padding: 6px 12px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font: 700 9.5px/1 var(--mono);
  letter-spacing: 0.1em;
  cursor: pointer;
}
.tdk-ip__seg button + button { border-left: 1px solid var(--line-2); }
.tdk-ip__seg button.is-on { background: var(--accent); color: #05070b; }
.tdk-ip__note { margin: 8px 0 0; font: 500 10.5px/1.6 var(--ui); color: var(--faint); max-width: 92ch; }
.tdk-ip__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(880px, 100%);
  margin-top: 10px;
  font: 600 10.5px/1.5 var(--mono);
  color: var(--faint);
}
.tdk-ip__foot button {
  padding: 7px 14px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  color: var(--ink);
  font: 700 10px/1 var(--mono);
  letter-spacing: 0.1em;
  cursor: pointer;
}
.tdk-ip__foot button[data-close] { margin-left: auto; background: var(--accent); color: #05070b; border-color: var(--accent); }
.tdk-ip__foot button:focus-visible,
.tdk-set__gear:focus-visible,
.tdk-set__sw:focus-visible,
.tdk-ip__auto:focus-visible,
.tdk-set__tabs button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 700px) {
  .tdk-ip__row,
  .tdk-ip__params li { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .tdk-set__indlist .tdk-set__ind { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .tdk-set__indacts { justify-content: flex-end; }
}

/* ---- the instrument card: what is behind the name in the chart bar ---- */
.tdk-sym { position: relative; }
.tdk-info {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 40;
  width: min(330px, 88vw);
  border: 1px solid var(--line-2);
  border-radius: 6px;
  background: linear-gradient(180deg, #0d1117, #080a0e);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.6);
  font: 600 11px/1.4 var(--mono);
}
.tdk-info > header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
}
.tdk-info > header b { color: var(--accent); letter-spacing: 0.1em; }
.tdk-info > header em { font-style: normal; color: var(--muted); }
.tdk-info > header button {
  margin-left: auto;
  width: 24px;
  height: 22px;
  border: 1px solid var(--line-2);
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}
.tdk-info dl { margin: 0; padding: 8px 10px; }
.tdk-info dl > div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 3px 0;
  border-bottom: 1px dotted var(--line-dot);
}
.tdk-info dl > div:last-child { border-bottom: 0; }
.tdk-info dt { color: var(--muted); }
.tdk-info dd { margin: 0; color: var(--ink); text-align: right; }
.tdk-info dd s { text-decoration: none; color: var(--muted); }
.tdk-info dd s.up { color: var(--up); }
.tdk-info dd s.down { color: var(--down); }
.tdk-info__note {
  margin: 0;
  padding: 8px 10px;
  border-top: 1px solid var(--line);
  color: var(--faint);
  font-weight: 500;
  line-height: 1.6;
}

.tdk-help ul { list-style: none; margin: 0; padding: 0; }
.tdk-help li {
  display: flex;
  gap: 8px;
  align-items: baseline;
  padding: 4px 0;
  border-bottom: 1px dotted var(--line-dot);
  font: 600 11px/1.5 var(--mono);
  color: var(--muted);
}
.tdk-help kbd {
  padding: 1px 6px;
  border: 1px solid var(--line-2);
  border-radius: 3px;
  background: #0b0f15;
  color: var(--ink-2);
  font: 700 10px/1.5 var(--mono);
}

/* ==========================================================================
   09c. THE DEPOSIT WINDOW — the gate in front of the ticket
   ==========================================================================
   Every BUY and SELL on this desk opens this, because an unfunded desk has no
   ticket to send. It is deliberately the most finished thing on the page: a
   reader who has just been stopped by it should be able to act on it without
   hunting for the cashier. */
.tdk-dep {
  position: fixed;
  inset: 0;
  z-index: 170;
  display: grid;
  place-items: center;
  padding: 18px;
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.18s var(--ease), visibility 0.18s;
}
.tdk-dep.is-open { visibility: visible; opacity: 1; }
.tdk-dep__scrim {
  position: absolute;
  inset: 0;
  background: rgba(3, 5, 8, 0.78);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}
.tdk-dep__card {
  position: relative;
  width: min(520px, 100%);
  max-height: min(88vh, 720px);
  overflow-y: auto;
  border: 1px solid var(--line-2);
  border-top: 3px solid var(--accent);
  border-radius: 12px;
  background: linear-gradient(180deg, #0c1119, #070a10);
  box-shadow: 0 40px 110px -46px #000, 0 0 0 1px rgba(var(--accent-rgb), 0.08), 0 0 80px -50px rgba(var(--accent-rgb), 0.9);
  transform: translateY(6px) scale(0.995);
  transition: transform 0.2s var(--ease);
}
.tdk-dep.is-open .tdk-dep__card { transform: none; }
.tdk-dep__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.34);
}
.tdk-dep__kicker {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 700 9.5px/1.4 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.tdk-dep__x {
  margin-left: auto;
  flex: none;
  width: 28px;
  height: 26px;
  border: 1px solid var(--line-2);
  border-radius: 5px;
  background: transparent;
  color: var(--muted);
  font: 700 15px/1 var(--mono);
}
.tdk-dep__x:hover { color: var(--ink); border-color: var(--accent); }
.tdk-dep__title {
  margin: 0;
  padding: 18px 18px 0;
  font: 800 clamp(20px, 4vw, 26px)/1.15 var(--mono);
  letter-spacing: -0.01em;
}
.tdk-dep__lead { margin: 10px 0 0; padding: 0 18px; color: var(--ink-2); font-size: 12.5px; line-height: 1.65; }
.tdk-dep__lead b { color: var(--accent); }
.tdk-dep__facts {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  margin: 16px 0 0;
  padding: 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--line-dot);
}
.tdk-dep__facts li { padding: 9px 12px; background: var(--panel); display: flex; flex-direction: column; gap: 5px; }
.tdk-dep__facts span { font: 700 8.5px/1 var(--mono); letter-spacing: 0.12em; text-transform: uppercase; color: var(--faint); }
.tdk-dep__facts b { font: 700 12px/1 var(--mono); color: var(--ink); }
.tdk-dep__nets { display: flex; flex-wrap: wrap; gap: 5px; padding: 14px 18px 0; }
.tdk-dep__net {
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #0a0e14;
  color: var(--muted);
  font: 700 9.5px/1 var(--mono);
  letter-spacing: 0.08em;
  white-space: nowrap;
}
.tdk-dep__net:hover { border-color: var(--line-2); color: var(--ink-2); }
.tdk-dep__net.is-on { border-color: rgba(var(--accent-rgb), 0.6); background: rgba(var(--accent-rgb), 0.14); color: var(--accent); }
.tdk-dep__addr {
  display: grid;
  gap: 8px;
  margin: 14px 18px 0;
  padding: 13px 14px;
  border: 1px solid var(--line-2);
  border-radius: 9px;
  background: #05080d;
}
.tdk-dep__addrlead { font: 600 10px/1.4 var(--mono); letter-spacing: 0.08em; color: var(--faint); }
.tdk-dep__addrlead b { color: var(--ink-2); }
.tdk-dep__addr code {
  font: 700 12.5px/1.5 var(--mono);
  letter-spacing: 0.02em;
  color: var(--accent);
  overflow-wrap: anywhere;
  user-select: all;
}
.tdk-dep__copy {
  justify-self: start;
  min-height: 30px;
  padding: 0 12px;
  border: 1px solid rgba(var(--accent-rgb), 0.5);
  border-radius: 6px;
  background: rgba(var(--accent-rgb), 0.1);
  color: var(--accent);
  font: 700 9.5px/1 var(--mono);
  letter-spacing: 0.14em;
}
.tdk-dep__copy:hover { background: rgba(var(--accent-rgb), 0.2); }
.tdk-dep__copy.is-done { border-color: rgba(var(--up-rgb), 0.6); background: rgba(var(--up-rgb), 0.14); color: var(--up); }
.tdk-dep__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 16px 18px 18px;
}
.tdk-dep__go {
  padding: 12px 18px;
  border-radius: 9px;
  background: linear-gradient(180deg, #ffc733, #ff9d0a);
  color: #100a00;
  font: 800 11.5px/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  box-shadow: 0 10px 26px -14px rgba(var(--accent-rgb), 1);
}
.tdk-dep__go:hover { filter: brightness(1.06); }
.tdk-dep__go:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.tdk-dep__hint { font: 600 9.5px/1.5 var(--mono); letter-spacing: 0.06em; color: var(--faint); }
@media (max-width: 560px) {
  .tdk-dep__facts { grid-template-columns: minmax(0, 1fr); }
  .tdk-dep__foot { padding: 14px 14px 16px; }
  .tdk-dep__go { flex: 1 1 100%; text-align: center; }
}

/* ==========================================================================
   09d. THE FUND BAR — DEPOSIT and WITHDRAW, named
   ==========================================================================
   The two account actions, in the top strip on a desk and pinned above the
   pane bar on a phone. Before this, the only way to fund the desk was to press
   BUY and be refused, and a payout had no button anywhere on the page — which
   is exactly what a reader on Android reported: neither action was findable. */
.tdk-fund { display: flex; align-items: center; gap: 6px; }
.tdk-fund button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 30px;
  padding: 0 12px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--ink-2);
  font: 800 10px/1 var(--mono);
  letter-spacing: 0.12em;
}
.tdk-fund button svg {
  width: 13px;
  height: 13px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* DEPOSIT is the one control on this page that has to be found without being
   looked for: an unfunded desk cannot send a ticket, so the button that funds it
   is filled rather than outlined, with a glow under it and white lettering on
   the fill. WITHDRAW stays an outline — it is the rarer action and the two
   should not compete. */
/* NOTE ON SPECIFICITY: `.tdk-fund button` (0,1,1) outranks a bare class
   (0,1,0), so these two rules are written as `.tdk-fund .tdk-fund__in` —
   otherwise the generic button background silently wins and DEPOSIT renders as
   an outlined chip, which is how it shipped once already. */
.tdk-fund .tdk-fund__in {
  border-color: rgba(var(--up-rgb), 0.9);
  /* 0.52 → 0.26 over the near-black page is a deep mint: white lettering on it
     clears AA (≈5.5:1), where a brighter fill would not. */
  background: linear-gradient(180deg, rgba(var(--up-rgb), 0.52), rgba(var(--up-rgb), 0.26));
  color: #ffffff;
  box-shadow: 0 0 0 1px rgba(var(--up-rgb), 0.3), 0 12px 26px -12px rgba(var(--up-rgb), 0.9);
}
.tdk-fund .tdk-fund__in svg { stroke-width: 2.8; }
.tdk-fund .tdk-fund__in b { color: #ffffff; letter-spacing: 0.14em; }
.tdk-fund .tdk-fund__in:hover { background: linear-gradient(180deg, rgba(var(--up-rgb), 0.62), rgba(var(--up-rgb), 0.34)); }
.tdk-fund .tdk-fund__out {
  border-color: rgba(var(--accent-rgb), 0.62);
  background: rgba(var(--accent-rgb), 0.16);
  color: #ffffff;
}
.tdk-fund .tdk-fund__out b { color: var(--accent); letter-spacing: 0.14em; }
.tdk-fund .tdk-fund__out:hover { background: rgba(var(--accent-rgb), 0.26); }
.tdk-fund button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The way into the studies' settings, beside the studies: a labelled chip with
   the same gear the function bar carries, so the button and the window it opens
   are recognisably the same thing. */
.tdk-indset {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 22px;
  padding: 0 9px;
  border: 1px solid rgba(var(--accent-rgb), 0.5);
  border-radius: 999px;
  background: rgba(var(--accent-rgb), 0.1);
  color: var(--accent);
  font: 700 9.5px/1 var(--mono);
  letter-spacing: 0.12em;
  cursor: pointer;
}
.tdk-indset svg {
  width: 12px;
  height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}
.tdk-indset:hover { background: rgba(var(--accent-rgb), 0.2); border-color: var(--accent); }
.tdk-indset:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* the gear in the function bar carries its own name now: an unlabelled icon
   between HELP and INFO read as decoration rather than as the way in */
/* the function bar is gold, so the label takes the bar's own ink rather than
   the accent — gold lettering on a gold bar is a label nobody can read */
.tdk-fn__gear .tdk-fn__geartxt {
  font: 700 10px/1 var(--mono);
  letter-spacing: 0.16em;
  color: inherit;
  opacity: 0.92;
}
.tdk-fn__gear { display: inline-flex; align-items: center; gap: 6px; padding: 0 10px; }
.tdk-fn__gear svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; }

/* the SET chip in the chart bar reads as a button, not as another icon */
.tdk-icon-btn--set { gap: 5px; }
.tdk-icon-btn--set b { font: 700 9.5px/1 var(--mono); letter-spacing: 0.1em; }

/* --------------------------------------------------------------------------
   the amount, and what it is worth in coins
   -------------------------------------------------------------------------- */
.tdk-dep__amt { display: grid; gap: 8px; padding: 16px 18px 0; }
/* `display: grid` above outranks the user agent's own `[hidden]` rule, so
   anything that hides this row has to be answered here as well. Nothing hides
   it any more — the window has one framing since the payout moved to the
   cashier — but a `hidden` attribute that paints anyway is the bug this file
   paid for once already, and the rule costs a line */
.tdk-dep__amt[hidden] { display: none; }
.tdk-dep__amt > label {
  font: 700 9px/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}
.tdk-dep__amtbox {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  border: 1px solid var(--line-2);
  border-radius: 9px;
  background: #05080d;
}
.tdk-dep__amtbox:focus-within { border-color: rgba(var(--accent-rgb), 0.6); }
.tdk-dep__amtbox span { font: 700 16px/1 var(--mono); color: var(--faint); }
.tdk-dep__amtbox input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: 800 19px/1 var(--mono);
  letter-spacing: 0.01em;
  outline: none;
}
.tdk-dep__chips { display: flex; flex-wrap: wrap; gap: 5px; }
.tdk-dep__chip {
  min-height: 30px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #0a0e14;
  color: var(--muted);
  font: 700 10px/1 var(--mono);
  letter-spacing: 0.06em;
}
.tdk-dep__chip:hover { border-color: rgba(var(--accent-rgb), 0.5); color: var(--accent); }
/* the sub-floor warning: an amber note, not a red one — the deposit is below
   the desk's minimum rather than wrong, and it is said under the field the
   reader is typing in, where nothing else is competing for the eye */
.tdk-dep__warn {
  margin: 9px 0 0;
  padding: 9px 11px;
  border: 1px solid rgba(255, 209, 102, 0.42);
  border-left-width: 3px;
  border-radius: 10px;
  background: rgba(255, 209, 102, 0.09);
  color: #ffe6b0;
  font: 600 11.5px/1.62 var(--ui);
}
.tdk-dep__warn[hidden] { display: none; }
/* the coin figure is the answer to the only question this window is asked */
.tdk-dep__coins {
  font: 800 22px/1.1 var(--mono);
  letter-spacing: -0.01em;
  color: var(--up);
  overflow-wrap: anywhere;
}
.tdk-dep__coins.is-dim { color: var(--muted); font-size: 14px; font-weight: 700; }
.tdk-dep__rate {
  font: 600 10px/1.5 var(--mono);
  letter-spacing: 0.04em;
  color: var(--faint);
}

/* ==========================================================================
   10. RESPONSIVE — the desk folds into a scrolling page on a phone
   ========================================================================== */
@media (max-width: 1180px) {
  body.tdk { height: auto; min-height: 100vh; overflow: auto; display: block; }
  .tdk-grid { grid-template-columns: minmax(0, 1fr); }
  .tdk-chart { min-height: 62vh; }
  .tdk-side { grid-template-rows: auto minmax(240px, auto) minmax(200px, auto); }
  .tdk-blotter { max-height: none; }
  .tdk-board__list { max-height: 320px; }
  .tdk-top { flex-wrap: wrap; gap: 8px; }
  .tdk-clocks, .tdk-acct, .tdk-links { margin-left: 0; padding-left: 0; border-left: 0; }
  /* The account strip is four readings that cannot shrink, so it wraps inside
     itself and takes a row of the bar. Left as one unbreakable flex line it
     measures 393px, which is wider than a 360px phone — and one element wider
     than the page drags the whole document sideways with it. */
  .tdk-acct { flex-wrap: wrap; width: 100%; min-width: 0; gap: 4px 14px; }
}
@media (max-width: 720px) {
  .tdk-feed { order: 3; width: 100%; justify-content: flex-start; }
  .tdk-ticket__math li { font-size: 10px; }
  .tdk-ohlc { font-size: 10px; }
  .tdk-fn__keys button { padding: 0 9px; }
}

/* --------------------------------------------------------------------------
   11. TOUCH — Android and any other coarse pointer
   --------------------------------------------------------------------------
   A finger is not a mouse: it has no hover, it is about 9mm wide, and it
   arrives while the page is also trying to scroll. Everything below is one of
   those three problems. */
/* The `mob` class is the switch, not the media query: the query decides when
   the desk puts the class on at all (see mobInit), so the pane rules can be
   written once and read without guessing which breakpoint they belong to. */
body.mob .tdk-grid { display: block; padding: 8px; }
body.mob .tdk-grid > *, body.mob .tdk-side > *, body.mob .tdk-blotter { display: none; }
body.mob[data-pane="board"] .tdk-board,
body.mob[data-pane="chart"] .tdk-chart,
body.mob[data-pane="blotter"] .tdk-blotter { display: flex; }
body.mob[data-pane="side"] .tdk-side { display: grid; gap: 8px; }
body.mob[data-pane="side"] .tdk-side > * { display: flex; }
/* 100dvh where the browser has it: a phone's URL bar is inside 100vh, so the
   pane would otherwise be taller than what the reader can actually see */
/* 190 / 176 are the chrome above the pane (strip, function bar, command line),
   plus the pane bar and the quick order strip below it — the pane fills exactly
   what is left of the screen between the two fixed bars. 58px is the strip's
   own height, and it is spelled out here rather than read from `--ord-h`
   because this rule can match before the markup that defines it. */
body.mob .tdk-panel { min-height: calc(100vh - 248px); min-height: calc(100dvh - 248px); }
body.mob .tdk-chart { min-height: calc(100vh - 234px); min-height: calc(100dvh - 234px); }
body.mob[data-pane="side"] .tdk-panel { min-height: 0; }
body.mob .tdk-mob { display: grid; }
body.mob { max-width: 100vw; overflow-x: hidden; }
/* A phone shows one pane at a time and there is no column to drag, so the
   grips go with the columns they resize. */
body.mob .tdk-grip, body.mob .tdk-grip--blotter { display: none; }
body.mob .tdk-blotter { height: auto; max-height: none; }

/* Both of the fixed bars are drawn by the query below and by nothing else: on a
   mouse there is no pane bar to move between panes with and no strip, because
   the four panes are all on screen at once and the ticket is one of them. */
.tdk-mob { display: none; }
.tdk-ord { display: none; }

@media (pointer: coarse), (max-width: 820px) {
  /* Android inflates text it thinks is a paragraph, which wrecks a desk whose
     whole language is the precise fit of a small monospace glyph in a cell. */
  body.tdk { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; overscroll-behavior-y: contain; }

  /* panes scroll on their own with momentum, and a flick that reaches the end
     of one does not drag the whole page with it */
  .tdk-board__list, .tdk-blotter__body, .tdk-trades__rows, .tdk-ticket,
  .tdk-book__side, .tdk-help, .tdk-modal__body, .tdk-canvas { -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }

  /* the one-pane-at-a-time bar */
  .tdk-mob {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 45;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1px;
    padding: 0 0 calc(env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--line-2);
    background: rgba(8, 11, 16, 0.97);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
  }
  .tdk-mob button {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-height: 54px;
    padding: 6px 2px;
    border: 0;
    background: transparent;
    color: var(--faint);
  }
  .tdk-mob button s {
    font: 700 9px/1 var(--mono);
    letter-spacing: 0.14em;
    text-decoration: none;
  }
  .tdk-mob button b {
    max-width: 100%;
    overflow: hidden;
    font: 700 10.5px/1 var(--mono);
    color: var(--muted);
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .tdk-mob button.is-on { color: var(--accent); background: rgba(var(--accent-rgb), 0.07); }
  .tdk-mob button.is-on b { color: var(--ink); }
  .tdk-mob button:active { background: rgba(var(--accent-rgb), 0.14); }

  /* ---- the quick order strip -------------------------------------------
     Three controls, and the strip is the whole of it: which side, how big, and
     nothing that needs a keyboard. It sits directly above the pane bar rather
     than at the very bottom, so the four pane buttons stay the last row of the
     screen and the reader does not have to re-learn where they are; and it is
     drawn only where the pane bar is, because a mouse has the ticket itself a
     scroll away and does not need a second one.

     The shape is the one every phone trading app has, because it is the one
     that works: a met tap target on each side, the size between them where the
     thumb already is, and the whole strip clear of the safe area. It is the
     desk's own palette rather than a new one — green up, red down, amber for
     the size, no curves beyond the desk's own small radii. */
  .tdk-ord {
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(54px + env(safe-area-inset-bottom, 0px));
    z-index: 46;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: stretch;
    gap: 6px;
    padding: 6px 8px;
    border-top: 1px solid var(--line-2);
    background: linear-gradient(180deg, rgba(8, 11, 16, 0.94), #05070b 62%);
    -webkit-backdrop-filter: blur(12px) saturate(120%);
    backdrop-filter: blur(12px) saturate(120%);
    box-shadow: 0 -18px 34px -26px rgba(0, 0, 0, 0.95), inset 0 1px 0 rgba(var(--accent-rgb), 0.14);
  }

  /* ---- the two sides --------------------------------------------------- */
  .tdk-ord__side {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 46px;
    padding: 0 12px;
    border: 1px solid var(--line-2);
    border-radius: 9px;
    background: var(--bg-3);
    color: var(--ink);
    cursor: pointer;
    transition: transform 0.12s var(--ease), box-shadow 0.18s var(--ease), filter 0.18s var(--ease);
  }
  .tdk-ord__side svg { width: 19px; height: 19px; flex: none; }
  .tdk-ord__txt { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; }
  .tdk-ord__txt b {
    font: 800 15px/1 var(--mono);
    letter-spacing: 0.1em;
    color: #ffffff;
  }
  .tdk-ord__txt em {
    font: 700 8.5px/1 var(--mono);
    font-style: normal;
    letter-spacing: 0.16em;
    color: rgba(255, 255, 255, 0.62);
  }
  .tdk-ord__side--buy {
    border-color: rgba(var(--up-rgb), 0.5);
    background: linear-gradient(180deg, rgba(var(--up-rgb), 0.34), rgba(var(--up-rgb), 0.1));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px -20px rgba(var(--up-rgb), 1);
    color: var(--up);
  }
  .tdk-ord__side--sell {
    border-color: rgba(var(--down-rgb), 0.5);
    background: linear-gradient(180deg, rgba(var(--down-rgb), 0.32), rgba(var(--down-rgb), 0.1));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 10px 24px -20px rgba(var(--down-rgb), 1);
    color: var(--down);
  }
  .tdk-ord__side:active { transform: translateY(1px) scale(0.995); }
  .tdk-ord__side:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

  /* ---- the size -------------------------------------------------------- */
  /* The size is the one thing on the strip that can run long: 0.01 is four
     characters and 10.00 is five, so the box is sized for the longest value
     the desk will take rather than for the default — a size that is cut off is
     a size the reader cannot read back before pressing. */
  .tdk-ord__lot {
    display: grid;
    grid-template-columns: 38px 60px 38px;
    grid-template-rows: auto auto;
    align-items: center;
    justify-items: center;
    column-gap: 3px;
    padding: 3px 5px 4px;
    border: 1px solid var(--line-2);
    border-radius: 9px;
    background: var(--bg-2);
  }
  .tdk-ord__lbl {
    grid-row: 1;
    grid-column: 1 / -1;
    font: 700 8.5px/1 var(--mono);
    letter-spacing: 0.22em;
    color: var(--muted);
  }
  .tdk-ord__step {
    grid-row: 2;
    width: 38px;
    height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--line);
    border-radius: var(--r);
    background: var(--bg-3);
    color: var(--accent);
    font: 800 17px/1 var(--mono);
    cursor: pointer;
    transition: background 0.15s var(--ease), color 0.15s var(--ease), border-color 0.15s;
  }
  .tdk-ord__step:hover:not(:disabled) { background: var(--accent); border-color: var(--accent); color: #000; }
  .tdk-ord__step:active:not(:disabled) { transform: translateY(1px); }
  .tdk-ord__step:disabled { opacity: 0.34; cursor: default; }
  .tdk-ord__step:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  #ordLotDown { grid-column: 1; }
  #ordLotUp { grid-column: 3; }
  .tdk-ord__val {
    grid-row: 2;
    grid-column: 2;
    width: 100%;
    padding: 7px 0 5px;
    text-align: center;
    border: 1px solid rgba(var(--accent-rgb), 0.34);
    border-radius: var(--r);
    background: rgba(var(--accent-rgb), 0.07);
    color: var(--ink);
    font: 800 14px/1 var(--mono);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
  }

  /* The pane bar is 54px of fixed chrome and the strip is another 58, so every
     bottom calculation on this page is measured from the two of them: the last
     row of a pane has to clear both, and a toast has to sit above both. */
  body.tdk { --ord-h: 58px; padding-bottom: calc(54px + var(--ord-h) + 12px + env(safe-area-inset-bottom, 0px)); }

  /* DEPOSIT and WITHDRAW ride in the header, on the feed's own row, in the same
     size of type as the feed they sit beside. They were a bar pinned over the
     bottom of the screen at 44px a button, which cost 60px of every pane —
     permanent rent, paid by the chart, for two buttons pressed rarely. Here
     they are still on screen without being asked for (the header is the first
     thing on the page), still two taps, and the panes get their 60px back. */
  /* The header is a grid on a phone, not a wrapping flex line. A wrapping
     flex line puts the two buttons wherever the feed's own text happens to end
     — the feed grows to fill whatever is left, and whether the buttons land
     beside it or on a row of their own depends on how many digits the latency
     reading has that second. A two-column grid says it instead: the feed is the
     first column, the buttons the second, on the same row, always.
     `minmax(0, 1fr)` and the clipped overflow are what keep a long feed line
     from widening the page — one element wider than the screen drags the whole
     document sideways on Android. */
  body.mob .tdk-top {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 8px;
    row-gap: 6px;
    align-items: center;
  }
  body.mob .tdk-brand { grid-row: 1; grid-column: 1; }
  body.mob .tdk-clocks { grid-row: 1; grid-column: 2; }
  body.mob .tdk-acct { grid-row: 2; grid-column: 1 / -1; }
  body.mob .tdk-links { grid-row: 3; grid-column: 1 / -1; }
  body.mob .tdk-feed {
    grid-row: 4;
    grid-column: 1;
    order: 0;
    flex: none;
    width: auto;
    min-width: 0;
    overflow: hidden;
    gap: 6px;
  }
  body.mob .tdk-fund {
    grid-row: 4;
    grid-column: 2;
    order: 0;
    flex: none;
    display: flex;
    gap: 5px;
    margin-left: 0;
    padding-left: 0;
  }
  .tdk-fund button { min-height: 30px; padding: 0 7px; gap: 4px; border-radius: 8px; font-size: 9px; }
  .tdk-fund button svg { width: 12px; height: 12px; }
  .tdk-fund .tdk-fund__in b,
  .tdk-fund .tdk-fund__out b { font-size: 9px; letter-spacing: 0.06em; }

  /* room for the pane bar — see the padding rule beside `.tdk-ord` above, which
     is the one that counts the strip in as well. */

  /* a modal on a phone must not hide its own primary button under the fold:
     the foot of the deposit window is pinned to the bottom of the card, the
     rail chips scroll sideways instead of stacking six rows deep, and the
     address can be read without pinching. */
  .tdk-dep { padding: 8px; }
  .tdk-dep__card { max-height: calc(100vh - 16px); max-height: calc(100dvh - 16px); }
  .tdk-dep__title { padding: 14px 14px 0; }
  .tdk-dep__lead { padding: 0 14px; }
  .tdk-dep__amt { padding: 14px 14px 0; }
  .tdk-dep__nets { flex-wrap: nowrap; overflow-x: auto; padding: 12px 14px 0; scrollbar-width: none; }
  .tdk-dep__nets::-webkit-scrollbar { display: none; }
  .tdk-dep__net { flex: 0 0 auto; min-height: 32px; }
  .tdk-dep__addr { margin: 12px 14px 0; }
  .tdk-dep__addr code { font-size: 12px; }
  .tdk-dep__foot {
    position: sticky;
    bottom: 0;
    margin-top: 14px;
    border-top: 1px solid var(--line);
    background: linear-gradient(180deg, rgba(7, 10, 16, 0.92), #070a10 40%);
  }
  .tdk-dep__x { width: 34px; height: 32px; }
  /* the top-strip links were 10px of text on a 360px phone — the row that takes
     a reader to the cashier was the least hittable thing on the page */
  .tdk-links { gap: 8px; }
  .tdk-links a {
    display: inline-flex;
    align-items: center;
    min-height: 32px;
    padding: 0 8px;
    border: 1px solid var(--line);
    border-radius: 6px;
  }

  /* a finger needs somewhere to land: every control grows to about 40px and
     nothing important hides behind a hover that never happens */
  /* the chart type row and the study row are the same control as the period
     row and were left at the 22px the desk draws with a mouse: the one row a
     reader uses most on a phone was the one row a finger could not hit */
  .tdk-fn__keys button, .tdk-tfs button, .tdk-types button, .tdk-ind button,
  .tdk-chart__btns button, .tdk-draw button,
  .tdk-board__tools button, .tdk-board__tools select, .tdk-ticket__types button,
  .tdk-ticket__pcts button, .tdk-ticket__go button, .tdk-book__mode button {
    min-height: 34px;
    padding-left: 10px;
    padding-right: 10px;
  }
  .tdk-board__row { min-height: 42px; }
  .tdk-row__star, .tdk-row__act { opacity: 1; }
  .tdk-ticket input, .tdk-board__tools select, .tdk-alerts input, .tdk-alerts select { min-height: 36px; font-size: 13px; }
  .tdk-btn, .tdk-mini { min-height: 34px; }
  /* the map is the one grid on the desk a finger drives: bigger tiles, a
     bigger target, and never narrower than a price fits in */
  .tdk-board__map { grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 6px; padding: 8px; }
  .tdk-tile { padding: 9px 9px 13px; }
  .tdk-tile b { font-size: 11.5px; }
  .tdk-tile s, .tdk-tile i { font-size: 10.5px; }
  .tdk-board__modes button { min-height: 30px; padding: 0 10px; }
  /* the keyboard hints stay off a phone — they name keys a phone does not have
     — but everything they hint at is on the screen: the key row below is
     tappable, and the command line it used to be hidden behind is not */
  .tdk-help kbd { display: none; }
  /* The command line was squeezed into whatever the key row left over — 106px
     on a 360px screen, prompt and GO included, which is a feature drawn and not
     usable. It takes its own full-width row under the keys instead, with the
     message line beneath the field rather than beside it. `.tdk-fn__cmd` was
     the class this rule used to hide; nothing in the markup has ever carried
     that name, so the line was never actually hidden. */
  .tdk-fn { flex-wrap: wrap; }
  .tdk-fn__keys { flex: 1 1 100%; }
  .tdk-cmd {
    flex: 1 1 100%;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    row-gap: 3px;
    margin: 4px 6px 5px;
    padding: 4px 8px;
  }
  .tdk-cmd__prompt { grid-row: 1; grid-column: 1; }
  .tdk-cmd input { grid-row: 1; grid-column: 2; min-height: 30px; font-size: 13px; }
  .tdk-cmd button { grid-row: 1; grid-column: 3; min-height: 30px; }
  .tdk-cmd__msg { grid-row: 2; grid-column: 1 / -1; flex: none; }
  .tdk-draw { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .tdk-draw::-webkit-scrollbar { display: none; }
  .tdk-top { padding: 8px 10px; }
  .tdk-acctgrid span { min-height: 40px; }

  /* the replay player is a row of controls like any other: it scrolls instead
     of wrapping, and every button in it is a finger's worth of target */
  .tdk-replay {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding: 6px 8px;
    gap: 8px;
  }
  .tdk-replay::-webkit-scrollbar { display: none; }
  .tdk-replay > * { flex: 0 0 auto; }
  .tdk-replay button { min-height: 34px; padding-left: 12px; padding-right: 12px; }
  .tdk-replay #rpSeek { flex: 1 1 140px; height: 30px; }
  .tdk-replay__speed select { min-height: 34px; }
  .tdk-replay__at { margin-left: 0; }

  /* ---- the symbol bar on a phone ----------------------------------------
     It used to be one row the reader scrolled sideways: 2,400px of controls in
     a 342px window, so the period row, the candle types, the studies and the
     tools were all off the right-hand edge and the name of the instrument was
     squeezed to nine pixels. It is a stack of rows now — what is charted, then
     the two picks, then the indicators, then the tools — with each group on a
     line of its own, which is the layout a reader can actually read on a
     phone. The period and type chip rows are replaced by the two buttons in
     `.tdk-picks` (see the sheet below); the indicator chips stay chips, because
     several of them are on at once, and they scroll inside their own row. */
  body.mob .tdk-chart__bar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 6px;
    padding: 6px 8px;
  }
  body.mob .tdk-chart__bar > * { flex: none; min-width: 0; }
  body.mob .tdk-sym { grid-row: 1; grid-column: 1; flex-direction: row; align-items: baseline; gap: 8px; min-height: 26px; }
  body.mob .tdk-sym b { overflow: hidden; font-size: 15px; text-overflow: ellipsis; white-space: nowrap; }
  body.mob .tdk-sym em { font-size: 9.5px; white-space: nowrap; }
  body.mob .tdk-picks { grid-row: 2; grid-column: 1 / -1; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
  body.mob .tdk-tfs,
  body.mob .tdk-grp--type { display: none; }
  body.mob .tdk-compare { grid-row: 1; grid-column: 2; }
  body.mob .tdk-grp--ind {
    grid-row: 3;
    grid-column: 1 / -1;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }
  body.mob .tdk-grp--ind::-webkit-scrollbar { display: none; }
  body.mob .tdk-chart__btns {
    grid-row: 4;
    grid-column: 1 / -1;
    margin-left: 0;
    overflow-x: auto;
    scrollbar-width: none;
  }
  body.mob .tdk-chart__btns::-webkit-scrollbar { display: none; }
  body.mob .tdk-chart__btns button, body.mob .tdk-types button, body.mob .tdk-ind button { min-width: 40px; }
  body.mob .tdk-ohlc,
  body.mob .tdk-chart__foot { padding: 4px 8px; white-space: nowrap; overflow-x: auto; scrollbar-width: none; }
  body.mob .tdk-ohlc::-webkit-scrollbar,
  body.mob .tdk-chart__foot::-webkit-scrollbar { display: none; }

  /* the label is back on a phone. The slab is the only control on this page
     that asks for money, and a gold glyph at the top of the chart with no word
     beside it is a guess — the mid-size desk bars, where the room is genuinely
     tight, are the ones that do without it (see the 1340px block above). */
  .tdk-ai span { display: inline; }
  .tdk-canvas .tdk-ai {
    padding: 0 13px 0 30px;
    min-height: 36px;
    gap: 8px;
    font-size: 10px !important;
    letter-spacing: 0.1em;
    border-radius: 11px;
  }
  .tdk-canvas .tdk-ai::before { left: 12px; width: 7px; height: 7px; margin-top: -3.5px; }
  .tdk-canvas .tdk-ai svg { width: 17px; height: 17px; }

  /* a toast is a thing you must be able to read without aiming at it, and the
     two things under it are the quick order strip and the pane bar */
  .toasts { left: 8px; right: 8px; bottom: calc(64px + var(--ord-h, 58px) + env(safe-area-inset-bottom, 0px)); }
  .toast { font-size: 12px; }
}

@media (max-width: 420px) {
  .tdk-brand__txt em { display: none; }
  /* the one-month period used to be hidden below 420px, which is a feature
     taken off a phone rather than a layout saved: it scrolls in its own row
     like the other ten, and on the phone's picker it is simply one more row. */
  /* both values, in this order: a browser with a URL bar inside 100vh would
     otherwise hand the pane 56px it cannot show */
  body.mob .tdk-panel { min-height: calc(100vh - 236px); min-height: calc(100dvh - 236px); }
}
