/* Overview screen (#view-dashboard).

   One hero (net worth, its change and its chart), smaller cards beside it, problems as
   single lines above it, and the review queue below. Desktop puts the hero and a side
   column of cards next to each other; a phone stacks them under a large-title header,
   with the two small figures side by side. */

/* ----------------------------------------------------------------------------
   Large-title header: phones only. Wider screens have the navbar's selected tab.
   ---------------------------------------------------------------------------- */
.dash-head {
  display: none;
}

.dash-head-date {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-3);
}

.dash-head-title {
  margin: var(--space-1) 0 0;
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--ink);
}

/* ----------------------------------------------------------------------------
   Attention lines. Each problem is one compact line with its action at the end;
   several stack. Amber asks for attention; the duplicate question is neutral.
   ---------------------------------------------------------------------------- */
.dash-attention {
  display: grid;
  gap: var(--space-2);
}

.dash-attention:has(> :not([hidden])) {
  margin-bottom: var(--space-6);
}

.attn-line {
  background: var(--attn-soft);
  border: 1px solid var(--attn-line);
  border-radius: var(--radius-md);
  color: var(--ink);
}

.attn-line[hidden] {
  display: none;
}

.attn-line-info {
  background: var(--sunk);
  border-color: var(--line);
}

.attn-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.attn-list > .attn-item + .attn-item {
  border-top: 1px solid var(--attn-line);
}

.attn-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-4);
  font-size: var(--fs-body-sm);
  line-height: 1.4;
}

.attn-item .action-alert-icon {
  margin-top: 0;
  display: inline-flex;
}

.attn-text {
  flex: 1;
  min-width: 0;
  color: var(--ink);
}

.attn-text strong {
  font-weight: 600;
}

.attn-detail {
  color: var(--ink-2);
}

.attn-detail a {
  color: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  overflow-wrap: anywhere;
}

.attn-line-info .attn-text,
.attn-line-info .attn-text strong {
  color: var(--ink-2);
}

/* The action reads as a small button at the end of the line, never wrapping. */
.attn-action {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-full);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  font-size: var(--fs-meta);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.attn-action:hover {
  background: var(--sunk);
}

button.attn-action {
  font-family: inherit;
  cursor: pointer;
}

/* On a touch screen the action is a finger tall. It reaches 4px into the line's padding
   above and below, so the line stays the height it is with a mouse. */
@media (pointer: coarse) {
  .attn-action {
    min-height: 44px;
    margin-block: -4px;
  }
}

/* ----------------------------------------------------------------------------
   Layout
   ---------------------------------------------------------------------------- */
.dash-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  grid-template-areas:
    "hero side"
    "review side";
  grid-template-rows: auto 1fr;
  gap: var(--space-6);
  align-items: start;
}

.dash-hero { grid-area: hero; }
.dash-side { grid-area: side; display: grid; gap: var(--space-6); align-content: start; }
.dash-review { grid-area: review; }

.dash-cards {
  display: grid;
  gap: var(--space-6);
}

/* The cards share one frame and differ only in what they say. */

/* While there are no accounts, one card in place of the layout: a heading, a line, and
   the ways to add the first account (css/addaccount.css), in a column a reader's eye can
   take in at once, centred across a wider screen and kept at the top. */
.dash-first-run {
  max-width: 40rem;
  margin: 0 auto;
}

.dash-first-run-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-title);
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.dash-first-run-text {
  margin: var(--space-2) 0 var(--space-4);
  font-size: var(--fs-body-sm);
  color: var(--ink-2);
}

@media (max-width: 768px) {
  .dash-first-run {
    padding: var(--space-4);
  }
}
.dash-layout .card {
  margin: 0;
}

.dash-label {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-3);
}

/* A figure counting up gains digits as it goes; one line, always, so the card never
   changes height mid-count. */
.metric-value {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-figure);
  white-space: nowrap;
  line-height: 1.1;
}

/* ----------------------------------------------------------------------------
   Hero: the one large figure.
   ---------------------------------------------------------------------------- */
.dash-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "figure range"
    "chart chart";
  gap: var(--space-4) var(--space-6);
  padding: var(--space-6) var(--space-8) var(--space-4);
}

