/* MealieShopper huisstijl: basilicumgroen op rustige neutrale vlakken.
   Manrope voor koppen en het woordmerk, Inter voor de interface; beide lokaal. */

@font-face {
  font-family: "Manrope";
  src: url("fonts/Manrope-Variable.woff2") format("woff2"),
    url("fonts/Manrope-Variable.ttf") format("truetype");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  src: url("fonts/Inter-Variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: light;

  /* Merk en actie */
  --primary: #176b45;
  --primary-strong: #105235;
  --selection: #eaf5ee;
  --selection-border: #b8d8c6; /* rand om een selectievlak (actieve tab, tag): volgt de accentkleur */
  --lemon: #f2cf45; /* decoratief: niet als tekst op wit */
  --info: #1565c0;

  /* Vlakken, tekst en rand */
  --bg: #f5f7f6;
  --surface: #ffffff;
  --surface-muted: #eef3f0;
  --text: #18251e;
  --muted: #59665e;
  --border: #d6dfd9;

  /* Meldingen: fouten blijven rood en krijgen altijd een tekstuele uitleg */
  --success-text: #105235;
  --success-bg: #eaf5ee;
  --success-border: #b8d8c6;
  --danger: #b42318;
  --danger-bg: #fff0ee;
  --danger-border: #f3b5af;
  --warning-text: #7a4f00;
  --warning-bg: #fff8e6;
  --warning-border: #e0a100;

  /* Menubalk onderaan op een telefoon. Het glas is --tabbar-rgb met de dekking van de schuif (--nav-alpha, 1 tot 0,15, zie
     static/theme.js); de inkt is zo gekozen dat de labels tot dekking 0,75 (schuif 29) boven elke foto 4,5 : 1 halen. */
  --tabbar-rgb: 255, 255, 255;
  --tabbar-tint: rgba(23, 107, 69, 0.14);
  --tabbar-ink: #3f4c45;
  --tabbar-ink-active: #0f4c31;
  --tabbar-solid: rgba(255, 255, 255, 0.97);
  --tabbar-border: rgba(255, 255, 255, 0.7);

  /* Tekst op een primair vlak, balk bovenaan, scherm achter de inlogkaart en kleine details */
  --on-primary: #fff;
  --topbar-bg: rgba(255, 255, 255, 0.96);
  --gate-bg: rgba(245, 247, 246, 0.96);
  --code-on-message: rgba(255, 255, 255, 0.7);
  --shadow-ink: 24, 37, 30; /* rgb-waarden voor schaduwen */

  /* Diepte en verfijning: drie schaduwniveaus, een focushalo, een rand voor het hoverniveau en het glas van de balk bovenaan */
  --shadow-xs: 0 1px 2px rgba(var(--shadow-ink), 0.06);
  --shadow-sm: 0 1px 2px rgba(var(--shadow-ink), 0.05), 0 2px 8px rgba(var(--shadow-ink), 0.04);
  --shadow-md: 0 2px 4px rgba(var(--shadow-ink), 0.04), 0 10px 28px rgba(var(--shadow-ink), 0.09);
  --shadow-lg: 0 4px 8px rgba(var(--shadow-ink), 0.05), 0 28px 64px rgba(var(--shadow-ink), 0.16);
  --btn-shadow: 0 1px 2px rgba(16, 82, 53, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.16);
  --btn-shadow-hover: 0 2px 8px rgba(16, 82, 53, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.16);
  --ring: rgba(23, 107, 69, 0.2);
  --border-strong: #c0ccc5;
  --control-border: #89958e; /* rand van een invoerveld: 3,1 : 1 op wit (App-Guidance vraagt 3 : 1 voor randen van bediening) */
  --placeholder: #66756c; /* 4,8 : 1 op wit */
  --topbar-glass: rgba(255, 255, 255, 0.9);
  --page-glow: rgba(23, 107, 69, 0.07);
  --ease: cubic-bezier(0.2, 0, 0, 1);

  --radius-sm: 4px;
  --radius-control: 8px;
  --radius-card: 12px;
  --radius-lg: 16px;
  --radius-pill: 999px;
  --control-height: 44px;

  /* Typeschaal: acht stappen. Gebruik alleen deze; een letterlijke grootte mag alleen voor wat geen lopende tekst is (de menubalk,
     een icoon, de initialen in een grote avatar) en de clamp() van de kookmodus. tests/test_brand.py houdt dat bij. */
  --text-xs: 12px; /* labels, badges, kleine meta */
  --text-sm: 13px; /* hulptekst, meta, chips */
  --text-md: 14px; /* ondersteunende tekst, tabellen */
  --text-ui: 15px; /* knoppen, tabs, tekst in kaarten */
  --text-base: 16px; /* lopende tekst en invoer (iOS zoomt niet in) */
  --text-lg: 18px; /* kop van een blok of venster */
  --text-xl: 20px; /* vakkop (h2), kerncijfer */
  --text-2xl: 24px; /* schermtitel */

  --font-body: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-heading: "Manrope", "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* Donker thema: wordt gezet met data-theme="dark" op <html> (zie static/theme.js en de kop van de pagina). */
:root[data-theme="dark"] {
  color-scheme: dark;

  --primary: #4cc38a;
  --primary-strong: #7bd9ab;
  --selection: #1d3a2c;
  --selection-border: #2a5c43;
  --info: #64b5f6;

  --bg: #0f1613;
  --surface: #17211c;
  --surface-muted: #1e2b24;
  --text: #e6eee9;
  --muted: #9fb0a6;
  --border: #2d3d34;

  --success-text: #8fe0b4;
  --success-bg: #163326;
  --success-border: #2a5c43;
  --danger: #ff8a80;
  --danger-bg: #3a1b18;
  --danger-border: #7a2f29;
  --warning-text: #f2c35a;
  --warning-bg: #33280d;
  --warning-border: #a67c00;

  --tabbar-rgb: 23, 33, 28;
  --tabbar-tint: rgba(76, 195, 138, 0.18);
  --tabbar-ink: #c5d1ca;
  --tabbar-ink-active: #c6efdb;
  --tabbar-solid: rgba(23, 33, 28, 0.97);
  --tabbar-border: rgba(255, 255, 255, 0.12);

  --on-primary: #0b1f15;
  --topbar-bg: rgba(15, 22, 19, 0.96);
  --gate-bg: rgba(15, 22, 19, 0.96);
  --code-on-message: rgba(0, 0, 0, 0.3);
  --shadow-ink: 0, 0, 0;

  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3), 0 2px 10px rgba(0, 0, 0, 0.22), inset 0 1px 0 rgba(255, 255, 255, 0.04);
  --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.3), 0 12px 32px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05);
  --shadow-lg: 0 4px 8px rgba(0, 0, 0, 0.35), 0 32px 72px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.06);
  --btn-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.28);
  --btn-shadow-hover: 0 2px 10px rgba(76, 195, 138, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.3);
  --ring: rgba(76, 195, 138, 0.28);
  --border-strong: #3d5247;
  --control-border: #5b7065; /* 3,1 : 1 op het donkere vlak */
  --placeholder: #8a9c91;
  --topbar-glass: rgba(15, 22, 19, 0.9);
  --page-glow: rgba(76, 195, 138, 0.08);
}

/* Donkergrijs in plaats van groen (Instellingen, Weergave): theme.js zet data-dark-bg="grey" op <html>. Alleen de neutrale
   vlakken, tekst en randen wisselen, met hetzelfde contrast als het groene donkere thema; meldingen houden hun eigen kleur. */
:root[data-theme="dark"][data-dark-bg="grey"] {
  --bg: #121314;
  --surface: #1b1c1e;
  --surface-muted: #232527;
  --text: #e8e9ea;
  --muted: #a6a8ab;
  --border: #343638;
  --border-strong: #47494c;
  --control-border: #686a6d; /* 3,1 : 1 op donkergrijs */
  --placeholder: #8f9194;

  --tabbar-rgb: 27, 28, 30;
  --tabbar-ink: #cacbcd;
  --tabbar-solid: rgba(27, 28, 30, 0.97);
  --topbar-bg: rgba(18, 19, 20, 0.96);
  --gate-bg: rgba(18, 19, 20, 0.96);
  --topbar-glass: rgba(18, 19, 20, 0.9);
}

/* Een eigen accentkleur (Instellingen, Weergave). theme.js zet de tinten op <html> (--accent-light, --accent-dark en hun
   -strong, -on en -ink), al gecontroleerd op contrast, samen met data-accent. Zonder eigen keuze gelden de waarden hierboven. Wat
   van de merkkleur afhangt volgt uit --primary; statussen (gelukt, fout, waarschuwing) volgen de accentkleur nooit. */
:root[data-accent] {
  --primary: var(--accent-light, #176b45);
  --primary-strong: var(--accent-light-strong, #105235);
  --on-primary: var(--accent-light-on, #fff);
  --selection: color-mix(in srgb, var(--primary) 9%, #fff);
  --selection-border: color-mix(in srgb, var(--primary) 30%, #fff);
  --tabbar-tint: color-mix(in srgb, var(--primary) 14%, transparent);
  --tabbar-ink-active: var(--accent-light-ink, #0f4c31); /* leesbaar op het glas van de menubalk, ook boven een foto */
  --btn-shadow: 0 1px 2px color-mix(in srgb, var(--primary-strong) 35%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.16);
  --btn-shadow-hover: 0 2px 8px color-mix(in srgb, var(--primary-strong) 32%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.16);
  --ring: color-mix(in srgb, var(--primary) 20%, transparent);
  --page-glow: color-mix(in srgb, var(--primary) 7%, transparent);
}

:root[data-accent][data-theme="dark"] {
  --primary: var(--accent-dark, #4cc38a);
  --primary-strong: var(--accent-dark-strong, #7bd9ab);
  --on-primary: var(--accent-dark-on, #0b1f15);
  --selection: color-mix(in srgb, var(--primary) 20%, var(--bg));
  --selection-border: color-mix(in srgb, var(--primary) 35%, var(--surface));
  --tabbar-tint: color-mix(in srgb, var(--primary) 18%, transparent);
  --tabbar-ink-active: var(--accent-dark-ink, #c6efdb);
  --btn-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.28);
  --btn-shadow-hover: 0 2px 10px color-mix(in srgb, var(--primary) 28%, transparent), inset 0 1px 0 rgba(255, 255, 255, 0.3);
  --ring: color-mix(in srgb, var(--primary) 28%, transparent);
  --page-glow: color-mix(in srgb, var(--primary) 8%, transparent);
}

/* De ruimte voor de scrollbalk blijft altijd gereserveerd: de pagina verspringt niet als een scherm hoger wordt dan het venster. */
html {
  scrollbar-gutter: stable;
}

@supports not (scrollbar-gutter: stable) {
  html {
    overflow-y: scroll;
  }
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

body {
  margin: 0;
  background: var(--bg) radial-gradient(1100px 380px at 50% -140px, var(--page-glow), transparent 72%) no-repeat;
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

::selection {
  background: var(--selection);
  color: var(--primary-strong);
}

a {
  color: var(--primary);
}

/* Zichtbare groene focusring voor toetsenbord en schermlezers */
:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
}

.input:focus-visible,
.textarea:focus-visible,
select:focus-visible {
  border-color: var(--primary);
  outline-offset: 0;
  box-shadow: 0 0 0 5px var(--ring);
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  border-bottom: 1px solid var(--border);
  background: var(--topbar-bg);
  box-shadow: 0 1px 0 rgba(var(--shadow-ink), 0.02), 0 6px 20px rgba(var(--shadow-ink), 0.04);
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .topbar {
    background: var(--topbar-glass);
    -webkit-backdrop-filter: saturate(180%) blur(18px);
    backdrop-filter: saturate(180%) blur(18px);
  }
}

.brand-link {
  display: flex;
  align-items: center;
  gap: 12px;
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius-control);
}

.brand-link:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 3px;
}

.topbar__inner {
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 1120px;
  min-height: 64px;
  margin: 0 auto;
  padding: 8px 16px;
}

.topbar .brand-mark {
  width: 40px;
  height: 40px;
}

.auth-gate {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 20px;
  background: radial-gradient(900px 520px at 50% -10%, var(--page-glow), transparent 70%), var(--gate-bg);
  overflow-y: auto;
}

.auth-card {
  width: min(440px, 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  padding: 28px;
  box-shadow: var(--shadow-lg);
  animation: rise-in 0.4s var(--ease) both;
}

.auth-card h2 {
  font-size: var(--text-2xl);
  letter-spacing: -0.02em;
}

.auth-card .brand-mark {
  margin: 0 auto 14px;
}

/* De slogan staat alleen hier, onder het beeldmerk (sinds 4.7.0 niet meer in de kop van elk scherm). */
.auth-card > .auth-card__tagline {
  margin: -6px 0 14px;
  color: var(--muted);
  font-size: var(--text-md);
}

.auth-card > h2,
.auth-card > p {
  text-align: center;
}

.auth-card > p {
  margin-top: 6px;
}

.box > h2 + .profile-avatar {
  margin-top: 14px;
}

.auth-form {
  display: grid;
  gap: 10px;
  margin-top: 16px;
}

.brand-mark {
  display: block;
  flex: none;
  width: 48px;
  height: 48px;
  filter: drop-shadow(0 2px 4px rgba(var(--shadow-ink), 0.14));
}

.brand-mark--large {
  width: 64px;
  height: 64px;
}

/* Lijnicoon: ronde uiteinden, kleur volgt de tekst */
.icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

h1,
h2,
h3,
p {
  margin: 0;
}

h1,
h2,
h3 {
  font-family: var(--font-heading);
  letter-spacing: -0.015em;
  text-wrap: balance;
}

h2 {
  font-size: var(--text-xl);
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -0.02em;
}

.wordmark {
  font-size: var(--text-xl);
  letter-spacing: -0.025em;
  font-weight: 800;
  line-height: 1.1;
}

.wordmark span {
  color: var(--primary);
}

.wordmark-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.beta-badge {
  padding: 1px 8px;
  border: 1px solid var(--warning-border);
  border-radius: var(--radius-pill);
  background: var(--warning-bg);
  color: var(--warning-text);
  font-size: var(--text-xs);
  font-weight: 800;
  letter-spacing: 0.04em;
  line-height: 1.5;
  text-transform: uppercase;
}

.shell {
  max-width: 1120px;
  margin: 0 auto;
  padding: 28px 16px 48px;
}

.tabs,
.subtabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  width: fit-content;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}

/* Tweede niveau als segmentbediening: een ingedeukt spoor met een oplichtend actief segment. */
.subtabs {
  background: var(--surface-muted);
  box-shadow: inset 0 1px 2px rgba(var(--shadow-ink), 0.05);
}

.tabs {
  margin-bottom: 24px;
}

.subtabs {
  margin-bottom: 20px;
}

/* Op een telefoon is een subtabbalk één regel die horizontaal scrolt, in plaats van twee of drie regels (Winkels met de
   winkelkeuze en vier tabbladen, Instellingen). Het gekozen tabblad scrolt in beeld (app.js). Staat de winkelkeuze open, dan
   scrolt de balk even niet: anders knipt de balk de lijst eronder af. */
@media (max-width: 640px) {
  .subtabs {
    flex-wrap: nowrap;
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }

  .subtabs::-webkit-scrollbar {
    display: none;
  }

  .subtabs > * {
    flex: none;
  }

  .subtabs .subtab {
    white-space: nowrap;
  }

  .subtabs:has(.subtab-menu__toggle[aria-expanded="true"]) {
    overflow: visible;
  }

  /* Er staat meer (sinds 4.13.0): de rand vervaagt aan de kant waar nog tabbladen buiten beeld staan. De klassen zet app.js
     (subtabsEdges) bij het scrollen. Niet met de winkelkeuze open: een masker zou de lijst eronder afknippen. */
  .subtabs.has-more-end:not(:has(.subtab-menu__toggle[aria-expanded="true"])) {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent);
  }

  .subtabs.has-more-start:not(:has(.subtab-menu__toggle[aria-expanded="true"])) {
    -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 36px), transparent);
    mask-image: linear-gradient(to left, #000 calc(100% - 36px), transparent);
  }

  .subtabs.has-more-start.has-more-end:not(:has(.subtab-menu__toggle[aria-expanded="true"])) {
    -webkit-mask-image: linear-gradient(to right, transparent, #000 36px, #000 calc(100% - 36px), transparent);
    mask-image: linear-gradient(to right, transparent, #000 36px, #000 calc(100% - 36px), transparent);
  }
}

/* De titel van een scherm (sinds 4.7.0). Bij Weekmenu en Recepten zoeken staat hij er alleen als het zijmenu de
   subtabbalk vervangt (page-title--tree, zie de regels vanaf 860 px): anders zegt het segment erboven al waar je bent. */
.page-title {
  margin: 0 0 16px;
  font-size: var(--text-2xl);
}

.page-title--tree {
  display: none;
}

/* Weekmenu: de titel en de weeknavigatie in één rij. */
.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 24px;
}

.page-head > .page-title {
  margin: 0;
}

.tab,
.subtab,
.button,
.icon-button {
  border: 0;
  border-radius: var(--radius-control);
  font: inherit;
  font-size: var(--text-ui);
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s var(--ease), color 0.15s var(--ease), border-color 0.15s var(--ease),
    box-shadow 0.2s var(--ease), transform 0.12s var(--ease);
  -webkit-tap-highlight-color: transparent;
}

.tab,
.subtab {
  position: relative;
  min-height: var(--control-height);
  padding: 0 16px;
  background: transparent;
  color: var(--muted);
}

@media (hover: hover) {
  .tab:hover:not(.is-active),
  .subtab:hover:not(.is-active) {
    background: var(--selection);
    color: var(--primary-strong);
  }
}

.tab.is-active {
  background: var(--selection);
  color: var(--primary-strong);
  box-shadow: inset 0 0 0 1px var(--selection-border);
}

.subtab.is-active {
  background: var(--surface);
  color: var(--primary-strong);
  box-shadow: 0 1px 2px rgba(var(--shadow-ink), 0.12), 0 0 0 1px var(--border);
}

/* Eén segmentbediening voor een keuze binnen een scherm (fase 4): de weergave van Aanbiedingen, de weergaven van aankopen en
   bestellingen, Recept of Notitie in het plan-venster. Hetzelfde ingedeukte spoor als .subtabs, maar met knoppen
   (aria-pressed) of radio's in plaats van links: .subtabs is navigatie, .segmented een keuze. Elk segment is minstens 44 px. */
.segmented {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 2px;
  width: fit-content;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface-muted);
  box-shadow: inset 0 1px 2px rgba(var(--shadow-ink), 0.05);
}

.segmented__item {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: var(--control-height);
  min-height: var(--control-height);
  padding: 0 14px;
  border: 0;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: var(--text-ui);
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s var(--ease), color 0.15s var(--ease), box-shadow 0.2s var(--ease);
  -webkit-tap-highlight-color: transparent;
}

.segmented__item--icon {
  padding: 0;
}

.segmented__item svg {
  flex: none;
  width: 20px;
  height: 20px;
  fill: currentColor;
}

/* Een radio in een segment: onzichtbaar, het segment is het doel (en het label). */
.segmented__item input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.segmented__item.is-active,
.segmented__item[aria-pressed="true"],
.segmented__item:has(input:checked) {
  background: var(--surface);
  color: var(--primary-strong);
  box-shadow: 0 1px 2px rgba(var(--shadow-ink), 0.12), 0 0 0 1px var(--border);
}

.segmented__item:focus-visible,
.segmented__item:has(input:focus-visible) {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

@media (hover: hover) {
  .segmented__item:hover:not(.is-active, [aria-pressed="true"], :has(input:checked)) {
    background: var(--selection);
    color: var(--primary-strong);
  }
}

.tab.is-active > svg {
  color: var(--primary);
}

/* Uitklapmenu in een subtabbalk (Instellingen > Koppelen): de knop opent een lijst met de winkels eronder. */
.subtab-menu {
  position: relative;
}

.subtab-menu__toggle {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

/* De winkelkeuze in Winkels kiest iets in plaats van een pagina te openen: lichte vulling in plaats van de actieve kleur. */
.subtab-menu__toggle--select {
  background: var(--selection);
  color: var(--primary-strong);
}

@media (hover: hover) {
  .subtab-menu__toggle--select:hover {
    background: var(--selection);
    color: var(--primary-strong);
  }
}

.subtab-menu__chevron {
  flex: none;
  width: 20px;
  height: 20px;
  fill: currentColor;
  transition: transform 0.15s ease;
}

.subtab-menu__toggle[aria-expanded="true"] .subtab-menu__chevron {
  transform: rotate(180deg);
}

.subtab-menu__list {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 100%;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  animation: pop-in 0.16s var(--ease) both;
  transform-origin: top left;
}

.subtab-menu__list[hidden] {
  display: none;
}

.subtab-menu__item {
  min-height: var(--control-height);
  padding: 0 16px;
  border: 0;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: var(--text-ui);
  font-weight: 600;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}

.subtab-menu__item.is-active {
  background: var(--selection);
  color: var(--primary-strong);
}

@media (hover: hover) {
  .subtab-menu__item:hover {
    background: var(--selection);
    color: var(--primary-strong);
  }
}

/* Navigatie is een echte link (router.js): Ctrl+klik en de middelste knop openen een nieuw tabblad. Zelfde uiterlijk als de knoppen. */
a.tab,
a.subtab,
a.subtab-menu__item,
a.user-menu__item,
a.ohc-item,
a.list-card__open {
  text-decoration: none;
}

a.subtab,
a.subtab-menu__item {
  display: inline-flex;
  align-items: center;
}

a.subtab[hidden],
a.subtab-menu__item[hidden] {
  display: none;
}

/* Iconen: Material Design Icons (Pictogrammers, licentie in static/icons/). In de bovenste tabs staan
   ze links van de tekst; in de onderste menubalk (PWA op een klein scherm) boven een kort label. */
.tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.subtab--icon {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.tab-icon {
  flex: none;
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.subtab-icon {
  flex: none;
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.tab-short {
  display: none;
}

/* De boom onder een onderdeel van het zijmenu (nav_tree.js): alleen op een groot scherm, zie verderop. */
.tab-tree {
  display: none;
}

.panel,
.subpanel {
  display: none;
}

/* backwards, niet both: na afloop is er niets meer van de animatie over. Met both bleef de transform actief, en dan is het
   paneel het bevattende blok voor alles met position: fixed erin; de filterlade van Aanbiedingen stond daardoor naast de
   zijbalk half in beeld, en opengeklapt op de verkeerde plek. De eindstand is de gewone stand, dus het ziet er hetzelfde uit. */
.panel.is-active,
.subpanel.is-active {
  display: block;
  animation: rise-in 0.28s var(--ease) backwards;
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .panel.is-active,
  .subpanel.is-active,
  .auth-card {
    animation: none;
  }
}

.toolbar,
.form-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.form-row .button {
  flex: none;
  white-space: nowrap;
}

.week-label {
  min-width: 180px;
  text-align: center;
}

.week-label strong,
.week-label span {
  display: block;
}

.week-label span,
.muted {
  color: var(--muted);
  font-size: var(--text-md);
}

.button,
.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--control-height);
  background: var(--primary);
  color: var(--on-primary);
  padding: 0 18px;
  box-shadow: var(--btn-shadow);
}

@media (hover: hover) {
  .button:hover,
  .icon-button:hover {
    background: var(--primary-strong);
    box-shadow: var(--btn-shadow-hover);
  }
}

.button:active:not(:disabled),
.icon-button:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: none;
}

.button:disabled {
  cursor: not-allowed;
  opacity: 0.6;
  box-shadow: none;
}

.button--secondary,
.icon-button {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-xs);
}

@media (hover: hover) {
  .button--secondary:hover,
  .icon-button:hover {
    border-color: var(--border-strong);
    background: var(--selection);
    color: var(--primary-strong);
    box-shadow: var(--shadow-sm);
  }
}

.icon-button {
  width: var(--control-height);
  padding: 0;
  font-size: 24px; /* geen tekst maar de maat van een teken-icoon (×, ‹); buiten de typeschaal */
  line-height: 1;
}

.inline-button {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  margin-top: 14px;
  text-decoration: none;
}

/* 16 px voorkomt dat iOS bij het focussen van een veld inzoomt */
.field {
  display: grid;
  gap: 6px;
}

.field > span {
  font-size: var(--text-md);
  font-weight: 600;
}

.input,
.textarea {
  width: 100%;
  border: 1px solid var(--control-border);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--text-base);
  box-shadow: inset 0 1px 2px rgba(var(--shadow-ink), 0.04);
  transition: border-color 0.15s var(--ease), box-shadow 0.2s var(--ease);
}

.input::placeholder,
.textarea::placeholder {
  color: var(--placeholder);
  opacity: 1;
}

@media (hover: hover) {
  .input:hover:not(:focus-visible),
  .textarea:hover:not(:focus-visible),
  .store-select:hover:not(:focus-visible) {
    border-color: var(--muted);
  }
}

.input {
  min-height: var(--control-height);
  padding: 0 12px;
}

.textarea {
  margin: 12px 0;
  padding: 10px 12px;
  resize: vertical;
}

.box,
.message,
.day-card,
.recipe-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
}

.box,
.day-card,
.recipe-card {
  box-shadow: var(--shadow-sm);
}

.box {
  max-width: 680px;
  margin-bottom: 16px;
  padding: 24px;
}

.narrow {
  max-width: 620px;
}

/* Verticaal ritme in een blok: kop, uitleg, invoer en knop krijgen vaste, rustige afstanden. */
.box > h2 + .muted,
.box > .toolbar + .muted,
.box > .list-header + .muted {
  margin-top: 6px;
}

.box > .muted + .form-row,
.box > .muted + form {
  margin-top: 16px;
}

.box .muted + .button,
.box .muted + .inline-button {
  margin-top: 14px;
}

.box .button + .muted {
  margin-top: 10px;
}

/* Recepten zoeken: de uitleg staat los van het zoekvak, elke winkel is een eigen groep onder de uitleg, en
   Meer recepten plakt niet aan de kaarten. */
#search-form + .muted {
  margin-top: 10px;
}

.search-store {
  margin-top: 24px;
}

.search-store .recipe-grid + p {
  margin-top: 14px;
}

/* Overzichten met kaarten gebruiken de volle breedte, zodat er meer naast elkaar passen */
.box--wide {
  max-width: none;
}

.message {
  margin: 16px 0;
  padding: 12px 16px 12px 18px;
  font-size: var(--text-ui);
}

/* Een gekleurde balk links maakt het soort melding in één oogopslag duidelijk; de tekst legt het altijd uit. */
.message.success {
  border-color: var(--success-border);
  background: var(--success-bg);
  color: var(--success-text);
  box-shadow: inset 4px 0 0 var(--primary);
}

.message.error {
  border-color: var(--danger-border);
  background: var(--danger-bg);
  color: var(--danger);
  box-shadow: inset 4px 0 0 var(--danger);
}

.message.warning {
  border-color: var(--warning-border);
  background: var(--warning-bg);
  color: var(--warning-text);
  box-shadow: inset 4px 0 0 var(--warning-border);
}

/* Neutraal: bezig, wachten, of een mededeling zonder oordeel (sinds 4.10.4). Geen groen: "Laden..." is geen succes. */
.message.info {
  background: var(--surface-muted);
  color: var(--text);
  box-shadow: inset 4px 0 0 var(--muted);
}

.message.warning code {
  background: var(--code-on-message);
}

/* Melding met een knop ernaast */
.message--action {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
}

.message--action .inline-button {
  margin-top: 0;
}

/* De melding van het koppelen (linking.js): de tekst neemt de ruimte en de knop staat ernaast, tot het smal wordt. */
.linking-notice > span {
  flex: 1 1 20rem;
}

/* Instellingen > Koppelen: de feiten van het koppelen bij AH in twee kolommen, met een meter voor het uurbudget (de zoekopdrachten
   van dit uur tegen de grens). De tekst ernaast zegt hetzelfde, dus de meter is versiering voor een schermlezer. */
.linking-facts {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 6px 16px;
  margin: 12px 0 16px;
}

.linking-facts dt {
  color: var(--muted);
}

.linking-facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.linking-meter {
  display: inline-block;
  width: 96px;
  height: 8px;
  margin-right: 8px;
  overflow: hidden;
  border-radius: var(--radius-pill);
  background: var(--surface-muted);
  box-shadow: inset 0 0 0 1px var(--border);
  vertical-align: middle;
}

.linking-meter i {
  display: block;
  height: 100%;
  background: var(--primary);
}

@media (max-width: 640px) {
  .linking-facts {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
  }

  .linking-facts dd + dt {
    margin-top: 8px;
  }
}

.day-grid,
.recipe-grid {
  display: grid;
  gap: 14px;
  margin-top: 18px;
}

.day-grid {
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}

.recipe-grid {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

.day-card,
.recipe-card {
  overflow: hidden;
  padding: 16px;
}

.day-card h3 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 12px;
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* Vandaag valt op: een groene rand en een kleine chip, zonder de andere dagen te dempen. */
.day-card--today {
  border-color: var(--primary);
  box-shadow: 0 0 0 1px var(--primary), var(--shadow-md);
}

.day-card--today h3 {
  color: var(--primary-strong);
}

.day-card__today {
  border-radius: var(--radius-pill);
  background: var(--primary);
  color: var(--on-primary);
  padding: 1px 8px;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
}

.meal {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.meal__type {
  display: block;
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
}

/* Geen automatisch afbreken: in een smalle dagkaart brak dat elke titel per lettergreep ("Boeren-koolstamp-pot"). Alleen
   een woord dat echt niet past, breekt. */
.meal strong {
  display: block;
  margin-top: 2px;
  font-size: var(--text-ui);
  overflow-wrap: break-word;
  hyphens: manual;
}

.meal small {
  display: block;
  margin-top: 3px;
  color: var(--muted);
  font-size: var(--text-sm);
}

.ingredients {
  margin-top: 18px;
  padding: 18px;
}

.ingredients ul {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 6px 16px;
  margin: 14px 0 0;
  padding-left: 18px;
}

/* De boodschappenlijst onder het weekmenu (shopping.js, 4.11.0): een aanvinklijst met per regel een huisje voor "altijd in huis",
   de dagen waarvoor je boodschappen doet als chips erboven, en wat in huis is ingeklapt eronder. Regels van 44 px. */
/* De knop Boodschappen en het zoeken springen naar deze koppen: onder de balk die bovenaan blijft staan, niet erachter. */
#shop-title,
#cart-review-title {
  scroll-margin-top: 96px;
}

.shop-days {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}

.shop-days__label {
  margin-right: 4px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 600;
}

.shop-days__note,
.shop-hint {
  margin: 8px 0 0;
  font-size: var(--text-sm);
}

.ingredients .shop-list {
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 0 16px;
  margin-top: 10px;
  padding: 0;
  list-style: none;
}

.shop-item {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}

.shop-item__label {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: 10px;
  min-width: 0;
  min-height: 44px;
  cursor: pointer;
}

.shop-item__label input {
  flex: none;
  width: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--primary);
}

.shop-item__label span {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Niet mee deze week: doorgestreept en gedempt, dus niet alleen aan het vinkje te zien. */
.shop-item.is-off .shop-item__label span {
  color: var(--muted);
  text-decoration: line-through;
}

.shop-item__pantry {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}

.shop-item__pantry svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
}

/* In huis: het gevulde huisje in de accentkleur (het icoon wisselt mee, dus niet alleen de kleur). */
.shop-item__pantry[aria-pressed="true"] {
  color: var(--primary);
}

@media (hover: hover) {
  .shop-item__pantry:hover {
    background: var(--selection);
    color: var(--primary-strong);
  }
}

.shop-pantry {
  margin-top: 10px;
  border-top: 1px solid var(--border);
}

/* display: list-item houdt het driehoekje van de browser, zodat je ziet dat het blok open en dicht kan. */
.shop-pantry > summary {
  display: list-item;
  padding: 11px 0;
  font-weight: 600;
  cursor: pointer;
}

.recipe-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease), border-color 0.2s var(--ease);
}

@media (hover: hover) {
  .recipe-card:hover {
    border-color: var(--border-strong);
    box-shadow: var(--shadow-md);
  }
}

/* Het oplichten van kaarten alleen met een muis: op een scherm blijft het na een tik anders hangen. */
@media (hover: hover) {
  .recipe-card:hover {
    transform: translateY(-2px);
  }

  .list-card:hover {
    transform: translateY(-1px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .recipe-card,
  .list-card,
  .button,
  .icon-button,
  .tab,
  .subtab,
  .input,
  .offer-chip,
  .product-card {
    transition: none;
  }

  .button:active:not(:disabled),
  .icon-button:active:not(:disabled) {
    transform: none;
  }

  @media (hover: hover) {
    .recipe-card:hover,
    .list-card:hover {
      transform: none;
    }
  }
}

.recipe-card img {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-control);
  object-fit: cover;
  background: var(--surface-muted);
  outline: 1px solid rgba(var(--shadow-ink), 0.08);
  outline-offset: -1px;
}

.recipe-card h3 {
  margin: 0;
  font-size: var(--text-base);
  line-height: 1.3;
}

/* De titel is de knop die het recept opent (recipeCardTitle, sinds 4.8.0). Zijn ::after beslaat de hele kaart, dus een tik
   op de foto of de tekst opent het recept; Inplannen en het vakje van In bulk importeren liggen erboven (z-index 1). De
   focusring staat om de kaart, niet om de tekst. */
.recipe-card:has(.recipe-card__open) {
  position: relative;
  cursor: pointer;
}

.recipe-card__open {
  display: inline;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.recipe-card__open::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.recipe-card__open:focus-visible {
  outline: none;
}

.recipe-card:has(.recipe-card__open:focus-visible) {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
}

.recipe-card .card-actions,
.recipe-card .recipe-import-result {
  position: relative;
  z-index: 1;
}

/* In de selectiemodus (In bulk importeren) selecteert een tik de kaart, zoals eerst: de titel opent dan niets. */
.recipe-card.is-selectable .recipe-card__open {
  pointer-events: none;
}

.recipe-card.is-selectable .recipe-card__open::after {
  content: none;
}

.recipe-card .recipe-card__headline {
  margin: 0;
  font-size: var(--text-md);
  line-height: 1.4;
}

.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

.tag {
  border-radius: var(--radius-pill);
  background: var(--selection);
  box-shadow: inset 0 0 0 1px var(--selection-border);
  color: var(--primary-strong);
  padding: 3px 10px;
  font-size: var(--text-xs);
  font-weight: 600;
}

/* Onderaan elke receptkaart alleen Inplannen, secundair: in een rij kaarten op dezelfde hoogte (de kaart is een flexkolom en de
   knop duwt zich met margin-top: auto naar onderen). Eerst stonden Bekijken en een groene Inplannen als twee volle knoppen op
   elke kaart: op een scherm met twaalf recepten twaalf primaire knoppen. */
.card-actions {
  display: flex;
  gap: 8px;
  margin-top: auto;
}

.card-actions .button {
  min-width: 0;
  padding: 0 14px;
}

.recipe-import-result:empty {
  display: none;
}

/* De knoppen in het detail van een recept: Inplannen, Importeer en de link naar de winkel of Mealie. */
.recipe-detail__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0;
}

.recipe-detail__actions .mdi {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.pager {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 18px;
}

.credential-list {
  display: grid;
  gap: 10px;
  margin-top: 16px;
}

.credential-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 12px;
}

.credential-row strong,
.credential-row small {
  display: block;
}

.credential-row small {
  margin-top: 3px;
  color: var(--muted);
  font-size: var(--text-sm);
}

.credential-row .list-link {
  flex: 1;
  color: inherit;
  text-decoration: none;
}

.credential-row .list-link strong {
  color: var(--primary);
}

.security-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
}

.steps {
  display: grid;
  gap: 8px;
  margin: 14px 0 0;
  padding-left: 20px;
  color: var(--text);
  font-size: var(--text-ui);
  line-height: 1.5;
}

code {
  background: var(--surface-muted);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 1px 5px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}

.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 10px;
  margin-top: 14px;
}

.product-card {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  padding: 10px;
  color: inherit;
  text-decoration: none;
  font-variant-numeric: tabular-nums;
  transition: border-color 0.15s var(--ease), background-color 0.15s var(--ease), box-shadow 0.2s var(--ease);
}

@media (hover: hover) {
  a.product-card:hover {
    border-color: var(--primary);
    background: var(--selection);
    box-shadow: var(--shadow-sm);
  }
}

.product-card img {
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: var(--radius-control);
  object-fit: contain;
  background: #fff;
  outline: 1px solid rgba(var(--shadow-ink), 0.08);
  outline-offset: -1px;
}

a.product-card strong {
  color: var(--primary);
}

.product-card small {
  display: block;
  margin-top: 3px;
  color: var(--muted);
  font-size: var(--text-sm);
}

.product-card .bonus {
  width: fit-content;
  margin-top: 4px;
  border-radius: var(--radius-pill);
  background: var(--danger-bg);
  box-shadow: inset 0 0 0 1px var(--danger-border);
  color: var(--danger);
  padding: 1px 8px;
  font-size: var(--text-xs);
  font-weight: 700;
}

/* De prijs is het eerste wat je zoekt: groter en vet, met de oude prijs er klein en doorgestreept naast. */
.product-card .product-card__price {
  margin-top: 4px;
  color: var(--text);
  font-family: var(--font-heading);
  font-size: var(--text-base);
  font-weight: 800;
  letter-spacing: -0.01em;
}

.product-card .product-card__price s {
  color: var(--muted);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 500;
}

.product-card s {
  margin-left: 4px;
  color: var(--muted);
}

/* Een gekoppeld product onder een receptvoorstel: een knop die op een link lijkt en het productvenster opent. */
.offer-match {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  color: var(--primary);
  text-align: left;
  cursor: pointer;
}

@media (hover: hover) {
  .offer-match:hover {
    text-decoration: underline;
  }
}

/* De kleine vlag naast een gekoppeld product: meld dat de koppeling niet klopt. */
.offer-flag {
  appearance: none;
  border: 0;
  background: none;
  padding: 2px;
  margin-left: 4px;
  color: var(--muted);
  cursor: pointer;
  vertical-align: middle;
  line-height: 0;
  border-radius: var(--radius-sm);
}

@media (hover: hover) {
  .offer-flag:hover {
    color: var(--danger);
  }
}

.offer-flag:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.offer-flag svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
}

