/* ==========================================================================
   MyNutriTrack — stylesheet
   ==========================================================================

   THIS FILE IS WRITTEN "MOBILE FIRST".

   What that means in plain English: the normal rules you read first are the
   PHONE design. That is the real design. Further down, in blocks that start
   with `@media (min-width: ...)`, we add extra rules that only switch on when
   the screen is BIG ENOUGH to deserve them.

   Why do it in that order? Because if you design for a big screen first and
   then try to squeeze it down, the phone always ends up feeling like an
   afterthought — cramped text, tiny buttons, things overflowing sideways. By
   starting at the phone, the phone gets the care, and the desktop just gets
   room to spread out.

   The screen size steps used here:
     (base)          up to 599px   — phones. THE PRIMARY EXPERIENCE.
     min-width 600px               — big phones held sideways, small tablets
     min-width 900px               — tablets and laptops
     min-width 1100px              — full desktop
   ========================================================================== */


/* ==========================================================================
   1. COLOUR VARIABLES
   A "variable" here is a nickname for a colour. Write --teal once, use it
   200 times. Change it here and the whole app changes at once.
   NOTE: --teal is OLIVE GREEN. The name is historical. Do not "correct" it.
   ========================================================================== */
:root {
  --bg:         #FDFAE0;  /* page background, pale cream        */
  --card:       #FFFFFF;  /* white panels                       */
  --card-hi:    #F6F1D6;  /* raised rows inside panels          */
  --well:       #F4EFCE;  /* sunken areas: inputs, bar tracks   */
  --border:     #E3DCAA;  /* every thin border, sand            */
  --teal:       #6C7839;  /* PRIMARY ACCENT — olive green       */
  --teal-deep:  #525C2A;  /* darker olive, end of gradients     */
  --carbs:      #D9A441;  /* carbohydrates — amber              */
  --protein:    #C0654B;  /* protein — terracotta               */
  --fat:        #8B5E34;  /* fat — brown                        */
  --text:       #2B3319;  /* main text, near-black olive        */
  --sub:        #71765A;  /* secondary text                     */
  --faint:      #7A7E57;  /* hints, units, placeholders         */
  --on-primary: #FBF8E6;  /* text sitting on an olive button    */

  /* See-through versions of the accents. */
  --teal-10:    rgba(108, 120, 57, 0.10);
  --teal-08:    rgba(108, 120, 57, 0.08);
  --teal-33:    rgba(108, 120, 57, 0.33);
  --teal-27:    rgba(108, 120, 57, 0.27);
  --protein-10: rgba(192, 101, 75, 0.10);
  --carbs-10:   rgba(217, 164, 65, 0.10);
  --fat-10:     rgba(139, 94, 52, 0.10);

  /* Shapes and spacing, reused everywhere so nothing drifts. */
  --r-card: 16px;
  --r-modal: 18px;
  --r-btn: 12px;
  --r-input: 10px;
  --r-round: 999px;
  --gap: 14px;            /* grows on bigger screens */
  --pad: 14px;            /* page side padding, grows too */
  --page-max: 1180px;

  /* The smallest a tappable thing is ever allowed to be. 44px is the size of
     an adult fingertip — anything smaller and people mis-tap. */
  --tap: 44px;

  /* Height of the bottom navigation bar on phones. */
  --bottomnav-h: 62px;

  /* iPhones have a rounded chin and a home bar at the bottom of the screen.
     `safe-area-inset-bottom` is a number the phone itself reports so we can
     keep our buttons above it instead of underneath it. */
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}


/* ==========================================================================
   2. RESET
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  /* Stops iOS from silently enlarging text when you rotate the phone. */
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--bg);
  background-image:
    radial-gradient(circle at 15% 0%, rgba(108,120,57,0.07), transparent 40%),
    radial-gradient(circle at 85% 20%, rgba(217,164,65,0.06), transparent 40%);
  background-attachment: fixed;
  font-family: Inter, system-ui, -apple-system, sans-serif;
  color: var(--text);
  -webkit-font-smoothing: antialiased;

  /* Nothing may ever stick out sideways and make the page slide left/right.
     Sideways scrolling is the single most common way a site feels broken on
     a phone, so it is banned outright here. */
  overflow-x: hidden;

  /* Leave room at the bottom for the phone navigation bar so the last card
     is never hidden behind it. */
  padding-bottom: calc(var(--bottomnav-h) + var(--safe-bottom));
}

h1, h2, h3, h4 { font-family: "Space Grotesk", Inter, sans-serif; margin: 0; }

button {
  font-family: Inter, sans-serif;
  /* Stops the grey flash iOS paints over anything you tap. */
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;   /* removes the 300ms tap delay */
}

img { max-width: 100%; }

