/* ============================================================
   Nurtra — acichromatic ledger redesign
   Achromatic chrome, one chart hue, flat surfaces.
   ============================================================ */

:root {
  --ground: #f8f8f8;
  --surface: #ffffff;
  --surface-2: #f0f0f0;
  --surface-3: #e8e8e8;
  --raised: #eeeeee;
  --border: #e6e6e6;
  --rule: #f0f0f0;
  --control: #d4d4d4;
  --text: #0a0a0a;
  --muted: #6b6b6b;
  --accent: #141414;
  --positive: #2e7d32;
  --negative: #c4242a;
  --warning: #92400e;
  --chart: #1d5fbf;
  --radius-card: 8px;
  --radius-control: 6px;
  --radius: 12px;
  --radius-sm: 8px;
  --gap: 12px;
  --pad: 24px;
  --control-height: 36px;
  --fs-title: 24px;
  --fs-section: 16px;
  --fs-kpi: 30px;
  --fs-body: 14px;
  --fs-small: 12px;
  /* Aliases kept for legacy references still in the stylesheet */
  --text-muted: var(--muted);
  --emerald: var(--positive);
  --emerald-soft: rgba(46, 125, 50, 0.12);
  --emerald-track: rgba(46, 125, 50, 0.15);
  --warm: var(--warning);
  --warm-soft: rgba(146, 64, 14, 0.14);
  --danger: var(--negative);
  --info: var(--chart);
  --shadow-sm: 0 1px 2px rgba(10, 10, 10, 0.06);
  --shadow-md: 0 8px 24px -12px rgba(10, 10, 10, 0.18);
  --ring-track: rgba(10, 10, 10, 0.08);
  --glass-bg: rgba(248, 248, 248, 0.82);
  --glass-border: rgba(230, 230, 230, 0.72);
  --glass-blur: 14px;
  --glass-sat: 160%;
  --glass-shadow: 0 8px 32px -8px rgba(10, 10, 10, 0.14);
}

/* ---- Global Page & Card Animations ------------------------- */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Disabled body/card animation on mobile to prevent blank screen rendering bugs */

::view-transition-old(root) {
  animation: 0.2s cubic-bezier(0.4, 0, 1, 1) both fade-out;
}

::view-transition-new(root) {
  animation: 0.3s cubic-bezier(0, 0, 0.2, 1) both fade-in;
}

@keyframes fade-out {
  to { opacity: 0; }
}

@keyframes fade-in {
  from { opacity: 0; }
}

/* Achromatic ledger dark mode: swap light tokens for inky equivalents.
   Theme toggle swaps this single attribute; View Transitions fade
   between the two states captured in app.js. */
html[data-theme="dark"] {
  --ground: #0a0a0a;
  --surface: #141414;
  --surface-2: #292929;
  --surface-3: #1f1f1f;
  --raised: #1f1f1f;
  --border: #262626;
  --rule: #1f1f1f;
  --control: #404040;
  --text: #ededed;
  --muted: #a3a3a3;
  --accent: #ffffff;
  --positive: #4ade80;
  --negative: #f87171;
  --warning: #fbbf24;
  --chart: #3b82f6;
  /* Dark-mode aliases for legacy refs */
  --text-muted: var(--muted);
  --emerald: var(--positive);
  --emerald-soft: rgba(74, 222, 128, 0.12);
  --emerald-track: rgba(74, 222, 128, 0.15);
  --warm: var(--warning);
  --warm-soft: rgba(251, 191, 36, 0.14);
  --danger: var(--negative);
  --info: var(--chart);
  --ring-track: rgba(237, 237, 237, 0.08);
  --glass-bg: rgba(20, 20, 20, 0.82);
  --glass-border: rgba(38, 38, 38, 0.72);
}

/* Smooth crossfade / circular wipe saat theme berubah (View Transitions API) */
::view-transition-old(root) {
  animation: fade-out 0.4s cubic-bezier(0.22, 1, 0.36, 1) reverse;
}
::view-transition-new(root) {
  animation: fade-in 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes fade-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* Fallback saat View Transitions API belum didukung */
html, body, .topbar, .card, .btn, .sheet, input, select, textarea {
  transition: background-color 0.35s ease, border-color 0.35s ease, color 0.35s ease, fill 0.35s ease, stroke 0.35s ease;
}

/* Transisi smooth untuk perubahan theme */
body,
.topbar,
.card,
.bd,
.btn,
.sheet,
.acct-menu,
.food-row,
.stat,
.form-grid,
input,
select,
textarea {
  transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
}

/* Support View Transitions API untuk efek smooth / circular sweep */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 0.4s;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family:
    "Geist",
    "Inter",
    system-ui,
    -apple-system,
    "Segoe UI",
    sans-serif;
  -webkit-font-smoothing: antialiased;
  line-height: 1.5;
}

.app {
  max-width: 520px;
  margin: 0 auto;
  min-height: 100dvh;
  padding: 0 16px 64px;
  position: relative;
  z-index: 1;
}