.dash-hero-figure { grid-area: figure; min-width: 0; }
.dash-range { grid-area: range; align-self: start; }
/* Not positioned: the readout is placed within the whole hero card (a .card is), so on
   a phone's short chart it still has room to sit above the finger. */
.dash-chart { grid-area: chart; min-width: 0; }

.dash-hero-value {
  margin-top: var(--space-2);
  font-size: var(--fs-hero);
}

/* Net worth's figure is a link to Accounts, as wide as the figure, so the room beside it
   is not one. The figure is fitted to the column it may take (fitFigure). */
.dash-figure-link {
  display: block;
  width: fit-content;
  max-width: 100%;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}

.dash-figure-link:hover .dash-hero-value {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 0.12em;
}

/* On a touch screen the link also takes in the gaps above and below the figure, so a
   figure fitted down to a smaller size is still a finger tall. flow-root keeps the
   figure's top margin inside the link; the negative margin gives the gap below back, so
   nothing around it moves. */
@media (pointer: coarse) {
  .dash-figure-link {
    display: flow-root;
    padding-bottom: var(--space-2);
    margin-bottom: calc(-1 * var(--space-2));
  }
}

.dash-hero-meta {
  margin: var(--space-2) 0 0;
  display: grid;
  justify-items: start;
  gap: var(--space-1);
  font-size: var(--fs-body-sm);
}

/* Holds only the line on other currencies and what it opens on; with none, it takes no
   space. */
.dash-hero-meta:not(:has(> :not([hidden]))) {
  display: none;
}

/* The change over a day, a month and a year: one row of plain text, not pills,
   each a small label and a figure. A gain is in the accent, a fall in ink-2 with its
   arrow, since a fall is not a fault; a period the history doesn't reach yet is ink-3. */
.dash-nw-changes {
  margin: var(--space-2) 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-4);
  font-size: var(--fs-body-sm);
  font-variant-numeric: tabular-nums;
}

.dash-nw-changes[hidden] {
  display: none;
}

/* With their amounts the three periods need about 30rem side by side. Where the figure's
   column is narrower (a phone, or the hero beside the side cards) they stand one to a
   line, so the row's height never hangs on how long the amounts are; the skeleton below
   takes the same three lines. */
.dash-hero-figure {
  container: nw-figure / inline-size;
}

@container nw-figure (max-width: 30rem) {
  .dash-nw-changes {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }
}

.nw-change {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  white-space: nowrap;
}

.nw-change-period {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-3);
}

.nw-change-value {
  font-weight: 600;
}

.nw-change-arrow {
  margin-right: 3px;
  font-size: 0.8em;
}

/* Net worth's change as a percentage, quieter than the amount it follows. */
.nw-change-pct {
  font-weight: 400;
  color: var(--ink-3);
}

.delta-positive { color: var(--accent); }
.delta-negative { color: var(--ink-2); }
.delta-flat { color: var(--ink-2); }
.delta-none { color: var(--ink-3); font-weight: 400; }

.dash-hero-other {
  margin: 0;
  color: var(--ink-2);
}

/* The line on other currencies, drawn as the folds on Accounts are: quiet text and a
   chevron that turns over when it is open. */
.dash-other-fold {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--font-text);
  font-size: var(--fs-meta);
  color: var(--ink-3);
  text-align: left;
  cursor: pointer;
}

.dash-other-fold[hidden] {
  display: none;
}

.dash-other-fold-chevron {
  flex: none;
  transition: transform var(--dur) var(--ease-out);
}

.dash-other-fold[aria-expanded="true"] .dash-other-fold-chevron {
  transform: rotate(180deg);
}

@media (pointer: coarse) {
  .dash-other-fold {
    min-height: 44px;
  }
}

/* The range control: a segmented control on the sunk fill, the chosen period raised. */
.dash-range {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: var(--sunk);
  border-radius: var(--radius-full);
}

.dash-range-btn {
  min-width: 44px;
  min-height: 36px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--ink-2);
  font: 600 var(--fs-meta) / 1 var(--font-text);
  cursor: pointer;
}

.dash-range-btn:hover {
  color: var(--ink);
}