.offer-match:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Een popup houdt het vegen voor zich. Zolang er een open is, scrolt de pagina erachter niet: niet bij vegen op de
   popup als die bovenaan of onderaan is, niet bij vegen op de donkere rand eromheen, en vegen naar beneden ververst de
   pagina niet (pull-to-refresh). Het slot zit op <html>: dat scrolt de pagina, ook waar html zelf overflow-y heeft. */
html:has(dialog[open]) {
  overflow: hidden;
  overscroll-behavior: none;
}

.product-dialog {
  width: min(480px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px); /* iOS: de zichtbare hoogte, zonder de werkbalk van Safari */
  overflow: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 0;
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 24px 80px rgba(var(--shadow-ink), 0.3);
}

/* Naar de inhoud (sinds 4.12.0): de eerste Tab-stop van de pagina, alleen te zien met de focus erop. Slaat de kop en het menu over. */
.skip-link {
  position: fixed;
  z-index: 100;
  top: 8px;
  left: 8px;
  padding: 10px 14px;
  border-radius: var(--radius-control);
  background: var(--primary);
  color: var(--on-primary);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
}

/* De inhoud krijgt de focus na een schermwissel en na Naar de inhoud, zodat Tab daar verdergaat (app.js, router.js). Het is
   geen bediening: een focusrand om de hele pagina zegt niets. */
#main:focus {
  outline: none;
}

/* De regel onder een veld (de wachtwoordregels, sinds 4.12.0): klein en gedempt, direct onder het veld waar hij bij hoort. */
.field__hint {
  display: block;
  margin-top: 4px;
  font-size: var(--text-sm);
}

/* Een veld met zijn label ervoor op één regel (de naam van een nieuwe passkey). */
.field--inline {
  display: flex;
  flex: 1 1 220px;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  margin: 0;
}

.field--inline .input {
  flex: 1 1 160px;
}

/* Een laadtoestand met vaste ruimte (loadingHtml in app.js, sinds 4.12.0), zoals .offers-loading bij de aanbiedingen. */
.loading-box {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 160px;
  color: var(--muted);
}

.loading-box__icon {
  flex: none;
  width: 28px;
  height: 28px;
  fill: currentColor;
  animation: spin 1s linear infinite;
}

/* Het weekmenu terwijl het laadt: lege kaarten met grijze balken waar de foto en de naam komen. Stil, zonder glans. */
.day-card--skeleton {
  display: grid;
  align-content: start;
  gap: 12px;
  min-height: 150px;
  padding: 16px;
}

.day-card--skeleton span {
  display: block;
  height: 14px;
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
}

.day-card--skeleton span:first-child {
  width: 35%;
}

.day-card--skeleton span:nth-child(2) {
  width: 80%;
  height: 44px;
}

.day-card--skeleton span:last-child {
  width: 55%;
}

@media (prefers-reduced-motion: reduce) {
  .loading-box__icon {
    animation: none;
  }
}

/* Een vraag (confirmDialog in app.js, sinds 4.12.0): de tekst, en de knoppen rechts met de bevestiging als laatste. */
.confirm-dialog {
  width: min(420px, calc(100vw - 32px));
}

.confirm-dialog__text {
  margin: 0;
  font-size: var(--text-base);
  line-height: 1.5;
}

/* Korte meldingen (toast in app.js): onderaan in het midden, boven de menubalk van de geinstalleerde app. */
.toasts {
  position: fixed;
  z-index: 60;
  right: 16px;
  bottom: max(16px, env(safe-area-inset-bottom));
  left: 16px;
  display: grid;
  justify-items: center;
  gap: 8px;
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(520px, 100%);
  padding: 10px 14px;
  border: 1px solid var(--success-border);
  border-radius: var(--radius-card);
  background: var(--success-bg);
  color: var(--success-text);
  box-shadow: var(--shadow-md);
  font-size: var(--text-ui);
  font-weight: 600;
  pointer-events: auto;
  animation: rise-in 0.2s var(--ease);
}

.toast--error {
  border-color: var(--danger-border);
  background: var(--danger-bg);
  color: var(--danger);
}

.toast__close {
  flex: none;
  min-height: 32px;
  padding: 0 10px;
  border: 1px solid currentColor;
  border-radius: var(--radius-control);
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
  .toast {
    animation: none;
  }
}

.product-dialog::backdrop {
  background: rgba(var(--shadow-ink), 0.5);
}

.product-dialog [hidden] {
  display: none;
}

.product-dialog__inner {
  display: grid;
  gap: 12px;
  padding: 20px;
}

.product-dialog__body {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.product-dialog__image {
  width: 112px;
  height: 112px;
  flex: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  object-fit: contain;
  background: var(--surface);
}

.product-dialog h3 {
  margin: 0 0 4px;
  font-size: var(--text-lg);
  overflow-wrap: anywhere;
}

.product-dialog p {
  margin: 4px 0;
}

.product-dialog .bonus {
  color: var(--danger);
  font-weight: 600;
}

.product-dialog s {
  margin-left: 6px;
  color: var(--muted);
}

.product-dialog__match {
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.product-dialog__actions .button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.product-dialog__actions .mdi {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.product-dialog__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}

@media (max-width: 640px) {
  .product-dialog__body {
    flex-direction: column;
  }
}

/* De productfoto in het groot, vanuit de controlelijst van het mandje. Vierkant, maar nooit hoger dan het scherm toelaat. */
.photo-dialog__image {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  max-height: max(160px, calc(100vh - 220px));
  max-height: max(160px, calc(100dvh - 220px)); /* iOS: de zichtbare hoogte, zonder de werkbalk van Safari */
  border-radius: var(--radius-control);
  object-fit: contain;
  background: #fff;
  outline: 1px solid rgba(var(--shadow-ink), 0.08);
  outline-offset: -1px;
}

@media (prefers-reduced-motion: reduce) {
  .review-thumb {
    transition: none;
  }

  .review-thumb:not(:disabled):active {
    transform: none;
  }

  @media (hover: hover) {
    .review-thumb:not(:disabled):hover {
      transform: none;
    }
  }
}

/* AI-beoordeling (optioneel): de balk boven de receptvoorstellen, het vinkje bij een goedgekeurde koppeling en het blok bij Instellingen. */
.offers-ai {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  margin: 8px 0;
}

.offers-ai[hidden] {
  display: none;
}

.offers-ai p {
  margin: 0;
}

#offers-ai-run .ai-run__icon {
  width: 18px;
  height: 18px;
  margin-right: 6px;
  vertical-align: middle;
  fill: currentColor;
  animation: spin 1s linear infinite;
}

.offer-ai {
  display: inline-flex;
  margin-left: 4px;
  vertical-align: middle;
  color: var(--success-text);
}

.offer-ai svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
}

.ai-provider {
  margin: 14px 0;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
}

.ai-provider h3 {
  margin: 0 0 4px;
}

.offer-matches {
  margin: 0;
  padding-left: 18px;
  font-size: var(--text-md);
}

.recipe-card .bonus {
  margin: 0;
  color: var(--danger);
  font-weight: 600;
  font-size: var(--text-md);
}

.product-card--list {
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}

.product-card__main {
  display: flex;
  align-items: center;
  gap: 12px;
  color: inherit;
  text-decoration: none;
}

@media (hover: hover) {
  a.product-card__main:hover strong {
    text-decoration: underline;
  }
}

.product-card--list.is-edited {
  border-color: var(--primary);
}

.qty {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
}

.qty__note {
  flex: 1;
  color: var(--muted);
  font-size: var(--text-sm);
}

.qty__step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
}

@media (hover: hover) {
  .qty__step:hover {
    background: var(--selection);
    color: var(--primary-strong);
  }
}

.qty__step svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.qty__input {
  width: 52px;
  height: 36px;
  padding: 0 4px;
  border: 1px solid var(--control-border);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-weight: 600;
  text-align: center;
  appearance: textfield;
  -moz-appearance: textfield;
}

.qty__input::-webkit-outer-spin-button,
.qty__input::-webkit-inner-spin-button {
  margin: 0;
  -webkit-appearance: none;
}

.row-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}

.cart-lines {
  margin: 10px 0 0;
  padding-left: 20px;
  columns: 2 260px;
}

/* Het receptdetail staat onder een kop met de terugknop; zonder deze ruimte plakt de foto aan de kop. */
.picnic-recipe {
  margin-top: 16px;
}

.picnic-recipe__image {
  display: block;
  width: 100%;
  max-width: 420px;
  height: auto;
  margin-bottom: 12px;
  border-radius: var(--radius-control);
}

/* ---- De kookweergave (recipe_view.js): ingrediënten naast de bereiding, zo groot en rustig dat je er tijdens het koken
   mee werkt. Op een smal vak staan ze onder elkaar; vanaf 640 px breed (het vak zelf, niet het scherm) naast elkaar, met de
   ingrediënten vast in beeld terwijl je door de stappen scrolt. --cook-sticky-top is de ruimte onder de balk bovenaan. */
.cook {
  --cook-sticky-top: 88px;
  --cook-sticky-room: 24px;
  container: cook / inline-size;
  margin-top: 12px;
}

.cook .mdi {
  width: 20px;
  height: 20px;
  fill: currentColor;
  flex: none;
}

.cook__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface-muted);
}

.cook__progress {
  display: grid;
  flex: 1 1 180px;
  gap: 6px;
  min-width: 0;
  font-size: var(--text-md);
  font-weight: 600;
}

.cook__meter {
  display: block;
  height: 6px;
  overflow: hidden;
  border-radius: var(--radius-pill);
  background: var(--border);
}

.cook__meter i {
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--primary);
  transition: width 220ms var(--ease);
}

.cook__wake {
  margin: 0;
  min-height: var(--control-height);
  font-size: var(--text-ui);
}

.cook__wake input {
  width: 22px;
  height: 22px;
}

.cook__columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr); /* issue #309: een lang woord (een link, een samenstelling) maakt de kolom niet breder dan het venster */
  gap: 24px;
  margin-top: 20px;
}

.cook .cook__heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 8px;
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  font-weight: 800;
  line-height: 1.25;
}

