/* ═══════════════════════════════════════════════════════════════
   app.css — signed-in app shell + polish layer.
   Loads AFTER site.css/auth.css and only overrides inside .app-shell,
   so the marketing pages keep their own chrome untouched.
   ═══════════════════════════════════════════════════════════════ */

:root {
  --app-sidebar-w: 248px;
  --app-content-max: 1080px;
  /* Narrower rail for single-column pages — a list of label→amount rows
     stops being readable long before 1080px. */
  --app-content-narrow: 820px;
  --app-gutter: clamp(1rem, 3vw, 2rem);
}

/* ── shell frame ──────────────────────────────────────────────── */
.app-shell {
  display: flex;
  min-height: 100dvh;
  background: var(--color-surface);
}
.app-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.app-main main { flex: 1; }

/* ── sidebar ──────────────────────────────────────────────────── */
.app-sidebar {
  flex: none;
  width: var(--app-sidebar-w);
  position: sticky;
  top: 0;
  height: 100dvh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.1rem 0.85rem 0.85rem;
  background: var(--color-surface-container-lowest);
  border-right: 1px solid color-mix(in srgb, var(--color-outline-variant) 55%, transparent);
}
/* brand — now a compact, muted signature pinned to the sidebar bottom */
.side-brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.5rem;
  padding: 0.7rem 0.6rem 0.15rem;
  border-top: 1px solid color-mix(in srgb, var(--color-outline-variant) 55%, transparent);
  text-decoration: none;
  color: var(--color-on-surface-variant);
}
.side-brand .mark {
  width: 26px;
  height: 26px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dim));
  color: var(--color-on-primary);
  flex: none;
}
.side-brand .mark .material-symbols-outlined { font-size: 15px; }
.side-brand-name {
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  font-size: 0.92rem;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--color-on-surface);
}
.side-brand-name span {
  display: block;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--color-on-surface-variant);
}