/* ---- Numbers get weight ----------------------------------- */
h1,
h2,
h3 {
  margin: 0;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -0.02em;
}

h1 { font-size: var(--fs-title); }
h2 { font-size: 18px; }
h3 { font-size: 15px; }

p { line-height: 1.55; }

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
}

/* ---- Top bar ---------------------------------------------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 14px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  /* Nav buttons claim their natural width; the brand takes what's left. It
     must be allowed to shrink, otherwise the date range under "Laporan"
     pushed the action buttons off-screen on narrow phones. */
  min-width: 0;
  flex: 1 1 auto;
}

.brand > div {
  min-width: 0;
  flex: 1 1 auto;
}

/* Mobile: brand wraps nicely when space is tight */
@media (max-width: 420px) {
  .brand {
    flex-wrap: wrap;
  }
  .brand h1 {
    max-width: 8rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .brand .date-label {
    margin-top: 2px;
  }
}

.brand h1 {
  font-size: 1.15rem;
  font-weight: 800;
  /* Sub-pages have longer titles ("Laporan Mingguan"); keep the topbar
     balanced by letting the title shrink before the nav buttons do. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 11rem;
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 6px;
  background: var(--accent);
  color: var(--surface);
  font-weight: 800;
  font-size: 0.9rem;
}

.date-label {
  font-size: 0.75rem;
  color: var(--text-muted);
  /* The date range wrapped to two stubby lines at 360px. Keep it on one
     line; the topbar can wrap the header itself if it must. */
  white-space: nowrap;
}

.date-label.neon {
  color: var(--text-muted);
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  /* Never let the nav buttons be squeezed off-screen; the brand shrinks
     first (see .brand). */
  flex: 0 0 auto;
}

/* Nav buttons run tighter than body buttons so three links + auth + theme
   fit the 488px content width without the brand colliding. */
.topbar-actions .btn {
  padding: 7px 10px;
  font-size: 0.82rem;
}

/* ---- Buttons ---------------------------------------------- */
.btn {
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 6px;
  padding: 8px 14px;
  font-weight: 600;
  font-size: 0.86rem;
  color: var(--text);
}

.btn-primary {
  background: var(--accent);
  color: var(--surface);
  border: 1px solid var(--accent);
}

/* ---- Account dropdown ------------------------------------- */

.acct-wrap {
  position: relative;
  display: flex;
}

.btn-acct {
  display: flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 999px;
  padding: 4px 10px 4px 4px;
  font-weight: 700;
  font-size: 0.8rem;
  color: var(--text);
}

.btn-acct:hover {
  border-color: var(--emerald);
}

.acct-caret {
  color: var(--text-muted);
  transition: transform 0.15s ease;
}

.acct-wrap.open .acct-caret {
  transform: rotate(180deg);
}

/* Initials circle; emerald when signed in, neutral when anonymous. */
.acct-avatar {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--raised);
  color: var(--text);
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.btn-acct.signed-in .acct-avatar {
  background: var(--chart);
  color: #ffffff;
}

.acct-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 60;
  min-width: 208px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px;
}

.acct-greeting {
  padding: 8px 10px 10px;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.acct-greeting b {
  color: var(--text);
  font-weight: 800;
}

.acct-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--text);
  font-size: 0.85rem;
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  font-family: inherit;
}

/* display:flex above would otherwise beat the UA style for [hidden],
   keeping Masuk/Daftar visible after login. Re-establish display:none. */
.acct-menu [hidden] {
  display: none !important;
}

/* Same specificity trap as .acct-menu: display:flex on these would render
   the chip/sheet even while [hidden]. */
.fasting-chip[hidden],
.sheet[hidden],
.sheet-backdrop[hidden] {
  display: none !important;
}

.acct-item:hover {
  background: var(--surface-2);
}

.acct-item .acct-ico {
  width: 18px;
  text-align: center;
  font-size: 0.85rem;
}

.acct-item.danger {
  color: var(--danger);
}

.acct-item.danger:hover {
  background: rgba(239, 68, 68, 0.1);
}

.btn-ghost {
  border-color: transparent;
  background: transparent;
  color: var(--text-muted);
}

.btn-ghost:hover {
  color: var(--text);
  border-color: var(--border);
}

.btn-tiny {
  padding: 5px 10px;
  font-size: 0.78rem;
  border-radius: 9px;
}

.btn-wide {
  width: 100%;
  padding: 12px;
  font-size: 0.92rem;
}

.icon-only {
  padding: 8px 10px;
  font-size: 1rem;
  line-height: 1;
}

.btn.warm {
  border-color: rgba(245, 158, 11, 0.5);
  color: var(--warm);
}

/* ---- Cards ------------------------------------------------- */
.view {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding-bottom: 24px;
}

/* Profile + report only: the sticky topbar sits flush against the first
   card otherwise. The dashboard is excluded via its #viewDashboard id —
   its hero card has its own spacing and this gap looked wrong there. */
