/* The public, crawlable recipe surface: /recipes/find. (project.md D188)
 *
 * Page-scoped. site.css is shared by sixteen pages and the signed-in app is a
 * different register (D89) -- nothing here may reach it.
 *
 * The card is deliberately the SAME shape as the homepage's .dish: photo on a
 * 4:3 crop, title in Gabarito, one line of quiet detail under it. A stranger
 * who arrives here from a search result and then visits the homepage should
 * see one product, not two. What differs is that these cards ARE links, because
 * here the click is the point (D172 keeps the homepage's own dish cards inert).
 */

.pub {
  --f-display: 'Gabarito', 'Public Sans', system-ui, sans-serif;
  background: var(--c-paper);
}
.pub h1, .pub h2 {
  font-family: var(--f-display);
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: 1.04;
  text-wrap: balance;
}
.pub .wrap, .pub .wrap > * { min-width: 0; }

.pwrap { padding-block: clamp(1.6rem, 4vw, 2.8rem) clamp(2.4rem, 6vw, 4rem); }
.pub h1 { font-size: clamp(1.9rem, 4.4vw, 3rem); margin: 0 0 .5rem; }
.plede {
  margin: 0 0 var(--sp-6);
  color: var(--c-ink-muted);
  font-size: 1.0625rem;
  line-height: 1.5;
}

/* ── the form. It works with no JavaScript: that is the whole point of the
      page existing at a URL rather than as a widget. */
.pform { margin: 0 0 var(--sp-7); }
.pform label {
  display: block;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: .9375rem;
  margin-bottom: .45rem;
}
.pform-row { display: flex; flex-wrap: wrap; gap: .6rem; }
.pform input {
  flex: 1 1 18rem;
  min-width: 0;
  font: inherit;
  padding: .8rem 1rem;
  min-height: 52px;
  border: 1px solid var(--c-rule);
  border-radius: var(--r-md);
  background: var(--c-paper-warm);
  color: var(--c-ink);
}
.pform input:focus-visible { outline: 3px solid var(--c-tomato); outline-offset: 2px; }
.pnote { margin: .6rem 0 0; font-size: .875rem; color: var(--c-ink-muted); }

/* ── the cards. auto-fill so it is one column on a phone and four on a desk
      without a breakpoint per width. */
.pcards {
  list-style: none; margin: 0 0 var(--sp-6); padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1.25rem;
}
/* Five is the cap, so give it five tracks rather than let auto-fill strand
   the fifth card alone on a second row. */
@media (min-width: 62rem) {
  .pcards { grid-template-columns: repeat(5, 1fr); gap: .9rem; }
}
.pcard { min-width: 0; }
.pcard-a {
  display: flex; flex-direction: column; height: 100%;
  text-decoration: none; color: inherit;
  border-radius: 8px;
  transition: transform var(--m-quick);
}
.pcard-a:hover { transform: translateY(-2px); }
.pcard-a:hover b { color: var(--c-tomato-deep); }
.pcard img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  display: block; border-radius: 8px;
  background: oklch(94% .006 60);
}
.pcard b {
  margin: .65rem 0 .15rem;
  font-family: var(--f-display); font-weight: 700;
  font-size: 1.05rem; letter-spacing: -.01em; line-height: 1.2;
  color: var(--c-ink);
}
.pdesc { font-size: .85rem; line-height: 1.35; color: var(--c-ink-muted); }
.pshort { font-size: .85rem; line-height: 1.35; color: var(--c-tomato); font-weight: 600; }
/* The join line is the CTA on every card Scott asked for. It sits at the
   bottom of the card whatever the description length, so a row of cards has
   one baseline rather than five. */
.pjoin {
  margin-top: auto; padding-top: .5rem;
  font-family: var(--f-display); font-weight: 700;
  font-size: .8125rem; color: var(--c-tomato-deep);
}
.pcard-a:hover .pjoin { text-decoration: underline; }

/* ── the count, and what membership buys. Numerals in the mono face, which is
      what DESIGN.md reserves it for. */
.pmore {
  margin: 0 0 var(--sp-5);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--c-rule);
  color: var(--c-ink-muted);
  font-size: .96rem; line-height: 1.5;
  max-width: 60ch;
}
.pmore .n, .pnone .n { color: var(--c-ink); font-size: 1.05em; }
.pcta { margin: 0; }
.pnone { color: var(--c-ink-muted); max-width: 54ch; }