::placeholder { color: var(--faint); }

/* Every NUMBER in the app wears this class so it renders in monospace.
   Monospace = every character is the same width, so digits line up neatly. */
.mono { font-family: "IBM Plex Mono", ui-monospace, monospace; }

/* Anything that must scroll sideways (a long row of chips) does it inside its
   own box, never by moving the whole page. */
.scroll-x {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;                 /* hide the bar on Firefox */
}
.scroll-x::-webkit-scrollbar { display: none; }   /* and on Safari/Chrome */


/* ==========================================================================
   3. TOP BAR
   On a phone this is just the logo and the live calorie pill. The six
   navigation links move to a bar at the BOTTOM of the screen, because that is
   where your thumb naturally rests when holding a phone one-handed.
   ========================================================================== */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(253, 250, 224, 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
  padding-top: env(safe-area-inset-top, 0px);
}

.topbar-inner {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 6px var(--pad);
  display: flex;
  align-items: center;
  gap: 10px;
}

.brand {
  display: flex;
  align-items: center;
  cursor: pointer;
  flex-shrink: 0;
  background: none;
  border: none;
  padding: 0;
}
.brand img {
  width: 108px;                /* the logo includes its own wordmark */
  height: 46px;
  object-fit: contain;
  display: block;
}

/* The row of six links. Hidden on phones — see the bottom bar instead. */
.nav { display: none; }

.nav-link {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 12px;
  border-radius: 9px;
  border: none;
  background: transparent;
  color: var(--sub);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s, color 0.15s;
}
.nav-link:hover { color: var(--teal); }
.nav-link.is-active { background: var(--card-hi); color: var(--teal); }

/* The read-only live calorie widget. On a phone it shrinks to just the
   important part: how many calories are left. */
.kcal-pill {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  padding: 7px 12px;
  border-radius: var(--r-round);
  background: var(--well);
  border: 1px solid var(--border);
  font-family: "IBM Plex Mono", monospace;
  font-size: 12px;
  flex-shrink: 0;
  white-space: nowrap;
}
.kcal-pill .eaten { color: var(--text); font-weight: 600; }
.kcal-pill .goal  { color: var(--faint); display: none; }   /* shown on tablets up */
.kcal-pill .left  { color: var(--teal); }

/* The little person button on the far right of the top bar.
   Olive-filled once you are signed in, so you can tell at a glance whether
   your data is syncing or only living on this device. */
.account-btn {
  width: 38px; height: 38px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--well);
  color: var(--sub);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: all 0.15s;
}
.account-btn:hover { border-color: var(--teal); color: var(--teal); }
.account-btn.is-in {
  background: var(--teal);
  border-color: var(--teal);
  color: var(--on-primary);
}


/* ==========================================================================
   4. BOTTOM NAVIGATION — phones only
   Six icon buttons pinned to the bottom of the screen. This is the standard
   pattern every phone app uses, because the top of a large phone cannot be
   reached without shuffling the device in your hand.
   ========================================================================== */
.bottomnav {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 50;
  display: flex;
  background: rgba(253, 250, 224, 0.96);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid var(--border);
  padding-bottom: var(--safe-bottom);
}

.bottomnav-item {
  flex: 1;
  min-width: 0;
  height: var(--bottomnav-h);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  border: none;
  background: none;
  color: var(--faint);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1px;
  cursor: pointer;
  padding: 0 2px;
  transition: color 0.15s;
}
.bottomnav-item span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.bottomnav-item.is-active { color: var(--teal); }

/* A small olive dot above the active icon, so the current tab is obvious
   even at a glance. */
.bottomnav-item.is-active::before {
  content: "";
  position: absolute;
  top: 0;
  width: 26px;
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: var(--teal);
}
.bottomnav-item { position: relative; }


/* ==========================================================================
   5. PAGE SHELL
   ========================================================================== */
.page {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: var(--pad);
}
.stack { display: flex; flex-direction: column; gap: var(--gap); }


/* ==========================================================================
   6. CARDS
   ========================================================================== */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: 16px;
}
.card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
  flex-wrap: wrap;    /* a long title + a button drop onto two lines */
}
.card-title {
  font-family: "Space Grotesk", sans-serif;
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  min-width: 0;       /* let a long title shrink rather than push the card wide */
}
.card-title.lg { font-size: 17px; }