/* The chosen period in ink, like the selected tab and theme: a raised surface on the
   sunk track all but vanishes in dark mode. */
.dash-range-btn[aria-pressed="true"] {
  background: var(--ink);
  color: var(--text-on-accent);
}

.dash-range-btn:focus-visible {
  outline-offset: 0;
}

.chart-svg {
  width: 100%;
  height: 260px;
  overflow: visible;
  display: block;
  /* A sideways drag scrubs across the days; a vertical one still scrolls the page. */
  touch-action: pan-y;
}

/* A period picked but not drawn yet: the line on screen is the old one, so it dims. */
#dash-chart-svg {
  transition: opacity var(--dur) ease-out;
}

.dash-chart.is-loading #dash-chart-svg {
  opacity: 0.4;
}

/* The chart takes focus to be read from the keyboard; its ring sits just outside the
   drawing so it doesn't cut through the line. */
/* A drawn chart opens the day clicked. */
#dash-chart-svg[tabindex] {
  cursor: pointer;
}

.chart-svg:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: var(--radius-sm);
}

/* ----------------------------------------------------------------------------
   Secondary cards: the same frame, a smaller figure.
   ---------------------------------------------------------------------------- */
.dash-card {
  padding: var(--space-4) var(--space-6);
}

/* Side by side on a phone, the grid stretches both small cards to the taller one. As
   columns with what follows the figure pushed to the bottom, they spend that slack
   instead of leaving it blank under the shorter one. */
.dash-cards > .dash-card {
  display: flex;
  flex-direction: column;
}

.dash-cards > .dash-card > .dash-card-value {
  margin-bottom: auto;
}

.dash-card-value {
  margin-top: var(--space-2);
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--ink-figure);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.dash-card-sub {
  margin: var(--space-1) 0 0;
  font-size: var(--fs-meta);
  color: var(--ink-2);
}

.dash-card-sub[hidden] {
  display: none;
}

/* The month-to-date spending curve: a quiet ink line that stops where the month has got
   to. It stretches to the card rather than being measured, so it needs no observer. */
.spark {
  display: block;
  width: 100%;
  height: 22px;
  margin-top: var(--space-2);
  overflow: visible;
}

.spark-empty {
  /* Nothing to draw yet. The space is held so the card's height doesn't jump once
     history arrives. */
  visibility: hidden;
}

