/*
 * Recipe Recordings - "Kitchen Notebook" Design System
 * A warm, editorial aesthetic with analog charm
 */

/* ========================================
   CSS Custom Properties (Design Tokens)
   ======================================== */
:root {
  /* Typography: DESIGN.md roles. Display is 30px on the phone. */
  --font-display: 'Fredoka', ui-rounded, system-ui, sans-serif;
  --font-body: 'Nunito', ui-rounded, system-ui, sans-serif;
  --text-display: 36px;
  --text-display-phone: 30px;
  --text-headline: 26px;
  --text-title: 22px;
  --text-body: 16px;
  --text-label: 12px;
  --leading-display: 1.1;
  --leading-headline: 1.15;
  --leading-title: 1.2;
  --leading-body: 1.5;
  --leading-label: 1.3;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  --weight-extrabold: 800;

  /* Layers, lowest first (DESIGN.md, Elevation). Stacking inside one component uses -1 to 5. */
  --z-popover: 20;
  --z-planning-preferences: 45;
  --z-search-page: 420;
  --z-navbar: 430;
  --z-edges: 435;
  --z-tab-bar: 440;
  --z-tab-bar-action: 441;
  --z-plan-toast: 445;
  --z-dialog-backdrop: 450;
  --z-dialog: 451;
  --z-dialog-toast: 452;
  --z-sheet-backdrop: 455;
  --z-sheet: 460;
  --z-toaster: 480;
  --z-search: 500;

  /* Colors - Calm Backyard: ink on cream, heeler blue is the one accent, tomato is for errors */
  --color-cream: #fffcf6;
  --color-cream-dark: #f4efe5;
  --color-paper: #fffdf9;
  --color-hover: #f0eadd;
  --color-ink: #1e2a4f;
  --color-ink-soft: #56607f;
  --color-ink-faint: #8c95b3;
  --color-heeler: #3d6fc4;
  --color-heeler-dark: #2b559e;
  --color-tomato: #e8744a;
  --color-tomato-ink: #a3321c;
  --color-tomato-light: #fde3e1;
  --color-border: #e3dccd;
  --color-border-strong: #969185;
  --color-plan-toast: #ffffff;
  --color-white: var(--color-paper);
  --color-black: var(--color-ink);

  /* Shadows: none. */
  --shadow-sm: none;
  --shadow-md: none;
  --shadow-lg: none;
  --shadow-lifted: none;
  /* Desktop Recipes idea cards only: lit from the top of the page, as iOS liftedCard(). */
  --shadow-raised: 0 1px 2px color-mix(in srgb, var(--color-ink) 6%, transparent), 0 10px 32px color-mix(in srgb, var(--color-ink) 10%, transparent);
  /* One line colour: ink. */
  --line-color: var(--color-ink);
  --line: 1.5px solid var(--line-color);

  /* Spacing */
  --space-2xs: 2px;
  --space-xs: 4px;
  --space-sm: 8px;
  --space-sm-md: 12px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-2xl: 48px;

  /* Component padding from DESIGN.md components */
  --button-primary-padding: 0 22px;
  --button-secondary-padding: 0 18px;
  --input-padding: 12px 14px;
  --card-padding: 24px;

  /* The sticky navbar's height (DESIGN.md, Navigation). Sticky pins and full-height pages sit under it. */
  --navbar-height: 72px;

  /* Border Radius */
  --radius-sm: 7px;
  --radius-md: 14px;
  --radius-cover: 16px;
  --radius-lg: 18px;
  --radius-xl: 24px;
  --radius-round: 9999px;

  /* Day view 3 (Add to plan on the recipe page): DESIGN.md, Buttons */
  --space-plan-hair: 1px;
  --space-plan-track: 3px;
  --space-plan-row: 6px;
  --space-plan-chip-end: 7px;
  --space-plan-gap: 10px;
  --space-plan-stack: 14px;
  --space-plan-sheet: 22px;
  --radius-plan-row: 10px;
  --radius-plan-chip: 12px;
  --radius-plan-track: 15px;
  --radius-plan-popover: 22px;
  --text-plan-chip: 11px;
  --text-plan-note: 13px;
  --text-plan-retry: 15px;
  --text-plan-toast: 15.5px;
  --text-plan-heading: 17px;
  --text-plan-date: 18px;
  --text-plan-title: 20px;
  --leading-plan-date: 1;
  --leading-masonry-title: 22px;
  --leading-masonry-meta: 22px;
  --leading-masonry-row: 20px;
  --leading-masonry-note: 16px;
  --tracking-plan-chip: 0.06em;

  /* Groceries tiles and card: DESIGN.md, Groceries tiles */
  --space-groceries-track: 3px;
  --space-groceries-tight: 6px;
  --space-groceries-gap: 10px;
  --space-groceries-stack: 14px;
  --space-groceries-aisle: 18px;
  --space-groceries-card: 20px;
  --space-groceries-page: 56px;
  --radius-groceries-cover: 5px;
  --radius-groceries-row: 10px;
  --radius-groceries-tile: 12px;
  --radius-groceries-sheet: 20px;
  --radius-groceries-card: 22px;
  --text-groceries-phone: 13.5px;
  --text-groceries-amount: 14px;
  --text-groceries-name: 15px;
  --text-groceries-heading: 17px;
  --text-groceries-total: 18px;
  --text-groceries-recipe: 19px;
  --text-groceries-card: 30px;
  --space-profile-2: 2px;
  --space-profile-3: 3px;
  --space-profile-4: 4px;
  --space-profile-6: 6px;
  --space-profile-7: 7px;
  --space-profile-8: 8px;
  --space-profile-10: 10px;
  --space-profile-12: 12px;
  --space-profile-13: 13px;
  --space-profile-14: 14px;
  --space-profile-16: 16px;
  --space-profile-18: 18px;
  --space-profile-20: 20px;
  --space-profile-22: 22px;
  --space-profile-36: 36px;
  --space-profile-44: 44px;
  --space-profile-pick: 40px;
  --tracking-profile-phone: -0.225px;
  --radius-profile-9: 9px;
  --radius-profile-10: 10px;
  --radius-profile-12: 12px;
  --radius-profile-14: 14px;
  --radius-profile-pick: 12px;
  --text-profile-12-5: 12.5px;
  --text-profile-13: 13px;
  --text-profile-14: 14px;
  --text-profile-15: 15px;
  --text-profile-16: 16px;
  --text-profile-24: 24px;
  --text-profile-avatar: 26.88px;
  --text-profile-avatar-phone: 23.52px;
  --text-profile-control: 15px;
  --leading-profile-1: 1;
  --leading-profile-1-15: 1.15;
  --leading-profile-1-25: 1.25;
  /* Buttons, tabs, chips, inputs and toggles. Round is only for circles. */
  --radius-control: var(--radius-md);

  /* Easing (DESIGN.md, Motion). JS animations read these with getComputedStyle. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-out-soft: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-out-cubic: cubic-bezier(0.33, 1, 0.68, 1);

  /* Transitions */
  --transition-fast: 150ms ease;

  /* Semantic UI Tokens (aliases only; pass 1 no usage changes) */
  --ui-bg-page: var(--color-cream);
  --ui-bg-surface: var(--color-paper);
  --ui-bg-surface-muted: var(--color-cream);
  --ui-bg-surface-muted-strong: var(--color-cream-dark);
  --ui-bg-inverse: var(--color-ink);
  --ui-bg-inverse-muted: var(--color-ink);

  --ui-text: var(--color-ink);
  --ui-text-strong: var(--color-ink);
  --ui-text-muted: var(--color-ink-soft);
  --ui-text-subtle: var(--color-ink-soft);
  --ui-text-inverse: var(--color-white);

  --ui-border: var(--color-border);
  --ui-border-subtle: var(--color-border);

  --ui-accent: var(--color-heeler);
  --ui-accent-hover: var(--color-heeler-dark);
  --ui-accent-soft: var(--color-border);

  --ui-positive: var(--color-heeler);
  --ui-positive-hover: var(--color-ink);
  --ui-positive-soft: var(--color-cream-dark);

  --ui-focus-ring: var(--color-hover);
  --ui-focus-outline: var(--color-heeler);

  --ui-shadow-1: var(--shadow-sm);
  --ui-shadow-2: var(--shadow-md);
  --ui-shadow-3: var(--shadow-lg);
  --ui-shadow-4: var(--shadow-lifted);

  --ui-notification-surface: var(--color-paper);
  --ui-notification-border: var(--line-color);
  --ui-notification-shadow: none;
  --ui-notification-shadow-raised: none;
  --ui-notification-shadow-back: none;
}

/* ========================================
   Base Styles & Reset
   ======================================== */
*, *::before, *::after {
  box-sizing: border-box;
}

/* One palette for the page and its screen edges. A page that changes
   color at its edges sets these on :root (page_edges_controller.js). */
:root {
  --page-color: var(--color-cream);
  --page-background: var(--page-color);
  --edge-top-background: var(--page-background);
  --edge-bottom-background: var(--page-background);
}

html {
  font-size: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background: var(--edge-top-background);
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  font-kerning: normal;
  color: var(--color-ink);
  background: var(--edge-bottom-background);
  min-height: 100vh;
  min-height: 100dvh;
}

/* Mobile Safari tints its status bar and bottom toolbar from what sits
   at the screen edges. Thin fixed strips there carry the edge colors;
   they stay inside the safe areas' padding, clear of content. */
.edge-top,
.edge-bottom {
  position: fixed;
  left: 0;
  right: 0;
  z-index: var(--z-edges);
  pointer-events: none;
}

.edge-top { top: 0; height: max(12px, env(safe-area-inset-top, 0px)); }
.edge-bottom { bottom: 0; height: max(12px, env(safe-area-inset-bottom, 0px)); }

.edge-top::after,
.edge-bottom::after {
  content: "";
  position: absolute;
  inset: 0;
}

