/* ===========================================================================
   Cratelog design-system components, ported from the React bundle
   (_ds_bundle.js) to plain CSS classes. Every value here is transcribed from
   the source component, not re-invented - if a component changes upstream,
   diff it against this file.
   =========================================================================== */

/* --- Icon (components/core/Icon.jsx) --------------------------------------
   Phosphor icon drawn as a CSS mask over `currentColor`, so it inherits text
   colour and theme automatically - an icon can never end up black on a dark
   surface. The SVGs are vendored under assets/icons/ so the page has no
   third-party runtime dependency. */
.icon {
  display: inline-block;
  width: var(--icon-size, 20px);
  height: var(--icon-size, 20px);
  flex: none;
  background: currentColor;
  -webkit-mask-image: var(--icon);
  mask-image: var(--icon);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}

.i-alarm          { --icon: url("../assets/icons/regular/alarm.svg"); }
.i-arrow-right    { --icon: url("../assets/icons/regular/arrow-right.svg"); }
.i-battery-full   { --icon: url("../assets/icons/regular/battery-full.svg"); }
.i-bell           { --icon: url("../assets/icons/regular/bell.svg"); }
.i-book-open      { --icon: url("../assets/icons/regular/book-open.svg"); }
.i-books          { --icon: url("../assets/icons/regular/books.svg"); }
.i-calendar-blank { --icon: url("../assets/icons/regular/calendar-blank.svg"); }
.i-caret-down     { --icon: url("../assets/icons/regular/caret-down.svg"); }
.i-caret-left     { --icon: url("../assets/icons/regular/caret-left.svg"); }
.i-caret-right    { --icon: url("../assets/icons/regular/caret-right.svg"); }
.i-cell-signal    { --icon: url("../assets/icons/regular/cell-signal-high.svg"); }
.i-check-circle   { --icon: url("../assets/icons/regular/check-circle.svg"); }
.i-clock          { --icon: url("../assets/icons/regular/clock.svg"); }
.i-credit-card    { --icon: url("../assets/icons/regular/credit-card.svg"); }
.i-house          { --icon: url("../assets/icons/regular/house.svg"); }
.i-list           { --icon: url("../assets/icons/regular/list.svg"); }
.i-package        { --icon: url("../assets/icons/regular/package.svg"); }
.i-stack          { --icon: url("../assets/icons/regular/stack.svg"); }
.i-warning        { --icon: url("../assets/icons/regular/warning.svg"); }
.i-wifi-high      { --icon: url("../assets/icons/regular/wifi-high.svg"); }

/* Bold weight - Chip renders its icon at weight="bold". */
.i-alarm-b        { --icon: url("../assets/icons/bold/alarm-bold.svg"); }
.i-check-circle-b { --icon: url("../assets/icons/bold/check-circle-bold.svg"); }
.i-stack-b        { --icon: url("../assets/icons/bold/stack-bold.svg"); }
.i-credit-card-b  { --icon: url("../assets/icons/bold/credit-card-bold.svg"); }

/* --- Card (components/core/Card.jsx) --------------------------------------
   The surface primitive. Flat and borderless by default - tone does the
   separating. */
.ds-card {
  border-radius: var(--radius-card);
  border: none;
  padding: 16px; /* pad="md" */
  background: var(--surface-card);
  box-shadow: var(--shadow-card);
  transition: background var(--dur-fast) var(--ease-out);
}

.ds-card--pad-sm { padding: 12px; }
.ds-card--pad-lg { padding: 20px; }
.ds-card--pad-none { padding: 0; }

.ds-card--sunken  { background: var(--surface-sunken); box-shadow: none; }
.ds-card--muted   { background: var(--surface-muted); box-shadow: none; }
.ds-card--warning { background: var(--warning-quiet); box-shadow: none; }
.ds-card--brand   { background: var(--brand-quiet); box-shadow: none; }
.ds-card--bordered { border: 1px solid var(--border-hairline); }

