/* Экран «Рецепты»: каталог, панель раскрытого рецепта, конструктор своего.
   Владелец: таск 35. Макеты 05-desktop-recepty, 24-iphone-recepty,
   12-desktop-konstruktor-recepta.

   Своей палитры здесь нет ни одного цвета: всё берётся переменными из styles.css,
   и --risk не тратится вовсе — риска на этом экране не бывает. Коробки, кнопки,
   чипы, плашки, выключатель и слой диалога — общие классы; ниже только
   раскладка и то, что у этого экрана действительно своё.

   Раскладка «каталог + панель» сделана переносом флекса, а не третьей границей
   по ширине: границ в проекте ровно две (ЯКОРЬ 900 и ЯКОРЬ 600), и заводить
   третью ради одного экрана — значит развести их со временем. Панель просто
   переезжает под сетку, когда рядом с ней не остаётся места. */

.recipes {
  display: flex;
  flex-direction: column;
  gap: var(--gap-lg);
}

/* ================================ ШАПКА ================================ */

.recipes-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--gap);
  flex-wrap: wrap;
}

.recipes-icon {
  display: inline-flex;
  align-items: center;
  flex: none;
}

/* ============================ СТРОКА ОТБОРА ============================ */

.recipes-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gap);
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
}

.recipes-search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 240px;
  min-width: 0;
}

.recipes-search-icon {
  position: absolute;
  left: 12px;
  color: var(--ink-2);
  pointer-events: none;
}

input.recipes-search-input {
  padding-left: 40px;
  background: var(--surface);
}

.recipes-slots { flex: none; }

.recipes-chips {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}

.button.recipes-reset {
  min-height: 32px;
  padding: 4px 6px;
  margin-left: auto;
}

/* ======================== КАТАЛОГ И ПАНЕЛЬ РЯДОМ ======================== */

.recipes-body {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: var(--gap-lg);
}

.recipes-catalog {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  flex: 1 1 460px;
  min-width: 0;
}

.recipes-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: var(--gap);
}

.recipes-more { align-self: flex-start; }

.recipes-empty { width: 100%; }

/* ============================== КАРТОЧКА ============================== */

.recipes-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow);
}

.recipes-card.is-open { border-color: var(--sage); }

/* Фокус карточки рисуется на самой карточке, а не на кнопке внутри: кнопка
   растянута невидимым слоем на всю карточку, и контур вокруг одного заголовка
   читался бы как фокус на тексте. Снять его у кнопки можно только потому,
   что взамен он появляется здесь. */
.recipes-card:has(.recipes-card-open:focus-visible) {
  outline: var(--focus-width) solid var(--ink);
  outline-offset: 2px;
}

.recipes-card-open:focus-visible { outline: none; }

.recipes-card-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px 14px;
  min-width: 0;
}

.recipes-card-open {
  display: block;
  width: 100%;
  padding: 0;
  text-align: left;
  color: var(--ink);
  background: none;
  border: 0;
  cursor: pointer;
}

/* Нажимается вся карточка, а не только заголовок. */
.recipes-card-open::after {
  content: '';
  position: absolute;
  inset: 0;
}

.recipes-card-kbju {
  margin: 0;
  font: 400 var(--fs-body)/1.4 var(--font-text);
  color: var(--ink-2);
}

.recipes-card-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0;
}

/* Метка-чип: не кнопка, поэтому без указателя и без наведения. */
.recipes-mark {
  cursor: default;
  background: var(--surface-2);
}

/* «Вернуть» у убранного рецепта (чип «убранные», волна 4). Поднята над
   нажимаемым слоем карточки, как и удаление ниже, — иначе нажатие открыло бы
   панель, а не вернуло блюдо в выбор. Высоту не трогаем: мишень — общее правило. */
.recipes-card-return {
  position: relative;
  z-index: 1;
  align-self: flex-start;
}

/* Удаление своего рецепта (История 157). Кнопка лежит поверх нажимаемого слоя
   карточки — иначе на неё было бы не попасть. */
.button.recipes-card-remove {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  min-height: 32px;
  padding: 6px;
  color: var(--ink-2);
  background: var(--surface);
  border-color: var(--border);
}

/* =============================== ФОТО =============================== */

.recipes-photo {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  aspect-ratio: 16 / 10;
  min-height: 0;
  overflow: hidden;
}

.recipes-photo-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Фотографии нет или она не доехала (A07, История 163): вместо картинки —
   калорийность крупно на холодной плашке. Подпись под числом говорит, какой
   именно это случай: ждать фото или нет. */
.recipes-photo.is-stub {
  gap: 2px;
  padding: 14px 16px;
  border-radius: 0;
}

.recipes-photo-kcal {
  font: 800 var(--fs-heading)/1 var(--font-display);
  letter-spacing: -.02em;
  color: inherit;
}

.recipes-photo-stub { color: var(--ink-2); }

/* ============================== ПАНЕЛЬ ============================== */