.banner {
  background: linear-gradient(135deg, #F5F0D2, #EDE6BE);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: 16px;
}
.banner-row { display: flex; flex-direction: column; gap: 14px; }
.banner-hello { color: var(--sub); font-size: 13px; margin-bottom: 4px; }
.banner-big {
  font-family: "Space Grotesk", sans-serif;
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.2;
}
/* On a phone the two banner buttons stack and go full width — far easier to
   hit than two small buttons side by side. */
.banner-actions { display: flex; flex-direction: column; gap: 8px; }
.banner-actions > * { width: 100%; }


/* ==========================================================================
   7. BUTTONS
   Every button is at least 44px tall so it can be tapped reliably.
   ========================================================================== */
.btn {
  min-height: var(--tap);
  background: linear-gradient(135deg, var(--teal), var(--teal-deep));
  color: var(--on-primary);
  border: none;
  border-radius: var(--r-btn);
  padding: 12px 18px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  box-shadow: 0 4px 14px var(--teal-33);
  transition: transform 0.12s, box-shadow 0.15s, opacity 0.15s;
}
.btn:active:not(:disabled) { transform: scale(0.98); }
.btn:disabled {
  background: var(--well);
  color: var(--faint);
  cursor: not-allowed;
  box-shadow: none;
}

.btn-ghost {
  min-height: var(--tap);
  background: transparent;
  border: 1px solid var(--border);
  color: var(--sub);
  border-radius: var(--r-btn);
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  transition: border-color 0.15s, color 0.15s, transform 0.12s;
}
.btn-ghost:active { transform: scale(0.98); }
.btn-ghost:hover { border-color: var(--teal); color: var(--teal); }

/* The one exception to the 44px rule: small controls tucked into a card's
   heading row, which sit beside a title rather than in the flow of the page. */
.btn-sm {
  min-height: 34px;
  padding: 7px 12px;
  font-size: 11.5px;
  flex-shrink: 0;
}
.btn-block { width: 100%; }

.btn-danger {
  min-height: var(--tap);
  background: var(--protein);
  border: none;
  color: #fff;
  border-radius: var(--r-btn);
  padding: 12px 14px;
  font-weight: 700;
  font-size: 13.5px;
  cursor: pointer;
}

.btn-log {
  min-height: 38px;
  border: none;
  border-radius: 9px;
  padding: 8px 12px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  flex-shrink: 0;
  background: var(--teal-10);
  color: var(--teal);
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.btn-log.is-logged { cursor: default; opacity: 0.7; }

.link {
  margin-top: 14px;
  /* 44px is the width of an adult fingertip and the minimum tap target in
     this project (§4.2). These text links were 34px — small enough that a
     thumb regularly misses them. The text itself has not changed size; the
     invisible tappable area around it has grown. */
  min-height: var(--tap);
  color: var(--teal);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  background: none;
  border: none;
  padding: 6px 0;
  display: inline-flex;
  align-items: center;
}
.link:hover { text-decoration: underline; }


/* ==========================================================================
   8. PILLS
   Rows of pills scroll sideways inside their own strip on a phone rather than
   wrapping into a tall stack that pushes the page down.
   ========================================================================== */
.pill {
  min-height: 40px;
  padding: 9px 15px;
  border-radius: var(--r-round);
  border: 1px solid var(--border);
  background: transparent;
  color: var(--sub);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: all 0.15s;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex-shrink: 0;
}
.pill:active { transform: scale(0.97); }
.pill:hover { border-color: var(--teal); color: var(--teal); }
.pill.is-active { border-color: var(--teal); background: var(--teal-10); color: var(--teal); }
.pill.pill-carbs.is-active { border-color: var(--carbs); background: var(--carbs-10); color: var(--carbs); }
.pill.pill-fat.is-active   { border-color: var(--fat);   background: var(--fat-10);   color: var(--fat); }

.pill-row { display: flex; gap: 8px; flex-wrap: wrap; }

/* A single non-wrapping line of pills that you swipe through. */
.pill-row.swipe {
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 2px;
  /* Snap so a pill never ends up half cut off at the edge. */
  scroll-snap-type: x proximity;
}
.pill-row.swipe::-webkit-scrollbar { display: none; }
.pill-row.swipe > * { scroll-snap-align: start; }


/* ==========================================================================
   9. FORM FIELDS
   ========================================================================== */
.label {
  font-size: 12px;
  color: var(--sub);
  font-weight: 600;
  display: block;
  margin-bottom: 6px;
}

.input, .textarea, .select-trigger {
  width: 100%;
  min-height: var(--tap);
  background: var(--well);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
  padding: 12px 13px;
  color: var(--text);
  font-family: Inter, sans-serif;

  /* 16px is not a style choice — it is a rule.
     If a text box uses anything SMALLER than 16px, iPhones automatically zoom
     the whole page in when you tap it, and never zoom back out. Keeping every
     input at 16px is the only way to stop that. */
  font-size: 16px;

  outline: none;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.15s;
}
.input:focus, .textarea:focus, .select-trigger:focus {
  border-color: var(--teal);
  box-shadow: 0 0 0 3px var(--teal-10);
}
.input.mono { font-family: "IBM Plex Mono", monospace; }
.textarea { resize: none; line-height: 1.5; }

.field { position: relative; }
.field .unit {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 11.5px;
  color: var(--faint);
  pointer-events: none;
}
.field .input { padding-right: 44px; }

/* Hide the tiny up/down arrows on number boxes — they are unusable by touch. */
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type=number] { -moz-appearance: textfield; }

/* Custom dropdown. */
.select { position: relative; margin-bottom: 14px; }
.select-trigger {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 15px;
}
.select-trigger svg { transition: transform 0.15s; flex-shrink: 0; }
.select.is-open .select-trigger svg { transform: rotate(180deg); }
.select-menu {
  position: absolute;
  top: 100%; left: 0; right: 0;
  margin-top: 4px;
  z-index: 10;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-input);
  overflow: hidden;
  box-shadow: 0 10px 30px rgba(43, 51, 25, 0.2);
  display: none;
}
.select.is-open .select-menu { display: block; }
.select-option {
  min-height: var(--tap);
  display: flex;
  align-items: center;
  padding: 11px 13px;
  font-size: 14.5px;
  cursor: pointer;
  color: var(--text);
}
.select-option:active { background: var(--card-hi); }
.select-option.is-selected { color: var(--teal); background: var(--teal-08); font-weight: 600; }