/* profile block — big centered avatar + name, links to /Account */
.side-profile {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.45rem;
  padding: 1rem 0.6rem 0.7rem;
  margin-bottom: 0.5rem;
  border-radius: 0.9rem;
  text-decoration: none;
  color: var(--color-on-surface);
  transition: background 120ms ease;
}
.side-profile:hover { background: var(--color-surface-container); }
.side-avatar {
  flex: none;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dim));
  color: var(--color-on-primary);
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  font-size: 1.4rem;
  letter-spacing: 0.02em;
  box-shadow: 0 10px 22px color-mix(in srgb, var(--color-primary) 32%, transparent);
}
.side-profile-name {
  font-family: "Plus Jakarta Sans", sans-serif;
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.25;
  text-transform: capitalize;
}
.side-profile-sub { font-size: 0.72rem; font-weight: 600; color: var(--color-on-surface-variant); }
.side-badge {
  margin-top: 0.1rem;
  padding: 0.12rem 0.5rem;
  border-radius: 9999px;
  background: var(--color-secondary-container);
  color: var(--color-on-secondary-container);
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

/* clinic selector — custom dropdown (native <select> can't style its open
   list). Lives in the footer; the menu opens upward. */
.side-clinic { position: relative; margin-bottom: 0.4rem; }
.side-clinic-trigger {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.55rem 0.6rem 0.55rem 0.7rem;
  border: 1px solid color-mix(in srgb, var(--color-outline-variant) 60%, transparent);
  border-radius: 0.7rem;
  background: var(--color-surface-container);
  font-family: "Plus Jakarta Sans", sans-serif;
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--color-on-surface);
  cursor: pointer;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.side-clinic-trigger:hover { border-color: var(--color-outline); }
.side-clinic-trigger > .material-symbols-outlined:first-child {
  font-size: 18px;
  color: var(--color-primary);
  flex: none;
}
.side-clinic-current {
  flex: 1;
  min-width: 0;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.side-clinic-caret {
  font-size: 20px;
  color: var(--color-on-surface-variant);
  flex: none;
  transition: transform 150ms ease;
}
.side-clinic.open .side-clinic-caret { transform: rotate(180deg); }
.side-clinic.open .side-clinic-trigger {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 22%, transparent);
}

.side-clinic-menu {
  display: none;
  position: absolute;
  bottom: calc(100% + 0.4rem);
  left: 0;
  right: 0;
  z-index: 50;
  padding: 0.3rem;
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: 0.85rem;
  box-shadow: 0 18px 44px color-mix(in srgb, var(--color-on-surface) 22%, transparent);
  max-height: 44vh;
  overflow-y: auto;
}
.side-clinic.open .side-clinic-menu { display: block; }
.side-clinic-option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: none;
  border-radius: 0.55rem;
  background: transparent;
  font-family: "Plus Jakarta Sans", sans-serif;
  font-size: 0.86rem;
  font-weight: 600;
  text-align: left;
  color: var(--color-on-surface);
  cursor: pointer;
}
.side-clinic-option > .material-symbols-outlined:first-child {
  font-size: 18px;
  color: var(--color-on-surface-variant);
  flex: none;
}
.side-clinic-option:hover { background: var(--color-surface-container); }
.side-clinic-option.active {
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
  font-weight: 700;
}
.side-clinic-option.active > .material-symbols-outlined { color: var(--color-on-primary-container); }
.side-clinic-option-name {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.side-clinic-check { margin-left: auto; font-size: 18px; flex: none; }

.side-nav {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  flex: 1;
}
.side-eyebrow {
  margin: 0.9rem 0.6rem 0.25rem;
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-outline);
}
.side-link {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  padding: 0.58rem 0.7rem;
  border: none;
  border-radius: 0.7rem;
  background: transparent;
  font-family: "Plus Jakarta Sans", sans-serif;
  font-size: 0.9rem;
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  color: var(--color-on-surface-variant);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.side-link .material-symbols-outlined {
  font-size: 20px;
  line-height: 1;
  flex: none;
}
.side-link:hover {
  background: var(--color-surface-container);
  color: var(--color-on-surface);
}
.side-link.active {
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
  font-weight: 700;
}
.side-link.active .material-symbols-outlined {
  font-variation-settings: 'FILL' 1;
}

/* plan chip — current plan + upgrade CTA, links to /Account/Plan */
.side-plan {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  padding: 0.6rem 0.7rem;
  border-radius: 0.8rem;
  text-decoration: none;
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
  transition: filter 120ms ease;
}
.side-plan:hover { filter: brightness(0.97); }
/* Top plan: the chip is now a label, not an offer, so it gives up the
   accent fill that made it read as the one thing to click down here. */
.side-plan-max {
  background: var(--color-surface-container-low);
  color: var(--color-on-surface-variant);
}
.side-plan-max .side-plan-name { color: var(--color-on-surface); }
.side-plan-info { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; }
.side-plan-label {
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.75;
}
.side-plan-name {
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  font-size: 0.95rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.side-plan-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  flex: none;
  font-size: 0.75rem;
  font-weight: 800;
}
.side-plan-cta .material-symbols-outlined { font-size: 15px; }

.side-foot {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding-top: 0.6rem;
  border-top: 1px solid color-mix(in srgb, var(--color-outline-variant) 55%, transparent);
}
.side-foot form { margin: 0; }
.side-signout:hover { color: var(--color-error); background: color-mix(in srgb, var(--color-error) 8%, transparent); }

/* Theme picker — lives on the Account page (see theme-switcher.js). Each
   swatch previews a theme's primary color; the active one is highlighted. */
.theme-picker {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.6rem;
}
.theme-swatch {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0.85rem;
  border: 1.5px solid var(--color-outline-variant);
  border-radius: 0.8rem;
  background: var(--color-surface-container-lowest);
  font-family: "Plus Jakarta Sans", sans-serif;
  font-size: 0.9rem;
  font-weight: 700;
  text-align: left;
  color: var(--color-on-surface);
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease, transform 120ms ease;
}
.theme-swatch:hover { border-color: var(--color-outline); transform: translateY(-1px); }
.theme-swatch.active {
  border-color: var(--color-primary);
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
}
.theme-swatch-dot {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  flex: none;
  box-shadow: inset 0 0 0 2px color-mix(in srgb, white 55%, transparent),
              0 2px 6px color-mix(in srgb, black 22%, transparent);
}

/* ── mobile chrome ────────────────────────────────────────────── */
.app-mobilebar {
  display: none;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem 0.25rem;
}
.mobile-signout {
  border: none;
  background: transparent;
  cursor: pointer;
  font-family: inherit;
}
@media (max-width: 979px) {
  .app-sidebar { display: none; }
  .app-mobilebar { display: flex; }
}
@media (min-width: 980px) {
  .app-shell .app-nav { display: none; }   /* pill bar is mobile-only */
}

/* ── app footer ───────────────────────────────────────────────── */
/* Full-width band (background comes from the base footer{} rule); the
   inner rail keeps the text aligned with the page content on the left. */
.app-footer {
  width: 100%;
  margin-top: 2rem;
  padding: 0;                 /* override base footer{} padding; inner owns height */
  font-size: 0.78rem;
  color: var(--color-on-surface-variant);
}
.app-footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: var(--app-content-max);
  margin: 0;
  padding: 1rem var(--app-gutter) 1.5rem;
}
.app-footer nav { display: flex; gap: 1rem; }
.app-footer a { color: inherit; }

/* ═══ polish layer — alignment + consistency inside the shell ═══ */

/* site.css styles the marketing page footer with a BARE `footer {}` —
   background, 2.5rem padding, 5rem top margin. That selector matches any
   <footer> element, including one used semantically inside a card or a
   tile, where it renders as a pale slab of dead space rather than a
   footer rail. The app shell's own footer is `.app-footer`, a sibling of
   <main> rather than a descendant, so it keeps the base rule and only
   in-content footers are reset here.

   :where() so the selector weighs exactly (0,0,1) — the same as the bare
   `footer {}` it is overriding, which this sheet outranks by load order,
   and less than any class rule a component writes for its own footer. A
   plain `.app-shell main footer` would win against `.check-foot` and
   flatten its padding right back to zero. */
:where(.app-shell main) footer {
  margin-top: 0;
  padding: 0;
  background: none;
}

/* One content width for every section (was 880/1000 mixed), left-aligned
   to the sidebar edge instead of floating centered in the viewport. */
