/* cookbook-recipe.css — the 2.0 recipe screen (js/views/cookbook/recipe.js;
 * boards RecipeDetail / RecipeSteps) and "Write it in" / Edit
 * (js/views/cookbook/write.js; boards RecipeWrite / RecipeWriteSteps).
 *
 * Same rules as shell.css (pinned by test/shell.mjs and
 * test/cookbook-recipe.mjs): 2.0 token names only, no raw hex, no
 * prefers-color-scheme, no fixed phone-width px widths, every class v2-
 * prefixed — this file's own are v2-rc… (recipe) and v2-rw… (write). The
 * accent is the skill scope's --accent* (body[data-skill="cookbook"]).
 */

/* ================================================================
 * Recipe (#/recipe/:id)
 * ================================================================ */

.v2-rc {
  background: var(--s-panel);
}

/* The pushed header floats over the photo hero (glass pills on a clear
 * bar) and takes no room of its own: the hero slides up beneath it. Once
 * the INSTRUCTIONS label reaches it, it becomes the compact "↑ Top · title"
 * bar on the panel colour (board RecipeSteps). */
.v2-rc__head {
  background: transparent;
  margin-bottom: calc(-1 * (env(safe-area-inset-top, 0px) + var(--head-h)));
  transition: background-color 0.18s ease, box-shadow 0.18s ease;
}
.v2-rc.is-plain .v2-rc__head {
  background: var(--s-panel);
  margin-bottom: 0;
}
.v2-rc__glass {
  background: var(--glass-nav);
  border-color: var(--glass-nav-line);
  box-shadow: none;
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  backdrop-filter: blur(20px) saturate(180%);
}
.v2-rc.is-plain .v2-rc__glass {
  background: var(--s-card);
  border-color: var(--raised-line);
  box-shadow: var(--sh-raised);
}
.v2-rc__head .v2-rc__top,
.v2-rc__head .v2-head__title--pushed {
  display: none;
}
.v2-rc__head.is-compact {
  background: var(--s-panel);
  box-shadow: inset 0 -1px 0 var(--strip-line);
}
.v2-rc__head.is-compact .v2-rc__backpill,
.v2-rc__head.is-compact .v2-head__spacer {
  display: none;
}
/* The action pill stays on the compact bar (like Save on RecipeWriteSteps),
 * solid rather than glass. */
.v2-rc__head.is-compact .v2-rc__glass {
  background: var(--s-card);
  border-color: var(--raised-line);
  box-shadow: var(--sh-raised);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.v2-rc__head.is-compact .v2-rc__top {
  display: flex;
  font: inherit;
  font-size: 14.5px;
  font-weight: 620;
  padding: 0 15px 0 11px;
}
.v2-rc__head.is-compact .v2-head__title--pushed {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  font-size: 14.5px;
  font-weight: 660;
  letter-spacing: -0.1px;
  color: var(--t-nav);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------- photo hero ---------- */
.v2-rc__hero {
  position: relative;
  flex: none;
  height: calc(env(safe-area-inset-top, 0px) + 176px);
  background: var(--s-chip);
  border-bottom: 1px solid var(--strip-line);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.v2-rc__heroimg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Item 6: the full photo fades in ONCE over the list's thumbnail (or the
   empty frame) after it is decoded; repaints keep the same node. */
.v2-rc__heroimg.is-fadein {
  animation: v2-rc-hero-in 180ms ease-out both;
}
@keyframes v2-rc-hero-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
.v2-rc__heroph {
  display: flex;
  color: var(--t-placeholder);
  padding-top: env(safe-area-inset-top, 0px);
}
.v2-rc__heroshade {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: calc(env(safe-area-inset-top, 0px) + 88px);
  background: linear-gradient(color-mix(in srgb, var(--viewer-bg) 16%, transparent), transparent);
  pointer-events: none;
}

/* ---------- the content (a panel with no strip edge) ---------- */
.v2-rc__panel {
  border-top: 0;
  border-radius: 0;
  padding-top: 16px;
  gap: 16px;
}
.v2-rc__intro {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.v2-rc__chiprow {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
}
.v2-rc__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}
.v2-rc__chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 23px;
  padding: 0 10px;
  border-radius: 12px;
  background: var(--s-card);
  border: 1px solid var(--raised-line);
  box-shadow: var(--sh-raised);
  color: var(--accent-ink);
  font: inherit;
  font-size: 12px;
  font-weight: 640;
  white-space: nowrap;
}
/* The "+" placeholder when the recipe is in no collection: the chip's
 * footprint in a dashed outline, no fill, no lift. */
.v2-rc__chip--add {
  justify-content: center;
  min-width: 34px;
  padding: 0 9px;
  background: transparent;
  border: 1px dashed var(--accent-tint-line);
  box-shadow: none;
}
.v2-rc__chip::after {
  content: "";
  position: absolute;
  inset: -10px -3px;
}
.v2-rc__src {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 5px;
  height: 23px;
  min-width: 0;
  color: var(--t-nav-off);
  font-size: 12px;
  font-weight: 570;
  text-decoration: none;
}
.v2-rc__src span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2-rc__src svg {
  flex: none;
}
.v2-rc__title {
  margin: 0;
  font-size: 25px;
  font-weight: 720;
  letter-spacing: -0.75px;
  line-height: 1.16;
  color: var(--t-primary);
  text-wrap: pretty;
  overflow-wrap: anywhere;
}
.v2-rc__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 14px;
  row-gap: 4px;
  font-size: 12.5px;
  color: var(--t-nav-off);
  font-variant-numeric: tabular-nums;
}
.v2-rc__metapart {
  display: flex;
  align-items: center;
  gap: 5px;
}
.v2-rc__status {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--r2-well);
  background: var(--accent-tint);
  border: 1px solid var(--accent-tint-line);
  color: var(--accent-ink);
  font-size: 13.5px;
  line-height: 1.4;
}
.v2-rc__status.is-failed {
  background: var(--s-card);
  border-color: var(--raised-line);
  color: var(--t-body);
}
.v2-rc__status p {
  margin: 0;
}
.v2-rc__sect {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}
.v2-rc__empty {
  margin: 0;
  font-size: 13.5px;
  color: var(--t-muted);
}