/* ─────────────────────────────────────────────────── articles (D190)
 *
 * Same page shell as /recipes/find, so a reader who arrives on an article and
 * then searches sees one product. The reading column is the only place on this
 * site that gets a real measure — an article is the one thing here anybody
 * reads for more than ten seconds.
 */
.asec { margin: 0 0 var(--sp-7); }
.asec h2 {
  font-size: 1.1rem; margin: 0 0 .9rem;
  padding-bottom: .4rem; border-bottom: 1px solid var(--c-rule);
}
.acards {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1.5rem 1.25rem;
}
.acard { min-width: 0; }
.acard a {
  display: flex; flex-direction: column; height: 100%;
  text-decoration: none; color: inherit;
  transition: transform var(--m-quick);
}
.acard a:hover { transform: translateY(-2px); }
.acard a:hover b { color: var(--c-tomato-deep); }
.acard img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: 8px; background: oklch(94% .006 60); margin-bottom: .6rem;
}
.akicker {
  font-size: .72rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--c-tomato);
}
.acard b {
  margin: .2rem 0 .25rem;
  font-family: var(--f-display); font-weight: 700;
  font-size: 1.05rem; line-height: 1.25; letter-spacing: -.01em;
}
.asum { font-size: .875rem; line-height: 1.45; color: var(--c-ink-muted); }
.ameta {
  margin-top: auto; padding-top: .5rem;
  font-size: .78rem; color: var(--c-ink-muted);
}
.acard .ameta { font-family: var(--f-numeric); }

/* ── one article
 *
 * NO column cap here. `.wrap` centres a 1180px box; capping THIS element to
 * 46rem re-centres that narrower box, so the body started at 410px while the
 * hero above it started at 186 — the same mismatched-gutter problem as the
 * hero cap, just inverted. The reading measure is done properly by
 * `.abody > * { max-width: 66ch }`, which limits the LINE while leaving the
 * column where every other band on the site has it. */
.acrumb { margin: 0 0 .6rem; font-size: .8125rem; color: var(--c-ink-muted); }
.awrap h1 { font-size: clamp(1.9rem, 4.4vw, 2.8rem); margin: 0 0 .5rem; }
.awrap > .ameta { margin: 0 0 1.2rem; padding: 0; font-size: .85rem; }
.ahero { margin: 0 0 1.75rem; }
.ahero img {
  width: 100%; height: auto; border-radius: var(--r-md);
  background: oklch(94% .006 60);
}

/* The reading column. 66ch, which is inside the 65-75 the type rules ask for,
   and the line-height is looser than the rest of the site because this is the
   only long-form text on it. */
.abody { font-size: 1.0625rem; line-height: 1.72; }
.abody > * { max-width: 66ch; }
.abody p { margin: 0 0 1.15rem; }
.abody h2 {
  font-family: var(--f-display); font-weight: 800; letter-spacing: -.02em;
  font-size: 1.5rem; line-height: 1.15; margin: 2.2rem 0 .7rem;
}
.abody h3 { font-size: 1.2rem; margin: 1.8rem 0 .5rem; font-weight: 700; }
.abody h4 { font-size: 1.05rem; margin: 1.5rem 0 .4rem; font-weight: 700; }
.abody ul, .abody ol { margin: 0 0 1.15rem; padding-left: 1.35rem; }
.abody li { margin: 0 0 .45rem; }
.abody li::marker { color: var(--c-tomato); }
.abody a { color: var(--c-tomato-deep); text-underline-offset: 2px; }
.abody blockquote {
  margin: 1.6rem 0; padding-left: 1.1rem;
  border-left: 3px solid var(--c-tomato);
  font-size: 1.1rem; line-height: 1.55; color: var(--c-ink);
}
.abody img {
  width: 100%; height: auto; border-radius: var(--r-md); margin: 1.6rem 0;
}
.abody figure { margin: 1.6rem 0; }
.abody figcaption { font-size: .82rem; color: var(--c-ink-muted); margin-top: .4rem; }
.abody table { width: 100%; border-collapse: collapse; margin: 1.6rem 0; font-size: .92rem; }
.abody th, .abody td { border: 1px solid var(--c-rule); padding: .5rem .65rem; text-align: left; }
.abody th { background: var(--c-paper-warm); font-weight: 700; }
.abody hr { border: 0; border-top: 1px solid var(--c-rule); margin: 2rem 0; }