.app-shell .app-header-inner,
.app-shell .pay-head,
.app-shell .pay-wrap,
.app-shell .pay-sim-bar,
.app-shell .cal-wrap,
.app-shell .settings-wrap,
.app-shell main > .account-grid {
  max-width: var(--app-content-max);
  margin-left: 0;
  margin-right: auto;
  padding-left: var(--app-gutter);
  padding-right: var(--app-gutter);
}
.app-shell .pay-head { margin-top: 1.4rem; align-items: center; flex-wrap: wrap; row-gap: 0.6rem; }
.app-shell .pay-wrap { margin-top: 1.1rem; }

/* Grids nested inside a wrapper fill it (the wrapper owns the width/gutter)
   and stay left-aligned rather than re-centering at their own max-width. */
.app-shell .pay-wrap > .account-grid {
  max-width: none;
  margin-left: 0;
  margin-right: 0;
  padding-left: 0;
  padding-right: 0;
}

/* /Calendar/Day is one clinic on one day: a hero tile and a single card,
   never two columns. On the shared rail its rows ran a label and an amount
   to opposite ends of a 1015px line with nothing between them. Narrower
   rail, same left edge — so it still lines up with the header above it. */
.app-shell .day-page .pay-head,
.app-shell .day-page .pay-wrap,
.app-shell .day-page .pay-sim-bar {
  max-width: var(--app-content-narrow);
}

/* Page titles: identical scale everywhere + room for a subtitle. */
.app-shell .pay-head h1 { font-size: 1.45rem; line-height: 1.2; }
.app-shell .page-sub {
  margin: 0.15rem 0 0;
  font-size: 0.85rem;
  color: var(--color-on-surface-variant);
}

/* Dashed rows: center-align both sides, keep amounts on one line. */
.app-shell .account-card .row { align-items: center; }
.app-shell .account-card .row > span:last-child:not(.label) { flex: none; white-space: nowrap; }
/* …except a cluster of controls. The rule above exists to keep a money
   amount on one line, which is right for a figure and wrong for buttons:
   it pinned the armed delete row at 489px tall and overflowing the card.
   Needs to live here, at this specificity, because app.css loads after
   auth.css and would otherwise win. */
.app-shell .account-card .row > span.report-actions:last-child:not(.label) {
  flex: 0 1 auto;
  white-space: normal;
}
.app-shell .account-card .row .label { min-width: 0; }
.app-shell .account-card .row .label a { color: var(--color-primary); font-weight: 600; text-decoration: none; }
.app-shell .account-card .row .label a:hover { text-decoration: underline; }

/* Buttons: consistent icon sizing/alignment at every size. */
.app-shell .btn { line-height: 1.2; }
.app-shell .btn .material-symbols-outlined { font-size: 18px; line-height: 1; }
.app-shell .btn-secondary { padding: 0.6rem 1.1rem; font-size: 0.88rem; }

/* Icon glyphs never wobble the baseline inside text lines. */
.app-shell .payday-pill .material-symbols-outlined,
.app-shell .cal-footnote .material-symbols-outlined { line-height: 1; }

/* Cards: uniform corner + padding rhythm. */
.app-shell .account-card { padding: 1.35rem 1.35rem 1.5rem; }
.app-shell .account-card h2 { font-size: 1.05rem; margin-bottom: 0.65rem; }

/* Alerts sit flush with the grid, same width as cards. */
.app-shell .alert-info,
.app-shell .alert-error { margin: 0 0 1rem; }

/* Keyboard focus is always visible (theme-aware). */
.app-shell a:focus-visible,
.app-shell button:focus-visible,
.app-shell input:focus-visible,
.app-shell select:focus-visible,
.app-shell summary:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 0.4rem;
}

/* ── app header band ──────────────────────────────────────────────
   Sticky title + breadcrumb strip that frames every signed-in page.
   Sits flush-left on the same content rail as the body below it. */
.app-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: color-mix(in srgb, var(--color-surface) 86%, transparent);
  -webkit-backdrop-filter: saturate(1.6) blur(12px);
  backdrop-filter: saturate(1.6) blur(12px);
  border-bottom: 1px solid color-mix(in srgb, var(--color-outline-variant) 55%, transparent);
}
.app-header-inner {
  padding-top: 1rem;
  padding-bottom: 0.85rem;
}
.app-crumbs {
  display: flex;
  align-items: center;
  gap: 0.28rem;
  flex-wrap: wrap;
  margin-bottom: 0.3rem;
  font-family: "Plus Jakarta Sans", sans-serif;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--color-on-surface-variant);
}
.app-crumbs a { color: var(--color-on-surface-variant); text-decoration: none; transition: color 120ms ease; }
.app-crumbs a:hover { color: var(--color-primary); }
.app-crumb-sep {
  font-size: 15px;
  line-height: 1;
  color: var(--color-outline);
}
.app-crumb-current { color: var(--color-on-surface); }

