/* Mawmaw's — shared recipe page in the brand (docs/brand.md §4, §6.5): a cast-iron page under
   one stove lamp, Flour text, the M’ lockup, New York (ui-serif) headings with a red rule under
   the title, Rounded numbers, Mono labels, the yolk accent and the timer channel colours.
   Mobile-first, system fonts only, no external assets, nothing drifts. Sizes are rem on a 17 px
   base so they follow Dynamic Type in iOS Safari. */

:root {
  color-scheme: dark;

  /* Surfaces and ink (Theme tokens). */
  --iron: #120c08;
  --void: var(--iron); /* the v2 name */
  --deep: #17100b;
  --hull: #1c140e; /* skillet */
  --panel: #261b13; /* griddle */
  --line: rgb(247 241 232 / 0.08);
  --rim: rgb(247 241 232 / 0.07);
  --ink: #f7f1e8; /* Flour */
  --ink2: #c2b5a4;
  --ink3: #9a8d7c;
  --ink4: #3e3229;
  --cream: #f6ecdb; /* her hand on dark */
  --lamp: #e0a458; /* the lamp over the stove: light only, never text */
  --rule-red: #e2474f; /* on paper */
  --rule-red-dark: #d9545a; /* on iron; a line, never text */
  --rule-blue: #9db6da;

  --yolk: #ffb23e;
  --yolk-hot: #ff8a1f;
  --yolk-light: #ffc860;
  --on-yolk: #1a0e00;

  /* Timer and category channels (unchanged). */
  --cryo: #5ce1ff;
  --plasma: #c77dff;
  --ember: #ff7a2f;
  --solar: #ffd23f;
  --ion: #ff4f7b;
  --aurora: #3cf2a0;
  --nebula: #8c9bff;

  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --serif: ui-serif, "New York", Georgia, serif;
  --rounded: ui-rounded, "SF Pro Rounded", system-ui, -apple-system, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  --max: 720px;
  --gutter: max(16px, env(safe-area-inset-left), env(safe-area-inset-right));
  --radius: 22px;
}

/* Channel colours: `--c` on anything tagged with a channel. */
.channel-cryo {
  --c: var(--cryo);
}
.channel-plasma {
  --c: var(--plasma);
}
.channel-ember {
  --c: var(--ember);
}
.channel-solar {
  --c: var(--solar);
}
.channel-ion {
  --c: var(--ion);
}
.channel-aurora {
  --c: var(--aurora);
}
.channel-nebula {
  --c: var(--nebula);
}
.channel-yolk {
  --c: var(--yolk);
}

/* MARK: Base */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  font-size: 106.25%; /* 17 px */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  background: var(--iron);
}

/* iOS Safari only: follow the reader's Dynamic Type size. */
@supports (font: -apple-system-body) and (-webkit-touch-callout: none) {
  html {
    font: -apple-system-body;
  }
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  /* Cast iron under one static lamp at the top centre (lamp 22 % → 0). */
  background:
    radial-gradient(ellipse 42rem 24rem at 50% 0, rgb(224 164 88 / 0.22), rgb(224 164 88 / 0) 100%) no-repeat,
    var(--iron);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}

img {
  max-width: 100%;
}

a {
  color: var(--yolk);
}

:focus-visible {
  outline: 3px solid var(--yolk);
  outline-offset: 3px;
  border-radius: 8px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--gutter);
  top: -100px;
  z-index: 10;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--yolk);
  color: var(--on-yolk);
  font-weight: 700;
  text-decoration: none;
}

.skip-link:focus {
  top: max(8px, env(safe-area-inset-top));
}

/* MARK: Chrome */

/* The wordmark (docs/brand.md §3): "Mawmaw’s" in New York Bold, its apostrophe the mark's yolk drop.
   The M’ is never set beside it. */
.site-header {
  width: 100%;
  max-width: var(--max);
  margin: 0 auto;
  padding: max(14px, env(safe-area-inset-top)) var(--gutter) 14px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  color: var(--ink);
  text-decoration: none;
}

.wordmark {
  font-family: var(--serif);
  font-size: 1.375rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.012em;
}

/* The drop (the comma): 0.39 cap tall (cap 0.70 em) = 0.273 em (as the app's Wordmark);
   its top on the cap height: its bottom 0.70 - 0.273 = 0.427 em above the baseline.
   Written by docs/design/brand/source/produce.py --install. */
.wordmark .drop,
.landing-wordmark .drop {
  display: inline-block;
  width: auto;
  height: 0.273em;
  margin: 0 0.035em 0 0.04em;
  vertical-align: 0.427em;
}