/* --- Button (components/core/Button.jsx) ----------------------------------
   Primary action control. One per screen region; everything else is secondary
   or ghost. */
.ds-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 42px;
  padding: 0 17px;
  font-family: var(--font-core);
  font-size: 14.5px;
  font-weight: var(--weight-semibold);
  letter-spacing: -0.01em;
  line-height: 1;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  background: var(--brand);
  color: var(--text-on-brand);
  transition: background var(--dur-fast) var(--ease-out),
    opacity var(--dur-fast) var(--ease-out);
}

.ds-btn:hover { background: var(--brand-hover); }

.ds-btn--sm { height: 34px; padding: 0 13px; font-size: 13.5px; gap: 6px; }
.ds-btn--lg { height: 50px; padding: 0 22px; font-size: 15.5px; gap: 8px; }

.ds-btn--full { display: flex; width: 100%; }

.ds-btn--secondary { background: var(--surface-muted); color: var(--text-primary); }
.ds-btn--ghost     { background: transparent; color: var(--brand); }
.ds-btn--quiet     { background: var(--brand-quiet); color: var(--brand-on-quiet); }
.ds-btn--danger    { background: var(--danger-quiet); color: var(--danger); }

.ds-btn:disabled { cursor: not-allowed; opacity: 0.4; }

/* --- Chip (components/core/Chip.jsx) --------------------------------------
   One short fact, tinted by urgency. Use at most one per card. */
.ds-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 24px;
  padding: 0 9px;
  border-radius: var(--radius-chip);
  font-size: var(--text-chip-size);
  font-weight: var(--text-chip-weight);
  line-height: 1;
  white-space: nowrap;
  background: var(--surface-muted);
  color: var(--text-secondary);
}

.ds-chip .icon { --icon-size: 13px; }

.ds-chip--brand   { background: var(--brand-quiet); color: var(--brand-on-quiet); }
.ds-chip--success { background: var(--success-quiet); color: var(--success); }
.ds-chip--warning { background: var(--warning-quiet); color: var(--warning); }
.ds-chip--danger  { background: var(--danger-quiet); color: var(--danger); }

.ds-chip--quiet {
  background: transparent;
  padding: 0;
  color: var(--text-tertiary);
  font-weight: var(--weight-medium);
}

/* --- BoxTile (components/core/BoxTile.jsx) --------------------------------
   Rounded-square identity tile for a book box, initial set in paper on its
   accent colour. Identity accents only - no green, amber or red, so a tile
   never reads as a status. */
.ds-tile {
  --tile: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tile);
  height: var(--tile);
  flex: none;
  border-radius: var(--radius-tile);
  background: var(--tile-color, var(--box-indigo));
  color: var(--paper-50);
  font-family: var(--font-core);
  font-size: calc(var(--tile) * 0.45);
  font-weight: var(--weight-semibold);
  line-height: 1;
}

/* Source: `size >= 40 ? radius-tile : radius-sm`. */
.ds-tile--sm { border-radius: var(--radius-sm); }

.c-slate  { --tile-color: var(--box-slate); }
.c-ink    { --tile-color: var(--box-ink); }
.c-indigo { --tile-color: var(--box-indigo); }
.c-violet { --tile-color: var(--box-violet); }
.c-plum   { --tile-color: var(--box-plum); }
.c-steel  { --tile-color: var(--box-steel); }
.c-stone  { --tile-color: var(--box-stone); }

/* --- BookCover (components/library/BookCover.jsx) -------------------------
   Placeholder book cover - title and author in paper type on a cloth-coloured
   board. Every dimension derives from --cover-w exactly as the source derives
   it from the `width` prop. */
.ds-cover {
  --cover-w: 72px;
  position: relative;
  width: var(--cover-w);
  height: calc(var(--cover-w) * 1.5);
  flex: none;
  border-radius: 3px var(--radius-sm) var(--radius-sm) 3px;
  overflow: hidden;
  background: var(--tile-color, var(--box-slate));
  box-shadow: var(--shadow-raised);
}

