/* ══════════════════════════════════════════════════════════════════════════
   PIPVANA — the app.

   The dashboard and the furniture the tool pages share, in the same language
   as the landing page: black ground, dotted field, violet and amber, panels
   with hairline borders. Laid out as a working screen rather than a page you
   read — tools first, the account under them, prices in a column beside both.

   Loaded after site.css, which holds the tokens, the buttons and the header.
   ══════════════════════════════════════════════════════════════════════════ */

/* A column the height of the window, so the footer sits at the bottom of the
   screen rather than floating with eighty pixels of dead ground beneath it.
   Short content pushes the space above the disclaimer, where it reads as room
   rather than as an unfinished page. */
.app { display: flex; flex-direction: column; min-height: 100svh; }
/* The header is STICKY, not fixed, so it already takes its own space in the
   flow — the padding that used to be here was clearing a bar that needed no
   clearing, and the two together left most of a hundred pixels of nothing
   between the header and the first word. This is breathing room and nothing
   more. */
.app-main { flex: 1; display: flex; flex-direction: column; padding-top: clamp(14px, 2vh, 22px); padding-bottom: clamp(10px, 1.4vh, 16px); }

/* Title and line on one row where there is width for it: two stacked lines
   above the tools cost forty pixels a laptop does not have to spare. */
.app-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-bottom: clamp(10px, 1.3vw, 14px);
}
.app-t { margin: 0; font-size: clamp(1.35rem, 2.2vw, 1.7rem); font-weight: 700; letter-spacing: -0.03em; }

/* Two columns across the whole width: the work on the left, the prices on the
   right at a width a list of sparklines actually needs.

   The grid takes the height left over, rather than the footer taking it. Those
   are the only two candidates on a page shorter than the screen, and giving it
   to the footer is what left a band of empty ground between the last card and
   the small print. Given to the grid, the prices column grows into it and the
   page ends where the screen does.

   Stretched rather than start-aligned for the same reason: a column that is
   only as tall as its content cannot grow into anything. */
.app-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(300px, 24vw, 380px);
  /* minmax(0, 1fr), not the default auto: an auto row is never smaller than
     its contents, so on a short window the prices panel pushed the page into
     scrolling instead of scrolling inside itself. This lets the row shrink,
     and the panel handles its own overflow. */
  grid-template-rows: minmax(0, 1fr);
  gap: clamp(14px, 1.8vw, 22px);
  align-items: stretch;
  flex: 1;
  min-height: 0;
  margin-bottom: clamp(12px, 1.6vh, 18px);
}
/* A column too, so the account panel below the tools can be told to take the
   rest of it. Otherwise the tools and the account sat at the top and the
   bottom third of this side of the screen was empty ground while the prices
   beside it ran the full height. */
.app-col { display: flex; flex-direction: column; min-width: 0; min-height: 0; }

@media (max-width: 1100px) {
  /* Stacked, there is no second column to balance against and nothing above
     the fold to protect, so everything goes back to its natural height and
     the page scrolls the way a phone expects. Two rows now, both auto — the
     single-row track above would have squeezed the first and left the second
     to fend for itself. */
  .app-grid { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto; flex: none; }
  /* Nothing to fill, so nothing stretches. The account panel's own reset is
     down beside its rules — put here it would lose to them, being earlier in
     the file at the same specificity. */
  .app-col { display: block; }
}

/* ── The balance, top right ───────────────────────────────────────────── */

.perch { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.perch-v {
  font-size: clamp(0.95rem, 1.6vw, 1.1rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  /* The same ink as the Real balance in the portfolio below it. It is the
     same money, in both modes, and two colours for one figure read as two
     figures. */
  color: var(--real);
}

.badge {
  padding: 5px 11px;
  font: inherit;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--violet-hi);
  background: var(--violet-tint);
  border: 1px solid var(--violet-edge);
  border-radius: 999px;
  cursor: pointer;
}
.badge--demo { color: var(--amber); background: var(--amber-tint); border-color: var(--amber-edge); }

/* ── Tools ────────────────────────────────────────────────────────────────
   Wide rows rather than square cards: three links do not need a grid, and a
   row gives the name, the line under it and the arrow somewhere to sit. */

/* Three across on a wide screen. Stacked, the three rows plus the account
   panel under them ran past the bottom of a laptop; across, the whole
   dashboard fits above the fold.

   Named dash-tools, not tools: the analysis page's settings panel is a
   .tools, and this grid was reaching across and forcing it into three
   columns — a class collision between two pages that share a stylesheet. */
.dash-tools { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(10px, 1.2vw, 14px); }
@media (max-width: 1000px) { .dash-tools { grid-template-columns: minmax(0, 1fr); } }

.tool {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) auto;
  align-items: center;
  gap: 3px 12px;
  padding: clamp(13px, 1.4vw, 16px);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  transition: border-color 0.16s ease, background 0.16s ease;
}
.tool:hover { background: var(--panel-2); border-color: var(--line-hi); }

