/* menutracker — warm/homely visual language (design pass r1).
   Replaces Pico. Styles bare elements so every page inherits the look;
   component classes match the mockups in web/design/*.dc.html. */

:root {
  --bg: #FBF9F4;
  --surface: #FFFFFF;
  --surface-2: #F4F0E6;
  --border: #E7E1D5;
  --ink: #3A342E;
  --muted: #8B8173;
  --accent: #B15C3B;
  --accent-hover: #8f462c;
  --accent-soft: #F3E3D9;
  --sage: #7E9478;
  --sage-soft: #E7EDE2;
  --sage-ink: #4F6249;
  --shadow: 0 1px 2px rgba(58, 52, 46, .05), 0 6px 20px rgba(58, 52, 46, .07);
  --radius: 14px;
}

* { box-sizing: border-box; }

/* Sits just above the normal document flow so iOS's native rubber-band
   bounce reveals it when pulling down at the top of the page; see the
   touch-tracking script in base.html for the reload trigger. */
#ptr {
  position: absolute;
  top: -56px; left: 0; right: 0; height: 56px;
  display: flex; align-items: center; justify-content: center;
  color: var(--muted);
  pointer-events: none;
}
#ptr svg { transition: transform .15s ease, color .15s ease; opacity: .6; }
#ptr.ready svg { color: var(--accent); opacity: 1; transform: rotate(180deg); }
#ptr.refreshing svg { color: var(--accent); opacity: 1; animation: ptr-spin .7s linear infinite; }
@keyframes ptr-spin { to { transform: rotate(360deg); } }

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  overflow-x: hidden;
  touch-action: pan-y;
  background: var(--bg);
  color: var(--ink);
  font-family: "Hanken Grotesk", system-ui, -apple-system, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: "Newsreader", Georgia, serif;
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -.01em;
  margin: 0 0 .5em;
}

h1, .page-title { font-size: 27px; }
h2 { font-size: 20px; margin-top: 1.4em; }
h3 { font-size: 17px; }
.page-title:empty { display: none; }

p { margin: 0 0 1em; }

a { color: var(--accent); text-decoration: none; font-weight: 600; }
a:hover { color: var(--accent-hover); text-decoration: underline; }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--surface-2);
  border-radius: 5px;
  padding: .1em .35em;
  font-size: .9em;
}

.muted { color: var(--muted); }
.kicker {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted);
}

.seg { display: flex; background: var(--surface-2); border-radius: 11px; padding: 3px; gap: 3px; }
.seg a {
  flex: 1; text-align: center; padding: 8px 6px; font-size: 12.5px; font-weight: 600;
  color: var(--muted); border-radius: 9px; text-decoration: none;
}
.seg a:hover { text-decoration: none; color: var(--ink); }
.seg a.on { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }

/* --- layout shell --------------------------------------------------------- */

main {
  max-width: 1120px;
  margin: 0 auto;
  padding: 26px 20px 28px;
}

@media (min-width: 900px) {
  main { padding: 34px 40px 56px; }
}

/* --- top bar (desktop / tablet) ----------------------------------------- */

.topbar {
  display: flex;
  align-items: center;
  gap: 22px;
  padding: calc(14px + env(safe-area-inset-top)) 20px 14px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
/* The offline banner already pads for the notch/status bar when it's
   showing — without this, the two stack into a big gap. */
body.mt-banner-shown .topbar { padding-top: 14px; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--accent);
  font-family: "Newsreader", serif;
  font-size: 19px;
  font-weight: 600;
}
.brand:hover { text-decoration: none; }
#offline-icon { display: none; color: #C4392F; margin-left: -2px; }
#offline-icon.show { display: inline-block; }

#offline-banner {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: calc(7px + env(safe-area-inset-top)) 14px 7px;
  background: rgba(196, 57, 47, 0.92);
  color: #fff;
  font-size: 12.5px;
  font-weight: 500;
  text-align: center;
}
#offline-banner[hidden] { display: none; }
#offline-banner button {
  background: none;
  border: none;
  color: #fff;
  font-size: 16px;
  line-height: 1;
  padding: 0;
  cursor: pointer;
}

