/* ------------------------------------------------------------------------
 * KortingsApp — "Helder Voordeel" design system
 *
 * From the Stitch project in Design/stitch. It keeps the Bonnetje idea —
 * money is always on screen, and one colour means a saving — on a warm oat
 * ground with deep forest ink, drawn edges and actions that say what they do.
 *
 * Two text sizes, picked in Instellingen and set as <html data-size>:
 * Normaal (the default) and Groot, which takes type and tap targets up a
 * step. Every rule below is written against the tokens, so both sizes come
 * from one set of rules.
 *
 * Rules worth stating because they're easy to erode:
 *   · Colours are the Stitch screens' own (their Tailwind config). `signal`
 *     (amber-brown) marks a saving, and — as on those screens — the list
 *     count and, in its pale form, the week pill. Never a warning.
 *   · Sizes come from the tokens. No literal font size below the metadata
 *     step, and nothing functional set in a faint grey.
 *   · Every control is at least --tap (--tap-min for steppers and chips),
 *     with at least 8px between neighbouring tap zones.
 *   · Cards are white and lift on a soft shadow (--shadow-card), as on the
 *     Stitch screens; controls on a lighter one (--shadow-soft). Every shadow
 *     comes from a token. No gradients.
 *   · Actions say what they do in words. An icon is never the whole label.
 * ---------------------------------------------------------------------- */

:root {
  /* ---- the palette, taken from the Stitch screens (Design/stitch/screens,
   *      their Tailwind config), not from DESIGN.md's prose ---- */
  --paper:       #FCF9F2;   /* surface: the warm page ground */
  --surface:     #FFFFFF;   /* surface-container-lowest: cards and controls */
  --sunken:      #F1EEE7;   /* surface-container: inset panels, photo boxes */
  --sunken-low:  #F6F3EC;   /* surface-container-low: the "nog over" box, stepper bed */
  --sunken-high: #EBE8E1;   /* surface-container-high: notes, the help strip */
  --track:       #EBE8E1;   /* the meter track */
  --ink:         #002211;   /* primary: headings, prices, the primary action */
  --ink-hover:   #123824;   /* primary-container: pressed and hover */
  --forest:      #123824;   /* primary-container: the active tab pill */
  --ink-body:    #414843;   /* on-surface-variant: secondary text, 9.7:1 on white */
  --ink-was:     #5C645D;   /* struck-through prices, 6:1 on white */
  --signal:      #8E4E04;   /* secondary: the −% badge, savings, the count badge */
  --on-signal:   #FFFFFF;
  --signal-soft: #FFDCC2;   /* secondary-fixed: peach, the savings strip and week pill */
  --on-signal-soft: #2E1500;
  --mint:        #C2EDCF;   /* primary-fixed: icon tiles */
  --on-mint:     #002111;
  --mint-soft:   #E3F8F0;   /* tertiary-fixed at 40%: your discount on the receipt */
  --success:     #1D4F40;   /* on-tertiary-fixed-variant */
  --success-soft:#BAEED9;   /* tertiary-fixed: "op je lijst", good news */
  --alert:       #93000A;   /* on-error-container: warnings and not-a-saving */
  --alert-soft:  #FFDAD6;   /* error-container */
  --border:      #E5E2DB;   /* surface-container-highest: the few edges left */
  --focus:       #8E4E04;
  --plan:        #7BA288;   /* on-primary-container: this list on the budget bar */

  /* Category tiles: the Stitch aisle tints, behind the product icon. */
  --tint-produce: #C2EDCF;
  --tint-bakery:  #FFDCC2;
  --tint-dairy:   #BAEED9;
  --tint-meat:    #FFDAD6;
  --tint-pantry:  #EBE8E1;
  --tint-snacks:  #FFDCC2;
  --tint-drinks:  #9ED1BD;
  --tint-frozen:  #BAEED9;
  --tint-house:   #E5E2DB;
  --tint-care:    #C2EDCF;

  /* Stitch lifts cards off the ground with a soft shadow instead of an edge. */
  --shadow-card: 0 4px 6px -1px rgba(0, 34, 17, .08), 0 2px 4px -2px rgba(0, 34, 17, .06);
  --shadow-soft: 0 1px 2px rgba(0, 34, 17, .06);

  /* Kept as aliases so component rules read in terms of role. */
  --hairline:  var(--border);
  --divider:   var(--border);
  --dashed:    var(--ink-body);
  --ink-meta:  var(--ink-body);
  --ink-label: var(--ink-body);
  --ink-faint: var(--ink-body);
  --bg:        var(--paper);
  --text:      var(--ink);
  --muted:     var(--ink-body);

  /* Bars and sheets that float over content: the Stitch tab bar's shadow. */
  --drop: 0 -2px 12px rgba(18, 56, 36, .06);
  --drop-up: 0 1px 8px rgba(0, 0, 0, .04);

  /* One family for words and numbers. Plus Jakarta Sans when the webfont
   * arrives, the platform sans otherwise — the app has to work with no
   * network, and every size and weight below still reads on the fallback. */
  --font-sans: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', Roboto,
               Helvetica, Arial, sans-serif;
  --font-num:  var(--font-sans);
  /* Code samples in the settings copy only. */
  --font-code: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Type scale: Normaal. Groot is below. */
  --fs-meta:     13px;  /* the floor, metadata only */
  --fs-body:     15px;
  --fs-body-lg:  17px;
  --fs-h-md:     19px;
  --fs-h-lg:     22px;
  --fs-h-xl:     24px;  /* screen titles on a phone */
  --fs-price-md: 19px;
  --fs-price-lg: 24px;
  --fs-tab:      12px;  /* five labels across a 320px phone */

  /* Radii: 8 standard, 16 for cards, 24 for sheets. */
  --r-screen: 24px;
  --r-card:   16px;
  --r-group:  16px;
  --r-button: 12px;
  --r-thumb:  12px;
  --r-add:    12px;
  --r-icon:   12px;
  --r-chip:   8px;
  --r-badge:  8px;
  --r-pill:   9999px;

  --tap:      48px;   /* every control */
  --tap-min:  44px;   /* steppers, chips, segmented buttons */
  --thumb:    112px;  /* product photo on an offer card */
  --row-photo: 76px;  /* product photo on a list row */

  --gutter:   16px;   /* cards and lists */
  --gutter-x: 16px;   /* titles and section headings */
}

/* Groot: the same rules a step up — the scale of the Stitch screens. */
:root[data-size="large"] {
  --fs-meta:     15px;
  --fs-body:     17px;
  --fs-body-lg:  19px;
  --fs-h-md:     22px;
  --fs-h-lg:     26px;
  --fs-h-xl:     28px;
  --fs-price-md: 22px;
  --fs-price-lg: 28px;
  --fs-tab:      14px;
  --tap:         52px;
  --tap-min:     48px;
  --thumb:       128px;
  --row-photo:   88px;
}

* { box-sizing: border-box; }

/* Any author rule that sets `display` outranks the UA stylesheet's
 * [hidden] { display: none }, so an element with a display of its own stays
 * visible while carrying the attribute. `.sheet` is display:flex, which made
 * both overlays sit on top of the app and swallow every click. Guard globally
 * rather than per-component — the next `display:` rule would reintroduce it. */
[hidden] { display: none !important; }

/* Focus is always visible and never colour-only thin: a 3px amber ring. */
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-body); line-height: 1.5; font-weight: 500;
  background: var(--paper);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  /* Room for the fixed tab bar. */
  padding-bottom: calc(92px + env(safe-area-inset-bottom, 0px));
}

h1, h2, h3 { margin: 0; font-weight: 700; }
h1 { font-size: var(--fs-h-md); line-height: 1.2; letter-spacing: -.01em; }
h2 { font-size: var(--fs-h-md); line-height: 1.3; letter-spacing: 0; }

.muted { color: var(--ink-body); }
.small { font-size: var(--fs-meta); line-height: 1.5; }
.sub   { color: var(--ink-body); }

/* Every number and price. Bold, lining, proportional — no condensed or
 * subscript decimals — so "€ 2,49" reads in one glance. */
.mono, .num, .running-total, .opt-cost, .amt, .ck-amt, .sp-price, .deal-price,
.route-dist, .store-km, .qty-tag, .ing-amt, .val, .pill, .badge, .meta {
  font-family: var(--font-num);
  font-variant-numeric: lining-nums proportional-nums;
}

/* ---------- top bar ---------- */

/* The Android app draws edge to edge, under the status bar. Capacitor hands
 * the bar's height over as --safe-area-inset-top; a browser uses env(). */
.topbar {
  position: sticky; top: 0; z-index: 25;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  padding: calc(12px + var(--safe-area-inset-top, env(safe-area-inset-top, 0px))) var(--gutter-x) 12px;
  background: rgba(252, 249, 242, .92);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  box-shadow: var(--drop-up);
}
.brand { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; }
/* The wordmark: "kortingsApp" in forest, one word, no chip — a chip read as
 * a button in testing with older users. */
.logo {
  display: inline; background: none; color: var(--ink);
  padding: 0; border-radius: 0;
  font-weight: 800; font-size: inherit; line-height: inherit; letter-spacing: inherit;
}
.brand h1 { font-size: var(--fs-h-md); font-weight: 800; letter-spacing: -.02em; }
/* The app icon before the wordmark, sized in em so it grows with Groot. */
.brand-mark { display: inline-block; width: 1.45em; height: 1.45em; vertical-align: -.4em; margin-right: .35em; }

