/* =====================================================================
 * All Accounts - the fleet cockpit (js/views/dashboard-fleet.js)
 *
 * Base rules live in components.css; this file is refinements only, same
 * convention as dashboard.css. Nothing here is loaded conditionally - the
 * classes simply do not appear in single-account mode.
 *
 * The visual argument of the view: three levels of weight, in the order the
 * screen is read.
 *   1. Attention  - the only section allowed a coloured rail and a tint.
 *   2. Pulse      - one large figure, everything else hairline-separated.
 *   3. Fleet      - a table, deliberately quiet, because a comparison is
 *                   read by scanning a column, not by looking at chrome.
 * ================================================================== */

/* A cockpit is denser than a single-account dashboard: more sections, each
   shallower. The section rhythm is tightened a step so the fold lands after
   the fleet table rather than in the middle of it. */
.view-container--fleet {
  gap: calc(var(--section-gap) * 0.8);
}

/* ---- Section wrapper (heading outside the card) ----------------------
   Attention and Accounts are SECTIONS, not cards: their heading belongs to
   the page, and what sits below it is a grid of cards or a table. Putting
   the title inside a card would make the two read as two more widgets
   rather than as the two halves of the cockpit. */

.fleet-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.fleet-section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.fleet-section__title {
  font-size: var(--fs-title3);
  letter-spacing: -0.01em;
}

.fleet-section__meta {
  font-size: var(--fs-caption);
  color: var(--color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

/* =====================================================================
 * 1. Attention
 * ================================================================== */

/* auto-fit with a MAX track, not `1fr`, and left-aligned.
   With `1fr` the cards stretched to whatever share of the row was left, so
   the same card was 282px wide when three accounts were flagged and 620px
   when one was - the least important state getting the most space. A capped
   track keeps one card size regardless of how many accounts are in trouble,
   which is what makes the section scannable. */
.attn-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(290px, 420px));
  justify-content: start;
  gap: var(--stack-gap);
}

/* A button, not a div: the whole card is one action ("open this account"),
   so it has to be reachable by keyboard and announced as such. The reset
   below undoes the UA button styling the rest of the app never needs. */
.attn-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--card-pad);
  padding-left: calc(var(--card-pad) + 4px);
  text-align: left;
  font: inherit;
  color: inherit;
  background-color: var(--color-surface);
  background-image: var(--surface-gradient);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm), inset 0 1px 0 var(--surface-highlight);
  cursor: pointer;
  overflow: hidden;
  transition: border-color var(--dur-base) var(--ease-standard),
    box-shadow var(--dur-base) var(--ease-standard),
    transform var(--dur-base) var(--ease-standard);
}

/* The rail is the severity. One 3px edge carries it, so the card body can
   stay neutral and the numbers inside keep their own profit/loss colours
   without competing with a tinted background. */
.attn-card::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--color-border-strong);
}

.attn-card--critical::before { background: var(--color-loss); }
.attn-card--warning::before { background: var(--color-warning); }
.attn-card--info::before { background: var(--color-accent); }

.attn-card:hover {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-lg), inset 0 1px 0 var(--surface-highlight);
  transform: translateY(-2px);
}

/* The orphan card is a <div>, not a button: there is no account to open, so
   it must not offer the hover/press affordances the others carry. */
.attn-card--static {
  cursor: default;
}

.attn-card--static:hover {
  transform: none;
  box-shadow: var(--shadow-sm), inset 0 1px 0 var(--surface-highlight);
  border-color: var(--color-border);
}

.attn-card--static .attn-card__cta {
  color: var(--color-text-tertiary);
}

.attn-card--static .attn-item__detail {
  overflow-wrap: anywhere;
}

.attn-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.attn-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: var(--radius-sm);
  flex: 0 0 26px;
}

.attn-card--critical .attn-card__icon {
  background: var(--color-loss-soft);
  color: var(--color-loss);
}