.cook__count {
  color: var(--muted);
  font-family: var(--font-body);
  font-size: var(--text-md);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.cook .cook__section {
  margin: 16px 0 4px;
  color: var(--muted);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.cook__note {
  margin-top: 12px;
}

.cook-ingredients {
  margin: 0;
  padding: 0;
  list-style: none;
}

.cook-ingredient + .cook-ingredient {
  border-top: 1px solid var(--border);
}

.cook-ingredient label {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-height: var(--control-height);
  padding: 10px 8px;
  border-radius: var(--radius-control);
  font-size: var(--text-lg);
  line-height: 1.45;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.cook-ingredient input {
  flex: none;
  width: 22px;
  height: 22px;
  margin: 1px 0 0;
  accent-color: var(--primary);
  cursor: pointer;
}

.cook-ingredient__text {
  min-width: 0;
  overflow-wrap: anywhere;
  transition: color 150ms var(--ease);
}

.cook-ingredient__amount {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.cook-ingredient input:checked + .cook-ingredient__text {
  color: var(--muted);
  text-decoration: line-through;
  text-decoration-thickness: 2px;
}

/* Kookmodus uit (Instellingen, Weergave, Voorkeuren; html.no-cook-mode, zie static/theme.js): geen balk met Start met koken,
   voortgang en Scherm aan laten, en de ingrediënten als gewone lijst zonder vinkjes (recipe_view.js zet ze ook op disabled). */
html.no-cook-mode .cook__bar,
html.no-cook-mode .cook-ingredient input,
html.no-cook-mode .cook [data-cook-ticked] {
  display: none;
}

html.no-cook-mode .cook__columns {
  margin-top: 0;
}

html.no-cook-mode .cook-ingredient label {
  cursor: default;
}

html.no-cook-mode .cook-ingredient input:checked + .cook-ingredient__text {
  color: inherit;
  text-decoration: none;
}

/* Calorieën (issue #283). Een kcal-waarde staat in een eigen span achter de andere feiten; de punt ervoor komt van hier,
   zodat er niets blijft hangen als Calorieën tonen uit staat (html.no-calories, zie static/theme.js). */
.kcal {
  white-space: nowrap; /* "490 kcal p.p." bij elkaar; afbreken mag wel bij de punt ervoor */
}

/* De korte voedingswaarden op een kaart mogen wel afbreken: ze zijn langer dan één kcal-waarde. */
.nutrition-brief {
  white-space: normal;
}

.nutrition-brief__part {
  white-space: nowrap;
}

.kcal--after::before {
  content: "\20\b7\20"; /* " · " */
  white-space: pre-wrap;
}

html.no-calories .kcal,
html.no-calories .day-card__nutrition,
html.no-calories .nutrition-facts,
html.no-calories .kcal-filter,
html.no-calories .nutrition-filter,
html.no-calories .plan-servings__kcal {
  display: none;
}

/* De voedingswaarden onder een recept als een kleine tabel, zoals op een etiket: per portie en (bij geplande porties) totaal. */
.nutrition-facts {
  margin-top: 16px;
}

.nutrition-facts__title {
  margin: 0 0 6px;
}

.nutrition-table {
  width: 100%;
  max-width: 440px;
  border-collapse: collapse;
  font-size: var(--text-md);
  font-variant-numeric: tabular-nums;
}

.nutrition-table th,
.nutrition-table td {
  padding: 5px 8px;
  border-bottom: 1px solid var(--border);
  text-align: right;
}

.nutrition-table th[scope="row"] {
  font-weight: 500;
  text-align: left;
}

.nutrition-table thead th {
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 600;
}

.nutrition-table th:first-child {
  padding-left: 0;
}

.nutrition-table__sub th[scope="row"] {
  padding-left: 16px;
  color: var(--muted);
  font-weight: 400;
}

/* Het dagtotaal onder een dag in het weekmenu. */
.day-card__nutrition {
  margin: 2px 0 8px;
  color: var(--muted);
  font-size: var(--text-sm);
}

/* Meer filters (eiwit, vet, koolhydraten, suikers, vezels, zout): ingeklapt onder de kcal. */
.nutrition-filter > summary {
  width: fit-content;
  color: var(--primary-strong);
  font-size: var(--text-md);
  font-weight: 600;
  cursor: pointer;
}

.nutrition-filter[open] {
  display: grid;
  gap: 8px;
}

.nutrition-filter .kcal-filter__label {
  min-width: 132px;
}

/* Het filter op calorieën: "Kcal per persoon [min.] – [max.]", in de receptkiezer en bij Recepten zoeken. */
.kcal-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 8px;
}

.kcal-filter__label {
  color: var(--muted);
  font-size: var(--text-md);
  font-weight: 600;
}

.kcal-filter__input {
  width: 96px;
  min-width: 0;
}

.kcal-filter__dash {
  color: var(--muted);
}

.kcal-filter--search {
  margin: 10px 0 8px;
}

#search-nutrition-filter {
  margin-bottom: 14px;
}

.kcal-filter__note {
  flex-basis: 100%;
  font-size: var(--text-sm);
}

/* Op een telefoon past "Kcal per persoon" niet naast twee velden: het label staat erboven. */
@media (max-width: 640px) {
  .kcal-filter__label {
    flex-basis: 100%;
  }

  .kcal-filter__input {
    flex: 1 1 0;
    width: auto;
  }
}

/* Porties kiezen in het plan-venster, onder het gekozen recept, met de kcal ernaast. */
.plan-servings {
  display: flex;
  flex-basis: 100%;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding-top: 4px;
}

.plan-servings__label {
  font-weight: 600;
}

.plan-servings .qty {
  justify-content: flex-start;
}

.plan-servings__kcal {
  color: var(--muted);
  font-size: var(--text-md);
}

.cook-steps {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.cook-step {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: 14px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  transition: background-color 200ms var(--ease), border-color 200ms var(--ease), box-shadow 200ms var(--ease);
}

.cook-step.is-current {
  border-color: var(--primary);
  background: var(--selection);
  box-shadow: inset 4px 0 0 var(--primary);
}

.cook-step__toggle {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 2px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 800;
  cursor: pointer;
  transition: background-color 150ms var(--ease), border-color 150ms var(--ease), color 150ms var(--ease);
  -webkit-tap-highlight-color: transparent;
}

.cook-step__toggle:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
}

.cook-step.is-current .cook-step__toggle {
  border-color: var(--primary);
  color: var(--primary);
}

.cook .cook-step__check {
  display: none;
  width: 24px;
  height: 24px;
}

.cook-step.is-done .cook-step__toggle {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--on-primary);
}

.cook-step.is-done .cook-step__number {
  display: none;
}

.cook-step.is-done .cook-step__check {
  display: block;
}

.cook-step__body {
  min-width: 0;
  padding-top: 8px;
}

.cook-step__now {
  display: none;
  margin-bottom: 4px;
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.cook-step.is-current .cook-step__now {
  display: block;
}

.cook .cook-step__title {
  margin: 0 0 4px;
  font-family: var(--font-heading);
  font-size: var(--text-lg);
  font-weight: 800;
}

.cook .cook-step__text {
  max-width: 68ch;
  margin: 0;
  font-size: var(--text-lg);
  line-height: 1.6;
  white-space: pre-line;
  overflow-wrap: anywhere;
  transition: color 200ms var(--ease);
}

.cook-step.is-done .cook-step__text {
  color: var(--muted);
}

@media (hover: hover) {
  .cook-ingredient label:hover {
    background: var(--surface-muted);
  }

  .cook-step__toggle:hover {
    border-color: var(--primary);
  }
}

/* Op een telefoon: iets minder ruimte rond een stap, zodat er meer tekst op een regel past. */
@container cook (max-width: 420px) {
  .cook-step {
    gap: 12px;
    padding: 12px;
  }

  .cook .cook-step__text {
    font-size: var(--text-lg);
  }
}

@container cook (min-width: 640px) {
  .cook__columns {
    grid-template-columns: minmax(240px, 0.85fr) minmax(0, 1.6fr);
    align-items: start;
    gap: 32px;
  }

  .cook__ingredients {
    position: sticky;
    top: var(--cook-sticky-top);
    max-height: calc(100vh - var(--cook-sticky-top) - var(--cook-sticky-room));
    max-height: calc(100dvh - var(--cook-sticky-top) - var(--cook-sticky-room)); /* iOS: de zichtbare hoogte, zonder de werkbalk van Safari */
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

.picnic-slots {
  margin-top: 14px;
}

.picnic-basket {
  margin-top: 14px;
}

/* De kerncijfers van een mandje (basketStats, sinds 4.8.0), naar .stats van App-Guidance: een klein label in hoofdletters boven
   een vet, tabulair getal, naast elkaar. */
.stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 28px;
  margin: 4px 0 14px;
}

.stats dt {
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.stats dd {
  margin: 2px 0 0;
  font-size: var(--text-xl);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 640px) {
  .stats {
    gap: 6px 20px;
  }

  .stats dd {
    font-size: var(--text-lg);
  }
}

/* Uitleg die je openklapt ("Hoe werkt dit?"): een regel tekst met een pijltje in plaats van alinea's boven de inhoud. Een gewoon
   <details>, dus het werkt met muis, toetsenbord en op een telefoon. */
details.help {
  margin: 0 0 12px;
}

details.help > summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  color: var(--primary-strong);
  font-size: var(--text-md);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

details.help > summary::-webkit-details-marker {
  display: none;
}

details.help > summary::before {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 0.15s var(--ease);
}

details.help[open] > summary::before {
  transform: rotate(45deg);
}

details.help > p {
  margin: 4px 0 0;
}

@media (prefers-reduced-motion: reduce) {
  details.help > summary::before {
    transition: none;
  }
}

.basket-lines {
  list-style: none;
  margin: 10px 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.basket-line {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 10px;
}

.basket-qty {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.basket-qty .review-qty {
  width: 64px;
  min-height: var(--control-height);
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  text-align: center;
}

.basket-line.is-unavailable .basket-title {
  opacity: 0.7;
}

.basket-unavailable {
  color: var(--danger, #b3261e);
  font-weight: 600;
}

.basket-price {
  min-width: 64px;
  text-align: right;
}

@media (max-width: 640px) {
  .basket-line {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .basket-title {
    grid-column: 1 / -1;
  }
}

/* De controlelijst gebruikt de hele breedte van de inhoud, niet de 680 px van .box: een regel heeft een ingrediënt, een foto, een
   keuzelijst met lange productnamen, een link en een aantal. */
.box.cart-review {
  max-width: none;
}

.review-list {
  display: grid;
  gap: 8px;
  margin-top: 14px;
  container-type: inline-size;
}

/* Een regel in drie breedtes, met benoemde vlakken zodat niets buiten de regel kan (de tekstkolommen zijn minmax(0, ...)):
   smal (telefoon): vinkje, foto en ingrediënt bovenaan, de keuzelijst eronder over de volle breedte, dan link en aantal;
   middel: foto en vinkje links over twee regels, rechts het ingrediënt met de link en daaronder keuzelijst en aantal;
   breed (vanaf 900 px): alles op één regel, van ingrediënt naar product. */
.review-row {
  display: grid;
  grid-template-columns: auto 56px minmax(0, 1fr) auto;
  grid-template-areas:
    "include thumb ingredient ingredient"
    "product product product product"
    "link link link qty";
  align-items: center;
  gap: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 10px 12px;
}

.review-row > input[type="checkbox"] {
  grid-area: include;
  align-self: start;
  margin: 2px 0 0;
}

.review-row .review-ingredient {
  grid-area: ingredient;
  align-self: start;
  min-width: 0;
}

.review-row .review-thumb {
  grid-area: thumb;
  align-self: start;
}

.review-row .review-product {
  grid-area: product;
  min-width: 0;
}

.review-row .review-link {
  grid-area: link;
}

.review-row .review-qty {
  grid-area: qty;
}

/* De opties van een regel (Wijzig): onder de regel, over de volle breedte. */
.review-row .review-options {
  grid-column: 1 / -1;
}

@container (min-width: 520px) {
  .review-row {
    grid-template-columns: auto 56px minmax(0, 1fr) auto;
    grid-template-areas:
      "include thumb ingredient link"
      "include thumb product qty";
  }

  .review-row .review-link {
    align-self: start;
    justify-self: end;
  }

  .review-row .review-options {
    grid-column: 3 / -1;
  }
}

@container (min-width: 900px) {
  .review-row {
    grid-template-columns: auto 56px minmax(0, 1fr) minmax(0, 1.4fr) auto auto;
    grid-template-areas: "include thumb ingredient product link qty";
  }

  .review-row > input[type="checkbox"] {
    align-self: center;
    margin: 0;
  }

  .review-row .review-link {
    align-self: center;
  }
}

.review-row.is-doubt {
  border-color: var(--warning-border);
  background: var(--warning-bg);
}

/* Niet gevonden: geen foto, keuzelijst of aantal, wel het zoekveld. */
.review-row.is-missing {
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "include ingredient"
    "search search";
  border-style: dashed;
}

.review-row.is-missing .review-search {
  grid-area: search;
}

@container (min-width: 520px) {
  .review-row.is-missing .review-search {
    grid-column: 2;
  }
}

@container (min-width: 900px) {
  .review-row.is-missing {
    grid-template-columns: auto minmax(0, 1fr) minmax(0, 1.4fr);
    grid-template-areas: "include ingredient search";
  }

  .review-row.is-missing .review-search {
    grid-column: auto;
  }
}

/* Toevoegen en Annuleren in een balk die onderaan in beeld blijft, zoals de balk van In bulk importeren: na het nalopen van een
   lange lijst hoef je niet terug naar boven. */
.cart-review__actions {
  position: sticky;
  z-index: 5;
  bottom: max(12px, env(safe-area-inset-bottom));
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-md);
}

/* Het geschatte totaal links in de balk met Toevoegen en Annuleren (sinds 4.11.0). Voor de regel van de telefoon hieronder, die het op een eigen regel zet. */
.cart-review__total {
  flex: 1 1 0;
  min-width: 7em;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.cart-review__total:empty {
  display: none;
}

/* Op een telefoon naast elkaar: de toevoegknop neemt de ruimte, zodat de balk laag blijft. */
@media (max-width: 640px) {
  .cart-review__actions {
    margin-inline: -12px;
    padding: 8px;
  }

  /* Het totaal op een eigen regel boven de knoppen: naast elkaar brak de tekst van de toevoegknop in vier regels. */
  .cart-review__total {
    flex: 1 0 100%;
    margin: 0 4px;
    font-size: var(--text-md);
  }

  .cart-review__actions #confirm-cart {
    flex: 1 1 0;
    min-width: 0;
  }
}

.review-row.is-missing .review-note {
  color: var(--muted);
}

.review-search {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}

.review-search[hidden] {
  display: none;
}

.review-search-status {
  flex-basis: 100%;
  color: var(--muted);
  font-size: var(--text-sm);
}

.review-search-status:empty {
  display: none;
}

.review-search-input {
  flex: 1;
  min-width: 0;
  min-height: var(--control-height);
  border: 1px solid var(--control-border);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--text-base);
  padding: 0 8px;
}

/* De vergelijking in de controlelijst: een goedkopere verpakking per eenheid, met "Kies" (#178). */
.review-cheaper {
  display: block;
  margin-top: 2px;
  color: var(--warning-text);
  font-size: var(--text-sm);
}

.review-cheaper:empty {
  display: none;
}

.review-row .review-cheaper .link-button {
  min-height: 0;
  padding: 0;
  font-size: var(--text-sm);
}

.review-note {
  display: block;
  margin-top: 3px;
  color: var(--warning-text);
  font-size: var(--text-sm);
}

/* Liever biologisch (#218): geen biologische variant gevonden, dus het gewone product staat er */
.review-organic-missing {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  font-size: var(--text-sm);
}

.review-row input[type="checkbox"] {
  width: 20px;
  height: 20px;
  accent-color: var(--primary);
}

/* Het gekozen product (sinds 4.11.0 een knop in plaats van een keuzelijst van het systeem, die op een telefoon de lange regel
   afkapte): de naam en daaronder inhoud, prijs en prijs per eenheid. Tikken klapt de opties uit. */
.review-row .review-product {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-width: 0;
  min-height: var(--control-height);
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--text-ui);
  padding: 6px 10px;
  text-align: left;
  cursor: pointer;
  box-shadow: var(--shadow-xs);
}

.review-row .review-product[aria-expanded="true"] {
  border-color: var(--primary);
}

.review-chosen__text {
  flex: 1 1 auto;
  min-width: 0;
}

.review-chosen__text strong,
.review-chosen__text small,
.review-option__text strong,
.review-option__text small {
  display: block;
  overflow-wrap: anywhere;
}

.review-chosen__text small,
.review-option__text small {
  margin-top: 1px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 400;
}

.review-chosen__change {
  flex: none;
  color: var(--primary);
  font-size: var(--text-sm);
  font-weight: 600;
}

/* Het aantal verpakkingen: de -/+-knop van de lijstjes, hier 44 px omdat je de lijst ook staand in de keuken naloopt. */
.review-qty .qty__step,
.review-qty .qty__input {
  width: 44px;
  height: 44px;
}

.review-options {
  display: grid;
  gap: 10px;
  padding-top: 4px;
}

.review-options__list {
  display: grid;
  gap: 6px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.review-option {
  display: grid;
  grid-template-columns: auto 40px minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  min-height: 52px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface);
  cursor: pointer;
}

.review-option.is-chosen {
  border-color: var(--primary);
  background: var(--selection);
}

.review-option input {
  width: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--primary);
}

.review-option__image {
  display: block;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  object-fit: contain;
  background: #fff;
}

span.review-option__image {
  background: var(--surface-muted);
}

/* Eerder gekozen (cart_memory): een label met de knop om het te vergeten. */
.review-remembered {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin-top: 3px;
  font-size: var(--text-sm);
}

.review-remembered__tag {
  padding: 1px 8px;
  border: 1px solid var(--selection-border);
  border-radius: var(--radius-pill);
  background: var(--selection);
  color: var(--primary-strong);
  font-weight: 600;
}

.review-row .review-remembered .link-button {
  min-height: 24px;
  padding: 0;
  font-size: var(--text-sm);
}

/* Een regel die nog gezocht wordt. */
.review-row.is-pending {
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "include ingredient";
  border-style: dashed;
  color: var(--muted);
}

.review-pending__icon {
  grid-area: include;
  width: 20px;
  height: 20px;
  fill: currentColor;
  animation: spin 1s linear infinite;
}

.review-row.is-pending .review-note {
  color: var(--muted);
}

/* De groepen van de controlelijst: wat je moet nakijken, wat in orde is en wat nog gezocht wordt. */
.review-group {
  margin-top: 18px;
}

.review-group[hidden] {
  display: none;
}

.review-group h3 {
  margin: 0;
  font-size: var(--text-base);
}

.review-group .review-list {
  margin-top: 8px;
}

.review-progress {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-top: 12px;
  padding: 8px 12px;
  border-radius: var(--radius-control);
  background: var(--surface-muted);
  font-weight: 600;
}

.review-progress[hidden] {
  display: none;
}

.review-progress .button {
  margin-left: auto;
}

/* De foto van het gekozen product; zelfde tegel als bij .product-card. Een knop: tikken toont hem groot (#photo-dialog). */
.review-thumb {
  display: block;
  width: 56px;
  height: 56px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius-control);
  background: none;
  cursor: zoom-in;
  transition: transform 0.15s var(--ease);
}

.review-thumb:disabled {
  cursor: default;
}

@media (hover: hover) and (pointer: fine) {
  .review-thumb:not(:disabled):hover {
    transform: scale(1.05);
  }
}

.review-thumb:not(:disabled):active {
  transform: scale(0.97);
}

.review-thumb:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.review-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: var(--radius-control);
  object-fit: contain;
  background: #fff;
  outline: 1px solid rgba(var(--shadow-ink), 0.08);
  outline-offset: -1px;
}

.store-select {
  min-height: var(--control-height);
  border: 1px solid var(--control-border);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--text-base);
  padding: 0 8px;
  box-shadow: var(--shadow-xs);
  transition: border-color 0.15s var(--ease), box-shadow 0.2s var(--ease);
}

/* Keuzelijsten: één eigen pijltje van twee kleurvlakken in plaats van het pijltje van de browser; het volgt --muted, dus ook in het donkere thema. */
select.input,
.store-select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 38px;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 20px) calc(50% + 1px), calc(100% - 15px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

select.input {
  padding-left: 12px;
}

.review-link {
  color: var(--primary);
  font-size: var(--text-md);
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
}

@media (hover: hover) {
  .review-link:hover {
    text-decoration: underline;
  }
}

@media (max-width: 640px) {
  .topbar__inner {
    flex-wrap: wrap;
    min-height: 56px;
    padding: 6px 12px 6px 16px;
  }

  .topbar .brand-mark {
    width: 34px;
    height: 34px;
  }

  .wordmark {
    font-size: var(--text-xl);
  }

  .toolbar,
  .form-row,
  .security-actions,
  .credential-row {
    align-items: stretch;
    flex-wrap: wrap;
  }

  /* Geen minimumbreedte op een telefoon: in een kader (Maaltijdboxen) viel de knop Verversen anders naar een tweede regel. */
  .week-label {
    flex: 1 1 140px;
    align-self: center;
    min-width: 0;
  }

  .form-row .button,
  .form-row .input,
  .security-actions .button,
  .security-actions .input,
  .credential-row .button {
    width: 100%;
  }
}

/* Zoekbalk bovenaan een overzicht (recepten, lijstjes) */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.searchbar {
  position: relative;
  display: block;
  margin: 14px 0;
}

.searchbar__icon {
  position: absolute;
  top: 50%;
  left: 12px;
  width: 20px;
  height: 20px;
  transform: translateY(-50%);
  fill: var(--muted);
  pointer-events: none;
}

.searchbar .input {
  padding-left: 42px;
}

/* Weekmenu: het plaatje uit Mealie links van de maaltijd */
.meal--with-image {
  display: flex;
  align-items: center;
  gap: 12px;
}

.meal__image {
  flex: none;
  width: 64px;
  height: 64px;
  border-radius: var(--radius-control);
  object-fit: cover;
  background: var(--surface-muted);
}

.meal__text {
  flex: 1;
  min-width: 0;
}

/* Een notitie zonder recept ("Uit eten"): de toelichting houdt haar regels. */
.meal__note {
  white-space: pre-line;
  overflow-wrap: break-word;
}

/* Een geplande maaltijd ziet eruit als tekst. Een tik erop opent het recept (een notitie: het plan-venster); het potlood
   rechtsboven is een eigen knop die de maaltijd wijzigt. De tekst houdt rechts ruimte vrij voor het potlood. */
.meal--planned {
  position: relative;
  display: block;
  width: calc(100% + 16px);
  margin: 0 -8px 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  transition: border-color 0.15s var(--ease), background-color 0.15s var(--ease);
}

.meal__open {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 6px 42px 6px 8px;
  border: 0;
  border-radius: inherit;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.meal__edit {
  position: absolute;
  top: 2px;
  right: 2px;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s var(--ease), background-color 0.15s var(--ease);
}

.meal__edit .mdi {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.meal__open:focus-visible,
.meal__edit:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

/* Het recept van een maaltijd in een venster: breder dan de andere vensters, voor de ingrediënten en de bereiding.
   De knoppen blijven onderaan in beeld terwijl je door een lang recept scrolt. */
.meal-recipe {
  width: min(640px, calc(100vw - 32px));
}

.meal-recipe .product-dialog__inner {
  padding-bottom: 0;
}

.meal-recipe__image {
  display: block;
  width: 100%;
  aspect-ratio: 2 / 1;
  object-fit: cover;
  border-radius: var(--radius-control);
  background: var(--surface-muted);
}

.meal-recipe__type {
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
}

.meal-recipe h3:focus {
  outline: none;
}

.meal-recipe__description {
  white-space: pre-line;
  overflow-wrap: break-word;
}

/* In het venster scrolt het venster zelf: de ingrediënten blijven vlak onder de bovenrand staan, en vrij van de knoppenbalk
   die onderaan in beeld blijft. Op een groot scherm is het venster breed genoeg voor twee kolommen. */
.meal-recipe .cook {
  --cook-sticky-top: 12px;
  --cook-sticky-room: 140px;
}

@media (min-width: 860px) {
  .meal-recipe {
    width: min(1040px, calc(100vw - 64px));
  }

  .meal-recipe__image {
    aspect-ratio: auto;
    height: 240px;
  }
}

.meal-recipe__actions {
  position: sticky;
  bottom: 0;
  margin: 0 -20px;
  padding: 12px 20px 20px;
  border-top: 1px solid var(--border);
  background: var(--surface);
}

/* ---- De kookmodus (#cook-mode, recipe_view.js): schermvullend, één stap in grote letters, met Vorige en Volgende onderaan
   binnen bereik van je duim. De ingrediënten liggen op een smal scherm als paneel over de onderkant, vanaf 860 px ernaast. */
.cook-mode {
  inset: 0;
  width: auto;
  max-width: none;
  height: auto;
  max-height: none;
  margin: 0;
  border: 0;
  border-radius: 0;
  overflow: hidden;
  background: var(--bg);
  box-shadow: none;
}

.cook-mode::backdrop {
  background: var(--bg);
}

/* De pagina houdt ruimte vrij voor de scrollbalk (html, scrollbar-gutter); zolang de kookmodus open is, scrolt ze niet
   (html:has(dialog[open])), en zonder die ruimte vult de kookmodus het hele scherm, zonder smalle strook rechts. */
html:has(#cook-mode[open]) {
  scrollbar-gutter: auto;
}

.cook-mode .mdi {
  width: 20px;
  height: 20px;
  fill: currentColor;
  flex: none;
}

.cook-mode__inner {
  position: relative;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  height: 100%;
}

.cook-mode__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "titles close" "tools tools" "meter meter";
  align-items: center;
  gap: 10px 16px;
  padding: max(12px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) 12px max(16px, env(safe-area-inset-left));
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}

.cook-mode__titles {
  grid-area: titles;
  min-width: 0;
}

.cook-mode .cook-mode__eyebrow {
  margin: 0;
  color: var(--primary);
  font-size: var(--text-xs);
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.cook-mode h2 {
  display: -webkit-box;
  overflow: hidden;
  font-size: var(--text-lg);
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.cook-mode__tools {
  grid-area: tools;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
}

.cook-mode__close {
  grid-area: close;
  width: var(--control-height);
  padding: 0;
}

.cook-mode__meter {
  grid-area: meter;
}

@media (min-width: 641px) {
  .cook-mode__head {
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas: "titles tools close" "meter meter meter";
  }

  .cook-mode__tools {
    justify-content: flex-end;
  }
}

.cook-mode__body {
  position: relative;
  display: grid;
  min-height: 0;
}

.cook-mode__stage {
  display: flex;
  flex-direction: column;
  gap: 20px;
  width: 100%;
  max-width: 52rem;
  min-height: 0;
  margin: 0 auto;
  /* Onderaan ruimte voor de zwevende timers (cook_timers.js zet --cook-timers-room), zodat er niets van de stap achter valt. */
  padding: 24px max(20px, env(safe-area-inset-right)) calc(24px + var(--cook-timers-room, 0px)) max(20px, env(safe-area-inset-left));
  scroll-padding-bottom: var(--cook-timers-room, 0px);
  overflow-y: auto;
  overscroll-behavior: contain;
  touch-action: pan-y;
}

.cook-mode__step {
  display: grid;
  gap: 12px;
}

.cook-mode .cook-mode__counter {
  margin: 0;
  color: var(--primary);
  font-family: var(--font-heading);
  font-size: var(--text-ui);
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.cook-mode__counter:focus {
  outline: none;
}

.cook-mode .cook-mode__step-title {
  margin: 0;
  font-size: clamp(20px, 1rem + 1vw, 26px);
}

.cook-mode .cook-mode__text {
  margin: 0;
  font-size: clamp(22px, 1.2rem + 1.5vw, 34px);
  line-height: 1.45;
  white-space: pre-line;
  overflow-wrap: anywhere;
  transition: color 200ms var(--ease);
}

.cook-mode__step.is-done .cook-mode__text {
  color: var(--muted);
}

.cook-mode__done {
  align-self: flex-start;
}

.cook-mode__done.is-done {
  border-color: var(--primary);
  background: var(--selection);
  color: var(--primary-strong);
}

.cook-mode__panel {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1;
  max-height: 65%;
  padding: 16px max(16px, env(safe-area-inset-right)) 16px max(16px, env(safe-area-inset-left));
  overflow-y: auto;
  overscroll-behavior: contain;
  border-top: 1px solid var(--border);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background: var(--surface);
  box-shadow: var(--shadow-lg);
}

.cook-mode .cook-mode__panel h3 {
  margin: 0 0 4px;
  font-size: var(--text-lg);
}

.cook-mode__panel .cook__section {
  margin: 12px 0 4px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.cook-mode__nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  padding: 12px max(16px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  border-top: 1px solid var(--border);
  background: var(--surface);
}

.cook-mode__nav .button {
  min-height: 56px;
  font-size: var(--text-lg);
}

@media (min-width: 860px) {
  .cook-mode--panel .cook-mode__body {
    grid-template-columns: minmax(0, 1fr) 360px;
  }

  .cook-mode__panel {
    position: static;
    max-height: none;
    border-top: 0;
    border-left: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
  }

  .cook-mode__nav {
    grid-template-columns: minmax(0, 240px) minmax(0, 240px);
    justify-content: center;
  }
}

/* De stap staat midden in het vlak met marges in plaats van justify-content: center. Is de stap met zijn ingrediënten en
   timers hoger dan het vlak, dan scrolt alles, ook de bovenkant (met center viel die buiten de scroll; issue #309). */
.cook-mode__stage > :first-child {
  margin-top: auto;
}

.cook-mode__stage > :last-child {
  margin-bottom: auto;
}

/* ---- Ingrediënten bij een stap (issue #309). In de lijst met stappen kort onder de tekst, in de kookmodus met vinkjes. */
.cook .cook-step__uses {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 0;
  max-width: 68ch;
  margin: 8px 0 0;
  color: var(--muted);
  font-size: var(--text-md);
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.cook-step__use b {
  color: var(--text);
  font-weight: 700;
}

.cook-mode__uses {
  display: grid;
  gap: 4px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
}

.cook-mode__uses-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
}

.cook-mode .cook-mode__uses-title {
  margin: 0;
  font-size: var(--text-base);
}

.cook-mode__auto {
  color: var(--muted);
  font-size: var(--text-sm);
}

.cook-mode__link {
  min-height: 40px;
  margin-left: auto;
  padding: 0 12px;
  font-size: var(--text-md);
}

.cook-mode__uses-none {
  margin: 0;
}

.cook-mode__uses-list .cook-ingredient label {
  padding: 8px 4px;
  font-size: var(--text-lg);
}

.cook-link fieldset {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.cook-link legend {
  margin-bottom: 4px;
  font-weight: 700;
}

.cook-link__items {
  display: grid;
}

.cook-link__section {
  margin: 10px 0 2px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.cook-link__item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-height: 44px;
  padding: 10px 4px;
  font-size: var(--text-base);
  line-height: 1.45;
  overflow-wrap: anywhere;
  cursor: pointer;
}

.cook-link__item input {
  flex: none;
  width: 22px;
  height: 22px;
  margin: 1px 0 0;
  accent-color: var(--primary);
}

.cook-link__item + .cook-link__item {
  border-top: 1px solid var(--border);
}

.cook-link__hint {
  margin: 8px 0;
  font-size: var(--text-sm);
}

.cook-link__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* ---- Timers. De knopjes onder de stap, en het formulier voor een eigen tijd. */
.cook-mode__timer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.cook-mode__timer {
  min-height: 44px;
  padding: 0 14px;
  font-variant-numeric: tabular-nums;
}

.cook-timer-new {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.cook-timer-new input {
  width: 5.5em;
  min-height: 44px;
  font-size: var(--text-base); /* iOS zoomt niet in bij 16px */
  font-variant-numeric: tabular-nums;
}

/* De zwevende timers: rechtsonder, smal, boven de menubalk of in de kookmodus boven Vorige en Volgende. Een timer die
   afgaat is rood en pulseert; in te klappen tot de kop met het aantal. */
.cook-timers {
  position: fixed;
  z-index: 61;
  right: max(12px, env(safe-area-inset-right));
  bottom: max(16px, env(safe-area-inset-bottom));
  display: grid;
  justify-items: end;
  gap: 6px;
  width: min(300px, calc(100vw - 24px));
  pointer-events: none;
}

.cook-timers.cook-timers--cook-mode {
  position: absolute;
  bottom: calc(88px + max(12px, env(safe-area-inset-bottom)));
}

.cook-timers > * {
  pointer-events: auto;
}

.cook-timers__toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-md);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
}

.cook-timers .mdi {
  width: 18px;
  height: 18px;
  fill: currentColor;
  flex: none;
}

.cook-timers__toggle[aria-expanded="true"] .cook-timers__chevron {
  transform: rotate(180deg);
}

.cook-timers__list {
  display: grid;
  gap: 6px;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

.cook-timer {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 2px 2px 2px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-md);
}

.cook-timer__info {
  display: grid;
  flex: 1;
  min-width: 0;
}

.cook-timer__name {
  overflow: hidden;
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cook-timer__clock {
  font-size: var(--text-lg);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.cook-timers .cook-timer__button {
  width: 44px;
  height: 44px;
  padding: 0;
  border-color: transparent;
  background: transparent;
}

.cook-timers__next {
  font-variant-numeric: tabular-nums;
}

.cook-timer.is-paused .cook-timer__clock {
  color: var(--muted);
}

.cook-timer.is-ringing {
  border-color: var(--danger-border);
  background: var(--danger-bg);
  color: var(--danger);
  animation: cook-timer-ring 1s ease-in-out infinite;
}

.cook-timer.is-ringing .cook-timer__name {
  color: var(--danger);
}

@keyframes cook-timer-ring {
  50% {
    box-shadow: 0 0 0 6px var(--danger-border);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cook__meter i,
  .cook-step,
  .cook-step__toggle,
  .cook-ingredient__text,
  .cook .cook-step__text,
  .cook-mode .cook-mode__text {
    transition: none;
  }

  .cook-timer.is-ringing {
    animation: none;
  }
}

/* De weekplanner: elke dag een kaart. Een lege dag heeft onderaan een rustige knop om een maaltijd toe te voegen, een dag met
   maaltijden een kleine "+" in de kop. De kaart is een container: is hij smal (vier of meer dagen naast elkaar), dan staat de
   foto boven de tekst, zodat de titel de hele breedte krijgt. */
.day-card {
  display: flex;
  flex-direction: column;
  container-type: inline-size;
}

.day-card__head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
}

/* De datum blijft heel; past "Vandaag" er niet naast, dan schuift het label naar de regel eronder. */
.day-card__head h3 {
  flex: 1;
  flex-wrap: wrap;
  row-gap: 4px;
  min-width: 0;
  margin: 0;
  white-space: nowrap;
}

.day-card > .meal:last-child {
  margin-bottom: 0;
}

@container (max-width: 279px) {
  .meal--with-image:not(.meal--planned),
  .meal--with-image .meal__open {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }

  .meal--with-image .meal__open {
    padding-right: 8px;
  }

  .meal--with-image .meal__image {
    width: 100%;
    height: auto;
    aspect-ratio: 2 / 1;
  }

  /* Het potlood staat dan op de foto: een eigen vlakje, zodat het op elke foto leesbaar blijft. */
  .meal--with-image .meal__edit {
    top: 10px;
    right: 10px;
    background: var(--surface);
    box-shadow: var(--shadow-xs);
  }
}

.day-card__add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  min-height: var(--control-height);
  margin-top: auto;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: var(--text-md);
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s var(--ease), background-color 0.15s var(--ease), color 0.15s var(--ease);
}


.day-card__add:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.day-card__add svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

/* De "+" in de kop: even groot als het potlood eronder en met het midden op dezelfde lijn; de negatieve marges houden de kop
   even hoog als zonder knop. */
.day-card__add--compact {
  flex: none;
  width: 36px;
  min-height: 0;
  height: 36px;
  margin: -10px -6px -10px 0;
  border: 0;
  color: var(--primary);
}

.day-card__add--compact svg {
  width: 22px;
  height: 22px;
}

/* De plan-dialoog: dag en maaltijd naast elkaar, een segmentbediening voor recept of notitie en een lijst recepten uit Mealie. */
.plan-dialog {
  width: min(560px, calc(100vw - 32px));
}

.plan-dialog h3 {
  margin: 0;
}

.plan-dialog__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.plan-dialog__part {
  display: grid;
  gap: 12px;
}

.plan-recipe-search {
  display: flex;
  gap: 8px;
}

.plan-recipe-search .input {
  flex: 1;
  min-width: 0;
}

.plan-recipe-search .mdi,
.plan-dialog__actions .mdi {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.plan-recipe-results {
  display: grid;
  gap: 4px;
  max-height: min(320px, 40vh);
  margin: 0;
  padding: 0;
  overflow: auto;
  list-style: none;
}

.plan-recipe-results:empty {
  display: none;
}

.plan-recipe {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 4px 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--text);
  font: inherit;
  text-align: left;
}

button.plan-recipe {
  cursor: pointer;
}

button.plan-recipe:focus-visible {
  border-color: var(--border);
  background: var(--selection);
}

button.plan-recipe:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

.plan-recipe img,
.plan-recipe__placeholder {
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-control);
  object-fit: cover;
  background: var(--surface-muted);
}

.plan-recipe__placeholder {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
}

.plan-recipe__placeholder svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.plan-recipe__text {
  display: grid;
  min-width: 0;
}

.plan-recipe__text strong {
  overflow-wrap: break-word;
}

.plan-recipe__text small {
  color: var(--muted);
  font-size: var(--text-sm);
}

.plan-recipe-chosen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 12px;
  padding: 4px 0;
}

.plan-recipe--chosen {
  flex: 1;
  width: auto;
  min-width: 200px;
  padding: 0;
}

.plan-recipe-chosen[hidden],
.plan-dialog [hidden] {
  display: none;
}

.plan-dialog .textarea {
  margin: 0;
}

/* Oplichten alleen met een muis: op een telefoon blijft een hover na een tik anders hangen. */
@media (hover: hover) {
  .meal--planned:hover,
  button.plan-recipe:hover {
    border-color: var(--border);
    background: var(--selection);
  }

  .meal__edit:hover {
    background: var(--surface);
    color: var(--primary-strong);
  }

  .day-card__add:hover {
    border-color: var(--primary);
    background: var(--selection);
    color: var(--primary-strong);
  }
}

.plan-dialog__delete {
  margin-right: auto;
  color: var(--danger);
}

/* Inplannen in een melding na een import: een link-knop midden in de tekst. */
.link-button--inline {
  min-height: 0;
  padding: 0;
  margin-left: 4px;
}

@media (max-width: 640px) {
  .plan-dialog__row {
    grid-template-columns: 1fr;
  }

  .plan-recipe-search {
    flex-wrap: wrap;
  }

  .plan-recipe-search .button {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .day-card__add,
  .meal--planned,
  .meal__edit {
    transition: none;
  }
}

/* Winkels > Albert Heijn > Weekplanner (ah_planner.js): de dagen zoals het weekmenu, zonder potlood. Wat niet meegaat naar
   het weekmenu (eigen recept, product, notitie) heeft een grijs label. De samenvatting van Naar weekmenu houdt haar regels. */
.ah-planner .meal__open {
  padding-right: 8px;
}

.ah-planner__other .meal__type {
  color: var(--muted);
}

.ah-planner__nothing {
  margin: 0;
  font-size: var(--text-sm);
}

#ah-planner-message .message {
  white-space: pre-line;
}

/* Receptkaarten: op een telefoon minstens twee naast elkaar, op een groter scherm zoveel als er passen */
.recipe-grid--compact {
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}

.recipe-grid--compact .recipe-card {
  padding: 12px;
  gap: 10px;
}

/* Ook de knop in de titel wordt op drie regels afgekapt (een knop is een eigen blok); zijn ::after valt daar niet onder, want die
   hoort bij de kaart. Geen automatisch afbreken: dat brak titels per lettergreep af ("Boerenkoolstamp-pot"). */
.recipe-grid--compact .recipe-card h3,
.recipe-grid--compact .recipe-card__open {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
  hyphens: manual;
}

/* De knop zo breed als de kaart, anders neemt hij de breedte van het langste woord aan en knipt de titel dat woord af. */
.recipe-grid--compact .recipe-card__open {
  width: 100%;
}

.recipe-import-result .message {
  margin: 0;
  padding: 8px 10px;
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}

/* AH lijstjes als kaarten naast elkaar */
.list-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
  margin-top: 16px;
}

.list-card {
  position: relative;
  display: flex;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  transition: border-color 0.15s var(--ease), box-shadow 0.2s var(--ease), transform 0.2s var(--ease);
}

@media (hover: hover) {
  .list-card:hover {
    border-color: var(--primary);
    box-shadow: var(--shadow-md);
  }
}

.list-card__open {
  display: block;
  flex: 1;
  min-width: 0;
  min-height: 88px;
  padding: 14px 52px 14px 14px;
  border: 0;
  border-radius: var(--radius-card);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

@media (hover: hover) {
  .list-card__open:hover {
    background: var(--selection);
  }
}

.list-card__open strong {
  display: block;
  color: var(--primary);
  font-size: var(--text-base);
  line-height: 1.3;
  overflow-wrap: break-word;
  hyphens: auto;
}

.list-card__open small {
  display: block;
  margin-top: 4px;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.35;
}

.list-card .list-card__hit {
  color: var(--primary-strong);
  font-weight: 600;
}

.list-card__sync {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 40px;
  min-height: 40px;
  height: 40px;
}

.icon-button svg,
.list-card__sync svg,
.list-card__action svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
}

/* Een ingelezen oude bestelling (uit je bevestigingsmails): een archiefdoos voor de datum, en de prullenbak waar bij een lijstje
   het synchroniseer-icoon staat. */
.list-card__action {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 40px;
  min-height: 40px;
  height: 40px;
}

.list-card__badge {
  display: inline-flex;
  vertical-align: -3px;
  margin-right: 6px;
  color: var(--muted);
}

.list-card__badge svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

@media (hover: hover) {
  .list-card__action:hover:not(:disabled) {
    color: var(--danger);
  }
}

/* Oude aankopen importeren bij Bestellingen: de knop met dezelfde archiefdoos als op de kaarten. */
.orders-import {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.orders-import .mdi {
  flex: none;
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.icon-button.is-busy svg {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* Zolang de aanbiedingen van een winkel laden: een draaiend icoon met tekst, op de plek van het raster. */
.offers-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 160px;
  color: var(--muted);
}

.offers-loading[hidden] {
  display: none;
}

.offers-loading__icon {
  width: 28px;
  height: 28px;
  flex: none;
  fill: currentColor;
  animation: spin 1s linear infinite;
}

.list-header {
  display: flex;
  align-items: center;
  gap: 12px;
}

.list-header h2 {
  flex: 1;
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere;
}

.list-header .icon-button,
.list-header .button {
  flex: none;
}

.list-header__actions {
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
}

.list-cart {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.list-cart svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
}

.icon-button:disabled {
  cursor: not-allowed;
  opacity: 0.45;
}

@media (max-width: 640px) {
  .recipe-grid--compact,
  .list-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }

  .recipe-grid--compact .recipe-card h3 {
    font-size: var(--text-md);
  }

  .list-header {
    flex-wrap: wrap;
  }

  .list-header h2 {
    flex: 1 1 0;
  }

  .list-header__actions {
    flex: 1 1 100%;
  }

  .list-header__actions .list-cart {
    flex: 1;
    justify-content: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .icon-button.is-busy svg {
    animation: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .offers-loading__icon {
    animation: none;
  }
}

/* Hetzelfde voor het icoon bij een regel van de controlelijst die nog gezocht wordt. */
@media (prefers-reduced-motion: reduce) {
  .review-pending__icon {
    animation: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  #offers-ai-run .ai-run__icon {
    animation: none;
  }
}

/* Inloggen: het wachtwoord- en MFA-formulier op de inlogpagina */
.auth-card .auth-form > .button,
.auth-card .auth-form > .link-button {
  width: 100%;
}

.auth-or {
  margin: 14px 0 0;
  text-align: center;
}

a.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

.link-button {
  min-height: var(--control-height);
  border: 0;
  background: none;
  color: var(--primary);
  font: inherit;
  font-size: var(--text-md);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

@media (hover: hover) {
  .link-button:hover {
    color: var(--primary-strong);
  }
}

.check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 28px;
  font-size: var(--text-ui);
  line-height: 1.4;
}

.check input {
  flex: none;
  width: 20px;
  height: 20px;
  margin: 1px 0 0;
  accent-color: var(--primary);
}

/* Installatiehulp (eerste start) */
body.has-onboarding {
  overflow: hidden;
}

.onboarding {
  position: fixed;
  inset: 0;
  z-index: 100;
  overflow-y: auto;
  padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
    max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  background: radial-gradient(900px 420px at 50% -80px, var(--page-glow), transparent 72%), var(--bg);
}

.onboarding[hidden] {
  display: none;
}

.onboarding__card {
  width: min(680px, 100%);
  margin: 0 auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  padding: 28px;
  animation: rise-in 0.4s var(--ease) both;
}

@media (prefers-reduced-motion: reduce) {
  .onboarding__card {
    animation: none;
  }
}

.onboarding__head {
  display: flex;
  align-items: center;
  gap: 14px;
}

.onboarding__head h2 {
  margin: 0;
  font-size: var(--text-2xl);
  line-height: 1.2;
}

.onboarding__head h2:focus {
  outline: none;
}

.onboarding__eyebrow {
  margin: 0 0 2px;
  color: var(--primary);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.ob-progress {
  display: flex;
  gap: 6px;
  margin: 20px 0 8px;
  padding: 0;
  list-style: none;
}

.ob-progress li {
  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  min-width: 0;
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 600;
  text-align: center;
}

.ob-progress__dot {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border: 2px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  font-size: var(--text-sm);
  transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease);
}

/* Een lijn tussen de stappen: grijs voor wat nog komt, groen voor wat klaar is. */
.ob-progress li:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 13px;
  left: calc(50% + 18px);
  right: calc(-50% + 12px);
  height: 2px;
  border-radius: 2px;
  background: var(--border);
}

.ob-progress li.is-done:not(:last-child)::after {
  background: var(--primary);
}

.ob-progress li.is-current {
  color: var(--primary-strong);
}

.ob-progress li.is-current .ob-progress__dot {
  border-color: var(--primary);
  background: var(--primary);
  box-shadow: 0 0 0 4px var(--ring);
  color: var(--on-primary);
}

.ob-progress li.is-done .ob-progress__dot {
  border-color: var(--primary);
  background: var(--selection);
  color: var(--primary-strong);
}

.ob-progress__label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#ob-body {
  margin-top: 12px;
  line-height: 1.55;
}

#ob-body p {
  margin: 12px 0;
}

.ob-env {
  padding: 10px 12px;
  border-radius: var(--radius-control);
  background: var(--surface-muted);
  font-size: var(--text-md);
  overflow-wrap: anywhere;
}

.ob-note {
  margin: 14px 0;
}

.ob-options {
  display: grid;
  gap: 12px;
  margin: 14px 0;
}

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

.ob-option--recommended {
  border-color: var(--primary);
  background: var(--selection);
}

.ob-option h3,
.ob-subtitle {
  margin: 0 0 6px;
  font-size: var(--text-lg);
}

.ob-subtitle {
  margin-top: 20px;
}

.ob-option p {
  margin: 0 0 12px;
  font-size: var(--text-ui);
}

.ob-badge {
  display: inline-block;
  margin-bottom: 8px;
  border-radius: var(--radius-pill);
  background: var(--primary);
  padding: 2px 10px;
  color: var(--on-primary);
  font-size: var(--text-xs);
  font-weight: 700;
}

.ob-skip {
  text-align: center;
}

.ob-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 20px;
}

.ob-actions--wrap {
  flex-wrap: wrap;
  justify-content: flex-start;
}

.ob-checklist {
  display: grid;
  gap: 10px;
  margin: 16px 0;
  padding: 0;
  list-style: none;
}

.ob-checklist li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  padding: 10px 12px;
  overflow-wrap: anywhere;
}

.ob-checklist .is-ok {
  background: var(--selection);
  border-color: var(--primary);
}

.ob-check {
  flex: none;
  width: 20px;
  color: var(--primary-strong);
  font-weight: 700;
  text-align: center;
}

.qr-box {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 18px;
  align-items: start;
  margin: 16px 0;
}

.qr {
  width: 200px;
  height: 200px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  /* Een QR-code scant het best zwart op wit, ook in een donker thema */
  background: #fff;
  padding: 4px;
}

.qr svg {
  display: block;
  width: 100%;
  height: 100%;
}

.qr-help p {
  margin: 8px 0;
}

.qr-secret {
  display: inline-block;
  letter-spacing: 0.08em;
  user-select: all;
}

.recovery-codes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin: 14px 0;
  padding: 0;
  list-style: none;
}

.recovery-codes li {
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface-muted);
  padding: 8px 10px;
  text-align: center;
}