.topbar-actions { display: flex; align-items: center; gap: 8px; }

.icon-btn {
  display: grid; place-items: center; flex: none;
  width: var(--tap); height: var(--tap); border-radius: var(--r-icon);
  border: 1.5px solid var(--border); background: var(--surface); color: var(--ink);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 700; cursor: pointer;
}
.icon-btn:hover { background: var(--sunken); }
.icon-btn svg { width: 24px; height: 24px; display: block; }

.meta { font-size: var(--fs-meta); font-weight: 600; color: var(--ink-body); }
/* The week number sits on a peach pill, as on the Stitch header. */
#weekMeta {
  padding: 2px 10px; border-radius: var(--r-pill);
  background: var(--signal-soft); color: var(--on-signal-soft); white-space: nowrap;
}

/* ---------- bottom tab bar ---------- */

.tabs {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  display: flex; justify-content: space-between; gap: 4px;
  padding: 8px 8px calc(10px + env(safe-area-inset-bottom, 0px));
  background: rgba(252, 249, 242, .96);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  box-shadow: var(--drop);
}
.tab {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; flex: 1 1 0; min-width: 0; min-height: var(--tap); padding: 2px 0;
  border: 0; background: none; color: var(--ink-body); cursor: pointer;
  font-family: var(--font-sans); font-size: var(--fs-tab); font-weight: 600;
  line-height: 1.2; letter-spacing: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tab.is-active { color: var(--ink); font-weight: 800; }
/* The glyph sits in a pill (.tab-ico, below); the active pill fills forest
 * and the stroke, drawn in currentColor, turns white on it. Position is never
 * the only cue: the active label also goes to full ink and extra-bold. */

.tabpanel { display: none; padding: 0 0 24px; }
.tabpanel.is-active { display: block; }

main { max-width: 640px; margin: 0 auto; }

/* ---------- headings and sections ---------- */

/* Screen title: "Gangen", "Mandje". */
.screen-head { display: block; padding: 20px var(--gutter-x) 14px; }
.screen-head h2 { font-size: var(--fs-h-xl); font-weight: 800; line-height: 1.2; letter-spacing: -.02em; }
.head-actions { display: flex; align-items: center; gap: 12px; }

/* Section heading: "Meest verlaagd" ↔ "t/m zo". */
.section-head {
  display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap;
  gap: 4px 12px; padding: 24px var(--gutter-x) 12px;
}
.section-head h2 { font-size: var(--fs-h-md); font-weight: 800; }
.section-head .meta { font-size: var(--fs-meta); color: var(--ink); font-weight: 700; }

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

.card {
  background: var(--surface); border: 0;
  border-radius: var(--r-card); box-shadow: var(--shadow-card);
  padding: 18px; margin: 0 var(--gutter) 16px;
}
.card-head {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: 8px 12px; margin-bottom: 12px;
}
.card-head h2 { font-size: var(--fs-body-lg); font-weight: 800; }

/* A note that isn't a card: a tinted panel, not a faint dashed outline. */
.note-card, .nudge-card {
  margin: 0 var(--gutter) 16px;
  background: var(--sunken); border: 1.5px solid var(--border);
  border-radius: var(--r-card); padding: 18px;
  font-size: var(--fs-body); line-height: 1.5;
}
.note-card ul { margin: 8px 0 0; padding-left: 1.2rem; color: var(--ink-body); }
.note-card li { margin-bottom: 4px; }
/* A list inside a note keeps its own cards but not the screen gutter — the
 * note already provides it. */
.note-card .list, .nudge-card .list, .nudges, .value-list {
  margin: 12px 0 0; padding: 0;
}

.field-label {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 22px 0 8px;
  font-size: var(--fs-body); font-weight: 700; color: var(--ink);
}
.card > .field-label:first-child { margin-top: 0; }

.pill {
  display: inline-block; padding: 2px 10px; border-radius: var(--r-pill);
  background: var(--sunken); color: var(--ink);
  font-size: var(--fs-meta); font-weight: 700; line-height: 1.4;
}

.empty {
  padding: 24px var(--gutter-x); text-align: center;
  font-size: var(--fs-body); line-height: 1.5; color: var(--ink-body);
}
.hint {
  margin: 16px var(--gutter) 0; padding: 16px;
  background: var(--sunken); border: 1.5px solid var(--border); border-radius: var(--r-card);
  font-size: var(--fs-body); line-height: 1.5; color: var(--ink);
}

/* ---------- lists ---------- */

/* Each row is its own white card with a drawn edge and a 12px gap to the
 * next — a mis-tap lands on the gap, not on the neighbour. Rows wrap, so the
 * controls drop under the name on a narrow phone instead of crushing it. */
.list {
  list-style: none; margin: 0 var(--gutter); padding: 0;
  display: flex; flex-direction: column; gap: 12px;
}
.list:empty { display: none; }
.list li {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  padding: 14px; background: var(--surface);
  border: 1.5px solid var(--border); border-radius: var(--r-card);
}
/* Inside a card the rows already sit on white, so they need no gutter. */
.card .list { margin: 0; }

.item-name { flex: 1 1 180px; min-width: 0; font-size: var(--fs-body-lg); font-weight: 700; line-height: 1.3; }
.item-name .sub {
  display: block; margin-top: 4px;
  font-size: var(--fs-meta); font-weight: 500; line-height: 1.45;
  color: var(--ink-body);
}

/* Stepper: big − and + either side of a big number, on a sunken panel. */
.qty {
  display: flex; align-items: center; gap: 8px; flex: none; margin-left: auto;
  padding: 4px; border-radius: var(--r-button); background: var(--sunken);
}
.qty button {
  width: var(--tap-min); height: var(--tap-min); border-radius: var(--r-chip); cursor: pointer;
  border: 1.5px solid var(--border); background: var(--surface); color: var(--ink);
  font-family: var(--font-sans); font-size: 24px; font-weight: 700; line-height: 1;
}
.qty button:hover { background: var(--paper); }
.qty button:active { transform: scale(.96); }
.qty span {
  min-width: 32px; text-align: center;
  font-family: var(--font-num); font-size: var(--fs-body-lg); font-weight: 800;
}

.star-btn {
  flex: none; width: var(--tap); height: var(--tap); border-radius: var(--r-button);
  border: 2px solid var(--border); background: var(--surface);
  color: var(--ink-body); font-size: 22px; line-height: 1; cursor: pointer;
}
.star-btn.is-on { background: var(--ink); border-color: var(--ink); color: var(--surface); }

.remove-btn {
  flex: none; width: var(--tap); height: var(--tap); border-radius: var(--r-button);
  border: 1.5px solid var(--border); background: var(--surface); color: var(--ink);
  font-size: 20px; font-weight: 700; line-height: 1; padding: 0; cursor: pointer;
}
.remove-btn:hover { background: var(--alert-soft); border-color: var(--alert); color: var(--alert); }

/* ---------- the deal row (screen 1) ---------- */

.thumb {
  flex: none; width: var(--thumb); height: var(--thumb); border-radius: var(--r-thumb);
  background: var(--sunken);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-num); font-size: 13px; font-weight: 700;
  color: var(--ink-body); text-align: center;
  position: relative; overflow: hidden;
}
.thumb.small { width: 44px; height: 44px; border-radius: var(--r-chip); font-size: 11px; }

/* The packshot, when there is one, sits over the pack-size text rather than
 * replacing it: if the retailer's CDN doesn't deliver, app.js drops the <img>
 * and the text underneath is already in place. Packshots are transparent PNGs,
 * so the tile colour is repeated here to keep the text from showing through.
 * `contain` because these are product cut-outs — cropping one is worse than
 * letterboxing it. */
.thumb img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  background: var(--sunken);
}

.prices {
  display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; margin-top: 6px;
  font-family: var(--font-num); font-size: var(--fs-body); font-weight: 600;
}
/* The old price keeps a clear stroke and its own tone, so it can't be read
 * as the price to pay. */
.prices .was, .was {
  text-decoration: line-through; text-decoration-thickness: 2px;
  color: var(--ink-was); font-weight: 600;
}
.prices .now, .now { font-size: var(--fs-price-md); font-weight: 800; color: var(--ink); letter-spacing: -.01em; }
.badge {
  background: var(--signal); color: var(--on-signal);
  padding: 2px 8px; border-radius: var(--r-badge); font-size: var(--fs-meta); font-weight: 800;
}

/* Add: a full-width, labelled button at the foot of the row card — not a
 * small "+" floating in a corner. */
.add-btn, .add {
  flex: 1 0 100%; display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--tap); padding: 12px 16px; border-radius: var(--r-add);
  border: 2px solid var(--ink); background: var(--ink); color: var(--surface);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 700;
  line-height: 1.2; text-align: center; cursor: pointer;
}
.add-btn:hover, .add:hover { background: var(--ink-hover); }
.add-btn:active, .add:active { transform: scale(.98); }
.add-btn.is-done { background: var(--surface); color: var(--ink); }

/* ---------- the budget card (screen 1) ---------- */

.budget-card { margin-top: 16px; }
.budget-row {
  display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap;
  gap: 4px 12px; margin-bottom: 14px;
}
.budget-row .label { font-size: var(--fs-h-md); font-weight: 800; }
.budget-row .amount { font-family: var(--font-num); font-size: var(--fs-price-md); font-weight: 800; }

.bar {
  height: 16px; border-radius: var(--r-pill);
  background: var(--track); overflow: hidden; display: flex;
}
.bar-fill { height: 100%; background: var(--ink); transition: width .2s ease-out; }
/* The saved segment is the one thing amber is for. */
.bar-fill.is-saved { background: var(--signal); }

