/* ============================================================================
   print.css — paper rules for the two printed views
   ----------------------------------------------------------------------------
   Loaded via <link rel="stylesheet" href="./print.css" media="print">, so it
   costs the screen nothing and lands last in the cascade: at equal specificity
   its rules win over styles.css without a single !important.

   Two documents come out of this app, both driven by `printMode` in the logic
   script (`doPrint('menu' | 'list')`), which puts `app--print-menu` or
   `app--print-list` on the app root:

     menu — the planner grid for the week. Landscape, one page, meant for a
            fridge door, with empty cells left blank so they can be written in.
     list — the shopping list rollup. Portrait, two columns, meant to be held
            in one hand in a shop and ticked off with the other.

   `printMode` decides *what* renders (the grid or the sidebar); this file
   decides how it sits on paper. Keep that split — a rule here should never be
   the reason a whole section appears or vanishes when that is the script's job.
   Hiding a *control* is this file's business; hiding content is not.

   Tokens come from styles.css `:root` and still apply. Same rule as there: no
   raw hex below this comment. Lengths are in pt, because paper has no pixels.
   ========================================================================== */


/* --- Page ----------------------------------------------------------------- */

/* Portrait is the default because the shopping list is the thing people
   actually carry; the menu opts into landscape by name below. Named pages are
   the only way to vary `size` per view — `@page` cannot be nested under a
   class — so where they are unsupported the menu prints portrait: squeezed,
   but not broken. */
@page { size: portrait; margin: 14mm 12mm; }
@page menu-page { size: landscape; margin: 10mm; }

.app--print-menu { page: menu-page; }

body {
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}


/* --- The document on screen ------------------------------------------------
   A tab opened from the print dialog carries `app--paper`, and in that tab
   this stylesheet is promoted to media="all" — so everything below applies to
   the screen too and the open tab *is* the printed page rather than a preview
   of it. These rules are the only ones that exist for the screen, which is why
   they are fenced in `@media screen`: in an ordinary tab this file is
   media="print" and the block never matches anything.

   The bar is the only thing on screen that is not on the paper. It is how you
   print again after dismissing the dialog, and it says what the document is.
   ------------------------------------------------------------------------- */

@media screen {
  /* White, not the app's warm page tint: this tab is a sheet of paper, and the
     only honest preview of a sheet of paper is a white one. */
  /* Doubled-up class so it outranks the blanket `background: none` the Ink
     section sets on `.app` further down — that rule is for paper, where bare
     is right; here bare would hand the page whatever the browser paints. */
  .app.app--paper {
    background: var(--surface);
    padding: 0 0 var(--sp-7);
    /* Fills the window so the white runs to the bottom edge. Without it the
       sheet stops at the end of the document and the browser's own canvas
       shows underneath, which reads as a second, greyer background. */
    min-height: 100vh;
  }

  /* The bar spans the window — it belongs to the tab, not to the document —
     so the app's side padding moves off it and onto the document itself. */
  .app--paper .print-title,
  .app--paper .layout {
    max-width: 1100px;
    margin-inline: auto;
    padding-inline: var(--sp-5);
  }

  .app--paper .print-title { padding-top: var(--sp-6); }

  /* A week is wider than most windows. On paper it is one landscape sheet and
     fits; on screen the sheet scrolls sideways inside its own frame rather
     than dragging the whole page with it — `html` is `overflow-x: hidden`, so
     left to the page the last two days would simply be unreachable.
     Doubled-up class to outrank the `overflow: visible` the menu section sets
     further down this file, which is what paper needs and screen does not. */
  .app--paper.app--print-menu .planner,
  .app--paper.app--print-menu .planner__grid {
    overflow-x: auto;
    padding-bottom: var(--sp-2);
  }

  .paper-bar {
    position: sticky;
    top: 0;
    z-index: 4;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2);
    padding: var(--sp-3) var(--sp-5);
    background: var(--surface);
    border-bottom: 1px solid var(--border-faint);
  }
}