.edge-top::after { background: var(--edge-top-background); }
.edge-bottom::after { background: var(--edge-bottom-background); }

/* A mouse-driven window has no Safari toolbars to tint; keep content clear. */
@media (hover: hover) and (pointer: fine) {
  .edge-top,
  .edge-bottom { display: none; }
}


body:not(.controller-prototype) :is(a, button, input, select, textarea):not(.recipe-index-search-input):focus-visible {
  outline: 2px solid var(--ui-focus-outline);
  outline-offset: 2px;
}

body:not(.controller-prototype) :is(.auth-title, .profile-header-copy h1, .video-hero-title) {
  text-wrap: balance;
}

.text-measure {
  max-width: 65ch;
}

/* Stream sources carry no content; keep them out of flex and grid gaps. */
turbo-cable-stream-source {
  display: none;
}

.header-search-toggle {
  width: 40px;
  height: 40px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--ui-text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: color var(--transition-fast), background var(--transition-fast);
}

.header-search-toggle:hover {
  color: var(--ui-text-strong);
  background: color-mix(in srgb, var(--ui-accent-soft) 35%, transparent);
}

.header-search-toggle[aria-expanded="true"] {
  color: var(--ui-accent-hover);
  background: color-mix(in srgb, var(--ui-accent-soft) 50%, transparent);
}

.header-search-toggle svg {
  width: 20px;
  height: 20px;
}

/* ========================================
   Notebook search - Backyard Blue.
   Phone: a full screen with a back arrow beside the field.
   Desktop: a page under the sky navbar band, one 872px column.
   ======================================== */
body.recipe-search-modal-open {
  overflow: hidden;
}

.recipe-index-search-shell {
  position: fixed;
  margin: 0;
  padding: 0;
  border: 0;
  width: 100%;
  max-width: none;
  max-height: none;
  top: var(--search-viewport-top, 0px);
  left: 0;
  right: 0;
  height: var(--search-viewport-height, 100dvh);
  z-index: var(--z-search);
  display: flex;
  background: var(--color-cream);
  color: var(--color-ink);
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms var(--ease-out-soft);
}

.recipe-index-search-shell::backdrop {
  background: transparent;
}

.recipe-index-search-shell[hidden] {
  display: none;
}

.recipe-index-search-shell.is-open {
  opacity: 1;
  pointer-events: auto;
}

.recipe-index-search-shell__inner {
  width: 100%;
  min-height: 0;
}

.recipe-index-search-shell__paper {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}

.recipe-index-search-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md) var(--space-sm-md) var(--space-sm-md);
}

.recipe-index-search-close {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: var(--radius-round);
  background: transparent;
  color: var(--color-ink);
  cursor: pointer;
}

.recipe-index-search-close svg { width: 20px; height: 20px; }

.recipe-index-search-bar {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-2xs) var(--space-xs) var(--space-2xs) var(--space-sm-md);
  border: var(--line);
  border-radius: var(--radius-lg);
  background: var(--color-paper);
  outline: 4px solid var(--color-hover);
}

.recipe-index-search-input-icon {
  flex: 0 0 auto;
  display: flex;
  width: 18px;
  height: 18px;
  color: var(--color-ink);
}

.recipe-index-search-input-icon svg { width: 100%; height: 100%; }

.recipe-index-search-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--space-sm-md) 0;
  border: 0;
  background: transparent;
  font-weight: var(--weight-regular);
  font-size: var(--text-body);
  line-height: var(--leading-label);
  font-family: var(--font-body);
  color: var(--color-ink);
}

.recipe-index-search-input::placeholder { color: var(--color-ink-soft); }

.recipe-index-search-input:focus,
.recipe-index-search-input:focus-visible {
  outline: none;
}

.recipe-index-search-clear {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: var(--radius-round);
  background: var(--color-cream-dark);
  color: var(--color-ink);
  cursor: pointer;
}

.recipe-index-search-clear svg { width: 14px; height: 14px; }

.recipe-index-search-clear[hidden],
.recipe-index-search-reset[hidden] {
  display: none;
}

.recipe-index-search-status {
  flex: 0 0 auto;
  padding: var(--space-xs) var(--space-md) var(--space-sm);
  font-weight: var(--weight-bold);
  font-size: var(--text-label);
  line-height: var(--leading-body);
  font-family: var(--font-body);
  color: var(--color-ink-soft);
}

.recipe-index-search-status:empty {
  display: none;
}

.recipe-index-search-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm-md);
  padding: 0 var(--space-md) var(--space-lg);
}

.recipe-index-search-empty {
  display: grid;
  place-items: center;
  min-height: 140px;
  padding: var(--space-xl) var(--space-xs);
  font-weight: var(--weight-semibold);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  font-family: var(--font-body);
  color: var(--color-ink-soft);
  text-align: center;
}

.recipe-index-search-empty.is-no-match {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-sm);
  min-height: 0;
  margin: var(--space-xs) 0;
  padding: var(--space-xl);
  border: 1.5px dashed var(--color-heeler);
  border-radius: var(--radius-xl);
  background: var(--color-paper);
  text-align: left;
}

.recipe-index-search-empty__title {
  font-weight: var(--weight-semibold);
  font-size: var(--text-title);
  line-height: var(--leading-label);
  font-family: var(--font-display);
  color: var(--color-ink);
}

.recipe-index-search-empty__hint {
  font-size: var(--text-body);
  font-weight: var(--weight-regular);
  color: var(--color-ink-soft);
}

.recipe-index-search-empty[hidden] {
  display: none;
}

.recipe-index-search-reset { align-self: center; }

/* Clear, Load more and Try again: secondary buttons. */
.recipe-index-search-body > .btn {
  align-self: center;
  min-height: 44px;
  padding: var(--button-secondary-padding);
  border: var(--line);
  border-radius: var(--radius-control);
  background: var(--color-paper);
  color: var(--color-ink);
  font-weight: var(--weight-semibold);
  font-size: var(--text-body);
  line-height: var(--leading-display);
  font-family: var(--font-display);
  cursor: pointer;
}

.recipe-index-search-body > .btn[hidden] { display: none; }

@media (hover: hover) and (pointer: fine) {
  .recipe-index-search-body > .btn:hover { background: var(--color-hover); }
}

.recipe-index-search-results {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.recipe-index-search-results[hidden] {
  display: none;
}

/* Result: framed thumbnail, recipe name, its source, chevron. */
.recipe-index-search-result-link {
  display: flex;
  align-items: center;
  gap: var(--space-sm-md);
  min-width: 0;
  padding: var(--space-sm) 0;
  border-bottom: 1.5px solid var(--color-border);
  color: var(--color-ink);
  text-decoration: none;
  animation: search-row-in 220ms var(--ease-out-soft) both;
}

@keyframes search-row-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; }
}

.recipe-index-search-result-link--active {
  background: var(--color-paper);
}

.recipe-index-search-thumb {
  flex: 0 0 auto;
  width: 88px;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: var(--line);
  border-radius: var(--radius-sm);
  background: var(--color-hover);
}

.recipe-index-search-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.recipe-index-search-copy {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.recipe-index-search-name,
.recipe-index-search-meta {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.recipe-index-search-name {
  font-weight: var(--weight-semibold);
  font-size: var(--text-body);
  line-height: var(--leading-label);
  font-family: var(--font-display);
}

.recipe-index-search-meta {
  font-weight: var(--weight-semibold);
  font-size: var(--text-label);
  line-height: var(--leading-body);
  font-family: var(--font-body);
  color: var(--color-ink-soft);
}

.recipe-index-search-chevron {
  display: none;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
}

@media (prefers-reduced-motion: reduce) {
  .recipe-index-search-result-link { animation: none; }
}

@media (min-width: 768px) {
  .recipe-index-search-shell {
    top: calc(var(--navbar-height) + env(safe-area-inset-top, 0px));
    bottom: 0;
    height: auto;
    z-index: var(--z-search-page);
  }

  /* The field stays put; the result list scrolls under it. */
  .recipe-index-search-shell__inner {
    max-width: 920px;
    margin: 0 auto;
    padding: var(--space-xl) var(--space-lg) 0;
  }

  .recipe-index-search-shell__paper {
    gap: var(--space-lg);
    padding: 0;
  }

  .recipe-index-search-results { padding-bottom: calc(var(--space-sm) * 8); }

  .recipe-index-search-head { padding: 0; }

  .recipe-index-search-bar {
    gap: var(--space-sm-md);
    padding: var(--space-sm) var(--space-sm) var(--space-sm) var(--space-lg);
    border-radius: var(--radius-xl);
    outline-width: 5px;
  }

  .recipe-index-search-input-icon { width: 24px; height: 24px; }
  .recipe-index-search-input { padding: var(--space-sm-md) 0; font-size: var(--text-title); }
  .recipe-index-search-clear { width: 44px; height: 44px; }
  .recipe-index-search-clear svg { width: 16px; height: 16px; }

  .recipe-index-search-status { margin-top: calc(var(--space-sm-md) * -1); padding: 0 var(--space-2xs); font-size: var(--text-body); }
  .recipe-index-search-body { padding: 0; }
  .recipe-index-search-results { gap: var(--space-sm-md); }

  .recipe-index-search-result-link {
    gap: var(--space-md);
    padding: var(--space-sm) var(--space-md) var(--space-sm) var(--space-sm);
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-cream);
    transition: background-color 150ms ease, border-color 150ms ease;
  }

  .recipe-index-search-result-link:hover,
  .recipe-index-search-result-link--active {
    border-color: var(--color-ink);
    background: var(--color-paper);
  }


  .recipe-index-search-thumb {
    width: 112px;
    border-radius: var(--radius-md);
  }

  .recipe-index-search-name { font-size: var(--text-title); }
  .recipe-index-search-meta { font-size: var(--text-label); }
  .recipe-index-search-chevron { display: block; }

  /* While search is open the navbar marks search, not a page. */
  .recipe-index-page--search-open .app-navbar-link--current {
    background: transparent;
    color: var(--color-ink);
    font-weight: var(--weight-medium);
  }
}

.app-shell {
  min-height: 100vh;
  min-height: 100dvh;
  overflow-x: clip;
  background: var(--page-background);
}

/* ========================================
   App navbar - Backyard Blue.
   Desktop: a sky band with a heeler-dark rule; tabs sit in one white track,
   and the current page is a filled Heeler Blue rounded rectangle.
   Phone: brand and round actions on cream; the tabs move to a
   floating white tab bar at the bottom of the screen.
   ======================================== */
.app-navbar-shell {
  position: sticky;
  top: 0;
  z-index: var(--z-navbar);
  padding-top: env(safe-area-inset-top, 0px);
  background: var(--color-cream);
}

.app-navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  width: 100%;
  margin: 0;
  padding: var(--space-md) max(var(--space-md), env(safe-area-inset-right, 0px)) var(--space-sm-md) max(var(--space-md), env(safe-area-inset-left, 0px));
}