.budget-figures {
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap;
  gap: 8px 12px; margin-top: 14px;
  font-family: var(--font-num); font-size: var(--fs-body); font-weight: 700;
}
.budget-figures .saved-pill {
  padding: 4px 12px; background: var(--signal-soft); color: var(--on-signal-soft);
  border-radius: var(--r-badge); font-weight: 800;
}
/* Over budget is not a saving, so it can never be amber. It gets the alert
 * outline instead. */
.budget-figures .over-pill {
  padding: 2px 10px; border: 2px solid var(--alert); border-radius: var(--r-badge);
  color: var(--alert); font-weight: 800;
}

.bar.mini { height: 10px; margin-top: 10px; max-width: 240px; }
.budget { margin-top: 14px; padding-top: 14px; border-top: 1.5px solid var(--border); }
.budget-fill { background: var(--ink); }
.budget-fill.over, .budget-fill.near { background: var(--alert); }

/* ---------- inputs ---------- */

.input, .select, input[type="search"], input[type="date"], input[type="number"] {
  width: 100%; min-height: var(--tap); padding: 12px 16px;
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 500;
  border: 2px solid var(--border); border-radius: var(--r-button);
  background: var(--surface); color: var(--ink);
}
input::placeholder { color: var(--ink-body); opacity: 1; }
.input:focus, input[type="search"]:focus, .select:focus {
  outline: 3px solid var(--focus); outline-offset: 0; border-color: var(--ink);
}
.select { width: auto; padding: 10px 14px; font-weight: 600; }
.row { display: flex; gap: 10px; align-items: center; }
.two-up { margin-top: 12px; flex-wrap: wrap; align-items: stretch; }
.two-up > * { flex: 1 1 140px; margin-top: 0; }

.range { width: 100%; height: 32px; accent-color: var(--ink); }
.checkbox {
  display: flex; align-items: flex-start; gap: 14px;
  margin-top: 14px; padding: 6px 0; min-height: var(--tap);
  font-size: var(--fs-body); line-height: 1.45; cursor: pointer;
}
.checkbox input[type="checkbox"] {
  flex: none; accent-color: var(--ink); width: 28px; height: 28px; margin: 0;
}

.search-wrap { position: relative; }
.suggestions {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 30;
  background: var(--surface); border: 2px solid var(--ink);
  border-radius: var(--r-button); overflow: hidden auto; max-height: 320px;
  box-shadow: var(--drop-up);
}
.suggestion {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; min-height: var(--tap); padding: 12px 16px; cursor: pointer;
  font-size: var(--fs-body); font-weight: 600;
  border-bottom: 1.5px solid var(--border);
}
.suggestion:last-child { border-bottom: 0; }
.suggestion:hover { background: var(--sunken); }
.suggestion .cat {
  display: block; margin-top: 2px;
  font-size: var(--fs-meta); font-weight: 500; color: var(--ink-body);
}

/* ---------- buttons ---------- */

/* Primary: solid forest, white bold label, a touch taller than a control. */
.primary-btn {
  display: block; width: calc(100% - var(--gutter) * 2); margin: 20px var(--gutter) 0;
  min-height: calc(var(--tap) + 2px); padding: 14px 18px; border: 2px solid var(--ink); border-radius: var(--r-button);
  background: var(--ink); color: var(--surface);
  font-family: var(--font-sans); font-size: var(--fs-body-lg); font-weight: 800;
  text-align: center; cursor: pointer;
}
.primary-btn:hover { background: var(--ink-hover); }
.primary-btn:active { transform: scale(.98); }
.primary-btn:disabled { opacity: .5; cursor: not-allowed; }
/* Inside a card or sheet the gutter is already there. */
.card .primary-btn, .sheet-inner .primary-btn { width: 100%; margin: 16px 0 0; }

/* Secondary: white with a 2px forest edge. */
.ghost-btn {
  width: 100%; margin-top: 12px; min-height: var(--tap); padding: 12px 16px;
  border: 2px solid var(--ink); border-radius: var(--r-button);
  background: var(--surface); color: var(--ink);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 700; cursor: pointer;
}
.ghost-btn:hover { background: var(--sunken); }
.ghost-btn.inline { width: auto; margin-top: 0; white-space: nowrap; }

/* Text actions are still buttons: full tap height, underlined, in ink. */
.link-btn {
  min-height: var(--tap-min); padding: 8px 4px;
  border: 0; background: none; color: var(--ink);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 700; cursor: pointer;
  text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px;
}
.link-btn:hover { color: var(--ink-hover); }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
/* One line that scrolls sideways: the staples on Zoeken, too many to wrap.
 * The padding keeps the chips' soft shadow from being clipped. */
.chip-row { flex-wrap: nowrap; overflow-x: auto; padding: 4px 2px 8px; scrollbar-width: none; }
.chip-row::-webkit-scrollbar { display: none; }
.chip-row .chip { flex: none; }
/* Round, white and lifted, as the Stitch filter chips are. */
.chip {
  min-height: var(--tap-min); padding: 10px 16px; border-radius: var(--r-pill); cursor: pointer;
  border: 0; background: var(--surface); color: var(--ink); box-shadow: var(--shadow-soft);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 600;
}
.chip:hover { background: var(--sunken-low); }
/* Selected never relies on colour alone: it also gains a tick. */
.chip.is-on { background: var(--ink); color: var(--surface); }
.chip.is-on::before { content: "✓ "; font-weight: 800; }
.chip-meta {
  font-family: var(--font-num); font-size: var(--fs-meta); font-weight: 700;
  color: var(--ink-body); margin-left: 6px;
}
.chip.is-on .chip-meta { color: var(--surface); }
.recipe-row { display: flex; align-items: center; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.recipe-picker { margin: 0 0 16px; }

.segmented {
  display: flex; gap: 8px; flex-wrap: wrap;
}
.segmented button {
  flex: 1 1 0; min-height: var(--tap-min); padding: 10px 8px; cursor: pointer;
  border: 2px solid var(--border); border-radius: var(--r-button);
  background: var(--surface); color: var(--ink);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 600;
}
.segmented button.is-active { background: var(--ink); border-color: var(--ink); color: var(--surface); font-weight: 800; }
.segmented button.is-active::before { content: "✓ "; }

/* ---------- aisle rows (screen 2) ---------- */

.store-row, .pantry-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  padding: 14px; background: var(--surface);
}
.store-row {
  font-size: var(--fs-body); min-height: var(--tap);
  border: 1.5px solid var(--border); border-radius: var(--r-card);
}
.store-list {
  margin-top: 10px; display: flex; flex-direction: column; gap: 10px;
}
.store-row .store-where { flex: 1 1 160px; min-width: 0; font-weight: 700; }
.store-row .store-where .sub {
  display: block; margin-top: 2px;
  font-size: var(--fs-meta); font-weight: 500;
  color: var(--ink-body);
}
.store-row .store-km { font-size: var(--fs-meta); font-weight: 700; color: var(--ink-body); }
.store-row.is-unpriced { background: var(--sunken); }

/* The deal-count badge: a count of savings, so it is allowed amber. */
.count-badge {
  flex: none; background: var(--signal-soft); color: var(--on-signal-soft);
  padding: 2px 10px; border-radius: var(--r-badge);
  font-family: var(--font-num); font-size: var(--fs-meta); font-weight: 800;
}

/* ---------- plan ---------- */

.options-card { padding-bottom: 18px; }
.option-row { display: flex; gap: 10px; overflow-x: auto; padding: 2px 2px 6px; }
.option {
  flex: 1 0 auto; min-width: 140px; min-height: var(--tap); text-align: left; cursor: pointer;
  border: 2px solid var(--border); border-radius: var(--r-button); padding: 14px;
  background: var(--surface); color: var(--ink); font-family: var(--font-sans);
}
.option.is-selected { border-color: var(--ink); border-width: 3px; padding: 13px; background: var(--success-soft); }
.option .opt-stops {
  font-size: var(--fs-meta); font-weight: 700;
  color: var(--ink-body); text-transform: uppercase; letter-spacing: .03em;
}
.option .opt-cost { font-size: var(--fs-price-md); font-weight: 800; margin: 4px 0; }
.option .opt-delta {
  display: inline-block; background: var(--signal); color: var(--on-signal);
  padding: 2px 8px; border-radius: var(--r-badge);
  font-family: var(--font-num); font-size: var(--fs-meta); font-weight: 800;
}
.option .opt-meta {
  margin-top: 4px;
  font-family: var(--font-num); font-size: var(--fs-meta); font-weight: 600;
  color: var(--ink-body);
}
.option .best-tag {
  display: inline-block; margin-left: 6px; padding: 1px 8px; border-radius: var(--r-badge);
  background: var(--ink); color: var(--surface);
  font-size: var(--fs-meta); font-weight: 800; letter-spacing: .04em;
}

.summary-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.stat {
  min-width: 0; padding: 12px; border-radius: var(--r-button); background: var(--sunken);
}
.stat .val { font-size: var(--fs-price-md); font-weight: 800; }
.stat .lbl {
  margin-top: 2px;
  font-size: var(--fs-meta); font-weight: 600;
  color: var(--ink-body);
}
.stat.saving .val { display: inline-block; background: var(--signal); color: var(--on-signal); padding: 0 8px; border-radius: var(--r-badge); }
@media (min-width: 560px) {
  .summary-grid { grid-template-columns: repeat(4, 1fr); }
}