/* The board's sewn spine. */
.ds-cover::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: rgba(0, 0, 0, 0.22);
}

.ds-cover__title {
  position: absolute;
  left: calc(var(--cover-w) * 0.16);
  right: calc(var(--cover-w) * 0.12);
  top: calc(var(--cover-w) * 1.5 * 0.14);
  display: block;
  font-size: max(8px, calc(var(--cover-w) * 0.14));
  line-height: 1.15;
  font-weight: var(--weight-semibold);
  color: var(--paper-50);
  letter-spacing: -0.01em;
}

.ds-cover__author {
  position: absolute;
  left: calc(var(--cover-w) * 0.16);
  right: calc(var(--cover-w) * 0.12);
  bottom: calc(var(--cover-w) * 1.5 * 0.12);
  font-size: max(6px, calc(var(--cover-w) * 0.085));
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--paper-50) 70%, transparent);
}

/* --- SectionLabel (components/core/SectionLabel.jsx) ----------------------
   Quiet sentence-case section heading with an optional count and trailing
   action. */
.ds-section-label {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.ds-section-label__text {
  font-size: var(--text-label-size);
  line-height: var(--text-label-line);
  font-weight: var(--text-label-weight);
  letter-spacing: var(--text-label-track);
  color: var(--text-secondary);
  white-space: nowrap;
}

.ds-section-label__count {
  color: var(--text-tertiary);
  font-weight: var(--weight-regular);
}

.ds-section-label__spacer { flex: 1; }

.ds-section-label__action {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-size: 12.5px;
  font-weight: var(--weight-medium);
  color: var(--text-tertiary);
}

/* --- StatRow (components/data/StatRow.jsx) --------------------------------
   One currency line in the spending table: code, this-month figure, projected
   year. */
.ds-stat-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 0;
}

.ds-stat-row--divider { border-bottom: 1px solid var(--border-soft); }

.ds-stat-row__code {
  width: 30px;
  flex: none;
  font-size: var(--text-caption-size);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  color: var(--text-tertiary);
}

.ds-stat-row__amount {
  flex: 1;
  font-size: var(--text-figure-size);
  line-height: var(--text-figure-line);
  font-weight: var(--text-figure-weight);
  letter-spacing: var(--text-figure-track);
  color: var(--text-primary);
}

.ds-stat-row__projected {
  font-size: var(--text-meta-size);
  color: var(--text-tertiary);
}

/* --- FigureBlock (components/data/FigureBlock.jsx) ------------------------
   Headline number with a caption above and optional note beneath. */
.ds-figure { text-align: left; }

.ds-figure__label {
  font-size: var(--text-label-size);
  font-weight: var(--text-label-weight);
  letter-spacing: var(--text-label-track);
  text-transform: uppercase;
  color: var(--text-label);
  margin-bottom: 5px;
}

.ds-figure__value {
  font-size: var(--text-figure-sm-size);
  font-weight: var(--text-figure-sm-weight);
  letter-spacing: -0.015em;
  color: var(--text-primary);
  line-height: 1.1;
}

.ds-figure--success .ds-figure__value { color: var(--success); }
.ds-figure--brand   .ds-figure__value { color: var(--brand); }
.ds-figure--danger  .ds-figure__value { color: var(--danger); }

.ds-figure__note {
  font-size: var(--text-caption-size);
  color: var(--text-tertiary);
  margin-top: 3px;
}

.ds-figure--right { text-align: right; }

/* --- ProgressMeter (components/data/ProgressMeter.jsx) --------------------
   Allowance / goal meter. With the ramp on, the fill walks green → amber → red
   as it fills. */
.ds-meter { display: block; }

.ds-meter__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 7px;
}

.ds-meter__label {
  font-size: var(--text-meta-size);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
}

.ds-meter__caption {
  font-size: var(--text-caption-size);
  color: var(--text-tertiary);
  font-weight: var(--weight-regular);
}

.ds-meter__track {
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--surface-muted);
  overflow: hidden;
}