.view:not(#viewDashboard) {
  padding-top: 20px;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 16px;
  position: relative;
}

.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 12px;
}

.card-sub {
  font-size: 0.75rem;
  color: var(--text-muted);
}

/* ---- Hero ring --------------------------------------------- */
.hero-card {
  position: relative;
  display: grid;
  place-items: center;
  padding: 20px 16px 8px;
  overflow: hidden;
}

.hero-card > * {
  position: relative;
}

.ring {
  width: min(66vw, 240px);
  height: auto;
  transform: rotate(0deg);
}

.ring-track {
  fill: none;
  stroke: var(--ring-track);
  stroke-width: 16;
}

.ring-progress {
  fill: none;
  stroke: var(--chart);
  stroke-width: 16;
  stroke-linecap: round;
  transition:
    stroke-dashoffset 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    stroke 0.3s ease;
}

.ring-progress.over {
  stroke: var(--danger);
}

.hero-inner {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  text-align: center;
  gap: 2px;
}

.hero-label {
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.hero-number {
  font-size: clamp(2.4rem, 9vw, 3.2rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
}

.hero-sub {
  font-size: 0.8rem;
  color: var(--text-muted);
}

/* ---- Breakdown chips --------------------------------------- */
.hero-breakdown {
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: 6px;
}

.bd {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 6px;
}

.bd-k {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

.bd-v {
  font-weight: 800;
  font-size: 1.02rem;
  font-variant-numeric: tabular-nums;
}

.bd-v.warm {
  color: var(--warm);
}

.bd-sep {
  align-self: center;
  color: var(--text-muted);
  font-weight: 700;
}
/* The "Terbakar" segment sits beside the equation as an informational stat,
   not part of it — a softer separator keeps the two groups visually apart. */
.bd-sep-soft {
  color: var(--glass-border);
  font-weight: 400;
  font-size: 0.9rem;
  align-self: center;
}

/* display:flex above would beat the UA [hidden] rule, so the banner would
   stay visible after login even though .hidden was set to true. */
.auth-banner[hidden] {
  display: none !important;
}

/* ---- Anonymous banner: login nudge on the dashboard ------------------ */
.auth-banner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding: 11px 14px;
  border-radius: var(--radius);
  background: var(--emerald-soft);
  border: 1px solid rgba(16, 185, 129, 0.3);
}
.auth-banner-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-size: 0.8rem;
  color: var(--text-muted);
  flex: 1 1 200px;
  min-width: 0;
}
.auth-banner-text strong {
  color: var(--text);
  font-size: 0.88rem;
}
.auth-banner-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

/* Phone (~360-400px): keep the two buttons on one row, not scattered.
   flex-wrap puts them at opposite edges or stacks them awkwardly, and
   a wrapping <a> doesn't shrink-to-fit so they overflow the banner. */
@media (max-width: 560px) {
  .auth-banner {
    flex-wrap: nowrap;
  }
  .auth-banner-text {
    flex: 1 1 auto;
    min-width: 0;
  }
  .auth-banner-text span {
    overflow-wrap: anywhere;
  }
}

/* ---- Photo recognition -------------------------------------- */
.photo-preview {
  display: flex;
  align-items: center;
  gap: 10px;
}
.photo-preview img {
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: 10px;
  border: 1px solid var(--border);
  flex: 0 0 auto;
}
.photo-status {
  font-size: 0.8rem;
  color: var(--text-muted);
}

.photo-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.photo-head strong {
  font-size: 0.88rem;
}
.photo-source {
  font-size: 0.72rem;
  color: var(--text-muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 1px 8px;
}
.photo-all {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 0.75rem;
  color: var(--text-muted);
  cursor: pointer;
  margin-right: auto;
}

/* Each detected item is a <label> row: checkbox + name + kcal. */
.food-check {
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, opacity 0.15s;
}
.food-check input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: var(--emerald);
  flex: 0 0 auto;
}
.food-check:not(:has(input:checked)) {
  opacity: 0.5;
}
.food-check:hover {
  border-color: var(--emerald);
}
.photo-total {
  margin-top: 8px;
  font-size: 0.78rem;
  color: var(--text-muted);
  text-align: center;
}
#btnPhotoAddAll:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ---- Fasting chip ------------------------------------------ */
.fasting-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 9px 14px;
  border-radius: 999px;
  background: var(--emerald-soft);
  border: 1px solid rgba(16, 185, 129, 0.3);
  font-size: 0.82rem;
  font-weight: 600;
  text-align: center;
  /* "Jendela makan 16:8 · 12:00–20:00 · Makan sekarang" is a long single
     string; on a 360px phone it overflowed the pill. Keep dot + text on
     ONE line and let the chip grow downward — never wrap them apart. */
  line-height: 1.4;
}