/* clinic switcher living inside the breadcrumb (opens downward) */
.crumb-clinic { position: relative; display: inline-flex; }
.crumb-clinic-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.1rem 0.35rem;
  border: none;
  border-radius: 0.45rem;
  background: transparent;
  font-family: inherit;
  font-size: inherit;
  font-weight: 700;
  color: var(--color-on-surface);
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.crumb-clinic-trigger:hover { background: var(--color-surface-container); color: var(--color-primary); }
.crumb-clinic-trigger > .material-symbols-outlined:first-child { font-size: 15px; color: var(--color-primary); }
.crumb-clinic-caret { font-size: 16px; color: var(--color-on-surface-variant); transition: transform 150ms ease; }
.crumb-clinic.open .crumb-clinic-caret { transform: rotate(180deg); }
.crumb-clinic.open .crumb-clinic-trigger { background: var(--color-surface-container); }

.crumb-clinic-menu {
  display: none;
  position: absolute;
  top: calc(100% + 0.35rem);
  left: 0;
  z-index: 60;
  min-width: 190px;
  margin: 0;
  padding: 0.3rem;
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: 0.75rem;
  box-shadow: 0 16px 40px color-mix(in srgb, var(--color-on-surface) 20%, transparent);
  max-height: 50vh;
  overflow-y: auto;
}
.crumb-clinic.open .crumb-clinic-menu { display: block; }
.crumb-clinic-option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.45rem 0.6rem;
  border: none;
  border-radius: 0.5rem;
  background: transparent;
  font-family: "Plus Jakarta Sans", sans-serif;
  font-size: 0.85rem;
  font-weight: 600;
  text-align: left;
  color: var(--color-on-surface);
  cursor: pointer;
}
.crumb-clinic-option > .material-symbols-outlined:first-child { font-size: 17px; color: var(--color-on-surface-variant); flex: none; }
.crumb-clinic-option:hover { background: var(--color-surface-container); }
.crumb-clinic-option.active {
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
  font-weight: 700;
}
.crumb-clinic-option.active > .material-symbols-outlined { color: var(--color-on-primary-container); }
.crumb-clinic-option-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crumb-clinic-check { margin-left: auto; font-size: 17px; flex: none; }
.app-title {
  margin: 0;
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  font-size: clamp(1.45rem, 2.4vw, 1.9rem);
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--color-on-surface);
}
.app-subtitle {
  margin: 0.28rem 0 0;
  font-size: 0.9rem;
  color: var(--color-on-surface-variant);
}

/* Clinic (and similar) summary values wrap instead of running off the
   card — overrides the nowrap money-amount rule above for text values. */
.app-shell .account-card .row > span.clinic-summary,
.app-shell .account-card .row > span.clinic-summary:last-child {
  flex: 0 1 auto;
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: right;
}

/* ── signed-in devices (Account) ──────────────────────────────── */
.app-shell .account-card .row.device-row { align-items: center; }
.device-name {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
  color: var(--color-on-surface);
}
.device-name .material-symbols-outlined { font-size: 18px; color: var(--color-primary); flex: none; }
.device-actions { display: inline-flex; align-items: center; gap: 0.6rem; }
.device-actions form { margin: 0; }
.device-actions .btn-secondary { padding: 0.38rem 0.75rem; font-size: 0.78rem; }
.device-status {
  padding: 0.18rem 0.55rem;
  border-radius: 9999px;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}
.device-status.active { background: var(--color-primary-container); color: var(--color-on-primary-container); }
.device-status.expired { background: var(--color-secondary-container); color: var(--color-on-secondary-container); }
.device-status.revoked { background: var(--color-surface-container-high); color: var(--color-on-surface-variant); }

/* ── pay: per-day breakdown of the accruing period ────────────── */
.pay-days { display: flex; flex-direction: column; gap: 0.35rem; margin-top: 0.5rem; }
/* The list used to be a narrow right-hand column; it now sits under the
   full-width period tiles, where a single stack would run a date and an
   amount to opposite ends of a 1000px line. Two columns instead — and
   the fortnight it holds fits on one screen. */
@media (min-width: 900px) {
  .pay-days {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 1.5rem;
  }
}
.pay-day {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 0.6rem;
  border-radius: 0.75rem;
  text-decoration: none;
  color: var(--color-on-surface);
  transition: background 120ms ease;
}
.pay-day:hover { background: var(--color-surface-container); }
.pay-day-cal {
  flex: none;
  width: 44px;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0.28rem 0;
  border-radius: 0.6rem;
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
  line-height: 1.05;
}
.pay-day-dow { font-size: 0.58rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.85; }
.pay-day-num { font-family: "Manrope", sans-serif; font-weight: 800; font-size: 1.05rem; }
.pay-day-info { display: flex; flex-direction: column; min-width: 0; flex: 1; line-height: 1.25; }
.pay-day-date { font-weight: 700; font-size: 0.9rem; }
.pay-day-meta { font-size: 0.74rem; color: var(--color-on-surface-variant); }
.pay-day .money { flex: none; font-weight: 700; font-variant-numeric: tabular-nums; }
.pay-day-go { flex: none; font-size: 18px; color: var(--color-outline); }