.recovery-codes code {
  border: 0;
  background: none;
  font-size: var(--text-ui);
  letter-spacing: 0.04em;
  user-select: all;
}

@media (max-width: 640px) {
  .onboarding__card {
    padding: 18px 16px;
  }

  .onboarding__head h2 {
    font-size: var(--text-xl);
  }

  .ob-progress li:not(.is-current) .ob-progress__label {
    display: none;
  }

  .qr-box {
    grid-template-columns: 1fr;
    justify-items: center;
  }

  .qr-help {
    width: 100%;
  }

  .ob-actions {
    flex-direction: column-reverse;
    align-items: stretch;
  }

  .ob-actions--wrap {
    flex-direction: column;
  }

  .ob-actions > span {
    display: none;
  }

  .recovery-codes {
    grid-template-columns: 1fr 1fr;
  }
}

/* Inklapbare blokken (Profiel > Beveiliging) */
.fold__title {
  margin: 0;
}

.fold__toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: var(--control-height);
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.fold__toggle:disabled {
  cursor: default;
}

.fold__toggle .fold__chevron {
  flex: none;
  width: 24px;
  height: 24px;
  margin-left: auto;
  fill: var(--muted);
  transition: transform 0.15s ease;
}

.fold__toggle[aria-expanded="true"] .fold__chevron {
  transform: rotate(180deg);
}

.fold__toggle.is-static .fold__chevron {
  display: none;
}

.fold__badge {
  border-radius: var(--radius-pill);
  background: var(--selection);
  padding: 2px 10px;
  color: var(--primary-strong);
  font-size: var(--text-xs);
  font-weight: 700;
}

.fold__body[hidden] {
  display: none;
}

.link-statuses {
  max-width: 680px; /* even breed als de blokken eronder */
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 16px;
}

.link-statuses .message {
  margin: 8px 0;
}

.link-statuses {
  margin-bottom: 8px;
}

.link-status {
  display: flex;
  align-items: center;
  gap: 8px;
}

.link-status__icon {
  display: none;
  flex: none;
  width: 22px;
  height: 22px;
  fill: currentColor;
}

.link-status--working {
  border-color: var(--success-text);
  font-weight: 600;
}