/* Stacked single-choice rows. */
.choice-list { display: flex; flex-direction: column; gap: 8px; }
.choice {
  min-height: var(--tap);
  padding: 12px 13px;
  border-radius: var(--r-input);
  cursor: pointer;
  font-size: 14px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  text-align: left;
  width: 100%;
  transition: all 0.15s;
  line-height: 1.35;
}
.choice:active { transform: scale(0.99); }
.choice.is-active { border-color: var(--teal); background: var(--teal-08); color: var(--teal); font-weight: 600; }

/* Sliders. The knob is deliberately big — a small knob is miserable to drag
   with a fingertip. */
.slider-wrap { padding: 6px 0 2px; }
input[type=range] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 8px;
  border-radius: var(--r-round);
  background: var(--well);
  border: 1px solid var(--border);
  outline: none;
  margin: 10px 0;
}
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 2px 8px var(--teal-33);
  cursor: pointer;
  border: 3px solid var(--on-primary);
}
input[type=range]::-moz-range-thumb {
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--teal);
  cursor: pointer;
  border: 3px solid var(--on-primary);
}
.slider-fat::-webkit-slider-thumb { background: var(--fat); box-shadow: 0 2px 8px rgba(139,94,52,0.4); }
.slider-fat::-moz-range-thumb     { background: var(--fat); }

.slider-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 12.5px;
  color: var(--sub);
}
.slider-value { font-size: 15px; color: var(--teal); font-weight: 700; }
.slider-value.fat { color: var(--fat); }

/* Grocery checkbox. The whole row is the tap target, not just the little box. */
.check-row {
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  min-height: var(--tap);
  padding: 4px 2px;
  border-radius: 8px;
}
.check-row:active { background: var(--card-hi); }
.check-box {
  width: 22px; height: 22px;
  border-radius: 6px;
  border: 1.5px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: all 0.15s;
}
.check-row.is-checked .check-box { border-color: var(--teal); background: var(--teal); }
.check-label { font-size: 14.5px; color: var(--text); }
.check-row.is-checked .check-label { color: var(--faint); text-decoration: line-through; }


/* ==========================================================================
   10. PROGRESS BARS
   ========================================================================== */
.bar {
  background: var(--well);
  border-radius: var(--r-round);
  overflow: hidden;
  border: 1px solid var(--border);
  height: 8px;
}
.bar-fill {
  height: 100%;
  border-radius: var(--r-round);
  /* The 0.6s easing is what makes the bar glide instead of snapping. */
  transition: width 0.6s cubic-bezier(.2, .8, .2, 1);
}


/* ==========================================================================
   11. GRIDS
   On a phone EVERY grid is a single column. They only split into columns
   further down this file, once there is genuinely room for them.
   ========================================================================== */
.grid-metrics, .grid-shortcut, .grid-log, .grid-scan,
.grid-plan, .grid-recipe, .grid-profile, .grid-detail, .grid-2 {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gap);
}
/* Three small macro boxes stay side by side even on the narrowest phone —
   they are short enough to fit, and stacking them would look odd. */
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }

/* ---------------------------------------------------------------------------
   THE `min-width: 0` RULE — small line, big consequences.

   By default a grid column refuses to become narrower than the widest
   unbreakable thing inside it. So one long word, one wide button, or one line
   of "520 kcal · P 45g · C 50g · F 15g" can shove a column wider than the
   phone screen, and the right-hand edge of the card silently disappears off
   the side of the display.

   Setting `min-width: 0` gives the column permission to be as narrow as its
   column track says, and lets the content inside wrap or ellipsis instead.
   Without this line the phone layout breaks on exactly the cards that matter
   most — the meal log and the macro rows.
   --------------------------------------------------------------------------- */
.grid-metrics > *, .grid-shortcut > *, .grid-log > *, .grid-scan > *,
.grid-plan > *, .grid-recipe > *, .grid-profile > *, .grid-detail > *,
.grid-2 > *, .grid-3 > *, .stack > * {
  min-width: 0;
}


/* ==========================================================================
   12. DASHBOARD PIECES
   ========================================================================== */
.big-number {
  font-family: "IBM Plex Mono", monospace;
  font-size: 32px;
  color: var(--text);
  font-weight: 600;
  line-height: 1.1;
}
.big-number .unit { font-size: 14px; color: var(--faint); font-weight: 500; }
.big-number.center { text-align: center; margin: 10px 0; }

.bar-legend {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--faint);
  font-family: "IBM Plex Mono", monospace;
  margin-top: 6px;
}

.macro-row { margin-bottom: 14px; }
.macro-row:last-child { margin-bottom: 0; }
.macro-top {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  margin-bottom: 6px;
}
.macro-name { color: var(--sub); display: flex; align-items: center; gap: 6px; }
.macro-val  { color: var(--text); font-family: "IBM Plex Mono", monospace; }

/* The three shortcut cards. On a phone they become short wide rows rather
   than tall boxes, so all three fit on screen without a long scroll. */