.recipes-panel {
  display: flex;
  flex-direction: column;
  flex: 0 1 380px;
  min-width: 0;
  overflow: hidden;
}

.recipes-panel-photo {
  aspect-ratio: 16 / 7;
  border-radius: 0;
}

.recipes-panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--gap);
  padding: 16px var(--gap-lg) 0;
}

.recipes-panel-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0 0;
}

.button.recipes-panel-close {
  flex: none;
  min-height: 36px;
  padding: 6px;
  color: var(--ink-2);
}

.recipes-panel-body {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  padding: var(--gap) var(--gap-lg);
  min-width: 0;
}

/* КБЖУ на одну порцию: четыре числа в ряд. Состав ниже — на порции самого
   рецепта; порции плана правит лист приёма пищи (волна 4). */
.recipes-kbju {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 4px;
  text-align: center;
}

.recipes-kbju-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.recipes-kbju-value {
  font: 700 var(--fs-card)/1.1 var(--font-display);
  color: inherit;
}

.recipes-kbju-cell .caption { color: inherit; }

.recipes-ing-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0;
  margin: 0;
}

.recipes-ing-list dt,
.recipes-ing-list dd {
  margin: 0;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  min-width: 0;
}

.recipes-ing-list dd {
  text-align: right;
  color: var(--ink-2);
  white-space: nowrap;
  padding-left: var(--gap);
}

.recipes-steps { display: contents; }

.recipes-steps-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: recipes-step;
}

.recipes-steps-list li {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  gap: 10px;
  align-items: start;
  counter-increment: recipes-step;
}

.recipes-steps-list li::before {
  content: counter(recipes-step);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  font: 400 var(--fs-caption)/1 var(--font-caption);
  color: var(--ink-2);
  background: var(--surface-2);
  border-radius: 999px;
}

.recipes-panel-foot {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: auto;
  padding: var(--gap) var(--gap-lg) var(--gap-lg);
  border-top: 1px solid var(--border);
}

.recipes-panel-buttons {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

/* ♥ ✕ в панели — как у «Сегодня» и листа приёма пищи: нажатая оценка мягкой
   заливкой, как выбранный сегмент. Красный занят тревогой, а ✕ — не ошибка,
   а «больше не предлагать». */
.recipes-rate {
  min-width: 44px;
  font-size: 16px;
}

.recipes-rate[aria-pressed="true"] {
  color: var(--sage);
  background: var(--sage-soft);
}

.recipes-copy { margin-left: auto; }

.recipes-fallback {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.recipes-fallback-area {
  min-height: 120px;
  font: 400 13px/1.5 var(--font-mono);
}

/* ЯКОРЬ 900 — от той же границы, где появляется сайдбар, рядом с сеткой хватает
   места на панель. Она липнет к верху окна: иначе состав уезжает вверх, пока
   листаешь полторы сотни карточек, и панель становится бесполезной. */
@media (min-width: 900px) {
  .recipes-panel {
    position: sticky;
    top: var(--gap-lg);
    max-height: calc(100dvh - var(--gap-lg) * 2);
    overflow-y: auto;
  }
}

/* ===================== РАЗВИЛКА ДО КОНСТРУКТОРА ===================== */

.recipes-own {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--gap-lg);
  padding: var(--gap-lg);
}

.recipes-own-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1 1 200px;
  min-width: 0;
}

.recipes-fork {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.recipes-fork-option {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  text-align: left;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  cursor: pointer;
  max-width: 220px;
}

.recipes-fork-option.is-active {
  background: var(--sage-soft);
  border-color: var(--sage);
}

@media (prefers-color-scheme: dark) {
  /* На тёмном листе заливка выбранного варианта тёмная — текст берём светлый. */
  .recipes-fork-option.is-active { color: var(--ink); }
}

.recipes-fork-dot {
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 2px;
  border: 1px solid var(--ink-3);
  border-radius: 999px;
  background: var(--surface);
}

.recipes-fork-option.is-active .recipes-fork-dot {
  border-color: var(--sage-deep);
  box-shadow: inset 0 0 0 3px var(--surface), inset 0 0 0 16px var(--sage-deep);
}

.recipes-fork-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.recipes-own-open { flex: none; }

/* ============================ КОНСТРУКТОР ============================ */

.recipes-modal-card {
  width: min(960px, 100%);
  display: flex;
  flex-direction: column;
}

.recipes-modal-head {
  display: flex;
  align-items: flex-start;
  gap: var(--gap);
  padding: var(--gap-lg) var(--gap-lg) 0;
}

.recipes-modal-titles {
  flex: 1 1 auto;
  min-width: 0;
}

/* Правда о черновике: он живёт в памяти app.js и перезагрузку не переживает. */
.recipes-draft-mark {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 6px 10px;
  border-radius: 999px;
  white-space: nowrap;
}

.button.recipes-modal-close {
  flex: none;
  min-height: 36px;
  padding: 6px;
  color: var(--ink-2);
}

.recipes-modal-body {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--gap-lg);
  padding: var(--gap-lg);
}

