/* Spec §5.1 names this file and nothing had written it. DEPENDENCIES.md
 * records the ruling it exists to make true — the row that rejected jsPDF and
 * pdf-lib in favour of "window.print() + print stylesheet — zero bytes, and
 * produces real selectable text with working links". Loaded with
 * media="print" (index.html), so nothing here is ever fetched by a screen
 * viewer: a browser only requests a print stylesheet once it is about to
 * print.
 *
 * This file is the SECOND and only other place a hex colour is permitted,
 * alongside tokens.css — see test/ui.base.test.mjs's exemption, which names
 * it for the same reason recorded here. A printed page must come out on a
 * WHITE background even when the viewer's on-screen theme is dark, and CSS
 * has no way to say "reuse tokens.css's light block's values here" without
 * either a build step (this project deliberately has none) or writing the
 * same six hex pairs a second time inside tokens.css itself — which is the
 * exact drift the one-token-layer rule exists to prevent. Copying them once
 * more, here, scoped to @media print and nowhere else, is the smaller cost.
 * The six values below are copied VERBATIM from tokens.css's own
 * :root[data-theme="light"] block, not re-derived, so a future change to the
 * light theme is one more file to touch and never a second decision. */
@media print {
  :root {
    --canvas: #F4F6F4;
    --surface: #FFFFFF;
    --line: #D5DCD7;
    --line-strong: #7B8880;
    --ink: #141815;
    --mute: #4A574E;
    /* THE SEVEN THIS BLOCK USED TO FORGET, and every one of them printed the
     * DARK value on white paper, because a token this file does not redeclare
     * falls through to tokens.css's own :root. Found when host.gameReview became
     * the first printable screen to render a QR — §8.4's lanyard sheet, which is
     * the whole reason that screen offers Print at all.
     *
     * --qr-quiet is the sharp one. ui/qr.js paints the mandatory opaque quiet
     * zone with it and the modules in currentColor, which here is --ink. So the
     * margin came out #121814 against modules at #141815: measured at 1.004:1,
     * a solid dark square, 180x180 of toner per code and unscannable. With the
     * light theme's own value it is 17.93:1.
     *
     * The badges are the same bug one step quieter, and they are on the same
     * sheet: gameReview's readiness rows print ▲ Warning and ✓ Done. On paper
     * --warn measured 1.41:1 and --done 3.33:1; the light values are 6.31 and
     * 6.99. --risk is 2.86 against 5.55 and rides along because it is the third
     * member of one state set, not because an error state is worth printing.
     *
     * The role colours are NOT inert either, which is what stopped them being
     * listed as deliberately omitted: expert.snapshot is archetype D — it has a
     * Print button — and it renders a GateRing whose arc is stroked var(--role).
     * --role-host at the dark value measures 1.68:1 on paper.
     *
     * Verbatim from tokens.css's own light block, like the six above, so a
     * change to the light theme stays one more file to touch and never a second
     * decision. test/ui.print.test.mjs now derives the whole required set from
     * tokens.css rather than listing it, so the next token added to that theme
     * cannot repeat this. */
    --role-player: #B23C00;
    --role-host: #0A6B41;
    --role-expert: #6B2FA8;
    --warn: #7A5300;
    --risk: #C2183A;
    --done: #4A574E;
    --qr-quiet: #FFFFFF;
    /* Depth is a screen-only layer (§7.7): a shadow or a gradient is ink a
     * printer lays down for no reader benefit, on top of most printers
     * already defaulting "print backgrounds" off. Belt-and-braces, not
     * redundant — a viewer who has turned that setting ON still gets a plain
     * page. */
    --elev-1: none;
    --elev-2: none;
    --glow-accent: none;
    --glow-halo: none;
    --wash-page: none;
  }

  /* The shell chrome and every interactive control, wherever it appears. A
   * Settings link and a Submit button are instructions for using the SCREEN;
   * on paper they are dead ink, and the footer's position: sticky would
   * otherwise repeat itself at the bottom of every page.
   *
   * .arch-b-field joins them in phase 2.5, and by this rule's own reasoning
   * rather than as a new one: host.gameReview is the §8.4 lanyard sheet AND the
   * screen that mints the experts on it, so its "Expert name" input would print
   * as an empty box with a label — dead ink of exactly the kind named above,
   * and the first time a field has ever shared a page with a Print button.
   * Every field in the client carries this wrapper, and no other printable
   * screen has one: archetype D is the only archetype offering print, and until
   * now no D screen had a field. */
  .shell-head, .shell-foot, .btn, .pill, [role="button"], .skip-link,
  .arch-b-field, .btn-reason {
    display: none !important;
  }

  /* §8.4'S LANYARD SHEET PRINTS WHATEVER THE SCREEN IS SHOWING. The credential
   * wrapper hides expert tokens and team codes on a projector until a host asks
   * for them; paper is the opposite case — the whole reason this screen offers
   * Print is to cut those codes up and hand them out. So the reveal is
   * unconditional here and the mask never prints, which also means the printed
   * sheet does not depend on which way a toggle happened to be left. */
  .credential .credential-value { display: block !important; }
  .credential .credential-mask { display: none !important; }

  /* THE TABLE PRINTS AND THE DIAGRAM DOES NOT — ruling 9's second reason, and
   * it is a measurement rather than a preference: ui/dag-layout.js lays the
   * shipped mode out at 3,224 x 344 px, so on A4 the SVG either overflows the
   * sheet or is scaled to about a fifth and its 21 labels become illegible.
   * The table beside it carries exactly the same information — every activity,
   * what it depends on, what it unlocks — in a shape paper was made for, and
   * it is the one a host marks up. This is also why the table is never hidden
   * on screen: a rendering only paper sees is a rendering nobody maintains. */
  .builder-graph-canvas { display: none; }

  /* host.builder.translations PRINTS ITS TRANSLATOR BRIEF AND NOT ITS TABLE —
   * ruling 10's "printable one-page sheet", and the three selectors below are
   * what make it one page rather than 229 rows of it.
   *
   * .arch-o1-rows is already almost empty on paper by the rules above: every
   * control inside a row is an .arch-b-field or a .btn, and both are hidden. So
   * what would print is 229 position labels ("Row 1 of 229") and 229 keys with
   * no values beside them — dead ink naming controls the reader cannot see,
   * which is the same judgement .arch-b-field itself is hidden under. Hiding
   * the container rather than its leftovers is the honest form of that, and it
   * applies to host.builder's section editor for the same reason.
   *
   * .arch-o1-status is outlier 1's live region and .arch-o1-narrow is its
   * "this screen wants 900 px" notice. Both are instructions for using the
   * SCREEN; a printed page has no live region and no viewport width. */
  .arch-o1-rows:not([data-print="rows"]), .arch-o1-status, .arch-o1-narrow { display: none; }

  /* THE ONE O1 SCREEN WHOSE ROWS ARE THE SHEET — host.invitations, phase 4.
   * The rule above is right for the two phase-3 screens and wrong for this one:
   * its rows carry the personal links, and "a credential is revealed by an act,
   * AND STILL PRINTS" is the settled decision those links are under. A
   * descendant of a display:none ancestor is not in the box tree at all, so
   * `.credential .credential-value` above could not reach past that <ul> — which
   * is why the exemption is here and not a second !important further down.
   * ui/archetypes/o1.js's `printable` prop is what sets the attribute, opt-in,
   * so the builder screens are unchanged.
   *
   * .invitations-link IS WHY LinkCell'S ROOT IS NOT .arch-b-field. Every field
   * wrapper in the client is hidden by the rule at the top of this file, and
   * that judgement is right for an input: an empty box with a label is dead ink.
   * A credential is the opposite — it is the reason the page is being printed —
   * so it carries its own wrapper and prints.
   *
   * The compose form and the action strip DO go, by the rule at the top of this
   * file rather than as a new one: a name field, a kind picker and four buttons
   * are instructions for using the SCREEN. Hiding the containers rather than the
   * empty wrappers their hidden contents leave behind is the same judgement
   * .arch-o1-rows itself is hidden under. */
  .invitations-compose, .arch-o1-actions { display: none; }

  /* THE BRIEF IS THE ONLY THING IN THAT HEADER THE TRANSLATOR IS MEANT TO READ,
   * and fix round 1 (promoted 6) is what made that true rather than nearly
   * true. The sheet was also printing the completeness strip and the noLink
   * note — and that note's words ("Send the CSV file and the brief below") are
   * addressed to the HOST, so the person holding the printed page was being
   * told to send themselves a file. This is the artefact handed to an outside
   * person; it has to read as one.
   *
   * ONE :not() RULE AND NOT A LIST OF SELECTORS, because a list is right only
   * until the next thing is added to that header — which is exactly how the
   * strip and the note came to print in the first place. It says the thing
   * that is actually true: in this header, the brief prints and nothing else
   * does. host.builder's section editor shares the class and LOSES NOTHING
   * READABLE: its three children are the nav, the section pills and the
   * language picker, whose CONTENTS are each already hidden as a .btn, a .pill
   * or an .arch-b-field — so what this rule removes there is the two empty
   * wrapper boxes those leave behind, which is the same leftover judgement
   * .arch-o1-rows is hidden under one rule up. */
  .builder-editor-header > *:not(.builder-brief) { display: none; }

  /* And the sheet itself does not split. Same hint .arch-d-fact takes, for the
   * same reason: a label on one page and its value on the next reads as two
   * different facts, and every row of this brief is a label-plus-value pair. */
  .builder-brief {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* A link's destination is only ever implied by a click, and a click is the
   * one thing paper cannot do. Printing the URL after the link text is what
   * keeps DEPENDENCIES.md's "real selectable text with working links" true
   * once the link is off screen, by making the address itself the text. */
  a[href]::after {
    content: ' (' attr(href) ')';
    font-size: var(--type-meta);
  }

  /* A grouped fact — archetype D's <dl> pair — must not split across a page
   * break: a label on one sheet and its value on the next reads as two
   * different facts. avoid is a hint the printed-page box model offers, not a
   * guarantee, and it is the whole of what that model has to give here. */
  .arch-d-fact {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* host.checkIn's roster prints as one card per student (finding 181): the
   * name, the team code and the personal link must land on one sheet to be cut
   * out and handed over. A hint, like .arch-d-fact's. */
  .arch-o1-row:has(.checkin-link) {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* Finding 282(g): each card carries its own two sentences on paper, where it
   * is cut out and read alone; the screen's once-only legend is not on the sheet.
   * span. for the specificity over base.css's screen rule, without naming either
   * cell class, which test/apps.hostCheckIn.test.mjs keeps out of print rules. */
  span.checkin-card-hint { display: block; }
  .checkin-legend { display: none; }

  /* Paper has no horizontal scroll. On screen outlier 1's rows keep 900 px and
   * scroll inside .arch-o1; an A4 sheet at 16 mm is ~673 px, so the card's QR
   * and link were cut off at the sheet's edge (measured in a PDF). */
  .arch-o1 { overflow-x: visible; }
  .arch-o1 > .arch-o1-rows { min-width: 0; }

  /* One margin, replacing each printer's own default. */
  @page { margin: 16mm; }

  /* host.prep's two printables, on the print-one-section mechanism at the end
   * of this file: a pair per section, written out. A briefing sheet goes to one
   * expert, so each sheet starts its own page. */
  html[data-printing="briefing"] [data-print-only="briefing"],
  html[data-printing="booklet"] [data-print-only="booklet"] { display: block; }
  .prep-sheet + .prep-sheet { break-before: page; page-break-before: always; }
  /* A step or an agenda entry stays with its own text, as .arch-d-fact does. */
  .prep-step, .prep-sheet .arch-activities-card { break-inside: avoid; page-break-inside: avoid; }
  .prep-sheet > h3 { break-after: avoid; page-break-after: avoid; }

  /* Nothing animates on a printed page regardless of prefers-reduced-motion —
   * a printer has no frames to skip, so this is the same INTENT as base.css's
   * reduced-motion block, applied to a medium that block does not reach. */
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ONE SECTION, PRINTED ALONE (phase 5 Task 15). core/print.js's printSection
 * sets <html data-printing="<name>">; everything else the screen renders is
 * dropped and the named [data-print-only] section is revealed. A pair per
 * printable, written out — CSS cannot match the two names to each other. */
@media print {
  html[data-printing] #screen-slot > :not([data-print-only]) { display: none; }
  html[data-printing="certificate"] [data-print-only="certificate"] { display: block; }
}
