/* Putting a note on paper — docs/PRINTING-PLAN.md.
 *
 * Loaded with media="print", so nothing in here can affect a screen. A separate
 * sheet rather than a block at the end of application.css: print rules are the
 * ones nobody looks at for months, and burying them among two thousand lines of
 * screen styles is how they stop being read at all.
 *
 * THE RULE FOR WHAT SURVIVES is not "is it useful" but "could you act on it with
 * a pen". A checkbox prints, because ticking it on paper means something. A Copy
 * link button does not.
 */

/* --- the page ------------------------------------------------------------- */

@page {
  /* Wide enough for a thumb, and the same on every edge so a page reads the same
     whichever way round it is filed. */
  margin: 18mm;
}

/* --- PRINT IS ALWAYS LIGHT ------------------------------------------------ *
 *
 * The first thing in the sheet, because everything else inherits from it.
 *
 * Measured before this existed: on the dark theme the text is rgb(232, 234, 238)
 * — near white — and browsers do not print background colours. So anybody
 * reading in the dark theme who printed a note got a page that looked blank.
 * That is a fault rather than a refinement.
 *
 * The selectors carry a little extra weight on purpose: themes.css sets these on
 * [data-theme="dark"], and a bare :root here would lose to it. */
:root,
:root[data-theme],
body[data-theme] {
  --bg: #ffffff;
  --surface: #ffffff;
  --surface-2: #ffffff;
  --border: #cccccc;
  --border-soft: #dddddd;
  --text: #000000;
  --muted: #444444;
  --accent: #000000;
  --accent-strong: #000000;
  --accent-soft: #f0f0f0;
  --accent-text: #000000;
  --shadow-sm: none;
  --shadow-md: none;
}

body {
  background: #ffffff;
  color: #000000;
}

/* --- everything that exists to OPERATE on the note ------------------------ */

.topbar,
.footer,
.sidebar,
.sidebar-scrim,
.sidebar-handle,
.pane-toggle,
.note__actions,
.quick-add,
.note__editor,
.conflict,
.touch-bar,
.keys-panel,
.uploads,
.uploader__bar,
.table-maker,
.diagram-preview,
.flash,
.freshness,
.banner,
.crumbs,
#note-link,
/* A twisty folds something. On paper nothing folds. */
.checklist__twisty,
.checklist-note-editor,
.map-note,
.card-panel,
.map-controls,
.board__filters {
  display: none !important;
}

/* The two-column grid is a screen arrangement. On paper there is one column. */
.layout {
  display: block;
}

.main,
.main--with-sidebar {
  margin: 0;
  padding: 0;
  max-width: none;
  width: auto;
}

/* --- what is left ---------------------------------------------------------- */

.note__title {
  /* A printed page with no title is a page nobody can file. */
  margin: 0 0 0.2rem;
  font-size: 1.6rem;
}

/* THE HEADER IS A ROW OF CONTROLS on a screen: a flex line, wrapping, with
   everything pushed to the far end and the title given a line of its own.
   On paper there are no controls — so what is left is a heading and a date being
   laid out by rules written for buttons.

   Reported: the date printed hard against the RIGHT margin, above the title
   rather than under it. Both follow from the flex line — `justify-content:
   flex-end` puts the only remaining item at the far end, and `order: 3` on the
   title moves it past a paragraph that comes before it in the markup. As blocks
   they are simply a title and then a date, which is the markup's own order. */
.note__header {
  display: block !important;
}

/* Paper-only. The hiding lives in application.css, because THIS sheet is only
   loaded for print — a `display: none` here would never reach a screen to hide
   anything, which is exactly how it first shipped. */
.print-only { display: block; }

.note__printed {
  margin: 0 0 1rem;
  /* Through the token, like everything else in the application — which also
     makes the palette reset above load-bearing rather than decorative. A literal
     colour here would print correctly while `.muted` elsewhere printed in the
     dark theme's near-white, and the test would not know. */
  color: var(--muted);
  font-size: 0.8rem;
}

/* --- NOBODY IS STANDING ON THE PAGE --------------------------------------- *
 *
 * A selection says where the keys will resume; a focus ring says where they are
 * now. Paper has neither, so both print as an unexplained box around whichever
 * row the reader's cursor happened to be resting on when they pressed print.
 * Reported: a checklist printed with a border around one item.
 *
 * The same reasoning as `.is-fading` below — a state of the reading session is
 * not a property of the note.
 *
 * Backgrounds are cleared ONLY where selection sets one. `background: none` on
 * a board card would take the card's own colour with it, and a card's colour is
 * content.
 */