.attn-card--warning .attn-card__icon {
  background: var(--color-warning-soft);
  color: var(--color-warning);
}

.attn-card--info .attn-card__icon {
  background: var(--color-accent-soft);
  color: var(--color-accent);
}

.attn-card__name {
  font-size: var(--fs-callout);
  font-weight: var(--fw-semibold);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.attn-card__ccy {
  margin-left: auto;
  font-size: var(--fs-caption);
  color: var(--color-text-tertiary);
  letter-spacing: 0.04em;
}

.attn-item__label {
  font-size: var(--fs-footnote);
  font-weight: var(--fw-semibold);
  line-height: 1.35;
}

.attn-item__detail {
  margin-top: 2px;
  font-size: var(--fs-caption);
  color: var(--color-text-secondary);
  line-height: 1.4;
  font-variant-numeric: tabular-nums;
}

.attn-item__meter {
  margin-top: var(--space-3);
  height: 6px;
}

/* Secondary items: same information, a third of the weight, so the card
   still has exactly one headline. */
.attn-card__rest {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}

.attn-item--compact .attn-item__label {
  font-size: var(--fs-caption);
  font-weight: var(--fw-medium);
  color: var(--color-text-secondary);
}

.attn-item--compact .attn-item__detail {
  font-size: var(--fs-caption);
  color: var(--color-text-tertiary);
}

.attn-card__cta {
  margin-top: auto;
  padding-top: var(--space-2);
  font-size: var(--fs-caption);
  font-weight: var(--fw-medium);
  color: var(--color-text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-standard);
}

.attn-card:hover .attn-card__cta {
  color: var(--color-accent);
}

/* Clean state. A real statement with the same visual weight as a flagged
   card, because "nothing needs you" is an answer, not an empty result. */
.attn-clear {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--card-pad);
  border-radius: var(--radius-xl);
  border: 1px solid var(--color-border);
  background: var(--color-profit-soft);
}

.attn-clear__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: 0 0 34px;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-profit);
}

.attn-clear__title {
  font-size: var(--fs-callout);
  font-weight: var(--fw-semibold);
}

.attn-clear__sub {
  margin-top: 2px;
  font-size: var(--fs-caption);
  color: var(--color-text-secondary);
  line-height: 1.45;
}

/* =====================================================================
 * 2. Pulse
 * ================================================================== */

.pulse-card {
  padding: var(--space-8);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.pulse__top {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.6fr);
  gap: var(--space-8);
  align-items: start;
}

.pulse__figure {
  margin-top: var(--space-2);
  font-size: var(--fs-hero);
  font-weight: var(--fw-bold);
  letter-spacing: -0.03em;
  line-height: 1.05;
  overflow-wrap: anywhere;
}

.pulse__delta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
  flex-wrap: wrap;
}

.pulse__delta-note {
  font-size: var(--fs-caption);
  color: var(--color-text-tertiary);
}

.pulse__note {
  margin-top: var(--space-3);
  font-size: var(--fs-caption);
  color: var(--color-text-tertiary);
  line-height: 1.45;
  max-width: 46ch;
}

.pulse__stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
}

.pulse__stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.pulse__stat-value {
  font-size: var(--fs-title2);
  font-weight: var(--fw-semibold);
  letter-spacing: -0.02em;
}

.pulse__stat-hint {
  font-size: var(--fs-caption);
  color: var(--color-text-tertiary);
  line-height: 1.35;
}

/* The money band. Present only when every visible account shares a
   currency; when they do not, the --split variant replaces it with a single
   line of wayfinding rather than a blocked figure. */