.topnav { display: flex; align-items: center; gap: 2px; flex: 1; flex-wrap: wrap; }
.topnav > a, .more summary {
  padding: 7px 11px;
  border-radius: 8px;
  color: var(--muted);
  font-weight: 500;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
}
.topnav > a:hover, .more summary:hover { color: var(--ink); text-decoration: none; }
.topnav > a.active { background: var(--accent-soft); color: var(--accent); }

.more { position: relative; }
.more summary { list-style: none; }
.more summary::-webkit-details-marker { display: none; }
.more > div {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 20;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
  padding: 6px;
  display: flex;
  flex-direction: column;
  min-width: 180px;
}
.more > div a { padding: 8px 10px; border-radius: 7px; font-size: 13px; font-weight: 500; color: var(--muted); }
.more > div a:hover { background: var(--surface-2); color: var(--ink); text-decoration: none; }

.who {
  font-size: 12.5px;
  color: var(--muted);
  white-space: nowrap;
  display: flex;
  align-items: baseline;
  gap: .4rem;
}
.who .logout { display: inline; margin: 0; }
.who .logout button {
  background: none; border: none; padding: 0; margin: 0; width: auto;
  font: inherit; color: var(--accent); text-decoration: underline; cursor: pointer;
}

@media (max-width: 720px) {
  .topbar { gap: 12px; }
  .topnav, .who { display: none; }

  /* iOS Safari auto-zooms on focus for any input under 16px. !important
     because the base input rule below (identical specificity, later in the
     cascade) would otherwise win and silently re-enable the zoom. */
  input, select, textarea, .input { font-size: 16px !important; }

  /* Clears the fixed .tabbar (~60px chrome + home-indicator safe area) so it never overlaps content. */
  main { padding-bottom: calc(60px + env(safe-area-inset-bottom)); }

  /* iOS standalone PWA only expands window.innerHeight to the true full-screen
     height once it decides the page is scrollable; a page short enough to fit
     without scrolling gets stuck ~60px short, so .tabbar (position:fixed,
     bottom:0) sits that far above the real bottom edge. Forcing body to always
     slightly overflow one viewport keeps every page "scrollable" so iOS always
     promotes it to the full-height viewport. */
  body { min-height: calc(100vh + 1px); }

  .hide-mobile { display: none; }
  .hide-desktop { display: inline; }
}

/* --- bottom tab bar (mobile) ------------------------------------------- */

.tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 30;
  display: flex;
  gap: 4px;
  padding: 5px 10px calc(5px + env(safe-area-inset-bottom));
  background: var(--surface);
  border-top: 1px solid var(--border);
  /* Forces its own compositing layer - iOS WKWebView can otherwise mis-place
     a fixed element at initial paint and only fix it on a real scroll event. */
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
  will-change: transform;
}
.tabbar a {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 4px 0;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--muted);
}
.tabbar a:hover { text-decoration: none; }
.tabbar a.on { color: var(--accent); }

@media (min-width: 721px) {
  .tabbar { display: none; }
}

/* --- messages ---------------------------------------------------------- */

.messages { margin-bottom: 18px; }
.flash {
  background: var(--accent-soft);
  color: var(--accent-hover);
  border-radius: 10px;
  padding: 10px 14px;
  margin: 0 0 8px;
  font-weight: 600;
  font-size: 13.5px;
}

