/* 看板 › PnL (views/dash/pnl.js). The cards reuse the PnL panel of charts.css (.pn-*); this file adds the page
   layout, the funds table, the daily bars and the figures. Green / red only on PnL: net / gross changes stay neutral. */

/* ---- figures */
.pnl .fig-l { font-size: var(--fs-sm); line-height: var(--lh-sm); font-weight: 500; color: var(--text-2); white-space: nowrap; }
.pnl .fig-v { font: 600 var(--fs-title1)/1.25 var(--font-display); letter-spacing: var(--track-hero); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pnl .fig-n { display: inline-block; margin: 0 -4px; padding: 0 4px; border-radius: var(--radius-xs); }
.pnl-hero .fig-v { font-size: var(--fs-large); }
/* (span.live: "live" is also a state class of the line chart's plot, which must not pick these up) */
.pnl span.live { display: inline-flex; align-items: center; gap: 5px; flex: none; font-size: var(--fs-xs); line-height: var(--lh-xs); font-weight: 600; color: var(--ok); font-variant-numeric: tabular-nums; }
.pnl span.live i { width: 6px; height: 6px; border-radius: var(--pill); background: var(--ok-fill); animation: pnl-beat 2.4s ease-out infinite; }
.pnl span.live.off { color: var(--text-3); font-weight: 500; }
.pnl span.live.off i { background: var(--text-4); animation: none; }
/* (a session that is still on but has had no snapshot for a while: the hint after its time is quieter still) */
.pnl span.live .pnl-late { font-weight: 400; }
@keyframes pnl-beat { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok-fill) 55%, transparent); } 70%, 100% { box-shadow: 0 0 0 5px transparent; } }
@media (prefers-reduced-motion: reduce) { .pnl span.live i { animation: none; } }

/* ---- layout, top to bottom: the day (.pnl-hero: the main fund's book + trading PnL and its curve), the main fund's
   trading curve beside its trades (.pnl-pair), the book card (.pnl-book: what the book PnL is made of), the funds
   table, the daily bars. The hero and the book card are as wide as the page (up to 1240px, shell.css): side by side
   the book card needs 716px for its winners and losers to sit next to each other with whole names (charts.css: 680px
   inside, plus its 18px padding on each side), which would leave the curve 508px of 1240. The trading curve sits
   beside today's trades from a page 1000px wide, with 528px for the trades, whose lists are one under the other in
   any case, and at least 456px for the curve: a 1328px window beside the 280px sidebar, so a 1366px laptop too, also
   with a scrollbar that takes room (15px); one column below, where a list 1000px wide would leave each PnL far from
   its name. By the page's own width, not the window's: pinned in a conversation's side panel the page is 347px wide
   in a window of any size (and the narrow rules at the end follow it there too). Side by side, the curve takes the
   height its neighbour gives the row (the chart measures its own box, so it simply redraws). */
.pnl { container: pnl / inline-size; }
.pnl-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: stretch; }
.pnl-grid + .pnl-grid, .pnl-grid.mt { margin-top: 16px; }
@container pnl (min-width: 1000px) {
  .pnl-grid.pnl-pair { grid-template-columns: minmax(0, 7fr) minmax(528px, 5fr); }
  .pnl-tcurve { display: flex; flex-direction: column; }
  .pnl-tcurve > .pn-chart { display: flex; flex-direction: column; flex: 1 1 0; min-height: var(--lc-h); }
  .pnl-tcurve > .pn-chart > .lc { flex: 1 1 0; height: auto; min-height: var(--lc-h); }
}
.pnl-hero-h { display: flex; align-items: center; gap: 10px; min-height: var(--ctl-h); margin-bottom: 4px; }
.pnl-hero-h h3 { margin: 0; font: 600 var(--fs-title3)/var(--lh-title3) var(--font-display); letter-spacing: var(--track-title); white-space: nowrap; }
.pnl-hero-h .card-sub { white-space: nowrap; }
.pnl-hero .pn-chart { --lc-h: 196px; margin-top: 10px; }
/* (a little taller as the card widens, so a wide curve does not flatten into a strip) */
@container pnl (min-width: 1040px) { .pnl-hero .pn-chart { --lc-h: 224px; } }
/* the main fund's trading curve: as tall as the day's (taller beside today's trades, whose lists set the row's height) */
.pnl-tcurve .pn-chart { --lc-h: 196px; margin-top: 10px; }
.pnl-tnote { margin: 10px 0 0; text-wrap: pretty; }
/* (Enfusion's figures are late, or the server cannot read them: the stamp says so in the warning colour) */
.pnl span.live.warn { color: var(--warn); font-weight: 600; }
.pnl span.live.warn i { background: var(--warn); animation: none; }
.pnl-book > .pnl-hero-h + .pn-ccys > .pn-h:first-child { margin-top: 4px; }
.pnl-book .card-sub b { font-weight: 600; }
/* the losers have a title of their own here (亏损最多): it stays when the card is too narrow for two columns, where
   charts.css drops the second column's heading (the desk's losers had none) */
