/* ==========================================================================
   Kanga’s Kitchen — the printed page
   US Letter, portrait. The left margin is deliberately wide so a 3-hole punch
   lands in white space instead of through the ingredients.

   Four templates, chosen per recipe. They differ only in density and whether
   a photo appears — never in typeface, rules, or the shape of the masthead,
   because every page has to look like it belongs to the same book.
   ========================================================================== */

@page {
  size: letter portrait;
  margin: 0.55in 0.6in 0.5in 1.15in;   /* top right bottom LEFT(gutter) */
}

/* --------------------------------------------------------------------------
   Shared page rules. Also used on screen by the page editor, which renders
   .ps inside .page-stage at true letter proportions — hence these live outside
   the @media print block.
   -------------------------------------------------------------------------- */

.ps {
  font-family: Georgia, "Times New Roman", serif;
  line-height: 1.42;
  color: #000;
  --ps-body: 10.5pt;
  --ps-ing: 10pt;
  --ps-title: 25pt;
  --ps-col: 2.35in;
  --ps-gap: 0.34in;
}

.ps + .ps { break-before: page; }

/* ---- Templates ---------------------------------------------------------- */

.ps--compact  { --ps-body: 9pt;    --ps-ing: 8.5pt;  --ps-title: 20pt; --ps-col: 2.1in;  --ps-gap: 0.26in; line-height: 1.3; }
.ps--generous { --ps-body: 12.5pt; --ps-ing: 12pt;   --ps-title: 30pt; line-height: 1.55; }
.ps--twopage  { --ps-body: 11pt;   --ps-ing: 10.5pt; --ps-title: 26pt; }

/* Compact exists to get a long recipe onto ONE sheet, so it spends every
   trick: no photo, tighter type, and the method in two columns as well.
   Stacking sections costs vertical space that the old side-by-side layout got
   for free, so compact has to work harder than it used to. Each step still
   carries break-inside: avoid, so nothing splits mid-instruction. */
.ps--compact .ps__hero { display: none; }
.ps--compact .ps__steps { columns: 2; column-gap: .28in; }
.ps--compact .ps__section { margin-bottom: .13in; }
.ps--compact .ps__steps li { margin-bottom: .07in; padding-left: .26in; }
.ps--compact .ps__aside { margin-top: .14in; }
.ps--compact .ps__foot { margin-top: .16in; }
.ps--compact .ps__head { padding-bottom: .1in; margin-bottom: .13in; }
.ps--compact .ps__facts { margin-bottom: .13in; padding-bottom: .08in; }

/* ---- Masthead ----------------------------------------------------------- */