/* --- cards ------------------------------------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px;
}
.card + .card { margin-top: 16px; }
.card.filter-card { margin-bottom: 20px; }

.filter-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }
.filter-bar .sort-field {
  display: inline-flex; align-items: center; gap: 7px;
  font-weight: 600; font-size: 13px; color: var(--ink);
}
.filter-bar .sort-field svg { color: var(--muted); flex: none; }
.filter-bar .sort-field select { margin-left: 2px; }

.filter-advanced { flex-basis: 100%; }
.filter-advanced summary {
  display: inline-flex; align-items: center; gap: 6px;
  list-style: none; cursor: pointer;
  padding: 7px 12px; border-radius: 999px;
  background: var(--surface-2); color: var(--muted);
  font-weight: 600; font-size: 12.5px;
}
.filter-advanced summary::-webkit-details-marker { display: none; }
.filter-advanced summary:hover { color: var(--ink); }
.filter-advanced[open] summary { color: var(--accent); background: var(--accent-soft); }
.filter-advanced-body {
  display: flex; flex-wrap: wrap; gap: .6rem 1.5rem;
  margin-top: 10px; padding: 12px 14px;
  background: var(--surface-2); border-radius: 10px;
}
.filter-advanced-body label {
  display: flex; align-items: center; justify-content: flex-start;
  gap: 8px; flex: 1 1 13rem;
}
.filter-advanced-body label span { font-weight: 600; font-size: 13px; white-space: nowrap; }
.filter-advanced-body input { width: 5rem; margin: 0; flex: none; }

.tag-check-group {
  display: flex; flex-direction: column; align-items: flex-start; gap: .5rem;
  flex-basis: 100%;
}

@media (min-width: 721px) {
  .filter-advanced-body { justify-content: space-between; }
}

.sechead {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 12px;
  gap: 12px;
}

/* --- buttons & inputs ------------------------------------------------- */

button, .btn {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 10px 16px;
  font-family: inherit;
  font-weight: 600;
  font-size: 13.5px;
  cursor: pointer;
}
button:hover, .btn:hover { background: var(--accent-hover); color: #fff; }

.btn-ghost, button.btn-ghost {
  display: inline-block;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--ink);
  border-radius: 10px;
  padding: 9px 14px;
  font-weight: 600;
  font-size: 13px;
}
.btn-ghost:hover { background: var(--surface-2); color: var(--ink); }

.chip, button.chip {
  background: var(--accent-soft);
  color: var(--accent);
  border: none;
  border-radius: 999px;
  padding: 7px 13px;
  font-weight: 600;
  font-size: 12.5px;
  white-space: nowrap;
}

.tag {
  display: inline-flex;
  align-items: center;
  background: var(--sage-soft);
  color: var(--sage-ink);
  border-radius: 999px;
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
}

input, select, textarea, .input {
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-family: inherit;
  font-size: 13.5px;
  background: var(--surface);
  color: var(--ink);
  max-width: 100%;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--accent-soft);
  border-color: var(--accent);
}
input.is-invalid, select.is-invalid, textarea.is-invalid {
  border-color: var(--accent);
  background: var(--accent-soft);
}
label { font-weight: 600; font-size: 13px; }

form.inline {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  align-items: end;
  margin-bottom: 18px;
}
form.inline label { display: flex; flex-direction: column; gap: .3rem; font-weight: 600; }
form.inline input, form.inline select { margin: 0; }
form.inline label.checkbox-row { flex-direction: row; align-items: center; gap: 8px; font-weight: 500; flex-basis: 100%; }
form.inline label.checkbox-row input { width: auto; accent-color: var(--sage); }

form.inline label:has(input[type="search"]) { flex: 1 1 auto; min-width: 0; }
form.inline input[type="search"] { width: 100%; }

form.inline label.rename-field { flex: 1 1 auto; min-width: 0; }
form.inline label.rename-field input { width: 100%; }

@media (min-width: 721px) {
  form.inline label:has(input[type="search"]) { flex: none; }
  form.inline input[type="search"] { width: 22rem; }

  form.inline label.rename-field { flex: none; }
  form.inline label.rename-field input { width: 26rem; }
}

form.stack { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; max-width: 34rem; }
form.stack > label { display: flex; flex-direction: column; gap: .35rem; width: 100%; font-weight: 600; }
form.stack input, form.stack textarea, form.stack select { width: 100%; }
form.stack .row { display: flex; gap: 12px; width: 100%; flex-wrap: wrap; }
form.stack .row > label { flex: 1 1 12rem; display: flex; flex-direction: column; gap: .35rem; font-weight: 600; }
form.stack label.checkbox-row { flex-direction: row; align-items: center; gap: 8px; font-weight: 500; }
form.stack label.checkbox-row input { width: auto; accent-color: var(--sage); }