.app-navbar-brand {
  min-width: 0;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  color: var(--color-ink);
  text-decoration: none;
}

/* The pot mark carries the brand alone: as tall as the round actions. */
.app-navbar-brand .brand-mark {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
}

.app-navbar-brand-title {
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-title);
  color: var(--color-ink);
}

/* Phone tab bar: white, heeler-dark line, floats above the page bottom.
   Inside the safe area, like the iOS tab bar: just above the home
   indicator, clear of the notch in landscape, centred on wide phones. */
.app-navbar-nav {
  position: fixed;
  z-index: var(--z-tab-bar);
  left: calc(12px + env(safe-area-inset-left, 0px));
  right: calc(12px + env(safe-area-inset-right, 0px));
  bottom: max(16px, env(safe-area-inset-bottom, 0px));
  max-width: 480px;
  margin: 0 auto;
}

/* Scroll targets and focus stay clear of the phone tab bar. */
html:has(.app-navbar-nav) {
  scroll-padding-bottom: calc(var(--space-sm) * 12 + env(safe-area-inset-bottom, 0px));
}

.app-navbar-links {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-xs);
  margin: 0;
  padding: var(--space-sm);
  list-style: none;
  background: var(--color-paper);
  border: var(--line);
  border-radius: var(--radius-xl);
}

.app-navbar-link-item {
  display: contents;
}

.app-navbar-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  min-height: 44px;
  padding: var(--space-sm) 0;
  border-radius: var(--radius-control);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
  line-height: var(--leading-body);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--transition-fast), color var(--transition-fast);
  /* Native tab feel: no grey tap flash, no double-tap zoom, and a long
     press does not select the label or open the link preview. */
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

.app-navbar-link:not(.app-navbar-link--current):active {
  background: var(--color-hover);
}

.app-navbar-link-icon {
  width: 22px;
  height: 22px;
}

/* Compact height (phone in landscape): icon beside label, as iOS does. */
@media (max-width: 767px) and (max-height: 500px) {
  .app-navbar-link {
    flex-direction: row;
    gap: var(--space-sm);
    padding: var(--space-xs) 0;
  }
}

/* The touch keyboard covers the page bottom; iOS hides the tab bar
   while it is open. Checkboxes and buttons bring no keyboard. */
@media (max-width: 767px) and (hover: none) and (pointer: coarse) {
  html:has(:is(input:not([type="checkbox"], [type="radio"], [type="button"], [type="submit"], [type="reset"], [type="file"], [type="range"], [type="color"], [type="image"]), textarea, [contenteditable="true"]):focus) .app-navbar-nav {
    visibility: hidden;
  }
}

.app-navbar-link--current {
  background: var(--color-heeler);
  color: var(--color-paper);
  font-weight: var(--weight-extrabold);
}

/* The round actions never shrink: the Kitchen name gives way and ellipsizes. */
.app-navbar-actions {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-sm);
}

/* Round actions: 44px circles on a quiet border line. */
.app-navbar-search-toggle,
.app-navbar-shell .kitchen-header-members,
.app-navbar-profile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  min-width: 44px;
  padding: 0;
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-round);
  background: transparent;
  color: var(--color-ink);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--transition-fast), transform 160ms var(--ease-out, ease);
}

/* Open search: a filled ink button, also under the pointer. */
.app-navbar-shell .app-navbar-search-toggle[aria-expanded="true"] {
  border-color: var(--color-ink);
  background: var(--color-ink);
  color: var(--color-paper);
}

.app-navbar-profile {
  overflow: hidden;
  background: var(--color-cream-dark);
}

.app-navbar-profile-avatar {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  border-radius: 50%;
  overflow: hidden;
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  color: var(--color-ink);
  background: var(--color-cream-dark);
}

.app-navbar-profile--current {
  outline: 3px solid var(--ui-focus-outline);
  outline-offset: 0;
}

/* Board: avatar disc only. The name stays for screen readers. */
.app-navbar-profile-meta {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

@media (hover: hover) and (pointer: fine) {
  .app-navbar-link:not(.app-navbar-link--current):hover {
    background: var(--color-hover);
  }

  .app-navbar-search-toggle:hover,
  .app-navbar-shell .kitchen-header-members:hover {
    background: var(--color-hover);
  }

  .app-navbar-profile:hover {
    border-color: var(--line-color);
    background: var(--color-hover);
  }
}

.app-navbar-search-toggle:active,
.app-navbar-shell .kitchen-header-members:active,
.app-navbar-profile:active {
  transform: scale(0.96);
}

.app-navbar-shell .app-navbar :is(.app-navbar-brand, .app-navbar-link, .app-navbar-search-toggle, .kitchen-header-members, .app-navbar-profile):focus-visible {
  outline: 3px solid var(--ui-focus-outline);
  outline-offset: 2px;
}

.app-navbar-shell .app-navbar .app-navbar-brand:focus-visible {
  border-radius: var(--radius-control);
}

@media (prefers-reduced-motion: reduce) {
  .app-navbar-link,
  .app-navbar-search-toggle,
  .app-navbar-shell .kitchen-header-members,
  .app-navbar-profile {
    transition: none;
  }

  .app-navbar-search-toggle:active,
  .app-navbar-shell .kitchen-header-members:active,
  .app-navbar-profile:active {
    transform: none;
  }
}

/* Tablet up: one row on the page colour over a quiet rule; the tabs sit bare. */
@media (min-width: 768px) {
  :root {
    --navbar-height: 83px;
  }

  .app-navbar-shell {
    border-bottom: 1px solid var(--color-border);
  }

  /* Boards size content-box: 1200px plus 24px gutters. */
  .app-navbar {
    max-width: 1248px;
    margin: 0 auto;
    padding: var(--space-md) max(var(--space-lg), env(safe-area-inset-right, 0px)) var(--space-md) max(var(--space-lg), env(safe-area-inset-left, 0px));
    gap: var(--space-md);
  }

  .app-navbar-brand {
    gap: var(--space-sm-md);
  }

  .app-navbar-brand .brand-mark {
    /* 16px + 50px + 16px + the 1px rule: the bar is --navbar-height tall. */
    width: 50px;
    height: 50px;
  }

  .app-navbar-brand-title {
    font-size: var(--text-title);
  }

  html:has(.app-navbar-nav) {
    scroll-padding-bottom: 0;
  }

  .app-navbar-nav {
    position: static;
    flex: 0 1 auto;
    max-width: none;
    margin: 0 auto;
  }

  .app-navbar-links {
    display: flex;
    gap: var(--space-sm);
    padding: var(--space-xs);
    border-color: transparent;
    border-radius: var(--radius-lg);
    background: transparent;
  }

  .app-navbar-link {
    flex-direction: row;
    min-height: 40px;
    padding: var(--space-sm) var(--space-md);
    border-radius: var(--radius-control);
    font-family: var(--font-display);
    font-size: var(--text-body);
    font-weight: var(--weight-medium);
    line-height: var(--leading-title);
  }

  .app-navbar-link--current {
    font-weight: var(--weight-semibold);
  }

  .app-navbar-link-icon {
    display: none;
  }

  .app-navbar-actions {
    margin-left: auto;
    gap: var(--space-sm-md);
  }

  .app-navbar-profile-avatar {
    font-size: var(--text-body);
  }
}

/* Equal side columns keep the tabs at the true centre. Tablets do this
   only beside the pot mark alone: a Kitchen switcher keeps content-sized
   sides, so a long Kitchen name has room before it ellipsizes. */
@media (min-width: 768px) {
  .app-navbar:not(:has(.kitchen-switcher)) :is(.kitchen-header-context, .app-navbar-actions) {
    flex: 1 1 0;
  }
}

@media (min-width: 1024px) {
  .kitchen-header-context,
  .app-navbar-actions {
    flex: 1 1 0;
  }
}

/* Pages own their gutters: a 1200px column plus 24px each side
   (16px on the phone). The phone keeps room for the tab bar, and a
   phone in landscape keeps content clear of the notch. */
.app-main {
  padding: 0 env(safe-area-inset-right, 0px) calc(var(--space-sm) * 13 + env(safe-area-inset-bottom, 0px)) env(safe-area-inset-left, 0px);
}

@media (min-width: 768px) {
  .app-main {
    padding-bottom: 0;
  }
}

.swipe-content {
  min-height: 100vh;
}

.swipe-content[inert] {
  pointer-events: none;
  user-select: none;
}

@media (max-width: 767px) {
  .app-main {
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
  }

  .swipe-content {
    min-height: 100vh;
    min-height: 100dvh;
  }

  body.is-authenticated .swipe-content {
    --tab-bar-clearance: calc(90px + env(safe-area-inset-bottom, 0px));
    padding-bottom: var(--tab-bar-clearance);
  }
}

.notification-toaster {
  position: fixed;
  right: calc(24px + env(safe-area-inset-right, 0px));
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  z-index: var(--z-toaster);
  width: min(380px, calc(100% - 48px));
  pointer-events: none;
}

body:has(.plan-week-bottom-search) .notification-toaster {
  bottom: calc(80px + env(safe-area-inset-bottom, 0px));
}

.notification-toaster--empty {
  width: 0;
}

/* Bottom-anchored pill stack. notification_stack_controller.js measures each
   card and sets the offsets; CSS picks the collapsed or expanded set. */
.notification-toaster-stack {
  --notification-stack-peek: 10px;
  --notification-stack-gap: 8px;
  --notification-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  position: relative;
  height: var(--notification-stack-collapsed, auto);
  transition: height 360ms var(--notification-ease-out);
}

.notification-toaster.is-expanded .notification-toaster-stack {
  height: var(--notification-stack-expanded, auto);
  /* Keep the pointer on the stack while it crosses the gaps between cards. */
  pointer-events: auto;
}

/* An ink pill: solid fill, paper text, no line (DESIGN.md Elevation). It is as
   wide as its words, up to the toaster, and keeps the toaster's right edge. */
.notification-card {
  --notification-fill: var(--color-ink);
  --notification-y: var(--notification-y-collapsed, 0px);
  --notification-scale: var(--notification-scale-collapsed, 1);
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  width: max-content;
  max-width: 100%;
  margin-left: auto;
  display: flex;
  gap: var(--space-sm-md);
  align-items: center;
  box-sizing: border-box;
  overflow: hidden;
  min-height: 44px;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-xl);
  border: 0;
  background: var(--notification-fill);
  box-shadow: none;
  color: var(--color-paper);
  opacity: 0;
  translate: 0 18px;
  scale: 0.96;
  transform:
    translate3d(var(--notification-swipe-x, 0px), var(--notification-y), 0)
    scale(var(--notification-scale));
  transform-origin: 50% 0;
  pointer-events: auto;
  touch-action: pan-y;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
  transition:
    transform 360ms var(--notification-ease-out),
    translate 420ms var(--notification-ease-out),
    scale 420ms var(--notification-ease-out),
    opacity 240ms var(--notification-ease-out),
    height 360ms var(--notification-ease-out),
    box-shadow 360ms var(--notification-ease-out),
    background-color 360ms var(--notification-ease-out);
}