/* Op een klein scherm staan twee meldingen naast elkaar: alleen het pictogram en de naam; de tekst blijft voor schermlezers. */
@media (max-width: 640px) {
  .link-status__icon {
    display: block;
  }

  .link-status__text {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .link-status__name {
    font-weight: 600;
  }
}

.fold__section {
  margin-top: 20px;
  border-top: 1px solid var(--border);
  padding-top: 16px;
}

.fold__section h3 {
  margin: 0 0 8px;
}

@media (prefers-reduced-motion: reduce) {
  .fold__toggle .fold__chevron {
    transition: none;
  }
}

/* Over */
.about-version {
  margin: 4px 0 12px;
  font-size: var(--text-ui);
}

.about-version strong {
  margin-left: 6px;
  font-family: var(--font-heading, inherit);
  font-size: var(--text-2xl);
  overflow-wrap: anywhere;
}

.about-group {
  margin: 22px 0 8px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.about-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.about-list li {
  display: grid;
  gap: 2px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 10px 12px;
}

.about-list__head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 8px;
}

.about-list__head a {
  color: var(--primary);
  font-weight: 700;
  overflow-wrap: anywhere;
}

.about-list__version {
  border-radius: var(--radius-pill);
  background: var(--surface-muted);
  padding: 1px 8px;
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 600;
}

.about-list small {
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.4;
}

.about-list .about-list__license {
  font-size: var(--text-xs);
}

.about-repo {
  width: fit-content;
  text-decoration: none;
}

.about-repo svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.about-coffee p {
  margin: 8px 0 14px;
}

.coffee-button svg {
  width: 20px;
  height: 20px;
  margin-right: 8px;
  fill: currentColor;
}

/* Taalkiezer (NL en EN) en de knop voor donker en licht: alleen nog op de inlogpagina, de uitnodiging en in de installatiehulp.
   In de app staan taal en thema in het menu onder je naam en bij Instellingen, Voorkeuren (sinds 4.7.0). De taal is tekst, geen
   vlag: een vlag staat voor een land, niet voor een taal. */
.switches {
  display: flex;
  flex: none;
  align-items: center;
  gap: 2px;
  margin-left: auto;
}

.lang-switch {
  display: flex;
  flex: none;
  gap: 2px;
}

/* Knop voor donker en licht, naast de taalkiezer: de maan in het lichte thema, de zon in het donkere */
.theme-toggle {
  display: grid;
  place-items: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-control);
  background: none;
  color: var(--muted);
  cursor: pointer;
}

@media (hover: hover) {
  .theme-toggle:hover {
    color: var(--primary);
  }
}

.theme-toggle__icon {
  grid-area: 1 / 1;
  width: 24px;
  height: 24px;
}

.theme-toggle__icon--sun,
:root[data-theme="dark"] .theme-toggle__icon--moon {
  display: none;
}

:root[data-theme="dark"] .theme-toggle__icon--sun {
  display: block;
}

.lang-switch__button {
  display: grid;
  place-items: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: color 0.15s var(--ease), background-color 0.15s var(--ease), border-color 0.15s var(--ease);
}

@media (hover: hover) {
  .lang-switch__button:hover {
    color: var(--primary-strong);
  }
}

/* De gekozen taal: het selectievlak met zijn rand, zoals een actief segment; de kleur is niet het enige signaal (aria-pressed). */
.lang-switch__button.is-active {
  border-color: var(--selection-border);
  background: var(--selection);
  color: var(--primary-strong);
}

.auth-card .switches {
  margin: -8px -8px 4px 0;
  justify-content: flex-end;
}

.onboarding__head .switches {
  align-self: flex-start;
  margin-right: -8px;
  margin-top: -6px;
}

@media (prefers-reduced-motion: reduce) {
  .lang-switch__button {
    transition: none;
  }
}

/* De geinstalleerde app (html.is-standalone, zie de kop van de pagina). De pagina veert niet mee als je bovenaan naar
   beneden sleept (of onderaan naar boven): zonder die rubberband blijft de titelbalk aan de
   bovenkant plakken, en Android ververst de pagina niet onder je duim. Scrollen gaat gewoon; knijp- en dubbeltikzoom niet,
   zoals in een native app (de viewport zet het script in de kop). Lijsten en vensters met een eigen scroll houden hun
   overscroll-behavior: contain. In de browser verandert er niets: daar blijven zoomen en verversen werken. */
html.is-standalone,
html.is-standalone body {
  overscroll-behavior: none;
  touch-action: pan-x pan-y;
}

/* Onderste menubalk: een zwevende glazen balk zoals een native tabbalk op iOS.
   Alleen in de geinstalleerde app (html.has-tabbar, zie de kop van de pagina) op een klein scherm. Twee uiterlijken van dezelfde
   tabs, gekozen met data-nav op <html> (Instellingen, Weergave, en shared/guidelines/navigation-bar.md van App-Guidance):
   iOS-achtig (zwevend glas, de basis hieronder) en Android-achtig (Material: over de volle breedte, een pil achter het actieve
   icoon). --tabbar-h is de enige hoogte die de rest van de pagina kent, zodat er niets onder de ene of de andere balk valt.
   Het glas: de dekking en vervaging zet static/theme.js als gewone waarden; de standaard hier is die van schuifstand 60. */
:root {
  --tabbar-h: 82px;
  --nav-alpha: 0.49;
  --nav-blur: 28px;
}

/* Buiten de balk is er één icoon per tab: het gevulde. In de balk krijgt een tab die niet actief is het omlijnde, als MDI dat heeft. */
.tab-icon--outline {
  display: none;
}

@media (max-width: 640px) {
  html.has-tabbar .shell {
    padding-bottom: calc(var(--tabbar-h) + 30px + env(safe-area-inset-bottom));
  }

  /* De balk van In bulk importeren boven de menubalk. */
  html.has-tabbar .bulk-bar {
    bottom: calc(var(--tabbar-h) + 14px + env(safe-area-inset-bottom));
  }

  /* Korte meldingen (toast) boven de menubalk. */
  html.has-tabbar .toasts {
    bottom: calc(var(--tabbar-h) + 22px + env(safe-area-inset-bottom));
  }

  /* De kooktimers buiten de kookmodus ook boven de menubalk. */
  html.has-tabbar .cook-timers:not(.cook-timers--cook-mode) {
    bottom: calc(var(--tabbar-h) + 22px + env(safe-area-inset-bottom));
  }

  /* En die met Toevoegen en Annuleren onder de controlelijst van het mandje. */
  html.has-tabbar .cart-review__actions {
    bottom: calc(var(--tabbar-h) + 14px + env(safe-area-inset-bottom));
  }

  html.has-tabbar .tabs {
    position: fixed;
    z-index: 20;
    left: max(12px, env(safe-area-inset-left));
    right: max(12px, env(safe-area-inset-right));
    bottom: max(12px, env(safe-area-inset-bottom));
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 2px;
    width: auto;
    margin: 0;
    padding: 6px;
    border: 1px solid var(--tabbar-border);
    border-radius: 32px;
    background: var(--tabbar-solid);
    box-shadow:
      0 10px 32px rgba(var(--shadow-ink), 0.16),
      0 0 0 0.5px rgba(var(--shadow-ink), 0.1),
      inset 0 1px 0 var(--tabbar-border);
  }

  /* Alleen gewone waarden in rgba() en blur(): met een berekening erin laat Safari het glas weg. */
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    html.has-tabbar .tabs {
      background: rgba(var(--tabbar-rgb), var(--nav-alpha));
      -webkit-backdrop-filter: saturate(180%) blur(var(--nav-blur));
      backdrop-filter: saturate(180%) blur(var(--nav-blur));
    }
  }

  html.has-tabbar .tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 0;
    min-height: 56px;
    padding: 6px 1px;
    border-radius: 26px;
    color: var(--tabbar-ink);
    font-size: 10px; /* label onder het icoon van de menubalk, zoals iOS en Android: buiten de typeschaal */
    font-weight: 600;
    line-height: 1.1;
    transition: background-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
    -webkit-tap-highlight-color: transparent;
    -webkit-touch-callout: none;
    user-select: none;
    -webkit-user-select: none;
  }

  html.has-tabbar .tab-icon {
    width: 24px;
    height: 24px;
  }

  /* Gevuld als de tab actief is, omlijnd als hij dat niet is: zo doen iOS en Material het, en het is niet alleen een kleur. */
  html.has-tabbar .tab:not(.is-active) > .tab-icon:has(+ .tab-icon--outline) {
    display: none;
  }

  html.has-tabbar .tab:not(.is-active) > .tab-icon--outline {
    display: block;
  }

  /* Het lange label is in de balk niet te zien, maar blijft de naam van de tab voor een schermlezer: het korte label eronder
     heeft aria-hidden. Tot 4.10.4 stond hier display: none en had een tab in de balk geen naam (zoals .visually-hidden). */
  html.has-tabbar .tab-text {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }

  html.has-tabbar .tab-short {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  @media (hover: hover) {
    html.has-tabbar .tab:hover:not(.is-active) {
      background: transparent;
      color: var(--tabbar-ink);
    }
  }

  html.has-tabbar .tab:active {
    transform: scale(0.95);
  }

  html.has-tabbar .tab.is-active {
    background: var(--tabbar-tint);
    color: var(--tabbar-ink-active);
    box-shadow: none;
  }

  html.has-tabbar .tab.is-active > svg {
    color: inherit;
  }

  html.has-tabbar .tab:focus-visible {
    outline-offset: -3px;
  }

  /* Android-achtig: de navigatiebalk van Material 3. Over de volle breedte op de rand, een vlak dat naar de accentkleur neigt
     (geen glas), en een pil van 64 x 32 achter het actieve icoon met een vet label eronder. */
  html.has-tabbar[data-nav="android"] {
    --tabbar-h: 84px;
  }

  html.has-tabbar[data-nav="android"] .tabs {
    left: 0;
    right: 0;
    bottom: 0;
    gap: 0;
    padding: 12px max(8px, env(safe-area-inset-right)) calc(16px + env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left));
    border: 0;
    border-radius: 0;
    background: color-mix(in srgb, var(--surface) 90%, var(--primary));
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: 0 -1px 0 var(--border), 0 -3px 14px rgba(var(--shadow-ink), 0.08);
  }

  html.has-tabbar[data-nav="android"] .tab {
    gap: 4px;
    padding: 0;
    border-radius: 0;
    background: none;
    color: var(--muted);
    font-size: var(--text-xs);
    font-weight: 500;
  }

  html.has-tabbar[data-nav="android"] .tab-icon {
    box-sizing: content-box;
    padding: 4px 20px;
    border-radius: var(--radius-pill);
    transition: background-color 0.2s ease;
  }

  @media (hover: hover) {
    html.has-tabbar[data-nav="android"] .tab:hover:not(.is-active) {
      color: var(--muted);
    }
  }

  html.has-tabbar[data-nav="android"] .tab:active {
    transform: none;
  }

  html.has-tabbar[data-nav="android"] .tab:active .tab-icon {
    background: var(--selection);
  }

  html.has-tabbar[data-nav="android"] .tab.is-active {
    background: none;
    color: var(--text);
    font-weight: 700;
  }

  html.has-tabbar[data-nav="android"] .tab.is-active > .tab-icon {
    background: color-mix(in srgb, var(--primary) 26%, transparent);
    color: var(--primary-strong);
  }
}

/* Minder doorzichtigheid gevraagd: een dichte balk, wat de schuif ook zegt. De Android-achtige balk is al dicht. */
@media (max-width: 640px) and (prefers-reduced-transparency: reduce) {
  html.has-tabbar:not([data-nav="android"]) .tabs {
    background: var(--tabbar-solid);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

@media (max-width: 640px) and (prefers-reduced-motion: reduce) {
  html.has-tabbar .tab,
  html.has-tabbar .tab-icon {
    transition: none;
  }

  html.has-tabbar .tab:active {
    transform: none;
  }
}

/* Gebruikers (Instellingen > Gebruikers) en regels die alleen de beheerder aangaan */
.user-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  background: var(--selection);
  color: var(--primary-strong);
  font-size: var(--text-xs);
  font-weight: 600;
}

#invite-result .form-row {
  margin: 8px 0;
}

#invite-result .input {
  flex: 1;
  min-width: 0;
}

/* Toestemmingsscherm voor AI-apps (templates/oauth.html) */
.oauth-page {
  display: flex;
  min-height: 100vh;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

.oauth-card {
  width: 100%;
  max-width: 480px;
  padding: 24px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
}

.oauth-card h1 {
  margin: 16px 0 8px;
  font-size: var(--text-2xl);
}

.oauth-card h2 {
  margin: 20px 0 6px;
  font-size: var(--text-base);
}

.oauth-list {
  margin: 0 0 12px;
  padding-left: 20px;
}

.oauth-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 20px;
}

/* AI-apps (Profiel > AI-apps) */
.ai-guide {
  margin: 8px 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
}

.ai-guide summary {
  cursor: pointer;
  font-weight: 600;
}

.ai-code {
  margin: 8px 0 0;
  padding: 10px 12px;
  overflow-x: auto;
  border-radius: var(--radius-control);
  background: var(--surface-muted);
  font-size: var(--text-sm);
}

.ai-tools {
  margin: 0;
  padding-left: 20px;
}

.ai-tool-off {
  opacity: 0.6;
}

#profile-ai .form-row {
  flex-wrap: wrap;
  width: 100%;
}

#profile-ai .form-row .input {
  flex: 1 1 220px;
  min-width: 0;
}

.switch-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 4px 0;
  font-weight: 600;
}

.switch-row input {
  width: 20px;
  height: 20px;
  accent-color: var(--primary);
}

/* Kassabon: een smalle strook papier zoals uit de kassa, in het midden, ook in de donkere modus licht. Het vak eromheen
   (#ah-order-items) scrolt op een breed scherm zelf (order-items--fit, fitReceiptBox in orders.js, voor elke weergave van de bestelpagina), zodat de pagina niet schuift. */
.order-items--fit {
  overflow-y: auto;
}

.receipt {
  --paper: #f7f4ea;
  --ink: #202020;
  position: relative;
  box-sizing: border-box;
  width: min(100%, 400px);
  margin: 12px auto 28px;
  padding: 22px 18px 20px;
  background: var(--paper);
  color: var(--ink);
  font-family: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size: var(--text-sm);
  line-height: 1.45;
  filter: drop-shadow(0 2px 5px rgb(0 0 0 / 0.22));
}

/* Bij zoeken: de gevonden regel op papier (de andere weergaven laten alleen de gevonden regels zien). */
.receipt__hit {
  background: rgb(242 207 69 / 0.45);
}

/* Onder de producten van een bon: de bonusregels met het bedrag. */
.receipt-summary {
  display: grid;
  gap: 2px;
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
  color: var(--muted);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}

.receipt-summary__title {
  color: var(--text);
  font-weight: 600;
}

.receipt::before,
.receipt::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 9px;
  background: linear-gradient(135deg, var(--paper) 50%, transparent 50%) 0 0 / 12px 12px repeat-x,
    linear-gradient(225deg, var(--paper) 50%, transparent 50%) 0 0 / 12px 12px repeat-x;
}

.receipt::before {
  top: -9px;
  transform: scaleY(-1);
}

.receipt::after {
  bottom: -9px;
}

.receipt__head {
  display: grid;
  gap: 2px;
  margin-bottom: 14px;
  text-align: center;
}

.receipt__store {
  font-size: var(--text-lg);
  letter-spacing: 0.18em;
}

.receipt__row {
  display: grid;
  grid-template-columns: 5.5ch minmax(0, 1fr) 8ch 9ch;
  gap: 0 8px;
}

@media (min-width: 1200px) {
  .receipt {
    padding: 28px 24px 26px;
  }
}

.receipt__row > span {
  overflow-wrap: anywhere;
}

.receipt__row > span:nth-child(3),
.receipt__row > span:nth-child(4) {
  text-align: right;
}

.receipt__cols {
  padding-bottom: 4px;
  margin-bottom: 4px;
  border-bottom: 1px dashed var(--ink);
  font-size: 11px; /* kolomkoppen van de nagemaakte kassabon (monospace): buiten de typeschaal */
}

.receipt__line .receipt__c1 {
  text-transform: uppercase;
}

.receipt__bonus {
  font-style: italic;
}

/* Je eigen koppeling (#238, product_links.js): de knop rechts in een productkaart van een bon of ingelezen bestelling, een klein
   icoon achter een regel op het bonnetje, en het venster Koppelen met de producten van de winkel. */
.product-card .product-link {
  flex: none;
  width: 36px;
  min-height: 36px;
  height: 36px;
  margin-left: auto;
}

.product-link svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.product-link--todo {
  border-color: var(--primary);
  color: var(--primary);
}

.receipt .product-link,
.cat-line .product-link,
.order-table .product-link {
  width: 24px;
  min-height: 24px;
  height: 24px;
  margin: -2px 0 0 6px;
  border: 0;
  background: transparent;
  box-shadow: none;
  color: inherit;
  vertical-align: middle;
}

.receipt .product-link svg,
.cat-line .product-link svg,
.order-table .product-link svg {
  width: 16px;
  height: 16px;
}

.link-dialog__current {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.link-dialog__search {
  display: flex;
  gap: 8px;
}

.link-dialog__search .input {
  flex: 1;
  min-width: 0;
}

.link-list {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
  max-height: 50vh;
  overflow-y: auto;
}

.link-list:empty {
  display: none;
}

.link-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  padding: 6px 8px;
  background: var(--surface);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.link-item:focus-visible {
  border-color: var(--primary);
  background: var(--selection);
}

@media (hover: hover) {
  .link-item:hover {
    border-color: var(--primary);
    background: var(--selection);
  }
}

.link-item.is-self {
  border-color: var(--primary);
}

.link-item img,
.link-item__photo {
  width: 48px;
  height: 48px;
  flex: none;
  border-radius: var(--radius-control);
  object-fit: contain;
  background: var(--surface);
}

.link-item__photo {
  display: grid;
  place-items: center;
  border: 1px dashed var(--border);
  color: var(--muted);
}

.link-item__photo svg {
  width: 24px;
  height: 24px;
  fill: currentColor;
}

.link-item__body {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.link-item__body strong {
  overflow-wrap: anywhere;
}

.link-item__body small {
  color: var(--muted);
}

.link-dialog__note {
  font-size: var(--text-sm);
}

.receipt__section {
  margin-top: 6px;
  font-weight: 700;
}

.receipt__rule {
  margin: 8px 0;
  border-top: 1px dashed var(--ink);
}

.receipt__total,
.receipt__pay {
  grid-template-columns: minmax(0, 1fr) auto;
}

.receipt__total {
  font-size: var(--text-ui);
  font-weight: 700;
}

.receipt__total > span:nth-child(2),
.receipt__pay > span:nth-child(2) {
  text-align: right;
}

.receipt__total > span:first-child,
.receipt__pay > span:first-child {
  text-align: left;
}

/* Winkels > Bestellingen: de aankopentabel (bestellingen en kassabonnen samen) met de filters erboven. Op een groot scherm
   vult de tabel de rest van het scherm en scrolt hij in zijn eigen vak (fitPurchaseTable in orders.js). */
.purchase-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 20px;
  margin: 0 0 10px;
}

.purchase-filters__check {
  align-items: center;
  min-height: 0;
}

.purchase-filters__amount {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: var(--text-ui);
}

.input--amount {
  width: 6.5em;
}

.purchase-status {
  margin: 0;
  font-size: var(--text-md);
}

/* De balk boven de lijst: links de statusregel, rechts de weergave, het sorteren en de opties. */
.purchase-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  margin: 0 0 8px;
}

.purchase-bar__tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}

/* De menu's rechts in de balk klappen naar links open, anders steken ze buiten het kader (en de pagina) uit. */
.purchase-bar__tools .subtab-menu__list {
  right: 0;
  left: auto;
  transform-origin: top right;
}

.subtab-menu__rule {
  margin: 4px 0;
  border: 0;
  border-top: 1px solid var(--border);
}

.purchase-options {
  min-width: 220px;
}

.purchase-options__title {
  padding: 6px 10px 2px;
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.purchase-options__check {
  padding: 4px 10px;
  min-height: 0;
  font-size: var(--text-md);
}

/* De kleur per soort aankoop: een bolletje in de tabel en bij de vinkjes, een streep op een kaart en in het overzicht. */
.purchase-kind {
  --purchase-kind: var(--muted);
  display: inline-block;
  flex: none;
  background: var(--purchase-kind);
}

.purchase-kind--order {
  --purchase-kind: var(--primary);
}

.purchase-kind--receipt {
  --purchase-kind: var(--lemon);
}

.purchase-kind--imported {
  --purchase-kind: var(--muted);
}

.purchase-kind--dot {
  width: 8px;
  height: 8px;
  margin-right: 6px;
  border-radius: 50%;
  vertical-align: 1px;
}

.purchase-kind--stripe {
  display: block;
}

/* Badges: een afgeronde pil met de kleur in --badge (tekst en rand), een lichte vulling erachter. De tekst staat er altijd. */
.badge {
  --badge: var(--muted);
  display: inline-block;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--badge) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--badge) 45%, transparent);
  color: var(--badge);
  padding: 1px 8px;
  font-size: var(--text-xs);
  font-weight: 700;
  line-height: 1.5;
  white-space: nowrap;
}

.badge--status-delivered {
  --badge: var(--primary);
}

.badge--status-planned {
  --badge: var(--info);
}

.badge--status-imported {
  --badge: var(--muted);
}

/* Geel is decoratief (niet als tekst op wit): de tekst blijft de gewone tekstkleur, de rand en vulling zijn geel. */
.badge--status-receipt {
  --badge: var(--lemon);
  color: var(--warning-text);
}

.badge--saved {
  --badge: var(--warning-text);
  background: transparent;
}

.badge--bonus {
  --badge: var(--danger);
  background: var(--danger-bg);
  box-shadow: inset 0 0 0 1px var(--danger-border);
}

.badge--before {
  --badge: var(--muted);
  background: var(--surface-muted);
  box-shadow: none;
}

/* De bestelpagina (order_views.js): de badges in de kop, het zoekveld met de chips, de categoriesecties, de productkaarten in de
   kleur van hun categorie en de tabel. De kleuren komen uit cat--<id> (--cat-bg, --cat-line), met de donkere varianten daar. */
.order-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 2px 0 6px;
}

.order-filter {
  margin: 0 0 12px;
}

.order-filter .offer-cats {
  margin-top: 10px;
}

.product-card[class*="cat--"] {
  border-color: var(--cat-line);
  background: var(--cat-bg);
}

.product-card__badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin-top: 4px;
}

/* De kortingsbadge van de aanbiedingen in een regel van tekst in plaats van op een plaatje (twee klassen: .offer-badge staat
   verderop en zou anders winnen). */
.offer-badge.offer-badge--inline {
  position: static;
  display: inline-block;
  padding: 2px 6px;
  font-size: var(--text-xs);
  box-shadow: none;
  vertical-align: middle;
}

.product-grid--small {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

.product-grid--large {
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
}

.cat-sections {
  display: grid;
  gap: 12px;
}

.cat-section {
  border: 1px solid var(--cat-line, var(--border));
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}

.cat-section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--cat-line, var(--border));
  border-radius: calc(var(--radius-card) - 1px) calc(var(--radius-card) - 1px) 0 0;
  background: var(--cat-bg);
}

.cat-section__title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: var(--text-ui);
}

.cat-section__count {
  color: var(--muted);
  font-size: var(--text-sm);
}

.cat-section__amount {
  margin-left: auto;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.cat-section__lines {
  margin: 0;
  padding: 0;
  list-style: none;
}

.cat-line {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto 72px;
  align-items: center;
  gap: 10px;
  padding: 6px 12px;
  border-top: 1px solid var(--border);
  font-variant-numeric: tabular-nums;
}

.cat-line:first-child {
  border-top: 0;
}

.cat-line__photo {
  width: 40px;
  height: 40px;
}

.cat-line__photo img {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-control);
  object-fit: contain;
  background: #fff;
  outline: 1px solid rgba(var(--shadow-ink), 0.08);
  outline-offset: -1px;
}

.cat-line__name a {
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
}

@media (hover: hover) {
  .cat-line__name a:hover {
    text-decoration: underline;
  }
}

.cat-line__meta {
  display: block;
  color: var(--muted);
  font-size: var(--text-xs);
}

.cat-line__badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin-top: 3px;
}

.cat-line__qty {
  color: var(--muted);
}

.cat-line__amount {
  font-weight: 600;
  text-align: right;
}

.cat-line__name {
  overflow-wrap: anywhere;
}

/* Op een telefoon: het bedrag boven het aantal, rechts, zodat de naam de breedte houdt. De weergaveknoppen van de bestelpagina
   (vier bij een bon) tonen alleen hun pictogram; de tekst blijft voor een schermlezer. */
@media (max-width: 640px) {
  .cat-line {
    grid-template-columns: 40px minmax(0, 1fr) auto;
    grid-template-areas: "photo body amount" "photo body qty";
    gap: 2px 10px;
    padding: 6px 10px;
  }

  .cat-line__photo {
    grid-area: photo;
  }

  .cat-line__body {
    grid-area: body;
  }

  .cat-line__amount {
    grid-area: amount;
  }

  .cat-line__qty {
    grid-area: qty;
    text-align: right;
    font-size: var(--text-sm);
  }

  [data-view-bar="order"] .segmented__item span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  [data-view-bar="order"] .segmented__item {
    padding: 0;
  }
}

/* De tabel schuift op een telefoon horizontaal in zijn eigen vak, zoals de aankopentabel. */
.order-table-wrap {
  margin-top: 2px;
}

.order-table {
  min-width: 760px;
}

.order-table td small {
  display: block;
  color: var(--muted);
  font-size: var(--text-xs);
}

.order-table__name a {
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
}

.order-table__cat {
  white-space: nowrap;
}

.order-table__cat .offer-chip__dot {
  display: inline-block;
  margin-right: 6px;
  vertical-align: middle;
}

.order-table__sort {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.order-table th[aria-sort] .order-table__sort {
  color: var(--primary);
}

.order-table th[aria-sort="descending"] .order-table__sort::after {
  content: " ↓";
}

.order-table th[aria-sort="ascending"] .order-table__sort::after {
  content: " ↑";
}

/* Kaarten: een raster van kaarten met een fotocollage; de breedte per kaartgrootte, op een telefoon twee naast elkaar. */
.purchase-cards {
  --purchase-card-width: 190px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--purchase-card-width), 1fr));
  gap: 12px;
  overflow: auto;
  padding: 2px;
  overscroll-behavior: contain;
}