/* Savings get amber; everything else states itself in ink. */
.savings-banner {
  margin-top: 14px; padding: 12px 14px; border-radius: var(--r-button);
  background: var(--signal-soft); color: var(--on-signal-soft);
  font-size: var(--fs-body); font-weight: 800;
}
/* A warning is crimson on a pale tint, with a drawn edge — never amber. */
.warn-banner {
  margin-top: 12px; padding: 12px 14px; border-radius: var(--r-button);
  background: var(--alert-soft); color: var(--alert); border: 2px solid var(--alert);
  font-size: var(--fs-body); line-height: 1.45; font-weight: 700;
}

.stop-card { padding-top: 18px; }
.stop-head { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 14px; }
.stop-num {
  flex: none; display: grid; place-items: center;
  width: 40px; height: 40px; border-radius: var(--r-chip);
  background: var(--ink); color: var(--surface);
  font-family: var(--font-num); font-size: var(--fs-body-lg); font-weight: 800;
}
.stop-title { flex: 1; min-width: 0; }
.stop-title .store { font-size: var(--fs-body-lg); font-weight: 800; }
.stop-title .meta { display: block; margin-top: 2px; font-size: var(--fs-meta); }
.stop-total { text-align: right; font-family: var(--font-num); font-size: var(--fs-price-md); font-weight: 800; }
.stop-total .saved {
  display: block; margin-top: 2px; font-size: var(--fs-meta); font-weight: 600;
  color: var(--ink-body);
}

.leg {
  padding: 12px var(--gutter-x) 8px;
  font-size: var(--fs-meta); font-weight: 600;
  color: var(--ink-body);
}
.leg::before { content: "↓ "; }

.buy-line {
  display: flex; align-items: baseline; gap: 12px;
  padding: 12px 0; border-bottom: 1.5px solid var(--border);
}
.buy-line:last-of-type { border-bottom: 0; }
.buy-line .qty-tag { flex: none; min-width: 36px; font-size: var(--fs-body); font-weight: 800; color: var(--ink); }
.buy-line .nm { flex: 1; min-width: 0; font-size: var(--fs-body); font-weight: 700; }
.buy-line .nm .unit {
  display: block; margin-top: 2px;
  font-size: var(--fs-meta); font-weight: 500;
  color: var(--ink-body);
}
.buy-line .amt { text-align: right; font-size: var(--fs-body-lg); font-weight: 800; }
.buy-line .amt .was { display: block; font-size: var(--fs-meta); font-weight: 600; }

.tag {
  display: inline-block; padding: 1px 8px; border-radius: var(--r-badge);
  font-size: var(--fs-meta); font-weight: 700;
  letter-spacing: 0; vertical-align: baseline;
}
.tag.sale { background: var(--signal-soft); color: var(--on-signal-soft); }
.tag.must { background: var(--sunken); color: var(--ink); }
.tag.card { background: var(--sunken); color: var(--ink); }

.card-note {
  margin: 0 0 14px; padding: 12px 14px; border-radius: var(--r-button);
  background: var(--sunken); color: var(--ink);
  font-size: var(--fs-body); font-weight: 600;
}
.card-cta {
  width: 100%; margin-bottom: 14px; min-height: var(--tap); padding: 12px 16px; border-radius: var(--r-button);
  border: 2px solid var(--ink); background: var(--ink); color: var(--surface);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 800; cursor: pointer;
}
.card-cta:hover { background: var(--ink-hover); }

/* ---------- the whole route ---------- */

.route-card { padding-bottom: 18px; }
.route-map {
  display: block; width: 100%; height: auto;
  background: var(--sunken); border-radius: var(--r-button); margin-bottom: 14px;
  border: 1.5px solid var(--border);
}
.route-leg {
  fill: none; stroke: var(--ink); stroke-width: 3;
  stroke-linejoin: round; stroke-linecap: round;
}
.route-leg.is-return { stroke: var(--ink-body); stroke-dasharray: 6 5; }
.route-stop circle { fill: var(--ink); }
.route-stop text { fill: var(--surface); font-family: var(--font-num); font-size: 12px; font-weight: 800; }
.route-home circle { fill: var(--surface); stroke: var(--ink); stroke-width: 2; }
.route-home text { fill: var(--ink); font-size: 11px; font-weight: 800; }

.route-list {
  display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px;
}
.route-row {
  display: flex; align-items: center; gap: 14px; min-height: var(--tap);
  padding: 12px 14px; background: var(--surface);
  border: 1.5px solid var(--border); border-radius: var(--r-button);
}
.route-mark {
  flex: none; display: grid; place-items: center;
  width: 40px; height: 40px; border-radius: var(--r-chip);
  background: var(--ink); color: var(--surface);
  font-family: var(--font-num); font-size: var(--fs-body); font-weight: 800;
}
.route-row.is-home .route-mark {
  background: var(--surface); color: var(--ink); border: 2px solid var(--ink);
}
.route-where { flex: 1; min-width: 0; font-size: var(--fs-body); font-weight: 700; }
.route-where .sub {
  display: block; margin-top: 2px;
  font-size: var(--fs-meta); font-weight: 500;
}
.route-dist { font-size: var(--fs-meta); font-weight: 700; color: var(--ink-body); }

.route-cta {
  width: 100%; margin-top: 14px; min-height: calc(var(--tap) + 2px); padding: 14px 18px;
  border: 2px solid var(--ink); border-radius: var(--r-button);
  background: var(--ink); color: var(--surface);
  font-family: var(--font-sans); font-size: var(--fs-body-lg); font-weight: 800; cursor: pointer;
}
.route-cta:hover { background: var(--ink-hover); }

/* ---------- mandje (screen 3) ---------- */

.progress-card { margin-bottom: 16px; }
.progress-line {
  display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap;
  gap: 4px 12px; margin-bottom: 12px;
}
.running-total { font-size: var(--fs-price-md); font-weight: 800; }

/* The receipt summary: normaal → nu te betalen → je bespaart. A white card
 * like a printed kassabon, with the saving stated in amber. */
.summary-block {
  margin: 0 var(--gutter) 14px; padding: 18px;
  background: var(--surface); color: var(--ink);
  border: 1.5px solid var(--border); border-radius: var(--r-card);
}
.summary-block .normal-row {
  display: flex; justify-content: space-between; gap: 12px;
  font-family: var(--font-num); font-size: var(--fs-body-lg); font-weight: 600; color: var(--ink-body);
}
.summary-block .normal-row > span:last-child {
  text-decoration: line-through; text-decoration-thickness: 2px; color: var(--ink-was);
}
.summary-block .pay-row {
  display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap;
  gap: 4px 12px; margin-top: 16px; padding-top: 16px; border-top: 1.5px solid var(--border);
}
.summary-block .pay-label { font-size: var(--fs-h-md); font-weight: 800; }
.summary-block .pay-amount { font-family: var(--font-num); font-size: var(--fs-price-lg); font-weight: 800; letter-spacing: -.02em; }
.savings-strip {
  display: flex; justify-content: space-between; gap: 12px; margin-top: 14px;
  padding: 12px 14px; border-radius: var(--r-button);
  background: var(--signal-soft); color: var(--on-signal-soft);
  font-family: var(--font-num); font-size: var(--fs-body-lg); font-weight: 800;
}
.budget-note {
  margin: 0 var(--gutter) 14px; padding: 14px 16px;
  background: var(--sunken); border-radius: var(--r-button);
  font-size: var(--fs-body); line-height: 1.5; color: var(--ink);
}
.budget-note b { font-weight: 800; }

.shop-stop.done { background: var(--sunken); }
.shop-stop.done .stop-num { background: var(--success); }

/* A whole row is the tap target; the box itself is large and heavy-edged. */
.check-line {
  display: flex; align-items: center; gap: 14px; min-height: 60px;
  padding: 12px 0; border-bottom: 1.5px solid var(--border); cursor: pointer;
}
.check-line:last-of-type { border-bottom: 0; }
.check-box {
  flex: none; display: grid; place-items: center;
  width: 32px; height: 32px; border-radius: var(--r-chip);
  border: 2.5px solid var(--ink); background: var(--surface);
  font-size: 20px; font-weight: 800; color: transparent;
}
.check-line.is-checked .check-box {
  background: var(--success); border-color: var(--success); color: var(--surface);
}
/* Strike only the title element — text-decoration propagates to descendants
 * and a child's `text-decoration: none` cannot cancel an ancestor's line. */
.check-line.is-checked .ck-title { text-decoration: line-through; text-decoration-thickness: 2px; }
.check-line.is-checked .ck-name { color: var(--ink-body); }
.ck-name { flex: 1; min-width: 0; font-size: var(--fs-body); font-weight: 700; }
.ck-name .unit {
  display: block; margin-top: 2px;
  font-size: var(--fs-meta); font-weight: 500;
  color: var(--ink-body);
}
.ck-amt { font-size: var(--fs-body-lg); font-weight: 800; }

.stop-done-btn {
  width: 100%; margin-top: 14px; min-height: var(--tap); padding: 12px 16px; border-radius: var(--r-button);
  border: 2px solid var(--ink); background: var(--surface); color: var(--ink);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 800; cursor: pointer;
}
.stop-done-btn:hover { background: var(--sunken); }

.trip-done {
  margin: 0 var(--gutter) 14px; padding: 18px; border-radius: var(--r-card);
  background: var(--signal-soft); color: var(--on-signal-soft);
  border: 1.5px solid var(--signal);
  font-size: var(--fs-body-lg); font-weight: 800; line-height: 1.45;
}
.trip-done .stop-done-btn { background: var(--ink); border-color: var(--ink); color: var(--surface); }

