/* GENERATED by scripts/build.py — edit site-src/static/, not this file. */
/* Warm editorial cookbook (decisions 28, 29).
 *
 * WHERE THE EFFORT GOES
 *   The recipe page. Large step text, ingredients set apart in their own
 *   panel, a column narrow enough to read at arm's length over a counter.
 *   The browse grid gets the opposite treatment — dense, quiet, fast to
 *   leave — because with no photographs and a collection built to grow, an
 *   editorial serif grid at several hundred entries is a wall of type.
 *
 * TYPE
 *   System serif for everything that is read: Iowan Old Style, Palatino,
 *   Georgia — good faces already on every device, zero bytes, nothing to
 *   maintain (decision 29). A system sans is used only for the small
 *   metadata chrome — labels, chips, counts, controls — which is an
 *   editorial convention, not a second typeface to maintain: no file is
 *   downloaded either way. Dropping in a self-hosted variable serif later
 *   is still one change, to --font-serif.
 *
 * NO EXTERNAL ANYTHING
 *   No CDN, no Google Fonts, no remote images, no @import. The whole
 *   stylesheet is this file (decisions 28, 29, and the design's Constraints).
 *
 * NO HOVER-DEPENDENT INTERACTION
 *   Nothing is revealed on hover, because the site gets used on a phone with
 *   wet hands. Hover states exist, but only ever as an echo of something
 *   already visible.
 */

/* -------------------------------------------------------------------------
 * Tokens
 * ---------------------------------------------------------------------- */

:root {
  --font-serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --font-sans: ui-sans-serif, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "Cascadia Mono", Consolas, "Liberation Mono", monospace;

  /* Cream and ink. */
  --paper:      #fbf7ef;
  --paper-sunk: #f3ece0;
  --ink:        #2a2521;
  --ink-soft:   #574f45;
  /* Dark enough to clear WCAG AA (4.5:1) against BOTH --paper and the sunk
   * panel, not just against the page. Ingredient sub-headings and facet
   * labels are muted text sitting on --paper-sunk, and a lighter grey that
   * passed on white was failing there at 4.14:1. Measured, not eyeballed. */
  --muted:      #6e6559;
  --rule:       #e3dac9;
  --rule-soft:  #efe7d9;
  --accent:     #8c3a1c;
  --accent-dim: #a75a38;
  --flag:       #86671b;

  --measure-read: 40rem;
  --measure-grid: 62rem;
  --radius: 3px;
}

/* Warm charcoal, not blue-black — the paper is cream, so the dark has to be
 * the same room with the lights off. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper:      #1e1c19;
    --paper-sunk: #262320;
    --ink:        #ece5da;
    --ink-soft:   #cdc4b6;
    --muted:      #9b9184;
    --rule:       #38332c;
    --rule-soft:  #2b2823;
    --accent:     #e2a074;
    --accent-dim: #eeb890;
    --flag:       #cdae62;
  }
}

/* -------------------------------------------------------------------------
 * Base
 * ---------------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  padding: 0 1.15rem 5rem;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-serif);
  font-size: 1.0625rem;
  line-height: 1.62;
  text-rendering: optimizeLegibility;
}

@media (min-width: 46rem) {
  body { font-size: 1.125rem; padding-left: 2rem; padding-right: 2rem; }
}

main, .wrap {
  max-width: var(--measure-read);
  margin-inline: auto;
}
.page-grid main, .page-grid .wrap {
  max-width: var(--measure-grid);
}

img { max-width: 100%; height: auto; }

a { color: var(--accent); text-underline-offset: 0.16em; }
a:hover { color: var(--accent-dim); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  position: static;
  display: inline-block;
  padding: 0.5rem 0.75rem;
  background: var(--paper-sunk);
}

/* -------------------------------------------------------------------------
 * Header and footer
 * ---------------------------------------------------------------------- */

.site-header { border-bottom: 1px solid var(--rule); }
.site-header .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 1.4rem;
  padding: 1.4rem 0 1.1rem;
}

.site-title {
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-decoration: none;
  color: var(--ink);
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.15rem;
  font-family: var(--font-sans);
  font-size: 0.82rem;
  letter-spacing: 0.02em;
}
/* Comfortable to hit with a thumb without making the bar tall. */
.site-nav a { padding: 0.35rem 0; text-decoration: none; }
.site-nav a:hover { text-decoration: underline; }
.site-nav a[aria-current="page"] { color: var(--ink); text-decoration: underline; }