.page {
  flex: 1;
  width: 100%;
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 var(--gutter) 64px;
}

.page:focus {
  outline: none;
}

.site-footer {
  width: 100%;
  max-width: var(--max);
  margin: 0 auto;
  padding: 22px var(--gutter) max(32px, env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  color: var(--ink3);
  font-size: 0.82rem;
  text-align: center;
}

.site-footer p {
  max-width: 42ch;
  margin: 0 auto;
}

.button {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 52px;
  padding: 0 26px;
  border: 0;
  border-radius: 999px;
  background: var(--panel);
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  box-shadow: inset 0 0 0 1px rgb(247 241 232 / 0.12);
}

.button.primary {
  background: linear-gradient(135deg, var(--yolk-light), var(--yolk) 45%, var(--yolk-hot));
  color: var(--on-yolk);
  box-shadow:
    inset 0 0 0 0.8px rgb(255 255 255 / 0.45),
    0 0 7px rgb(255 178 62 / 0.38),
    0 0 26px rgb(255 178 62 / 0.2);
}

/* MARK: Cover (only when a real one exists; otherwise the title starts the page) */

.hero {
  position: relative;
  height: clamp(300px, 54vh, 430px);
  margin: 0 calc(-1 * var(--gutter));
  overflow: hidden;
  background: var(--iron);
}

.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgb(18 12 8 / 0) 40%, rgb(18 12 8 / 0.8) 80%, var(--iron));
  pointer-events: none;
}

.hero-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 32%;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.hero.is-loaded .hero-image {
  opacity: 1;
}

.ai-tag {
  position: absolute;
  right: var(--gutter);
  bottom: 118px;
  z-index: 1;
  padding: 6px 12px;
  border: 1px solid rgb(247 241 232 / 0.18);
  border-radius: 999px;
  background: rgb(18 12 8 / 0.45);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  color: var(--ink);
  font-size: 0.76rem;
  font-weight: 600;
}

.ai-tag span {
  color: var(--plasma);
}

/* MARK: Identity */

.recipe {
  --channel: var(--c, var(--nebula));
}

.recipe-body {
  position: relative;
  z-index: 1;
  margin-top: 22px;
}

.recipe-body.overlaps {
  margin-top: -96px;
}

.channel-line {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 6px;
  color: var(--channel);
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.channel-dot {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--channel);
}

/* The title in New York Bold on the index-card's red rule (full bleed on a phone, like the card). */
.recipe-title {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(1.9rem, 1.3rem + 3vw, 2.75rem);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.01em;
  text-wrap: balance;
  text-shadow: 0 0 22px rgb(18 12 8 / 0.75);
}

.recipe-title::after {
  content: "";
  display: block;
  height: 2px;
  margin: 14px calc(-1 * var(--gutter)) 0;
  background: var(--rule-red-dark);
}

.summary {
  margin: 14px 0 0;
  color: var(--ink2);
  font-size: 1.06rem;
  text-wrap: pretty;
}

.byline {
  margin: 12px 0 0;
  color: var(--ink2);
  font-size: 0.88rem;
}

.byline strong {
  color: var(--ink);
  font-weight: 700;
}

/* MARK: Fact tiles */

.facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 18px 0 0;
  padding: 13px 4px;
  border: 1px solid var(--rim);
  border-radius: var(--radius);
  background: var(--hull);
  list-style: none;
}

.facts.count-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.facts.count-1 {
  grid-template-columns: minmax(0, 1fr);
}

.fact {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 0 12px;
}

.fact + .fact {
  border-left: 1px solid var(--line);
}

.fact-label {
  color: var(--ink3);
  font-family: var(--mono);
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.fact-value {
  font-family: var(--rounded);
  font-size: 1.47rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}

.unit {
  margin-left: 1px;
  color: var(--ink2);
  font-family: var(--sans);
  font-size: 0.55em;
  font-weight: 600;
}

.unit.word {
  margin-left: 0;
  font-size: 0.62em;
  white-space: nowrap;
}

/* A yield in words ("A big pot"): body-sized, so it fits its third of the row. */
.fact-value.words {
  font-family: var(--sans);
  font-size: 1.06rem;
  font-weight: 700;
  line-height: 1.25;
}

.fact-sub {
  color: var(--ink2);
  font-size: 0.76rem;
  font-weight: 600;
}

.fact-wait {
  color: var(--nebula);
}

@media (max-width: 359px) {
  .facts,
  .facts.count-2 {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }

  .fact + .fact {
    border-left: 0;
  }
}

/* MARK: Blocks */

.block {
  margin-top: 30px;
}

.block-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}

.block-title {
  margin: 0;
  font-family: var(--serif);
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.005em;
}

