/*
 * The perps terminal, in the ghost lens.
 *
 * One rule decides every colour on this screen:
 *
 *   Vivid green and red belong to YOUR money. Nothing else may use them.
 *   The market ticks in drained green and red. Always.
 *
 * That is the opposite of how every exchange is built, and it is the whole
 * point. On a normal terminal the market screams in saturated green and red all
 * day, so by the time you have a position on, your own numbers are just two more
 * coloured cells in a screen full of them. Here the market is deliberately
 * quiet, which leaves the vivid palette free to mean exactly one thing: this is
 * yours. Your Long and Short buttons, a filled input, your liquidation price,
 * your open position. When you have nothing on, almost nothing on screen is
 * bright, and that is correct.
 *
 * The second idea follows from the first: because the market is quiet, a single
 * warm line can carry real weight. Type a limit price and it appears on the
 * chart exactly where your order would rest (drawMyLevels in perps-pro.js), the
 * only lit thing among the candles. That is also where an open position's entry
 * and liquidation lines will go.
 *
 * Structure, shell, sheets and the veil come from ghost-lens.css, which now maps
 * everything onto the app's own tokens from styles.css. So this file introduces
 * no colours, no radii and no type of its own, and follows the app into light
 * mode without knowing that light mode exists.
 */

/* ── header ─────────────────────────────────────────────────────────────────── */

.pp-sym {
  display: flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 0;
  padding: 2px 0;
  color: var(--gl-mine);
  font: inherit;
}
.pp-sym b {
  font-family: var(--font-display, 'Space Grotesk', Inter, sans-serif);
  font-size: 17.5px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.pp-chev {
  font-size: 9px;
  font-style: normal;
  color: var(--gl-market-faint);
}
.pp-chg {
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  /* Market data, so it takes the drained pair via .pp-up / .pp-down and never
     the vivid one. Stated here because a percentage next to a big number is the
     first thing anyone is tempted to make loud. */
}

/* Two icons in one pill: chart, or the order form. */
.pp-modes {
  margin-left: auto;
  display: flex;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
}
.pp-modes button {
  display: grid;
  place-items: center;
  width: 34px;
  height: 27px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--gl-market-faint);
  transition: background 0.16s var(--gl-ease), color 0.16s var(--gl-ease);
}
.pp-modes button.on {
  background: var(--gl-panel-2);
  color: var(--gl-mine);
}

/* ── the price strip ────────────────────────────────────────────────────────
   Market data, so cool even though it is the biggest number here. Direction
   uses the drained pair; the vivid pair is not available to the market. */

.pp-strip {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 0 14px 9px;
  flex: none;
}
.pp-last {
  min-width: 0;
}
.pp-last .pp-big {
  font-family: var(--font-display, 'Space Grotesk', Inter, sans-serif);
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.04;
  color: var(--gl-market);
  transition: color 0.3s var(--gl-ease);
}
/* Neutral, both ways. Direction is the job of the chip next to the symbol. */
.pp-last .pp-big.pp-up,
.pp-last .pp-big.pp-down {
  color: var(--gl-mine);
}
.pp-last .pp-mark {
  font-size: 11px;
  color: var(--gl-market-faint);
  margin-top: 3px;
}
.pp-stats {
  margin-left: auto;
  display: grid;
  grid-template-columns: auto auto;
  gap: 2px 12px;
  font-size: 10.5px;
  align-items: baseline;
}
.pp-stats span:nth-child(odd) {
  color: var(--gl-market-faint);
}
.pp-stats span:nth-child(even) {
  text-align: right;
  color: var(--gl-market-dim);
  font-variant-numeric: tabular-nums;
}

/* The market's own up and down, drained. Used by the book, the stats and the
   market list, never by anything the reader owns. */
.pp-up {
  color: var(--gl-bid);
}
.pp-down {
  color: var(--gl-ask);
}

/* A single frame of colour on a tick. Barely there on purpose: a terminal that
   flashes at you is a terminal you learn to stop looking at. */
@keyframes pp-flash-up {
  from { background: var(--gl-bid-wash); }
  to { background: transparent; }
}
@keyframes pp-flash-down {
  from { background: var(--gl-ask-wash); }
  to { background: transparent; }
}
.pp-flash-up {
  animation: pp-flash-up 0.45s ease-out;
}
.pp-flash-down {
  animation: pp-flash-down 0.45s ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .pp-flash-up, .pp-flash-down { animation: none; }
}

/* ── body and the split ─────────────────────────────────────────────────────── */

.pp-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 8px);
}

/* Chart mode is a viewport to fill, not a document to scroll: the chart takes
   whatever is left once the trade bar and the tabs have had their share. */
