/* App-level styles. Every color/size comes from /theme.css variables
   (generated from design/tokens.json) — no hardcoded style values here. */

#app {
  max-width: 480px;
  margin: 0 auto;
  padding: var(--space-5) var(--space-4);
  /* Fullscreen mini-app: Telegram draws the device status bar and its round
     Close/More pills on top of the webview, so content must start below that
     chrome. Outside fullscreen every inset is 0 and this collapses to the
     plain paddings above. */
  padding-top: calc(
    var(--space-5) +
      var(--tg-safe-area-inset-top, env(safe-area-inset-top, 0px)) +
      var(--tg-content-safe-area-inset-top, 0px)
  );
  padding-bottom: calc(
    var(--space-5) +
      max(
        var(--tg-safe-area-inset-bottom, 0px),
        env(safe-area-inset-bottom, 0px)
      )
  );
}

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-card);
  padding: var(--space-4);
  margin-top: var(--space-3);
  box-shadow: var(--shadow-card);
}

.label {
  font-size: var(--type-label-size);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
}

/* The receipt total: solid ink, monospace, heavy — no gradient in Ledger. */
.hero-amount {
  font-family: var(--font-display);
  font-size: var(--type-hero-size);
  line-height: var(--type-hero-lh);
  font-weight: var(--font-weight-hero);
  letter-spacing: var(--letter-spacing-hero);
  color: var(--color-ink);
}

.chip {
  display: inline-block;
  background: var(--color-surface-alt);
  color: var(--color-ink-muted);
  border-radius: var(--radius-control);
  padding: var(--space-1) var(--space-3);
  font-size: var(--type-caption-size);
  margin-right: var(--space-2);
}

.muted {
  color: var(--color-ink-muted);
  font-size: var(--type-caption-size);
}

a,
button.primary {
  color: var(--color-accent);
}

/* Period switcher */
.tabs {
  display: flex;
  gap: var(--space-2);
  margin: var(--space-3) 0 var(--space-2);
}
.tab {
  flex: 1;
  background: var(--color-surface);
  color: var(--color-ink-muted);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-control);
  padding: var(--space-2) var(--space-3);
  font: inherit;
  cursor: pointer;
}
.tab-active {
  background: var(--color-ink);
  border-color: var(--color-ink);
  color: var(--color-bg);
}
.tab,
.nav-item {
  transition:
    transform var(--motion-fast) var(--motion-spring),
    background var(--motion-base) ease,
    color var(--motion-base) ease;
}
.tab:active {
  transform: scale(0.96);
}
.nav-item:active {
  transform: scale(0.95);
}

/* Goal ribbon (Aurora signature: glow on data) */
.goal-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--space-2);
}
.glowbar {
  height: 12px;
  border-radius: var(--radius-control);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-line);
  overflow: hidden;
}
.glowbar i {
  display: block;
  height: 100%;
  border-radius: 0;
  background: var(--color-ink);
}

/* Category donut + legend */
.donut-row {
  display: flex;
  gap: var(--space-4);
  align-items: center;
}
.legend {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  flex: 1;
  min-width: 0;
}
.legend li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--type-caption-size);
}
.dot {
  width: 9px;
  height: 9px;
  border-radius: 3px;
  flex-shrink: 0;
}
.legend-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.legend-val {
  margin-left: auto;
  color: var(--color-ink-muted);
}

/* Recent records */
.rec {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-line);
  font-size: var(--type-body-size);
}
.rec:last-child {
  border-bottom: 0;
}
.rec-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.rec-date {
  font-size: var(--type-caption-size);
}
.foreign {
  padding: var(--space-2) var(--space-4);
}
.num {
  font-variant-numeric: tabular-nums;
}

/* Top nav */
.nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: var(--space-2) 0 var(--space-3);
}
.nav-item {
  flex: 1 1 40%;
  text-align: center;
  text-decoration: none;
  color: var(--color-ink-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-control);
  padding: var(--space-2) var(--space-2);
  font-size: var(--type-caption-size);
  white-space: nowrap;
}
.nav-active {
  color: var(--color-ink);
  background: var(--color-surface-alt);
}

