/* ==========================================================================
   terminal.css — the trading page.

   Layered on dashboard.css, which already carries the tokens, the reset and
   the app bar. Nothing here redefines a token: one palette, one type scale,
   and a page that inherits both stays in step when either moves.

   The layout is three columns because the three things a trader does are
   sequential and constant — find a market, read the position, send the order —
   and hiding any of them behind a tab means a decision made without one of
   them on screen.
   ========================================================================== */

/* ==========================================================================
   [hidden] MUST WIN

   Every panel below sets `display`, and a `display` rule beats the browser's
   default `[hidden] { display: none }` — so `el.hidden = true` silently did
   nothing and the order ticket showed an empty "Refused" box next to a
   successful estimate, permanently.

   Found by looking at the page. The contract test could not see it (the API was
   answering correctly) and the DOM-reference check could not either (the
   element existed and was being written to). Some bugs are only visible.
   ========================================================================== */
[hidden]{ display:none !important; }

/* The terminal's own measure, shared by the rail and the grid below it so the
   two line up. Declared here rather than on `.term` because the rail is a
   sibling, not a child. */
:root{ --term:2200px; }

/* ==========================================================================
   THE TICKER

   Every listed market, scrolling. The market list beside the chart holds twenty
   rows and can show about seven; this shows all of them without an interaction,
   which is the thing a list cannot do.

   ## Why the animation is on a duplicated track

   A marquee that scrolls one copy has to jump back to the start, and the jump is
   visible. Two identical copies translated by exactly -50% put copy two where
   copy one began at the moment the animation restarts, so there is no seam. It
   costs a second render of twenty small rows, which is nothing.

   ## It stops when anybody might be reading it

   Paused on hover and on keyboard focus, because a price that slides away while
   being read is worse than no ticker — and `prefers-reduced-motion` turns the
   animation off entirely and leaves the strip scrollable by hand. Motion nobody
   asked for is the one accessibility failure a trading page has no excuse for.
   ========================================================================== */
.tick{
  border-bottom:1px solid var(--hair);
  background:rgba(255,255,255,.014);
  overflow:hidden;
  /* Room for a wheel/trackpad scroll when the animation is off. */
  overflow-x:auto;
  scrollbar-width:none;
}
.tick::-webkit-scrollbar{ display:none; }

.tick__track{
  display:flex; width:max-content;
  animation:tickscroll 90s linear infinite;
}
.tick:hover .tick__track,
.tick:focus-within .tick__track{ animation-play-state:paused; }

@keyframes tickscroll{
  from{ transform:translateX(0); }
  to{ transform:translateX(-50%); }
}

@media (prefers-reduced-motion: reduce){
  .tick__track{ animation:none; }
}

.tick__i{
  display:flex; align-items:baseline; gap:7px;
  padding:7px 15px; border-right:1px solid rgba(255,255,255,.05);
  font-size:12px; font-variant-numeric:tabular-nums; white-space:nowrap;
  color:var(--ink-2); transition:background .16s, color .16s;
}
.tick__i:hover{ background:rgba(255,255,255,.045); color:var(--ink); }
.tick__i[aria-current="true"]{ background:rgba(211,176,124,.09); color:var(--ink); }
.tick__s{ font-weight:600; letter-spacing:.02em; }
.tick__p{ color:var(--ink); }
.tick__c{ font-size:11.5px; }

/* ==========================================================================
   THE INSTRUMENT STRIP

   Mark, 24h change, funding and open interest — the four numbers a perp trader
   checks before sizing anything, in the place every terminal puts them. A
   definition list rather than divs, because that is what these are: each figure
   is meaningless without its label, and "0.00055%" beside "Funding 1h" is a
   different statement from the same digits beside "Change".
   ========================================================================== */
/* This row wrapped for a while and the cause was not here.
 *
 * `dashboard.css` defines a `.stats` of its own for the dashboard's big-number band, and
 * its `.stats div{padding:2px 34px}` reached every `.stat` in this strip — 68px each, five
 * of them, so the row came to 813px in 740px and Max leverage sat alone underneath. The
 * fix is in that file; the note is here because this is where the symptom was.
 *
 * `flex-basis:100%` was tried here first, to give the five figures a line of their own. It
 * moved the wrap rather than removing it, and with the padding gone they fit beside the
 * title as designed. */
.panel__hd--stats{ flex-wrap:wrap; row-gap:8px; }
.stats{ display:flex; flex-wrap:wrap; align-items:baseline; gap:0 22px; margin-left:auto; }
.stat{ display:flex; flex-direction:column; gap:1px; }
.stat dt{
  font-size:10px; letter-spacing:.05em; text-transform:uppercase; color:var(--mute);
}
.stat__v{
  font-family:var(--mono); font-size:14px; font-variant-numeric:tabular-nums;
  letter-spacing:-.01em;
}
/* The mark is the number the ticket charges against, so it is the largest. */
.stat:first-child .stat__v{ font-size:17px; }

/* ==========================================================================
   THE RAIL

   The three numbers docs/13 §4 says must always be visible: how far to the
   daily floor, how far to the total floor, how much of the target is done.
   Above the fold, above the chart, and never behind an interaction.
   ========================================================================== */
.rail{
  border-bottom:1px solid var(--hair);
  background:linear-gradient(180deg, rgba(255,255,255,.022), transparent);
}
.rail__in{
  max-width:var(--term); margin-inline:auto; padding:14px 20px;
  display:grid; grid-template-columns:1.1fr repeat(3, minmax(0,1fr)); gap:26px; align-items:center;
}
.rail__equity b{
  display:block; font-family:var(--display); font-weight:500;
  font-size:30px; letter-spacing:-.02em; line-height:1.05;
}
.rail__equity span{ display:block; margin-top:3px; font-size:12.5px; color:var(--mute); }
.rail__equity .delta{ font-variant-numeric:tabular-nums; }

