/* Telegram theme variables with fallbacks, so the page looks native in both themes and still
   readable if the webview supplies nothing (opening the URL in a plain browser while
   debugging). */
:root {
  --bg: var(--tg-theme-bg-color, #ffffff);
  --fg: var(--tg-theme-text-color, #000000);
  --hint: var(--tg-theme-hint-color, #8a8a8e);
  --accent: var(--tg-theme-button-color, #2481cc);
  --accent-fg: var(--tg-theme-button-text-color, #ffffff);
  --sep: var(--tg-theme-section-separator-color, #e4e4e7);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  /* Room for the fixed footer: checkout plus the status bar's reserved line. */
  padding: 12px 12px calc(124px + env(safe-area-inset-bottom));
  background: var(--bg);
  color: var(--fg);
  font: 17px/1.35 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  -webkit-tap-highlight-color: transparent;
}

/* The tab strip. Underline rather than a pill or a segmented control: it survives both
   Telegram themes with one colour variable, and the inactive tab stays readable instead of
   becoming a low-contrast ghost on the dark theme. */
#tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--sep);
  margin: 0 -12px 10px;
  padding: 0 8px;
}

.tab {
  flex: 1;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--hint);
  font: inherit;
  font-weight: 600;
  /* 44px, the same floor as the list rows: a tab is tapped one-handed too, and a thin strip
     at the top of a phone is the hardest thing on the page to hit. */
  min-height: 44px;
  padding: 10px 8px;
  cursor: pointer;
}

.tab[aria-selected="true"] { color: var(--fg); border-bottom-color: var(--accent); }

#summary, #empty, #todo-empty, #status {
  color: var(--hint); font-size: 14px; margin: 0 0 10px;
}
#status[data-kind="warn"] { color: #c8811a; }

/* The status bar, inside the fixed footer (F5). Its line is reserved on the shopping tab —
   min-height, whether or not there is text — so a status arriving or leaving never changes
   the footer's height, let alone the list's position. */
#bar {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 32px;
  margin-bottom: 8px;
}
#bar[hidden] { display: none; }
#bar #status { flex: 1; margin: 0; cursor: pointer; }
/* The line's head (a notice, or the plain status) stops at two lines; a tap opens it in
   full, the next tap acknowledges it. The tail — offline, «Ждут отправки: n», the storage
   warning — is never cut: it is what is still true, and hiding it is how unsent work went
   unnoticed (W4 review). Before this a long notice took seven lines of a 640px screen. */
#status .note {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
#status .note.open { display: block; -webkit-line-clamp: unset; line-clamp: none; }
#status .tail { display: block; }
/* «Отменить» and a notice's action: accent text buttons, not grey system buttons. */
#status-cancel, #status-action {
  background: none;
  border: 0;
  color: var(--accent);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  padding: 6px 4px;
  white-space: nowrap;
  cursor: pointer;
}
#status-cancel[hidden], #status-action[hidden], #checkout[hidden] { display: none; }

#items, #todos { list-style: none; margin: 0; padding: 0; }

/* Due date and the repeat marker, beside the title rather than under it: a second line per
   row would halve how much of the list fits on a phone. */
.meta { color: var(--hint); font-size: 14px; margin-inline-start: 6px; }

/* The tap target is the whole row and it is 52px tall on purpose. This is the one action a
   supermarket trip performs 30-40 times, one-handed, while pushing a trolley — which is the
   same reasoning that kept «⋯» off the keyboard rows (CLAUDE.md, Phase 3b). */
.row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  padding: 6px 4px;
  border-bottom: 1px solid var(--sep);
}

.tick {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  text-align: start;
  padding: 8px 0;
  cursor: pointer;
}

.box { font-size: 20px; line-height: 1; }
.row.in-cart .label { color: var(--hint); text-decoration: line-through; }
.qty { color: var(--hint); font-size: 15px; }

/* An item added while offline: shown immediately, marked as not yet agreed with the server. */
.row.pending { opacity: 0.55; }

.remove {
  background: none;
  border: 0;
  color: var(--hint);
  font: inherit;
  font-size: 14px;
  padding: 10px 8px;
  cursor: pointer;
}

#add-form { display: flex; gap: 8px; margin-top: 14px; }
#add-input {
  flex: 1;
  min-width: 0;
  padding: 11px 12px;
  font: inherit;
  color: var(--fg);
  background: var(--bg);
  border: 1px solid var(--sep);
  border-radius: 10px;
}
#add-button, #checkout {
  padding: 11px 16px;
  font: inherit;
  font-weight: 600;
  color: var(--accent-fg);
  background: var(--accent);
  border: 0;
  border-radius: 10px;
  cursor: pointer;
}
#add-button:disabled, #checkout:disabled { opacity: 0.4; cursor: default; }

footer {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  background: var(--bg);
  border-top: 1px solid var(--sep);
}
#checkout { width: 100%; }

/* Explicit rather than relying on the UA rule, because `footer` above sets `position: fixed`
   and a reader has to be able to see that hiding it actually removes it from the layout. */
footer[hidden] { display: none; }

/* The body reserves room for the fixed footer. On the todo tab there is no footer, so that
   reservation becomes 84px of dead space at the end of the list — which on a phone reads as
   "the list ends here" a screenful before it does. */
body.no-footer { padding-bottom: calc(16px + env(safe-area-inset-bottom)); }
/* The todo tab while its footer shows the bar: room for it at the end of the list. Only the
   scroll extent changes — no row above moves. */
body.no-footer.with-bar { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