/* ── the live search at the foot. This is the difference between an article
      and a blog post: it ends with the actual answer from the corpus. */
.alive {
  margin: 2.5rem 0 0;
  padding: 1.5rem 0 0;
  border-top: 3px solid var(--c-tomato);
}
.alive h2 {
  font-family: var(--f-display); font-weight: 800; letter-spacing: -.02em;
  font-size: 1.35rem; margin: 0 0 .3rem;
}
.vnote-a { margin: 0 0 1.1rem; font-size: .9rem; color: var(--c-ink-muted); }
/* The article column is 46rem, so four cards would be 9rem each. Two up. */
.alive .pcards { grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: 1rem; }
@media (min-width: 62rem) { .alive .pcards { grid-template-columns: repeat(4, 1fr); } }
.aback { margin: 2rem 0 0; font-size: .9rem; }

/* ══════════════════════════════════════════════════ page bands (D190b)
 *
 * Scott, 2026-09-09: *"I want this page to look similar to the homepage with
 * backgrounds, etc"*.
 *
 * The homepage is built from BANDS — photo, then dark, then paper, then warm
 * paper, then tomato — and these pages were one flat sheet of paper, so they
 * read as a different site. Same tokens, same rhythm, same closing block.
 * The tokens are duplicated from home.css deliberately: home.css is inlined
 * into index.html by the build and never loaded here (HANDOFF 217).
 */
.pub {
  --rule: oklch(91% .004 60);
  --ink-band: oklch(21% .012 40);
  --on-ink: oklch(99% .004 80);
  --on-ink-muted: oklch(80% .01 60);
  --tomato-lit: oklch(72% .17 38);
}

/* ── the dark opener, doing the job the photo hero does on the homepage */
.pband {
  background: var(--ink-band);
  color: var(--on-ink);
  padding-block: clamp(2.2rem, 5.5vw, 3.6rem);
}
/* NO max-width HERE. A headline capped at 20ch inside a 1180px wrap renders at
   about half the page and reads as a broken column, not as restraint. Written
   down twice already: the sandiegokaraoke hero (2026-05-28) and the homepage
   row sub-lines (D185 addendum). A hero runs to the same gutter as everything
   below it. */
.pband h1 {
  color: var(--on-ink);
  font-size: clamp(2rem, 5vw, 3.2rem);
  margin: 0 0 .5rem;
}
.pband h1 em { font-style: normal; color: var(--tomato-lit); }
.pband .plede {
  color: var(--on-ink-muted);
  margin: 0;
  font-size: clamp(1rem, 1.5vw, 1.15rem);
}
.pband .acrumb { color: var(--on-ink-muted); }
.pband .acrumb a { color: var(--tomato-lit); }
.pband .ameta { color: var(--on-ink-muted); }

/* The search form sits ON the dark band, like the shelf list does. */
.pband .pform { margin: 1.4rem 0 0; }
.pband .pform label { color: var(--on-ink); }
.pband .pform input {
  background: oklch(99% .004 80 / .07);
  border-color: oklch(99% .004 80 / .28);
  color: var(--on-ink);
}
.pband .pform input::placeholder { color: oklch(80% .01 60 / .8); }
.pband .pform input:focus-visible { outline-color: var(--tomato-lit); }
.pband .pnote { color: var(--on-ink-muted); }

/* ── the body bands */
.pmain { background: var(--c-paper); padding-block: clamp(2rem, 5vw, 3.2rem); }
.pmain.alt {
  background: var(--c-paper-warm);
  border-block: 1px solid var(--rule);
}

/* ── the close, straight from the homepage's tomato block */
.pclose {
  background: var(--c-tomato);
  color: oklch(99% .004 80);
  padding-block: clamp(2.4rem, 5.5vw, 3.6rem);
  text-align: center;
}
.pclose h2 {
  font-family: var(--f-display, 'Gabarito', system-ui, sans-serif);
  font-weight: 800; letter-spacing: -.025em;
  font-size: clamp(1.6rem, 3.6vw, 2.4rem);
  margin: 0 auto .9rem; max-width: 20ch; color: inherit;
}
/* Full-strength on-tomato, not 88% white: at .88 the paragraph measured 3.9:1
   on the tomato fill (Lighthouse, D309/D312); solid it is 4.7:1, the same
   treatment as the homepage's .h-close notes. */