.notification-card.is-visible {
  opacity: var(--notification-swipe-fade, 1);
  translate: 0 0;
  scale: 1;
}

.notification-card.is-settled {
  transition: none;
}

.notification-card--alert {
  --notification-fill: var(--color-tomato-ink);
}

/* Collapsed: back cards match the front card, hide their words, and peek above
   it in lighter fills, so pills without a line still read as a stack. */
.notification-toaster:not(.is-expanded) .notification-card:not(.is-front) {
  width: var(--notification-front-width, max-content);
  height: var(--notification-front-height, auto);
  box-shadow: var(--ui-notification-shadow-back);
}

/* Key the fills on the stack controller's depth classes, so a new card is
   never drawn as a back card before the controller places it. A closing card
   keeps its old class until it leaves, so it never sets the depth, and the
   front card never takes a back fill. */
.notification-toaster:not(.is-expanded) .notification-card.is-next {
  background: color-mix(in srgb, var(--notification-fill) 75%, var(--color-cream));
}

.notification-toaster:not(.is-expanded) .notification-card.is-next:not(.is-closing) ~ .notification-card:not(.is-front) {
  background: color-mix(in srgb, var(--notification-fill) 55%, var(--color-cream));
}

.notification-card > * {
  transition: opacity 240ms var(--notification-ease-out);
}

.notification-toaster:not(.is-expanded) .notification-card:not(.is-front) > * {
  opacity: 0;
  transition-duration: 120ms;
}

/* While the front notice is swiped away, show the notice under it. */
.notification-toaster-stack:has(> .is-front.is-swiping) > .notification-card.is-next {
  width: max-content;
  background: var(--notification-fill);
}

.notification-toaster-stack:has(> .is-front.is-swiping) > .notification-card.is-next > * {
  opacity: 1;
}

/* Let opening cards separate before their words fade in, so lines never overlap. */
.notification-toaster.is-expanded .notification-card:not(.is-front) > * {
  transition-delay: 120ms;
}

.notification-card.is-buried.is-visible {
  opacity: 0;
  pointer-events: none;
}

.notification-toaster.is-expanded .notification-card {
  --notification-y: var(--notification-y-expanded, 0px);
  --notification-scale: 1;
}

.notification-toaster.is-expanded .notification-card.is-buried.is-visible {
  opacity: 1;
  pointer-events: auto;
}

.notification-card.is-swiping {
  transition: opacity 120ms linear;
  cursor: grabbing;
}

.notification-card.is-closing {
  opacity: 0;
  translate: 0 10px;
  scale: 0.96;
  pointer-events: none;
  transition-duration: 220ms;
  transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}

.notification-card.is-swiped.is-closing {
  translate: 0 0;
  scale: 1;
  transition-timing-function: var(--notification-ease-out);
}

/* A bare mark leads each pill: a tick when done, "!" for a problem. */
.notification-card__indicator {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  color: var(--color-paper);
}

.notification-card__indicator svg {
  width: 18px;
  height: 18px;
  stroke-width: 2.8;
}

.notification-card__content {
  flex: 1 1 auto;
  min-width: 0;
}

.notification-card__text {
  margin: 0;
  overflow-wrap: anywhere;
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-label);
  color: var(--color-paper);
  text-wrap: pretty;
}

/* The time left runs out along the bottom edge, inset clear of the round ends. */
.notification-card__time {
  position: absolute;
  left: var(--space-lg);
  bottom: 0;
  width: calc(100% - 2 * var(--space-lg));
  height: 3px;
  border-radius: var(--radius-round);
  background: color-mix(in srgb, var(--color-paper) 60%, transparent);
  transform-origin: left;
}

.notification-card:focus-visible {
  outline: 2px solid var(--ui-focus-outline);
  outline-offset: 2px;
}

@media (hover: hover) and (pointer: fine) {
  .notification-toaster.is-expanded .notification-card.is-front {
    box-shadow: var(--ui-notification-shadow-raised);
  }
}

@media (max-width: 767px) {
  .notification-toaster {
    left: calc(16px + env(safe-area-inset-left, 0px));
    right: calc(16px + env(safe-area-inset-right, 0px));
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    width: auto;
  }

  /* Sit 12px above the phone tab bar (76px tall), never on it. */
  body:has(.app-navbar-nav) .notification-toaster {
    bottom: calc(max(16px, env(safe-area-inset-bottom, 0px)) + 76px + var(--space-sm-md));
  }

  /* Floating controls above the tab bar: the recipes add button (top at
     160px) and the plan picker's bottom search (top at 158px). */
  body:has(.rx-add__toggle) .notification-toaster {
    bottom: calc(160px + var(--space-sm-md) + env(safe-area-inset-bottom, 0px));
  }

  body:has(.plan-week-bottom-search) .notification-toaster {
    bottom: calc(158px + var(--space-sm-md) + env(safe-area-inset-bottom, 0px));
  }

  .notification-toaster-stack {
    --notification-stack-peek: 8px;
  }

  /* On the phone the toaster spans the screen, so a pill sits in its centre. */
  .notification-card {
    margin-right: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  /* Reduced motion: always show every card in a still list. */
  .notification-toaster-stack,
  .notification-toaster.is-expanded .notification-toaster-stack {
    height: var(--notification-stack-expanded, auto);
    pointer-events: auto;
    transition: none;
  }

  .notification-card,
  .notification-toaster.is-expanded .notification-card {
    --notification-y: var(--notification-y-expanded, 0px);
    --notification-scale: 1;
    translate: none;
    scale: none;
    transition: opacity 120ms linear;
  }

  .notification-toaster:not(.is-expanded) .notification-card:not(.is-front) {
    width: max-content;
    height: auto;
    box-shadow: var(--ui-notification-shadow);
  }

  .notification-toaster:not(.is-expanded) .notification-card.is-next,
  .notification-toaster:not(.is-expanded) .notification-card.is-next:not(.is-closing) ~ .notification-card:not(.is-front) {
    background: var(--notification-fill);
  }

  .notification-toaster:not(.is-expanded) .notification-card:not(.is-front) > *,
  .notification-card.is-buried.is-visible {
    opacity: 1;
    pointer-events: auto;
  }

  .notification-card.is-closing {
    translate: none;
    scale: none;
  }
}

@media (min-width: 640px) and (max-width: 767px) {
  :root {
    --mobile-tablet-edge-gutter: clamp(18px, 3.4vw, 28px);
  }

  .header {
    padding-left: var(--mobile-tablet-edge-gutter);
    padding-right: var(--mobile-tablet-edge-gutter);
  }

  .header::after {
    left: var(--mobile-tablet-edge-gutter);
    right: var(--mobile-tablet-edge-gutter);
  }
}

/* ========================================
   Recipe Shelf (index)
   ======================================== */
@keyframes shelf-dots {
  0%, 100% { opacity: 0.25; }
  50% { opacity: 1; }
}

.recipe-shelf-empty {
  padding: var(--space-2xl) var(--space-md);
  text-align: center;
}

.recipe-shelf-empty h2 {
  margin: 0 0 var(--space-xs);
  font-family: var(--font-display);
  font-size: var(--text-title);
  color: var(--ui-text-strong);
}

.recipe-shelf-empty p {
  margin: 0;
  color: var(--ui-text-muted);
}

/* Channel attribution */
.channel-attribution {
  display: inline-flex;
  align-items: center;
  min-width: 44px;
  min-height: 44px;
  max-width: 100%;
  border-radius: var(--radius-control);
  color: inherit;
  text-decoration: none;
  transition: color var(--transition-fast);
}

.channel-attribution__avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  flex-shrink: 0;
  overflow: hidden;
  position: relative;
  background: var(--color-cream-dark);
}

.channel-attribution__avatar-image {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}