.purchase-cards--small {
  --purchase-card-width: 150px;
}

.purchase-cards--medium {
  --purchase-card-width: 190px;
}

.purchase-cards--large {
  --purchase-card-width: 240px;
}

.purchase-cards__empty {
  grid-column: 1 / -1;
  margin: 0;
}

.purchase-card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  content-visibility: auto;
  contain-intrinsic-size: 0 280px;
  transition: transform 0.15s var(--ease), box-shadow 0.15s var(--ease);
}

.purchase-card .purchase-kind--stripe {
  height: 3px;
}

.purchase-card__link {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 2px;
  padding: 8px 10px 10px;
  color: inherit;
  text-decoration: none;
}

.purchase-card__date {
  margin-top: 6px;
  color: var(--primary);
  font-size: var(--text-ui);
  line-height: 1.3;
}

.purchase-card__kind,
.purchase-card__line {
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.35;
}

.purchase-card__names,
.purchase-card__hits {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.purchase-card__hits {
  color: var(--text);
}

.purchase-card__savings {
  color: var(--primary);
  font-weight: 600;
}

.purchase-card__action {
  position: absolute;
  top: 9px;
  right: 6px;
  width: 30px;
  height: 30px;
  min-height: 0;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

@media (hover: hover) {
  .purchase-card:hover {
    box-shadow: var(--shadow-lg);
    transform: translateY(-1px);
  }
}

/* De kaart en de rij knippen hun inhoud af, dus de focusring van de link erin zou wegvallen: de kaart tekent hem zelf. */
.purchase-card:focus-within,
.purchase-overview__row:focus-within {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
}

.purchase-card__link:focus-visible,
.purchase-overview__link:focus-visible {
  outline: none;
}

/* De collage: een vierkant met 1, 2, 3, 4, 5 of 6 foto's; de eerste foto krijgt bij 3 en 5 de linkerkolom. */
.purchase-collage {
  display: grid;
  gap: 2px;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: var(--radius-control);
  background: var(--surface-muted);
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 1fr;
}

.purchase-collage img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #fff;
}

.purchase-collage--1 {
  grid-template-columns: 1fr;
}

.purchase-collage--3 img:first-child,
.purchase-collage--5 img:first-child {
  grid-row: span 2;
}

.purchase-collage--5,
.purchase-collage--6 {
  grid-template-columns: repeat(3, 1fr);
}

.purchase-collage--empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px;
  color: var(--muted);
  text-align: center;
}

.purchase-collage__icon {
  width: 36px;
  height: 36px;
  fill: currentColor;
  opacity: 0.6;
}

.purchase-collage--empty small {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  font-size: var(--text-xs);
}

@media (max-width: 640px) {
  .purchase-cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Overzicht: rijen met een strook foto's links en de details rechts; de streep in de kleur van de soort aan de linkerrand. */
/* Meer aankopen (sinds 4.13.0): de knop onder de lijst, in het midden, zoals Meer bij de aanbiedingen. */
.purchase-more {
  margin: 16px 0 0;
  text-align: center;
}

.purchase-more:has([hidden]) {
  display: none;
}

.purchase-overview {
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow: auto;
  padding: 2px;
  overscroll-behavior: contain;
}

.purchase-overview > p {
  margin: 0;
}

.purchase-overview__row {
  position: relative;
  display: flex;
  flex: none; /* in de kolom van de lijst: anders krimpen 500 rijen samen tot streepjes */
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  content-visibility: auto;
  contain-intrinsic-size: 0 84px;
}

.purchase-overview__row .purchase-kind--stripe {
  width: 3px;
  flex: none;
  align-self: stretch;
}

.purchase-overview__link {
  display: flex;
  flex: 1;
  gap: 12px;
  align-items: center;
  min-width: 0;
  padding: 10px 44px 10px 10px;
  color: inherit;
  text-decoration: none;
}

/* De strook rechts, op de breedte van zes foto's (56 met 4 ertussen): zo begint de tekst links in elke rij op dezelfde plek, of
   een aankoop nu zes foto's, een foto of alleen het icoon van zijn soort heeft. */
.purchase-overview__strip {
  display: flex;
  flex: none;
  gap: 4px;
  align-items: center;
  justify-content: flex-end;
  width: 356px;
  min-height: 56px;
}

.purchase-overview__strip img {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-control);
  object-fit: contain;
  background: #fff;
  outline: 1px solid var(--border);
}

.purchase-overview__icon {
  width: 32px;
  height: 32px;
  margin: 12px;
  fill: var(--muted);
  opacity: 0.6;
}

.purchase-overview__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.purchase-overview__head {
  display: flex;
  gap: 12px;
  justify-content: space-between;
  align-items: baseline;
}

.purchase-overview__head strong {
  color: var(--primary);
  font-size: var(--text-ui);
}

.purchase-overview__amount {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.purchase-overview__meta,
.purchase-overview__names {
  overflow: hidden;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.35;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.purchase-overview__names--hits {
  color: var(--text);
}

.purchase-overview__action {
  position: absolute;
  top: 50%;
  right: 8px;
  width: 30px;
  height: 30px;
  min-height: 0;
  transform: translateY(-50%);
}

@media (hover: hover) {
  .purchase-overview__row:hover {
    background: var(--selection);
  }
}

@media (max-width: 640px) {
  .purchase-overview__strip img {
    width: 40px;
    height: 40px;
  }

  .purchase-overview__strip img:nth-child(n + 5) {
    display: none;
  }

  .purchase-overview__strip {
    width: auto;
    justify-content: flex-start;
  }

  /* Op een telefoon past de strook niet naast de tekst: de details boven, de foto's eronder. */
  .purchase-overview__link {
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    padding-right: 40px;
  }

  .purchase-overview__row {
    contain-intrinsic-size: 0 120px;
  }
}

.purchase-table__sort {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.purchase-table th[aria-sort] .purchase-table__sort {
  color: var(--primary);
}

.purchase-table th[aria-sort="descending"] .purchase-table__sort::after {
  content: " ↓";
}

.purchase-table th[aria-sort="ascending"] .purchase-table__sort::after {
  content: " ↑";
}

.purchase-table-wrap {
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  overscroll-behavior: contain;
}

.purchase-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-md);
}

.purchase-table th,
.purchase-table td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}

.purchase-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-muted);
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 600;
}

.purchase-table__row {
  cursor: pointer;
}

@media (hover: hover) {
  .purchase-table__row:hover {
    background: var(--selection);
  }
}

.purchase-table__row:last-child td {
  border-bottom: 0;
}

.purchase-table__row td:first-child a {
  color: var(--primary);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.purchase-table .purchase-table__amount {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.purchase-table__actions {
  width: 1%;
  padding-top: 3px;
  padding-bottom: 3px;
}

.purchase-table__action {
  width: 30px;
  height: 30px;
  min-height: 0;
}

/* Het archief-icoon achter "Bestelling" bij een ingelezen bestelling (tabel, kaarten, overzicht): het enige dat de herkomst noemt.
   Achter het woord, zodat "Bestelling" in de kolom Soort onder elkaar uitlijnt. */
.purchase-kind-badge {
  display: inline-flex;
  margin-left: 4px;
  vertical-align: -0.2em;
  color: var(--muted);
}

.purchase-kind-badge svg {
  width: 1.15em;
  height: 1.15em;
  fill: currentColor;
}

/* Op een telefoon vallen de kolommen Soort en Status weg: de datum, de producten en het bedrag blijven. */
@media (max-width: 640px) {
  .purchase-table th:nth-child(2),
  .purchase-table td:nth-child(2),
  .purchase-table th:nth-child(3),
  .purchase-table td:nth-child(3) {
    display: none;
  }

  .purchase-table th,
  .purchase-table td {
    padding: 8px 6px;
  }

  .purchase-table__row td:first-child a {
    white-space: normal;
  }

  .purchase-table__actions:empty {
    padding: 0;
  }
}

/* Updatecheck (Instellingen > Updates): een bolletje bij de tab en een melding als er een nieuwe versie is */
.update-dot {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--danger);
  box-shadow: 0 0 0 2px var(--surface);
}

.message__actions {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 8px;
}

.message__actions .inline-button {
  margin-top: 0;
}

/* Fabrieksinstellingen (Instellingen > Systeem > Opschonen) */
.button--danger {
  border: 1px solid var(--danger-border);
  background: var(--danger-bg);
  color: var(--danger);
}

@media (hover: hover) {
  .button--danger:hover {
    border-color: var(--danger);
  }
}

.reset-form {
  margin-top: 16px;
}

.reset-warning ul {
  margin: 8px 0 0;
  padding-left: 20px;
}

.reset-warning li + li {
  margin-top: 4px;
}

.update-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 16px;
  margin: 16px 0;
}

.update-facts dt {
  color: var(--muted);
}

.update-facts dd {
  margin: 0;
  font-weight: 600;
}

#ah-orders-main h3 {
  margin: 24px 0 10px;
}

/* Auditlog (Instellingen > Auditlog) */
.audit-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
}

.audit-chip {
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface-muted);
  font-size: var(--text-sm);
}

.audit-failed {
  color: var(--danger);
  font-weight: 600;
}

.audit-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 16px;
}

.audit-toolbar .input {
  flex: 1 1 220px;
  min-width: 0;
}

.audit-list {
  display: grid;
  gap: 8px;
  margin-top: 16px;
}

.audit-entry {
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
}

.audit-entry.is-error {
  border-color: var(--danger-border);
}

.audit-entry summary {
  display: grid;
  grid-template-columns: max-content max-content minmax(0, 1fr) max-content max-content;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  cursor: pointer;
}

.audit-action strong,
.audit-action small {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.audit-action small {
  margin-top: 2px;
  color: var(--muted);
  font-size: var(--text-sm);
}

.audit-time,
.audit-duration {
  font-size: var(--text-sm);
  white-space: nowrap;
}

.audit-service {
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  background: var(--selection);
  color: var(--primary-strong);
  font-size: var(--text-xs);
  font-weight: 600;
  white-space: nowrap;
}

.audit-status {
  min-width: 36px;
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: 700;
  text-align: center;
}

.audit-status.is-ok {
  background: var(--success-bg);
  color: var(--success-text);
}

.audit-status.is-error {
  background: var(--danger-bg);
  color: var(--danger);
}

.audit-detail {
  padding: 0 12px 12px;
}

.audit-detail h4 {
  margin: 14px 0 6px;
  font-size: var(--text-md);
}

.audit-facts {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 4px 16px;
  margin: 0;
}

.audit-facts dt {
  color: var(--muted);
}

.audit-facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.audit-body {
  max-height: 320px;
  margin: 0;
  padding: 10px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface-muted);
  font-size: var(--text-sm);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.audit-body--error {
  border-color: var(--danger-border);
  background: var(--danger-bg);
}

.audit-related {
  display: grid;
  gap: 4px;
  margin: 0;
  padding-left: 18px;
}

@media (max-width: 640px) {
  .audit-entry summary {
    grid-template-columns: max-content minmax(0, 1fr) max-content;
    gap: 6px 10px;
  }

  .audit-time {
    grid-column: 1 / -1;
  }

  .audit-action strong,
  .audit-action small {
    white-space: normal;
    overflow-wrap: anywhere;
  }

  .audit-duration {
    display: none;
  }
}

/* Avatar en avatar-menu: op een groot scherm de avatar in de kop, op een klein scherm de knop Meer (hamburger) in de tabbalk.
   Op een klein scherm staat het Mandje in dat menu in plaats van in de tabbalk. */
.avatar {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--primary);
  color: var(--on-primary);
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: 1;
}

.avatar img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar--lg {
  width: 44px;
  height: 44px;
  font-size: var(--text-base);
}

.avatar--xl {
  width: 96px;
  height: 96px;
  font-size: 32px; /* initialen in de grote avatar: buiten de typeschaal */
}

.user-menu {
  display: flex;
  margin-left: auto;
}

.user-menu__button {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--control-height);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  padding: 3px 8px 3px 4px;
  color: var(--text);
  cursor: pointer;
  font: inherit;
  font-size: var(--text-md);
  font-weight: 600;
}

.user-menu__button {
  box-shadow: var(--shadow-xs);
  transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease), box-shadow 0.2s var(--ease);
}

@media (hover: hover) {
  .user-menu__button:hover {
    border-color: var(--border-strong);
    background: var(--selection);
    box-shadow: var(--shadow-sm);
  }
}

.user-menu__name {
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.user-menu__chevron {
  width: 20px;
  height: 20px;
  fill: var(--muted);
}

.user-menu__button[aria-expanded="true"] .user-menu__chevron {
  transform: rotate(180deg);
}

.user-menu__list {
  position: fixed;
  z-index: 50;
  min-width: 220px;
  max-width: calc(100vw - 16px);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  padding: 8px;
  animation: pop-in 0.16s var(--ease) both;
  transform-origin: top right;
}

@keyframes pop-in {
  from {
    opacity: 0;
    transform: scale(0.96) translateY(-4px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .user-menu__list,
  .subtab-menu__list {
    animation: none;
  }
}

.user-menu__list[hidden] {
  display: none;
}

.user-menu__who {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 6px;
  border-bottom: 1px solid var(--border);
  padding: 4px 8px 12px;
}

.user-menu__who small {
  display: block;
  color: var(--muted);
  font-size: var(--text-sm);
}

.user-menu__item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 40px;
  border: 0;
  border-radius: var(--radius-control);
  background: none;
  padding: 0 12px;
  color: inherit;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  text-align: left;
}

.user-menu__item:focus-visible {
  background: var(--selection);
}

@media (hover: hover) {
  .user-menu__item:hover {
    background: var(--selection);
  }
}

.user-menu__item[hidden],
.user-menu__item--small,
.user-menu__item--standalone {
  display: none;
}

/* Vernieuwen staat alleen in de geïnstalleerde app (sinds 4.13.0): die heeft geen knop van de browser, en omlaag slepen
   ververst er niet. */
html.is-standalone .user-menu__item--standalone:not([hidden]) {
  display: flex;
}

.user-menu__icon {
  flex: none;
  width: 20px;
  height: 20px;
  fill: currentColor;
  color: var(--muted);
}

.user-menu__item:focus-visible .user-menu__icon {
  color: inherit;
}

@media (hover: hover) {
  .user-menu__item:hover .user-menu__icon {
    color: inherit;
  }
}

/* Het bolletje voor een update staat achter Instellingen, niet in de hoek van het menu. */
.user-menu__item .update-dot {
  position: static;
  margin-left: auto;
  box-shadow: none;
}

.user-menu__separator {
  height: 1px;
  margin: 6px 0;
  background: var(--border);
}

.tab--more {
  display: none;
}

.tab[hidden] {
  display: none !important;
}

.profile-avatar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 20px;
}

.profile-avatar__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.user-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

@media (max-width: 640px) {
  .tab--more:not([hidden]) {
    display: inline-flex;
  }

  .user-menu {
    display: none;
  }

  /* Het Mandje verhuist naar het menu Meer. */
  .tabs .tab[data-tab="basket"] {
    display: none;
  }

  .user-menu__item--small:not([hidden]) {
    display: flex;
  }
}

/* Supermarktkeuze en knop onder de boodschappenlijst in het weekmenu. */
.ingredients__actions {
  margin-top: 16px;
  flex-wrap: wrap;
}

.ingredients__actions .cart-organic {
  margin: 0;
  font-weight: 500;
}

/* Navigatiemenu links vanaf 860 px (sinds 4.7.0, eerder 1024 px; 860 is het breekpunt van App-Guidance, navigation.md). Het
   blijft een nav met dezelfde knoppen: daaronder staat het zoals altijd boven de pagina (of als onderste menubalk in de app), en de knop om in te klappen is er dan niet. */
.tabs__toggle {
  display: none;
}

@media (min-width: 860px) {
  .topbar__inner,
  .shell {
    max-width: 1360px;
  }

  .shell {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 24px;
    align-items: start;
  }

  .shell > * {
    grid-column: 2;
    min-width: 0;
  }

  .shell > .tabs {
    grid-column: 1;
    grid-row: 1 / span 12;
    position: sticky;
    top: 88px;
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 2px;
    width: 232px;
    margin-bottom: 0;
    padding: 8px;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    transition: width 0.2s ease;
  }

  .tabs .tab {
    justify-content: flex-start;
    gap: 12px;
    width: 100%;
    text-align: left;
  }

  /* Het actieve onderdeel krijgt links een groene streep, zoals in een professioneel beheerscherm. */
  .shell > .tabs .tab.is-active::before {
    content: "";
    position: absolute;
    top: 10px;
    bottom: 10px;
    left: -7px;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--primary);
  }

  .tabs__toggle {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: var(--control-height);
    margin-top: 4px;
    padding: 0 16px;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0 0 var(--radius-control) var(--radius-control);
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: var(--text-ui);
    font-weight: 600;
    text-align: left;
    cursor: pointer;
  }

  @media (hover: hover) {
    .tabs__toggle:hover {
      background: var(--selection);
      color: var(--primary-strong);
    }
  }

  .tabs__toggle-icon {
    flex: none;
    width: 20px;
    height: 20px;
    fill: currentColor;
    transition: transform 0.2s ease;
  }

  html.nav-collapsed .shell > .tabs {
    width: 62px;
  }

  html.nav-collapsed .tabs .tab,
  html.nav-collapsed .tabs__toggle {
    justify-content: center;
    padding: 0;
  }

  html.nav-collapsed .tabs .tab-text,
  html.nav-collapsed .tabs__toggle-text {
    display: none;
  }

  html.nav-collapsed .tabs__toggle-icon {
    transform: rotate(180deg);
  }

  html.nav-collapsed .tabs .update-dot {
    top: 6px;
    right: 6px;
  }

  /* De boom (nav_tree.js): onder een onderdeel zijn subtabs, ingesprongen tot onder de naam. Alleen met het menu open en
     als de boom in de hoogte past (html.nav-tree); anders staan de subtabbalken boven de inhoud zoals altijd. */
  html.nav-tree:not(.nav-collapsed) .tab-tree {
    display: grid;
    gap: 1px;
    padding: 2px 0 6px 40px;
  }

  /* Alleen onder het onderdeel dat open is: met alle subtabs van alle onderdelen werd het menu een lange lijst. */
  html.nav-tree:not(.nav-collapsed) .tab:not(.is-active) + .tab-tree {
    display: none;
  }

  /* De subtabbalk is weg, dus de titel zegt waar je bent. */
  html.nav-tree:not(.nav-collapsed) .page-title--tree {
    display: block;
  }

  .tab-tree__item {
    position: relative;
    display: flex;
    align-items: center;
    min-height: 32px;
    padding: 0 10px 0 12px;
    border-radius: var(--radius-control);
    color: var(--muted);
    font-size: var(--text-md);
    font-weight: 600;
    text-decoration: none;
  }

  @media (hover: hover) {
    .tab-tree__item:hover {
      background: var(--selection);
      color: var(--primary-strong);
    }
  }

  /* Het open subtab: een bolletje voor de naam, de kleur van het actieve onderdeel. */
  .tab-tree__item.is-current {
    color: var(--primary-strong);
    font-weight: 700;
  }

  .tab-tree__item.is-current::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 0;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--primary);
    transform: translateY(-50%);
  }

  html.nav-tree:not(.nav-collapsed) .subtabs--tree > a.subtab,
  html.nav-tree:not(.nav-collapsed) .subtabs--tree.subtabs--empty {
    display: none;
  }
}

@media (min-width: 860px) and (prefers-reduced-motion: reduce) {
  .shell > .tabs,
  .tabs__toggle-icon {
    transition: none;
  }
}

/* Instellingen > Koppelen: de aanbiedingen per winkel. */
.offers-sync-list {
  display: grid;
  gap: 4px;
  margin: 12px 0;
  padding-left: 18px;
  font-size: var(--text-md);
}

.offers-sync-list__failed {
  color: var(--danger);
}

#offers-sync-box .toolbar {
  margin-top: 12px;
}

/* Aanbiedingen > Prijsgeschiedenis: de zoeklijst links en het product met de grafiek rechts (op een smal scherm onder elkaar). */
.ohc-layout {
  display: grid;
  gap: 20px;
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 1200px) {
  .ohc-layout {
    grid-template-columns: minmax(240px, 300px) minmax(0, 1fr);
    align-items: start;
  }
}

/* De schakelaar "Alleen eerder gekocht": een gewoon selectievakje (toetsenbord en schermlezer werken zoals altijd), getekend als schakelaar. */
.ohc-filter {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 12px 0 2px;
  font-weight: 600;
  cursor: pointer;
}

.ohc-filter input {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: none;
  width: 40px;
  height: 24px;
  margin: 0;
  border: 2px solid var(--muted);
  border-radius: var(--radius-pill);
  background: var(--surface);
  cursor: pointer;
  transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease);
}

.ohc-filter input::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--muted);
  transition: transform 0.15s var(--ease), background-color 0.15s var(--ease);
}

.ohc-filter input:checked {
  border-color: var(--primary);
  background: var(--primary);
}

.ohc-filter input:checked::before {
  background: var(--surface);
  transform: translateX(16px);
}

.ohc-filter input:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .ohc-filter input,
  .ohc-filter input::before {
    transition: none;
  }
}

.ohc-list {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 0;
  max-height: 420px;
  overflow-y: auto;
  list-style: none;
}

/* Op een breed scherm passen de lijst en het product samen op het scherm en scrolt elke kolom in zijn eigen vak
   (offerHistoryFitList zet de hoogte, want waar de kolommen beginnen hangt van de tekst erboven af). */
@media (min-width: 1200px) {
  .ohc-detail {
    overflow-y: auto;
  }
}

.ohc-item {
  display: grid;
  gap: 2px;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.ohc-item small {
  color: var(--muted);
}

@media (hover: hover) {
  .ohc-item:hover:not(.is-active) {
    background: var(--selection);
  }
}

.ohc-item.is-active {
  border-color: var(--primary);
  background: var(--selection);
}

.ohc-head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.ohc-head img {
  flex: none;
  width: 64px;
  height: 64px;
  border-radius: var(--radius-control);
  object-fit: contain;
  background: var(--surface-muted);
}

.ohc-head--compact {
  align-items: flex-start;
}

.ohc-head--compact img {
  width: 160px;
  height: 160px;
  background: #fff;
}

.ohc-head h3,
.ohc-head p {
  margin: 0;
}

.ohc-head__price b {
  font-size: var(--text-base);
}

.ohc-head__price s {
  color: var(--muted);
}

.ohc-head__price small {
  margin-left: 6px;
  color: var(--muted);
}

.ohc-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 14px 0;
}

.ohc-stat {
  min-width: 120px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface-muted);
}

.ohc-stat dt {
  color: var(--muted);
  font-size: var(--text-sm);
}

.ohc-stat dd {
  margin: 0;
  font-weight: 600;
}

.ohc-chart {
  overflow-x: hidden;
}

.ohc {
  display: block;
  max-width: 100%;
  font-size: var(--text-xs);
}

.ohc-grid {
  stroke: var(--border);
  stroke-width: 1;
}

.ohc-grid--x {
  stroke-dasharray: 2 4;
}

.ohc-axis,
.ohc-regular-label {
  fill: var(--muted);
  font-size: var(--text-xs);
}

.ohc-price {
  fill: var(--text);
  font-size: var(--text-xs);
  font-weight: 600;
}

.ohc-regular {
  stroke: var(--muted);
  stroke-width: 1.5;
  stroke-dasharray: 6 4;
}

.ohc-today {
  stroke: var(--primary-strong);
  stroke-width: 1;
  stroke-dasharray: 2 3;
}

.ohc-axis--today {
  fill: var(--primary-strong);
}

.ohc-bar rect,
.ohc-bar path {
  fill: var(--primary);
}

.ohc-bar:focus rect,
.ohc-bar:focus path {
  fill: var(--primary-strong);
}

@media (hover: hover) {
  .ohc-bar:hover rect,
  .ohc-bar:hover path {
    fill: var(--primary-strong);
  }
}

.ohc-bar:focus {
  outline: none;
}

.ohc-bar:focus-visible rect {
  stroke: var(--text);
  stroke-width: 2;
}

/* De gewone prijs als trap: een onzichtbare dikke lijn eronder maakt elke trede makkelijk aan te wijzen. */
.ohc-step-hit {
  stroke: transparent;
  stroke-width: 12;
}

.ohc-step:focus {
  outline: none;
}

.ohc-step:focus-visible .ohc-regular {
  stroke: var(--text);
}

@media (hover: hover) {
  .ohc-step:hover .ohc-regular {
    stroke: var(--text);
  }
}

/* Een folderactie voor de hele lijn (uit het folderarchief): een streepje onderaan, zonder prijs. */
.ohc-line rect {
  fill: #c98a1b;
}

.ohc-line--priced rect {
  fill: #c98a1b;
  opacity: 0.85;
}

.ohc-line:focus rect {
  fill: var(--text);
}

@media (hover: hover) {
  .ohc-line:hover rect {
    fill: var(--text);
  }
}

.ohc-line:focus {
  outline: none;
}

/* Een aankoop: een stip op de prijs per stuk die je betaalde. */
.ohc-paid circle {
  fill: var(--surface);
  stroke: var(--text);
  stroke-width: 2;
}