.shared-note {
  margin: 14px 0 0; padding-top: 12px; border-top: 1.5px solid var(--border);
  font-size: var(--fs-body); line-height: 1.5; color: var(--ink-body);
}

/* ---------- deals ---------- */

.deals li { align-items: center; }
.deal-info { flex: 1 1 180px; min-width: 0; }
.deal-info .nm { font-size: var(--fs-body-lg); font-weight: 700; line-height: 1.3; }
.deal-info .sub {
  display: block; margin-top: 4px;
  font-size: var(--fs-meta); font-weight: 500; line-height: 1.45;
  color: var(--ink-body);
}
.deal-price { text-align: right; flex: none; margin-left: auto; }
.deal-price .now { font-size: var(--fs-price-md); font-weight: 800; }
.deal-price .was { display: block; font-size: var(--fs-meta); font-weight: 600; }
.deal-pct {
  flex: none; background: var(--signal); color: var(--on-signal);
  padding: 2px 8px; border-radius: var(--r-badge);
  font-family: var(--font-num); font-size: var(--fs-meta); font-weight: 800;
}

/* ---------- deal quality ---------- */

.q-badge {
  display: inline-block; padding: 1px 8px; border-radius: var(--r-badge); white-space: nowrap;
  font-size: var(--fs-meta); font-weight: 700; line-height: 1.5;
}
/* Genuinely cheap = a saving = amber. */
.q-best, .q-great { background: var(--signal); color: var(--on-signal); }
.q-good { background: var(--success-soft); color: var(--success); }
.q-fair { border: 1.5px solid var(--border); color: var(--ink); background: var(--surface); }
/* Not a saving. Crimson on a pale tint — never amber. */
.q-poor, .q-fake { background: var(--alert-soft); color: var(--alert); }

.spark { display: block; overflow: visible; }
.spark-line { fill: none; stroke: var(--ink); stroke-width: 2.5; stroke-linejoin: round; }
.spark-area { fill: var(--sunken); opacity: 1; }
.spark-dot { fill: var(--ink); }
.spark-dot.promo { fill: var(--signal); stroke: var(--surface); stroke-width: 2; }
.spark-dot.synthetic { fill: var(--surface); stroke: var(--ink); stroke-width: 1.5; }
.spark-med { stroke: var(--ink-body); stroke-width: 1.5; stroke-dasharray: 4 4; }

.hist-row { display: flex; align-items: center; gap: 14px; margin-top: 12px; }
.hist-row .spark-wrap { flex: 1; min-width: 0; }
.hist-legend {
  display: flex; justify-content: space-between; margin-top: 4px;
  font-size: var(--fs-meta); font-weight: 600; color: var(--ink-body);
}

/* ---------- pantry ---------- */

.pantry li { align-items: flex-start; }
.pantry-row { padding: 14px; }

/* ---------- item detail ---------- */

.detail-head {
  display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap;
  gap: 8px; margin-bottom: 6px; font-size: var(--fs-body);
}
.store-price-row {
  display: flex; align-items: center; gap: 14px; min-height: var(--tap);
  padding: 12px 0; border-bottom: 1.5px solid var(--border);
}
.store-price-row:last-child { border-bottom: 0; }
.store-price-row .sp-store { flex: 1; min-width: 0; font-size: var(--fs-body); font-weight: 700; }
.store-price-row .sp-store .sub {
  display: block; margin-top: 2px;
  font-size: var(--fs-meta); font-weight: 500;
}
.store-price-row .sp-price { text-align: right; font-size: var(--fs-body-lg); font-weight: 800; }
.store-price-row .sp-price .was { display: block; font-size: var(--fs-meta); font-weight: 600; }
.store-price-row .sp-price .sub { display: block; font-size: var(--fs-meta); font-weight: 500; }
.store-price-row.cheapest {
  margin: 0 -10px; padding: 12px 10px; border-bottom: 0;
  background: var(--success-soft); border-radius: var(--r-chip);
}
.store-price-row.is-tappable { cursor: pointer; }
.store-price-row.is-tappable:hover { background: var(--sunken); }