/* ---------- servings stepper + Convert ---------- */
.v2-rc__scale {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}
.v2-rc__stepper {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 40px;
  padding: 0 5px;
  border-radius: 20px;
  background: var(--s-card);
  border: 1px solid var(--raised-line);
  box-shadow: var(--sh-raised);
  flex: none;
}
.v2-rc__stepbtn {
  position: relative;
  width: 30px;
  height: 30px;
  border-radius: 15px;
  border: 0;
  padding: 0;
  background: var(--accent-pill);
  color: var(--accent-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.v2-rc__stepbtn::after {
  content: "";
  position: absolute;
  inset: -7px;
}
.v2-rc__stepbtn:disabled {
  opacity: 0.4;
}
.v2-rc__stepn {
  min-width: 28px;
  text-align: center;
  font-size: 15px;
  font-weight: 680;
  color: var(--t-primary);
  font-variant-numeric: tabular-nums;
}
.v2-rc__stepnoun {
  font-size: 13.5px;
  font-weight: 570;
  color: var(--t-muted);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2-rc__convert {
  position: relative;
  margin-left: auto;
  flex: none;
}
.v2-rc__convbtn {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 40px;
  padding: 0 15px 0 13px;
  border-radius: 20px;
  background: var(--s-card);
  border: 1px solid var(--raised-line);
  box-shadow: var(--sh-raised);
  color: var(--t-primary);
  font: inherit;
  font-size: 13.5px;
  font-weight: 640;
}
.v2-rc__convbtn svg {
  color: var(--accent-ink);
}
.v2-rc__scalenote {
  margin: -2px 2px 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--t-muted);
}

/* ---------- ingredients (tap to strike) ---------- */
.v2-rc__ings {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.v2-rc__ing {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  min-height: 32px;
  padding: 3px 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.v2-rc__box {
  width: 20px;
  height: 20px;
  box-sizing: border-box;
  border-radius: 6px;
  border: 1.5px solid var(--dash-line);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--on-accent);
  flex: none;
}
.v2-rc__ing.is-done .v2-rc__box {
  background: var(--done);
  border-color: transparent;
}
.v2-rc__ing input:focus-visible + .v2-rc__box {
  outline: 2px solid var(--accent-ink);
  outline-offset: 2px;
}
.v2-rc__ingtext {
  font-size: 14.5px;
  line-height: 1.35;
  color: var(--t-body);
  min-width: 0;
  overflow-wrap: anywhere;
}
.v2-rc__amt {
  font-weight: 660;
  color: var(--t-primary);
  font-variant-numeric: tabular-nums;
}
.v2-rc__ing.is-done .v2-rc__ingtext {
  color: var(--t-label);
  text-decoration: line-through;
}
/* Batch 6 §13b: "(AI estimate)" after an estimated amount — the muted note ink. */
.v2-rc__ingest {
  color: var(--t-muted);
  font-size: 0.92em;
  white-space: nowrap;
}
.v2-rc__ing.is-done .v2-rc__amt {
  color: inherit;
}
/* Item 17: a not-converted line ends in a small accent "*"; the reason is
   one short muted footnote under the list — a system note, not ingredient
   text. */
.v2-rc__ingstar {
  margin-left: 0.1em;
  color: var(--accent-ink);
  font-weight: 700;
  text-decoration: none;
  display: inline-block;
}
.v2-rc__ingfoots {
  margin: 0.5rem 2px 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.v2-rc__ingfoot {
  margin: 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--t-muted);
}

/* ---------- instructions ---------- */
.v2-rc__steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* A step is a tap target: tapping crosses it off (Randy 2026-10-01), the
 * same spirit as the ingredient checklist. */
.v2-rc__step {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}
.v2-rc__step.is-done .v2-rc__steptext {
  color: var(--t-label);
  text-decoration: line-through;
}
.v2-rc__step.is-done .v2-rc__stepnum {
  color: var(--t-label);
}
.v2-rc__step input:focus-visible ~ .v2-rc__steptext {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
/* A fixed column sized to the list's longest number (.is-num2 / .is-num3,
 * set by stepsHtml), numbers right-aligned so the dots line up and every
 * step's text starts at the same edge. */
.v2-rc__stepnum {
  width: calc(1ch + 0.4em);
  text-align: right;
  font-size: 14.5px;
  line-height: 1.5;
  font-weight: 700;
  color: var(--accent-ink);
  font-variant-numeric: tabular-nums;
  flex: none;
}
.v2-rc__steps.is-num2 .v2-rc__stepnum {
  width: calc(2ch + 0.4em);
}
.v2-rc__steps.is-num3 .v2-rc__stepnum {
  width: calc(3ch + 0.4em);
}
.v2-rc__steptext {
  display: block;
  margin: 0;
  min-width: 0;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--t-body);
  text-wrap: pretty;
  overflow-wrap: anywhere;
}

/* ---------- my notes ---------- */
/* The fuller source link above My notes (Randy 2026-10-03): a thin raised
 * card — thumbnail, title, the muted URL. */
.v2-rc__srccard {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding: 9px 12px 9px 9px;
  border-radius: var(--r2-card);
  background: var(--s-card);
  border: 1px solid var(--raised-line);
  box-shadow: var(--sh-raised);
  color: var(--t-primary);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.v2-rc__srccard:active {
  transform: translateY(1px);
}
.v2-rc__srccard-thumb {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--accent-tint);
  display: flex;
  align-items: center;
  justify-content: center;
}
.v2-rc__srccard-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.v2-rc__srccard-tile {
  display: flex;
  color: var(--accent-ink);
}
.v2-rc__srccard-text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.v2-rc__srccard-title {
  font-size: 14.5px;
  font-weight: 620;
  line-height: 1.3;
}
.v2-rc__srccard-url {
  font-size: 12.5px;
  color: var(--t-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-rc__srccard-go {
  flex: none;
  display: flex;
  color: var(--t-chevron);
}
.v2-rc__notes {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 13px 14px;
  border-radius: var(--r2-card);
  background: var(--s-card);
  border: 1px solid var(--raised-line);
  box-shadow: var(--sh-raised);
}
.v2-rc__noteshead {
  display: flex;
  align-items: center;
  gap: 8px;
}
.v2-rc__notesicon {
  display: flex;
  color: var(--accent-ink);
}
.v2-rc__noteslabel {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--t-label);
}
/* Batch 8 §9: separate notes — text 16 px primary, its time 12 px muted
 * under it, a 0.5 px divider BETWEEN notes (none after the last), 12 px of
 * space around each divider, oldest first. */
.v2-rc__notelist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.v2-rc__note {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 0;
}
.v2-rc__note:first-child {
  padding-top: 0;
}
.v2-rc__note:last-child {
  padding-bottom: 0;
}
.v2-rc__note + .v2-rc__note {
  border-top: 0.5px solid var(--strip-line);
}
.v2-rc__notetext {
  margin: 0;
  font-size: 16px;
  line-height: 1.45;
  color: var(--t-primary);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* Batch 14 §1 (Randy 2026-10-15): a note line that starts with a list
 * number or a bullet hangs — the marker in a fixed 1.6 em column (the
 * secondary ink, medium weight), the text and its wrapped lines under the
 * text. The line is a full-width inline-block inside the pre-wrap <p>, so
 * the note's own "\n" breaks still separate the lines exactly as before. */
.v2-rc__noteli {
  display: inline-block;
  width: 100%;
  box-sizing: border-box;
  position: relative;
  padding-left: 1.6em;
  vertical-align: top;
}
.v2-rc__notemark {
  position: absolute;
  left: 0;
  top: 0;
  width: 1.6em;
  white-space: nowrap;
  overflow: hidden;
  color: var(--t-muted);
  font-weight: 500;
}
.v2-rc__notewhen {
  font-size: 12px;
  line-height: 1.3;
  color: var(--t-muted);
}
/* The shared in-place editor (inline-edit.js .iedit) in the Cookbook accent;
 * the text sits where the resting text sat. */
.v2-rc__notes .iedit {
  border-color: var(--accent);
  border-radius: var(--r2-well);
  /* Batch 10 §7b: the box ends where the text's row ends (the shared
   * editor's negative bottom margin reached 3.5 px into the note's date
   * line); its top and sides keep the text where it sat. */
  margin-bottom: 0;
}
.v2-rc__notes .iedit__field {
  caret-color: var(--accent);
  white-space: pre-wrap;
}
.v2-rc__notes .iedit__btn--save {
  background: var(--accent);
  color: var(--on-accent);
}
.v2-rc__notes .iedit__btn--cancel {
  border-color: var(--raised-line);
  color: var(--t-muted);
}
.v2-rc__noteadd {
  height: 38px;
  box-sizing: border-box;
  width: 100%;
  padding: 0 13px;
  border-radius: var(--r2-well);
  background: var(--s-panel);
  border: 1px solid var(--raised-line);
  box-shadow: var(--sh-raised);
  color: var(--t-primary);
  font: inherit;
  font-size: 13.5px;
  outline: none;
}
.v2-rc__noteadd::placeholder {
  color: var(--t-placeholder);
}
.v2-rc__noteadd:focus-visible {
  border-color: var(--accent-tint-line);
}

/* ---------- missing / error ---------- */
.v2-rc__gone {
  padding: 2rem 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  font-size: 15px;
  color: var(--t-body);
}
.v2-rc__gone p {
  margin: 0;
}
.v2-rc__gonelink {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 15px;
  font-weight: 620;
  color: var(--accent-ink);
  text-decoration: none;
}

/* ---------- the collections checklist sheet (recipe + write) ---------- */
.v2-rc__sheetwrap {
  position: fixed;
  inset: 0;
  z-index: 60;
}
.v2-rc__scrim {
  position: absolute;
  inset: 0;
  background: var(--scrim);
  -webkit-backdrop-filter: blur(var(--scrim-blur));
  backdrop-filter: blur(var(--scrim-blur));
}
.v2-rc__sheet {
  position: absolute;
  left: 0;
  right: 0;
  /* Rides above the keyboard while the New collection name is typed. */
  bottom: var(--kb-inset, 0px);
  max-height: 80vh;
  overflow-y: auto;
  box-sizing: border-box;
  padding: 8px var(--pad-x) calc(20px + env(safe-area-inset-bottom, 0px));
  border-radius: var(--r2-panel) var(--r2-panel) 0 0;
  background: var(--s-panel);
  border-top: 1px solid var(--strip-line);
  box-shadow: var(--sh-nav);
  display: flex;
  flex-direction: column;
  gap: 12px;
  color: var(--t-primary);
}
.v2-rc__grab {
  align-self: center;
  width: 36px;
  height: 5px;
  border-radius: 3px;
  background: var(--s-track);
}
.v2-rc__sheethead {
  display: flex;
  align-items: center;
  gap: 10px;
}
.v2-rc__sheettitle {
  margin: 0;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.3px;
}
.v2-rc__sheetx {
  position: relative;
  margin-left: auto;
  width: 32px;
  height: 32px;
  border-radius: 16px;
  border: 0;
  padding: 0;
  background: var(--s-chip);
  color: var(--t-muted);
  display: flex;
  align-items: center;
  justify-content: center;
}
.v2-rc__sheetx::after {
  content: "";
  position: absolute;
  inset: -6px;
}
.v2-rc__sheetlist {
  overflow: hidden;
}
.v2-rc__sheetrow {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 48px;
  padding: 0 13px;
  box-sizing: border-box;
  background: none;
  border: 0;
  color: var(--t-primary);
  font: inherit;
  font-size: 15px;
  font-weight: 560;
  text-align: left;
}
.v2-rc__sheettile {
  width: 28px;
  height: 28px;
  border-radius: var(--r2-tile);
  background: var(--accent-tint);
  color: var(--accent-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.v2-rc__sheetname {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.v2-rc__sheetcheck {
  display: flex;
  width: 18px;
  color: var(--accent-ink);
  flex: none;
}
.v2-rc__sheetrule {
  border: 0;
  height: 1px;
  margin: 0 0 0 53px;
  background: var(--strip-line);
}
.v2-rc__sheetempty {
  margin: 0;
  font-size: 14px;
  color: var(--t-muted);
}
.v2-rc__sheetnew {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  border-radius: var(--r2-well);
  border: 1.5px dashed var(--accent-tint-line);
  color: var(--accent-ink);
  font-size: 14px;
  font-weight: 620;
  text-decoration: none;
}
button.v2-rc__sheetnew {
  width: 100%;
  background: none;
  font: inherit;
  font-size: 14px;
  font-weight: 620;
}
.v2-rc__sheetform {
  display: flex;
  gap: 8px;
  align-items: center;
}
.v2-rc__sheetinput {
  flex: 1;
  min-width: 0;
  height: 44px;
  box-sizing: border-box;
  padding: 0 14px;
  font-size: 16px;
}

/* ================================================================
 * Write it in / Edit (#/recipe/new, #/recipe/:id/edit)
 * ================================================================ */

.v2-rw__head .v2-rw__top,
.v2-rw__head .v2-rw__htitle {
  display: none;
}
.v2-rw__head.is-compact {
  box-shadow: inset 0 -1px 0 var(--strip-line);
}
.v2-rw__head.is-compact .v2-rw__cancel,
.v2-rw__head.is-compact .v2-rw__spacer {
  display: none;
}
.v2-rw__head.is-compact .v2-rw__top {
  display: flex;
  padding: 0 14px 0 10px;
}
.v2-rw__head.is-compact .v2-rw__htitle {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  font-size: 14.5px;
  font-weight: 660;
  color: var(--t-nav);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-rw__body {
  gap: 14px;
}
.v2-rw__title {
  height: 44px;
  box-sizing: border-box;
  width: 100%;
  padding: 0 13px;
  font-size: 15.5px;
  font-weight: 650;
  outline: none;
}

/* The photo: full width at the top — a dashed accent box when empty, the
 * picture (4:3) when set or on its way. */
.v2-rw__photobox {
  min-width: 0;
}
.v2-rw__photo {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 1;
  box-sizing: border-box;
  border-radius: var(--r2-card);
  background: transparent;
  border: 1px dashed var(--accent-tint-line);
  color: var(--accent-ink);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0;
  font: inherit;
  overflow: hidden;
}
.v2-rw__photo.has-img,
.v2-rw__photo.is-busy {
  aspect-ratio: 4 / 3; /* 6a: a photo on its way already holds its frame — no layout shift when it lands */
}
.v2-rw__photo.has-img {
  border-style: solid;
  border-color: var(--raised-line);
  background: var(--s-chip);
  color: var(--t-placeholder);
}
.v2-rw__photolabel {
  font-size: 13px;
  font-weight: 620;
}
.v2-rw__photoimg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.v2-rw__photohit {
  position: absolute;
  inset: 0;
  border: 0;
  padding: 0;
  background: none;
}
.v2-rw__photox {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 30px;
  height: 30px;
  border-radius: 15px;
  border: 1px solid var(--glass-nav-line);
  padding: 0;
  background: var(--glass-nav);
  color: var(--t-primary);
  display: flex;
  align-items: center;
  justify-content: center;
}
.v2-rw__photox::after {
  content: "";
  position: absolute;
  inset: -8px;
}

/* The import photo chooser (item 3, Randy 2026-10-08 batch 2): 2+ photos
 * found by an import. The SAME box as the photo (4:3, card radius); inside
 * it a horizontal strip that snaps one photo at a time. "Best match" rides
 * on the first photo only (Cookbook tint), "1 of N" sits top right beside
 * the existing ✕, the dots sit under the box. One photo: none of this. */
.v2-rw__chooser {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
}
.v2-rw__choices {
  display: block;
}
.v2-rw__track {
  position: absolute;
  inset: 0;
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  scroll-behavior: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.v2-rw__track::-webkit-scrollbar {
  display: none;
}
.v2-rw__slide {
  position: relative;
  flex: 0 0 100%;
  height: 100%;
  scroll-snap-align: center;
  scroll-snap-stop: always;
}
.v2-rw__best,
.v2-rw__count {
  position: absolute;
  top: 13px;
  height: 24px;
  box-sizing: border-box;
  padding: 0 9px;
  border-radius: var(--r2-round);
  font-size: 12px;
  font-weight: 500;
  line-height: 24px;
  white-space: nowrap;
  pointer-events: none;
}
.v2-rw__best {
  left: 10px;
  background: var(--accent-tint);
  color: var(--accent-ink);
  border: 1px solid var(--accent-tint-line);
  line-height: 22px;
}
.v2-rw__count {
  right: 48px;
  background: var(--photo-chip);
  color: var(--photo-chip-ink);
  font-variant-numeric: tabular-nums;
}
.v2-rw__dots {
  display: flex;
  justify-content: center;
  gap: 6px;
}
.v2-rw__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--t-chevron);
  transition: background-color 0.15s ease;
}
.v2-rw__dot.is-on {
  background: var(--accent);
}

/* Collection chips: raised accent chips (tap to remove) + the dashed add. */
.v2-rw__chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  min-height: 28px;
}
.v2-rw__chip,
.v2-rw__addcol {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 28px;
  padding: 0 11px;
  border-radius: var(--r2-chip);
  font: inherit;
  font-size: 12.5px;
  font-weight: 620;
  color: var(--accent-ink);
  white-space: nowrap;
}
.v2-rw__chip {
  background: var(--s-card);
  border: 1px solid var(--raised-line);
  box-shadow: var(--sh-raised);
}
.v2-rw__addcol {
  padding: 0 12px 0 10px;
  background: transparent;
  border: 1px dashed var(--accent-tint-line);
}
.v2-rw__chip::after,
.v2-rw__addcol::after {
  content: "";
  position: absolute;
  inset: -8px -3px;
}

/* Servings: a − / + stepper (no typing). */
.v2-rw__servings {
  position: relative; /* the servings tip's box (servings-tip-bubble.js) */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-width: 0;
}
.v2-rw__slabel {
  font-size: 14.5px;
  font-weight: 640;
  color: var(--t-primary);
}
.v2-rw__stepper {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.v2-rw__stepbtn {
  position: relative;
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: var(--r2-round);
  border: 1px solid var(--raised-line);
  background: var(--s-card);
  box-shadow: var(--sh-raised);
  color: var(--accent-ink);
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.v2-rw__stepbtn:disabled {
  opacity: 0.4;
}
.v2-rw__stepbtn::after {
  content: "";
  position: absolute;
  inset: -4px;
}
.v2-rw__sval {
  min-width: 5.5rem;
  text-align: center;
  font-size: 14px;
  color: var(--t-body);
  font-variant-numeric: tabular-nums;
}
.v2-rw__sval b {
  font-size: 16px;
  font-weight: 720;
  color: var(--t-primary);
}
/* Item 15b: the unit word is tappable ("loaves", "rolls"); same type as
   before, a dotted underline says it can be changed. */
.v2-rw__sunit {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  text-decoration: underline dotted;
  text-decoration-color: var(--t-dim);
  text-underline-offset: 3px;
  cursor: text;
}
.v2-rw__sunit-in {
  font: inherit;
  color: var(--t-primary);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--accent-ink);
  border-radius: 0;
  padding: 0 0 1px;
  margin: 0;
  max-width: 9rem;
  text-align: center;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}
.v2-rw__sunit-in::placeholder {
  color: var(--t-placeholder);
}

/* Item 12c: "Suggest servings" — a small accent link inline after the
   Servings label, "Servings (suggest?)" (Randy's item 9, 2026-10-07), only
   while servings are unset; disabled with "Add ingredients first" on the
   line below; a spinner while the estimate runs. */
.v2-rw__slabels {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15em;
  min-width: 0;
  flex: 1 1 0; /* the stepper keeps its width; the link + hint wrap */
}
.v2-rw__suggest {
  display: inline-block;
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.3;
  color: var(--t-muted);
  white-space: nowrap;
}
.v2-rw__suggest.is-busy {
  display: inline-flex;
  align-items: center;
  vertical-align: bottom;
}
.v2-rw__suggest.is-busy .v2-upload__spin {
  width: 0.85em;
  height: 0.85em;
  margin-inline: 0.15em;
  border-width: 1.5px;
}
.v2-rw__sgbtn {
  position: relative;
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  font-weight: 680;
  text-align: start;
  color: var(--accent-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.v2-rw__sgbtn::after {
  content: "";
  position: absolute;
  inset: -0.6em -0.3em;
}
.v2-rw__sgbtn:disabled {
  color: var(--t-dim);
  text-decoration: none;
  cursor: default;
}
.v2-rw__sghint {
  font-size: 0.8125rem;
  line-height: 1.3;
  color: var(--t-muted);
}

/* An import's servings range, offered — never applied — above the stepper
   (Write it in) or in its place (the recipe view): "Recipe says 6–8
   servings · Use 6" (Randy 2026-10-05). */
.v2-rw__srvblock {
  display: flex;
  flex-direction: column;
  gap: 0.5em;
  min-width: 0;
}
.v2-rc__srvhint {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25em 0.45em;
  min-width: 0;
  font-size: 0.8125rem;
  line-height: 1.35;
  color: var(--t-muted);
}
.v2-rc__srvuse {
  position: relative;
  padding: 0.2em 0.75em;
  border-radius: var(--r2-round);
  border: 1px solid var(--accent-tint-line);
  background: var(--accent-tint);
  color: var(--accent-ink);
  font: inherit;
  font-weight: 680;
}
.v2-rc__srvuse::after {
  content: "";
  position: absolute;
  inset: -0.6em -0.3em;
}
.v2-rc__scale .v2-rc__srvhint {
  flex: 1 1 auto;
}

/* Prep / Cook (+ the derived total under them) */
.v2-rw__total {
  margin: -6px 0 0;
  font-size: 12.5px;
  font-weight: 560;
  color: var(--t-muted);
  font-variant-numeric: tabular-nums;
}
.v2-rw__total:empty {
  display: none;
}
.v2-rw__times {
  display: flex;
  gap: 9px;
  min-width: 0;
}
.v2-rw__field {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.v2-rw__flabel {
  font-size: 11px;
  font-weight: 640;
  color: var(--t-muted);
}
.v2-rw__fwell {
  height: 42px;
  box-sizing: border-box;
  width: 100%;
  padding: 0 12px;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  outline: none;
}
.v2-rw__sect {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  margin-top: 2px;
}

/* The editable rows at the board's size; every well wraps and grows (a
 * textarea), its far-right corner kept for the type switch (shell.css). */
.v2-rw .v2-elist__well {
  min-height: 44px;
  padding: 11px 13px;
  line-height: 1.45;
  font-size: 14.5px;
  outline: none;
}
.v2-rw .v2-elist__field.has-kind .v2-elist__well {
  padding-inline-end: calc(13px + 28px + 6px);
}
.v2-rw .v2-rw__stepwell {
  min-height: 62px;
}
.v2-rw .v2-elist__kind {
  top: 8px;
}
.v2-rw .v2-elist__row {
  align-items: flex-start;
}
.v2-rw [data-elist="steps"] .v2-elist__row .v2-elist__mark {
  margin-top: 11px;
  line-height: 1.45;
}
.v2-rw [data-elist="steps"] .v2-elist__row .v2-elist__grip,
.v2-rw [data-elist="steps"] .v2-elist__row .v2-elist__del {
  margin-top: 8px;
}
/* Ingredient rows grow too: the ✕ / grip stay level with the first line. */
.v2-rw [data-elist="ingredients"] .v2-elist__row .v2-elist__grip,
.v2-rw [data-elist="ingredients"] .v2-elist__row .v2-elist__del {
  margin-top: 6px;
}
.v2-rw .v2-elist__add {
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 13.5px;
}
.v2-rw .v2-elist__well:focus-visible {
  border-color: var(--accent-tint-line);
}
.v2-rw__notes {
  min-height: 76px;
  box-sizing: border-box;
  width: 100%;
  padding: 13px 14px;
  border-radius: 15px;
  font-size: 14px;
  line-height: 1.5;
  resize: none;
  outline: none;
}
.v2-rw__gone {
  padding: 2rem 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  color: var(--t-body);
  font-size: 15px;
}
.v2-rw__gone p {
  margin: 0;
}
.v2-rw__gonelink {
  color: var(--accent-ink);
  font-weight: 620;
  text-decoration: none;
}
.v2-rw__opt {
  text-transform: none;
  letter-spacing: 0;
}

/* "INGREDIENTS 8 ····· Reorder" */
.v2-rw__sectlabel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-width: 0;
}
/* The Reorder / Done toggle is the shared .v2-reorder-toggle (shell.css).
   Batch 6 §9: "Show as written" (the translation notice's link style,
   .v2-rw__trbtn) sits beside it; the one muted note under the label row
   while the originals show. */
.v2-rw__sectacts {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  flex: 0 0 auto;
}
.v2-rw__sectacts .v2-rw__trbtn {
  font-size: 13px;
}
.v2-rw__aswnote {
  margin: 2px 0 10px;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--t-muted);
}
.v2-elist.is-readonly .v2-elist__well {
  color: var(--t-muted);
  cursor: default;
}

/* Recipe link */
.v2-rw__link {
  display: flex;
  align-items: center;
  gap: 9px;
  height: 44px;
  box-sizing: border-box;
  padding: 0 13px;
  color: var(--t-placeholder);
}
.v2-rw__linkinput {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  border: 0;
  padding: 0;
  background: none;
  color: var(--t-primary);
  font: inherit;
  font-size: 14px;
  outline: none;
}
.v2-rw__linkinput::placeholder {
  color: var(--t-placeholder);
}

/* A section heading inside a saved recipe's ingredients. */
.v2-rc__inghead {
  margin: 12px 0 2px;
}
.v2-rc__inghead:first-child {
  margin-top: 0;
}
.v2-rc__ingheadtext {
  margin: 0;
  font-size: 15px;
  font-weight: 720;
  letter-spacing: -0.2px;
  color: var(--t-primary);
}

/* Ingredients label + "Start over" (clears what's checked off — kept on the
 * device for 24 hours, Randy 2026-10-03). Shown only once something is.
 * The row's height is the label's alone (Randy's item 6, 2026-10-06): the
 * button's line box was ~2 px taller than the small caps label, so the row
 * — and everything below — moved each time it appeared or went. Its box
 * now has no height of its own; the icon and words are centred on the
 * row's middle and overflow it evenly, and the tap target (::after) is
 * sized from that middle.
 * No tap highlight (Randy's item 8, 2026-10-07): WebKit paints its default
 * one — black at 40 % — over the button's box plus that tall ::after, and
 * fades it out after the tap while the button hides: a dark bar behind
 * "Start over" on the light ground (the same layer on the dark ground is
 * near-invisible). The checklist rows above already switch it off. */
.v2-rc__ingshead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.v2-rc__reset {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 0;
  overflow: visible;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-ink);
  font: inherit;
  font-size: 13px;
  font-weight: 640;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.v2-rc__reset[hidden] {
  display: none;
}
.v2-rc__reset::after {
  content: "";
  position: absolute;
  inset: -20px -6px;
}

/* Batch 10 §2 (Randy 2026-10-13): "Paste a whole recipe" — ONE dashed
 * Cookbook-amber row at the top of the New recipe form, above the photo. It
 * expands in place (~200 ms, grid rows 0fr → 1fr — the notices row's pattern;
 * none under Reduce Motion) into the box: the growing text area, the amber
 * "Organize it", a plain Cancel, the live status / error line and the muted
 * "You review everything before it saves." Section tokens only. */
.v2-rw__paste {
  border: 1px dashed var(--accent-tint-line);
  border-radius: var(--r2-card);
  color: var(--accent-ink);
  box-sizing: border-box;
}
.v2-rw__pasterow {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
  padding: 0 14px;
  margin: 0;
  border: 0;
  border-radius: inherit;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 14.5px;
  font-weight: 640;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.v2-rw__pasterow:disabled {
  cursor: default;
}
.v2-rw__pasterow svg {
  flex: none;
}
.v2-rw__pastelabel {
  flex: 1 1 auto;
  min-width: 0;
}
.v2-rw__pastechev {
  display: inline-flex;
  transition: transform 200ms ease;
}
.v2-rw__paste.is-open .v2-rw__pastechev {
  transform: rotate(180deg);
}
.v2-rw__pastebox {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 200ms ease;
}
.v2-rw__paste.is-open .v2-rw__pastebox {
  grid-template-rows: 1fr;
}
.v2-rw__pastebox-inner {
  min-height: 0;
  overflow: hidden;
}
.v2-rw__pastebody {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 2px 12px 12px;
}
.v2-rw__pastefield {
  display: block;
  width: 100%;
  min-height: 110px;
  padding: 11px 13px;
  box-sizing: border-box;
  resize: none;
  line-height: 1.45;
  overflow: hidden;
}
.v2-rw__pastefield:focus-visible {
  border-color: var(--accent-tint-line); /* the editor's wells' focus look */
}
.v2-rw__pasteacts {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.v2-rw__pastecancel {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-size: 14.5px;
  font-weight: 620;
  color: var(--t-muted);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.v2-rw__pastecancel:disabled {
  opacity: 0.45;
  cursor: default;
}
.v2-rw__pastestatus {
  margin: -4px 0 0;
  min-height: 1.35em;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--t-muted);
  overflow-wrap: anywhere;
}
.v2-rw__pastestatus:empty {
  display: none;
}
.v2-rw__pastestatus.is-error {
  color: var(--t-body);
}
.v2-rw__pastenote {
  margin: 0;
  font-size: 12px;
  line-height: 1.35;
  color: var(--t-muted);
}
@media (prefers-reduced-motion: reduce) {
  .v2-rw__pastebox,
  .v2-rw__pastechev {
    transition: none;
  }
}