.site-footer {
  margin-top: 5rem;
  border-top: 1px solid var(--rule);
  color: var(--muted);
  font-family: var(--font-sans);
  font-size: 0.78rem;
}
.site-footer .wrap { padding-top: 1rem; }

/* -------------------------------------------------------------------------
 * Typography
 * ---------------------------------------------------------------------- */

h1, h2, h3 {
  line-height: 1.18;
  font-weight: 600;
  letter-spacing: -0.011em;
  text-wrap: balance;
}

h1 { font-size: clamp(1.85rem, 1.35rem + 2vw, 2.6rem); margin: 2.2rem 0 0.4rem; }
h2 { font-size: 1.32rem; margin: 2.6rem 0 0.6rem; }
h3 { font-size: 1.06rem; margin: 1.6rem 0 0.3rem; }

p { margin: 0 0 1rem; }

.lede, .recipe-summary, .card-summary, .technique-summary {
  color: var(--ink-soft);
}
.lede, .recipe-summary, .technique-summary {
  font-size: 1.08em;
  font-style: italic;
  margin-bottom: 1.4rem;
}

/* Every small explanatory voice on the site: section notes, caveats, empty
 * states. Sans, small, quiet — it is apparatus, not prose. */
.section-note, .caveat, .empty, .search-note, .gloss, .technique-gloss {
  font-family: var(--font-sans);
  font-size: 0.83rem;
  line-height: 1.5;
  color: var(--muted);
}
.gloss, .technique-gloss { font-size: 0.92rem; }

code { font-family: var(--font-mono); font-size: 0.88em; }

.more { margin-top: 2.5rem; font-family: var(--font-sans); font-size: 0.88rem; }

/* -------------------------------------------------------------------------
 * Labels, chips, badges
 * ---------------------------------------------------------------------- */

.facet-label {
  font-family: var(--font-sans);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}

.chip {
  display: inline-block;
  padding: 0.2rem 0.6rem;
  margin: 0.12rem 0.2rem 0.12rem 0;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--paper);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  line-height: 1.5;
  text-decoration: none;
  color: var(--ink-soft);
}
a.chip:hover { border-color: var(--accent); color: var(--accent); }

/* `dietary` is inferred from the ingredient list, never asserted by the
 * source, and family read this site. The dashed edge says "provisional"
 * visually; the wording ("looks vegetarian") and the caveat beside it carry
 * the actual meaning, because a border style is not a sentence (decision 12). */
.chip-provisional { border-style: dashed; }
.chip-tag { border-color: var(--rule-soft); color: var(--muted); }

.badge {
  display: inline-block;
  padding: 0.3rem 0.7rem;
  margin: 0.2rem 0 0.6rem;
  border-left: 3px solid var(--flag);
  background: var(--paper-sunk);
  font-family: var(--font-sans);
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

/* An estimated total time is never allowed to read as a stated one
 * (decision 36). */
.estimate {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.03em;
  color: var(--flag);
  white-space: nowrap;
}

.count {
  font-family: var(--font-sans);
  font-size: 0.75rem;
  color: var(--muted);
}

/* -------------------------------------------------------------------------
 * Cards and the grid
 *
 * Dense and quiet on purpose. No image, ever, structurally — the card is
 * built from type and rules so a photograph can only ever be decoration
 * added later (decision 11).
 * ---------------------------------------------------------------------- */

.cards {
  display: grid;
  gap: 1px;
  margin: 1.2rem 0 0;
  background: var(--rule-soft);
  border: 1px solid var(--rule-soft);
}
@media (min-width: 34rem) { .cards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 58rem) { .page-grid .cards { grid-template-columns: repeat(3, 1fr); } }

/* Hairline separators rather than boxes: at several hundred entries, boxes
 * become a grid of boxes and the type stops being scannable. */
.card {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 0.95rem 1.05rem 1.05rem;
  background: var(--paper);
}
.card:hover { background: var(--paper-sunk); }

.card-title { margin: 0; font-size: 1.08rem; line-height: 1.25; }
.card-title a { text-decoration: none; }
.card-title a:hover { text-decoration: underline; }

.card-summary {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.5;
  /* Three lines, so a long summary cannot make one card twice the height of
   * its neighbours and break the scan. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.9rem;
  margin: auto 0 0;
  padding-top: 0.55rem;
  font-family: var(--font-sans);
  font-size: 0.78rem;
}
.card-meta dt {
  font-size: 0.68rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}
.card-meta dd { margin: 0 0.5rem 0 0.3rem; color: var(--ink-soft); }

.card-draft { background: linear-gradient(var(--paper-sunk), var(--paper-sunk)) padding-box; }
.card-draft .badge { margin: 0; padding: 0.15rem 0.5rem; font-size: 0.74rem; }

/* -------------------------------------------------------------------------
 * Home
 * ---------------------------------------------------------------------- */

.home-section { margin-bottom: 3rem; }
.home-section h2 {
  margin-bottom: 0.2rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--rule);
}

/* -------------------------------------------------------------------------
 * Browse: facets first, list second
 * ---------------------------------------------------------------------- */

.facets {
  margin: 1.5rem 0 2.5rem;
  padding: 1.1rem 1.2rem 0.6rem;
  background: var(--paper-sunk);
  border-radius: var(--radius);
}
.facet-group { margin-bottom: 1.1rem; }
.facet-group h2 {
  margin: 0 0 0.35rem;
  font-family: var(--font-sans);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}
.facet-values {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.9rem;
  font-family: var(--font-sans);
  font-size: 0.86rem;
}
.facet-values li { display: flex; align-items: baseline; gap: 0.25rem; }
.facet-values a { padding: 0.2rem 0; text-decoration: none; }
.facet-values a:hover { text-decoration: underline; }
.facets .caveat { margin: 0.3rem 0 0; }

.all-heading {
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--rule);
}