/* History */
.search {
  width: 100%;
  box-sizing: border-box;
  background: var(--color-surface);
  color: var(--color-ink);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-control);
  padding: var(--space-2) var(--space-3);
  font: inherit;
  margin-bottom: var(--space-2);
}
.search::placeholder {
  color: var(--color-ink-muted);
}
.hist-item {
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-line);
}
.hist-item:last-child {
  border-bottom: 0;
}
.hist-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
}
.hist-desc {
  font-size: var(--type-caption-size);
  margin-top: 2px;
}
.edit-box {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px dashed var(--color-line);
}
.edit-input {
  background: var(--color-bg-elevated);
  color: var(--color-ink);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-control);
  padding: var(--space-2) var(--space-3);
  font: inherit;
}
.edit-input:focus-visible,
.search:focus-visible {
  outline: 0;
  border-color: var(--color-accent);
  box-shadow: var(--focus-ring);
}
.edit-controls {
  display: flex;
  gap: var(--space-2);
}
.btn-primary,
.btn-danger {
  flex: 1;
  border: 0;
  border-radius: var(--radius-control);
  padding: var(--space-2) var(--space-3);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.btn-primary {
  background: var(--color-ink);
  color: var(--color-bg);
}
.btn-danger {
  background: var(--color-surface-alt);
  border: 1px solid var(--color-line);
  color: var(--color-danger);
}
.goal-del {
  margin-top: var(--space-2);
  width: 100%;
}

/* Settings rows */
.set-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-line);
}
.set-row:last-of-type {
  border-bottom: 0;
}
.set-label {
  color: var(--color-ink-muted);
  font-size: var(--type-caption-size);
}
.set-tz {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  /* Without this the long IANA name can't shrink and shoves the detect
     button past the card edge. */
  min-width: 0;
}
.tz-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.set-btn {
  flex: 0 0 auto;
  width: auto;
}
.set-toast {
  text-align: right;
  min-height: 1em;
  /* success green, not accentAlt: the amber reads under AA on light paper, and
     a "saved" confirmation is semantically a success anyway. */
  color: var(--color-success);
}

/* ---------- Ultra controls (T-904a) ---------- */
.edit-input,
.search {
  min-height: 48px;
}

/* sheet-select field */
.field {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  text-align: left;
}
.field .f-emoji {
  font-size: 17px;
}
.field .f-label {
  flex: 1;
  font-weight: 650;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.field .f-chev {
  color: var(--color-ink-muted);
  font-size: 11px;
  transition: transform var(--motion-base) var(--motion-ease);
}
.field[aria-expanded="true"] .f-chev {
  transform: rotate(180deg);
}
.set-row .field {
  max-width: 60%;
}

/* bottom sheet */
.sheet-dim {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  opacity: 0;
  transition: opacity var(--motion-base) ease;
  z-index: 40;
}
.sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 41;
  display: flex;
  flex-direction: column;
  max-height: 75vh;
  background: var(--color-surface);
  border-radius: calc(var(--radius-card) + 6px) calc(var(--radius-card) + 6px) 0
    0;
  box-shadow: var(--shadow-sheet);
  padding-bottom: max(
    var(--tg-safe-area-inset-bottom, 0px),
    env(safe-area-inset-bottom, 0px)
  );
  transform: translateY(105%);
  transition: transform var(--motion-base) var(--motion-ease);
}
.sheet-dim.open {
  opacity: 1;
}
.sheet.open {
  transform: translateY(0);
}
/* Grab handle + title form the swipe-to-close drag zone (T-904b); touch-action
   none keeps the browser from stealing the vertical drag as a page scroll. */
.sheet-grab {
  flex: 0 0 4px;
  width: 38px;
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--color-ink-muted);
  opacity: 0.35;
  margin: 10px auto 6px;
  touch-action: none;
}
.sheet-title {
  text-align: center;
  font-weight: 800;
  font-size: var(--type-label-size);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
  margin-bottom: var(--space-2);
  touch-action: none;
}
.sheet-search {
  margin: 0 var(--space-3) var(--space-2);
}
.sheet-opts {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 var(--space-2) var(--space-3);
}
.sheet-opt {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  border: 0;
  background: transparent;
  color: var(--color-ink);
  font: inherit;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-control);
  min-height: 44px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.sheet-opt:active {
  background: var(--color-surface-alt);
}
.sheet-opt[aria-selected="true"] {
  background: var(--color-surface-alt);
  font-weight: 700;
}
.sheet-opt[aria-selected="true"]::after {
  content: "✓";
  margin-left: auto;
  font-weight: 800;
  color: var(--color-accent);
}
.sheet-empty {
  padding: var(--space-4);
  text-align: center;
  color: var(--color-ink-muted);
  font-size: var(--type-caption-size);
}

/* settle-to-zero celebration in the group view (T-904b): the card pulses one
   gradient flash and the message reads in accent ink. */
.settled-card {
  position: relative;
  overflow: hidden;
}
.settled {
  font-weight: 800;
  font-size: var(--type-body-size);
  color: var(--color-owed);
}
.settled-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--color-owed);
  opacity: 0;
  pointer-events: none;
}
.settled-card.flash::after {
  animation: settle-flash var(--motion-settle-flash) ease;
}
@keyframes settle-flash {
  0% {
    opacity: 0;
  }
  28% {
    opacity: 0.16;
  }
  100% {
    opacity: 0;
  }
}