/* ── cancel / retention page ──────────────────────────────────── */
.app-shell .cancel-wrap { max-width: 680px; }
.cancel-card { padding: 1.75rem 1.6rem 1.5rem; }
.cancel-eyebrow {
  display: block;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-primary);
}
.cancel-title {
  margin: 0.4rem 0 0.6rem;
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  font-size: clamp(1.4rem, 3vw, 1.8rem);
  letter-spacing: -0.02em;
}
.cancel-lead { margin: 0 0 1.4rem; color: var(--color-on-surface-variant); line-height: 1.55; }
.cancel-lose h3,
.cancel-alts h3 {
  margin: 0 0 0.7rem;
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-on-surface-variant);
}
.cancel-lose { padding: 1.1rem 1.15rem; border-radius: 1rem; background: var(--color-surface-container-low); margin-bottom: 1.4rem; }
.cancel-lose ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
.cancel-lose li { display: flex; align-items: center; gap: 0.6rem; font-size: 0.92rem; }
.cancel-lose li .material-symbols-outlined { font-size: 19px; color: var(--color-primary); flex: none; }
.cancel-lose .muted-note { margin-top: 0.9rem; }

.cancel-alts { margin-bottom: 1.5rem; }
.cancel-alt {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.85rem 0.95rem;
  border: 1px solid var(--color-outline-variant);
  border-radius: 0.9rem;
  text-decoration: none;
  color: var(--color-on-surface);
  transition: border-color 130ms ease, transform 130ms ease, box-shadow 130ms ease;
}
.cancel-alt + .cancel-alt { margin-top: 0.6rem; }
.cancel-alt:hover {
  border-color: var(--color-primary);
  transform: translateY(-1px);
  box-shadow: 0 10px 24px color-mix(in srgb, var(--color-on-surface) 8%, transparent);
}
.cancel-alt > .material-symbols-outlined:first-child { font-size: 24px; color: var(--color-primary); flex: none; }
.cancel-alt-text { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.cancel-alt-text strong { font-weight: 700; font-size: 0.95rem; }
.cancel-alt-text .muted-note { font-size: 0.82rem; }
.cancel-alt-go { margin-left: auto; color: var(--color-outline); flex: none; }

.cancel-actions { display: flex; flex-direction: column; align-items: center; gap: 0.35rem; }
.cancel-confirm-form { margin: 0; }
.cancel-confirm {
  border: none;
  background: transparent;
  padding: 0.5rem 0.75rem;
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-on-surface-variant);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.cancel-confirm:hover { color: var(--color-error); }

/* ── gradient money tile ──────────────────────────────────────────
   Was the dashboard hero; the dashboard now uses the money route below
   and /Calendar/Day is the only caller left (see .day-hero in
   auth.css, which extends these). Kept here rather than moved so the
   day tile and the route's final card stay visually identical. */
.dash-primary {
  position: relative;
  overflow: hidden;
  border-radius: 1.25rem;
  padding: 1.5rem 1.6rem;
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dim));
  color: var(--color-on-primary);
  box-shadow: 0 18px 44px color-mix(in srgb, var(--color-primary) 30%, transparent);
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.dash-primary::after {
  /* soft radial sheen — texture without another color */
  content: "";
  position: absolute;
  top: -60%;
  right: -20%;
  width: 70%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--color-on-primary) 18%, transparent), transparent 70%);
  pointer-events: none;
}
.dash-primary-label {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.85;
}
.dash-primary-value {
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  font-size: clamp(2rem, 4.5vw, 2.6rem);
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
}
.dash-primary-hint { font-size: 0.85rem; opacity: 0.9; }

/* ── the money route ──────────────────────────────────────────────
   Three stages, ordered by how far each dollar still has to travel:
   today → the open period → the closed period with a payday. The cards
   gain weight left to right (outline → tinted → full gradient) so the
   crescendo reads as "closer to the bank", and the connectors between
   them carry the hand-off in words. That pairing is what replaced the
   old "Accruing now" label, which named a mechanism and explained
   nothing. */
.flow {
  display: grid;
  grid-template-columns: 1fr auto 1fr auto 1fr;
  align-items: stretch;
  gap: 0.5rem;
  /* Was 0.85rem when a legend line sat underneath and carried the rest of
     the gap. The route now runs straight into the cards below it, so the
     air it needs lives here. */
  margin-bottom: 1.25rem;
}
.flow-card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 1.15rem 1.2rem 1.1rem;
  border-radius: 1.15rem;
  text-decoration: none;
  color: var(--color-on-surface);
  background: var(--color-surface-container-lowest);
  border: 1px solid color-mix(in srgb, var(--color-outline-variant) 70%, transparent);
  transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease;
  /* Staggered reveal, left to right — the route draws itself once.
     TRANSFORM ONLY, never opacity: a paused or never-started animation
     must not be able to hide a money figure. Worst case the card is
     10px low for a moment; it is never blank. */
  animation: flow-in 420ms cubic-bezier(0.22, 1, 0.36, 1) backwards;
}
/* nth-CHILD, not nth-of-type — the connectors are siblings, and counting
   by element type would hand the same delay to two cards. */