.ds-meter__fill {
  width: var(--meter-pct, 0%);
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--meter-fill, var(--brand));
  transition: width var(--dur-slow) var(--ease-out),
    background var(--dur-slow) var(--ease-out);
}

/* --- Chart furniture ------------------------------------------------------
   Small shared bits the chart components render inline. */

/* The "Charged / Projected year" header above the currency table. */
.ds-caption-row {
  display: flex;
  justify-content: space-between;
  font-size: var(--text-caption-size);
  color: var(--text-tertiary);
  margin-bottom: 2px;
}

/* DashboardScreen and CalendarScreen both render a bare 14px spacer div. */
.ds-gap-14 { height: 14px; }

/* LineChart / BarChart axis labels. */
.ds-chart-labels {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  margin-top: 2px;
}

.ds-chart-labels > span {
  text-align: center;
  font-size: 9.5px;
  letter-spacing: 0.04em;
  color: var(--text-tertiary);
}

.ds-chart-label--hi { color: var(--text-secondary); }

/* --- DonutChart (components/data/DonutChart.jsx) --------------------------
   Share-of-total ring with a figure in the middle. Six slices maximum. */
.ds-donut {
  display: flex;
  align-items: center;
  gap: 18px;
}

.ds-donut__ring {
  position: relative;
  width: 124px;
  height: 124px;
  flex: none;
}

/* Arcs are authored from 0 and rotated so the first slice starts at 12
   o'clock, matching the component's `transform: rotate(-90deg)`. */
.ds-donut__svg { transform: rotate(-90deg); }

.ds-donut__center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
}

.ds-donut__value {
  font-size: 20px;
  font-weight: var(--weight-semibold);
  letter-spacing: -0.025em;
  color: var(--text-primary);
}

.ds-donut__label {
  font-size: var(--text-caption-size);
  color: var(--text-tertiary);
}

.ds-donut__legend {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  flex: 1;
}

.ds-donut__row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.ds-donut__swatch {
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 2px;
}