/* -------------------------------------------------------------------------
 * Search controls
 * ---------------------------------------------------------------------- */

.search-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1.4rem;
  margin: 1rem 0 0.4rem;
  font-family: var(--font-sans);
  font-size: 0.85rem;
}
.search-field { display: flex; align-items: center; gap: 0.45rem; margin: 0; }
.search-field label { color: var(--muted); }

.search-controls input[type="search"],
.search-controls select {
  font: inherit;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  /* 44px-ish tap targets: this gets used one-handed at a counter. */
  padding: 0.5rem 0.6rem;
}
.search-controls input[type="search"] { min-width: 14rem; flex: 1 1 14rem; }
.search-controls input[type="checkbox"] { width: 1.05rem; height: 1.05rem; accent-color: var(--accent); }
.search-field label:has(input[type="checkbox"]) {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--ink-soft);
  cursor: pointer;
}

.search-note { flex-basis: 100%; }

.search-status {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0;
  color: var(--muted);
}
.search-controls button {
  font: inherit;
  padding: 0.35rem 0.7rem;
  color: var(--accent);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  cursor: pointer;
}
.search-controls button:hover { border-color: var(--accent); }

/* -------------------------------------------------------------------------
 * The recipe page — where the typographic effort goes
 * ---------------------------------------------------------------------- */

.recipe-header { margin-bottom: 2.5rem; }

.recipe-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.1rem 2rem;
  margin: 1.4rem 0 1.2rem;
  padding: 0.9rem 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-sans);
}
.recipe-facts dt {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}
.recipe-facts dd {
  margin: 0.1rem 0 0.5rem;
  font-size: 0.98rem;
  color: var(--ink);
}
/* Each fact is a label stacked on its value, side by side across the rule. */
.recipe-facts dt { flex: 0 0 auto; width: 100%; }
@media (min-width: 30rem) {
  .recipe-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(6.5rem, max-content)); column-gap: 2.2rem; }
  .recipe-facts dt { width: auto; grid-row: 1; }
  .recipe-facts dd { grid-row: 2; margin-bottom: 0; }
}

.facet-line { margin: 0.3rem 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.3rem 0.5rem; }
/* Wide enough for "MAIN INGREDIENT" on one line — the longest label there is.
 * Below that width the labels stack above their chips instead, which is
 * better than a two-line label knocking the row out of alignment. */
.facet-line .facet-label { flex: 0 0 7.5rem; }
@media (max-width: 26rem) { .facet-line .facet-label { flex-basis: 100%; } }
.facet-dietary .caveat { flex-basis: 100%; margin: 0.15rem 0 0; }

/* Ingredients, set apart. The one block a cook looks at from two steps away
 * while holding something. */