.spark-line {
  stroke: var(--ink-3);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.spark-area {
  fill: var(--sunk);
}

.spark-dot {
  fill: var(--ink-3);
}

/* Last month to the same day, behind this month's line and fainter. */
.spark-compare {
  stroke: var(--ink-3);
  stroke-opacity: 0.4;
  stroke-width: 1.25;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The spending card opens the Spending page, and the Next 30 days card the Cash flow
   page: a link laid over the whole card, so the card is one target however it is tapped. */
.dash-spend-card,
.dash-cash-card {
  transition: border-color var(--dur) ease-out;
}

.dash-spend-card:hover,
.dash-cash-card:hover {
  border-color: var(--line-strong);
}

/* The cash card's big text is the answer in words, in the colour of what it means:
   covered, money to move, short. Words, not a figure counting up, so it may wrap onto a
   second line where the card is narrow rather than shrink to fit. */
#dash-flow-figure {
  white-space: normal;
  text-wrap: balance;
}

.dash-flow-card[data-state="covered"] .dash-card-value {
  color: var(--accent);
}

.dash-flow-card[data-state="move"] .dash-card-value {
  color: var(--attn);
}

.dash-flow-card[data-state="short"] .dash-card-value {
  color: var(--crit);
}

.dash-card-cover {
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

/* Inside the card's edge: the card clips what overflows it. */
.dash-card-cover:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.dash-card-chevron {
  width: 14px;
  height: 14px;
  margin-left: var(--space-1);
  vertical-align: -2px;
  color: var(--ink-3);
}

/* ----------------------------------------------------------------------------
   What you own and owe
   ---------------------------------------------------------------------------- */
.dash-comp {
  display: grid;
  gap: var(--space-4);
}

.dash-comp-head {
  margin: 0;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
}

.dash-comp-total {
  font-size: var(--fs-body-sm);
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.comp-bar {
  display: flex;
  gap: 2px;
  height: 10px;
  margin: var(--space-2) 0 var(--space-3);
  border-radius: var(--radius-full);
  background: var(--sunk);
  overflow: hidden;
}

/* Each segment's fraction, set by dashboard.js as --share. */
.comp-seg {
  flex: var(--share, 0) 1 0;
  min-width: 2px;
}

.comp-key {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-2);
  font-size: var(--fs-meta);
}

/* Each row is a link to its kind's section on Accounts. */
.comp-link {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--space-2);
  color: inherit;
  text-decoration: none;
}

.comp-link:hover .comp-label {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* On a touch screen each row is a finger tall, which spaces them already. */
@media (pointer: coarse) {
  .comp-key {
    gap: 0;
  }

  .comp-link {
    min-height: 44px;
  }
}

.comp-label {
  color: var(--ink-2);
  overflow-wrap: anywhere;
}

.comp-pct {
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  min-width: 2.5em;
  text-align: right;
}

.comp-amount {
  color: var(--ink);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* Tones by rank, so the largest part always takes the strongest: the accent stepping
   towards the card for what is owned, ink-3 stepping towards it for what is owed. */
.comp-tone-0 { background: var(--accent); }
.comp-tone-1 { background: color-mix(in srgb, var(--accent) 72%, var(--surface)); }
.comp-tone-2 { background: color-mix(in srgb, var(--accent) 52%, var(--surface)); }
.comp-tone-3 { background: color-mix(in srgb, var(--accent) 36%, var(--surface)); }
.comp-tone-4 { background: var(--ink-3); }
.comp-tone-5 { background: var(--line-strong); }
.comp-tone-none { background: transparent; box-shadow: inset 0 0 0 1px var(--line-strong); }

#dash-owe .comp-tone-0 { background: var(--chart-liabilities); }
#dash-owe .comp-tone-1 { background: color-mix(in srgb, var(--chart-liabilities) 55%, var(--surface)); }
#dash-owe .comp-tone-2,
#dash-owe .comp-tone-3,
#dash-owe .comp-tone-4,
#dash-owe .comp-tone-5 { background: color-mix(in srgb, var(--chart-liabilities) 30%, var(--surface)); }

/* Nothing owed: the heading's $0.00 says so, and an empty bar would only add noise. */
#dash-owe.is-empty .comp-bar,
#dash-owe.is-empty .comp-key {
  display: none;
}

/* ----------------------------------------------------------------------------
   Review: a count, a way to start, the latest few rows.
   ---------------------------------------------------------------------------- */
.dash-review {
  padding: var(--space-4) var(--space-6);
}

.dash-review-summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "label button"
    "count button"
    "age   button"
    "sub   button"
    "filed button";
  column-gap: var(--space-6);
  align-items: center;
}

.dash-review-summary .dash-label { grid-area: label; }
.dash-review-summary .dash-card-value { grid-area: count; }
.dash-review-summary .age-bar { grid-area: age; max-width: 360px; }
.dash-review-summary .dash-card-sub { grid-area: sub; }
.dash-review-summary .dash-card-sub:empty { display: none; }
/* A row of its own: with nothing to review there is no button, and placed by itself the
   line would take the button's place beside the count and leave the count a sliver. */
.dash-review-summary .dash-auto-filed { grid-area: filed; justify-self: start; }

.dash-start-review {
  grid-area: button;
  min-height: 44px;
  padding: 0 var(--space-6);
}

.dash-start-review[hidden] {
  display: none;
}

.dash-review-rows {
  margin-top: var(--space-4);
  border-top: 1px solid var(--line);
}

/* The latest rows are Review's own list rows (transactions.css). The card is their
   frame, so the list drops its own, and the rows run to the card's edges so a hovered
   row is tinted across the card's width. The lines between them stay inside the card's
   padding, in line with the ones above and below the list. */
.dash-review-list.tx-list {
  margin: 0 calc(-1 * var(--space-6));
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: transparent;
}

.dash-review-list .tx-row-main {
  padding-inline: var(--space-6);
}

.dash-review-list .tx-row + .tx-row {
  border-top: 0;
}

.dash-review-list .tx-row + .tx-row::before {
  content: "";
  position: absolute;
  top: 0;
  left: var(--space-6);
  right: var(--space-6);
  z-index: 1;
  border-top: 1px solid var(--line);
}

/* The note button stays in view, after the amount, with or without a hover: the preview
   is three rows. Opening the row is the row itself, so its separate button is left out. */
.dash-review-list .tx-row-actions {
  position: relative;
  top: auto;
  right: auto;
  display: flex;
  flex: none;
  padding-left: 0;
  transform: none;
  background: none;
}

.dash-review-list .tx-act[data-action="openTxModal"] {
  display: none;
}

@media (pointer: coarse) {
  .dash-review-list .tx-act {
    width: 44px;
    height: 44px;
  }

  .dash-range-btn {
    min-height: 44px;
  }
}

/* A row a newer transaction pushes out of the preview fades, then its space closes
   (dashboard.js removes it at once under reduced motion). */
.dash-review-list .tx-row.is-dropping {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  transition: opacity var(--dur) ease-out, max-height var(--dur) var(--ease-out) 60ms;
}

/* The list runs to the card's edges, so the line takes the card's padding back. */
.dash-review-empty {
  padding: var(--space-4) var(--space-6);
  color: var(--ink-3);
  font-size: var(--fs-body-sm);
}

.dash-review-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2) var(--space-6);
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
}