.ds-donut__name {
  flex: 1;
  min-width: 0;
  font-size: var(--text-meta-size);
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ds-donut__amount {
  font-size: var(--text-meta-size);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

/* Two FigureBlocks side by side above the allowance meter. */
.ds-figures-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 14px;
}

/* --- ListRow (components/subscriptions/ListRow.jsx) -----------------------
   Generic row: leading slot, title + note, optional trailing value. */
.ds-list-row {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 11px 0;
  background: none;
  border: none;
  text-align: left;
}

.ds-list-row--divider { border-bottom: 1px solid var(--border-soft); }

.ds-list-row__main { flex: 1; min-width: 0; }

.ds-list-row__title {
  display: block;
  font-size: 14.5px;
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ds-list-row__note {
  display: block;
  font-size: var(--text-meta-size);
  color: var(--text-tertiary);
}

.ds-list-row__value {
  display: block;
  font-size: 14.5px;
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  text-align: right;
}

/* --- EventRow (components/library/EventRow.jsx) ---------------------------
   A dated event in the calendar sheet or activity feed. */
.ds-event-row {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 9px 0;
  background: none;
  border: none;
  text-align: left;
}

.ds-event-row__glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
  color: var(--text-secondary);
}

.ds-event-row__glyph .icon { --icon-size: 16px; }

.ds-event-row__glyph--billing  { background: var(--brand-quiet); color: var(--brand); }
.ds-event-row__glyph--deadline { background: var(--warning-quiet); color: var(--warning); }
.ds-event-row__glyph--read     { background: var(--success-quiet); color: var(--success); }

.ds-event-row__main { flex: 1; min-width: 0; }

.ds-event-row__title {
  display: block;
  font-size: 14.5px;
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ds-event-row__note {
  display: block;
  font-size: var(--text-meta-size);
  color: var(--text-tertiary);
}

.ds-event-row__note--deadline { color: var(--warning); }

.ds-event-row__value {
  font-size: 14px;
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}

/* --- AttentionCard (components/subscriptions/AttentionCard.jsx) -----------
   Amber block listing decisions whose deadline is closing. Warning colour,
   nothing else. */
.ds-attention__head {
  display: flex;
  align-items: center;
  gap: 7px;
  color: var(--warning);
  margin-bottom: 10px;
  font-size: var(--text-label-size);
  font-weight: var(--text-label-weight);
  letter-spacing: var(--text-label-track);
}

.ds-attention__head .icon { --icon-size: 15px; }

.ds-attention__items {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ds-attention__item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 0;
  border: none;
  background: none;
  text-align: left;
}

.ds-attention__name {
  flex: 1;
  min-width: 0;
  font-size: 14.5px;
  font-weight: var(--weight-medium);
  color: var(--text-primary);
}

.ds-attention__note {
  font-size: var(--text-meta-size);
  font-weight: var(--weight-medium);
  color: var(--warning);
}

.ds-attention__note--urgent { color: var(--danger); }

.ds-attention__item .icon { --icon-size: 14px; color: var(--text-tertiary); }

/* --- SubscriptionCard (components/subscriptions/SubscriptionCard.jsx) -----
   One book-box subscription. Deliberately quiet: one chip at most, no state
   badge when active. */
.ds-sub-card__row {
  display: flex;
  gap: 13px;
  align-items: flex-start;
}

.ds-sub-card__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Name line - holds the state Badge on non-active subscriptions. */
.ds-sub-card__head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.ds-sub-card__name {
  flex: 1;
  min-width: 0;
  font-size: var(--text-heading-size);
  font-weight: var(--text-heading-weight);
  letter-spacing: var(--text-heading-track);
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ds-sub-card__meta {
  font-size: var(--text-meta-size);
  color: var(--text-tertiary);
}

.ds-sub-card__price {
  font-size: 14.5px;
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  margin-top: 3px;
}

.ds-sub-card__price .muted {
  color: var(--text-tertiary);
  font-weight: var(--weight-regular);
}

.ds-sub-card__aside {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  padding-top: 2px;
}

/* --- ActionLink (components/core/ActionLink.jsx) --------------------------
   Quiet text action that leads deeper. */
.ds-action-link {
  display: flex;
  margin-left: auto;
  align-items: center;
  gap: 5px;
  background: none;
  border: none;
  padding: 2px 0;
  cursor: pointer;
  color: var(--brand);
  font-size: 13px;
  font-weight: var(--weight-medium);
}

.ds-action-link .icon { --icon-size: 14px; }

/* --- IconButton (components/core/IconButton.jsx) -------------------------- */
.ds-icon-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-pill);
  color: var(--text-secondary);
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}

.ds-icon-btn .icon { --icon-size: 20px; }

.ds-icon-btn__badge {
  position: absolute;
  top: 7.2px;
  right: 8px;
  width: 7px;
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--danger);
  box-shadow: 0 0 0 2px var(--surface-card);
}

/* --- TopBar (components/navigation/TopBar.jsx) ---------------------------- */
.ds-topbar {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 6px 16px 10px;
}

.ds-topbar__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: var(--radius-pill);
  background: var(--brand-quiet);
  border: 1px solid color-mix(in oklab, var(--brand) 40%, transparent);
  color: var(--brand-on-quiet);
  font-size: 16px;
  font-weight: var(--weight-semibold);
}

.ds-topbar__main { min-width: 0; flex: 1; }

.ds-topbar__greeting {
  font-size: var(--text-display-size);
  line-height: var(--text-display-line);
  font-weight: var(--text-display-weight);
  letter-spacing: var(--text-display-track);
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ds-topbar__date {
  font-size: var(--text-meta-size);
  color: var(--text-tertiary);
}

/* --- TabBar (components/navigation/TabBar.jsx) ---------------------------- */
.ds-tabbar {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: stretch;
  border-top: 1px solid var(--border-hairline);
  background: var(--surface-nav);
  padding-bottom: 6px;
}

.ds-tabbar__item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 52px;
  padding: 8px 0 6px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-tertiary);
  transition: color var(--dur-fast) var(--ease-out);
}