.tool-icon {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  background: var(--panel-2);
  border: 1px solid var(--line-hi);
  border-radius: 11px;
}
/* Placed explicitly rather than left to auto-flow: an item with a row but no
   column gets put wherever the algorithm likes, which is how the title ended
   up above the icon instead of beside it. Icon left spanning both lines,
   arrow right spanning both, name and line between them. */
/* Aligned to the top of the name, not centred across both lines: centred,
   it reads as sitting under the title rather than beside it. */
.tool-icon { grid-column: 1; grid-row: 1 / span 2; align-self: start; margin-top: 1px; }
.tool-h { grid-column: 2; grid-row: 1; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tool-t { font-size: 1.02rem; font-weight: 650; letter-spacing: -0.02em; }
.tool-p { grid-column: 2; grid-row: 2; font-size: 0.88rem; color: var(--text-2); }
.tool-go { grid-column: 3; grid-row: 1 / span 2; align-self: center; color: var(--text-3); }
.tool:hover .tool-go { color: var(--violet-hi); }

.tag {
  padding: 3px 9px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--violet-hi);
  border: 1px solid var(--violet-edge);
  border-radius: 999px;
  white-space: nowrap;
}

/* The MetaTrader mark is a wide wordmark, not a square glyph: the icon box
   grows to fit it rather than squeezing it to 24x4. The column stays `auto`
   for that reason, and the arrow keeps its own. */
.tool--logo { grid-template-columns: auto minmax(0, 1fr) auto; }
.tool--logo .tool-icon { width: auto; min-width: 38px; padding: 0 10px; }
.tool-logo { height: 16px; width: auto; max-width: 130px; object-fit: contain; }

/* The MetaTrader wordmark ships white, which disappears on a light panel.
   Two files, one per ground; the theme picks which is painted. */
.tool-logo--ink { display: none; }
:root[data-theme="light"] .tool-logo--ink { display: block; }
:root[data-theme="light"] .tool-logo--pale { display: none; }

/* ── Account panel ────────────────────────────────────────────────────── */

/* Fills what the tools above it leave, and is a column itself so the accounts
   can take the slack while the note and the transfer link stay put at the
   foot of the card. A short portfolio then reads as a panel with room in it
   rather than as a card that stopped early. */
.acctp {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  margin-top: clamp(10px, 1.2vw, 14px);
  padding: clamp(14px, 1.5vw, 18px);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
}
.acctp[hidden] { display: none; }
.acctp-head { flex: none; display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-bottom: 11px; }
/* The accounts take the slack, which is what holds the note and the transfer
   link against the bottom of the card. A portfolio longer than the card is
   tall grows the row and scrolls the page instead — the overflow here is a
   guard against spilling out of the border, not the usual path. */
.acctp-body { flex: 1; min-height: 0; overflow-y: auto; scrollbar-width: thin; }
.acctp-k { margin: 0 0 2px; font-size: 10px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-3); }
.acctp-t { margin: 0; font-size: 0.98rem; font-weight: 650; letter-spacing: -0.02em; }
.acctp-note { margin: 0; font-size: 11.5px; line-height: 1.6; color: var(--text-3); }
.acctp-note strong { color: var(--text-2); font-weight: 600; }

/* Stacked, there is no column height to fill, so the card is as tall as what
   is in it and nothing scrolls inside anything. Down here rather than up with
   the grid's own reset: at the same specificity the rules above would win. */
@media (max-width: 1100px) {
  .acctp { display: block; flex: none; }
  .acctp-body { overflow: visible; }
}

.grp + .grp { margin-top: 10px; }
.grp-t {
  margin: 0 0 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
}

/* The Real group carries the account's own colour: a coloured pill on the
   title and the balance in the same ink, so the row that is actual money is
   the one the eye lands on. Demo stays quiet. Same in practice mode — the
   figure changes, the emphasis does not. */