.checklist-root.is-active .checklist__row.is-selected,
.checklist__row.is-selected {
  background: none !important;
  box-shadow: none !important;
}

.map__node.is-selected,
.board-card.is-selected,
.board-column__head.is-selected,
.map-frame:focus-visible,
.board-frame:focus-visible,
.board-card:focus-visible,
.board-column__head:focus-visible,
.board-card__has-note:focus-visible,
.task-list__checkbox:focus-visible,
.checklist__check:focus-visible {
  outline: none !important;
}

/* --- HEADINGS KEEP THEIR CONTENT ------------------------------------------ *
 *
 * `break-after: avoid` moves the HEADING down to join what follows, rather than
 * pushing the content up to join a stranded heading. Same outcome, fewer
 * half-empty pages. */
h1, h2, h3, h4, h5, h6,
.markdown h1, .markdown h2, .markdown h3,
.markdown h4, .markdown h5, .markdown h6 {
  break-after: avoid;
  break-inside: avoid;
}

/* And a paragraph never leaves one line stranded on either side of the fold. */
p, li, blockquote {
  orphans: 3;
  widows: 3;
}

/* --- things that are one thing stay on one page --------------------------- */

img,
figure,
pre,
.diagram__drawing,
.task-progress,
.checklist__item > .checklist__row,
.board-card {
  break-inside: avoid;
}

/* A tall picture is scaled to fit rather than cut in half. In print, `vh` is a
   PAGE rather than a screen, which makes "no taller than a page" one line. */
img,
.diagram__drawing svg {
  max-width: 100%;
  max-height: 86vh;
  /* Not `height: auto`, which was here and is redundant twice over: an <img>
     with no height attribute is auto already, and `.markdown img` in the screen
     sheet says it at a specificity this rule cannot reach anyway. Deleting it
     changed no measurement. What does the work when an image DOES carry
     attributes is the line below — the box may end up wider than the picture,
     and the picture keeps its shape inside it. */
  object-fit: contain;
}

/* A table crossing pages repeats its headings — the print behaviour people miss
   most and never think to ask for. */
thead { display: table-header-group; }
tr { break-inside: avoid; }

/* Borders rather than fills: a background is somebody's toner, and the tables
   read perfectly well without one. */
.markdown th { background: none; }

/* --- a checklist ---------------------------------------------------------- *
 *
 * Prints as a list with its boxes. The boxes are the reason: a printed checklist
 * is a thing somebody ticks with a pen, which is the whole test for what belongs
 * on paper.
 */

/* The row is a flex line on screen and stays one — the box, then the words. What
   goes is everything that operated on it. */
.checklist__has-note,
.checklist__timer,
.checklist__row-actions,
.checklist__nudge,
.checklist__add {
  display: none !important;
}

/* A spacer that reserved room for a twisty has nothing to reserve room for now
   that no row folds. */
.checklist__twisty--spacer { display: none !important; }

/* Fading is a countdown to a row disappearing from a screen. On paper there is
   no countdown and the row is simply there. */
.checklist__row.is-fading { opacity: 1; }

/* The selected row is where somebody's keyboard is, which is not a fact about
   the list. */
.checklist__row.is-selected,
.checklist__item:focus > .checklist__row {
  background: none;
  outline: none;
}

/* Nothing here about the boxes themselves, deliberately. The application draws
   them with `appearance: none` and a real border, and borders print — so they
   arrive on paper looking exactly as they do on screen.
   
   A rule forcing `appearance: checkbox` was written here first. It was not
   merely redundant: it would have swapped the application's circle for the
   platform's square on paper and nowhere else, which is a difference nobody
   asked for. Removing it failed no test, which is what prompted looking. */

/* An item's own note is content and prints; it just stops being a panel. */
.checklist__note {
  break-inside: avoid;
  background: none;
  border-left: 2px solid #cccccc;
}

/* --- a board -------------------------------------------------------------- *
 *
 * The hard one for paper. On screen it is columns side by side, which on A4 is
 * either four columns of nothing or a page cut off at the right margin.
 *
 * So each column becomes a section down the page — which the markup already is,
 * because the columns were built as <section>s with headings for screen readers.
 * The accessibility work pays for itself here.
 */
