/* Kidney Diet Log — base styles: design tokens (light and dark), layout, header and tabs,
   cards and lists, rating icons, buttons, forms, toast and badges. No external assets.
   Link order (index.html): base.css, today.css, add.css, plan.css, trends.css, profile.css,
   sheets.css, pwa.css, touch.css. Later files rely on coming after this one, and touch.css must
   stay last (its 44 px minimums override rules of equal specificity everywhere). */

:root {
  color-scheme: light;
  --bg: #f4f5f7;
  --surface: #ffffff;
  --surface-2: #eef0f3;
  --surface-3: #e3e6eb;
  --border: #d7dbe2; /* cards, lists and dividers */
  /* The edge of a field, a select or a choice box: at least 3:1 on bg, surface and surface-2 (WCAG 1.4.11) */
  --control-border: #7d8590; /* 3.4:1 on bg, 3.7:1 on surface, 3.3:1 on surface-2 */
  --text: #1b1f24;
  --text-2: #4b5563;
  --text-3: #5f6673; /* 5.0:1 on surface-2, 5.3:1 on bg */
  --accent: #1565c0;
  --accent-hover: #0d4f9c;
  --accent-text: #ffffff;
  --accent-tint: #e3eefc;
  --focus: #1565c0;

  /* status palette (contract colors on light) */
  --ok: #2e7d32;
  --caution: #f9a825;
  --over: #c62828;
  --ok-text: #1e6b23;
  --caution-text: #7a4f00;
  --over-text: #a61b1b;
  --ok-tint: #e5f3e6;
  --caution-tint: #fdf2d6;
  --over-tint: #fbe4e4;
  --caution-glyph: #2b1d00;
  /* toast backgrounds: the same in both themes (white text 5.1:1 and 5.6:1) */
  --ok-solid: #2e7d32;
  --over-solid: #c62828;

  --track: #e2e5ea;
  --shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.1);
  --shadow-lg: 0 -4px 24px rgba(16, 24, 40, 0.18);
  --radius: 14px;
  --radius-sm: 10px;
  --tap: 44px;
  --tabbar-h: 60px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #111417;
    --surface: #1b1f24;
    --surface-2: #242a31;
    --surface-3: #2d343d;
    --border: #353d47;
    --control-border: #76808c; /* 4.6:1 on bg, 4.1:1 on surface, 3.6:1 on surface-2 */
    --text: #f1f3f5;
    --text-2: #b5bcc6;
    --text-3: #8b949e;
    --accent: #6cb4f8;
    --accent-hover: #8cc5fa;
    --accent-text: #08203a;
    --accent-tint: #1b3350;
    --focus: #8cc5fa;
    --ok: #4caf50;
    --caution: #fbc02d;
    --over: #ef5350;
    --ok-text: #8bd48e;
    --caution-text: #ffd96b;
    --over-text: #ff9e9b;
    --ok-tint: #1b2e1d;
    --caution-tint: #332a12;
    --over-tint: #3a1d1d;
    --caution-glyph: #1b1400;
    --track: #2d343d;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 -4px 24px rgba(0, 0, 0, 0.6);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #111417;
  --surface: #1b1f24;
  --surface-2: #242a31;
  --surface-3: #2d343d;
  --border: #353d47;
  --control-border: #76808c;
  --text: #f1f3f5;
  --text-2: #b5bcc6;
  --text-3: #8b949e;
  --accent: #6cb4f8;
  --accent-hover: #8cc5fa;
  --accent-text: #08203a;
  --accent-tint: #1b3350;
  --focus: #8cc5fa;
  --ok: #4caf50;
  --caution: #fbc02d;
  --over: #ef5350;
  --ok-text: #8bd48e;
  --caution-text: #ffd96b;
  --over-text: #ff9e9b;
  --ok-tint: #1b2e1d;
  --caution-tint: #332a12;
  --over-tint: #3a1d1d;
  --caution-glyph: #1b1400;
  --track: #2d343d;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 -4px 24px rgba(0, 0, 0, 0.6);
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* viewport-fit=cover: keep content out of the notch / status bar (a host page may pad the root
   the same way; the value is identical, so it is not applied twice). */