.grp--real .grp-t {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 999px;
  background: var(--real-tint); color: var(--real);
}
.grp--real .grp-t::before {
  content: ""; width: 6px; height: 6px; border-radius: 999px;
  background: var(--real); box-shadow: 0 0 0 3px var(--real-tint);
}
.grp--real .acct-bal { color: var(--real); font-weight: 750; }
.accts { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.acct {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 7px 0;
  border-bottom: 1px solid var(--line);
  font-size: 12.5px;
}
.acct:last-child { border-bottom: 0; }
.acct--none, .acct--wait { display: block; color: var(--text-3); }
.acct-kind {
  padding: 2px 8px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-2);
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 6px;
}
.acct-id { color: var(--text-2); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.acct-bal { font-weight: 650; font-variant-numeric: tabular-nums; }

.sheet-who { margin: 0 0 8px; font-size: 12.5px; font-weight: 650; }
.sheet-note { margin-top: 16px; font-size: 11.5px; line-height: 1.6; color: var(--text-3); }
.sheet-note strong { color: var(--text-2); }

.btn--sm { padding: 7px 13px; font-size: 12px; border-radius: 9px; }
.btn[hidden] { display: none; }

/* The one control here that undoes something wears the colour that says so.
   The border stays quiet until hover: a permanently red outline sitting in a
   panel reads as an alert about the account rather than an action on it. */
.btn--danger { color: var(--danger); }
.btn--danger:hover { color: var(--danger); border-color: var(--danger); background: var(--danger-tint); }

/* The note and the way out of it, on one line: two stacked blocks under the
   accounts cost a row the fold does not have. */
.acctp-foot {
  flex: none;   /* holds its place at the bottom of the card */
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 16px;
  margin-top: 12px;
}

.linkout {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 13px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--violet-hi);
  border: 1px solid var(--line-hi);
  border-radius: 10px;
}
.linkout:hover { border-color: var(--violet); background: var(--violet-tint); }

/* ── Prices ───────────────────────────────────────────────────────────── */

/* A column itself, so the list below the heading can be told to take whatever
   height the panel was given. */
.markets {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;   /* so it can be shorter than its list and let it scroll */
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
}
/* ── This card is Evie's ──────────────────────────────────────────────────
   The prices panel is the one piece of furniture the two sites share
   outright: same heading, same three columns, same paddings, same sparkline
   box, same pill on the right. Only the palette is Pipvana's. Sizes below are
   the numbers from evietrader.site rather than anything derived here, so
   changing one of them there and not here is what would break the pair. */

.mk-head {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  padding: 14px 16px;
  font-size: 13px;
  font-weight: 650;
  color: var(--text);
  border-bottom: 1px solid var(--line);
}

/* A quiet pulse while prices are arriving. */
.mk-live {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--mint);
  animation: beat 2s ease-in-out infinite;
}

.mk-list {
  list-style: none;
  margin: 0;
  padding: 4px 6px 6px;
  /* Exactly the height the panel has, no more and no less. It used to be
     capped at a flat 460px, which is a guess about the screen rather than a
     measurement of it: on a laptop it was still too tall, and on a monitor the
     list scrolled inside itself while a hundred and sixty pixels of the page
     sat empty underneath. Now it is whatever is left after the heading, so ten
     markets show without scrolling wherever there is room for ten, and it
     scrolls where there is not. */
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--line-hi) transparent;
}
/* An ordinary block again, and this is not cosmetic.

   Stacked, the rail stands at its full height and has nothing to scroll inside
   itself — but `overflow-y: auto` still made it a scroll container, and
   `overscroll-behavior: contain` on a scroll container stops the gesture
   reaching the page. So a swipe that began anywhere on the card scrolled
   neither the card, which had nowhere to go, nor the page. On a phone the card
   is most of the screen, which is why the page seemed to lock near the footer.
   Both properties belong to the wide layout, where the list really does scroll
   within a fixed panel, so they are returned to their initial values here
   rather than removed above — the same thing .acctp-body does. */