.ohc-paid:focus circle {
  fill: var(--text);
}

@media (hover: hover) {
  .ohc-paid:hover circle {
    fill: var(--text);
  }
}

.ohc-paid:focus {
  outline: none;
}

/* Onbekende actiestatus: paarse ruiten, los van aankopen en gewone prijzen. */
.ohc-observed path {
  fill: #8b5fc7;
  stroke: var(--surface);
  stroke-width: 1;
}

.ohc-observed:focus path {
  stroke: var(--text);
  stroke-width: 2;
}

@media (hover: hover) {
  .ohc-observed:hover path {
    stroke: var(--text);
    stroke-width: 2;
  }
}

.ohc-observed:focus {
  outline: none;
}

/* De actie van een folderactie, onder de naam in de folder. */
.ohc-line-action {
  display: block;
  color: var(--muted);
  overflow-wrap: anywhere;
}

/* De periode van de grafiek: 1 jaar, 3 jaar of alles. */
.ohc-range {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 4px 0 6px;
}

.ohc-range-button {
  min-height: 32px;
  padding: 4px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}

.ohc-range-button[aria-pressed="true"] {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--on-primary, #fff);
}

.ohc-range-button:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 2px;
}

.ohc-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  color: var(--muted);
  font-size: var(--text-sm);
}

.ohc-legend li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.ohc-key {
  display: inline-block;
  width: 18px;
  height: 8px;
}

.ohc-key--offer {
  border-radius: 3px;
  background: var(--primary);
}

.ohc-key--regular {
  height: 0;
  border-top: 2px dashed var(--muted);
}

.ohc-key--paid {
  width: 9px;
  height: 9px;
  border: 2px solid var(--text);
  border-radius: 50%;
}

.ohc-key--line {
  height: 8px;
  border-radius: 1.5px;
  background: #c98a1b;
}

.ohc-key--observed {
  width: 9px;
  height: 9px;
  margin: 0 2px;
  background: #8b5fc7;
  transform: rotate(45deg);
}

.ohc-note {
  margin: 6px 8px 0;
  font-size: var(--text-sm);
}

/* De bewaarde afbeeldingen van een product dat je kocht, met de naam van toen eronder. */
.ohc-images {
  margin-top: 18px;
}

.ohc-images h4 {
  margin: 0;
  font-size: var(--text-ui);
}

.ohc-images > p {
  margin: 2px 0 10px;
  font-size: var(--text-sm);
}

.ohc-images ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ohc-images figure {
  margin: 0;
}

.ohc-images a {
  display: block;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface-muted);
}

.ohc-images a:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.ohc-images img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: contain;
}

.ohc-images figcaption {
  margin-top: 4px;
  font-size: var(--text-sm);
  line-height: 1.35;
  overflow-wrap: anywhere;
}

.ohc-images figcaption small {
  display: block;
  color: var(--muted);
}

.ohc-table caption {
  padding: 0 8px 4px;
  font-weight: 600;
  text-align: left;
}

.ohc-table {
  width: 100%;
  margin-top: 14px;
  border-collapse: collapse;
  font-size: var(--text-md);
}

.ohc-table th,
.ohc-table td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
  text-align: left;
}

.ohc-table th {
  color: var(--muted);
  font-weight: 600;
}

/* Aanbiedingen: de looptijd van de bonus, vet boven het aantal aanbiedingen. */
.offers-period {
  margin: 4px 0 0;
  font-weight: 600;
}

/* Aanbiedingen: de week, dezelfde als die van het weekmenu, en wat er al voor later bekend is. */
/* Maaltijdboxen: ruimte tussen de uitleg en de weeknavigatie, zoals bij de andere kaders. */
#mealkits-weeks {
  margin-top: 14px;
}

.offers-week {
  margin: 8px 0 12px;
}

.offers-later {
  margin: 4px 0 0;
}

/* Aanbiedingen: categorieën als knoppen met het aantal ("5x Groente & Fruit"). */
.offer-cats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
}

.offer-cats[hidden] {
  display: none;
}

.offer-chip {
  min-height: 36px;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  color: var(--muted);
  font: inherit;
  font-size: var(--text-md);
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s var(--ease), color 0.15s var(--ease), border-color 0.15s var(--ease), box-shadow 0.2s var(--ease);
  -webkit-tap-highlight-color: transparent;
}

@media (hover: hover) {
  .offer-chip:hover:not(.is-active) {
    border-color: var(--border-strong);
    background: var(--selection);
    color: var(--primary-strong);
  }
}

.offer-chip.is-active {
  border-color: var(--primary);
  background: var(--primary);
  box-shadow: var(--btn-shadow);
  color: var(--on-primary);
}

.offer-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* Het aantal achter de naam van een chip, gedempt ("Vlees 412"). Op de gekozen chip in de kleur van de tekst van die chip. */
.offer-chip__count {
  margin-left: 2px;
  color: var(--muted);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.offer-chip.is-active .offer-chip__count {
  color: inherit;
  opacity: 0.8;
}

/* Op een telefoon is de rij categorieën één regel die opzij scrolt: eerst stonden er tien regels chips voor het eerste product. */
@media (max-width: 640px) {
  .offer-cats--scroll {
    flex-wrap: nowrap;
    margin-inline: -16px;
    padding: 2px 16px 6px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }

  .offer-cats--scroll::-webkit-scrollbar {
    display: none;
  }

  .offer-cats--scroll > .offer-chip {
    flex: none;
    white-space: nowrap;
  }
}

.offer-chip__dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--cat-line, var(--border-strong));
}

/* Een kleur per categorie: de achtergrond en het accent (kaarten, koppen, bolletjes). */
.cat--groente_fruit {
  --cat-bg: #e3f4e1;
  --cat-line: #4caf50;
}

.cat--vlees {
  --cat-bg: #fbe3e3;
  --cat-line: #d9534f;
}

.cat--vis {
  --cat-bg: #dff0fb;
  --cat-line: #2e86c1;
}

.cat--kaas_vleeswaren {
  --cat-bg: #fdf0d5;
  --cat-line: #e0a030;
}

.cat--zuivel_eieren {
  --cat-bg: #fff8d6;
  --cat-line: #d4b800;
}

.cat--brood_bakkerij {
  --cat-bg: #f3e6d3;
  --cat-line: #b07a3c;
}

.cat--maaltijden {
  --cat-bg: #f6e4f2;
  --cat-line: #b05aa0;
}

.cat--sauzen_conserven {
  --cat-bg: #ffe9d6;
  --cat-line: #e07b2a;
}

.cat--ontbijt_beleg {
  --cat-bg: #f1ecdd;
  --cat-line: #9c8a4d;
}

.cat--snacks_snoep {
  --cat-bg: #efe3f8;
  --cat-line: #8e5bd1;
}

.cat--frisdrank {
  --cat-bg: #ddf5f3;
  --cat-line: #20a39e;
}

.cat--koffie_thee {
  --cat-bg: #e9dfd6;
  --cat-line: #7a5230;
}

.cat--bier_wijn {
  --cat-bg: #ecdcee;
  --cat-line: #7b3f8c;
}

.cat--diepvries {
  --cat-bg: #e0f0fa;
  --cat-line: #4aa3df;
}

.cat--huishouden {
  --cat-bg: #e8eaee;
  --cat-line: #6b7a90;
}

.cat--drogisterie {
  --cat-bg: #e3f1f0;
  --cat-line: #3a9d8f;
}

.cat--baby {
  --cat-bg: #fde8ef;
  --cat-line: #d26a95;
}

.cat--huisdier {
  --cat-bg: #f0e6dc;
  --cat-line: #a0744a;
}

.cat--overig {
  --cat-bg: #ececec;
  --cat-line: #8a8a8a;
}