/* A tappable name says so: a solid underline, not a faint dotted one. */
.tap-name {
  cursor: pointer; text-decoration: underline;
  text-decoration-color: var(--border); text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.tap-name:hover { text-decoration-color: var(--ink); }

/* ---------- recipes ---------- */

.serve-row { display: flex; align-items: center; gap: 12px; margin: 8px 0 4px; }
.serve-row button {
  width: var(--tap-min); height: var(--tap-min); border-radius: var(--r-chip); cursor: pointer;
  border: 1.5px solid var(--border); background: var(--surface); color: var(--ink);
  font-family: var(--font-sans); font-size: 24px; font-weight: 700; line-height: 1;
}
.serve-row button:hover { background: var(--sunken); }
.serve-count { font-family: var(--font-num); font-size: var(--fs-body-lg); font-weight: 800; }

.ingredient {
  display: flex; align-items: baseline; gap: 14px;
  padding: 12px 0; border-bottom: 1.5px solid var(--border);
}
.ingredient:last-child { border-bottom: 0; }
.ingredient .ing-mark {
  flex: none; min-width: 32px;
  font-family: var(--font-num); font-size: var(--fs-body); font-weight: 800;
}
.ingredient .ing-name { flex: 1; min-width: 0; font-size: var(--fs-body); font-weight: 700; }
.ingredient .ing-name .sub {
  display: block; margin-top: 2px; font-size: var(--fs-meta); font-weight: 500; color: var(--ink-body);
}
.ingredient .ing-amt { font-size: var(--fs-body); font-weight: 800; }
.ingredient.is-covered .ing-mark { color: var(--success); }
.ingredient.is-covered .ing-name { color: var(--ink-body); }

/* ---------- scanner ---------- */

.scan-stage {
  position: relative; width: 100%; aspect-ratio: 4 / 3;
  border-radius: var(--r-card); overflow: hidden; background: var(--ink);
  margin-bottom: 12px;
}
.scan-video { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Barcodes are wide and short, so the reticle is too — a square would have
 * people holding the phone at the wrong distance. */
.scan-reticle {
  position: absolute; left: 10%; right: 10%; top: 34%; height: 32%;
  border: 3px solid var(--surface); border-radius: var(--r-icon);
  box-shadow: 0 0 0 100vmax rgba(18, 56, 36, .5);
}
.scan-headline { margin: 12px 0 6px; font-size: var(--fs-h-md); font-weight: 800; }
#scanTorch.is-active { background: var(--ink); border-color: var(--ink); color: var(--surface); }

/* ---------- loyalty wallet & barcode ---------- */

.wallet {
  margin-top: 10px; padding: 0 16px;
  border: 1.5px solid var(--border); border-radius: var(--r-card);
  background: var(--surface);
}
.wallet-row { padding: 16px 0; border-bottom: 1.5px solid var(--border); }
.wallet-row:last-child { border-bottom: 0; }
.wallet-row .checkbox { margin-top: 0; margin-bottom: 10px; font-weight: 700; }
.wallet-row .row { gap: 8px; }

/* Always white, never themed: a scanner reads contrast, and an inverted
 * barcode is an unreadable one. */
.barcode-holder {
  background: #fff; padding: 18px 12px; border-radius: var(--r-card);
  border: 1.5px solid var(--border);
}
.barcode { display: block; width: 100%; height: auto; }
.card-number {
  margin-top: 12px; text-align: center;
  font-family: var(--font-num); font-size: var(--fs-h-md); font-weight: 700; letter-spacing: .12em;
}

/* ---------- location banner ---------- */

.loc-banner {
  display: flex; align-items: center; flex-wrap: wrap; gap: 12px;
  margin: 16px var(--gutter) 0; padding: 14px 16px;
  border: 1.5px solid var(--border); border-radius: var(--r-card);
  background: var(--surface); font-size: var(--fs-body);
}
.loc-banner.is-warn { background: var(--alert-soft); border: 2px solid var(--alert); color: var(--alert); }
.loc-banner.is-ok { background: var(--success-soft); border-color: var(--success); color: var(--success); }
.loc-text { flex: 1 1 200px; min-width: 0; }
.loc-text strong { font-weight: 800; }
.loc-text .sub { display: block; margin-top: 2px; font-size: var(--fs-meta); line-height: 1.45; color: inherit; }
.loc-btn {
  flex: none; min-height: var(--tap); padding: 10px 16px; border-radius: var(--r-button); cursor: pointer;
  border: 2px solid currentColor; background: var(--surface); color: inherit;
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 800;
}

/* ---------- sync + offline chips ---------- */

.sync-dot { width: 12px; height: 12px; border-radius: 50%; background: var(--border); flex: none; }
.sync-dot.is-on { background: var(--success); }
.sync-dot.is-pending { background: var(--surface); border: 2px solid var(--ink); }
.offline-dot {
  padding: 3px 8px; border-radius: var(--r-badge);
  background: var(--ink); color: var(--surface);
  font-size: var(--fs-meta); font-weight: 800; letter-spacing: .06em;
}

/* ---------- sheets ---------- */

.sheet {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(18, 56, 36, .5);
  display: flex; align-items: flex-end; justify-content: center;
}
.sheet-inner {
  width: 100%; max-width: 560px; max-height: 92vh; overflow-y: auto;
  background: var(--paper);
  border-radius: var(--r-screen) var(--r-screen) 0 0;
  box-shadow: var(--drop);
  padding: 20px var(--gutter) calc(32px + env(safe-area-inset-bottom, 0px));
}
.sheet-inner > .card-head { margin-bottom: 16px; }
.sheet-inner > .card-head h2 { font-size: var(--fs-h-lg); font-weight: 800; letter-spacing: -.01em; }
.sheet-inner .card { margin-left: 0; margin-right: 0; }
.sheet-inner .list { margin-left: 0; margin-right: 0; }
.sheet-inner .empty { padding-left: 0; padding-right: 0; }
.sheet-inner .note-card { margin-left: 0; margin-right: 0; }

.danger-zone {
  margin-top: 24px; padding: 16px;
  background: var(--sunken); border: 1.5px solid var(--border); border-radius: var(--r-card);
  font-size: var(--fs-body); line-height: 1.5; color: var(--ink);
}
code {
  font-family: var(--font-code); font-size: .9em;
  background: var(--sunken); color: var(--ink);
  padding: 0 6px; border-radius: 4px;
}

.toast {
  position: fixed; left: 50%; bottom: calc(104px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%); z-index: 60; max-width: min(92vw, 480px);
  padding: 14px 18px; border-radius: var(--r-button);
  background: var(--ink); color: var(--surface);
  box-shadow: var(--drop-up);
  font-size: var(--fs-body); font-weight: 700;
}


/* ==========================================================================
 * The prototype screens ("KortingsApp Helder"): Mijn lijst, Aanbiedingen,
 * Boodschappen doen, and their sheets. Built on the tokens above, so both
 * text sizes come out of the same rules.
 * ========================================================================== */

.ico {
  width: 24px; height: 24px; flex: none; display: inline-block; vertical-align: middle;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

/* ---------- header ---------- */

.week-pill {
  display: inline-flex; padding: 2px 10px; border-radius: var(--r-pill);
  background: var(--signal-soft); color: var(--on-signal-soft);
  font-size: var(--fs-meta); font-weight: 700; white-space: nowrap;
}
.head-btn {
  min-width: 64px; min-height: var(--tap); padding: 4px 8px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  border-radius: var(--r-button); border: 0; background: var(--sunken);
  color: var(--ink); font-family: var(--font-sans); font-size: var(--fs-tab); font-weight: 700; cursor: pointer;
}
.head-btn:hover { background: var(--sunken-high); }

/* ---------- tab bar ---------- */

/* The active tab: a forest pill behind the glyph and a short bar on top of
 * the tab, as on the Stitch nav. */
.tab-ico { display: flex; padding: 4px 16px; border-radius: var(--r-pill); }
.tab.is-active .tab-ico { background: var(--forest); color: var(--surface); }
.tab.is-active::before {
  content: ''; position: absolute; top: -8px; left: 50%; transform: translateX(-50%);
  width: 48px; height: 4px; border-radius: var(--r-pill); background: var(--ink);
}
.tab-count {
  position: absolute; top: 0; left: calc(50% + 12px);
  min-width: 24px; height: 24px; padding: 0 6px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-pill); border: 2px solid var(--paper);
  background: var(--signal); color: var(--on-signal);
  font-family: var(--font-num); font-size: 13px; font-weight: 800;
}

/* ---------- screens ---------- */

.lede { margin: 4px 0 0; color: var(--ink-body); font-weight: 600; }
.view { display: flex; flex-direction: column; gap: 16px; padding: 0 var(--gutter); }
.view .card { margin: 0; }
.view .section-head { padding: 4px 0 0; }
.view h3, .sheet-inner h3 { margin: 0; font-size: var(--fs-body-lg); font-weight: 800; line-height: 1.3; }
.sub-head { margin-top: 8px; }
.stack { display: flex; flex-direction: column; gap: 12px; }
.stack-sm { display: flex; flex-direction: column; gap: 8px; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.grow { flex: 1; min-width: 0; }
.money {
  font-family: var(--font-num); font-weight: 800; letter-spacing: -.01em; white-space: nowrap;
}
.chain {
  display: inline-flex; align-items: center; padding: 0 7px;
  border: 1.5px solid var(--ink); border-radius: var(--r-chip); background: var(--surface); color: var(--ink);
  font-size: var(--fs-meta); font-weight: 800; line-height: 1.6; white-space: nowrap;
}
/* The shop's own mark in front of its name, as on a folder or a receipt.
 * The one place colour comes from outside the palette: a recoloured logo is
 * not that shop's logo any more. The marks are complete images in
 * js/logos.js, so this stylesheet itself still paints only palette colours. */
.chain { padding-left: 4px; }
.shop-logo {
  display: inline-block; flex: none; vertical-align: -.2em;
  width: 1.2em; height: 1.2em; margin-right: .35em;
  border-radius: 3px; object-fit: contain; background: var(--surface);
}
.shop-logo > svg { display: block; width: 100%; height: 100%; border-radius: 3px; }
/* In a shop heading the name is bigger, so the mark grows with it. */
.stop-head h3 .shop-logo { width: 1.3em; height: 1.3em; }
.footnote {
  display: flex; gap: 10px; align-items: flex-start; margin: 0; padding: 14px;
  background: var(--sunken-high); border-radius: var(--r-card);
  color: var(--ink-body); font-size: var(--fs-meta); font-weight: 600;
}
.empty-card { display: flex; flex-direction: column; gap: 12px; align-items: center; text-align: center; }

/* ---------- buttons ---------- */

.btn {
  width: 100%; min-height: var(--tap); padding: 10px 18px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  border: 2px solid var(--ink); border-radius: var(--r-button);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 700; line-height: 1.2;
  text-align: center; cursor: pointer;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--ink); color: var(--surface); box-shadow: var(--shadow-soft); }
.btn-primary:hover { background: var(--ink-hover); }
.btn-secondary { background: var(--surface); color: var(--ink); }
.btn-secondary:hover { background: var(--sunken); }
.btn-quiet { background: var(--sunken); color: var(--ink); border-color: var(--border); }
.btn-inline { width: auto; flex: none; min-height: var(--tap-min); padding: 8px 14px; }
.btn:disabled { background: var(--sunken); color: var(--ink-body); border-color: var(--border); cursor: not-allowed; }
.btn-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* ---------- product tile ---------- */

/* Tinted per category, with the packshot laid over it when there is one. */
.tile {
  position: relative; flex: none; overflow: hidden;
  width: 52px; height: 52px; border-radius: var(--r-thumb);
  display: flex; align-items: center; justify-content: center;
  background: var(--sunken); color: var(--ink);
}
.tile .ico { width: 28px; height: 28px; }
.tile.big { width: var(--thumb); height: var(--thumb); }
.tile.big .ico { width: 34px; height: 34px; }
.tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: var(--surface); }
.cat-produce { background: var(--tint-produce); }
.cat-bakery  { background: var(--tint-bakery); }
.cat-dairy   { background: var(--tint-dairy); }
.cat-meat    { background: var(--tint-meat); }
.cat-pantry  { background: var(--tint-pantry); }
.cat-snacks  { background: var(--tint-snacks); }
.cat-drinks  { background: var(--tint-drinks); }
.cat-frozen  { background: var(--tint-frozen); }
.cat-house   { background: var(--tint-house); }
.cat-care    { background: var(--tint-care); }

/* ---------- budget ---------- */

.budget-card { display: flex; flex-direction: column; gap: 14px; }
.saved-strip {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px;
  border-radius: var(--r-button); background: var(--signal-soft); color: var(--on-signal-soft); font-weight: 700;
}
.saved-strip .money { font-size: var(--fs-body-lg); }
.left-box { padding: 12px 14px; border-radius: var(--r-button); background: var(--sunken-low); }
/* A heading with its icon on a mint tile, as on the Stitch budget card. */
.title-ico { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ico-tile {
  flex: none; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-chip); background: var(--mint); color: var(--on-mint);
}
.ico-tile .ico { width: 20px; height: 20px; }
.label-caps {
  font-size: var(--fs-meta); font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-body);
}
.big-money {
  font-family: var(--font-num); font-size: calc(var(--fs-price-lg) + 8px); font-weight: 800;
  line-height: 1.1; letter-spacing: -.02em;
}
.bar-fill.is-plan { background: var(--plan); }
.bar-fill.is-over { background: var(--alert); }
.legend { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: var(--fs-meta); font-weight: 600; color: var(--ink-body); }
.key { display: inline-block; width: 14px; height: 14px; margin-right: 6px; border-radius: 4px; vertical-align: -2px; }
.key-spent { background: var(--ink); }
.key-plan { background: var(--plan); }
.verdict { margin: 0; font-weight: 700; }
.verdict.over {
  padding: 10px 12px; border: 2px solid var(--alert); border-radius: var(--r-button);
  background: var(--alert-soft); color: var(--alert);
}

/* ---------- list rows ---------- */

.rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.item-row { background: var(--surface); border-radius: var(--r-card); box-shadow: var(--shadow-card); overflow: hidden; }
.row-main {
  width: 100%; display: flex; gap: 12px; align-items: flex-start; padding: 14px 14px 10px;
  border: 0; background: none; color: var(--ink); text-align: left;
  font-family: var(--font-sans); font-size: var(--fs-body); cursor: pointer;
}
.row-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.row-name { font-size: var(--fs-body-lg); font-weight: 800; line-height: 1.3; }
.row-price { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 4px; font-weight: 600; }
.row-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: 0 10px 10px; padding: 6px; border-radius: var(--r-button); background: var(--sunken-low);
}
.row-foot .money { padding-right: 8px; font-size: var(--fs-body-lg); }
.row-missing { color: var(--alert); font-size: var(--fs-meta); font-weight: 700; }