.channel-attribution__label {
  display: block;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ========================================
   Animations
   ======================================== */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

.header {
  animation: none;
}

/* ========================================
   Utility Classes
   ======================================== */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: calc(var(--space-2xs) * -1);
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.recipe-favorite-control {
  margin: 0;
}

.recipe-favorite-button {
  width: 44px;
  min-width: 44px;
  height: 44px;
  padding: 0;
  display: grid;
  place-items: center;
  border: var(--line);
  border-radius: var(--radius-round);
  background: var(--color-paper);
  color: var(--color-ink);
  cursor: pointer;
  transition: background-color var(--transition-fast), transform 120ms ease;
}

.recipe-favorite-button svg {
  width: 19px;
  height: 19px;
}

.recipe-favorite-button:focus-visible {
  outline: 2px solid var(--ui-focus-outline);
  outline-offset: 2px;
}

@media (hover: hover) and (pointer: fine) {
  .recipe-favorite-button:hover {
    background: var(--color-hover);
  }
}

.recipe-favorite-button:active {
  transform: scale(0.95);
}

.recipe-favorite-button.is-favorited {
  border-color: var(--line-color);
  background: var(--color-cream-dark);
}

.recipe-favorite-button.is-favorited svg {
  fill: var(--color-ink);
}

.recipe-favorite-button:disabled {
  cursor: wait;
  opacity: 0.65;
}

.prep-ahead-section {
  padding: 0 var(--space-lg) var(--space-lg);
  animation: none;
}

.prep-analysis-status {
  font-size: var(--text-body);
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  border: 1px solid var(--ui-border-subtle);
  background: var(--ui-bg-surface);
  color: var(--ui-text);
}

.prep-analysis-status--succeeded {
  background: var(--ui-positive-soft);
  border-color: color-mix(in srgb, var(--ui-positive) 28%, var(--ui-border-subtle));
  color: var(--ui-text);
}

.prep-analysis-status--failed {
  background: color-mix(in srgb, var(--ui-accent-soft) 55%, var(--ui-bg-surface));
  border-color: color-mix(in srgb, var(--ui-accent) 28%, var(--ui-border-subtle));
  color: var(--ui-text);
}

.prep-analysis-status--running,
.prep-analysis-status--queued {
  background: var(--ui-bg-surface-muted-strong);
  color: var(--ui-text);
}

.prep-analysis-error,
.prep-analysis-note {
  margin: 0 0 var(--space-md);
  color: var(--ui-text-muted);
}

.prep-task-list {
  display: grid;
  gap: var(--space-md);
}

.prep-task-card {
  padding: var(--space-md) 0 0;
  border-top: 1px solid var(--ui-border-subtle);
}

.prep-task-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  margin-bottom: var(--space-xs);
}

.prep-task-header h3 {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-body);
  color: var(--ui-text-strong);
}

.prep-task-timing {
  flex-shrink: 0;
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  color: var(--color-ink-soft);
}

.prep-task-instruction {
  margin: 0;
  font-size: var(--text-body);
  color: var(--ui-text-muted);
}

/* ========================================
   Desktop Expansion - Kitchen Notebook
   ======================================== */
@media (min-width: 768px) {
  .header {
    padding-left: clamp(var(--space-lg), 3vw, var(--space-xl));
    padding-right: clamp(var(--space-lg), 3vw, var(--space-xl));
  }

  .header::after {
    left: clamp(22px, 3vw, 34px);
    right: clamp(22px, 3vw, 34px);
  }
}

/* ========================================
   Ingredient sprite review page
   ======================================== */
.sprites-page {
  width: min(1180px, calc(100vw - 32px));
  margin: 0 auto;
  padding: clamp(var(--space-xl), 5vw, calc(var(--space-sm) * 7)) 0;
}

.sprites-hero {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: var(--space-lg);
  margin-bottom: var(--space-xl);
}

.sprites-kicker {
  margin: 0 0 var(--space-sm);
  color: var(--color-ink-soft);
  font-size: var(--text-label);
  font-weight: var(--weight-extrabold);
}

.sprites-hero h1 {
  margin: 0;
  color: var(--color-ink);
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: var(--weight-semibold);
  letter-spacing: 0;
  line-height: var(--leading-display);
}

.sprites-intro {
  max-width: 58ch;
  margin: var(--space-md) 0 0;
  color: var(--color-ink-soft);
  font-size: var(--text-body);
  line-height: var(--leading-body);
}

.sprites-count {
  display: grid;
  justify-items: end;
  gap: var(--space-2xs);
  min-width: 128px;
  padding: var(--space-md) var(--space-lg);
  border: var(--line);
  border-radius: var(--radius-xl);
  background: var(--color-paper);
  color: var(--color-ink);
  font-size: var(--text-label);
  font-weight: var(--weight-extrabold);
}

.sprites-count span {
  color: var(--color-ink);
  font-family: var(--font-display);
  font-size: var(--text-display);
  line-height: var(--leading-display);
}

.sprites-table-shell {
  overflow-x: auto;
  border: var(--line);
  border-radius: var(--radius-xl);
  background: var(--color-paper);
}

.sprites-table-shell:focus-visible {
  outline: 2px solid var(--ui-focus-outline);
  outline-offset: 2px;
}

.sprites-table {
  width: 100%;
  min-width: 980px;
  border-collapse: collapse;
}

.sprites-table th,
.sprites-table td {
  padding: var(--space-md) var(--space-md);
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
  text-align: left;
}

.sprites-table th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--color-cream);
  color: var(--color-ink);
  font-weight: var(--weight-semibold);
  font-size: var(--text-body);
  line-height: var(--leading-title);
  font-family: var(--font-display);
}

.sprites-table tbody tr {
  background: var(--color-paper);
}

.sprites-table tbody tr:hover {
  background: var(--color-cream);
}

.sprites-table tbody tr:last-child td {
  border-bottom: 0;
}

.sprites-recipe-cell,
.sprites-ingredient-cell {
  max-width: 220px;
  overflow-wrap: anywhere;
}

.sprites-recipe-link {
  color: var(--color-ink);
  font-family: var(--font-display);
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-label);
  text-decoration: none;
}

.sprites-recipe-link:hover {
  color: var(--color-heeler-dark);
}

.sprites-ingredient-cell {
  color: var(--color-ink);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-body);
}

.sprites-normalized-pill {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: var(--space-sm) var(--space-sm-md);
  border: var(--line);
  border-color: var(--line-color);
  border-radius: var(--radius-sm);
  background: var(--color-cream-dark);
  color: var(--color-ink-soft);
  font-size: var(--text-body);
  font-weight: var(--weight-extrabold);
}

.ingredient-art-slot {
  display: flex;
  flex: 0 0 32px;
}

/* An ingredient with no art keeps its text against the check box. */
.ingredient-art-slot:empty { display: none; }

.ingredient-art {
  width: 32px;
  height: 32px;
  object-fit: contain;
  image-rendering: pixelated;
  flex-shrink: 0;
}

.sprites-muted {
  color: var(--color-ink-soft);
  font-size: var(--text-body);
  font-style: italic;
}

.sprites-action-cell form {
  margin: 0;
}

.sprites-action-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 var(--space-md);
  border: var(--line);
  border-radius: var(--radius-control);
  background: var(--color-heeler);
  color: var(--color-paper);
  cursor: pointer;
  font-weight: var(--weight-semibold);
  font-size: var(--text-body);
  line-height: var(--leading-title);
  font-family: var(--font-display);
  transition: transform 160ms var(--ease-out);
}

.sprites-action-button:not(:disabled):active {
  transform: scale(0.97);
}

.sprites-action-button--secondary {
  background: var(--color-paper);
  color: var(--color-ink);
}

@media (hover: hover) and (pointer: fine) {
  .sprites-action-button:not(:disabled):hover { background: var(--color-heeler-dark); }
  .sprites-action-button--secondary:not(:disabled):hover { background: var(--color-hover); }
}

.sprites-action-button--disabled,
.sprites-action-button:disabled {
  background: var(--color-cream-dark);
  color: var(--color-ink-soft);
  cursor: not-allowed;
}

@media (prefers-reduced-motion: reduce) {
  .sprites-action-button:not(:disabled):active { transform: none; }
}

@media (max-width: 767px) {
  .sprites-hero {
    align-items: start;
    flex-direction: column;
  }

  .sprites-count {
    justify-items: start;
  }

  .sprites-hero h1 {
    font-size: var(--text-display-phone);
  }
}

.sprites-normalized-stack {
  display: flex;
  align-items: center;
  gap: var(--space-sm-md);
}

.sprites-recipe-owner {
  display: block;
  margin-top: var(--space-sm);
  color: var(--color-ink-soft);
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
}

.sprites-row-note {
  display: block;
  margin-top: var(--space-sm);
  color: var(--color-heeler-dark);
  font-size: var(--text-label);
  font-weight: var(--weight-extrabold);
}

/* Art inbox (ADR0048). One slot language on every screen: dashed = no art yet,
   ink line = draft, plain = live. Lanes run Missing, Review, Live, left to right. */
.art-inbox-title {
  margin: 0;
  color: var(--color-ink);
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-display);
}

.art-inbox-open {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  width: min(320px, 100%);
  min-height: 44px;
  padding: 0 var(--space-xs) 0 var(--space-sm-md);
  border: var(--line);
  border-radius: var(--radius-control);
  background: var(--color-paper);
  color: var(--color-ink-soft);
}

.art-inbox-open:focus-within {
  outline: 2px solid var(--ui-focus-outline);
  outline-offset: 2px;
}

.art-inbox-open-icon { width: 18px; height: 18px; flex: none; }

.art-inbox-open-input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--color-ink);
  font: inherit;
  outline: none;
}

.art-inbox-open-go {
  display: grid;
  place-items: center;
  flex: none;
  width: 36px;
  height: 34px;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--color-heeler);
  color: var(--color-paper);
  cursor: pointer;
}