.pnl-book .pn-cols > div + div > .pn-h { display: grid; margin-top: 8px; }
@media (min-width: 768px) {
  @container (min-width: 680px) { .pnl-book .pn-cols > div + div > .pn-h { margin-top: 0; } }   /* (charts.css) */
}
.pnl-trades > .pnl-hero-h + .pn-h { margin-top: 4px; }

/* the day under the curve: total, book, trading */
.pnl-sum { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-top: 14px; padding-top: 12px; border-top: var(--hair) solid var(--hairline); }
.pnl-sum > div { display: flex; flex-direction: column; min-width: 0; }
.pnl-sum .fig-l { overflow: hidden; text-overflow: ellipsis; }
.pnl-sum b { margin-top: 1px; font: 600 var(--fs-title2)/var(--lh-title2) var(--font-display); letter-spacing: var(--track-title); white-space: nowrap; }
.pnl-sum small { font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--text-3); white-space: nowrap; }

.pnl-ls { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 10px; padding-top: 8px; border-top: var(--hair) solid var(--hairline); font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--text-2); }
.pnl-ls b { font-weight: 600; }
.pnl-ls .muted { margin-left: auto; }

/* date navigation in the page header */
.pnl-nav { display: inline-flex; align-items: center; gap: 2px; }
.pnl-nav .icon-btn:disabled, .pnl-nav .btn:disabled { opacity: .35; pointer-events: none; }
.pnl-nav .flip { transform: scaleX(-1); }

.pnl-quiet { font-size: var(--fs-sm); line-height: var(--lh-sm); color: var(--text-3); }
.pnl-quiet.pad { padding: 2px 16px 16px; }
.pnl-book > .pnl-quiet { display: flex; align-items: center; justify-content: center; min-height: 120px; text-align: center; }
.pnl-foot { margin: 0; padding: 10px 16px 14px; font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--text-3); text-wrap: pretty; }
.card:not(.flush) > .pnl-foot { padding: 10px 0 0; }
.pnl-sk-line { margin: 12px 0; }

/* ---- the funds table */
.pnl-funds { container: pnl-funds / inline-size; --ft-side: 18px; }   /* narrow: stacked rows, see the end */
.pnl-funds .card-sub.warn { color: var(--warn); font-weight: 600; }
.pnl-ft th small { display: block; margin-top: 1px; font-size: var(--fs-xs); line-height: var(--lh-xs); font-weight: 400; color: var(--text-3); }
.pnl-ft td { vertical-align: top; }
.pnl-ft td small { display: block; margin-top: 1px; font-size: var(--fs-xs); line-height: var(--lh-xs); color: var(--text-3); white-space: nowrap; }
.pnl-ft td > b { font-weight: 600; }
.pnl-fund { font-weight: 600; color: var(--text); }
/* (the space before it is a margin: Vue drops a space at the start of an element's text) */
.pnl-ft td > small.muted { display: inline; margin: 0 0 0 5px; }
.pnl-basis { display: inline-block; margin-left: 6px; padding: 0 4px; border-radius: var(--radius-xs); background: var(--fill-2); color: var(--text-3); font-size: 10px; line-height: 15px; font-weight: 600; vertical-align: 1px; }
.pnl-ng { white-space: nowrap; color: var(--text-2); }
.pnl-ng b { font-weight: 600; color: var(--text); }
.pnl-live { color: var(--text-2); white-space: nowrap; }
.pnl-ft tr.quiet td { color: var(--text-3); }
.pnl-caret-h, .pnl-caret { width: 28px; padding-left: 0 !important; text-align: right; }
.pnl-caret .icon { color: var(--text-4); transition: transform var(--t) var(--ease); }
.pnl-ft tr:is(.open, .unfolded) .pnl-caret .icon { transform: rotate(90deg); color: var(--text-3); }
/* the other funds (separately managed accounts): one row with their sum and names, which unfolds them; unfolded, each
   is set in under it */