.stepper { display: flex; align-items: center; gap: 8px; }
.step-btn {
  width: var(--tap); height: var(--tap); display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--r-button); background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-soft);
  font-family: var(--font-sans); font-size: 24px; font-weight: 700; line-height: 1; cursor: pointer;
}
.step-btn:hover { background: var(--sunken-low); }
.step-qty { min-width: 3ch; text-align: center; font-family: var(--font-num); font-size: var(--fs-body-lg); font-weight: 800; }

/* ---------- offers ---------- */

.search-box { position: relative; display: block; }
.search-box .ico { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--ink-body); }
.search-box input {
  width: 100%; min-height: calc(var(--tap) + 4px); padding: 10px 52px 10px 48px;
  border: 0; border-radius: var(--r-button); background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-card);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 600;
}
/* The app draws its own ×, so the WebView's is hidden: one way to empty the box. */
.search-box input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.search-clear {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: var(--tap-min); height: var(--tap-min); padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--r-button); background: none; color: var(--ink-body); cursor: pointer;
  font-family: var(--font-sans); font-size: 26px; font-weight: 700; line-height: 1;
}
.search-clear:hover { background: var(--sunken); color: var(--ink); }
.offer { display: flex; flex-direction: column; gap: 12px; }
/* The photo first: the badges get their own row across the top, so the
 * packshot can take a wide left column (--thumb) with the name, size, price
 * and dates beside it. Same markup as before; the text block is opened up
 * with display: contents so its pieces sit in the grid. */
.offer-top {
  display: grid; grid-template-columns: var(--thumb) minmax(0, 1fr);
  column-gap: 14px; row-gap: 4px; align-items: start;
}
.offer-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.offer-top > .offer-text { display: contents; }
.offer-top .offer-badges { grid-column: 1 / -1; grid-row: 1; margin-bottom: 6px; }
.offer-top > .tile { grid-column: 1; grid-row: 2 / span 6; }
.offer-top .offer-text > :not(.offer-badges) { grid-column: 2; min-width: 0; }
.offer-badges { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.offer-name {
  padding: 0; border: 0; background: none; color: var(--ink); text-align: left; cursor: pointer;
  font-family: var(--font-sans); font-size: var(--fs-body-lg); font-weight: 800; line-height: 1.3;
  text-decoration: underline; text-decoration-color: var(--border); text-decoration-thickness: 2px; text-underline-offset: 4px;
}
.offer-name.small-name { font-size: var(--fs-body); }
.price-line { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; }
.price-big { font-family: var(--font-num); font-size: var(--fs-price-lg); font-weight: 800; line-height: 1.15; letter-spacing: -.02em; }
.until { display: flex; gap: 6px; align-items: center; }
.until .ico { width: 18px; height: 18px; }
.note-line { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0; color: var(--ink-body); font-weight: 700; }
.check { display: flex; gap: 8px; align-items: flex-start; margin: 0; padding: 10px 12px; border-radius: var(--r-button); font-weight: 700; }
.check.good { background: var(--success-soft); color: var(--success); }
.check.plain { background: var(--sunken); color: var(--ink-body); }
.check.warn { background: var(--alert-soft); color: var(--alert); }
.onlist {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 6px 6px 14px;
  border-radius: var(--r-button); background: var(--success-soft); color: var(--success); font-weight: 800;
}
.onlist > span { display: flex; align-items: center; gap: 6px; }
.plain-row { display: flex; gap: 12px; align-items: center; }
/* List rows and search rows show the product bigger too. */
.row-main > .tile, .plain-row > .tile:not(.big) { width: var(--row-photo); height: var(--row-photo); }
.row-main > .tile .ico, .plain-row > .tile:not(.big) .ico { width: 34px; height: 34px; }
.offer-top > .tile .ico { width: 48px; height: 48px; }

/* ---------- go shopping ---------- */

.options { display: flex; flex-direction: column; gap: 10px; }
.opt {
  width: 100%; display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center; padding: 14px;
  border: 2px solid var(--surface); border-radius: var(--r-card); background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-card);
  text-align: left; font-family: var(--font-sans); font-size: var(--fs-body); cursor: pointer;
}
.opt.is-on { border: 3px solid var(--ink); padding: 13px; }
.opt-radio {
  width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
  border: 2.5px solid var(--ink); border-radius: var(--r-pill);
}
.opt.is-on .opt-radio::after { content: ''; width: 14px; height: 14px; border-radius: var(--r-pill); background: var(--ink); }
.opt-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.opt-title { font-size: var(--fs-body-lg); font-weight: 800; }
.opt-price { font-size: var(--fs-price-md); }
.save-text { color: var(--signal); font-weight: 800; }
.advice {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-start; margin: 0; padding: 12px 14px;
  border-radius: var(--r-card); background: var(--success-soft); font-weight: 600;
}
.advice > span { flex: 1 1 200px; }
.advice .ico { color: var(--success); }
.route-card { display: flex; flex-direction: column; gap: 12px; }
.route-home rect { fill: var(--surface); stroke: var(--ink); stroke-width: 2.5; }
.route-steps { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; font-weight: 700; }
.route-steps .ico { width: 18px; height: 18px; }
.stop { display: flex; flex-direction: column; gap: 12px; }
.stop .stop-head { margin: 0; align-items: center; }
.cardcall {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px; border-radius: var(--r-button); background: var(--sunken-high); font-weight: 700;
}
.checklist { display: flex; flex-direction: column; gap: 8px; }
.ck {
  display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center; min-height: 60px;
  padding: 10px 12px; border-radius: var(--r-button);
  background: var(--sunken-low); cursor: pointer;
}
.ck.is-done { background: var(--sunken-high); }
.ck-text { display: flex; flex-direction: column; min-width: 0; }
.ck .ck-name { font-size: var(--fs-body); font-weight: 800; line-height: 1.3; }
.ck.is-done .ck-name { text-decoration: line-through; text-decoration-thickness: 2px; color: var(--ink-body); }
.box {
  width: 30px; height: 30px; flex: none; display: flex; align-items: center; justify-content: center;
  border: 2.5px solid var(--ink); border-radius: var(--r-chip); background: var(--surface); color: var(--surface);
}
.box .ico { width: 20px; height: 20px; stroke-width: 3; visibility: hidden; }
.ck.is-done .box { background: var(--ink); }
.ck.is-done .box .ico { visibility: visible; }
.cat-note { display: flex; gap: 6px; align-items: center; color: var(--ink-body); font-size: var(--fs-meta); font-weight: 700; }
.stop-foot .money { font-size: var(--fs-body-lg); }
.receipt { display: flex; flex-direction: column; gap: 10px; }
.r-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font-size: var(--fs-body); font-weight: 600; }
/* Your discount sits on mint, as on the Stitch kassabon. */
.r-save { padding: 8px 10px; border-radius: var(--r-button); background: var(--mint-soft); color: var(--forest); font-weight: 800; }
.r-total { padding-top: 12px; border-top: 2px solid var(--sunken-high); font-size: var(--fs-h-md); font-weight: 800; }

/* ---------- sheets ---------- */

