/* ═══ THE RECIPE LIBRARY ═══════════════════════════════════════════════
   Built on the shop's own variables so it inherits the site's colours and
   dark mode rather than declaring a second palette that drifts from the
   first. */

.rz-index, .rz-page { max-width: 1000px; margin: 0 auto; padding: 1.5rem 1.25rem 3rem; }
.rz-index-head { text-align: center; margin-bottom: 1.5rem; }
.rz-index-head h1 { color: var(--color-primary); margin-bottom: .5rem; }
.rz-index-head p { color: var(--color-muted); max-width: 620px; margin: 0 auto; line-height: 1.65; }

/* ── the filters ─────────────────────────────────────────────────────── */
.rz-filters {
  border: 1px solid var(--admin-border); border-radius: 14px;
  background: var(--color-bg-alt); padding: 1rem; margin-bottom: 1.75rem;
}
.rz-search-row { margin-bottom: .9rem; }
#rzSearch {
  width: 100%; padding: .7rem .9rem; font-size: 16px;
  border: 1px solid var(--admin-border); border-radius: 10px;
  background: var(--color-bg); color: var(--color-text);
}
.rz-facet { border: 0; padding: 0; margin: 0 0 .8rem; }
.rz-facet legend {
  font-size: .78rem; font-weight: 700; color: var(--color-muted);
  text-transform: uppercase; letter-spacing: .04em; padding: 0; margin-bottom: .4rem;
}
.rz-facet-note { text-transform: none; letter-spacing: 0; font-weight: 400; }
.rz-chips { display: flex; flex-wrap: wrap; gap: .35rem; }
.rz-chip {
  border: 1px solid var(--admin-border); border-radius: 999px;
  background: var(--color-bg); color: var(--color-text);
  font-size: .82rem; padding: .35rem .75rem; cursor: pointer;
  min-height: 34px; line-height: 1.2;
}
.rz-chip:hover { border-color: var(--color-primary); }
.rz-chip.is-on { background: var(--color-primary); border-color: var(--color-primary); color: #fff; font-weight: 600; }
/* "Ohne Milch" is a removal, not a selection, so it reads red rather than
   green when it is on - the same colour language as a warning. */
.rz-chip-avoid.is-on { background: #B3574D; border-color: #B3574D; }
.rz-filter-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: .75rem; padding-top: .6rem; border-top: 1px solid var(--admin-border);
  font-size: .85rem; color: var(--color-muted); flex-wrap: wrap;
}
.rz-reset {
  border: 1px solid var(--admin-border); border-radius: 999px; background: none;
  color: var(--color-muted); font-size: .8rem; padding: .3rem .8rem; cursor: pointer;
}
.rz-reset:hover { color: var(--color-primary); border-color: var(--color-primary); }

/* ── the quickbar ────────────────────────────────────────────────────────
   Sticky rather than fixed: it settles just under the site header once you
   scroll past it and stays there through all 76 cards, instead of floating
   over content that was never laid out to sit under a fixed bar. Three
   things live here because they are the three a phone in a shop actually
   reaches for mid-scroll: how many match, a way to stop choosing, a way
   back up to the filters. */
.rz-quickbar {
  position: sticky; top: var(--nav-height, 72px); z-index: 60;
  display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; flex-wrap: wrap;
  background: var(--color-bg-alt); border: 1px solid var(--admin-border);
  border-radius: 12px; padding: .55rem .8rem; margin-bottom: .9rem;
  box-shadow: 0 4px 14px rgba(0,0,0,.05);
  font-size: .85rem; font-weight: 600; color: var(--color-heading);
}
.rz-quickbar-actions { display: flex; gap: .4rem; flex-wrap: wrap; }
.rz-quickbar-btn {
  border: 1px solid var(--admin-border); border-radius: 999px;
  background: var(--color-bg); color: var(--color-text);
  font-size: .8rem; font-weight: 600; padding: .4rem .7rem; cursor: pointer;
  min-height: 36px; white-space: nowrap;
}
.rz-quickbar-btn:hover { border-color: var(--color-primary); color: var(--color-primary); }
.rz-quickbar-btn:active { transform: scale(.95); }
.rz-surprise { background: var(--color-accent-light, #FCEEDD); border-color: transparent; }
#rzFilterToggle[aria-expanded="false"] { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }

/* Retriggered on every filter change (rezepte-filter.js adds and removes the
   class) so the number itself gives feedback that a tap landed, not just the
   chip that was pressed. */
@keyframes rzPulse { 0% { transform: scale(1); } 35% { transform: scale(1.18); } 100% { transform: scale(1); } }
@media (prefers-reduced-motion: no-preference) {
  #rzCount.rz-count-pulse { animation: rzPulse .32s ease; display: inline-block; }
}

/* ── the level row: the one facet that is never folded away ─────────── */
.rz-facet-level .rz-chips { gap: .5rem; }
.rz-facet-level .rz-chip {
  font-size: .88rem; padding: .55rem 1rem; font-weight: 600;
  border-width: 1.5px;
}
.rz-chip-count {
  font-size: .72em; font-weight: 700; opacity: .65; margin-left: .1rem;
}
.rz-chip.is-on .rz-chip-count { opacity: .85; }

/* ── the fold-away panel ──────────────────────────────────────────────
   A plain <details>: closed, its content is not merely invisible but out of
   the layout and out of the accessibility tree, which is exactly what "the
   rest of the filters" should be on a phone until asked for. Open by
   default in the markup - JS closes it on narrow screens as an enhancement,
   so a page that never runs JavaScript still shows every filter, same as
   before this existed. */
.rz-more { border: 0; margin: 0 0 .8rem; }
.rz-more-toggle {
  display: flex; align-items: center; gap: .4rem; cursor: pointer;
  list-style: none; font-size: .82rem; font-weight: 700; color: var(--color-muted);
  padding: .3rem 0; user-select: none;
}
.rz-more-toggle::-webkit-details-marker { display: none; }
.rz-more-toggle::marker { content: ""; }
.rz-more-toggle:hover { color: var(--color-primary); }
.rz-more-badge {
  background: var(--color-primary); color: #fff; font-size: .68rem; font-weight: 700;
  border-radius: 999px; min-width: 1.3rem; height: 1.3rem; padding: 0 .35rem;
  display: inline-flex; align-items: center; justify-content: center;
}
/* Higher specificity than the rule above on purpose - see the identical note
   on .rz-sticky-shop[hidden]. An unconditional "display: inline-flex" on the
   bare class beats the browser's own [hidden]{display:none} default (author
   CSS always outranks a UA default, regardless of specificity), so at zero
   active filters this badge showed a red "0" instead of vanishing - caught by
   looking at the actual rendered page on a phone, not by reading the code. */
.rz-more-badge[hidden] { display: none; }
.rz-more-chevron { transition: transform .2s ease; margin-left: auto; }
.rz-more[open] > .rz-more-toggle .rz-more-chevron { transform: rotate(180deg); }
.rz-more-body { padding-top: .5rem; }

/* ── touch feedback everywhere a card or chip is the thing being pressed ── */
@media (hover: none) {
  .rz-card:active { transform: scale(.97); }
  .rz-chip:active { transform: scale(.94); }
}
@keyframes rzPickPulse {
  0% { box-shadow: 0 0 0 0 rgba(47,93,70,.55); }
  100% { box-shadow: 0 0 0 14px rgba(47,93,70,0); }
}
@media (prefers-reduced-motion: no-preference) {
  .rz-card-picked { animation: rzPickPulse .65s ease-out; border-color: var(--color-primary); }
}

/* ── sections and cards ──────────────────────────────────────────────── */
.rz-section { margin-bottom: 2.25rem; }
.rz-section h2 {
  color: var(--color-primary); font-size: 1.2rem;
  margin: 0 0 .2rem; display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
}
.rz-section-note { font-size: .82rem; font-weight: 400; color: var(--color-muted); }
.rz-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: .85rem; margin-top: .9rem;
}
.rz-card {
  display: flex; gap: .8rem; align-items: flex-start;
  border: 1px solid var(--admin-border); border-radius: 14px;
  background: var(--color-bg-alt); padding: .8rem; text-decoration: none;
  color: inherit; transition: transform .15s ease, box-shadow .15s ease;
}
.rz-card:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(0,0,0,.09); }
.rz-thumb { flex: 0 0 auto; line-height: 0; }
.rz-thumb svg { border-radius: 12px; display: block; }
.rz-card-body { min-width: 0; flex: 1; }
.rz-card-body h3 { margin: 0 0 .15rem; font-size: 1rem; color: var(--color-primary); line-height: 1.3; }
.rz-sub { margin: 0 0 .45rem; font-size: .82rem; color: var(--color-muted); line-height: 1.45; }

.rz-badges { display: flex; flex-wrap: wrap; gap: .25rem; }
.rz-badge {
  font-size: .68rem; padding: .12rem .45rem; border-radius: 999px;
  background: var(--color-bg); border: 1px solid var(--admin-border); color: var(--color-muted);
  white-space: nowrap;
}
.rz-lv-anfaenger { color: #2F7D4F; border-color: #A9D6BB; }
.rz-lv-mittel { color: #B5751E; border-color: #E6C68C; }
.rz-lv-profi { color: #9C3D1B; border-color: #E0AE99; }
.rz-diet-vegan { color: #2F7D4F; border-color: #A9D6BB; }

.rz-empty { text-align: center; color: var(--color-muted); padding: 2rem 0; }

/* ── one recipe ──────────────────────────────────────────────────────── */
.rz-crumbs { margin-bottom: 1rem; font-size: .88rem; }
.rz-crumbs a { color: var(--color-muted); text-decoration: none; }
.rz-crumbs a:hover { color: var(--color-primary); }

/* Language toggle - German at the root, English at /en/rezepte/ (see
   AGENTS.md 8.170). Small and out of the way on purpose: it's a switch
   somebody reaches for once per visit, not a second nav bar. */
.rz-lang-switch { margin-bottom: 1.25rem; font-size: .85rem; color: var(--color-muted); }
.rz-lang-switch a { color: var(--color-primary); text-decoration: none; font-weight: 600; }
.rz-lang-switch a:hover { text-decoration: underline; }
.rz-lang-switch .rz-lang-current { font-weight: 600; color: var(--color-text, #222); }
.rz-index-head .rz-lang-switch { margin: .5rem 0 1rem; }
.rz-head { display: flex; gap: 1.1rem; align-items: flex-start; margin-bottom: 1rem; }
.rz-head-thumb { flex: 0 0 auto; line-height: 0; }
.rz-head-thumb svg { border-radius: 16px; display: block; }
.rz-head h1 { color: var(--color-primary); margin: 0 0 .25rem; line-height: 1.2; }
.rz-head .rz-sub { font-size: .95rem; margin-bottom: .55rem; }
.rz-intro { font-size: 1.02rem; line-height: 1.75; margin: 0 0 1rem; }
.rz-level-note {
  background: var(--color-bg-alt); border-left: 3px solid var(--color-primary);
  padding: .6rem .85rem; border-radius: 0 8px 8px 0; font-size: .88rem;
  line-height: 1.6; margin: 0 0 1.2rem;
}
.rz-facts {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: .5rem;
  border: 1px solid var(--admin-border); border-radius: 12px;
  padding: .8rem; margin-bottom: 1rem; background: var(--color-bg-alt);
}
.rz-facts div { text-align: center; min-width: 0; }
.rz-facts span { display: block; font-size: .7rem; color: var(--color-muted); text-transform: uppercase; letter-spacing: .04em; }
.rz-facts b { font-size: .98rem; overflow-wrap: anywhere; }

/* The allergen block is a promise, so it is styled as a notice rather than as
   decoration - and the caveat is never smaller than legible. */
.rz-allergens {
  border: 1px solid #E0AE99; background: #FDF3EF; color: #7A3A28;
  border-radius: 12px; padding: .75rem .9rem; margin-bottom: 1.4rem; font-size: .88rem; line-height: 1.6;
}
.rz-allergens-none { border-color: #A9D6BB; background: #EFF7F1; color: #2F5D46; }
.rz-allergen {
  display: inline-block; background: #fff; border: 1px solid currentColor;
  border-radius: 999px; padding: .05rem .5rem; margin: 0 .2rem .2rem 0; font-size: .82rem;
}
.rz-allergen-note { display: block; margin-top: .35rem; font-size: .78rem; opacity: .85; }

.rz-cols { display: grid; grid-template-columns: minmax(220px, 1fr) 2fr; gap: 1.75rem; }
.rz-cols h2, .rz-tips h2, .rz-shop h2, .rz-related h2 {
  color: var(--color-primary); font-size: 1.08rem; margin: 0;
}

/* ── the cook-along checklist ─────────────────────────────────────────
   A recipe on a phone is read once and then propped against something while
   the hands are busy - it is worth more as a checklist than as prose from
   that point on. Ticks are kept per recipe in localStorage (rezepte-cook.js)
   so leaving to check the shop tab does not lose the place. */
.rz-progress-head { display: flex; align-items: baseline; justify-content: space-between; gap: .6rem; margin-bottom: .4rem; }
.rz-progress-text { font-size: .78rem; font-weight: 700; color: var(--color-muted); white-space: nowrap; }
.rz-progress-track {
  height: 6px; border-radius: 999px; background: var(--admin-border);
  overflow: hidden; margin-bottom: .7rem;
}
.rz-progress-fill {
  height: 100%; width: 0%; background: var(--color-primary); border-radius: 999px;
}
@media (prefers-reduced-motion: no-preference) { .rz-progress-fill { transition: width .25s ease; } }
.rz-progress-fill.is-complete { background: #2F7D4F; }

.rz-ing-list { list-style: none; padding: 0; margin: 0; }
.rz-ing-item { border-bottom: 1px dashed var(--admin-border); }
.rz-ing-item label {
  display: flex; align-items: baseline; gap: .55rem; padding: .5rem .1rem;
  font-size: .92rem; line-height: 1.5; cursor: pointer;
}
.rz-ing-check {
  flex: 0 0 auto; width: 20px; height: 20px; margin: .1rem 0 0; accent-color: var(--color-primary);
  cursor: pointer;
}
.rz-qty { flex: 0 0 5.2rem; font-weight: 600; color: var(--color-primary); }
/* :has() only styles the strike-through; the checkbox itself works with no
   support for it at all, so a browser without it just shows a plain tick. */
.rz-ing-item:has(.rz-ing-check:checked) .rz-ing-name,
.rz-ing-item:has(.rz-ing-check:checked) .rz-qty { text-decoration: line-through; opacity: .5; }

.rz-step-list { list-style: none; padding: 0; margin: 0; counter-reset: none; }
.rz-step-item { display: flex; gap: .7rem; align-items: flex-start; margin-bottom: .85rem; }
.rz-step-num {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%;
  border: 1.5px solid var(--color-primary); background: var(--color-bg);
  color: var(--color-primary); font-weight: 700; font-size: .88rem;
  cursor: pointer; line-height: 1; display: flex; align-items: center; justify-content: center;
}
.rz-step-num:active { transform: scale(.9); }
.rz-step-item.is-done .rz-step-num { background: var(--color-primary); color: #fff; }
.rz-step-text { line-height: 1.7; padding-top: .2rem; }
.rz-step-item.is-done .rz-step-text { text-decoration: line-through; opacity: .55; }

.rz-mini-reset {
  border: 0; background: none; color: var(--color-muted); font-size: .78rem;
  padding: .5rem 0 0; cursor: pointer; text-decoration: underline;
}
.rz-mini-reset:hover { color: var(--color-primary); }

/* One small delight when a list is finished, rather than only a full bar -
   a full progress bar reads as "done" only if you already know what full
   looks like; a sentence does not require that. */
.rz-progress-done {
  font-size: .78rem; font-weight: 700; color: #2F7D4F; margin: -.3rem 0 .5rem;
}
.rz-tips { margin-top: 1.75rem; background: var(--color-bg-alt); border-radius: 12px; padding: 1rem 1.1rem; }
.rz-tips ul { margin: 0; padding-left: 1.1rem; }
.rz-tips li { margin-bottom: .5rem; line-height: 1.65; }
.rz-shop { margin-top: 1.75rem; text-align: center; }
.rz-shop-links { display: flex; flex-wrap: wrap; gap: .35rem; justify-content: center; margin: .7rem 0 1rem; }
.rz-shop-link {
  border: 1px solid var(--admin-border); border-radius: 999px; padding: .3rem .8rem;
  font-size: .84rem; text-decoration: none; color: var(--color-text); background: var(--color-bg-alt);
}
.rz-shop-link:hover { border-color: var(--color-primary); color: var(--color-primary); }
.rz-related { margin-top: 2.25rem; }

/* ── the mobile-only shop shortcut ────────────────────────────────────
   Fixed, but only for as long as the real "Zutaten im Shop" section further
   down is out of view (rezepte-cook.js toggles [hidden] with an
   IntersectionObserver) - a shortcut back to it while reading, not a second
   copy of it sitting permanently over whatever the page ends on. */
.rz-sticky-shop {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 500;
  padding: .6rem .9rem calc(.6rem + env(safe-area-inset-bottom, 0px));
  background: var(--color-bg-alt); border-top: 1px solid var(--admin-border);
  box-shadow: 0 -4px 16px rgba(0,0,0,.08);
}
.rz-sticky-shop-btn {
  display: block; text-align: center; background: var(--color-primary); color: #fff;
  border-radius: 999px; padding: .75rem 1rem; font-weight: 700; text-decoration: none;
}
.rz-sticky-shop-btn:active { transform: scale(.98); }

.rz-footer {
  margin-top: 3rem; padding: 2rem 1rem; border-top: 1px solid var(--admin-border);
  text-align: center; color: var(--color-muted); font-size: .88rem;
}
.rz-footer a { color: inherit; }

/* The sticky shop bar is a phone affordance - on a desktop the shop section
   is a short scroll away already, and a bar fixed over the bottom of a wide
   window reads as a stray banner rather than a shortcut. */
.rz-sticky-shop { display: none; }

@media (max-width: 720px) {
  /* One column, and the ingredient quantity stops reserving a fixed width it
     no longer has room for. */
  .rz-cols { grid-template-columns: 1fr; gap: 1.25rem; }
  .rz-facts { grid-template-columns: repeat(2, 1fr); }
  .rz-head { flex-direction: column; gap: .8rem; }
  .rz-qty { flex-basis: 4.4rem; }
  .rz-grid { grid-template-columns: 1fr; }

  .rz-sticky-shop { display: block; }
  /* Higher specificity than the rule above on purpose: [hidden] is a normal-
     priority author rule here, not the (lower-priority) UA default, and it
     has to win over "display: block" once rezepte-cook.js sets the
     attribute - the whole point of the attribute is to be able to hide this
     again while the real shop section is on screen. */
  .rz-sticky-shop[hidden] { display: none; }
  /* Room at the bottom of the page so the fixed bar never sits over the
     tips, the real shop section or the related recipes it is a shortcut to.
     #rzStickyShop is on every recipe page, so this is unconditional rather
     than :has()-guarded - simpler, and it costs nothing on the index page,
     which uses .rz-index instead of .rz-page and never sees this rule. */
  .rz-page { padding-bottom: 5rem; }

  .rz-quickbar { top: calc(var(--nav-height, 72px) - 1px); }
  .rz-quickbar-btn { font-size: .78rem; padding: .45rem .6rem; }
}

/* Product cards under each ingredient in the shop section */
.rz-shop-grid { text-align: left; margin: .9rem 0 .5rem; display: grid; gap: 1rem; }
.rz-shop-term h3 { margin: 0 0 .4rem; font-size: .95rem; }
.rz-pcards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .5rem; }
.rz-pcard {
  display: flex; flex-direction: column; gap: .25rem; text-decoration: none; color: var(--color-text);
  border: 1px solid var(--admin-border); border-radius: 12px; padding: .5rem; background: var(--color-bg-alt);
}
.rz-pcard:hover { border-color: var(--color-primary); }
.rz-pcard-img { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; background: #fff; border-radius: 8px; overflow: hidden; font-size: 1.6rem; }
.rz-pcard-img img { width: 100%; height: 100%; object-fit: contain; }
.rz-pcard-name { font-size: .8rem; line-height: 1.3; overflow-wrap: anywhere; }
.rz-pcard-price { font-size: .85rem; font-weight: 700; color: var(--color-primary); }
@media (min-width: 700px) { .rz-shop-grid { grid-template-columns: 1fr 1fr; } }

/* Recommended products right under an ingredient line */
.rz-ing-prods { display: flex; flex-wrap: wrap; gap: .4rem; padding: 0 0 .6rem 2.1rem; }
.rz-ing-prod {
  display: flex; align-items: center; gap: .5rem; min-width: 0; max-width: 100%; flex: 1 1 13rem;
  text-decoration: none; color: var(--color-text);
  border: 1px solid var(--admin-border); border-radius: 10px; padding: .3rem .5rem .3rem .3rem; background: var(--color-bg-alt);
}
.rz-ing-prod:hover { border-color: var(--color-primary); }
.rz-ing-prod-img { flex: none; width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; background: #fff; border-radius: 8px; overflow: hidden; }
.rz-ing-prod-img img { width: 100%; height: 100%; object-fit: contain; }
.rz-ing-prod-txt { display: flex; flex-direction: column; min-width: 0; }
.rz-ing-prod-name { font-size: .8rem; line-height: 1.25; overflow-wrap: anywhere; }
.rz-ing-prod-price { font-size: .82rem; font-weight: 700; color: var(--color-primary); }