/* On paper the bar is furniture, not content. This has to be fenced in
   `@media print` rather than left bare: in a document tab this whole file is
   media="all", and a bare rule here would sit after the screen block above and
   hide the bar on screen too — which is exactly what it did. */
@media print {
  .paper-bar { display: none; }
}


/* --- Ink ------------------------------------------------------------------
   Nothing prints as a filled panel. Every background in the app is doing one of
   two jobs — tinting a surface, or carrying text on top of it — and on paper the
   first is a wash of toner that buys nothing. So surfaces go to bare paper and
   the colour moves into the border and the type, which is where a meal's
   identity survives a black-and-white printer anyway.

   Two fills are kept on purpose, both named below: they are the ones with text
   sitting on them that would otherwise vanish. -------------------------------- */

html,
body,
.app,
.layout,
.card,
.chip,
.note-cell,
.slot-empty,
.shop-item,
.section-head,
.day-head {
  background: none;
}

.card,
.chip,
.note-cell {
  box-shadow: none;
}

/* The meal bar down the side of each row is the grid's key, and its label is
   white-on-colour. Emptied of its fill it would be white on white, so the bar
   becomes an outline and the word takes the meal's own colour. */
.row-label__bar {
  background: none;
  border: .75pt solid var(--meal-color);
}

.row-label__text {
  color: var(--meal-color);
}

/* Today's tint and ring are screen state, not information about the week — and
   `.day-head.is-today` outranks the bare `.day-head` above, so the fill has to
   be turned off where it was turned on. The date keeps the accent colour; that
   much is worth knowing on a printed week. */
.day-head.is-today {
  background: none;
  box-shadow: none;
}

/* Side dishes carry their meal's tint as a filled row. The bullet and the
   indent already say what they are, so the fill is pure toner. */
.side-row {
  background: none;
}

/* The exception that stays filled: an assignee's avatar is a 26px disc whose
   initial sits on the person's own colour. It is the cheapest ink on the page
   and the only thing saying whose meal this is — see the menu section. */

/* `min-height: 100vh` and the `--layout-fit` chain exist to pin a footer inside
   a window. Paper has no window, and holding the height only forces blank
   pages. */
.app,
.layout {
  min-height: 0;
  height: auto;
  display: block;
}


/* --- Controls are not content --------------------------------------------- */

/* Anything whose only purpose is to be clicked. The print title carries the
   week, so the header's controls have nothing left to say. */
.app-header__profile,
.app-footer,
.drawer,
.drawer-backdrop,
.sheet-scrim,
.sidebar-remove,
.menu,
.segmented,
.add-row,
.fab {
  display: none;
}

/* The brand mark stays — a page pulled off the fridge should say what it is —
   but it stops being the centrepiece. Floated up into the top right corner it
   lets the title take the top left, which is where the eye starts, and the two
   share one line instead of costing two. */
.app-header {
  display: block;
  float: right;
  text-align: right;
  margin: 0 0 4pt 8mm;
}

.brand { display: inline-flex; }

.print-title {
  font-size: 16pt;
  margin: 0 0 8pt;
}

/* The week must start below the masthead, not wrap around it. */
.layout { clear: both; }

/* ============================================================================
   MENU — the week, landscape, one page
   ========================================================================== */

/* Empty slots keep their box (somewhere to pencil in a meal) but lose the `+`
   affordance and the dashed "drop here" cue that meant something only on
   screen. */
.app--print-menu .slot-empty {
  border-style: solid;
  border-color: var(--border-faint);
  min-height: 0;
}

.app--print-menu .slot-empty > * {
  visibility: hidden;
}