.dash-review-rows.is-empty .dash-review-foot:not(:has(> :not([hidden]))) {
  display: none;
}

.dash-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--ink);
  font-size: var(--fs-body-sm);
  font-weight: 600;
  text-decoration: none;
}

.dash-link[hidden] {
  display: none;
}

.dash-link:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.dash-pending-link {
  margin-left: auto;
  font-weight: 500;
  color: var(--ink-2);
}

/* The review queue's age split, sized by share of the queue. A bar that is all ink is a
   queue you are keeping up with; the amber tail is the part that has stopped being a
   task and started being a problem. */
.age-bar {
  display: flex;
  gap: 3px;
  height: 6px;
  margin: var(--space-2) 0 var(--space-1);
}

/* Each segment's count, set by dashboard.js as --n, decides its share. */
.age-bar span {
  flex: var(--n, 1);
  border-radius: var(--radius-full);
  min-width: 3px;
}

.age-seg-fresh { background: var(--ink-3); }
.age-seg-week { background: var(--line-strong); }
.age-seg-stale { background: var(--attn); }

/* ----------------------------------------------------------------------------
   Loading: the overview's skeleton (drawDashboardSkeleton in dashboard.js). Each block
   sits in the box its figure will fill, so nothing moves when the data lands.
   ---------------------------------------------------------------------------- */
/* The chart's block takes the drawing's place, at its height (.chart-svg). */
#view-dashboard[aria-busy="true"] #dash-chart-svg {
  display: none;
}

.skel-chart {
  border-radius: var(--radius-md);
}

/* The change row's line, at the height its words will have. */
.skel-changes {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 1.4706em;
  margin: var(--space-2) 0 0;
  font-size: var(--fs-body-sm);
}

@container nw-figure (max-width: 30rem) {
  .skel-changes {
    flex-direction: column;
    align-items: flex-start;
    justify-content: space-around;
    gap: 0;
    min-height: calc(3 * 1.4706em);
  }
}

.skel-comp-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 1.4706em;
  font-size: var(--fs-meta);
}

.skel-comp-row .skel:last-child {
  margin-left: auto;
}

.skel-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
}

.skel-button {
  width: 9rem;
  border-radius: var(--radius-full);
}

.dash-review-list .skel-row {
  min-height: 60px;
  padding-inline: var(--space-6);
}

/* ----------------------------------------------------------------------------
   Narrower desktops and tablets: a slimmer side column, a shorter chart.
   ---------------------------------------------------------------------------- */
/* Below 1280 the review rows need the page's full width: Review's row keeps its note button
   in view only with that much room. The whole side column beside
   the hero would leave the hero's row as tall as the column, blank under the chart, so
   only the two small cards sit beside it, stretched to its height, and what you own and
   owe gets a row of its own after review. */