html { -webkit-text-size-adjust: 100%; padding-top: env(safe-area-inset-top, 0px); }
/* A control reached with Tab is scrolled clear of the sticky header and, on a phone, of the tab bar at the bottom. */
html { scroll-padding-top: calc(64px + env(safe-area-inset-top, 0px)); scroll-padding-bottom: calc(var(--tabbar-h) + 8px + env(safe-area-inset-bottom, 0px)); }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 1rem; /* 16 px unless the person chose bigger text in their browser */
  line-height: 1.45;
  overflow-wrap: break-word; /* a word longer than its line breaks instead of running out of its box (large text) */
  color: var(--text);
  background: var(--bg);
  min-height: 100vh;
  min-height: 100dvh;
  -webkit-tap-highlight-color: transparent;
}
h1, h2, h3, h4 { margin: 0; font-weight: 650; line-height: 1.25; }
p { margin: 0 0 8px; }
ul { list-style: none; margin: 0; padding: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: var(--accent); }
svg { display: inline-block; vertical-align: middle; }
[hidden] { display: none !important; }
.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 8px; top: -48px; background: var(--accent); color: var(--accent-text);
  padding: 8px 12px; border-radius: 8px; z-index: 100; text-decoration: none;
}
.skip-link:focus { top: 8px; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.muted { color: var(--text-2); }
.small { font-size: 0.85rem; }
.hint { display: block; color: var(--text-3); font-size: 0.8rem; margin-top: 4px; line-height: 1.35; }
.spacer { flex: 1; }
.nobr { white-space: nowrap; } /* a name with a hyphen that must not break at it (C-CDA) */
.tabular { font-variant-numeric: tabular-nums; }

/* ---------- layout ---------- */
.topbar {
  position: sticky; top: env(safe-area-inset-top, 0px); z-index: 20;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
/* Covers the inset strip above the stuck header so content never scrolls visibly behind it. */
.topbar::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 100%;
  height: env(safe-area-inset-top, 0px); background: var(--surface);
}
.topbar-inner {
  max-width: 880px; margin: 0 auto; padding: 0 16px;
  min-height: 56px; display: flex; align-items: center; gap: 8px;
}
/* The brand is a size container: the name is drawn only where it fits whole beside the logo (and the Preview pill when there is one),
   never cut to "K…". Elsewhere it is hidden from the eye and still read aloud. The logo and the pill always keep their room.
   The name is about 130 px wide; the limits below leave room for a wider font. */
.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 1.05rem; flex: 1; min-width: 28px; container: brand / inline-size; }
.brand:has(#brand-pill:not([hidden])) { min-width: 112px; }
.brand-icon { width: 28px; height: 28px; flex: none; }
.brand-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@container brand (max-width: 191.98px) {
  .brand-name { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); }
}
@container brand (max-width: 279.98px) {
  .brand:has(#brand-pill:not([hidden])) .brand-name { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); }
}
@media (max-width: 349.98px) { .topbar-inner { gap: 4px; padding: 0 8px; } }
.brand-pill {
  flex: none; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 999px; background: var(--accent-tint); color: var(--accent);
}

/* Preview / demo notice under the header (dismissed in memory only). */
.preview-banner {
  max-width: 880px; margin: 8px auto 0; padding: 4px 4px 4px 14px;
  display: flex; align-items: center; gap: 8px;
  background: var(--accent-tint); color: var(--text); border-radius: var(--radius-sm);
  font-size: 0.85rem; line-height: 1.4;
}
.preview-banner p { margin: 0; flex: 1; min-width: 0; padding: 4px 0; }
.preview-banner .icon-btn { color: var(--text-2); }
@media (max-width: 911.98px) { .preview-banner { margin-left: 16px; margin-right: 16px; } }

/* The iOS Home Screen tip (js/pwa.js countVisit, note 02 R10): in the page flow, never over it. */
.install-tip {
  max-width: 880px; margin: 8px auto 0; padding: 4px 4px 8px 14px;
  display: flex; align-items: flex-start; gap: 8px;
  background: var(--surface-2, var(--accent-tint)); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius-sm);
  font-size: 0.9rem; line-height: 1.45;
}
.install-tip-text { flex: 1; min-width: 0; }
.install-tip-title { margin: 8px 0 4px; font-weight: 700; }
.install-tip .install-steps { margin: 0 0 4px; padding-left: 1.3em; }
.install-tip .hint { margin: 0; }
.install-tip .icon-btn { color: var(--text-2); flex: none; }
@media (max-width: 911.98px) { .install-tip { margin-left: 16px; margin-right: 16px; } }

.main {
  max-width: 880px; margin: 0 auto;
  padding: 12px 16px calc(var(--tabbar-h) + 24px + env(safe-area-inset-bottom, 0px));
}
.view { display: flex; flex-direction: column; gap: 12px; }