.art-inbox-open-go svg,
.art-inbox-pair-arrow svg { width: 20px; height: 20px; }

.art-inbox-count {
  display: grid;
  place-items: center;
  min-width: 28px;
  height: 28px;
  padding: 0 var(--space-sm);
  border-radius: var(--radius-round);
  background: var(--color-cream-dark);
  color: var(--color-ink);
  font-family: var(--font-display);
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
}

.art-inbox-note {
  grid-column: 1 / -1;
  margin: 0;
  color: var(--color-ink-soft);
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
}

.art-inbox-name {
  max-width: 100%;
  overflow: hidden;
  font-size: var(--text-body);
  font-weight: var(--weight-bold);
  line-height: var(--leading-label);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.art-inbox-slot {
  position: relative;
  display: grid;
  place-items: center;
  width: 96px;
  aspect-ratio: 1;
  box-sizing: border-box;
  border-radius: var(--radius-md);
  background: var(--color-cream-dark);
  color: var(--color-ink-soft);
}

.art-inbox-slot img {
  width: 72px;
  height: 72px;
  image-rendering: pixelated;
}

.art-inbox-slot--missing { border: 1.5px dashed var(--color-border-strong); background: transparent; }
.art-inbox-slot--draft { border: var(--line); }
.art-inbox-slot--big { width: 144px; border-radius: var(--radius-lg); }
.art-inbox-slot--big img { width: 120px; height: 120px; }

.art-inbox-plus { width: 22px; height: 22px; }

.art-inbox-uses {
  position: absolute;
  top: var(--space-xs);
  right: var(--space-xs);
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-2xs) var(--space-sm);
  border-radius: var(--radius-round);
  background: var(--color-cream-dark);
  color: var(--color-ink);
  font-size: var(--text-label);
  font-weight: var(--weight-extrabold);
  line-height: var(--leading-label);
}

.art-inbox-uses svg { width: 12px; height: 12px; }

.art-inbox-back {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  min-height: 44px;
  margin-bottom: var(--space-xs);
  color: var(--color-ink);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  text-decoration: none;
}

.art-inbox-back svg { width: 18px; height: 18px; }
.art-inbox-back:hover { color: var(--color-heeler-dark); }

.art-inbox-title-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm-md);
}

.art-inbox-badge {
  padding: var(--space-xs) var(--space-sm);
  border: var(--line);
  border-radius: var(--radius-sm);
  color: var(--color-ink);
  font-family: var(--font-display);
  font-size: var(--text-label);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-label);
}

.art-inbox-form {
  display: grid;
  gap: var(--space-lg);
  justify-items: start;
}

.art-inbox-pair {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin: var(--space-lg) 0;
}

.art-inbox-form .art-inbox-pair { margin: 0; }
.art-inbox-pair-arrow { display: grid; color: var(--color-ink-soft); }

/* The drop slot wraps the real file input: the dashed hole in the accent, filled by the chosen PNG. */
.art-inbox-drop {
  position: relative;
  display: grid;
  justify-items: center;
  gap: var(--space-sm);
  cursor: pointer;
}

.art-inbox-slot--drop {
  border: 1.5px dashed var(--color-heeler);
  background: var(--color-paper);
  color: var(--color-heeler-dark);
}

.art-inbox-drop[data-filled] .art-inbox-slot--drop { border: var(--line); background: var(--color-cream-dark); }
.art-inbox-drop:focus-within .art-inbox-slot--drop { outline: 2px solid var(--ui-focus-outline); outline-offset: 2px; }

.art-inbox-drop-face {
  display: grid;
  justify-items: center;
  gap: var(--space-xs);
  font-size: var(--text-label);
  font-weight: var(--weight-extrabold);
}

.art-inbox-drop-face[hidden] { display: none; }
.art-inbox-drop-face svg { width: 22px; height: 22px; }

.art-inbox-dim {
  color: var(--color-ink-soft);
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
}

.art-inbox-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-md);
  width: min(560px, 100%);
}

.art-inbox-field {
  display: grid;
  gap: var(--space-xs);
  min-width: 0;
}

.art-inbox-label {
  color: var(--color-ink);
  font-size: var(--text-label);
  font-weight: var(--weight-extrabold);
}

.art-inbox-input {
  min-width: 0;
  min-height: 44px;
  padding: var(--space-sm) var(--space-sm-md);
  border: var(--line);
  border-radius: var(--radius-control);
  background: var(--color-paper);
  color: var(--color-ink);
  font: inherit;
}

.art-inbox-input:focus-visible {
  outline: 2px solid var(--ui-focus-outline);
  outline-offset: 2px;
}

.art-inbox-bridge {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  color: var(--color-ink-soft);
}

.art-inbox-bridge .art-inbox-input { flex: 1; width: 0; }

.ingredient-art-errors {
  padding: var(--space-md);
  border: var(--line);
  border-color: var(--color-tomato);
  border-radius: var(--radius-control);
  background: var(--color-tomato-light);
  color: var(--color-tomato-ink);
  font-weight: var(--weight-bold);
}

.ingredient-art-errors p { margin: 0; }

/* The draft as it will sit in a recipe's ingredient row. */
.art-inbox-recipe-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm-md);
  width: min(380px, 100%);
  margin-bottom: var(--space-md);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-control);
  background: var(--color-paper);
  color: var(--color-ink);
}

.art-inbox-recipe-row .ingredient-box { border-color: var(--color-border-strong); }

.art-inbox-changes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin: 0 0 var(--space-lg);
  padding: 0;
  list-style: none;
}

.art-inbox-changes li {
  padding: var(--space-xs) var(--space-sm-md);
  border-radius: var(--radius-round);
  background: var(--color-cream-dark);
  color: var(--color-ink);
  font-size: var(--text-label);
  font-weight: var(--weight-extrabold);
}

.art-inbox-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm-md);
}

.art-inbox-actions form { margin: 0; }

/* The wall: every visual in one picture. Holes to draw lead; a lens shows the pointed spot at full size. */
.art-wall-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: var(--space-md);
  margin-bottom: var(--space-lg);
}

.art-wall-heading { display: grid; gap: var(--space-xs); }

.art-wall-score {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-md);
  margin: 0;
  color: var(--color-ink-soft);
  font-weight: var(--weight-bold);
}

.art-wall-score strong {
  color: var(--color-ink);
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
}

.art-wall-review { color: var(--color-heeler-dark); text-decoration: none; }
.art-wall-review strong { color: var(--color-heeler-dark); }
.art-wall-review:hover { text-decoration: underline; }

.art-wall-stage {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: var(--space-xl);
  align-items: start;
}

.art-wall-main { display: grid; gap: var(--space-xl); min-width: 0; }

/* How much of the pantry is drawn: one ink bar that fills on the first look. */
.art-wall-meter {
  display: block;
  width: min(320px, 100%);
  height: var(--space-sm);
  margin-top: var(--space-xs);
  overflow: hidden;
  border-radius: var(--radius-round);
  background: var(--color-cream-dark);
}

.art-wall-meter span {
  display: block;
  height: 100%;
  border-radius: var(--radius-round);
  background: var(--color-ink);
  transform: scaleX(var(--drawn, 0));
  transform-origin: left;
}

.art-lens {
  position: sticky;
  top: var(--space-2xl);
  display: grid;
  justify-items: start;
  gap: var(--space-sm);
  padding: var(--space-lg);
  border: var(--line);
  border-radius: var(--radius-xl);
  background: var(--color-paper);
}

.art-lens-slot {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1;
  margin-bottom: var(--space-xs);
  box-sizing: border-box;
  border-radius: var(--radius-lg);
  background: var(--color-cream-dark);
}

.art-lens-slot img { width: 75%; height: 75%; image-rendering: pixelated; }
.art-lens-slot > * { grid-area: 1 / 1; }
.art-lens-plus { width: 40px; height: 40px; color: var(--color-ink-faint); }
.art-lens:not([data-kind="hole"]) .art-lens-plus { display: none; }
.art-lens-action { text-decoration: none; }
.art-lens[data-kind="hole"] .art-lens-slot { border: 1.5px dashed var(--color-border-strong); background: var(--color-cream); }
.art-lens[data-kind="draft"] .art-lens-slot { border: var(--line); }

.art-lens-name {
  color: var(--color-ink);
  font-family: var(--font-display);
  font-size: var(--text-title);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-title);
}

.art-lens-line {
  min-height: calc(var(--text-label) * 2);
  color: var(--color-ink-soft);
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
  line-height: var(--leading-label);
}

.art-lens-action { width: 100%; margin-top: var(--space-xs); }

.art-wall-shelf-name {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin: 0 0 var(--space-md);
  color: var(--color-ink);
  font-family: var(--font-display);
  font-size: var(--text-title);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-title);
}

.art-wall-holes {
  display: grid;
  grid-template-columns: repeat(auto-fill, 96px);
  gap: var(--space-md);
}

.art-wall-shelves { display: grid; gap: var(--space-lg); }

.art-wall-shelf .art-wall-shelf-name { font-size: var(--text-body); }

.art-wall-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, 48px);
  gap: var(--space-sm);
}

.art-spot {
  display: grid;
  justify-items: center;
  gap: var(--space-sm);
  min-width: 0;
  color: var(--color-ink);
  text-decoration: none;
  border-radius: var(--radius-sm);
}

.art-spot:focus-visible { outline: 2px solid var(--ui-focus-outline); outline-offset: 2px; }

.art-spot-face > .art-inbox-plus { color: var(--color-ink-faint); }

.art-spot-face {
  position: relative;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  border-radius: var(--radius-sm);
  transition: transform 120ms ease-out;
}