/* `+ side`, `+ who` and the clear affordance are all invitations to click, and
   an invitation is worthless on paper. Note what this does NOT touch: an
   assignment that exists renders as `.avatar`, a separate element — only the
   empty `+ who` prompt is `.chip__assign`. So who is cooking prints; the offer
   to pick someone does not. The avatar keeps its fill for the same reason (see
   Ink above): the initial sits on the person's colour. */
.app--print-menu .side-add,
.app--print-menu .chip__assign,
.app--print-menu .chip__clear {
  display: none;
}

/* Small enough to read at arm's length on a fridge door. */
.app--print-menu .avatar {
  --avatar-size: 18pt;
}

/* The notes row prints as ruled space to write in, so the placeholder must not
   print "Notes…" seven times across the page, and a resize grip on paper is
   nonsense. */
.app--print-menu .note-cell__input,
.app--print-menu .note-box__input {
  resize: none;
}

.app--print-menu .note-cell__input::placeholder,
.app--print-menu .note-box__input::placeholder {
  color: transparent;
}

/* A week is one page by definition — it must not break mid-row, and the
   horizontal scroll that the pinned meal column needs on screen would clip the
   later days on paper. */
.app--print-menu .planner,
.app--print-menu .planner__grid {
  overflow: visible;
}

.app--print-menu .planner__week {
  break-inside: avoid;
}

.app--print-menu .chip {
  break-inside: avoid;
}


/* ============================================================================
   LIST — the shopping list, portrait, two columns
   ========================================================================== */

/* The one that actually mattered. On screen the list is a 340px sticky column
   inside a clipped card, capped at `--scroll-max`. Printed as-is it took a
   quarter of the sheet and silently cut every item past 560px — a shopping
   list that loses its last aisle is worse than no list. Release all three. */
.app--print-list .sidebar {
  position: static;
  width: auto;
  max-height: none;
  overflow: visible;
  flex: 1 1 auto;
}

.app--print-list .card--sidebar {
  max-height: none;
  overflow: visible;
  padding: 0;
  border: 0;
}

.app--print-list .scroll-y {
  max-height: none;
  overflow: visible;
  padding-right: 0;
  margin-right: 0;
}

/* The range is already in the print title. */
.app--print-list .shop-head {
  display: none;
}

/* Two columns turn a skinny ribbon of items into a page. Balanced, so the
   second column fills rather than trailing off after one entry. */
.app--print-list .shop-list {
  display: block;
  columns: 2;
  column-gap: 14mm;
  column-fill: balance;
}

/* A category must not be split across a column or a page — you scan a shopping
   list by aisle, and half an aisle at the foot of a column is how things get
   missed. */
.app--print-list .shop-list > * {
  break-inside: avoid;
  margin-bottom: 6pt;
}

/* A dotted rule per row: the thing that makes a dense list scannable when you
   are holding it in one hand and reading across from a name to its quantity.
   Dotted rather than solid so it separates without ruling the page into a
   table, and the padding stays tight — the line is doing the work that
   whitespace would otherwise have to, so more of the list fits the page. */
.app--print-list .shop-item {
  break-inside: avoid;
  padding: 2pt 0;
  border-bottom: .5pt dotted var(--border-strong);
}

/* No trailing rule under an aisle — the gap to the next heading already says
   the aisle ended. */
.app--print-list .shop-item:last-child {
  border-bottom: 0;
}

/* An empty aisle is a heading with nothing under it: noise on a list you are
   scanning while walking. The section only earns its place if it holds an
   item. */
.app--print-list .shop-list > *:not(:has(.shop-item)) {
  display: none;
}

/* Ticking happens with a pen, so the box has to be a box — and the quantity is
   the half of the line you actually read in the shop, so it stops being a
   whisper. */
.app--print-list .shop-check {
  border: 1pt solid var(--text);
  border-radius: 1pt;
}

.app--print-list .shop-item__name {
  font-size: 11pt;
}

.app--print-list .shop-item__qty {
  font-size: 10pt;
  color: var(--text-body);
}

.app--print-list .section-head {
  break-after: avoid;
}