.flow > :nth-child(1) { animation-delay: 0ms; }
.flow > :nth-child(3) { animation-delay: 70ms; }
.flow > :nth-child(5) { animation-delay: 140ms; }
@keyframes flow-in {
  from { transform: translateY(10px); }
  to   { transform: none; }
}
.flow-card:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--color-primary) 45%, transparent);
  box-shadow: 0 14px 32px color-mix(in srgb, var(--color-on-surface) 10%, transparent);
  /* The card is an <a>, so site.css's a:hover recolours it — and out-
     specifies the class that set the colour, so the money figure (which
     has no colour of its own and simply inherits) changed on hover. The
     lift and the shadow are the affordance; the amount holds still. */
  color: var(--color-on-surface);
}

.flow-stage {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--color-on-surface-variant);
}
.flow-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-primary);
  flex: none;
}
.flow-value {
  margin-top: 0.35rem;
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  font-size: clamp(1.6rem, 3.1vw, 2.15rem);
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
}
.flow-value-none { color: var(--color-on-surface-variant); }
.flow-cap {
  margin-top: 0.15rem;
  font-size: 0.8rem;
  color: var(--color-on-surface-variant);
}
/* The day's shape, directly under the caption — it describes the figure
   above it, so it belongs to the figure, not to the footer. */
.flow-facts {
  margin-top: 0.35rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem 0.55rem;
  font-size: 0.78rem;
  color: var(--color-on-surface-variant);
}
/* A footer rail, pinned to the bottom of every card and separated by a
   hairline. The cards stretch to the tallest of the three, so without a
   rule the shortest one just showed a hole; with one, the same air reads
   as a footer and all three bottom lines sit on the same baseline. It
   carries ONE line — what happens next, or where this card goes. */
.flow-meta {
  margin-top: auto;
  padding-top: 0.7rem;
  border-top: 1px solid color-mix(in srgb, var(--color-outline-variant) 60%, transparent);
  /* A rail holding a pill is ~4px taller than one holding plain text, which
     is enough to knock the three hairlines out of line with each other.
     Floor them all at the pill's height so the rules read as one. */
  min-height: 2.25rem;
  box-sizing: border-box;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem 0.55rem;
  font-size: 0.78rem;
  color: var(--color-on-surface-variant);
}
/* Hairline separators between meta facts — cheaper than bullets and they
   disappear cleanly when the row wraps. */
.flow-facts > span + span:not(.flow-chip)::before,
.flow-meta > span + span:not(.flow-chip)::before {
  content: "";
  display: inline-block;
  width: 1px;
  height: 0.7em;
  margin-right: 0.55rem;
  vertical-align: -0.05em;
  background: currentColor;
  opacity: 0.35;
}
/* A pill already separates itself — a rule right after one reads as debris. */
.flow-facts > .flow-chip + span::before,
.flow-meta > .flow-chip + span::before { content: none; }
.flow-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.16rem 0.5rem;
  border-radius: 999px;
  background: var(--color-surface-container);
  font-weight: 700;
  font-size: 0.74rem;
  color: var(--color-on-surface-variant);
}
.flow-chip .material-symbols-outlined { font-size: 14px; line-height: 1; }
/* The one date on this screen that is a commitment rather than an
   estimate — it gets full ink where the facts around it stay muted. */
.flow-chip-strong { color: var(--color-on-surface); font-weight: 800; }
.flow-go {
  position: absolute;
  top: 1.05rem;
  right: 1.05rem;
  color: var(--color-outline);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 150ms ease, transform 150ms ease;
}
.flow-go .material-symbols-outlined { font-size: 18px; line-height: 1; display: block; }
.flow-card:hover .flow-go,
.flow-card:focus-visible .flow-go { opacity: 1; transform: none; }

/* Stage 1 — today. Lightest weight: this money hasn't gone anywhere yet. */
.flow-today.is-quiet .flow-value { color: var(--color-on-surface-variant); }
.flow-today.is-quiet .flow-dot { background: var(--color-outline); }

/* Stage 2 — the open period. Tinted: committed, not yet closed. */
.flow-period {
  background: var(--color-surface-container-low);
  border-color: color-mix(in srgb, var(--color-primary) 22%, transparent);
}
/* Elapsed time, not money — deliberately a different quantity from the
   figure above it, so it answers a question the total can't. */
.flow-track {
  margin-top: 0.7rem;
  height: 5px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-on-surface) 10%, transparent);
  overflow: hidden;
}
.flow-track-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--color-primary);
}

/* Stage 3 — closed and waiting on a payday. Full weight: this is real. */
.flow-mail {
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dim));
  border-color: transparent;
  color: var(--color-on-primary);
  box-shadow: 0 16px 38px color-mix(in srgb, var(--color-primary) 28%, transparent);
}
.flow-mail::after {
  /* soft radial sheen — texture without another color */
  content: "";
  position: absolute;
  top: -70%;
  right: -25%;
  width: 80%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--color-on-primary) 18%, transparent), transparent 70%);
  pointer-events: none;
}
.flow-mail > * { position: relative; z-index: 1; }
/* Colour only — the arrow keeps the shared show-on-hover opacity, which a
   rule in here would out-specify and pin permanently visible. */
.flow-mail .flow-stage,
/* 0.94, not the 0.88 the old hero used: measured against every theme's
   primary, sage and terracotta drop small text under 4.5:1 by 0.88. */