.art-spot--tile .art-spot-face { width: 48px; height: 48px; }
.art-spot--tile img { width: 48px; height: 48px; image-rendering: pixelated; }
.art-spot--hole .art-spot-face { width: 96px; height: 96px; border-radius: var(--radius-md); }
.art-spot--hole img { width: 72px; height: 72px; image-rendering: pixelated; }
.art-spot--hole.art-spot--hole .art-spot-face { border: 1.5px dashed var(--color-border-strong); }
.art-spot--draft .art-spot-face { border: var(--line); background: var(--color-cream-dark); }
.art-spot--hole.art-spot--draft .art-spot-face { border: var(--line); }
.art-spot--hole .art-inbox-name {
  display: -webkit-box;
  max-width: 96px;
  font-size: var(--text-label);
  text-align: center;
  white-space: normal;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

@media (hover: hover) and (pointer: fine) {
  .art-spot:hover .art-spot-face { transform: translate(-2px, -2px); background: var(--color-hover); }
  .art-spot--hole:hover .art-spot-face { border-color: var(--color-ink); }
}

/* First look: once the art is decoded, the wall prints in reading order, one spot after another. */
.art-wall[data-art-loading] :is(.art-spot, .art-wall-meter span) { opacity: 0; }

@media (prefers-reduced-motion: no-preference) {
  .art-wall[data-art-print] .art-spot { animation: art-wall-print 360ms var(--ease-out-soft) both; animation-delay: calc(var(--i, 0) * 4ms); }
  .art-wall[data-art-print] .art-wall-meter span { animation: art-wall-fill 1600ms var(--ease-out-soft) both; }
}

/* The catch: after an approval the page opens on the new art, which lands with a pop. */
.art-spot[data-art-wall-target="caught"] .art-spot-face { outline: 2px solid var(--ui-focus-outline); outline-offset: 2px; }

@media (prefers-reduced-motion: no-preference) {
  .art-wall[data-art-print] .art-spot[data-art-wall-target="caught"] .art-spot-face { animation: art-wall-catch 520ms cubic-bezier(0.34, 1.56, 0.64, 1) both; animation-delay: 900ms; }
}

@keyframes art-wall-catch {
  from { transform: scale(0.6); }
  to { transform: none; }
}

@keyframes art-wall-fill {
  from { transform: scaleX(0); }
}

@keyframes art-wall-print {
  from { opacity: 0; transform: scale(0.6); }
  to { opacity: 1; transform: none; }
}

@media (max-width: 1023px) {
  .art-wall-stage { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); }
  .art-lens { position: static; grid-template-columns: 96px minmax(0, 1fr); align-items: center; column-gap: var(--space-md); padding: var(--space-md); }
  .art-lens-slot { grid-row: span 3; margin: 0; }
  .art-lens-action { grid-column: 1 / -1; }
}

@media (max-width: 767px) {
  .art-wall-head { flex-direction: column; align-items: stretch; }
  .art-wall-meter { width: 100%; }
  .art-wall-holes { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-sm-md); }
  .art-spot--hole { grid-template-columns: minmax(0, 1fr); align-content: start; }
  .art-spot--hole .art-spot-face { width: 100%; height: auto; aspect-ratio: 1; }
  .art-spot--hole img { width: 75%; height: 75%; }
  .art-wall-tiles { grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); }
  .art-spot--tile .art-spot-face, .art-spot--tile img { width: 40px; height: 40px; }
  .art-spot .art-inbox-uses { top: var(--space-2xs); right: var(--space-2xs); padding: 0 var(--space-xs); }
  .art-spot .art-inbox-name { font-size: var(--text-label); font-weight: var(--weight-extrabold); }
}

/* Phone: the upload and review pages. */
@media (max-width: 767px) {
  .art-inbox-title { font-size: var(--text-display-phone); }
  .art-inbox-open { width: auto; }
  .art-inbox-slot--big { width: 120px; }
  .art-inbox-slot--big img { width: 96px; height: 96px; }
  .art-inbox-fields { grid-template-columns: minmax(0, 1fr); }
}

.planning-preferences {
  position: absolute;
  z-index: var(--z-planning-preferences);
  top: var(--space-lg);
  right: var(--space-lg);
  color: var(--ui-text);
}

.planning-preferences > summary {
  border: 1px solid var(--ui-border);
  border-radius: 50%;
  background: var(--ui-bg-surface);
  color: var(--ui-text-muted);
  box-shadow: var(--ui-shadow-1);
  cursor: pointer;
  display: grid;
  place-items: center;
  list-style: none;
  transition: transform var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast), box-shadow var(--transition-fast);
}

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

.planning-preferences > summary:hover {
  border-color: color-mix(in srgb, var(--ui-accent) 42%, var(--ui-border));
  color: var(--ui-accent-hover);
  box-shadow: var(--ui-shadow-2);
  transform: translateY(-1px);
}

.planning-preferences > summary:focus-visible {
  outline: 4px solid color-mix(in srgb, var(--ui-focus-outline) 44%, transparent);
  outline-offset: 0;
  border-color: var(--ui-accent);
}

.planning-preferences[open] > summary {
  border-color: color-mix(in srgb, var(--ui-positive) 48%, var(--ui-border));
  background: color-mix(in srgb, var(--ui-bg-surface) 86%, var(--ui-positive) 14%);
  color: var(--ui-positive-hover);
}

.planning-preferences > summary svg {
  width: 21px;
  height: 21px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.7;
}

.planning-preferences form {
  position: absolute;
  right: 0;
  width: min(380px, calc(100vw - 32px));
  max-height: min(70vh, 640px);
  overflow-y: auto;
  padding: var(--space-lg);
  border: 1px solid var(--ui-border);
  border-radius: var(--radius-xl);
  background: var(--ui-bg-surface);
  box-shadow: var(--ui-shadow-4);
  display: grid;
  gap: var(--space-md);
}

.planning-preferences fieldset {
  margin: 0;
  padding: var(--space-md) 0 0;
  border: 0;
  border-top: 1px solid var(--ui-border-subtle);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.planning-preferences fieldset:first-of-type {
  padding-top: 0;
  border-top: 0;
}

.planning-preferences legend {
  width: 100%;
  margin-bottom: var(--space-sm);
  color: var(--ui-text-strong);
  font-size: var(--text-label);
  font-weight: var(--weight-bold);
}

.planning-preferences label {
  min-height: 36px;
  border: 1px solid var(--ui-border);
  border-radius: var(--radius-control);
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-label);
}

.planning-preferences input[type="text"] {
  width: 100%;
  min-height: 44px;
  padding: 0 var(--space-sm-md);
  border: 1px solid var(--ui-border);
  border-radius: var(--radius-md);
  background: var(--ui-bg-page);
  color: var(--ui-text-strong);
  font-weight: var(--weight-regular);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  font-family: var(--font-body);
}

.planning-preferences input[type="submit"] {
  min-height: 44px;
  padding: 0 var(--space-md);
  border: 0;
  border-radius: var(--radius-control);
  background: var(--ui-accent);
  color: var(--ui-bg-surface);
  font-weight: var(--weight-bold);
  font-size: var(--text-body);
  line-height: var(--leading-display);
  font-family: var(--font-body);
}

/* Profile: stacked settings on phones, account sidebar and aligned desktop form. */
.profile-shell {
  --ui-focus-outline: var(--ui-positive-hover);
  --profile-control-border: var(--line-color);
  color: var(--ui-text);
  display: grid;
  gap: var(--space-lg);
  max-width: 1120px;
  margin: 0 auto;
  padding: var(--space-md) var(--space-md) var(--space-xl);
}

.profile-shell :is(h1, h2, p, form) {
  margin: 0;
}
.profile-shell :is(section, fieldset) {
  min-width: 0;
}

.profile-header { order: 0; }


.profile-layout { order: 2; }



.profile-header h1 {
  margin-bottom: var(--space-sm);
  font-weight: var(--weight-semibold);
  font-size: var(--text-display);
  line-height: var(--leading-display);
  font-family: var(--font-display);
}

.profile-header-copy > p{
  color: var(--ui-text-muted);
  line-height: var(--leading-body);
}











.profile-hint {
  color: var(--ui-text-muted);
  font-size: var(--text-label);
  line-height: var(--leading-body);
}

.profile-layout{
  display: grid;
  gap: var(--space-lg);
  align-items: start;
}
.profile-pane {
  scroll-margin-top: calc(var(--space-sm) * 14);
}




.profile-card {
  padding: var(--space-md);
  border: 1px solid var(--ui-border);
  border-radius: var(--radius-xl);
  background: var(--ui-bg-surface);
}



.profile-shell .auth-input {
  min-width: 0;
  min-height: 48px;
  border-color: var(--profile-control-border);
  background-color: var(--ui-bg-surface);
  box-shadow: none;
}

.profile-shell .auth-input::placeholder {
  color: var(--ui-text-muted);
}
.kitchen-rules-shell .profile-select {
    appearance: none;
    padding-right: var(--space-2xl);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23101827' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 18px center;
  }




.profile-field-label {
  display: block;
  font-size: var(--text-body);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-body);
}


.profile-planning-options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-sm);
  margin-top: var(--space-sm-md);
}


.profile-planning-option {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  min-height: 48px;
  padding: var(--space-sm-md);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: var(--color-cream);
  cursor: pointer;
  font-size: var(--text-body);
  line-height: var(--leading-label);
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.profile-planning-option input { margin: 0; accent-color: var(--ui-positive-hover); appearance: none; width: 21px; height: 21px; flex: 0 0 21px; background: var(--color-paper); border: var(--line); border-radius: var(--radius-sm); }

.profile-planning-option:hover {
  background: var(--ui-bg-surface-muted);
}
.profile-planning-option:has(:checked) {
  background: var(--color-cream-dark);
  border-color: var(--ui-positive-hover);
}
.profile-planning-option:has(:focus-visible) {
  outline: 2px solid var(--ui-positive-hover);
  outline-offset: 2px;
}


.profile-button {
  min-height: 48px;
  padding: var(--space-sm-md) var(--space-md);
  border: 1px solid var(--ui-accent-hover);
  border-radius: var(--radius-lg);
  background: var(--ui-accent-hover);
  color: var(--ui-text-inverse);
  cursor: pointer;
  font-weight: var(--weight-semibold);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  font-family: var(--font-body);
}

@media (hover: hover) and (pointer: fine) {
  .profile-button:hover {
    filter: brightness(0.94);
  }
}
.profile-button:active {
  transform: translateY(1px);
}


.profile-text-action{
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--space-sm) 0;
  border: 0;
  background: none;
  color: var(--ui-positive-hover);
  font-weight: var(--weight-medium);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  font-family: var(--font-body);
  text-align: left;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .profile-text-action:hover{
    color: var(--ui-text-strong);
  }
}