@media (max-width: 560px) {
  .fasting-chip {
    flex-wrap: nowrap;
    justify-content: flex-start;
    border-radius: 14px;
    font-size: 0.78rem;
    text-align: left;
  }

  #fastingText {
    flex: 1 1 auto;
    min-width: 0;
    /* The full status ("Puasa 16:8 · makan 12:00–20:00 · di luar jendela
       makan") wraps to three lines at 360px and pushes the dot far away.
       Truncate instead so the pill stays one tidy line. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--emerald);
  box-shadow: 0 0 0 4px var(--emerald-track);
}

.dot.fasting {
  background: var(--warm);
  box-shadow: 0 0 0 4px var(--warm-soft);
}

/* Outside the eating window: the chip flips from green to red so the fasting
   state reads at a glance, not just from the small dot. */
.fasting-chip.is-fasting {
  background: rgba(239, 68, 68, 0.1);
  border-color: rgba(239, 68, 68, 0.4);
  color: var(--danger);
}
.fasting-chip.is-fasting .dot.fasting {
  background: var(--danger);
  box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.15);
}

/* The whole Log Makanan card gets a red wash + warning header while fasting,
   so logging a meal during the window still works but clearly breaks the
   fast. */
#mealCard.is-fasting {
  border-color: rgba(239, 68, 68, 0.45);
  /* Cards paint from --glass-bg, so override it explicitly for the red wash. */
  background: rgba(239, 68, 68, 0.05) !important;
}
#mealCard.is-fasting .card-head h2::after {
  content: " ⦻ di luar jendela makan";
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--danger);
  vertical-align: 1px;
}
#mealCard.is-fasting .empty-meal {
  color: var(--danger);
}
#mealCard.is-fasting .btn-tiny {
  border-color: rgba(239, 68, 68, 0.4);
  color: var(--danger);
}
#mealCard.is-fasting .btn-tiny:hover {
  background: rgba(239, 68, 68, 0.1);
}

/* ---- Macro bars -------------------------------------------- */
.macro-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.macro-row {
  display: grid;
  grid-template-columns: 92px 1fr 74px;
  align-items: center;
  gap: 10px;
}

.macro-name {
  font-size: 0.82rem;
  font-weight: 600;
}