.ingredient-rows { display: flex; flex-direction: column; gap: 8px; width: 100%; }
.ingredient-row { display: flex; gap: 8px; align-items: center; width: 100%; }
.ingredient-row input { flex: 1; margin: 0; }
.ingredient-row .ingredient-remove { padding: 6px 11px; font-size: 15px; line-height: 1; }

textarea { width: 100%; resize: vertical; font-family: inherit; }

fieldset {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px;
  width: 100%;
  margin: 0;
}
fieldset legend {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted); padding: 0 6px;
}
fieldset label {
  display: inline-flex; align-items: center; gap: 7px;
  font-weight: 500; font-size: 13px; margin: 4px 14px 4px 0;
}
fieldset input { width: auto; accent-color: var(--sage); }

mark {
  background: var(--accent-soft);
  color: var(--accent-hover);
  border-radius: 6px;
  padding: .1em .4em;
  font-weight: 600;
}

main ul { padding-left: 1.1rem; }
main ul li { margin: .25rem 0; }

/* long-form day/month text on desktop, short-form on mobile where space is tighter */
.hide-desktop { display: none; }

/* --- tables ---------------------------------------------------------- */

table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 1.2em;
}
th, td { text-align: left; padding: 11px 14px; border-bottom: 1px solid var(--border); }
th {
  font-size: 10.5px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); background: var(--surface-2);
}
tbody tr:last-child td { border-bottom: none; }
td.num, th.num { text-align: right; }
.count { display: inline-block; min-width: 2.5rem; }

@media (max-width: 640px) {
  table { display: block; overflow-x: auto; white-space: nowrap; }
}

/* --- week planner --------------------------------------------------- */

.planner {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}
@media (min-width: 720px) {
  .planner { grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); align-items: start; }
}

.day {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
  margin: 0;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.day > header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin: 0;
}
.day > header strong { font-family: "Newsreader", serif; font-size: 16px; font-weight: 500; }