.pclose p { margin: 0 auto 1.3rem; max-width: 46ch; color: var(--c-on-tomato); }
.pclose .btn-primary {
  background: oklch(99% .004 80); color: var(--c-tomato-deep); border-color: transparent;
}
.pclose .btn-primary:hover { background: oklch(94% .01 70); }

/* The old flat wrapper is now only used inside a band. */
.pwrap { padding-block: 0; }
/* The reading measure is for the article BODY only. The band above it uses the
   plain .wrap, so the hero runs to the SAME gutter as the site's other pages —
   full width of the column, not full width of the screen. Overriding
   max-width here instead pushed the hero out to 1328px where every other page
   stops at 1180. */
.awrap { padding-block: 0; }   /* see "one article": no width cap */

/* Category sections no longer need their own rule: the band edge does it. */
.pmain .asec:last-child { margin-bottom: 0; }

/* THE HUB LINKS. (project.md D202)
 *
 * Every ingredient page was an orphan — "URL is unknown to Google" — because a
 * sitemap gets a URL discovered and only a link gets it treated as worth
 * having. These are real navigation, not a footer tag cloud: readable size, a
 * proper heading, and each one goes somewhere that answers a question.
 */
.phub { margin: var(--sp-6) 0 0; padding-top: var(--sp-5); border-top: 1px solid var(--c-rule); }
.phub h2 {
  margin: 0 0 .7rem;
  font-size: .8125rem; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--c-ink-muted);
}
.phub ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem .5rem; }
.phub a {
  display: inline-block; padding: .38rem .7rem; min-height: 34px;
  font-size: .875rem; line-height: 1.5; text-decoration: none;
  color: var(--c-ink); background: var(--c-paper-warm);
  border: 1px solid var(--c-rule); border-radius: var(--r-pill);
}
.phub a:hover { border-color: var(--c-tomato); color: var(--c-tomato-deep); }
.phub a:focus-visible { outline: 2px solid var(--c-tomato); outline-offset: 2px; }

/* ── "what to make with X" pages (project.md D309)
 *
 * Section headings, the text list of further titles under the five cards, and
 * the short facts block. Same quiet scale as the hub heading so the cards stay
 * the loudest thing on the page.
 */
.psec {
  margin: 0 0 .8rem;
  font-size: clamp(1.15rem, 2.2vw, 1.4rem);
}
.pcards + .psec, .ptitles + .pfacts { margin-top: var(--sp-6); }
.ptitles {
  margin: 0; padding-left: 1.6rem;
  display: grid; gap: .1rem 2rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr));
}
.ptitles li { padding: .45rem 0; border-bottom: 1px solid var(--c-rule); min-width: 0; }
.ptitles li::marker { color: var(--c-ink-muted); font-family: var(--f-numeric); font-size: .85em; }
.ptitles a { color: var(--c-ink); font-weight: 600; text-decoration: none; }
.ptitles a:hover { color: var(--c-tomato-deep); text-decoration: underline; }
.pmeta { display: block; font-size: .8125rem; color: var(--c-ink-muted); }
.pfacts { margin: var(--sp-6) 0 var(--sp-5); max-width: 70ch; }
.pfacts ul { margin: 0 0 .8rem; padding-left: 1.2rem; }
.pfacts li { margin: 0 0 .35rem; line-height: 1.5; }
.pfacts li::marker { color: var(--c-tomato); }
.pfacts .n { font-family: var(--f-numeric); }
.phub-sub { margin-top: 1.1rem !important; }
.prel + .phub { margin-top: var(--sp-5); }

/* ── no layout shift when the phone menu builds itself (project.md D312)
 *
 * The article pages inline their CSS, so the first paint can land BEFORE the
 * deferred nav.js has swapped the four inline links for the menu button. At
 * 412px those links wrap to two rows (98px masthead) and then collapse to the
 * 44px button (72px), and everything below jumps up: Lighthouse measured CLS
 * 0.029. The page's head adds html.navjs only when scripts run, so here the
 * phone paints the masthead the way nav.js will leave it. No JS: no class, the
 * plain links show (D193's no-JS state). nav.js fails to load: its onerror
 * removes the class. Only the article shell sets the class today.
 */
@media (max-width: 47.99rem) {
  .navjs .mastnav { display: none; }
  .navjs .masthead .wrap { min-height: 44px; }
}