@media (max-width: 1100px) {
  .mk-list { flex: none; overflow: visible; overscroll-behavior: auto; }
}
.mk {
  display: grid;
  /* Name takes the slack; the sparkline and the figure keep fixed widths so
     the percentages line up as a column down the right. */
  grid-template-columns: minmax(0, 1fr) 96px 64px;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-top: 1px solid var(--line);
}
.mk:first-child { border-top: 0; }
.mk-name { font-size: 12px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The slot holds the row's height before a price has arrived, which is what
   stops the list growing under the cursor on a refresh. Both are the size the
   sparkline is actually drawn at, so nothing is scaled. */
.mk-spark, .mk-slot { display: block; width: 96px; height: 34px; }

.mk-pct {
  padding: 4px 0;
  font-size: 11.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: center;
  border-radius: 7px;
  white-space: nowrap;
}
.mk-pct--up { color: var(--mint); background: var(--mint-tint); }
.mk-pct--down { color: var(--danger); background: var(--danger-tint); }
.mk-pct--idle { color: var(--text-3); background: var(--panel-2); }

/* ── The sheet ────────────────────────────────────────────────────────── */

.sheet {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.sheet[hidden] { display: none; }
.sheet-back { position: absolute; inset: 0; background: rgba(3, 3, 6, 0.55); }
.sheet-card {
  position: relative;
  width: 100%;
  max-width: 460px;
  max-height: 84vh;
  overflow-y: auto;
  padding: clamp(18px, 2.4vw, 26px);
  background: var(--panel);
  border: 1px solid var(--line-hi);
  border-radius: var(--r);
  transform: translateY(8px);
  opacity: 0;
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.sheet.is-in .sheet-card { transform: none; opacity: 1; }
.sheet-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-bottom: 16px; }
.sheet-t { margin: 0; font-size: 1.05rem; font-weight: 650; letter-spacing: -0.02em; }
.sheet-x {
  flex: none;
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  background: none;
  color: var(--text-2);
  border: 1px solid var(--line-hi);
  border-radius: 9px;
  cursor: pointer;
}
.sheet-foot { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); }

/* ── Flash, footer, and the simulator's door ──────────────────────────── */

/* The flash is in site.css: the landing page raises one too, and that is
   the only stylesheet it loads. */

/* Pinned to the bottom by the auto margin, and as small as a line of small
   print should be: it is a caution, not a section. */
.app-foot { margin-top: auto; padding-top: 9px; border-top: 1px solid var(--line); }
.disclaimer { margin: 0; font-size: 0.72rem; line-height: 1.5; color: var(--text-3); }

/* No affordance on the door: a dotted underline would turn a private mode
   into a thing every visitor pokes at. `cursor: text` is what the rest of a
   heading already shows, so the letter gives nothing away by looking
   selectable. */
.door { cursor: text; }

/* The field the first visit asks for. No placeholder, no label, no width worth
   noticing — it borrows the page's own panel colours so that a person who has
   opened it by accident sees a stray box rather than a prompt. */
.door-key {
  width: 6.5em;
  margin-left: 10px;
  padding: 4px 9px;
  border: 1px solid var(--line-hi);
  border-radius: 9px;
  background: var(--panel);
  color: var(--text);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 500;
  vertical-align: middle;
}
.door-key:focus { outline: none; border-color: var(--violet); }
.door-key[hidden] { display: none; }

/* The whole of the announcement: one second on the word, then gone. It fades
   in and out rather than switching, so a repeat press reads as a deliberate
   pulse instead of a flicker. Anybody not watching the word misses it, which
   is the intention. */
@keyframes door-lit {
  0%   { color: var(--text); }
  22%  { color: var(--violet-hi); }
  70%  { color: var(--violet-hi); }
  100% { color: var(--text); }
}
.app-t.lit { animation: door-lit 1s ease-in-out; }

@media (prefers-reduced-motion: reduce) {
  .app-t.lit { animation-duration: 1ms; color: var(--violet-hi); }
}

/* ── The theme button ─────────────────────────────────────────────────────
   One icon, whichever one you are not looking at: a moon while the page is
   dark, a sun while it is light. The word is there for a screen reader and
   nowhere else — the header has three controls and no room for a fourth
   label. */

.btn--icon { padding: 10px; }
.vh {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.ico-sun { display: none; }
:root[data-theme="light"] .ico-sun { display: block; }
:root[data-theme="light"] .ico-moon { display: none; }

/* ── The bar on a small screen ────────────────────────────────────────────
   A balance like "USD 1,284.55" plus a badge plus two buttons will not fit
   389px at full size: the figure wrapped onto two lines and Home ran off the
   edge. Everything shrinks together and the wordmark goes last — each part
   here answers a question somebody opened the page to ask, so nothing is
   dropped until it has to be. */

@media (max-width: 700px) {
  .top-in { gap: 8px; height: 58px; }
  .perch { gap: 6px; min-width: 0; }
  .perch-v {
    font-size: 13px;
    letter-spacing: -0.03em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .badge { padding: 4px 8px; font-size: 9.5px; letter-spacing: 0.06em; }
  .btn { padding: 9px 12px; font-size: 13px; }
  .btn--icon { padding: 9px; }
}

@media (max-width: 430px) {
  /* The mark carries the brand on its own at this width. */
  .brand span { display: none; }
}