.macro-name small {
  display: block;
  font-weight: 500;
  color: var(--text-muted);
  font-size: 0.68rem;
  /* The macro row is narrow on a 360px phone; "prioritas utama" forced the
     label onto three lines and made the macro bars misalign with each
     other. Keep it on one line and let the bar take the width it needs. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.macro-bar {
  height: 10px;
  border-radius: 999px;
  background: var(--raised);
  overflow: hidden;
}

.macro-fill {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  transition: width 0.8s cubic-bezier(0.16, 1, 0.3, 1);
  position: relative;
  overflow: hidden;
}

.macro-fill::after {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0; bottom: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
  transform: translateX(-100%);
  animation: macroSweep 2.5s ease-in-out infinite;
}

@keyframes macroSweep {
  0% { transform: translateX(-100%); }
  50% { transform: translateX(100%); }
  100% { transform: translateX(100%); }
}

.macro-fill.protein {
  background: var(--chart);
}

.macro-fill.carb {
  background: var(--muted);
}

.macro-fill.fat {
  background: var(--accent);
}

/* Slow gradient sweep — keeps the bars from looking like flat paint. */
@keyframes shimmer {
  from {
    background-position: 200% 0;
  }
  to {
    background-position: -200% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .macro-fill {
    animation: none;
    background-size: 100% 100%;
  }
}

.macro-val {
  text-align: right;
  font-size: 0.78rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.macro-val small {
  color: var(--text-muted);
  font-weight: 500;
}

/* ---- Meal sections ----------------------------------------- */
.meal-section {
  border-top: 1px solid var(--border);
  padding: 12px 0;
}

.meal-section:first-child {
  border-top: none;
  padding-top: 0;
}

.meal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.meal-head h3 {
  font-size: 0.9rem;
}

.meal-kcal {
  font-size: 0.78rem;
  color: var(--text-muted);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.meal-items {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.add-btn {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  border-radius: 9px;
  color: var(--emerald);
  font-weight: 800;
  font-size: 1.05rem;
  line-height: 1;
  /* Was flush against the last meal item — give it air so the log and its
     trigger read as separate things. */
  margin-top: 8px;
  transition:
    transform 0.12s ease,
    background 0.15s ease,
    border-color 0.15s ease;
}

.add-btn:hover {
  border-color: var(--emerald);
  background: var(--emerald-soft);
  transform: scale(1.08);
}

.add-btn:active {
  transform: scale(0.94);
}

.meal-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: var(--surface-2);
  border-radius: 10px;
  padding: 8px 10px;
  font-size: 0.83rem;
  /* Pop-in when a new entry is added. The JS re-renders the whole list on
     add, so every row animates — kept short (0.2s) to stay playful, not
     annoying, on a long list. */
  animation: itemPop 0.22s cubic-bezier(0.22, 1, 0.36, 1) both;
  transition:
    transform 0.12s ease,
    background 0.15s ease;
}

.meal-item:hover {
  transform: translateX(2px);
  background: var(--emerald-soft);
}

@keyframes itemPop {
  from {
    opacity: 0;
    transform: translateY(6px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.meal-item .mi-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.meal-item .mi-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

.icon-btn {
  border: none;
  background: transparent;
  color: var(--text-muted);
  padding: 2px 4px;
  border-radius: 6px;
  font-size: 0.85rem;
}

.icon-btn:hover {
  color: var(--danger);
  background: rgba(239, 68, 68, 0.08);
}

.tag-vol {
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  color: var(--emerald);
  background: var(--emerald-soft);
  border-radius: 5px;
  padding: 1px 5px;
}

/* ---- Named meal groups ------------------------------------- */
.meal-group {
  flex-direction: column;
  align-items: stretch;
  background: var(--surface-3, var(--surface-2));
  border: 1px solid rgba(16, 185, 129, 0.35);
}
.mi-group-row {
  display: flex;
  align-items: center;
  /* caret hugs the group name; kcal + buttons keep together on the right */
  justify-content: flex-start;
  gap: 4px;
}
.mi-group-row .mi-name {
  flex: 1 1 auto;
  min-width: 0;
}
.mi-group-row .mi-meta {
  flex: 0 0 auto;
  gap: 4px;
}
.mi-caret {
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 0.95rem;
  line-height: 1;
  /* 30px keeps it inside a compact row while staying a comfortable tap
     target on mobile — the old 20px was too small to hit reliably */
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  flex: 0 0 auto;
  cursor: pointer;
  /* The glyph spins with the expand/collapse state rather than swapping
     between two characters, so the toggle reads as one continuous motion. */
  transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.mi-caret.is-open {
  transform: rotate(180deg);
}
.mi-caret:hover {
  color: var(--emerald);
  background: var(--emerald-soft);
}
.mi-group-items {
  display: flex;
  flex-direction: column;
  gap: 3px;
  overflow: hidden;
  /* Collapsed: no border, no box, scaled out of view. Height is driven by
     max-height rather than the `hidden` attribute because toggling display
     does not reliably restart a CSS animation, so the list would freeze at
     opacity 0. The class on the parent row (is-open) transitions it open. */
  max-height: 0;
  opacity: 0;
  margin-top: 0;
  padding-top: 0;
  border-top: 1px dashed transparent;
  transform-origin: top center;
  transform: translateY(-6px);
  transition:
    max-height 0.3s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.24s ease,
    transform 0.3s cubic-bezier(0.22, 1, 0.36, 1),
    margin-top 0.3s ease,
    padding-top 0.3s ease,
    border-top-color 0.3s ease;
}
.meal-group.is-open .mi-group-items {
  /* Generous ceiling so a long group never clips; the easing still reads
     as a quick unfold for the common 2-5 item case. */
  max-height: 500px;
  opacity: 1;
  transform: none;
  margin-top: 6px;
  padding-top: 6px;
  border-top-color: var(--border);
}

/* Members fade and rise one after the other for a cascade effect. */
.mi-group-items > .mi-sub {
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.22s ease, transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
}
.meal-group.is-open .mi-group-items > .mi-sub {
  opacity: 1;
  transform: none;
}
.meal-group.is-open .mi-group-items > .mi-sub:nth-child(1) { transition-delay: 0.03s; }
.meal-group.is-open .mi-group-items > .mi-sub:nth-child(2) { transition-delay: 0.06s; }
.meal-group.is-open .mi-group-items > .mi-sub:nth-child(3) { transition-delay: 0.09s; }
.meal-group.is-open .mi-group-items > .mi-sub:nth-child(4) { transition-delay: 0.12s; }
.meal-group.is-open .mi-group-items > .mi-sub:nth-child(5) { transition-delay: 0.15s; }
.meal-group.is-open .mi-group-items > .mi-sub:nth-child(n + 6) { transition-delay: 0.18s; }
/* Match the caret's hit area so all three controls in a group row are
   equally easy to tap. */
.meal-group .icon-btn {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  font-size: 0.9rem;
  cursor: pointer;
}
.mi-sub {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 0.75rem;
  color: var(--text-muted);
  padding-left: 34px;
}
.mi-sub-kcal {
  font-variant-numeric: tabular-nums;
}
.tag-grp {
  font-size: 0.6rem;
  font-weight: 800;
  color: var(--text-muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0 5px;
  vertical-align: 1px;
}

/* Group-name field inside the portion editor */
.field-group {
  margin-top: 10px;
}
.field-label {
  font-size: 0.72rem;
  color: var(--text-muted);
  font-weight: 600;
}
.photo-group-name {
  margin: 12px 0 4px;
}

.empty-meal {
  font-size: 0.78rem;
  color: var(--text-muted);
  padding: 4px 0 6px;
}

/* ---- Exercise list ----------------------------------------- */
.exercise-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.exercise-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: var(--warm-soft);
  border: 1px solid rgba(245, 158, 11, 0.28);
  border-radius: 10px;
  padding: 9px 12px;
  font-size: 0.83rem;
}

.exercise-item .ex-kcal {
  color: var(--warm);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

/* ---- Report ------------------------------------------------- */
.report-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.report-head h2 {
  font-size: 1.1rem;
  font-weight: 800;
  flex: 1;
}

/* The week select previously inherited a transparent surface and blended
   into the card background. Give it an explicit surface + border and an
   emerald accent so it reads as an interactive control. */
.report-head select {
  appearance: none;
  -webkit-appearance: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 34px 8px 12px;
  font-size: 0.84rem;
  font-weight: 700;
  color: var(--text);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  /* chevron */
  background-image:
    linear-gradient(45deg, transparent 50%, var(--emerald) 50%),
    linear-gradient(135deg, var(--emerald) 50%, transparent 50%);
  background-position:
    calc(100% - 17px) 50%,
    calc(100% - 12px) 50%;
  background-size:
    5px 5px,
    5px 5px;
  background-repeat: no-repeat;
}

.report-head select:hover {
  border-color: var(--emerald);
}

.report-head select:focus {
  outline: none;
  border-color: var(--emerald);
  box-shadow: 0 0 0 3px var(--emerald-soft);
}

.report-head select option {
  background: var(--surface);
  color: var(--text);
}

.chart {
  width: 100%;
  height: auto;
  display: block;
  /* viewBoxes are 640 wide; on narrow screens the auto height makes the
     charts short and cramped. Pin a sensible min-height so axis labels
     and the bar values stay legible. */
  min-height: 220px;
}

.legend {
  display: flex;
  gap: 14px;
  margin-top: 8px;
  font-size: 0.74rem;
  color: var(--text-muted);
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
}

.sw {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  display: inline-block;
}

.sw.emerald {
  background: var(--emerald);
}
.sw.warm {
  background: var(--warm);
}
.sw.line {
  background: transparent;
  border-top: 2px solid var(--text);
  height: 0;
  border-radius: 0;
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 8px;
  text-align: center;
}

.stat-k {
  display: block;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  margin-bottom: 4px;
}

.stat-v {
  font-size: 1.15rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

/* ---- Insights ----------------------------------------------- */
.badge {
  font-size: 0.64rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--emerald-soft);
  color: var(--emerald);
}

.insight-summary {
  margin: 0 0 12px;
  font-size: 0.88rem;
  color: var(--text-muted);
}

.insight-list,
.rec-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.insight-item {
  border-left: 3px solid var(--info);
  background: var(--surface-2);
  border-radius: 0 10px 10px 0;
  padding: 9px 12px;
  font-size: 0.83rem;
}

.insight-item.warning {
  border-left-color: var(--warm);
}
.insight-item.alert {
  border-left-color: var(--danger);
}

.insight-item strong {
  display: block;
  margin-bottom: 2px;
}

.rec-item {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 0.83rem;
}

.rec-item .rec-cat {
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--emerald);
  font-weight: 800;
}

.rec-item p {
  margin: 2px 0;
}

.rec-item .rec-why {
  color: var(--text-muted);
  font-size: 0.77rem;
}

/* ---- Forms --------------------------------------------------- */
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
}

.form-grid label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-muted);
}

.form-grid input,
.form-grid select,
.quick-form input,
.quick-form select,
textarea,
.field input {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 9px 11px;
  font-size: 0.88rem;
  color: var(--text);
  outline: none;
}

.form-grid input:focus,
.form-grid select:focus,
.quick-form input:focus,
textarea:focus,
#foodSearch:focus {
  border-color: var(--emerald);
  box-shadow: 0 0 0 3px var(--emerald-track);
}

.form-result {
  grid-column: 1 / -1;
  font-size: 0.8rem;
  color: var(--text-muted);
  background: var(--surface-2);
  border-radius: 10px;
  padding: 10px 12px;
  white-space: pre-line;
}

/* Two columns squeeze fields to ~160px and overflow long option labels
   on a ~360px phone. Stack to one column under 560px. */
@media (max-width: 560px) {
  .form-grid {
    grid-template-columns: 1fr;
  }
}

/* ---- Bottom sheets ------------------------------------------- */
.sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 60;
}

.sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 70;
  background: var(--surface);
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: 12px 12px 0 0;
  padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
  max-height: 86dvh;
  overflow-y: auto;
}

.sheet-grip {
  width: 40px;
  height: 4px;
  border-radius: 999px;
  background: var(--border);
  margin: 4px auto 10px;
  /* Make it read as a handle, not decoration. Slightly taller + wider hit
     area so a finger drag on mobile registers reliably. */
  cursor: grab;
  touch-action: none;
  position: relative;
  padding: 6px 0;
  margin-top: 10px;
}

/* Visual pill stays 4px; the padding above/below expands the touch target
   without making the grip look chunky. Background is drawn on an inner
   pseudo so only the 4px center reads as the handle. */
.sheet-grip::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 40px;
  height: 4px;
  border-radius: 999px;
  background: var(--border);
}

.sheet.dragging {
  /* During a drag the sheet follows the finger exactly; spring back is
     applied on release via .sheet-settle's transition. */
  transition: none !important;
  will-change: transform;
}

.sheet-settle {
  /* Spring back after a drag. Slightly overshooting cubic-bezier makes the
     snap feel physical rather than linear. */
  transition: transform 0.34s cubic-bezier(0.34, 1.4, 0.5, 1);
}

.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.sheet-head h3 {
  font-size: 1rem;
}

.sheet-search {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}

#foodSearch {
  flex: 1;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 10px 12px;
  font-size: 0.9rem;
  outline: none;
}