/* segmented control */
.seg {
  display: flex;
  gap: var(--space-2);
}
.seg button {
  flex: 1;
  border: 1.5px solid var(--color-line);
  background: var(--color-surface-alt);
  /* ink, not ink-muted: muted on the recessed surface-alt track is 4.25:1 on
     light — under AA for this persistent interactive label. */
  color: var(--color-ink);
  font: inherit;
  font-size: var(--type-caption-size);
  font-weight: 700;
  padding: var(--space-2);
  border-radius: var(--radius-control);
  min-height: 44px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.seg button.on {
  background: var(--color-ink);
  border-color: var(--color-ink);
  color: var(--color-bg);
}

/* pressable CTAs: squeeze + spring back, shine sweep on submit */
.btn-primary {
  position: relative;
  overflow: hidden;
  min-height: 48px;
  transition:
    transform var(--motion-fast) var(--motion-spring),
    box-shadow var(--motion-base) ease;
}
.btn-primary:active {
  transform: scale(0.965);
}
.btn-primary::after {
  /* A faint specular sweep on press (a light reflection, not a surface color).
     Ledger is matte, so this is far subtler than Ultra's — a paper glint, not
     a shine. Literal white on purpose. */
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
      105deg,
      transparent 42%,
      rgba(255, 255, 255, 0.14) 50%,
      transparent 58%
    )
    no-repeat;
  background-size: 240% 100%;
  background-position: 140% 0;
  pointer-events: none;
}
.btn-primary.flash::after {
  animation: btn-shine 0.7s ease;
}
@keyframes btn-shine {
  from {
    background-position: 150% 0;
  }
  to {
    background-position: -80% 0;
  }
}
.btn-glow {
  box-shadow: var(--shadow-cta);
}
.btn-danger {
  transition: transform var(--motion-fast) var(--motion-spring);
}
.btn-danger:active {
  transform: scale(0.97);
}

/* ---------- Screen transitions (T-904b) ---------- */
/* Tab switches slide the new screen in from the side you are heading toward
   (nav order = ORDER in router.js). The nav re-renders identically on every
   screen, so it must not animate — it has to read as fixed chrome. theme.css
   already disables all animation under prefers-reduced-motion. */
#app[data-view-dir] > * {
  --view-dx: 18px;
  animation: view-in var(--motion-base) var(--motion-ease);
}
#app[data-view-dir] > .nav {
  animation: none;
}
#app[data-view-dir="back"] > * {
  --view-dx: -18px;
}
@keyframes view-in {
  from {
    opacity: 0;
    transform: translateX(var(--view-dx));
  }
}

/* ---------- Settings polish (T-904c) ---------- */
.set-row {
  min-height: 52px;
}

/* Gradient toggle: the checked state is "live", so it wears the accent. */
input.toggle {
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
  flex-shrink: 0;
  width: 50px;
  height: 30px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-alt);
  border: 1.5px solid var(--color-line);
  position: relative;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background var(--motion-base) ease,
    border-color var(--motion-base) ease;
}
input.toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 3px;
  width: 21px;
  height: 21px;
  transform: translateY(-50%);
  border-radius: var(--radius-pill);
  background: var(--color-accent-ink);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
  transition:
    left var(--motion-base) var(--motion-ease),
    width var(--motion-fast) var(--motion-ease);
}
input.toggle:checked {
  background: var(--color-accent);
  border-color: transparent;
}
input.toggle:checked::after {
  left: calc(100% - 24px);
}
/* iOS-style knob stretch while pressed */
input.toggle:active::after {
  width: 26px;
}
input.toggle:checked:active::after {
  left: calc(100% - 29px);
}
input.toggle:focus-visible {
  outline: 0;
  box-shadow: var(--focus-ring);
}

/* Chip button: compact secondary action (detect, export formats). */
.btn-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  background: var(--color-surface-alt);
  color: var(--color-ink);
  border: 1.5px solid var(--color-line);
  border-radius: var(--radius-control);
  padding: var(--space-2) var(--space-4);
  font: inherit;
  font-size: var(--type-caption-size);
  font-weight: 700;
  min-height: 40px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    transform var(--motion-fast) var(--motion-spring),
    background var(--motion-base) ease;
}
.btn-chip:active {
  transform: scale(0.95);
}
.btn-chip:focus-visible {
  outline: 0;
  box-shadow: var(--focus-ring);
}
.chip-arrow {
  color: var(--color-ink-muted);
  font-weight: 800;
}

.export-row {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
}
.export-row .btn-chip {
  flex: 1;
}

