/**
 * The print stylesheet — spec §11.6, item D9.7. A MUST, and the whole of the
 * PDF story.
 *
 * There is no PDF rendering library anywhere in this system, by design. The
 * counter receipt, the travelling consignment manifest, the appointment
 * confirmation and the Monday attendance report all reach paper through this
 * file or they do not reach paper at all. The alternative is a parallel
 * component tree for print, and it is worse for one reason that outlives any
 * argument about effort: it can drift from the screen layout, because it is not
 * the screen layout. This cannot.
 *
 * WHY IT LIVES IN public/ AND NOT IN src/styles.
 *
 * §11.6 also asks that routes accept `?print=1` to render the print layout on
 * screen for review. CSS cannot express "apply when printing OR when this
 * attribute is set" — a media query is not a selector and the two cannot be
 * combined — so the usual way to get both is to write the rules twice, once
 * under `@media print` and once under a scope selector. That duplication drifts
 * in the one direction nobody catches: the copy seen only on paper falls behind
 * the copy reviewed on screen, and the difference surfaces on a Monday morning.
 *
 * Served as a file instead, the same bytes do both jobs. The root layout links
 * it with `media="print"` normally and `media="all"` when `?print=1`, so the
 * preview is not a reimplementation of the print layout — it is the print
 * layout, with the condition removed. One file, no second copy to keep in step.
 *
 * The cost is that it is not processed by Tailwind and not fingerprinted. It
 * needs neither: every value below is a literal or a token that tokens.css
 * already defines, and a `media="print"` link is fetched at low priority and
 * blocks nothing.
 *
 * WHAT IS ACTUALLY EXERCISED TODAY, STATED PLAINLY. Nothing in this repository
 * renders a table, a status pill or a report. The three rules §11.6 calls the
 * ones that matter — repeating a table header across pages, keeping a row off a
 * page boundary, and stopping a printer stripping the colour from an
 * attended/no-show pill — therefore have nothing to act on yet. They are
 * written now because they are correct in advance and because D7.2, D7.3 and
 * D8.4 each add markup that needs them already working. But written is not
 * proved: until a screen with a two-hundred-row table exists, nobody has seen
 * these do anything. D9.1's Playwright sweep is what changes that, with
 * `page.emulateMedia({ media: 'print' })`.
 */

/* A4 is the paper in Berlin. The deeper first-page top margin leaves room for a
   letterhead; the wider foot leaves room for the generated-at stamp. */
@page {
  size: A4 portrait;
  margin: 16mm 14mm 18mm;
}

@page :first {
  margin-top: 22mm;
}

/**
 * Force the light token set.
 *
 * Every colour on the site is a `var()` away from these, so this one block
 * turns a dark-theme screen into ink on paper without a single component
 * knowing it is being printed. Without it, a reader who chose the dark theme
 * prints white text on a ground most printers drop — an apparently empty page.
 *
 * `!important` IS LOAD-BEARING HERE AND IS NOT A SHORTCUT. tokens.css sets
 * these same properties under `:root[data-theme="dark"]`,
 * `:root[data-contrast="high"]` and the two combined, every one of which is
 * more specific than the bare `:root` this rule needs to use — the accessibility
 * panel writes those attributes, so on a printed page they would win and the
 * theme would survive onto paper. Raising the specificity by hand would mean
 * naming every present and future combination of those attributes here, and
 * missing one is invisible until somebody prints. Printing overrides theming
 * unconditionally, so it is declared unconditionally.
 */