.block-aside {
  color: var(--ink3);
  font-size: 0.76rem;
  text-align: right;
}

/* MAKES beside "Ingredients" (1.6 R6), as the app's header shows it without the stepper: the label
   over the number (big) and its noun (small), right-aligned, standing on the title's line. */
.block-header:has(.makes) {
  flex-wrap: wrap;
  align-items: flex-end;
}

/* A long yield in words goes under the title, still on the right. */
.makes {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  min-width: 0;
  margin-left: auto;
  text-align: right;
}

.makes-value {
  font-family: var(--rounded);
  font-size: 1.3rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}

/* A yield in words ("A big pot"). */
.makes-value.words {
  font-family: var(--sans);
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.25;
}

.section-label {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 14px 0 2px;
  color: var(--ink3);
  font-family: var(--mono);
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.section-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.ingredient-list,
.step-list,
.timers,
.chips,
.notes-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* "Sugar ……… 2½ cups" */
.ingredient {
  padding: 9px 0;
}

.ingredient-line {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.ingredient-name {
  min-width: 0;
}

.optional {
  color: var(--ink3);
  font-size: 0.72rem;
  font-style: italic;
}

.leader {
  flex: 1 1 16px;
  min-width: 16px;
  align-self: flex-end;
  height: 1px;
  margin-bottom: 0.38em;
  background-image: radial-gradient(circle, var(--ink4) 0.85px, transparent 1.1px);
  background-position: left center;
  background-repeat: repeat-x;
  background-size: 5px 2px;
  padding-top: 2px;
}

.amount {
  flex: none;
  font-family: var(--rounded);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.ingredient-note {
  display: block;
  margin-top: 2px;
  color: var(--ink3);
  font-size: 0.76rem;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}

.chip {
  padding: 5px 12px;
  border: 1px solid var(--rim);
  border-radius: 999px;
  background: var(--panel);
  color: var(--ink2);
  font-size: 0.76rem;
  font-weight: 500;
}

/* MARK: Steps */

.step {
  /* The badge: 30 px at the 17 px base, following Dynamic Type up to 2× (the app's @ScaledMetric). */
  --step-badge: clamp(30px, 1.765rem, 60px);
  /* One line of the step title (1rem × line-height 1.3): the badge is centred on it. */
  --step-line: 1.3rem;
  position: relative;
  display: grid;
  grid-template-columns: var(--step-badge) minmax(0, 1fr);
  gap: 10px;
  padding: 12px 0;
}

/* The rail runs from under one badge to the next. */
.step:not(:last-child)::before {
  content: "";
  position: absolute;
  top: calc(12px + (var(--step-line) + var(--step-badge)) / 2 + 4px);
  bottom: -4px;
  left: calc(var(--step-badge) / 2 - 0.5px);
  width: 1px;
  background: var(--line);
}

/* Step numbers in circles, never "01" (docs/design/1.3/detail-spec.md §8, the app's
   StepNumberBadge at rest): the griddle inside a 1.5 px cream-ink rim (ink2 at 45 %), the plain
   number in Flour, SF Pro Rounded Bold 15, tabular digits. */
.step-number {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--step-badge);
  height: var(--step-badge);
  margin-top: calc((var(--step-line) - var(--step-badge)) / 2);
  border: 1.5px solid color-mix(in srgb, var(--ink2) 45%, transparent);
  border-radius: 50%;
  background: var(--panel);
  color: var(--ink);
  font-family: var(--rounded);
  font-size: 0.88rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* "123" still fits the circle (the app's minimumScaleFactor 0.7). */
.step-number.wide {
  font-size: 0.66rem;
  letter-spacing: -0.02em;
}

.step-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

/* The way to cook it a step belongs to (1.16: the microwave or the oven), over its title. */
.step-method {
  display: inline-block;
  margin: 0 0 4px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--panel);
  color: var(--ink2);
  font-size: 0.75rem;
  font-weight: 600;
}

.step-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.3;
}

.step-duration {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  flex: none;
  font-family: var(--rounded);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.step-duration.wait {
  color: var(--nebula);
}

.step-duration .symbol {
  align-self: center;
}

.step-text {
  margin: 4px 0 0;
  color: var(--ink2);
  font-size: 0.88rem;
}

.timers {
  display: grid;
  gap: 4px;
  margin-top: 8px;
}

.timer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  color: var(--c, var(--cryo));
  font-size: 0.82rem;
  font-weight: 600;
}

.timer-rest {
  color: var(--ink2);
  font-weight: 400;
}

.symbol {
  flex: none;
  width: 14px;
  height: 14px;
}

.symbol .fill {
  fill: currentColor;
}

.symbol .stroke {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.symbol-spoonful .stroke {
  stroke: var(--iron);
  stroke-width: 1.5;
}

/* MARK: Notes, open in app */

.notes-list li {
  position: relative;
  padding: 4px 0 4px 16px;
  color: var(--ink2);
  font-size: 0.94rem;
}

.notes-list li::before {
  content: "";
  position: absolute;
  top: calc(4px + 0.68em);
  left: 2px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ink4);
}

.source {
  margin: 10px 0 0;
  color: var(--ink2);
  font-size: 0.88rem;
  font-weight: 600;
}

.source a {
  text-decoration: none;
}

.open-app {
  display: grid;
  gap: 8px;
  margin-top: 34px;
  padding: 18px;
  border: 1px solid rgb(255 178 62 / 0.22);
  border-radius: 24px;
  background: var(--hull);
}

.open-app-title {
  margin: 0;
  font-family: var(--serif);
  font-size: 1.18rem;
  font-weight: 700;
}

.open-app-text {
  margin: 0 0 6px;
  color: var(--ink2);
  font-size: 0.88rem;
}

/* MARK: States */

.state {
  display: grid;
  justify-items: center;
  gap: 12px;
  max-width: 34rem;
  margin: 0 auto;
  padding: 56px 8px 40px;
  text-align: center;
}

.state-badge {
  display: grid;
  place-items: center;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  background: var(--panel);
  box-shadow: inset 0 0 0 1px var(--rim);
}

.state-icon {
  width: 36px;
  height: 36px;
}

.state-icon .stroke {
  fill: none;
  stroke: var(--ink3);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.state-title {
  margin: 4px 0 0;
  font-family: var(--serif);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.15;
  text-wrap: balance;
}

.state-message {
  margin: 0 0 8px;
  color: var(--ink2);
  text-wrap: pretty;
}

/* MARK: Loading (lines only: whether there is a cover is unknown until the share arrives) */

.skeleton {
  display: grid;
  gap: 12px;
  margin-top: 22px;
}

.skeleton-line,
.skeleton-block {
  height: 14px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--hull), var(--panel), var(--hull));
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}

.skeleton-line.short {
  width: 30%;
}

.skeleton-line.title {
  width: 80%;
  height: 34px;
}

.skeleton-line.medium {
  width: 60%;
}

.skeleton-block {
  height: 86px;
  margin: 8px 0;
  border-radius: var(--radius);
}

@keyframes shimmer {
  from {
    background-position: 100% 0;
  }
  to {
    background-position: -100% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton-line,
  .skeleton-block {
    animation: none;
  }

  .hero-image {
    transition: none;
  }
}

@media (prefers-contrast: more) {
  :root {
    --ink3: var(--ink2);
    --line: rgb(247 241 232 / 0.16);
    --rim: rgb(247 241 232 / 0.16);
  }
}

/* MARK: Wider screens */

@media (min-width: 760px) {
  .hero {
    margin: 0;
    border-radius: 28px;
  }

  .hero::after {
    border-radius: 28px;
  }

  .ai-tag {
    right: 18px;
  }

  .recipe-title::after {
    margin-inline: 0;
  }
}

/* MARK: Landing and 404 */

.landing .page {
  display: grid;
  place-items: center;
}

.landing-card {
  padding-top: 72px;
}

/* The stacked lockup, as in the app's Settings header (docs/brand.md §3.2): MAW / MAW in cream with the yolk
   heart (mark.png, the app's own watercolor art, web/tools/render-images.swift) standing on the red rule, the
   wordmark under it. The rule's top edge is the art's baseline (the PNG's bottom edge: the letters stand on it),
   and it runs 1.58 × the mark's width, as in the app. */
.landing-mark {
  display: block;
  box-sizing: content-box;
  width: auto;
  height: 112px;
  padding: 0 46px 2px;
  background: linear-gradient(var(--rule-red-dark), var(--rule-red-dark)) 0 112px / 100% 2px no-repeat;
  margin-bottom: 14px;
}

.landing-wordmark {
  margin: 0;
  font-family: var(--serif);
  font-size: 2.1rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.012em;
}

.landing-line {
  margin: 0;
  color: var(--ink);
  font-size: 1.1rem;
  text-wrap: balance;
}

.landing-about {
  max-width: 30rem;
  margin: 4px 0 0;
  color: var(--ink2);
  text-wrap: pretty;
}

.landing-card .state-message {
  max-width: 30rem;
  margin-top: 6px;
  color: var(--ink3);
  font-size: 0.9rem;
  text-wrap: balance;
}