.invite-cta {
  display: block;
  width: 100%;
  margin-top: var(--space-4);
}

/* ---------- Trash & undo (T-907) ---------- */
.trash-row {
  display: flex;
  justify-content: flex-end;
  margin-top: var(--space-2);
}
.trash-note {
  margin-top: var(--space-2);
}
.trash-rec {
  gap: var(--space-2);
}
.trash-info {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}
.trash-cat {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.trash-restore {
  flex-shrink: 0;
}
.trash-clear {
  width: 100%;
  margin-top: var(--space-3);
}

/* Undo bar: fixed above the home indicator, one at a time. The thin gradient
   line drains over the undo window (duration set inline by ui.js). */
.undo-bar {
  position: fixed;
  left: var(--space-4);
  right: var(--space-4);
  bottom: calc(
    var(--space-4) +
      max(
        var(--tg-safe-area-inset-bottom, 0px),
        env(safe-area-inset-bottom, 0px)
      )
  );
  z-index: 30;
  max-width: 448px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  background: var(--color-bg-elevated);
  color: var(--color-ink);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-control);
  padding: var(--space-3) var(--space-4);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.35);
  overflow: hidden;
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity var(--motion-base) ease,
    transform var(--motion-base) var(--motion-ease);
}
.undo-bar.open {
  opacity: 1;
  transform: translateY(0);
}
.undo-text {
  flex: 1;
  font-size: var(--type-body-size);
}
.undo-act {
  border: 0;
  font: inherit;
  font-weight: 800;
  cursor: pointer;
  padding: var(--space-1) var(--space-2);
  background: transparent;
  color: var(--color-accent);
  -webkit-tap-highlight-color: transparent;
}
.undo-timer {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: 100%;
  background: var(--color-accent);
  animation: undo-drain linear forwards;
}
@keyframes undo-drain {
  from {
    width: 100%;
  }
  to {
    width: 0;
  }
}

/* Group view — Ledger receipt (2026-08-02). The whole screen is one paper slip:
   a centered head + total, perforation rules between sections, ledger lines with
   dotted leaders, a rubber stamp for the settle state, and a barcode footer.
   Every color is a theme.css token, so both themes flip automatically. */
.receipt {
  position: relative;
  padding: var(--space-4);
}
.receipt-head {
  text-align: center;
}
.receipt-eyebrow {
  font-size: var(--type-label-size);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
}
.receipt-title {
  font-size: var(--type-caption-size);
  color: var(--color-ink-muted);
  margin-top: 2px;
}
.receipt .hero-amount {
  display: block;
  margin-top: var(--space-1);
}

/* Perforation divider between sections. */
.perf {
  height: 0;
  border: 0;
  /* neutral-mid, not the hairline --color-line: the perforation is the receipt's
     signature and needs to actually read in both themes. */
  border-top: 1.5px dashed var(--color-neutral-mid);
  margin: var(--space-3) 0;
}

.sec-label {
  font-size: var(--type-label-size);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--color-ink);
  margin-bottom: var(--space-2);
}

/* A printed ledger line: label · dotted leader · right-aligned figure. */
.led-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: 3px 0;
  font-size: var(--type-body-size);
}
.led-name {
  max-width: 64%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.led-dots {
  flex: 1 1 auto;
  min-width: 10px;
  align-self: center;
  border-bottom: 1.5px dotted var(--color-neutral-mid);
  transform: translateY(2px);
}
.led-amt {
  flex: 0 0 auto;
  font-weight: 700;
  white-space: nowrap;
}
.led-amt.owed {
  color: var(--color-owed);
}
.led-amt.owe {
  color: var(--color-owe);
}

/* Rubber stamp for the settle state, canted like a hand-pressed one. */
.stamp {
  position: absolute;
  top: 16px;
  right: 12px;
  transform: rotate(-9deg);
  padding: 2px 8px;
  border: 2.5px solid var(--color-accent);
  border-radius: 5px;
  color: var(--color-accent);
  font-size: var(--type-label-size);
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  pointer-events: none;
}
.stamp.paid {
  border-color: var(--color-owed);
  color: var(--color-owed);
}

/* Barcode footer — a printed flourish that closes the slip. */
.receipt-foot {
  text-align: center;
}
.barcode {
  height: 26px;
  margin-bottom: var(--space-1);
  background-image: repeating-linear-gradient(
    90deg,
    var(--color-ink) 0 1px,
    transparent 1px 3px,
    var(--color-ink) 3px 5px,
    transparent 5px 6px,
    var(--color-ink) 6px 9px,
    transparent 9px 12px
  );
  opacity: 0.78;
}
.foot-tag {
  font-size: var(--type-label-size);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
}