.recipes-modal-left,
.recipes-modal-right {
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  min-width: 0;
}

.recipes-form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: var(--gap);
}

.recipes-number {
  position: relative;
  display: block;
}

.recipes-number input { padding-right: 44px; }

.recipes-number-unit {
  position: absolute;
  top: 50%;
  right: 12px;
  transform: translateY(-50%);
  pointer-events: none;
}

.recipes-sub-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gap);
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}

.recipes-editor {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.recipes-editor-rows {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.recipes-editor-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 88px 96px auto;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.recipes-editor-row > * { min-width: 0; }

.recipes-step-row { grid-template-columns: 24px minmax(0, 1fr) auto; }

.recipes-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  background: var(--surface-2);
  border-radius: 999px;
}

.button.recipes-editor-remove {
  min-height: 34px;
  padding: 6px;
  color: var(--ink-2);
}

.recipes-editor-add { align-self: flex-start; }

.recipes-fork-note,
.recipes-unknown {
  display: flex;
  align-items: flex-start;
  gap: 2px;
  margin: 0;
}

.recipes-manual {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
  gap: 8px;
}

.recipes-portable {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
}

.recipes-portable p { margin: 0; }

.recipes-modal-foot {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--gap);
  padding: var(--gap) var(--gap-lg);
  background: var(--surface-2);
  border-top: 1px solid var(--border);
}

.recipes-modal-status {
  flex: 1 1 260px;
  min-width: 0;
}

.recipes-errors {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--ink-2);
}

.recipes-errors li {
  display: flex;
  align-items: flex-start;
  gap: 2px;
}

.recipes-modal-buttons {
  display: flex;
  gap: 8px;
  flex: none;
}

/* --------------------------------------------------------------------------
   ЯКОРЬ 600 — телефон (История 164).

   Панель раскрытого рецепта превращается в лист снизу над таб-баром: рядом
   с сеткой ей места нет, а под сеткой из полутора сотен карточек её никто
   не найдёт. Конструктор листом снизу делает уже styles.css — здесь только
   высота, чтобы он читался как лист на всю высоту, а не как всплывшая полоска.
   -------------------------------------------------------------------------- */

@media (max-width: 600px) {
  .recipes-add-label { display: none; }

  .recipes-add {
    min-width: var(--tap);
    padding: 12px;
  }

  .recipes-bar {
    align-items: stretch;
    flex-direction: column;
    gap: 8px;
  }

  .recipes-slots,
  .recipes-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .recipes-slots::-webkit-scrollbar,
  .recipes-chips::-webkit-scrollbar { display: none; }

  .recipes-slots > * { white-space: nowrap; }

  .recipes-panel {
    position: fixed;
    inset: auto 0 calc(var(--tabbar-h) + env(safe-area-inset-bottom)) 0;
    z-index: 90;
    max-height: 82dvh;
    overflow-y: auto;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    border-bottom: 0;
  }

  /* Полоска-ручка сверху: лист снизу узнаётся по ней раньше, чем прочитан. */
  .recipes-panel::before {
    content: '';
    align-self: center;
    width: 44px;
    height: 4px;
    margin: 8px 0 0;
    background: var(--border);
    border-radius: 999px;
    flex: none;
  }

  /* Снимок раскрытого рецепта остаётся и на телефоне: до итерации 7 он прятался
     целиком, и от блюда оставался один текст — ровно то, что читать труднее всего.
     Соотношение остаётся панельным (16/7 из правила выше), а не карточным (16/10):
     лист снизу ограничен 82dvh, и на 695 px доступной высоты полоса в 16/7 занимает
     около 170 px против 245 — разница ровно в тот экран, где стоят ♥ ✕
     и «Скопировать рецепт». Здесь нужен только `flex: none`: лист прокручиваемый, и без
     него снимок сжимался бы длинным составом до полоски. */
  .recipes-panel-photo { flex: none; }

  /* Мишень икон-кнопок возвращается к 44 px. Пять правил выше режут высоту
     до 32–36 px одноклассовым селектором — а это ровно та же специфичность
     (0,2,0), что у `.button.button` в styles.css, и recipes.css грузится позже,
     так что ничью забирал экран. Правило размера мишени по-прежнему одно,
     здесь только отказ от собственной перебивки — как в shopping.css. */
  .button.recipes-reset,
  .button.recipes-card-remove,
  .button.recipes-panel-close,
  .button.recipes-modal-close,
  .button.recipes-editor-remove {
    min-height: var(--tap);
    min-width: var(--tap);
  }

  .recipes-modal-card { min-height: 84dvh; }

  .recipes-editor-row { grid-template-columns: minmax(0, 1fr) 80px 88px auto; }

  .recipes-fork-option { max-width: none; flex: 1 1 100%; }

  .recipes-own-open { width: 100%; }
}