.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 16px; }
.sheet-head h2 { font-size: var(--fs-h-lg); font-weight: 800; letter-spacing: -.01em; }
.closebtn {
  min-height: var(--tap-min); padding: 0 14px; display: inline-flex; align-items: center; gap: 6px;
  border: 0; border-radius: var(--r-button); background: var(--sunken); color: var(--ink);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 700; cursor: pointer;
}
.set-group { display: flex; flex-direction: column; gap: 10px; margin-bottom: 22px; }
.toggle-row {
  position: relative; display: flex; align-items: center; gap: 12px; min-height: 60px; padding: 8px 14px;
  border-radius: var(--r-button); background: var(--surface); box-shadow: var(--shadow-soft); cursor: pointer;
}
/* The real checkbox stays in the page for screen readers and keyboards; the box draws it. */
.toggle-row input { position: absolute; width: 1px; height: 1px; margin: 0; clip-path: inset(50%); }
.toggle-row input:checked + .box { background: var(--ink); }
.toggle-row input:checked + .box .ico { visibility: visible; }
.toggle-row input:focus-visible + .box { outline: 3px solid var(--focus); outline-offset: 2px; }
.toggle-row .grow { display: flex; flex-direction: column; }
.toggle-row strong { font-weight: 800; }
.card-number-row { display: flex; gap: 8px; align-items: center; }
.budget-set {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 8px 8px 16px;
  border-radius: var(--r-card); background: var(--surface); box-shadow: var(--shadow-soft);
}
.budget-value { font-family: var(--font-num); font-size: var(--fs-price-md); font-weight: 800; }
.adv { margin-bottom: 8px; border-radius: var(--r-button); background: var(--surface); box-shadow: var(--shadow-soft); }
.adv summary {
  min-height: var(--tap); padding: 0 14px; display: flex; align-items: center;
  font-weight: 800; list-style: none; cursor: pointer;
}
.adv summary::-webkit-details-marker { display: none; }
.adv summary::after { content: '+'; margin-left: auto; font-size: 24px; font-weight: 600; }
.adv[open] summary::after { content: '−'; }
.adv-body { padding: 0 14px 14px; display: flex; flex-direction: column; gap: 12px; }
.adv-body h3 { margin-top: 6px; }
.share-text {
  width: 100%; min-height: 220px; margin: 12px 0; padding: 12px; resize: vertical;
  border: 2px solid var(--border); border-radius: var(--r-button); background: var(--surface); color: var(--ink);
  font-family: var(--font-sans); font-size: var(--fs-body); line-height: 1.5;
}
#sharePanel .btn + .btn { margin-top: 10px; }
.compare { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.compare li {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; align-items: center; padding: 10px 12px;
  border: 2px solid var(--surface); border-radius: var(--r-button); background: var(--surface); box-shadow: var(--shadow-soft);
}
.compare li.best { border-color: var(--ink); }
.compare .per { grid-column: 1 / -1; }
.compare .money { font-size: var(--fs-body-lg); }
/* Where a compared price comes from: "folder" or "schap". */
.src-chip {
  display: inline-flex; padding: 0 6px; border-radius: var(--r-badge);
  background: var(--sunken-high); color: var(--ink); font-size: var(--fs-meta); font-weight: 800;
}

/* ---------- Product toevoegen ---------- */

/* Full height from the start, so the sheet doesn't jump while results come and go. */
.add-sheet .sheet-inner { height: 92vh; height: 92dvh; }
.add-view { margin-top: 16px; }

/* ---------- pull to refresh ---------- */

.pull-indicator {
  height: 44px; overflow: hidden; display: flex; align-items: flex-end; justify-content: center;
  padding-bottom: 8px; color: var(--ink-body); font-size: var(--fs-meta); font-weight: 700;
}
.pull-indicator.is-ready { color: var(--ink); }

/* ---------- Over deze app ---------- */

#aboutBox p { margin: 0; }
.about-line { font-weight: 600; }
.whats-new { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 4px; }

/* ---------- leaflets: departments ---------- */

/* The Stitch aisle rows: icon tile, name, how many offers, a way in. */
.dept-group { margin: 8px 0 0; }
.dept-row {
  width: 100%; min-height: 76px; display: flex; align-items: center; gap: 14px; padding: 12px 14px;
  border: 0; border-radius: var(--r-card); background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-soft); text-align: left; cursor: pointer; font-family: var(--font-sans);
}
.dept-row .tile { width: 52px; height: 52px; }
.dept-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.dept-name { font-size: var(--fs-body-lg); font-weight: 800; line-height: 1.25; }
.dept-text .meta:not(:empty) {
  padding: 1px 10px; border-radius: var(--r-pill);
  background: var(--sunken-high); color: var(--ink); font-weight: 700;
}
.dept-go { flex: none; display: flex; color: var(--ink-body); }
.back-btn { align-self: flex-start; }
.back-btn .ico { width: 20px; height: 20px; }
.feed-state { margin: 0; padding: 18px; text-align: center; color: var(--ink-body); font-weight: 700; }

/* ---------- product sheet ---------- */

/* A card you can tap anywhere to open its product sheet. */
.is-tappable { cursor: pointer; }
/* The product sheet opens over the add sheet it can be reached from. */
#detailPanel { z-index: 55; }
.detail-hero {
  position: relative; overflow: hidden; height: 240px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-card); background: var(--sunken); color: var(--ink);
}
.detail-hero .ico { width: 72px; height: 72px; stroke-width: 1.5; }
/* The packshot covers the icon tile; `contain`, because cropping a cut-out
 * is worse than letterboxing it. */
.detail-hero img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; padding: 16px; background: var(--surface);
}
.photo-cap { margin: 0; text-align: right; }
.detail-facts { display: flex; flex-direction: column; gap: 6px; }
.detail-facts p { margin: 0; }
.detail-name { font-size: var(--fs-h-md); font-weight: 800; line-height: 1.25; letter-spacing: -.01em; }
.price-hero {
  font-family: var(--font-num); font-size: calc(var(--fs-price-lg) + 8px); font-weight: 800;
  line-height: 1.1; letter-spacing: -.02em; color: var(--ink);
}
.price-for { font-size: var(--fs-body); font-weight: 700; color: var(--ink-body); }
.explain {
  padding: 10px 12px; border-radius: var(--r-button);
  background: var(--sunken-low); color: var(--ink); font-weight: 600;
}
/* "2 voor € 1,79", "ACTIE", "25% KORTING": what the shelf tag says. */
.promo-chip {
  display: inline-flex; padding: 2px 8px; border-radius: var(--r-badge);
  background: var(--forest); color: var(--surface);
  font-size: var(--fs-meta); font-weight: 800; letter-spacing: .02em; white-space: nowrap;
}

/* ---------- toast, credit ---------- */

.toast { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.toast-undo {
  min-height: 44px; padding: 0 6px; border: 0; background: none; color: var(--surface); cursor: pointer;
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 800;
  text-decoration: underline; text-underline-offset: 3px;
}
/* "Aanbiedingen via PrijsProfeet": the last line of a screen or sheet with their data, inside its padding. */
.pp-credit { margin: 12px 0 0; text-align: center; color: var(--ink-body); font-size: var(--fs-meta); }
.pp-credit a { color: var(--ink); font-weight: 700; }


/* ---------- the route on a real map ----------
 *
 * js/tilemap.js: OpenStreetMap tiles, drag to pan, pinch or scroll to zoom.
 * The tiles keep their own colours, so it reads like any street map; the
 * route is drawn in ink on a white casing so it stays the strongest line on
 * screen. Each stop is the shop's own logo with its number, home is a house. */
.route-map-stage { margin: 4px 0; }
.tilemap {
  position: relative; overflow: hidden; height: 260px;
  border: 1.5px solid var(--border); border-radius: var(--r-button); background: var(--sunken);
  /* A drag pans the map instead of scrolling the tab underneath it. */
  touch-action: none; cursor: grab; user-select: none; -webkit-user-select: none;
}
.tilemap:active { cursor: grabbing; }
.tilemap:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.tilemap.is-expanded { position: absolute; inset: 0; height: auto; border-radius: var(--r-card); }
.tilemap-layer { position: absolute; inset: 0; }
/* max-width: none, or a global img rule squashes every tile wider than the box. */
.tilemap-tile { position: absolute; top: 0; left: 0; max-width: none; pointer-events: none; }
.tilemap.is-blind .tilemap-layer { display: none; }
.tilemap-overlay { position: absolute; inset: 0; pointer-events: none; }
.route-casing {
  fill: none; stroke: var(--surface); stroke-width: 8;
  stroke-linejoin: round; stroke-linecap: round;
}
.tilemap-overlay .route-leg {
  fill: none; stroke: var(--ink); stroke-width: 4; stroke-linejoin: round; stroke-linecap: round;
}
.tilemap-overlay .route-leg.is-return { stroke: var(--ink-body); stroke-dasharray: 7 6; }

.tilemap-pins { position: absolute; inset: 0; pointer-events: none; }
.tilemap-pin { position: absolute; transform: translate(-50%, -50%); }
.pin-shop {
  position: relative; width: 42px; height: 42px;
  display: flex; align-items: center; justify-content: center;
  border: 2.5px solid var(--ink); border-radius: var(--r-button); background: var(--surface);
}
.pin-shop .shop-logo { width: 28px; height: 28px; margin: 0; }
.pin-num {
  position: absolute; top: -10px; right: -10px; min-width: 22px; height: 22px; padding: 0 5px;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--surface); border-radius: var(--r-pill); background: var(--ink); color: var(--surface);
  font-family: var(--font-num); font-size: 13px; font-weight: 800;
}
.pin-home {
  width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  border: 2.5px solid var(--surface); border-radius: var(--r-pill); background: var(--ink); color: var(--surface);
}
.pin-home .ico { width: 22px; height: 22px; }

.tilemap-controls { position: absolute; top: 8px; right: 8px; display: flex; flex-direction: column; gap: 6px; }
.tilemap-btn {
  width: var(--tap-min); height: var(--tap-min); padding: 0; display: grid; place-items: center;
  border: 1.5px solid var(--border); border-radius: var(--r-button); background: var(--surface); color: var(--ink);
  font-family: var(--font-sans); font-size: 22px; font-weight: 700; line-height: 1; cursor: pointer;
}
.tilemap-btn:hover { background: var(--sunken); }
.tilemap-note {
  position: absolute; left: 8px; right: 64px; top: 8px; margin: 0; padding: 6px 10px;
  border-radius: var(--r-chip); background: var(--ink); color: var(--surface);
  font-size: var(--fs-meta); font-weight: 600;
}
/* Attribution is a condition of using the tiles, so it lives on the map. */
.tilemap-credit {
  position: absolute; left: 0; right: 0; bottom: 0; margin: 0; padding: 2px 8px;
  background: var(--surface); color: var(--ink-body); font-size: 13px; text-align: right;
}
.route-steps > span { display: inline-flex; align-items: center; gap: 4px; }
.map-sheet .sheet-inner { height: 88vh; height: 88dvh; display: flex; flex-direction: column; overflow: hidden; }
.map-stage { position: relative; flex: 1 1 auto; min-height: 240px; margin: 4px 0 10px; }


/* ---------- closing a sheet ----------
 * A sheet closes with Sluiten, the phone's back button, or a swipe down from
 * the top of its content. The grab bar says the last one can be done. */
.sheet-grab { width: 48px; height: 5px; margin: -8px auto 12px; border-radius: var(--r-pill); background: var(--border); }
.sheet-inner { overscroll-behavior: contain; }

@media (min-width: 560px) {
  .sheet { align-items: center; }
  .sheet-inner { border-radius: var(--r-screen); max-height: 88vh; }
}