.pulse__money {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

.pulse__money--split {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.pulse__money-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.pulse__money-item--muted {
  opacity: 0.7;
}

.pulse__money-label {
  font-size: var(--fs-footnote);
  color: var(--color-text-secondary);
  font-weight: var(--fw-medium);
}

.pulse__money-value {
  font-size: var(--fs-title2);
  font-weight: var(--fw-semibold);
  letter-spacing: -0.02em;
  overflow-wrap: anywhere;
}

.pulse__money-note {
  font-size: var(--fs-caption);
  color: var(--color-text-tertiary);
  line-height: 1.45;
}

/* metric-grid is bordered by its own leading edges, so it needs the card's
   padding removed on the sides it touches. */
.pulse__detail {
  margin: 0 calc(var(--space-8) * -1) calc(var(--space-8) * -1);
  border-top: 1px solid var(--color-border);
  border-radius: 0 0 var(--radius-xl) var(--radius-xl);
  overflow: hidden;
}

@media (max-width: 1080px) {
  .pulse__top {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
  }
}

@media (max-width: 700px) {
  .pulse-card {
    padding: var(--card-pad);
    gap: var(--space-5);
  }

  .pulse__stats {
    gap: var(--space-4);
  }

  .pulse__stat-value,
  .pulse__money-value {
    font-size: var(--fs-title3);
  }

  .pulse__money {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-4);
  }

  .pulse__money-item--muted {
    display: none;
  }

  .pulse__detail {
    margin: 0 calc(var(--card-pad) * -1) calc(var(--card-pad) * -1);
  }
}

/* =====================================================================
 * 3. Fleet table
 * ================================================================== */

/* The table draws its own row separators and needs to reach the card edge,
   so the card contributes the frame and nothing else. */
.card--flush {
  padding: 0;
  overflow: hidden;
}

/* Wide content scrolls inside its own container - the page body must never
   scroll horizontally (see the CLAUDE.md invariant). */
.fleet-table-wrap {
  overflow-x: auto;
  scrollbar-gutter: stable;
}

.fleet-table {
  min-width: 860px;
}

/* Column-group header. This row is the answer to "which of these numbers
   is live and which follows the period selector" - saying it is cheaper and
   more honest than forcing every column onto one basis. */
.fleet-table__grouprow th {
  padding-bottom: 0;
  border-bottom: none;
  font-size: 10px;
  letter-spacing: 0.09em;
  color: var(--color-text-tertiary);
}

.fleet-table__group {
  position: relative;
  padding-top: var(--space-4);
}

.fleet-table__group::after {
  content: "";
  position: absolute;
  left: var(--space-4);
  right: var(--space-4);
  bottom: -2px;
  height: 1px;
  background: var(--color-border);
}

.fleet-th--sortable {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-standard);
}

.fleet-th--sortable:hover {
  color: var(--color-text-secondary);
}

.fleet-th--sortable.is-active {
  color: var(--color-text-primary);
}

.fleet-th__arrow {
  margin-left: 4px;
  font-size: 9px;
}

.fleet-row {
  cursor: pointer;
}

/* A hairline on the left edge repeats the attention rail from the section
   above, so an account that was flagged there is recognisable here without
   a second badge in every row. */
.fleet-row td:first-child {
  box-shadow: inset 3px 0 0 transparent;
}

.fleet-row--critical td:first-child { box-shadow: inset 3px 0 0 var(--color-loss); }
.fleet-row--warning td:first-child { box-shadow: inset 3px 0 0 var(--color-warning); }
.fleet-row--info td:first-child { box-shadow: inset 3px 0 0 var(--color-accent); }

.fleet-cell--num {
  text-align: right;
  white-space: nowrap;
}

.fleet-cell__empty {
  font-size: var(--fs-caption);
}