.pp-root.pp-mode-chart .pp-body {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.pp-root.pp-mode-chart .pp-chartwrap {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

/* 57/43 rather than half and half: the form has inputs that need width, the
   book needs two numbers and a bar. */
.pp-split {
  display: grid;
  grid-template-columns: 57fr 43fr;
  gap: 11px;
  padding: 0 12px 14px;
  align-items: start;
}

/* ── the order form: cold until you touch it ─────────────────────────────────
   An untouched form is not yours yet, so it sits back with the market. Filling
   a field is the moment it becomes yours, and it lights accordingly. */

.pp-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.pp-duo {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 7px;
}
.pp-pick {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  height: 42px;
  padding: 0 11px;
  border-radius: var(--gl-radius);
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
  color: var(--gl-mine);
  font: inherit;
  font-size: 13px;
}
.pp-pick span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pp-pick i {
  color: var(--gl-market-faint);
  font-size: 9px;
  font-style: normal;
  flex: none;
}
.pp-pick:active {
  background: var(--gl-panel-2);
}

.pp-avail {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 11px;
  color: var(--gl-market-dim);
  padding: 0 2px;
}
.pp-avail b {
  color: var(--gl-mine);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
/* Equity trails the available figure, quietly: margin behind an open
   position is money you have, and "available" on its own reads as though
   it were gone. */
.pp-availright {
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.pp-availeq:empty {
  display: none;
}
.pp-availeq {
  font-size: 10.5px;
  color: var(--gl-market-dim);
}

.pp-field {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 44px;
  padding: 0 11px;
  border-radius: var(--gl-radius);
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
  transition: border-color 0.16s var(--gl-ease), background 0.16s var(--gl-ease);
}
.pp-field input {
  flex: 1;
  min-width: 0;
  background: none;
  border: 0;
  outline: none;
  color: var(--gl-market);
  font: inherit;
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
  transition: color 0.16s var(--gl-ease);
}
.pp-field input::placeholder {
  color: var(--gl-market-faint);
}
.pp-field input:disabled {
  color: var(--gl-market-faint);
}
/* Yours now. A number you typed is the one thing in this column that is not
   the market's, so it reads in white against a warmed edge. */
.pp-field:has(input:not(:placeholder-shown)) {
  border-color: color-mix(in srgb, var(--success, #34e8a4) 34%, transparent);
  background: var(--gl-live-soft);
}
.pp-field input:not(:placeholder-shown) {
  color: var(--gl-mine);
  font-weight: 600;
}
.pp-field:focus-within {
  border-color: color-mix(in srgb, var(--success, #34e8a4) 50%, transparent);
}
.pp-field .pp-unit {
  flex: none;
  font-size: 10.5px;
  color: var(--gl-market-faint);
  letter-spacing: 0.02em;
}
.pp-field .pp-mid {
  flex: none;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 3px 6px;
  border-radius: 5px;
  background: var(--gl-panel-2);
  border: 0;
  color: var(--gl-market-dim);
  font-family: inherit;
}
.pp-field .pp-mid:active {
  color: var(--gl-live);
}

/* ── the size slider ────────────────────────────────────────────────────────── */

.pp-slider {
  padding: 5px 2px 1px;
}
.pp-track {
  position: relative;
  height: 3px;
  border-radius: 3px;
  background: var(--gl-edge);
}
.pp-track .pp-fill {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: 3px;
  background: var(--gl-live);
  opacity: 0.85;
}
.pp-track .pp-notch {
  position: absolute;
  top: 50%;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gl-void);
  border: 1.5px solid var(--gl-edge);
  transform: translate(-50%, -50%);
}
.pp-track .pp-notch.on {
  border-color: var(--gl-live);
}
.pp-track .pp-knob {
  position: absolute;
  top: 50%;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--gl-live);
  border: 2px solid var(--gl-void);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--success, #34e8a4) 50%, transparent), 0 1px 5px rgba(0, 0, 0, 0.6);
  transform: translate(-50%, -50%);
}
.pp-pcts {
  display: flex;
  justify-content: space-between;
  margin-top: 7px;
  font-size: 10.5px;
  color: var(--gl-market-faint);
}
.pp-pcts button {
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  padding: 2px 4px;
}
.pp-pcts button.on {
  color: var(--gl-live);
  font-weight: 600;
}

/* ── the consequences panel ─────────────────────────────────────────────────
   What this order does to you, so risk is amber: neither the market's colour
   nor a win, but the number to look at twice. */

.pp-facts {
  display: grid;
  gap: 7px;
  padding: 10px 11px;
  border-radius: var(--gl-radius);
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
}
/* Label left, number right, qualifier under the number. Baseline-aligned so
   the labels and the primary figures sit on one line however many of the
   rows carry a second. */
.pp-facts > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  font-size: 11.5px;
}
.pp-factlabel {
  color: var(--gl-market-dim);
  white-space: nowrap;
}
.pp-factval {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  min-width: 0;
  text-align: right;
}
.pp-factval b {
  font-weight: 600;
  color: var(--gl-mine);
  font-variant-numeric: tabular-nums;
}
/* The qualifier is context, not a second reading: quieter, and never the
   thing the eye lands on first. */
.pp-factnote {
  font-style: normal;
  font-size: 10px;
  line-height: 1.25;
  color: var(--gl-market-dim);
}
.pp-facts .pp-warn .pp-factval b,
.pp-facts .pp-liq .pp-factval b {
  color: var(--gl-risk);
}

/* ── flags ──────────────────────────────────────────────────────────────────── */

.pp-flags {
  display: grid;
  gap: 7px;
  padding: 1px 2px;
}
.pp-flag {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--gl-market-dim);
  background: none;
  border: 0;
  padding: 0;
  font-family: inherit;
}
.pp-box {
  width: 15px;
  height: 15px;
  border-radius: 4px;
  border: 1.5px solid var(--gl-edge);
  display: grid;
  place-items: center;
  flex: none;
}
/* The tick is always in the DOM so the box cannot change size when toggled;
   only its ink appears. Without this an unchecked box still shows a grey tick,
   which reads as "on" and is a dangerous thing to get wrong on post-only. */
.pp-box svg {
  opacity: 0;
  transition: opacity 0.1s ease;
}
.pp-flag.on .pp-box {
  background: var(--gl-live);
  border-color: var(--gl-live);
  color: var(--bg, #050609);
}
.pp-flag.on .pp-box svg {
  opacity: 1;
}
.pp-flag.on {
  color: var(--gl-mine);
}
.pp-flag .pp-tif {
  margin-left: auto;
  color: var(--gl-market-faint);
  font-size: 11px;
}

/* ── Long and Short: the warmest things on the screen ───────────────────────
   Your action, so the vivid pair, which nothing else here is allowed to use. */

.pp-sides {
  display: grid;
  gap: 8px;
  margin-top: 2px;
}
.pp-side {
  border: 0;
  /* A pill, like every other primary action in the app. */
  border-radius: 999px;
  padding: 14px 0 12px;
  font-family: var(--font, Inter, sans-serif);
  font-size: 16px;
  font-weight: 800;
  letter-spacing: 0.1px;
  display: grid;
  gap: 1px;
  transition: transform 0.08s var(--gl-ease), filter 0.14s var(--gl-ease);
}
.pp-side small {
  font-family: Inter, sans-serif;
  font-size: 10.5px;
  font-weight: 600;
  opacity: 0.72;
  font-variant-numeric: tabular-nums;
}
.pp-side.pp-long {
  background: var(--gl-live);
  color: var(--bg, #050609);
  box-shadow: 0 3px 18px color-mix(in srgb, var(--success, #34e8a4) 16%, transparent);
}
.pp-side.pp-short {
  background: var(--gl-loss);
  color: var(--bg, #050609);
  box-shadow: 0 3px 18px color-mix(in srgb, var(--red, #ff5c7a) 15%, transparent);
}
.pp-side:active {
  transform: scale(0.985);
  filter: brightness(1.07);
}
.pp-side[disabled] {
  opacity: 0.4;
  box-shadow: none;
}

/* ── the order book: cold, and read as a table ──────────────────────────────── */

.pp-book {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.pp-fund {
  font-size: 10.5px;
  color: var(--gl-market-faint);
  text-align: right;
  line-height: 1.5;
}
.pp-fund b {
  color: var(--gl-risk);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.pp-bookhead {
  display: flex;
  justify-content: space-between;
  font-size: 9.5px;
  letter-spacing: 0.04em;
  color: var(--gl-market-faint);
  padding: 2px 2px 1px;
  border-bottom: 1px solid var(--gl-edge-soft);
}
.pp-rows {
  display: grid;
}
.pp-row {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 19px;
  padding: 0 2px;
  background: none;
  border: 0;
  font: inherit;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.pp-row .pp-depth {
  position: absolute;
  top: 1px;
  bottom: 1px;
  right: 0;
  border-radius: 2px 0 0 2px;
  pointer-events: none;
}
.pp-row.ask .pp-depth {
  background: var(--gl-ask-wash);
}
.pp-row.bid .pp-depth {
  background: var(--gl-bid-wash);
}
.pp-row .pp-px {
  position: relative;
  font-weight: 600;
}
.pp-row.ask .pp-px {
  color: var(--gl-ask);
}
.pp-row.bid .pp-px {
  color: var(--gl-bid);
}
.pp-row .pp-sz {
  position: relative;
  color: var(--gl-market-dim);
}
.pp-row:active {
  background: var(--gl-panel);
}

/* The spread block. Market data, so the mid price is cool no matter how large. */
.pp-spread {
  padding: 5px 2px 4px;
}
.pp-mid-px {
  font-family: var(--font-display, 'Space Grotesk', Inter, sans-serif);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--gl-market);
}
.pp-mid-px.pp-up {
  color: color-mix(in srgb, var(--success, #34e8a4) 34%, var(--gl-mine));
}
.pp-mid-px.pp-down {
  color: color-mix(in srgb, var(--red, #ff5c7a) 34%, var(--gl-mine));
}
.pp-mid-sub {
  font-size: 10px;
  color: var(--gl-market-faint);
  margin-top: 1px;
  font-variant-numeric: tabular-nums;
}

.pp-ratio {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 9.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.pp-ratio .pp-bar {
  flex: 1;
  height: 3px;
  border-radius: 3px;
  overflow: hidden;
  display: flex;
}
.pp-ratio .pp-bar span:first-child {
  background: var(--gl-bid);
}
.pp-ratio .pp-bar span:last-child {
  background: var(--gl-ask);
}

/* ── chart ──────────────────────────────────────────────────────────────────── */

.pp-tfs {
  display: flex;
  gap: 4px;
  padding: 0 12px 8px;
  flex: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.pp-tfs::-webkit-scrollbar {
  display: none;
}
.pp-tfs button {
  flex: none;
  padding: 5px 11px;
  border-radius: 8px;
  border: 0;
  background: none;
  color: var(--gl-market-faint);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
}
.pp-tfs button.on {
  background: var(--gl-panel-2);
  color: var(--gl-mine);
}

.pp-chartwrap {
  position: relative;
  padding: 0 4px;
}
.pp-chartwrap canvas {
  display: block;
  width: 100%;
  touch-action: pan-y;
}
/* The crosshair readout: the only way to read a chart this size without
   pinch-zooming. */
.pp-ohlc {
  position: absolute;
  /* Under the legend, on whichever side the pointer is not. A table rather
     than a wrapping strip: eleven label/value pairs read down a column and do
     not read across a line. */
  left: 10px;
  top: 62px;
  display: grid;
  gap: 1px;
  font-size: 10px;
  font-variant-numeric: tabular-nums;
  color: var(--gl-market-dim);
  background: rgba(4, 5, 10, 0.86);
  border: 1px solid var(--gl-edge-soft);
  border-radius: 7px;
  padding: 4px 7px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s var(--gl-ease);
}
.pp-ohlc.on {
  opacity: 1;
}
.pp-ohlc b {
  color: var(--gl-mine);
  font-weight: 600;
}

/* The trade bar under the chart, with the price on the button so you never
   wonder what you are about to pay. */
.pp-quick {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 7px;
  padding: 10px 12px;
  flex: none;
  background: linear-gradient(to top, var(--gl-void) 62%, transparent);
}
.pp-quick .pp-field {
  height: 42px;
}

/* ── positions ──────────────────────────────────────────────────────────────── */

.pp-tabs {
  display: flex;
  gap: 16px;
  padding: 6px 14px 0;
  flex: none;
  border-bottom: 1px solid var(--gl-edge-soft);
}
.pp-tabs button {
  background: none;
  border: 0;
  padding: 6px 0 9px;
  color: var(--gl-market-faint);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  position: relative;
}
.pp-tabs button.on {
  color: var(--gl-mine);
}
.pp-tabs button.on::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  border-radius: 2px;
  background: var(--gl-live);
}
.pp-tabs .pp-count {
  color: var(--gl-market-faint);
  font-weight: 500;
  margin-left: 3px;
  font-variant-numeric: tabular-nums;
}

.pp-empty {
  text-align: center;
  color: var(--gl-market-faint);
  font-size: 12px;
  padding: 26px 20px 30px;
  line-height: 1.55;
}
/* In chart mode every pixel this takes is a pixel off the chart, and an empty
   panel has earned none of them. */
.pp-root.pp-mode-chart .pp-empty {
  padding: 10px 20px 12px;
  font-size: 11px;
}
.pp-root.pp-mode-chart .pp-empty div + div {
  display: none;
}

/* ── sheets: markets, leverage, order type ──────────────────────────────────── */

.pp-search {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 11px;
  margin-bottom: 6px;
  border-radius: var(--gl-radius);
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
  color: var(--gl-market-faint);
}
.pp-search svg {
  flex: none;
}
.pp-search input {
  flex: 1;
  min-width: 0;
  background: none;
  border: 0;
  outline: none;
  color: var(--gl-mine);
  font: inherit;
  font-size: 13.5px;
}
.pp-search input::placeholder {
  color: var(--gl-market-faint);
}

.pp-list {
  max-height: 58vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.pp-opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 11px 2px;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--gl-edge-soft);
  text-align: left;
  font: inherit;
  color: var(--gl-market-dim);
  font-size: 13px;
}
.pp-opt b {
  color: var(--gl-mine);
  font-weight: 600;
}
.pp-opt.on b {
  color: var(--gl-live);
}
.pp-opt-sub {
  display: block;
  font-size: 10.5px;
  color: var(--gl-market-faint);
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
.pp-opt-right {
  text-align: right;
  flex: none;
  color: var(--gl-mine);
  font-variant-numeric: tabular-nums;
}

/* Leverage as a grid of choices, with the consequence stated underneath rather
   than left for the reader to work out. */
.pp-levs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-bottom: 12px;
}
.pp-levs button {
  padding: 13px 0;
  border-radius: var(--gl-radius);
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
  color: var(--gl-market);
  font-family: var(--font-display, 'Space Grotesk', Inter, sans-serif);
  font-size: 14px;
  font-weight: 700;
}
.pp-levs button.on {
  background: var(--gl-risk-soft);
  border-color: color-mix(in srgb, var(--amber, #f0c46a) 45%, transparent);
  color: var(--gl-risk);
}

.pp-warn {
  padding: 10px 12px;
  border-radius: var(--gl-radius);
  background: color-mix(in srgb, var(--amber, #f0c46a) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--amber, #f0c46a) 22%, transparent);
  font-size: 11.5px;
  line-height: 1.5;
  color: color-mix(in srgb, var(--amber, #f0c46a) 55%, var(--text, #f5f6f8));
}
.pp-warn b {
  color: #fff;
}

.pp-num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* The drained pair is tuned for a price at 11px on a panel. At 10.5px inside a
   list row it drops to about 4:1 against the sheet background, which is thin for
   a number people actually read. Lifted here only, so the market stays quiet
   without the percentage becoming guesswork. */
.pp-opt-sub.pp-up {
  color: var(--success, #34e8a4);
}
.pp-opt-sub.pp-down {
  color: var(--red, #ff5c7a);
}

/* The way out of an empty positions panel. Lit, because funding is the reader's
   own next move rather than something the market is doing. */
.pp-fundlink {
  margin-top: 7px;
  background: none;
  border: 0;
  padding: 4px 2px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--gl-live);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── TP/SL, positions and feedback ─────────────────────────────────────────── */

.pp-brackets {
  display: grid;
  /* minmax(0, 1fr), not 1fr. A grid item's default min-width is auto, which is
     its min-content width, so a field whose placeholder is longer than the
     column refuses to shrink and overflows. "Take profit" did exactly that: the
     field measured 259px inside a 215px column and pushed its USDC label 21px
     into the order book. 1fr alone does not fix it; the explicit zero minimum
     does. */
  grid-template-columns: minmax(0, 1fr);
  gap: 7px;
}
.pp-brackets .pp-field {
  min-width: 0;
}
/* Belt and braces for the whole left column: every field in the form is now
   allowed to shrink, so a future label cannot reintroduce the same bug. */
.pp-form > *,
.pp-form .pp-field {
  min-width: 0;
}

.pp-pos {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--gl-edge-soft);
}
.pp-pos b {
  display: block;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--gl-mine);
}
.pp-pos-sub {
  display: block;
  font-size: 11px;
  color: var(--gl-market);
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
.pp-pos-right {
  text-align: right;
}
/* Your money, so this is where the vivid pair belongs. */
.pp-win {
  color: var(--success, #34e8a4);
}
.pp-lose {
  color: var(--red, #ff5c7a);
}
.pp-cancel {
  flex: none;
  padding: 7px 13px;
  border-radius: 999px;
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge);
  color: var(--gl-market);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
}
.pp-cancel:active {
  background: var(--gl-panel-2);
}

/* A trading screen should not open a dialog to say "order placed". */
/* The amount above the Pay-with rows. The rows themselves are the app's own
   .pk-* component, inherited rather than restyled, so this sheet follows
   whatever gifts, premium and stars follow. */
.pp-paysub {
  margin: 0 2px 12px;
}
.pp-payamt {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 2px 14px;
}
.pp-payamt-l {
  font-size: 13px;
  color: var(--gl-market);
}
.pp-payinput {
  flex: 1;
  min-width: 0;
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid var(--gl-edge);
  background: var(--bg-elev-2, #12151a);
  color: var(--gl-mine);
  font-size: 17px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* The venue's own words when it declines an order. Deliberately not a toast:
   the reason is the whole value of the message, and it has to outlive the
   glance that missed it. */
.pp-refuse {
  margin: 2px 0 10px;
  font-size: 15px;
  line-height: 1.45;
  color: var(--gl-mine);
  font-weight: 600;
}
.pp-refuse-detail {
  margin: 0 0 18px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--gl-market);
  font-variant-numeric: tabular-nums;
}

.pp-toast {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 18px);
  z-index: 10;
  padding: 13px 16px;
  border-radius: 999px;
  background: var(--bg-elev-3, #1d2127);
  border: 1px solid var(--gl-edge);
  color: var(--gl-mine);
  font-size: 13px;
  font-weight: 600;
  text-align: center;
  box-shadow: 0 12px 32px -10px rgba(0, 0, 0, 0.7);
  animation: pp-toast-in 0.24s var(--gl-ease) both;
}
.pp-toast.going {
  animation: pp-toast-out 0.26s var(--gl-ease) both;
}
@keyframes pp-toast-in {
  from { transform: translateY(14px); opacity: 0; }
}
@keyframes pp-toast-out {
  to { transform: translateY(10px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .pp-toast, .pp-toast.going { animation: none; }
}

/* ── header money controls and the pair row ────────────────────────────────── */

.pp-money {
  /* The only auto margin in the header. .pp-modes also had one, and two auto
     margins in a flex row share the free space between them, which parked this
     group in the middle instead of at the right edge. */
  margin-left: auto;
  display: flex;
  gap: 6px;
}
.pp-head .pp-modes {
  margin-left: 0;
}
.pp-moneybtn {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
  color: var(--gl-market);
}
.pp-moneybtn:active {
  background: var(--gl-panel-2);
}
/* Money in is the one you reach for first, so it carries the app's signature:
   the spectral silver gradient every primary action in GhosterDex uses, not the
   mint that belongs to positions and balances. Same treatment as the CTA, at
   icon size. */
.pp-moneybtn.pp-dep {
  background: var(--grad, linear-gradient(135deg, #ffffff, #dde5ee 55%, #93a2b5));
  border-color: transparent;
  color: var(--cta-text, #0a0d12);
  box-shadow:
    0 8px 20px -8px color-mix(in srgb, var(--ink, #fff) 34%, transparent),
    inset 0 1px 0 color-mix(in srgb, #ffffff 45%, transparent);
}
.pp-moneybtn.pp-dep:active {
  background: var(--grad, linear-gradient(135deg, #ffffff, #dde5ee 55%, #93a2b5));
  filter: brightness(1.06);
}

/* The pair picker, given room of its own rather than crowding the back control. */
.pp-pairrow {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 14px 8px;
  flex: none;
}
.pp-sym {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 13px;
  border-radius: 999px;
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge);
  color: var(--gl-mine);
  font: inherit;
}
.pp-sym:active {
  background: var(--gl-panel-2);
}
.pp-sym b {
  font-family: var(--font-display, 'Space Grotesk', Inter, sans-serif);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.2px;
}

/* ── the bracket editor ────────────────────────────────────────────────────── */

/* The armed summary in the form. One row, because the detail lives in the sheet. */
.pp-brackets {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 11px 13px;
  border-radius: var(--gl-radius);
  background: var(--gl-live-soft);
  border: 1px solid color-mix(in srgb, var(--success, #34e8a4) 28%, transparent);
  color: var(--gl-mine);
  font: inherit;
  text-align: left;
}
.pp-brackets-t {
  font-size: 12.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pp-brackets-go {
  flex: none;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--gl-live);
}

/* The facts strip at the top of the sheet: what this bracket is measured against. */
.pp-bstrip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  padding: 12px 14px;
  margin-bottom: 14px;
  border-radius: var(--gl-radius);
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
}
.pp-bstrip span {
  display: block;
  font-size: 10.5px;
  color: var(--gl-market-faint);
}
.pp-bstrip b {
  display: block;
  margin-top: 2px;
  font-size: 14px;
  font-weight: 700;
  color: var(--gl-mine);
}

.pp-srcrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}
.pp-srclabel {
  font-size: 12.5px;
  color: var(--gl-market);
}

/* A segmented control in the app's pill idiom. */
.pp-seg {
  display: flex;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
}
.pp-seg button {
  padding: 6px 12px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--gl-market);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  transition: background 0.16s var(--gl-ease), color 0.16s var(--gl-ease);
}
.pp-seg button.on {
  background: var(--gl-panel-2);
  color: var(--gl-mine);
}
.pp-seg.pp-seg-sm button {
  padding: 5px 10px;
  font-size: 11px;
}

.pp-bracket {
  display: grid;
  gap: 8px;
  padding: 14px;
  margin-bottom: 12px;
  border-radius: var(--gl-radius);
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
}
.pp-bhead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.pp-bhead b {
  font-size: 14.5px;
  font-weight: 700;
  color: var(--gl-mine);
}
.pp-bracket .pp-field {
  min-width: 0;
}

.pp-bquick {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
}
.pp-bquick button {
  padding: 8px 0;
  border-radius: 999px;
  background: var(--gl-panel-2);
  border: 1px solid var(--gl-edge-soft);
  color: var(--gl-market);
  font: inherit;
  font-size: 11.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.pp-bquick button:active {
  color: var(--gl-mine);
}

/* The sentence. This is the feature: a stop you have read is a different thing
   from a number you typed. */
.pp-bnote {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--gl-market);
}
.pp-bnote b {
  color: var(--gl-mine);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.pp-bnote.good b {
  color: var(--gl-live);
}
.pp-bnote.bad b {
  color: var(--gl-loss);
}

.pp-bclear {
  width: 100%;
  padding: 12px 0;
  border-radius: 999px;
  background: none;
  border: 1px solid var(--gl-edge);
  color: var(--gl-market);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
}

/* ── the right column: book or tape ────────────────────────────────────────── */

.pp-right {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.pp-righttabs {
  display: flex;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
}
.pp-righttabs button {
  flex: 1;
  padding: 5px 0;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--gl-market-faint);
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  transition: background 0.16s var(--gl-ease), color 0.16s var(--gl-ease);
}
.pp-righttabs button.on {
  background: var(--gl-panel-2);
  color: var(--gl-mine);
}

.pp-tape .pp-bookhead {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 6px;
}
.pp-trade {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 6px;
  align-items: center;
  height: 19px;
  padding: 0 2px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
/* The aggressor's side, drained like the book: this is the market's activity,
   not yours. */
.pp-trade.bid .pp-px {
  color: var(--gl-bid);
}
.pp-trade.ask .pp-px {
  color: var(--gl-ask);
}
.pp-trade .pp-px {
  font-weight: 600;
}
.pp-trade .pp-sz {
  color: var(--gl-market-dim);
  text-align: right;
}
.pp-trade .pp-tt {
  color: var(--gl-market-faint);
  font-size: 10px;
  text-align: right;
  min-width: 46px;
}
.pp-tape-empty {
  padding: 22px 6px;
  text-align: center;
  font-size: 11px;
  color: var(--gl-market-faint);
}

/* ── TP/SL: two depths ─────────────────────────────────────────────────────── */

.pp-tpsl {
  display: grid;
  gap: 7px;
}

/* The depth switch, riding on the TP/SL row. */
.pp-depth {
  margin-left: auto;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--gl-panel-2);
  border: 1px solid var(--gl-edge-soft);
  color: var(--gl-market);
  font: inherit;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.pp-depth:active {
  color: var(--gl-mine);
}
/* The flag row puts its TIF label in the same slot, so only one can claim it. */
.pp-flag .pp-depth + .pp-tif {
  margin-left: 8px;
}

/* Basic: the two prices, in the form, where the common case belongs. */
.pp-basic {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 7px;
}
.pp-basicrow {
  min-width: 0;
}
.pp-basicfield {
  min-width: 0;
}
/* Which price is watched. A label, not a control: the venue takes no
   instruction about it. */
.pp-srcpill {
  flex: none;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 3px 7px;
  border-radius: 6px;
  background: var(--gl-panel-2);
  color: var(--gl-market-dim);
}
.pp-srcnote {
  background: none;
  border: 0;
  padding: 2px;
  text-align: left;
  font: inherit;
  font-size: 10.5px;
  color: var(--gl-market-faint);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ── the market's mark, its star, and the favourites tabs ─────────────────────
 *
 * The logo comes from the app's own /api/icon route, same origin, so watching a
 * market tells no one outside the app which one. Perps list far more markets
 * than the wallet has coins for, indices among them, so the ticker fallback is
 * the ordinary case rather than an error state and is styled to look intended.
 */

.pp-logo {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  overflow: hidden;
  background: var(--gl-panel-2);
}
.pp-logo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.pp-logo.fallback {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--gl-market-dim);
}

.pp-sym .pp-logo.fallback {
  font-size: 8.5px;
}

/* Big enough to hit without magnifying the row: the star is the smallest
   target in the sheet and sits next to a control that navigates away, so a
   near miss costs you the screen you were on. */
.pp-star {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  margin-left: -6px;
  border-radius: 50%;
  color: var(--gl-market-dim);
  opacity: 0.55;
}
.pp-star.on {
  color: var(--gl-warn, #f5b73d);
  opacity: 1;
}
.pp-star.on svg {
  fill: currentColor;
}
.pp-star:active {
  transform: scale(0.88);
}

.pp-opt-name {
  flex: 1 1 auto;
  min-width: 0;
}

.pp-mkttabs {
  display: flex;
  gap: 6px;
  margin: 10px 0 2px;
  /* Scrolls itself. It used to simply overflow, so the only thing that
     could move to reveal the far end of it was the CARD, which took the
     whole list sideways with it. */
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.pp-mkttabs::-webkit-scrollbar {
  display: none;
}
.pp-mkttabs button {
  flex: none;
}
.pp-mkttabs button {
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--gl-edge);
  background: none;
  color: var(--gl-market-dim);
  font: inherit;
  font-size: 12.5px;
}
.pp-mkttabs button.on {
  background: var(--gl-panel-2);
  border-color: var(--gl-edge-strong, var(--gl-edge));
  color: var(--gl-mine);
  font-weight: 700;
}

.pp-mktempty {
  padding: 26px 4px;
  text-align: center;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--gl-market-dim);
}

/* ── the maker's mark ────────────────────────────────────────────────────────── */

.pp-head {
  position: relative;
}
.pp-brand {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex;
  pointer-events: none;
}
.pp-brand img {
  width: 22px;
  height: 22px;
  border-radius: 7px;
  object-fit: cover;
}
/* On a narrow phone the right-hand cluster closes in on the centre; the mark
   yields rather than overlaps. It is decoration, and decoration goes first. */
@media (max-width: 379px) {
  .pp-brand {
    display: none;
  }
}

/* ── chart tools and the account tabs ────────────────────────────────────────── */

/* The style and indicator buttons ride the timeframe row, pushed to its far
   end so the timeframes keep their muscle memory. */
.pp-tfs .pp-tool {
  margin-left: auto;
  width: auto;
  padding: 0 11px;
  font-size: 11px;
  color: var(--gl-market-dim);
}
.pp-tfs .pp-tool + .pp-tool {
  margin-left: 4px;
}

.pp-pill {
  flex: none;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--gl-panel-2);
  border: 1px solid var(--gl-edge);
  color: var(--gl-market-faint);
}
.pp-pill.on {
  background: var(--gl-live-soft);
  border-color: color-mix(in srgb, var(--success, #34e8a4) 40%, transparent);
  color: var(--gl-live);
}

.pp-posact {
  display: flex;
  gap: 7px;
  padding: 2px 0 10px;
}
.pp-balrow {
  border-bottom: 1px solid var(--gl-edge-soft);
}

/* ── the chart, alone ────────────────────────────────────────────────────────
 *
 * Expand hides everything that is not the price, and turning the phone gives a
 * genuine landscape chart: MainActivity is not orientation-locked and already
 * handles `orientation` in configChanges, so a rotation resizes the WebView
 * without recreating anything.
 *
 * Deliberately NOT a CSS rotation of the canvas. That trick makes a landscape
 * chart on a portrait phone, and it silently breaks every pointer coordinate on
 * the screen: getBoundingClientRect returns an axis-aligned box for a rotated
 * element, so the crosshair, the pan and every drawn line would land somewhere
 * other than the finger. Hiding the chrome is honest and keeps the maths true.
 */
/* Full screen means the chart and its tools, nothing else. The sub-tabs pick
   what the pane shows, and in full screen the answer is always the chart. */
html.pp-fullchart .pp-charttabs,
html.pp-fullchart .pp-strip,
html.pp-fullchart .pp-tabs,
html.pp-fullchart .pp-quick,
html.pp-fullchart .pp-split,
html.pp-fullchart .pp-pairrow,
html.pp-fullchart .pp-positions {
  display: none !important;
}
html.pp-fullchart .pp-head {
  padding-top: 2px;
  padding-bottom: 2px;
}
html.pp-fullchart .pp-chartwrap {
  flex: 1 1 auto;
  min-height: 0;
}
html.pp-fullchart .pp-tool.on,
.pp-tfs .pp-tool.on {
  background: var(--gl-panel-2);
  color: var(--gl-mine);
}
/* In landscape the toolbar and the header are the only chrome left, so they
   shrink to give the price the screen. */
@media (orientation: landscape) {
  html.pp-fullchart .pp-tfs {
    padding-top: 2px;
    padding-bottom: 2px;
  }
  html.pp-fullchart .gl-head {
    display: none;
  }
}
.pp-rotatehint {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--gl-panel-2);
  border: 1px solid var(--gl-edge);
  color: var(--gl-market-dim);
  font-size: 11.5px;
  pointer-events: none;
  animation: gl-fade 0.3s var(--gl-ease) both;
}
@media (orientation: landscape) {
  .pp-rotatehint {
    display: none;
  }
}

/* ── the drawing toolbar ─────────────────────────────────────────────────────
   Fifty tools is too many to scan as one list, so they arrive grouped, with the
   two destructive actions pinned above the groups where they can be reached
   without scrolling past every Fibonacci variant to undo a stray line. */
.pp-drawbar {
  display: flex;
  gap: 8px;
  margin-bottom: 4px;
}
.pp-drawact {
  flex: 1;
  padding: 10px 8px;
  border-radius: 12px;
  border: 1px solid var(--gl-market-line, rgba(255, 255, 255, 0.08));
  background: rgba(255, 255, 255, 0.03);
  color: var(--gl-market-text, #dde5f2);
  font: 600 12px Inter, system-ui, sans-serif;
}
.pp-drawact:disabled {
  opacity: 0.4;
}
.pp-drawgroup {
  font: 700 10px Inter, system-ui, sans-serif;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gl-market-faint, #7c8798);
  margin: 14px 2px 4px;
}
.pp-drawgroup:first-child {
  margin-top: 4px;
}

/* Text for the annotation tools. Asked for after the shape is placed, so the
   keyboard never covers the spot being annotated. */
.pp-textwrap {
  margin: 2px 0 10px;
}
.pp-textin {
  width: 100%;
  padding: 13px 14px;
  border-radius: 12px;
  border: 1px solid var(--gl-market-line, rgba(255, 255, 255, 0.08));
  background: rgba(255, 255, 255, 0.04);
  color: var(--gl-market-text, #dde5f2);
  font: 600 15px Inter, system-ui, sans-serif;
}
.pp-textin:focus {
  outline: none;
  border-color: var(--gl-accent, #34e8a4);
}

/* Where TradingView's widget lives when the licensed library is installed. It
   fills the same box our own canvas would, so landscape and the expand toggle
   behave identically whichever engine is drawing. */
.pp-tvhost {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* TradingView's lightweight-charts renders here; our canvas sits directly over
   it as the tool surface, transparent until a tool is armed. */
.pp-lwc {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.pp-chartwrap canvas.pp-overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: transparent;
}

/* The mode toggle says what it does. Icon-only, it was undiscoverable enough
   that the audit suite could not find it either. */
.pp-modelabel {
  font: 700 11px Inter, system-ui, sans-serif;
  letter-spacing: 0.01em;
  margin-left: 5px;
}
/* Rotation is lit while it is holding the screen, so the button reads as a
   state rather than as a thing that might or might not have worked. */
.pp-tool.pp-rot.on {
  background: var(--gl-accent, #34e8a4);
  color: #08120d;
  border-color: transparent;
}

/* Book mode: the chart keeps a compact strip above the ticket rather than
   disappearing, so the price stays in sight while the order is being set. The
   toggle chooses emphasis, not presence. */
.pp-root.pp-compactchart .pp-chartwrap {
  height: 190px;
  min-height: 190px;
  flex: none;
  overflow: hidden;
}
.pp-root.pp-compactchart .pp-tfs {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.pp-root.pp-compactchart .pp-tfs::-webkit-scrollbar {
  display: none;
}
/* The compact strip keeps its controls.

   An earlier rule hid every .pp-tool here to save width, which took the
   pencil and More with it: the drawing tools became unreachable by finger in
   book mode, and only a script could open them. The rail scrolls instead, so
   width is not actually scarce. Only the separate Landscape button goes,
   since the fullscreen button already does both. */
.pp-root.pp-compactchart .pp-tool.pp-rot {
  display: none;
}

/* Conditional and Scaled only show their own controls when chosen, so the
   ticket stays a ticket rather than a settings page. */
.pp-trigwrap,
.pp-scalewrap {
  display: grid;
  gap: 8px;
  margin-top: 8px;
}
.pp-scalewrap {
  grid-template-columns: 1fr 1fr;
}
.pp-trigstyle {
  display: flex;
  gap: 8px;
}
.pp-trigbtn {
  flex: 1;
  height: 36px;
  border-radius: 10px;
  border: 1px solid var(--gl-edge-soft, rgba(255, 255, 255, 0.08));
  background: rgba(255, 255, 255, 0.03);
  color: var(--gl-market-dim, #9aa7bb);
  font: 600 12px Inter, system-ui, sans-serif;
}
.pp-trigbtn.on {
  background: var(--gl-mine, #eef2f8);
  color: var(--bg, #10151d);
  border-color: transparent;
}
.pp-scaleinfo {
  grid-column: 1 / -1;
  font-size: 11px;
  color: var(--gl-market-faint, #7c8798);
}

/* Depth grouping sits on the book's own tab strip. */
.pp-group {
  margin-left: auto;
  min-width: 34px;
  height: 26px;
  padding: 0 9px;
  border-radius: 8px;
  border: 1px solid var(--gl-edge-soft, rgba(255, 255, 255, 0.08));
  background: rgba(255, 255, 255, 0.04);
  color: var(--gl-market-dim, #9aa7bb);
  font: 700 11px Inter, system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
}
/* Which way the visible book leans. */
.pp-ratio {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 2px 2px;
  font: 700 10px Inter, system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
}
.pp-ratio-b { color: var(--gl-accent, #34e8a4); }
.pp-ratio-s { color: var(--red, #ff5c7a); }
.pp-ratio-track {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 92, 122, 0.55);
  overflow: hidden;
}
.pp-ratio-fill {
  height: 100%;
  width: 50%;
  background: var(--gl-accent, #34e8a4);
}

/* Working-order settings, and the strip a running one keeps on screen. */
.pp-algowrap {
  display: grid;
  gap: 8px;
  margin-top: 8px;
}
.pp-algobar {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 10px;
  padding: 9px 11px;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--gl-accent, #34e8a4) 35%, transparent);
  background: color-mix(in srgb, var(--gl-accent, #34e8a4) 8%, transparent);
}
.pp-algotext {
  font: 600 11px Inter, system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
  color: var(--gl-mine, #eef2f8);
  white-space: nowrap;
}
.pp-algotrack {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
}
.pp-algofill {
  height: 100%;
  width: 0%;
  background: var(--gl-accent, #34e8a4);
  transition: width 0.3s ease;
}
.pp-algostop {
  flex: none;
  height: 26px;
  padding: 0 12px;
  border-radius: 8px;
  border: 0;
  background: var(--red, #ff5c7a);
  color: var(--bg, #10151d);
  font: 700 11px Inter, system-ui, sans-serif;
}

/* ── the chart's own controls ────────────────────────────────────────────────
   Five intervals on the rail and the rest behind More, because fifteen buttons
   do not fit a phone and the sixth one along is the one nobody can reach. */
.pp-tfrail {
  display: inline-flex;
  gap: 2px;
}
.pp-tfgrid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin: 4px 0 8px;
}
.pp-tfcell {
  height: 42px;
  border-radius: 11px;
  border: 1px solid var(--gl-edge-soft, rgba(255, 255, 255, 0.08));
  background: rgba(255, 255, 255, 0.03);
  color: var(--gl-market-dim, #9aa7bb);
  font: 700 12px Inter, system-ui, sans-serif;
}
.pp-tfcell.on {
  background: var(--gl-mine, #eef2f8);
  color: var(--bg, #10151d);
  border-color: transparent;
}

/* The pencil's strip: tools on the chart, not over it. */
.pp-drawbarstrip {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  padding: 6px 8px;
  background: rgba(255, 255, 255, 0.02);
  border-bottom: 1px solid var(--gl-edge-soft, rgba(255, 255, 255, 0.06));
}
.pp-drawbarstrip::-webkit-scrollbar { display: none; }
.pp-drawtool {
  flex: none;
  height: 30px;
  padding: 0 11px;
  border-radius: 9px;
  border: 1px solid var(--gl-edge-soft, rgba(255, 255, 255, 0.08));
  background: rgba(255, 255, 255, 0.03);
  color: var(--gl-market-dim, #9aa7bb);
  font: 600 11.5px Inter, system-ui, sans-serif;
  white-space: nowrap;
}
.pp-drawtool.on {
  background: var(--gl-accent, #34e8a4);
  color: #08120d;
  border-color: transparent;
}
.pp-drawall {
  border-style: dashed;
}
.pp-tool.pp-pencil.on {
  background: var(--gl-accent, #34e8a4);
  color: #08120d;
  border-color: transparent;
}
/* Hiding the chart is a state, so the control reads as one. */
.pp-hidechart.on {
  color: var(--gl-mine, #eef2f8);
  border-color: color-mix(in srgb, var(--gl-mine, #eef2f8) 30%, transparent);
}

/* Square, so a row of marks reads as a toolbar rather than a row of chips. */
.pp-drawtool {
  width: 34px;
  height: 34px;
  padding: 0;
  display: grid;
  place-items: center;
}
.pp-drawtool svg {
  display: block;
}
.pp-drawclear {
  color: var(--red, #ff5c7a);
}

/* The chart view's sub-tabs, and the panes behind them. */
.pp-charttabs {
  display: flex;
  gap: 18px;
  padding: 10px 14px 8px;
  border-bottom: 1px solid var(--gl-edge-soft, rgba(255, 255, 255, 0.06));
}
.pp-charttabs button {
  background: none;
  border: 0;
  padding: 0 0 6px;
  color: var(--gl-market-faint, #7c8798);
  font: 700 14px Inter, system-ui, sans-serif;
  border-bottom: 2px solid transparent;
}
.pp-charttabs button.on {
  color: var(--gl-mine, #eef2f8);
  border-bottom-color: var(--gl-mine, #eef2f8);
}
.pp-chartpane {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 12px 14px calc(env(safe-area-inset-bottom, 0px) + 20px);
}
.pp-panefacts {
  display: flex;
  flex-direction: column;
}
/* The tape: price, size, time, colour-coded by the side that took it. */
.pp-tape {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.pp-taperow {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: 10px;
  padding: 7px 2px;
  font-size: 12.5px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.03);
}
.pp-taperow.up > :first-child { color: var(--gl-accent, #34e8a4); }
.pp-taperow.down > :first-child { color: var(--red, #ff5c7a); }
.pp-taperow > :nth-child(2) { text-align: right; color: var(--gl-market-dim, #9aa7bb); }
.pp-tapetime { color: var(--gl-market-faint, #7c8798); font-size: 11.5px; }

.pp-panefacts .pp-fact {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 11px 0;
  font-size: 13.5px;
  color: var(--gl-market-dim, #9aa7bb);
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.pp-panefacts .pp-fact .pp-num {
  color: var(--gl-mine, #eef2f8);
  font-weight: 650;
}

/* The denomination is a control, so it reads as one. */
.pp-unitswap {
  cursor: pointer;
  padding: 4px 8px;
  margin: -4px -4px -4px 0;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  white-space: nowrap;
}
.pp-unitswap:active {
  background: rgba(255, 255, 255, 0.12);
}

/* The time-in-force reads as the control it now is. */
.pp-tifbtn {
  cursor: pointer;
  padding: 3px 8px;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.06);
}
.pp-tifbtn:active { background: rgba(255, 255, 255, 0.14); }

/* ── the account strip stays in reach ────────────────────────────────────────
   Positions, orders, history and balances were the last thing in a scrolling
   column, so whether you could see them depended on how tall the ticket
   happened to be on your phone: fine on one device, entirely below the fold on
   the next. Two pinned versions tried to fix that and both lost: sticky
   floated the strip over the last rows of the bids, and a reserved footer
   swallowed the Long and Short buttons on shorter phones. The venue apps
   do neither. They cap the book at six rows a side so the terminal is
   short, and let the strip sit UNDER it in plain flow, on screen because
   the content above it is, and wearing the page's own background because
   it has none of its own to get the theme wrong with. */
.pp-root .pp-tabs {
  border-top: 1px solid var(--gl-edge-soft);
  border-bottom: 0;
}
/* Room for the empty line without a jolt when real rows replace it. */
.pp-root:not(.pp-mode-chart) .pp-positions {
  min-height: 84px;
}

/* Three pickers share the row now, so they shrink together rather than one of
   them pushing the others off. */
.pp-root .pp-pick {
  flex: 1 1 0;
  min-width: 0;
}
.pp-root .pp-pick > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── the position card, in the venue apps' anatomy ───────────────────── */

.pp-poscard {
  margin: 10px 14px;
  padding: 12px 14px;
  border-radius: var(--gl-radius-lg);
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
}
.pp-poshead {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}
.pp-posid {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  flex-wrap: wrap;
}
.pp-posid b {
  font-size: 15px;
  color: var(--gl-mine);
}
.pp-sidechip {
  font-size: 11px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
}
.pp-sidechip.long {
  color: var(--gl-live);
  background: var(--gl-live-soft);
}
.pp-sidechip.short {
  color: var(--gl-loss);
  background: var(--gl-loss-soft);
}
.pp-levchip {
  font: inherit;
  font-size: 11px;
  color: var(--gl-market-dim);
  background: var(--gl-panel-2);
  border: 1px solid var(--gl-edge-soft);
  border-radius: 999px;
  padding: 2px 8px;
}
.pp-pospnl {
  text-align: right;
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: none;
}
.pp-pospnl b {
  font-size: 17px;
}
.pp-pospnl span {
  font-size: 11.5px;
  opacity: 0.85;
}
.pp-posgrid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px 8px;
  margin: 12px 0 2px;
}
.pp-poscell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  text-align: left;
  min-width: 0;
}
.pp-poscell span {
  font-size: 10.5px;
  color: var(--gl-market-faint);
  white-space: nowrap;
}
.pp-poscell b {
  font-size: 12.5px;
  color: var(--gl-market);
  overflow: hidden;
  text-overflow: ellipsis;
}
.pp-poscell.pp-risk b {
  color: var(--gl-risk);
}
.pp-closebtn {
  color: var(--gl-mine);
}

/* ── the close sheet ─────────────────────────────────────────────── */

.pp-closeseg {
  display: flex;
  gap: 4px;
  padding: 3px;
  border-radius: 999px;
  background: var(--gl-panel);
  border: 1px solid var(--gl-edge-soft);
  margin-bottom: 12px;
}
.pp-closeseg button {
  flex: 1;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 0;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--gl-market-faint);
}
.pp-closeseg button.on {
  background: var(--gl-panel-2);
  color: var(--gl-mine);
}
.pp-closefield {
  margin-top: 10px;
}
.pp-unit {
  color: var(--gl-market-faint);
  font-size: 12px;
  flex: none;
}
.pp-closechips {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}
.pp-closechips button {
  flex: 1;
  font: inherit;
  font-size: 11.5px;
  font-weight: 600;
  padding: 6px 0;
  border-radius: 999px;
  border: 1px solid var(--gl-edge-soft);
  background: var(--gl-panel);
  color: var(--gl-market-dim);
}
.pp-closechips button.on {
  color: var(--gl-mine);
  border-color: var(--gl-edge);
  background: var(--gl-panel-2);
}
.pp-closeproj {
  margin-top: 12px;
  font-size: 12.5px;
  min-height: 18px;
}
.pp-tpsl-label {
  margin-top: 14px;
  font-size: 12px;
  font-weight: 700;
  color: var(--gl-mine);
}
.pp-tpsl-note {
  margin-top: 12px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--gl-market-faint);
}

/* Live brackets on the card: visible guards, tap to edit in place.
   pp-poschips, not pp-brackets: that name already belongs to the entry
   ticket's bracket panel, and the last identical collision shipped a
   broken build. Grep before naming. */
.pp-poschips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin: 8px 0 2px;
}
.pp-bracketchip {
  font: inherit;
  font-size: 11.5px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--gl-edge-soft);
  background: var(--gl-panel-2);
}
.pp-bracketchip.tp {
  color: var(--gl-live);
}
.pp-bracketchip.sl {
  color: var(--gl-loss);
}
.pp-quietcta {
  background: var(--gl-panel-2);
  color: var(--gl-loss);
  border: 1px solid var(--gl-edge);
  box-shadow: none;
  margin-top: 10px;
}

/* ── the market list ─────────────────────────────────────────────────────────
   474 markets across ten venues: crypto on Hyperliquid's own book, and
   equities, indices, commodities, FX, rates and pre-IPO names on the HIP-3
   builder DEXs.

   The shape of the problem is choosing, not browsing, so everything above
   the rows is fixed and only the rows move: category, venue and sort stay
   under the thumb while a list of hundreds scrolls past them. Each row
   answers three questions in the order they are asked — what is it, is
   anyone trading it, and what has it done today. */

.pp-mkthead {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--gl-deep);
  padding-bottom: 6px;
  margin-bottom: 2px;
}

.pp-mktsub,
.pp-mktsort {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  /* A rail that has reached its end must stop, not hand the gesture to
     whatever is behind it. Without this the swipe chains outward and the
     sheet itself travels. */
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  padding: 0 2px;
}
.pp-mktsub::-webkit-scrollbar,
.pp-mktsort::-webkit-scrollbar {
  display: none;
}
.pp-mktsub {
  padding-bottom: 8px;
}
.pp-mktsub button,
.pp-mktsort button {
  flex: none;
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--gl-edge-soft);
  background: none;
  color: var(--gl-market-dim);
}
.pp-mktsub button.on {
  color: var(--gl-mine);
  border-color: var(--gl-edge);
  background: var(--gl-panel-2);
}

/* Sort reads as a set of questions rather than a control: the active one
   carries the direction it is answering in. */
.pp-mktsort {
  padding-top: 2px;
  padding-bottom: 6px;
  border-top: 1px solid var(--gl-edge-soft);
  margin-top: 2px;
}
.pp-mktsort button.on {
  color: var(--gl-live);
  border-color: color-mix(in srgb, var(--gl-live) 34%, transparent);
  background: var(--gl-live-soft);
}
.pp-sortdir {
  font-style: normal;
  margin-left: 4px;
  font-size: 10px;
}

/* The count beside a category, so the rail says how much is behind it. */
.pp-mktn {
  margin-left: 5px;
  font-size: 10px;
  font-weight: 600;
  color: var(--gl-market-faint);
  font-variant-numeric: tabular-nums;
}
.pp-mkttabs button.on .pp-mktn {
  color: var(--gl-market-dim);
}

/* ── a row ─────────────────────────────────────────────────────────────── */

.pp-mktlist {
  padding-bottom: 4px;
}
.pp-mktrow {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 6px;
  border: 0;
  border-bottom: 1px solid var(--gl-edge-soft);
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
}
.pp-mktrow:active {
  background: var(--gl-panel);
}
/* Where you already are, marked by a rail rather than a fill: the row is
   still a row, it just knows it is the one on screen behind this sheet. */
.pp-mktrow.on {
  background: var(--gl-panel);
  box-shadow: inset 2px 0 var(--gl-live);
}

.pp-mktleft {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.pp-mkttitle {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.pp-mkttitle b {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--gl-mine);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pp-mktsub {
  font-size: 11px;
  color: var(--gl-market-faint);
}
.pp-mktrow .pp-mktsub {
  display: block;
  padding: 0;
  overflow: visible;
}

/* Leverage and venue, as chips: both change how a market behaves, and both
   are things the venue itself puts on the row. */
.pp-lev,
.pp-dex {
  flex: none;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 1.5px 5px;
  border-radius: 5px;
  text-transform: uppercase;
}
.pp-lev {
  background: color-mix(in srgb, var(--gl-live) 16%, transparent);
  color: var(--gl-live);
}
.pp-dex {
  background: var(--gl-panel-2);
  color: var(--gl-market-faint);
  border: 1px solid var(--gl-edge-soft);
}

.pp-mktright {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 3px;
}
.pp-mktpx {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--gl-mine);
}
/* The day's move as a filled pill: it is the one number on the row that is
   read by colour before it is read by value. */
.pp-chgpill {
  font-size: 11px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 6px;
  line-height: 1.35;
}
.pp-chgpill.up {
  color: var(--gl-live);
  background: var(--gl-live-soft);
}
.pp-chgpill.down {
  color: var(--gl-loss);
  background: var(--gl-loss-soft);
}

/* A drawn mark for the markets the venue has no artwork for, coloured from
   the ticker so the same market is the same colour everywhere and a long
   list does not read as rows of identical grey. */
.pp-logo.pp-mark {
  background: hsl(var(--mark-h, 210) 46% 26%);
  color: hsl(var(--mark-h, 210) 82% 86%);
  border: 1px solid hsl(var(--mark-h, 210) 42% 38%);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.pp-logo.pp-mark-long {
  font-size: 7.5px;
  letter-spacing: -0.04em;
}

.pp-mktmore {
  width: 100%;
  margin: 10px 0 2px;
  padding: 11px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  border: 1px dashed var(--gl-edge);
  border-radius: var(--gl-radius);
  background: none;
  color: var(--gl-market-dim);
}

/* A setting that has been proposed but not yet confirmed by the venue. It
   must not look chosen: the whole bug this marks was a chip lighting up over
   a change the venue never accepted. */
.pp-levs button.pending {
  opacity: 0.55;
  border-style: dashed;
}

/* The order's own progress trail, in the app's trail language. Sits under the
   side buttons, where near.com puts it, and only exists while a tap is being
   carried out in more than one instruction. */
.pp-trailbox {
  margin: 12px 2px 2px;
}
.pp-trailbox .trail-label {
  font-size: 13px;
}

/* A book holding collateral of its own, with the way back. Laid out like a
   position row rather than a fact row, because it carries an action. */
.pp-balbook {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.pp-balbook > span:first-child {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

/* ── account health ─────────────────────────────────────────────────────────
   The whole account's risk in one slim strip above the position cards:
   margin usage as the bar, the nearest liquidation anywhere as the words.
   Colored by tier, not by decoration. */
.pp-health {
  margin: 2px 2px 10px;
  padding: 10px 12px 12px;
  border-radius: 14px;
  border: 1px solid var(--gl-edge);
  background: var(--bg-elev-1, #0d1014);
}
.pp-health-head {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
  color: var(--gl-market);
  margin-bottom: 8px;
}
.pp-health-bar {
  height: 5px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--gl-edge) 60%, transparent);
  overflow: hidden;
}
.pp-health-fill {
  height: 100%;
  border-radius: 999px;
  transition: width 0.4s var(--gl-ease);
}
.pp-health-ok .pp-health-fill { background: var(--gl-live); }
.pp-health-warm .pp-health-fill { background: var(--gl-risk); }
.pp-health-hot .pp-health-fill { background: var(--gl-loss); }
.pp-health-hot .pp-health-head span:last-child { color: var(--gl-loss); }

/* ── the Ghost receipt ──────────────────────────────────────────────────────
   A closed trade as a card worth showing someone. Leads with the move,
   keeps the dollars behind a tap: the flex without the disclosure. */
.pp-pos-tap { cursor: pointer; }
.pp-receiptwrap {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.pp-receipt {
  position: relative;
  width: min(340px, 92vw);
  padding: 26px 24px 20px;
  border-radius: 22px;
  border: 1px solid var(--gl-edge);
  background:
    radial-gradient(120% 90% at 50% -20%,
      var(--gl-live-soft) 0%, transparent 55%),
    var(--bg-elev-2, #12151a);
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.8);
  overflow: hidden;
  text-align: center;
}
.pp-receipt.lose {
  background:
    radial-gradient(120% 90% at 50% -20%,
      var(--gl-loss-soft) 0%, transparent 55%),
    var(--bg-elev-2, #12151a);
}
.pp-receipt-ghost {
  position: absolute;
  right: -28px;
  bottom: -34px;
  width: 150px;
  height: 150px;
  fill: color-mix(in srgb, var(--gl-mine) 5%, transparent);
}
.pp-receipt-ghost .eye {
  fill: var(--bg-elev-2, #12151a);
}
.pp-receipt-head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  font-size: 15px;
  color: var(--gl-mine);
}
.pp-receipt-move {
  margin-top: 18px;
  font-size: 44px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--gl-live);
}
.pp-receipt.lose .pp-receipt-move { color: var(--gl-loss); }
.pp-receipt-sub {
  margin-top: 2px;
  font-size: 12px;
  color: var(--gl-market);
}
.pp-receipt-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 14px;
  margin: 20px 4px 0;
  text-align: left;
}
.pp-receipt-grid div {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.pp-receipt-grid span {
  font-size: 11px;
  color: var(--gl-market-dim);
}
.pp-receipt-grid b {
  font-size: 14px;
  color: var(--gl-mine);
}
.pp-receipt-pnl {
  margin-top: 18px;
  width: 100%;
  padding: 11px 0;
  border-radius: 12px;
  border: 1px dashed var(--gl-edge);
  background: transparent;
  color: var(--gl-market);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.pp-receipt-brand {
  margin-top: 18px;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.34em;
  color: var(--gl-mine);
}
.pp-receipt-tag {
  margin-top: 2px;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gl-market-dim);
}
.pp-receipt-close {
  margin-top: 16px;
  padding: 10px 26px;
  border-radius: 999px;
  border: 1px solid var(--gl-edge);
  background: var(--bg-elev-2, #12151a);
  color: var(--gl-mine);
  font-size: 13px;
}

/* The shared card's preview: the PNG itself, at phone width, with the two
   decisions under it. What you see is byte-for-byte what leaves. */
.pp-cardpreview {
  width: min(320px, 86vw);
  border-radius: 18px;
  border: 1px solid var(--gl-edge);
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.8);
}
.pp-cardshare {
  margin-top: 16px;
  width: min(320px, 86vw);
}

/* Everything in the receipt overlay rides above its own scrim. The scrim is
   a positioned element, so it paints over static siblings: the card escaped
   by being position relative while the Share and Close buttons sat behind
   the veil, styled correctly and unreadable. */
.pp-receiptwrap > *:not(.gl-scrim) {
  position: relative;
}

/* ── the chart's risk layer ─────────────────────────────────────────────────
   Prices that are yours, riding the chart at their own height: the entry
   with its live PnL, the liquidation, and the brackets, which carry a grab
   handle because dragging one IS the edit. */
.pp-risklayer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  overflow: hidden;
}
.pp-riskchip {
  position: absolute;
  left: 6px;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  background: rgba(10, 13, 17, 0.88);
  border: 1px solid var(--gl-edge);
  color: var(--gl-mine);
  white-space: nowrap;
}
.pp-riskchip.entry.win { border-color: color-mix(in srgb, var(--gl-live) 45%, transparent); color: var(--gl-live); }
.pp-riskchip.entry.lose { border-color: color-mix(in srgb, var(--gl-loss) 45%, transparent); color: var(--gl-loss); }
.pp-riskchip.liq { border-color: color-mix(in srgb, var(--gl-loss) 55%, transparent); color: var(--gl-loss); }
.pp-riskchip.tp { border-color: color-mix(in srgb, var(--gl-live) 55%, transparent); color: var(--gl-live); }
.pp-riskchip.sl { border-color: color-mix(in srgb, var(--gl-risk) 60%, transparent); color: var(--gl-risk); }
.pp-riskdrag {
  pointer-events: auto;
  touch-action: none;
  cursor: grab;
  padding-right: 9px;
}
.pp-riskchip.dragging {
  cursor: grabbing;
  box-shadow: 0 6px 22px -6px rgba(0, 0, 0, 0.8);
  border-style: solid;
  z-index: 6;
}

/* The measure toggle, in the chart's corner where rulers live. */
.pp-measurebtn {
  position: absolute;
  right: 8px;
  top: 8px;
  z-index: 5;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  border: 1px solid var(--gl-edge);
  background: rgba(10, 13, 17, 0.7);
  color: var(--gl-market);
}
.pp-measurebtn.on {
  color: var(--gl-live);
  border-color: color-mix(in srgb, var(--gl-live) 45%, transparent);
}

/* The long-press menu's rows. */
.pp-stagebtn {
  display: block;
  width: 100%;
  margin: 0 0 8px;
  padding: 13px 14px;
  border-radius: 13px;
  border: 1px solid var(--gl-edge);
  background: var(--bg-elev-2, #12151a);
  color: var(--gl-mine);
  font-size: 14px;
  font-weight: 600;
  text-align: left;
}

/* A chip whose price lies beyond the window: pinned to the edge, arrowed. */
.pp-riskchip.pin-up::before,
.pp-riskchip.pin-down::before {
  content: '';
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
}
.pp-riskchip.pin-up::before { border-bottom: 5px solid currentColor; }
.pp-riskchip.pin-down::before { border-top: 5px solid currentColor; }

/* ── the mode switch, redesigned ────────────────────────────────────────────
   A segmented pill of two glyphs: candles for the chart, the ladder for the
   book. The active cell is lifted, not labelled. */
.pp-modes {
  display: flex;
  gap: 2px;
  padding: 3px;
  margin-left: auto;
  border-radius: 12px;
  border: 1px solid var(--gl-edge);
  background: color-mix(in srgb, var(--gl-edge) 35%, transparent);
}
.pp-modes button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 30px;
  border: none;
  border-radius: 9px;
  background: transparent;
  color: var(--gl-market-dim);
  transition: background 0.15s var(--gl-ease), color 0.15s var(--gl-ease);
}
.pp-modes button.on {
  background: var(--bg-elev-3, #1d2127);
  color: var(--gl-mine);
  box-shadow: 0 2px 10px -3px rgba(0, 0, 0, 0.65);
}

/* ── perps in the Activity page ─────────────────────────────────────────────
   Drawn in the APP's variables and the app's own row classes, not the
   terminal's: these rows sit among the wallet's own history, and a block
   wearing the trading palette would read as a widget dropped onto the page.
   Only what the app has no rule for is styled here. */
.pp-acthost {
  display: block;
}
.pp-acthost[hidden] { display: none; }
.pp-actblock {
  margin-top: 4px;
}
.pp-acthead {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 14px 2px 2px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--text);
}
.pp-acthead i {
  font-style: normal;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-faint);
}
/* Pushed to the far edge so the header reads "Perps ... See all 17" rather
   than crowding the label it belongs to. */
.pp-actmore {
  margin-left: auto;
  padding: 4px 0;
  background: none;
  border: 0;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-dim);
}
.pp-actmore:active { opacity: 0.6; }

/* The round face. A fill wears the market's artwork through .token-icon, so
   only the two cases the app has no picture for are drawn here. */
.pp-actbadge,
.pp-actmark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--bg-elev-2);
  box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--ink) 13%, transparent);
}
.pp-actbadge.in { color: var(--success); }
.pp-actbadge.out { color: var(--red); }
.pp-actbadge.move { color: var(--text-dim); }
.pp-actmark {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: hsl(var(--mark-h, 210) 70% 72%);
  background: hsl(var(--mark-h, 210) 45% 22%);
}
.pp-actrow .pp-acttitle {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The venue's own size and price, which is detail rather than headline: the
   app's .l2 is its loudest line, and a fill's amount does not deserve that. */
.pp-actrow .pp-actsub {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-dim);
}
.pp-actval.win { color: var(--success); }
.pp-actval.lose { color: var(--red); }

/* Rows that open a card answer the finger the way the app's rows do. */
.pp-acttap { transition: opacity 0.15s; }
.pp-acttap:active { opacity: 0.65; }

/* ── the demo account ───────────────────────────────────────────────────────
 *
 * Off: one small outlined word beside the balance. No colour, no fill, no
 * call to action, so someone who came here to trade is not sold a tutorial.
 * On: it lights, and a hairline runs across the top of the screen, because
 * trading paper money while believing it is real is the one mistake this
 * feature could cause and it must be impossible to hold that belief.
 */
/* In the header's money group, beside deposit and withdraw: sized to sit with
   those icon buttons rather than to compete with them. */
.pp-demochip {
  align-self: center;
  margin-right: 2px;
  padding: 6px 11px;
  border-radius: 999px;
  border: 1px solid var(--gl-edge);
  background: transparent;
  color: var(--gl-market-dim);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.pp-demochip:active { opacity: 0.6; }
.pp-demochip.on {
  color: var(--gl-warn, #f0c46a);
  border-color: color-mix(in srgb, var(--gl-warn, #f0c46a) 55%, transparent);
  background: color-mix(in srgb, var(--gl-warn, #f0c46a) 14%, transparent);
}
/* The whole screen wears it, quietly: a single lit hairline along the top. */
.pp-root.pp-demo::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  z-index: 40;
  pointer-events: none;
  background: linear-gradient(90deg, transparent,
    var(--gl-warn, #f0c46a) 25%, var(--gl-warn, #f0c46a) 75%, transparent);
  opacity: 0.75;
}

/* ── the open position, as a live ticket ───────────────────────────────────
 *
 * Not a row. Pinned above the wallet's history in the wallet's own row
 * anatomy, an open trade read as the first entry OF that history - two
 * rounded panels touching, same background, nothing saying where one ended.
 * A position is the one thing on this page that has not finished happening,
 * so it is shaped like a thing rather than like an entry, and the lane it
 * sits in closes with a rule so the history below STARTS rather than
 * continues.
 */
.pp-livelane {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 10px 0 0;
}
.pp-lanerule {
  height: 1px;
  margin: 18px 0 4px;
  background: linear-gradient(90deg, transparent, var(--stroke), transparent);
}
.pp-live {
  display: block;
  width: 100%;
  text-align: left;
  padding: 14px 15px 15px;
  border-radius: 18px;
  border: 1px solid var(--stroke);
  background:
    radial-gradient(120% 100% at 100% 0%, var(--pp-live-wash), transparent 62%),
    var(--bg-elev);
  box-shadow: inset 0 1px 0 var(--bump-hi), 0 10px 26px -18px rgba(0, 0, 0, 0.9);
  transition: transform 0.15s ease, opacity 0.15s ease;
}
.pp-live:active { transform: scale(0.988); opacity: 0.9; }
.pp-live.win {
  --pp-live-wash: color-mix(in srgb, var(--success) 16%, transparent);
  border-color: color-mix(in srgb, var(--success) 34%, var(--stroke));
}
.pp-live.lose {
  --pp-live-wash: color-mix(in srgb, var(--red) 15%, transparent);
  border-color: color-mix(in srgb, var(--red) 32%, var(--stroke));
}

.pp-live-head { display: flex; align-items: center; gap: 11px; }
.pp-live-head .token-icon-wrap { flex: none; }
.pp-live-head .token-icon,
.pp-live-head .pp-actmark { width: 34px; height: 34px; }
.pp-live-name { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.pp-live-name > b {
  font-size: 15px; font-weight: 700; color: var(--text); letter-spacing: -0.01em;
}
.pp-live-tags { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pp-live-tags i {
  font-style: normal; font-size: 10.5px; font-weight: 700; letter-spacing: 0.02em;
  padding: 2.5px 7px; border-radius: 999px;
  border: 1px solid var(--stroke-soft); color: var(--text-dim);
}
.pp-live-side.long {
  color: var(--success);
  border-color: color-mix(in srgb, var(--success) 40%, transparent);
}
.pp-live-side.short {
  color: var(--red);
  border-color: color-mix(in srgb, var(--red) 40%, transparent);
}

/* The one thing on this screen that is genuinely still moving, saying so. */
.pp-live-beat {
  display: flex; align-items: center; gap: 5px; flex: none;
  font-size: 9.5px; font-weight: 800; letter-spacing: 0.16em;
  color: var(--text-faint);
}
.pp-live-beat i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--gold);
  animation: pp-beat 1.6s ease-in-out infinite;
}
@keyframes pp-beat {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 color-mix(in srgb, var(--gold) 55%, transparent); }
  50% { opacity: 0.45; box-shadow: 0 0 0 5px transparent; }
}

.pp-live-body {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 14px; margin-top: 13px;
}
.pp-live-pct {
  font-family: var(--font-display); font-size: 30px; font-weight: 700;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums; line-height: 1;
}
.pp-live.win .pp-live-pct { color: var(--success); }
.pp-live.lose .pp-live-pct { color: var(--red); }
.pp-live-legs { display: flex; gap: 16px; padding-bottom: 2px; }
.pp-live-legs span { display: flex; flex-direction: column; gap: 2px; }
.pp-live-legs i {
  font-style: normal; font-size: 10px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-faint);
}
.pp-live-legs b {
  font-size: 13px; font-weight: 700; color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

/* ── the position sheet ─────────────────────────────────────────────────────
   Tapping a row opens a receipt everywhere else in this app; a position
   behaves the same way. Read it first, then decide - and the three decisions
   worth having are show someone, get out, or go and work the market. */
.pp-possheet {
  position: fixed; inset: 0; z-index: 62;
  display: flex; flex-direction: column; justify-content: flex-end;
}
.pp-possheet > *:not(.gl-scrim) { position: relative; }
.pp-posbody {
  padding: 10px 18px calc(18px + env(safe-area-inset-bottom, 0px));
  border-radius: 22px 22px 0 0;
  border-top: 1px solid var(--stroke);
  background:
    radial-gradient(120% 70% at 50% 0%, var(--pp-live-wash), transparent 70%),
    var(--bg-elev);
  animation: pp-posrise 0.24s cubic-bezier(0.2, 0.9, 0.25, 1);
}
.pp-posbody.win { --pp-live-wash: color-mix(in srgb, var(--success) 14%, transparent); }
.pp-posbody.lose { --pp-live-wash: color-mix(in srgb, var(--red) 13%, transparent); }
@keyframes pp-posrise { from { transform: translateY(14px); opacity: 0; } }
/* A handle that means it: the sheet is dragged away from anywhere on it, and
   the gesture is claimed from the first frame so a downward pull is never
   half-given to a scroll underneath. */
.pp-posbody { touch-action: none; }
.pp-posgrip {
  display: block; width: 42px; height: 4px; border-radius: 999px;
  margin: 2px auto 14px; background: var(--stroke);
}
.pp-posbody:active .pp-posgrip { background: var(--text-faint); }
.pp-poshead { display: flex; align-items: center; gap: 12px; }
.pp-poshead .token-icon, .pp-poshead .pp-actmark { width: 38px; height: 38px; }
/* Left, explicitly. The sheet sits inside a centring flex column, and without
   this the name and its chips drift to the far edge away from their own
   icon. */
.pp-poswho {
  display: flex; flex-direction: column; gap: 4px;
  flex: 1; min-width: 0; align-items: flex-start; text-align: left;
}
.pp-poswho > b { font-size: 17px; font-weight: 700; color: var(--text); }
.pp-poshead { align-items: center; }
.pp-pospct {
  font-family: var(--font-display); font-size: 42px; font-weight: 700;
  letter-spacing: -0.025em; font-variant-numeric: tabular-nums;
  margin-top: 16px; line-height: 1;
}
.pp-posbody.win .pp-pospct { color: var(--success); }
.pp-posbody.lose .pp-pospct { color: var(--red); }
.pp-possub { font-size: 12.5px; color: var(--text-faint); margin-top: 5px; }
.pp-posfacts {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px 14px; margin-top: 18px;
}
.pp-posfacts > div {
  display: flex; flex-direction: column; gap: 3px;
  padding: 10px 12px; border-radius: 13px;
  border: 1px solid var(--stroke-soft); background: var(--glass-2);
}
.pp-posfacts span { font-size: 10.5px; color: var(--text-faint); font-weight: 600; }
.pp-posfacts b {
  font-size: 14px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums;
}
/* The dollars: revealed on purpose, never sitting there for a passing glance. */
.pp-posmoney {
  width: 100%; margin-top: 12px; padding: 12px;
  border-radius: 13px; border: 1px dashed var(--stroke);
  background: transparent; color: var(--text-dim);
  font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.pp-posacts { display: flex; align-items: stretch; gap: 9px; margin-top: 16px; }
/* Three equal pills with their labels dead centre.
 *
 * `flex: 1` alone was not enough for either half of that. The basis defaults
 * to `auto`, so each pill was sized by its own text and "Share" came out
 * narrower than "Close position"; and the app resets button text alignment,
 * so every label sat against its own left edge instead of in the middle. Flex
 * centring rather than `text-align` because these are flex containers, and
 * `min-width: 0` so the longest label cannot push its neighbours narrower. */
.pp-posact {
  flex: 1 1 0;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  white-space: nowrap;
  padding: 13px 8px;
  border-radius: 999px;
  border: 1px solid var(--stroke);
  background: var(--bg-elev-2);
  color: var(--text);
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.1;
  transition: opacity 0.15s;
}
.pp-posact:active { opacity: 0.65; }
.pp-posact.close {
  border-color: color-mix(in srgb, var(--red) 45%, transparent);
  color: var(--red);
}
.pp-posact.go { background: var(--ink); color: var(--bg); border-color: transparent; }

/* ── Edit activity: the row in the air follows the finger ───────────────────
 *
 * `.aes-row` carries `transition: transform 0.18s ease` so that settling rows
 * ease into place. Applied to the row being DRAGGED, that same rule makes it
 * trail the finger by a fifth of a second: measured at 270px of travel, the
 * row had moved 52px. It reads as lag, and it made every threshold in the
 * reorder fire late and in bursts.
 *
 * The dragged row is the one element that must be exactly where the finger
 * is, so it opts out. Everything else keeps its easing. This applies to the
 * sheet's own rows as well as the beta's, because the rule was never right
 * for either.
 */
.aes-row.lift {
  transition: box-shadow 0.22s ease, border-color 0.2s ease, background 0.2s ease;
  will-change: transform;
}
/* The grip is the one control here that must never be read as a scroll, a
   text selection or a long-press callout. */
.pp-aesrow .aes-grip,
.pp-aesrow .aes-btn {
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
/* A wider target than the dots suggest: six 4px dots is a 20px column, and a
   thumb is nearer 40. Padding rather than size, so nothing moves. */
.pp-aesrow .aes-grip { padding: 10px 9px; margin: -10px -9px; }

/* Nothing in this block is text to be selected, and on Android a long press
   that starts a selection freezes touch until the callout is dismissed. The
   app's own controls are React elements that prevent it in JS; these say it
   in CSS as well, so a press that misses the chip and lands on a row cannot
   raise the callout either. */
.pp-actchip,
.pp-actrow,
.pp-acthead {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* Perps selected: the app's own list stands down. Done with a class on the
   page rather than by hiding the list itself, which React rebuilds. The
   child combinator matters - the block's own .asset-list is nested. */
.page.pp-perpsonly > .asset-list,
.page.pp-perpsonly > .empty-state { display: none; }

/* ── paired devices ───────────────────────────────────────────────────────
   The list of everything the venue lets trade this account, and the way
   out. Deliberately plain: this is a security screen, and a row that has to
   be decoded is a row nobody audits. */
.pp-devices { margin: 2px 0 18px; }
.pp-devices-h {
  font-size: 14px;
  font-weight: 700;
  margin: 18px 0 6px;
  opacity: 0.85;
}
.pp-device {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 11px 13px;
  margin-bottom: 8px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.09);
}
.pp-device-meta {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  flex: 1 1 auto;
}
.pp-device-key {
  font-family: monospace;
  font-size: 12px;
  opacity: 0.65;
  word-break: break-all;
}
.pp-device-when { font-size: 11.5px; opacity: 0.5; }
.pp-device-x {
  flex: 0 0 auto;
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  color: #ff6b6b;
  background: rgba(255, 107, 107, 0.12);
  border: 1px solid rgba(255, 107, 107, 0.3);
}
.pp-device-x:disabled { opacity: 0.6; }
.pp-device-err {
  flex: 1 1 100%;
  color: #f66;
  font-size: 12.5px;
  margin-top: 6px;
}

/* The account row reads as a fact, not an offer: no red, and the key wraps
   in full rather than being shortened, because this is the value someone
   copies out to ask a question with. */
.pp-acct { background: rgba(255, 255, 255, 0.03); }
.pp-acct .pp-device-key { font-size: 11.5px; opacity: 0.8; }
.pp-acct-copy {
  color: inherit;
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.16);
}

/* ── position actions ─────────────────────────────────────────────────────
 *
 * Four buttons that all looked alike, in a row packed to its content: no two
 * cards agreed on where their actions sat, a four-button card crowded itself
 * against the edge, and the one that ENDS a position was styled exactly like
 * the one that draws a picture of it.
 *
 * The row shares its width evenly instead, so a three-button card and a
 * four-button card line up down the screen, and each button carries the
 * weight of what it does: protect, fund, end, share.
 */
/* Scoped to the position card on purpose. `.pp-posact` is overloaded in this
   stylesheet: a container here, a BUTTON in the sheet rules above (with
   .close and .go variants), and the Deposit/Withdraw row uses the container
   form too. An unscoped grid rule would have turned those buttons into
   grids. */
.pp-poscard .pp-posact {
  display: grid;
  /* Four across, one line. It went two-by-two when the labels carried icons,
     because "Adjust margin" at 12.5px plus a 14px icon needed about 110px and
     each column had 104. Without icons the same label is about 76px, so four
     fit on one line with room, and the tile loses a whole row of height —
     which is the thing actually being complained about. */
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  padding: 4px 0 12px;
  /* `.pp-posact` is styled as a BUTTON further up this file (pill border,
     999px radius, panel fill) for the activity sheet's row. The same class on
     a container meant this block wore a giant pill outline around all four
     buttons, visible on the phone as a ghost rectangle behind them. Layout
     alone did not undo it; the decoration has to be undone too. */
  border: 0;
  border-radius: 0;
  background: none;
}
/* A cross position has three of these, not four, so the row is told how many
   it is holding rather than leaving a gap where the fourth would be. */
.pp-poscard .pp-posact.pp-act3 {
  grid-template-columns: repeat(3, 1fr);
}
.pp-posbtn {
  /* Beats .pp-cancel's flex:none, which is what made the row pack. */
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Still a real target under a live position, just not a two-row block. */
  padding: 10px 4px;
  font-size: 11.5px;
  line-height: 1;
  min-width: 0;
  white-space: nowrap;
}
.pp-posbtn svg {
  flex: none;
  opacity: 0.8;
}
/* Ending a position is the only irreversible thing in the row, and the only
   red thing in it. */
.pp-danger {
  color: var(--gl-loss);
  border-color: var(--gl-loss-soft);
  background: color-mix(in srgb, var(--gl-loss) 9%, transparent);
}
.pp-danger:active {
  background: color-mix(in srgb, var(--gl-loss) 16%, transparent);
}
/* A picture to show a friend is not a trading action, and should not compete
   with three that are. */
.pp-quiet {
  color: var(--gl-market-dim);
  background: transparent;
}
.pp-quiet:active {
  background: var(--gl-panel);
}

/* The word that makes one number honest: an entry built from several fills
   is an average, and saying so is what stops three orders looking like one. */
.pp-cellnote {
  font-size: 10px;
  color: var(--gl-market-faint);
  opacity: 0.85;
  white-space: nowrap;
}

/* Narrow phones: four 1fr columns get tight, so let the labels shrink before
   the row does. */
@media (max-width: 360px) {
  .pp-posbtn { font-size: 12px; padding: 10px 6px; gap: 5px; }
}

/* ── the tile, tightened ──────────────────────────────────────────────────
 *
 * Measured against Bybit's, which the owner sent as the reference: it says
 * the same things in noticeably less height. Two changes carry most of it.
 * The name, side and leverage stop being three padded chips on one line and
 * become a name with a subtitle. And the six stats stop being two rows of
 * three: the four a position is actually read for share one row, and margin
 * and value keep their exact figures on a quiet line underneath.
 */
.pp-posid {
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  min-width: 0;
}
.pp-posid-top {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.pp-posid-sub {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 11.5px;
  line-height: 1;
}
/* The side as a word in its own colour, not a filled chip: at subtitle size
   a pill is more padding than information. */
.pp-sideword {
  font-weight: 700;
  letter-spacing: 0.01em;
}
.pp-sideword.long { color: var(--gl-live); }
.pp-sideword.short { color: var(--gl-loss); }
/* Still the edit affordance it was, just without the pill around it. */
.pp-levword {
  background: none;
  border: 0;
  padding: 0;
  font-size: 11.5px;
  color: var(--gl-market-dim);
}
.pp-levword:active { color: var(--gl-market); }

.pp-poscard .pp-posgrid {
  grid-template-columns: repeat(4, 1fr);
  gap: 0 8px;
  margin: 11px 0 0;
}
/* Margin and value, exact but quiet: they answer questions asked after the
   four above, and they do not deserve a row each. */
.pp-posmeta {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 6px;
  margin-top: 9px;
  font-size: 11px;
  color: var(--gl-market-faint);
}
.pp-posmeta b {
  font-size: 11.5px;
  color: var(--gl-market);
}
.pp-posmeta-dot { opacity: 0.5; }

/* ── switching panels ─────────────────────────────────────────────────────
 *
 * Positions, orders, history and balances used to swap by clearing the panel
 * and rebuilding it, which lands as a flicker: the old list vanishes and the
 * new one appears in the same frame with nothing connecting them. The
 * reference app moves between them like a pager, and one short slide in the
 * direction of the tap buys most of that for one class and no library.
 *
 * On the container only. Animating rows would cost a composite per row on a
 * screen that already redraws a book six times a second.
 */
@keyframes pp-slide-l {
  from { opacity: 0; transform: translateX(14px); }
  to { opacity: 1; transform: none; }
}
@keyframes pp-slide-r {
  from { opacity: 0; transform: translateX(-14px); }
  to { opacity: 1; transform: none; }
}
.pp-slide-l { animation: pp-slide-l 0.19s var(--gl-ease) both; }
.pp-slide-r { animation: pp-slide-r 0.19s var(--gl-ease) both; }

/* The underline travels with the label rather than blinking to it. */
.pp-tabs button::after {
  transition: opacity 0.16s var(--gl-ease);
}

@media (prefers-reduced-motion: reduce) {
  .pp-slide-l, .pp-slide-r { animation: none; }
}

/* ── the tile, as the reference draws it ──────────────────────────────────
 *
 * Studied frame by frame from the videos the owner sent. The differences that
 * mattered were not sizes, they were containers: the reference gives a
 * position NO card at all. No border, no fill, no radius. It is a block of
 * type on the page with a hairline under it, and that single decision is most
 * of why it reads lighter than ours did at the same information density.
 *
 * Everything else here follows from it: without a panel to sit on, the
 * buttons have to hold their own edges, so they are outlined and transparent;
 * and the labels carry the dotted underline that says "this has more behind
 * it" rather than relying on a card to group them.
 */
.pp-poscard {
  background: none;
  border: 0;
  border-radius: 0;
  border-bottom: 1px solid var(--gl-edge-soft);
  margin: 0;
  padding: 15px 14px 14px;
}
.pp-poscard:last-child { border-bottom: 0; }

/* P&L: a named fact on one line, not a number with a percentage under it. */
.pp-pospnl {
  align-items: flex-end;
  gap: 4px;
}
.pp-pospnl-k {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--gl-market-faint);
  letter-spacing: 0.01em;
}
.pp-pospnl b { font-size: 16px; letter-spacing: -0.01em; }
/* The percentage rode in its own element before; nothing else needs it. */
.pp-pospnl > span:not(.pp-pospnl-k) { display: none; }

/* Labels that admit there is more behind them. */
.pp-poscard .pp-poscell > span:first-child {
  border-bottom: 1px dotted var(--gl-edge);
  padding-bottom: 1px;
  align-self: flex-start;
}
/* The number that decides whether you still own this position sits at the
   right edge, where the reference puts it. */
.pp-cell-end { align-items: flex-end; text-align: right; }
.pp-cell-end > span:first-child { align-self: flex-end; }

/* Outlined, transparent, evenly spaced: without a card behind them these
   have to describe their own shape. */
.pp-poscard .pp-posbtn {
  background: none;
  border: 1px solid var(--gl-edge);
  color: var(--gl-market);
  padding: 11px 4px;
  border-radius: 999px;
}
.pp-poscard .pp-posbtn:active { background: var(--gl-panel); }
.pp-poscard .pp-posact { padding: 13px 0 0; gap: 9px; }

/* Tighter vertical rhythm, measured against the reference frames: the block
   from the stats to the buttons was carrying about 20px more air than theirs,
   which is the last thing making ours look the taller of the two. */
.pp-poscard .pp-posgrid { margin: 12px 0 0; }
.pp-poscard .pp-posmeta { margin-top: 7px; font-size: 11px; }
.pp-poscard .pp-posact { padding: 12px 0 0; }

/* The one deliberate departure from the reference.
 *
 * Theirs draws all three actions identically. Ours has a Close that really
 * does end a position, and it is the only irreversible thing on the tile, so
 * it keeps a red label inside the same outlined shape. The specificity is
 * explicit because .pp-poscard .pp-posbtn above would otherwise win and paint
 * it the same grey as the rest — which it did, silently, until it was looked
 * at on the phone. */
.pp-poscard .pp-posbtn.pp-danger {
  color: var(--gl-loss);
  border-color: color-mix(in srgb, var(--gl-loss) 42%, transparent);
}
.pp-poscard .pp-posbtn.pp-danger:active {
  background: color-mix(in srgb, var(--gl-loss) 14%, transparent);
}

/* The share, hung off the P&L label the way the reference does. Small, quiet,
   and out of the action row where it was taking a quarter of the width to do
   something that does not touch the position. */
.pp-pnlshare {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: -2px;
  margin-left: 5px;
  padding: 2px;
  background: none;
  border: 0;
  color: var(--gl-market-faint);
  line-height: 0;
}
.pp-pnlshare svg { width: 12px; height: 12px; }
.pp-pnlshare:active { color: var(--gl-market); }

/* With three buttons instead of four, each label has room again. The padding
   goes back up because the pill no longer has to hug the words to fit. */
.pp-poscard .pp-posbtn { padding: 11px 10px; font-size: 12px; }

/* A sheet's second answer is still an answer: full width, under the primary,
   with air between them. It was a content-width pill in the bottom corner. */
.pp-sheetalt {
  display: block;
  width: 100%;
  flex: none;
  margin-top: 10px;
  padding: 13px 14px;
  text-align: center;
  font-size: 13px;
}

/* ── the Markets header ───────────────────────────────────────────────────
 *
 * It was a filled block: `background: var(--gl-deep)` on a sheet of a
 * different colour, so the search and the two chip rails sat inside a
 * visible box that stopped dead at the first market row. The box was never
 * a design decision, it was the price of `position: sticky` — a sticky
 * header needs an opaque background or the list scrolls through it — and the
 * colour picked to pay it did not match the surface it sat on.
 *
 * Now it pays that price in the surface's OWN colour, so nothing is drawn
 * that the eye can call a box, and the separation is carried by a hairline
 * that only has to exist where two things actually meet.
 */
.pp-mkthead {
  background: var(--sheet-bg, #000000);
  padding-bottom: 10px;
  margin-bottom: 0;
  border-bottom: 1px solid var(--gl-edge-soft);
}

/* Tighter, and with the two rails no longer looking like the same control.
   Category answers "which markets"; sort answers "in what order". They were
   near-identical rows of pills stacked on each other. */
.pp-mkthead .pp-search {
  height: 42px;
  margin-bottom: 10px;
  border-radius: 14px;
}
.pp-mkthead .pp-mkttabs {
  margin: 0 0 8px;
}
/* The sort rail reads as a subordinate line: smaller, lighter, and set off
   by a label rather than pretending to be a second filter. */
.pp-mkthead .pp-mktsort {
  padding: 0;
  gap: 5px;
}
.pp-mkthead .pp-mktsort button {
  font-size: 11.5px;
  padding: 5px 11px;
}

/* ── chart engine switch: Original | Trading View | Depth ───────────────────
   The venues put this on the chart's own toolbar, right-aligned away from the
   timeframes, because it changes what the chart IS rather than how it looks.
   `margin-left: auto` is what pushes it there without a wrapper — the bar is
   already a flex row.

   Themed through the app's own tokens rather than literal whites: the terminal
   ships in light mode too, and a hardcoded rgba(255,255,255,.5) label is
   invisible on a #f2f4f8 panel. Every colour below resolves through
   :root[data-theme] in styles.css, which is why the fallbacks are only there
   for the case where this sheet loads before the app's. */
.pp-modeseg {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin-left: auto;
  padding: 2px;
  border-radius: 9px;
  background: var(--gl-panel, var(--glass, rgba(255, 255, 255, 0.045)));
  border: 1px solid var(--gl-edge-soft, var(--stroke-soft, rgba(255, 255, 255, 0.07)));
  flex: none;
}
.pp-modeseg button {
  padding: 5px 10px;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--text-dim, rgba(255, 255, 255, 0.52));
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.14s, background 0.14s;
}
.pp-modeseg button:hover { color: var(--text, rgba(255, 255, 255, 0.82)); }
.pp-modeseg button.on {
  background: var(--gl-panel-2, var(--glass-2, rgba(255, 255, 255, 0.10)));
  color: var(--gl-mine, var(--ink, #fff));
}

/* Candle-only controls step aside for the other two engines: the drawing
   strip, the style picker and the indicator list all act on the candle
   renderer, so over a depth curve they are buttons that do nothing. */
.pp-tfs.pp-nocandle .pp-style,
.pp-tfs.pp-nocandle .pp-pencil,
.pp-tfs.pp-nocandle .pp-ind,
.pp-tfs.pp-nocandle .pp-drawsheet,
.pp-tfs.pp-nocandle .pp-tfrail,
.pp-tfs.pp-nocandle .pp-more { display: none; }

/* ── the book column's lower half: Trades / Top Movers ──────────────────────
   Hidden by default. A phone shows one panel at a time through the Book/Trades
   tabs above; this stacked pair is a desktop affordance and desktop.css is
   where it is revealed, inside the min-width query the guard enforces. */
.pp-lower { display: none; }
.pp-lowertabs { display: flex; gap: 2px; }
.pp-lowertabs button {
  flex: 1; padding: 7px 8px; border: 0; background: none;
  color: var(--text-dim, rgba(255, 255, 255, 0.48));
  font-size: 11.5px; font-weight: 700;
  cursor: pointer; border-bottom: 1.5px solid transparent; transition: color .14s;
}
.pp-lowertabs button:hover { color: var(--text, rgba(255, 255, 255, 0.78)); }
.pp-lowertabs button.on {
  color: var(--gl-mine, var(--ink, #fff));
  border-bottom-color: var(--gl-mine, var(--ink, #fff));
}

.pp-lowertape { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }

/* Top movers */
.pp-movers { flex-direction: column; min-height: 0; overflow: hidden; }
.pp-mv-chips { display: flex; gap: 4px; padding: 6px 6px 4px; }
.pp-mv-chips button {
  padding: 3px 9px; border-radius: 999px;
  border: 1px solid var(--gl-edge-soft, var(--stroke-soft, rgba(255, 255, 255, 0.08)));
  background: var(--gl-panel, var(--glass, rgba(255, 255, 255, 0.035)));
  color: var(--text-dim, rgba(255, 255, 255, 0.55));
  font-size: 10.5px; font-weight: 700; cursor: pointer; white-space: nowrap;
  transition: color .14s, background .14s, border-color .14s;
}
.pp-mv-chips button:hover { color: var(--text, rgba(255, 255, 255, 0.85)); }
.pp-mv-chips button.on {
  background: var(--gl-panel-2, var(--glass-2, rgba(255, 255, 255, 0.12)));
  color: var(--gl-mine, var(--ink, #fff));
  border-color: var(--gl-edge, var(--stroke, rgba(255, 255, 255, 0.16)));
}
.pp-mv-head, .pp-mv-row {
  display: grid; grid-template-columns: 1fr 1fr 62px; align-items: center; gap: 6px;
}
.pp-mv-head {
  padding: 4px 8px; font-size: 9.5px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-faint, rgba(255, 255, 255, 0.32));
}
.pp-mv-head span:nth-child(2), .pp-mv-row .pp-mv-px { text-align: right; }
.pp-mv-head span:nth-child(3), .pp-mv-row .pp-mv-chg { text-align: right; }
.pp-mv-body { flex: 1 1 0; min-height: 0; overflow-y: auto; }
.pp-mv-row {
  width: 100%; padding: 5px 8px; border: 0; background: none; cursor: pointer;
  font-size: 11.5px; text-align: left; transition: background .12s;
}
.pp-mv-row:hover { background: var(--gl-panel, var(--glass, rgba(255, 255, 255, 0.05))); }
.pp-mv-row.on { background: var(--gl-panel-2, var(--glass-2, rgba(255, 255, 255, 0.08))); }
.pp-mv-sym { color: var(--gl-mine, var(--ink, rgba(255, 255, 255, 0.92))); font-weight: 700; }
.pp-mv-px { color: var(--text-dim, rgba(255, 255, 255, 0.62)); }
.pp-mv-chg { font-weight: 700; }
.pp-mv-chg.up { color: var(--gl-bid, var(--success, #2ed18a)); }
.pp-mv-chg.dn { color: var(--gl-ask, var(--red, #ff5c7a)); }
.pp-mv-empty {
  padding: 18px 8px; text-align: center; font-size: 11.5px;
  color: var(--text-faint, rgba(255, 255, 255, 0.32));
}

/* ── Waiting for a number, and waiting for an account ─────────────────────── */

/*
 * The Available slot before the venue has answered.
 *
 * It used to read "checking…". Three problems with a word there: it is a
 * different width from the figure that replaces it, so the row twitches when
 * the balance lands; on a book where two sources have to agree it can sit for
 * the best part of half a minute, which reads as stuck rather than working; and
 * it asks the reader to parse a state where they were looking for a number.
 *
 * A bar the size of the number says the same thing without words, and holds the
 * space so nothing moves when the figure arrives.
 */
.pp-num.pp-wait {
  display: inline-block;
  min-width: 58px;
  height: 0.82em;
  vertical-align: -0.04em;
  border-radius: 4px;
  color: transparent;
  background-image: linear-gradient(
    90deg,
    rgba(220, 228, 242, 0.05) 0%,
    rgba(220, 228, 242, 0.17) 45%,
    rgba(220, 228, 242, 0.05) 90%
  );
  background-size: 260% 100%;
  animation: pp-wait-sweep 1.6s ease-in-out infinite;
}
@keyframes pp-wait-sweep {
  from { background-position: 130% 0; }
  to { background-position: -30% 0; }
}
/* Matching the file's other three: a sweep behind a number is decoration, and
   decoration is the first thing to drop when someone has asked for less. */
@media (prefers-reduced-motion: reduce) {
  .pp-num.pp-wait {
    animation: none;
    background-image: none;
    background-color: rgba(220, 228, 242, 0.09);
  }
}

/*
 * No trading account yet, where Long and Short would be.
 *
 * Those two buttons could not do anything without a key, and tapping one
 * answered with a toast, an error for a state that was knowable before the
 * tap. Offering the action instead is both shorter and honest: one control,
 * the same pill and the same footprint, so the panel does not resize when an
 * account appears.
 *
 * Deliberately neither green nor red. It is not a direction, and borrowing
 * either colour would make the first thing a new reader sees look like a side.
 */
.pp-setup {
  border: 0;
  border-radius: 999px;
  padding: 14px 0 13px;
  width: 100%;
  font-family: var(--font, Inter, sans-serif);
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0.1px;
  cursor: pointer;
  color: #0a0d11;
  background: linear-gradient(180deg, #e8eefb 0%, #c8d4e8 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
}
.pp-setup:active { transform: translateY(1px); }
.pp-setup-hint {
  display: block;
  margin: 8px 2px 0;
  text-align: center;
  font-size: 11.5px;
  line-height: 1.45;
  color: rgba(220, 228, 242, 0.55);
}

/* ── the crosshair readout ────────────────────────────────────────────────── */

/*
 * One cell per value: a dim label and the figure beside it. The label is what
 * makes thirteen numbers legible rather than a wall, and it is the thing the
 * old four-value version did not need.
 */
.pp-oh {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  white-space: nowrap;
}
.pp-oh i {
  font-style: normal;
  opacity: 0.55;
  font-size: 9px;
  letter-spacing: 0.02em;
}
/* The candle's own time, first and slightly brighter: it is the answer to
   "which candle am I looking at", which everything after it depends on. */
.pp-oh.time b { color: var(--gl-market-ink, #dde5f2); }
.pp-oh.up b { color: #34e8a4; }
.pp-oh.down b { color: #ff5c7a; }
/* Matched to the lines they describe, so the legend and the chart agree
   without the reader having to work out which curve is which. */
.pp-oh.ma7 b { color: #f0c46a; }
.pp-oh.ma14 b { color: #7fa7f0; }
.pp-oh.ma28 b { color: #b48ff0; }

/* ── the permanent legend ─────────────────────────────────────────────────── */

/*
 * Always on, above the plot, the way every venue chart does it. It answers
 * "where are the averages" with no gesture at all, which is the difference
 * between a chart you read and a chart you interrogate. Values follow the
 * crosshair when one is placed and sit on the newest candle when it is not.
 */
.pp-legend {
  position: absolute;
  left: 10px;
  top: 5px;
  display: grid;
  gap: 1px;
  font-size: 9.5px;
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
}
.pp-lgrow {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.pp-lg {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  white-space: nowrap;
}
.pp-lg i {
  font-style: normal;
  opacity: 0.5;
  font-size: 9px;
}
/* Each value wears its own line's colour, so the legend and the chart agree
   without the reader matching them up by hand. */
.pp-lg b { color: var(--gl-market-dim); font-weight: 700; }
.pp-lg.ma7 b { color: #f0c46a; }
.pp-lg.ma14 b { color: #7fa7f0; }
.pp-lg.ma28 b { color: #b48ff0; }
.pp-lg.boll b { color: rgba(127, 167, 240, 0.85); }

/* ── the crosshair card ───────────────────────────────────────────────────── */

.pp-ohrow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
}
.pp-ohrow i {
  font-style: normal;
  opacity: 0.55;
  font-size: 9.5px;
}
.pp-ohrow b { font-weight: 700; }
.pp-ohrow.up b { color: #34e8a4; }
.pp-ohrow.down b { color: #ff5c7a; }

/* ── an order that will open rather than close ────────────────────────────── */

/*
 * A resting trigger with no reduce-only flag starts a new leveraged position
 * when it fires. It reads like an ordinary stop until it does, so the list has
 * to say which is which before it is too late to matter.
 */
.pp-ordwarn {
  display: grid;
  gap: 3px;
  margin: 0 0 8px;
  padding: 9px 11px;
  border-radius: 10px;
  border: 1px solid rgba(255, 92, 122, 0.35);
  background: rgba(255, 92, 122, 0.08);
}
.pp-ordwarn b { color: #ff5c7a; font-size: 12.5px; }
.pp-ordwarn span { color: var(--gl-market-dim); font-size: 11px; line-height: 1.45; }
.pp-pos.pp-pos-warn { border-left: 2px solid rgba(255, 92, 122, 0.6); padding-left: 8px; }
.pp-pos-opens {
  display: block;
  margin-top: 1px;
  font-size: 10.5px;
  font-weight: 700;
  color: #ff5c7a;
}