.flow-mail .flow-cap,
.flow-mail .flow-facts,
.flow-mail .flow-meta { color: var(--color-on-primary); opacity: 0.94; }
/* The footer rule has to be drawn out of the card's own ink here — the
   outline token is a light-surface grey and vanishes on the gradient. */
.flow-mail .flow-meta { border-top-color: color-mix(in srgb, var(--color-on-primary) 28%, transparent); }
/* `.flow-mail > *` above ties with .flow-go on specificity and wins on
   order, which dropped the arrow out of the corner and into the bottom of
   the column. Restated here, at two classes, so it stays pinned top-right
   like every other card's. */
.flow-mail .flow-go {
  position: absolute;
  color: var(--color-on-primary);
}
.flow-mail .flow-dot { background: var(--color-on-primary); }
.flow-mail .flow-chip {
  background: color-mix(in srgb, var(--color-on-primary) 18%, transparent);
  color: var(--color-on-primary);
}
.flow-mail:hover {
  border-color: transparent;
  box-shadow: 0 20px 46px color-mix(in srgb, var(--color-primary) 36%, transparent);
  /* Same a:hover story as the light cards, in this card's own ink — and it
     has to be restated after .flow-card:hover, which ties on specificity. */
  color: var(--color-on-primary);
}

/* The hand-off between stages, in words. */
.flow-link {
  align-self: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.1rem;
  padding: 0 0.1rem;
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-align: center;
  color: var(--color-outline);
  white-space: nowrap;
}
.flow-link .material-symbols-outlined { font-size: 20px; line-height: 1; }

/* Stacked: the route turns vertical and the connectors point down. */
@media (max-width: 900px) {
  .flow { grid-template-columns: 1fr; gap: 0.4rem; }
  .flow-link { flex-direction: row; gap: 0.4rem; padding: 0.1rem 0; }
  .flow-link .material-symbols-outlined { transform: rotate(90deg); }
  .flow-value { font-size: 1.8rem; }
}

/* ── period bar strip ─────────────────────────────────────────────
   One series, so no legend — the card heading names it. Every calendar
   day keeps its slot, so days off read as gaps instead of vanishing.
   Today is marked by an outline and a bolder tick as well as colour,
   never colour alone. */
.bars {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  min-height: 118px;
  padding-top: 0.35rem;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
}
.bar {
  flex: 1 1 0;
  min-width: 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  text-decoration: none;
  border-radius: 0.35rem;
  padding-bottom: 0.15rem;
}
.bar-col {
  width: 100%;
  height: 92px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  /* baseline the bars sit on — visible even where nothing was earned */
  box-shadow: inset 0 -1px 0 0 color-mix(in srgb, var(--color-on-surface) 16%, transparent);
}
/* Deliberately NOT animated. A grow-from-zero keyframe leaves every bar
   flat whenever the animation is paused or never starts, and a chart of
   money that renders empty is worse than one that simply appears. */
.bar-fill {
  width: 100%;
  min-height: 2px;
  border-radius: 4px 4px 0 0;
  background: var(--color-primary);
  transition: background-color 130ms ease;
}
.bar-tick {
  font-size: 0.66rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-on-surface-variant);
  opacity: 0.75;
}
/* Today's tick carries a dot. EVERY tick reserves the room for one, or
   that one bar is taller than its neighbours — and since .bars aligns to
   flex-end, a taller bar lifts its column and today's fill floats off the
   shared baseline. The dot is only painted on today. */
.bar-tick::after {
  content: "";
  display: block;
  width: 3px;
  height: 3px;
  margin: 2px auto 0;
  border-radius: 50%;
  background: transparent;
}
.bar:hover .bar-fill { background: var(--color-primary-dim); }
.bar:hover .bar-tick { opacity: 1; color: var(--color-on-surface); }

/* Days with nothing logged: baseline only, no mark to misread as small. */
.bar:not(.has-money) .bar-fill { background: transparent; }
/* Not yet arrived — dimmer tick, so the empty tail isn't read as days missed. */
.bar.is-future .bar-tick { opacity: 0.4; }

.bar.is-today .bar-col {
  border-radius: 0.4rem 0.4rem 0 0;
  background: color-mix(in srgb, var(--color-primary) 10%, transparent);
  box-shadow: inset 0 -2px 0 0 var(--color-primary);
}
.bar.is-today .bar-tick {
  opacity: 1;
  font-weight: 800;
  color: var(--color-primary);
}
.bar.is-today .bar-tick::after { background: var(--color-primary); }

/* ── the strip's hover card ───────────────────────────────────────
   Inverse ink, not another pale panel: it floats over a light card and
   has to read instantly as "on top of" rather than "part of". The
   on-surface / surface pair inverts with the theme, so this stays a
   legible overlay in every one of them.

   The wrapper exists purely to position it — .bars itself scrolls, and a
   scroll container clips both axes no matter what overflow-y says. */
.bars-wrap { position: relative; }