.ds-tabbar__item .icon { --icon-size: 22px; }

.ds-tabbar__item--active { color: var(--brand); }

.ds-tabbar__glyph { position: relative; display: inline-flex; }

.ds-tabbar__dot {
  position: absolute;
  top: -1px;
  right: -3px;
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--danger);
}

.ds-tabbar__label { font-size: 11px; font-weight: var(--weight-regular); }

.ds-tabbar__item--active .ds-tabbar__label { font-weight: var(--weight-semibold); }

.ds-tabbar__item--active::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 26%;
  right: 26%;
  height: 2.5px;
  border-radius: var(--radius-pill);
  background: var(--brand);
}

/* --- SegmentedControl (components/navigation/SegmentedControl.jsx) -------- */
.ds-segmented {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border-radius: var(--radius-pill);
  background: var(--surface-muted);
  border: 1px solid var(--border-soft);
}

.ds-segmented__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 14px;
  border-radius: var(--radius-pill);
  border: none;
  cursor: pointer;
  font-size: 13px;
  font-weight: var(--weight-medium);
  background: transparent;
  color: var(--text-tertiary);
  transition: background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

.ds-segmented__item .icon { --icon-size: 14px; }

.ds-segmented__item--active {
  font-weight: var(--weight-semibold);
  background: var(--surface-card);
  color: var(--text-primary);
  box-shadow: var(--shadow-subtle);
}

/* --- MonthNav (components/navigation/MonthNav.jsx) ------------------------ */
.ds-month-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}

.ds-month-nav__label {
  font-size: var(--text-heading-size);
  font-weight: var(--text-heading-weight);
  letter-spacing: var(--text-heading-track);
  color: var(--text-primary);
}

.ds-month-nav__arrows { display: flex; gap: 2px; }

.ds-month-nav__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-pill);
  background: none;
  border: none;
  color: var(--text-tertiary);
  cursor: pointer;
}

.ds-month-nav__arrow .icon { --icon-size: 17px; }

/* --- CalendarGrid (components/library/CalendarGrid.jsx) -------------------
   Month grid marking billing days and skip deadlines with a single dot per
   day. */
.ds-cal__weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  margin-bottom: 6px;
}

.ds-cal__weekday {
  text-align: center;
  font-size: var(--text-caption-size);
  font-weight: var(--weight-medium);
  color: var(--text-tertiary);
}

.ds-cal__days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  row-gap: 2px;
}

.ds-cal__day {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  height: 38px;
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-secondary);
  font-weight: var(--weight-regular);
  font-size: 14px;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}

.ds-cal__day--marked { font-weight: var(--weight-semibold); }

.ds-cal__day--selected {
  background: var(--brand);
  color: var(--text-on-brand);
  font-weight: var(--weight-semibold);
}

.ds-cal__dot {
  width: 4px;
  height: 4px;
  border-radius: var(--radius-pill);
  background: transparent;
}

.ds-cal__dot--billing  { background: var(--brand); }
.ds-cal__dot--deadline { background: var(--warning); }
.ds-cal__dot--urgent   { background: var(--danger); }

.ds-cal__day--selected .ds-cal__dot { background: var(--text-on-brand); }

.ds-cal__legend {
  display: flex;
  gap: 14px;
  margin-top: 12px;
  font-size: var(--text-caption-size);
  color: var(--text-tertiary);
}

.ds-cal__legend > span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.ds-cal__key {
  width: 5px;
  height: 5px;
  border-radius: var(--radius-pill);
}

.ds-cal__key--billing  { background: var(--brand); }
.ds-cal__key--deadline { background: var(--warning); }

/* ===========================================================================
   TodayMock (AppPhone.jsx) - the "Needs your attention" hero mockup. Page-
   level composition, not a standalone DS component, so it's namespaced `tm-`
   rather than `ds-`.
   =========================================================================== */