/* ---------- the app did not start (index.html #boot-fail) ----------
   Shown with no script at all: invisible at first, visible after 8 seconds. It is a step, not a fade, so it stays on with reduced
   motion: the class's !important outranks the reduced-motion rule's `*`. js/main.js sets [hidden] once a screen is showing, and
   adds .boot-fail-now to show it at once when boot fails. */
.boot-fail {
  margin: 12px 0; padding: 4px 18px 16px; background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius); line-height: 1.5;
  visibility: hidden; animation: kh-boot-fail-show 0s linear 8s forwards !important;
}
.boot-fail.boot-fail-now { visibility: visible; animation: none !important; }
.boot-fail h2 { font-size: 1.15rem; margin: 14px 0 6px; }
.boot-fail p { margin: 8px 0; }
.boot-fail-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; }
@keyframes kh-boot-fail-show { to { visibility: visible; } }

/* ---------- tabs ---------- */
.tabs { position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  background: var(--surface); border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.tablist { display: flex; justify-content: space-around; max-width: 880px; margin: 0 auto; }
.tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-height: var(--tabbar-h); min-width: var(--tap); border: 0; background: none; color: var(--text-3);
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.01em; padding: 6px 4px; border-radius: 10px;
}
.tab-icon { width: 24px; height: 24px; flex: none; }
.tab[aria-selected="true"] { color: var(--accent); }
.tab:hover { color: var(--text); }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--tap); height: var(--tap); border-radius: 50%; border: 0; background: none; color: var(--text-2); flex: none;
}
.icon-btn svg { width: 24px; height: 24px; }
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
/* Learn (the patient handbook, js/learn.js): a book icon like the gear next to it. The header is at
   most 880 px wide and the word would squeeze out the app's name, so it is read by screen readers
   (the link is called "Learn") and shown as the tooltip, not printed. */
.learn-link { text-decoration: none; }
.learn-link .learn-text {
  position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
/* "Learn: Potassium" after a warning, an alert or the target notes (opens in a new tab). */
.learn-more { display: inline-block; margin-top: 2px; padding: 2px 0; font-weight: 600; font-size: 0.85rem; text-underline-offset: 2px; } /* ≥ 24 px tall: WCAG 2.2 target size; 44 px on touch screens (touch.css) */
.learn-more::after { content: "\00a0\2197"; content: "\00a0\2197" / ""; font-weight: 400; } /* arrow: leaves the app; not read aloud; a no-break space keeps it on the line of the last word */
#theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] #theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] #theme-toggle .icon-moon { display: inline-block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) #theme-toggle .icon-sun { display: none; }
  :root:not([data-theme="light"]) #theme-toggle .icon-moon { display: inline-block; }
}

@media (min-width: 720px) {
  :root { --tabbar-h: 0px; }
  .tabs { position: static; border: 0; background: none; padding: 0; }
  .tablist { gap: 4px; }
  .tab { flex: 0 1 auto; flex-direction: row; gap: 8px; min-height: var(--tap); padding: 0 8px; font-size: 0.95rem; }
  .tab-icon { width: 20px; height: 20px; }
  .tab[aria-selected="true"] { background: var(--accent-tint); }
  .main { padding: 20px 24px 40px; }
}

/* Six tabs and four icons need about 810 px beside the logo and the Preview pill. Below 880 px only the open tab keeps its word;
   the others are icons (still named for screen readers) so the header never runs past the window. */
@media (min-width: 720px) and (max-width: 879.98px) {
  .tab:not([aria-selected="true"]) > span { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}

/* ---------- cards & lists ---------- */
.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 14px 16px; box-shadow: var(--shadow);
}
.card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 8px; flex-wrap: wrap; }
.card-title { font-size: 1.05rem; }
.details-card > summary { cursor: pointer; font-weight: 600; min-height: 28px; padding: 4px 0; }
.details-card[open] > summary { margin-bottom: 8px; }