.gauge__top{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; }
.gauge__k{ font-size:12px; color:var(--mute); letter-spacing:.01em; }
.gauge__v{ font-family:var(--mono); font-size:17px; font-variant-numeric:tabular-nums; }
.gauge__bar{
  margin-top:8px; height:4px; border-radius:99px;
  background:rgba(255,255,255,.07); overflow:hidden;
}
.gauge__fill{ height:100%; border-radius:99px; transition:width .5s var(--ease); }
.gauge--target .gauge__fill{ background:var(--gold); }
/* Headroom bars read as "how much is left", so they empty toward the floor
   rather than filling toward it — and they go red only near the end, because a
   bar that is always red teaches a trader to ignore it. */
.gauge--room .gauge__fill{ background:var(--up); }
.gauge--room.is-tight .gauge__fill{ background:var(--down); }
.gauge__sub{ margin-top:6px; font-size:11.5px; color:var(--mute); font-variant-numeric:tabular-nums; }

/* ==========================================================================
   THE GRID
   ========================================================================== */
/* ==========================================================================
   THE PAGE IS NOT A DOCUMENT

   `--col` is 1280px, which is the right measure for a marketing page and wrong
   for a terminal: on a 1568px screen it threw away 288px, and 640px on a 1920.
   Every exchange terminal is full-bleed for the same reason — the chart is the
   product, and horizontal room is the only thing that makes more of it visible.

   `--term` is deliberately generous rather than unbounded. Past about 2200px the
   ticket and the market list stop growing and only the chart does, which is the
   correct behaviour; a hard cap here would put the empty margins back on the
   screens that have the most to give.
   ========================================================================== */
.term{
  max-width:var(--term); margin-inline:auto; padding:16px 20px 48px;
  /* Two columns: the working area and the ticket rail.
   *
   * This was three -- a markets rail, the chart, the ticket -- and the markets rail spent a
   * permanent 300px on choosing a market, which a trader does a few times a session, beside
   * the chart they read continuously. The list now opens from the chart's own symbol, and
   * that width went to the chart and the book.
   *
   * The ticket rail is a separate column rather than a third track inside `.mid` so that
   * its height -- the ticket plus the equity chart under it -- cannot stretch the chart's
   * row. A spanning item in a shared grid grows the rows it spans, and the book beside the
   * chart would then sit on a gap the height of the equity panel. */
  display:grid; grid-template-columns:minmax(0,1fr) 320px; gap:14px; align-items:start;
}
.panel{
  background:#0A0A0A; border:1px solid var(--hair); border-radius:14px; overflow:hidden;
}
.panel__hd{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:13px 15px; border-bottom:1px solid var(--hair);
}
.panel__hd h2{ font-family:var(--display); font-size:14px; font-weight:500; letter-spacing:.01em; }
.panel__hd .muted{ font-size:12px; color:var(--mute); }

/* The markets panel's header stacks, for the same reason its buttons wrap.
 *
 * "Markets" plus "5 markets · your crypto account" is about 225px of text in a 200px row, so
 * the count was pushed against the heading and out of the box. The count cannot be shortened
 * away — it is what tells a trader who saw a hundred markets before buying and forty-one
 * after that the rest were filtered rather than delisted — so the header takes the second
 * line instead. */
.panel--mkts .panel__hd{
  flex-direction:column; align-items:flex-start; gap:2px;
}

/* ==========================================================================
   MARKETS
   ========================================================================== */
/* The market-type toggle, in a 230px rail.
 *
 * `flex:1` in a 230px column leaves 100px per button once the 12px padding and the 6px gap
 * are taken, and "Crypto perpetuals" needs about 105px at 12.5px — so the longer label spilled
 * out of its own button. It only showed on a crypto account, because `.term--pred` widens the
 * column to 340px and the same labels fit there.
 *
 * The labels are not shortened. "Crypto perpetuals" and "Prediction markets" name the two
 * things an account can be, and this is the control where somebody chooses which one they are
 * looking at — "Crypto" alone drops the word that distinguishes a perpetual from spot. So the
 * button grows to its text instead: it wraps to two lines, both buttons match height because
 * flex stretches them, and `min-height` keeps the single-line case exactly as it was.
 *
 * `overflow-wrap` rather than a fixed break, so it stays correct when the labels are
 * translated or the column is widened. */
.filters{ display:flex; gap:6px; padding:11px 12px; border-bottom:1px solid var(--hair); }
.filters button{
  flex:1; min-width:0;
  min-height:29px; padding:5px 6px;
  border-radius:8px; font-size:12.5px; line-height:1.25; color:var(--mute);
  overflow-wrap:anywhere;
  border:1px solid transparent; transition:color .2s, background .2s, border-color .2s;
}
.filters button:hover{ color:var(--ink); }
.filters button[aria-pressed="true"]{
  color:var(--ink); background:rgba(255,255,255,.05); border-color:var(--hair-2);
}

.mkts{ max-height:520px; overflow:auto; }
.mkt{
  width:100%; display:grid; grid-template-columns:1fr auto; gap:4px 10px;
  padding:11px 15px; border-bottom:1px solid rgba(255,255,255,.045);
  text-align:left; transition:background .18s;
}
.mkt:hover{ background:rgba(255,255,255,.028); }
.mkt[aria-current="true"]{ background:rgba(211,176,124,.07); box-shadow:inset 2px 0 0 var(--gold); }
.mkt__sym{ font-size:13.5px; font-weight:600; letter-spacing:.01em; }
.mkt__name{ grid-column:1; font-size:11.5px; color:var(--mute); }
.mkt__px{ font-family:var(--mono); font-size:13.5px; font-variant-numeric:tabular-nums; text-align:right; }
.mkt__ch{ grid-column:2; font-size:11.5px; text-align:right; font-variant-numeric:tabular-nums; }

/* A prediction market as a card.
 *
 * The row above is four cells sized for "BTC · 79,061.24 · Bitcoin · +1.1%". A prediction
 * market has no symbol and a QUESTION rather than a name, and squeezing "Will the Fed
 * decrease interest rates by 25 bps after the September 2026 meeting?" into the 11.5px muted
 * line meant for "Bitcoin" truncated it after four words — which is exactly the words that
 * do not distinguish it from the four other Fed markets.
 *
 * So: the question gets the full width and up to three lines, and the two facts that decide
 * whether somebody trades it — the probability and when it closes — sit under it. */