.tm-card-body { display: flex; flex-direction: column; gap: 11px; }

.tm-row { display: flex; align-items: center; gap: 11px; }

.tm-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }

.tm-row__title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tm-row__note {
  font-size: var(--text-meta-size);
  line-height: 1.4;
  color: var(--text-secondary);
}

.tm-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 11px;
  border-top: 1px solid var(--border-hairline);
}

.tm-foot__text {
  flex: 1;
  min-width: 0;
  font-size: var(--text-caption-size);
  line-height: 1.4;
  color: var(--text-tertiary);
}

.tm-choices { display: flex; flex-direction: column; gap: 13px; }

.tm-choices__head { display: flex; align-items: center; gap: 8px; }

.tm-choices__label {
  flex: 1;
  min-width: 0;
  font-size: var(--text-label-size);
  font-weight: var(--text-label-weight);
  color: var(--text-secondary);
}

.tm-choices__head .icon { --icon-size: 15px; color: var(--text-tertiary); }

.tm-choices__stats { display: flex; align-items: stretch; gap: 14px; }

.tm-choices__stat { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }

.tm-choices__value {
  font-size: 26px;
  line-height: 1.1;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text-primary);
}

.tm-choices__value--success { color: var(--success); }

.tm-choices__caption {
  font-size: var(--text-meta-size);
  line-height: 1.35;
  color: var(--text-secondary);
}

.tm-choices__rule { flex: none; width: 1px; background: var(--border-soft); }

.tm-incoming { display: flex; align-items: center; gap: 11px; }

.tm-incoming__glyph {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
}

.tm-incoming__glyph .icon { --icon-size: 18px; }

.tm-incoming__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }

/* ===========================================================================
   PhoneFrame (ui_kits/cratelog-app/PhoneFrame.jsx) + AppPhone.jsx
   The landing mockups. `--phone-scale` drives the whole thing; the slot
   reserves the scaled footprint so layout never depends on the transform.
   =========================================================================== */
.phone-slot {
  --phone-scale: 1;
  width: calc(390px * var(--phone-scale));
  height: calc(800px * var(--phone-scale));
  flex: none;
}

.phone-scaler {
  width: 390px;
  height: 800px;
  transform: scale(var(--phone-scale));
  transform-origin: top left;
}

.phone-frame {
  position: relative;
  width: 390px;
  height: 800px;
  border-radius: var(--radius-phone);
  background: var(--bg-app);
  border: 9px solid #100e0c;
  box-shadow: var(--shadow-modal);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.phone-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 22px 4px;
  flex: none;
}

.phone-status__time {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}

.phone-status__notch {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: 8px;
  width: 108px;
  height: 26px;
  border-radius: 999px;
  background: #100e0c;
}

.phone-status__icons {
  display: flex;
  gap: 5px;
  align-items: center;
  color: var(--text-primary);
}

/* ScreenBody */
.phone-body {
  flex: 1;
  overflow: hidden; /* mockup: no scrollbars, the content is already framed */
  padding: 0 var(--gutter-screen) 88px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.phone-nav {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
}

.phone-home-indicator {
  display: flex;
  justify-content: center;
  padding: 2px 0 7px;
  background: var(--surface-nav);
}

.phone-home-indicator > span {
  width: 128px;
  height: 4px;
  border-radius: 999px;
  background: var(--text-primary);
  opacity: 0.3;
}

/* A screen section inside the phone: label above a card. */
.phone-section {
  display: flex;
  flex-direction: column;
  gap: 9px;
}

/* The SegmentedControl strip sits outside ScreenBody, flex: none. */
.phone-viewswitch {
  display: flex;
  justify-content: center;
  padding: 0 16px 12px;
  flex: none;
}

/* Everything inside a mockup is decorative - kill pointer affordances so the
   phone reads as an image, not a broken app. */
.phone-frame button {
  cursor: default;
  pointer-events: none;
}