.fleet-name {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

/* Same colour as this account's line in the comparison chart, assigned by
   position in the fleet - so it survives a re-sort. */
.fleet-name__dot {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  flex: 0 0 8px;
}

.fleet-name__text {
  font-weight: var(--fw-semibold);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fleet-name__flag {
  display: inline-flex;
  flex: 0 0 auto;
}

.fleet-name__flag--critical { color: var(--color-loss); }
.fleet-name__flag--warning { color: var(--color-warning); }
.fleet-name__flag--info { color: var(--color-accent); }

.fleet-name__sub {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-caption);
  color: var(--color-text-tertiary);
  font-variant-numeric: tabular-nums;
}

.fleet-open {
  margin-left: 4px;
  font-size: var(--fs-caption);
  color: var(--color-accent);
}

/* ---- Risk budget cell ---- */

.fleet-risk {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 132px;
}

.fleet-risk__row {
  display: grid;
  grid-template-columns: 12px minmax(48px, 1fr) 34px;
  align-items: center;
  gap: var(--space-2);
}

.fleet-risk__label {
  font-size: 10px;
  color: var(--color-text-tertiary);
  letter-spacing: 0.05em;
}

.fleet-risk__meter {
  height: 5px;
}

.fleet-risk__pct {
  font-size: var(--fs-caption);
  color: var(--color-text-secondary);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ---- Challenge cell ---- */

.fleet-chal {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 150px;
}

.fleet-chal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.fleet-chal__name {
  font-size: var(--fs-caption);
  font-weight: var(--fw-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fleet-chal__meta {
  font-size: var(--fs-caption);
  color: var(--color-text-tertiary);
}

.fleet-chal__meter {
  height: 4px;
  margin-top: 2px;
}

/* ---- Mobile: the table becomes one card per account -----------------
   components.css already turns .data-table into stacked cards below 700px
   using the data-label attributes the row renderer emits. Only the pieces
   that are specific to this table need adjusting - one rendering path, no
   parallel markup. */
@media (max-width: 700px) {
  .fleet-table {
    min-width: 0;
  }

  .fleet-table-wrap {
    overflow-x: visible;
  }

  .fleet-row td:first-child,
  .fleet-row--critical td:first-child,
  .fleet-row--warning td:first-child,
  .fleet-row--info td:first-child {
    box-shadow: none;
  }

  /* The severity rail moves to the card itself, where it reads the same way
     it does on an attention card. */
  .fleet-row {
    position: relative;
    padding-left: var(--space-3);
  }

  .fleet-row::before {
    content: "";
    position: absolute;
    inset: var(--space-2) auto var(--space-2) 0;
    width: 3px;
    border-radius: var(--radius-pill);
    background: transparent;
  }

  .fleet-row--critical::before { background: var(--color-loss); }
  .fleet-row--warning::before { background: var(--color-warning); }
  .fleet-row--info::before { background: var(--color-accent); }

  .fleet-risk,
  .fleet-chal {
    min-width: 0;
    width: 100%;
    max-width: 60%;
  }

  .fleet-cell--num {
    text-align: right;
  }
}

/* =====================================================================
 * 4. Chart legend
 *
 * Doubles as the ranked summary of the comparison: each entry carries the
 * account's cumulative R for the period, which is the number the chart is
 * about. Tapping one hides that line.
 * ================================================================== */

.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-4);
}

.chart-legend:empty {
  display: none;
}

.chart-legend__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 30px;
  padding: 4px var(--space-3);
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  background: none;
  font-size: var(--fs-caption);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-standard),
    opacity var(--dur-fast) var(--ease-standard),
    background-color var(--dur-fast) var(--ease-standard);
}

.chart-legend__item:hover {
  background: var(--color-surface-hover);
  border-color: var(--color-border-strong);
}

/* Hidden series stay legible - they are still a row you can bring back, not
   disabled controls. */
.chart-legend__item.is-off {
  opacity: 0.45;
}

.chart-legend__item.is-off .chart-legend__swatch {
  filter: grayscale(1);
}

.chart-legend__swatch {
  width: 9px;
  height: 9px;
  border-radius: 2px;
  flex: 0 0 9px;
}

.chart-legend__name {
  color: var(--color-text-secondary);
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chart-legend__value {
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}