.day .meals { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.day .meals li {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  padding: 8px 10px;
  background: var(--surface-2);
  border-radius: 10px;
}
.day .meals li.empty { background: none; padding: 0; color: var(--muted); font-size: 13px; }
.day .meals li.for-group { background: var(--sage-soft); }
.day .meals li.non-meal { background: none; border: 1px dashed var(--border); color: var(--muted); font-style: italic; }

.non-meal-options { margin-top: 8px; }
.non-meal-label {
  display: block; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 6px;
}
.non-meal-buttons { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.non-meal-buttons .btn-ghost { padding: 5px 10px; font-size: 12.5px; }
.non-meal-other-form { display: inline-flex; gap: 6px; margin: 0; }
.non-meal-other-input { padding: 5px 10px; font-size: 12.5px; width: 8rem; }
.who-tag {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  font-weight: 700; padding: 2px 7px; border-radius: 999px;
  background: var(--sage-soft); color: var(--sage-ink);
}
.non-meal-tag {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  font-weight: 700; padding: 2px 7px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--border); color: var(--muted);
}

.del-meal { display: inline; margin: 0; margin-left: auto; }
.del-meal button {
  background: none; border: none; color: var(--muted); opacity: .7;
  padding: 0 .2rem; margin: 0; width: auto; font-size: 1.1rem; line-height: 1;
}
.del-meal button:hover { opacity: 1; background: none; }

.add-meal { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0; position: relative; }
.add-meal .dish-input { flex: 1 1 8rem; }
.add-meal input, .add-meal select { padding: 8px 10px; font-size: 13px; }
.add-meal button { display: inline-flex; align-items: center; gap: 5px; padding: 8px 12px; font-size: 12.5px; }
@media (max-width: 720px) {
  /* iOS Safari auto-zooms on focus for any input under 16px */
  .add-meal input, .add-meal select { font-size: 16px; }
}
.add-meal .suggest-btn { background: var(--sage); border: 1px solid var(--sage); color: #fff; }
.add-meal .suggest-btn:hover { background: var(--sage-ink); border-color: var(--sage-ink); }
.suggest-btn .icon-spinner { display: none; }
.suggest-btn.is-loading .icon-sparkle { display: none; }
.suggest-btn.is-loading .icon-spinner { display: inline-flex; animation: ptr-spin .7s linear infinite; }
.suggest-btn.is-loading, .suggest-refresh.is-loading { pointer-events: none; opacity: .75; }

.day .hint { font-size: 12.5px; margin: 0; color: var(--muted); }

ul.ac {
  position: absolute;
  top: 100%; left: 0; right: 0;
  z-index: 10;
  list-style: none;
  margin: .3rem 0 0;
  padding: .3rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 11px;
  box-shadow: var(--shadow);
  max-height: 14rem;
  overflow-y: auto;
}
ul.ac li {
  display: flex;
  justify-content: space-between;
  gap: .5rem;
  padding: .5rem .6rem;
  cursor: pointer;
  border-radius: 8px;
  font-size: 13.5px;
}
ul.ac li:hover { background: var(--surface-2); }

.suggestions {
  margin: 0; font-size: 13.5px; display: flex; flex-direction: column; gap: 12px;
  border-top: 1px dashed var(--border); padding-top: 13px;
}
.suggestions[hidden] { display: none; }
.suggestions:empty { border-top: none; padding-top: 0; }
.suggest-head, .suggestions .suggest-head {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted); margin: 0;
}
.suggestions .suggestion {
  display: flex; flex-direction: row; align-items: flex-start; gap: 11px; margin: 0;
}
.suggestions .suggestion button {
  margin: 0; padding: 8px 14px; font-size: 13px;
  background: var(--accent-soft); color: var(--accent); border-radius: 999px;
}
.suggestions .suggestion button:hover { background: #ecd7c8; }
.suggestions .suggestion .why { color: var(--muted); font-size: 12px; }

.suggest-filter { margin-bottom: 16px; font-size: 13.5px; }
.suggest-filter summary { cursor: pointer; color: var(--muted); font-weight: 600; }
.suggest-filter > div { display: flex; flex-wrap: wrap; gap: .4rem .9rem; margin-top: .5rem; }
.suggest-filter label { display: inline-flex; align-items: baseline; gap: .3rem; font-weight: 500; }

/* --- per-screen ---------------------------------------------------- */

.home-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}
@media (min-width: 860px) {
  .home-grid { grid-template-columns: 1fr 1fr; align-items: start; }
}

.lately-row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 13.5px;
}
.lately-row:last-child { border-bottom: none; }
.lately-row > .photo { width: 40px; height: 40px; }
.lately-row > div {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.lately-row > div > a,
.lately-row > div > span:first-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lately-row > .muted { margin-left: auto; flex: none; }
.lately-row .muted { font-size: 11.5px; white-space: nowrap; }

a.tag:hover { text-decoration: none; background: #dde7d5; }

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

.feed-list { margin: 0 -18px; }
.feed-list .lately-row { padding-left: 18px; padding-right: 18px; }

.feed-foot { margin: 11px 0 0; font-size: 12.5px; }

.while-refresh, .suggest-refresh {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 26px; height: 26px; padding: 0; margin: -5px -4px -5px 0;
  background: none; border: none; border-radius: 8px; color: var(--muted);
}
.while-refresh:hover, .suggest-refresh:hover { color: var(--accent); background: var(--surface-2); }
.while-refresh:active svg, .suggest-refresh:active svg { transform: rotate(-120deg); transition: transform .3s ease; }
.while-card .feed-list > .lately-row:nth-child(n+5) { display: none; }
.suggestions .feed-head { margin-bottom: 0; }
.suggest-refresh.is-loading { color: var(--accent); }
.suggest-refresh.is-loading svg { animation: ptr-spin .7s linear infinite; }

.statgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 16px;
  margin-bottom: 16px;
}
.statgrid > div { display: flex; flex-direction: column; gap: 3px; }
.statgrid strong {
  font-family: "Newsreader", serif;
  font-weight: 500;
  font-size: 28px;
  line-height: 1;
}
.statgrid .muted { font-size: 12px; }

table.bare {
  border: none;
  border-radius: 0;
  margin: 10px 0 0;
  background: none;
}
table.bare td { padding: 8px 0; border-bottom: 1px solid var(--border); }
table.bare tr:last-child td { border-bottom: none; }
table.bare tr:first-child td { padding-top: 0; }

.member-actions { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }

@media (max-width: 640px) {
  /* The generic `table { display: block; white-space: nowrap }` mobile rule
     (above) collapses table.bare's rows into an anonymous table box without
     giving each row its own line, so cells stack with no gap and buttons from
     different rows land on top of each other. Rebuild each row as a flex line
     instead of relying on the generic table fallback. */
  table.bare { display: block; overflow: visible; white-space: normal; }
  table.bare tbody { display: block; }
  table.bare tr {
    display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center;
    gap: 6px 14px; padding: 8px 0; border-bottom: 1px solid var(--border);
  }
  /* align-items:flex-end right-aligns each button to the widest one, which
     reads as an odd indent once the row goes full-width on mobile. */
  .member-actions { align-items: flex-start; }
  table.bare tr:last-child { border-bottom: none; }
  table.bare td { display: block; padding: 0; border-bottom: none; }
}

.planlist { display: flex; flex-direction: column; gap: 12px; margin-top: 20px; }
.planrow {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  font-weight: 400;
  color: var(--ink);
}
.planrow:hover { text-decoration: none; border-color: #d8cfbd; }
.planrow > div:not(.planrow-meta) { display: flex; flex-direction: column; gap: 3px; }
.planrow strong { font-family: "Newsreader", serif; font-weight: 500; font-size: 16px; }
.planrow .muted { font-size: 12.5px; }
.planrow-meta { display: flex; align-items: center; gap: 10px; white-space: nowrap; }
.planrow-meta .muted { font-size: 12.5px; }

.toggles, .tag-toggles { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; margin-bottom: 18px; }
.toggles label, .tag-toggles label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 9px 15px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.toggles label:has(input:checked), .tag-toggles label:has(input:checked) {
  background: var(--sage-soft);
  border-color: #c3d0bd;
  color: var(--sage-ink);
}
.toggles label:has(input:focus-visible), .tag-toggles label:has(input:focus-visible) {
  outline: 2px solid var(--accent-soft);
  outline-offset: 1px;
}
.toggles input, .tag-toggles input {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.toggles label::before, .tag-toggles label::before {
  content: "";
  width: 14px; height: 14px;
  flex: none;
  border-radius: 999px;
  border: 1.5px solid var(--border);
  background: var(--surface);
  transition: background .12s, border-color .12s;
}
.toggles label:has(input:checked)::before, .tag-toggles label:has(input:checked)::before {
  background: var(--sage);
  border-color: var(--sage);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3.5 8.5l3 3 6-6.5' stroke='white' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-size: 11px; background-repeat: no-repeat; background-position: center;
}
.toggles button { margin-left: 4px; }

/* Search's tag filter: small uppercase pill like the homepage's dish-name
   pills (.tag), same sage green — but outlined (white background, sage
   border/text) rather than filled with the sage-soft pastel, since that
   pastel is too close in lightness to this panel's --surface-2 background
   to read clearly against it. Just the label text plus an inline '+'/'✓',
   no surrounding icon box. */
form.inline .tag-filter-toggles label {
  /* Fully self-contained, and qualified with form.inline to out-specificity
     both .filter-advanced-body label (forces a 13rem-wide flex item) and
     form.inline label (display:flex + flex-direction:column). Note
     flex-direction is its own longhand: overriding display alone doesn't
     unset it, so it must be reset here explicitly too, or form.inline
     label's "column" is the only declared value and wins regardless of
     which display/specificity won. */
  display: inline-flex;
  flex-direction: row;
  flex: none;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  gap: 3px;
  background: var(--surface);
  border: 1px solid var(--sage);
  border-radius: 999px;
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--sage-ink);
}
.tag-filter-toggles label:has(input:checked) {
  background: var(--sage);
  border-color: var(--sage);
  color: #fff;
}
.tag-filter-toggles label::before {
  content: "+";
  width: auto; height: auto;
  border: none;
  border-radius: 0;
  background: none;
  font-weight: 700;
}
.tag-filter-toggles label:has(input:checked)::before {
  content: "\2713";
  background: none;
  border: none;
}

/* One root pill per tag facet (Cuisine, Dietary, ...), each a dropdown of
   that facet's own tags — keeps the row a small fixed size regardless of
   how many tags a facet has. Mirrors the topbar's .more dropdown
   positioning, but with checkbox rows instead of links, and the summary
   styled as one more .tag-filter-toggles pill. */
.tag-more { position: relative; }
form.inline .tag-more summary {
  /* form.inline/.tag-more, not just .tag-more, to out-specificity
     .filter-advanced[open] summary — this pill sits inside the outer
     "Tag / ingredient" <details>, which is open whenever this is visible
     at all, so that rule's active-state orange would otherwise win. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  list-style: none;
  cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--sage);
  border-radius: 999px;
  padding: 3px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--sage-ink);
  gap: 3px;
}
form.inline .tag-more summary::-webkit-details-marker { display: none; }
form.inline .tag-more[open] summary { background: var(--sage-soft); color: var(--sage-ink); }
form.inline .tag-more summary::before { content: "+"; font-weight: 700; }
form.inline .tag-more summary.active {
  /* At least one tag inside this facet's dropdown is selected — filled
     solid so that's visible without opening the dropdown to check.
     Toggled live by JS as checkboxes change, not just after a reload. */
  background: var(--sage);
  border-color: var(--sage);
  color: #fff;
}
form.inline .tag-more summary.active::before { content: "\2713"; }
.tag-more-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 11rem;
  max-height: 14rem;
  overflow-y: auto;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: var(--shadow);
}
.tag-more.drop-up .tag-more-panel {
  top: auto;
  bottom: calc(100% + 6px);
}
form.inline .tag-more-panel label {
  /* Fully reset: this label is a DOM descendant of .tag-filter-toggles
     (the panel's own <details> lives inside that pill row so its "+ Other"
     summary sits inline with the other pills) as well as form.inline and
     .filter-advanced-body, so every one of those leaks in without an
     explicit override here — including .tag-filter-toggles label's ::before
     content below. */
  display: flex;
  flex-direction: row;
  flex: none;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  white-space: nowrap;
  background: none;
  border: none;
  padding: 5px 7px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  cursor: pointer;
}
form.inline .tag-more-panel label:hover { background: var(--surface-2); }
form.inline .tag-more-panel label::before { content: none; }
form.inline .tag-more-panel input {
  /* .tag-toggles input visually hides the checkbox for its own custom
     ::before indicator — undo that here for an ordinary checkbox list. */
  position: static;
  width: auto; height: auto;
  margin: 0; padding: 0;
  overflow: visible;
  clip: auto;
  accent-color: var(--sage);
}

/* Dish page's selected-tags preview: same skinny pill as the search
   filter's checked .tag-filter-toggles label (solid sage, small uppercase
   caps), plus a remove (x) button baked in — see dish_detail.html. */
.selected-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.tag-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: var(--sage);
  color: #fff;
  border-radius: 999px;
  padding: 3px 6px 3px 10px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
}
.tag-pill-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: #fff;
  font-size: 13px;
  line-height: 1;
  padding: 2px;
  cursor: pointer;
}