.chips-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.chip {
  border: 1px solid var(--border);
  background: var(--surface-2);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 0.76rem;
  font-weight: 600;
}

.chip:hover {
  border-color: var(--emerald);
}

.chip .chip-star {
  color: var(--warm);
  margin-right: 3px;
}

.search-results {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 12px;
  max-height: 44dvh;
  overflow-y: auto;
}

.food-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  border-radius: 12px;
  padding: 10px 12px;
  text-align: left;
  width: 100%;
}

.food-row:hover {
  border-color: var(--emerald);
}

.food-row .fr-name {
  font-weight: 700;
  font-size: 0.86rem;
}

.food-row .fr-sub {
  font-size: 0.72rem;
  color: var(--text-muted);
}

.food-row .fr-kcal {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---- Portion box --------------------------------------------- */
.portion-box {
  border-top: 1px solid var(--border);
  padding-top: 12px;
}

.portion-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}

.portion-kcal {
  font-size: 1.35rem;
  font-weight: 800;
  color: var(--emerald);
  font-variant-numeric: tabular-nums;
}

.presets {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.preset {
  border: 1px solid var(--border);
  background: var(--surface-2);
  border-radius: 9px;
  padding: 6px 12px;
  font-size: 0.78rem;
  font-weight: 700;
}

.preset.active {
  background: var(--emerald);
  border-color: var(--emerald);
  color: #04120d;
}

#portionRange,
#exDuration {
  width: 100%;
  accent-color: var(--emerald);
}