.pnl-ft tr.pnl-group .pnl-fund { color: var(--text-2); }
.pnl-ft td.pnl-group-note { max-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--text-3); font-size: var(--fs-sm); }
@container pnl-funds (min-width: 640px) {
  .card.flush .table.pnl-ft tr.sma > td.ft-fund { padding-left: calc(var(--ft-side) + 14px); }
  .pnl-ft tr.pnl-sub.sma .pnl-sub-c { padding-left: 28px; }
}
.pnl-ft tr.open td { border-bottom-color: transparent; }
/* a fund by currency: rows of the same table (so its columns line up), on a sunken band */
.pnl-ft tr.pnl-sub td { padding-top: 5px; padding-bottom: 5px; border-bottom-color: transparent; background: var(--bg-sunken); font-size: var(--fs-md); line-height: var(--lh-md); }
.pnl-ft tr.open + tr.pnl-sub td { padding-top: 8px; }
.pnl-ft tr.pnl-sub.end td { padding-bottom: 10px; border-bottom-color: var(--hairline); }
.pnl-ft tbody tr.pnl-sub:hover { background: none; }
.pnl-sub-c { padding-left: 14px; font-weight: 600; color: var(--text-2); }
.pnl-ft td.pnl-sub-note { white-space: normal; padding-left: 32px; color: var(--text-3); font-size: var(--fs-sm); line-height: var(--lh-sm); }
.ft-ph { display: none; }   /* phone only: "笔" between the trade count and the amount */

/* today's trades: buy / sell mark before the name */
.pnl-side { display: inline-block; width: 16px; height: 16px; margin-right: 6px; border-radius: var(--radius-xs); font: 600 10px/16px var(--font); font-style: normal; text-align: center; letter-spacing: 0; text-indent: 0; vertical-align: 1px; }
/* (a name on more than one line goes on under its first letter, not under the mark: a hanging indent as wide as the
   mark and its margin) */
.pnl-trades .pn-pos > .ellipsis { padding-left: 22px; text-indent: -22px; }
.pnl-side.b { background: var(--info-soft); color: var(--link); }
.pnl-side.s { background: var(--fill-2); color: var(--text-2); }