:root {
  --bg: #fff !important;
  --bg-subtle: #fff !important;
  --bg-raised: #fff !important;
  --fg: #000 !important;
  --fg-muted: #333 !important;
  /* WHITE, not the `#000` the rest of this block is made of, and it was `#000`
     until the pairs were computed. Everything above forces a dark ink because
     its ground is forced to white — but `--primary` and `--accent` below are
     NOT forced to white, they are forced back to the flag's own green and red.
     Black on `--ke-green` is 2.89:1 and on `--ke-red` 2.83:1; white is 6.61:1
     and 6.75:1. The ink was swept to ink-on-paper with everything else while
     its ground stayed coloured, which is the same mistake the dark theme made
     in the other direction — the two are decided together or not at all.

     `button` is hidden further down, so this reaches paper only through the
     anchors styled as buttons: the hero's calls to action and the error
     page's. Those do print. */
  --fg-onPrimary: #fff !important;
  --border: #999 !important;
  --border-strong: #666 !important;
  --shadow-1: none !important;
  --shadow-2: none !important;

  /* The button's two elevations, killed on the same argument and with one
     addition of their own: these are the lift that tells a reader a control
     can be pushed, and nothing on a sheet of paper can be. A `button` is
     hidden further down, so what reaches print is the anchors wearing a rank —
     the hero's calls to action and the error page's — where the cast would
     land as a grey smudge under a box that does nothing. */
  --shadow-button: none !important;
  --shadow-button-hover: none !important;

  /**
   * The accents, back to their light values — and this is the half that is easy
   * to miss, because the page still looks broadly right without it.
   *
   * tokens.css lifts both accents for legibility on a dark ground: the green
   * goes from #006b3f to #2f9f6b and the red from #bb0000 to #ff5a52. Those are
   * correct choices against near-black and poor ones against white paper, where
   * the lifted green drops to roughly 2.5:1 and stops being readable as body
   * text. So a reader who chose the dark theme would print headings and links
   * in colours chosen for a screen they are not using.
   *
   * Written as the flag tokens rather than as hex, because `--ke-green` and
   * `--ke-red` are not themed — they are the flag, and the flag does not change
   * with the time of day. One definition, in tokens.css, still.
   */
  --primary: var(--ke-green) !important;
  --primary-hover: var(--ke-green-deep) !important;
  --primary-tint: var(--ke-green-tint) !important;
  --accent: var(--ke-red) !important;
  --accent-hover: var(--ke-red-deep) !important;
  --danger: var(--ke-red) !important;
  --success: #0e7a4a !important;
  --warning: #b26a00 !important;
  --info: #1b6fe0 !important;
  --focus-ring: #1b6fe0 !important;

  /* The staff console's chrome. The sidebar is a `nav` and is hidden below, but
     the top bar is a `header` and is not — and on a dark theme it would print
     as near-black ink across the top of every sheet, which most printers render
     as a grey smear and some render as a solid block. Forced to ink on white
     for the same reason everything above it is. */
  --admin-shell: #fff !important;
  --admin-shell-raised: #fff !important;
  --admin-shell-active: #fff !important;
  --admin-shell-fg: #000 !important;
  --admin-shell-fg-muted: #333 !important;
  --admin-shell-border: #999 !important;

  /* The emblem's gold. Only the deep value and the tint are themed — the bright
     one is the emblem's own colour and does not change — and the deep value is
     inverted on a dark ground, where it becomes a pale yellow that is close to
     invisible on paper. */
  --ke-gold-deep: #7a6114 !important;
  --ke-gold-tint: #f8f2dd !important;

  /* The appointments chart. Its four series are re-stepped for a dark surface
     and for high contrast, and the dark steps are chosen to sit on #1a1e1c —
     printed on white they are three pale lines and one that reads. Forced back
     to the light set, which was validated against white in the first place.

     They survive greyscale printing on their own, which is the other half of
     why this chart is drawn the way it is: each series also carries a dash
     pattern and a marker shape, and the legend prints its figures. */
  --chart-expected: #006b3f !important;
  --chart-pending: #b87400 !important;
  --chart-completed: #1b6fe0 !important;
  --chart-missed: #bb0000 !important;
}

/* Screen furniture: navigation nobody can follow on paper, controls nobody can
   press, and the accessibility panel, which is fixed to the corner and would
   otherwise print across the content of every single page. */
nav,
aside,
button,
.skip-link,
.no-print,
[data-slot="toolbar"] {
  display: none !important;
}

/* A fixed public masthead would otherwise print on top of every sheet. */
[data-public-chrome] {
  position: static !important;
}

/* No URL noise. A counter manifest with every href spelled out after its link
   is unreadable, and the addresses are of no use to anybody holding paper. */
a[href]::after {
  content: "";
}

/* The rule that makes a 200-row attendance report legible: the header repeats
   at the top of every page, rather than appearing once and leaving pages two
   onward as anonymous columns of times and names. */
thead {
  display: table-header-group;
}