/* ==========================================================================
   PREDICTION MARKETS ARE CARDS

   The first attempt made them a taller ROW, and a taller row in a 230px rail is a worse
   row: a question wrapped to three lines against a bottom border, with a price and a date
   competing for the same line beneath it. Congested, which is exactly what it looked like.

   Two things were wrong, and only fixing both helps.

   **The column was too narrow.** 230px is a ticker rail, sized for "BTC 79,061.24". No
   typography rescues a sentence in it. Because an account now trades one vertical, a
   prediction trader sees ONLY prediction markets — so the column can be sized for what it
   actually holds rather than for the other product's shape. `.term--pred` widens it.

   **And a row is the wrong object.** These are not instruments with a symbol and a price;
   they are questions with a probability. So: a real card with its own surface and border,
   separated by space rather than divided by a line, with the question given room to be
   read and the two facts that decide a trade — the probability, and when it closes — on a
   settled row beneath it.
   ========================================================================== */
/* `.term--pred` no longer changes the GRID — the rails are one width in both verticals, so
   switching the filter cannot re-lay-out the page. The class stays because the market rows
   themselves differ: a question needs a different row than a ticker does. */

/* The line under the market-type tabs. Quiet: it is a fact about the product, not an
   instruction, and it disappears the moment an account settles the question. */
.filters__note{
  padding:0 12px 10px;
  font-size:10.5px; line-height:1.45; color:var(--mute);
}
.filters__note[hidden]{ display:none; }

.mkts--cards{ padding:9px; display:flex; flex-direction:column; gap:8px; }

.mkt--card{
  display:block;
  border:1px solid var(--hair);
  border-bottom:1px solid var(--hair);
  border-radius:11px;
  background:rgba(255,255,255,.018);
  padding:12px 13px 11px;
  transition:border-color .18s, background .18s, transform .18s;
}
.mkt--card:hover{
  background:rgba(255,255,255,.045);
  border-color:rgba(211,176,124,.35);
  transform:translateY(-1px);
}
.mkt--card[aria-current="true"]{
  border-color:rgba(211,176,124,.65);
  background:rgba(211,176,124,.08);
  box-shadow:none;
}

.mkt__q{
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
  font-size:12.5px; line-height:1.45; color:var(--ink);
  /* Two lines, not three. At 340px two lines carry about twelve words, which is enough to
     tell four Fed markets apart — and a uniform card height is what stops a list of sixty
     reading as rubble. */
  min-height:2.9em;
}

/* The probability and the close date, settled on one row under the question. A meter bar
   between them turns "38.5%" into something readable at a glance down a list of sixty. */