.profile-shell summary:focus-visible {
  outline: 2px solid var(--ui-positive-hover);
  outline-offset: 4px;
  border-radius: var(--radius-sm);
}






.profile-calendar-card {
  padding-top: var(--space-xs);
}
.profile-calendar-action {
  display: flex;
  align-items: center;
  gap: var(--space-sm-md);
  min-height: 56px;
  padding: var(--space-sm-md) 0;
  color: var(--ui-text);
  text-decoration: none;
  font-size: var(--text-body);
}

.profile-calendar-action span {
  flex: 1;
}
.profile-shell svg {
  width: 20px;
  height: 20px;
  flex: 0 0 20px;
}
.profile-calendar-action:hover {
  color: var(--ui-positive-hover);
}
.profile-calendar-help {
  border-block: 1px solid var(--ui-border-subtle);
}
.profile-calendar-help summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm-md);
  min-height: 52px;
  cursor: pointer;
  font-size: var(--text-body);
  list-style: none;
}
.profile-calendar-help summary::-webkit-details-marker {
  display: none;
}
.profile-calendar-help summary::after {
  content: '';
  width: 7px;
  height: 7px;
  border-top: 1.5px solid;
  border-right: 1.5px solid;
  transform: rotate(45deg);
  margin-right: var(--space-xs);
}
.profile-calendar-help[open] summary::after {
  transform: rotate(135deg);
}
.profile-calendar-help p {
  padding-bottom: var(--space-sm-md);
  font-size: var(--text-body);
  color: var(--ui-text-muted);
}
.calendar-subscribe-field {
  padding-top: var(--space-md);
}
.calendar-subscribe-row {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
  margin-top: var(--space-sm);
}
.calendar-subscribe-input {
  flex: 1;
  text-overflow: ellipsis;
}
.calendar-subscribe-copy {
  flex-shrink: 0;
  padding-inline: var(--space-xs);
  color: var(--ui-text);
}
.calendar-subscribe-feedback {
  min-height: 20px;
  padding-top: var(--space-xs);
  visibility: hidden;
}
.calendar-subscribe-feedback.is-visible {
  visibility: visible;
}
.profile-calendar-card .calendar-subscribe-rotate {
  padding-top: 0;
  padding-bottom: 0;
}








@media (min-width: 640px) {
  .profile-shell {
    max-width: 720px;
    padding: var(--space-lg) var(--space-lg) var(--space-xl);
  }
  .profile-card {
    padding: var(--space-lg);
  }
}

/* The calendar uses native disclosure, including keyboard and screen-reader support. */








body:has(.profile-shell)::before { display: none; }

.profile-planning-option input:checked { appearance: auto; }










/* Beats the auth input focus padding so typed text clears the icon in every state. */

/* The list box keeps one height while filtering, so the page never shifts as rows hide. */

















.profile-planning-submit {
  min-height: 54px;
  background: var(--color-heeler);
  border-color: var(--line-color);
  border-radius: var(--radius-sm);
}






.profile-shell .auth-input { border-radius: var(--radius-sm); background-color: var(--color-paper); font-size: var(--text-body); }

@media (max-width: 1023px) {
  .profile-header h1 { font-size: var(--text-display); }
  
}

@media (min-width: 1024px) {
  .app-shell:has(.profile-shell) .app-main { padding: 0 var(--space-xl); min-height: calc(100dvh - var(--navbar-height)); }
  .profile-shell {
    max-width: 1120px;
    padding: var(--space-lg) 0 var(--space-xl);
    grid-template-columns: 248px minmax(0, 1fr);
    grid-template-rows: auto auto;
    gap: var(--space-lg) calc(var(--space-sm) * 8);
  }
  .profile-header { grid-column: 2; grid-row: 1; }
  .profile-header h1 { font-size: var(--text-display); line-height: var(--leading-display); margin-bottom: var(--space-xs); }
  .profile-header-copy > p { font-size: var(--text-title); line-height: var(--leading-label); }
  
  
  
  
  
  
  
  
  
  
  #profile-photo-hint > span:last-child { display: block; }
  #profile-photo-hint { font-size: var(--text-body); line-height: var(--leading-label); }
  
  
  
  
  
  .profile-layout { grid-column: 2; grid-row: 2; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); }
  
  .profile-card { padding: var(--card-padding); }
  
  
  
  
  
  
  .profile-field-label{ font-size: var(--text-body); line-height: var(--leading-body); font-weight: var(--weight-semibold); }
  .profile-hint { font-size: var(--text-body); line-height: var(--leading-body); }
  
  .profile-shell .auth-input { height: 50px; min-height: 50px; font-size: var(--text-body); line-height: var(--leading-body); padding: var(--space-sm-md) var(--space-md); }
  
  .profile-planning-options { margin: 0; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-sm) var(--space-sm-md); }
  .profile-planning-option { min-height: 52px; padding: var(--space-sm-md) var(--space-md); gap: var(--space-md); font-size: var(--text-body); }
  
  .profile-planning-submit { justify-self: end; width: 328px; font-size: var(--text-body); margin-top: calc(var(--space-xs) * -1); }
  
  
  
  
  
  
  
}

@media (min-width: 1024px) and (max-width: 1279px) {
  .profile-shell { grid-template-columns: 190px minmax(0, 1fr); gap: var(--space-lg) var(--space-xl); }
  
  
  .profile-planning-option { padding-inline: var(--space-sm); gap: var(--space-sm); font-size: var(--text-body); }
  
}

/* Kitchen rules use one settings column, without the Profile account sidebar. */
.profile-shell.kitchen-rules-shell {
  max-width: 760px;
  padding: var(--space-lg) var(--space-md) var(--space-2xl);
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: none;
  gap: var(--space-lg);
}

@media (max-width: 639px) {
  .profile-shell.kitchen-rules-shell { padding-top: var(--space-md); }
}

.kitchen-rules-back {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  min-height: 44px;
  color: var(--ui-text-muted);
  text-underline-offset: 4px;
}

.kitchen-rules-header h1 {
  margin-bottom: var(--space-sm-md);
  font-weight: var(--weight-semibold);
  font-size: var(--text-display);
  line-height: var(--leading-display);
  font-family: var(--font-display);
}

.kitchen-rules-header p {
  color: var(--ui-text-muted);
  line-height: var(--leading-body);
}

.kitchen-rules-shell .profile-card { min-width: 0; padding: clamp(var(--space-md), 4vw, var(--space-xl)); }
.kitchen-rules-shell .profile-planning-form { display: grid; gap: var(--space-lg); background: var(--color-paper); border: 1px solid var(--color-border); border-radius: var(--radius-lg); }
.kitchen-rules-fieldset { margin: 0; padding: 0; border: 0; }
.kitchen-rules-shell .profile-field-label { font-size: var(--text-body); }
.kitchen-rules-fieldset > .profile-hint { margin-top: var(--space-sm); }
.kitchen-rules-shell .kitchen-rules-options { grid-template-columns: minmax(0, 1fr); margin-top: var(--space-sm-md); gap: var(--space-sm-md); }
.kitchen-rules-shell .profile-planning-option { min-width: 0; padding: var(--space-sm-md); gap: var(--space-sm-md); font-size: var(--text-body); }
.kitchen-rules-shell input[type="radio"] { appearance: auto; border-radius: 50%; }
.kitchen-rules-fields { display: grid; gap: var(--space-md); }
.kitchen-rules-field { display: grid; min-width: 0; gap: var(--space-sm); }

.kitchen-rules-fieldset + .kitchen-rules-fieldset,
.kitchen-rules-fields,
.kitchen-rules-shell form > .kitchen-rules-field,
.kitchen-rules-actions {
  padding-top: var(--space-lg);
  border-top: 1px solid var(--ui-border);
}

.kitchen-rules-actions { display: flex; justify-content: flex-end; }
.kitchen-rules-shell .profile-planning-submit { width: 100%; margin: 0; font-size: var(--text-body); }

@media (min-width: 640px) {
  .kitchen-rules-shell .kitchen-rules-options { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .kitchen-rules-shell .profile-planning-submit { width: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .profile-shell * {
    transition: none;
  }
  .profile-button:active {
    transform: none;
  }
}

/* Native share fallback keeps the pending source in one explicit Kitchen form. */
.import-fallback {
  max-width: 36rem;
  padding: var(--space-lg);
  border: 1px solid var(--ui-border);
  border-radius: var(--radius-xl);
  background: var(--ui-bg-surface);
}

.import-fallback h1 {
  margin-top: 0;
  font-family: var(--font-display);
}

.import-fallback form {
  display: grid;
  gap: var(--space-sm-md);
  margin-block: var(--space-lg);
}

.import-fallback select,
.import-fallback input[type="submit"] {
  min-height: 44px;
  padding: var(--space-sm-md);
  border: 1px solid var(--ui-border);
  border-radius: var(--radius-md);
  font: inherit;
}

.import-fallback select {
  max-width: 100%;
  color: var(--ui-text);
  background: var(--ui-bg-page);
}

.import-fallback input[type="submit"] {
  color: var(--ui-text-inverse);
  background: var(--ui-accent);
  cursor: pointer;
}

.import-fallback a {
  display: inline-block;
  margin-right: var(--space-md);
  color: var(--ui-accent-hover);
}