.list { display: flex; flex-direction: column; }
.list > li + li { border-top: 1px solid var(--border); }
.row-btn {
  width: 100%; text-align: left; border: 0; background: none; padding: 10px 4px; min-height: var(--tap);
  display: grid; grid-template-columns: 28px 1fr auto; column-gap: 12px; align-items: center; border-radius: var(--radius-sm);
}
.row-btn:hover { background: var(--surface-2); }
.row-main { min-width: 0; }
.row-title { font-weight: 600; overflow-wrap: anywhere; }
.row-sub { color: var(--text-2); font-size: 0.85rem; }
.row-nums { color: var(--text-2); font-size: 0.82rem; font-variant-numeric: tabular-nums; white-space: nowrap; display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end; max-width: 320px; }
.row-nums b { color: var(--text); font-weight: 600; }
.row-nums .n { white-space: nowrap; }
@media (max-width: 480px) {
  .row-btn { grid-template-columns: 28px 1fr; }
  .row-nums { grid-column: 2; justify-content: flex-start; max-width: none; margin-top: 2px; }
}

/* ---------- rating & level icons ---------- */
.rating { width: 22px; height: 22px; flex: none; }
.rating.green .shape { fill: var(--ok); }
.rating.yellow .shape { fill: var(--caution); }
.rating.red .shape { fill: var(--over); }
.rating .glyph { fill: #fff; }
.rating.yellow .glyph { fill: var(--caution-glyph); }
.rating.unknown .shape { fill: var(--text-2); }

.level-ok { --lv: var(--ok); --lv-text: var(--ok-text); --lv-tint: var(--ok-tint); }
.level-caution { --lv: var(--caution); --lv-text: var(--caution-text); --lv-tint: var(--caution-tint); }
.level-over { --lv: var(--over); --lv-text: var(--over-text); --lv-tint: var(--over-tint); }
/* A total that misses values some foods do not list: neither "OK" green nor a warning colour. */
.level-unknown { --lv: var(--text-2); --lv-text: var(--text); --lv-tint: var(--surface-2); }

.pill {
  display: inline-flex; align-items: center; gap: 5px; font-size: 0.75rem; font-weight: 600;
  padding: 2px 8px 2px 4px; border-radius: 999px; background: var(--lv-tint); color: var(--lv-text); white-space: nowrap;
}
.pill .rating { width: 16px; height: 16px; }
/* "+ 1 not listed": a total that misses values some foods do not list (never a bare 0). */
.not-listed { color: var(--text); font-weight: 600; }

/* ---------- buttons ---------- */
/* A button's words stay on one line while they fit; with large text a long label wraps instead of running off the screen. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--tap); padding: 0 16px; border-radius: var(--radius-sm); border: 1px solid transparent;
  font-weight: 600; text-decoration: none; text-align: center;
}
.btn svg { width: 20px; height: 20px; }
.btn.primary { background: var(--accent); color: var(--accent-text); }
.btn.primary:hover { background: var(--accent-hover); }
.btn.secondary { background: var(--surface); color: var(--text); border-color: var(--border); }
.btn.secondary:hover { background: var(--surface-2); }
.btn.danger { background: var(--over-tint); color: var(--over-text); }
.btn.danger:hover { filter: brightness(0.96); }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.55; pointer-events: none; }
.btn.danger-solid { background: var(--over-text); color: var(--surface); }
.btn.danger-solid:hover { filter: brightness(1.08); }
.link-btn { border: 0; background: none; color: var(--accent); font-weight: 600; min-height: 36px; padding: 0 8px; border-radius: 8px; }
.link-btn:hover { text-decoration: underline; }

.segmented { display: inline-flex; border: 1px solid var(--control-border); border-radius: var(--radius-sm); overflow: hidden; background: var(--surface); }
.segmented .seg {
  border: 0; background: none; min-height: 36px; min-width: 44px; padding: 0 12px; color: var(--text-2); font-weight: 600; font-size: 0.85rem;
}
.segmented .seg + .seg { border-left: 1px solid var(--border); }
.segmented .seg[aria-pressed="true"] { background: var(--accent-tint); color: var(--accent); }
/* position: relative keeps each hidden radio inside its group, so the keyboard scrolls its label into view with it. */
/* Four in a row; with large text, two rows of two, so no word is cut off. */
.meal-seg { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 4.25rem), 1fr)); width: 100%; position: relative; }
.meal-seg input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.meal-seg label {
  display: flex; align-items: center; justify-content: center; min-height: var(--tap); font-weight: 600; font-size: 0.9rem;
  color: var(--text-2); cursor: pointer; text-align: center; padding: 0 4px;
}
.meal-seg label + input + label { border-left: 1px solid var(--border); }
.meal-seg input:checked + label { background: var(--accent-tint); color: var(--accent); }
.meal-seg input:focus-visible + label { outline: 3px solid var(--focus); outline-offset: -3px; }