.dish-facts { margin-top: 7px; font-size: 13.5px; }

.plan-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  /* Delete plan can wrap below the title on narrow screens; without this, it
     sits flush against whatever comes next (often another tappable control,
     e.g. the "Filter suggestions" toggle) with no room for a safe tap. */
  margin-bottom: 20px;
}
.plan-head .dish-facts { margin-bottom: 0; }
.plan-head-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.plan-head-actions .btn-ghost { display: inline-flex; align-items: center; gap: 6px; }
.plan-delete { margin: 0; flex: none; }
.btn-ghost.danger { color: var(--accent); border-color: var(--accent-soft); }
.btn-ghost.danger:hover { background: var(--accent-soft); color: var(--accent); }

.recipe-rows, .history-rows, .season-rows { display: flex; flex-direction: column; margin-top: 8px; }
.recipe-row, .history-row, .season-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  font-size: 13.5px;
}
.recipe-row:last-child, .history-row:last-child, .season-row:last-child { border-bottom: none; }
.recipe-row .muted, .history-row .muted, .season-row .muted { font-size: 11.5px; text-align: right; }
.season-row { align-items: center; }

.community-highlight {
  display: flex; align-items: center; gap: 12px;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);
}
.community-highlight-name { font-weight: 600; font-size: 13.5px; }
.community-highlight p.muted { margin: 2px 0 0; font-size: 12px; }