.recipe-ingredients {
  margin: 2.5rem 0;
  padding: 1.3rem 1.4rem 1.4rem;
  background: var(--paper-sunk);
  border-radius: var(--radius);
}
.recipe-ingredients h2 { margin-top: 0; }
.recipe-ingredients ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.recipe-ingredients li {
  padding: 0.42rem 0;
  border-bottom: 1px solid var(--rule-soft);
  line-height: 1.45;
}
.recipe-ingredients li:last-child { border-bottom: 0; }
/* `### For the frosting` — a real division of the list, not a heading in the
 * document outline sense. */
.recipe-ingredients h3 {
  margin: 1.5rem 0 0.2rem;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}
.recipe-ingredients h3:first-of-type { margin-top: 0.6rem; }

/* Steps: the largest text on the site. Read standing up, at arm's length,
 * probably in bad light. */
.recipe-instructions ol {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}
.recipe-instructions li {
  counter-increment: step;
  position: relative;
  margin-bottom: 1.5rem;
  padding-left: 2.6rem;
  font-size: 1.09em;
  line-height: 1.68;
}
.recipe-instructions li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0.04em;
  width: 1.75rem;
  text-align: right;
  font-family: var(--font-sans);
  font-size: 0.82em;
  font-weight: 700;
  color: var(--accent);
}

.recipe-notes, .recipe-variations, .recipe-mynotes, .recipe-related,
.recipe-source, .recipe-equipment {
  margin: 2.5rem 0;
}
/* `## Notes & Tips` is the source's; `## My notes` is the cook's. They are
 * never allowed to look like one section (decision 13). */
.recipe-mynotes {
  padding-left: 1rem;
  border-left: 3px solid var(--rule);
}
.recipe-source {
  padding-top: 1.2rem;
  border-top: 1px solid var(--rule);
  font-size: 0.92rem;
  color: var(--ink-soft);
}
.recipe-source h2 { font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; font-family: var(--font-sans); color: var(--muted); }

/* -------------------------------------------------------------------------
 * Techniques
 * ---------------------------------------------------------------------- */

.technique-list { list-style: none; margin: 1.5rem 0 0; padding: 0; }
.technique-list-item {
  padding: 1rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.technique-list-item h2 { margin: 0 0 0.15rem; font-size: 1.1rem; }
.technique-list-item h2 a { text-decoration: none; }
.technique-list-item h2 a:hover { text-decoration: underline; }
.technique-list-item .gloss { margin: 0 0 0.3rem; }
.technique-list-meta { margin: 0; font-family: var(--font-sans); font-size: 0.78rem; color: var(--muted); }
.backlog { color: var(--flag); }

.technique-section { margin-bottom: 2rem; }
.technique-gloss { margin-bottom: 1.2rem; }
.technique-recipes { margin-top: 3rem; padding-top: 0.5rem; border-top: 1px solid var(--rule); }

/* -------------------------------------------------------------------------
 * Needs attention
 * ---------------------------------------------------------------------- */

.attention-group {
  margin: 2.5rem 0;
  padding-top: 1.2rem;
  border-top: 1px solid var(--rule);
}
.attention-group h2 { margin-top: 0; }
.attention-group .section-note { margin-bottom: 0.9rem; }

.attention-list { list-style: none; margin: 0; padding: 0; }
.attention-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.2rem 0.7rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--rule-soft);
}
.attention-list li:last-child { border-bottom: 0; }

.flag-kind {
  margin: 1.2rem 0 0.2rem;
  font-family: var(--font-sans);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--flag);
}
.flag-list li { display: block; }
.flag-where { font-family: var(--font-mono); font-size: 0.78rem; color: var(--muted); }
.flag-message { font-family: var(--font-sans); font-size: 0.85rem; }
.flag-context {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

/* -------------------------------------------------------------------------
 * Print — a recipe on paper, propped against something
 * ---------------------------------------------------------------------- */

@media print {
  body { padding: 0; font-size: 11pt; background: #fff; color: #000; }
  .site-header, .site-footer, .site-nav, .skip,
  .search-controls, .facets, .recipe-related, .more { display: none; }
  main { max-width: none; }
  .recipe-ingredients { background: none; border: 1px solid #999; }
  .recipe-instructions li { page-break-inside: avoid; font-size: 11pt; }
  a { color: #000; text-decoration: none; }
}
