/* Public Recipes site — styles for /recipes, /recipes/cuisine/*,
   /recipes/tag/*, /recipes/collections/*, /recipe/[slug-id].

   Ports the desktop sidebar + responsive grid from
   apps/mobile/components/RecipesDesktopView.tsx and the card design from
   RecipeSearchGrid, layered onto the landing's Lora/Nunito + brand-green
   palette so the public site reads as one cohesive product.

   All colors + spacing reference --prepful-* CSS custom properties from
   landing/css/tokens.generated.css (loaded before this file). */

* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: 'Nunito', system-ui, -apple-system, sans-serif;
  background: var(--prepful-bg, #FDFCFA);
  color: var(--prepful-text-primary, #2C2925);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
a { color: inherit; text-decoration: none; }
img { display: block; max-width: 100%; }

/* --- Site chrome (shared header/footer) ---------------------------------- */
/* Three-column grid keeps the section nav truly centered regardless of how
   wide the logo or actions group is. Equal 1fr side rails balance the
   middle column; on narrow screens we collapse the right rail to keep the
   logo + nav visible without horizontal scroll. */
.site-header {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  /* Push the chrome below the iPhone safe-area inset so the centered nav
     can't sit under the Dynamic Island. Pair with viewport-fit=cover in
     the shell <meta> for this to actually take effect on notched iPhones. */
  padding: calc(10px + env(safe-area-inset-top)) 24px 10px;
  border-bottom: 1px solid var(--prepful-bg-secondary, #F7F5F2);
  background: var(--prepful-bg, #FDFCFA);
}
.logo {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'Lora', serif;
  font-weight: 600;
  font-size: 18px;
  color: var(--prepful-text-primary, #2C2925);
  justify-self: start;
}
.logo img { width: 28px; height: 28px; border-radius: 6px; }
.site-header__nav {
  display: flex;
  align-items: center;
  gap: 28px;
  justify-self: center;
}
.site-header__actions {
  display: flex;
  align-items: center;
  gap: 16px;
  justify-self: end;
}
.site-header__link {
  font-size: 14px;
  font-weight: 600;
  color: var(--prepful-text-secondary, #5C5752);
  transition: color 0.15s;
  /* Reserve the active-state border height up-front so the row doesn't
     reflow vertically when switching between sections. */
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
  /* iPhone bug fix (mirrors landing index.html header-nav__link): the
     plain 14px text gave only ~26px of tap height — well below Apple's
     44pt minimum. Real iPhone users reported "tapping Recipes did
     nothing" because they were missing the link. Inflate the vertical
     hit area without changing the visible style. */
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  padding-top: 10px;
  padding-bottom: 12px;
  -webkit-tap-highlight-color: rgba(45, 134, 89, 0.18);
}
/* Reserve a stable horizontal hit area on the section nav links (Home /
   Recipes) so the fallback-→-Nunito web-font swap can't pull the link
   narrower under a tapping finger. Scoped to .site-header__nav so the
   "Sign in" link in .site-header__actions (which lives in a different
   layout column) isn't widened. Mirrors the landing index.html fix. */
.site-header__nav .site-header__link {
  min-width: 56px;
  justify-content: center;
}
.site-header__link--active {
  color: var(--prepful-primary, #2D8659);
  font-weight: 700;
  border-bottom-color: var(--prepful-primary, #2D8659);
}
.site-header__link:hover { color: var(--prepful-primary, #2D8659); }
.site-header__cta {
  padding: 8px 16px;
  background: var(--prepful-primary, #2D8659);
  color: #fff;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  transition: background 0.15s;
}
.site-header__cta:hover { background: var(--prepful-primary-dark, #1E6B45); }

/* Narrow viewports: drop Sign in to keep room for the centered nav.
   Get-the-app stays as the primary CTA. */
@media (max-width: 540px) {
  .site-header { padding: 10px 16px; grid-template-columns: 1fr auto 1fr; }
  .site-header__nav { gap: 18px; }
  .site-header__actions .site-header__link { display: none; }
}

.site-footer {
  padding: 64px 48px 48px;
  text-align: center;
  color: var(--prepful-text-tertiary, #6B6660);
  font-size: 14px;
  border-top: 1px solid var(--prepful-bg-secondary, #F7F5F2);
  margin-top: 96px;
}
.site-footer a { color: var(--prepful-primary, #2D8659); }

/* --- Page wrappers ------------------------------------------------------- */
.recipes-page {
  max-width: 1600px;
  margin: 0 auto;
  padding: 0 48px 80px;
}
/* Tighten the page gutter on phones — the 48px desktop padding eats ~25%
   of a 375px viewport, pushing cards and the search form awkwardly narrow.
   Match the rest of the landing site's mobile gutter (16px) so card art
   nearly reaches the screen edge. */
@media (max-width: 720px) {
  .recipes-page { padding: 0 16px 56px; }
}

/* --- Breadcrumb (only on /recipes/all — back to curated picks) ---------- */
.recipes-breadcrumb {
  padding: 24px 0 0;
  margin-bottom: -8px;
}
.recipes-breadcrumb__link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 14px;
  font-weight: 600;
  color: var(--prepful-primary, #2D8659);
  text-decoration: none;
  transition: color 0.15s;
}
.recipes-breadcrumb__link:hover { color: var(--prepful-primary-dark, #1E6B45); }
.recipes-breadcrumb__link:focus-visible {
  outline: 2px solid var(--prepful-primary, #2D8659);
  outline-offset: 2px;
  border-radius: 4px;
}

/* --- Hero band (only on /recipes root, suppressed on hubs/collections) --- */
.recipes-hero {
  padding: 40px 0 28px;
  border-bottom: 1px solid var(--prepful-bg-secondary, #F7F5F2);
  margin-bottom: 28px;
}
.recipes-hero__inner {
  max-width: 720px;
}
.recipes-hero__heading {
  font-family: 'Lora', serif;
  font-weight: 600;
  font-size: 40px;
  line-height: 1.1;
  margin: 0 0 12px;
  color: var(--prepful-text-primary, #2C2925);
  letter-spacing: -0.01em;
}
.recipes-hero__heading em {
  color: var(--prepful-primary, #2D8659);
  font-style: normal;
}
.recipes-hero__sub {
  font-size: 16px;
  color: var(--prepful-text-secondary, #5C5752);
  margin: 0 0 20px;
  max-width: 560px;
}
/* Tighter hero on phones — drop the heading + padding so cards reach
   the viewport faster. */
@media (max-width: 720px) {
  .recipes-hero { padding: 24px 0 20px; margin-bottom: 20px; }
  .recipes-hero__heading { font-size: 30px; }
  .recipes-hero__sub { font-size: 15px; margin-bottom: 16px; }
}
.recipes-hero__searchform {
  display: flex;
  align-items: stretch;
  gap: 0;
  max-width: 520px;
  border: 1px solid var(--prepful-border, #E5E0DA);
  border-radius: 999px;
  background: var(--prepful-surface, #FFFFFF);
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
  transition: box-shadow 0.18s, border-color 0.18s;
}
.recipes-hero__searchform:focus-within {
  border-color: var(--prepful-primary, #2D8659);
  box-shadow: 0 4px 16px rgba(45, 134, 89, 0.12);
}
.recipes-hero__searchform input {
  flex: 1;
  border: 0;
  outline: 0;
  padding: 14px 22px;
  font: inherit;
  font-size: 15px;
  background: transparent;
  color: var(--prepful-text-primary);
}
.recipes-hero__searchform button {
  border: 0;
  background: var(--prepful-primary, #2D8659);
  color: #fff;
  padding: 0 26px;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s;
  /* Lock the button width to its content + padding so the input can't grow
     past it and clip the "Search" label. Without flex-shrink:0 the input's
     `flex: 1` was nudging the button narrower than 26+text+26 on phones,
     truncating the label to "Searc". white-space:nowrap is belt-and-
     suspenders for narrow buttons or longer translated labels. */
  flex-shrink: 0;
  white-space: nowrap;
}
/* Grey-circle X clear button. Mirrors the app's Ionicons "close-circle"
   affordance (RecipeSearchGrid uses textTertiary at 18px) so the public
   site and the in-app search feel like the same component family. The
   anchor target is 32×32 for comfortable tap-area while the visible icon
   stays at 20px. Hidden by default (`hidden` attribute server-side, JS
   shows/hides as the user types). Native browsers also draw a small ✕
   inside `<input type="search">` — we suppress that in the input rule
   below so we have a single, branded affordance. */
.recipes-hero__searchform input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}
.recipes-hero__searchclear {
  flex-shrink: 0;
  align-self: stretch;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  padding: 0 4px;
  margin-right: 2px;
  color: var(--prepful-text-tertiary, #6B6660);
  text-decoration: none;
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: color 0.15s, transform 0.1s;
}
.recipes-hero__searchclear[hidden] { display: none; }
.recipes-hero__searchclear:hover {
  color: var(--prepful-text-secondary, #5C5752);
  transform: scale(1.06);
}
.recipes-hero__searchclear:focus-visible {
  outline: 2px solid var(--prepful-primary, #2D8659);
  outline-offset: 2px;
  border-radius: 50%;
}
.recipes-hero__searchclear svg { display: block; }
.recipes-hero__searchform button:hover { background: var(--prepful-primary-dark, #1E6B45); }
/* On phones the 26px button padding still pushes the search input quite
   narrow. Trim the input padding a touch so the placeholder reads cleanly
   alongside a comfortable "Search" button. */
@media (max-width: 720px) {
  .recipes-hero__searchform input { padding: 12px 16px; }
  .recipes-hero__searchform button { padding: 0 20px; }
}

/* --- Pill (hub related-rail) --------------------------------------------- */
/* The left-rail cuisine sidebar was removed 2026-05-21. The horizontal
   "Explore by cuisine" shelf above the grid (styled via .cuisine-shelf*)
   is now the only in-page cuisine discovery surface on /recipes. The
   single .pill rule below survives because hub pages still render
   sibling-cuisine anchors as <a class="pill"> in the related-rail. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 13px;
  background: var(--prepful-bg-secondary, #F7F5F2);
  border: 1px solid var(--prepful-bg-secondary, #F7F5F2);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  color: var(--prepful-text-secondary, #5C5752);
  transition: background 0.15s, color 0.15s, transform 0.1s, border-color 0.15s;
  text-transform: capitalize;
  cursor: pointer;
}
.pill:hover {
  background: var(--prepful-bg-tertiary, #F0EDE8);
  color: var(--prepful-text-primary, #2C2925);
  transform: translateY(-1px);
}

/* --- Main column --------------------------------------------------------- */
.recipes-main { min-width: 0; }
.recipes-main__topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.recipes-main__count {
  font-size: 14px;
  color: var(--prepful-text-tertiary, #6B6660);
}
.recipes-main__sort {
  display: flex;
  gap: 4px;
  align-items: center;
}
.recipes-main__sort a {
  font-size: 13px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 999px;
  color: var(--prepful-text-secondary);
}
.recipes-main__sort a:hover { background: var(--prepful-bg-secondary); }
.recipes-main__sort a.is-active {
  background: var(--prepful-bg-tertiary);
  color: var(--prepful-text-primary);
}

/* --- Editorial top: "Editor's picks" magazine band ----------------------
   Only rendered on the bare curated /recipes index (page 1, no filters) so
   the page feels editorial above the fold. Once the user filters or pages,
   we drop this and fall back to a plain grid. Layout: a large hero card
   alongside a 2×2 rail of supporting cards on desktop; stacked above the
   rail on tablet; single column on phones. Reuses .recipe-card markup
   so card content stays identical to the standard grid. */
.editors-picks {
  margin: 0 0 48px;
}
.editors-picks__header {
  margin-bottom: 20px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.editors-picks__title {
  font-family: 'Lora', serif;
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--prepful-text-primary, #2C2925);
  margin: 0;
}
.editors-picks__sub {
  font-size: 14px;
  color: var(--prepful-text-secondary, #5C5752);
  margin: 0;
}
.editors-picks__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 24px;
  align-items: stretch;
}
/* Hero card stretches to the height of the right rail, but the extra space
   goes into the image area rather than a blank card body. */
.editors-picks__hero {
  min-width: 0;
  align-self: stretch;
}
.editors-picks__hero .recipe-card { height: 100%; }
.editors-picks__hero .recipe-card__link { height: 100%; }
.editors-picks__hero .recipe-card__imgwrap {
  flex: 1 1 0;
  min-height: 280px;
  aspect-ratio: auto;
}
.editors-picks__hero .recipe-card__img {
  height: 100%;
  aspect-ratio: auto;
}
.editors-picks__hero .recipe-card__img--placeholder {
  height: 100%;
  min-height: 280px;
  aspect-ratio: auto;
}
.editors-picks__hero .recipe-card__body {
  flex: 0 0 auto;
}
.editors-picks__hero .recipe-card__title { font-size: 24px; }
.editors-picks__rail {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  align-items: start;
  align-content: start;
  min-width: 0;
}
.editors-picks__rail .recipe-card__body {
  flex: 0 0 auto;
  padding: 10px 14px 12px;
  gap: 4px;
}
.editors-picks__rail .recipe-card__title {
  font-size: 18px;
  line-height: 1.22;
}
.editors-picks__rail .recipe-card__meta {
  margin-top: 0;
}
.editors-picks__rail .recipe-card__byline {
  display: none;
}
@media (max-width: 960px) {
  .editors-picks__grid { grid-template-columns: 1fr; }
  .editors-picks__hero .recipe-card { height: auto; }
  .editors-picks__hero .recipe-card__link { height: auto; }
  .editors-picks__hero .recipe-card__imgwrap {
    flex: 0 0 auto;
    min-height: 0;
    aspect-ratio: 16 / 9;
  }
  .editors-picks__hero .recipe-card__img,
  .editors-picks__hero .recipe-card__img--placeholder {
    height: auto;
    aspect-ratio: 16 / 9;
    min-height: 0;
  }
}
@media (max-width: 640px) {
  .editors-picks__rail { grid-template-columns: 1fr; }
  .editors-picks__hero .recipe-card__title { font-size: 22px; }
}

/* --- Cuisine shelf ------------------------------------------------------
   Horizontal pill row that sits between editor's picks and the main grid.
   Gives mobile visitors a way to filter (the sidebar is hidden < 960px)
   and acts as the editorial "categories" surface for desktop. Pills wrap
   on desktop; on mobile they scroll horizontally with snap to keep the
   shelf compact. */
.cuisine-shelf {
  margin: 0 0 36px;
}
.cuisine-shelf__title {
  font-family: 'Lora', serif;
  font-size: 18px;
  font-weight: 600;
  color: var(--prepful-text-primary, #2C2925);
  margin: 0 0 12px;
  letter-spacing: -0.005em;
}
.cuisine-shelf__row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.cuisine-shelf__pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: var(--prepful-bg-secondary, #F7F5F2);
  color: var(--prepful-text-primary, #2C2925);
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background 0.15s, border-color 0.15s, transform 0.15s;
  white-space: nowrap;
}
.cuisine-shelf__pill:hover {
  background: var(--prepful-bg-tertiary, #F0EDE8);
  border-color: var(--prepful-bg-tertiary, #F0EDE8);
  transform: translateY(-1px);
}
.cuisine-shelf__pill:focus-visible {
  outline: 2px solid var(--prepful-primary, #2D8659);
  outline-offset: 2px;
}
.cuisine-shelf__pill-count {
  font-size: 12px;
  font-weight: 500;
  color: var(--prepful-text-tertiary, #6B6660);
}
@media (max-width: 720px) {
  /* On phones, scroll horizontally instead of wrapping so the shelf doesn't
     dominate the viewport. Edge padding mirrors the page gutter so the
     first/last pill doesn't kiss the screen edge. */
  .cuisine-shelf__row {
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    padding-bottom: 4px;
    margin: 0 -16px;
    padding-left: 16px;
    padding-right: 16px;
    scrollbar-width: thin;
  }
  .cuisine-shelf__pill { scroll-snap-align: start; flex: 0 0 auto; }
}

/* --- Main-grid section title (above the post-editorial grid) ------------ */
.recipes-main__section-title {
  font-family: 'Lora', serif;
  font-size: 20px;
  font-weight: 600;
  color: var(--prepful-text-primary, #2C2925);
  margin: 0 0 12px;
  letter-spacing: -0.005em;
}

/* --- Latest from the community (preview of /recipes/all) -----------------
   Rendered at the bottom of the curated /recipes page so visitors who
   scrolled past the editorial top see the start of the broader catalog
   without leaving the page. The grid reuses .recipe-grid styles so the
   visual continuity sells the "beginning of All Recipes" effect. */
.latest-preview {
  margin-top: 64px;
  padding-top: 36px;
  border-top: 1px solid var(--prepful-bg-secondary, #F7F5F2);
}
.latest-preview__header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}
.latest-preview__title {
  font-family: 'Lora', serif;
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--prepful-text-primary, #2C2925);
  margin: 0 0 4px;
}
.latest-preview__sub {
  font-size: 14px;
  color: var(--prepful-text-secondary, #5C5752);
  margin: 0;
}
.latest-preview__cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--prepful-primary, #2D8659);
  text-decoration: none;
  transition: color 0.15s;
}
.latest-preview__cta:hover { color: var(--prepful-primary-dark, #1E6B45); }
.latest-preview__cta:focus-visible {
  outline: 2px solid var(--prepful-primary, #2D8659);
  outline-offset: 3px;
  border-radius: 4px;
}
.latest-preview__footer {
  margin-top: 32px;
  text-align: center;
}
.latest-preview__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 12px 24px;
  background: var(--prepful-primary, #2D8659);
  color: #fff;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
  transition: background 0.15s, transform 0.18s ease, box-shadow 0.2s ease;
}
.latest-preview__btn:hover {
  background: var(--prepful-primary-dark, #1E6B45);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(45, 134, 89, 0.18);
}
.latest-preview__btn:focus-visible {
  outline: 2px solid var(--prepful-primary, #2D8659);
  outline-offset: 3px;
}
@media (max-width: 720px) {
  .latest-preview { margin-top: 48px; padding-top: 28px; }
  .latest-preview__title { font-size: 22px; }
}

/* --- Recipe grid --------------------------------------------------------- */
.recipe-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 24px;
}
/* Magazine first-card treatment was retired 2026-05-19. See
   renderRecipesIndexBody.ts for rationale (empty bottom slot + mobile
   bugs + scaling). All cards are uniform; the grid uses auto-fill so
   it reflows cleanly from desktop down to phones. */

/* --- Browse-more CTA (curated /recipes only, after cards + pagination) -- */
.recipes-more {
  margin: 56px auto 16px;
  padding: 36px 32px;
  max-width: 640px;
  text-align: center;
  background: var(--prepful-bg-secondary, #F7F5F2);
  border-radius: 18px;
}
.recipes-more__lede {
  font-family: 'Lora', serif;
  font-size: 22px;
  font-weight: 600;
  color: var(--prepful-text-primary, #2C2925);
  margin: 0 0 6px;
  letter-spacing: -0.005em;
}
.recipes-more__sub {
  font-size: 15px;
  color: var(--prepful-text-secondary, #5C5752);
  margin: 0 0 20px;
  line-height: 1.4;
}
.recipes-more__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 11px 22px;
  background: var(--prepful-primary, #2D8659);
  color: #fff;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
  transition: background 0.15s, transform 0.18s ease, box-shadow 0.2s ease;
}
.recipes-more__btn:hover {
  background: var(--prepful-primary-dark, #1E6B45);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(45, 134, 89, 0.18);
}
.recipes-more__btn:focus-visible {
  outline: 2px solid var(--prepful-primary, #2D8659);
  outline-offset: 3px;
}
@media (max-width: 720px) {
  .recipes-more {
    margin: 40px 16px 8px;
    padding: 28px 20px;
  }
  .recipes-more__lede { font-size: 19px; }
}

.recipe-grid__empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 96px 24px;
  color: var(--prepful-text-tertiary, #6B6660);
}
.recipe-grid__empty-title {
  font-family: 'Lora', serif;
  font-size: 24px;
  font-weight: 600;
  color: var(--prepful-text-primary);
  margin: 0 0 8px;
}
.recipe-grid__empty-body { font-size: 15px; margin: 0; }

/* --- Recipe card --------------------------------------------------------- */
/* Card is an <article> (positioning context + visual chrome). The clickable
 * surface is the inner <a class="recipe-card__link">; the save button is a
 * sibling so we don't nest <button> inside <a> (invalid HTML, breaks save on
 * some browsers). */
.recipe-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--prepful-surface, #FFFFFF);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
  transition: transform 0.18s ease-out, box-shadow 0.18s ease-out;
}
.recipe-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 28px rgba(0, 0, 0, 0.08);
}
.recipe-card__link {
  display: flex;
  flex-direction: column;
  flex: 1;
  color: var(--prepful-text-primary, #2C2925);
  text-decoration: none;
}
.recipe-card__link:focus-visible {
  outline: 2px solid var(--prepful-primary);
  outline-offset: -2px;
}
.recipe-card__imgwrap {
  position: relative;
  overflow: hidden;
}
.recipe-card__img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--prepful-bg-tertiary, #F0EDE8);
  transition: transform 0.4s ease-out;
}
.recipe-card:hover .recipe-card__img { transform: scale(1.04); }
.recipe-card__img--placeholder {
  width: 100%;
  aspect-ratio: 4 / 3;
  background: linear-gradient(135deg, var(--prepful-bg-secondary, #F7F5F2), var(--prepful-bg-tertiary, #F0EDE8));
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--prepful-text-tertiary);
  font-family: 'Lora', serif;
  font-size: 14px;
}
.recipe-card__badges {
  position: absolute;
  top: 10px;
  left: 10px;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  max-width: calc(100% - 64px);
}
.recipe-card__badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  color: var(--prepful-text-primary);
  text-transform: capitalize;
  letter-spacing: 0.02em;
}
.recipe-card__badge--time {
  background: var(--prepful-primary, #2D8659);
  color: #fff;
}
.recipe-card__save {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: background 0.15s, transform 0.15s, color 0.15s;
  color: var(--prepful-text-secondary);
  font-size: 18px;
  line-height: 1;
  padding: 0;
}
.recipe-card__save:hover {
  background: #fff;
  color: var(--prepful-primary);
  transform: scale(1.08);
}
.recipe-card__save:focus-visible {
  outline: 2px solid var(--prepful-primary);
  outline-offset: 2px;
}
.recipe-card__save.is-busy { opacity: 0.5; pointer-events: none; }
.recipe-card__body {
  padding: 16px 18px 18px;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.recipe-card__title {
  font-family: 'Lora', serif;
  font-weight: 600;
  font-size: 19px;
  line-height: 1.25;
  margin: 0;
  letter-spacing: -0.005em;
}
.recipe-card__desc {
  display: none;
  font-size: 14px;
  color: var(--prepful-text-secondary);
  margin: 4px 0 0;
  line-height: 1.5;
}
.recipe-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  color: var(--prepful-text-secondary, #5C5752);
  font-size: 13px;
  margin: 2px 0 0;
}
.recipe-card__meta-sep {
  color: var(--prepful-text-tertiary);
  opacity: 0.5;
}
.recipe-card__byline {
  margin: 10px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--prepful-bg-secondary);
  color: var(--prepful-text-tertiary, #6B6660);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* --- Pagination ---------------------------------------------------------- */
.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 64px;
  /* Keep "Newer / Page X / Older" on a single row at every viewport. The
     previous flex-wrap let the middle "Page" indicator drop below the
     buttons on phones; the row now stays one line because we trim button
     padding and font-size on narrow screens (see media query below). */
  flex-wrap: nowrap;
  font-size: 14px;
}
.pagination__link {
  display: inline-flex;
  align-items: center;
  padding: 10px 18px;
  border-radius: 10px;
  background: var(--prepful-surface);
  border: 1px solid var(--prepful-border, #E5E0DA);
  color: var(--prepful-text-primary);
  font-weight: 600;
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
  white-space: nowrap;
}
.pagination__link:hover {
  background: var(--prepful-bg-secondary);
  border-color: var(--prepful-text-tertiary);
  transform: translateY(-1px);
}
.pagination__link--disabled {
  color: var(--prepful-text-tertiary);
  background: transparent;
  border-color: var(--prepful-bg-secondary);
  pointer-events: none;
}
.pagination__current {
  padding: 10px 16px;
  color: var(--prepful-text-secondary);
  font-weight: 600;
  white-space: nowrap;
}
@media (max-width: 480px) {
  /* Tight pagination row for narrow phones: smaller padding, smaller gap,
     and a slightly smaller font so all three pills fit on one line at
     375px-wide viewports. */
  .pagination { gap: 4px; font-size: 13px; }
  .pagination__link { padding: 8px 12px; border-radius: 8px; }
  .pagination__current { padding: 8px 8px; }
}

/* --- Hub + collection hero band ----------------------------------------- */
.hub-hero,
.collection-hero {
  position: relative;
  margin: 0 auto 40px;
  border-radius: 20px;
  overflow: hidden;
  background: linear-gradient(135deg, var(--prepful-primary-light, #4CAF7A) 0%, var(--prepful-primary, #2D8659) 100%);
  min-height: 320px;
  color: #fff;
  display: flex;
  align-items: flex-end;
}
.hub-hero__bg,
.collection-hero__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}
.hub-hero::after,
.collection-hero::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.12) 0%, rgba(0, 0, 0, 0.55) 100%);
  z-index: 1;
}
.hub-hero__inner,
.collection-hero__inner {
  position: relative;
  z-index: 2;
  padding: 40px 48px;
  max-width: 720px;
}
.hub-hero__eyebrow,
.collection-hero__eyebrow {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 12px;
  opacity: 0.92;
}
.hub-hero__title,
.collection-hero__title {
  font-family: 'Lora', serif;
  font-weight: 600;
  font-size: 48px;
  line-height: 1.1;
  margin: 0 0 12px;
  letter-spacing: -0.01em;
}
.hub-hero__sub,
.collection-hero__sub {
  font-size: 16px;
  margin: 0;
  opacity: 0.92;
  max-width: 540px;
  line-height: 1.5;
}

/* Editorial intro after hero */
.hub-intro,
.collection-intro {
  max-width: 680px;
  margin: 0 auto 40px;
  font-family: 'Lora', serif;
  font-size: 18px;
  line-height: 1.65;
  color: var(--prepful-text-primary);
}
.hub-intro__paragraph,
.collection-intro__paragraph { margin: 0 0 18px; }

/* --- Related cuisines rail ---------------------------------------------- */
.related-rail {
  margin: 64px 0 0;
}
.related-rail__title {
  font-family: 'Lora', serif;
  font-size: 22px;
  font-weight: 600;
  margin: 0 0 16px;
  color: var(--prepful-text-primary);
}
.related-rail__items {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* --- Related-recipes rail (recipe detail body, sibling of SPA root) ----- */
/* Sits below the SPA-rendered detail. Full-width background strip using
 * --prepful-bg-secondary, matching the homepage's warm-cream section feel.
 * Content (header + grid) is constrained to 1200px centered inside. */
.related-rail {
  background: var(--prepful-bg-secondary, #F7F5F2);
  max-width: none;
  margin: 64px 0 0;
  padding: 48px 24px 64px;
  font-family: 'Nunito', system-ui, sans-serif;
}
.related-rail__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 24px;
  padding-bottom: 16px;
  max-width: 1200px;
  margin-left: auto;
  margin-right: auto;
  border-bottom: 1px solid var(--prepful-border, #E8E5E1);
}
.related-rail__heading {
  font-family: 'Lora', serif;
  font-weight: 600;
  font-size: 24px;
  letter-spacing: -0.01em;
  color: var(--prepful-text-primary, #2C2925);
  margin: 0;
}
.related-rail__seeall {
  font-size: 14px;
  font-weight: 600;
  color: var(--prepful-primary, #2D8659);
  text-decoration: none;
  white-space: nowrap;
}
.related-rail__seeall:hover { text-decoration: underline; }
.related-rail__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 20px;
  max-width: 1200px;
  margin: 0 auto;
}
@media (max-width: 720px) {
  .related-rail { padding: 40px 16px 56px; }
  .related-rail__heading { font-size: 20px; }
}

/* --- Recipe detail page --------------------------------------------------
   Server-rendered body for /recipe/[slug-shortId]. Mirrors the in-app UX
   from apps/mobile/components/RecipeDetailModal.tsx — the actual layout the
   app uses, not just the content sections:
     Mobile  (≤1023px): hero image 240px tall at top; content panel slides
                        OVER the hero's bottom 16px with 20px-rounded top
                        corners (mirrors mobileAbsoluteHero + mobileBodyPanel
                        in RecipeDetailModal).
     Desktop (≥1024px): two-column split — hero LEFT 45% (sticky to viewport
                        top, fills available height); content RIGHT 55%
                        scrolls naturally past it. Mirrors desktopSplitLayout
                        + desktopHeroCol + desktopContentCol.
   All colors / spacing pull from --prepful-* tokens. */

.recipe-detail {
  max-width: 1200px;
  margin: 0 auto 64px;
  padding: 0;
}

/* Hero column */
.recipe-detail__hero {
  position: relative;
  background: var(--prepful-bg-secondary, #F7F5F2);
  height: 240px; /* MOBILE_HERO_HEIGHT from RecipeDetailModal */
  overflow: hidden;
}
.recipe-detail__hero-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Content column — on mobile, slides over the hero with rounded top */
.recipe-detail__content {
  position: relative;
  z-index: 1;
  margin-top: -16px;
  background: var(--prepful-bg, #FDFCFA);
  border-top-left-radius: 20px;
  border-top-right-radius: 20px;
  padding: 24px 24px 32px;
}

/* Desktop: side-by-side hero + content. Hero sticks to viewport top while
   the content column scrolls past it, matching the in-app modal feel where
   the image stays in view. max-width removed so the hero reaches the left
   viewport edge (matches the full-bleed hero in the app). */
@media (min-width: 1024px) {
  .recipe-detail {
    display: grid;
    grid-template-columns: 45vw 1fr;
    gap: 0;
    align-items: start;
    max-width: none;
    margin: 0 0 96px;
  }
  .recipe-detail__hero {
    position: sticky;
    top: 0;
    height: min(100vh, 720px);
  }
  .recipe-detail__content {
    margin-top: 0;
    border-radius: 0;
    background: transparent;
    padding: 48px 48px 64px;
    max-width: 720px;
  }
}

/* Body padding override: desktop content column uses spacing.2xl (32px)
   horizontal per RecipeDetailModal.desktopContentInner. Mobile keeps the
   24px from .recipe-detail__content above (matches mobileBodyPanelInner). */
@media (min-width: 1024px) {
  .recipe-detail__content {
    padding: 32px 32px 64px; /* spacing.2xl horizontal + 4xl bottom */
  }
}

/* ─── Typography & spacing — token-derived from packages/ui/src/themes/spacing.ts
   Tokens used (px values from spacing.ts):
     fontSize: sm=13, md=15, lg=17, 2xl=24
     spacing:  xs=4, sm=8, md=12, lg=16, xl=24, 2xl=32
     borderRadius: md=12
     lineHeight: snug=1.35, normal=1.5, relaxed=1.625
     letterSpacing tight: -0.25
   Reference: apps/mobile/components/RecipeContentSections.tsx +
   apps/mobile/components/RecipeDetailBody.tsx + packages/ui/src/components/Button.tsx
   ─────────────────────────────────────────────────────────────────────────── */

/* Title section (mirrors RecipeHeaderSection.titleSection variant=detail:
   paddingTop spacing.2xl, paddingHorizontal 0, gap spacing.sm) */
.recipe-detail__title-section {
  padding-top: 32px; /* spacing.2xl */
  margin: 0 0 8px; /* spacing.sm gap before description/meta */
}
.recipe-detail__title {
  /* size 2xl serif semibold, lineHeight = 2xl * snug = 24 * 1.35 = 32.4 */
  margin: 0 0 10px; /* recipeTitle marginBottom 10 (hardcoded in app) */
  font-family: 'Lora', serif;
  font-weight: 600;
  font-size: 24px; /* fontSize.2xl */
  line-height: 1.35; /* lineHeight.snug */
  letter-spacing: -0.25px; /* letterSpacing.tight */
  color: var(--prepful-text-primary, #2C2925);
}
.recipe-detail__attribution {
  /* attributionRow: flexDirection row, text size md color secondary */
  margin: 0;
  font-size: 15px; /* fontSize.md */
  line-height: 1.5; /* lineHeight.normal */
  color: var(--prepful-text-secondary, #5C5752);
}
.recipe-detail__source-link {
  font-size: 15px; /* matches attributionLink fontSize.md */
  color: var(--prepful-primary, #2D8659);
  text-decoration: underline;
}
.recipe-detail__source-link:hover { color: var(--prepful-primary-dark, #1E6B45); }

/* Rating chip strip — mirrors apps/mobile/components/RatingChipStrip:
   community pill directly under the title, with RatingMark-style dot +
   serif wordmark and muted review count. Public pages intentionally omit
   app-only personal rating and plan count. */
.recipe-detail__rating-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px; /* ROW_GAP */
  margin: 0 0 12px; /* matches RatingChipStrip container bottom rhythm */
}
.recipe-detail__rating-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px; /* PILL_GAP */
  padding: 7px 14px; /* PILL_PADDING_V/H */
  border-radius: 999px;
  background: var(--prepful-bg-secondary, #F7F5F2);
  border: 1px solid var(--prepful-border, #E5E0DA);
}
.recipe-detail__rating-mark {
  display: inline-flex;
  align-items: center;
  gap: 7px; /* RatingMark standard gap */
}
.recipe-detail__rating-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: currentColor;
  flex: 0 0 auto;
}
.recipe-detail__rating-wordmark {
  font-family: 'Lora', serif;
  font-weight: 600;
  font-size: 13px;
  line-height: 1.25;
  color: currentColor;
}
.recipe-detail__rating-mark--tier-1 { color: var(--prepful-rating-tier-1, #8B4A38); }
.recipe-detail__rating-mark--tier-2 { color: var(--prepful-rating-tier-2, #8E6B36); }
.recipe-detail__rating-mark--tier-3 { color: var(--prepful-rating-tier-3, #558870); }
.recipe-detail__rating-mark--tier-4 { color: var(--prepful-rating-tier-4, #2D8659); }
.recipe-detail__rating-mark--tier-5 { color: var(--prepful-rating-tier-5, #1E6B45); }
.recipe-detail__rating-meta {
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--prepful-text-tertiary, #6B6660);
}

/* Description (detail variant: marginBottom 20, color secondary, line normal) */
.recipe-detail__description {
  margin: 0 0 20px; /* detailDescriptionText marginBottom 20 */
  font-size: 15px; /* fontSize.md */
  line-height: 1.5; /* fontSize.md * lineHeight.normal = 22.5 */
  color: var(--prepful-text-secondary, #5C5752);
}

/* Meta bar (RecipeMetaBar: paddingVertical 14, marginTop lg=16,
   marginBottom xl=24, border top+bottom, item gap 4, value size lg
   semibold, label size sm color tertiary) */
.recipe-detail__meta-bar {
  display: flex;
  justify-content: space-around;
  align-items: flex-start;
  padding: 14px 0;
  margin: 16px 0 24px; /* lg / xl */
  border-top: 1px solid var(--prepful-bg-tertiary, #F0EDE8);
  border-bottom: 1px solid var(--prepful-bg-tertiary, #F0EDE8);
}
.recipe-detail__meta-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px; /* spacing.xs */
}
.recipe-detail__meta-value {
  font-family: 'Nunito', system-ui, sans-serif;
  font-weight: 600;
  font-size: 17px; /* fontSize.lg */
  color: var(--prepful-text-primary, #2C2925);
  font-variant-numeric: tabular-nums;
}
.recipe-detail__meta-label {
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 13px; /* fontSize.sm */
  color: var(--prepful-text-tertiary, #6B6660);
}
/* Servings stepper — mirrors RecipeMetaBar servingsBtn in the app:
   18×18px circle, borderRadius 9, border 1px, centered icon. */
.recipe-detail__servings-control {
  display: flex;
  align-items: center;
  gap: 6px; /* metaBarItem gap 4 + a bit more for the buttons */
}
.recipe-detail__servings-btn {
  width: 20px;
  height: 20px;
  border-radius: 10px;
  border: 1px solid var(--prepful-bg-tertiary, #F0EDE8);
  background: var(--prepful-surface, #fff);
  color: var(--prepful-text-tertiary, #6B6660);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: border-color 0.15s, color 0.15s;
}
.recipe-detail__servings-btn:hover {
  border-color: var(--prepful-primary, #2D8659);
  color: var(--prepful-primary, #2D8659);
}

/* Hero pill buttons — float over the hero image top-right, matching the
   app's mobileFloatingNavRight translucent pills (RecipeDetailModal.tsx).
   Background mirrors theme.colors.background + 'D9' = rgba(#FDFCFA, 0.85).
   backdrop-filter adds the blur the native shadow achieves in the app. */
.recipe-detail__hero-pills {
  position: absolute;
  top: 16px;
  right: 16px;
  display: flex;
  gap: 8px; /* spacing.sm — mobileFloatingNavRight gap */
  z-index: 10;
}
.recipe-detail__hero-pill {
  /* inline-flex + center alignment is what keeps the 16x16 SVG vertically
     centered with the text — without this the icon falls to the text
     baseline and looks ~2px low. gap replaces the implicit whitespace
     character so spacing stays consistent across browsers. */
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  border-radius: 999px;
  padding: 8px 16px;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--prepful-text-primary, #2C2925);
  background: rgba(253, 252, 250, 0.85); /* --prepful-bg + D9 alpha */
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.10);
  cursor: pointer;
  /* `transform` here is the no-op identity — declaring it in the base
     state lets the hover transition cleanly into translateY(-2px). */
  transform: translateY(0);
  transition:
    background 0.18s ease,
    box-shadow 0.2s ease,
    transform 0.18s ease;
}
.recipe-detail__hero-pill:hover {
  background: rgba(253, 252, 250, 0.97);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.16);
  transform: translateY(-2px);
}
.recipe-detail__hero-pill:focus-visible {
  outline: 2px solid var(--prepful-primary, #2D8659);
  outline-offset: 2px;
}
.recipe-detail__hero-pill:active {
  transform: translateY(0);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.10);
}
.recipe-detail__hero-pill svg {
  /* Lock SVG sizing so it can't be re-baselined by surrounding flex math.
     `display: block` also prevents the legacy inline-svg descender gap. */
  display: block;
  flex: 0 0 16px;
}
.recipe-detail__hero-pill--ghost,
.recipe-detail__hero-pill--info { color: var(--prepful-text-secondary, #5C5752); }
.recipe-detail__hero-pill--info {
  width: 36px;
  height: 36px;
  justify-content: center;
  padding: 0;
}
.recipe-detail__hero-pill.is-busy {
  opacity: 0.6;
  pointer-events: none;
  transform: translateY(0);
}

/* --- AI image disclosure (only on AI-generated hero images) -------------
   The trigger uses the same top hero pill treatment as Save / Plan / Print.
   The native <dialog> gives us a modal sheet with no script framework —
   `showModal()` + a <form method="dialog"> close button is the entire JS
   surface. */
.recipe-detail__ai-dialog {
  border: none;
  border-radius: 18px;
  padding: 0;
  max-width: 420px;
  width: calc(100% - 32px);
  background: var(--prepful-surface, #FFFFFF);
  color: var(--prepful-text-primary, #2C2925);
  box-shadow: 0 32px 80px rgba(0, 0, 0, 0.22);
}
.recipe-detail__ai-dialog::backdrop {
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.recipe-detail__ai-dialog-form {
  padding: 28px 28px 24px;
  margin: 0;
}
.recipe-detail__ai-dialog-title {
  font-family: 'Lora', serif;
  font-size: 20px;
  font-weight: 600;
  margin: 0 0 10px;
  letter-spacing: -0.01em;
}
.recipe-detail__ai-dialog-body {
  font-size: 15px;
  line-height: 1.5;
  color: var(--prepful-text-secondary, #5C5752);
  margin: 0 0 20px;
}
.recipe-detail__ai-dialog-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 18px;
  background: var(--prepful-primary, #2D8659);
  color: #fff;
  border: none;
  border-radius: 999px;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s;
}
.recipe-detail__ai-dialog-close:hover { background: var(--prepful-primary-dark, #1E6B45); }
.recipe-detail__ai-dialog-close:focus-visible {
  outline: 2px solid var(--prepful-primary, #2D8659);
  outline-offset: 2px;
}

/* Print suppresses the AI affordance (decorative only). */
@media print {
  .recipe-detail__hero-pill--info,
  .recipe-detail__ai-dialog { display: none !important; }
}

/* Section title (mirrors RecipeContentSections.sectionTitle:
   serif semibold size lg=17, line snug, letter tight, marginBottom md=12).
   App passes serifTitle, titleSize="lg" to ingredients + instructions. */
.recipe-detail__section {
  margin: 0 0 24px; /* spacing.xl between sections */
}
.recipe-detail__h2 {
  margin: 0 0 12px; /* spacing.md */
  font-family: 'Lora', serif;
  font-weight: 600;
  font-size: 17px; /* fontSize.lg per titleSize="lg" in RecipeDetailBody */
  line-height: 1.35; /* lineHeight.snug */
  letter-spacing: -0.25px; /* letterSpacing.tight */
  color: var(--prepful-text-primary, #2C2925);
}

/* Ingredients (RecipeIngredientsSection: dot bullet, two-column ≥640px).
   ingredientItem: paddingVertical 9, gap 10. dot: 6×6 marginTop 8 opacity 0.4.
   text: size md=15, lineHeight md * normal = 22.5. */
.recipe-detail__ingredient-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.recipe-detail__ingredient {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 0;
  scroll-margin-top: 24px;
}
.recipe-detail__ingredient + .recipe-detail__ingredient {
  border-top: 1px solid var(--prepful-bg-tertiary, #F0EDE8);
}
.recipe-detail__ingredient:target {
  background: linear-gradient(90deg, rgba(45, 134, 89, 0.16), transparent);
  animation: recipe-detail-flash 1.4s ease-out;
}
@keyframes recipe-detail-flash {
  0% { background-color: rgba(45, 134, 89, 0.32); }
  100% { background-color: transparent; }
}
.recipe-detail__ingredient-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--prepful-primary, #2D8659);
  opacity: 0.4;
  flex-shrink: 0;
  margin-top: 8px; /* ingredientDot marginTop 8 */
}
.recipe-detail__ingredient-text {
  flex: 1;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 15px; /* fontSize.md */
  line-height: 1.5; /* fontSize.md * lineHeight.normal */
  color: var(--prepful-text-primary, #2C2925);
}
/* Two-column ingredient layout via HTML-split flex columns (not CSS columns).
   Splitting in the renderer means the first item of the right column is the
   first <li> in its own <ul>, so the li+li border-top never bleeds across. */
@media (min-width: 640px) {
  .recipe-detail__ingredient-cols {
    display: flex;
    gap: 24px; /* spacing.xl */
  }
  .recipe-detail__ingredient-cols .recipe-detail__ingredient-list {
    flex: 1;
    min-width: 0;
  }
}

/* Steps (RecipeInstructionsSection: instructionItem marginBottom 32,
   "Step N" inline label semibold 700 primary, step text size lg=17,
   relaxed lineHeight). App's stepLabel: fontWeight 700, fontSize lg.
   App's instructionText: lineHeight = lg * relaxed = 17 * 1.625 = 27.6. */
.recipe-detail__step-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.recipe-detail__step {
  margin: 0 0 32px; /* spacing.2xl instructionItem marginBottom */
}
.recipe-detail__step:last-child { margin-bottom: 0; }
.recipe-detail__step-label {
  margin: 0 0 2px; /* stepLabel marginBottom 2 */
  font-family: 'Nunito', system-ui, sans-serif;
  font-weight: 700; /* stepLabel fontWeight 700 */
  font-size: 17px; /* fontSize.lg */
  color: var(--prepful-primary, #2D8659);
}
.recipe-detail__step-text {
  margin: 0;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 17px; /* fontSize.lg */
  line-height: 1.625; /* lineHeight.relaxed */
  color: var(--prepful-text-primary, #2C2925);
}
.recipe-detail__step-ingredient {
  /* ingredientUnderline: textDecorationLine underline, dashed, primary */
  text-decoration: underline;
  text-decoration-style: dashed;
  text-decoration-color: var(--prepful-primary, #2D8659);
  text-underline-offset: 3px;
}

/* Step chip row (app chip: paddingVertical 4 paddingHorizontal 11
   borderRadius 20, bg backgroundSecondary, border 1 border. chipQty size md
   color text. chipName size md color textSecondary. chipRow gap 6
   marginTop 10. */
.recipe-detail__chip-row {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.recipe-detail__chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 11px;
  border-radius: 20px;
  background: var(--prepful-bg-secondary, #F7F5F2);
  border: 1px solid var(--prepful-bg-tertiary, #F0EDE8);
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 15px; /* fontSize.md */
  color: var(--prepful-text-secondary, #5C5752);
  text-decoration: none;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.recipe-detail__chip:hover {
  background: var(--prepful-bg-tertiary, #F0EDE8);
  border-color: var(--prepful-primary-light, #4CAF7A);
}
.recipe-detail__chip-qty {
  font-weight: 600; /* semibold */
  color: var(--prepful-text-primary, #2C2925);
}
.recipe-detail__chip-name {
  color: var(--prepful-text-secondary, #5C5752);
}
.recipe-detail__chip--inert { cursor: default; }
.recipe-detail__chip--inert:hover {
  background: var(--prepful-bg-secondary, #F7F5F2);
  border-color: var(--prepful-bg-tertiary, #F0EDE8);
}

/* Nutritional Info (RecipeDetailBody nutritionSection: marginTop xl=24.
   Header reuses .recipe-detail__h2 so it matches Ingredients + Steps.
   MacroBox: borderRadius md=12, padding md=12, alignItems center, gap xs=4.
   Label: size md color secondary. Value: serif bold size xl=20. */
.recipe-detail__macros { margin-top: 24px; }
.recipe-detail__macros-label {
  margin: 0 0 8px; /* spacing.sm marginBottom on nutritionLabel */
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 15px; /* size md */
  line-height: 1.5;
  color: var(--prepful-text-secondary, #5C5752);
}
.recipe-detail__macros-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px; /* spacing.sm */
}
.recipe-detail__macro {
  background: var(--prepful-bg-secondary, #F7F5F2);
  border-radius: 12px; /* borderRadius.md */
  padding: 12px; /* spacing.md */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px; /* spacing.xs */
}
.recipe-detail__macro-label {
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 15px; /* MacroBox label size md */
  color: var(--prepful-text-secondary, #5C5752);
}
.recipe-detail__macro-value {
  font-family: 'Lora', serif;
  font-weight: 700; /* MacroBox uses `bold` prop */
  font-size: 20px; /* fontSize.xl */
}
.recipe-detail__macro--calories .recipe-detail__macro-value { color: #E86B5A; }
.recipe-detail__macro--protein .recipe-detail__macro-value { color: #4A9B7F; }
.recipe-detail__macro--carbs .recipe-detail__macro-value { color: #E5A84B; }
.recipe-detail__macro--fat .recipe-detail__macro-value { color: #B085C9; }
.recipe-detail__nutrition-learn-more {
  color: var(--prepful-primary, #2D8659);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.recipe-detail__nutrition-learn-more:hover { text-decoration: underline; }

/* ── App upsell — Apple-style compact banner (all viewports) ─────────────── */
.recipe-detail__app-upsell {
  display: grid;
  grid-template-columns: 52px 1fr auto;
  align-items: center;
  column-gap: 12px;
  margin-top: 28px;
  padding: 12px 14px;
  background: var(--prepful-surface, #FFFFFF);
  border: 1px solid rgba(0, 0, 0, 0.09);
  border-radius: 16px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.07);
}
.recipe-detail__app-upsell-icon {
  width: 52px;
  height: 52px;
  border-radius: 12px; /* iOS icon shape */
  display: block;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
}
.recipe-detail__app-upsell-text {
  min-width: 0;
}
.recipe-detail__app-upsell-name {
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 15px;
  font-weight: 700;
  color: var(--prepful-text-primary, #2C2925);
  margin: 0;
  line-height: 1.2;
}
.recipe-detail__app-upsell-tagline {
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 12px;
  color: var(--prepful-text-secondary, #5C5752);
  margin: 3px 0 0;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.recipe-detail__app-upsell-cta {
  -webkit-appearance: none;
  appearance: none;
  background: var(--prepful-primary, #2D8659);
  color: #fff;
  font-family: 'Nunito', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 700;
  border: none;
  border-radius: 20px;
  padding: 7px 20px;
  cursor: pointer;
  letter-spacing: 0.02em;
  transition: background 0.15s;
  white-space: nowrap;
}
.recipe-detail__app-upsell-cta:hover { background: #236b48; }
.recipe-detail__app-upsell-cta:active { background: #1a5236; }

/* ── Get-the-app dialog (used by the app upsell CTA on recipe pages) ─────── */
.get-app-dialog {
  position: fixed;
  inset: 0;
  margin: auto;
  border: none;
  padding: 0;
  border-radius: 20px;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.20);
  background: var(--prepful-surface, #ffffff);
  color: var(--prepful-text-primary, #2C2925);
  max-width: 380px;
  width: calc(100% - 32px);
  max-height: calc(100vh - 32px);
  overflow: visible;
}
.get-app-dialog::backdrop {
  background: rgba(0, 0, 0, 0.50);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.get-app-dialog__body {
  padding: 28px 28px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
}
.get-app-dialog__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  border: none;
  background: var(--prepful-bg-secondary, #F7F5F2);
  color: var(--prepful-text-secondary, #5C5752);
  border-radius: 50%;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: background 0.15s, color 0.15s;
}
.get-app-dialog__close:hover {
  background: var(--prepful-bg-tertiary, #F0EDE8);
  color: var(--prepful-text-primary, #2C2925);
}
.get-app-dialog__close:focus-visible {
  outline: 2px solid var(--prepful-primary, #2D8659);
  outline-offset: 2px;
}
.get-app-dialog__title {
  font-family: 'Lora', serif;
  font-weight: 600;
  font-size: 22px;
  margin: 4px 0 0;
}
.get-app-dialog__subtitle {
  font-size: 14px;
  color: var(--prepful-text-secondary, #5C5752);
  margin: 0;
  line-height: 1.5;
}
.get-app-dialog__qr {
  width: 200px;
  height: 200px;
  background: #fff;
  border-radius: 14px;
  padding: 10px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.06);
  margin-top: 4px;
}
.get-app-dialog__qr img {
  width: 100%;
  height: 100%;
  display: block;
  image-rendering: pixelated;
}
.get-app-dialog__divider {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  margin: 4px 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--prepful-text-tertiary, #6B6660);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.get-app-dialog__divider::before,
.get-app-dialog__divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--prepful-bg-tertiary, #F0EDE8);
}
.get-app-dialog__badges {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
  align-items: center;
}
.get-app-dialog__badges .app-badge img { height: 48px; }
@media (max-width: 420px) {
  .get-app-dialog__qr,
  .get-app-dialog__divider { display: none; }
}
.recipe-detail__nutrition-learn-more:focus-visible {
  outline: 2px solid var(--prepful-primary, #2D8659);
  outline-offset: 2px;
  border-radius: 4px;
}
.recipe-detail__nutrition-source-link {
  color: var(--prepful-primary, #2D8659);
  font-weight: 700;
}

/* Mobile */
@media (max-width: 720px) {
  .recipe-detail__macros-grid { grid-template-columns: repeat(2, 1fr); }
}

/* --- Handoff overlay -----------------------------------------------------
   Painted instantly when a save/plan handoff click fires so the user never
   sees the public site frozen during the /api/handoff-intent round trip OR
   the subsequent navigation to app.prepfulapp.com. Background is the brand
   bg (#FDFCFA) so the cross-origin nav doesn't flash white. Mirrors the
   look of the app's auth screen so the transition feels continuous.
   The overlay is rendered hidden by both _shell.html files and toggled by
   the inline handoff script (see landing/recipe/_shell.html). */
.handoff-overlay {
  position: fixed;
  inset: 0;
  z-index: 99999;
  background: var(--prepful-bg, #FDFCFA);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease-out;
}
.handoff-overlay[data-visible="true"] {
  opacity: 1;
  pointer-events: auto;
}
.handoff-overlay__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  padding: 24px;
  text-align: center;
}
.handoff-overlay__logo {
  width: 64px;
  height: 64px;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.10);
  background: #fff;
}
.handoff-overlay__logo img {
  width: 100%;
  height: 100%;
  display: block;
}
.handoff-overlay__title {
  margin: 0;
  font-family: 'Lora', Georgia, serif;
  font-size: 18px;
  font-weight: 600;
  color: var(--prepful-text-primary, #2C2925);
}
.handoff-overlay__spinner {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2.5px solid rgba(45, 134, 89, 0.15);
  border-top-color: var(--prepful-primary, #2D8659);
  animation: handoff-spin 0.8s linear infinite;
}
@keyframes handoff-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .handoff-overlay { transition: none; }
  .handoff-overlay__spinner { animation: none; border-top-color: rgba(45, 134, 89, 0.15); }
}

/* Print: hide chrome + actions, single column, tighter spacing */
@media print {
  .site-header,
  .site-footer,
  .recipe-detail__hero-pills,
  .related-rail {
    display: none !important;
  }
  body { background: #fff; color: #000; font-size: 11pt; line-height: 1.45; }
  .recipe-detail {
    display: block !important; /* unset the desktop grid */
    max-width: 100%;
    margin: 0;
  }
  .recipe-detail__hero {
    position: static !important; /* unset desktop sticky */
    height: auto !important;
    max-height: 200pt;
  }
  .recipe-detail__hero-img { max-height: 200pt; object-fit: contain; }
  .recipe-detail__content {
    margin-top: 0 !important;
    border-radius: 0 !important;
    padding: 16pt 0 0 !important;
    background: transparent !important;
  }
  .recipe-detail__title { font-size: 22pt; }
  .recipe-detail__attribution,
  .recipe-detail__description { font-size: 10pt; }
  .recipe-detail__meta-bar { padding: 8pt 0; margin: 12pt 0; }
  .recipe-detail__section { margin-bottom: 16pt; }
  .recipe-detail__ingredient-cols { display: block; }
  .recipe-detail__ingredient-list { columns: 1; }
  .recipe-detail__ingredient { padding: 4pt 0; page-break-inside: avoid; }
  .recipe-detail__step { margin-bottom: 12pt; page-break-inside: avoid; }
  .recipe-detail__step-text { font-size: 11pt; line-height: 1.4; }
  .recipe-detail__chip { background: #f0f0f0; color: #000; border: 1px solid #ddd; }
  .recipe-detail__macros-grid { grid-template-columns: repeat(4, 1fr); }
  .recipe-detail__macro { background: none; border: 1pt solid #ddd; padding: 8pt; }
}

/* --- Recipe Not Found page ----------------------------------------------- */
.recipe-not-found {
  min-height: calc(100vh - 200px);
}
.recipe-not-found__hero {
  padding: 64px 0 48px;
  text-align: center;
  border-bottom: 1px solid var(--prepful-bg-secondary, #F7F5F2);
  margin-bottom: 48px;
}
.recipe-not-found__heading {
  font-family: 'Lora', serif;
  font-size: 36px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--prepful-text-primary, #2C2925);
  margin: 0 0 12px;
  letter-spacing: -0.01em;
}
.recipe-not-found__sub {
  font-size: 16px;
  color: var(--prepful-text-secondary, #5C5752);
  margin: 0 auto 28px;
  max-width: 440px;
}
.recipe-not-found__searchform {
  margin: 0 auto 20px;
}
.recipe-not-found__browse {
  display: inline-block;
  font-size: 14px;
  font-weight: 600;
  color: var(--prepful-primary, #2D8659);
  text-decoration: none;
  transition: color 0.15s;
}
.recipe-not-found__browse:hover {
  color: var(--prepful-primary-dark, #1E6B45);
}
.recipe-not-found__suggestions {
  margin-bottom: 48px;
}
.recipe-not-found__suggestions-heading {
  font-family: 'Lora', serif;
  font-size: 24px;
  font-weight: 600;
  color: var(--prepful-text-primary, #2C2925);
  margin: 0 0 24px;
}
@media (max-width: 720px) {
  .recipe-not-found__hero {
    padding: 40px 0 32px;
    margin-bottom: 32px;
  }
  .recipe-not-found__heading { font-size: 28px; }
  .recipe-not-found__sub { font-size: 15px; }
}