.shortcut {
  cursor: pointer;
  transition: border-color 0.15s, transform 0.12s;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px;
}
.shortcut:active { transform: scale(0.99); }
.shortcut:hover { border-color: var(--teal); }
.icon-tile {
  width: 42px; height: 42px;
  border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.shortcut-body { min-width: 0; }
.shortcut-title {
  font-family: "Space Grotesk", sans-serif;
  font-size: 14.5px; font-weight: 600;
  color: var(--text); margin-bottom: 2px;
}
.shortcut-desc { font-size: 12.5px; color: var(--sub); line-height: 1.35; }

.meal-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  background: var(--card-hi);
  border-radius: 12px;
  border: 1px solid var(--border);
}
.meal-emoji {
  width: 42px; height: 42px;
  border-radius: 11px;
  background: var(--well);
  display: flex; align-items: center; justify-content: center;
  font-size: 20px; flex-shrink: 0;
}
.meal-body { flex: 1; min-width: 0; }
.meal-title-row { display: flex; align-items: center; gap: 8px; }
.meal-title {
  color: var(--text); font-size: 14px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.meal-macros {
  font-size: 11.5px; color: var(--faint);
  font-family: "IBM Plex Mono", monospace; margin-top: 3px;
}
.grade {
  font-size: 10.5px; font-weight: 700;
  padding: 2px 8px; border-radius: var(--r-round);
  background: var(--teal-10); color: var(--teal);
  font-family: "IBM Plex Mono", monospace; flex-shrink: 0;
}
.grade.lg { font-size: 12px; padding: 3px 10px; }

/* Icon-only buttons still get a full finger-sized tap area, even though the
   icon drawn inside them is small. */
.icon-btn {
  background: none; border: none; cursor: pointer;
  color: var(--faint); flex-shrink: 0;
  width: var(--tap); height: var(--tap);
  display: flex; align-items: center; justify-content: center;
  border-radius: 10px;
  margin: -6px;
}
.icon-btn:active { background: var(--well); }
.icon-btn:hover { color: var(--protein); }

.empty {
  text-align: center;
  padding: 28px 0;
  color: var(--faint);
  font-size: 13.5px;
  line-height: 1.6;
}
.empty.tall { padding: 44px 0; }
.empty svg { opacity: 0.5; margin-bottom: 10px; }
.empty.loading { color: var(--teal); }


/* ==========================================================================
   13. NUTRISCAN
   ========================================================================== */
.dropzone {
  border: 2px dashed var(--border);
  border-radius: 14px;
  padding: 26px 16px;
  text-align: center;
  cursor: pointer;
  background: var(--well);
  margin-bottom: 16px;
  transition: border-color 0.15s, background 0.15s;
}
.dropzone:active, .dropzone.is-dragging { border-color: var(--teal); background: var(--card-hi); }
.dropzone svg { color: var(--faint); margin-bottom: 8px; }
.dropzone-main { color: var(--text); font-size: 14px; font-weight: 600; }
.dropzone-sub  { color: var(--faint); font-size: 12px; margin-top: 4px; }
.dropzone-preview {
  max-width: 100%; max-height: 160px;
  border-radius: 10px; margin-bottom: 10px;
  object-fit: contain;
}

.macro-box {
  background: var(--well);
  border-radius: 11px;
  padding: 11px 6px;
  text-align: center;
  border: 1px solid var(--border);
}
.macro-box-val { font-size: 17px; font-weight: 700; font-family: "IBM Plex Mono", monospace; }
.macro-box-lab { font-size: 10.5px; color: var(--faint); margin-top: 2px; }
.macro-box.sm { padding: 8px 2px; border-radius: 9px; }
.macro-box.sm .macro-box-val { font-size: 14px; }

.result-head {
  display: flex; justify-content: space-between;
  align-items: flex-start; gap: 10px; margin-bottom: 14px;
}
.result-name {
  color: var(--text); font-size: 17px; font-weight: 700;
  font-family: "Space Grotesk", sans-serif; line-height: 1.25;
}
.result-context { color: var(--faint); font-size: 12px; margin-top: 3px; }


/* ==========================================================================
   14. MEAL PLAN + RECIPE
   ========================================================================== */
.plan-meal {
  font-size: 10.5px; color: var(--teal); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.4px;
}

.recipe-title-row {
  display: flex; justify-content: space-between;
  align-items: flex-start; gap: 10px; margin-bottom: 4px;
}
.recipe-title {
  font-family: "Space Grotesk", sans-serif;
  font-size: 19px; font-weight: 700; color: var(--text); line-height: 1.25;
}
.recipe-badge {
  font-size: 11px; color: var(--fat); background: var(--fat-10);
  padding: 4px 10px; border-radius: var(--r-round);
  font-weight: 700; flex-shrink: 0; white-space: nowrap;
}
.recipe-sub { font-size: 12.5px; color: var(--faint); margin-bottom: 16px; }

.section-label {
  font-size: 12px; color: var(--sub); font-weight: 700;
  margin-bottom: 10px; text-transform: uppercase; letter-spacing: 0.4px;
}
.ing-row {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: 14px; color: var(--text);
  border-bottom: 1px dashed var(--border);
  padding-bottom: 8px;
}
.ing-amt { font-family: "IBM Plex Mono", monospace; color: var(--faint); flex-shrink: 0; }
.steps {
  margin: 0; padding-left: 20px; color: var(--text);
  font-size: 14px; line-height: 1.5;
  display: flex; flex-direction: column; gap: 10px;
}


/* ==========================================================================
   15. AI COACH CHAT
   The chat is sized off the real visible screen height so the input box sits
   just above the keyboard, not underneath it.
   ========================================================================== */
.chat-card {
  max-width: 760px; margin: 0 auto;
  display: flex; flex-direction: column;
  /* 100dvh = the "dynamic viewport height": the space actually visible right
     now, after the phone's address bar has slid away. Plain 100vh guesses
     wrong on phones and pushes the input off the bottom of the screen. */
  height: calc(100dvh - var(--bottomnav-h) - 130px);
  min-height: 380px;
}
.chat-scroll {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex; flex-direction: column; gap: 10px;
  padding-right: 2px;
}
.msg { display: flex; }
.msg.from-user { justify-content: flex-end; }
.msg.from-ai   { justify-content: flex-start; }
.bubble {
  max-width: 85%;
  padding: 11px 14px;
  border-radius: 15px;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--text);
  word-break: break-word;
}
.msg.from-user .bubble { background: var(--teal-10); border: 1px solid var(--teal-27); }
.msg.from-ai   .bubble { background: var(--card-hi); border: 1px solid var(--border); }
.bubble.typing { color: var(--faint); font-size: 13.5px; display: flex; align-items: center; gap: 6px; }
.chat-input-row { display: flex; gap: 8px; margin-top: 12px; }
.chat-input-row .btn { padding: 0 18px; flex-shrink: 0; }


/* ==========================================================================
   16. MODALS
   On a phone a centred floating box is the wrong shape. These slide up from
   the bottom instead — a "bottom sheet" — so they open right where your thumb
   already is, and they can be dismissed downward the way people expect.
   ========================================================================== */
.overlay {
  position: fixed; inset: 0;
  background: rgba(43, 51, 25, 0.4);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: flex;
  align-items: flex-end;               /* stuck to the bottom on phones */
  justify-content: center;
  z-index: 100;
  animation: fadeIn 0.18s ease;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.modal {
  background: var(--card);
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: var(--r-modal) var(--r-modal) 0 0;
  padding: 20px 16px calc(20px + var(--safe-bottom));
  width: 100%;
  max-height: 92vh;
  overflow-y: auto;
  box-shadow: 0 -8px 40px rgba(43, 51, 25, 0.25);
  animation: slideUp 0.24s cubic-bezier(.2, .8, .2, 1);
}
@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }

/* The little grey handle at the top of a sheet that says "drag me down". */
.modal::before {
  content: "";
  display: block;
  width: 38px; height: 4px;
  border-radius: 999px;
  background: var(--border);
  margin: -8px auto 14px;
}

.modal.sm { text-align: center; }
.modal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.modal-title { font-family: "Space Grotesk", sans-serif; font-size: 18px; color: var(--text); }
.modal-icon {
  width: 48px; height: 48px; border-radius: 13px;
  background: var(--protein-10);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 14px;
  color: var(--protein);
}
.modal-text { margin: 0 0 20px; color: var(--sub); font-size: 14px; line-height: 1.5; }

.toast {
  position: fixed;
  bottom: calc(var(--bottomnav-h) + var(--safe-bottom) + 14px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--teal);
  color: var(--on-primary);
  padding: 12px 20px;
  border-radius: var(--r-round);
  font-weight: 700; font-size: 13.5px;
  z-index: 200;
  max-width: calc(100vw - 32px);
  text-align: center;
  box-shadow: 0 8px 24px var(--teal-33);
  animation: toastIn 0.22s ease;
}
@keyframes toastIn {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* The sticky Save button on the Profile tab must clear the bottom nav. */
.sticky-save {
  position: sticky;
  bottom: calc(var(--bottomnav-h) + var(--safe-bottom) + 10px);
  z-index: 10;
}

.spin { animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Anyone who has asked their device to reduce motion gets no animation. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}


/* ==========================================================================
   ==========================================================================
   BIGGER SCREENS
   Everything above this line is the phone design. Everything below only
   switches on once the screen is wide enough to make good use of it.
   ==========================================================================
   ========================================================================== */


/* --------------------------------------------------------------------------
   600px and up — big phones held sideways, and small tablets
   -------------------------------------------------------------------------- */
@media (min-width: 600px) {
  :root { --gap: 16px; --pad: 20px; }

  .banner-row { flex-direction: row; justify-content: space-between; align-items: center; }
  .banner-actions { flex-direction: row; }
  .banner-actions > * { width: auto; }
  .banner-big { font-size: 24px; }

  .grid-2, .grid-detail { grid-template-columns: 1fr 1fr; }

  /* Room now for the full "1250 / 2200 kcal" reading. */
  .kcal-pill { font-size: 12.5px; padding: 7px 14px; }
  .kcal-pill .goal { display: inline; }

  .modal { max-width: 460px; }
}


/* --------------------------------------------------------------------------
   900px and up — tablets and laptops
   This is where the layout stops being a phone app: the navigation moves back
   up to the top bar, the bottom bar disappears, and cards sit side by side.
   -------------------------------------------------------------------------- */
@media (min-width: 900px) {
  :root { --gap: 20px; --pad: 24px; --bottomnav-h: 0px; }

  body { padding-bottom: 0; }

  .nav { display: flex; gap: 4px; flex: 1; overflow-x: auto; }
  .bottomnav { display: none; }

  .topbar-inner { padding: 8px var(--pad); gap: 20px; }
  .brand img { width: 150px; height: 64px; }

  .card { padding: 20px; }

  .grid-metrics { grid-template-columns: 1.1fr 1.4fr; }
  .grid-log     { grid-template-columns: 1.6fr 1fr; }
  .grid-scan    { grid-template-columns: 1fr 1fr; }
  .grid-recipe  { grid-template-columns: .9fr 1.5fr; }
  .grid-profile { grid-template-columns: 1fr 1fr; }
  .grid-shortcut { grid-template-columns: repeat(3, 1fr); }
  .grid-3 { gap: 10px; }

  /* Back to tall cards with the icon above the text. */
  .shortcut { flex-direction: column; align-items: flex-start; gap: 0; padding: 20px; }
  .icon-tile { width: 38px; height: 38px; margin-bottom: 12px; }

  /* Pills have room to wrap now, so no more sideways swiping. */
  .pill-row.swipe { flex-wrap: wrap; overflow-x: visible; }

  /* Inputs can drop back to their designed size: desktop browsers do not
     zoom in on focus, so the 16px rule no longer applies. */
  .input, .textarea { font-size: 13.5px; padding: 10px 12px; min-height: 40px; }
  .select-trigger { font-size: 13.5px; min-height: 40px; }
  .select-option { font-size: 13px; min-height: 38px; padding: 9px 12px; }
  .choice { font-size: 13px; min-height: 40px; padding: 10px 12px; }
  .check-label { font-size: 13.5px; }
  .check-row { min-height: 32px; }
  .check-box { width: 18px; height: 18px; border-radius: 5px; }

  /* A mouse pointer is precise, so the slider knob can shrink back down. */
  input[type=range]::-webkit-slider-thumb { width: 18px; height: 18px; border-width: 2px; }
  input[type=range]::-moz-range-thumb     { width: 16px; height: 16px; border-width: 2px; }

  .btn-ghost:hover { transform: none; }
  .btn:hover:not(:disabled) { transform: translateY(-1px); }
  .shortcut:hover { transform: translateY(-2px); }

  /* Modals go back to being centred floating boxes. */
  .overlay { align-items: center; padding: 16px; }
  .modal {
    border: 1px solid var(--border);
    border-radius: var(--r-modal);
    padding: 24px;
    animation: popIn 0.18s ease;
    box-shadow: 0 20px 60px rgba(43, 51, 25, 0.28);
  }
  .modal::before { display: none; }   /* no drag handle on desktop */
  .modal.sm { max-width: 360px; }
  .modal.md { max-width: 420px; }
  @keyframes popIn {
    from { opacity: 0; transform: scale(0.96); }
    to   { opacity: 1; transform: scale(1); }
  }

  .toast { bottom: 24px; }
  .sticky-save { bottom: 16px; }

  .chat-card { height: 70vh; min-height: 480px; }
  .bubble { max-width: 80%; font-size: 13.5px; }

  .big-number { font-size: 30px; }
  .meal-title { font-size: 13.5px; }
  .ing-row, .steps { font-size: 13px; }
  .label { font-size: 11.5px; }
}


/* --------------------------------------------------------------------------
   1100px and up — full desktop. The three-column meal planner fits here.
   -------------------------------------------------------------------------- */
@media (min-width: 1100px) {
  .grid-plan { grid-template-columns: .85fr 1.6fr .8fr; }
}


/* --------------------------------------------------------------------------
   Short landscape screens — a phone turned sideways has very little height,
   so trim the tall bits rather than letting them fill the whole screen.
   -------------------------------------------------------------------------- */
@media (max-height: 500px) and (orientation: landscape) {
  .chat-card { height: auto; min-height: 300px; }
  .empty.tall { padding: 20px 0; }
  .dropzone { padding: 16px; }
}

/* ==========================================================================
   ACCESSIBILITY
   --------------------------------------------------------------------------
   Not everybody uses a mouse or a touchscreen. Some people move through a page
   using only the Tab key, and some cannot see the screen at all and listen to
   it instead. This block is for them.
   ========================================================================== */

/* THE FOCUS RING — the single most important rule in this file for keyboard
   users. Pressing Tab moves an invisible cursor from one control to the next.
   Without a visible marker showing where that cursor is, the page is
   unusable: you are pressing Enter and hoping.

   `:focus-visible` (rather than plain `:focus`) means the ring appears when
   somebody is tabbing, but NOT when they simply click a button with a mouse —
   so keyboard users get the help and nobody else sees a stray outline.

   The 3px offset lifts the ring clear of the button's own edge so it stays
   readable on the olive buttons as well as the pale ones. */
:focus-visible {
  outline: 3px solid var(--teal);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Inputs already draw their own olive border on focus, but a keyboard user
   needs the same strong ring as everything else. */
.input:focus-visible,
.textarea:focus-visible,
.select-trigger:focus-visible {
  outline: 3px solid var(--teal);
  outline-offset: 2px;
}

/* SKIP TO CONTENT — every page starts with a logo and six navigation links.
   Someone tabbing through has to walk past all of them on every single screen
   before reaching the actual content. This link is invisible until it is
   focused, and it is the very first thing the Tab key finds, so one keypress
   jumps straight to the page. It is a standard pattern; sighted mouse users
   will never see it. */
.skip-link {
  position: absolute;
  left: 8px;
  top: -60px;                    /* parked off the top of the screen */
  z-index: 200;
  background: var(--teal);
  color: var(--on-primary);
  padding: 12px 18px;
  border-radius: var(--r-btn);
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
  transition: top 0.15s;
}
.skip-link:focus { top: 8px; }   /* slides into view when tabbed to */

/* Text that only a screen reader should read out. It is genuinely on the page
   — so it gets announced — but occupies no space and cannot be seen.
   `display:none` would NOT work here: hidden content is skipped by screen
   readers too, which is the opposite of what we want. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Some people set their system to "increase contrast". Honour it by making
   every border darker and the focus ring thicker, rather than ignoring a
   preference they deliberately turned on. */
@media (prefers-contrast: more) {
  :root { --border: #B9AE6A; --sub: #4F5340; --faint: #55583C; }
  :focus-visible { outline-width: 4px; }
}