.board,
.board-frame,
.board__scroller {
  display: block !important;
  width: auto !important;
  min-height: 0;
  overflow: visible !important;
  padding: 0;
}

/* No `display` or `width` here: `.board` above is a block now, so its children
   stopped being flex items and lay themselves out down the page on their own.
   Overriding them as well looked careful and did nothing — removing those three
   lines changed no pixel and failed no test, which is how they were found. */
.board-column {
  margin: 0 0 1rem;
  background: none;
  /* Not `avoid`: a column with forty cards in it would be pushed whole onto a
     new page and leave most of one blank. The cards inside it are what must not
     be split, and they say so themselves. */
  break-inside: auto;
}

.board-column__head {
  break-after: avoid;
  border-bottom: 1px solid #cccccc;
}

.board-column__cards {
  display: block !important;
  padding: 0.4rem 0 0;
}

.board-card {
  margin: 0 0 0.4rem;
  background: none;
}

/* Emptiness is a fact about the board and prints; the button that fills it does
   not. */
.board-card__add,
.board-column__add,
.board-column__menu,
.board__archive-toggle {
  display: none !important;
}

/* --- a map ---------------------------------------------------------------- *
 *
 * The drawing, scaled to the page. Nothing here expands a folded branch, and
 * nothing needs to: `MapTree` gives a folded node no children at all, so what is
 * not on screen was never in the page to begin with. Plan §6.1.
 */
.map-frame,
.map-view {
  overflow: visible !important;
  height: auto !important;
  max-height: none !important;
}

/* The frame's edge is the edge of a WINDOW onto the map, and there is no window
   here — the whole drawing is on the page. Left in, it reads as a border round
   the content, which is a different claim. */
.map-frame {
  border: none !important;
  background: none !important;
}

.map {
  break-inside: avoid;
  max-width: 100%;
}

/* THE FIT, and it is CSS after all.
 *
 * Fitting a drawing to a page is a division: the page's width over the map's
 * own. The map's own is a number the SERVER computed, and `_map.html.erb` hands
 * it over as a unitless custom property — so this is `min()` over three plain
 * numbers, which CSS has always been able to do. An earlier version measured
 * the page in JavaScript on `beforeprint` and could not: that event fires before
 * the page is laid out, so the only width available is the one on the screen.
 *
 * `!important` because the zoom controller writes the reader's own scale inline,
 * and an author rule marked important outranks an inline one that is not. The
 * reader's zoom is therefore left alone — nothing is changed and nothing has to
 * be put back afterwards, which is the other half of what the JavaScript was for.
 *
 * If the custom properties are ever missing the whole declaration is invalid at
 * computed-value time and the map prints at its natural size, which is where it
 * started.
 *
 * THE PAGE IS THE SMALLER OF A4 AND US LETTER, inside the 18mm @page margin
 * above, at the 96dpi a CSS pixel assumes — fitting the smaller of each fits
 * both. Portrait: A4 is the narrower at 174mm across (658px), Letter the shorter
 * at 243mm down (920px). The height allows for the title and the date, which
 * print above the map, and a fit that ignored them would put the last row of
 * nodes onto a second page.
 */
.map-sizer {
  --paper-width: 658;
  --paper-height: 800;

  --fit: min(1, var(--paper-width) / var(--map-width), var(--paper-height) / var(--map-height));

  width: calc(var(--map-width) * var(--fit) * 1px) !important;
  height: calc(var(--map-height) * var(--fit) * 1px) !important;
}

/* Turned on its side the page is the other way round, and the reader chose that
   in the print dialogue precisely so a wide drawing would have room. Reported:
   a map printed landscape kept the width it had been given for a portrait page
   and left a third of the sheet empty. */
@media (orientation: landscape) {
  .map-sizer {
    --paper-width: 920;
    --paper-height: 538;
  }
}

.map {
  transform: scale(var(--fit)) !important;
  transform-origin: 0 0 !important;
}

/* --- an exported page on paper — docs/EXPORT-PLAN.md §4.5.2 ---------------- */

/* A PRINTED PAGE HAS NO CLICKING, so every note is open. One that hid half its
   content behind a triangle, or behind a fragment nobody can follow, would be a
   bad printout of a good page. */
@media print {
  .export-note__body { display: block !important; }
  .export-note-inline > *:not(summary) { display: block !important; }
  .export-note__back { display: none; }
}