@media (min-width: 769px) and (max-width: 1279px) {
  .dash-layout {
    grid-template-areas:
      "hero cards"
      "review review"
      "comp comp";
    grid-template-rows: auto;
  }

  .dash-side {
    display: contents;
  }

  .dash-hero,
  .dash-cards {
    align-self: stretch;
  }

  /* The two figures share the hero's height. */
  .dash-cards {
    grid-area: cards;
    grid-template-rows: 1fr 1fr;
  }

  .dash-comp {
    grid-area: comp;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--space-8);
  }
}

@media (max-width: 1100px) {
  .dash-layout {
    grid-template-columns: minmax(0, 1fr) 290px;
  }

  .dash-hero {
    padding: var(--space-4) var(--space-6);
  }

  .dash-hero-value {
    font-size: 48px;
  }
}

/* A short window, an iPhone Duo open sideways at 890x626 or a laptop with its browser
   chrome: the hero and its chart shrink so the page doesn't open on two cards filling
   the screen. */
@media (max-height: 760px) and (min-width: 769px) {
  .chart-svg {
    height: 180px;
  }

  .dash-hero-value {
    font-size: 44px;
  }

  .dash-layout,
  .dash-side,
  .dash-cards {
    gap: var(--space-4);
  }

  .dash-card-value {
    font-size: 26px;
  }
}

/* ----------------------------------------------------------------------------
   Phones: a large-title header, the hero first, the two small figures side by side,
   then review, then what you own and owe.
   ---------------------------------------------------------------------------- */
@media (max-width: 768px) {
  .dash-head {
    display: block;
    margin: 0 0 var(--space-4);
  }

  .dash-attention:has(> :not([hidden])) {
    margin-bottom: var(--space-4);
  }

  .dash-layout {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
  }

  /* The Start review button is the way in on a phone; a second link to the same
     place would only add a line. */
  #dash-review-all-link {
    display: none;
  }

  /* The side column's cards join the page's own column, so review can sit between
     the small figures and the breakdown. */
  .dash-side {
    display: contents;
  }

  .dash-hero { order: 1; }
  .dash-cards { order: 2; }

  /* Side by side the two small cards are narrow enough that these lines take two, so
     two are kept for each from the skeleton on, and the summary landing after the rest
     moves nothing. */
  #dash-flow-line,
  #dash-flow-sum {
    min-height: 2lh;
  }

  /* "Cash for next 30 days" takes two lines there; the spending card's title keeps the
     same room, so the two big figures stay level. */
  .dash-cards > .dash-card > .dash-label {
    min-height: 2lh;
  }
  .dash-review { order: 3; }
  .dash-comp { order: 4; }

  .dash-hero {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "figure"
      "chart"
      "range";
    gap: var(--space-2);
    padding: var(--space-4);
  }

  .dash-range {
    justify-self: center;
  }

  .dash-hero-value {
    font-size: var(--fs-hero-sm);
  }

  .dash-hero-meta {
    font-size: var(--fs-meta);
  }

  .dash-nw-changes {
    column-gap: var(--space-3);
  }

  .chart-svg {
    height: 150px;
  }

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

  .dash-card,
  .dash-review {
    padding: var(--space-4);
  }

  .dash-card-value {
    font-size: var(--fs-title);
  }

  /* On a phone the card is the count and the button; Review is one tap away. */
  .dash-review-list {
    display: none !important;
  }

  .dash-review-rows {
    margin-top: var(--space-3);
  }

  .dash-review-foot {
    padding-top: var(--space-1);
  }

  .dash-review-rows:has(#dash-pending-link:not([hidden])) {
    border-top: 0;
  }

  .dash-review-rows:not(:has(#dash-pending-link:not([hidden]))) {
    display: none;
  }

  .dash-review-summary {
    grid-template-areas:
      "label label"
      "count button"
      "age   age"
      "sub   sub"
      "filed filed";
    column-gap: var(--space-3);
  }

  .attn-item {
    padding-left: var(--space-3);
    font-size: var(--fs-meta);
  }
}