.range-labels {
  display: flex;
  justify-content: space-between;
  font-size: 0.72rem;
  color: var(--text-muted);
  margin: 4px 0 14px;
}

/* ---- Quick form ----------------------------------------------- */
.quick-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.quick-form label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-muted);
}

.ai-parse-box {
  /* Stack: textarea+button row on top, results below — flex-wrap would also
     work, but a vertical group keeps the results full-width, which matters
     because the result rows are themselves flex rows of food cards. */
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--emerald-soft);
  border: 1px solid rgba(16, 185, 129, 0.3);
  border-radius: 12px;
  padding: 10px;
  margin-bottom: 10px;
}

/* display:flex above would beat the UA [hidden] rule, so toggling
   .hidden=true silently does nothing (same pitfall as .auth-banner). */
.ai-parse-box[hidden] {
  display: none !important;
}

.ai-parse-box > .ai-parse-input {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}

.ai-parse-box textarea {
  flex: 1;
  resize: vertical;
  min-height: 44px;
  /* textarea needs an explicit width basis or flex can collapse it in some engines */
  width: 100%;
  min-width: 0;
}

.ai-parse-box #btnAIParseGo {
  flex: none;
  align-self: stretch;
}

#aiParseResult {
  font-size: 0.78rem;
  color: var(--text-muted);
  width: 100%;
  margin-top: 6px;
}

/* ---- Toast ----------------------------------------------------- */
.toast {
  position: fixed;
  bottom: 18px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  border: 1px solid var(--glass-border);
  color: var(--text);
  border-radius: 12px;
  padding: 10px 16px;
  font-size: 0.83rem;
  font-weight: 600;
  z-index: 90;
  box-shadow: var(--glass-shadow);
  max-width: 90vw;
  text-align: center;
  animation: toastIn 0.26s cubic-bezier(0.22, 1, 0.36, 1);
}

@keyframes toastIn {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(12px) scale(0.96);
  }
  to {
    opacity: 1;
    transform: translateX(-50%) translateY(0) scale(1);
  }
}

html[data-theme="dark"] .toast {
  background: var(--glass-bg);
  border-color: var(--glass-border);
  color: var(--text);
}

/* ---- Sub-pages (profile.html / report.html) ---------------------------- */
.brand-link {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  color: var(--text);
  font-size: 1.1rem;
  font-weight: 800;
  text-decoration: none;
}

.brand-link:hover {
  background: var(--surface-2);
}

.view-form {
  max-width: 640px;
  margin: 0 auto;
  width: 100%;
}

.page-intro {
  font-size: 0.85rem;
  color: var(--text-muted);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 16px;
  margin: 0;
}