.ps__head { border-bottom: 2px solid #000; padding-bottom: .16in; margin-bottom: .2in; }
.ps__title { font-size: var(--ps-title); font-weight: 600; margin: 0 0 .04in; line-height: 1.12; }
.ps__desc { font-size: calc(var(--ps-body) - 0.5pt); font-style: italic; color: #333; margin: .06in 0 0; }
.ps__source { font-size: 9pt; color: #444; margin: .07in 0 0; }

/* ---- Facts strip -------------------------------------------------------- */

.ps__facts {
  display: flex; flex-wrap: wrap; gap: 0 .34in;
  font-size: 9.5pt; margin-bottom: .2in;
  padding-bottom: .12in; border-bottom: 1px solid #bbb;
}
.ps__fact strong {
  display: block; font-size: 7.5pt; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: #555;
  font-family: Helvetica, Arial, sans-serif;
}

/* A banner, not a float. Floating it right meant the two-column grid below
   wrapped around it and the method column collapsed to a sliver. */
.ps__hero {
  display: block; width: 100%; height: 1.75in; object-fit: cover;
  margin: 0 0 .18in; border: 1px solid #999;
}
.ps--generous .ps__hero { height: 2.2in; }

/* ---- The opener: hero beside the description ----------------------------
   Stacked, a masthead plus a full-measure hero plus a long description came to
   about six inches of a nine-and-a-half-inch text block — no recipe began work
   on its own first sheet. Side by side they cost about two.

   A grid, and the description is the flexible track, so with the hero switched
   off the band simply becomes the description at full measure and there is no
   hole where a picture used to be.
   ------------------------------------------------------------------------- */
.ps__opener {
  display: grid; grid-template-columns: 2.1in 1fr; gap: .24in;
  align-items: start; margin-bottom: .16in; break-inside: avoid;
}
.ps__opener .ps__hero { height: 1.35in; margin: 0; }
.ps__opener .ps__desc { margin: 0; }
.ps--generous .ps__opener { grid-template-columns: 2.6in 1fr; }
.ps--generous .ps__opener .ps__hero { height: 1.7in; }

/* ---- Body --------------------------------------------------------------- */

/*
 * Sections stack full-width; columns live INSIDE a section.
 *
 * The old side-by-side grid let a long ingredient list run past the bottom of
 * the sheet and strand its last line or two on page 2, where it gets missed and
 * the dish comes out wrong. Now the ingredient list flows into columns within
 * its own block, and that whole block refuses to break across pages — so it
 * either fits, or it moves as one piece. Nothing is ever left behind.
 */
.ps__section { margin-bottom: .22in; }

/* The ingredient section is ALLOWED to continue onto the next sheet.
   It used to carry `break-inside: avoid`, which made it all-or-nothing: a
   twenty-two-ingredient list either fitted or moved whole. Combined with
   `break-after: avoid` on the facts strip above it, that produced a chain the
   engine had to keep together, and when the chain did not fit it pushed
   everything down — far enough, on a long recipe, to leave sheet one holding
   nothing but the title.

   A section running over two sheets is fine. What is not fine is a runt at
   either end of the break, and that is what the widow/orphan rules and the
   per-line `break-inside: avoid` below are for. */

.ps__ing { column-gap: var(--ps-gap); column-fill: balance; }
.ps__ing--c2 { columns: 2; }
.ps__ing--c3 { columns: 3; }

/* Generous runs big type, so three columns would read as confetti. */
.ps--generous .ps__ing--c3 { columns: 2; }

/* An individual line must never split across a column or a page break. */
.ps__ing li { break-inside: avoid; page-break-inside: avoid; }

/* A heading inside the list stays with the items beneath it. */
.ps__section--ingredients h3 { break-after: avoid; break-inside: avoid; }

.ps h2 {
  font-size: 12pt; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  font-family: Helvetica, Arial, sans-serif;
  margin: 0 0 .09in; padding-bottom: .04in; border-bottom: 1px solid #000;
  break-after: avoid;
}
.ps--compact h2 { font-size: 10pt; }
.ps h3 { font-size: calc(var(--ps-body) - 0.5pt); font-style: italic; font-weight: 600; margin: .16in 0 .06in; }
.ps h3:first-child { margin-top: 0; }

.ps__ing { list-style: none; padding: 0; margin: 0; font-size: var(--ps-ing); }
.ps__ing li { padding: .045in 0 .045in .13in; text-indent: -.13in; }
.ps__ing li::before { content: "\2022  "; font-weight: 700; }

.ps__steps { list-style: none; padding: 0; margin: 0; counter-reset: s; font-size: var(--ps-body); }
.ps__steps li { counter-increment: s; position: relative; padding-left: .32in; margin-bottom: .1in; break-inside: avoid; page-break-inside: avoid; }
.ps__steps li::before {
  content: counter(s) "."; position: absolute; left: 0; top: 0;
  font-weight: 700; font-family: Helvetica, Arial, sans-serif; font-size: 10pt;
}

/* ---- Trailing blocks ---------------------------------------------------- */

.ps__aside { margin-top: .26in; break-inside: avoid; }
.ps__notes { border: 1px solid #999; padding: .12in .15in; }
.ps__notes p { white-space: pre-wrap; margin: 0; font-size: var(--ps-body); }

.ps__nut {
  list-style: none; padding: 0; margin: .07in 0 0; font-size: 9pt;
  columns: 2; column-gap: .34in;
}
.ps__nut li {
  display: flex; justify-content: space-between; gap: .12in;
  padding: .035in 0; border-bottom: 1px solid #ddd;
  break-inside: avoid;
}
.ps__nut b { font-weight: 700; }
.ps--compact .ps__nut { columns: 3; column-gap: .22in; }
.ps--generous .ps__nut { columns: 2; }

/*
 * Notes from the family. Set apart from the recipe's own notes — these came
 * from other people, so they read as marginalia rather than as instructions.
 */
.ps__family { border-left: 3px solid #999; padding-left: .16in; }
.ps__familynote {
  font-size: calc(var(--ps-body) - 0.5pt); font-style: italic;
  margin: .04in 0; break-inside: avoid;
}
.ps__familynote span { font-style: normal; color: #555; white-space: nowrap; }

/* Conversion caveats. Approximate weights are stated on the page, never hidden. */
.ps__caveats { margin-top: .16in; font-size: 8pt; color: #444; }
.ps__caveats li { margin-bottom: .02in; }

.ps__foot {
  margin-top: .3in; padding-top: .1in; border-top: 1px solid #bbb;
  font-size: 8pt; color: #555; display: flex; align-items: flex-start; gap: .16in;
  font-family: Helvetica, Arial, sans-serif;
  break-inside: avoid;
}
.ps__foot-text { display: flex; flex-direction: column; gap: .02in; flex: 1; }
.ps__foot-text span:last-child { color: #777; }
.ps__qr { width: .82in; height: .82in; flex: none; }
.ps__code { font-variant-numeric: tabular-nums; letter-spacing: .04em; }

/* ---- Break rules --------------------------------------------------------
   A section is ALLOWED to run onto the next sheet. What is forbidden is a runt
   at either end of the break — a heading alone at the foot of a page, one step
   carried over on its own, a single line of a paragraph stranded.

   This is ALL of it. There is no engine behind it and there is not meant to be
   one: a simulated paginator that placed its own breaks was built, measured
   against twenty real recipes, found to move a break on none of them, and
   removed. `orphans` and `widows` are line counts inside a block and Chrome
   honours both in paged media; the rest is keeping the indivisible things
   indivisible. public/fitter.js now only counts sheets — where the breaks
   fall is decided here.

   Every atom is enumerated below. Missing one is exactly how a stray label ends
   up alone at the bottom of a sheet.
   ------------------------------------------------------------------------- */
/* The masthead is ONE unit. Without break-inside it split: the title printed on
   sheet one and the byline on sheet two, with nine inches of white between
   them. break-after alone only says "not immediately after me". */
.ps__head { break-inside: avoid; }
.ps__head, .ps__facts { break-after: avoid; }

/* No heading is ever the last thing on a sheet. */
.ps__section > h2,
.ps__section h3,
.ps__aside h2,
.ps__comp__name { break-after: avoid; }

/* Two lines minimum either side of a break, in any prose block. */
.ps, .ps__desc, .ps__notes p, .ps__familynote, .ps__aside p { orphans: 2; widows: 2; }

/* The indivisible things. A step, an ingredient, a fact, a picture and a note
   are each read as one unit, so none of them may be cut in half.

   `break-inside` ONLY. Read the rule below before adding anything to this list:
   a second declaration here does not stay here. */
.ps__steps li,
.ps__ing li,
.ps__fact,
.ps__hero,
.ps__opener,
.ps__aside,
.ps__linenote { break-inside: avoid; }

/* The footer must never be the only thing on a sheet.
   It was: a ledger page ran to three sheets, and the third held nothing but
   "Kanga's Kitchen · added by Mom" — a whole sheet of paper for one line.
   `break-inside: avoid` kept the footer whole but said nothing about what came
   before it, so when it did not fit the remainder of a page it moved alone.
   `break-before: avoid` binds it to the block above, and the two travel
   together. If neither fits, both move — a bigger gap, but never a blank sheet
   with a byline on it.

   ITS OWN RULE, and it has to stay that way. This was once written by adding
   `.ps__foot` to the end of the selector list above, which gave `break-before:
   avoid` to every step, every ingredient, every fact and every aside as well.
   The damage was not subtle and was still invisible on screen: nothing may
   begin a column if nothing may have a break before it, so the three-column
   ingredient list stopped flowing altogether — every item piled into column
   one and two thirds of the sheet printed blank. It cost a whole extra sheet
   per recipe and was found by rendering a PDF, not by reading the CSS.

   The comment underneath even claimed the asides were excluded. They were not.
   A rule and a comment that disagree are just a comment. */
.ps__foot { break-before: avoid; }

/* NOT applied to the asides, though the same reasoning seems to fit.
   Chaining `break-before: avoid` across Notes, Around-the-table and the footer
   makes one indivisible run at the end of the page: if the run does not fit, the
   whole run moves, which pushed a ledger from three sheets to four. The footer
   is a single short line and can safely be bound to whatever precedes it; a
   stack of content blocks cannot. Asides keep `break-inside: avoid` only. */

/* ---- Index page --------------------------------------------------------- */

.ps-index { font-family: Georgia, "Times New Roman", serif; }
.ps-index h1 { font-size: 26pt; margin: 0 0 .06in; border-bottom: 2px solid #000; padding-bottom: .1in; }
.ps-index__sub { font-size: 9pt; color: #555; margin: 0 0 .28in; font-family: Helvetica, Arial, sans-serif; }
.ps-index h2 {
  font-size: 11pt; text-transform: uppercase; letter-spacing: .05em;
  font-family: Helvetica, Arial, sans-serif; margin: .22in 0 .06in;
  border-bottom: 1px solid #999; padding-bottom: .03in; break-after: avoid;
}
.ps-index ul { list-style: none; padding: 0; margin: 0; columns: 2; column-gap: .4in; font-size: 10pt; }
.ps-index li { break-inside: avoid; padding: .03in 0; }
.ps-index li span { color: #666; font-size: 8.5pt; }

/* --------------------------------------------------------------------------
   Print-only
   -------------------------------------------------------------------------- */

@media print {
  :root {
    --ink: #000; --ink-soft: #333; --ink-faint: #555;
    --rule: #bbb; --accent: #000; --accent-deep: #000;
  }

  html, body { background: #fff !important; color: #000 !important; font-size: 11pt; }

  /* Hide the application; print only the generated sheet. */
  #app, #screen-login, #busy, #print-dialog, #toast { display: none !important; }
  #print-sheet { display: block !important; }

  /* The fitter's offscreen measuring rig.
     It hangs off document.body rather than #app, so hiding the application did
     not hide it — and being absolutely positioned a foot off the left edge
     makes it invisible on screen but does NOT keep it off paper. A printer
     paginates whatever is laid out, so it printed as blank sheets after the
     recipe. It is emptied after every measurement too; this is the second
     lock on the same door. */
  .measure-rig { display: none !important; }

  /* The editor's on-screen page furniture must never reach paper. */
  .page-stage, .page-stage__chrome { all: unset; }
  [contenteditable] { outline: none !important; }
  .pe-overflow, .pe-hint { display: none !important; }
}

/*
 * A note attached to one ingredient or step.
 *
 * Set small, italic and indented under its line — the thing somebody wrote in
 * the margin beside step four, not a second step. It must never be mistaken for
 * an instruction, because on paper there is nobody to ask.
 */
.ps__linenote {
  display: block;
  margin-top: .04in;
  font-size: .82em;
  font-style: italic;
  line-height: 1.35;
  color: #4E6B8A;
}

/* ---- Counter -------------------------------------------------------------
   Big type, one column, room to write in the margin. Its ancestor is the 1930
   loose-leaf binder page, which was designed to be written on rather than
   admired. The template to reach for when the reader's eyes are tired.
   ------------------------------------------------------------------------- */
.ps--counter { --ps-body: 13pt; }
.ps--counter .ps__ing { columns: 1; }
.ps--counter .ps__ing li { padding: .055in 0; }
.ps--counter .ps__steps li { margin-bottom: .16in; line-height: 1.46; }
.ps--counter .ps__opener { grid-template-columns: 2.6in 1fr; }
.ps--counter .ps__opener .ps__hero { height: 1.75in; }

/* ---- Ledger --------------------------------------------------------------
   Two columns, for the long recipe. Chrome fragments multicol page-major —
   verified by printing a twelve-step method to PDF: steps 1–5 fill the left
   column of sheet one, 6–11 the right, and only then does it move to sheet two.
   Reading order is preserved, so the columns are safe as they stand.

   What they are NOT safe from is an ugly tail: a single step alone on a final
   sheet. The widow/orphan rules above are what guard against that.
   ------------------------------------------------------------------------- */
.ps--ledger .ps__section--ingredients .ps__ing { columns: 2; column-gap: .30in; }
.ps--ledger .ps__steps { columns: 2; column-gap: .30in; }
.ps--ledger .ps__steps li { break-inside: avoid; }
/* A group heading inside a column must not be the last thing in that column. */
.ps--ledger .ps__section h3 { break-after: avoid; column-span: none; }

/* ---- Bench ---------------------------------------------------------------
   Component-major: each part of the recipe complete in its own block, with its
   ingredients beside its own steps. Julia Child's setting — "on the left are
   the ingredients... on the right is a paragraph of instruction" — so the eye
   travels sideways rather than back up to a list.

   The body is a GRID, and that is the safety argument: a page break can only
   land between rows, so a part's ingredients can never end up on a different
   sheet from its method. There is no `columns` property anywhere in this
   template.

   The one thing a grid cannot do is split a row, so a part taller than the
   space left moves whole and strands white. The ingredient track goes two-up on
   a wide part, which halves its height and is usually enough.
   ------------------------------------------------------------------------- */
.ps--bench .ps__comp { margin-bottom: .04in; }
.ps--bench .ps__comp-name {
  font-family: Helvetica, Arial, sans-serif; font-size: 9.5pt; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  border-bottom: 1px solid #000; padding-bottom: .04in; margin: .2in 0 .1in;
  break-after: avoid;
}
.ps--bench .ps__comp-body { display: grid; grid-template-columns: 2.3in 1fr; gap: .28in; }
/* A method-only stage — "Assembly", "To serve". There is no ingredient column
   to sit beside, so it takes the full measure rather than leaving a hole where
   a list would have been. */
.ps--bench .ps__comp-body--wide { display: block; }
.ps--bench .ps__comp-ing .ps__ing { columns: 1; }
.ps--bench .ps__comp-ing h3, .ps--bench .ps__comp-steps h3 { display: none; }
.ps--bench .ps__comp-steps .ps__steps { margin: 0; }
/* A line's note belongs under its line, indented with it. Left at the list's
   own indent it broke back to the margin and read as a stray fragment. */
.ps__ing .ps__linenote { display: block; margin-left: .13in; text-indent: 0; }

/* ---- Room to write -------------------------------------------------------
   A binder is a working document. Somebody will write on it — the oven that
   runs hot, the year it was doubled, the fact that Nick likes it saltier — and
   if there is nowhere to put that, it ends up in the margin at an angle or not
   at all.

   Ruled, because a blank box invites one sentence and lines invite a list.
   Off by default: this costs room on the sheet, and a recipe that fits on one
   should keep fitting on one until she asks otherwise.
   ------------------------------------------------------------------------- */
.ps__blank {
  margin-top: .3in;
  break-inside: avoid;
}
.ps__rules {
  /* Six lines, drawn rather than marked up: they are furniture for a pen, not
     content, and nothing should try to read them aloud or search them. */
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent calc(.26in - 1px),
    #bbb calc(.26in - 1px),
    #bbb .26in
  );
  height: 1.56in;
  margin-top: .06in;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}