/* ---------- forms ---------- */
.field { display: flex; flex-direction: column; gap: 4px; min-width: 0; border: 0; padding: 0; margin: 0; }
.field label, .field legend, .field .label { font-size: 0.85rem; font-weight: 600; color: var(--text-2); }
.field legend { padding: 0; margin-bottom: 6px; }
input[type="text"], input[type="number"], input[type="search"], input[type="date"], input[type="url"], select, textarea {
  width: 100%; min-height: var(--tap); padding: 8px 12px; border-radius: var(--radius-sm);
  border: 1px solid var(--control-border); background: var(--surface); color: var(--text);
}
/* :focus-within: the calendar button inside a date or time field takes the focus without the field matching :focus. */
input:focus, input:focus-within, select:focus { outline: 3px solid var(--focus); outline-offset: 0; border-color: transparent; }
input::placeholder, textarea::placeholder { color: var(--text-3); opacity: 1; }
input[type="number"] { font-variant-numeric: tabular-nums; }
/* Two columns; one when a column would be narrower than 10rem (a narrow phone, or large text). */
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, max(10rem, calc(50% - 6px))), 1fr)); gap: 12px; }
.form-grid .span-2 { grid-column: 1 / -1; }
/* Two fields side by side whose labels may wrap differently: the boxes line up on their bottom edge. */
.form-grid.align-end { align-items: end; }
/* A field that takes the whole row on a phone, where half a row cuts its words (a select, a placeholder). */
@media (max-width: 480px) { .form-grid .span-2-narrow { grid-column: 1 / -1; } }
.range-inputs { display: flex; align-items: center; gap: 8px; }
.range-inputs input { flex: 1; }
.req { color: var(--over-text); }
.checks { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px; }
.check { display: flex; align-items: flex-start; gap: 8px; min-height: 36px; font-size: 0.9rem; font-weight: 500; color: var(--text); }
.check input { width: 20px; height: 20px; margin: 8px 0 0; flex: none; accent-color: var(--accent); }
.check .check-text { display: flex; flex-direction: column; padding-top: 7px; }
.check .hint { margin-top: 0; }
.stepper { display: flex; align-items: center; gap: 6px; }
.stepper input { flex: 1; text-align: center; min-width: 0; padding-inline: 6px; -moz-appearance: textfield; appearance: textfield; }
/* The stepper has its own − / + buttons; the native spinner only takes room from the digits. */
.stepper input::-webkit-inner-spin-button, .stepper input::-webkit-outer-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }
.step-btn {
  width: var(--tap); height: var(--tap); border-radius: var(--radius-sm); border: 1px solid var(--border); background: var(--surface);
  font-size: 1.3rem; line-height: 1; color: var(--text); flex: none;
}
.step-btn:hover { background: var(--surface-2); }
.form-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.notes { background: var(--accent-tint); border-radius: var(--radius-sm); padding: 10px 12px; margin-bottom: 12px; font-size: 0.88rem; }
.notes ul { list-style: disc; padding-left: 18px; }
.notes li + li { margin-top: 4px; }
.notes .notes-title { font-weight: 700; margin-bottom: 4px; }
.notes .notes-learn { margin-top: 6px; }
.notes p { margin: 0; }
.notes:focus { outline: none; }
.notes:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- toast ---------- */
.toast {
  position: fixed; left: 50%; bottom: calc(var(--tabbar-h) + 16px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%) translateY(20px);
  z-index: 60; background: var(--text); color: var(--bg); padding: 10px 14px; border-radius: 10px; font-size: 0.9rem;
  max-width: min(92vw, 480px); box-shadow: var(--shadow); opacity: 0; pointer-events: none; transition: opacity 0.2s, transform 0.2s;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); } /* text only: never takes a tap from what is under it */
.toast.error { background: var(--over-solid); color: #fff; }
.toast.ok { background: var(--ok-solid); color: #fff; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ---------- badges ---------- */
.badge {
  display: inline-flex; align-items: center; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase;
  padding: 1px 7px; border-radius: 999px; margin-left: 8px; vertical-align: middle; white-space: nowrap;
}
.badge.planned { color: var(--accent); border: 1.5px dashed var(--accent); background: var(--accent-tint); }
.badge.today { background: var(--accent); color: var(--accent-text); margin-left: 0; }
.badge.dialysis { background: var(--surface-3); color: var(--text-2); margin-left: 0; }
.rating.dashed { color: var(--text-3); }