@media (min-width: 640px) {
  .stat-grid {
    grid-template-columns: repeat(3, 1fr);
  }
  .sheet {
    left: 50%;
    right: auto;
    width: 520px;
    transform: translateX(-50%);
    border-radius: 22px;
  }
}
@media (max-width: 420px) {
  .macro-row {
    grid-template-columns: 76px 1fr 66px;
  }
  .stat-grid {
    grid-template-columns: 1fr;
  }
  /* The three breakdown chips (Target − Makan + Olahraga) squeeze to ~104px
     at 360px and the labels wrap ugly. Let them stack the label under the
     value and shrink the separators so the row still fits. */
  .hero-breakdown {
    gap: 4px;
  }
  .bd {
    padding: 8px 4px;
  }
  .bd-k {
    font-size: 0.6rem;
  }
  .bd-v {
    font-size: 0.92rem;
  }
  .bd-sep {
    font-size: 0.85rem;
  }
}


/* ===================== Water tracker ===================== */
.water-wrap {
  display: flex;
  align-items: center;
  gap: 18px;
  margin: 6px 0 14px;
}

/* The cup is a rounded box whose fill is a second box anchored to its
 * bottom; setting the fill's height to the goal percentage animates it. */
.water-cup {
  position: relative;
  width: 74px;
  height: 110px;
  flex: 0 0 74px;
  border-radius: 12px 12px 26px 26px;
  border: 2px solid var(--border, rgba(255, 255, 255, 0.18));
  background: rgba(56, 189, 248, 0.08);
  overflow: hidden;
  box-shadow: inset 0 -14px 24px -18px rgba(56, 189, 248, 0.9);
}

.water-fill {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 0%;
  background: linear-gradient(
    180deg,
    rgba(56, 189, 248, 0.95),
    rgba(14, 116, 190, 0.95)
  );
  transition: height 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Slight wave at the surface so the top edge is not a flat line. */
.water-fill::after {
  content: "";
  position: absolute;
  top: -5px;
  left: 0;
  right: 0;
  height: 10px;
  border-radius: 50%;
  background: rgba(125, 211, 252, 0.75);
}

/* Bubbles drift up while filling, paused once the goal is hit. */
.water-bubble {
  position: absolute;
  bottom: 0;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(186, 230, 253, 0.9);
  animation: waterBubble 2.6s ease-in infinite;
}
.water-bubble.b1 { left: 18%; animation-delay: 0s; }
.water-bubble.b2 { left: 52%; width: 5px; height: 5px; animation-delay: 0.9s; }
.water-bubble.b3 { left: 78%; width: 9px; height: 9px; animation-delay: 1.7s; }

@keyframes waterBubble {
  0% { transform: translateY(0); opacity: 0; }
  20% { opacity: 0.85; }
  100% { transform: translateY(-104px); opacity: 0; }
}

.water-cup.goal-hit .water-bubble {
  animation-play-state: paused;
}

.water-cup.goal-hit {
  animation: waterPulse 1.4s ease-out 2;
}

@keyframes waterPulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

.water-fill.full {
  background: linear-gradient(
    180deg,
    rgba(52, 211, 153, 0.95),
    rgba(5, 150, 105, 0.95)
  );
}

.water-meta { min-width: 0; }
.water-total {
  font-size: 1.45rem;
  font-weight: 800;
  line-height: 1.1;
}
.water-sub { font-size: 0.85rem; opacity: 0.65; margin-top: 2px; }

.water-btns {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.btn-glass {
  padding: 10px 4px;
  font-size: 0.88rem;
  font-weight: 700;
  border-radius: 10px;
  border: 1px solid rgba(56, 189, 248, 0.4);
  background: rgba(56, 189, 248, 0.1);
  color: inherit;
  transition: transform 0.15s ease, background 0.2s ease;
}
.btn-glass:hover { background: rgba(56, 189, 248, 0.2); }
.btn-glass:active { transform: scale(0.94); }

.btn-glass.custom span { opacity: 0.9; font-weight: 600; }

.water-log { margin-top: 12px; display: flex; flex-direction: column; gap: 2px; }

.water-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 2px;
  border-top: 1px solid var(--border, rgba(255, 255, 255, 0.08));
  animation: itemPop 0.3s ease both;
}

.wr-main { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.wr-ml { font-weight: 700; }
.wr-label {
  font-size: 0.78rem;
  opacity: 0.6;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wr-side { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.wr-time { font-size: 0.78rem; opacity: 0.5; font-variant-numeric: tabular-nums; }
.wr-del {
  width: 26px;
  height: 26px;
  border-radius: 8px;
  border: none;
  background: transparent;
  color: inherit;
  opacity: 0.45;
  font-size: 0.8rem;
  cursor: pointer;
}
.wr-del:hover { opacity: 1; background: rgba(239, 68, 68, 0.15); }

@media (prefers-reduced-motion: reduce) {
  .water-fill { transition: none; }
  .water-bubble { animation: none; }
  .water-cup.goal-hit { animation: none; }
}