.mkt__foot{
  display:flex; align-items:center; gap:9px; margin-top:9px;
}
.mkt__prob{
  font-family:var(--mono); font-size:15.5px; line-height:1;
  font-variant-numeric:tabular-nums; color:var(--gold);
  min-width:54px;
}
.mkt__bar{
  flex:1; height:3px; border-radius:2px;
  background:rgba(255,255,255,.07); overflow:hidden;
}
.mkt__bar i{ display:block; height:100%; background:var(--gold); border-radius:2px; }
.mkt__when{
  font-size:10.5px; color:var(--mute); white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
.up{ color:var(--up); } .down{ color:var(--down); }

/* ==========================================================================
   THE MIDDLE COLUMN

   Price, then book, then positions — top to bottom in the order a trader reads
   them. The middle column was one chart and one table; it is three panels now,
   so it needs its own grid rather than an inline style.
   ========================================================================== */
/* The chart with the book to its right, and positions across the width of both.
 *
 * The book was under the chart, sharing a row with positions, and that pairing did two jobs
 * badly: it pushed the ladder below the fold on a laptop, where it is read while sizing an
 * order, and it squeezed positions into whatever the book left -- which is why the table had
 * no room for margin, leverage or a close control.
 *
 * Beside the chart, the book is at the height the eye already works at. It costs the chart
 * 300px of width, and on a terminal that is the right trade: the chart is context, the book
 * is the price you are about to get. */
.mid{
  display:grid; gap:14px; min-width:0;
  grid-template-columns:minmax(0,1fr) 300px;
  grid-template-areas:
    "price book"
    "pos   pos";
  align-items:start;
}
.panel--price{ grid-area:price; }
.panel--book { grid-area:book; }
.panel--pos  { grid-area:pos; }

/* The book fills the chart's height and scrolls inside it.
 *
 * `contain:size` is what lets it: without it the ladder's own twenty rows decide the row's
 * height, and whichever of the two panels is taller leaves a gap under the other. Contained,
 * the book contributes nothing to the row, `align-self:stretch` hands it the chart's height,
 * and the ladder scrolls within that. Only in this layout -- where the book is its own row
 * below 1180px, containment would collapse it to nothing, so it is lifted there. */
.panel--book{
  align-self:stretch; contain:size;
  display:flex; flex-direction:column; min-height:0;
}
.panel--book .book{ flex:1 1 auto; min-height:0; overflow:auto; }
.mid__row{ display:contents; }

/* The ticket and the account chart, as one column.
 *
 * The equity panel was a direct child of `.term` and auto-placed itself into
 * row 2 of column 1 — under the market list, and because `align-items:start`
 * puts row 2 below the tallest row-1 panel, a full chart's height of empty
 * space below the ticket. Grouping them makes "under the ticket" mean it. */
.side{ display:grid; gap:14px; min-width:0; }

/* ==========================================================================
   PRICE CHART

   Candles, because that is what a price chart is everywhere else and a line
   would have been us deciding a trader does not need the range. The history is
   Binance's and the last candle's close is our own mark — #pxSrc says so, and
   it is not decoration: the two numbers come from different places and anybody
   comparing the chart to the ticket has to know where the join is.

   Hand-drawn SVG, no library. 180 candles is 360 nodes, which is nothing, and
   the alternative is a build step and a CDN dependency for a rectangle.
   ========================================================================== */
.tfs{
  display:flex; align-items:center; gap:4px;
  padding:9px 12px; border-bottom:1px solid var(--hair);
}
/* Each set is its own flex row so hiding one does not leave a gap where it was. The
   explicit `[hidden]` rule is needed because `display:flex` beats the browser's own
   `[hidden]{display:none}` — a hidden set would otherwise still be laid out. */
.tfs__set{ display:flex; align-items:center; gap:4px; }
.tfs__set[hidden]{ display:none; }
.stat[hidden]{ display:none; }

.tfs button{
  height:26px; min-width:34px; padding-inline:8px; border-radius:7px;
  font-size:11.5px; color:var(--mute); border:1px solid transparent;
  font-variant-numeric:tabular-nums; transition:color .18s, background .18s, border-color .18s;
}
.tfs button:hover{ color:var(--ink); }
.tfs button[aria-pressed="true"]{
  color:var(--ink); background:rgba(255,255,255,.055); border-color:var(--hair-2);
}
/* Pushed to the right edge: it is a provenance label, not a control. */
.tfs__src{ margin-left:auto; font-size:11px; color:var(--mute); }

/* The chart draws itself into this box. `autoSize` reads the box, so the height
   lives here and nowhere in the JS — one place to change it, and it follows the
   media queries below without the script knowing they exist. */
.px{ padding:8px 4px 4px; height:400px; }
.px > div{ height:100%; }
/* The library paints its own background, so the panel's has to show through or
   the chart sits in a black rectangle inside a near-black panel. */
.px .tv-lightweight-charts{ background:transparent !important; }

.px__attr{
  padding:0 15px 11px; font-size:10.5px; color:var(--mute); opacity:.75;
}
.px__attr a{ color:var(--mute); text-decoration:underline; text-underline-offset:2px; }
.px__attr a:hover{ color:var(--ink); }

.px__read{
  display:flex; flex-wrap:wrap; gap:14px; padding:0 15px 12px;
  font-size:11.5px; color:var(--mute); font-variant-numeric:tabular-nums;
}
.px__read b{ color:var(--ink); font-weight:500; }

/* ==========================================================================
   THE ORDER BOOK

   Asks descending into the spread, bids descending away from it — the standard
   arrangement, so the best prices meet in the middle where the eye already goes.

   The depth bar behind each row is scaled to the deepest CUMULATIVE level on
   screen, not to the row's own size. Our rows are equal-sized by construction
   (the ladder is a straight line through the cost curve), so per-row scaling
   would draw twelve identical bars and say nothing.
   ========================================================================== */
.book{ padding:4px 0 8px; }
.book__hd, .book__row{
  display:grid; grid-template-columns:1fr 1fr 1fr; gap:8px;
  padding:0 15px; font-size:11.5px; font-variant-numeric:tabular-nums;
}
.book__hd{ color:var(--mute); padding-block:7px; }
.book__row{ position:relative; height:21px; align-items:center; }

/* `nth-of-type`, NOT `nth-child`.
 *
 * The depth bar is `position:absolute` so it takes no grid cell — but it is
 * still the row's first CHILD, so `nth-child(2)` selected the price and
 * `nth-child(3)` the size. The result on screen: price and size right-aligned,
 * total left-aligned, and none of the three lining up with the header above
 * them. `nth-of-type` counts spans only, which is what these rules meant.
 *
 * The same slip made `--ask span:first-child` colour the bar instead of the
 * price, so neither side's prices were tinted at all. Both only visible by
 * looking at the page. */
.book__hd span:nth-of-type(2), .book__hd span:nth-of-type(3),
.book__row span:nth-of-type(2), .book__row span:nth-of-type(3){ text-align:right; }
/* Behind the text, anchored right so the ladder reads as a histogram growing
   outward from the spread. */
.book__bar{ position:absolute; inset:1px 0 1px auto; right:0; border-radius:3px; z-index:0; }
.book__row span{ position:relative; z-index:1; }
.book__row--ask .book__bar{ background:rgba(255,75,75,.13); }
.book__row--bid .book__bar{ background:rgba(159,232,75,.12); }
.book__row--ask span:first-of-type{ color:var(--down); }
.book__row--bid span:first-of-type{ color:var(--up); }

.book__mid{
  display:flex; align-items:baseline; justify-content:space-between; gap:10px;
  margin-block:5px; padding:8px 15px;
  border-block:1px solid var(--hair);
  background:rgba(255,255,255,.022);
}
.book__mark{ font-family:var(--mono); font-size:15px; font-variant-numeric:tabular-nums; }
.book__sp{ font-size:11.5px; color:var(--mute); font-variant-numeric:tabular-nums; }

/* The disclaimer, and it is load-bearing rather than legal boilerplate. This
   ladder is perfectly symmetric and nothing rests in it — two things a trader
   who assumes it is an exchange book will read as bugs. */
.book__note{ padding:9px 15px 2px; font-size:11px; line-height:1.5; color:var(--mute); }

/* ==========================================================================
   ACCOUNT EQUITY

   A sparkline of the account's own history, under the ticket. It used to be the
   page's main chart, which put the account where a trader looks for the market.
   ========================================================================== */
.chart{ padding:16px 15px 12px; }
.chart svg{ width:100%; height:190px; overflow:visible; }
.chart__floor{ stroke:var(--down); stroke-width:1; stroke-dasharray:3 4; opacity:.65; }
.chart__line{ fill:none; stroke:var(--gold); stroke-width:1.6; stroke-linejoin:round; }
.chart__area{ fill:url(#eqfade); }
.chart__lbl{ font-size:10.5px; fill:var(--mute); }

/* ==========================================================================
   POSITIONS
   ========================================================================== */
.pos{ width:100%; border-collapse:collapse; }
.pos th, .pos td{ padding:10px 15px; text-align:right; font-size:12.5px; font-variant-numeric:tabular-nums; }
.pos th{ color:var(--mute); font-weight:450; font-size:11.5px; border-bottom:1px solid var(--hair); }
.pos td{ border-bottom:1px solid rgba(255,255,255,.045); }
.pos th:first-child, .pos td:first-child{ text-align:left; }
.pos tbody tr:last-child td{ border-bottom:0; }
.side-tag{
  display:inline-block; padding:2px 7px; border-radius:5px; font-size:10.5px;
  font-weight:600; letter-spacing:.03em;
}
.side-tag--long{ color:var(--up); background:rgba(159,232,75,.1); }
.side-tag--short{ color:var(--down); background:rgba(255,75,75,.1); }

/* ==========================================================================
   THE TICKET

   Up and down are the whole product (docs/13 §2), so they are the largest
   controls on the page and they are a real pair — choosing one visibly
   deselects the other, because a ticket that looks like it has no direction
   selected is a ticket somebody sends in the wrong one.
   ========================================================================== */
.ticket{ padding:15px; display:grid; gap:13px; }
.dir{ display:grid; grid-template-columns:1fr 1fr; gap:9px; }
.dir button{
  height:52px; border-radius:11px; border:1px solid var(--hair-2);
  font-family:var(--display); font-size:15px; font-weight:500; color:var(--mute);
  display:grid; place-items:center; gap:1px; transition:all .18s var(--ease);
}
.dir button small{ font-size:10.5px; letter-spacing:.06em; text-transform:uppercase; opacity:.75; }
.dir button:hover{ color:var(--ink); border-color:rgba(255,255,255,.2); }
.dir button[aria-pressed="true"][data-side="long"]{
  color:#06210A; background:var(--up); border-color:var(--up);
}
.dir button[aria-pressed="true"][data-side="short"]{
  color:#2B0606; background:var(--down); border-color:var(--down);
}

.field label{ display:block; font-size:11.5px; color:var(--mute); margin-bottom:6px; }
.field input, .field select{
  width:100%; height:42px; padding-inline:12px; border-radius:10px;
  background:rgba(255,255,255,.03); border:1px solid var(--hair-2); color:var(--ink);
  font:inherit; font-size:14px; font-variant-numeric:tabular-nums;
}
.field input:focus, .field select:focus{ outline:none; border-color:var(--gold); }

/* The leverage control was near-white text on a white box.
 *
 * A `<select>` without `appearance:none` is drawn by the OPERATING SYSTEM. Every rule
 * above — the background, the radius, the border — was being honoured for layout and then
 * painted over by Windows' own light combobox, under a `color` of #EDEAE5. Nothing was
 * wrong in the CSS as written; it simply never took effect, and it looks correct on a Mac,
 * which is how a bug like this survives review.
 *
 * So: draw it ourselves. The arrow is an inline SVG data URI rather than a pseudo-element
 * because `::after` does not render on a replaced element. */
.field select{
  appearance:none; -webkit-appearance:none; -moz-appearance:none;
  padding-right:34px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%238C877F' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 12px center;
  cursor:pointer;
}
.field select:hover{ border-color:var(--hair-2); }

/* The OPEN list is a separate surface and `appearance` does not reach it: the popup is
   drawn by the browser outside the page. `color-scheme` gets Chrome to pick a dark one,
   and the explicit colours below cover the platforms where it does not — without them the
   options inherit #EDEAE5 onto a white popup, which is the reported bug and is invisible
   in a screenshot of the CLOSED control. */
.field select{ color-scheme:dark; }
.field select option{
  background-color:#141210;
  color:var(--ink);
}
.chips{ display:flex; gap:6px; margin-top:7px; }
.chips button{
  flex:1; height:26px; border-radius:7px; font-size:11.5px; color:var(--mute);
  border:1px solid var(--hair); transition:color .18s, border-color .18s;
}
.chips button:hover{ color:var(--ink); border-color:var(--hair-2); }

.est{ display:grid; gap:6px; padding:11px 12px; border-radius:10px;
      background:rgba(255,255,255,.025); border:1px solid var(--hair); }
.est div{ display:flex; justify-content:space-between; font-size:12.5px; }
/* The liquidation price is the one figure on the ticket a trader must not skim past,
   so it is ruled off from the costs above it and carries the warning colour. */
.est__liq{
  margin-top:2px; padding-top:7px; border-top:1px solid var(--hair);
}
.est__liq span:last-child{ color:var(--down); }
.est span:first-child{ color:var(--mute); }
.est span:last-child{ font-variant-numeric:tabular-nums; }

/* The refusal. D55 made exposure limits a pre-trade refusal rather than a
   breach, which only helps if the trader can see WHY — a ticket that just
   greys out its button teaches nothing and generates a support message. */
.refusal{
  display:grid; gap:4px; padding:11px 12px; border-radius:10px;
  background:rgba(255,75,75,.07); border:1px solid rgba(255,75,75,.25);
}
.refusal b{ font-size:12px; color:var(--down); letter-spacing:.02em; }
.refusal p{ font-size:12.5px; line-height:1.45; color:var(--ink-2); }

.send{
  height:48px; border-radius:11px; font-family:var(--display); font-size:15px; font-weight:500;
  background:var(--ink); color:#0A0A0A; transition:opacity .18s, transform .06s;
}
.send:hover{ opacity:.9; }
.send:active{ transform:translateY(1px); }
.send[disabled]{ opacity:.32; cursor:not-allowed; }

.toast{
  position:fixed; left:50%; bottom:26px; transform:translateX(-50%) translateY(8px);
  padding:11px 17px; border-radius:11px; background:#101010; border:1px solid var(--hair-2);
  font-size:13px; opacity:0; pointer-events:none; transition:opacity .25s, transform .25s var(--ease);
  z-index:50; max-width:min(520px, calc(100vw - 32px));
}
.toast.is-on{ opacity:1; transform:translateX(-50%) translateY(0); }

.empty{ padding:26px 15px; text-align:center; font-size:12.5px; color:var(--mute); }

/* ==========================================================================
   RESPONSIVE

   The ticket goes first on a narrow screen, not last. On a phone the trader is
   most often closing something in a hurry, and making them scroll past the
   market list to do it is the wrong order under pressure.
   ========================================================================== */
@media (max-width:1320px){
  .mid{ grid-template-columns:minmax(0,1fr) 270px; }
}

/* Below this the chart is too narrow to share its row, so the book drops under it -- the
   book before positions, because it is the one being watched while sizing an order. */
@media (max-width:1180px){
  .mid{
    grid-template-columns:minmax(0,1fr);
    grid-template-areas: "price" "book" "pos";
  }
  .panel--book{ contain:none; align-self:auto; }
  .panel--book .book{ max-height:440px; }
}

@media (max-width:1080px){
  .term{ grid-template-columns:minmax(0,1fr) 300px; }
  .px{ height:300px; }
}
@media (max-width:820px){
  /* The strip wraps rather than scrolls: five labelled figures in a row do not
     fit, and a horizontally scrolling header hides the ones that matter most. */
  .stats{ gap:0 16px; }   /* `margin-left` is 0 for every width now, see above */
  .stat dt{ font-size:9.5px; }
  .stat__v{ font-size:13px; }
  .stat:first-child .stat__v{ font-size:15px; }

  .term{ grid-template-columns:minmax(0,1fr); padding-inline:16px; }
  .side{ order:1; }
  .mid{ order:2; }
  .rail__in{ grid-template-columns:1fr 1fr; gap:16px; padding-inline:16px; }
  .rail__equity{ grid-column:1 / -1; }
  .px{ height:230px; }
  /* Kept on small screens: the library's crosshair responds to touch, so the
     readout is reachable rather than being a hover-only affordance. */
  .px__read{ gap:10px; font-size:11px; }

  /* The positions table scrolls sideways rather than being cut off.
   *
   * It carries nine columns — market, size, entry, mark, stop, liquidation and P&L — which
   * need roughly 470px at this type size. At 390px the single-column layout gives it about
   * 358px, and `.panel` is `overflow:hidden`, so Stop, Liquidation and P&L were simply not
   * on the screen and there was no way to reach them. Liquidation and the stop are the two
   * prices at which the position ends; they are the last things that should fall off.
   *
   * Scrolled rather than column-dropped on purpose. Every figure here is one a trader may
   * need, and hiding some would mean choosing which — on the panel whose whole job is
   * telling somebody where they stand. `min-width` keeps the columns from crushing into
   * each other instead of scrolling. */
  /* `#fills` as well as `#posWrap`: `analytics.js` builds the same `table.pos` for the fill
     history, six columns of it, and analytics.html loads this stylesheet. One rule rather
     than two, so the next panel that renders a `.pos` gets it for free. */
  #posWrap, #fills{ overflow-x:auto; overscroll-behavior-x:contain; }
  .pos{ min-width:780px; }
  .pos th, .pos td{ padding-inline:11px; }
}


/* ---------------------------------------------------------------- the stop cell

   An editable price inside the positions table, beside the liquidation price. The two are
   the prices at which this position ends and the only difference is which one the trader
   chose — so they sit together, and the chosen one looks like something you can change.

   Styled as a field only on hover and focus. A table of eight input boxes reads as a form;
   a table with one number that turns into a field when you reach for it reads as a table.
   -------------------------------------------------------------------------- */
.stopc{ display:inline-flex; flex-direction:column; gap:2px; }

.stopc__in{
  width:82px; padding:3px 6px;
  border:1px solid transparent; border-radius:6px;
  background:transparent;
  font:inherit; font-variant-numeric:tabular-nums; color:var(--ink);
  transition:border-color .18s var(--ease), background-color .18s var(--ease);
}
.stopc__in::placeholder{ color:#6F6B66; }
.stopc__in:hover{ border-color:var(--hair-2); background:rgba(255,255,255,.03); }
.stopc__in:focus{
  outline:none;
  border-color:rgba(211,176,124,.5); background:rgba(211,176,124,.06);
}
/* Mid-request. `cursor:progress` rather than `not-allowed`: the field is working, not
   refusing. */
.stopc__in:disabled{ opacity:.6; cursor:progress; }

/* Holds no height when it is empty, so a row does not grow the moment a stop is saved and
   shrink again a second later. */
.stopc__note{ font-size:11px; line-height:1.3; color:#807C77; }
.stopc__note--bad{ color:#E48A8A; }


/* ---------------------------------------------------------------- account standing

   The banner for an account that can no longer trade. There was no interface for this at
   all: a breached account rendered a completely normal terminal, down to a live Buy button.

   Full-bleed and above the rail, because once an account is over every number below it is
   history rather than standing.
   -------------------------------------------------------------------------- */
.standing{
  padding:11px 18px;
  border-bottom:1px solid var(--hair);
  font-size:13.5px; line-height:1.5;
}
.standing[hidden]{ display:none; }

/* Final. Red, because it is a loss and reading it as anything softer wastes the one moment
   somebody needs to understand what happened. */
.standing--over{
  background:rgba(255,75,75,.10);
  border-bottom-color:rgba(255,75,75,.28);
  color:#F3B9B9;
}

/* A wait, not a loss. Gold rather than red: nothing has gone wrong for the trader here and
   showing them the colour of a breach for a provisioning delay is a small cruelty. */
.standing--wait{
  background:rgba(211,176,124,.09);
  border-bottom-color:rgba(211,176,124,.28);
  color:#E4CDA6;
}

/* Whether the figures on this page are streaming or being polled.
 *
 * A price that has not moved for ten seconds is either a quiet market or a dead connection,
 * and those are very different things to a trader about to size a position. The dot is the
 * cheapest way to say which. Dim by default: polling is the floor and is not a fault, so the
 * unlit state is "working, slower" rather than "broken". */
.live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--muted, #6b7280);
  opacity: 0.35;
  margin-left: 6px;
  flex: 0 0 auto;
  transition: opacity 160ms ease, background-color 160ms ease;
}

.live-dot.is-live {
  background: var(--up, #16a34a);
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .live-dot { transition: none; }
}


/* ==========================================================================
   THE MARKET PICKER

   The symbol is the control. It reads as a heading until it is reached for, then as a
   button -- the same restraint as the stop cell, for the same reason: a header full of
   boxed controls reads as a form, and this one is mostly read.

   The panel has to show the popover over the chart, and `.panel` clips its children for
   the rounded corners. The price panel alone opts out; nothing in it reaches its edges.
   ========================================================================== */
.panel--price{ overflow:visible; }

/* Its own width, not whatever the stats leave. The header already wraps, so when the name and
   the stats do not fit on one line the stats move down -- rather than the one element that says
   which market this is being cut to "BTC · Bi...". */
.pick{ position:relative; flex:0 0 auto; max-width:100%; }

.pick__btn{
  /* `calc(100% + 18px)`, not `100%`. `.pick` sizes to this button's MARGIN box, which the
     negative margins below make 18px narrower than the button -- so a plain 100% capped the button
     18px short of its own content and clipped "BTC · Bitcoin" to "BTC · Bi..." with the header half
     empty. Adding the margins back keeps the cap, so a long question still ellipsizes on a phone. */
  display:inline-flex; align-items:center; gap:9px; max-width:calc(100% + 18px);
  padding:5px 10px 5px 8px; margin:-5px -10px -5px -8px;
  border-radius:9px; border:1px solid transparent; color:var(--ink); text-align:left;
  transition:background-color .18s var(--ease), border-color .18s var(--ease);
}
.pick__btn:hover{ background:rgba(255,255,255,.04); border-color:var(--hair); }
.pick__btn[aria-expanded="true"]{ background:rgba(255,255,255,.055); border-color:var(--hair-2); }
.pick__btn:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; }

.pick__sym{
  font-family:var(--display); font-size:15px; font-weight:500; letter-spacing:.01em;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.pick__caret{
  flex:0 0 auto; width:12px; height:8px; color:var(--mute);
  transition:transform .22s var(--ease);
}
.pick__btn[aria-expanded="true"] .pick__caret{ transform:rotate(180deg); }

.pick__pop{
  position:absolute; top:calc(100% + 10px); left:-8px; z-index:40;
  width:min(380px, calc(100vw - 32px)); max-height:min(620px, 72vh);
  display:flex; flex-direction:column;
  /* A literal, as `.panel` uses. `var(--card-2)` does not resolve on this page, and an invalid
     background is dropped rather than defaulted -- the popover rendered transparent, with the
     chart's candles and timeframe buttons showing through its rows. */
  background:#0D0D0D; border:1px solid var(--hair-2); border-radius:13px;
  box-shadow:0 24px 48px -16px rgba(0,0,0,.72), 0 2px 8px rgba(0,0,0,.4);
  overflow:hidden;
  transform-origin:top left;
  animation:pick-in .18s cubic-bezier(.16,1,.3,1);
}
.pick__pop[hidden]{ display:none; }
@keyframes pick-in{
  from{ opacity:0; transform:translateY(-4px) scale(.985); }
  to  { opacity:1; transform:none; }
}

.pick__top{
  display:flex; align-items:center; gap:10px;
  padding:10px 12px; border-bottom:1px solid var(--hair);
}
.pick__find{
  flex:1 1 auto; min-width:0; height:34px; padding-inline:11px; border-radius:9px;
  background:rgba(255,255,255,.03); border:1px solid var(--hair-2); color:var(--ink);
  font:inherit; font-size:13px;
}
.pick__find::placeholder{ color:#6F6B66; }
.pick__find:focus{ outline:none; border-color:var(--gold); }
.pick__count{ flex:0 0 auto; font-size:11.5px; color:var(--mute); white-space:nowrap; }

/* The list keeps every rule it had in the rail; only its height changes, to the popover's. */
.pick__pop .mkts{ max-height:none; flex:1 1 auto; min-height:0; overflow:auto; }
.pick__pop .mkt:focus-visible{ outline:2px solid var(--gold); outline-offset:-2px; }

@media (prefers-reduced-motion: reduce){
  .pick__pop{ animation:none; }
  .pick__caret, .pick__btn{ transition:none; }
}


/* ==========================================================================
   POSITIONS, WIDENED

   The table has the width the book used to share with it, so a row carries what a trader
   manages a position by: the margin it holds, its leverage, where it is liquidated, the stop
   beside that, the PnL with its return on margin, and a way out.
   ========================================================================== */
/* A mark we could not refresh is still shown, because it is the last price we actually had,
   and marked so it is never read as current. */
.pos td.stale{ color:var(--mute); text-decoration:underline dotted; text-underline-offset:3px; }

.pos__lev{
  margin-left:7px; padding:1px 5px; border-radius:4px;
  font-size:10.5px; color:var(--mute); border:1px solid var(--hair-2);
  font-variant-numeric:tabular-nums; vertical-align:1px;
}
.pos__sub{ display:block; margin-top:1px; font-size:11px; color:var(--mute); }
.pos__pnl b{ font-weight:600; }
.pos__pnl small{ display:block; margin-top:1px; font-size:11px; opacity:.8; }
.pos__act{ width:1%; white-space:nowrap; }

/* Close takes two presses. The first arms it and turns it the colour of a loss, because a
   market close is final and costs the spread; the second sends it. It disarms by itself after
   four seconds or on leaving it, so an armed button is never left waiting for a stray click. */
.pos__close{
  height:28px; padding-inline:12px; border-radius:8px;
  border:1px solid var(--hair-2); font-size:12px; color:var(--ink);
  transition:background-color .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}
.pos__close:hover{ border-color:rgba(255,255,255,.22); background:rgba(255,255,255,.04); }
.pos__close.is-armed{ color:#2B0606; background:var(--down); border-color:var(--down); }
.pos__close:disabled{ opacity:.55; cursor:progress; }
.pos__close:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; }

/* ==========================================================================
   THE TICKET IN DOLLARS
   ========================================================================== */
.field__unit{ margin-left:3px; color:var(--ink-2); }
.field__in{ position:relative; }
.field__pre{
  position:absolute; left:13px; top:50%; transform:translateY(-50%);
  color:var(--mute); font-size:14px; pointer-events:none;
}
.field__in input{ padding-left:26px; }
.field__in.is-bare input{ padding-left:12px; }
/* The same trap this file has hit before: a `display` rule outranks the browser's own
   `[hidden]`, so a hidden element with one still lays out. Stated explicitly. */
.chips[hidden], .field__pre[hidden], .field__hint:empty{ display:none; }

.field__hint{
  margin-top:8px; font-size:11.5px; line-height:1.45; color:var(--mute);
  font-variant-numeric:tabular-nums;
}

/* Size and margin lead the estimate and read as the answer; the costs under them read as the
   working. */
.est__key span:last-child{ color:var(--ink); font-weight:600; }
.est small{ margin-left:3px; font-size:10.5px; color:var(--mute); opacity:.85; }

/* --- close confirmation. The scrim is account.css's `.modal`; the card is small and its own. --- */
.modal .confirm{
  position:relative; z-index:1; width:100%; max-width:380px;
  padding:22px 22px 18px; border:1px solid var(--hair-2, rgba(255,255,255,.14)); border-radius:16px;
  background:#0C0C0B; box-shadow:0 40px 90px rgba(0,0,0,.7);
}
.modal .confirm__title{ margin:0 0 14px; font-size:17px; font-weight:560; color:#F2EEE8; }
.modal .confirm__rows{ display:grid; grid-template-columns:auto 1fr; gap:7px 16px; margin:0 0 14px; font-size:13px; }
.modal .confirm__rows dt{ color:#8E8A85; }
.modal .confirm__rows dd{ margin:0; text-align:right; color:#E9E5DF; font-variant-numeric:tabular-nums; }
.modal .confirm__rows dd.up{ color:var(--up); }
.modal .confirm__rows dd.down{ color:var(--down); }
.modal .confirm__note{ margin:0 0 14px; font-size:12px; line-height:1.45; color:#807C77; }
.modal .confirm__skip{ display:flex; align-items:center; gap:8px; margin:0 0 18px; font-size:13px; color:#B9B4AE; cursor:pointer; }
.modal .confirm__skip input{ accent-color:var(--gold); width:15px; height:15px; }
.modal .confirm__actions{ display:flex; justify-content:flex-end; gap:10px; }
.modal .confirm__cancel,
.modal .confirm__go{ padding:9px 16px; border-radius:10px; font:inherit; font-size:13.5px; font-weight:520; cursor:pointer; }
.modal .confirm__cancel{ border:1px solid var(--hair-2, rgba(255,255,255,.14)); background:none; color:#D9D4CE; }
.modal .confirm__cancel:hover{ background:rgba(255,255,255,.05); }
.modal .confirm__go{ border:1px solid var(--down); background:var(--down); color:#2B0606; }
.modal .confirm__go:hover{ filter:brightness(1.08); }
.modal .confirm__cancel:focus-visible,
.modal .confirm__go:focus-visible,
.modal .confirm__skip input:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; }
.confirm__toggle{ margin:8px 2px 0; font-size:12px; color:#807C77; }
.confirm__again{ padding:0; border:0; background:none; font:inherit; color:var(--gold); cursor:pointer; text-decoration:underline; }

/* Market or limit. Quieter than the direction buttons above it on purpose: the direction is the
   decision, the order type is how it is carried out. docs/14 D1. */
.otype{ display:flex; gap:6px; margin-top:-4px; }
.otype[hidden], #limitWrap[hidden], .porders[hidden]{ display:none; }
.otype button{
  flex:1; height:30px; border-radius:8px; font-size:12px; color:var(--mute);
  border:1px solid var(--hair); transition:color .18s, border-color .18s;
}
.otype button:hover{ color:var(--ink); border-color:var(--hair-2); }
.otype button[aria-pressed="true"]{ color:var(--ink); border-color:var(--gold); }
.porders{ border-top:1px solid var(--hair); }

/* Stop-loss and take profit, side by side: two optional prices about one trade. docs/14 D1. */
.brackets{ display:grid; grid-template-columns:1fr 1fr; gap:9px; }
.brackets[hidden]{ display:none; }

/* PnL after fees: the fees under the figure, quieter than it. */
.pos__pnl .pos__fees{ opacity:.65; }

/* "This market only", at the end of the positions header. */
.pos__only{
  display:inline-flex; align-items:center; gap:6px; margin-left:auto;
  font-size:12px; color:var(--mute); cursor:pointer; user-select:none;
}
.pos__only input{ accent-color:var(--gold); margin:0; }

/* ==========================================================================
   PRESS FEEDBACK
   The terminal stays calm: no entrances, nothing a trader waits on. What it lacked was an answer to
   a click on its small controls, which already colour on hover but did nothing on press. A 3%
   squeeze in 120ms, the same on every one, so the ticket feels solid without being busy.
   ========================================================================== */
.filters button{ transition:color .2s, background .2s, border-color .2s, transform .12s var(--ease); }
.tfs button{ transition:color .18s, background .18s, border-color .18s, transform .12s var(--ease); }
.chips button, .otype button{ transition:color .18s, border-color .18s, transform .12s var(--ease); }
.pos__close{ transition:background-color .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease), transform .12s var(--ease); }
.pick__btn{ transition:background-color .18s var(--ease), border-color .18s var(--ease), transform .12s var(--ease); }

.filters button:active, .tfs button:active, .chips button:active, .otype button:active,
.pos__close:active, .pick__btn:active, .dir button:active{ transform:scale(.97); }

/* A row under the pointer is the row the next click acts on. */
.pos tbody tr{ transition:background-color .15s var(--ease); }
.pos tbody tr:hover{ background:rgba(255,255,255,.022); }

@media (prefers-reduced-motion:reduce){
  .filters button:active, .tfs button:active, .chips button:active, .otype button:active,
  .pos__close:active, .pick__btn:active, .dir button:active{ transform:none; }
}