/* --- dish photo placeholder ---------------------------------------- */

.photo {
  position: relative;
  display: inline-flex;
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface-2);
  flex: none;
  line-height: 0;
}
.photo .dish-photo { display: block; width: 100%; height: 100%; }
.photo-full { display: block; width: 100%; aspect-ratio: 3 / 1; border-radius: 0; }
.photo-empty { border: 1.5px dashed var(--border); background: none; }

.dish-hero {
  margin: -34px -40px 20px;
  height: 150px;
  overflow: hidden;
}
.dish-hero .photo-full { height: 100%; aspect-ratio: auto; }
@media (max-width: 899px) {
  .dish-hero { margin: -26px -20px 18px; height: 120px; }
}

.week-strip { display: flex; gap: 8px; margin: 0 0 16px; flex-wrap: wrap; }
.week-strip .photo, .week-strip .photo-empty { width: 50px; height: 50px; border-radius: 12px; }

.cell-dish { display: inline-flex; align-items: center; gap: 9px; }
.cell-dish .photo { width: 32px; height: 32px; border-radius: 8px; }

.stat-stack { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; flex: none; }

/* planner day-card meal rows */
.day .meals li .photo { width: 40px; height: 40px; }
.meal-body { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.meal-name { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-weight: 600; }

.suggestions .suggestion .photo { width: 48px; height: 48px; flex: none; }
.suggestion-body { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; flex: 1; }
.suggestions .suggestion button { white-space: normal; text-align: left; max-width: 100%; }

/* recommender tuning (staff) */
.tune { display: flex; flex-direction: column; gap: 14px; margin-bottom: 24px; }
.tune label { display: grid; grid-template-columns: 10rem 1fr 3rem auto; align-items: center; gap: 10px; font-weight: 600; font-size: 13px; }
.tune input[type=range] { width: 100%; accent-color: var(--accent); }
.tune output { font-variant-numeric: tabular-nums; }
.tune .muted { font-weight: 400; font-size: 12px; }
.tune button { justify-self: start; }
@media (max-width: 640px) { .tune label { grid-template-columns: 1fr 3rem; } .tune input[type=range] { grid-column: 1 / -1; } }

/* planrow / recipe rows with a leading photo */
.planrow { align-items: center; }
.planrow > .photo { width: 40px; height: 40px; }
.planrow > div:not(.planrow-meta) { flex: 1; min-width: 0; }

/* --- shopping list ------------------------------------------------------ */
.shopping-group + .shopping-group { margin-top: 14px; }
.shopping-lines { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; }
.shopping-line {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 0; border-bottom: 1px solid var(--border); font-size: 13.5px;
}
.shopping-line:last-child { border-bottom: none; }
.shopping-line label { display: flex; align-items: center; gap: 10px; flex: 1; cursor: pointer; }
.shopping-line input[type=checkbox] { width: 17px; height: 17px; accent-color: var(--sage); flex: none; }
.shopping-line .shop-name { font-weight: 600; flex: 1; color: inherit; }
.shopping-line .shop-name:hover { color: var(--accent); text-decoration: underline; }
.shopping-line.checked .shop-name { text-decoration: line-through; color: var(--muted); font-weight: 500; }

@media print {
  .no-print { display: none !important; }
  .tabbar, .topbar { display: none !important; }
  .card { box-shadow: none; border: none; }
}

/* ---- accounts: sign-in / sign-up / settings ---- */
.who a { color: inherit; text-decoration: none; }
.who a:hover { color: var(--ink); text-decoration: underline; }
ul.errorlist { list-style: none; margin: 4px 0 0; padding: 0; color: var(--accent); font-size: 13px; font-weight: 500; }
form.stack label small { font-weight: 400; }