tfoot {
  display: table-footer-group;
}

/* Nothing splits across a page boundary. An appointment row broken in half is
   how somebody at the counter reads the wrong person's time. `li` and `dl` are
   here because that is what the admin renders its rows and detail pairs as
   today, where §11.6's example assumed a table. */
tr,
li,
dl,
.card,
.case-row {
  break-inside: avoid;
}

/* A heading at the foot of a page with its content overleaf reads as an empty
   section followed by an unlabelled one. */
h1,
h2,
h3 {
  break-after: avoid;
}

/* Printers strip background colour by default, which would render the attended
   and no-show pills as identical white boxes — the one distinction the
   attendance report exists to show. */
.status-pill,
[data-print-colour] {
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

/* The mission name and generated-at stamp on every sheet. A page of consular
   records that leaves a printer with nothing saying where it came from or when
   is a page nobody can file. */
.page-footer {
  position: fixed;
  bottom: 0;
}

/* A reading measure is a screen constraint; on A4 the page margin is the
   measure, and a 68ch column inside it wastes a third of the sheet. */
.prose-measure {
  max-width: none;
}

/**
 * The console locks `html`/`body` overflow so the masthead and rail stay
 * put. Paper has to flow, and `?print=1` uses this same file, so the lock
 * is lifted here rather than in a second copy.
 */
html:has([data-admin-shell]),
html:has([data-admin-shell]) body {
  height: auto !important;
  max-height: none !important;
  overflow: visible !important;
}

/**
 * The homepage hero, the quick-action panel, and the later flag-coloured
 * bands sit on Kenyan colours with flag-white or flag-black text. Those
 * tokens are not themed — they are the flag — so the block above that
 * forces `--fg` and `--bg` back to ink on paper does not reach them. A
 * printer that then drops the green, red and black grounds would print
 * the type as white on white.
 *
 * Flattening here, rather than switching the components to themed tokens, is
 * the same decision as the four-band rule: the flag does not change with the
 * reader's theme, and paper is not a place the flag has to appear.
 */
[data-hero],
[data-hero-frame],
[data-quick-actions],
[data-subscribe],
[data-appointments],
[data-home-night],
[data-night-head],
[data-console-head],
[data-announcement-strip],
[data-exception],
[data-footer] {
  background: transparent !important;
  color: #000 !important;
  min-height: 0 !important;
}

/*
 * The dashboard lattice is a screen grain. Paper has none, and the shorthand
 * on the night bands above does not reach `#main`.
 */
[data-dashboard],
#main:has([data-dashboard]) {
  background-image: none !important;
}

/*
 * Both leadership messages reach paper, whichever tab is on screen.
 *
 * The tabs are CSS-only — a radio and a sibling selector — so the panel that
 * is not selected is `display: none`, and print would otherwise drop the
 * Ambassador's message from a page that carries the President's. On screen a
 * reader chose one; on paper nobody is there to choose the other.
 */
[data-leadership] [data-leadership-panel] {
  display: block !important;
}

[data-hero] [aria-hidden="true"],
[data-night-head] [aria-hidden="true"],
[data-console-head] [aria-hidden="true"] {
  display: none !important;
}

[data-hero] h1,
[data-hero] p,
[data-hero] a,
[data-hero] span,
[data-hero] button,
[data-night-head] h1,
[data-night-head] p,
[data-night-head] a,
[data-night-head] span,
[data-console-head] h1,
[data-console-head] p,
[data-console-head] a,
[data-console-head] span,
[data-console-head] button,
[data-quick-actions] a,
[data-quick-actions] span,
[data-quick-actions] p,
[data-quick-actions] li,
[data-subscribe] h2,
[data-subscribe] span,
[data-appointments] h2,
[data-appointments] p,
[data-appointments] a,
[data-appointments] span,
[data-home-night] h2,
[data-home-night] p,
[data-exception] h1,
[data-exception] p,
[data-exception] a,
[data-exception] button,
[data-exception] span,
[data-footer] h2,
[data-footer] p,
[data-footer] a,
[data-footer] span,
[data-footer] li,
[data-announcement-strip] p,
[data-announcement-strip] a,
[data-announcement-strip] strong {
  background: transparent !important;
  color: #000 !important;
}