/* ---- daily bars */
.db-plot { height: 124px; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.db-plot svg { display: block; overflow: visible; }
.db-bar { transition: opacity var(--t-fast); }
.db-bar.pos { fill: var(--pos-line); }
.db-bar.neg { fill: var(--neg-line); }
.db-bar.flat { fill: var(--chart-neutral); }
/* (.scrub: the pointer is on a day — not over the empty stretch before a short history, which opens nothing) */
.db-plot.scrub { cursor: pointer; }
@media (hover: hover) { .db-plot.scrub .db-bar:not(.on) { opacity: .4; } }
.db-bar.sel { stroke: var(--text); stroke-width: 1; paint-order: stroke; }
.db-zero { stroke: var(--chart-baseline); stroke-width: 1; shape-rendering: crispEdges; }
.db-lab { font-size: var(--fs-xs); fill: var(--text-3); font-variant-numeric: tabular-nums; }
.db-read { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; min-height: var(--lh-md); margin-top: 8px; font-size: var(--fs-md); line-height: var(--lh-md); color: var(--text-2); }
.db-read b { font-weight: 600; }
.db-read .muted { font-size: var(--fs-sm); }
/* no history with the book in it yet (the trader DB could not be read): the bars' place says why */
.pnl-days-none { display: flex; flex-direction: column; justify-content: center; min-height: 124px; text-align: center; text-wrap: balance; }

/* ---- narrow: a phone, or the conversation's side panel — by the page's own width (up to 479px; a tablet beside
   the sidebar gives the page 484px and more, and keeps the full sizes) */
@container pnl (max-width: 479px) {
  .pnl-hero .pn-chart, .pnl-tcurve .pn-chart { --lc-h: 168px; }
  .pnl-sum { gap: 8px; }
  .pnl-sum b { font-size: var(--fs-headline); line-height: var(--lh-headline); }
  .pnl-hero-h { flex-wrap: wrap; }
  .pnl-wide { display: none; }
}
/* the funds table's side padding follows the card's: 16px on a phone (base.css) and in a conversation's side panel
   (chat.css), 18px elsewhere */
@media (max-width: 767px) {
  .pnl-funds { --ft-side: 16px; }
}
@media (min-width: 768px) {
  .insp-body .pnl-funds { --ft-side: 16px; }
}

/* ---- the funds table in a narrow card (a phone, a tablet beside the list, the chat's side panel): seven columns do
   not fit, so each fund becomes a block: the fund and its trading PnL, its trades under the name, then net and gross
   side by side under small labels. A fund's currencies keep the same two columns. */
@container pnl-funds (max-width: 639px) {
  .pnl-funds .pnl-wide { display: none; }
  .pnl-ft thead, .pnl-ft .pnl-live { display: none; }
  .table.pnl-ft, .pnl-ft tbody { display: block; }
  .pnl-ft tr { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 14px; grid-template-areas: "fund pnl caret" "n pnl caret" "net gross ."; column-gap: 12px; padding: 11px var(--ft-side) 12px; border-bottom: var(--hair) solid var(--hairline); }
  .pnl-ft tbody tr:last-child { border-bottom-color: transparent; }
  .pnl-ft tr.open { border-bottom-color: transparent; }
  .pnl-ft tr.pnl-group { grid-template-areas: "fund pnl caret" "n pnl caret"; }
  .pnl-ft td.pnl-group-note { display: none; }
  .pnl-ft tr.sma { padding-left: calc(var(--ft-side) + 12px); }
  .card.flush .table.pnl-ft td { padding: 0; border: 0; }
  .table.pnl-ft td.ft-fund { grid-area: fund; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .table.pnl-ft td.ft-pnl { grid-area: pnl; }
  .table.pnl-ft td.ft-n { grid-area: n; text-align: left; color: var(--text-3); font-size: var(--fs-sm); line-height: var(--lh-sm); }
  .table.pnl-ft td.ft-n small { display: inline; margin: 0; font-size: inherit; line-height: inherit; }
  .pnl-ft tr.quiet .ft-n { display: none; }
  .ft-ph { display: inline; }
  .table.pnl-ft td.ft-net { grid-area: net; margin-top: 8px; text-align: left; }
  .table.pnl-ft td.ft-gross { grid-area: gross; margin-top: 8px; text-align: left; }
  .pnl-ft td[data-l]::before { content: attr(data-l); display: block; margin-bottom: 1px; color: var(--text-3); font-size: var(--fs-xs); line-height: var(--lh-xs); }
  .pnl-ft .ft-net small, .pnl-ft .ft-gross small { white-space: normal; }
  .table.pnl-ft td.pnl-caret { grid-area: caret; width: auto; }
  .pnl-ft tr.pnl-sub { grid-template-areas: "fund pnl ." "net gross ."; padding-top: 6px; padding-bottom: 6px; border-bottom-color: transparent; background: var(--bg-sunken); }
  .pnl-ft tr.pnl-sub td { background: none; }
  .pnl-ft tr.pnl-sub td:empty { display: none; }
  .table.pnl-ft tr.pnl-sub td.ft-net, .table.pnl-ft tr.pnl-sub td.ft-gross { margin-top: 1px; }
  .pnl-ft tr.open + tr.pnl-sub { padding-top: 10px; }
  .pnl-ft tr.pnl-sub.end { padding-bottom: 12px; border-bottom-color: var(--hairline); }
  .card.flush .table.pnl-ft td.pnl-sub-note { grid-column: 1 / -1; padding-left: 8px; }
  .pnl-sub-c { padding-left: 8px; }
  /* (in the side panel chat.css pads a flush card's first and last cells, for a table's columns: here the rows
     carry the side padding, and the name would sit 16px in from the card's title) */
  .insp-body .page .card.flush .table.pnl-ft td:is(:first-child, :last-child) { padding-left: 0; padding-right: 0; }
  .insp-body .page .card.flush .table.pnl-ft td.pnl-sub-note { padding-left: 8px; }
}