:root[data-theme="dark"] .cat--groente_fruit {
  --cat-bg: color-mix(in srgb, #4caf50 18%, var(--surface));
  --cat-line: #4caf50;
}

:root[data-theme="dark"] .cat--vlees {
  --cat-bg: color-mix(in srgb, #d9534f 18%, var(--surface));
  --cat-line: #d9534f;
}

:root[data-theme="dark"] .cat--vis {
  --cat-bg: color-mix(in srgb, #2e86c1 18%, var(--surface));
  --cat-line: #2e86c1;
}

:root[data-theme="dark"] .cat--kaas_vleeswaren {
  --cat-bg: color-mix(in srgb, #e0a030 18%, var(--surface));
  --cat-line: #e0a030;
}

:root[data-theme="dark"] .cat--zuivel_eieren {
  --cat-bg: color-mix(in srgb, #d4b800 18%, var(--surface));
  --cat-line: #d4b800;
}

:root[data-theme="dark"] .cat--brood_bakkerij {
  --cat-bg: color-mix(in srgb, #b07a3c 18%, var(--surface));
  --cat-line: #b07a3c;
}

:root[data-theme="dark"] .cat--maaltijden {
  --cat-bg: color-mix(in srgb, #b05aa0 18%, var(--surface));
  --cat-line: #b05aa0;
}

:root[data-theme="dark"] .cat--sauzen_conserven {
  --cat-bg: color-mix(in srgb, #e07b2a 18%, var(--surface));
  --cat-line: #e07b2a;
}

:root[data-theme="dark"] .cat--ontbijt_beleg {
  --cat-bg: color-mix(in srgb, #9c8a4d 18%, var(--surface));
  --cat-line: #9c8a4d;
}

:root[data-theme="dark"] .cat--snacks_snoep {
  --cat-bg: color-mix(in srgb, #8e5bd1 18%, var(--surface));
  --cat-line: #8e5bd1;
}

:root[data-theme="dark"] .cat--frisdrank {
  --cat-bg: color-mix(in srgb, #20a39e 18%, var(--surface));
  --cat-line: #20a39e;
}

:root[data-theme="dark"] .cat--koffie_thee {
  --cat-bg: color-mix(in srgb, #7a5230 18%, var(--surface));
  --cat-line: #7a5230;
}

:root[data-theme="dark"] .cat--bier_wijn {
  --cat-bg: color-mix(in srgb, #7b3f8c 18%, var(--surface));
  --cat-line: #7b3f8c;
}

:root[data-theme="dark"] .cat--diepvries {
  --cat-bg: color-mix(in srgb, #4aa3df 18%, var(--surface));
  --cat-line: #4aa3df;
}

:root[data-theme="dark"] .cat--huishouden {
  --cat-bg: color-mix(in srgb, #6b7a90 18%, var(--surface));
  --cat-line: #6b7a90;
}

:root[data-theme="dark"] .cat--drogisterie {
  --cat-bg: color-mix(in srgb, #3a9d8f 18%, var(--surface));
  --cat-line: #3a9d8f;
}

:root[data-theme="dark"] .cat--baby {
  --cat-bg: color-mix(in srgb, #d26a95 18%, var(--surface));
  --cat-line: #d26a95;
}

:root[data-theme="dark"] .cat--huisdier {
  --cat-bg: color-mix(in srgb, #a0744a 18%, var(--surface));
  --cat-line: #a0744a;
}

:root[data-theme="dark"] .cat--overig {
  --cat-bg: color-mix(in srgb, #8a8a8a 18%, var(--surface));
  --cat-line: #8a8a8a;
}

#offers-more {
  margin-top: 14px;
}

/* Back-up en terugzetten (Instellingen > Systeem) */
#backup-box .field,
#backup-box .check {
  margin-top: 12px;
}

.backup-confirm {
  margin-top: 16px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
}

.backup-confirm h4 {
  margin: 0 0 6px;
}

.backup-confirm ul {
  margin: 8px 0;
  padding-left: 20px;
}

/* Prijsarchief: per winkel een regel met de periode en daaronder wat erbij komt. */
.price-archive-stores li + li {
  margin-top: 8px;
}

.price-archive-stores li {
  overflow-wrap: anywhere;
}

.backup-progress {
  margin-top: 16px;
}

.backup-progress p {
  margin: 0 0 6px;
}

.backup-progress progress {
  display: block;
  width: 100%;
  height: 10px;
  accent-color: var(--primary);
}

#backup-box h3 {
  margin-top: 24px;
}

/* Aanbiedingen: de titel is de link naar de winkel, zodat de kaart ook een knop kan hebben (Vergelijk verpakkingen). */
.offer-card .offer-card__link {
  color: inherit;
  text-decoration: none;
}

.offer-card .offer-card__link strong {
  color: var(--primary);
}

.offer-card .offer-card__link:focus-visible strong {
  text-decoration: underline;
}

@media (hover: hover) {
  .offer-card .offer-card__link:hover strong {
    text-decoration: underline;
  }
}

.offer-card .offer-card__per-unit {
  color: var(--text);
  font-weight: 600;
}

/* De kaart van een aanbieding: het plaatje boven, groot genoeg om het product te herkennen, met de badge en het prijslabel erop,
   de tekst eronder en de twee links op één rij onderaan. Smaller dan een gewone productkaart, dus meer per rij. */
.product-grid--offers {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

.offer-card {
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
  content-visibility: auto;
  contain-intrinsic-size: 200px 380px;
}

.offer-card__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.offer-card__body > small:first-of-type {
  margin-top: 2px;
}

.offer-card__thumb {
  position: relative;
  display: block;
  height: 140px;
  margin: -10px -10px 4px;
  background: #fff;
  border-bottom: 1px solid var(--border);
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  overflow: hidden;
}

/* In het donkere thema geen wit vlak tot de rand (een dambord van felle blokken), maar een ingezette tegel. */
:root[data-theme="dark"] .offer-card__thumb {
  margin: 0 0 6px;
  border-bottom: 0;
  border-radius: var(--radius-control);
}

.offer-card__thumb--empty {
  background: var(--surface-muted);
}

/* Zonder foto: een lege-foto-icoon in het midden, zodat de kaart niet alleen een grijs vlak is. */
.offer-card__thumb-icon {
  display: block;
  width: 36px;
  height: 36px;
  margin: 0 auto;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
  fill: var(--muted);
  opacity: 0.5;
}

.offer-row .offer-card__thumb-icon {
  width: 24px;
  height: 24px;
}

.offer-card__thumb-link {
  display: block;
  width: 100%;
  height: 100%;
}

.offer-card__thumb img {
  width: 100%;
  height: 100%;
  padding: 8px;
  object-fit: contain;
  background: #fff;
  border-radius: 0;
  outline: none;
}

/* De kortingsbadge, naar het oordeel (offerBadge, sinds 4.8.0; daarvoor de vijf kleuren van het userscript, met rood voor een kleine
   korting). Echt voordelig: vol groen uit de statuskleuren, die de accentkleur niet volgen. Een klein voordeel: neutraal. Geen
   korting: gedempt, met het woord in plaats van "0%". De claim van de winkel (geen gemeten verschil): een stippelrand. De randen
   zijn een border en geen box-shadow, zodat ze ook in een regel van tekst blijven (.offer-badge--inline zet de schaduw uit). */
.offer-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 1;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  padding: 3px 7px;
  font-size: var(--text-md);
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  cursor: help;
}

.offer-badge--good {
  border-color: var(--success-text);
  background: var(--success-text);
  color: var(--surface);
}

.offer-badge--small {
  border-color: var(--border-strong);
  background: var(--surface);
  color: var(--text);
}

.offer-badge--none {
  border-color: var(--border);
  background: var(--surface-muted);
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 700;
}

.offer-badge--store {
  border: 2px dashed currentColor;
  background: var(--surface);
}

.offer-badge--store.offer-badge--good {
  color: var(--success-text);
}

/* Het prijslabel uit de geschiedenis, rechtsonder op het plaatje. */
.offer-label {
  position: absolute;
  right: 8px;
  bottom: 8px;
  z-index: 1;
  max-width: calc(100% - 16px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-radius: var(--radius-pill);
  padding: 1px 8px;
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: 1.5;
}

.offer-label--green {
  background: var(--success-bg);
  box-shadow: inset 0 0 0 1px var(--success-border);
  color: var(--success-text);
}

.offer-label--grey {
  background: var(--surface-muted);
  box-shadow: inset 0 0 0 1px var(--border);
  color: var(--muted);
}

/* De hover-zoom naast een kaart: het grote plaatje met daaronder het prijsverloop van een jaar. Vast op het scherm, nooit buiten
   beeld (offers.js rekent de plek uit), en zonder muisgevoeligheid zodat hij niet zelf de hover vasthoudt. */
/* De popup met de prijsgeschiedenis bij een aanbieding (offers.js): vast op het scherm, 640 px breed, scrolt binnen het venster. */
.offer-popup {
  position: fixed;
  z-index: 60;
  width: 640px;
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px); /* iOS: de zichtbare hoogte, zonder de werkbalk van Safari */
  overflow: auto;
  overscroll-behavior: contain;
  padding: 16px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg);
}

.offer-popup[hidden] {
  display: none;
}

.offer-popup__inner .ohc-stats {
  margin: 10px 0;
}

.offer-popup__packs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0 0;
}

.offer-popup__loading {
  margin: 14px 0;
}

/* De uitleg van de kortingsbadge (sinds 4.12.0): op de kaart staat hij alleen in een tooltip, die er op een aanraakscherm niet is. */
.offer-popup__verdict {
  margin: 6px 0 0;
  font-size: var(--text-sm);
}

.offer-popup__foot {
  margin: 10px 0 0;
  font-weight: 600;
}

/* Het venster zonder muis: zo breed als de popup plus de rand, op een telefoon het scherm. */
.offer-zoom-dialog {
  width: min(682px, calc(100vw - 32px));
}

.offer-popup__dialog {
  min-width: 0;
}

@media (max-width: 640px) {
  .offer-popup__dialog .ohc-head--compact img {
    width: 96px;
    height: 96px;
  }
}

/* De grafiek is getekend op 608 px en schaalt mee met een smallere popup of het venster. */
.offer-popup .ohc-chart svg,
.offer-popup__dialog .ohc-chart svg {
  max-width: 100%;
  height: auto;
}

/* De hovervensters op de aankopenlijst (popover.js): alleen met een muis, vast op het scherm en binnen de randen (popover.js
   rekent de plek uit). Hoger dan het scherm min 32 px wordt het niet: wat niet past, schuift binnen het venster. */
.popover {
  position: fixed;
  z-index: 60;
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px); /* iOS: de zichtbare hoogte, zonder de werkbalk van Safari */
  overflow: auto;
  overscroll-behavior: contain;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg);
  font-size: var(--text-md);
  line-height: 1.35;
}

.popover[hidden] {
  display: none;
}

.popover img {
  object-fit: contain;
  background: #fff;
  outline: 1px solid rgba(var(--shadow-ink), 0.08);
  outline-offset: -1px;
}

.popover__error {
  margin: 0;
  padding: 10px 14px;
  color: var(--muted);
}

/* Het product: de foto groot links, de gegevens rechts, de linkerrand in de kleur van de categorie. */
.popover--product {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  width: 440px;
  max-width: 100%;
  padding: 12px 14px;
  border-left: 5px solid var(--cat-line);
}

.popover__photo {
  flex: none;
  width: 180px;
  height: 180px;
  border-radius: var(--radius-control);
}

.popover__info {
  display: grid;
  gap: 6px;
  min-width: 0;
  justify-items: start;
}

.popover__title {
  font-size: var(--text-ui);
}

.popover__meta,
.popover__history,
.popover__summary,
.popover__cat-count,
.popover__more {
  color: var(--muted);
}

.popover__info .offer-chip {
  min-height: 28px;
  padding: 0 10px;
  font-size: var(--text-sm);
  cursor: default;
}

.popover__amount {
  font-variant-numeric: tabular-nums;
}

/* De aankoop: de kop, een regel per categorie (bolletje, naam, stuks en soorten, fotootjes, subtotaal) en onderaan het totaal. */
.popover--purchase {
  display: grid;
  gap: 8px;
  width: 620px;
  max-width: 100%;
  padding: 12px 14px;
}

.popover__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: var(--text-ui);
}

.popover__summary {
  margin: 0;
}

.popover__cats {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.popover__cat {
  display: grid;
  grid-template-columns: 14px 150px 90px 1fr 70px;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  border-top: 1px solid var(--border);
}

.popover__cat-count {
  font-size: var(--text-sm);
}

.popover__cat-amount {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.popover__thumbs {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}

.popover__thumbs img {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
}

.popover__thumbs--small img {
  width: 22px;
  height: 22px;
}

.popover__more {
  font-size: var(--text-xs);
}

.popover__foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}

.popover__total {
  font-variant-numeric: tabular-nums;
}

/* Onderaan de kaart twee icoonknoppen rechts (Vergelijk verpakkingen, Prijsgeschiedenis), zoals in de compacte rij; ze vallen
   iets over de rand van de kaart, zodat het icoon op de lijn van de tekst staat en het tikvlak toch 44 px is. */
.offer-card__foot {
  display: flex;
  justify-content: flex-end;
  gap: 4px;
  margin: auto -6px -6px;
  padding-top: 2px;
}

.offer-card__foot .icon-button {
  border-color: transparent;
  background: none;
  box-shadow: none;
  color: var(--muted);
}

@media (hover: hover) {
  .offer-card__foot .icon-button:hover {
    color: var(--primary-strong);
  }
}

/* Een persoonlijke aanbieding (AH: de Bonus Box): groen als je haar in de AH-app hebt geactiveerd, geel als dat nog moet. */
.product-card .offer-card__personal {
  width: fit-content;
  margin-top: 4px;
  border-radius: var(--radius-pill);
  padding: 1px 8px;
  background: var(--surface-muted);
  box-shadow: inset 0 0 0 1px var(--border);
  color: var(--text);
  font-size: var(--text-xs);
  font-weight: 700;
}

.product-card .offer-card__personal--on {
  background: var(--success-bg);
  box-shadow: inset 0 0 0 1px var(--success-border);
  color: var(--success-text);
}

.product-card .offer-card__personal--off {
  background: var(--warning-bg);
  box-shadow: inset 0 0 0 1px var(--warning-border);
  color: var(--warning-text);
}

/* De schakelaar "Alleen Bonus Box" boven de categorieën, met wat er over je Bonus Box te zeggen is. */
/* De werkbalk boven de categorieën: het zoekveld, de schakelaars (Bonus Box, alleen echt voordelig) en de sorteerchips. */
/* De aanbiedingen met de filterzijbalk links. Vanaf 1200 px staat de zijbalk open naast de kaarten, daaronder is hij een
   uitschuifpaneel achter de knop Filters. */
.offers-layout {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

.offers-main {
  min-width: 0;
}

.offers-filters {
  position: sticky;
  top: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
}

.offers-filters__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.offers-filters__head h3,
.offers-filters__section h4 {
  margin: 0;
  font-size: var(--text-md);
}

.offers-filters__section h4 {
  margin-bottom: 8px;
  color: var(--muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: var(--text-xs);
}

.offers-filters__section {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.offers-filters .ohc-filter {
  margin: 0;
}

.offers-filters .offer-cats {
  margin-top: 0;
  gap: 6px;
}

.offer-chip--small {
  min-height: 30px;
  padding: 0 10px;
  font-size: var(--text-sm);
}

.offer-chip--small small {
  margin-left: 2px;
  font-weight: 400;
  opacity: 0.8;
}

.offers-filters__field label {
  font-weight: 600;
  font-size: var(--text-md);
}

.offers-filters__range {
  display: flex;
  align-items: center;
  gap: 10px;
}

.offers-filters__range input {
  flex: 1 1 auto;
  min-width: 0;
}

.offers-filters__range output {
  min-width: 84px;
  color: var(--muted);
  font-size: var(--text-sm);
  text-align: right;
}

.offers-filters__unit {
  display: flex;
  gap: 8px;
}

.offers-filters__unit .input {
  min-height: var(--control-height);
  padding: 0 10px;
}

.offers-filters__unit input {
  flex: 1 1 80px;
  min-width: 0;
}

.offers-filters__unit select {
  flex: 0 1 120px;
}

.offers-filters__close,
.offers-filters__toggle,
.offers-filters__backdrop {
  display: none;
}

.offer-cats--active-filters {
  margin-top: 10px;
  align-items: center;
}

@media (max-width: 1199px) {
  .offers-layout {
    display: block;
  }

  .offers-filters {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 60;
    width: min(320px, 86vw);
    overflow: auto;
    border-radius: 0 var(--radius-card) var(--radius-card) 0;
    transform: translateX(-100%);
    transition: transform 0.2s var(--ease);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
  }

  .offers-filters.is-open {
    transform: none;
  }

  .offers-filters__close,
  .offers-filters__toggle {
    display: inline-flex;
  }

  .offers-filters__backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 59;
    background: rgba(0, 0, 0, 0.35);
  }

  .offers-filters__backdrop[hidden] {
    display: none;
  }

  body.offers-filters-open {
    overflow: hidden;
  }
}

.offers-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 18px;
  margin: 12px 0 0;
}

.offers-tools__search {
  flex: 1 1 220px;
  max-width: 360px;
  min-height: var(--control-height);
  padding: 0 12px;
}

.offers-tools .ohc-filter {
  margin: 0;
}

.offers-personal {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}

.offers-personal[hidden] {
  display: none;
}

/* Sorteren: een keuzelijst met een zichtbaar label, naast de raster/lijst-schakelaar (sinds 4.8.0; daarvoor vijf chips). */
.offers-sort {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: var(--text-md);
  font-weight: 600;
}

.offers-sort .input {
  width: auto;
  min-width: 0;
  color: var(--text);
  font-weight: 500;
}

/* De weergaveknoppen (kaarten of compact) staan rechts in de werkbalk; de stijl is .segmented. */
#offers-view {
  margin-left: auto;
}

/* De compacte weergave: één regel per aanbieding met vaste kolommen en een kopregel erboven. */
.product-grid--compact {
  container-type: inline-size;
  grid-template-columns: 1fr;
  gap: 4px;
}

.offer-row {
  display: grid;
  grid-template-columns: 48px 60px minmax(0, 1fr) 110px 100px 150px 106px;
  align-items: center;
  gap: 10px;
  min-height: 56px;
  padding: 4px 10px;
}

.offer-row--head {
  min-height: 0;
  padding-top: 0;
  padding-bottom: 2px;
  border: 0;
  box-shadow: none;
  background: none;
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.offer-row--head span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.offer-row .offer-row__thumb {
  width: 48px;
  height: 48px;
  margin: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
}

.offer-row .offer-row__thumb img {
  padding: 2px;
}

.offer-row .offer-badge {
  position: static;
  display: inline-block;
  width: 52px;
  padding: 4px 0;
  text-align: center;
  font-size: var(--text-sm);
}

.offer-row__product {
  min-width: 0;
}

.offer-row__product strong {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--text-md);
}

.offer-row__product small {
  margin-top: 1px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* De actie van de winkel in de compacte rij: vet, in de kleur van de tekst (rood is voor fouten, sinds 4.8.0). */
.offer-row__promo {
  color: var(--text);
  font-weight: 700;
}

.offer-row .product-card__price {
  margin-top: 0;
  font-size: var(--text-ui);
}

.offer-row .offer-row__unit {
  margin-top: 0;
  color: var(--text);
  font-weight: 600;
}

.offer-row .offer-label,
.offer-row .verdict {
  position: static;
  margin: 0;
}

.offer-row__links {
  display: flex;
  justify-content: flex-end;
  gap: 2px;
}

.offer-row__links .icon-button {
  width: 32px;
  min-width: 32px;
  height: 32px;
  min-height: 32px;
  padding: 0;
  background: transparent;
  color: var(--primary);
  box-shadow: none;
}

@media (hover: hover) {
  .offer-row__links .icon-button:hover {
    background: var(--surface-muted);
    color: var(--primary-strong);
    box-shadow: none;
  }
}

.offer-row__links .icon-button svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

/* Is de lijst zelf smaller dan 800 px, dan past de kolom Geschiedenis niet meer naast de rest: die gaat onder de productnaam.
   Een container query, want hoeveel ruimte de lijst heeft hangt af van het menu links en de filters ernaast, niet van het scherm
   alleen (bij 1280 px met beide open is de lijst ~690 px breed). */
@container (max-width: 799px) {
  .offer-row {
    grid-template-columns: 48px 60px minmax(0, 1fr) 100px 90px 106px;
    row-gap: 2px;
  }

  .offer-row__history {
    grid-column: 3;
    grid-row: 2;
  }

  .offer-row__history:empty {
    display: none;
  }

  .offer-row--head span:nth-child(6) {
    display: none;
  }
}

@media (max-width: 640px) {
  /* Twee kaarten naast elkaar op een telefoon, met een lager plaatje. De compacte lijst blijft één kolom. */
  .product-grid--offers:not(.product-grid--compact) {
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
    gap: 8px;
  }

  .offer-card__thumb {
    height: 110px;
  }

  /* De compacte regel op een telefoon (zo'n 300 pixels voor de regel): links het plaatje met de badge eronder, rechts de naam
     (hooguit twee regels), daaronder de prijs met rechts de prijs per eenheid, en daaronder het prijslabel. */
  .offer-row {
    grid-template-columns: 48px minmax(0, 1fr) auto;
    row-gap: 4px;
  }

  .offer-row .offer-row__thumb {
    grid-column: 1;
    grid-row: 1;
  }

  .offer-row__badge {
    grid-column: 1;
    grid-row: 2 / span 2;
    align-self: start;
  }

  .offer-row .offer-badge {
    width: 48px;
  }

  .offer-row__product {
    grid-column: 2 / span 2;
    grid-row: 1;
  }

  .offer-row__product strong {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    white-space: normal;
  }

  .offer-row__price {
    grid-column: 2;
    grid-row: 2;
  }

  .offer-row__unit {
    grid-column: 3;
    grid-row: 2;
    justify-self: end;
  }

  .offer-row__history {
    grid-column: 2 / span 2;
    grid-row: 3;
    justify-self: start;
  }

  .offer-row__history:empty {
    display: none;
  }

  .offer-row--head,
  .offer-row__links {
    display: none;
  }
}

@media (max-width: 640px) {
  .offers-tools {
    align-items: stretch;
  }

  .offers-tools__search {
    max-width: none;
  }
}

.offers-personal__note {
  margin-top: 10px;
}

.ohc-filter:has(input:disabled) {
  cursor: not-allowed;
  opacity: 0.6;
}

.ohc-filter input:disabled {
  cursor: not-allowed;
}

/* De inzichten bij een aanbieding (#178), sinds 4.8.0 in twee tonen: goed nieuws (laagste prijs in een jaar, en het prijslabel
   laagste ooit of in 12 of 6 maanden) in de groene statuskleur, de rest neutraal (n× dit jaar, boven de laagste van het jaar,
   een andere verpakking die per eenheid goedkoper is). Geel en rood zijn voor waarschuwingen en fouten. Of het echt een aanbieding
   is, zegt de badge op het plaatje. */
.product-card .verdict {
  width: fit-content;
  margin-top: 4px;
  border-radius: var(--radius-pill);
  padding: 1px 8px;
  background: var(--surface-muted);
  box-shadow: inset 0 0 0 1px var(--border);
  color: var(--muted);
  font-size: var(--text-xs);
  font-weight: 600;
}

/* Deze hint loopt vaak over twee of drie regels: een tegel met de radius van een bedieningselement, geen pil. */
.product-card .verdict--pack {
  border-radius: var(--radius-control);
  padding: 3px 8px;
  color: var(--text);
  white-space: normal;
}

.product-card .verdict--year-low {
  background: var(--success-bg);
  box-shadow: inset 0 0 0 1px var(--success-border);
  color: var(--success-text);
}

.product-card .verdict--year-above {
  white-space: normal;
}

/* De rij met inzichten onder de prijs op een kaart: het prijslabel (niet meer op het plaatje) en de chips, naast elkaar. */
.offer-insights {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}

.offer-insights .verdict {
  margin-top: 0;
}

.offer-insights .offer-label {
  position: static;
  max-width: 100%;
}

/* De actie van de winkel ("2 voor 2,99", "1+1 gratis") op een kaart: een vette regel tekst. Eerst was het een rode pil, die
   hetzelfde zei als de badge en rood gebruikte voor iets goeds. .bonus wordt elders ook gebruikt, dus alleen hier. */
.offer-card .bonus {
  margin-top: 4px;
  padding: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: 700;
}

/* De verpakkingen van een product onder de kaart: maat, prijs en prijs per eenheid, de goedkoopste vet, een punt bij een aanbieding. */
.offer-packs {
  display: grid;
  gap: 2px;
  margin: 8px 0 0;
  padding: 6px 0 0;
  border-top: 1px dashed var(--border);
  list-style: none;
  font-size: var(--text-xs);
}

.offer-pack {
  display: flex;
  flex-wrap: wrap;
  gap: 0 8px;
  align-items: baseline;
  min-width: 0;
  padding: 2px 4px;
  border-radius: var(--radius-sm);
  cursor: default;
}

.offer-pack__size {
  white-space: nowrap;
}

.offer-pack--cheapest {
  background: var(--success-bg);
  font-weight: 600;
}

.offer-pack--dimmed {
  opacity: 0.45;
}

.offer-pack__dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin: 0 4px 1px 0;
  border-radius: 50%;
  background: var(--primary);
}

.offer-pack__unit {
  color: var(--muted);
}

.offer-pack__unit b {
  color: var(--success-text);
}

.offer-pack__warning {
  flex-basis: 100%;
  color: var(--warning-text);
}

.offer-packs__note {
  display: block;
  margin-top: 4px;
}

/* Verpakkingen vergelijken: de prijs per eenheid voorop, gekleurd naar plek in de lijst. */
.compare-list {
  display: grid;
  gap: 6px;
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
  max-height: 60vh;
  overflow-y: auto;
}

.compare-item {
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  padding: 6px 8px;
}

.compare-item.is-self {
  border-color: var(--primary);
  background: var(--selection);
}

.compare-item__unit {
  flex: none;
  min-width: 92px;
  border-radius: var(--radius-pill);
  padding: 2px 8px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  text-align: center;
}

.compare-item__body {
  display: grid;
  gap: 2px;
  min-width: 0;
}

/* Productnamen die een link zijn (een kaart van een bestelling, bon of het mandje, en het vergelijkvenster): in de tekstkleur met
   een vage onderstreping, zodat ze ook op een touchscreen als link herkenbaar blijven, en groen bij hover en focus. Een lijst
   vol groene, onderstreepte namen was onrustig. */
.compare-item__body a,
.product-card strong a {
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 30%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color 0.15s var(--ease), text-decoration-color 0.15s var(--ease);
}

.compare-item__body a:focus-visible,
.product-card strong a:focus-visible {
  color: var(--primary);
  text-decoration-color: currentColor;
}

@media (hover: hover) {
  .compare-item__body a:hover,
  .product-card strong a:hover {
    color: var(--primary);
    text-decoration-color: currentColor;
  }
}

@media (prefers-reduced-motion: reduce) {
  .compare-item__body a,
  .product-card strong a {
    transition: none;
  }
}

.compare-item .rank-1,
.compare-item .rank-2 {
  background: var(--success-bg);
  color: var(--success-text);
}

.compare-item .rank-3 {
  background: var(--surface-muted);
  color: var(--text);
}

.compare-item .rank-4 {
  background: var(--warning-bg);
  color: var(--warning-text);
}

.compare-item .rank-5 {
  background: var(--danger-bg);
  color: var(--danger);
}

/* De filters boven de lijst: drie schakelaars en een veld om op naam te filteren. */
.compare-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  margin-top: 8px;
}

.compare-filter {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-md);
}

.compare-filters__text {
  flex: 1 1 160px;
  min-width: 0;
}

.compare-summary {
  margin: 8px 0 0;
  font-weight: 600;
}

.compare-summary:empty {
  display: none;
}

.compare-dialog__note {
  margin: 8px 0 0;
  font-size: var(--text-sm);
}

/* Oude aankopen importeren (#178) */
.ohc-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
}

.ohc-tools .button {
  margin-top: 10px;
}

.import-steps {
  display: grid;
  gap: 14px;
  margin: 0;
  padding-left: 1.3em;
}

.import-steps p {
  margin: 0 0 8px;
}

.import-steps label {
  display: block;
  margin-bottom: 6px;
  font-weight: 600;
}

.import-prompt {
  margin-top: 8px;
}

.import-prompt pre {
  max-height: 220px;
  overflow: auto;
  margin: 8px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  background: var(--surface-muted);
  font-size: var(--text-sm);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.import-data {
  width: 100%;
  min-height: 140px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--text-base);
  resize: vertical;
}

.import-report {
  display: grid;
  gap: 4px;
  max-height: 220px;
  overflow: auto;
  margin: 0;
  padding: 0;
  list-style: none;
}

.import-report li {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 2px 12px;
  padding: 4px 0;
  border-bottom: 1px solid var(--border);
}

.import-report li.is-known small,
.import-report li.is-problem small {
  color: var(--muted);
}

.import-report li.is-new small {
  color: var(--success-text);
  font-weight: 600;
}

.import-dialog__actions {
  flex-wrap: wrap;
}

.import-dialog__spacer {
  flex: 1 1 auto;
}

/* In bulk importeren (recipe_bulk.js): selecteren op de kaarten, een vaste balk eronder en het venster met de voortgang. */
.bulk-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 4px 0 12px;
}

.bulk-tools .button[aria-pressed="true"] {
  border-color: var(--primary);
  box-shadow: inset 0 0 0 1px var(--primary);
}

.bulk-status {
  max-width: 100%;
  white-space: normal;
  text-align: left;
}

.recipe-card.is-selectable {
  position: relative;
  cursor: pointer;
}

.recipe-card.is-selected {
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--primary);
}

.bulk-check {
  position: absolute;
  z-index: 1;
  top: 24px;
  left: 24px;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  box-shadow: var(--shadow-md);
  cursor: pointer;
}

.bulk-check input {
  width: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--primary);
  cursor: pointer;
}

/* Zonder afbeelding staat het vakje voor de titel. */
.recipe-card.is-selectable:not(:has(img)) h3 {
  padding-left: 44px;
}

.recipe-card.is-selectable:not(:has(img)) .bulk-check {
  top: 8px;
  left: 8px;
}

.bulk-bar {
  position: sticky;
  z-index: 5;
  bottom: max(12px, env(safe-area-inset-bottom));
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-md);
}

.bulk-bar__count {
  flex: 1 1 auto;
  font-weight: 600;
}

.bulk-bar__note {
  flex: 1 1 100%;
  margin: 0;
  color: var(--muted);
  font-size: var(--text-md);
}

.bulk-dialog {
  width: min(560px, calc(100vw - 32px));
}

.bulk-intro p {
  margin: 4px 0;
}

.bulk-progress p {
  margin: 0 0 6px;
}

.bulk-progress progress {
  display: block;
  width: 100%;
  height: 10px;
  margin-bottom: 6px;
  accent-color: var(--primary);
}

.bulk-report {
  max-height: min(320px, 40vh);
}

.bulk-report:empty {
  display: none;
}

/* Op een telefoon een lage balk: de knop met het aantal bovenaan, de telling alleen voor schermlezers. */
@media (max-width: 640px) {
  .bulk-bar {
    gap: 6px;
    padding: 8px;
  }

  .bulk-bar__count {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .bulk-bar [data-bulk-import] {
    order: -1;
    flex: 1 1 100%;
  }

  .bulk-bar [data-bulk-all],
  .bulk-bar [data-bulk-clear] {
    flex: 1 1 auto;
    padding: 0 12px;
    white-space: nowrap;
  }
}

/* Instellingen, Weergave (appearance.js): het thema, de donkere achtergrond en de accentkleur. Elke keuze is een echt
   keuzerondje (pijltjestoetsen, schermlezers), alleen anders getekend; de gekozen optie heeft een rand en een vinkje, dus
   niet alleen een kleur. */
.appearance-options {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 0;
  padding: 0;
  border: 0;
}

.appearance-option {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: var(--control-height);
  padding: 8px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-control);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  color: var(--text);
  font-weight: 600;
  cursor: pointer;
  transition: border-color 150ms var(--ease), background-color 150ms var(--ease), box-shadow 150ms var(--ease);
}

.appearance-option input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

@media (hover: hover) {
  .appearance-option:hover {
    border-color: var(--primary);
  }
}

.appearance-option:has(input:checked) {
  border-color: var(--primary);
  background: var(--selection);
  color: var(--primary-strong);
  box-shadow: inset 0 0 0 1px var(--primary);
}

.appearance-option:has(input:focus-visible) {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
}

.appearance-option .mdi {
  width: 20px;
  height: 20px;
  flex: none;
  fill: currentColor;
}

.appearance-option__check {
  display: none;
}

.appearance-option:has(input:checked) .appearance-option__check {
  display: inline-block;
}

/* Een voorbeeld van de donkere achtergrond: het vlak, een kaart en een streepje accent. Altijd donker, ook in het lichte thema. */
.appearance-sample {
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px;
  width: 56px;
  height: 36px;
  padding: 5px;
  border-radius: 6px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12);
}

.appearance-sample i {
  display: block;
  border-radius: 3px;
}

.appearance-sample i:last-child {
  width: 60%;
  height: 4px;
  background: var(--accent-dark, #4cc38a); /* de accentkleur zoals hij in het donkere thema is */
}

.appearance-sample--green {
  background: #0f1613;
}

.appearance-sample--green i:first-child {
  background: #1e2b24;
}

.appearance-sample--grey {
  background: #121314;
}

.appearance-sample--grey i:first-child {
  background: #232527;
}

.appearance-swatches {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 12px 0 0;
  padding: 0;
  border: 0;
}

.appearance-swatches__list {
  display: contents;
}

.appearance-swatch {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: var(--control-height);
  height: var(--control-height);
  border-radius: 50%;
  background: var(--swatch);
  box-shadow: inset 0 0 0 1px rgba(var(--shadow-ink), 0.18);
  color: var(--swatch-on);
  cursor: pointer;
  transition: transform 150ms var(--ease), box-shadow 150ms var(--ease);
}

.appearance-swatch input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.appearance-swatch .mdi {
  display: none;
  width: 22px;
  height: 22px;
  fill: currentColor;
}

.appearance-swatch:has(input:checked) {
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--text);
}

.appearance-swatch:has(input:checked) .mdi {
  display: block;
}

.appearance-swatch:has(input:focus-visible) {
  outline: 3px solid var(--primary);
  outline-offset: 5px;
}

@media (hover: hover) {
  .appearance-swatch:hover {
    transform: scale(1.06);
  }
}

/* Eigen kleur: de kleurkiezer van het apparaat in een rondje, met een regenboog zolang hij niet gekozen is. */
.appearance-custom {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  font-weight: 600;
  cursor: pointer;
}

.appearance-custom__dot {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: var(--control-height);
  height: var(--control-height);
  border-radius: 50%;
  background: conic-gradient(#e5484d, #d9730d, #f2cf45, #2f9e44, #0c9aa6, #0a84ff, #6c5ce7, #bf5af2, #e5484d);
  box-shadow: inset 0 0 0 1px rgba(var(--shadow-ink), 0.18);
  color: var(--swatch-on, #fff);
}

.appearance-custom.is-chosen .appearance-custom__dot {
  background: var(--swatch);
  box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--text);
}

.appearance-custom__dot .mdi {
  display: none;
  width: 22px;
  height: 22px;
  fill: currentColor;
}

.appearance-custom.is-chosen .appearance-custom__dot .mdi {
  display: block;
}

.appearance-custom input[type="color"] {
  position: absolute;
  inset: 0;
  width: var(--control-height);
  height: var(--control-height);
  opacity: 0;
  cursor: pointer;
}

.appearance-custom:has(input:focus-visible) .appearance-custom__dot {
  outline: 3px solid var(--primary);
  outline-offset: 5px;
}

.appearance-current {
  margin: 14px 0 0;
  color: var(--muted);
  font-size: var(--text-md);
}

.appearance-current strong {
  color: var(--text);
}

.appearance-current code {
  font-size: var(--text-sm);
}

.appearance-actions {
  margin-top: 14px;
}

@media (prefers-reduced-motion: reduce) {
  .appearance-option,
  .appearance-swatch {
    transition: none;
  }

  @media (hover: hover) {
    .appearance-swatch:hover {
      transform: none;
    }
  }
}

/* Instellingen, Weergave, Navigatiebalk: een kleine tekening van beide balken, en de schuif voor het glas. */
.appearance-navsample {
  position: relative;
  display: block;
  width: 36px;
  height: 44px;
  overflow: hidden;
  border-radius: 7px;
  background: var(--surface-muted);
  box-shadow: inset 0 0 0 1px var(--border-strong);
}

.appearance-navsample i {
  position: absolute;
  display: block;
}

.appearance-navsample--ios i {
  left: 4px;
  right: 4px;
  bottom: 4px;
  height: 9px;
  border-radius: 5px;
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--border-strong), 0 2px 4px rgba(var(--shadow-ink), 0.18);
}

.appearance-navsample--android i {
  left: 0;
  right: 0;
  bottom: 0;
  height: 11px;
  background: color-mix(in srgb, var(--surface) 80%, var(--primary));
  box-shadow: 0 -1px 0 var(--border-strong);
}

.appearance-navsample--android i::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 2px;
  width: 12px;
  height: 5px;
  border-radius: 3px;
  background: var(--primary);
  transform: translateX(-50%);
}

.appearance-glass {
  margin-top: 14px;
}

.appearance-glass__label {
  display: block;
  font-weight: 700;
}

.appearance-glass .muted {
  margin: 4px 0 8px;
}

.appearance-glass__control {
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 420px;
}

.appearance-glass__control input[type="range"] {
  flex: 1;
  min-width: 120px;
  min-height: var(--control-height);
  accent-color: var(--primary);
}

.appearance-glass__control output {
  min-width: 3.2em;
  text-align: right;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* De regel bij een AI-sleutel kan een lang adres zonder spaties bevatten (OPENAI_BASE_URL): op een smal scherm afbreken waar het moet. */
.ai-review__status {
  overflow-wrap: anywhere;
}

/* Compacte inklapbare blokken: Instellingen, Weergave (Voorkeuren en Thema) en Instellingen, Koppelen (Aanbiedingen, de
   AI-beoordeling, Mealie en de winkels). Dicht is een blok alleen zijn kop: minder ruimte eromheen, de knop blijft 44 px hoog.
   Open lopen de onderdelen door, gescheiden door een lijn (.fold__section), met een tussenkop van 16 px onder de kop van 18 px. */
.box.fold--compact {
  margin-bottom: 12px;
  padding: 8px 20px;
}

.box.fold--compact:has(> .fold__title > .fold__toggle[aria-expanded="true"]) {
  padding-bottom: 20px;
}

.fold--compact .fold__title {
  font-size: var(--text-lg);
}

.fold--compact .fold__body {
  margin-top: 4px;
}

.fold--compact .fold__section {
  margin-top: 18px;
  padding-top: 14px;
}

.fold--compact .fold__body h3 {
  margin: 0 0 2px;
  font-size: var(--text-base);
}

/* Een schakelaar binnen een onderdeel (Supermarkt, Weekplanner van de AH-app): een kleinere kop en wat ruimte ertussen. */
.fold--compact .fold__body h4 {
  margin: 0 0 2px;
  font-size: var(--text-ui);
}

.appearance-section .appearance-setting {
  margin-top: 12px;
}

/* Een klein getal naast de uitleg (Porties per recept): smal, en het blijft rechts zoals een schakelaar. */
.appearance-number {
  flex: none;
  width: 5.5rem;
}

.appearance-section > .muted,
.appearance-setting .muted {
  margin: 0;
  font-size: var(--text-md);
}

.appearance-sublabel {
  margin: 14px 0 0;
  color: var(--muted);
  font-size: var(--text-md);
  font-weight: 600;
}

/* Een instelling met een schakelaar rechts: de naam en uitleg links. */
.appearance-setting {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.appearance-setting__text {
  min-width: 0;
}

/* Een schakelaar: een echt selectievakje (role="switch", toetsenbord en schermlezer werken zoals altijd), getekend als een
   schuifje. Aan is gevuld in de accentkleur met het bolletje rechts; uit is een rand met het bolletje links. */
.switch {
  position: relative;
  flex: none;
  width: 52px;
  height: 32px;
  margin: 6px 0;
  border: 2px solid var(--placeholder); /* 3 : 1 of meer: de rand van een bediening moet je zien */
  border-radius: var(--radius-pill);
  background: var(--surface-muted);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color 150ms var(--ease), border-color 150ms var(--ease);
}

.switch::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--muted);
  transform: translateY(-50%);
  transition: transform 150ms var(--ease), background-color 150ms var(--ease);
}

.switch:checked {
  border-color: var(--primary);
  background: var(--primary);
}

.switch:checked::before {
  background: var(--on-primary);
  transform: translate(20px, -50%);
}

.switch:focus-visible {
  outline: 3px solid var(--primary);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .switch,
  .switch::before {
    transition: none;
  }
}

/* Tikvlakken van 44 px op een aanraakscherm (sinds 4.12.0). De kleine knoppen (min en plus, het potlood en de plus in het
   weekmenu, verwijderen bij een aankoop, de iconen in de compacte aanbiedingenlijst) houden hun maat, zodat de regels niet
   hoger worden; hun tikvlak is groter, met een onzichtbaar vlak eromheen. Met een muis verandert er niets. */
@media (pointer: coarse) {
  .qty__step,
  .day-card__add--compact,
  .product-card .product-link,
  .purchase-table__action,
  .offer-row__links .icon-button {
    position: relative;
  }

  .qty__step::after,
  .meal__edit::after,
  .day-card__add--compact::after,
  .product-card .product-link::after,
  .purchase-card__action::after,
  .purchase-overview__action::after,
  .purchase-table__action::after,
  .offer-row__links .icon-button::after,
  .list-card__action::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
  }

  .ohc-range-button,
  details.help > summary,
  .user-menu__item {
    min-height: 44px;
  }
}

/* De installatiehulp: welke winkels gebruik je? (sinds 4.13.0). Een regel per winkel, het hele vlak is het vinkje. */
.ob-stores {
  display: grid;
  gap: 8px;
  margin: 14px 0;
  padding: 0;
  border: 0;
}

.ob-store {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  cursor: pointer;
}

.ob-store:has(input:checked) {
  border-color: var(--primary);
  background: var(--selection);
}

.ob-store input {
  width: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--primary);
}

.ob-store strong,
.ob-store small {
  display: block;
}

.ob-store small {
  margin-top: 2px;
  color: var(--muted);
  font-size: var(--text-sm);
}