.bar-tip {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 20;
  /* Two panes wide rather than one pane tall: the plot band is ~118px,
     and a stacked card would have to leave the section to clear a bar. */
  display: flex;
  align-items: stretch;
  gap: 0.85rem;
  width: max-content;
  max-width: min(22rem, 100%);
  /* Kept trim on purpose: it floats over a ~118px plot, and every row of
     padding here is a row of the chart it hides. */
  padding: 0.6rem 0.8rem 0.65rem;
  border-radius: 0.9rem;
  background: var(--color-on-surface);
  color: var(--color-surface-container-lowest);
  box-shadow: 0 18px 40px color-mix(in srgb, var(--color-on-surface) 32%, transparent);
  /* Never intercepts the pointer: catching its own hover would flicker
     the card off and on as the box passes under the cursor. */
  pointer-events: none;
  opacity: 0;
  /* Rises INTO place from just under the ticks, matching the direction it
     now sits in relative to the chart. */
  transform: translateY(-4px);
  transition: opacity 130ms ease, transform 130ms ease;
}
.bar-tip.is-on { opacity: 1; transform: none; }
/* Points up at the day number it belongs to. Sits on --caret, which the
   script keeps aimed at that tick even after the box has been nudged in
   from an edge. */
.bar-tip::after {
  content: "";
  position: absolute;
  bottom: 100%;
  left: var(--caret, 50%);
  margin-left: -6px;
  border: 6px solid transparent;
  border-bottom-color: var(--color-on-surface);
}
/* The local `.bar-tip [hidden]` patch that used to live here is gone —
   site.css settles [hidden] globally now. */
.bar-tip-main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.bar-tip-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
}
.bar-tip-day {
  font-size: 0.67rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  opacity: 0.72;
}
.bar-tip-today {
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-surface-container-lowest) 22%, transparent);
  font-size: 0.56rem;
  font-weight: 800;
  letter-spacing: 0.1em;
}
.bar-tip-earned {
  margin-top: 0.2rem;
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.bar-tip-note {
  font-size: 0.72rem;
  opacity: 0.7;
}
/* Right pane: the day's facts, past a hairline. Label left, figure right,
   the same shape as the dashed rows on every card in the app. */
.bar-tip-stats {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.28rem;
  padding-left: 0.85rem;
  border-left: 1px solid color-mix(in srgb, var(--color-surface-container-lowest) 20%, transparent);
}
.bar-tip-stat {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.1rem;
}
.bar-tip-stat-label {
  font-size: 0.58rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.62;
}
.bar-tip-stat-value {
  font-size: 0.82rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* The day's weight in the period, as a line rather than a fourth figure. */
.bar-tip-share {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: auto;
  padding-top: 0.4rem;
  font-size: 0.64rem;
  white-space: nowrap;
  opacity: 0.78;
}
.bar-tip-share-track {
  width: 2.6rem;
  flex: none;
  height: 3px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-surface-container-lowest) 22%, transparent);
  overflow: hidden;
}
.bar-tip-share-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: currentColor;
}

/* Period totals — the two figures as label-over-value blocks and nothing
   else. The old single flex row also carried the pay-rule summary, which
   met the money coming the other way in the middle of the card. */
.bars-foot {
  margin-top: 0.9rem;
  padding-top: 0.85rem;
  border-top: 1px solid color-mix(in srgb, var(--color-outline-variant) 55%, transparent);
  color: var(--color-on-surface-variant);
}
.bars-figs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem 2.4rem;
}
.bars-fig {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  position: relative;
}
/* Hairline between the pair, same device as .flow-meta — it disappears on
   its own when the row wraps to two lines. */
.bars-fig + .bars-fig::before {
  content: "";
  position: absolute;
  left: -1.2rem;
  top: 0.15rem;
  bottom: 0.15rem;
  width: 1px;
  background: color-mix(in srgb, var(--color-outline-variant) 65%, transparent);
}
.bars-fig-label {
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--color-on-surface-variant);
}
.bars-fig-value {
  font-family: "Manrope", sans-serif;
  font-weight: 800;
  font-size: 1.4rem;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  color: var(--color-on-surface);
}
/* Take-home carries the bar colour, so the figure and the strip above it
   are visibly the same quantity. */
.bars-fig.is-earned .bars-fig-value { color: var(--color-primary); }
.bars-fig-note {
  margin-top: 0.1rem;
  font-size: 0.72rem;
  color: var(--color-on-surface-variant);
  font-variant-numeric: tabular-nums;
}

/* Card headings: title left, a quiet unit/count note right. */
.dash-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}
.dash-card-head h2 { margin-bottom: 0; }
.dash-card-title { display: flex; flex-direction: column; gap: 0.12rem; min-width: 0; }
/* The window the card is about, stated once under its title so the totals
   in the footer can stay bare. */
.dash-card-sub {
  margin: 0;
  font-size: 0.78rem;
  color: var(--color-on-surface-variant);
  font-variant-numeric: tabular-nums;
}
.dash-card-note {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-on-surface-variant);
  white-space: nowrap;
}
.app-shell .dash-grid .dash-card-head { margin-bottom: 0.65rem; }
/* The strip wants the full grid width; the tiles beside it don't. */
.dash-grid > .dash-span { grid-column: 1 / -1; }

@media (prefers-reduced-motion: reduce) {
  .app-shell *, .app-shell *::before, .app-shell *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}
