/* santa.haus – the Polar post office. Night sky, snow paper, Santa's red, airmail blue ink.
   Handwriting (Caveat) for what a person would write by hand: headings, names, letters. System sans for the rest. */

/* `fallback`: a font ready within 100 ms (preloaded, from the cache) shows at once, without a moment in another font;
   one later than 3 s stays away from this page instead of swapping while it is read. */
@font-face {
  font-family: "Caveat";
  src: url("/fonts/caveat-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-display: fallback;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Caveat";
  src: url("/fonts/caveat-latin-ext.woff2") format("woff2");
  font-weight: 400 700;
  font-display: fallback;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Russian and Ukrainian. */
@font-face {
  font-family: "Caveat";
  src: url("/fonts/caveat-cyrillic.woff2") format("woff2");
  font-weight: 400 700;
  font-display: fallback;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

:root {
  --night: #1d2638;
  --night-up: #273350;
  --sky: #8fc4ee;
  --dawn: #f2b8c6;
  --snow: #f4f8fb;
  --ink: #1d2638;
  --pen: #2b4c8c;
  --red: #c8233b;
  --red-deep: #a51a2f;
  /* The sack's rope, and a gold gift or letter wherever it is. */
  --gold: #e8b64c;
  --gold-deep: #a8761f;
  --muted-night: #aab6cc;
  --muted-paper: #5a6880;
  --line: #d3dde9;
  --hand: "Caveat", "Segoe Print", "Bradley Hand", cursive;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --column: 36rem;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  /* What moves across a picture: away slowly, quickly over, gently down. */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  /* The stripes of an airmail envelope, for border-image. */
  --airmail: repeating-linear-gradient(-45deg, var(--red) 0 12px, var(--snow) 12px 18px, var(--pen) 18px 30px, var(--snow) 30px 36px);
  color-scheme: dark;
}

/* Caveat has no Vietnamese tones (ạ, ế…) and no Japanese, Korean or Chinese: those pages write their headings and
   names in the system's font, not half in one and half in another. */
:root:lang(vi),
:root:lang(ja),
:root:lang(ko),
:root:lang(zh-Hans) {
  --hand: var(--sans);
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  /* The page scrolls but does not zoom: no pinch, no double tap (with the viewport meta and public/app.js). */
  touch-action: pan-x pan-y;
}

body {
  margin: 0;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  background: var(--night);
  color: var(--snow);
  font: 1.0625rem/1.5 var(--sans);
}

h1,
h2 {
  font-family: var(--hand);
  font-weight: 700;
  line-height: 1;
  margin: 0;
  text-wrap: balance;
}

h1 {
  font-size: clamp(3rem, 13vw, 4.75rem);
  letter-spacing: -0.01em;
}

h2 {
  font-size: 2.125rem;
  margin-bottom: 0.5rem;
}

p {
  margin: 0 0 0.75rem;
  text-wrap: pretty;
}

a {
  color: var(--sky);
  text-underline-offset: 0.18em;
}

:focus-visible {
  outline: 3px solid var(--sky);
  outline-offset: 2px;
  border-radius: 6px;
}

/* ---------- top bar ---------- */

.bar {
  position: relative;
  /* Over the hero's copy: the language menu opens onto it. */
  z-index: 3;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: var(--column);
  margin: 0 auto;
  padding: calc(env(safe-area-inset-top) + 0.75rem) max(1.25rem, env(safe-area-inset-right)) 0.75rem max(1.25rem, env(safe-area-inset-left));
}

.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  /* The links after it (your groups, the other language) keep together on the right. */
  margin-right: auto;
  color: var(--snow);
  font-weight: 650;
  letter-spacing: 0.01em;
  text-decoration: none;
}

/* public/logo.png (art/logo.py), 32 × 32 pixels, one per CSS pixel: a screen that enlarges it keeps them square, not blurred. */
.logo img {
  image-rendering: pixelated;
}

.hat-red {
  fill: var(--red);
}

.hat-white {
  fill: var(--snow);
}

.bar-link {
  color: var(--snow);
  font-size: 0.9375rem;
  text-decoration: none;
  padding: 0.5rem 0;
}

/* The language menu (`site::Bar`): its button the globe and the code of this language, 44px to tap; the list under it
   on the right, inside the screen down to 320px. */
.lang-menu {
  position: relative;
}

/* Open, it reaches below the hero, which otherwise hides what overflows it: over the page that follows. */
.hero:has(.lang-menu[open]) {
  z-index: 3;
  overflow: visible;
}

.lang-menu summary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  min-width: 44px;
  min-height: 44px;
  margin-right: -0.5rem;
  padding: 0 0.5rem;
  border-radius: 6px;
  list-style: none;
  white-space: nowrap;
  cursor: pointer;
}

.lang-menu summary::-webkit-details-marker {
  display: none;
}

.lang-menu summary:hover,
.lang-menu[open] summary {
  background: var(--night-up);
}

.globe {
  fill: currentColor;
}

/* All twenty at once: four columns of five. */
.lang-list {
  display: grid;
  grid-template-columns: repeat(4, auto);
  position: absolute;
  top: calc(100% + 0.25rem);
  right: -0.5rem;
  max-width: calc(100vw - 1.5rem);
  margin: 0;
  padding: 0.25rem;
  list-style: none;
  background: var(--night-up);
  border: 1px solid rgb(244 248 251 / 0.18);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.35);
  /* Twenty languages are taller than a short screen: the list ends above its bottom and scrolls inside itself. */
  max-height: calc(100vh - env(safe-area-inset-top) - 5rem);
  max-height: calc(100dvh - env(safe-area-inset-top) - 5rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.lang-list a,
.lang-list [aria-current] {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  /* Every name where the current one's starts, after its ✓. */
  padding: 0 0.75rem 0 2rem;
  border-radius: 6px;
  color: var(--snow);
  font-size: 0.9375rem;
  text-decoration: none;
  white-space: nowrap;
}

.lang-list [aria-current] {
  padding-left: 0.75rem;
  font-weight: 650;
}

.lang-check {
  width: 0.75rem;
  color: var(--gold);
}

.lang-list a:hover,
.lang-list a:focus-visible {
  background: var(--night);
}

/* On a phone two columns, so all of them fit on the screen at once. */
@media (max-width: 40rem) {
  .lang-list {
    grid-template-columns: 1fr 1fr;
    width: min(22rem, calc(100vw - 1.5rem));
  }

  .lang-list a,
  .lang-list [aria-current] {
    padding: 0.25rem 0.5rem 0.25rem 1.75rem;
    white-space: normal;
  }

  .lang-list [aria-current] {
    padding-left: 0.5rem;
  }
}

/* The offer of the page in the browser's language (`lang::hint`), above the bar: snow paper, like the footer. */
.lang-hint {
  position: relative;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.25rem 0.75rem;
  padding: calc(env(safe-area-inset-top) + 0.375rem) max(1.25rem, env(safe-area-inset-right)) 0.375rem max(1.25rem, env(safe-area-inset-left));
  background: var(--snow);
  color: var(--ink);
  font-size: 0.9375rem;
  text-align: center;
}

.lang-hint a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.75rem;
  border-radius: 6px;
  color: var(--pen);
  font-weight: 650;
}

.lang-hint .lang-hint-yes {
  background: var(--red);
  color: var(--snow);
  text-decoration: none;
}

/* Beside the lists: closer together on a phone, so they keep to one line. */
@media (max-width: 420px) {
  .bar {
    gap: 0.625rem;
  }

  .bar-link {
    font-size: 0.875rem;
  }
}

/* ---------- hero ---------- */

.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-bottom: 2.5rem;
  background:
    radial-gradient(ellipse 70% 60% at 85% -10%, rgb(143 196 238 / 0.32), transparent 70%),
    radial-gradient(ellipse 60% 50% at 0% 0%, rgb(242 184 198 / 0.2), transparent 70%),
    var(--night);
}

.hero-copy {
  position: relative;
  z-index: 2;
  max-width: var(--column);
  margin: 0 auto;
  padding: 1.5rem max(1.25rem, env(safe-area-inset-right)) 0 max(1.25rem, env(safe-area-inset-left));
}

.hero-copy h1 {
  margin-bottom: 0.75rem;
}

.lead {
  font-size: 1.125rem;
  color: var(--muted-night);
  max-width: 32rem;
}

/* The days to Christmas under the lead of the home page, a link to the countdown; tall enough for a finger. */
.home-countdown {
  margin-top: 0.5rem;
  font-weight: 700;
}

.home-countdown a {
  display: inline-block;
  padding: 0.5rem 0;
  color: var(--gold);
}

/* The home page: Santa as a black negative against the moon (public/santa.svg), in the room between the bar and the
   words, as big as it lets him. */
.hero-home {
  min-height: min(100svh, 56rem);
  display: flex;
  flex-direction: column;
}

.santa {
  flex: 1 1 0;
  min-height: 15rem;
  width: 100%;
  object-fit: contain;
}

.hero-home .hero-copy {
  margin-top: auto;
  width: 100%;
}

.hero-home h1 {
  font-size: clamp(3.4rem, 15vw, 5.5rem);
}

.hero-home .lead {
  color: #d5deeb;
}

/* The days to Christmas Eve, under Santa: a little sign in pixel art. Its gold frame is four shadows of 4px, which
   leave its corners out as square steps; the present is 9 × 9 pixels, each 2 × 2 CSS pixels. On a phone the words
   wrap inside the sign, and the frame stays inside the column. */
.countdown {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  width: fit-content;
  max-width: calc(100% - 8px);
  margin: 4px 4px 1.25rem;
  padding: 0.375rem 0.75rem 0.5rem;
  background: var(--night-up);
  color: var(--snow);
  font-size: 0.9375rem;
  font-weight: 650;
  line-height: 1.3;
  text-wrap: balance;
  box-shadow:
    0 -4px var(--gold),
    0 4px var(--gold),
    -4px 0 var(--gold),
    4px 0 var(--gold),
    inset 0 -4px rgb(0 0 0 / 0.3);
}

.countdown-gift {
  flex: none;
  shape-rendering: crispEdges;
}

.countdown-box {
  fill: var(--red);
}

.countdown-bow {
  fill: var(--gold);
}

/* Snow (public/pixel-snow.js): one canvas over the whole page, above even the QR code on the full screen. Clicks
   and taps go through it to the page. The two rules of PixelSnow's CSS, its container fixed to the screen: the canvas
   stays as large as the screen however long the page, and the script carries the flakes along when the page scrolls.
   As tall as the screen with the address bar hidden (lvh; vh before it, the same on a phone): the bar hiding and showing
   as a phone scrolls does not resize the canvas, which would clear it and take flakes away or add them. */
.pixel-snow-container {
  position: fixed;
  inset: 0 0 auto;
  height: 100vh;
  height: 100lvh;
  z-index: 2147483647;
  overflow: hidden;
  pointer-events: none;
}

.pixel-snow-canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* ---------- page body ---------- */

.sheet {
  flex: 1;
  width: 100%;
  max-width: var(--column);
  margin: 0 auto;
  padding: 0 max(1rem, env(safe-area-inset-right)) 2rem max(1rem, env(safe-area-inset-left));
  display: flex;
  flex-direction: column;
  gap: 2.25rem;
}

/* The parts of a two-column page (Shell `wide`): on a phone one column, as if they were not there. */
.stack {
  display: flex;
  flex-direction: column;
  gap: 2.25rem;
}

/* On a desktop: wider, with the side (the nice list and what goes with it) on the right of the rest. The second row
   takes only what the side needs beyond the first, so the left column keeps its spacing. */
@media (min-width: 64rem) {
  .wide {
    --column: 68rem;
  }

  .wide .sheet {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 24rem;
    grid-template-rows: auto 1fr;
    align-items: start;
    gap: 2.25rem 3rem;
  }

  .wide .sheet > * {
    grid-column: 1;
  }

  .wide .side {
    grid-column: 2;
    grid-row: 1 / span 2;
  }
}

.block {
  padding: 0 0.25rem;
}

/* A game alone (`games::GamePage` at `{page}/play`): under the bar its name, small, and the way back to its page
   beside it – the screen is the game's. */
.play-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.25rem 1rem;
  padding-top: 0.5rem;
}

.play-head h1 {
  font-size: clamp(2rem, 8vw, 2.75rem);
}

/* What only the printer gets: on a game's page the sheet of the game played alone (`{page}/play`), and there the sheet
   it deals its cards from. */
@media screen {
  .print-only {
    display: none !important;
  }
}

.block > p,
.hint {
  color: var(--muted-night);
}

/* A block of the page's own controls – a heading, a sentence, a field or a button – on a card of its own: on the bare
   night such blocks ran into each other. Blocks with their own paper or picture stay on the night. */
.panel {
  padding: 1.25rem 1.25rem 1.375rem;
  background: var(--night-up);
  border: 1px solid rgb(143 196 238 / 0.22);
  border-radius: 20px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.panel > :last-child {
  margin-bottom: 0;
}

/* Another list, outside this one: framed in the gold of the countdown („start your list today”). */
.panel-gold {
  border: 2px solid var(--gold);
}

.paper {
  color-scheme: light;
  background: var(--snow);
  color: var(--ink);
  border-radius: 20px;
  padding: 1.5rem 1.25rem 1.375rem;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.paper .hint {
  color: var(--muted-paper);
}

.paper a {
  color: var(--pen);
}

.notice {
  margin: 0;
  padding: 0.875rem 1rem;
  border-radius: 12px;
  background: #e3f1fb;
  color: #17365a;
  font-weight: 550;
}

.notice-error {
  background: #fde7ea;
  color: #8a1023;
}

.paper .notice {
  margin-bottom: 1rem;
}

/* ---------- forms ---------- */

.form {
  display: flex;
  flex-direction: column;
  gap: 1.125rem;
}

.field {
  display: grid;
  gap: 0.375rem;
  font-weight: 600;
}

.field > span {
  font-size: 0.9375rem;
}

input:not([type="radio"], [type="checkbox"], [type="file"]),
select,
textarea {
  width: 100%;
  font: 400 1.0625rem/1.4 var(--sans);
  color: var(--ink);
  background: #fff;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  padding: 0.8rem 0.875rem;
  transition: border-color 150ms ease;
}

/* Not on a radio or checkbox: a click there would draw this square around it; Tab still rings it (:focus-visible). */
input:not([type="radio"], [type="checkbox"], [type="file"]):focus,
textarea:focus,
select:focus {
  border-color: var(--pen);
  outline: 3px solid rgb(143 196 238 / 0.7);
  outline-offset: 0;
}

textarea {
  resize: vertical;
  min-height: 6rem;
}

/* iPhone Safari draws a date as its own button, wider than the field, centred, and flat when empty: as a plain field it fits like the others. */
input[type="datetime-local"] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 0;
  min-height: calc(1.4em + 1.6rem + 3px);
}

input[type="datetime-local"]::-webkit-date-and-time-value {
  text-align: left;
}

::placeholder {
  color: #8b97ad;
}

.choices {
  border: 0;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.choices legend {
  font-weight: 650;
  padding: 0;
  margin-bottom: 0.5rem;
}

.choices > .hint {
  margin: 0;
}

/* A card of paper wherever it stands – on a `.paper` or on the night of a `.panel` (bingo online): ink on white. */
.choice {
  color-scheme: light;
  color: var(--ink);
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 0.75rem;
  align-items: start;
  padding: 0.875rem 1rem;
  border: 1.5px solid var(--line);
  border-radius: 14px;
  background: #fff;
  cursor: pointer;
  transition: border-color 150ms ease, background-color 150ms ease;
}

.choice input {
  grid-row: span 2;
  width: 1.25rem;
  height: 1.25rem;
  margin: 0.1rem 0 0;
  accent-color: var(--red);
}

.choice-title {
  font-weight: 650;
}

.choice-hint {
  font-size: 0.9375rem;
  color: var(--muted-paper);
}

.choice:has(input:checked) {
  border-color: var(--red);
  background: #fff5f6;
}

/* The date of a choice shows once the choice that needs it is picked. */
.when {
  display: none;
  margin-top: 0.25rem;
}

.choices:has(input[value="date"][name="draw"]:checked) .when-draw,
.choices:has(input[value="date"][name="reveal"]:checked) .when-reveal,
.choices:has(input[value="number"]:checked) .when-reveal {
  display: grid;
}

@supports not selector(:has(*)) {
  .when {
    display: grid;
  }
}

/* Letters that go to the organizer have no gift sack: its settings hide (without :has they show, and do not count). */
.form:has(input[name="letters"][value="organizer"]:checked) .sack-only {
  display: none;
}

.check {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  font-weight: 500;
}

.check input {
  width: 1.125rem;
  height: 1.125rem;
  accent-color: var(--red);
}

.file {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  font-weight: 500;
}

.file input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.file-button {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0 1rem;
  border: 1.5px dashed var(--pen);
  border-radius: 12px;
  color: var(--pen);
  font-weight: 600;
  cursor: pointer;
}

.file:has(input:focus-visible) .file-button {
  outline: 3px solid var(--sky);
  outline-offset: 2px;
}

.file-name {
  font-size: 0.9375rem;
  color: var(--muted-paper);
  overflow-wrap: anywhere;
}

/* ---------- buttons ---------- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3.25rem;
  padding: 0 1.5rem;
  border: 0;
  border-radius: 14px;
  background: var(--red);
  color: #fff;
  font: 650 1.0625rem/1 var(--sans);
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  transition: transform 120ms var(--ease-out), background-color 150ms ease;
}

.button:active {
  transform: scale(0.97);
}

.button:disabled,
.button[aria-busy="true"] {
  background: #b9c2d0;
  color: #eef2f7;
  cursor: default;
  transform: none;
}

.button-quiet {
  background: transparent;
  color: var(--red);
  box-shadow: inset 0 0 0 1.5px var(--red);
}

.button-small {
  min-height: 2.75rem;
  padding: 0 1rem;
  font-size: 0.9375rem;
  border-radius: 12px;
  flex: none;
}

.button-navy {
  background: var(--pen);
}

.form > .button,
.draw form .button,
.hero-home .button {
  width: 100%;
}

.hero .button {
  margin-top: 0.5rem;
}

/* On the night of the hero, the quiet button is snow. */
.hero .button-quiet {
  color: var(--snow);
  box-shadow: inset 0 0 0 1.5px rgb(244 248 251 / 0.7);
}

.block > .button {
  margin-top: 1rem;
}

/* A smaller way under the button: „Google Calendar” under „Add to calendar”. */
.block > .button + p {
  margin-top: 0.875rem;
}

/* A button only where it works, shown by `public/app.js`: „Turn on notifications”. */
.button[hidden] {
  display: none;
}

@media (hover: hover) {
  .button:hover:not(:disabled) {
    background: var(--red-deep);
  }

  .button-navy:hover:not(:disabled) {
    background: #213b6e;
  }

  .button-quiet:hover:not(:disabled) {
    background: #fff0f2;
  }

  .hero .button-quiet:hover:not(:disabled) {
    background: rgb(244 248 251 / 0.12);
  }

  .choice:hover {
    border-color: #aab6cc;
  }
}

.link-button {
  border: 0;
  background: none;
  color: var(--sky);
  font: inherit;
  font-size: 0.9375rem;
  text-decoration: underline;
  text-underline-offset: 0.18em;
  padding: 0.5rem 0.25rem;
  cursor: pointer;
}

/* Who doesn't draw whom: a pair per line, and the two names to pick side by side. */
.pairs {
  list-style: none;
  padding: 0;
  margin: 0.5rem 0;
}

.pairs li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.pair-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.pair-form select {
  flex: 1 1 8rem;
  width: auto;
  min-width: 0;
}

/* ---------- lists ---------- */

.steps {
  list-style: none;
  counter-reset: step;
  margin: 0.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 1rem;
}

.steps li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 2.25rem 1fr;
  color: var(--muted-night);
}

.steps li::before {
  content: counter(step);
  grid-row: span 2;
  font: 700 2rem/1 var(--hand);
  color: var(--dawn);
}

/* The budgets of the gift ideas page, as links to their sections. */
.budgets ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  font-weight: 650;
}

/* The budget page's table: the occasion, its amount (a link to its gift ideas) and what is good to know. */
.budget-table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 1rem;
}

.budget-table th,
.budget-table td {
  text-align: left;
  vertical-align: top;
  padding: 0.6rem 0.75rem 0.6rem 0;
  border-bottom: 1px solid rgb(244 248 251 / 0.18);
}

.budget-table th[scope="row"],
.budget-table td:nth-child(2) {
  color: var(--snow);
  font-weight: 650;
}

.budget-table td:nth-child(2) {
  white-space: nowrap;
}

.steps strong {
  color: var(--snow);
  font-weight: 650;
}

.mine,
.numbers {
  list-style: none;
  margin: 0;
  padding: 0;
}

.mine {
  display: grid;
  gap: 0.5rem;
}

.mine a {
  display: grid;
  gap: 0.125rem;
  padding: 0.875rem 1rem;
  border-radius: 14px;
  background: var(--night-up);
  color: var(--snow);
  text-decoration: none;
}

.mine-name {
  font: 700 1.625rem/1.1 var(--hand);
}

.mine-meta {
  font-size: 0.9375rem;
  color: var(--muted-night);
}

/* Santa's list of good children: a page of his notebook, held by candy-cane tape. The people of the group by hand,
   numbered in the red margin, one to a line of the paper (every row, wrapped or not, is a whole number of lines);
   what is known about them in tags. */
.nice {
  color-scheme: light;
  --lh: 2.5rem;
  --margin: 2.25rem;
  position: relative;
  padding: 1.5rem 1rem 1rem calc(var(--margin) + 0.75rem);
  background: linear-gradient(to right, transparent var(--margin), rgb(200 35 59 / 0.4) var(--margin) calc(var(--margin) + 1.5px), transparent 0), #fff;
  color: var(--pen);
  border-radius: 4px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
  transform: rotate(0.6deg);
}

/* The candy-cane tape, also on the own letter under the list and on the letters that come to the organizer. */
.nice::before,
.letter-mine::before {
  content: "";
  position: absolute;
  top: -0.7rem;
  left: 50%;
  width: 6.5rem;
  height: 1.4rem;
  translate: -50% 0;
  rotate: -4deg;
  background: repeating-linear-gradient(-45deg, rgb(200 35 59 / 0.85) 0 7px, rgb(255 255 255 / 0.85) 7px 14px);
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.25);
}

/* The title on the left, the letters on the right. */
.nice h2 {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  color: var(--red);
  margin: 0 0 0.5rem;
}

/* How many letters are written, in the blue pen of the names, with an envelope. */
.nice-letters {
  color: var(--pen);
  font-size: 0.8em;
  white-space: nowrap;
}

.nice-letters svg {
  width: 0.9em;
  height: 0.9em;
  margin-right: 0.15em;
  vertical-align: -0.1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linejoin: round;
}

.nice ol {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: child;
}

.nice li {
  counter-increment: child;
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 0.375rem;
}

.nice li::before {
  content: counter(child);
  position: absolute;
  top: 0;
  left: calc(-0.75rem - var(--margin));
  width: var(--margin);
  text-align: center;
  font: 700 1.25rem/var(--lh) var(--hand);
  color: rgb(200 35 59 / 0.75);
}

.person-name {
  margin-right: 0.25rem;
  font: 600 1.75rem/var(--lh) var(--hand);
  overflow-wrap: anywhere;
  min-width: 0;
}

/* Yourself, marked with a highlighter. */
.nice .me .person-name {
  background: linear-gradient(transparent 46%, rgb(255 220 64 / 0.6) 46% 76%, transparent 76%);
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  height: 1.5rem;
  margin-block: calc((var(--lh) - 1.5rem) / 2);
  padding: 0 0.5625rem;
  border-radius: 999px;
  background: #edf2f8;
  color: var(--muted-paper);
  font: 600 0.75rem/1 var(--sans);
  white-space: nowrap;
}

.tag-you {
  background: #fff1a8;
  color: #634c00;
}

.tag-organizer {
  padding-left: 0.375rem;
  background: #fde7ea;
  color: var(--red-deep);
}

/* Santa's hat, its white edged in the red of the text so it shows on the pink. */
.tag-organizer .hat {
  width: 1.125rem;
  height: 1.125rem;
}

.tag-organizer .hat-white {
  fill: #fff;
  stroke: var(--red-deep);
  stroke-width: 1.5;
}

/* Whether they wrote a letter: an envelope in the blue pen, a dashed one in pencil while they have not. */
.nice-letter {
  width: 1.5rem;
  height: 1.5rem;
  fill: #e3f1fb;
  stroke: var(--pen);
  stroke-width: 1.75;
  stroke-linejoin: round;
}

/* 3:1 on the paper, as a drawing that means something must be. */
.nice-letter.none {
  fill: none;
  stroke: #8391a6;
  stroke-dasharray: 2.5 2;
}

.tag-vote {
  background: #e4f3e8;
  color: #1d6236;
}

.nice form {
  margin-left: auto;
}

/* The organizer's reminder to those without a letter, under the names. */
.nice .nice-nudge {
  margin: 0.75rem 0 0;
}

.nice .hint {
  margin: 0.5rem 0 0;
  color: var(--muted-paper);
  font-size: 0.875rem;
}

.nice .link-button {
  padding: 0 0.25rem;
  color: var(--red);
  font: 600 0.8125rem/var(--lh) var(--sans);
}

/* Good deeds on the organizer's list „Only me”: the stars by the name; under it, two lines to note a deed and a line for
   each of the last ones, so the rows stay whole lines of the paper. */
.nice-stars {
  color: var(--gold-deep);
  font: 700 0.875rem/var(--lh) var(--sans);
  white-space: nowrap;
}

.nice .nice-deed-form {
  flex-basis: 100%;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  height: calc(2 * var(--lh));
  margin: 0;
}

.nice-deed-form input[name="note"] {
  flex: 1;
  min-width: 0;
  padding: 0.5rem 0.75rem;
  font-size: 0.9375rem;
}

.nice-deed {
  flex-basis: 100%;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  margin: 0;
  color: var(--muted-paper);
  font: 400 0.875rem/var(--lh) var(--sans);
}

.nice-deed-note {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nice-deed time {
  flex: none;
  font-size: 0.8125rem;
}

/* The child's own stars, in gold over Santa's notes. */
.block > .deeds-count {
  margin: 0.25rem 0 0;
  color: var(--gold);
  font: 700 2rem/1.2 var(--sans);
}

/* A naughty child (public/app.js), without a number: its line opens on the paper, the pen writes the name in from left
   to right, and Santa crosses it out with a stroke of red. Each part waits for the one before; what the rules say is
   how it ends, so without motion it stands crossed out. */
.nice .naughty {
  counter-increment: none;
  height: var(--lh);
  animation: naughty-line 0.5s ease-out backwards;
}

.nice .naughty::before {
  content: none;
}

.naughty .person-name {
  position: relative;
}

.naughty .person-name span {
  animation: naughty-write 1.2s linear 0.5s backwards;
}

.naughty .person-name::after {
  content: "";
  position: absolute;
  left: -0.2em;
  right: -0.2em;
  top: 54%;
  height: 0.09em;
  border-radius: 1em;
  background: var(--red);
  transform-origin: left;
  rotate: -4deg;
  animation: naughty-strike 0.4s ease-in 1.9s backwards;
}

@keyframes naughty-line {
  from {
    height: 0;
  }
}

/* The clip reaches past the letters, so none is cut when it goes. */
@keyframes naughty-write {
  from {
    clip-path: inset(-0.5em 100% -0.5em -0.5em);
  }

  to {
    clip-path: inset(-0.5em);
  }
}

@keyframes naughty-strike {
  from {
    scale: 0 1;
  }
}

.numbers {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: 0.5rem;
}

.numbers li {
  display: flex;
  align-items: baseline;
  gap: 0.625rem;
  padding: 0.625rem 0.875rem;
  border-radius: 12px;
  background: var(--night-up);
  overflow-wrap: anywhere;
}

.number {
  font: 700 1.5rem/1 var(--hand);
  color: var(--dawn);
  flex: none;
}

.copy {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.copy input {
  min-width: 0;
  flex: 1;
  background: var(--night-up) !important;
  color: var(--snow) !important;
  border-color: transparent !important;
  /* Not under 16px: iOS zooms into a smaller field when it is tapped. */
  font-size: 1rem !important;
}

/* The access key: Santa's elf with a key (public/elf.svg) stands on the left. On a phone next to the heading and the
   text, with the link under them across the card; where there is room, next to the whole card. */
.key {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  column-gap: 1rem;
}

.key > * {
  grid-column: 2;
}

.key .elf {
  grid-column: 1;
  grid-row: 1 / span 2;
  align-self: end;
  width: 100%;
  height: auto;
  margin-bottom: 0.25rem;
}

.key .copy {
  grid-column: 1 / -1;
}

@media (min-width: 40rem) {
  .key {
    grid-template-columns: 7rem minmax(0, 1fr);
    column-gap: 1.25rem;
  }

  .key .elf {
    grid-row: 1 / span 3;
    align-self: center;
    margin-bottom: 0;
  }

  .key .copy {
    grid-column: 2;
  }
}

/* ---------- the gift sack ---------- */

/* Drawn in pages.rs (Sack). data-open is how far it is untied, in tenths: style.css turns it into --open (0–1), which
   turns the parts. public/app.js changes it from what this browser saw last to what the page says, so the parts move. */
.sack {
  display: block;
  width: min(100%, 20rem);
  height: auto;
  margin: -0.75rem auto 0.5rem;
  overflow: visible;
  --open: 0;
  --lean: 1;
}

.sack[data-open="1"] { --open: 0.1; }
.sack[data-open="2"] { --open: 0.2; }
.sack[data-open="3"] { --open: 0.3; }
.sack[data-open="4"] { --open: 0.4; }
.sack[data-open="5"] { --open: 0.5; }
.sack[data-open="6"] { --open: 0.6; }
.sack[data-open="7"] { --open: 0.7; }
.sack[data-open="8"] { --open: 0.8; }
.sack[data-open="9"] { --open: 0.9; }
.sack[data-open="10"] { --open: 1; }

.sack-ground {
  fill: rgb(29 38 56 / 0.12);
  transform-origin: 160px 197px;
}

.sack-cloth {
  fill: var(--red);
}

.sack-shade {
  fill: var(--red-deep);
}

/* The moon is on the left: light on the left half, shadow on the right (the same line, mirrored). */
.sack-light {
  fill: none;
  stroke: #e2526a;
  stroke-width: 6;
  stroke-linecap: round;
  opacity: 0.8;
}

.sack-mirror .sack-light {
  stroke: var(--red-deep);
  stroke-width: 9;
  opacity: 0.7;
}

.sack-fold {
  fill: none;
  stroke: var(--red-deep);
  stroke-width: 2;
  stroke-linecap: round;
  opacity: 0.6;
}

.sack-mouth {
  fill: #4a0c18;
}

/* The inside of the back, between the falling top. */
.sack-back {
  fill: #7e1022;
}

.sack-rope {
  fill: none;
  stroke: var(--gold);
  stroke-width: 5;
  stroke-linecap: round;
}

.sack-loops,
.sack-knot {
  fill: var(--gold);
  stroke: var(--gold-deep);
  stroke-width: 1.5;
}

.sack-count {
  font: 700 42px var(--hand);
  fill: var(--snow);
  text-anchor: middle;
}

.sack-string {
  fill: none;
  stroke: var(--pen);
  stroke-width: 1.5;
}

.sack-tag rect {
  fill: #ecd6a8;
  stroke: #c9a96b;
  stroke-width: 1.5;
}

.sack-tag circle {
  fill: var(--snow);
  stroke: #c9a96b;
  stroke-width: 1.5;
}

.sack-tag text {
  fill: var(--pen);
  text-anchor: middle;
}

.sack-day {
  font: 700 30px var(--hand);
}

.sack-month {
  font: 700 16px var(--hand);
}

.sack-time {
  font: 600 11px var(--sans);
}

/* How --open moves the parts: the halves lean out (the neck gets wider), the top falls open, the mouth shows, the
   gifts inside come up, the bow comes undone and its ends hang. Each point is where the part turns, in the sack's
   coordinates (the right half's are mirrored with it). */
.sack-side {
  transform-origin: 160px 194px;
  rotate: calc(var(--open) * -8deg);
}

.sack-flap {
  transform-origin: 143px 96px;
  rotate: calc(var(--open) * -34deg);
  scale: calc(1 + var(--open) * 0.15) calc(1 - var(--open) * 0.3);
}

.sack-back {
  transform-origin: 160px 96px;
  scale: calc(1 + var(--open) * 0.5) calc(1 - var(--open) * 0.35);
}

.sack-mouth {
  transform-origin: 160px 90px;
  scale: var(--open);
}

.sack-inside > g {
  translate: 0 calc((1 - var(--open)) * 36px);
}

.sack-inside > g:nth-child(2) {
  translate: 0 calc((1 - var(--open)) * 42px);
}

.sack-loops {
  transform-origin: 160px 99px;
  scale: calc(1 - var(--open));
}

.sack-end {
  transform-origin: 158px 101px;
  rotate: calc(var(--open) * -16deg);
  scale: 1 calc(1 + var(--open) * 0.4);
}

.sack-end-right {
  transform-origin: 162px 101px;
  rotate: calc(var(--open) * 16deg);
}

.sack-side,
.sack-flap,
.sack-back,
.sack-mouth,
.sack-inside > g,
.sack-loops,
.sack-end {
  transition:
    rotate 1s var(--ease-out),
    scale 1s var(--ease-out),
    translate 1s var(--ease-out);
}

/* Tied, it stirs now and then: the gifts inside. */
.sack-bag {
  transform-origin: 160px 196px;
  animation: sack-stir 6s ease-in-out 1.5s infinite;
}

@keyframes sack-stir {
  0%,
  84%,
  100% {
    rotate: 0deg;
  }

  87% {
    rotate: -2.5deg;
  }

  91% {
    rotate: 2deg;
  }

  95% {
    rotate: -1deg;
  }
}

.gift-box {
  fill: var(--box);
}

.gift-side {
  fill: rgb(0 0 0 / 0.14);
}

.gift-ribbon {
  fill: var(--ribbon);
}

.gift-gold {
  --box: var(--gold);
  --ribbon: var(--red);
}

.gift-green {
  --box: #2f8f5b;
  --ribbon: var(--snow);
}

.gift-sky {
  --box: var(--sky);
  --ribbon: var(--red);
}

.gift-snow {
  --box: var(--snow);
  --ribbon: var(--red);
}

.gift-dawn {
  --box: var(--dawn);
  --ribbon: var(--pen);
}

/* Open, over the envelope: on the night sky, with the gifts that came out lying around it. */
.sack-opened {
  width: min(100%, 22rem);
  margin: 0 auto -1.5rem;
}

.sack-opened .sack-ground {
  fill: rgb(0 0 0 / 0.3);
}

.sack-opened .sack-bag {
  animation: none;
}

/* The gift sack open on its day (GiftSack in pages.rs): on the paper of its card, not over the envelope. */
.draw .sack-opened {
  width: min(100%, 20rem);
  margin: -0.75rem auto 0.5rem;
}

.draw .sack-opened .sack-ground {
  fill: rgb(29 38 56 / 0.12);
}

/* The number of the own parcel, the one to open, when the gift sack opens. */
.gift-number {
  margin: 0;
  color: var(--red);
  font: 700 3.5rem/1.1 var(--hand);
  text-align: center;
}

/* Tied and tapped (public/app.js, .sack-poke), it reacts each time another way (data-poke): it wiggles, squishes, hops
   or leans away from the side tapped (data-side); the bow, tapped, springs and the sack nods. */
.sack-poke[data-poke="shake"] .sack-bag {
  animation: sack-shake 450ms ease-in-out;
}

.sack-poke[data-poke="squish"] .sack-bag {
  animation: sack-squish 600ms ease-out;
}

.sack-poke[data-poke="hop"] .sack-bag {
  animation: sack-hop 750ms ease-in-out;
}

.sack-poke[data-poke="hop"] .sack-ground {
  animation: sack-ground-hop 750ms ease-in-out;
}

.sack-poke[data-poke="lean"] .sack-bag {
  animation: sack-lean 900ms ease-in-out;
}

.sack[data-side="right"] {
  --lean: -1;
}

.sack-poke[data-poke="bow"] .sack-bag {
  animation: sack-nod 600ms ease-in-out;
}

.sack-bow {
  transform-origin: 160px 99px;
}

.sack-poke[data-poke="bow"] .sack-bow {
  animation: sack-bow 600ms ease-out;
}

/* Tapped quickly over and over, it neither zooms the page nor selects its words. */
.sack {
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* Its top can be grabbed and pulled (public/app.js moves .sack-hold): too heavy to lift, it stretches and, pulled
   hard, trembles (.sack-strain). Open, its gifts can be taken out and carried. */
.sack :is(.sack-flap, .sack-back, .sack-mouth, .sack-bow, .sack-side > .sack-rope),
.sack-opened .gift {
  cursor: grab;
}

.sack-held,
.sack-held * {
  cursor: grabbing !important;
}

.sack-strain .sack-bag {
  animation: sack-strain 90ms linear infinite alternate;
}

/* A gift taken out of the open sack (public/app.js): the next one comes up from inside. */
.sack-inside > .sack-refill {
  animation: gift-refill 1.3s var(--ease-out);
}

/* Opened in front of this browser (public/app.js, .sack-spill): it shakes, comes undone, the gifts fly out of it one
   after another (each from the mouth, where it lies: --dx, --dy) and then the letter comes out of the envelope. */
.sack-spill .sack-bag {
  animation: sack-shake 450ms ease-in-out;
}

.sack-spill :is(.sack-side, .sack-flap, .sack-back, .sack-mouth, .sack-inside > g, .sack-loops, .sack-end) {
  transition-delay: 350ms;
}

.sack-spill .sack-spilled > g {
  animation: gift-out 950ms var(--ease-out) backwards;
}

.sack-spilled > g:nth-child(1) { --dx: 88px; --dy: -112px; animation-delay: 700ms; }
.sack-spilled > g:nth-child(2) { --dx: 54px; --dy: -115px; animation-delay: 1050ms; }
.sack-spilled > g:nth-child(3) { --dx: -88px; --dy: -112px; animation-delay: 850ms; }
.sack-spilled > g:nth-child(4) { --dx: -124px; --dy: -115px; animation-delay: 1200ms; }
.sack-spilled > g:nth-child(5) { --dx: -56px; --dy: -116px; animation-delay: 1350ms; }

.sack-spill + .envelope .letter {
  animation-delay: 2.1s;
}

@keyframes sack-shake {
  25% {
    rotate: -4deg;
  }

  50% {
    rotate: 3.5deg;
  }

  75% {
    rotate: -2deg;
  }
}

@keyframes sack-squish {
  20% {
    scale: 1.1 0.86;
  }

  45% {
    scale: 0.95 1.06;
  }

  70% {
    scale: 1.03 0.97;
  }
}

@keyframes sack-hop {
  15% {
    translate: 0 0;
    scale: 1.08 0.9;
  }

  45% {
    translate: 0 -22px;
    scale: 0.95 1.07;
  }

  70% {
    translate: 0 0;
    scale: 1.1 0.88;
  }

  85% {
    scale: 0.98 1.03;
  }
}

@keyframes sack-ground-hop {
  45% {
    scale: 0.75;
    opacity: 0.6;
  }
}

@keyframes sack-lean {
  30% {
    rotate: calc(var(--lean) * 8deg);
  }

  55% {
    rotate: calc(var(--lean) * -3.5deg);
  }

  78% {
    rotate: calc(var(--lean) * 1.5deg);
  }
}

@keyframes sack-nod {
  30% {
    rotate: -1.5deg;
  }

  60% {
    rotate: 1deg;
  }
}

@keyframes sack-bow {
  20% {
    rotate: -16deg;
    scale: 1.15;
  }

  45% {
    rotate: 11deg;
    scale: 0.94;
  }

  70% {
    rotate: -5deg;
    scale: 1.04;
  }
}

@keyframes sack-strain {
  from {
    rotate: -0.8deg;
  }

  to {
    rotate: 0.8deg;
  }
}

@keyframes gift-out {
  from {
    translate: var(--dx) var(--dy);
    scale: 0.4;
    opacity: 0;
  }

  10% {
    opacity: 1;
  }

  45% {
    translate: calc(var(--dx) * 0.55) calc(var(--dy) - 46px);
    scale: 1;
  }

  80% {
    translate: 0 0;
  }

  90% {
    translate: 0 -5px;
  }
}

@keyframes gift-refill {
  from,
  40% {
    translate: 0 48px;
  }
}

/* ---------- the drawn letter, in its envelope ---------- */

.envelope {
  color-scheme: light;
  position: relative;
  margin-top: 1.75rem;
  padding: 4.75rem 1.125rem 1.5rem;
  background: var(--snow);
  color: var(--ink);
  border: 9px solid transparent;
  border-image: var(--airmail) 9;
  box-shadow: 0 24px 48px -26px rgb(0 0 0 / 0.8);
}

.seal {
  position: absolute;
  top: -2.1rem;
  left: 50%;
  display: grid;
  place-items: center;
  width: 3.75rem;
  height: 3.75rem;
  border-radius: 50%;
  translate: -50% 0;
  background: radial-gradient(circle at 35% 30%, #e2526a, var(--red) 45%, var(--red-deep) 75%);
  box-shadow: 0 0 0 4px rgb(165 26 47 / 0.35), 0 6px 14px rgb(0 0 0 / 0.35);
}

.seal .hat {
  width: 2.1rem;
  height: 2.1rem;
}

.seal .hat-red,
.seal .hat-white {
  fill: rgb(255 228 233 / 0.85);
}

.postmark {
  position: absolute;
  top: 0.75rem;
  right: 0.625rem;
  display: grid;
  place-content: center;
  width: 4.75rem;
  height: 4.75rem;
  border-radius: 50%;
  border: 2px solid rgb(43 76 140 / 0.55);
  box-shadow: inset 0 0 0 4px var(--snow), inset 0 0 0 5.5px rgb(43 76 140 / 0.45);
  rotate: -14deg;
  color: rgb(43 76 140 / 0.75);
  font: 700 0.6875rem/1.15 var(--sans);
  text-align: center;
  letter-spacing: 0.02em;
}

/* Under the envelope, close to it: where to look when the letter gives no idea. */
.gift-ideas {
  margin: -1.25rem 0 0;
  text-align: center;
}

.envelope-note {
  margin: 1.25rem 0 0;
  text-align: center;
  color: var(--muted-paper);
  font-size: 0.9375rem;
}

/* Help with what to write, above the sheet of the own letter (before its first save): closed, a line of the night
   page; open, the short questionnaire, a button that puts it into the letter and a link to all the questions. */
.letter-help {
  margin: 0 0 1rem;
  color: var(--muted-night);
}

.letter-help summary {
  width: fit-content;
  padding: 0.5rem 0;
  color: var(--sky);
  font-weight: 650;
  cursor: pointer;
}

.letter-help summary:focus-visible {
  outline: 3px solid rgb(143 196 238 / 0.7);
  outline-offset: 2px;
  border-radius: 4px;
}

.letter-help p {
  margin: 0.25rem 0 0.75rem;
}

.letter-help pre {
  margin: 0 0 1rem;
  padding: 0.75rem 1rem;
  border-left: 3px solid var(--sky);
  font: inherit;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  color: var(--snow);
}

.letter-help .button {
  margin: 0 1rem 0.75rem 0;
}

.letter-help a {
  display: inline-block;
  color: var(--sky);
}

/* Lined writing paper; the handwriting sits on its lines (line-height = line spacing). The drawn letter, Santa's
   list and the own letter being written are all on it. */
.letter,
.nice ol,
.writing,
.writing textarea {
  background-image: repeating-linear-gradient(to bottom, transparent 0 calc(var(--lh) - 1px), #d6e6f5 calc(var(--lh) - 1px) var(--lh));
  background-origin: content-box;
}

/* The own letter being written: the sheet of the drawn letter, not tilted (it is typed in). It already starts, and the
   fields are lines of it, without boxes: the wish goes on from the opening, the link and the photo are sentences. */
.writing {
  color-scheme: light;
  --lh: 2.125rem;
  padding: 0.75rem 1.125rem 1rem;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 0 #e6edf5, 0 14px 30px -18px rgb(29 38 56 / 0.5);
  color: var(--pen);
  font: 600 1.5rem/var(--lh) var(--hand);
}

.writing p {
  margin: 0;
}

.writing > label,
.writing > label span,
.writing-photo > label:first-child {
  display: block;
}

.writing textarea,
.writing input:not([type="file"], [type="checkbox"]) {
  display: block;
  width: 100%;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 2px;
  font: inherit;
  /* What the person writes in red, the printed letter stays in blue pen. */
  color: var(--red);
  caret-color: var(--red);
  background-color: transparent;
}

/* Whole lines, so what comes after stays on the lines of the paper. */
.writing textarea {
  min-height: calc(3 * var(--lh));
  background-attachment: local;
}

@supports (field-sizing: content) {
  .writing textarea {
    field-sizing: content;
    resize: none;
  }
}

.writing input:not([type="file"], [type="checkbox"]) {
  height: var(--lh);
}

.writing textarea:focus,
.writing input:not([type="file"], [type="checkbox"]):focus {
  border: 0;
  outline: 2px dashed rgb(43 76 140 / 0.4);
  outline-offset: 3px;
}

.writing-link {
  display: flex;
  flex-wrap: wrap;
  column-gap: 0.5ch;
}

.writing-link input:not([type]) {
  flex: 1 1 10rem;
  width: auto;
  min-width: 0;
}

/* The photo, clipped to the sheet with a paper clip; before there is one, an empty card to put it on. */
.clip {
  position: relative;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  width: fit-content;
  max-width: 100%;
  cursor: pointer;
}

.clip-wire {
  position: absolute;
  z-index: 1;
  top: -0.125rem;
  left: 1.5rem;
  width: 1rem;
  height: 2.5rem;
  fill: none;
  stroke: #8f9bb0;
  stroke-width: 2.2;
  stroke-linecap: round;
  transform: rotate(-8deg);
}

/* Six lines high, whatever its shape (a white frame around the rest), so the signature stays on a line. */
.clip .letter-photo {
  width: auto;
  height: calc(6 * var(--lh) - 1rem);
  object-fit: contain;
  transform: rotate(1.5deg);
}

.clip .file-button {
  min-width: 12rem;
  min-height: calc(3 * var(--lh) - 1rem);
  margin: 0.5rem 0;
  justify-content: center;
  border-radius: 3px;
  background: rgb(43 76 140 / 0.04);
  font: inherit;
}

.clip .letter-photo + .file-button {
  min-width: 0;
  min-height: var(--lh);
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  text-decoration: underline dashed 1.5px;
  text-underline-offset: 0.2em;
}

/* The photo shows what was chosen; its file name only when it cannot. */
.clip .letter-photo ~ .file-name {
  display: none;
}

.writing .file-name,
.writing .check {
  font: 500 0.9375rem/var(--lh) var(--sans);
}

.writing .check {
  min-height: var(--lh);
  color: var(--ink);
}

.letter {
  --lh: 2.125rem;
  padding: 0.75rem 1.125rem 1rem;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 0 #e6edf5, 0 14px 30px -18px rgb(29 38 56 / 0.5);
  color: var(--pen);
  font: 600 1.625rem/var(--lh) var(--hand);
  transform: rotate(-1deg);
  animation: letter-out 700ms var(--ease-out) 200ms both;
}

.letter p {
  margin: 0;
}

/* The own letter as it was saved: taped under the nice list, lying there already (not coming out of an envelope). So
   are the letters that come to the organizer, one under another. */
.letter-mine {
  position: relative;
  margin-top: 1.25rem;
  animation: none;
}

.letter-gift {
  color: var(--red);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.letter-sign {
  text-align: right;
}

.letter-empty {
  color: var(--muted-paper);
  font-size: 1.5rem;
}

.letter-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--lh);
  font: 600 1rem/1.3 var(--sans);
  color: var(--red) !important;
  overflow-wrap: anywhere;
}

.letter-photo {
  display: block;
  max-width: 100%;
  max-height: 22rem;
  margin: 0.5rem 0;
  border: 6px solid #fff;
  border-radius: 3px;
  box-shadow: 0 6px 16px -6px rgb(29 38 56 / 0.45);
  background: #fff;
}

.letter .letter-photo {
  transform: rotate(1.5deg);
}

/* A Santa and the person they drew write each other (`Talk` in pages.rs): on the lined paper of the letters, by hand,
   one's own in blue pen on the right, the other's in red on the left; who and when in small print above each. */
.talk {
  color-scheme: light;
  --lh: 2.125rem;
  list-style: none;
  margin: 1rem 0;
  padding: 0.75rem 1.125rem 1rem;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 0 #e6edf5, 0 14px 30px -18px rgb(29 38 56 / 0.5);
  font: 600 1.5rem/var(--lh) var(--hand);
}

.talk li {
  max-width: 85%;
}

.talk li + li {
  margin-top: 0.5rem;
}

.talk-mine {
  margin-left: auto;
  text-align: right;
  color: var(--pen);
}

.talk-other {
  color: var(--red);
}

.talk p {
  margin: 0;
}

.talk-who {
  font: 600 0.8125rem/var(--lh) var(--sans);
  color: var(--muted-paper);
}

.talk-who time {
  margin-left: 0.5rem;
  font-weight: 400;
}

.talk-text {
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.talk-form {
  margin-top: 1rem;
  gap: 0.75rem;
}

/* In the hero: the Santa asked, the answer is waited for. */
.asked a {
  color: var(--snow);
  font-weight: 600;
}

@keyframes letter-out {
  from {
    opacity: 0;
    transform: translateY(1.25rem) rotate(-1deg);
  }
}

/* ---------- the invite: the join link as a QR code ---------- */

.qr-card {
  display: grid;
  justify-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0 0.75rem;
}

/* A white stamp in airmail stripes; the code keeps its own white margin, which scanners need. */
.qr {
  display: block;
  width: min(15rem, 72vw);
  height: auto;
  background: #fff;
  border: 9px solid transparent;
  border-image: var(--airmail) 9;
}

.qr-actions {
  display: flex;
  gap: 0.5rem;
}

/* A square button with an icon only; its name is in aria-label. It widens for "Copied" where the phone cannot share. */
.button-icon {
  min-width: 2.75rem;
  padding: 0 0.6875rem;
}

.button-icon svg {
  width: 1.375rem;
  height: 1.375rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The QR code on the full screen (#qr), on snow paper, for another phone to scan. Closed: back to #invite. */
.qr-full {
  display: none;
}

.qr-full:target {
  color-scheme: light;
  position: fixed;
  inset: 0;
  z-index: 10;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 1rem;
  padding: max(1.25rem, env(safe-area-inset-top)) 1.25rem max(1.25rem, env(safe-area-inset-bottom));
  overflow: auto;
  overscroll-behavior: contain;
  background: var(--snow);
  color: var(--ink);
  text-align: center;
}

.qr-full p {
  margin: 0;
  max-width: 22rem;
}

.qr-full .qr {
  width: min(86vw, 58svh);
}

.qr-name {
  font: 700 2.5rem/1 var(--hand);
  color: var(--pen);
  overflow-wrap: anywhere;
}

/* ---------- the examples of the home page: what each choice of the form does ---------- */

/* Where there is room, wider than the column: the choices of a question side by side, the words over them centred. */
.examples {
  display: flex;
  flex-direction: column;
}

.examples h3 {
  margin: 2rem 0 0.875rem;
  font: 700 1.875rem/1.05 var(--hand);
  text-wrap: balance;
}

.examples-row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
}

.examples > .button {
  margin-top: 2.25rem;
}

@media (min-width: 40rem) {
  .examples {
    align-self: center;
    width: min(68rem, 100vw - 3rem);
    text-align: center;
  }

  .examples > p {
    max-width: 32rem;
    margin-inline: auto;
  }

  .example {
    max-width: 22rem;
  }

  .examples > .button {
    align-self: center;
    padding: 0 2.5rem;
  }
}

/* A choice: its scene on a sheet of snow paper, under it its name in the form and what it does. */
.example {
  flex: 1 1 17rem;
  color-scheme: light;
  padding: 0.5rem 0.5rem 1.125rem;
  border-radius: 20px;
  background: var(--snow);
  color: var(--ink);
  text-align: left;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.example h4 {
  margin: 0.75rem 0.625rem 0.25rem;
  font: 700 1.625rem/1.05 var(--hand);
  color: var(--red);
  text-wrap: balance;
}

.example p {
  margin: 0 0.625rem;
  color: var(--muted-paper);
  font-size: 0.9375rem;
}

/* In the new-list form: over the choices of a question, the scene of the picked one, framed like a choice. Picking
   another swaps it, and public/app.js plays the new one once it shows. Without :has none shows: the rule drops.
   No wider than on the home page: drawn for a card, wider it is mostly sky. */
.choices > .scene {
  display: none;
  width: 100%;
  max-width: 24rem;
  margin-inline: auto;
  border: 1.5px solid var(--line);
}

.choices:has(input[name="letters"][value="sack"]:checked) > .scene-draw,
.choices:has(input[name="letters"][value="organizer"]:checked) > .scene-mine,
.choices:has(input[name="draw"][value="organizer"]:checked) > .scene-button,
.choices:has(input[name="draw"][value="vote"]:checked) > .scene-vote,
.choices:has(input[name="draw"][value="date"]:checked) > .scene-date,
.choices:has(input[name="reveal"][value="name"]:checked) > .scene-name,
.choices:has(input[name="reveal"][value="date"]:checked) > .scene-later,
.choices:has(input[name="reveal"][value="number"]:checked) > .scene-number {
  display: block;
}

/* A scene: white paper with the snow it stands on, 320 × 180 like its picture (.scene-art), the sack under the
   picture where its scene has one. Only a picture: it takes no taps. */
.scene {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 14px;
  background: linear-gradient(#fff 83%, #e8f0f8 83%);
  pointer-events: none;
}

.scene-art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.scene .sack {
  position: absolute;
  margin: 0;
}

.scene .sack .sack-ground {
  fill: rgb(29 38 56 / 0.12);
}

/* Where each sack stands, in the units of the picture (left / 320, top / 180, width / 320). */
.scene-button .sack { left: 53.125%; top: 34.11%; width: 45.94%; }
.scene-vote .sack { left: 55%; top: 36.28%; width: 44.06%; }
.scene-date .sack { left: 46.875%; top: 30.56%; width: 49.375%; }
.scene-later .sack { left: 50.625%; top: 32.22%; width: 47.5%; }
.scene-number .sack { left: 53.125%; top: 36.67%; width: 43.75%; }

/* People: a jumper in the colour of their letter, a face, hair or Santa's hat, their name in the blue pen. */
.person-body {
  fill: var(--box);
}

.gift-santa {
  --box: var(--red);
}

.person-face {
  fill: #f3cfb3;
}

.gift-green .person-face {
  fill: #c48a5f;
}

.gift-dawn .person-face {
  fill: #8d5b3e;
}

.person-hair {
  fill: #6b4a33;
}

.gift-gold .person-hair {
  fill: #b5652c;
}

:is(.gift-sky, .gift-dawn) .person-hair {
  fill: #2e2a33;
}

.person-eye {
  fill: var(--ink);
}

.person-smile {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.2;
  stroke-linecap: round;
}

.person-name {
  font: 700 15px var(--hand);
  fill: var(--pen);
  text-anchor: middle;
}

/* Santa's hat on a head: its white edged in red, so it shows on the paper. */
.scene .hat-white {
  fill: #fff;
  stroke: var(--red-deep);
  stroke-width: 1.5;
}

/* A letter to Santa: the opening and the signature in the blue pen, the wish in the writer's red. */
.note-sheet {
  fill: #fff;
  stroke: #dbe5f0;
  filter: drop-shadow(0 3px 4px rgb(29 38 56 / 0.18));
}

.note-lines {
  fill: none;
  stroke: #d6e6f5;
}

.note-hello {
  font: 600 14px var(--hand);
  fill: var(--pen);
}

.note-wish {
  font: 700 19px var(--hand);
  fill: var(--red);
}

.note-sign {
  font: 700 16px var(--hand);
  fill: var(--pen);
  text-anchor: end;
}

.note-name {
  font-size: 20px;
  fill: var(--red);
}

.strike {
  fill: none;
  stroke: var(--red);
  stroke-width: 2;
  stroke-linecap: round;
}

/* The airmail envelope the drawn letter comes out of: red and blue dashes in turn. */
.airmail {
  fill: none;
  stroke-width: 3.5;
  stroke-dasharray: 8 8;
}

.airmail-red {
  fill: var(--snow);
  stroke: var(--red);
}

.airmail-blue {
  stroke: var(--pen);
  stroke-dashoffset: 8;
}

.envelope-flap {
  fill: none;
  stroke: #c6d3e2;
  stroke-width: 1.5;
}

.envelope-seal {
  fill: var(--red);
}

.arrow {
  fill: none;
  stroke: var(--pen);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.arrow path:first-child {
  stroke-dasharray: 5 5;
}

/* The organizer's button and the pointer that presses it. */
.button-art {
  fill: var(--red);
}

.button-art-text {
  font: 650 12.5px var(--sans);
  fill: #fff;
  text-anchor: middle;
}

.pointer {
  fill: #fff;
  stroke: var(--ink);
  stroke-width: 1.3;
  stroke-linejoin: round;
}

/* A vote: a green tick over the head, as on the nice list. */
.vote circle {
  fill: #2f8f5b;
}

.vote path {
  fill: none;
  stroke: #fff;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.vote-count {
  font: 700 18.5px var(--hand);
  fill: var(--snow);
  text-anchor: middle;
}

.calendar {
  fill: #fff;
  stroke: #c9d6e6;
  stroke-width: 1.5;
}

.calendar-top {
  fill: var(--red);
}

.calendar-ring {
  fill: var(--snow);
  stroke: var(--muted-paper);
  stroke-width: 1.5;
}

.calendar-day {
  font: 700 46px var(--hand);
  fill: var(--pen);
  text-anchor: middle;
}

.calendar-time {
  font: 600 11px var(--sans);
  fill: var(--muted-paper);
  text-anchor: middle;
}

/* The two days of a list that hides the names, over their halves. */
.scene-day {
  font: 700 14px var(--hand);
  fill: var(--muted-paper);
  text-anchor: middle;
}

.parcel-label {
  fill: #fff;
  stroke: #c9d6e6;
}

.parcel-number {
  font: 700 15px var(--hand);
  fill: var(--pen);
  text-anchor: middle;
}

.yours {
  font: 600 14px var(--hand);
  fill: var(--muted-paper);
  text-anchor: middle;
}

.yours-number {
  font: 700 28px var(--hand);
  fill: var(--red);
  text-anchor: middle;
}

/* The steps of a scene: public/app.js sets data-step (0, 1, …) once the scene is on the screen, and it stays at the
   last. Without it a scene stands at its last step, so that is what the rules above draw; each rule below takes a
   part back to an earlier step. Moved by transitions from step to step, in the units of the picture. */
.scene :is(.at-1, .at-2, .at-3) {
  transform-box: fill-box;
  transform-origin: center;
  transition:
    opacity 400ms var(--ease-out),
    translate 700ms var(--ease-out),
    scale 500ms var(--ease-out);
}

/* at-N: there from step N on – rising (.rise), growing (.vote) or drawn from the left (.strike). */
.scene[data-step="0"] :is(.at-1, .at-2, .at-3),
.scene[data-step="1"] :is(.at-2, .at-3),
.scene[data-step="2"] .at-3 {
  opacity: 0;
  translate: 0 var(--rise, 0px);
  scale: var(--grow, 1);
}

.rise {
  --rise: 14px;
}

/* The drawn letter comes up out of its envelope. */
.note-rise {
  --rise: 34px;
}

.vote {
  --grow: 0.4;
}

.scene .strike {
  --grow: 0 1;
  transform-origin: left center;
}

/* The draw: the letters go up, change places over the heads and come down, each to someone else. */
.scene .fly {
  transition: translate 900ms var(--ease-in-out);
}

.scene-draw[data-step="0"] :is(.fly-1, .fly-2) { translate: 100px 0; }
.scene-draw[data-step="0"] .fly-3 { translate: -200px 0; }
.scene-draw[data-step="1"] :is(.fly-1, .fly-2) { translate: 100px -44px; }
.scene-draw[data-step="1"] .fly-3 { translate: -200px -64px; }
.scene-draw[data-step="2"] :is(.fly-1, .fly-2) { translate: 0 -44px; }
.scene-draw[data-step="2"] .fly-3 { translate: 0 -64px; }

/* Only me: the children's letters, over their heads, fly to Santa one after another, in an arc. */
.scene-mine .fly-1 { --dx: -172px; --dy: -51px; }
.scene-mine .fly-2 { --dx: -132px; --dy: -45px; }
.scene-mine .fly-3 { --dx: -92px; --dy: -53px; }

.scene-mine[data-step="0"] .fly,
.scene-mine[data-step="1"] :is(.fly-2, .fly-3),
.scene-mine[data-step="2"] .fly-3 {
  translate: var(--dx) var(--dy);
}

.scene-mine[data-step="1"] .fly-1,
.scene-mine[data-step="2"] .fly-2,
.scene-mine[data-step="3"] .fly-3 {
  animation: fly-arc 1s var(--ease-in-out);
}

@keyframes fly-arc {
  from {
    translate: var(--dx) var(--dy);
  }

  50% {
    translate: calc(var(--dx) / 2) calc(var(--dy) / 2 - 44px);
  }
}

/* The button: the pointer comes to it, presses it, and then the sack opens. */
.scene .pointer {
  transform-box: fill-box;
  transform-origin: 0 0;
  transition:
    translate 800ms var(--ease-in-out),
    opacity 300ms var(--ease-out);
}

.scene-button[data-step="0"] .pointer {
  opacity: 0;
  translate: 40px 34px;
}

.scene .press {
  transform-box: fill-box;
  transform-origin: center;
}

.scene-button[data-step="2"] .press {
  animation: button-press 450ms var(--ease-out);
}

.scene-button[data-step="2"] .pointer {
  animation: pointer-press 450ms var(--ease-out);
}

@keyframes button-press {
  35% {
    scale: 0.93;
  }
}

@keyframes pointer-press {
  35% {
    translate: 1px 2px;
    scale: 0.9;
  }
}

/* The votes: the count on the sack goes up, and with each vote the sack unties a little more. */
.scene-vote .vote-count:not(.count-3),
.scene-vote:is([data-step="0"], [data-step="1"], [data-step="2"]) .count-3 {
  opacity: 0;
}

.scene-vote[data-step="0"] .count-0,
.scene-vote[data-step="1"] .count-1,
.scene-vote[data-step="2"] .count-2 {
  opacity: 1;
}

.scene-vote[data-step="1"] .sack { --open: 0.3; }
.scene-vote[data-step="2"] .sack { --open: 0.7; }

/* The chosen day: the calendar turns its days until the day of the tag. */
.calendar-day {
  transition:
    opacity 400ms var(--ease-out),
    translate 500ms var(--ease-out);
}

.scene-date .calendar-day:not(.day-2) {
  opacity: 0;
  translate: 0 -10px;
}

.scene-date[data-step="0"] .day-0,
.scene-date[data-step="1"] .day-1 {
  opacity: 1;
  translate: none;
}

.scene-date[data-step="0"] :is(.day-1, .day-2),
.scene-date[data-step="1"] .day-2 {
  opacity: 0;
  translate: 0 10px;
}

/* The sacks: tied until their step, then they shake, open and let out what is in them. */
:is(.scene-button, .scene-date):is([data-step="0"], [data-step="1"], [data-step="2"]) .sack,
.scene-vote[data-step="0"] .sack,
.scene-later[data-step="0"] .sack,
.scene-number:is([data-step="0"], [data-step="1"]) .sack {
  --open: 0;
}

:is(.scene-button, .scene-vote, .scene-date):is([data-step="0"], [data-step="1"], [data-step="2"]) .sack-spilled,
.scene-later[data-step="0"] .sack-spilled,
.scene-number:is([data-step="0"], [data-step="1"]) .sack-spilled {
  opacity: 0;
}

:is(.scene-button, .scene-vote, .scene-date)[data-step="3"] .sack-bag,
.scene-later[data-step="1"] .sack-bag,
.scene-number[data-step="2"] .sack-bag {
  animation: sack-shake 450ms ease-in-out;
}

/* Longhands: the delay of each comes from .sack-spilled > g:nth-child. */
:is(.scene-button, .scene-vote, .scene-date)[data-step="3"] .sack-spilled > g,
.scene-later:is([data-step="1"], [data-step="2"]) .sack-spilled > g,
.scene-number:is([data-step="2"], [data-step="3"]) .sack-spilled > g {
  animation-name: gift-out;
  animation-duration: 950ms;
  animation-timing-function: var(--ease-out);
  animation-fill-mode: backwards;
}

/* Back to the first step, off the screen: at once. */
.scene-rewind,
.scene-rewind * {
  transition: none !important;
  animation: none !important;
}

/* ---------- footer: the North Pole in pixel art ---------- */

/* At the bottom of the screen also when the page is short (the page of a link that leads nowhere). */
.footer {
  margin-top: auto;
  padding-top: 1rem;
  text-align: center;
}

/* public/north-pole.png (art/north-pole.py), 960 × 160 pixels, each shown as 2 × 2 CSS pixels: square and sharp at
   every width. Its top is the night of the page, its bottom the snow under it. Centred, so a phone sees the pole and
   the workshop; its left and right edges meet, so it repeats on screens wider than 1920px. */
.north-pole {
  height: 320px;
  background: url("/north-pole.png") center bottom / 1920px 320px repeat-x;
  image-rendering: pixelated;
}

/* White space on the snow, and in it the links, the languages, who helps Santa on the internet and, under it,
   MistyLists as on its own pages: the round logo and the name in its ink. */
.footer-snow {
  padding: 2.5rem 1.25rem calc(env(safe-area-inset-bottom) + 3rem);
  background: var(--snow);
  color: var(--muted-paper);
  font-size: 0.9375rem;
}

/* The links in two parts (`site::Footer`), Secret Santa's and the games', each under its heading in the ink of the
   paper; one under the other, centred, as wide as the page's column. */
.footer-part {
  max-width: 64rem;
  margin: 0 auto 1.75rem;
}

.footer-part h2 {
  margin-bottom: 0.625rem;
  color: var(--ink);
  font-size: 1.625rem;
}

/* The pages people search for in the season: small links in a grid of columns, read like an index, not a
   centred wall of words – two on a phone, up to five on a wide screen. */
.footer-links {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: 0 1.5rem;
  margin: 0;
  font-size: 0.875rem;
  text-align: left;
}

.footer-links a {
  display: block;
  padding: 0.1875rem 0;
  overflow-wrap: anywhere;
}

.footer-links a {
  color: inherit;
}

/* Every language in its own name, under the links; this one in ink, not a link. */
.footer-langs {
  margin: 0;
  font-size: 0.875rem;
}

.footer-langs a {
  display: inline-block;
  padding: 0.75rem 0.25rem;
  color: inherit;
}

.footer-langs strong {
  padding: 0 0.25rem;
  color: var(--ink);
}

.mistylists {
  display: flex;
  width: fit-content;
  margin: 0.5rem auto 0;
  align-items: center;
  gap: 0.625rem;
  padding: 0.25rem 0.5rem;
  color: oklch(22% 0.07 280);
  font-size: 1.3125rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  text-decoration: none;
}

.mistylists img {
  border-radius: 50%;
}

.mistylists:focus-visible {
  outline-color: var(--pen);
}

@media (prefers-reduced-motion: reduce) {
  .letter,
  .sack *,
  .naughty,
  .naughty *,
  .naughty *::after {
    animation: none !important;
    transition: none !important;
  }

  .button {
    transition: none;
  }
}

/* ---------- the questions of the home page: one sheet of paper, each question opening to its answer ---------- */

.faq-sheet {
  color-scheme: light;
  margin-top: 0.5rem;
  padding: 0.25rem 1.25rem;
  border-radius: 20px;
  background: var(--snow);
  color: var(--ink);
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.faq details + details {
  border-top: 1.5px solid var(--line);
}

/* The whole question is the button, big enough for a thumb; a red hand-drawn plus turns into a cross when open. */
.faq summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.875rem 0;
  font-weight: 650;
  cursor: pointer;
  list-style: none;
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: "+";
  flex: none;
  font: 700 2rem/0.5 var(--hand);
  color: var(--red);
  transition: rotate 200ms var(--ease-out);
}

.faq details[open] summary::after {
  rotate: 45deg;
}

.faq summary:focus-visible {
  outline: 3px solid rgb(143 196 238 / 0.7);
  outline-offset: 2px;
  border-radius: 4px;
}

.faq details p {
  margin: 0 0 1rem;
  color: var(--muted-paper);
}

@media (prefers-reduced-motion: reduce) {
  .faq summary::after {
    transition: none;
  }
}

/* ---------- the name picker: one phone passed around ---------- */

/* The pairs who do not draw each other, folded under the names. */
.picker-pairs summary {
  font-weight: 600;
  cursor: pointer;
  margin-bottom: 0.5rem;
}

/* The card of one person at a time (`public/app.js`): whose turn it is in big handwriting, then their person. */
.pick-card {
  color-scheme: light;
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  padding: 2rem 1.25rem;
  border-radius: 20px;
  background: var(--snow);
  color: var(--ink);
  text-align: center;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75), inset 0 0 0 4px var(--gold);
}

.pick-card p {
  margin: 0;
}

.pick-to,
.pick-gift {
  color: var(--muted-paper);
  font-weight: 600;
}

.pick-card .pick-name {
  font: 700 clamp(3rem, 16vw, 5rem)/1 var(--hand);
  color: var(--pen);
  overflow-wrap: anywhere;
  margin-bottom: 0.75rem;
}

.pick-child {
  color: var(--red);
}

.pick-done {
  font: 700 2rem/1.1 var(--hand);
  text-wrap: balance;
}

.pick-card .button {
  width: 100%;
  margin-top: 0.5rem;
}

.picker-end form {
  margin-top: 0.75rem;
}

.picker-end .button {
  width: 100%;
}

/* On the night of the page, as in the hero. */
.picker-end .button-quiet {
  color: var(--snow);
  box-shadow: inset 0 0 0 1.5px rgb(244 248 251 / 0.7);
}

/* The order of play of a gift swap (`OrderPage`): one name per line under a big hand-written number. */
.order {
  list-style: none;
  margin: 0 0 1.25rem;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.order li {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px dashed var(--line);
  font-size: 1.25rem;
}

.order-number {
  min-width: 2.5ch;
  font: 700 2.5rem/1 var(--hand);
  color: var(--red);
  text-align: right;
}

/* The die and the timer of the dice game (`DiceTools`, /party/white-elephant/play), side by side where they fit;
   hidden until `app.js` runs. */
.tools {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 1rem;
  margin-top: 1.25rem;
}

.tools[hidden] {
  display: none;
}

.dice,
.timer {
  display: grid;
  justify-items: center;
  align-content: start;
  gap: 0.75rem;
  text-align: center;
}

.dice p,
.timer p {
  margin: 0;
}

/* A die in pixels, as the North Pole: hard edges, the gold of a gift around snow, Santa's red pips. */
.die {
  shape-rendering: crispEdges;
}

.die-edge {
  fill: var(--gold);
}

.die-face {
  fill: var(--snow);
}

.die-pip {
  fill: var(--red);
}

.die.rolling {
  animation: roll 0.4s var(--ease-out);
}

@keyframes roll {
  0% {
    transform: rotate(-25deg) scale(0.85);
  }
  60% {
    transform: rotate(10deg) scale(1.05);
  }
  100% {
    transform: none;
  }
}

.dice-said,
.timer-said {
  min-height: 1.5em;
  font-weight: 600;
}

.timer-time {
  font: 700 3.5rem/1 var(--sans);
  font-variant-numeric: tabular-nums;
}

.timer-buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
}

.timer .button-quiet {
  color: var(--snow);
  box-shadow: inset 0 0 0 1.5px rgb(244 248 251 / 0.7);
}

@media (prefers-reduced-motion: reduce) {
  .die.rolling {
    animation: none;
  }
}

/* The poems of /secret-santa/poems: each on a tag of paper, in handwriting – the name line in the blue pen. The field
   for the name and the copy buttons are shown by app.js. */
.poem-book {
  display: grid;
  gap: 2rem;
}

.poem-name[hidden] {
  display: none;
}

.poems {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 24rem), 1fr));
}

.poem {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0;
  padding: 1rem 1.25rem 1.125rem;
  background: var(--snow);
  color: var(--ink);
  border-radius: 14px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.poem-to {
  margin: 0;
  font: 700 1.25rem/1.2 var(--hand);
  color: var(--pen);
}

.poem-lines {
  flex: 1;
  margin: 0;
  white-space: pre-line;
  font: 600 1.3125rem/1.3 var(--hand);
}

.poem .button {
  align-self: flex-start;
}

/* The invitations of /secret-santa/invitation: on the same paper as the poems, in plain type as they are sent, their
   gaps („[link]”) in the blue pen. The fields and the copy buttons are shown by app.js. */
.invitation-fields {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
}

.invitation-text {
  flex: 1;
  margin: 0;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.invitation-gap {
  font-weight: 700;
  color: var(--pen);
}

/* Under the gift ideas line of the envelope. */
.poems-hint {
  margin: 0.5rem 0 0;
  text-align: center;
}

/* The wishes of /advent-calendar/wishes: the sections in a row of links, then each wish on the same paper as the poems,
   in plain type as it is sent, with its copy button (`Copy`) under it – without the field: the text over it is what
   it copies. */
.wishes-toc ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.wishes {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
}

.wishes-card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0;
  padding: 1rem 1.25rem 1.125rem;
  background: var(--snow);
  color: var(--ink);
  border-radius: 14px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.wishes-text {
  flex: 1;
  margin: 0;
  overflow-wrap: anywhere;
}

.wishes-card .copy {
  margin-top: 0;
}

.wishes-card .copy input {
  display: none;
}

/* The gift tags of /secret-santa/gift-tags: on the screen a sheet of paper with the tags as the printer gives them,
   9 × 5.5 cm each, a hole to thread a ribbon through on the left and a star in the corner, cut along the dashed
   lines. Printed (`@media print`), only the sheet: two tags across, which fit both A4 and US Letter. Over it (and over
   the letter from Santa) the print button, its keys and a line on the paper (`site::PrintBar`). */
.print-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}

.print-bar > .button {
  margin-top: 0;
}

.print-bar > p {
  flex-basis: 100%;
  margin: 0;
}

.gift-tag-sheet {
  color-scheme: light;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  padding: 1rem;
  background: #fff;
  color: var(--ink);
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

@media (min-width: 30rem) {
  .gift-tag-sheet {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.gift-tag {
  position: relative;
  aspect-ratio: 9 / 5.5;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.25rem;
  padding: 0.75rem 2.25rem 0.75rem 2.25rem;
  border: 1px dashed #8b97ad;
  break-inside: avoid;
}

.gift-tag::before {
  content: "";
  position: absolute;
  left: 0.75rem;
  top: 50%;
  width: 0.625rem;
  height: 0.625rem;
  border: 1.5px solid currentColor;
  border-radius: 50%;
  transform: translateY(-50%);
}

.gift-tag-star {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  width: 1.375rem;
  height: 1.375rem;
  fill: none;
  stroke: var(--red);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.gift-tag p {
  margin: 0;
}

.gift-tag-to {
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  font: 700 1.375rem/1.2 var(--hand);
}

.gift-tag-line {
  flex: 1;
  border-bottom: 1.5px solid currentColor;
}

.gift-tag-number {
  font: 700 2.5rem/1 var(--hand);
}

.gift-tag-poem {
  white-space: pre-line;
  font: 600 1rem/1.2 var(--hand);
}

.gift-tag-from {
  font: 600 1rem/1.2 var(--hand);
  color: var(--pen);
}

@page tags {
  margin: 1cm;
}

@media print {
  body:has(.gift-tag-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.gift-tag-sheet) > :not(main),
  body:has(.gift-tag-sheet) main > :not(.gift-tag-sheet) {
    display: none !important;
  }

  body:has(.gift-tag-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .gift-tag-sheet {
    page: tags;
    grid-template-columns: repeat(2, 9cm);
    justify-content: center;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
  }

  .gift-tag {
    width: 9cm;
    height: 5.5cm;
    aspect-ratio: auto;
    padding: 0.4cm 1.1cm;
    border-color: #777;
  }

  .gift-tag::before {
    left: 0.4cm;
    width: 0.35cm;
    height: 0.35cm;
    border-width: 1pt;
  }

  .gift-tag-star {
    top: 0.3cm;
    right: 0.3cm;
    width: 0.7cm;
    height: 0.7cm;
  }

  .gift-tag-to {
    font-size: 17pt;
  }

  .gift-tag-number {
    font-size: 32pt;
  }

  .gift-tag-poem {
    font-size: 11pt;
  }

  .gift-tag-from {
    font-size: 12pt;
  }
}

/* The letters to print (`.letter-sheet`): the letter from Santa of /printables/letter-from-santa and the letter to
   Santa of /printables/letter-to-santa. On the screen a sheet of airmail paper in a hand, its fields lines
   to write on – what is typed shows in blue pen, an example in grey until then. Printed (`@media print`), only the
   sheet, on one page of A4 or US Letter: an empty field a line to write on by hand, its example not at all, the stripes
   and the rules of the lines as on the screen. */
.letter-sheet {
  color-scheme: light;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  padding: 1.5rem 1.25rem 1.25rem;
  background: #fff;
  color: var(--ink);
  border: 9px solid transparent;
  border-image: var(--airmail) 9;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
  font: 500 1.375rem/1.3 var(--hand);
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

.letter-sheet p {
  margin: 0;
}

.letter-line {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.letter-line > span {
  flex: none;
}

.letter-field {
  display: grid;
  margin-bottom: 0.375rem;
}

.letter-sheet input,
.letter-sheet textarea {
  min-width: 0;
  padding: 0 0.25rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--pen);
  font: 600 1.375rem/2rem var(--hand);
}

.letter-sheet input {
  flex: 1;
  border-bottom: 1.5px solid #8b97ad;
}

/* Two ruled lines, and more as the text grows where the browser can (field-sizing). */
.letter-sheet textarea {
  min-height: 4rem;
  height: 4rem;
  resize: none;
  field-sizing: content;
  background: repeating-linear-gradient(transparent 0 calc(2rem - 1.5px), #8b97ad calc(2rem - 1.5px) 2rem);
}

.letter-sheet input:focus,
.letter-sheet textarea:focus {
  border-color: #8b97ad;
  outline: 2px solid rgb(43 76 140 / 0.35);
}

.letter-sheet ::placeholder {
  color: #9aa5b8;
  opacity: 1;
}

.letter-sheet .letter-bye {
  margin-top: 0.5rem;
}

/* The letter from Santa: the place in red on the right, Santa's signature. */
.santa-letter-place {
  align-self: flex-end;
  font-weight: 700;
  font-size: 1.75rem;
  color: var(--red);
}

/* The date under the place, on the right as in a letter. */
.santa-letter-place + .letter-line {
  align-self: flex-end;
  width: min(100%, 16rem);
}

.santa-letter-signature {
  align-self: flex-end;
  padding-right: 1rem;
  font-weight: 700;
  font-size: 2.5rem;
  line-height: 1;
  color: var(--red);
  transform: rotate(-4deg);
}

/* The letter to Santa: „Drogi Mikołaju!” in red, a short field for the age, an empty frame to draw in, the child's
   signature on the right. */
.child-letter-dear {
  font-weight: 700;
  font-size: 1.75rem;
  color: var(--red);
}

.letter-sheet .letter-age {
  flex: 0 1 4.5rem;
  text-align: center;
}

.child-letter-drawing {
  display: flex;
  min-height: 11rem;
  margin: 0.25rem 0;
  padding: 0.5rem 0.75rem;
  border: 2px dashed #8b97ad;
  border-radius: 12px;
}

.child-letter-drawing > p {
  color: #6b778c;
  font-size: 1.125rem;
}

.child-letter-sheet .letter-bye + .letter-line {
  align-self: flex-end;
  width: min(100%, 18rem);
}

@page letter {
  margin: 1.2cm;
}

@media print {
  body:has(.letter-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.letter-sheet) > :not(main),
  body:has(.letter-sheet) main > :not(.letter-sheet) {
    display: none !important;
  }

  body:has(.letter-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .letter-sheet {
    page: letter;
    gap: 0.15cm;
    padding: 0.8cm 1.1cm;
    box-shadow: none;
    font-size: 15pt;
    break-inside: avoid;
  }

  .santa-letter-place,
  .child-letter-dear {
    font-size: 20pt;
  }

  /* The system's font of these pages (no Caveat) is taller and wider at the same size. */
  :root:lang(vi) .letter-sheet,
  :root:lang(ja) .letter-sheet,
  :root:lang(ko) .letter-sheet,
  :root:lang(zh-Hans) .letter-sheet {
    font-size: 13pt;
  }

  .letter-sheet input,
  .letter-sheet textarea {
    font-size: 15pt;
    line-height: 0.9cm;
  }

  /* Two lines, three at most: a longer text is cut rather than pushing the end of the letter onto a second page. */
  .letter-sheet textarea {
    min-height: 1.8cm;
    max-height: 2.7cm;
    height: auto;
    overflow: hidden;
    background: repeating-linear-gradient(transparent 0 calc(0.9cm - 1pt), #777 calc(0.9cm - 1pt) 0.9cm);
  }

  .letter-sheet input {
    border-bottom: 1pt solid #777;
  }

  .letter-sheet ::placeholder {
    color: transparent;
  }

  .santa-letter-signature {
    font-size: 30pt;
  }

  /* The frame a dashed line on paper, as tall as one page leaves it. */
  .child-letter-drawing {
    min-height: 6cm;
    border: 1.5pt dashed #777;
  }

  .child-letter-drawing > p {
    color: #777;
    font-size: 12pt;
  }
}

/* The name slips of /secret-santa/name-slips (`.slip-sheet`): on the screen a sheet of paper with the slips as the
   printer gives them, cut along the dashed lines. Each slip is two halves: a line for the name – what is typed in
   blue pen, „Name” in grey until then – and, past the dotted fold, the cover with a star that lies over the name once
   folded. Printed (`@media print`), only the sheet: three across, six down, on one page of A4 or US Letter; an empty
   field a line to write on by hand, its placeholder not at all. */
.slip-sheet {
  color-scheme: light;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  padding: 1rem;
  background: #fff;
  color: var(--ink);
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

@media (min-width: 30rem) {
  .slip-sheet {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.slip {
  display: grid;
  grid-template-rows: 1fr 1fr;
  aspect-ratio: 6.2 / 4.1;
  border: 1px dashed #8b97ad;
  break-inside: avoid;
}

.slip input {
  align-self: end;
  min-width: 0;
  margin: 0 0.5rem 0.25rem;
  padding: 0 0.125rem;
  width: auto;
  border: 0;
  border-bottom: 1.5px solid #8b97ad;
  border-radius: 0;
  background: transparent;
  color: var(--pen);
  font: 600 1.25rem/1.6rem var(--hand);
  text-align: center;
}

.slip input[type="text"]:focus {
  border-color: #8b97ad;
  outline: 2px solid rgb(43 76 140 / 0.35);
}

.slip input::placeholder {
  color: #9aa5b8;
  opacity: 1;
}

.slip-cover {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  padding: 0.25rem 0.5rem;
  border-top: 1.5px dotted #8b97ad;
  text-align: center;
}

.slip-cover svg {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: var(--red);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.slip-cover p {
  margin: 0;
  font: 600 0.9375rem/1.15 var(--hand);
}

@page slips {
  margin: 1cm;
}

@media print {
  body:has(.slip-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.slip-sheet) > :not(main),
  body:has(.slip-sheet) main > :not(.slip-sheet) {
    display: none !important;
  }

  body:has(.slip-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  /* 3 × 6.2 cm by 6 × 4.1 cm: inside the margins of A4 (19 × 27.7 cm) and of US Letter (19.6 × 25.9 cm). */
  .slip-sheet {
    page: slips;
    grid-template-columns: repeat(3, 6.2cm);
    grid-auto-rows: 4.1cm;
    justify-content: center;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
  }

  .slip {
    aspect-ratio: auto;
    border-color: #777;
  }

  .slip input {
    margin: 0 0.4cm 0.15cm;
    border-bottom: 1pt solid #777;
    font-size: 16pt;
    line-height: 0.9cm;
  }

  .slip input::placeholder {
    color: transparent;
  }

  .slip-cover {
    border-top: 1pt dotted #777;
  }

  .slip-cover svg {
    width: 0.6cm;
    height: 0.6cm;
  }

  .slip-cover p {
    font-size: 11pt;
  }
}

/* The questionnaire of /secret-santa/questionnaire-printable (`.questionnaire-sheet`): over it the two versions, for
   grown-ups and about a child, the one shown filled in red. On the screen a sheet of paper: its title in red, then
   each question in print with a line under it to write on – what is typed in blue pen. Printed (`@media print`), only
   the sheet, on one page of A4 or US Letter even with every field full: an empty field a line to write on by hand, a
   long answer cut in its field rather than pushing the sheet onto a second page. */
.questionnaire-versions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.questionnaire-versions [aria-current] {
  background: var(--red);
  color: #fff;
  box-shadow: none;
}

.questionnaire-sheet {
  color-scheme: light;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.5rem 1.25rem;
  background: #fff;
  color: var(--ink);
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.questionnaire-sheet p {
  margin: 0;
}

.questionnaire-title {
  color: var(--red);
  font: 700 2rem/1.1 var(--hand);
}

.questionnaire-about {
  color: #4a5568;
  font-size: 0.9375rem;
}

.questionnaire-sheet ol {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin: 0;
  padding-left: 2rem;
}

.questionnaire-field {
  display: grid;
  font-size: 0.9375rem;
  line-height: 1.3;
}

.questionnaire-who {
  font-weight: 650;
}

.questionnaire-field input {
  min-width: 0;
  width: 100%;
  padding: 0 0.25rem;
  border: 0;
  border-bottom: 1.5px solid #8b97ad;
  border-radius: 0;
  background: transparent;
  color: var(--pen);
  font: 600 1.375rem/2rem var(--hand);
}

.questionnaire-field input[type="text"]:focus {
  border-color: #8b97ad;
  outline: 2px solid rgb(43 76 140 / 0.35);
}

.questionnaire-field input::placeholder {
  color: #9aa5b8;
  opacity: 1;
}

@page questionnaire {
  margin: 1.2cm;
}

@media print {
  body:has(.questionnaire-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.questionnaire-sheet) > :not(main),
  body:has(.questionnaire-sheet) main > :not(.questionnaire-sheet) {
    display: none !important;
  }

  body:has(.questionnaire-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  /* 13 fields of 1.45 cm and the title: inside the margins of US Letter (25.5 cm), the shorter page. */
  .questionnaire-sheet {
    page: questionnaire;
    gap: 0.2cm;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    break-inside: avoid;
  }

  .questionnaire-title {
    font-size: 24pt;
  }

  .questionnaire-about {
    color: #444;
    font-size: 10.5pt;
  }

  .questionnaire-sheet ol {
    gap: 0.2cm;
    padding-left: 0.9cm;
  }

  .questionnaire-field {
    font-size: 11pt;
  }

  .questionnaire-field input {
    height: 0.9cm;
    border-bottom: 1pt solid #777;
    font-size: 15pt;
    line-height: 0.9cm;
  }

  .questionnaire-field input::placeholder {
    color: transparent;
  }
}

/* ---------- the countdown page: the days left, then the plan, the stage of today open ---------- */

/* The big sign of the day people search for (`Sign` with `big`), a bigger present. */
.countdown-big {
  font-size: clamp(1.25rem, 5vw, 1.75rem);
  line-height: 1.2;
}

/* Each day on its line: its name, then the days left in bold. */
.days-left {
  padding: 0;
  list-style: none;
}

.days-left li {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0 1rem;
  padding: 0.5rem 0;
  border-bottom: 1.5px solid var(--line);
}

/* „Now” next to the stage of today. */
.stage-label {
  margin-left: 0.25rem;
  padding: 0.0625rem 0.5rem;
  border-radius: 999px;
  background: var(--red);
  color: var(--snow);
  font-size: 0.8125rem;
}

/* ---------- Santa tracker (/advent-calendar/santa-tracker) ---------- */

/* What Santa does now, big; under it, after his night, when the next one starts. */
.tracker-said {
  margin: 0 0 1.25rem;
  font-size: clamp(1.25rem, 5vw, 1.75rem);
  line-height: 1.25;
  text-wrap: balance;
}

.tracker-said strong,
.tracker-said span {
  display: block;
}

.tracker-said strong {
  color: var(--snow);
}

.tracker-said span {
  margin-top: 0.375rem;
  color: var(--muted-night);
  font-size: 1rem;
}

/* The map (public/santa-map.png, art/santa-map.py, 240 × 100 pixels) the width of the column, its pixels square and
   sharp, in the gold frame of the countdown sign; on it, in the map's own pixels, the stops and the sleigh
   (public/santa-sleigh.png). The map goes round: the sleigh over its edge is cut there and comes in on the other side. */
.tracker-map {
  display: block;
  width: calc(100% - 8px);
  height: auto;
  margin: 4px;
  overflow: hidden;
  image-rendering: pixelated;
  box-shadow:
    0 -4px var(--gold),
    0 4px var(--gold),
    -4px 0 var(--gold),
    4px 0 var(--gold);
}

.tracker-map image {
  image-rendering: pixelated;
}

/* The stops: pale ahead, gold where Santa has been. */
.tracker-stop {
  fill: #cad8ea;
  shape-rendering: crispEdges;
}

.tracker-stop.tracker-done {
  fill: var(--gold);
}

/* His stop, the next one and the times, each on a card of its own: side by side on a wide screen, one under another
   on a narrow phone. */
.tracker-where {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: 0.75rem;
  margin: 1.5rem 0 0;
}

.tracker-where div {
  padding: 0.625rem 0.875rem 0.75rem;
  background: var(--night-up);
  border-radius: 12px;
}

.tracker-where dt {
  color: var(--muted-night);
  font-size: 0.875rem;
}

.tracker-where dd {
  margin: 0.125rem 0 0;
  color: var(--snow);
  font-size: 1.125rem;
  font-weight: 700;
}

.tracker-note {
  margin: 0.75rem 0 0;
  font-size: 0.875rem;
}

/* The timetable of the night: each stop with its time under it, in two columns down to a phone. A tick in gold before
   the stops Santa has been to. */
.tracker-route {
  columns: 2 9rem;
  column-gap: 1.5rem;
  padding: 0;
  list-style: none;
}

.tracker-route li {
  display: flex;
  flex-direction: column;
  padding: 0.375rem 0;
  border-bottom: 1.5px solid var(--line);
  break-inside: avoid;
}

.tracker-route li span:last-child {
  color: var(--muted-night);
  font-size: 0.875rem;
}

.tracker-route .tracker-done span:first-child::before {
  content: "✓ ";
  color: var(--gold);
  font-weight: 700;
}

/* ---------- elf names (/advent-calendar/elf-name) ---------- */

/* The elf name, big, on a card framed in gold over the form; a long one breaks between its words. */
.elf-result {
  padding: 1.25rem 1.25rem 1.375rem;
  background: var(--night-up);
  border: 2px solid var(--gold);
  border-radius: 20px;
  text-align: center;
}

.elf-result .elf-label {
  margin: 0;
  color: var(--muted-night);
  font-weight: 600;
}

.elf-result .elf-name,
.elf-result .reindeer-name {
  margin: 0.25rem 0 0.75rem;
  font-family: var(--hand);
  font-size: clamp(2.25rem, 10vw, 3.25rem);
  line-height: 1.1;
  color: var(--gold);
  overflow-wrap: anywhere;
}

/* The drawing of a Christmas character (/quiz/which-character) over its name: a coloring page, or the gold star. */
.elf-result .character-picture {
  max-width: 200px;
  margin: 0.75rem auto 0;
}

.character-picture .cp-part {
  cursor: auto;
}

.character-star {
  fill: var(--gold);
  stroke: #000;
  stroke-width: 2.5;
  stroke-linejoin: round;
}

/* The reindeer of /advent-calendar/reindeer-name in pixels, over its name or alone over the form. */
.reindeer-drawing {
  max-width: 160px;
  margin: 0 auto 0.75rem;
}

.reindeer-drawing svg {
  display: block;
  width: 100%;
  height: auto;
}

/* The day and the month side by side where they fit, one under the other on a narrow phone. */
.elf-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 1rem;
}

/* The two tables the name comes from: next to each other where there is room. */
.elf-tables {
  display: grid;
  gap: 1.5rem;
  margin-top: 1rem;
}

@media (min-width: 34rem) {
  .elf-tables {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }
}

.elf-table {
  width: 100%;
  border-collapse: collapse;
}

.elf-table th,
.elf-table td {
  text-align: left;
  vertical-align: top;
  padding: 0.4rem 0.75rem 0.4rem 0;
  border-bottom: 1px solid rgb(244 248 251 / 0.18);
  overflow-wrap: anywhere;
}

.elf-table th[scope="col"] {
  color: var(--muted-night);
  font-weight: 600;
}

.elf-table th[scope="row"],
.elf-table td {
  color: var(--snow);
}

.elf-table th[scope="row"] {
  font-weight: 650;
  white-space: nowrap;
}

/* ---------- advent calendar (/advent-calendar/) ---------- */

/* The calendar made online: over whom it is for, what it is (`.advent-kind`); on its maker's page the doors as fields
   (`.advent-doors`); on the page it opens on, the doors in a grid (`.advent-doors-open`) – each a card of snow paper
   with its day large: an open one opens to what is behind it (a `<details>`, today's open already and framed in
   gold), a closed one says when it opens and nothing more. */
.advent-kind {
  margin: 0 0 0.25rem;
  font-weight: 650;
  letter-spacing: 0.04em;
  color: var(--gold);
}

.advent-doors {
  display: grid;
  gap: 0.75rem;
}

.advent-doors textarea {
  min-height: 3.5rem;
}

.advent-mine {
  margin: 0;
  padding-left: 1.25rem;
}

.advent-doors-open {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

.advent-door {
  min-width: 0;
  min-height: 7rem;
  padding: 0.75rem;
  border: 2px solid transparent;
  border-radius: 14px;
  background: var(--snow);
  color: var(--ink);
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
  overflow-wrap: anywhere;
}

.advent-door summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  cursor: pointer;
  list-style: none;
}

.advent-door summary::-webkit-details-marker {
  display: none;
}

.advent-day {
  font: 700 2.25rem/1 var(--hand);
  color: var(--red);
}

.advent-badge {
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  background: var(--gold);
  color: var(--ink);
  font-size: 0.8125rem;
  font-weight: 700;
}

.advent-today {
  border-color: var(--gold);
}

.advent-text {
  margin: 0.5rem 0 0;
  white-space: pre-line;
}

.advent-text:empty::before {
  content: "★";
  color: var(--gold);
}

.advent-closed {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background: repeating-linear-gradient(-45deg, var(--snow) 0 10px, #e9eef5 10px 20px);
}

.advent-closed .advent-day {
  color: var(--muted-paper);
}

.advent-when {
  font-size: 0.8125rem;
  color: var(--muted-paper);
}

/* The numbers to stick on the bags (`.advent-sheet`): on the screen a sheet of paper with the squares as the printer
   gives them, cut along the dashed lines, each a big number in a hand, red and green by turns, under the gift tags'
   star. Printed (`@media print`), only the sheet: five across of 3.6 cm, 24 or 31 on one page of A4 or US Letter. */
.advent-sheet {
  color-scheme: light;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  padding: 1rem;
  background: #fff;
  color: var(--ink);
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

@media (min-width: 30rem) {
  .advent-sheet {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
}

.advent-number {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border: 1px dashed #8b97ad;
  break-inside: avoid;
  color: var(--red);
}

.advent-number:nth-child(even) {
  color: #1f6b45;
}

.advent-number svg {
  position: absolute;
  top: 0.375rem;
  right: 0.375rem;
  width: 1rem;
  height: 1rem;
  fill: none;
  stroke: var(--gold-deep);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.advent-number span {
  font: 700 clamp(1.75rem, 9vw, 2.75rem)/1 var(--hand);
}

@page advent {
  margin: 1cm;
}

@media print {
  body:has(.advent-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.advent-sheet) > :not(main),
  body:has(.advent-sheet) main > :not(.advent-sheet) {
    display: none !important;
  }

  body:has(.advent-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  /* 5 × 3.6 cm by 7 × 3.6 cm at most: inside the margins of A4 (19 × 27.7 cm) and of US Letter (19.6 × 25.9 cm). */
  .advent-sheet {
    page: advent;
    grid-template-columns: repeat(5, 3.6cm);
    grid-auto-rows: 3.6cm;
    justify-content: center;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
  }

  .advent-number {
    aspect-ratio: auto;
    border-color: #777;
    print-color-adjust: exact;
  }

  .advent-number svg {
    top: 0.25cm;
    right: 0.25cm;
    width: 0.6cm;
    height: 0.6cm;
  }

  .advent-number span {
    font-size: 44pt;
  }
}

/* ---------- elf ideas (/advent-calendar/elf-ideas) ---------- */

/* Today's idea on a card framed in gold, tomorrow's on a plain one: the date small in gold over the scene, what it
   takes under it. */
.elf-idea {
  margin-top: 0.75rem;
}

.elf-idea .elf-date,
.elf-days .elf-date {
  margin: 0 0 0.375rem;
  color: var(--gold);
  font-size: 0.875rem;
  font-weight: 650;
}

.elf-date a {
  color: inherit;
}

.elf-idea h3,
.elf-days h3 {
  margin: 0 0 0.375rem;
  color: var(--snow);
  font-size: 1.1875rem;
  line-height: 1.25;
}

.elf-idea p,
.elf-days p {
  margin-bottom: 0.375rem;
  color: var(--snow);
}

.elf-idea .elf-need,
.elf-days .elf-need {
  margin: 0;
  color: var(--muted-night);
  font-size: 0.9375rem;
}

.elf-need strong {
  font-weight: 650;
}

/* All the days, one under another; today's on the gold of the countdown, its anchor (`#day-5`) clear of the top. */
.elf-days {
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
}

.elf-days li {
  padding: 0.875rem 0;
  border-bottom: 1px solid rgb(244 248 251 / 0.18);
  scroll-margin-top: 1rem;
}

.elf-days .elf-today {
  margin: 0.5rem 0;
  padding: 0.875rem 1rem;
  background: var(--night-up);
  border: 2px solid var(--gold);
  border-radius: 16px;
}

.elf-days .elf-date .stage-label {
  font-weight: 600;
}

/* ---------- Christmas quiz (/quiz/christmas) ---------- */

/* The quizzes played on the page (`quiz::pages::QuizForm`, the Christmas quiz and the emoji quiz): one form, the
   questions numbered across the rounds, each a set of three answers lettered A, B and C, a whole row to tap. Checked
   (`.quiz-score` on top), the right answer of each is green, a wrong one picked red, and the verdict under it says why.
   The sheet to print (`.quiz-sheet`) is not on the screen; printed (`@media print`), it is all there is: the questions
   on one or two pages of A4 or US Letter, then the answer key on a page of its own, for the host to keep apart. */
.quiz {
  display: grid;
  gap: 1.25rem;
  margin: 0;
  padding-left: 1.75rem;
}

.quiz-question::marker {
  font-weight: 700;
  color: var(--gold);
}

.quiz-choice {
  display: grid;
  gap: 0.375rem;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.quiz-ask {
  margin: 0 0 0.375rem;
  padding: 0;
  font-weight: 650;
}

.quiz-ask .emoji-clue {
  font-size: 2.25rem;
}

.quiz-option {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  min-height: 2.75rem;
  padding: 0.375rem 0.75rem;
  border: 2px solid var(--night-up);
  border-radius: 12px;
  background: var(--night-up);
  cursor: pointer;
  overflow-wrap: anywhere;
}

.quiz-option:has(input:checked) {
  border-color: var(--gold);
}

.quiz-option input {
  margin: 0;
  accent-color: var(--gold);
}

.quiz-letter {
  font-weight: 700;
  color: var(--gold);
}

.quiz-option-right {
  border-color: #3f9b62;
  background: #1f4a36;
}

.quiz-option-right:has(input:checked) {
  border-color: #6fd39a;
}

.quiz-option-wrong,
.quiz-option-wrong:has(input:checked) {
  border-color: var(--red);
  background: #4a1f2a;
}

.quiz-verdict {
  margin: 0.5rem 0 0;
  color: var(--muted-night);
  overflow-wrap: anywhere;
}

.quiz-right .quiz-verdict strong {
  color: #6fd39a;
}

.quiz-wrong .quiz-verdict strong,
.quiz-none .quiz-verdict strong {
  color: var(--dawn);
}

.quiz-score {
  text-align: center;
}

.quiz-points {
  margin: 0;
  font: 700 3rem/1.1 var(--hand);
  color: var(--gold);
}

/* The same form played alone (`app.js`, data-quiz): one question at a time under which one of how many and the
   points, the verdict under it in its aria-live line and the button that goes on; at the end the score, each round's,
   and the buttons to share it, play again or pick another quiz. Hidden until `app.js` shows them. */
.quiz-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.25rem 1rem;
  margin-bottom: 1.5rem;
  font-weight: 650;
  color: var(--gold);
}

.quiz-bar[hidden] {
  display: none;
}

.quiz-keys {
  flex-basis: 100%;
  font-weight: 400;
  font-size: 0.875rem;
  color: var(--muted-night);
}

/* No keyboard to speak of on a phone. */
@media (hover: none) {
  .quiz-keys {
    display: none;
  }
}

.quiz-option:has(input:disabled) {
  cursor: default;
}

.quiz-question:focus {
  outline: none;
}

.quiz-step {
  display: grid;
  justify-items: start;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

.quiz-step[hidden] {
  display: none;
}

.quiz-said {
  margin: 0;
  color: var(--muted-night);
  overflow-wrap: anywhere;
}

.quiz-said:empty {
  display: none;
}

.quiz-said-right strong {
  color: #6fd39a;
}

.quiz-said-wrong strong {
  color: var(--dawn);
}

.quiz-end {
  text-align: center;
}

.quiz-end .quiz-total {
  margin: 0;
  font: 700 3.5rem/1.1 var(--hand);
  color: var(--gold);
}

.quiz-end h2:focus {
  outline: none;
}

.quiz-rounds {
  display: grid;
  gap: 0.375rem;
  margin: 1rem auto;
  padding: 0;
  max-width: 26rem;
  list-style: none;
  text-align: left;
}

.quiz-rounds li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0.75rem;
  border-radius: 12px;
  background: var(--night);
}

.quiz-rounds strong {
  color: var(--gold);
  white-space: nowrap;
}

.quiz-end-buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.625rem;
}

.quiz-sheet {
  display: none;
}

@page quiz {
  margin: 1.5cm;
}

@media print {
  body:has(.quiz-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.quiz-sheet) > :not(main),
  body:has(.quiz-sheet) main > :not(.quiz-sheet) {
    display: none !important;
  }

  body:has(.quiz-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .quiz-sheet {
    page: quiz;
    display: block;
    color: #000;
    font: 10.5pt/1.35 var(--sans);
  }

  .quiz-sheet h2 {
    margin: 0 0 0.3cm;
    font-size: 20pt;
    color: #000;
  }

  .quiz-sheet h3 {
    margin: 0.35cm 0 0.15cm;
    font-size: 12pt;
  }

  .quiz-team {
    margin: 0 0 0.2cm;
  }

  .quiz-sheet ol {
    margin: 0;
    padding-left: 0.8cm;
  }

  .quiz-sheet li {
    margin-bottom: 0.15cm;
    break-inside: avoid;
  }

  .quiz-sheet-options {
    display: flex;
    flex-wrap: wrap;
    gap: 0 0.8cm;
  }

  .quiz-key {
    break-before: page;
  }
}

/* ---------- Christmas emoji quiz (/quiz/emoji) ---------- */

/* The emoji quiz is played in the form of the quizzes (`.quiz`, above), its emoji large in the question – one span
   each, drawn with an emoji font, wrapping rather than pushing the page sideways. The sheet to print (`.emoji-sheet`)
   is not on the screen; printed (`@media print`), it is all there is: the 30 puzzles, each with a line to write the
   answer on, on one or two pages of A4 or US Letter, then the answer key on a page of its own. */
.emoji-clue,
.emoji-sheet-clue {
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
}

.emoji-clue {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.375rem;
  margin: 0;
  font-size: 2.25rem;
  line-height: 1.2;
}

.emoji-sheet {
  display: none;
}

@page emoji {
  margin: 1.5cm;
}

@media print {
  body:has(.emoji-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.emoji-sheet) > :not(main),
  body:has(.emoji-sheet) main > :not(.emoji-sheet) {
    display: none !important;
  }

  body:has(.emoji-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .emoji-sheet {
    page: emoji;
    display: block;
    color: #000;
    font: 10.5pt/1.35 var(--sans);
  }

  .emoji-sheet h2 {
    margin: 0 0 0.3cm;
    font-size: 20pt;
    color: #000;
  }

  .emoji-sheet h3 {
    margin: 0.35cm 0 0.15cm;
    font-size: 12pt;
  }

  .emoji-team {
    margin: 0 0 0.2cm;
  }

  .emoji-sheet-list {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .emoji-sheet-list li {
    display: flex;
    counter-increment: list-item;
    align-items: flex-end;
    gap: 0.3cm;
    padding: 0.08cm 0;
    break-inside: avoid;
  }

  .emoji-sheet-list li::before {
    content: counter(list-item) ".";
    min-width: 0.8cm;
    font-weight: 700;
  }

  .emoji-sheet-clue {
    display: flex;
    gap: 0.12cm;
    width: 6.2cm;
    font-size: 18pt;
    line-height: 1.15;
    white-space: nowrap;
  }

  .emoji-line {
    flex: 1;
    border-bottom: 1pt solid #000;
  }

  .emoji-key {
    break-before: page;
  }

  .emoji-key ol {
    columns: 2;
    column-gap: 0.8cm;
    margin: 0;
    padding-left: 0.8cm;
  }

  .emoji-key li {
    margin-bottom: 0.12cm;
    break-inside: avoid;
  }
}

/* ---------- Rooms of the games played live (room.rs) and the live quiz (/quiz/live/{token}, /quiz/play/{code}) ---------- */

/* Joining a room: the code typed in capitals, spaced like the one on the big screen. */
.room-code-field {
  text-transform: uppercase;
  letter-spacing: 0.2em;
  font-weight: 700;
}

.room-code {
  margin: 0 0 1rem;
  font: 800 2.5rem/1 var(--sans);
  letter-spacing: 0.2em;
  text-align: center;
  color: var(--pen);
}

/* The host's screen, on a TV or a screen shared on a video call: wider than a phone's column. Its words in gold or
   large over the muted ones of a block (`.live …`). */
body:has(.live-screen) {
  --column: 64rem;
}

.live {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.live h3 {
  margin: 1.5rem 0 0.5rem;
  font-size: 1.125rem;
}

/* Waiting for the start: how to join, the code large in gold, its QR code, who joined. */
.live-join {
  display: grid;
  justify-items: center;
  gap: 0.75rem;
  text-align: center;
}

.live-join p {
  margin: 0;
}

.live .live-code {
  font: 800 clamp(3rem, 14vw, 7rem)/1 var(--sans);
  letter-spacing: 0.15em;
  color: var(--gold);
}

.live-players {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1.25rem;
  padding: 0;
  list-style: none;
}

.live-players li {
  padding: 0.375rem 0.875rem;
  border-radius: 999px;
  background: var(--night-up);
  font-weight: 650;
  overflow-wrap: anywhere;
}

/* A question: which of how many and the time left over it, the question large, the answers each a colour and a
   letter – red A, blue B, gold C, never the colour alone. Shown, the right one is ringed in green with how many picked
   it, the others fade. */
.live-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem 1rem;
  font-weight: 650;
  color: var(--gold);
}

.live-time {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0;
  color: var(--muted-night);
}

.live-time strong {
  min-width: 2ch;
  font: 800 2.5rem/1 var(--sans);
  color: var(--snow);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.live-ask {
  margin: 0 0 1.25rem;
  font: 650 clamp(1.375rem, 3.2vw, 2.25rem)/1.25 var(--sans);
  overflow-wrap: anywhere;
}

.live-ask .emoji-clue {
  font-size: clamp(2.75rem, 7vw, 4.5rem);
}

.live-answers {
  display: grid;
  gap: 0.75rem;
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}

/* On the host's screen the answers side by side: three of a quiz, two of „Would you rather?”. */
@media (min-width: 48rem) {
  .live-screen .live-answers {
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }
}

.live-answer,
.live-pick {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  border-radius: 16px;
  color: #fff;
  font: 650 1.25rem/1.25 var(--sans);
  overflow-wrap: anywhere;
}

.live-a0 {
  background: var(--red);
}

.live-a1 {
  background: var(--pen);
}

.live-a2 {
  background: var(--gold);
  color: var(--ink);
}

.live-letter {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 10px;
  background: rgb(255 255 255 / 0.92);
  color: var(--ink);
  font: 800 1.375rem/1 var(--sans);
}

.live-text {
  flex: 1;
}

/* A letter alone (the answer a phone sent) in the colour of its answer. */
.live-letter.live-a0,
.live-letter.live-a1 {
  color: #fff;
}

.live-letter.live-a0 {
  background: var(--red);
}

.live-letter.live-a1 {
  background: var(--pen);
}

.live-letter.live-a2 {
  background: var(--gold);
}

.live-count {
  flex: none;
  font: 800 1.75rem/1 var(--sans);
}

.live-reveal .live-answer:not(.live-right) {
  opacity: 0.4;
}

/* A question with no right answer, shown: the share of each answer large over its votes, the minority ringed in gold
   – its letter says it too, in the words under it –, what the room does now, and who picked the minority if the host
   asked. On a phone the player's own pick is ringed in white. */
.live-share {
  display: grid;
  justify-items: end;
  gap: 0.25rem;
  flex: none;
  font-size: 0.875rem;
}

.live-few {
  box-shadow: 0 0 0 4px var(--gold);
}

.live-mine {
  box-shadow: 0 0 0 4px var(--snow);
}

.live-me .live-answers {
  text-align: left;
}

.live-said-pick strong {
  color: var(--snow);
}

.live .live-say {
  font: 650 clamp(1.125rem, 2.4vw, 1.5rem)/1.35 var(--sans);
  color: var(--snow);
}

.live .live-who {
  color: var(--gold);
  font-weight: 650;
  overflow-wrap: anywhere;
}

/* The end of a vote: each question's answers with their shares, one row each. */
.live-results {
  display: grid;
  gap: 0.75rem;
  margin: 0;
  padding-left: 2rem;
}

.live-results li {
  display: grid;
  gap: 0.375rem;
  padding: 0.625rem 0.75rem;
  border-radius: 12px;
  background: var(--night-up);
}

.live-results li::marker {
  font-weight: 700;
  color: var(--gold);
}

.live-result {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  overflow-wrap: anywhere;
}

.live-result .live-letter {
  width: 1.75rem;
  height: 1.75rem;
  font-size: 1rem;
}

.live-result strong {
  flex: none;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}

.live-right {
  box-shadow: 0 0 0 4px #6fd39a;
}

.live-why,
.live-answered {
  color: var(--muted-night);
}

.live-why strong {
  color: #6fd39a;
}

.live-next {
  margin-top: 1rem;
}

.live-end {
  align-self: flex-start;
}

.live-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.625rem;
  margin-top: 1.25rem;
}

/* The ranking: each player under their place, their points on the right. */
.live-ranking {
  display: grid;
  gap: 0.375rem;
  margin: 0;
  padding-left: 2rem;
}

.live-ranking li {
  padding: 0.5rem 0.75rem;
  border-radius: 12px;
  background: var(--night-up);
}

.live-ranking li::marker {
  font-weight: 700;
  color: var(--gold);
}

.live-ranking li > span {
  overflow-wrap: anywhere;
}

.live-ranking strong {
  float: right;
  margin-left: 1rem;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}

/* The podium: the first in the middle and highest, in gold, the second on its left, the third on its right. */
.podium {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: end;
  gap: 0.5rem;
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
  text-align: center;
}

.podium li {
  display: grid;
  align-content: start;
  gap: 0.25rem;
  padding: 1rem 0.5rem;
  border-radius: 14px 14px 0 0;
  background: var(--night-up);
  overflow-wrap: anywhere;
}

.podium-place {
  font: 700 2.5rem/1 var(--hand);
  color: var(--gold);
}

.podium-name {
  font-weight: 700;
}

.podium .podium-1 {
  order: 2;
  min-height: 12rem;
  background: var(--gold);
  color: var(--ink);
}

.podium-1 .podium-place {
  color: var(--ink);
}

.podium-2 {
  order: 1;
  min-height: 9rem;
}

.podium-3 {
  order: 3;
  min-height: 7rem;
}

/* A player's phone: the buttons of the answers big enough for a thumb, one tap sends; then what was sent, right or
   not with its points, the place. */
.live-picks {
  display: grid;
  gap: 0.75rem;
}

.live-pick {
  width: 100%;
  min-height: 4.5rem;
  border: 0;
  text-align: left;
  cursor: pointer;
  transition: transform 120ms var(--ease-out);
}

.live-pick:active {
  transform: scale(0.98);
}

.live-pick:disabled {
  opacity: 0.6;
}

.live-me {
  text-align: center;
}

.live-me .live-buttons {
  justify-content: center;
}

.live .live-sent {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  font-weight: 650;
  color: var(--snow);
}

.live-said {
  font: 700 2.5rem/1.1 var(--hand);
}

.live-said-right strong {
  color: #6fd39a;
}

.live-said-wrong strong {
  color: var(--dawn);
}

.live .live-place {
  margin: 0.5rem 0;
  font: 700 2.25rem/1.1 var(--hand);
  color: var(--gold);
}

/* ---------- Christmas bingo (/bingo/) ---------- */

/* A card (`.bingo-grid`): BINGO over five columns, five rows of words, the free square in the middle. On the screen the
   first card of the set (`.bingo-preview`), on snow paper, as wide as the column – a long word breaks rather than
   pushing the page sideways. The sheet to print (`.bingo-sheet`) is not on the screen; printed (`@media print`), it is
   all there is: two cards a page of A4 or US Letter, each with its number, then the 40 words for the draw on a page of
   their own, in boxes to cut apart. */
.bingo-form {
  margin-bottom: 1rem;
}

.bingo-preview {
  padding: 0.75rem 0.5rem 0.5rem;
  border-radius: 0.5rem;
  background: var(--snow);
  color: var(--ink);
}

.bingo-number {
  margin: 0 0 0.25rem;
  font-size: 0.8125rem;
  text-align: right;
  color: var(--muted-paper);
}

.bingo-grid {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}

.bingo-grid th {
  padding-bottom: 0.25rem;
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--red);
}

.bingo-grid td {
  height: 3.5rem;
  padding: 0.25rem 0.125rem;
  border: 1px solid var(--ink);
  font-size: 0.75rem;
  line-height: 1.2;
  text-align: center;
  vertical-align: middle;
  overflow-wrap: anywhere;
  hyphens: auto;
}

.bingo-grid .bingo-free {
  font-weight: 800;
  color: var(--red);
}

/* The bingo on the phones (`.bingo-play`, shown by public/app.js): a card of its own on snow paper, each square a
   button to tap – marked, it gets a red dab (`aria-pressed`) –, the free one marked from the start; under it the word
   just called, large, and those called before it. */
.bingo-mine td {
  padding: 0;
}

.bingo-mine button {
  width: 100%;
  height: 100%;
  min-height: 3.5rem;
  padding: 0.25rem 0.125rem;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  overflow-wrap: anywhere;
  hyphens: auto;
  cursor: pointer;
  touch-action: manipulation;
}

.bingo-mine button[aria-pressed="true"] {
  background: radial-gradient(circle, rgb(200 35 59 / 0.35) 0 60%, transparent 62%);
  font-weight: 700;
}

.bingo-mine .bingo-free button {
  cursor: default;
  color: var(--red);
  font-weight: 800;
}

.bingo-said,
.bingo-count {
  margin: 0.75rem 0;
  text-align: center;
  font-weight: 650;
}

.bingo-said {
  font: 700 2rem/1.2 var(--hand);
  color: var(--gold);
}

/* Over `.block > p`: the word is gold, not muted. */
.block > .bingo-call {
  margin: 0.5rem 0;
  font: 700 2.25rem/1.2 var(--hand);
  text-align: center;
  color: var(--gold);
  overflow-wrap: anywhere;
}

/* The words called for cards on paper, alone at `/bingo/call`: the last one large, to read from across the room. */
.bingo-play > .bingo-call {
  font-size: clamp(2.5rem, 10vw, 4.5rem);
}

.bingo-buttons {
  text-align: center;
}

.bingo-called {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
  color: var(--muted-night);
}

/* Bingo online (`bingo::live`). The host's screen (`.bingo-live`), on a TV or shared on a video call, under a small head
   of the site. Waiting: how to join, the code and its QR code in a panel, beside it who joined and „Draw the first
   word”. A word drawn: on the stage how many with a bar, the word very large in gold, „Draw a word” (focused: Space or
   Enter draws), the last few drawn before it; beside it who called a true bingo – the first largest –, the QR code and
   the code for whoever comes late; under both the board of the 40 words, the ones drawn lit and the last ringed – not
   by colour alone: drawn is filled, not drawn only outlined. */
body:has(.bingo-live) .hero {
  padding-bottom: 0.75rem;
}

body:has(.bingo-live) .hero-copy {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 1.25rem;
  padding-top: 0.25rem;
}

body:has(.bingo-live) .hero-copy h1 {
  margin: 0;
  font-size: clamp(2.25rem, 4vw, 3.25rem);
}

body:has(.bingo-live) .lead {
  margin: 0;
  max-width: none;
}

.bingo-live {
  gap: 1.5rem;
}

.bingo-live .live-join {
  padding: 1.25rem;
  border-radius: 20px;
  background: var(--night-up);
  border: 1px solid rgb(143 196 238 / 0.22);
}

.bingo-live .live-join p:first-child {
  max-width: 28rem;
  color: var(--muted-night);
}

.bingo-live .qr {
  width: min(13rem, 60vw);
}

.bingo-live .live-players {
  font-size: 1.125rem;
}

.bingo-live .live-next {
  margin: 0 0 1rem;
}

.bingo-draw {
  min-height: 4rem;
  padding: 0 2.25rem;
  font-size: 1.375rem;
  box-shadow: 0 14px 30px -16px rgb(200 35 59 / 0.9);
}

.bingo-host {
  display: grid;
  gap: 1.5rem;
}

.bingo-stage {
  display: grid;
  justify-items: center;
  gap: 0.75rem;
  padding: 1.25rem 1.5rem 1.5rem;
  border-radius: 24px;
  background:
    radial-gradient(ellipse 60% 70% at 50% 45%, rgb(232 182 76 / 0.16), transparent 70%),
    var(--night-up);
  border: 1px solid rgb(232 182 76 / 0.35);
  text-align: center;
}

.bingo-stage .live-bar {
  justify-content: center;
}

/* How many of 40: a bar of gold (`<progress>`, the count in its text where it is not drawn). */
.bingo-progress {
  appearance: none;
  width: min(100%, 24rem);
  height: 0.5rem;
  border: 0;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.12);
  color: var(--gold);
  overflow: hidden;
}

.bingo-progress::-webkit-progress-bar {
  background: rgb(255 255 255 / 0.12);
}

.bingo-progress::-webkit-progress-value {
  border-radius: 999px;
  background: var(--gold);
}

.bingo-progress::-moz-progress-bar {
  border-radius: 999px;
  background: var(--gold);
}

.live .bingo-word {
  max-width: 100%;
  margin: 0;
  font: 700 clamp(3rem, min(7.5vw, 15vh), 8rem)/1.05 var(--hand);
  color: var(--gold);
  text-shadow: 0 0.06em 0.3em rgb(232 182 76 / 0.35);
  overflow-wrap: break-word;
  hyphens: auto;
}

.bingo-host .live-next {
  margin: 0.25rem 0 0;
}

.bingo-before {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
}

.bingo-before h2 {
  margin: 0;
  font: 650 0.9375rem/1.4 var(--sans);
  color: var(--muted-night);
}

.bingo-before:has(ol:empty) {
  display: none;
}

/* Before the last, only the four last ones: the board shows them all. */
.bingo-before li:nth-child(n + 5) {
  display: none;
}

.bingo-side {
  display: grid;
  align-content: start;
  gap: 1rem;
}

.bingo-won {
  padding: 1rem 1.25rem;
  border-radius: 20px;
  background: rgb(111 211 154 / 0.12);
  border: 2px solid #6fd39a;
}

.bingo-won h2 {
  color: #6fd39a;
}

.bingo-late {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.bingo-late .qr {
  width: 7.5rem;
  flex: none;
}

.bingo-join {
  margin: 0;
  color: var(--muted-night);
  font-weight: 650;
}

.bingo-join strong {
  display: block;
  font: 800 clamp(2rem, 4vw, 3rem)/1 var(--sans);
  letter-spacing: 0.15em;
  color: var(--gold);
}

.bingo-side > p {
  margin: 0;
  font-size: 0.9375rem;
}

/* The 40 words: eight in a row on a TV, fewer on a phone. */
.bingo-board {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(9rem, 40%), 1fr));
  gap: 0.375rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.bingo-board li {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem;
  padding: 0.25rem 0.5rem;
  border: 1px dashed rgb(170 182 204 / 0.35);
  border-radius: 10px;
  color: rgb(170 182 204 / 0.75);
  font-size: 0.9375rem;
  line-height: 1.15;
  text-align: center;
  overflow-wrap: anywhere;
  hyphens: auto;
}

.bingo-board .bingo-drawn {
  border: 1px solid var(--gold);
  background: rgb(232 182 76 / 0.2);
  color: var(--snow);
  font-weight: 700;
}

.bingo-board .bingo-last {
  background: var(--gold);
  color: var(--ink);
  box-shadow: 0 0 0 3px var(--night), 0 0 0 5px var(--gold);
}

.bingo-winners {
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding-left: 2rem;
}

.bingo-winners li::marker {
  font-weight: 700;
  color: var(--gold);
}

.bingo-winners strong {
  margin-right: 0.75rem;
  overflow-wrap: anywhere;
}

.bingo-winners span {
  color: var(--muted-night);
}

.bingo-winners li:first-child strong {
  font: 700 clamp(2rem, 5vw, 3.5rem)/1.1 var(--hand);
  color: var(--gold);
}

.bingo-over h2 {
  font-size: clamp(2.5rem, 6vw, 4rem);
}

.bingo-over .live-buttons {
  justify-content: center;
}

@media (min-width: 52rem) {
  .bingo-live:has(.live-join) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;
    gap: 1.5rem 2.5rem;
  }

  .bingo-live .live-end {
    grid-column: 1 / -1;
  }

  .bingo-host {
    grid-template-columns: minmax(0, 1.7fr) minmax(15rem, 1fr);
    align-items: stretch;
  }

  .bingo-board {
    grid-template-columns: repeat(8, minmax(0, 1fr));
  }
}

/* A player's phone (`.bingo-screen`): one screen of the phone, nothing to scroll – on top the name and what wins, the
   word just drawn, the card filling what is left, and „Bingo!” (or what the server said of it) at the bottom, where
   the thumb is. The squares of the card share the height left (a grid, the rows of the table laid out in it); the
   page neither scrolls nor zooms, and taps that follow fast stay taps (`manipulation`). Landscape: the card on the
   right. */
body:has(.bingo-screen) {
  height: 100svh;
  height: 100dvh;
  min-height: 0;
  overflow: hidden;
  overscroll-behavior: none;
}

.live.bingo-screen {
  flex: 1;
  min-height: 0;
  width: 100%;
  max-width: 30rem;
  margin: 0 auto;
  padding: max(0.625rem, env(safe-area-inset-top)) max(0.75rem, env(safe-area-inset-right)) max(0.75rem, env(safe-area-inset-bottom)) max(0.75rem, env(safe-area-inset-left));
  gap: 0.5rem;
  touch-action: manipulation;
}

.bingo-top {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.75rem;
}

.bingo-top h1 {
  min-width: 0;
  max-width: 100%;
  font-size: 2rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bingo-top p {
  margin: 0;
  font-size: 0.875rem;
  color: var(--muted-night);
}

.bingo-now {
  display: grid;
  justify-items: center;
  text-align: center;
}

.bingo-now p {
  margin: 0;
}

.bingo-now > p:first-child {
  font-size: 0.875rem;
  font-weight: 650;
  color: var(--gold);
}

.bingo-screen .bingo-call {
  font: 700 clamp(1.75rem, 6dvh, 2.75rem)/1.1 var(--hand);
  color: var(--gold);
  overflow-wrap: anywhere;
}

.bingo-screen .live-sent {
  margin-top: 0.25rem;
}

.bingo-hint {
  font-size: 0.875rem;
  color: var(--muted-night);
}

.bingo-screen .bingo-preview {
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 0.25rem 0.375rem 0.375rem;
}

.bingo-screen .bingo-number {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.2;
}

.bingo-screen .bingo-mine {
  flex: 1 1 0;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  grid-template-rows: auto repeat(5, minmax(0, 1fr));
}

.bingo-screen .bingo-mine :is(thead, tbody, tr) {
  display: contents;
}

.bingo-screen .bingo-mine th {
  padding: 0 0 0.125rem;
  font-size: clamp(1.125rem, 3.5dvh, 1.5rem);
  line-height: 1.1;
}

.bingo-screen .bingo-mine td {
  height: auto;
  min-height: 0;
  border: 0;
  border-right: 1px solid var(--ink);
  border-bottom: 1px solid var(--ink);
  overflow: hidden;
}

.bingo-screen .bingo-mine td:first-child {
  border-left: 1px solid var(--ink);
}

.bingo-screen .bingo-mine tr:first-child td {
  border-top: 1px solid var(--ink);
}

.bingo-screen .bingo-mine button {
  min-height: 0;
  font-size: clamp(0.6875rem, min(3.4vw, 2.1dvh), 1rem);
  line-height: 1.15;
}

.bingo-shout {
  width: 100%;
  min-height: 3.75rem;
  font-size: 1.75rem;
}

.bingo-screen .live-me {
  display: grid;
  align-content: center;
  min-height: 3.75rem;
  padding: 0.375rem 0.75rem;
  border-radius: 14px;
  background: var(--night-up);
}

.bingo-screen .live-me p {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.3;
}

.bingo-screen .live-me .live-said {
  font: 700 1.75rem/1.1 var(--hand);
}

.bingo-screen .bingo-over {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 1.25rem;
}

.bingo-screen .bingo-over h2 {
  font-size: 2.5rem;
}

.live-me .bingo-winners {
  padding-left: 0;
  list-style-position: inside;
}

.bingo-screen .live-buttons {
  justify-content: center;
}

@media (orientation: landscape) and (max-height: 32rem) {
  .live.bingo-screen {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    grid-template-rows: auto auto 1fr auto;
    max-width: 56rem;
    column-gap: 1rem;
  }

  .bingo-screen > * {
    grid-column: 1;
  }

  .bingo-screen > .bingo-preview {
    grid-column: 2;
    grid-row: 1 / -1;
  }

  .bingo-screen > .bingo-claim,
  .bingo-screen > .live-me {
    grid-row: 4;
  }
}

.bingo-sheet {
  display: none;
}

@page bingo {
  margin: 1cm;
}

@media print {
  html:has(.bingo-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.bingo-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.bingo-sheet) > :not(main),
  body:has(.bingo-sheet) main > :not(.bingo-sheet) {
    display: none !important;
  }

  body:has(.bingo-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .bingo-sheet {
    page: bingo;
    display: block;
    color: #000;
    font: 11pt/1.2 var(--sans);
  }

  /* Two to a page: 2 × 12.4 cm and the gap between fit the 25.9 cm of Letter and the 27.7 cm of A4 inside the margins;
     the third, fifth… card starts a page. */
  .bingo-card {
    height: 12.4cm;
    break-inside: avoid;
  }

  .bingo-card:nth-child(even) {
    margin-top: 0.6cm;
  }

  .bingo-card:nth-child(odd):not(:first-child) {
    break-before: page;
  }

  .bingo-sheet .bingo-number {
    margin: 0 0 0.1cm;
    font-size: 10pt;
    color: #000;
  }

  .bingo-sheet .bingo-grid {
    height: 11.6cm;
  }

  .bingo-sheet .bingo-grid th {
    height: 1.6cm;
    padding: 0;
    font-size: 34pt;
    color: #000;
  }

  .bingo-sheet .bingo-grid td {
    height: auto;
    padding: 0.1cm;
    border: 1.5pt solid #000;
    font-size: 12pt;
  }

  .bingo-sheet .bingo-free {
    color: #000;
  }

  .bingo-list {
    break-before: page;
  }

  .bingo-list h2 {
    margin: 0 0 0.4cm;
    font-size: 16pt;
    color: #000;
  }

  .bingo-list ul {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1pt dashed #000;
    border-left: 1pt dashed #000;
  }

  .bingo-list li {
    padding: 0.4cm 0.2cm;
    border-right: 1pt dashed #000;
    border-bottom: 1pt dashed #000;
    text-align: center;
    overflow-wrap: anywhere;
  }
}

/* ---------- The game of teams of the party games (/party/charades, /party/who-am-i, /party/minute-games) ---------- */

/* `party::pages::TeamGame`, as wide as the tools of its game (hidden until `app.js` runs): the form of the teams on a
   panel, then the score – each team a chip with its name and points, the one whose turn it is red, two a row on a
   360 px phone –, the round and whose turn it is, the panels of the game's turn side by side where they fit, the line
   of what a turn gave and „New game”. A long name breaks rather than pushing the page sideways. */
.team-game {
  grid-column: 1 / -1;
  display: grid;
  gap: 1rem;
  min-width: 0;
}

.team-setup,
.team-play {
  display: grid;
  gap: 1rem;
  min-width: 0;
}

.team-setup[hidden],
.team-play[hidden],
.team-turn-panel[hidden],
.team-verdict[hidden],
.team-names input[hidden] {
  display: none;
}

.team-setup p {
  margin: 0;
}

.team-names {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 9rem), 1fr));
  gap: 0.5rem;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.team-names legend {
  margin-bottom: 0.375rem;
  padding: 0;
  font-size: 0.9375rem;
  font-weight: 600;
}

.team-board {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.team-board li {
  display: flex;
  flex: 1 1 8rem;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  min-width: 0;
  padding: 0.625rem 0.875rem;
  background: var(--night-up);
  border: 1px solid rgb(143 196 238 / 0.22);
  border-radius: 14px;
  overflow-wrap: anywhere;
}

.team-board li[aria-current="true"] {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
}

.team-board strong {
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
}

.team-turn {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 750;
  text-align: center;
  overflow-wrap: anywhere;
}

.team-turn:focus:not(:focus-visible) {
  outline: none;
}

.team-turn-panel {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  gap: 1rem;
}

.team-verdict {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.team-verdict .button {
  flex: 1 1 7rem;
}

.team-verdict .button-quiet {
  color: var(--snow);
  box-shadow: inset 0 0 0 1.5px rgb(244 248 251 / 0.7);
}

.team-said {
  min-height: 1.5em;
  margin: 0;
  font-weight: 650;
  text-align: center;
  overflow-wrap: anywhere;
}

/* „Share your score” after the last round, over „New game”. */
.team-play > [data-share-score] {
  justify-self: center;
}

.team-play > .button-quiet {
  justify-self: center;
  color: var(--snow);
  box-shadow: inset 0 0 0 1.5px rgb(244 248 251 / 0.7);
}

/* The one-minute games: the game to pick, with what it needs and how it is played; the timer of its minutes; the teams
   to tap when it is over, the pressed ones red. */
.minute-pick,
.minute-won {
  display: grid;
  align-content: start;
  gap: 0.75rem;
  min-width: 0;
}

.minute-pick p,
.minute-won p {
  margin: 0;
}

.minute-how {
  color: var(--muted-night);
}

.minute-teams {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.minute-teams .button {
  flex: 1 1 7rem;
  padding: 0.5rem 1rem;
  line-height: 1.2;
  color: var(--snow);
  box-shadow: inset 0 0 0 1.5px rgb(244 248 251 / 0.7);
  overflow-wrap: anywhere;
}

.minute-teams [aria-pressed="true"] {
  background: var(--red);
  color: #fff;
  box-shadow: none;
}

/* ---------- Christmas charades (/party/charades) ---------- */

/* On the screen: the turn of the game of teams on the phone (`.charades-tools`, beside the 60-second timer where they
   fit; hidden until `app.js` runs) and the 60 words in three levels, in columns as wide as they fit – a long word breaks rather than
   pushing the page sideways. The sheet to print (`.charades-sheet`) is not on the screen; printed (`@media print`), it
   is all there is: 60 cards in three columns, 7 rows a page of A4 or US Letter, in dashed lines to cut along, then a
   score sheet for two teams on a page of its own. */
.charades-draw {
  display: grid;
  align-content: start;
  gap: 0.75rem;
  text-align: center;
}

.charades-draw p {
  margin: 0;
}

.charades-levels {
  display: grid;
  gap: 0.375rem;
  margin: 0;
  padding: 0;
  border: 0;
  text-align: left;
}

.charades-levels legend {
  margin-bottom: 0.25rem;
  padding: 0;
  font-weight: 650;
}

.charades-levels input {
  accent-color: var(--red);
}

.charades-stars {
  color: var(--gold);
  letter-spacing: 0.1em;
}

.charades-draw .button-quiet,
.charades-room .button-quiet {
  color: var(--snow);
  box-shadow: inset 0 0 0 1.5px rgb(244 248 251 / 0.7);
}

.charades-said {
  min-height: 1.5em;
  font-weight: 600;
}

.charades-shown {
  padding: 0.75rem 0.5rem;
  border-radius: 0.5rem;
  background: var(--snow);
  color: var(--ink);
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

.charades-shown[hidden] {
  display: none;
}

.charades-list {
  columns: 12rem auto;
  column-gap: 1.5rem;
  margin: 0 0 1rem;
  padding-left: 1.25rem;
  overflow-wrap: anywhere;
}

.charades-list li {
  break-inside: avoid;
}

.charades-sheet {
  display: none;
}

@page charades {
  margin: 1cm;
}

@media print {
  html:has(.charades-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.charades-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.charades-sheet) > :not(main),
  body:has(.charades-sheet) main > :not(.charades-sheet) {
    display: none !important;
  }

  body:has(.charades-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .charades-sheet {
    page: charades;
    display: block;
    color: #000;
    font: 11pt/1.2 var(--sans);
  }

  /* Seven rows of 3.65 cm fit the 25.9 cm of Letter and the 27.7 cm of A4 inside the margins: 21 cards a page, the
     60 on three pages. */
  .charades-cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: 3.65cm;
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1pt dashed #000;
    border-left: 1pt dashed #000;
  }

  .charades-card {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 0.2cm;
    padding: 0.2cm 0.3cm;
    border-right: 1pt dashed #000;
    border-bottom: 1pt dashed #000;
    text-align: center;
    break-inside: avoid;
    overflow-wrap: anywhere;
  }

  .charades-card .charades-stars {
    font-size: 12pt;
    color: #000;
  }

  .charades-card .charades-word {
    font-size: 15pt;
    font-weight: 700;
    line-height: 1.15;
  }

  .charades-score {
    break-before: page;
  }

  .charades-score h2 {
    margin: 0 0 0.4cm;
    font-size: 16pt;
    color: #000;
  }

  .charades-score table {
    width: 100%;
    border-collapse: collapse;
  }

  .charades-score th,
  .charades-score td {
    height: 1.6cm;
    padding: 0 0.3cm;
    border: 1pt solid #000;
    text-align: left;
  }

  .charades-score tbody td:first-child {
    width: 3cm;
    text-align: center;
  }
}

/* ---------- Christmas would you rather (/quiz/would-you-rather) ---------- */

/* On the screen: the draw on the phone (`.wyr-tools`, hidden until `app.js` runs) – the three sets as buttons, the one
   pressed red, and the two options of the question drawn as two big cards, side by side where they fit, one over the
   other on a phone –, and all 60 questions in `.wyr-all`, a `<details>` open without a script. A long word breaks
   rather than pushing the page sideways. The sheet to print (`.wyr-sheet`) is not on the screen; printed
   (`@media print`), it is all there is: 60 cards, two a row and six rows a page of A4 or US Letter, in dashed lines to
   cut along, none split between two pages. */
.wyr-draw {
  display: grid;
  align-content: start;
  gap: 0.75rem;
  text-align: center;
}

.wyr-draw p {
  margin: 0;
}

.wyr-sets {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  border: 0;
}

.wyr-sets legend {
  width: 100%;
  margin-bottom: 0.25rem;
  padding: 0;
  font-weight: 650;
}

.wyr-sets .button-quiet {
  color: var(--snow);
  box-shadow: inset 0 0 0 1.5px rgb(244 248 251 / 0.7);
}

.wyr-sets [aria-pressed="true"] {
  background: var(--red);
  color: #fff;
  box-shadow: none;
}

.wyr-ask {
  font-size: 1.25rem;
  font-weight: 800;
}

.wyr-pair {
  display: grid;
  gap: 0.5rem;
}

.wyr-pair[hidden] {
  display: none;
}

.wyr-option {
  display: grid;
  place-items: center;
  min-height: 5rem;
  padding: 1rem 0.75rem;
  border-radius: 0.5rem;
  background: var(--snow);
  color: var(--ink);
  font-size: 1.375rem;
  font-weight: 800;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.wyr-pair .wyr-or {
  font-weight: 700;
  color: var(--gold);
}

@media (min-width: 40rem) {
  .wyr-pair {
    grid-template-columns: 1fr auto 1fr;
    align-items: stretch;
  }

  .wyr-pair .wyr-or {
    align-self: center;
  }
}

.wyr-said {
  min-height: 1.5em;
  font-weight: 600;
}

.wyr-count {
  font-variant-numeric: tabular-nums;
}

.wyr-all summary {
  cursor: pointer;
  width: fit-content;
  margin-bottom: 0.75rem;
  font-weight: 650;
  color: var(--gold);
}

.wyr-list {
  margin: 0 0 1rem;
  padding-left: 1.75rem;
  overflow-wrap: anywhere;
}

.wyr-list li {
  margin-bottom: 0.375rem;
}

.wyr-list .wyr-or {
  font-style: italic;
  color: var(--gold);
}

.wyr-sheet {
  display: none;
}

@page wyr {
  margin: 1cm;
}

@media print {
  html:has(.wyr-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.wyr-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.wyr-sheet) > :not(main),
  body:has(.wyr-sheet) main > :not(.wyr-sheet) {
    display: none !important;
  }

  body:has(.wyr-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .wyr-sheet {
    page: wyr;
    display: block;
    color: #000;
    font: 11pt/1.2 var(--sans);
  }

  /* Six rows of 4.3 cm fit the 25.9 cm of Letter and the 27.7 cm of A4 inside the margins: 12 cards a page, the 60
     on five pages. */
  .wyr-cards {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: 4.3cm;
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1pt dashed #000;
    border-left: 1pt dashed #000;
  }

  .wyr-card {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 0.15cm;
    padding: 0.25cm 0.4cm;
    border-right: 1pt dashed #000;
    border-bottom: 1pt dashed #000;
    text-align: center;
    break-inside: avoid;
    overflow: hidden;
    overflow-wrap: anywhere;
  }

  .wyr-card .wyr-label {
    font-size: 8.5pt;
    color: #444;
  }

  .wyr-card .wyr-a,
  .wyr-card .wyr-b {
    font-size: 12.5pt;
    font-weight: 700;
    line-height: 1.15;
  }

  .wyr-card .wyr-or {
    font-size: 10pt;
    font-style: italic;
  }
}

/* ---------- Christmas word search (/puzzles/word-search) ---------- */

/* On the screen: the two levels as buttons (the current one red), the grid on snow paper as wide as the column, each
   letter a square – 13 of them fit 360 px –, the words to find under it; on the phone a tapped first letter is gold and
   the letters of a found word red, the word struck off the list (`app.js`). The solution under it, in
   `.wordsearch-answer` – a `<details>`, so it opens without a script. The sheet to print (`.wordsearch-sheet`) is not on
   the screen; printed (`@media print`), it is all there is: the grid and the words with boxes to tick on the first page
   of A4 or US Letter, the solution on the second. */
.wordsearch-levels {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.wordsearch-levels [aria-current] {
  background: var(--red);
  color: #fff;
  box-shadow: none;
}

.wordsearch-grid {
  width: 100%;
  max-width: 32rem;
  margin: 0 auto;
  table-layout: fixed;
  border-collapse: collapse;
  border-radius: 0.5rem;
  background: var(--snow);
  color: var(--ink);
}

/* Square letters: a table ignores aspect-ratio, so the height is the grid's width (that of its container, up to 32rem)
   over its letters. */
.wordsearch,
.wordsearch-answer {
  container-type: inline-size;
}

.wordsearch-grid td {
  height: calc(min(100cqi, 32rem) / 10);
  padding: 0;
  text-align: center;
  vertical-align: middle;
  font-size: min(1.25rem, 4.6vw);
  font-weight: 700;
  line-height: 1;
  user-select: none;
}

.wordsearch-grid[data-size="13"] td {
  height: calc(min(100cqi, 32rem) / 13);
}

.wordsearch-grid td:focus-visible {
  outline: 2px solid var(--pen);
  outline-offset: -2px;
}

.wordsearch td {
  cursor: pointer;
}

.wordsearch-first {
  background: var(--gold);
}

.wordsearch-found,
.wordsearch-hit {
  background: rgb(200 35 59 / 0.18);
  color: var(--red-deep);
}

.wordsearch-said {
  min-height: 1.5em;
  font-weight: 600;
}

.wordsearch-words {
  columns: 7rem auto;
  column-gap: 1.5rem;
  margin: 0 0 1rem;
  padding-left: 1.25rem;
  overflow-wrap: anywhere;
}

.wordsearch-words li {
  break-inside: avoid;
}

.wordsearch-done {
  text-decoration: line-through;
  opacity: 0.6;
}

.wordsearch-answer summary {
  cursor: pointer;
  width: fit-content;
  margin-bottom: 0.75rem;
  font-weight: 650;
  color: var(--gold);
}

.wordsearch-sheet {
  display: none;
}

@page wordsearch {
  margin: 1.5cm;
}

@media print {
  html:has(.wordsearch-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.wordsearch-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.wordsearch-sheet) > :not(main),
  body:has(.wordsearch-sheet) main > :not(.wordsearch-sheet) {
    display: none !important;
  }

  body:has(.wordsearch-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .wordsearch-sheet {
    page: wordsearch;
    display: block;
    color: #000;
    font: 12pt/1.3 var(--sans);
  }

  .wordsearch-sheet h2 {
    margin: 0 0 0.5cm;
    font-size: 18pt;
    color: #000;
  }

  .wordsearch-sheet h3 {
    margin: 0.6cm 0 0.3cm;
    font-size: 13pt;
    color: #000;
  }

  /* 15 cm across: squares of 1.5 cm for kids, 1.15 cm for adults – the grid and its words fit a page of A4 and of
     Letter inside the margins. */
  .wordsearch-sheet .wordsearch-grid {
    width: 15cm;
    max-width: none;
    margin: 0;
    border: 1.5pt solid #000;
    border-radius: 0;
    background: #fff;
    color: #000;
  }

  .wordsearch-sheet .wordsearch-grid td {
    height: 1.5cm;
    border: 0.5pt solid #999;
    font-size: 20pt;
  }

  .wordsearch-sheet .wordsearch-grid[data-size="13"] td {
    height: 1.15cm;
    font-size: 16pt;
  }

  .wordsearch-sheet .wordsearch-hit {
    background: #d9d9d9;
    color: #000;
    font-weight: 900;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  .wordsearch-checklist {
    columns: 3;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .wordsearch-checklist li {
    display: flex;
    align-items: center;
    gap: 0.25cm;
    margin-bottom: 0.2cm;
    break-inside: avoid;
  }

  .wordsearch-box {
    flex: none;
    width: 0.45cm;
    height: 0.45cm;
    border: 1pt solid #000;
  }

  .wordsearch-solution {
    break-before: page;
  }
}

/* The nice list certificate of /printables/nice-list-certificate (`.certificate-sheet`): on the screen a sheet of
   cream paper in a red frame with a gold line inside and a gold star in each corner, its title in red, a line for the
   name and a field for the reason – what is typed shows in blue pen, an example in grey until then –, the ready
   reasons under it to tap, the date and two signatures with Santa's seal of the year between them. Printed
   (`@media print`), only the sheet, on one landscape page of A4 or US Letter: an empty field a line to write on by
   hand, its example and the reasons not at all. */
.certificate-sheet {
  color-scheme: light;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 2.25rem 1.5rem 1.75rem;
  background: #fffdf5;
  color: var(--ink);
  border: 6px solid var(--red);
  outline: 2px solid var(--gold-deep);
  outline-offset: -14px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
  font: 500 1.375rem/1.3 var(--hand);
  text-align: center;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

.certificate-corner {
  position: absolute;
  width: 1.25rem;
  height: 1.25rem;
  fill: var(--gold);
  stroke: var(--gold-deep);
  stroke-width: 1;
}

.certificate-corner-tl {
  top: 18px;
  left: 18px;
}

.certificate-corner-tr {
  top: 18px;
  right: 18px;
}

.certificate-corner-bl {
  bottom: 18px;
  left: 18px;
}

.certificate-corner-br {
  right: 18px;
  bottom: 18px;
}

.certificate-title {
  max-width: 100%;
  padding: 0 1rem;
  color: var(--red);
  font-size: clamp(1.875rem, 7vw, 3rem);
  line-height: 1.05;
  overflow-wrap: anywhere;
}

.certificate-name,
.certificate-for,
.certificate-date {
  width: min(100%, 34rem);
}

.certificate-sheet p {
  margin: 0;
}

.certificate-sheet input,
.certificate-sheet textarea {
  min-width: 0;
  padding: 0 0.25rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--pen);
  font: 600 1.375rem/2rem var(--hand);
  text-align: center;
}

.certificate-sheet input {
  flex: 1;
  border-bottom: 1.5px solid #8b97ad;
}

.certificate-name input {
  font-size: 2rem;
  line-height: 2.75rem;
}

/* Two ruled lines, and more as the text grows where the browser can (field-sizing). */
.certificate-sheet textarea {
  min-height: 4rem;
  height: 4rem;
  resize: none;
  field-sizing: content;
  background: repeating-linear-gradient(transparent 0 calc(2rem - 1.5px), #8b97ad calc(2rem - 1.5px) 2rem);
}

.certificate-sheet input:focus,
.certificate-sheet textarea:focus {
  border-color: #8b97ad;
  outline: 2px solid rgb(43 76 140 / 0.35);
}

.certificate-sheet ::placeholder {
  color: #9aa5b8;
  opacity: 1;
}

.certificate-for .letter-field {
  margin-bottom: 0.5rem;
}

.certificate-hint {
  color: var(--muted-paper);
  font: 0.875rem/1.4 var(--sans);
}

/* The ready reasons: small tags to tap, in the page's own font. */
.certificate-reasons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.375rem;
  margin: 0.5rem 0 0;
  padding: 0;
  list-style: none;
}

.certificate-reason {
  padding: 0.25rem 0.625rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  color: var(--pen);
  font: 0.875rem/1.3 var(--sans);
  text-align: left;
  cursor: pointer;
}

.certificate-reason:hover,
.certificate-reason:focus-visible {
  border-color: var(--pen);
}

.certificate-date .letter-line {
  justify-content: center;
}

.certificate-date input {
  flex: 0 1 12rem;
}

/* The signatures in a hand on their lines, the seal between them; one under the other on a narrow screen. */
.certificate-signs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  width: 100%;
}

.certificate-sign {
  flex: 1 1 9rem;
  padding: 0 0.5rem 0.25rem;
  border-bottom: 1.5px solid #8b97ad;
  color: var(--pen);
  font-weight: 700;
  font-size: 1.625rem;
  line-height: 1.1;
  transform: rotate(-2deg);
}

.certificate-sign-giver {
  color: var(--red);
  font-size: 2rem;
}

.certificate-seal {
  flex: none;
  width: 6.5rem;
  height: 6.5rem;
  margin: 0 auto;
}

.certificate-seal-edge {
  fill: var(--red);
  stroke: var(--gold);
  stroke-width: 3;
  stroke-dasharray: 2 3;
}

.certificate-seal-ring {
  fill: none;
  stroke: var(--gold);
  stroke-width: 1.5;
}

.certificate-seal text {
  fill: #fff;
  font-family: var(--sans);
  font-weight: 700;
}

.certificate-seal-year {
  font-size: 22px;
}

.certificate-seal .certificate-seal-stars {
  fill: var(--gold);
  font-size: 11px;
}

@page certificate {
  size: landscape;
  margin: 1cm;
}

@media print {
  body:has(.certificate-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.certificate-sheet) > :not(main),
  body:has(.certificate-sheet) main > :not(.certificate-sheet) {
    display: none !important;
  }

  body:has(.certificate-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  /* As high as the shorter page leaves (A4 across: 21 cm less the margins), so one page holds it whole. */
  .certificate-sheet {
    page: certificate;
    justify-content: space-between;
    height: 18.6cm;
    gap: 0.2cm;
    padding: 1.2cm 2cm 1cm;
    border-width: 0.25cm;
    outline-width: 1.5pt;
    outline-offset: -0.5cm;
    box-shadow: none;
    font-size: 16pt;
    overflow: hidden;
    break-inside: avoid;
  }

  .certificate-corner {
    width: 0.6cm;
    height: 0.6cm;
  }

  .certificate-corner-tl,
  .certificate-corner-tr {
    top: 0.7cm;
  }

  .certificate-corner-bl,
  .certificate-corner-br {
    bottom: 0.7cm;
  }

  .certificate-corner-tl,
  .certificate-corner-bl {
    left: 0.7cm;
  }

  .certificate-corner-tr,
  .certificate-corner-br {
    right: 0.7cm;
  }

  .certificate-title {
    font-size: 38pt;
  }

  .certificate-name,
  .certificate-for {
    width: 17cm;
  }

  .certificate-date {
    width: 9cm;
  }

  .certificate-sheet input,
  .certificate-sheet textarea {
    font-size: 18pt;
    line-height: 0.9cm;
  }

  .certificate-name input {
    font-size: 26pt;
    line-height: 1.3cm;
    border-bottom: 1pt solid #777;
  }

  .certificate-sheet input {
    border-bottom: 1pt solid #777;
  }

  /* Two lines, no more: a longer text is cut rather than pushing the signatures onto a second page. */
  .certificate-sheet textarea {
    min-height: 1.8cm;
    max-height: 1.8cm;
    height: 1.8cm;
    overflow: hidden;
    background: repeating-linear-gradient(transparent 0 calc(0.9cm - 1pt), #777 calc(0.9cm - 1pt) 0.9cm);
  }

  .certificate-sheet ::placeholder {
    color: transparent;
  }

  .certificate-hint,
  .certificate-reasons {
    display: none !important;
  }

  .certificate-signs {
    flex-wrap: nowrap;
    padding: 0 0.5cm;
  }

  .certificate-sign {
    flex: 0 1 7.5cm;
    border-bottom: 1pt solid #777;
    font-size: 20pt;
  }

  .certificate-sign-giver {
    font-size: 26pt;
  }

  .certificate-seal {
    width: 3.4cm;
    height: 3.4cm;
  }

  /* The system's font of these pages (no Caveat) is taller and wider at the same size. */
  :root:lang(vi) .certificate-sheet,
  :root:lang(ja) .certificate-sheet,
  :root:lang(ko) .certificate-sheet,
  :root:lang(zh-Hans) .certificate-sheet {
    font-size: 13pt;
  }

  :root:lang(vi) .certificate-title,
  :root:lang(ja) .certificate-title,
  :root:lang(ko) .certificate-title,
  :root:lang(zh-Hans) .certificate-title {
    font-size: 30pt;
  }
}

/* ---------- Left right game (/party/left-right) ---------- */

/* On the screen: the two stories to read out, each word at which the gifts move bold and underlined, with its arrow –
   left gold with ← before it, right sky blue with → after it and underlined twice, so the two differ without colour too.
   The sheet to print (`.lr-sheet`) is not on the screen; printed (`@media print`), it is all there is: each story from a
   new page of A4 or US Letter in 13.5 pt, the words black, bold and underlined (once for left, twice for right). */
.lr-toc ul {
  margin: 0;
}

.lr-kind {
  margin-top: -0.5rem;
  color: var(--muted-night);
}

.lr-count {
  font-weight: 700;
  letter-spacing: 0.02em;
}

.lr-story p {
  overflow-wrap: break-word;
}

.lr {
  font-weight: 800;
  text-decoration: underline;
  text-decoration-thickness: 0.1em;
  text-underline-offset: 0.2em;
  white-space: nowrap;
}

.lr-left {
  color: var(--gold);
}

.lr-right {
  color: var(--sky);
  text-decoration-style: double;
}

.lr-sheet {
  display: none;
}

@page lr {
  margin: 1.6cm 1.8cm;
}

@media print {
  html:has(.lr-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.lr-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.lr-sheet) > :not(main),
  body:has(.lr-sheet) main > :not(.lr-sheet) {
    display: none !important;
  }

  body:has(.lr-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .lr-sheet {
    page: lr;
    display: block;
    color: #000;
    font: 13.5pt/1.45 Georgia, "Times New Roman", serif;
  }

  .lr-print + .lr-print {
    break-before: page;
  }

  .lr-print h2 {
    margin: 0 0 0.15cm;
    font-size: 19pt;
    line-height: 1.2;
    break-after: avoid;
  }

  .lr-print .lr-count {
    margin: 0 0 0.45cm;
    font: 700 10pt/1.3 var(--sans);
  }

  .lr-print p {
    margin: 0 0 0.3cm;
    orphans: 2;
    widows: 2;
  }

  .lr-sheet .lr {
    color: #000;
    text-decoration-color: #000;
  }
}

/* ---------- Christmas scavenger hunt (/party/scavenger-hunt) ---------- */

/* On the screen: both sets for the one who hides the cards, each riddle with its answer under it. The sheet to print
   (`.hunt-sheet`) is not on the screen; printed (`@media print`), it is all there is: each set on a page of its own –
   its title, the start card and 10 cards in two columns of six rows of 3.9 cm, dashed to cut along, a box „No. __” on
   each and no answer (6 × 3.9 cm and the title fit the 25.9 cm of Letter inside the margins) –, then the answer key on
   its own page. */
.hunt-toc ul {
  margin: 0;
}

.hunt-kind {
  margin-top: -0.5rem;
  color: var(--muted-night);
}

.hunt-clues li {
  margin-bottom: 0.9rem;
  overflow-wrap: break-word;
}

.hunt-clues p {
  margin: 0;
}

.hunt-answer {
  color: var(--muted-night);
}

.hunt-sheet {
  display: none;
}

@page hunt {
  margin: 1cm;
}

@media print {
  html:has(.hunt-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.hunt-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.hunt-sheet) > :not(main),
  body:has(.hunt-sheet) main > :not(.hunt-sheet) {
    display: none !important;
  }

  body:has(.hunt-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .hunt-sheet {
    page: hunt;
    display: block;
    color: #000;
    font: 11.5pt/1.3 var(--sans);
  }

  .hunt-print + .hunt-print,
  .hunt-key {
    break-before: page;
  }

  .hunt-print h2 {
    margin: 0 0 0.3cm;
    font-size: 14pt;
    line-height: 1.2;
    color: #000;
  }

  .hunt-cards {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: 3.9cm;
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1pt dashed #000;
    border-left: 1pt dashed #000;
  }

  .hunt-card {
    display: flex;
    flex-direction: column;
    gap: 0.2cm;
    padding: 0.3cm 0.4cm;
    border-right: 1pt dashed #000;
    border-bottom: 1pt dashed #000;
    break-inside: avoid;
    overflow: hidden;
    overflow-wrap: anywhere;
  }

  .hunt-card p {
    margin: 0;
  }

  .hunt-no {
    font-weight: 700;
  }

  .hunt-box {
    display: inline-block;
    width: 1.3cm;
    height: 0.7cm;
    margin: 0 0.1cm;
    border: 1.5pt solid #000;
    vertical-align: middle;
  }

  .hunt-start {
    justify-content: center;
    text-align: center;
    font-weight: 700;
  }

  .hunt-start .hunt-label {
    font-size: 18pt;
  }

  .hunt-key {
    font-size: 10pt;
    line-height: 1.35;
  }

  .hunt-key h2 {
    margin: 0 0 0.3cm;
    font-size: 16pt;
    color: #000;
  }

  .hunt-key h3 {
    margin: 0.3cm 0 0.15cm;
    font-size: 12pt;
    color: #000;
    break-after: avoid;
  }

  .hunt-key ol {
    margin: 0;
    padding-left: 0.7cm;
  }

  .hunt-key li {
    break-inside: avoid;
  }
}

/* ---------- Secret Santa clues (/secret-santa/clues) ---------- */

/* On the screen: the questions, hints and openings on the paper of the wishes (`.wishes-card`), each with its copy
   button; a gap „___” is a line to write on, its „___” there to copy but not seen. The sheet to print (`.clue-sheet`)
   is not on the screen; printed (`@media print`), it is all there is: the 15 hints as cards in two columns of eight
   rows of 3.1 cm, dashed to cut along, on one page of A4 or Letter (8 × 3.1 cm fit the 25.9 cm of Letter inside the
   margins). */
.clue-blank {
  display: inline-block;
  min-width: 4.5em;
  border-bottom: 1.5px solid currentColor;
  color: transparent;
  line-height: 1;
}

.clue-sheet {
  display: none;
}

@page clue {
  margin: 1cm;
}

@media print {
  html:has(.clue-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.clue-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.clue-sheet) > :not(main),
  body:has(.clue-sheet) main > :not(.clue-sheet) {
    display: none !important;
  }

  body:has(.clue-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .clue-sheet {
    page: clue;
    display: block;
    color: #000;
    font: 11pt/1.3 var(--sans);
  }

  .clue-cards {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: 3.1cm;
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1pt dashed #000;
    border-left: 1pt dashed #000;
  }

  .clue-card {
    display: flex;
    flex-direction: column;
    gap: 0.25cm;
    padding: 0.35cm 0.45cm;
    border-right: 1pt dashed #000;
    border-bottom: 1pt dashed #000;
    break-inside: avoid;
    overflow: hidden;
    overflow-wrap: anywhere;
  }

  .clue-card p {
    margin: 0;
  }

  .clue-from {
    display: flex;
    justify-content: space-between;
    gap: 0.3cm;
    font-size: 9.5pt;
    font-weight: 700;
  }

  .clue-text {
    font-size: 12pt;
    line-height: 1.75;
  }

  .clue-text .clue-blank {
    min-width: 3.5cm;
    border-bottom: 1pt solid #000;
  }
}

/* ---------- Christmas Who am I? (/party/who-am-i) ---------- */

/* On the screen: the turn of the game of teams on the phone (`.whoami-tools`, hidden until `app.js` runs) – the sets
   as buttons, the one pressed red, a line to hold the phone to the forehead and the word drawn, very big for the others to read from two
   metres, a size smaller when it is long (`.whoami-long`) –, and all 30 words in `.whoami-all`, a closed `<details>`.
   A long word breaks rather than pushing the page sideways. The sheet to print (`.whoami-sheet`) is not on the screen;
   printed (`@media print`), it is all there is: 30 cards, two a row and three rows a page of A4 or US Letter, in dashed
   lines to cut along, none split between two pages. */
.whoami-draw {
  display: grid;
  align-content: start;
  gap: 0.75rem;
  text-align: center;
}

.whoami-draw p {
  margin: 0;
}

.whoami-sets {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  border: 0;
}

.whoami-sets legend {
  width: 100%;
  margin-bottom: 0.25rem;
  padding: 0;
  font-weight: 650;
}

.whoami-sets .button-quiet {
  color: var(--snow);
  box-shadow: inset 0 0 0 1.5px rgb(244 248 251 / 0.7);
}

.whoami-sets [aria-pressed="true"] {
  background: var(--red);
  color: #fff;
  box-shadow: none;
}

.whoami-said {
  min-height: 1.5em;
  font-size: 1.375rem;
  font-weight: 800;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.whoami-draw .whoami-word {
  display: grid;
  place-items: center;
  min-height: 9rem;
  padding: 1rem 0.5rem;
  border-radius: 0.5rem;
  background: var(--snow);
  color: var(--ink);
  font-size: clamp(2.5rem, 14vw, 5.5rem);
  font-weight: 800;
  line-height: 1.1;
  overflow-wrap: anywhere;
}

.whoami-draw .whoami-long {
  font-size: clamp(1.75rem, 8.5vw, 3.75rem);
}

.whoami-draw .whoami-word[hidden] {
  display: none;
}

/* The turn on the forehead (`.whoami-mode` starts it, `.whoami-forehead`): the whole screen – full screen where the
   browser has it, over the page where not (an iPhone) – laid out across, the word as big as the screen lets it, for
   the others to read; the clock and „×” small at the top. Held upright, a phone that does not turn its screen (its
   rotation locked, an iPhone) gets the face turned a quarter clockwise, to read with the phone across. Without the
   sensor, the halves are the buttons: left „Pass”, right „Guessed it”, their words at the bottom. Then green or orange
   for an instant after each answer, only where motion is welcome. The turn's summary (`.whoami-end`) is not turned:
   it is read with the phone in the hand. */
.whoami-mode {
  display: grid;
  gap: 0.5rem;
}

.whoami-mode[hidden],
.whoami-forehead[hidden],
.whoami-forehead [hidden] {
  display: none;
}

.whoami-mode p {
  color: var(--muted-night);
  font-size: 0.9375rem;
}

.whoami-forehead {
  position: fixed;
  inset: 0;
  z-index: 10;
  container-type: size;
  overflow: hidden;
  background: var(--night);
  color: var(--snow);
}

.whoami-face {
  position: relative;
  container-type: size;
  display: grid;
  grid-template: auto 1fr auto / 1fr auto;
  width: 100%;
  height: 100%;
  padding: max(0.75rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right)) max(0.75rem, env(safe-area-inset-bottom))
    max(1rem, env(safe-area-inset-left));
}

@media (orientation: portrait) {
  .whoami-face {
    position: absolute;
    top: 0;
    left: 100%;
    width: 100cqh;
    height: 100cqw;
    transform-origin: 0 0;
    transform: rotate(90deg);
  }
}

.whoami-face p {
  position: relative;
  margin: 0;
  pointer-events: none;
}

.whoami-clock {
  font-size: 1.5rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.whoami-stop {
  position: relative;
  width: 3rem;
  height: 3rem;
  border: 0;
  border-radius: 50%;
  background: rgb(244 248 251 / 0.14);
  color: inherit;
  font: inherit;
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
}

.whoami-big {
  grid-column: 1 / -1;
  align-self: center;
  font-size: min(30cqh, 14cqw);
  font-weight: 800;
  line-height: 1.05;
  text-align: center;
  overflow-wrap: anywhere;
}

.whoami-big.whoami-long {
  font-size: min(20cqh, 8.5cqw);
}

.whoami-hint {
  grid-column: 1 / -1;
  font-size: 1.25rem;
  font-weight: 650;
  text-align: center;
}

.whoami-half {
  position: absolute;
  inset: 0 50% 0 0;
  display: flex;
  align-items: flex-end;
  padding: 1rem max(1rem, env(safe-area-inset-left));
  border: 0;
  background: rgb(232 122 31 / 0.14);
  color: inherit;
  font: inherit;
  font-size: 1.25rem;
  font-weight: 700;
  cursor: pointer;
}

.whoami-half[data-half="guessed"] {
  inset: 0 0 0 50%;
  justify-content: flex-end;
  padding-right: max(1rem, env(safe-area-inset-right));
  background: rgb(46 160 96 / 0.16);
}

@media (prefers-reduced-motion: no-preference) {
  .whoami-forehead[data-flash="guessed"] {
    background: #1e7a46;
  }

  .whoami-forehead[data-flash="pass"] {
    background: #b85a12;
  }
}

.whoami-end {
  display: grid;
  align-content: start;
  gap: 1rem;
  max-width: 48rem;
  height: 100%;
  margin: 0 auto;
  padding: max(1.25rem, env(safe-area-inset-top)) max(1.25rem, env(safe-area-inset-right)) max(1.25rem, env(safe-area-inset-bottom))
    max(1.25rem, env(safe-area-inset-left));
  overflow-y: auto;
}

.whoami-told {
  margin: 0;
  font-size: 1.75rem;
  font-weight: 800;
  overflow-wrap: anywhere;
}

.whoami-lists {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: 1rem;
}

.whoami-lists h3 {
  margin: 0 0 0.375rem;
  font-size: 1.125rem;
  color: #6fd29b;
}

.whoami-lists div + div h3 {
  color: #f0a35e;
}

.whoami-lists ul {
  margin: 0;
  padding-left: 1.25rem;
  font-size: 1.125rem;
  overflow-wrap: anywhere;
}

.whoami-end .button {
  justify-self: start;
}

.whoami-all summary {
  cursor: pointer;
  width: fit-content;
  margin-bottom: 0.75rem;
  font-weight: 650;
  color: var(--gold);
}

.whoami-list {
  columns: 12rem auto;
  column-gap: 1.5rem;
  margin: 0 0 1rem;
  padding-left: 1.25rem;
  overflow-wrap: anywhere;
}

.whoami-list li {
  break-inside: avoid;
}

.whoami-sheet {
  display: none;
}

@page whoami {
  margin: 1cm;
}

@media print {
  html:has(.whoami-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.whoami-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.whoami-sheet) > :not(main),
  body:has(.whoami-sheet) main > :not(.whoami-sheet) {
    display: none !important;
  }

  body:has(.whoami-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .whoami-sheet {
    page: whoami;
    display: block;
    color: #000;
    font: 11pt/1.2 var(--sans);
  }

  /* Three rows of 8.5 cm fit the 25.9 cm of Letter and the 27.7 cm of A4 inside the margins: 6 cards a page, the 30
     on five pages. */
  .whoami-cards {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: 8.5cm;
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1pt dashed #000;
    border-left: 1pt dashed #000;
  }

  .whoami-card {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 0.4cm;
    padding: 0.4cm 0.5cm;
    border-right: 1pt dashed #000;
    border-bottom: 1pt dashed #000;
    text-align: center;
    break-inside: avoid;
    overflow: hidden;
    overflow-wrap: anywhere;
  }

  .whoami-label {
    font-size: 9pt;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }

  .whoami-card .whoami-word {
    font-size: 36pt;
    font-weight: 800;
    line-height: 1.1;
    hyphens: auto;
  }

  .whoami-long .whoami-word {
    font-size: 28pt;
  }
}

/* ---------- Christmas color by number (/printables/color-by-number) ---------- */

/* On the screen and on paper alike (`.cbn-sheet`): each picture on snow paper – its name, its colors to tap
   (`.cbn-tools`, hidden until `app.js` runs, held at the top while the grid scrolls under them), the grid as wide as
   the column up to 480 px, a legend of its colors in framed swatches (they still read printed in black and white), and
   the finished picture in `.cbn-answer`, a closed `<details>`. A tap colors a square; a double tap does not zoom and a
   finger on the grid still scrolls the page. Printed (`@media print`), the sheet is all there is, without the colors
   to tap and the finished pictures: a picture a page of A4 or US Letter, squares of 9.5 mm, numbers of 9 pt. */
.cbn-contents {
  columns: 12rem auto;
  column-gap: 1.5rem;
  margin: 0 0 1rem;
  padding-left: 1.5rem;
}

.cbn-contents a {
  color: var(--gold);
}

.cbn-sheet {
  display: grid;
  gap: 1.5rem;
}

.cbn-picture {
  padding: 1rem;
  border-radius: 20px;
  background: var(--snow);
  color: var(--ink);
  scroll-margin-top: 1rem;
}

.cbn-picture h2 {
  margin: 0 0 0.75rem;
  color: var(--ink);
  text-align: center;
}

.cbn-tools {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin: 0 -0.5rem 0.75rem;
  padding: 0.5rem;
  border-radius: 12px;
  background: var(--snow);
  box-shadow: 0 8px 16px -12px rgb(0 0 0 / 0.6);
}

.cbn-tools[hidden] {
  display: none;
}

.cbn-colors {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.375rem;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

/* The crayons of `pages::CBN_COLORS`, by number: the button to tap and the swatch of the legend. */
.cbn-c1 {
  --crayon: #d62828;
}

.cbn-c2 {
  --crayon: #2e9e44;
}

.cbn-c3 {
  --crayon: #16572a;
}

.cbn-c4 {
  --crayon: #8a5a2b;
}

.cbn-c5 {
  --crayon: #f5c518;
}

.cbn-c6 {
  --crayon: #3d7ee0;
}

.cbn-c7 {
  --crayon: #222222;
}

.cbn-c8 {
  --crayon: #f28a1c;
}

.cbn-c9 {
  --crayon: #f7b2c4;
}

.cbn-color {
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--crayon);
  color: #fff;
  font: 800 1rem/1 var(--sans);
  text-shadow: 0 0 3px #000, 0 0 2px #000;
  cursor: pointer;
}

.cbn-color[aria-pressed="true"] {
  outline: 3px solid var(--red);
  outline-offset: 2px;
}

.cbn-color:focus-visible {
  outline: 3px solid var(--pen);
  outline-offset: 2px;
}

.cbn-tools .cbn-clear {
  color: var(--ink);
  box-shadow: inset 0 0 0 1.5px var(--ink);
}

.cbn-said {
  flex-basis: 100%;
  min-height: 1.25em;
  margin: 0;
  text-align: center;
  font-weight: 800;
  color: var(--red-deep);
}

.cbn-said:empty {
  min-height: 0;
}

.cbn-grid {
  display: block;
  width: 100%;
  max-width: 480px;
  height: auto;
  margin: 0 auto;
  /* The outer lines of the grid are half outside its box. */
  overflow: visible;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.cbn-grid rect {
  fill: #fff;
  cursor: pointer;
}

.cbn-grid .cbn-lines {
  fill: none;
  stroke: #8a97ab;
  stroke-width: 0.5;
  pointer-events: none;
}

.cbn-grid text {
  font: 700 5px var(--sans);
  fill: #4a5568;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}

.cbn-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.375rem 1rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
}

.cbn-legend li {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.cbn-swatch {
  width: 1.25rem;
  height: 1.25rem;
  border: 1.5px solid var(--ink);
  border-radius: 4px;
  background: var(--crayon);
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

.cbn-answer {
  margin-top: 0.75rem;
  text-align: center;
}

.cbn-answer summary {
  cursor: pointer;
  width: fit-content;
  margin: 0 auto 0.5rem;
  font-weight: 650;
  color: var(--pen);
}

.cbn-solution {
  display: block;
  width: 10rem;
  height: auto;
  margin: 0 auto;
  border: 1px solid var(--line);
  background: #fff;
}

@page cbn {
  margin: 1cm;
}

@media print {
  html:has(.cbn-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.cbn-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.cbn-sheet) > :not(main),
  body:has(.cbn-sheet) main > :not(.cbn-sheet),
  .cbn-sheet [data-cbn],
  .cbn-sheet .cbn-answer {
    display: none !important;
  }

  body:has(.cbn-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .cbn-sheet {
    page: cbn;
    display: block;
    color: #000;
    font: 12pt/1.3 var(--sans);
  }

  .cbn-picture {
    padding: 0;
    border-radius: 0;
    background: none;
    break-before: page;
    break-inside: avoid;
  }

  .cbn-picture:first-child {
    break-before: auto;
  }

  .cbn-picture h2 {
    margin: 0 0 0.4cm;
    font-size: 20pt;
    color: #000;
  }

  .cbn-grid {
    max-width: 100%;
  }

  .cbn-grid[data-cols="14"] {
    width: 133mm;
  }

  .cbn-grid[data-cols="15"] {
    width: 142.5mm;
  }

  .cbn-grid[data-cols="16"] {
    width: 152mm;
  }

  .cbn-grid[data-cols="17"] {
    width: 161.5mm;
  }

  .cbn-grid[data-cols="18"] {
    width: 171mm;
  }

  .cbn-grid[data-cols="19"] {
    width: 180.5mm;
  }

  .cbn-grid[data-cols="20"] {
    width: 190mm;
  }

  .cbn-grid .cbn-lines {
    stroke: #333;
    stroke-width: 0.4;
  }

  .cbn-grid text {
    font-size: 3.4px;
    font-weight: 600;
    fill: #444;
  }

  .cbn-legend {
    gap: 0.25cm 0.6cm;
    margin-top: 0.4cm;
    font-size: 12pt;
  }

  .cbn-swatch {
    width: 0.6cm;
    height: 0.6cm;
    border: 1pt solid #000;
  }
}

/* The printable Christmas cards of /printables/christmas-cards (`.card-sheet`), on the screen and on paper
   alike. On the screen each card opened on snow paper: its front (the colored picture and a short wish in the font of
   the headings) beside the inside, where „To:” and „From:” are lines to type on; the left of the inside and the back
   are only on paper. Under it the panel (`[data-xmas-card]`, hidden until `app.js` runs). Printed (`@media print`),
   the sheet is all there is, a card a page of A4 or US Letter: a block of 19 × 25.9 cm in the middle of the paper
   (it fits both), four quarters of 9.5 × 12.95 cm and dashed lines to fold along, right through the middle of the
   paper. Folded twice – the top half back behind the bottom one, the print outside, then the left half back behind
   the right one – the bottom right quarter is the front, the bottom left one the back, and the two top ones, printed
   upside down, the inside. */
.card-sheet {
  display: grid;
  gap: 1.5rem;
}

.xmas-card {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 1rem;
  padding: 1rem;
  border-radius: 20px;
  background: var(--snow);
  color: var(--ink);
  scroll-margin-top: 1rem;
}

.xmas-card-front,
.xmas-card-inside {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1rem;
  min-width: 0;
  aspect-ratio: 95 / 129.5;
  padding: 1.25rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #fff;
}

.xmas-card-front {
  align-items: center;
  text-align: center;
}

.xmas-card-picture {
  width: 75%;
  max-height: 65%;
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

.xmas-card-greeting {
  margin: 0;
  color: var(--red);
  font-family: var(--hand);
  font-size: 2.25rem;
  font-weight: 700;
  line-height: 1;
  text-wrap: balance;
}

.xmas-card-name {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.xmas-card-name input {
  flex: 1;
  min-width: 0;
  padding: 0 0.125rem;
  border: 0;
  border-bottom: 1.5px solid #8b97ad;
  border-radius: 0;
  background: transparent;
  color: var(--pen);
  font: 600 1.25rem/1.6rem var(--hand);
}

.xmas-card-name input[type="text"]:focus {
  border-color: #8b97ad;
  outline: 2px solid rgb(43 76 140 / 0.35);
}

.xmas-card-wish {
  margin: 0;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* No wish of the list: lines to write one by hand. */
.xmas-card-wish:empty {
  min-height: 6em;
  background: repeating-linear-gradient(transparent 0 calc(1.5em - 1px), #8b97ad calc(1.5em - 1px) 1.5em);
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

.xmas-card-left,
.xmas-card-back {
  display: none;
}

.xmas-card-star {
  width: 6mm;
  height: 6mm;
  fill: var(--gold);
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

.xmas-card-back p {
  margin: 0;
  color: #888;
  font-size: 8pt;
  text-align: center;
}

.xmas-card-tools {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
}

.xmas-card-tools[hidden] {
  display: none;
}

@page xmascard {
  margin: 0;
}

@media print {
  html:has(.card-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.card-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.card-sheet) > :not(main),
  body:has(.card-sheet) main > :not(.card-sheet),
  .card-sheet [data-xmas-card],
  .card-sheet:has(.xmas-card-alone) .xmas-card:not(.xmas-card-alone) {
    display: none !important;
  }

  body:has(.card-sheet) main {
    display: block;
    max-width: none;
    margin: 0;
    padding: 0;
  }

  .card-sheet {
    page: xmascard;
    display: block;
    color: #000;
    font: 11.5pt/1.4 var(--sans);
  }

  /* The whole page (no margins), the block of quarters in its middle; a hair short of it, so it never spills onto
     another page. */
  .xmas-card {
    position: relative;
    grid-template-columns: 95mm 95mm;
    grid-template-rows: 129.5mm 129.5mm;
    grid-template-areas:
      "inside left"
      "back front";
    place-content: center;
    gap: 0;
    height: calc(100vh - 0.4mm);
    padding: 0;
    overflow: hidden;
    border-radius: 0;
    background: none;
    break-before: page;
    break-inside: avoid;
  }

  .xmas-card:first-of-type {
    break-before: auto;
  }

  .xmas-card::before,
  .xmas-card::after {
    content: "";
    position: absolute;
    border: 0 dashed #bbb;
  }

  .xmas-card::before {
    top: calc(50% - 129.5mm);
    left: calc(50% - 0.15mm);
    height: 259mm;
    border-left-width: 0.3mm;
  }

  .xmas-card::after {
    top: calc(50% - 0.15mm);
    left: calc(50% - 95mm);
    width: 190mm;
    border-top-width: 0.3mm;
  }

  .xmas-card-front,
  .xmas-card-inside,
  .xmas-card-left,
  .xmas-card-back {
    display: flex;
    flex-direction: column;
    min-height: 0;
    aspect-ratio: auto;
    padding: 10mm;
    overflow: hidden;
    border: 0;
    border-radius: 0;
    background: none;
  }

  .xmas-card-front {
    grid-area: front;
    gap: 6mm;
  }

  .xmas-card-inside {
    grid-area: inside;
    gap: 8mm;
    transform: rotate(180deg);
  }

  .xmas-card-left {
    grid-area: left;
    justify-content: flex-end;
    align-items: flex-end;
    transform: rotate(180deg);
  }

  .xmas-card-back {
    grid-area: back;
    justify-content: flex-end;
  }

  .xmas-card-picture {
    width: 64mm;
    max-width: none;
    max-height: 78mm;
  }

  .xmas-card-greeting {
    font-size: 26pt;
  }

  .xmas-card-name {
    gap: 2mm;
  }

  .xmas-card-name input {
    border-bottom: 0.3mm solid #777;
    font-size: 15pt;
    line-height: 9mm;
  }

  .xmas-card-wish {
    font-size: 11.5pt;
  }
}

/* The Christmas cards to color of /printables/cards-to-color: the cards above (`.card-sheet`), the front a
   line drawing of the coloring pages (`.cp-part`, `.cp-line`) – nothing to tap on it. Printed, the drawing about three
   quarters of the quarter wide (71 mm, its outline 0.9 mm) over the greeting, on a narrower margin. */
.xmas-card-color .cp-part {
  cursor: auto;
}

@media print {
  .xmas-card-color .xmas-card-front {
    gap: 4mm;
    padding: 6mm;
  }

  .xmas-card-color .xmas-card-picture {
    width: 71mm;
    max-height: 99.4mm;
  }
}

/* ---------- Christmas memory game (/puzzles/memory) ---------- */

/* The game on the screen (`.memory-game`, hidden until `app.js` runs): the choices of pairs and players, the counts,
   and the cards – square buttons, 3 or 4 a row, as wide as the column allows (360 px: no sideways scroll). A card face
   down is red with small white stars, all CSS; turned over, the picture on white; it turns on its axis only for those
   who do not ask for less motion. A double tap does not zoom. Under it the sheet to print (`.memory-sheet`): 16 cards
   in dashed cut lines, each picture twice. Printed (`@media print`), the sheet is all there is, on one page of A4 or US
   Letter: cards of 45 × 45 mm, pictures of 32 mm, the 180 × 180 mm grid in the middle of the paper. */
.memory-game[hidden] {
  display: none;
}

.memory-options {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.75rem 1.25rem;
}

.memory-choice {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.memory-choice legend {
  float: left;
  margin-right: 0.25rem;
  padding: 0;
  font-weight: 650;
}

.memory-option {
  min-width: 2.75rem;
  height: 2.75rem;
  padding: 0 0.75rem;
  border: 2px solid var(--muted-night);
  border-radius: 999px;
  background: none;
  color: inherit;
  font: 700 1rem/1 var(--sans);
  cursor: pointer;
  touch-action: manipulation;
}

.memory-option[aria-pressed="true"] {
  border-color: var(--gold);
  background: var(--gold);
  color: var(--ink);
}

.memory-count,
.memory-turn,
.memory-said {
  margin: 0.75rem 0 0;
  text-align: center;
  font-weight: 650;
}

.memory-count {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.25rem 1.5rem;
}

.memory-turn[hidden],
.memory-scores[hidden] {
  display: none;
}

.memory-scores {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.25rem 1.25rem;
  margin: 0.5rem 0 0;
  padding: 0;
  list-style: none;
}

.memory-said {
  min-height: 1.5em;
  color: var(--gold);
}

/* „Share your score” of one player, once all the pairs are found. */
.memory-share {
  display: flex;
  justify-content: center;
  margin: 0;
}

.memory-share > .button {
  margin-top: 0.75rem;
}

.memory-board {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.5rem;
  width: 100%;
  max-width: 28rem;
  margin: 1rem auto 0;
}

.memory-cols-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  max-width: 21rem;
}

.memory-card {
  position: relative;
  aspect-ratio: 1;
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: 10px;
  background: none;
  cursor: pointer;
  touch-action: manipulation;
}

.memory-card:disabled {
  cursor: default;
}

.memory-card:focus-visible {
  outline: 3px solid var(--sky);
  outline-offset: 3px;
}

.memory-back,
.memory-front {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: 10px;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.memory-back {
  border: 3px solid var(--snow);
  background:
    radial-gradient(circle, #fff 0 1.5px, transparent 2px) 0 0 / 16px 16px,
    radial-gradient(circle, rgb(255 255 255 / 0.55) 0 1px, transparent 1.5px) 8px 8px / 16px 16px,
    var(--red);
  box-shadow: 0 4px 10px -6px rgb(0 0 0 / 0.7);
  transform: perspective(500px) rotateY(0deg);
}

.memory-front {
  border: 3px solid var(--line);
  background: #fff;
  transform: perspective(500px) rotateY(180deg);
}

.memory-front svg {
  width: 72%;
  height: 72%;
}

.memory-card.is-open .memory-back {
  transform: perspective(500px) rotateY(-180deg);
}

.memory-card.is-open .memory-front {
  transform: perspective(500px) rotateY(0deg);
}

.memory-card.is-matched .memory-front {
  border-color: var(--gold);
}

@media (prefers-reduced-motion: no-preference) {
  .memory-back,
  .memory-front {
    transition: transform 0.35s var(--ease-out);
  }
}

.memory-sheet {
  padding: 1rem;
  border-radius: 20px;
  background: var(--snow);
  color: var(--ink);
}

.memory-print-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  max-width: 24rem;
  margin: 0 auto;
  border-top: 1px dashed #8a95a5;
  border-left: 1px dashed #8a95a5;
}

.memory-print-card {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border-right: 1px dashed #8a95a5;
  border-bottom: 1px dashed #8a95a5;
  background: #fff;
}

.memory-picture {
  width: 71%;
  height: 71%;
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

.memory-print-tip {
  margin: 0.75rem 0 0;
  text-align: center;
  font-size: 0.875rem;
  color: var(--muted-paper);
}

@page memory {
  margin: 0;
}

@media print {
  html:has(.memory-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.memory-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.memory-sheet) > :not(main),
  body:has(.memory-sheet) main > :not(.memory-sheet) {
    display: none !important;
  }

  body:has(.memory-sheet) main {
    display: block;
    max-width: none;
    margin: 0;
    padding: 0;
  }

  /* The whole page (no margins), the grid in its middle; a hair short of it, so it never spills onto another page. */
  .memory-sheet {
    page: memory;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5mm;
    height: calc(100vh - 0.4mm);
    padding: 0;
    overflow: hidden;
    border-radius: 0;
    background: none;
    color: #000;
    font: 9pt/1.3 var(--sans);
    break-inside: avoid;
  }

  .memory-print-grid {
    grid-template-columns: repeat(4, 45mm);
    max-width: none;
    margin: 0;
    border-top: 0.25mm dashed #999;
    border-left: 0.25mm dashed #999;
  }

  .memory-print-card {
    box-sizing: border-box;
    width: 45mm;
    height: 45mm;
    border-right: 0.25mm dashed #999;
    border-bottom: 0.25mm dashed #999;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  .memory-picture {
    width: 32mm;
    height: 32mm;
  }

  .memory-print-tip {
    margin: 0;
    font-size: 9pt;
    color: #555;
  }
}

/* The Christmas coloring pages (`.coloring-sheet`), on the screen and on paper alike: each picture on snow paper – its
   name, the drawing on white (each shape `.cp-part`, white with a thick black outline; `.cp-line` a line that closes
   nothing and lets a tap through), the crayons under it (`.cp-tools`, hidden until `app.js` runs; the colors of
   `.cbn-c1`…`.cbn-c9` and white). One column on a phone, two on a wide screen. A tap fills a shape; a double tap does
   not zoom and a finger on the picture still scrolls the page. Printed (`@media print`), the sheet is all there is,
   without the crayons: a picture a page of A4 or US Letter, as large as fits, its name and santa.haus small under it,
   the colors given on the screen too; with `.cp-page-alone` (its print button) that picture only. */
.coloring-sheet {
  display: grid;
  gap: 1.5rem;
}

@media (min-width: 64rem) {
  .coloring-sheet {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    width: min(60rem, 100vw - 3rem);
    margin-inline: calc((100% - min(60rem, 100vw - 3rem)) / 2);
  }
}

.cp-page {
  min-width: 0;
  padding: 1rem;
  border-radius: 20px;
  background: var(--snow);
  color: var(--ink);
  scroll-margin-top: 1rem;
}

.cp-page h2 {
  margin: 0 0 0.75rem;
  color: var(--ink);
  text-align: center;
}

.cp-picture {
  display: block;
  width: 100%;
  max-width: 420px;
  height: auto;
  margin: 0 auto;
  border-radius: 12px;
  background: #fff;
  touch-action: manipulation;
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

.cp-part {
  fill: #fff;
  stroke: #000;
  stroke-width: 2.5;
  stroke-linejoin: round;
  stroke-linecap: round;
  cursor: pointer;
}

.cp-line {
  fill: none;
  stroke: #000;
  stroke-width: 2.5;
  stroke-linejoin: round;
  stroke-linecap: round;
  pointer-events: none;
}

.cp-site {
  display: none;
}

.cp-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.75rem;
}

.cp-tools[hidden] {
  display: none;
}

.cp-colors {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.375rem;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.cp-white {
  --crayon: #fff;
}

.cp-tools .cp-clear,
.cp-tools .cp-print {
  color: var(--ink);
  box-shadow: inset 0 0 0 1.5px var(--ink);
}

/* The jump to each coloring page by its name, above the sheet: a wrapping row of snow chips. On paper it is left out
   with all but the sheet (`main > :not(.coloring-sheet)`). */
.cp-index ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.cp-index a {
  display: inline-block;
  padding: 0.375rem 0.875rem;
  border-radius: 999px;
  background: var(--snow);
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
}

.cp-index a:hover,
.cp-index a:focus-visible {
  text-decoration: underline;
}

@page coloring {
  margin: 10mm;
}

@media print {
  html:has(.coloring-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.coloring-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.coloring-sheet) > :not(main),
  body:has(.coloring-sheet) main > :not(.coloring-sheet),
  .coloring-sheet [data-coloring],
  .coloring-sheet:has(.cp-page-alone) .cp-page:not(.cp-page-alone) {
    display: none !important;
  }

  body:has(.coloring-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .coloring-sheet {
    page: coloring;
    display: block;
    width: auto;
    margin: 0;
    color: #000;
  }

  .cp-page {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0;
    border-radius: 0;
    background: none;
    break-before: page;
    break-inside: avoid;
  }

  .cp-page:first-child,
  .cp-page-alone {
    break-before: auto;
  }

  .cp-picture {
    order: 1;
    width: auto;
    max-width: none;
    height: 236mm;
    border-radius: 0;
  }

  .cp-page h2 {
    order: 2;
    margin: 3mm 0 0;
    font: 700 11pt/1.2 var(--sans);
    color: #000;
  }

  .cp-site {
    order: 3;
    display: block;
    margin: 1mm 0 0;
    font: 8pt/1.2 var(--sans);
    color: #888;
  }
}

/* The Christmas crosswords (`.crossword-sheet`), on the screen and on paper alike: each crossword on white – its name,
   the grid (an SVG as many millimetres a square as it prints, as wide as the column at most: 12 squares of 28 px fit
   360 px), the number of each word small in the corner of its first square, only the squares of the words framed –,
   then the clues across and down, side by side where there is room; its answers in `.crossword-answer`, a `<details>`.
   The key (`.crossword-key`) and „santa.haus” are for paper only. Printed (`@media print`), the sheet is all there is,
   without the answers under the crosswords: the kids' crossword on page 1 (squares of 10 mm), the adults' on page 2
   (9 mm, 8 for more than 16 rows: `puzzles::pages::crossword_square`), both filled in small on page 3 – three pages of A4 or US Letter –, santa.haus small and grey at the foot of
   each. */
.crossword-sheet {
  display: grid;
  gap: 1.5rem;
}

.crossword {
  min-width: 0;
  padding: 1rem 0.5rem;
  border-radius: 20px;
  background: #fff;
  color: #000;
  scroll-margin-top: 1rem;
}

.crossword h2,
.crossword h3 {
  color: #000;
  text-align: center;
}

.crossword-grid {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
  overflow: visible;
}

.cw-cell {
  fill: #fff;
  stroke: #000;
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
}

.cw-num {
  font: 600 3.2px/1 var(--sans);
  fill: #000;
}

.cw-letter {
  font: 700 6px/1 var(--sans);
  fill: #000;
  text-anchor: middle;
  dominant-baseline: central;
}

.cw-clues {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 0 1.5rem;
  padding: 0 0.5rem;
}

.cw-list h3 {
  margin: 1rem 0 0.5rem;
  text-align: start;
}

.cw-list ol {
  margin: 0;
  padding-left: 2rem;
}

.cw-list li {
  margin-bottom: 0.25rem;
}

.crossword-answer {
  margin-top: 1rem;
}

.crossword-answer summary {
  cursor: pointer;
  width: fit-content;
  margin: 0 0.5rem 0.75rem;
  font-weight: 650;
  color: var(--red-deep);
}

/* Filled in on the screen (`.cw-play`, shown by public/app.js): a table of squares as wide as the crossword's white,
   each with its letter (`.cw-v`), its number small in the corner; the word being filled in yellow, its square darker
   and framed, its clue in the lists under it too (`.cw-now`). The keyboard writes in one field over that square
   (`.cw-field`), unseen – but for a letter of Japanese, Korean or Chinese being composed (`.cw-typing`). Checked, a
   right letter turns green, a wrong one red on pink with a thick red frame – not by its colour alone –, an uncovered
   one blue. Then the grid drawn above it is for paper only. */
.crossword:has(.cw-play:not([hidden])) > .crossword-grid {
  display: none;
}

.cw-how,
.cw-said {
  margin: 0 0.5rem 0.75rem;
  text-align: center;
  color: #000;
}

.cw-said {
  margin-top: 0.5rem;
  font-weight: 650;
}

.cw-grid {
  position: relative;
}

.cw-board {
  width: 100%;
  max-width: 30rem;
  margin: 0 auto;
  table-layout: fixed;
  border-collapse: collapse;
}

.cw-board td {
  padding: 0;
}

.cw-square {
  position: relative;
  border: 1px solid #000;
  background: #fff;
  cursor: pointer;
}

.cw-v {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  font: 700 1.125rem/1 var(--sans);
  color: #000;
}

.cw-square.cw-word {
  background: #fff1bf;
}

.cw-square.cw-at {
  background: #ffd45c;
  box-shadow: inset 0 0 0 2px #000;
}

.cw-square[data-state="right"] .cw-v {
  color: #1f7a45;
}

.cw-square[data-state="wrong"] {
  background: #fde3e7;
  box-shadow: inset 0 0 0 3px var(--red);
}

.cw-square[data-state="wrong"] .cw-v {
  color: var(--red-deep);
}

.cw-square[data-state="shown"] .cw-v {
  color: var(--pen);
}

.cw-field {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  border: 0;
  /* 16 px: Safari on iOS zooms into a smaller field. */
  font: 700 16px/1 var(--sans);
  text-align: center;
  color: #000;
  background: #fff;
  caret-color: transparent;
  opacity: 0;
  pointer-events: none;
}

.cw-field.cw-typing {
  min-width: 6em;
  outline: 2px solid #000;
  opacity: 1;
  z-index: 1;
}

.cw-list li[tabindex] {
  cursor: pointer;
}

.cw-list li.cw-now {
  background: #fff1bf;
  font-weight: 650;
}

.cw-n {
  position: absolute;
  top: 1px;
  left: 2px;
  font: 600 0.5625rem/1 var(--sans);
  pointer-events: none;
}

.cw-buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.375rem;
  margin: 0.75rem 0 0;
}

.crossword-key,
.cw-site {
  display: none;
}

@page crossword {
  margin: 10mm;
}

@media print {
  html:has(.crossword-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.crossword-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.crossword-sheet) > :not(main),
  body:has(.crossword-sheet) main > :not(.crossword-sheet),
  .crossword-sheet .crossword-answer,
  .crossword-sheet .cw-play {
    display: none !important;
  }

  /* Filled in on the screen or not, the paper gets the grid to write on. */
  .crossword-sheet .crossword:has(.cw-play) > .crossword-grid {
    display: block;
  }

  body:has(.crossword-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .crossword-sheet {
    page: crossword;
    display: block;
    color: #000;
    font: 10pt/1.3 var(--sans);
  }

  .crossword {
    padding: 0;
    border-radius: 0;
    break-inside: avoid;
  }

  .crossword + .crossword,
  .crossword-key {
    break-before: page;
  }

  .crossword h2,
  .crossword-key h2 {
    margin: 0 0 5mm;
    font: 700 16pt/1.2 var(--sans);
    color: #000;
    text-align: center;
  }

  /* As many millimetres a square as its `width` says: 10 for kids, 9 for adults, 5 in the key. */
  .crossword-sheet .crossword-grid {
    max-width: none;
  }

  .cw-clues {
    grid-template-columns: 1fr 1fr;
    gap: 0 8mm;
    margin-top: 5mm;
    padding: 0;
  }

  .cw-list h3,
  .crossword-key h3 {
    margin: 0 0 2mm;
    font: 700 11pt/1.2 var(--sans);
    color: #000;
  }

  .cw-list ol {
    padding-left: 7mm;
  }

  .crossword:first-child .cw-clues {
    font-size: 12pt;
  }

  .cw-list li {
    margin-bottom: 1mm;
    break-inside: avoid;
  }

  .crossword-key {
    display: block;
  }

  .cw-key-grids {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: flex-start;
    gap: 10mm;
  }

  .crossword-key h3 {
    text-align: center;
  }

  .crossword-key .cw-letter {
    font-weight: 600;
  }

  .cw-site {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: block;
    margin: 0;
    font: 8pt/1 var(--sans);
    color: #888;
    text-align: center;
  }
}

/* ---------- Christmas jokes (/printables/jokes) ---------- */

/* On the screen: the jokes for kids and for the table (`.jokes`), each on snow paper (`.joke-card`) – the question,
   its punchline under it in `.joke-answer`, a `<details>` that opens without a script, and its copy button (the field
   of `site::Copy` hidden, as on the clues page). A long word breaks rather than pushing the page sideways. The sheet
   to print (`.joke-sheet`) is not on the screen; printed (`@media print`), it is all there is: the 30 jokes as slips of
   9.5 × 5 cm, two a row and five rows a page of A4 or US Letter (5 × 5 cm fit the 25.9 cm of Letter inside the
   margins), in dashed lines to cut along, none split between two pages, the punchline upside down at the foot of each
   (`.joke-flip`) – turned round, it reads like the joke in a Christmas cracker – and „santa.haus” small and grey at
   the foot of each page. */
.jokes {
  padding: 0 0.25rem;
  scroll-margin-top: 1rem;
}

.joke-cards {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
}

.joke-card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
  margin: 0;
  padding: 1rem 1.25rem 1.125rem;
  background: var(--snow);
  color: var(--ink);
  border-radius: 14px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
  overflow-wrap: anywhere;
}

.joke-question {
  flex: 1;
  margin: 0;
  font-weight: 650;
}

.joke-answer summary {
  cursor: pointer;
  width: fit-content;
  font-weight: 650;
  color: var(--red-deep);
}

.joke-answer p {
  margin: 0.375rem 0 0;
}

.joke-card .copy {
  margin-top: 0;
}

.joke-card .copy input {
  display: none;
}

.joke-sheet {
  display: none;
}

@page jokes {
  margin: 10mm;
}

@media print {
  html:has(.joke-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.joke-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.joke-sheet) > :not(main),
  body:has(.joke-sheet) main > :not(.joke-sheet) {
    display: none !important;
  }

  body:has(.joke-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .joke-sheet {
    page: jokes;
    display: block;
    color: #000;
    font: 11pt/1.3 var(--sans);
  }

  .joke-slips {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: 5cm;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .joke-slip {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 0.3cm;
    padding: 0.45cm 0.5cm;
    border-right: 1pt dashed #000;
    border-bottom: 1pt dashed #000;
    break-inside: avoid;
    overflow: hidden;
    overflow-wrap: anywhere;
    text-align: center;
  }

  /* Ten slips a page: the two at the top of each page and the left ones close the dashed lines. */
  .joke-slip:nth-child(10n + 1),
  .joke-slip:nth-child(10n + 2) {
    border-top: 1pt dashed #000;
  }

  .joke-slip:nth-child(odd) {
    border-left: 1pt dashed #000;
  }

  .joke-slip p {
    margin: 0;
  }

  .joke-slip-question {
    font-size: 12pt;
    font-weight: 650;
  }

  .joke-flip {
    transform: rotate(180deg);
    font-size: 11pt;
  }

  .joke-site {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    margin: 0;
    font: 8pt/1 var(--sans);
    color: #888;
    text-align: center;
  }
}

/* ---------- Christmas mazes (/puzzles/maze) ---------- */

/* On the screen: the mazes two a level (`.mazes`), each on white – its task with its level after it, the maze as wide
   as the column (an SVG, `height: auto`, so a 360 px phone never scrolls sideways) and its way through under it in
   `.maze-answer`, a `<details>`. The sheet to print (`.maze-sheet`) is not on the screen; printed (`@media print`), it
   is all there is: a maze a page – a line for the name, its task and level, the maze 190 × 215 mm at most, so a cell
   of the easy ones prints at least 15 mm, of the medium ones 11 mm and of the hard ones 7.3 mm –, then the six ways
   through, small, two a row on a seventh page: seven pages of A4 or US Letter, none split, none empty. „santa.haus”
   small and grey at the foot of each. */
.mazes {
  padding: 0 0.25rem;
  scroll-margin-top: 1rem;
}

.maze-pair {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
}

.maze {
  min-width: 0;
  margin: 0;
  padding: 1rem 0.75rem;
  border-radius: 20px;
  background: #fff;
  color: #000;
  overflow-wrap: anywhere;
  scroll-margin-top: 1rem;
}

.maze figcaption {
  margin: 0 0.25rem 0.75rem;
  font-weight: 650;
}

.maze-tag {
  display: block;
  font-weight: 400;
  color: #555;
}

.maze-drawing {
  display: block;
  width: 100%;
  height: auto;
}

.maze-label {
  font-family: var(--sans);
  font-weight: 700;
}

/* The maze walked on the screen (public/app.js, `.maze-on`): the way drawn in red from the start, the walls over it,
   its end a red dot; the way through, under „Show the way”, a broad green band under it. Drawing on the maze does not
   scroll the page, select its words or open a menu. Traced out and the dot hopping at the finish only for those who
   do not ask the screen to keep still. */
.maze-on .maze-drawing {
  touch-action: none;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

.maze-walked,
.maze-shown {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.maze-walked {
  stroke: var(--red);
  stroke-width: 4;
}

.maze-shown {
  display: none;
  stroke: #2f8f5b;
  stroke-opacity: 0.4;
  stroke-width: 7;
}

.maze-shown-on {
  display: inline;
}

.maze-at {
  fill: var(--red);
  stroke: #fff;
  stroke-width: 1.5;
}

@media (prefers-reduced-motion: no-preference) {
  .maze-shown-on {
    stroke-dasharray: 1;
    animation: maze-trace 1.2s var(--ease-out) both;
  }

  .maze-won .maze-at {
    transform-box: fill-box;
    transform-origin: center;
    animation: maze-hop 0.45s ease-in-out 3;
  }
}

@keyframes maze-trace {
  from {
    stroke-dashoffset: 1;
  }

  to {
    stroke-dashoffset: 0;
  }
}

@keyframes maze-hop {
  50% {
    transform: scale(1.7);
  }
}

/* The six mazes to pick from (`.maze-pick`), over the maze walked: their shapes, two a level under its name, the one
   walked marked; what the maze says (`.maze-said`, aria-live) and its buttons under it. */
.maze-pick {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
}

.maze-pick[hidden] {
  display: none;
}

.maze-pick p {
  display: grid;
  grid-template-columns: auto auto;
  justify-items: center;
  gap: 0 0.25rem;
  margin: 0;
}

.maze-pick span {
  grid-column: 1 / -1;
  font-size: 0.75rem;
  line-height: 1.4;
  color: #555;
}

.maze-pick a {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 2px solid var(--line);
  border-radius: 12px;
  color: var(--night);
}

.maze-pick a[aria-current] {
  border-color: var(--red);
  color: var(--red);
}

.maze-pick svg {
  width: 1.875rem;
  height: 1.875rem;
  fill: currentColor;
}

.maze-said {
  min-height: 1.5em;
  margin: 0.5rem 0.5rem 0;
  text-align: center;
  font-size: 0.9375rem;
}

.maze-won .maze-said {
  font-weight: 700;
  color: var(--red-deep);
}

.maze-tools {
  margin: 0.5rem 0 0;
  text-align: center;
}

.maze-answer {
  margin-top: 0.75rem;
}

.maze-answer summary {
  cursor: pointer;
  width: fit-content;
  margin: 0 0.25rem 0.75rem;
  font-weight: 650;
  color: var(--red-deep);
}

.maze-sheet {
  display: none;
}

@page maze {
  margin: 10mm;
}

@media print {
  html:has(.maze-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.maze-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.maze-sheet) > :not(main),
  body:has(.maze-sheet) main > :not(.maze-sheet) {
    display: none !important;
  }

  body:has(.maze-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .maze-sheet {
    page: maze;
    display: block;
    color: #000;
    font: 11pt/1.3 var(--sans);
  }

  .maze-page,
  .maze-key {
    break-inside: avoid;
  }

  .maze-page {
    break-after: page;
  }

  .maze-name {
    display: flex;
    align-items: baseline;
    gap: 2mm;
    margin: 0 0 3mm;
    font-size: 12pt;
  }

  .maze-line {
    width: 70mm;
    border-bottom: 0.8pt solid #000;
  }

  .maze-page h2,
  .maze-key h2 {
    margin: 0;
    font: 700 15pt/1.2 var(--sans);
    color: #000;
    text-align: center;
  }

  .maze-level {
    margin: 1mm 0 3mm;
    color: #444;
    text-align: center;
  }

  .maze-page .maze-drawing {
    width: 100%;
    height: 215mm;
  }

  .maze-key-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3mm 8mm;
    margin-top: 4mm;
  }

  .maze-key figure {
    margin: 0;
  }

  .maze-key figcaption {
    font-size: 8.5pt;
    text-align: center;
  }

  .maze-key .maze-drawing {
    width: 100%;
    height: 68mm;
  }

  .maze-site {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    margin: 0;
    font: 8pt/1 var(--sans);
    color: #888;
    text-align: center;
  }
}

/* ---------- Christmas one-minute party games (/party/minute-games) ---------- */

/* On the screen: links to the three sections, then the games of each (`.party-games`) on snow paper
   (`.party-game`) – the name, what it needs, how it is played and a line with the minutes, players and age. A long
   word breaks rather than pushing a 360 px phone sideways. The sheet to print (`.party-sheet`) is not on the screen;
   printed (`@media print`), it is all there is: the 15 games as cards of 84 mm in dashed lines to cut along, two a row
   and three rows a page (the 252 mm fit the 259 mm of US Letter inside the margins), none split between two pages,
   then the score sheet on a fourth page – a row a game, a column for each of six teams with room for its name at the
   top, and the total. „santa.haus” small and grey at the foot of each page. */
.party-toc {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
}

.party-toc a {
  font-weight: 650;
}

.party-games {
  padding: 0 0.25rem;
  scroll-margin-top: 1rem;
}

.party-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr));
}

.party-game {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
  padding: 1rem 1.25rem 1.125rem;
  background: var(--snow);
  color: var(--ink);
  border-radius: 14px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
  overflow-wrap: anywhere;
  scroll-margin-top: 1rem;
}

.party-game h3,
.party-game p {
  margin: 0;
}

.party-game .hint {
  margin-top: auto;
  color: #555;
  font-size: 0.9em;
}

.party-sheet {
  display: none;
}

@page party {
  margin: 10mm;
}

@media print {
  html:has(.party-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.party-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.party-sheet) > :not(main),
  body:has(.party-sheet) main > :not(.party-sheet) {
    display: none !important;
  }

  body:has(.party-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .party-sheet {
    page: party;
    display: block;
    color: #000;
    font: 9.5pt/1.3 var(--sans);
  }

  .party-cards {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: 84mm;
    margin: 0;
    padding: 0;
    list-style: none;
    break-after: page;
  }

  .party-card {
    display: flex;
    flex-direction: column;
    gap: 1.6mm;
    padding: 5mm 5.5mm;
    border-right: 1pt dashed #000;
    border-bottom: 1pt dashed #000;
    break-inside: avoid;
    overflow: hidden;
    overflow-wrap: anywhere;
  }

  /* Six cards a page: the two at the top and the left ones close the dashed lines. */
  .party-card:nth-child(-n + 2) {
    border-top: 1pt dashed #000;
  }

  .party-card:nth-child(odd) {
    border-left: 1pt dashed #000;
  }

  .party-card p,
  .party-card h3 {
    margin: 0;
  }

  .party-card-section {
    font-size: 8pt;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #555;
  }

  .party-card h3 {
    font: 700 13pt/1.15 var(--sans);
    color: #000;
  }

  .party-how {
    flex: 1;
  }

  .party-time {
    font-weight: 650;
  }

  .party-score {
    break-inside: avoid;
  }

  .party-score h2 {
    margin: 0 0 4mm;
    font: 700 15pt/1.2 var(--sans);
    color: #000;
    text-align: center;
  }

  .party-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
  }

  .party-table th,
  .party-table td {
    height: 12mm;
    padding: 1mm 2mm;
    border: 0.8pt solid #000;
    font: 9pt/1.2 var(--sans);
    color: #000;
    text-align: left;
    overflow-wrap: anywhere;
  }

  .party-table tr > :first-child {
    width: 34%;
    font-weight: 650;
  }

  /* Room at the top of each team's column for its name. */
  .party-table thead th {
    height: 18mm;
    vertical-align: top;
    font-size: 8pt;
    font-weight: 400;
    color: #555;
  }

  .party-table thead th:first-child {
    vertical-align: bottom;
    font-size: 9pt;
    font-weight: 650;
    color: #000;
  }

  .party-total th,
  .party-total td {
    border-top-width: 2pt;
  }

  .party-site {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    margin: 0;
    font: 8pt/1 var(--sans);
    color: #888;
    text-align: center;
  }
}

/* ---------- The features (/{language}/, the home pages of the games, under each game) ---------- */

/* Each feature or game a card of the night (`directory::Features`, `games::Home`): its name in handwriting – a link, and
   the whole card is one to tap – and a line of what it is under it. */
.features {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

.features > li {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  padding: 1rem 1.125rem;
  border-radius: 16px;
  background: var(--night-up);
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.features > li:hover,
.features > li:focus-within {
  outline: 2px solid var(--gold);
}

.features > li > a {
  font: 700 1.625rem/1.15 var(--hand);
  color: var(--snow);
  text-decoration: none;
}

.features > li > a::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.features > li > span {
  color: var(--muted-night);
}

/* The home page of the site: Secret Santa the whole width and bigger, on the red of the hat; the advent calendar under
   it, or beside it where there is room. */
.feature-santa {
  grid-column: 1 / -1;
}

.features > .feature-santa {
  padding: 1.375rem 1.375rem 1.5rem;
  background: var(--red-deep);
}

.features > .feature-santa > a {
  font-size: 2.25rem;
}

.features > .feature-santa > span {
  color: var(--snow);
}

/* The games of each of the four on the home page, under its name: links of their own above the card's link, which
   covers the card; tall enough for a finger. */
.tile-games {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tile-games a {
  position: relative;
  z-index: 1;
  display: inline-block;
  padding: 0.5rem 0;
  color: var(--snow);
  text-decoration-color: var(--muted-night);
}

.tile-games a:hover {
  color: var(--gold);
}

/* A game's line follows its heading elsewhere, so it starts small. */
.games span::first-letter {
  text-transform: uppercase;
}

/* ---------- Christmas ornaments to print (/printables/ornaments) ---------- */

/* The sheet (`.ornament-sheet`): four kinds, each its heading and steps over its pages of paper (`.ornament-page`) –
   on the screen white A4 pages side by side, smaller, the things on them in the same places. Printed (`@page
   ornaments`), only the pages, each on its own sheet of A4: the ornaments 85 × 119 mm, the 3D parts 85 × 85 mm with
   their letter, the strips 160 × 22 mm, the flags 90 × 90 mm – within 198 × 280 mm. */
.ornament-kind {
  display: grid;
  gap: 0.75rem;
  margin: 0 0 2rem;
}

.ornament-kind h2,
.ornament-kind .steps {
  margin: 0;
}

.ornament-pages {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
}

.ornament-page {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: center;
  gap: 1.5% 3%;
  aspect-ratio: 210 / 297;
  padding: 3%;
  background: #fff;
  color: #000;
  border-radius: 4px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.ornament-page svg {
  display: block;
  height: auto;
}

.ornament-hang {
  width: 42%;
}

.ornament-part {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 38%;
  margin: 0;
  font: 700 0.75rem/1.2 var(--sans);
}

.ornament-part svg {
  width: 100%;
}

.ornament-strip {
  width: 80%;
}

.ornament-flag {
  width: 43%;
}

@page ornaments {
  size: A4 portrait;
  margin: 6mm;
}

@media print {
  html:has(.ornament-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.ornament-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.ornament-sheet) > :not(main),
  body:has(.ornament-sheet) main > :not(.ornament-sheet),
  .ornament-kind > :not(.ornament-pages) {
    display: none !important;
  }

  body:has(.ornament-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .ornament-sheet {
    page: ornaments;
    display: block;
  }

  .ornament-kind,
  .ornament-pages {
    display: block;
    margin: 0;
  }

  .ornament-page {
    height: 280mm;
    aspect-ratio: auto;
    padding: 0;
    gap: 4mm 6mm;
    border-radius: 0;
    box-shadow: none;
    overflow: hidden;
    break-inside: avoid;
    break-after: page;
  }

  .ornament-kind:last-child .ornament-page:last-child {
    break-after: auto;
  }

  .ornament-hang,
  .ornament-part {
    width: 85mm;
  }

  .ornament-part {
    font-size: 10pt;
  }

  .ornament-strip {
    width: 160mm;
  }

  .ornament-flag {
    width: 90mm;
  }
}

/* ---------- Christmas place cards to print (/printables/place-cards) ---------- */

/* The sheet (`.place-sheet`): two pages of paper (`.place-page`), six cards each – on the screen white sheets, the
   cards as the printer gives them. A card is two halves around the dashed fold: the back on top, upside down so it
   reads upright once folded into a tent, a star and the question; the front below, a drawing to color and the name –
   what is typed in blue pen, „Name” in grey until then. Printed (`@page placecards`), only the pages, each on its own
   sheet of A4 or US Letter: two across and three down, 95 × 84 mm each – 190 × 252 mm inside the margins of both
   (190 × 277 mm and 195.9 × 259.4 mm); an empty field a line to write on by hand, its placeholder not at all, a full
   one the name alone. */
.place-sheet {
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.place-page {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  padding: 1rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

@media (min-width: 36rem) {
  .place-page {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.place-card {
  display: grid;
  grid-template-rows: 1fr 1fr;
  aspect-ratio: 95 / 84;
  border: 1px solid #000;
  break-inside: avoid;
}

.place-back {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  min-height: 0;
  padding: 0.5rem 1rem;
  text-align: center;
  transform: rotate(180deg);
}

.place-back svg {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
}

.place-back p {
  margin: 0;
  font: 600 0.9375rem/1.25 var(--sans);
  text-wrap: balance;
}

.place-front {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 0;
  padding: 0 0.75rem;
  border-top: 1px dashed #000;
}

.place-drawing {
  flex: none;
  width: auto;
  height: 80%;
}

.place-front input {
  flex: 1;
  min-width: 0;
  padding: 0 0.125rem;
  border: 0;
  border-bottom: 1.5px solid #000;
  border-radius: 0;
  background: transparent;
  color: var(--pen);
  font: 700 2rem/1.2 var(--hand);
  text-align: center;
}

.place-front input[type="text"]:focus {
  border-color: #000;
  outline: 2px solid rgb(43 76 140 / 0.35);
}

.place-front input::placeholder {
  color: #9aa5b8;
  opacity: 1;
}

@page placecards {
  margin: 10mm;
}

@media print {
  html:has(.place-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.place-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.place-sheet) > :not(main),
  body:has(.place-sheet) main > :not(.place-sheet) {
    display: none !important;
  }

  body:has(.place-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .place-sheet {
    page: placecards;
    display: block;
  }

  .place-page {
    grid-template-columns: repeat(2, 95mm);
    grid-auto-rows: 84mm;
    justify-content: center;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
  }

  .place-page:last-child {
    break-after: auto;
  }

  .place-card {
    aspect-ratio: auto;
    border: 0.3mm solid #000;
  }

  .place-back {
    gap: 2mm;
    padding: 3mm 6mm;
  }

  .place-back svg {
    width: 5mm;
    height: 5mm;
  }

  .place-back p {
    font-size: 11pt;
  }

  .place-front {
    gap: 3mm;
    padding: 0 5mm 0 4mm;
    border-top: 0.3mm dashed #000;
  }

  .place-drawing {
    height: 34mm;
  }

  .place-front input {
    border-bottom: 0.3mm solid #000;
    color: #000;
    font-size: 26pt;
  }

  .place-front input::placeholder {
    color: transparent;
  }

  .place-front input:not(:placeholder-shown) {
    border-bottom-color: transparent;
  }
}

/* ---------- Christmas gift vouchers to print (/printables/gift-vouchers) ---------- */

/* The sheet (`.voucher-sheet`): two pages of paper (`.voucher-page`), four vouchers each – on the screen white sheets.
   A voucher: a solid cut line, a dashed frame inside it, a drawing to color on the left and on the right its title and
   four fields – what is typed in blue pen, a hint in grey until then. Printed (`@page vouchers`), only the pages, each
   on its own sheet of A4 or US Letter: four vouchers 190 × 64 mm one under another – 190 × 256 mm inside the margins of
   both (190 × 277 mm and 195.9 × 259.4 mm); an empty field a line to write on by hand, its hint not at all, a full one
   its text alone. */
.voucher-sheet {
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.voucher-page {
  display: grid;
  gap: 0.75rem;
  padding: 1rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.voucher {
  position: relative;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.25rem 1.5rem;
  border: 1px solid #000;
  break-inside: avoid;
}

.voucher::before {
  content: "";
  position: absolute;
  inset: 0.5rem;
  border: 1.5px dashed #000;
  pointer-events: none;
}

.voucher-drawing {
  flex: none;
  width: auto;
  height: 7rem;
}

.voucher-body {
  display: grid;
  flex: 1;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: end;
  gap: 0.25rem 0.5rem;
  min-width: 0;
}

.voucher-title {
  grid-column: 1 / -1;
  margin: 0 0 0.25rem;
  font: 700 2rem/1.1 var(--hand);
  text-align: center;
}

.voucher-body label {
  display: contents;
}

.voucher-body span {
  padding-bottom: 0.25rem;
  font: 600 0.8125rem/1.2 var(--sans);
  white-space: nowrap;
}

.voucher-body input {
  width: 100%;
  min-width: 0;
  padding: 0 0.125rem;
  border: 0;
  border-bottom: 1.5px solid #000;
  border-radius: 0;
  background: transparent;
  color: var(--pen);
  font: 700 1.375rem/1.2 var(--hand);
}

.voucher-body input[type="text"]:focus {
  border-color: #000;
  outline: 2px solid rgb(43 76 140 / 0.35);
}

.voucher-body input::placeholder {
  color: #9aa5b8;
  opacity: 1;
}

@media (max-width: 30rem) {
  .voucher {
    gap: 0.5rem;
    padding: 1.25rem 1rem;
  }

  .voucher-drawing {
    height: 4rem;
  }
}

@page vouchers {
  margin: 10mm;
}

@media print {
  html:has(.voucher-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.voucher-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.voucher-sheet) > :not(main),
  body:has(.voucher-sheet) main > :not(.voucher-sheet) {
    display: none !important;
  }

  body:has(.voucher-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .voucher-sheet {
    page: vouchers;
    display: block;
  }

  .voucher-page {
    grid-template-columns: 190mm;
    grid-auto-rows: 64mm;
    justify-content: center;
    gap: 0;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
  }

  .voucher-page:last-child {
    break-after: auto;
  }

  .voucher {
    gap: 6mm;
    padding: 0 9mm 0 8mm;
    border: 0.3mm solid #000;
  }

  .voucher::before {
    inset: 3mm;
    border: 0.4mm dashed #000;
  }

  .voucher-drawing {
    height: 48mm;
  }

  .voucher-body {
    gap: 1.5mm 3mm;
  }

  .voucher-title {
    margin-bottom: 1mm;
    font-size: 24pt;
  }

  .voucher-body span {
    padding-bottom: 1mm;
    font-size: 10pt;
  }

  .voucher-body input {
    border-bottom: 0.3mm solid #000;
    color: #000;
    font-size: 15pt;
  }

  .voucher-body input::placeholder {
    color: transparent;
  }

  .voucher-body input:not(:placeholder-shown) {
    border-bottom-color: transparent;
  }
}

/* ---------- Christmas planner to print (/printables/planner) ---------- */

/* The sheet (`.planner-sheet`): three pages of paper (`.planner-page`) – on the screen white sheets –, each under a
   drawing to color and its heading: the gift list (a table with boxes to tick and a line for the total), the plan
   (four stages of tasks with a box each, two empty lines to add own ones), the menu, the shopping list and the cards.
   Black lines on white, nothing to type: filled in by hand. Printed (`@page planner`), only the pages, each on its own
   sheet of A4 or US Letter, 190 mm wide and at most 255 mm high – inside the margins of both (190 × 277 mm and
   195.9 × 259.4 mm). */
.planner-sheet {
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.planner-page {
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.planner-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
}

.planner-drawing {
  flex: none;
  width: auto;
  height: 4rem;
}

.planner-head h2 {
  margin: 0;
  color: #000;
  font: 700 2.25rem/1.1 var(--hand);
}

.planner-page h3 {
  margin: 0.75rem 0 0.25rem;
  color: #000;
  font: 700 1rem/1.3 var(--sans);
}

.planner-gifts {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}

.planner-gifts th,
.planner-gifts td {
  border: 1px solid #000;
  padding: 0.25rem 0.375rem;
  overflow-wrap: anywhere;
  hyphens: auto;
}

.planner-gifts th {
  font: 600 0.8125rem/1.2 var(--sans);
  text-align: left;
}

.planner-gifts th:nth-child(1) {
  width: 21%;
}

.planner-gifts th:nth-child(2) {
  width: 38%;
}

.planner-gifts th:nth-child(3) {
  width: 15%;
}

.planner-gifts th:nth-child(n + 4),
.planner-gifts td:nth-child(n + 4) {
  text-align: center;
}

.planner-gifts td {
  height: 2.25rem;
}

.planner-box,
.planner-checks li::before {
  display: inline-block;
  flex: none;
  width: 0.875rem;
  height: 0.875rem;
  border: 1.5px solid #000;
  border-radius: 2px;
  vertical-align: middle;
}

.planner-total {
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
  margin: 1rem 0 0 auto;
  width: 50%;
  font: 700 1rem/1.2 var(--sans);
}

.planner-blank {
  flex: 1;
  border-bottom: 1.5px solid #000;
}

.planner-lines {
  margin: 0;
  padding: 0;
  list-style: none;
}

.planner-lines li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 1.75rem;
  border-bottom: 1px solid #000;
  font: 400 0.9375rem/1.3 var(--sans);
}

.planner-checks li::before {
  content: "";
}

.planner-menu li {
  min-height: 3.5rem;
}

.planner-food {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.5rem;
}

.planner-cards .planner-lines {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: 1.5rem;
}

.planner-tasks {
  margin-top: 0.25rem;
}

@media (max-width: 30rem) {
  .planner-page {
    padding: 0.75rem;
  }

  .planner-food {
    grid-template-columns: minmax(0, 1fr);
  }
}

@page planner {
  margin: 10mm;
}

@media print {
  html:has(.planner-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.planner-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.planner-sheet) > :not(main),
  body:has(.planner-sheet) main > :not(.planner-sheet) {
    display: none !important;
  }

  body:has(.planner-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .planner-sheet {
    page: planner;
    display: block;
  }

  .planner-page {
    box-sizing: border-box;
    width: 190mm;
    margin: 0 auto;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .planner-page:last-child {
    break-after: auto;
  }

  .planner-head {
    gap: 4mm;
    height: 18mm;
    margin-bottom: 4mm;
  }

  .planner-drawing {
    height: 18mm;
  }

  .planner-head h2 {
    font-size: 26pt;
  }

  .planner-page h3 {
    margin: 3mm 0 1mm;
    font-size: 11pt;
  }

  .planner-gifts th,
  .planner-gifts td {
    border: 0.3mm solid #000;
    padding: 1mm 1.5mm;
  }

  .planner-gifts th {
    height: 8mm;
    font-size: 8.5pt;
  }

  .planner-gifts td {
    height: 12mm;
    padding: 0 1.5mm;
  }

  .planner-box,
  .planner-checks li::before {
    width: 3.5mm;
    height: 3.5mm;
    border-width: 0.3mm;
  }

  .planner-total {
    margin-top: 5mm;
    font-size: 11pt;
  }

  .planner-blank {
    border-bottom-width: 0.3mm;
  }

  .planner-lines li {
    box-sizing: border-box;
    gap: 2mm;
    height: 7.5mm;
    min-height: 0;
    border-bottom-width: 0.2mm;
    font-size: 10pt;
  }

  .planner-stage .planner-lines li {
    height: 5.8mm;
  }

  .planner-stage h3 {
    margin-top: 2.5mm;
  }

  .planner-menu li {
    height: 15mm;
  }

  .planner-food {
    gap: 8mm;
  }

  .planner-cards {
    margin-top: 5mm;
  }

  .planner-cards .planner-lines {
    column-gap: 8mm;
  }
}

/* ---------- Paper snowflakes (/printables/paper-snowflakes) ---------- */

/* The sheet (`.snowflake-sheet`): two pages of paper (`.snowflake-page`) – on the screen white sheets. Page 1: the five
   steps of folding, drawn, and the eight snowflakes unfolded (`.snowflake-preview`, white on blue on the screen, grey
   on paper); page 2: a legend and the eight templates (`.snowflake-template`) – printed 40.32 × 76.32 mm, 0.72 mm a
   unit of the drawing: 72 mm from the tip to the arc, at 100% scale. Printed (`@page snowflakes`), only the pages, each
   on its own sheet of A4 or US Letter, 190 mm wide and at most 255 mm high. Below the sheet, on the screen only, each
   snowflake with its template (`.snowflake-cards`). */
.snowflake-sheet {
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.snowflake-page {
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.snowflake-page h2 {
  margin: 0 0 0.75rem;
  color: #000;
  font: 700 2rem/1.1 var(--hand);
}

.snowflake-folds {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0.75rem;
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
  counter-reset: snowflake-fold;
}

.snowflake-folds li {
  display: grid;
  justify-items: center;
  gap: 0.25rem;
  text-align: center;
  font: 600 0.8125rem/1.25 var(--sans);
  counter-increment: snowflake-fold;
}

.snowflake-folds span::before {
  content: counter(snowflake-fold) ". ";
}

.snowflake-folds svg {
  width: 100%;
  max-width: 6rem;
  height: auto;
}

.snowflake-previews,
.snowflake-templates {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.75rem;
}

.snowflake-figure {
  display: grid;
  justify-items: center;
  gap: 0.25rem;
  margin: 0;
  font: 600 0.8125rem/1.25 var(--sans);
  text-align: center;
}

.snowflake-preview {
  width: 100%;
  height: auto;
  border-radius: 50%;
  background: #1d3c78;
}

.snowflake-template {
  width: 100%;
  max-width: 8rem;
  height: auto;
}

.snowflake-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
  font: 400 0.875rem/1.3 var(--sans);
}

.snowflake-legend li {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.snowflake-legend svg {
  width: 1rem;
  height: 1rem;
}

.snowflake-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  gap: 1rem;
}

.snowflake-card {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 1.4fr);
  align-items: center;
  gap: 0.75rem;
  margin: 0;
  padding: 0.75rem;
  border-radius: 6px;
  background: #1d3c78;
  color: #fff;
}

.snowflake-card .snowflake-preview {
  border-radius: 0;
  background: none;
}

.snowflake-card .snowflake-template {
  border-radius: 4px;
  background: #fff;
}

.snowflake-card figcaption {
  grid-column: 1 / -1;
  font: 600 0.9375rem/1.3 var(--sans);
}

@media (max-width: 30rem) {
  .snowflake-page {
    padding: 0.75rem;
  }

  .snowflake-folds {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .snowflake-previews,
  .snowflake-templates {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@page snowflakes {
  margin: 10mm;
}

@media print {
  html:has(.snowflake-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.snowflake-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.snowflake-sheet) > :not(main),
  body:has(.snowflake-sheet) main > :not(.snowflake-sheet) {
    display: none !important;
  }

  body:has(.snowflake-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .snowflake-sheet {
    page: snowflakes;
    display: block;
  }

  .snowflake-page {
    box-sizing: border-box;
    width: 190mm;
    margin: 0 auto;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .snowflake-page:last-child {
    break-after: auto;
  }

  .snowflake-page h2 {
    margin-bottom: 5mm;
    font-size: 24pt;
  }

  .snowflake-folds {
    gap: 4mm;
    margin-bottom: 8mm;
  }

  .snowflake-folds li {
    gap: 1mm;
    font-size: 9pt;
  }

  .snowflake-folds svg {
    width: 30mm;
    max-width: none;
  }

  .snowflake-previews {
    grid-template-columns: repeat(4, 40mm);
    justify-content: space-between;
    gap: 6mm 0;
  }

  .snowflake-figure {
    gap: 1.5mm;
    font-size: 9pt;
  }

  .snowflake-preview {
    width: 40mm;
    height: 40mm;
    border-radius: 0;
    background: none;
  }

  .snowflake-paper {
    fill: #bbb;
  }

  .snowflake-legend {
    gap: 2mm 8mm;
    margin-bottom: 6mm;
    font-size: 10pt;
  }

  .snowflake-legend svg {
    width: 4mm;
    height: 4mm;
  }

  .snowflake-templates {
    grid-template-columns: repeat(4, 40.32mm);
    justify-content: space-between;
    gap: 8mm 0;
  }

  .snowflake-template {
    width: 40.32mm;
    height: 76.32mm;
    max-width: none;
  }
}

/* ---------- Gingerbread house template (/printables/gingerbread-house) ---------- */

/* The sheet (`.gingerbread-sheet`): two pages of paper (`.gingerbread-page`) – on the screen white sheets. Each a
   heading and a drawing of its pieces (`.gingerbread-pieces`), a unit of it a millimetre: printed 190 mm wide, the
   pieces at their real size at 100% scale, with a scale bar of 5 cm. Page 1: the list of the pieces, the gable wall
   and the chimney; page 2: the side wall and the roof. Printed (`@page gingerbread`), only the pages, each on its own
   sheet of A4 or US Letter, 190 mm wide and at most 252 mm high. Below the sheet, on the screen only, the house put
   together (`.gingerbread-house`) and the table of measurements (`.gingerbread-table`). */
.gingerbread-sheet {
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.gingerbread-page {
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.gingerbread-page h2 {
  margin: 0 0 0.75rem;
  color: #000;
  font: 700 2rem/1.1 var(--hand);
}

.gingerbread-list {
  margin: 0 0 1rem;
  padding-left: 1.25rem;
  font: 400 0.9375rem/1.4 var(--sans);
}

.gingerbread-pieces {
  display: block;
  width: 100%;
  max-width: 190mm;
  height: auto;
}

.gingerbread-pieces text {
  font-family: var(--sans);
}

.gingerbread-figure {
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  margin: 0;
  font: 600 0.9375rem/1.3 var(--sans);
  text-align: center;
}

.gingerbread-house {
  width: 100%;
  max-width: 18rem;
  height: auto;
}

.gingerbread-table {
  overflow-x: auto;
}

.gingerbread-table table {
  width: 100%;
  border-collapse: collapse;
  font: 400 0.9375rem/1.35 var(--sans);
}

.gingerbread-table th,
.gingerbread-table td {
  padding: 0.375rem 0.5rem;
  border-bottom: 1px solid rgb(127 127 127 / 0.35);
  text-align: left;
  vertical-align: top;
}

.gingerbread-table td:not(:last-child) {
  white-space: nowrap;
}

@media (max-width: 30rem) {
  .gingerbread-page {
    padding: 0.75rem;
  }
}

@page gingerbread {
  margin: 10mm;
}

@media print {
  html:has(.gingerbread-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.gingerbread-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.gingerbread-sheet) > :not(main),
  body:has(.gingerbread-sheet) main > :not(.gingerbread-sheet) {
    display: none !important;
  }

  body:has(.gingerbread-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .gingerbread-sheet {
    page: gingerbread;
    display: block;
  }

  .gingerbread-page {
    box-sizing: border-box;
    width: 190mm;
    margin: 0 auto;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .gingerbread-page:last-child {
    break-after: auto;
  }

  .gingerbread-page h2 {
    margin-bottom: 4mm;
    font-size: 20pt;
  }

  .gingerbread-list {
    margin-bottom: 5mm;
    padding-left: 5mm;
    font-size: 9.5pt;
    line-height: 1.35;
  }

  .gingerbread-pieces {
    width: 190mm;
    max-width: none;
  }
}

/* ---------- Gift box template (/printables/gift-box) ---------- */

/* The sheet (`.giftbox-sheet`): three pages of paper (`.giftbox-page`) – on the screen white sheets. Each a heading
   and a drawing of its net (`.giftbox-nets`), a unit of it a millimetre: printed 190 mm wide, the boxes at their real
   size at 100% scale, with a scale bar of 5 cm. Page 1: the cube and what the lines say; page 2: the box for a gift
   card; page 3: the box with a lid, its bottom and its lid. Printed (`@page giftbox`), only the pages, each on its own
   sheet of A4 or US Letter, 190 mm wide and at most 252 mm high. Below the sheet, on the screen only, the boxes put
   together (`.giftbox-boxes`) and the table of the boxes (`.giftbox-table`). The scene's `.gift-box` is another. */
.giftbox-sheet {
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.giftbox-page {
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.giftbox-page h2 {
  margin: 0 0 0.75rem;
  color: #000;
  font: 700 1.75rem/1.1 var(--hand);
}

.giftbox-nets {
  display: block;
  width: 100%;
  max-width: 190mm;
  height: auto;
}

.giftbox-nets text {
  font-family: var(--sans);
}

.giftbox-figure {
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  margin: 0;
  font: 600 0.9375rem/1.3 var(--sans);
  text-align: center;
}

.giftbox-boxes {
  width: 100%;
  max-width: 24rem;
  height: auto;
}

.giftbox-table {
  overflow-x: auto;
}

.giftbox-table table {
  width: 100%;
  border-collapse: collapse;
  font: 400 0.9375rem/1.35 var(--sans);
}

.giftbox-table th,
.giftbox-table td {
  padding: 0.375rem 0.5rem;
  border-bottom: 1px solid rgb(127 127 127 / 0.35);
  text-align: left;
  vertical-align: top;
}

.giftbox-table td:nth-child(2) {
  white-space: nowrap;
}

@media (max-width: 30rem) {
  .giftbox-page {
    padding: 0.75rem;
  }
}

@page giftbox {
  margin: 10mm;
}

@media print {
  html:has(.giftbox-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.giftbox-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.giftbox-sheet) > :not(main),
  body:has(.giftbox-sheet) main > :not(.giftbox-sheet) {
    display: none !important;
  }

  body:has(.giftbox-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .giftbox-sheet {
    page: giftbox;
    display: block;
  }

  .giftbox-page {
    box-sizing: border-box;
    width: 190mm;
    margin: 0 auto;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .giftbox-page:last-child {
    break-after: auto;
  }

  .giftbox-page h2 {
    margin-bottom: 4mm;
    font-size: 16pt;
  }

  .giftbox-nets {
    width: 190mm;
    max-width: none;
  }
}

/* ---------- Christmas dot to dot (/printables/dot-to-dot) ---------- */

/* The sheet (`.dots-sheet`): four pages of paper (`.dots-page`) – on the screen white sheets –, two pictures on each
   (`.dots-item`), its name and level over its drawing (`.dots-picture`, a unit of it 1.1 mm: printed 110 mm wide).
   Printed (`@page dots`), only the pages, each on its own sheet of A4 or US Letter, 190 mm wide and at most 252 mm
   high. Below the sheet, on the screen only, the pictures joined up (`.dots-answer`), small. */
.dots-sheet {
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.dots-page {
  display: grid;
  gap: 1.5rem;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.dots-item {
  display: grid;
  justify-items: center;
  gap: 0.5rem;
}

.dots-item h2 {
  margin: 0;
  color: #000;
  font: 700 1.75rem/1.1 var(--hand);
  text-align: center;
}

.dots-level {
  font: 600 1rem/1.2 var(--sans);
  white-space: nowrap;
}

.dots-picture {
  display: block;
  width: 100%;
  max-width: 110mm;
  height: auto;
}

.dots-picture text {
  font-family: var(--sans);
}

.dots-answer summary {
  cursor: pointer;
  font-weight: 700;
}

.dots-answers {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
  gap: 1rem;
  margin-top: 1rem;
}

.dots-answers figure {
  display: grid;
  justify-items: center;
  gap: 0.25rem;
  margin: 0;
  font: 600 0.875rem/1.3 var(--sans);
  text-align: center;
}

.dots-answers .dots-picture {
  max-width: 10rem;
  background: #fff;
  border-radius: 4px;
}

@media (max-width: 30rem) {
  .dots-page {
    padding: 0.75rem;
  }
}

@page dots {
  margin: 10mm;
}

@media print {
  html:has(.dots-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.dots-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.dots-sheet) > :not(main),
  body:has(.dots-sheet) main > :not(.dots-sheet) {
    display: none !important;
  }

  body:has(.dots-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .dots-sheet {
    page: dots;
    display: block;
  }

  .dots-page {
    box-sizing: border-box;
    width: 190mm;
    margin: 0 auto;
    padding: 0;
    gap: 8mm;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .dots-page:last-child {
    break-after: auto;
  }

  .dots-item {
    gap: 2mm;
  }

  .dots-item h2 {
    font-size: 16pt;
  }

  .dots-level {
    font-size: 11pt;
  }

  .dots-picture {
    width: 110mm;
    max-width: none;
  }
}

/* ---------- Christmas window silhouettes (/printables/window-silhouettes) ---------- */

/* The sheet (`.silhouette-sheet`): eight pages of paper (`.silhouette-page`) – on the screen white sheets –, a
   silhouette on each under its name, level and size, drawn at its real size (`.silhouette-picture`, its width and
   height in mm), shrunk to fit on the screen only. Printed (`@page silhouettes`), only the pages, each on its own
   sheet of A4 or US Letter, 190 mm wide and at most 252 mm high, the silhouettes at 100%. Below the sheet, on the
   screen only, the silhouettes white on a dark window (`.silhouette-window`). */
.silhouette-sheet {
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.silhouette-page {
  display: grid;
  justify-items: center;
  gap: 1rem;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.silhouette-page h2 {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
  margin: 0;
  color: #000;
  font: 700 1.75rem/1.1 var(--hand);
  text-align: center;
}

.silhouette-level,
.silhouette-size {
  font: 600 1rem/1.2 var(--sans);
  white-space: nowrap;
}

.silhouette-picture {
  display: block;
  max-width: 100%;
  height: auto;
}

.silhouette-window {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 1.25rem;
  padding: 1.25rem;
  background: #14213d;
  border-radius: 6px;
}

.silhouette-window figure {
  display: grid;
  grid-template-rows: 10rem auto;
  justify-items: center;
  align-items: end;
  gap: 0.5rem;
  margin: 0;
  color: #fff;
  font: 600 0.875rem/1.3 var(--sans);
  text-align: center;
}

.silhouette-preview {
  display: block;
  width: 100%;
  max-height: 10rem;
}

@media (max-width: 30rem) {
  .silhouette-page {
    padding: 0.75rem;
  }
}

@page silhouettes {
  margin: 10mm;
}

@media print {
  html:has(.silhouette-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.silhouette-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.silhouette-sheet) > :not(main),
  body:has(.silhouette-sheet) main > :not(.silhouette-sheet) {
    display: none !important;
  }

  body:has(.silhouette-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .silhouette-sheet {
    page: silhouettes;
    display: block;
  }

  .silhouette-page {
    box-sizing: border-box;
    width: 190mm;
    margin: 0 auto;
    padding: 0;
    gap: 5mm;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .silhouette-page:last-child {
    break-after: auto;
  }

  .silhouette-page h2 {
    font-size: 16pt;
  }

  .silhouette-level,
  .silhouette-size {
    font-size: 11pt;
  }

  .silhouette-picture {
    max-width: none;
  }
}

/* ---------- Christmas envelope template (/printables/envelopes) ---------- */

/* The sheet (`.envelope-sheet`): three pages of paper (`.envelope-page`) – on the screen white sheets. Each the name
   and size of its envelope, what fits (`.envelope-fits`) and a drawing of its nets (`.envelope-nets`, `.envelope-net`
   each), a unit of it a millimetre, its width and height in mm: printed 190 mm wide, the envelopes at their real size,
   with a scale bar of 5 cm and what the lines say on page 1. Printed (`@page envelopes`), only the pages, each on its
   own sheet of A4 or US Letter, 190 mm wide and at most 252 mm high. The home page's `.envelope-art`, `.envelope-flap`
   and `.envelope-seal` are another. */
.envelope-sheet {
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.envelope-page {
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.envelope-page h2 {
  margin: 0;
  color: #000;
  font: 700 1.75rem/1.1 var(--hand);
}

.envelope-fits {
  margin: 0.25rem 0 0.75rem;
  font: 400 0.9375rem/1.35 var(--sans);
}

.envelope-nets {
  display: block;
  max-width: 100%;
  height: auto;
}

.envelope-nets text {
  font-family: var(--sans);
}

@media (max-width: 30rem) {
  .envelope-page {
    padding: 0.75rem;
  }
}

@page envelopes {
  margin: 10mm;
}

@media print {
  html:has(.envelope-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.envelope-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.envelope-sheet) > :not(main),
  body:has(.envelope-sheet) main > :not(.envelope-sheet) {
    display: none !important;
  }

  body:has(.envelope-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .envelope-sheet {
    page: envelopes;
    display: block;
  }

  .envelope-page {
    box-sizing: border-box;
    width: 190mm;
    margin: 0 auto;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .envelope-page:last-child {
    break-after: auto;
  }

  /* The heading of a page within 12 mm, even with what fits in two lines – the card envelope's net is 240 mm high –,
     its line tall enough for the Vietnamese marks over the letters to stay on its page. */
  .envelope-page h2 {
    font: 700 11pt/1.35 var(--sans);
  }

  .envelope-fits {
    margin: 0.3mm 0 1mm;
    font-size: 7pt;
    line-height: 1.2;
  }

  .envelope-nets {
    max-width: none;
  }
}

/* ---------- Christmas thank you cards (/printables/thank-you-cards) ---------- */

/* The sheet (`.thanks-sheet`): two pages of paper (`.thanks-page`), four cards each (`.thanks-card`) between thin cut
   lines – on the screen white sheets. A child's card: „Thank you!” beside a drawing to color, the fields to fill in on
   lines (`.thanks-field`, `.thanks-line`), a frame to draw the gift in (`.thanks-draw`); a grown-up's: the drawing, a
   printed thank-you (`.thanks-note`), lines to write on and „From:”. Printed (`@page thanks`), only the pages, each on
   its own sheet of A4 or US Letter: 2 × 2 cards of 95 × 120 mm – 190 × 240 mm under a heading of 6 mm, inside the
   margins of both (190 × 277 mm and 195.9 × 259.4 mm); the cut lines an outline on the edge of each card, the same
   line where two meet; nothing within 6 mm of them. Black, white and grey only: for any printer, and to color. */
.thanks-sheet {
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.thanks-page {
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.thanks-page h2 {
  margin: 0 0 0.75rem;
  color: #000;
  font: 700 1.75rem/1.1 var(--hand);
}

.thanks-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 13rem), 1fr));
}

.thanks-card {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  aspect-ratio: 95 / 120;
  padding: 1rem;
  outline: 1px solid #000;
  outline-offset: -0.5px;
  font: 400 0.8125rem/1.3 var(--sans);
}

.thanks-top {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.thanks-art {
  flex: none;
  width: 3rem;
  height: 3rem;
}

.thanks-grown .thanks-art {
  align-self: center;
}

.thanks-hello {
  margin: 0;
  font: 700 2rem/1 var(--hand);
}

.thanks-field {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0 0.375rem;
  min-height: 1.75rem;
  margin: 0;
}

.thanks-line {
  flex: 1 0 3rem;
  height: 1.25rem;
  border-bottom: 1px solid #000;
}

.thanks-draw {
  flex: 1;
  min-height: 6rem;
  margin: 0.5rem 0 0.25rem;
  padding: 0.25rem 0.5rem;
  border: 1px dashed #777;
  border-radius: 8px;
  color: #555;
  font-size: 0.75rem;
}

.thanks-note {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  font: 700 1.375rem/1.15 var(--hand);
  text-align: center;
  text-wrap: balance;
}

.thanks-set h3 {
  margin: 1.5rem 0 0.75rem;
  font: 700 1.625rem/1.1 var(--hand);
}

.thanks-app {
  margin: 1rem 0 0;
}

@media (max-width: 30rem) {
  .thanks-page {
    padding: 0.75rem;
  }
}

@page thanks {
  margin: 10mm;
}

@media print {
  html:has(.thanks-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.thanks-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.thanks-sheet) > :not(main),
  body:has(.thanks-sheet) main > :not(.thanks-sheet) {
    display: none !important;
  }

  body:has(.thanks-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .thanks-sheet {
    page: thanks;
    display: block;
  }

  .thanks-page {
    width: 190mm;
    margin: 0 auto;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .thanks-page:last-child {
    break-after: auto;
  }

  /* The heading of a page within 6 mm, its line tall enough for the Vietnamese marks over the letters. */
  .thanks-page h2 {
    height: 6mm;
    margin: 0;
    font: 700 9pt/1.35 var(--sans);
  }

  .thanks-cards {
    grid-template-columns: repeat(2, 95mm);
    grid-auto-rows: 120mm;
  }

  .thanks-card {
    overflow: hidden;
    gap: 1mm;
    aspect-ratio: auto;
    padding: 7mm;
    outline: 0.25mm solid #000;
    outline-offset: -0.125mm;
    font-size: 10.5pt;
  }

  .thanks-top {
    gap: 4mm;
  }

  .thanks-art {
    width: 18mm;
    height: 18mm;
  }

  .thanks-grown .thanks-art {
    width: 17mm;
    height: 17mm;
  }

  .thanks-hello {
    font-size: 30pt;
  }

  .thanks-field {
    gap: 0 2mm;
    min-height: 8mm;
  }

  .thanks-line {
    flex-basis: 15mm;
    height: 5mm;
    border-bottom: 0.25mm solid #000;
  }

  .thanks-draw {
    min-height: 36mm;
    margin: 2mm 0 1mm;
    padding: 1.5mm 2.5mm;
    border: 0.3mm dashed #777;
    border-radius: 3mm;
    font-size: 8pt;
  }

  .thanks-note {
    font-size: 19pt;
  }

  /* The system's font, wider than Caveat: „ありがとう！” on one line, the thank-you broken between phrases. */
  :root:lang(ja) .thanks-hello,
  :root:lang(ko) .thanks-hello,
  :root:lang(zh-Hans) .thanks-hello {
    font-size: 24pt;
  }

  :root:lang(ja) .thanks-note,
  :root:lang(ko) .thanks-note,
  :root:lang(zh-Hans) .thanks-note {
    font-size: 15pt;
  }
}

:root:lang(ja) .thanks-hello,
:root:lang(ja) .thanks-note {
  word-break: auto-phrase;
}

/* ---------- Christmas bookmarks (/printables/bookmarks) ---------- */

/* The sheet (`.bookmark-sheet`): three pages of paper (`.bookmark-page`), four bookmarks side by side on each
   (`.bookmark`, 47 × 190 mm – `pages::BOOKMARK`), the same size on the screen, where they wrap. On each, the mark of
   a hole for a ribbon (`.bookmark-hole`: ⌀ 6 mm, its middle 10 mm under the top), nothing above 16 mm nor within 5 mm
   of the cut lines (`pages::BOOKMARK_TOP`, `BOOKMARK_CLEAR`). To color: a coloring page's picture 37 mm wide over
   three drawings on a thread; a reading list: a heading in the hand font, eight lines each with a circle to tick; for
   a book given: a drawing, „To:”, a printed wish, three lines and the signature. Printed (`@page bookmarks`), only the
   pages, each on its own sheet of A4 or US Letter: 188 × 190 mm under a heading of 6 mm, inside the margins of both
   (190 × 277 mm and 195.9 × 259.4 mm); the cut lines an outline on the edge of each bookmark, the same line where
   two meet. Black, white and grey only: for any printer, and to color. */
.bookmark-sheet {
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.bookmark-page {
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.bookmark-page h2 {
  margin: 0 0 0.75rem;
  color: #000;
  font: 700 1.75rem/1.1 var(--hand);
}

.bookmark-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, 47mm);
  grid-auto-rows: 190mm;
  justify-content: center;
}

.bookmark {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2.5mm;
  overflow: hidden;
  padding: 16mm 5mm 5mm;
  outline: 0.25mm solid #000;
  outline-offset: -0.125mm;
  font: 400 10pt/1.3 var(--sans);
}

.bookmark-hole {
  position: absolute;
  top: 0;
  left: 0;
  width: 47mm;
  height: 16mm;
}

.bookmark-picture {
  flex: none;
  width: 37mm;
  height: 51.8mm;
}

/* Outlines a little thicker than on a whole page: the picture is a fifth of its size. */
.bookmark-picture .cp-part,
.bookmark-picture .cp-line {
  stroke-width: 3.5;
  cursor: auto;
}

.bookmark-garland {
  flex: none;
  width: 37mm;
  height: 84mm;
  margin: auto 0;
}

.bookmark-art {
  flex: none;
  width: 13mm;
  height: 13mm;
}

.bookmark-gift .bookmark-art {
  width: 28mm;
  height: 28mm;
}

.bookmark-field {
  display: flex;
  align-items: flex-end;
  gap: 1.5mm;
  width: 100%;
  min-height: 8mm;
  margin: 0;
}

/* The name at the foot of the bookmark. */
.bookmark > .bookmark-field:last-child {
  margin-top: auto;
}

.bookmark-line {
  flex: 1 0 8mm;
  height: 5mm;
  border-bottom: 0.25mm solid #000;
}

/* Room for two lines, so the lists of all four start at the same height. */
.bookmark-head {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.1em;
  margin: 1mm 0 0;
  font: 700 22pt/1.05 var(--hand);
  text-align: center;
  text-wrap: balance;
}

.bookmark-books {
  display: grid;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

.bookmark-books li {
  display: flex;
  align-items: flex-end;
  gap: 1.5mm;
  height: 12.5mm;
}

.bookmark-tick {
  flex: none;
  width: 3.5mm;
  height: 3.5mm;
  margin-bottom: 0.4mm;
  border: 0.25mm solid #000;
  border-radius: 50%;
}

.bookmark-wish {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  margin: 0;
  font: 700 19pt/1.1 var(--hand);
  text-align: center;
  text-wrap: balance;
}

.bookmark-from {
  width: 100%;
  margin: 2mm 0 0;
  font-size: 9.5pt;
  font-weight: 600;
  text-align: center;
  text-wrap: balance;
}

/* The system's font, wider than Caveat: the headings and wishes smaller, broken between phrases. */
:root:lang(vi) .bookmark-head,
:root:lang(ja) .bookmark-head,
:root:lang(ko) .bookmark-head,
:root:lang(zh-Hans) .bookmark-head {
  font-size: 13pt;
  line-height: 1.25;
  min-height: 2.5em;
}

:root:lang(vi) .bookmark-wish,
:root:lang(ja) .bookmark-wish,
:root:lang(ko) .bookmark-wish,
:root:lang(zh-Hans) .bookmark-wish {
  font-size: 12.5pt;
  line-height: 1.3;
}

:root:lang(ja) .bookmark-head,
:root:lang(ja) .bookmark-wish {
  word-break: auto-phrase;
}

@media (max-width: 30rem) {
  .bookmark-page {
    padding: 0.75rem;
  }
}

@page bookmarks {
  margin: 10mm;
}

@media print {
  html:has(.bookmark-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.bookmark-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.bookmark-sheet) > :not(main),
  body:has(.bookmark-sheet) main > :not(.bookmark-sheet) {
    display: none !important;
  }

  body:has(.bookmark-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .bookmark-sheet {
    page: bookmarks;
    display: block;
  }

  .bookmark-page {
    width: 188mm;
    margin: 0 auto;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .bookmark-page:last-child {
    break-after: auto;
  }

  /* The heading of a page within 6 mm, its line tall enough for the Vietnamese marks over the letters. */
  .bookmark-page h2 {
    height: 6mm;
    margin: 0;
    font: 700 9pt/1.35 var(--sans);
  }

  .bookmark-row {
    grid-template-columns: repeat(4, 47mm);
    grid-auto-rows: 190mm;
  }
}

/* ---------- Christmas printables hub (/printables/) ---------- */

/* A small drawing beside the heading of each group: black lines in the SVG, drawn grey here to show on the navy. */
.printables-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.printables-head h2 {
  margin: 0;
}

.printables-art {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
}

.printables-art path {
  stroke: #bbb;
  stroke-width: 0.8;
}

/* The links of a group in columns where the screen is wide enough. */
.printables-list {
  columns: 2 18rem;
  column-gap: 2rem;
}

.printables-list li {
  break-inside: avoid;
  margin-bottom: 0.35rem;
}

/* ---------- Christmas menu (/printables/menu) ---------- */

/* Over the sheet, on the screen only and shown by public/app.js: a field for each line of the cards, in columns where
   the screen is wide enough, and the buttons to clear the dishes and bring back the traditional menu. */
.xmenu-inputs {
  display: grid;
  gap: 0.75rem 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
}

.xmenu-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 1rem 0 0;
}

/* The sheet (`.xmenu-sheet`): two pages of paper (`.xmenu-page`). Page 1: one big card for the table (`.xmenu-big`,
   170 × 240 mm) in a double frame; page 2: two cards for the plates (`.xmenu-card`, 90 × 240 mm), the cut lines an
   outline on the edge of each, the same line where the two meet, a frame 3 mm inside it and the words at least 7 mm
   from it. On the screen at three quarters of that size, where a narrow one scrolls sideways. On each card, top to
   bottom: three ornaments, the title in the hand font, the line under it, a line with a star, the dishes in the middle
   of the room left – one a line, a long one on two –, a line with a star and the last line. Text black, the drawings
   and frames in the site's red and green, thin, on white: little ink. Nothing hides what does not fit – it all fits:
   twelve dishes of 40 characters on two lines each in a small card. Printed (`@page xmenu`), only the pages, each on
   its own sheet of A4 or US Letter: 170 or 180 × 240 mm, inside the margins of both (190 × 277 mm and
   195.9 × 259.4 mm). */
.xmenu-sheet {
  /* The green of a green gift (`.gift-green`). */
  --xmenu-green: #2f8f5b;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.xmenu-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.xmenu-pair {
  display: flex;
  width: 180mm;
  margin: 0 auto;
}

.xmenu-card {
  position: relative;
  display: flex;
  flex: none;
  flex-direction: column;
  align-items: center;
  width: 90mm;
  height: 240mm;
  padding: 8mm 7mm 7mm;
  outline: 0.25mm solid #000;
  outline-offset: -0.125mm;
  color: #000;
  font: 400 12pt/1.25 var(--sans);
  text-align: center;
}

/* The frame: a green line 3 mm inside the cut line and a red one 1.2 mm further in. */
.xmenu-card::before,
.xmenu-card::after {
  content: "";
  position: absolute;
  inset: 3mm;
  border: 0.35mm solid var(--xmenu-green);
  pointer-events: none;
}

.xmenu-card::after {
  inset: 4.2mm;
  border: 0.2mm solid var(--red);
}

.xmenu-card [hidden] {
  display: none;
}

.xmenu-art {
  flex: none;
  width: 46mm;
  height: 24.8mm;
}

.xmenu-art g {
  fill: none;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.xmenu-red {
  stroke: var(--red);
}

.xmenu-green {
  stroke: var(--xmenu-green);
}

.xmenu-title {
  margin: 2mm 0 0;
  font: 700 26pt/1.05 var(--hand);
  text-wrap: balance;
}

.xmenu-subtitle {
  margin: 1mm 0 0;
  font-size: 9.5pt;
  font-weight: 600;
  text-wrap: balance;
}

.xmenu-rule {
  flex: none;
  width: 40mm;
  height: 8mm;
  margin: 1.5mm 0;
}

/* The dishes in the middle of what is left: fewer dishes, no gap at the bottom. */
.xmenu-dishes {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  justify-content: center;
  gap: 1.8mm;
  width: 100%;
  min-height: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A row of 10 mm each on a small card (12 mm on the big one), so a short menu still fills it; less where a long one
   needs the room. */
.xmenu-dishes li {
  display: flex;
  flex: 0 1 10mm;
  align-items: center;
  justify-content: center;
  text-wrap: balance;
  overflow-wrap: anywhere;
}

.xmenu-end {
  margin: 0;
  font: 700 20pt/1.1 var(--hand);
  text-wrap: balance;
}

.xmenu-big {
  width: 170mm;
  margin: 0 auto;
  padding: 11mm 12mm 10mm;
  outline: 0;
  font-size: 13.5pt;
}

.xmenu-big::before {
  inset: 0;
  border-width: 0.5mm;
}

.xmenu-big::after {
  inset: 1.6mm;
  border-width: 0.25mm;
}

.xmenu-big .xmenu-art {
  width: 58mm;
  height: 31.2mm;
}

.xmenu-big .xmenu-title {
  margin-top: 3mm;
  font-size: 42pt;
}

.xmenu-big .xmenu-subtitle {
  font-size: 13pt;
}

.xmenu-big .xmenu-rule {
  width: 50mm;
  height: 10mm;
  margin: 1.5mm 0;
}

.xmenu-big .xmenu-dishes {
  gap: 2.4mm;
}

.xmenu-big .xmenu-dishes li {
  flex-basis: 12mm;
}

.xmenu-big .xmenu-end {
  font-size: 28pt;
}

/* The system's font, wider than Caveat: the title and the last line smaller. */
:root:lang(vi) .xmenu-title,
:root:lang(ja) .xmenu-title,
:root:lang(ko) .xmenu-title,
:root:lang(zh-Hans) .xmenu-title {
  font-size: 19pt;
  line-height: 1.25;
}

:root:lang(vi) .xmenu-big .xmenu-title,
:root:lang(ja) .xmenu-big .xmenu-title,
:root:lang(ko) .xmenu-big .xmenu-title,
:root:lang(zh-Hans) .xmenu-big .xmenu-title {
  font-size: 30pt;
}

:root:lang(vi) .xmenu-end,
:root:lang(ja) .xmenu-end,
:root:lang(ko) .xmenu-end,
:root:lang(zh-Hans) .xmenu-end {
  font-size: 15pt;
  line-height: 1.3;
}

:root:lang(vi) .xmenu-big .xmenu-end,
:root:lang(ja) .xmenu-big .xmenu-end,
:root:lang(ko) .xmenu-big .xmenu-end,
:root:lang(zh-Hans) .xmenu-big .xmenu-end {
  font-size: 21pt;
}

/* On the screen, the cards at three quarters of their size: the big one fits the column of a computer. */
@media screen {
  .xmenu-big,
  .xmenu-pair {
    zoom: 0.75;
  }
}

@page xmenu {
  margin: 10mm;
}

@media print {
  html:has(.xmenu-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.xmenu-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.xmenu-sheet) > :not(main),
  body:has(.xmenu-sheet) main > :not(.xmenu-sheet) {
    display: none !important;
  }

  body:has(.xmenu-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .xmenu-sheet {
    page: xmenu;
    display: block;
  }

  .xmenu-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .xmenu-page:last-child {
    break-after: auto;
  }
}

/* ---------- Reindeer food (/printables/reindeer-food) ---------- */

/* The sheet (`.rfood-sheet`): two pages of paper (`.rfood-page`), each a grid of 2 columns of 90 mm, 180 × 240 mm.
   Page 1: four toppers for a small bag (`.rfood-topper`, 90 × 120 mm), folded on the dashed line in the middle (60 mm)
   over the top of the bag – the lower half the front (the name in the hand font, a line with a star, the poem), the
   upper half the back: the reindeer and „From: ____”, turned by 180° (`.rfood-turned`), because folding it over the
   top and looking at it from behind turns it by 180° once more. Page 2: eight labels (`.rfood-label`, 90 × 60 mm),
   the same as a front. The cut lines an outline on the edge of each, the same line where two meet; the words at least
   5 mm from a cut line and from the fold. Text black, the reindeer and the line red and green, on white. Nothing hides
   what does not fit – it all fits: a name of 34 characters on two lines and four lines of 40 in half a topper. On the
   screen at three quarters of that size, where a narrow one scrolls sideways. Printed (`@page rfood`), only the pages,
   each on its own sheet of A4 or US Letter, inside the margins of both (190 × 277 mm and 195.9 × 259.4 mm). */
.rfood-sheet {
  /* The green of a green gift (`.gift-green`). */
  --rfood-green: #2f8f5b;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.rfood-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.rfood-grid {
  display: grid;
  grid-template-columns: repeat(2, 90mm);
  width: 180mm;
  margin: 0 auto;
}

.rfood-toppers {
  grid-auto-rows: 120mm;
}

.rfood-labels {
  grid-auto-rows: 60mm;
}

.rfood-topper,
.rfood-label {
  position: relative;
  box-sizing: border-box;
  outline: 0.25mm solid #000;
  outline-offset: -0.125mm;
  color: #000;
  font: 400 9.5pt/1.3 var(--sans);
  text-align: center;
}

.rfood-topper {
  display: grid;
  grid-template-rows: 60mm 60mm;
}

/* The fold: a dashed line across the middle, from cut line to cut line. */
.rfood-topper::after {
  content: "";
  position: absolute;
  top: 60mm;
  right: 0;
  left: 0;
  border-top: 0.3mm dashed #555;
  transform: translateY(-50%);
}

.rfood-front,
.rfood-label,
.rfood-turned {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-width: 0;
  padding: 5mm;
}

.rfood-turned {
  width: 100%;
  height: 100%;
  transform: rotate(180deg);
}

.rfood-deer {
  flex: none;
  width: 26.2mm;
  height: 28mm;
}

/* `silhouette_svg` paints it white, for a window; here it is red. */
.rfood-deer path {
  fill: var(--red);
}

.rfood-from {
  display: flex;
  align-items: flex-end;
  gap: 1.5mm;
  margin: 5mm 0 0;
  font-size: 10pt;
  font-weight: 600;
}

.rfood-sign {
  width: 42mm;
  height: 5mm;
  border-bottom: 0.25mm solid #000;
}

.rfood-name {
  max-width: 100%;
  margin: 0;
  font: 700 20pt/1.05 var(--hand);
  text-wrap: balance;
  overflow-wrap: anywhere;
}

.rfood-rule {
  flex: none;
  width: 30mm;
  height: 6mm;
  margin: 1mm 0 1.5mm;
}

.rfood-green {
  stroke: var(--rfood-green);
}

.rfood-red {
  stroke: var(--red);
}

.rfood-poem {
  max-width: 100%;
  margin: 0;
}

.rfood-poem span {
  display: block;
  text-wrap: balance;
  overflow-wrap: anywhere;
}

/* The system's font, wider than Caveat: the name smaller; Japanese, Korean and Chinese lines are short, their
   letters wide – a little bigger. */
:root:lang(vi) .rfood-name,
:root:lang(ja) .rfood-name,
:root:lang(ko) .rfood-name,
:root:lang(zh-Hans) .rfood-name {
  font-size: 14pt;
  line-height: 1.25;
}

:root:lang(ja) .rfood-poem,
:root:lang(ko) .rfood-poem,
:root:lang(zh-Hans) .rfood-poem {
  font-size: 11pt;
  line-height: 1.4;
}

@media screen {
  .rfood-grid {
    zoom: 0.75;
  }
}

@page rfood {
  margin: 10mm;
}

@media print {
  html:has(.rfood-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.rfood-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.rfood-sheet) > :not(main),
  body:has(.rfood-sheet) main > :not(.rfood-sheet) {
    display: none !important;
  }

  body:has(.rfood-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .rfood-sheet {
    page: rfood;
    display: block;
  }

  .rfood-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .rfood-page:last-child {
    break-after: auto;
  }
}

/* ---------- Door hangers (/printables/door-hangers) ---------- */

/* The sheet (`.dhanger-sheet`): two pages of paper (`.dhanger-page`), each two door hangers side by side
   (`.dhanger-pair`, 2 × 90 mm = 180 × 240 mm). Each hanger (`.dhanger`) exactly 90 × 240 mm; its cut lines drawn over
   it in one SVG of its size (`.dhanger-cut`, black, 0.25 mm): the outline – the same line where the two meet –, the
   hole for the handle (⌀ 50 mm, its centre 40 mm from the top) and the slit from its side to the outer edge; the green
   frame 4 mm inside the edge and two red stars to color in the top corners. Under the hole (`.dhanger-body`, from
   71 mm: 6 mm under it, 8 mm from the sides – 4 mm inside the frame –, 9 mm from the bottom): the big words in the
   hand font in red, a line with a star, the picture to color (white shapes with a black outline, 55 mm wide), the
   small words, on the first the line for a name. White, no big areas of ink. Nothing hides what does not fit – it all
   fits: big words of 34 characters (14 in Japanese) and small ones of 48 (20). On the screen at three quarters of
   that size, where a narrow one scrolls sideways. Printed (`@page dhanger`), only the pages, each on its own sheet
   of A4 or US Letter, inside the margins of both (190 × 277 mm and 195.9 × 259.4 mm). */
.dhanger-sheet {
  /* The green of a green gift (`.gift-green`). */
  --dhanger-green: #2f8f5b;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.dhanger-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.dhanger-pair {
  display: grid;
  grid-template-columns: repeat(2, 90mm);
  grid-template-rows: 240mm;
  width: 180mm;
  margin: 0 auto;
}

.dhanger {
  position: relative;
  box-sizing: border-box;
  width: 90mm;
  height: 240mm;
  color: #000;
  text-align: center;
}

.dhanger-cut {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.dhanger-line {
  fill: none;
  stroke: #000;
  stroke-width: 0.25;
}

.dhanger-frame {
  fill: none;
  stroke: var(--dhanger-green);
  stroke-width: 0.5;
}

.dhanger-star {
  fill: #fff;
  stroke: var(--red);
  stroke-width: 1.4;
  stroke-linejoin: round;
}

.dhanger-body {
  position: relative;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  padding: 71mm 8mm 9mm;
}

.dhanger-say {
  max-width: 100%;
  margin: 0;
  color: var(--red);
  font: 700 22pt/1.05 var(--hand);
  text-wrap: balance;
  overflow-wrap: anywhere;
}

.dhanger-rule {
  flex: none;
  width: 30mm;
  height: 6mm;
  margin: 1.5mm 0 2.5mm;
}

.dhanger-green {
  stroke: var(--dhanger-green);
}

.dhanger-red {
  stroke: var(--red);
}

.dhanger-picture {
  flex: none;
  width: 55mm;
  height: 77mm;
}

/* Outlines a little thicker than on a whole page: the picture is a quarter of its size. */
.dhanger-picture .cp-part,
.dhanger-picture .cp-line {
  stroke-width: 3;
  cursor: auto;
}

.dhanger-small {
  max-width: 100%;
  margin: 3mm 0 0;
  font: 600 11pt/1.3 var(--sans);
  text-wrap: balance;
  overflow-wrap: anywhere;
}

.dhanger-home {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: center;
  gap: 1.5mm;
  max-width: 100%;
  margin: 5mm 0 0;
  font: 700 11pt/1.2 var(--sans);
}

.dhanger-sign {
  width: 42mm;
  height: 6mm;
  border-bottom: 0.25mm solid #000;
}

/* The system's font, wider than Caveat: the big words smaller. */
:root:lang(vi) .dhanger-say,
:root:lang(ja) .dhanger-say,
:root:lang(ko) .dhanger-say,
:root:lang(zh-Hans) .dhanger-say {
  font-size: 17pt;
  line-height: 1.25;
}

/* Japanese breaks between phrases, not inside a word („サンタ／さん”). */
:root:lang(ja) .dhanger-say {
  word-break: auto-phrase;
}

@media screen {
  .dhanger-pair {
    zoom: 0.75;
  }
}

@page dhanger {
  margin: 10mm;
}

@media print {
  html:has(.dhanger-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.dhanger-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.dhanger-sheet) > :not(main),
  body:has(.dhanger-sheet) main > :not(.dhanger-sheet) {
    display: none !important;
  }

  body:has(.dhanger-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .dhanger-sheet {
    page: dhanger;
    display: block;
  }

  /* Room for the half of the cut lines outside the hangers, so that none of page 2 is drawn at the foot of page 1. */
  .dhanger-page {
    overflow: visible;
    padding: 0.25mm;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .dhanger-page:last-child {
    break-after: auto;
  }
}

/* ---------- Wrapping paper (/printables/wrapping-paper) ---------- */

/* The sheet (`.wpaper-sheet`): five pages of paper (`.wpaper-page`), each one panel of pattern (`.wpaper-panel`, one
   SVG, exactly 190 × 252 mm, its tile an SVG `<pattern>`) inside a thin light grey line to cut along. White paper,
   no area filled with ink. On the screen the pages small, side by side as many as fit – one under another on a phone –,
   each under its caption (`.wpaper-caption`: its number, its name, in color or to color). Printed (`@page wpaper`),
   only the panels, each on its own sheet of A4 or US Letter, inside the margins of both (190 × 277 mm and
   195.9 × 259.4 mm); no caption. */
.wpaper-sheet {
  color-scheme: light;
  display: block;
}

.wpaper-caption {
  display: none;
}

.wpaper-panel {
  display: block;
  width: 190mm;
  height: 252mm;
  background: #fff;
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

/* The outlines of the pictures to color, 4.5 units of their drawing: 0.7 mm at 44 mm high. */
.wpaper-panel .cp-part,
.wpaper-panel .cp-line {
  stroke-width: 4.5;
  cursor: auto;
}

@media screen {
  .wpaper-sheet {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
    gap: 1rem;
  }

  .wpaper-page {
    padding: 0.75rem;
    background: #fff;
    color: #000;
    border-radius: 6px;
    box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
  }

  .wpaper-caption {
    display: block;
    margin: 0 0 0.5rem;
    font: 600 0.95rem/1.3 var(--sans);
  }

  .wpaper-panel {
    width: 100%;
    height: auto;
    aspect-ratio: 190 / 252;
  }
}

@page wpaper {
  margin: 10mm;
}

@media print {
  html:has(.wpaper-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.wpaper-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.wpaper-sheet) > :not(main),
  body:has(.wpaper-sheet) main > :not(.wpaper-sheet) {
    display: none !important;
  }

  body:has(.wpaper-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .wpaper-sheet {
    page: wpaper;
  }

  .wpaper-page {
    break-after: page;
    break-inside: avoid;
  }

  .wpaper-page:last-child {
    break-after: auto;
  }
}

/* ---------- Santa's magic key (/printables/santa-key) ---------- */

/* The sheet (`.skey-sheet`): two pages of paper (`.skey-page`), each one SVG in mm (`.skey-art`, 165 × 170 mm): the
   key, exactly 70 × 170 mm, and 15 mm to its right its tag, exactly 80 × 100 mm. Page 1 in color (`.skey-color`): the
   key light gold with darker gold lines, red stars and dots, the tag cream; page 2 to color (`.skey-plain`): white
   with black lines. The cut lines – outlines and the holes for the ribbon, ⌀ 5 mm – black, 0.25 mm, drawn last; the
   tag's thin green frame 3 mm inside its edge. The words in the hand font (the system's in Vietnamese, Japanese,
   Korean and Chinese), their size set by the server to fit. On the screen at three quarters of that size, where a
   narrow one scrolls sideways. Printed (`@page skey`), only the pages, each on its own sheet of A4 or US Letter. */
.skey-sheet {
  /* The green of a green gift (`.gift-green`). */
  --skey-green: #2f8f5b;
  --skey-gold: #f3c64b;
  --skey-gold-deep: #a8761f;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.skey-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.skey-art {
  display: block;
  width: 165mm;
  height: 170mm;
  margin: 0 auto;
  overflow: visible;
}

.skey-hand {
  font-family: var(--hand);
  font-weight: 700;
}

.skey-cut,
.skey-hole {
  stroke: #000;
  stroke-width: 0.25;
}

.skey-cut {
  fill: none;
}

.skey-hole {
  fill: #fff;
}

.skey-ink {
  fill: none;
  stroke-width: 0.7;
}

.skey-dot {
  stroke-width: 0.4;
}

.skey-frame {
  fill: none;
  stroke: var(--skey-green);
  stroke-width: 0.5;
}

.skey-green {
  fill: none;
  stroke: var(--skey-green);
  stroke-width: 0.5;
}

.skey-sign {
  fill: none;
  stroke: #000;
  stroke-width: 0.25;
}

.skey-color .skey-body {
  fill: var(--skey-gold);
}

.skey-color .skey-ink,
.skey-color .skey-dot {
  stroke: var(--skey-gold-deep);
}

.skey-color .skey-dot,
.skey-color .skey-star {
  fill: var(--red);
}

.skey-color .skey-star {
  stroke: var(--red-deep);
  stroke-linejoin: round;
}

.skey-color .skey-word {
  fill: var(--red-deep);
}

.skey-color .skey-paper {
  fill: #fff8e7;
}

.skey-color .skey-poem {
  fill: var(--skey-green);
}

.skey-color .skey-from {
  fill: var(--red-deep);
}

.skey-plain .skey-body,
.skey-plain .skey-paper,
.skey-plain .skey-dot,
.skey-plain .skey-star {
  fill: #fff;
}

.skey-plain .skey-ink,
.skey-plain .skey-dot,
.skey-plain .skey-star {
  stroke: #000;
  stroke-linejoin: round;
}

.skey-plain .skey-word,
.skey-plain .skey-poem,
.skey-plain .skey-from {
  fill: #000;
}

@media screen {
  .skey-art {
    zoom: 0.75;
  }
}

@page skey {
  margin: 10mm;
}

@media print {
  html:has(.skey-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.skey-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.skey-sheet) > :not(main),
  body:has(.skey-sheet) main > :not(.skey-sheet) {
    display: none !important;
  }

  body:has(.skey-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .skey-sheet {
    page: skey;
    display: block;
  }

  /* Room for the half of the cut lines outside the SVG, so that none of page 2 is drawn at the foot of page 1. */
  .skey-page {
    overflow: visible;
    padding: 0.25mm;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .skey-page:last-child {
    break-after: auto;
  }
}

/* ---------- Jar labels (/printables/jar-labels) ---------- */

/* The sheet (`.jlabel-sheet`): three pages of paper (`.jlabel-page`), each one SVG in mm (`.jlabel-art`, 190 mm wide,
   its height in its own attributes): eight round labels for the lid, ⌀ 60 mm, eight front labels, 90 × 50 mm, with a
   hole for the string, and four blank ones of each. Cream paper, a red ring or frame and a thin green one inside it,
   a holly sprig of light green leaves and red berries, the word for homemade in green and the treat's name in red, in
   the hand font (the system's in Vietnamese, Japanese, Korean and Chinese), their size set by the server to fit. The
   cut lines black, 0.25 mm, drawn last; the lines to write on grey. On the screen at three quarters of that size,
   where a narrow one scrolls sideways. Printed (`@page jlabel`), only the pages, each on its own sheet of A4 or US
   Letter. */
.jlabel-sheet {
  /* The green of a green gift (`.gift-green`). */
  --jlabel-green: #2f8f5b;
  --jlabel-leaf: #d3ecd9;
  --jlabel-cream: #fff8e7;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.jlabel-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.jlabel-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.jlabel-hand {
  font-family: var(--hand);
  font-weight: 700;
}

.jlabel-paper {
  fill: var(--jlabel-cream);
}

.jlabel-ring {
  fill: none;
  stroke: var(--red);
  stroke-width: 0.8;
}

.jlabel-dots {
  fill: none;
  stroke: var(--jlabel-green);
  stroke-width: 0.5;
  stroke-dasharray: 0.1 1.4;
  stroke-linecap: round;
}

.jlabel-line {
  fill: none;
  stroke: var(--jlabel-green);
  stroke-width: 0.3;
}

.jlabel-leaf {
  fill: var(--jlabel-leaf);
  stroke: var(--jlabel-green);
  stroke-width: 0.35;
  stroke-linejoin: round;
}

.jlabel-vein {
  fill: none;
  stroke: var(--jlabel-green);
  stroke-width: 0.25;
}

.jlabel-berry {
  fill: var(--red);
}

.jlabel-home {
  fill: var(--jlabel-green);
}

.jlabel-name {
  fill: var(--red-deep);
}

.jlabel-word {
  fill: #333;
}

.jlabel-write {
  fill: none;
  stroke: #777;
  stroke-width: 0.3;
}

.jlabel-cut,
.jlabel-hole {
  stroke: #000;
  stroke-width: 0.25;
}

.jlabel-cut {
  fill: none;
}

.jlabel-hole {
  fill: #fff;
}

@media screen {
  .jlabel-art {
    zoom: 0.75;
  }
}

@page jlabel {
  margin: 10mm;
}

@media print {
  html:has(.jlabel-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.jlabel-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.jlabel-sheet) > :not(main),
  body:has(.jlabel-sheet) main > :not(.jlabel-sheet) {
    display: none !important;
  }

  body:has(.jlabel-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .jlabel-sheet {
    page: jlabel;
    display: block;
  }

  /* The drawing keeps half a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .jlabel-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .jlabel-page:last-child {
    break-after: auto;
  }
}

/* ---------- Christmas Eve box (/printables/christmas-eve-box) ---------- */

/* The sheet (`.evebox-sheet`): three pages of paper (`.evebox-page`), each one SVG in mm (`.evebox-art`, 190 mm wide,
   its height in its own attributes): the big label for the lid, 180 × 120 mm, eight small labels, 85 × 50 mm, with a
   picture of the thing each goes on and a hole for a ribbon, two tags, 60 × 100 mm, and four blank labels. Cream
   paper, a navy frame, a band of pale night sky with an outlined moon, stars and a tree – light fills only, little
   ink –, the box's title and the names in red, in the hand font (the system's in Vietnamese, Japanese, Korean and
   Chinese), their size set by the server to fit. The cut lines black, 0.25 mm, drawn last; the lines to write on
   grey. On the screen at three quarters of that size, where a narrow one scrolls sideways. Printed (`@page evebox`),
   only the pages, each on its own sheet of A4 or US Letter. */
.evebox-sheet {
  --evebox-navy: #23407a;
  --evebox-sky: #e9eff9;
  --evebox-blue: #dbe5f6;
  --evebox-green: #2f8f5b;
  --evebox-mint: #d5eedc;
  --evebox-rose: #fbdada;
  --evebox-gold: #fff1b5;
  --evebox-cocoa: #ecd3b8;
  --evebox-cream: #fffaf0;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.evebox-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.evebox-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.evebox-hand {
  font-family: var(--hand);
  font-weight: 700;
}

.evebox-paper {
  fill: var(--evebox-cream);
}

.evebox-sky {
  fill: var(--evebox-sky);
}

.evebox-frame {
  fill: none;
  stroke: var(--evebox-navy);
  stroke-width: 0.8;
}

.evebox-line {
  fill: none;
  stroke: var(--red);
  stroke-width: 0.3;
}

.evebox-green {
  fill: none;
  stroke: var(--evebox-green);
  stroke-width: 0.3;
}

.evebox-moon {
  fill: var(--evebox-gold);
  stroke: var(--evebox-navy);
  stroke-width: 0.4;
  stroke-linejoin: round;
}

.evebox-star {
  fill: var(--evebox-gold);
  stroke: #c79a16;
  stroke-linejoin: round;
}

.evebox-art [class^="evebox-i-"] {
  stroke: var(--evebox-navy);
  stroke-width: 0.35;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.evebox-i-blue {
  fill: var(--evebox-blue);
}

.evebox-i-rose {
  fill: var(--evebox-rose);
}

.evebox-i-mint {
  fill: var(--evebox-mint);
}

.evebox-i-gold {
  fill: var(--evebox-gold);
}

.evebox-i-cocoa {
  fill: var(--evebox-cocoa);
}

.evebox-i-cream {
  fill: #fff;
}

.evebox-i-line {
  fill: none;
}

.evebox-art .evebox-i-dot {
  fill: var(--evebox-navy);
  stroke: none;
}

.evebox-art .evebox-i-red {
  fill: var(--red);
  stroke: none;
}

.evebox-title,
.evebox-name {
  fill: var(--red-deep);
}

.evebox-foot {
  fill: var(--evebox-green);
}

.evebox-word {
  fill: var(--evebox-navy);
}

.evebox-write {
  fill: none;
  stroke: #777;
  stroke-width: 0.3;
}

.evebox-cut,
.evebox-hole {
  stroke: #000;
  stroke-width: 0.25;
}

.evebox-cut {
  fill: none;
}

.evebox-hole {
  fill: #fff;
}

@media screen {
  .evebox-art {
    zoom: 0.75;
  }
}

@page evebox {
  margin: 10mm;
}

@media print {
  html:has(.evebox-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.evebox-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.evebox-sheet) > :not(main),
  body:has(.evebox-sheet) main > :not(.evebox-sheet) {
    display: none !important;
  }

  body:has(.evebox-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .evebox-sheet {
    page: evebox;
    display: block;
  }

  /* The drawing keeps half a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .evebox-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .evebox-page:last-child {
    break-after: auto;
  }
}

/* ---------- Photo booth props (/printables/photo-booth-props) ---------- */

/* The sheet (`.pbooth-sheet`): six pages of paper (`.pbooth-page`), each one SVG in mm (`.pbooth-art`, 190 mm wide,
   its height in its own attributes) with the props of the photo booth – a Santa hat, a beard, a moustache, reindeer
   antlers and a nose, an elf hat, star glasses, a bow tie and six speech bubbles –, each with a grey tab for its stick.
   Full colors, so that the props show on a photo: red, white, green, gold and brown, no big dark field. Each prop's
   outline drawn wide and dark under it (`.pbooth-edge`), so that 0.6 mm of it shows round the prop and its tab as one
   cut line; the holes to cut out pale grey. The bubbles' texts in the hand font (the system's in Vietnamese, Japanese,
   Korean and Chinese), their size set by the server to fit. On the screen at three quarters of that size, where a
   narrow one scrolls sideways. Printed (`@page pbooth`), only the pages, each on its own sheet of A4 or US Letter. */
.pbooth-sheet {
  --pbooth-edge: #2b1d16;
  --pbooth-red: #d7262e;
  --pbooth-red-deep: #a8141f;
  --pbooth-red-light: #ee6a64;
  --pbooth-green: #2f9a4f;
  --pbooth-green-deep: #1f7339;
  --pbooth-gold: #f5c533;
  --pbooth-gold-deep: #c58f12;
  --pbooth-brown: #8b5a2b;
  --pbooth-brown-light: #b98250;
  --pbooth-brown-deep: #5a3517;
  --pbooth-fur: #b9bec8;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.pbooth-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.pbooth-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.pbooth-hand {
  font-family: var(--hand);
  font-weight: 700;
}

.pbooth-edge {
  fill: var(--pbooth-edge);
  stroke: var(--pbooth-edge);
  stroke-width: 1.2;
  stroke-linejoin: round;
}

.pbooth-edge-beam,
.pbooth-edge-band,
.pbooth-beam,
.pbooth-beam-light,
.pbooth-band {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.pbooth-edge-beam,
.pbooth-edge-band {
  stroke: var(--pbooth-edge);
}

.pbooth-edge-beam {
  stroke-width: 10.2;
}

.pbooth-edge-band {
  stroke-width: 8.2;
}

.pbooth-beam {
  stroke: var(--pbooth-brown);
  stroke-width: 9;
}

.pbooth-beam-light {
  stroke: var(--pbooth-brown-light);
  stroke-width: 2.6;
}

.pbooth-band {
  stroke: var(--pbooth-red);
  stroke-width: 7;
}

.pbooth-stick {
  fill: #cfcfcf;
}

.pbooth-stick-word {
  fill: #555;
  font-family: var(--sans);
  font-weight: 700;
}

.pbooth-red {
  fill: var(--pbooth-red);
}

.pbooth-red-deep {
  fill: var(--pbooth-red-deep);
}

.pbooth-red-light {
  fill: var(--pbooth-red-light);
}

.pbooth-white,
.pbooth-dot {
  fill: #fff;
}

.pbooth-white-edged {
  fill: #fff;
  stroke: var(--pbooth-edge);
  stroke-width: 0.6;
  stroke-linejoin: round;
}

.pbooth-shine {
  fill: #fff;
  opacity: 0.85;
}

.pbooth-green {
  fill: var(--pbooth-green);
}

.pbooth-green-deep {
  fill: var(--pbooth-green-deep);
}

.pbooth-gold {
  fill: var(--pbooth-gold);
}

.pbooth-brown {
  fill: var(--pbooth-brown);
}

.pbooth-fur,
.pbooth-gold-line,
.pbooth-brown-line,
.pbooth-line {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.pbooth-fur {
  stroke: var(--pbooth-fur);
  stroke-width: 0.7;
}

.pbooth-gold-line {
  stroke: var(--pbooth-gold-deep);
  stroke-width: 0.7;
}

.pbooth-brown-line {
  stroke: var(--pbooth-brown-deep);
  stroke-width: 0.8;
}

.pbooth-line {
  stroke: var(--pbooth-edge);
  stroke-width: 0.6;
}

.pbooth-hole {
  fill: #ececec;
  stroke: var(--pbooth-edge);
  stroke-width: 0.6;
}

.pbooth-say {
  fill: var(--pbooth-red-deep);
}

.pbooth-say-green {
  fill: var(--pbooth-green-deep);
}

@media screen {
  .pbooth-art {
    zoom: 0.75;
  }
}

@page pbooth {
  margin: 10mm;
}

@media print {
  html:has(.pbooth-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.pbooth-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.pbooth-sheet) > :not(main),
  body:has(.pbooth-sheet) main > :not(.pbooth-sheet) {
    display: none !important;
  }

  body:has(.pbooth-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .pbooth-sheet {
    page: pbooth;
    display: block;
  }

  /* The drawing keeps a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .pbooth-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .pbooth-page:last-child {
    break-after: auto;
  }
}

/* ---------- Paper angel (/printables/paper-angel) ---------- */

/* The sheet (`.angel-sheet`): four pages of paper (`.angel-page`), each one SVG in mm (`.angel-art`, 190 mm wide, its
   height in its own attributes) with the three parts of one standing paper angel – the cone dress with its glue strip,
   the head with its halo and neck, the wings with their grey middle. The same drawing on each page, its colors from
   the page's class: gold and white (`.angel-gold`), red and white (`.angel-red`), light blue and silver (`.angel-blue`)
   and outlines only, to color in (`.angel-line`). Each part's outline drawn wide and dark under it (`.angel-edge`), so
   that 0.6 mm of it shows round the part as one cut line; no big dark field. On the screen at three quarters of that
   size, where a narrow one scrolls sideways. Printed (`@page angel`), only the pages, each on its own sheet of A4 or
   US Letter. */
.angel-sheet {
  --angel-edge: #3a2a20;
  --angel-ink: #5a3a2a;
  --angel-thin: rgb(58 42 32 / 0.4);
  --angel-skin: #fde3cf;
  --angel-cheek: #f6a6a6;
  --angel-halo: #f5c533;
  --angel-halo-light: #fff1b0;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.angel-gold {
  --angel-dress: #fffdf5;
  --angel-trim: #f2c230;
  --angel-hem-star: #fff8dc;
  --angel-star: #e9b824;
  --angel-wing: #fff;
  --angel-wing-deep: #fdf0c8;
  --angel-hair: #f0bf5a;
}

.angel-red {
  --angel-dress: #d7262e;
  --angel-trim: #fff;
  --angel-hem-star: #d7262e;
  --angel-star: #fff;
  --angel-wing: #fff;
  --angel-wing-deep: #fbe1e1;
  --angel-hair: #9a6232;
}

.angel-blue {
  --angel-dress: #a9d8f5;
  --angel-trim: #dde3ea;
  --angel-hem-star: #fff;
  --angel-star: #fff;
  --angel-wing: #f5f8fb;
  --angel-wing-deep: #dfe6ee;
  --angel-hair: #e3b469;
  --angel-halo: #cfd6df;
  --angel-halo-light: #f5f8fb;
}

.angel-line {
  --angel-thin: var(--angel-edge);
  --angel-skin: #fff;
  --angel-cheek: #fff;
  --angel-halo: #fff;
  --angel-halo-light: #fff;
  --angel-dress: #fff;
  --angel-trim: #fff;
  --angel-hem-star: #fff;
  --angel-star: #fff;
  --angel-wing: #fff;
  --angel-wing-deep: #fff;
  --angel-hair: #fff;
}

.angel-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.angel-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.angel-edge {
  fill: var(--angel-edge);
  stroke: var(--angel-edge);
  stroke-width: 1.2;
  stroke-linejoin: round;
}

.angel-dress,
.angel-trim,
.angel-hem-star,
.angel-star,
.angel-wing,
.angel-wing-deep,
.angel-hair,
.angel-halo,
.angel-halo-light,
.angel-cheek {
  stroke: var(--angel-thin);
  stroke-width: 0.35;
  stroke-linejoin: round;
}

.angel-dress {
  fill: var(--angel-dress);
}

.angel-trim {
  fill: var(--angel-trim);
}

.angel-hem-star {
  fill: var(--angel-hem-star);
}

.angel-star {
  fill: var(--angel-star);
}

.angel-wing {
  fill: var(--angel-wing);
}

.angel-wing-deep {
  fill: var(--angel-wing-deep);
}

.angel-hair {
  fill: var(--angel-hair);
}

.angel-halo {
  fill: var(--angel-halo);
}

.angel-halo-light {
  fill: var(--angel-halo-light);
}

.angel-skin {
  fill: var(--angel-skin);
}

.angel-cheek {
  fill: var(--angel-cheek);
}

.angel-ink,
.angel-shaft {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.angel-ink {
  stroke: var(--angel-ink);
  stroke-width: 0.7;
}

.angel-shaft {
  stroke: var(--angel-thin);
  stroke-width: 0.4;
}

.angel-glue {
  fill: #cfcfcf;
}

.angel-glue-word,
.angel-number {
  fill: #555;
  font-family: var(--sans);
  font-weight: 700;
}

@media screen {
  .angel-art {
    zoom: 0.75;
  }
}

@page angel {
  margin: 10mm;
}

@media print {
  html:has(.angel-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.angel-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.angel-sheet) > :not(main),
  body:has(.angel-sheet) main > :not(.angel-sheet) {
    display: none !important;
  }

  body:has(.angel-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .angel-sheet {
    page: angel;
    display: block;
  }

  /* The drawing keeps a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .angel-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .angel-page:last-child {
    break-after: auto;
  }
}

/* ---------- Christmas crackers (/printables/christmas-crackers) ---------- */

/* The sheet (`.cracker-sheet`): six pages of paper (`.cracker-page`), each one SVG in mm (`.cracker-art`, 190 mm wide,
   its height in its own attributes). Four wraps to roll round a toilet paper roll – red and gold with a star
   (`.cracker-red`), green and white with a tree (`.cracker-green`), light blue and silver with a snowflake
   (`.cracker-blue`), outlines to color with a gift (`.cracker-line`) – and two pages of a paper crown in four parts
   (`.cracker-crown`), gold (`.cracker-gold`) and to color (`.cracker-line`). Each outline drawn wide and dark under the
   paint (`.cracker-edge`), so that 0.6 mm of it shows as the cut line; no big dark field. On the screen at three
   quarters of that size, where a narrow one scrolls sideways. Printed (`@page cracker`), only the pages, each on its own
   sheet of A4 or US Letter. */
.cracker-sheet {
  --cracker-edge: #3a2a20;
  --cracker-thin: rgb(58 42 32 / 0.35);
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.cracker-red {
  --cracker-field: #d7262e;
  --cracker-stripe: #f2c230;
  --cracker-trim: #f2c230;
  --cracker-disc: #fff6d8;
  --cracker-motif: #f2c230;
  --cracker-motif-2: #fff6d8;
  --cracker-dot: #f7d774;
}

.cracker-green {
  --cracker-field: #1f8a4c;
  --cracker-stripe: #fff;
  --cracker-trim: #fff;
  --cracker-disc: #fff;
  --cracker-motif: #1f8a4c;
  --cracker-motif-2: #d7262e;
  --cracker-dot: #fff;
}

.cracker-blue {
  --cracker-field: #a9d8f5;
  --cracker-stripe: #fff;
  --cracker-trim: #c9d1db;
  --cracker-disc: #fff;
  --cracker-motif: #5aa7dc;
  --cracker-motif-2: #c9d1db;
  --cracker-dot: #fff;
}

.cracker-gold {
  --cracker-field: #f5c533;
  --cracker-band: #c99a1a;
  --cracker-pearl: #fff8dc;
  --cracker-jewel-a: #d7262e;
  --cracker-jewel-b: #1f8a4c;
  --cracker-jewel-c: #5aa7dc;
}

.cracker-line {
  --cracker-thin: var(--cracker-edge);
  --cracker-field: #fff;
  --cracker-stripe: #fff;
  --cracker-trim: #fff;
  --cracker-disc: #fff;
  --cracker-motif: #fff;
  --cracker-motif-2: #fff;
  --cracker-dot: #fff;
  --cracker-band: var(--cracker-edge);
  --cracker-pearl: #fff;
  --cracker-jewel-a: #fff;
  --cracker-jewel-b: #fff;
  --cracker-jewel-c: #fff;
}

.cracker-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.cracker-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.cracker-edge {
  fill: var(--cracker-edge);
  stroke: var(--cracker-edge);
  stroke-width: 1.2;
  stroke-linejoin: round;
}

.cracker-field,
.cracker-stripe,
.cracker-trim,
.cracker-disc,
.cracker-motif,
.cracker-motif-2,
.cracker-dot,
.cracker-pearl,
.cracker-jewel-a,
.cracker-jewel-b,
.cracker-jewel-c {
  stroke: var(--cracker-thin);
  stroke-width: 0.35;
  stroke-linejoin: round;
}

.cracker-field {
  fill: var(--cracker-field);
}

.cracker-stripe {
  fill: var(--cracker-stripe);
}

.cracker-trim {
  fill: var(--cracker-trim);
}

.cracker-disc {
  fill: var(--cracker-disc);
}

.cracker-motif {
  fill: var(--cracker-motif);
}

.cracker-motif-2 {
  fill: var(--cracker-motif-2);
}

.cracker-dot {
  fill: var(--cracker-dot);
}

.cracker-pearl {
  fill: var(--cracker-pearl);
}

.cracker-jewel-a {
  fill: var(--cracker-jewel-a);
}

.cracker-jewel-b {
  fill: var(--cracker-jewel-b);
}

.cracker-jewel-c {
  fill: var(--cracker-jewel-c);
}

/* The snowflake's arms: a wide line of the motif's color. */
.cracker-flake {
  fill: none;
  stroke: var(--cracker-motif);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.cracker-band {
  fill: none;
  stroke: var(--cracker-band);
  stroke-width: 0.5;
}

/* Where the ribbon ties the cracker: a thin dashed line, no cut. */
.cracker-tie {
  fill: none;
  stroke: var(--cracker-edge);
  stroke-width: 0.3;
  stroke-dasharray: 2 1.5;
}

/* The crown's marks „glue here” at the end of its fourth part. */
.cracker-mark {
  fill: none;
  stroke: var(--cracker-edge);
  stroke-width: 0.5;
}

.cracker-glue {
  fill: #cfcfcf;
}

.cracker-word,
.cracker-number {
  fill: #555;
  font-family: var(--sans);
  font-weight: 700;
}

@media screen {
  .cracker-art {
    zoom: 0.75;
  }
}

@page cracker {
  margin: 10mm;
}

@media print {
  html:has(.cracker-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.cracker-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.cracker-sheet) > :not(main),
  body:has(.cracker-sheet) main > :not(.cracker-sheet) {
    display: none !important;
  }

  body:has(.cracker-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .cracker-sheet {
    page: cracker;
    display: block;
  }

  /* The drawing keeps a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .cracker-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .cracker-page:last-child {
    break-after: auto;
  }
}

/* ---------- 3D paper star (/printables/3d-paper-star) ---------- */

/* The sheet (`.pstar-sheet`): eight pages of paper (`.pstar-page`), each one SVG in mm (`.pstar-art`, 190 mm wide, its
   height in its own attributes): the nets of the halves of a star pyramid – the big star in gold (`.pstar-gold`), red
   (`.pstar-red`) and outlines to color (`.pstar-line`), a half on each page, the small one in gold and red. The faces
   light and dark by turns (`.pstar-light`, `.pstar-dark`), the grey glue tabs (`.pstar-glue`), the fold lines up
   (`.pstar-up`, dash and dot) and down (`.pstar-down`, dashes) with their key. Each outline drawn wide and dark under
   the paint (`.pstar-edge`), so that 0.6 mm of it shows as the cut line; no big dark field. On the screen at three
   quarters of that size, where a narrow one scrolls sideways. Printed (`@page pstar`), only the pages, each on its own
   sheet of A4 or US Letter. */
.pstar-sheet {
  --pstar-edge: #3a2a20;
  --pstar-thin: rgb(58 42 32 / 0.35);
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.pstar-gold {
  --pstar-light: #f7cf4a;
  --pstar-dark: #e2a91f;
  --pstar-star: #fff3c4;
  --pstar-dot: #fff8dc;
}

.pstar-red {
  --pstar-light: #e0343b;
  --pstar-dark: #b81d25;
  --pstar-star: #f7d774;
  --pstar-dot: #fff3c4;
}

.pstar-line {
  --pstar-thin: var(--pstar-edge);
  --pstar-light: #fff;
  --pstar-dark: #fff;
  --pstar-star: #fff;
  --pstar-dot: #fff;
}

.pstar-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.pstar-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.pstar-edge {
  fill: var(--pstar-edge);
  stroke: var(--pstar-edge);
  stroke-width: 1.2;
  stroke-linejoin: round;
}

.pstar-glue {
  fill: #cfcfcf;
}

.pstar-light {
  fill: var(--pstar-light);
}

.pstar-dark {
  fill: var(--pstar-dark);
}

.pstar-star,
.pstar-dot {
  stroke: var(--pstar-thin);
  stroke-width: 0.3;
  stroke-linejoin: round;
}

.pstar-star {
  fill: var(--pstar-star);
}

.pstar-dot {
  fill: var(--pstar-dot);
}

/* Fold up – a ridge, from the middle to a point and round the rim tabs: dash and dot. */
.pstar-up {
  fill: none;
  stroke: var(--pstar-edge);
  stroke-width: 0.35;
  stroke-dasharray: 3 1 0.6 1;
}

/* Fold down – a valley, from the middle to a notch and at the slit's tab: dashes. */
.pstar-down {
  fill: none;
  stroke: var(--pstar-edge);
  stroke-width: 0.35;
  stroke-dasharray: 1.4 1.1;
}

.pstar-word,
.pstar-letter {
  fill: #555;
  font-family: var(--sans);
  font-weight: 700;
}

.pstar-key {
  fill: #333;
  font-family: var(--sans);
}

@media screen {
  .pstar-art {
    zoom: 0.75;
  }
}

@page pstar {
  margin: 10mm;
}

@media print {
  html:has(.pstar-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.pstar-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.pstar-sheet) > :not(main),
  body:has(.pstar-sheet) main > :not(.pstar-sheet) {
    display: none !important;
  }

  body:has(.pstar-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .pstar-sheet {
    page: pstar;
    display: block;
  }

  /* The drawing keeps a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .pstar-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .pstar-page:last-child {
    break-after: auto;
  }
}

/* ---------- Countdown paper chain (/printables/countdown-chain) ---------- */

/* The sheet (`.cchain-sheet`): pages of paper (`.cchain-page`), each one SVG in mm (`.cchain-art`, 190 mm wide, its
   height in its own attributes) with up to nine strips of 180 × 24 mm, one under another – a strip for each day, red
   (`.cchain-red`), green (`.cchain-green`) and gold (`.cchain-gold`) by turns: light paper with a band along each long
   edge, the grey glue field, the task in dark letters, the day in white in a ring of its color; then a page of blank
   strips (`.cchain-line`) to fill in. The cut line (`.cchain-cut`) 0.4 mm on top; no big dark field. On the screen at
   three quarters of that size, where a narrow one scrolls sideways. Printed (`@page cchain`), only the pages, each on
   its own sheet of A4 or US Letter. */
.cchain-sheet {
  --cchain-ink: #2b2522;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.cchain-red {
  --cchain-light: #fde3e1;
  --cchain-strong: #c8323a;
  --cchain-star: #f2b544;
}

.cchain-green {
  --cchain-light: #dff1e2;
  --cchain-strong: #2f7d46;
  --cchain-star: #f2b544;
}

.cchain-gold {
  --cchain-light: #fdf1c9;
  --cchain-strong: #c98d12;
  --cchain-star: #c8323a;
}

.cchain-line {
  --cchain-light: #fff;
  --cchain-strong: #fff;
  --cchain-star: #fff;
}

.cchain-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.cchain-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.cchain-paper {
  fill: var(--cchain-light);
}

.cchain-band,
.cchain-ring {
  fill: var(--cchain-strong);
}

.cchain-empty {
  fill: #fff;
  stroke: var(--cchain-ink);
  stroke-width: 0.35;
}

.cchain-glue {
  fill: #d4d4d4;
}

.cchain-word {
  fill: #555;
  font-family: var(--sans);
  font-weight: 700;
}

.cchain-day {
  fill: #fff;
  font-family: var(--sans);
  font-weight: 800;
}

.cchain-task {
  fill: var(--cchain-ink);
  font-family: var(--sans);
}

.cchain-blank {
  fill: #555;
  font-family: var(--sans);
}

.cchain-write {
  fill: none;
  stroke: #777;
  stroke-width: 0.3;
}

.cchain-star,
.cchain-dot {
  fill: var(--cchain-star);
  stroke: var(--cchain-ink);
  stroke-width: 0.2;
  stroke-linejoin: round;
}

/* Its width, 0.4 mm, in its own attribute (`CCHAIN_CUT`). */
.cchain-cut {
  fill: none;
  stroke: var(--cchain-ink);
}

@media screen {
  .cchain-art {
    zoom: 0.75;
  }
}

@page cchain {
  margin: 10mm;
}

@media print {
  html:has(.cchain-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.cchain-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.cchain-sheet) > :not(main),
  body:has(.cchain-sheet) main > :not(.cchain-sheet) {
    display: none !important;
  }

  body:has(.cchain-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .cchain-sheet {
    page: cchain;
    display: block;
  }

  /* The drawing keeps a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .cchain-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .cchain-page:last-child {
    break-after: auto;
  }
}

/* ---------- Christmas pop-up card (/printables/pop-up-card) ---------- */

/* The sheet (`.popup-sheet`): three pages of paper (`.popup-page`), each one SVG in mm (`.popup-art`, 190 mm wide, its
   height in its own attributes): the insert of 180 × 170 mm on its printed side – the „To / From” field, lines for
   the wishes, the folds (valleys dashed `.popup-valley`, mountains dash and dot `.popup-mountain`), the cuts of the
   steps solid and red (`.popup-slit`), on each riser where its figure is glued – the figure's bottom dashed
   (`.popup-glue`) with the word for glue (`.popup-word`) – and a key; the cover, its front upside down on the half that
   becomes the front; the figures in color (`.popup-color`) and to color (`.popup-line`), with a short dashed mark
   (`.popup-glue`) outside the cut line on each side, at the height of the riser's top edge.
   The cut lines (`.popup-cut`) 0.4 mm, their width in their own attribute; the lines inside a figure as thin as their
   group's attribute says. No big dark field. On the screen at three quarters of that size, where a narrow one scrolls
   sideways. Printed (`@page popup`), only the pages, each on its own sheet of A4 or US Letter. */
.popup-sheet {
  --popup-ink: #2b2522;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.popup-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.popup-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.popup-paper {
  fill: #fff;
}

.popup-cover-paper {
  fill: #fdf6e3;
}

.popup-cut {
  fill: none;
  stroke: var(--popup-ink);
  stroke-linejoin: round;
}

.popup-slit {
  fill: none;
  stroke: #c8323a;
  stroke-width: 0.7;
}

.popup-valley,
.popup-mountain {
  fill: none;
  stroke: var(--popup-ink);
  stroke-width: 0.35;
}

/* A valley: dashes. */
.popup-valley {
  stroke-dasharray: 1.4 1.1;
}

/* A mountain: dash and dot. */
.popup-mountain {
  stroke-dasharray: 3 1 0.6 1;
}

.popup-field {
  fill: #fff;
  stroke: #c8323a;
  stroke-width: 0.4;
}

.popup-frame {
  fill: none;
  stroke: #c8323a;
  stroke-width: 0.6;
}

.popup-write {
  fill: none;
  stroke: #999;
  stroke-width: 0.3;
}

.popup-field-word,
.popup-key,
.popup-site {
  fill: #333;
  font-family: var(--sans);
}

/* The word for glue, on a riser inside the dashed shape of its figure – hidden once the figure is glued on: a white
   rim keeps it readable. */
.popup-word {
  fill: #555;
  stroke: #fff;
  stroke-width: 0.6;
  paint-order: stroke;
  font-family: var(--sans);
  font-weight: 700;
}

.popup-wish {
  fill: #c8323a;
  font-family: var(--sans);
  font-weight: 800;
}

.popup-glue {
  fill: none;
  stroke: #555;
  stroke-width: 0.35;
  stroke-dasharray: 1.4 1.1;
}

.popup-flake {
  opacity: 0.55;
}

/* A figure: the light paper, the drawing inside it (its lines as thin as its group says), the dark cut line. */
.popup-color {
  --popup-fill: #fff;
  --popup-trunk: #e3c9a6;
  --popup-bauble: #e0343b;
  --popup-hat: #c9ced6;
  --popup-ribbon: #f2b544;
  --popup-scarf: #f39a9d;
  --popup-nose: #f5a35c;
  --popup-eye: #2b2522;
  --popup-box-1: #fbc9c6;
  --popup-box-2: #cbe7d0;
  --popup-box-3: #fde6a6;
}

.popup-color.popup-tree {
  --popup-fill: #cfe8c8;
}

.popup-color.popup-snowman {
  --popup-fill: #f2f6fb;
}

.popup-line {
  --popup-fill: #fff;
  --popup-trunk: #fff;
  --popup-bauble: #fff;
  --popup-hat: #fff;
  --popup-ribbon: #fff;
  --popup-scarf: #fff;
  --popup-nose: #fff;
  --popup-eye: var(--popup-ink);
  --popup-box-1: #fff;
  --popup-box-2: #fff;
  --popup-box-3: #fff;
}

.popup-fill {
  fill: var(--popup-fill);
}

.popup-inside,
.popup-edge {
  fill: none;
  stroke: var(--popup-ink);
  stroke-linejoin: round;
  stroke-linecap: round;
}

.popup-inside circle {
  fill: var(--popup-bauble);
}

.popup-inside .popup-eye {
  fill: var(--popup-eye);
}

.popup-trunk {
  fill: var(--popup-trunk);
}

.popup-hat {
  fill: var(--popup-hat);
}

.popup-ribbon {
  fill: var(--popup-ribbon);
}

.popup-scarf {
  fill: var(--popup-scarf);
}

.popup-nose {
  fill: var(--popup-nose);
}

.popup-box-1 {
  fill: var(--popup-box-1);
}

.popup-box-2 {
  fill: var(--popup-box-2);
}

.popup-box-3 {
  fill: var(--popup-box-3);
}

@media screen {
  .popup-art {
    zoom: 0.75;
  }
}

@page popup {
  margin: 10mm;
}

@media print {
  html:has(.popup-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.popup-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.popup-sheet) > :not(main),
  body:has(.popup-sheet) main > :not(.popup-sheet) {
    display: none !important;
  }

  body:has(.popup-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .popup-sheet {
    page: popup;
    display: block;
  }

  /* The drawing keeps a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .popup-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .popup-page:last-child {
    break-after: auto;
  }
}

/* ---------- Christmas paper lantern (/printables/paper-lantern) ---------- */

/* The sheet (`.lantern-sheet`): three pages of paper (`.lantern-page`), each one SVG in mm (`.lantern-art`, 190 mm wide,
   its height in its own attributes): the shell (`.lantern-shell`) – bands with holly and stars (`.lantern-band`), ribs
   red, green and gold (`.lantern-rib`) with stars and snowflakes, the fold dashed (`.lantern-fold`), the slits solid
   and red (`.lantern-slit`), the tab (`.lantern-tab`) grey where it is glued; the liner (`.lantern-liner`), warm yellow
   with little stars, grey where the shell and its tab are glued on; the handle (`.lantern-handle`) and a key. In
   color (`.lantern-color`) and to color (`.lantern-line`). The cut lines (`.lantern-cut`) 0.4 mm, their width in their
   own attribute. On the screen at three quarters of that size, where a narrow one scrolls sideways. Printed (`@page
   lantern`), only the pages, each on its own sheet of A4 or US Letter. */
.lantern-sheet {
  --lantern-ink: #2b2522;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.lantern-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.lantern-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.lantern-color {
  --lantern-paper: #fff;
  --lantern-band: #fbe7a8;
  --lantern-red: #d8363c;
  --lantern-green: #2e7d4f;
  --lantern-gold: #f2c14e;
  --lantern-glow: #ffd166;
  --lantern-strap: #d8363c;
  --lantern-star: #f6c445;
  --lantern-star-line: #a8741a;
  --lantern-light: #f4a261;
  --lantern-flake: #fff;
  --lantern-leaf: #2e7d4f;
  --lantern-berry: #d8363c;
  --lantern-edge: none;
}

.lantern-line {
  --lantern-paper: #fff;
  --lantern-band: #fff;
  --lantern-red: #fff;
  --lantern-green: #fff;
  --lantern-gold: #fff;
  --lantern-glow: #fff;
  --lantern-strap: #fff;
  --lantern-star: #fff;
  --lantern-star-line: var(--lantern-ink);
  --lantern-light: #fff;
  --lantern-flake: var(--lantern-ink);
  --lantern-leaf: #fff;
  --lantern-berry: #fff;
  --lantern-edge: var(--lantern-ink);
}

.lantern-paper {
  fill: var(--lantern-paper);
}

.lantern-glow {
  fill: var(--lantern-glow);
}

.lantern-strap {
  fill: var(--lantern-strap);
}

.lantern-band {
  stroke: var(--lantern-edge);
  stroke-width: 0.25;
}

.lantern-band {
  fill: var(--lantern-band);
}

.lantern-red {
  fill: var(--lantern-red);
}

.lantern-green {
  fill: var(--lantern-green);
}

.lantern-gold {
  fill: var(--lantern-gold);
}

/* The drawings: their own lines, whatever the art they come from says. */
.lantern-star path {
  fill: var(--lantern-star);
  stroke: var(--lantern-star-line);
  stroke-width: 0.3;
}

.lantern-light path {
  fill: var(--lantern-light);
  stroke: var(--lantern-edge);
  stroke-width: 0.3;
}

.lantern-flake path {
  stroke: var(--lantern-flake);
  stroke-width: 0.45;
}

.lantern-holly {
  stroke: var(--lantern-ink);
  stroke-linejoin: round;
}

.lantern-leaf {
  fill: var(--lantern-leaf);
}

.lantern-berry {
  fill: var(--lantern-berry);
}

.lantern-tab {
  fill: #fff;
  stroke: #999;
  stroke-width: 0.25;
}

.lantern-glue {
  fill: #e4e4e4;
  stroke: #999;
  stroke-width: 0.25;
}

.lantern-cut {
  fill: none;
  stroke: var(--lantern-ink);
  stroke-linejoin: round;
}

.lantern-slit {
  fill: none;
  stroke: #c8323a;
  stroke-width: 0.7;
}

/* The fold, across the shell's middle: dashes on a white line, so that they show on the dark ribs as well. */
.lantern-halo {
  fill: none;
  stroke: #fff;
  stroke-width: 0.9;
}

.lantern-fold {
  fill: none;
  stroke: var(--lantern-ink);
  stroke-width: 0.35;
  stroke-dasharray: 1.4 1.1;
}

.lantern-word,
.lantern-key {
  fill: #333;
  font-family: var(--sans);
}

.lantern-word {
  fill: #555;
  font-weight: 700;
}

@media screen {
  .lantern-art {
    zoom: 0.75;
  }
}

@page lantern {
  margin: 10mm;
}

@media print {
  html:has(.lantern-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.lantern-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.lantern-sheet) > :not(main),
  body:has(.lantern-sheet) main > :not(.lantern-sheet) {
    display: none !important;
  }

  body:has(.lantern-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .lantern-sheet {
    page: lantern;
    display: block;
  }

  /* The drawing keeps a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .lantern-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .lantern-page:last-child {
    break-after: auto;
  }
}

/* ---------- Christmas gift bag (/printables/gift-bag) ---------- */

/* The sheet (`.gbag-sheet`): three pages of paper (`.gbag-page`), each one SVG in mm (`.gbag-art`, 190 mm wide, its
   height in its own attributes) with the nets of the bag (`.gbag-net`): the band (`.gbag-band`) gold with the targets
   of the holes (`.gbag-hole`), the front red (`.gbag-front`) with a tree, stars and the label (`.gbag-label`), the back
   green (`.gbag-back`) with a snowflake and stars, the sides striped (`.gbag-side`, `.gbag-stripe`), the flaps
   (`.gbag-flap`), the glue fields grey (`.gbag-glue`); the folds up dashed (`.gbag-up`), down dash and dot
   (`.gbag-down`), each on a white line (`.gbag-halo`); the cut line (`.gbag-cut`) 0.4 mm, its width in its own
   attribute; and a key. In color (`.gbag-color`) and to color (`.gbag-line`). On the screen at three quarters of
   that size, where a narrow one scrolls sideways. Printed (`@page gbag`), only the pages, each on its own sheet of A4
   or US Letter. */
.gbag-sheet {
  --gbag-ink: #2b2522;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.gbag-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.gbag-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.gbag-color {
  --gbag-band: #f2c14e;
  --gbag-front: #d8363c;
  --gbag-back: #2e7d4f;
  --gbag-side: #fff;
  --gbag-stripe: #d8363c;
  --gbag-tree: #2e7d4f;
  --gbag-tree-line: #f6c445;
  --gbag-star: #f6c445;
  --gbag-star-line: #a8741a;
  --gbag-flake: #fff;
  --gbag-edge: none;
}

.gbag-line {
  --gbag-band: #fff;
  --gbag-front: #fff;
  --gbag-back: #fff;
  --gbag-side: #fff;
  --gbag-stripe: #fff;
  --gbag-tree: #fff;
  --gbag-tree-line: var(--gbag-ink);
  --gbag-star: #fff;
  --gbag-star-line: var(--gbag-ink);
  --gbag-flake: var(--gbag-ink);
  --gbag-edge: var(--gbag-ink);
}

.gbag-band {
  fill: var(--gbag-band);
}

.gbag-front {
  fill: var(--gbag-front);
}

.gbag-back {
  fill: var(--gbag-back);
}

.gbag-side {
  fill: var(--gbag-side);
}

.gbag-stripe {
  fill: var(--gbag-stripe);
  stroke: var(--gbag-edge);
  stroke-width: 0.2;
}

/* The drawings: their own lines, whatever the art they come from says. */
.gbag-tree path {
  fill: var(--gbag-tree);
  stroke: var(--gbag-tree-line);
  stroke-width: 0.4;
}

.gbag-star path {
  fill: var(--gbag-star);
  stroke: var(--gbag-star-line);
  stroke-width: 0.3;
}

.gbag-flake path {
  stroke: var(--gbag-flake);
  stroke-width: 0.6;
}

.gbag-label {
  fill: #fff;
  stroke: var(--gbag-ink);
  stroke-width: 0.3;
}

.gbag-write {
  fill: none;
  stroke: #777;
  stroke-width: 0.25;
}

.gbag-hole {
  fill: #fff;
  stroke: var(--gbag-ink);
  stroke-width: 0.25;
}

.gbag-glue {
  fill: #e4e4e4;
  stroke: #999;
  stroke-width: 0.25;
}

.gbag-cut {
  fill: none;
  stroke: var(--gbag-ink);
  stroke-linejoin: round;
}

/* The folds: dashes, or dashes and dots, on a white line, so that they show on the red and the green. */
.gbag-halo {
  fill: none;
  stroke: #fff;
  stroke-width: 0.9;
}

.gbag-up {
  fill: none;
  stroke: var(--gbag-ink);
  stroke-width: 0.35;
  stroke-dasharray: 1.6 1.1;
}

.gbag-down {
  fill: none;
  stroke: var(--gbag-ink);
  stroke-width: 0.35;
  stroke-dasharray: 2.4 0.9 0.4 0.9;
}

.gbag-word,
.gbag-key,
.gbag-label-word {
  fill: #333;
  font-family: var(--sans);
}

.gbag-word {
  fill: #555;
  font-weight: 700;
}

@media screen {
  .gbag-art {
    zoom: 0.75;
  }
}

@page gbag {
  margin: 10mm;
}

@media print {
  html:has(.gbag-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.gbag-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.gbag-sheet) > :not(main),
  body:has(.gbag-sheet) main > :not(.gbag-sheet) {
    display: none !important;
  }

  body:has(.gbag-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .gbag-sheet {
    page: gbag;
    display: block;
  }

  /* The drawing keeps a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .gbag-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .gbag-page:last-child {
    break-after: auto;
  }
}

/* ---------- Christmas napkin rings (/printables/napkin-rings) ---------- */

/* The sheet (`.nring-sheet`): two pages of paper (`.nring-page`), each one SVG in mm (`.nring-art`, 190 mm wide, its
   height in its own attributes) with four rings (`.nring-ring`): the strip (`.nring-paper`) red, green, gold or navy
   with its pattern – dots (`.nring-dot`), little stars (`.nring-spark`), stripes (`.nring-stripe`) –, the topper
   (`.nring-topper`) with its drawing – holly (`.nring-holly`), a star, a tree, a snowflake –, the white field for the
   name (`.nring-name`) and its line (`.nring-write`); the slits red (`.nring-slit`) on a white line (`.nring-halo`);
   the cut line (`.nring-cut`) 0.4 mm, its width in its own attribute; and a key. In color (`.nring-color`) and to
   color (`.nring-line`). On the screen at three quarters of that size, where a narrow one scrolls sideways. Printed
   (`@page nring`), only the pages, each on its own sheet of A4 or US Letter. */
.nring-sheet {
  --nring-ink: #2b2522;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.nring-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.nring-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.nring-color {
  --nring-red: #c8323a;
  --nring-green: #2e7d4f;
  --nring-gold: #f2c14e;
  --nring-navy: #1f3a68;
  --nring-dot: #fff;
  --nring-spark: #f6c445;
  --nring-spark-line: #a8741a;
  --nring-stripe: #e0a127;
  --nring-snow: #fff;
  --nring-top-star: #f6c445;
  --nring-top-tree: #2e7d4f;
  --nring-top-holly: #fff;
  --nring-top-flake: #fff;
  --nring-star: #fff3c4;
  --nring-star-line: #a8741a;
  --nring-tree: #3f9a62;
  --nring-tree-line: #f6c445;
  --nring-leaf: #2e7d4f;
  --nring-leaf-line: #1d5534;
  --nring-berry: #c8323a;
  --nring-flake: #1f3a68;
  --nring-edge: none;
}

.nring-line {
  --nring-red: #fff;
  --nring-green: #fff;
  --nring-gold: #fff;
  --nring-navy: #fff;
  --nring-dot: #fff;
  --nring-spark: #fff;
  --nring-spark-line: var(--nring-ink);
  --nring-stripe: #fff;
  --nring-snow: #fff;
  --nring-top-star: #fff;
  --nring-top-tree: #fff;
  --nring-top-holly: #fff;
  --nring-top-flake: #fff;
  --nring-star: #fff;
  --nring-star-line: var(--nring-ink);
  --nring-tree: #fff;
  --nring-tree-line: var(--nring-ink);
  --nring-leaf: #fff;
  --nring-leaf-line: var(--nring-ink);
  --nring-berry: #fff;
  --nring-flake: var(--nring-ink);
  --nring-edge: var(--nring-ink);
}

.nring-red {
  fill: var(--nring-red);
}

.nring-green {
  fill: var(--nring-green);
}

.nring-gold {
  fill: var(--nring-gold);
}

.nring-navy {
  fill: var(--nring-navy);
}

.nring-top-star {
  fill: var(--nring-top-star);
}

.nring-top-tree {
  fill: var(--nring-top-tree);
}

.nring-top-holly {
  fill: var(--nring-top-holly);
}

.nring-top-flake {
  fill: var(--nring-top-flake);
}

/* The pattern: the snow on navy is the dots' look, the stripes only outlined to color. */
.nring-dot {
  fill: var(--nring-dot);
  stroke: var(--nring-edge);
  stroke-width: 0.2;
}

.nring-stripe {
  fill: var(--nring-stripe);
  stroke: var(--nring-edge);
  stroke-width: 0.2;
}

/* The drawings: their own lines, whatever the art they come from says. */
.nring-spark path {
  fill: var(--nring-spark);
  stroke: var(--nring-spark-line);
  stroke-width: 0.2;
}

.nring-star path {
  fill: var(--nring-star);
  stroke: var(--nring-star-line);
  stroke-width: 0.4;
}

.nring-tree path {
  fill: var(--nring-tree);
  stroke: var(--nring-tree-line);
  stroke-width: 0.4;
}

.nring-flake path {
  stroke: var(--nring-flake);
  stroke-width: 0.6;
}

.nring-leaf {
  fill: var(--nring-leaf);
  stroke: var(--nring-leaf-line);
  stroke-linejoin: round;
}

.nring-berry {
  fill: var(--nring-berry);
  stroke: var(--nring-leaf-line);
}

.nring-name {
  fill: #fff;
  stroke: var(--nring-ink);
  stroke-width: 0.25;
}

.nring-write {
  fill: none;
  stroke: #777;
  stroke-width: 0.3;
}

.nring-cut {
  fill: none;
  stroke: var(--nring-ink);
  stroke-linejoin: round;
}

/* The slits: solid and red, on a white line, so that they show on every color. */
.nring-halo {
  fill: none;
  stroke: #fff;
  stroke-width: 1.2;
}

.nring-slit {
  fill: none;
  stroke: #d0021b;
  stroke-width: 0.45;
}

.nring-key {
  fill: #333;
  font-family: var(--sans);
}

@media screen {
  .nring-art {
    zoom: 0.75;
  }
}

@page nring {
  margin: 10mm;
}

@media print {
  html:has(.nring-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.nring-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.nring-sheet) > :not(main),
  body:has(.nring-sheet) main > :not(.nring-sheet) {
    display: none !important;
  }

  body:has(.nring-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .nring-sheet {
    page: nring;
    display: block;
  }

  /* The drawing keeps a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .nring-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .nring-page:last-child {
    break-after: auto;
  }
}

/* ---------- Christmas headbands (/printables/christmas-headbands) ---------- */

/* The sheet (`.hband-sheet`): five pages of paper (`.hband-page`), each one SVG in mm (`.hband-art`, 190 mm wide,
   its height in its own attributes). Four fronts on two pages (`.hband-front`): the paper (`.hband-paper`) tan, gold,
   green or navy with the decoration – ears (`.hband-ear`), round feet (`.hband-foot`) and antlers (`.hband-beam…`),
   the crown's teeth (`.hband-teeth`) and stars, trees (`.hband-tree`) with trunks and baubles, snowflakes
   (`.hband-flake`) –, the band (`.hband-band`) with its pattern – the nose, dots, jewels, pearls, little stars, snow –,
   the glue fields grey (`.hband-glue`) with their word; then the same four to color. The side strips (`.hband-side`)
   light gold, every other one with the scale (`.hband-scale`). The cut line (`.hband-cut`) 0.4 mm, its width in its
   own attribute; a key on each page. In color (`.hband-color`) and to color (`.hband-line`). On the screen at three
   quarters of that size, where a narrow one scrolls sideways. Printed (`@page hband`), only the pages, each on its own
   sheet of A4 or US Letter. */
.hband-sheet {
  --hband-ink: #2b2522;
  color-scheme: light;
  display: grid;
  gap: 1rem;
}

.hband-page {
  overflow-x: auto;
  padding: 1.25rem;
  background: #fff;
  color: #000;
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.hband-art {
  display: block;
  margin: 0 auto;
  overflow: visible;
}

.hband-color {
  --hband-tan: #e8c99b;
  --hband-gold: #f2c14e;
  --hband-green: #1d5534;
  --hband-navy: #1f3a68;
  --hband-band-antlers: #8b5a2b;
  --hband-band-crown: #e0a127;
  --hband-band-trees: #c8323a;
  --hband-band-flakes: #2b5592;
  --hband-edge: none;
  --hband-ear: #8b5a2b;
  --hband-ear-in: #f2a7a0;
  --hband-beam-edge: #5a3517;
  --hband-beam: #8b5a2b;
  --hband-beam-light: #b98250;
  --hband-teeth: #f2c14e;
  --hband-line-gold: #a8741a;
  --hband-crown-star: #fff3c4;
  --hband-tree: #2e7d4f;
  --hband-tree-line: #f6c445;
  --hband-trunk: #8b5a2b;
  --hband-red: #c8323a;
  --hband-bright-gold: #f6c445;
  --hband-flake: #fff;
  --hband-nose: #d7262e;
  --hband-white: #fff;
  --hband-gem-green: #2e9e5b;
  --hband-gem-blue: #2f6fd0;
}

.hband-line {
  --hband-tan: #fff;
  --hband-gold: #fff;
  --hband-green: #fff;
  --hband-navy: #fff;
  --hband-band-antlers: #fff;
  --hband-band-crown: #fff;
  --hband-band-trees: #fff;
  --hband-band-flakes: #fff;
  --hband-edge: var(--hband-ink);
  --hband-ear: #fff;
  --hband-ear-in: #fff;
  --hband-beam-edge: var(--hband-ink);
  --hband-beam: #fff;
  --hband-beam-light: none;
  --hband-teeth: #fff;
  --hband-line-gold: var(--hband-ink);
  --hband-crown-star: #fff;
  --hband-tree: #fff;
  --hband-tree-line: var(--hband-ink);
  --hband-trunk: #fff;
  --hband-red: #fff;
  --hband-bright-gold: #fff;
  --hband-flake: var(--hband-ink);
  --hband-nose: #fff;
  --hband-white: #fff;
  --hband-gem-green: #fff;
  --hband-gem-blue: #fff;
}

.hband-tan {
  fill: var(--hband-tan);
}

.hband-gold {
  fill: var(--hband-gold);
}

.hband-green {
  fill: var(--hband-green);
}

.hband-navy {
  fill: var(--hband-navy);
}

/* The band between the glue fields: outlined only to color, where the decoration runs into it. */
.hband-band {
  stroke: var(--hband-edge);
  stroke-width: 0.3;
}

.hband-band-antlers {
  fill: var(--hband-band-antlers);
}

.hband-band-crown {
  fill: var(--hband-band-crown);
}

.hband-band-trees {
  fill: var(--hband-band-trees);
}

.hband-band-flakes {
  fill: var(--hband-band-flakes);
}

.hband-ear,
.hband-foot {
  fill: var(--hband-ear);
  stroke: var(--hband-beam-edge);
  stroke-width: 0.5;
}

.hband-ear-in {
  fill: var(--hband-ear-in);
  stroke: var(--hband-edge);
  stroke-width: 0.3;
}

.hband-beam-edge,
.hband-beam,
.hband-beam-light {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.hband-beam-edge {
  stroke: var(--hband-beam-edge);
}

.hband-beam {
  stroke: var(--hband-beam);
}

.hband-beam-light {
  stroke: var(--hband-beam-light);
}

.hband-teeth {
  fill: var(--hband-teeth);
  stroke: var(--hband-line-gold);
  stroke-width: 0.5;
  stroke-linejoin: round;
}

.hband-crown-star {
  fill: var(--hband-crown-star);
  stroke: var(--hband-line-gold);
  stroke-width: 0.4;
  stroke-linejoin: round;
}

.hband-tree {
  fill: var(--hband-tree);
  stroke: var(--hband-tree-line);
  stroke-width: 0.5;
  stroke-linejoin: round;
}

.hband-trunk {
  fill: var(--hband-trunk);
  stroke: var(--hband-edge);
  stroke-width: 0.3;
}

.hband-bauble-red,
.hband-gem-red {
  fill: var(--hband-red);
  stroke: var(--hband-edge);
  stroke-width: 0.3;
}

.hband-bauble-gold {
  fill: var(--hband-bright-gold);
  stroke: var(--hband-edge);
  stroke-width: 0.3;
}

.hband-flake path {
  fill: none;
  stroke: var(--hband-flake);
  stroke-linecap: round;
}

.hband-nose {
  fill: var(--hband-nose);
  stroke: var(--hband-edge);
  stroke-width: 0.4;
}

.hband-shine,
.hband-dot,
.hband-pearl,
.hband-snow {
  fill: var(--hband-white);
  stroke: var(--hband-edge);
  stroke-width: 0.25;
}

.hband-gem-green {
  fill: var(--hband-gem-green);
  stroke: var(--hband-edge);
  stroke-width: 0.3;
}

.hband-gem-blue {
  fill: var(--hband-gem-blue);
  stroke: var(--hband-edge);
  stroke-width: 0.3;
}

.hband-spark path {
  fill: var(--hband-bright-gold);
  stroke: var(--hband-line-gold);
  stroke-width: 0.25;
}

.hband-glue {
  fill: #e4e4e4;
  stroke: #999;
  stroke-width: 0.25;
}

.hband-word {
  fill: #555;
  font-family: var(--sans);
  font-weight: 700;
}

/* The side strips: light gold, which goes with every front, colored or not; the scale dark. */
.hband-strip {
  fill: #fbeab0;
}

.hband-side-dot {
  fill: #f2c14e;
}

.hband-tick {
  fill: none;
  stroke: #5a3517;
  stroke-width: 0.35;
}

.hband-number {
  fill: #5a3517;
  font-family: var(--sans);
  font-weight: 700;
}

.hband-cut {
  fill: none;
  stroke: var(--hband-ink);
  stroke-linejoin: round;
}

.hband-key {
  fill: #333;
  font-family: var(--sans);
}

@media screen {
  .hband-art {
    zoom: 0.75;
  }
}

@page hband {
  margin: 10mm;
}

@media print {
  html:has(.hband-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.hband-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.hband-sheet) > :not(main),
  body:has(.hband-sheet) main > :not(.hband-sheet) {
    display: none !important;
  }

  body:has(.hband-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .hband-sheet {
    page: hband;
    display: block;
  }

  /* The drawing keeps a millimetre of paper round the cut lines, so nothing of a page runs onto the next. */
  .hband-page {
    overflow: visible;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .hband-page:last-child {
    break-after: auto;
  }
}

/* The letters from the elf of /printables/elf-letters (`.elfl-sheet`): three pages of paper (`.elfl-page`) – the
   welcome letter and the goodbye letter (`.elfl-letter`) in a hand inside a double green frame, the elf's hat between
   stars and snowflakes at the top (`.elfl-top`), the child's and the elf's names on lines to type on (`.elfl-line`),
   what is typed in blue pen, an example in grey until then; under „What I liked best” three lines to write on by hand
   (`.elfl-rules`) –, then twelve notes to cut out (`.elfl-note`, the two empty ones `.elfl-blank`) along dashed lines,
   each with its drawing. Little color, all of it readable in black and white. Printed (`@page elfl`), only the pages,
   each 190 × 252 mm on its own sheet of A4 or Letter, the notes 58 × 55 mm; an empty field a line, its example not at
   all. */
.elfl-sheet {
  --elfl-ink: #23302a;
  --elfl-green: #2e6b45;
  --elfl-red: #b8323d;
  --elfl-rule: #8b97ad;
  color-scheme: light;
  display: grid;
  gap: 1.5rem;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

.elfl-page {
  background: #fff;
  color: var(--elfl-ink);
  border-radius: 6px;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
}

.elfl-page p {
  margin: 0;
}

.elfl-letter {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1.25rem 1.5rem 1.5rem;
  border: 7px double var(--elfl-green);
  font: 500 1.375rem/1.3 var(--hand);
}

.elfl-top {
  align-self: center;
  width: min(100%, 16rem);
  height: auto;
}

.elfl-hat {
  fill: #d4ebd8;
  stroke: var(--elfl-ink);
  stroke-width: 0.7;
  stroke-linejoin: round;
}

.elfl-band {
  fill: #fff;
  stroke: var(--elfl-ink);
  stroke-width: 0.7;
}

.elfl-bell {
  fill: #f6d77a;
  stroke: var(--elfl-ink);
  stroke-width: 0.7;
}

.elfl-hello {
  font-weight: 700;
  font-size: 2rem;
  line-height: 1.1;
  text-align: center;
  color: var(--elfl-red);
}

.elfl-line {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.elfl-line > span {
  flex: none;
}

.elfl-line input {
  flex: 1;
  min-width: 0;
  padding: 0 0.25rem;
  border: 0;
  border-bottom: 1.5px solid var(--elfl-rule);
  border-radius: 0;
  background: transparent;
  color: var(--pen);
  font: 600 1.375rem/2rem var(--hand);
}

.elfl-line input[type="text"]:focus {
  outline: 2px solid rgb(43 76 140 / 0.35);
}

.elfl-line input::placeholder {
  color: #9aa5b8;
  opacity: 1;
}

/* The elf signs at the bottom, on the right. */
.elfl-sign {
  align-self: flex-end;
  width: min(100%, 22rem);
  margin-top: auto;
  padding-top: 0.5rem;
  font-weight: 700;
  color: var(--elfl-green);
}

.elfl-liked {
  margin-top: 0.25rem;
  font-weight: 700;
}

.elfl-rule {
  display: block;
  height: 2rem;
  border-bottom: 1.5px solid var(--elfl-rule);
}

.elfl-notes {
  padding: 1rem;
}

.elfl-key {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  font: 0.875rem var(--sans);
  color: #333;
}

.elfl-dash {
  width: 2rem;
  border-top: 1.5px dashed #333;
}

.elfl-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
}

.elfl-note {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: 10rem;
  padding: 0.6rem;
  border: 1.5px dashed #333;
  text-align: center;
  font: 600 1.2rem/1.2 var(--hand);
  overflow-wrap: anywhere;
}

.elfl-note-art {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
}

.elfl-blank .elfl-rule {
  align-self: stretch;
  height: 1.6rem;
}

@media (max-width: 40rem) {
  .elfl-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@page elfl {
  margin: 10mm;
}

@media print {
  html:has(.elfl-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.elfl-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.elfl-sheet) > :not(main),
  body:has(.elfl-sheet) main > :not(.elfl-sheet) {
    display: none !important;
  }

  body:has(.elfl-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .elfl-sheet {
    page: elfl;
    display: block;
  }

  .elfl-page {
    width: 190mm;
    height: 252mm;
    margin: 0;
    border-radius: 0;
    box-shadow: none;
    break-after: page;
    break-inside: avoid;
  }

  .elfl-page:last-child {
    break-after: auto;
  }

  .elfl-letter {
    gap: 6mm;
    padding: 12mm 16mm 14mm;
    border-width: 2.4mm;
    font-size: 21pt;
  }

  .elfl-top {
    width: 110mm;
  }

  .elfl-hello {
    font-size: 32pt;
  }

  .elfl-line input {
    font-size: 21pt;
    line-height: 12mm;
    border-bottom: 1pt solid #777;
  }

  .elfl-line input::placeholder {
    color: transparent;
  }

  .elfl-rule {
    height: 13mm;
    border-bottom: 1pt solid #777;
  }

  .elfl-notes {
    padding: 0;
  }

  .elfl-key {
    margin-bottom: 4mm;
    font-size: 9pt;
  }

  .elfl-grid {
    grid-template-columns: repeat(3, 58mm);
    grid-auto-rows: 55mm;
    gap: 4mm;
    justify-content: center;
  }

  .elfl-note {
    min-height: 0;
    gap: 2.5mm;
    padding: 4mm;
    border: 0.3mm dashed #333;
    font-size: 17pt;
  }

  .elfl-note-art {
    width: 14mm;
    height: 14mm;
  }

  .elfl-blank .elfl-rule {
    height: 8mm;
  }

  /* The system's font of these pages (no Caveat) is taller and wider at the same size. */
  :root:lang(vi) .elfl-letter,
  :root:lang(ja) .elfl-letter,
  :root:lang(ko) .elfl-letter,
  :root:lang(zh-Hans) .elfl-letter,
  :root:lang(vi) .elfl-line input,
  :root:lang(ja) .elfl-line input,
  :root:lang(ko) .elfl-line input,
  :root:lang(zh-Hans) .elfl-line input {
    font-size: 16pt;
  }

  :root:lang(vi) .elfl-note,
  :root:lang(ja) .elfl-note,
  :root:lang(ko) .elfl-note,
  :root:lang(zh-Hans) .elfl-note {
    font-size: 14pt;
  }
}

/* The Christmas bucket list of /printables/christmas-bucket-list (`.bucket-sheet`): two pages of paper (`.bucket-page`)
   in a double green frame, each with a Christmas tree between stars and snowflakes at the top (`.bucket-top`), the
   heading and a line to type the family's name on (`.bucket-line`): the 24 ideas in two columns of twelve, each with a
   box to tick (`.bucket-box`, a square drawn here, no glyph), and a line for the best memory (`.bucket-memory`); then
   24 empty lines with their boxes (`.bucket-empty`). Little color, all of it readable in black and white. Printed
   (`@page bucket`), only the pages, each 190 × 252 mm on its own sheet of A4 or Letter; an empty field a line. */
.bucket-sheet {
  --bucket-ink: #23302a;
  --bucket-green: #2e6b45;
  --bucket-red: #b8323d;
  --bucket-rule: #8b97ad;
  color-scheme: light;
  display: grid;
  gap: 1.5rem;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

.bucket-page {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1.25rem 1.5rem 1.5rem;
  border: 7px double var(--bucket-green);
  border-radius: 6px;
  background: #fff;
  color: var(--bucket-ink);
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
  font: 500 1.25rem/1.2 var(--hand);
}

.bucket-page p {
  margin: 0;
}

.bucket-top {
  align-self: center;
  width: min(100%, 16rem);
  height: auto;
}

.bucket-title {
  font-weight: 700;
  font-size: 2rem;
  line-height: 1.1;
  text-align: center;
  color: var(--bucket-red);
}

.bucket-line,
.bucket-memory {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-weight: 700;
}

.bucket-line > span,
.bucket-memory > span:first-child {
  flex: none;
}

.bucket-line input {
  flex: 1;
  min-width: 0;
  padding: 0 0.25rem;
  border: 0;
  border-bottom: 1.5px solid var(--bucket-rule);
  border-radius: 0;
  background: transparent;
  color: var(--pen);
  font: 600 1.25rem/2rem var(--hand);
}

.bucket-line input[type="text"]:focus {
  outline: 2px solid rgb(43 76 140 / 0.35);
}

.bucket-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: repeat(12, auto);
  grid-auto-flow: column;
  gap: 0.35rem 1.5rem;
  margin: 0.25rem 0 0;
  padding: 0;
  list-style: none;
}

.bucket-list li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 2.2rem;
  overflow-wrap: anywhere;
}

.bucket-box {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  border: 2px solid var(--bucket-green);
  border-radius: 3px;
  background: #fff;
}

.bucket-rule {
  flex: 1;
  align-self: flex-end;
  min-width: 0;
  height: 1.6rem;
  border-bottom: 1.5px solid var(--bucket-rule);
}

.bucket-memory {
  margin-top: 0.5rem;
}

@media (max-width: 40rem) {
  .bucket-list {
    grid-template-columns: 1fr;
    grid-template-rows: none;
    grid-auto-flow: row;
  }
}

@page bucket {
  margin: 10mm;
}

@media print {
  html:has(.bucket-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.bucket-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.bucket-sheet) > :not(main),
  body:has(.bucket-sheet) main > :not(.bucket-sheet) {
    display: none !important;
  }

  body:has(.bucket-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .bucket-sheet {
    page: bucket;
    display: block;
  }

  .bucket-page {
    width: 190mm;
    height: 252mm;
    margin: 0;
    gap: 3mm;
    padding: 9mm 12mm 10mm;
    border-width: 2.4mm;
    border-radius: 0;
    box-shadow: none;
    font-size: 15pt;
    break-after: page;
    break-inside: avoid;
  }

  .bucket-page:last-child {
    break-after: auto;
  }

  .bucket-top {
    width: 90mm;
  }

  .bucket-title {
    font-size: 28pt;
  }

  .bucket-line input {
    font-size: 16pt;
    line-height: 10mm;
    border-bottom: 1pt solid #777;
  }

  .bucket-list {
    flex: 1;
    grid-template-rows: repeat(12, 1fr);
    gap: 0 8mm;
    margin-top: 2mm;
  }

  .bucket-list li {
    min-height: 0;
    gap: 3mm;
    line-height: 1.1;
  }

  .bucket-box {
    width: 5mm;
    height: 5mm;
    border: 0.5mm solid #23302a;
    border-radius: 0.8mm;
  }

  .bucket-rule {
    height: 8mm;
    border-bottom: 1pt solid #777;
  }

  .bucket-empty .bucket-list li {
    align-items: flex-end;
    padding-bottom: 1mm;
  }

  .bucket-memory {
    margin-top: 1mm;
  }

  /* The system's font of these pages (no Caveat) is taller and wider at the same size. */
  :root:lang(vi) .bucket-page,
  :root:lang(ja) .bucket-page,
  :root:lang(ko) .bucket-page,
  :root:lang(zh-Hans) .bucket-page,
  :root:lang(vi) .bucket-line input,
  :root:lang(ja) .bucket-line input,
  :root:lang(ko) .bucket-line input,
  :root:lang(zh-Hans) .bucket-line input {
    font-size: 12pt;
  }
}

/* The Christmas wish list of /printables/christmas-wish-list (`.wlist-sheet`): two pages of paper (`.wlist-page`) in a
   double red frame, each with a tree between baubles and stars at the top (`.wlist-top`), the heading and a line to
   type a name on (`.wlist-line`). The child's (`.wlist-kid`): the key of the star (`.wlist-key`), 8 numbered boxes in
   two columns to draw or glue a wish in (`.wlist-box`), each with a star to color (`.wlist-star`, lines of an SVG, no
   glyph) and a line under the drawing, then the good deed in return (`.wlist-promise`). The grown-up's
   (`.wlist-adult`): a frame of four sizes (`.wlist-sizes`), a table of 12 gifts with a box to tick when bought
   (`.wlist-check`, a square drawn here) and the line of what not to buy (`.wlist-dont`). Little color, all of it
   readable in black and white. Printed (`@page wlist`), only the pages, each 190 × 252 mm on its own sheet of A4 or
   Letter; an empty field a line. */
.wlist-sheet {
  --wlist-ink: #2a2526;
  --wlist-red: #b8323d;
  --wlist-green: #2e6b45;
  --wlist-rule: #8b97ad;
  color-scheme: light;
  display: grid;
  gap: 1.5rem;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

.wlist-page {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1.25rem 1.5rem 1.5rem;
  border: 7px double var(--wlist-red);
  border-radius: 6px;
  background: #fff;
  color: var(--wlist-ink);
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
  font: 500 1.25rem/1.2 var(--hand);
}

.wlist-page p {
  margin: 0;
}

.wlist-top {
  align-self: center;
  width: min(100%, 14rem);
  height: auto;
}

.wlist-title {
  font-weight: 700;
  font-size: 2rem;
  line-height: 1.1;
  text-align: center;
  color: var(--wlist-red);
}

.wlist-line,
.wlist-promise,
.wlist-dont {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-weight: 700;
}

.wlist-line > span,
.wlist-promise > span:first-child,
.wlist-dont > span:first-child {
  flex: none;
}

.wlist-line input,
.wlist-size input {
  flex: 1;
  min-width: 0;
  padding: 0 0.25rem;
  border: 0;
  border-bottom: 1.5px solid var(--wlist-rule);
  border-radius: 0;
  background: transparent;
  color: var(--pen);
  font: 600 1.25rem/2rem var(--hand);
}

.wlist-line input[type="text"]:focus,
.wlist-size input[type="text"]:focus {
  outline: 2px solid rgb(43 76 140 / 0.35);
}

.wlist-rule {
  flex: 1;
  align-self: flex-end;
  min-width: 0;
  height: 1.6rem;
  border-bottom: 1.5px solid var(--wlist-rule);
}

.wlist-key {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font-size: 1.05rem;
}

.wlist-star {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
}

.wlist-star path {
  stroke: var(--wlist-red);
  stroke-width: 0.9;
}

.wlist-boxes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.wlist-box {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 9rem;
  padding: 0 0.75rem 0.75rem;
  border: 2px solid var(--wlist-green);
  border-radius: 10px;
}

.wlist-box .wlist-star {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
}

.wlist-n {
  position: absolute;
  top: 0.4rem;
  left: 0.5rem;
  display: grid;
  place-items: center;
  width: 1.6rem;
  height: 1.6rem;
  border: 2px solid var(--wlist-green);
  border-radius: 50%;
  font-weight: 700;
  font-size: 1rem;
  line-height: 1;
}

.wlist-box .wlist-rule {
  flex: none;
}

.wlist-deal {
  font-size: 1rem;
  text-align: center;
}

.wlist-sizes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.25rem 1.5rem;
  padding: 0.5rem 0.9rem 0.75rem;
  border: 2px solid var(--wlist-green);
  border-radius: 8px;
}

.wlist-sizes > p {
  grid-column: 1 / -1;
  font-weight: 700;
  color: var(--wlist-green);
}

.wlist-size {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.wlist-size > span {
  flex: none;
}

.wlist-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}

.wlist-table th,
.wlist-table td {
  padding: 0.2rem 0.4rem;
  border: 1.5px solid var(--wlist-rule);
  vertical-align: middle;
}

.wlist-table th {
  overflow-wrap: anywhere;
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.1;
  text-align: left;
  color: var(--wlist-green);
}

.wlist-table th:nth-child(1) {
  width: 43%;
}

.wlist-table th:nth-child(2) {
  width: 27%;
}

.wlist-table th:nth-child(3) {
  width: 16%;
}

.wlist-table th:last-child,
.wlist-table td:last-child {
  text-align: center;
}

.wlist-table td {
  height: 2.2rem;
}

.wlist-check {
  display: inline-block;
  width: 1.1rem;
  height: 1.1rem;
  border: 2px solid var(--wlist-green);
  border-radius: 3px;
  background: #fff;
  vertical-align: middle;
}

@media (max-width: 40rem) {
  .wlist-boxes,
  .wlist-sizes {
    grid-template-columns: 1fr;
  }
}

@page wlist {
  margin: 10mm;
}

@media print {
  html:has(.wlist-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.wlist-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.wlist-sheet) > :not(main),
  body:has(.wlist-sheet) main > :not(.wlist-sheet) {
    display: none !important;
  }

  body:has(.wlist-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .wlist-sheet {
    page: wlist;
    display: block;
  }

  .wlist-page {
    width: 190mm;
    height: 252mm;
    margin: 0;
    gap: 2.5mm;
    padding: 7mm 10mm 8mm;
    border-width: 2.4mm;
    border-radius: 0;
    box-shadow: none;
    font-size: 15pt;
    break-after: page;
    break-inside: avoid;
  }

  .wlist-page:last-child {
    break-after: auto;
  }

  .wlist-top {
    width: 56mm;
  }

  .wlist-title {
    font-size: 24pt;
  }

  .wlist-line input,
  .wlist-size input {
    font-size: 15pt;
    line-height: 9mm;
    border-bottom: 1pt solid #777;
  }

  .wlist-rule {
    height: 8mm;
    border-bottom: 1pt solid #777;
  }

  .wlist-key {
    gap: 2mm;
    font-size: 13pt;
  }

  .wlist-star {
    width: 6mm;
    height: 6mm;
  }

  .wlist-star path {
    stroke: #000;
    stroke-width: 0.7;
  }

  .wlist-boxes {
    flex: 1;
    grid-template-rows: repeat(4, 1fr);
    gap: 3mm 5mm;
  }

  .wlist-box {
    min-height: 0;
    padding: 0 4mm 3mm;
    border: 0.5mm solid #23302a;
    border-radius: 3mm;
  }

  .wlist-box .wlist-star {
    top: 2mm;
    right: 2mm;
    width: 7mm;
    height: 7mm;
  }

  .wlist-n {
    top: 2mm;
    left: 2mm;
    width: 7mm;
    height: 7mm;
    border: 0.4mm solid #23302a;
    font-size: 12pt;
  }

  .wlist-deal {
    font-size: 12pt;
  }

  .wlist-sizes {
    gap: 0 8mm;
    padding: 2mm 4mm 3mm;
    border: 0.4mm solid #23302a;
    border-radius: 2mm;
  }

  .wlist-table th,
  .wlist-table td {
    padding: 1mm 2mm;
    border: 0.3mm solid #777;
  }

  .wlist-table th {
    height: 9mm;
    font-size: 13pt;
    color: #000;
  }

  .wlist-table td {
    height: 11mm;
  }

  .wlist-check {
    width: 5mm;
    height: 5mm;
    border: 0.5mm solid #23302a;
    border-radius: 0.8mm;
  }

  /* The system's font of these pages (no Caveat) is taller and wider at the same size. */
  :root:lang(vi) .wlist-page,
  :root:lang(ja) .wlist-page,
  :root:lang(ko) .wlist-page,
  :root:lang(zh-Hans) .wlist-page,
  :root:lang(vi) .wlist-line input,
  :root:lang(ja) .wlist-line input,
  :root:lang(ko) .wlist-line input,
  :root:lang(zh-Hans) .wlist-line input,
  :root:lang(vi) .wlist-size input,
  :root:lang(ja) .wlist-size input,
  :root:lang(ko) .wlist-size input,
  :root:lang(zh-Hans) .wlist-size input {
    font-size: 12pt;
  }

  :root:lang(vi) .wlist-table th,
  :root:lang(ja) .wlist-table th,
  :root:lang(ko) .wlist-table th,
  :root:lang(zh-Hans) .wlist-table th,
  :root:lang(vi) .wlist-key,
  :root:lang(ja) .wlist-key,
  :root:lang(ko) .wlist-key,
  :root:lang(zh-Hans) .wlist-key,
  :root:lang(vi) .wlist-deal,
  :root:lang(ja) .wlist-deal,
  :root:lang(ko) .wlist-deal,
  :root:lang(zh-Hans) .wlist-deal {
    font-size: 10.5pt;
  }
}

/* ---------- Christmas recipe cards (/printables/recipe-cards) ---------- */

/* The recipe cards and cookie exchange labels of /printables/recipe-cards (`.rcard-sheet`): two pages of paper
   (`.rcard-page`). The first, two blank cards (`.rcard-card`) in a thin dashed cut line, printed exactly 6 × 4 inches
   (152.4 × 101.6 mm) to fit a recipe box: a small tree (`.rcard-art`, lines of an SVG) by the line for the recipe's
   name, four small fields (`.rcard-facts`), the columns of ingredients and method of 9 lines (`.rcard-lines`) and the
   cook's name (`.rcard-from`). The second, 8 cookie exchange labels (`.rcard-label`, 85 × 55 mm) 2 × 4 in cut lines,
   each with a drawing, two lines, 5 allergens with a box to tick (`.rcard-box`, a square drawn here) and a line for
   notes. Little color, all of it readable in black and white. Printed (`@page rcard`), only the pages, each
   190 × 252 mm on its own sheet of A4 or Letter; an empty field a line. */
.rcard-sheet {
  --rcard-ink: #2a2526;
  --rcard-red: #b8323d;
  --rcard-green: #2e6b45;
  --rcard-rule: #8b97ad;
  color-scheme: light;
  display: grid;
  gap: 1.5rem;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

.rcard-page {
  display: grid;
  gap: 1rem;
  padding: 1.25rem;
  border-radius: 6px;
  background: #fff;
  color: var(--rcard-ink);
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
  font: 500 1.1rem/1.2 var(--hand);
}

.rcard-labels {
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}

.rcard-page p {
  margin: 0;
}

.rcard-card,
.rcard-label {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
  padding: 0.9rem 1rem;
  border: 1.5px dashed #777;
}

.rcard-card {
  min-height: 24rem;
}

.rcard-head,
.rcard-facts,
.rcard-from,
.rcard-field {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  min-width: 0;
}

.rcard-head {
  align-items: center;
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--rcard-red);
}

.rcard-head .rcard-field {
  flex: 1;
}

.rcard-facts {
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
}

.rcard-facts .rcard-field {
  flex: 1 1 8rem;
}

.rcard-field > span:first-child,
.rcard-from > span {
  flex: none;
  font-weight: 700;
}

.rcard-rule {
  flex: 1;
  align-self: flex-end;
  min-width: 1.5rem;
  height: 1.3rem;
  border-bottom: 1.5px solid var(--rcard-rule);
}

.rcard-art {
  flex: none;
  width: 1.75rem;
  height: 1.75rem;
}

.rcard-art path {
  fill: none;
  stroke: var(--rcard-green);
  stroke-width: 0.9;
}

.rcard-cols {
  flex: 1;
  display: grid;
  grid-template-columns: 2fr 3fr;
  gap: 1.25rem;
}

.rcard-col {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.rcard-col-title {
  font-weight: 700;
  color: var(--rcard-green);
}

.rcard-lines {
  flex: 1;
  display: grid;
  grid-template-rows: repeat(9, 1fr);
  margin: 0;
  padding: 0;
  list-style: none;
}

.rcard-lines li {
  min-height: 1.5rem;
  border-bottom: 1.5px solid var(--rcard-rule);
}

.rcard-from input {
  flex: 1;
  min-width: 0;
  padding: 0 0.25rem;
  border: 0;
  border-bottom: 1.5px solid var(--rcard-rule);
  border-radius: 0;
  background: transparent;
  color: var(--pen);
  font: 600 1.1rem/1.8rem var(--hand);
}

.rcard-from input[type="text"]:focus {
  outline: 2px solid rgb(43 76 140 / 0.35);
}

.rcard-label .rcard-head {
  color: var(--rcard-ink);
  font-size: inherit;
}

.rcard-contains {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.2rem 0.6rem;
}

.rcard-contains > span:first-child {
  font-weight: 700;
}

.rcard-allergen {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  white-space: nowrap;
}

.rcard-box {
  flex: none;
  display: inline-block;
  width: 0.85rem;
  height: 0.85rem;
  border: 2px solid var(--rcard-green);
  border-radius: 2px;
  background: #fff;
}

@media (max-width: 40rem) {
  .rcard-cols {
    grid-template-columns: 1fr;
  }
}

@page rcard {
  margin: 10mm;
}

@media print {
  html:has(.rcard-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.rcard-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.rcard-sheet) > :not(main),
  body:has(.rcard-sheet) main > :not(.rcard-sheet) {
    display: none !important;
  }

  body:has(.rcard-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .rcard-sheet {
    page: rcard;
    display: block;
  }

  .rcard-page {
    box-sizing: border-box;
    width: 190mm;
    height: 252mm;
    margin: 0;
    padding: 0;
    border-radius: 0;
    box-shadow: none;
    font-size: 12pt;
    break-after: page;
    break-inside: avoid;
  }

  .rcard-page:last-child {
    break-after: auto;
  }

  .rcard-cards {
    grid-template-columns: 152.4mm;
    grid-template-rows: repeat(2, 101.6mm);
    align-content: start;
    justify-content: center;
    gap: 12mm;
    padding-top: 8mm;
  }

  .rcard-labels {
    grid-template-columns: repeat(2, 85mm);
    grid-template-rows: repeat(4, 55mm);
    align-content: start;
    justify-content: center;
    gap: 6mm 8mm;
    padding-top: 2mm;
  }

  .rcard-card,
  .rcard-label {
    box-sizing: border-box;
    min-height: 0;
    overflow: hidden;
    border: 0.3mm dashed #555;
  }

  .rcard-card {
    width: 152.4mm;
    height: 101.6mm;
    gap: 1.8mm;
    padding: 4mm 5mm;
  }

  .rcard-label {
    width: 85mm;
    height: 55mm;
    justify-content: space-between;
    gap: 2.2mm;
    padding: 4mm 4mm 5mm;
    font-size: 12.5pt;
  }

  .rcard-head {
    gap: 2mm;
    font-size: 14pt;
    color: #000;
  }

  .rcard-art {
    width: 7mm;
    height: 7mm;
  }

  .rcard-art path {
    stroke: #23302a;
    stroke-width: 0.7;
  }

  .rcard-facts {
    flex-wrap: nowrap;
    gap: 4mm;
    font-size: 10.5pt;
  }

  .rcard-facts .rcard-field {
    flex: 1 1 0;
  }

  .rcard-rule {
    min-width: 6mm;
    height: 6mm;
    border-bottom: 0.3mm solid #777;
  }

  .rcard-cols {
    gap: 6mm;
  }

  .rcard-col-title {
    font-size: 11pt;
    color: #000;
  }

  .rcard-lines li {
    min-height: 0;
    border-bottom: 0.3mm solid #777;
  }

  .rcard-from {
    font-size: 11pt;
  }

  .rcard-from input {
    font-size: 12pt;
    line-height: 6mm;
    border-bottom: 0.3mm solid #777;
  }

  .rcard-contains {
    gap: 1.5mm 3mm;
    font-size: 11pt;
  }

  .rcard-box {
    width: 3.2mm;
    height: 3.2mm;
    border: 0.4mm solid #23302a;
    border-radius: 0.6mm;
  }

  /* The system's font of these pages (no Caveat) is taller and wider at the same size. */
  :root:lang(vi) .rcard-page,
  :root:lang(ja) .rcard-page,
  :root:lang(ko) .rcard-page,
  :root:lang(zh-Hans) .rcard-page,
  :root:lang(vi) .rcard-label,
  :root:lang(ja) .rcard-label,
  :root:lang(ko) .rcard-label,
  :root:lang(zh-Hans) .rcard-label {
    font-size: 9pt;
  }

  :root:lang(vi) .rcard-head,
  :root:lang(ja) .rcard-head,
  :root:lang(ko) .rcard-head,
  :root:lang(zh-Hans) .rcard-head {
    font-size: 11pt;
  }

  :root:lang(vi) .rcard-facts,
  :root:lang(ja) .rcard-facts,
  :root:lang(ko) .rcard-facts,
  :root:lang(zh-Hans) .rcard-facts,
  :root:lang(vi) .rcard-contains,
  :root:lang(ja) .rcard-contains,
  :root:lang(ko) .rcard-contains,
  :root:lang(zh-Hans) .rcard-contains {
    font-size: 8.5pt;
  }
}

/* The viewer of a printable (`printables::pages::viewer`): one item alone on one screen, nothing to scroll and no
   site bar – the item's SVG takes all the height the thin bar under it leaves, drawn as large as fits (the SVG's own
   `meet`, as `object-fit: contain`), in portrait and landscape alike. A swipe goes to the previous or the next
   (`public/app.js`). The links to it from the item's page (`.viewer-to`) look like what they name. Printed: the item
   alone, as large as fits one page of A4 or US Letter. */
body:has(.viewer) {
  height: 100svh;
  height: 100dvh;
  min-height: 0;
  overflow: hidden;
  overscroll-behavior: none;
}

.viewer {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  touch-action: pan-y pinch-zoom;
}

.viewer .viewer-item {
  flex: 1;
  min-height: 0;
  width: 100%;
  height: auto;
  max-width: none;
  max-height: none;
  margin: 0;
  border-radius: 0;
  background: #fff;
}

/* A part of a printable's page in the viewer (`.viewer-fit`, `printables::pages::sheet_viewer`): in the tags of its page,
   so it looks as there, drawn at the size of the page and scaled by `public/app.js` so the part (`[data-viewed]`)
   fills the screen; what is round it is cut off. Its buttons to color on the screen are left out. */
.viewer .viewer-fit {
  position: relative;
  overflow: hidden;
  color: #1d1d1d;
}

.viewer-fit > * {
  width: 100%;
  margin: 0;
  transform-origin: 0 0;
}

/* What the viewed part is cut out with is only a frame: not its sheet's shadow round the part. */
.viewer-fit :has([data-viewed]) {
  box-shadow: none;
}

/* The link in the corner of each part of a printable's page to it alone (`public/app.js`); not printed. */
.viewer-corner {
  position: absolute;
  top: 0.25rem;
  right: 0.25rem;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: #1f2937;
  color: #fff;
  font-size: 1.4rem;
  line-height: 1;
  text-decoration: none;
  opacity: 0.85;
}

@media print {
  .viewer-corner {
    display: none !important;
  }
}

.viewer-fit [class$="-tools"] {
  display: none;
}

/* The jokes to print are not on their page's screen, only printed: here they are what is shown. */
.viewer-fit .joke-sheet {
  display: block;
}

.viewer-fit .joke-slips {
  margin: 0;
  padding: 1rem;
  list-style: none;
}

.viewer-fit .joke-slip {
  padding: 2rem 1.25rem;
  border: 2px dashed #b9b9b9;
  border-radius: 1rem;
  font-size: 1.5rem;
  line-height: 1.4;
  text-align: center;
}

.viewer-fit .joke-flip {
  margin-top: 1.5rem;
  color: #b3261e;
}

.viewer-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  height: 3rem;
  padding: 0 0.375rem;
  font-size: 0.9375rem;
  white-space: nowrap;
}

.viewer-bar a,
.viewer-print {
  display: inline-flex;
  align-items: center;
  height: 2.5rem;
  padding: 0 0.75rem;
  border: 0;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.12);
  color: var(--snow);
  font: inherit;
  text-decoration: none;
  cursor: pointer;
}

.viewer-bar .viewer-step {
  padding: 0 0.625rem;
  font-size: 1.75rem;
  line-height: 1;
}

/* A narrow phone (360 px): the longest words of the bar still on one line. */
@media (max-width: 24rem) {
  .viewer-bar {
    font-size: 0.8125rem;
  }

  .viewer-bar a,
  .viewer-print {
    padding: 0 0.5rem;
  }
}

.viewer-print[hidden] {
  display: none;
}

.viewer-count {
  min-width: 3rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.viewer-back {
  margin-right: auto;
}

.viewer-print {
  margin-left: auto;
}

.viewer-open {
  text-align: center;
}

.viewer-open .button {
  font-size: 1.25rem;
}

a.viewer-to {
  color: inherit;
  text-decoration: none;
}

@page viewer {
  margin: 1cm;
}

@media print {
  html:has(.viewer) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.viewer) {
    display: block;
    height: auto;
    overflow: visible;
    background: #fff;
  }

  .viewer {
    display: block;
    padding: 0;
    page: viewer;
  }

  .viewer-bar {
    display: none;
  }

  /* Not left out with what is round a sheet in `<main>` (`body:has(.…-sheet) main > :not(.…-sheet)`, `!important`) by
     its page's print: more specific. */
  html body main.viewer > div.viewer-item.viewer-fit {
    display: block !important;
    height: auto;
    max-height: none;
    overflow: visible;
  }

  .viewer-fit > * {
    transform: none !important;
  }

  /* A4 is 297 mm high, US Letter 279 mm: less the margins, the item fits both. */
  .viewer .viewer-item {
    display: block;
    height: 255mm;
    max-height: 255mm;
    break-inside: avoid;
  }
}

/* A game alone on one screen (`games::Game` with `screen`), in the frame of the viewer of the printables (`.viewer`,
   above): its one item in the stage, which takes all the height the thin bar under it leaves and scrolls nothing –
   what is in it shrinks to fit, in portrait and landscape alike; no site bar, no text round it. */
.play-screen {
  touch-action: manipulation;
}

.play-stage {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: safe center;
  gap: 0.5rem;
  padding: 0.5rem;
  overflow: auto;
}

.play-stage > * {
  min-height: 0;
  margin: 0;
}

/* A maze: the mazes to pick from over it, its drawing as large as fits – as wide as a phone held upright –, what it
   says and its buttons under it; in landscape, walked (`.maze-on`), all but the drawing beside it. */
.play-stage:has(.maze) {
  padding-inline: 0;
}

.play-stage .maze {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 0.5rem 0;
}

.play-stage .maze-drawing {
  flex: 1;
  min-height: 0;
  height: 100%;
}

@media (orientation: landscape) {
  .play-stage .maze {
    padding-inline: 0.5rem;
  }

  .play-stage .maze-on {
    display: grid;
    grid-template: 1fr repeat(3, auto) 1fr / minmax(0, 1fr) minmax(14rem, 22rem);
    gap: 0 1rem;
  }

  .play-stage .maze-on .maze-drawing {
    grid-area: 1 / 1 / -1 / 2;
  }

  .play-stage .maze-on .maze-pick {
    grid-area: 2 / 2;
  }

  .play-stage .maze-on .maze-said {
    grid-area: 3 / 2;
  }

  .play-stage .maze-on .maze-tools {
    grid-area: 4 / 2;
  }
}

/* A crossword: the clue of the word being filled in over the board (`data-clue`, public/app.js), held at the top while
   the stage scrolls, the board as large as the screen lets it (`--cols`, `--rows`) – its squares 30 px at least but
   never wider than the white, which keeps 28 px for 12 columns (`CROSSWORD_COLUMNS`) across 360 px, and 3rem at most;
   so the stage scrolls down, never sideways –, the buttons under it, then the lists of clues to tap; in landscape the
   lists beside the board, scrolled on their own. Not zoomed out to fit (app.js). */
.play-stage:has(.crossword) {
  padding-inline: 0.25rem;
}

.play-stage .crossword-sheet {
  flex: none;
}

.play-stage .crossword {
  padding: 0.5rem 0.25rem;
}

.play-stage .cw-how {
  position: sticky;
  top: 0;
  z-index: 2;
  min-height: 3em;
  margin: 0 0 0.5rem;
  padding: 0.25rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  background: #fff;
}

.play-stage .cw-board {
  width: min(100%, var(--cols) * 3rem, max(var(--cols) * 30px, (100dvh - 15rem) * var(--cols) / var(--rows)));
  max-width: none;
}

.play-stage .cw-said {
  min-height: 1.5em;
  margin: 0.25rem 0 0;
}

.play-stage .cw-buttons {
  margin: 0.25rem 0 0;
}

@media (orientation: landscape) {
  .play-stage .crossword {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(14rem, 26rem);
    align-items: start;
    gap: 0 1rem;
  }

  .play-stage .cw-board {
    width: min(100%, var(--cols) * 3rem, max(var(--cols) * 30px, (100dvh - 15rem) * var(--cols) / var(--rows)));
  }

  .play-stage .cw-clues {
    grid-template-columns: 1fr;
    max-height: calc(100dvh - 7rem);
    overflow-y: auto;
  }
}

/* A word search: the level on top, the grid as large as fits (`--side`), the words under it and a new grid at the end;
   in landscape all but the grid beside it. */
.play-stage .wordsearch {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.375rem;
  container-type: size;
  --side: min(100cqw, 100cqh - 12rem);
}

.play-stage .wordsearch > * {
  margin: 0;
}

.play-stage .wordsearch-levels,
.play-stage .wordsearch-new {
  justify-content: center;
  text-align: center;
}

.play-stage .wordsearch-hint {
  font-size: 0.9375rem;
  text-align: center;
}

.play-stage .wordsearch-grid {
  width: var(--side);
  max-width: none;
}

.play-stage .wordsearch-grid td {
  height: calc(var(--side) / 10);
  font-size: calc(var(--side) / 20);
}

.play-stage .wordsearch-grid[data-size="13"] td {
  height: calc(var(--side) / 13);
  font-size: calc(var(--side) / 26);
}

.play-stage .wordsearch-said {
  min-height: 1.4em;
  text-align: center;
}

.play-stage .wordsearch-words {
  font-size: 0.9375rem;
  line-height: 1.4;
}

@media (orientation: landscape) {
  .play-stage .wordsearch {
    display: grid;
    grid-template: "grid levels" auto "grid hint" auto "grid said" auto "grid words" auto "grid new" auto / auto 1fr;
    align-content: center;
    gap: 0.375rem 1rem;
    --side: min(55cqw, 100cqh);
  }

  .play-stage .wordsearch-grid {
    grid-area: grid;
  }

  .play-stage .wordsearch-levels {
    grid-area: levels;
  }

  .play-stage .wordsearch-hint {
    grid-area: hint;
  }

  .play-stage .wordsearch-said {
    grid-area: said;
  }

  .play-stage .wordsearch-words {
    grid-area: words;
  }

  .play-stage .wordsearch-new {
    grid-area: new;
  }
}

/* The memory game: the board as large as fits under the choices and the count (`--ratio`: its columns over its rows),
   beside them in landscape. */
.play-stage .memory-game {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0;
  container-type: size;
}

.play-stage .memory-game[hidden] {
  display: none;
}

.play-stage .memory-board {
  --ratio: 1;
  width: min(100cqw, (100cqh - 11rem) * var(--ratio));
  max-width: none;
  margin-top: 0.5rem;
}

.play-stage .memory-cols-3 {
  --ratio: 0.75;
}

.play-stage .memory-count,
.play-stage .memory-turn,
.play-stage .memory-said {
  margin-top: 0.375rem;
}

@media (orientation: landscape) {
  .play-stage .memory-game {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-auto-flow: dense;
    align-content: center;
    gap: 0.25rem 1rem;
  }

  .play-stage .memory-game > * {
    grid-column: 2;
  }

  .play-stage .memory-board {
    grid-column: 1;
    grid-row: 1 / span 9;
    width: min(60cqw, (100cqh - 0.5rem) * var(--ratio));
    margin: 0;
  }
}

/* A text alone on one screen (a paragraph of a story to read out, a clue): a white card as large as the stage, the text
   in the middle, as large as fits (`data-fit`, public/app.js). */
.play-stage .play-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.75em;
  padding: 1rem;
  border-radius: 20px;
  background: #fff;
  color: #000;
  font-size: 1.125rem;
  line-height: 1.45;
  overflow: hidden;
}

.play-stage .play-text > * {
  margin: 0;
}

.play-stage .play-text h2 {
  font-size: 1.3em;
  color: #000;
}

.play-stage .play-text .hunt-answer {
  font-size: 0.7em;
  color: #555;
}

/* The party games of teams on one phone (`party::pages::TeamGame`), the white elephant: their panels closer together, the
   timer smaller, in landscape side by side; what still does not fit is zoomed out to fit (public/app.js). */
.play-stage .tools,
.play-stage .team-game,
.play-stage .team-setup,
.play-stage .team-play {
  gap: 0.5rem;
}

.play-stage .panel {
  padding: 0.75rem;
  border-radius: 16px;
  box-shadow: none;
}

.play-stage .team-setup p,
.play-stage .minute-pick p {
  font-size: 0.9375rem;
  line-height: 1.4;
}

.play-stage .team-board li {
  padding: 0.375rem 0.75rem;
}

.play-stage .team-board strong {
  font-size: 1.25rem;
}

.play-stage .team-turn-panel {
  gap: 0.5rem;
}

.play-stage .timer {
  gap: 0.375rem;
}

.play-stage .timer-name {
  display: none;
}

.play-stage .timer-time {
  font-size: 2.75rem;
}

@media (orientation: landscape) {
  .play-stage .team-setup {
    grid-template-columns: 1fr 1fr;
    align-items: start;
    column-gap: 1rem;
  }

  .play-stage .team-setup > p {
    grid-row: span 4;
  }

  .play-stage .team-turn-panel {
    grid-template-columns: 1fr 1fr;
  }
}

.play-stage .paper {
  padding: 0.75rem;
}

.play-stage .paper .form {
  gap: 0.5rem;
}

.play-stage .dice svg {
  width: 4.5rem;
  height: 4.5rem;
}

@media (orientation: landscape) {
  .play-stage:has(#order) {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-content: center;
  }
}

/* A quiz: a question at a time (public/app.js), without the keys to press. */
.play-stage .quiz-keys {
  display: none;
}

.play-stage .quiz-play > .block,
.play-stage .quiz-play section.block {
  margin-block: 0.5rem;
}

/* The room uses the same board, lobby and clock as the other live games. */
.charades-room-form,
.charades-team-choice {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 1rem;
}

.charades-room-form label,
.charades-team-choice label {
  flex: 1 1 9rem;
  min-width: 0;
}

.charades-room select {
  width: 100%;
}

.charades-person h3 {
  overflow-wrap: anywhere;
}

.charades-turn {
  text-align: center;
}

.charades-turn .live-time,
.charades-room .team-verdict {
  justify-content: center;
}

.charades-turn .charades-shown {
  margin: 1.5rem 0 0.5rem;
  color: var(--ink);
}

.charades-turn .charades-stars {
  color: var(--gold);
}

.charades-room .charades-mode,
.charades-room .charades-outcome {
  font-size: 1.5rem;
  font-weight: 750;
  color: var(--gold);
}

.charades-room .team-verdict form {
  margin: 0;
}

@media print {
  .charades-room-setup {
    display: none;
  }
}

/* A shared drawing has the same proportions on a phone and on the common screen. */
.drawing {
  margin-block: 1.5rem;
  text-align: start;
}
.drawing canvas {
  display: block;
  width: 100%;
  height: auto;
  background: #fff;
  border: 2px solid var(--gold);
  border-radius: 0.5rem;
}
.drawing canvas[data-writable] {
  touch-action: none;
  cursor: crosshair;
}
.drawing-tools,
.drawing-actions,
.drawing-colors {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}
.drawing-tools {
  margin-block-end: 0.75rem;
  align-items: end;
}
.drawing-tools fieldset {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}
.drawing-tools legend {
  color: var(--muted-night);
  font-size: 0.875rem;
  margin-block-end: 0.35rem;
}
.drawing-tools .button {
  min-height: 44px;
  padding: 0.5rem 0.75rem;
  font-size: 1rem;
}
.drawing-color {
  width: 44px;
  height: 44px;
  border: 3px solid var(--snow);
  border-radius: 50%;
  cursor: pointer;
}
.drawing-color[data-color="0"] { background: #202020; }
.drawing-color[data-color="1"] { background: #c62828; }
.drawing-color[data-color="2"] { background: #b85c00; }
.drawing-color[data-color="3"] { background: #237047; }
.drawing-color[data-color="4"] { background: #245bcc; }
.drawing-color[data-color="5"] { background: #783ca5; }
.drawing [aria-pressed="true"] {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
.drawing-guess {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 0.75rem;
}
.drawing-guess label { flex: 1 1 12rem; min-width: 0; }
.drawing-guess input { width: 100%; }
.drawing-status { min-height: 1.5em; color: var(--gold); }
.drawing-guesses {
  max-height: 15rem;
  overflow-y: auto;
  overflow-wrap: anywhere;
  padding-inline-start: 1.5rem;
}

/* ---------- online Christmas cards (`/cards/`, features/cards) ---------- */

/* The six pictures to pick from, three a row: the picked one framed in red. */
.ecard-designs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.625rem;
}

.ecard-design {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  padding: 0.5rem;
  border: 2px solid var(--line);
  border-radius: 14px;
  background: #fff;
  cursor: pointer;
  transition: border-color 150ms ease, transform 150ms var(--ease-out);
}

/* The radio stays for the keyboard and screen readers, over the picture and unseen. */
.ecard-design input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.ecard-design:has(input:checked) {
  border-color: var(--red);
  background: #fff5f6;
  transform: scale(1.03);
}

.ecard-design:has(input:focus-visible) {
  outline: 3px solid rgb(143 196 238 / 0.9);
  outline-offset: 2px;
}

.ecard-picture {
  width: 100%;
  height: 100%;
  max-height: 9rem;
}

.ecard-ready {
  display: grid;
  gap: 0.5rem;
}

.ecard-ready summary {
  cursor: pointer;
  font-weight: 650;
  color: var(--pen);
}

.ecard-ready[open] summary {
  margin-bottom: 0.5rem;
}

.ecard-ready .choice {
  grid-template-columns: auto 1fr;
  margin-top: 0.5rem;
}

.ecard-ready .choice-title {
  font-weight: 450;
}

/* The inside of a card, on its page and as the preview of the form: snow paper, the picture over the words. */
.ecard-inside {
  color-scheme: light;
  display: grid;
  gap: 0.75rem;
  justify-items: center;
  padding: 1.5rem 1.25rem 1.75rem;
  border-radius: 20px;
  background: var(--snow);
  color: var(--ink);
  text-align: center;
  box-shadow: 0 24px 48px -28px rgb(0 0 0 / 0.75);
  border-top: 10px solid var(--red);
}

.ecard-art {
  width: min(12rem, 60%);
}

.ecard-art[hidden],
.ecard-inside [hidden] {
  display: none;
}

.ecard-to,
.ecard-from,
.ecard-text {
  margin: 0;
  overflow-wrap: anywhere;
}

.ecard-label {
  color: var(--muted-paper);
  font-size: 0.9375rem;
}

.ecard-to strong,
.ecard-from strong {
  font-family: var(--hand);
  font-size: 1.75rem;
  color: var(--red);
}

.ecard-text {
  white-space: pre-line;
  font-family: var(--hand);
  font-size: 1.625rem;
  line-height: 1.3;
  color: var(--pen);
}

.ecard-heading {
  margin: 1rem 0 0;
  text-align: center;
}

/* A card on its page: the cover – the picture and the greeting – folds open to the left and shows the inside. Open is
   how it stands; the animation only starts it closed, so without animations it is open at once. */
.ecard {
  position: relative;
  perspective: 1600px;
}

.ecard-cover {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 1rem;
  border-radius: 20px;
  background: var(--red);
  color: var(--snow);
  transform-origin: left center;
  transform: rotateY(-180deg);
  backface-visibility: hidden;
  visibility: hidden;
  animation: ecard-open 1.6s var(--ease-in-out) 0.5s both;
}

.ecard-cover .ecard-picture {
  width: min(11rem, 55vw);
  height: auto;
  max-height: none;
  padding: 1rem;
  border-radius: 16px;
  background: var(--snow);
}

.ecard-cover p {
  margin: 0;
  font-family: var(--hand);
  font-size: 2.5rem;
}

@keyframes ecard-open {
  from {
    transform: rotateY(0);
    visibility: visible;
  }
  to {
    transform: rotateY(-180deg);
    visibility: hidden;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ecard-cover {
    animation: none;
  }
}

.ecard-cta {
  display: grid;
  gap: 0.75rem;
  justify-items: center;
  text-align: center;
}

.ecard-cta p {
  margin: 0;
}

.button-big {
  font-size: 1.25rem;
  padding: 1rem 1.75rem;
}

/* ---------- Christmas word of the day (/puzzles/word-of-the-day) ---------- */
/* The board: 6 rows of 5 squares (Japanese 4, Korean 3, Chinese 2); each square says its colour aloud too. */
.wotd-board {
  display: grid;
  gap: 0.375rem;
  width: min(100%, 20rem);
  margin: 1rem auto;
}

.wotd-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.375rem;
}

.wotd-4 .wotd-row {
  grid-template-columns: repeat(4, 1fr);
}

.wotd-3 .wotd-row {
  grid-template-columns: repeat(3, 1fr);
}

.wotd-2 .wotd-row {
  grid-template-columns: repeat(2, 1fr);
}

.wotd-cell {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border: 2px solid var(--line);
  border-radius: 0.375rem;
  background: var(--snow);
  color: var(--ink);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
  text-transform: none;
}

.wotd-2 .wotd-cell,
.wotd-3 .wotd-cell {
  font-size: 2rem;
}

.wotd-green {
  border-color: #2f7d43;
  background: #2f7d43;
  color: #fff;
}

.wotd-yellow {
  border-color: var(--gold);
  background: var(--gold);
  color: var(--ink);
}

.wotd-gray {
  border-color: #6b7486;
  background: #6b7486;
  color: #fff;
}

.wotd-next {
  color: var(--muted-paper);
  text-align: center;
}

.wotd-wrong {
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  background: #fde8eb;
  color: var(--red-deep);
  text-align: center;
}

.wotd-form {
  display: flex;
  gap: 0.5rem;
  justify-content: center;
  margin: 1rem 0;
}

.wotd-form input[name="w"] {
  width: 10rem;
  font-size: 1.25rem;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.wotd-keys {
  text-align: center;
}

.wotd-keys ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  justify-content: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

.wotd-keys .wotd-cell {
  width: 2.25rem;
  font-size: 1rem;
}

.wotd-end {
  text-align: center;
}

.wotd-share {
  display: inline-block;
  margin: 0 auto;
  padding: 0.75rem 1rem;
  border-radius: 0.5rem;
  background: var(--snow);
  color: var(--ink);
  font: 1rem/1.4 var(--sans);
  text-align: left;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.wotd-legend {
  padding: 0;
  list-style: none;
}

.wotd-legend li {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  margin: 0.375rem 0;
}

.wotd-legend .wotd-cell {
  flex: none;
  width: 1.75rem;
}

.wotd-form input[name="w"]::placeholder {
  font-size: 1rem;
  text-transform: none;
  letter-spacing: 0;
}

/* ---------- Christmas sudoku (/puzzles/sudoku) ---------- */

/* On the screen: the pictures and their names (`.sudoku-legend`), then a section a size, its two boards side by side
   where there is room, each on white – a CSS grid of squares, thin lines between them and thick ones between the
   blocks (`.sudoku-r`, `.sudoku-b`) –, its button to check (`app.js`) and its answer in `.sudoku-answer`, a
   `<details>`. Each picture has its own colour (`.sudoku-i1`…, through `currentColor`). The sheet to print
   (`.sudoku-sheet`) is not on the screen; printed, it is all there is: two boards a page – 4 × 4 at 25.5 mm a square,
   6 × 6 at 18 mm, 9 × 9 at 12 mm –, the pictures white with a black outline, to color in, and the six answers small
   on a fourth page: four pages of A4 or US Letter. */
.sudoku-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  margin: 0.5rem 0 1rem;
  padding: 0;
  list-style: none;
}

.sudoku-legend li {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.sudoku-legend .sudoku-icon {
  width: 1.9rem;
  height: 1.9rem;
}

.sudoku-pair {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
}

.sudoku-puzzle {
  min-width: 0;
  margin: 0;
  padding: 1rem 0.75rem;
  border-radius: 20px;
  background: #fff;
  color: var(--ink);
}

.sudoku-board {
  display: grid;
  width: 100%;
  margin: 0 auto;
  border: 3px solid var(--ink);
  background: #fff;
  color: var(--ink);
  user-select: none;
}

.sudoku-4 {
  grid-template-columns: repeat(4, 1fr);
  max-width: 17rem;
}

.sudoku-6 {
  grid-template-columns: repeat(6, 1fr);
  max-width: 21rem;
}

.sudoku-9 {
  grid-template-columns: repeat(9, 1fr);
  max-width: 24rem;
}

.sudoku-cell {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  min-width: 0;
  border-right: 1px solid #9aa7ba;
  border-bottom: 1px solid #9aa7ba;
  font: 700 clamp(1rem, 4.5vw, 1.45rem)/1 var(--sans);
}

.sudoku-4 > .sudoku-cell:nth-child(4n),
.sudoku-6 > .sudoku-cell:nth-child(6n),
.sudoku-9 > .sudoku-cell:nth-child(9n) {
  border-right: 0;
}

.sudoku-4 > .sudoku-cell:nth-last-child(-n + 4),
.sudoku-6 > .sudoku-cell:nth-last-child(-n + 6),
.sudoku-9 > .sudoku-cell:nth-last-child(-n + 9) {
  border-bottom: 0;
}

.sudoku-cell.sudoku-r {
  border-right: 3px solid var(--ink);
}

.sudoku-cell.sudoku-b {
  border-bottom: 3px solid var(--ink);
}

.sudoku-icon {
  width: 78%;
  height: 78%;
}

.sudoku-i1 {
  color: #f2b705;
}

.sudoku-i2 {
  color: #2e7d32;
}

.sudoku-i3 {
  color: #d32f2f;
}

.sudoku-i4 {
  color: #1e6fd9;
}

.sudoku-i5 {
  color: #8e44ad;
}

.sudoku-i6 {
  color: #f06292;
}

/* A square to fill on the screen (`app.js`): tapped, the next picture; filled by hand, a digit in blue. */
.sudoku-cell[role="button"] {
  cursor: pointer;
  color: var(--pen);
  font-weight: 500;
}

.sudoku-cell[role="button"]:hover {
  background: #eef4fb;
}

.sudoku-cell[role="button"]:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: -3px;
}

.sudoku-cell.sudoku-bad {
  background: #ffd5da;
}

.sudoku-board.sudoku-won {
  border-color: #2e7d32;
}

.sudoku-tools {
  margin: 0.75rem 0 0;
  text-align: center;
}

.sudoku-said {
  display: block;
  margin-top: 0.4rem;
  font-weight: 600;
}

.sudoku-answer {
  margin-top: 0.75rem;
}

.sudoku-answer summary {
  cursor: pointer;
  color: var(--pen);
  font-weight: 600;
}

.sudoku-answer .sudoku-board {
  max-width: 12rem;
  margin-top: 0.5rem;
}

.sudoku-answer .sudoku-cell {
  font-size: 0.85rem;
}

.sudoku-solved {
  background: #eef3e6;
  font-weight: 400;
}

.sudoku-sheet {
  display: none;
}

@page sudoku {
  margin: 10mm;
}

@media print {
  html:has(.sudoku-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.sudoku-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.sudoku-sheet) > :not(main),
  body:has(.sudoku-sheet) main > :not(.sudoku-sheet) {
    display: none !important;
  }

  body:has(.sudoku-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .sudoku-sheet {
    page: sudoku;
    display: block;
    color: #000;
    font: 11pt/1.3 var(--sans);
  }

  .sudoku-page,
  .sudoku-key {
    break-inside: avoid;
  }

  .sudoku-page {
    break-after: page;
  }

  .sudoku-name {
    display: flex;
    align-items: baseline;
    gap: 2mm;
    margin: 0 0 2mm;
    font-size: 12pt;
  }

  .sudoku-line {
    width: 70mm;
    border-bottom: 0.8pt solid #000;
  }

  .sudoku-page h2,
  .sudoku-key h2 {
    margin: 0 0 2mm;
    font: 700 15pt/1.2 var(--sans);
    color: #000;
    text-align: center;
  }

  .sudoku-sheet .sudoku-legend {
    justify-content: center;
    gap: 1mm 5mm;
    margin: 0 0 3mm;
    font-size: 10pt;
  }

  .sudoku-sheet .sudoku-legend .sudoku-icon {
    width: 7mm;
    height: 7mm;
  }

  /* The pictures white, outlined in black: to color in. */
  .sudoku-sheet .sudoku-icon {
    color: #fff;
  }

  .sudoku-sheet .sudoku-icon g {
    stroke: #000;
  }

  .sudoku-sheet .sudoku-board {
    width: auto;
    max-width: none;
    margin: 0 auto 5mm;
    border: 0.9mm solid #000;
    color: #000;
    justify-content: center;
  }

  .sudoku-sheet .sudoku-cell {
    aspect-ratio: auto;
    border-color: #000;
    border-right-width: 0.25mm;
    border-bottom-width: 0.25mm;
  }

  .sudoku-sheet .sudoku-cell.sudoku-r {
    border-right-width: 0.9mm;
  }

  .sudoku-sheet .sudoku-cell.sudoku-b {
    border-bottom-width: 0.9mm;
  }

  .sudoku-page .sudoku-4 {
    grid-template-columns: repeat(4, 25.5mm);
    grid-auto-rows: 25.5mm;
    width: max-content;
  }

  .sudoku-page .sudoku-6 {
    grid-template-columns: repeat(6, 18mm);
    grid-auto-rows: 18mm;
    width: max-content;
  }

  .sudoku-page .sudoku-9 {
    grid-template-columns: repeat(9, 12mm);
    grid-auto-rows: 12mm;
    width: max-content;
    font-size: 20pt;
    font-weight: 400;
  }

  .sudoku-key-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3mm 8mm;
    margin-top: 3mm;
  }

  .sudoku-key figure {
    margin: 0;
  }

  .sudoku-key figcaption {
    margin-bottom: 1mm;
    font-size: 9pt;
    text-align: center;
  }

  .sudoku-key .sudoku-board {
    width: max-content;
    margin-bottom: 2mm;
  }

  .sudoku-key .sudoku-4 {
    grid-template-columns: repeat(4, 12mm);
    grid-auto-rows: 12mm;
  }

  .sudoku-key .sudoku-6 {
    grid-template-columns: repeat(6, 9mm);
    grid-auto-rows: 9mm;
  }

  .sudoku-key .sudoku-9 {
    grid-template-columns: repeat(9, 7mm);
    grid-auto-rows: 7mm;
    font-size: 11pt;
  }

  .sudoku-key .sudoku-cell {
    font-weight: 700;
  }

  .sudoku-key .sudoku-solved {
    background: none;
    font-weight: 400;
    color: #555;
  }

  .sudoku-site {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    margin: 0;
    font: 8pt/1 var(--sans);
    color: #888;
    text-align: center;
  }
}

/* ---------- Christmas story with gaps (/party/story-game) ---------- */

/* On the screen (`public/app.js`, `[data-story-game]`): the stories as buttons that wrap, then a hint at a time over
   its field, then the story large to read out, each word put in gold, bold and underlined – so it shows without colour
   too. The sheet to print (`.story-sheet`) is not on the screen; printed (`@media print`), it is all there is: each
   story on a page of its own of A4 or US Letter – its title, the hints numbered with a line to write each word on, and
   the story with its numbered blanks. */
.story-picks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.story-ask {
  display: grid;
  gap: 0.6rem;
  max-width: 32rem;
}

.story-count {
  margin: 0;
  color: var(--muted-night);
  font-weight: 700;
  letter-spacing: 0.04em;
}

.story-ask label {
  font-size: 1.3rem;
  font-weight: 700;
}

.story-text {
  font-size: 1.25rem;
  line-height: 1.6;
  overflow-wrap: break-word;
}

.story-text mark {
  padding: 0 0.15em;
  background: none;
  color: var(--gold);
  font-weight: 800;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.story-done h2:focus {
  outline: none;
}

.story-sheet {
  display: none;
}

@page story {
  margin: 1.4cm 1.6cm;
}

@media print {
  html:has(.story-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.story-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.story-sheet) > :not(main),
  body:has(.story-sheet) main > :not(.story-sheet) {
    display: none !important;
  }

  body:has(.story-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .story-sheet {
    page: story;
    display: block;
    color: #000;
    font: 12pt/1.4 Georgia, "Times New Roman", serif;
  }

  .story-print {
    break-inside: avoid;
  }

  .story-print + .story-print {
    break-before: page;
  }

  .story-print h2 {
    margin: 0 0 0.35cm;
    font-size: 18pt;
    line-height: 1.2;
  }

  .story-hints {
    margin: 0 0 0.5cm;
    padding-left: 0.9cm;
    font: 11pt/1.2 var(--sans);
  }

  .story-hints li {
    display: list-item;
    padding: 0.2cm 0 0;
  }

  .story-hints li > span {
    display: inline-block;
    width: 6cm;
    margin-left: 0.3cm;
    border-bottom: 1px solid #000;
  }

  .story-blanks {
    margin: 0;
    line-height: 1.75;
    orphans: 2;
    widows: 2;
  }
}

/* ---------- Christmas tree calculator (/christmas-tree/) ---------- */

/* The form's fields side by side where there is room; the plan as a table of label and value, the chosen style in gold. */
.tree-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 1rem;
}

.tree-table {
  width: 100%;
  border-collapse: collapse;
}

.tree-table th,
.tree-table td {
  text-align: left;
  vertical-align: top;
  padding: 0.4rem 0.75rem 0.4rem 0;
  border-bottom: 1px solid rgb(244 248 251 / 0.18);
  color: var(--snow);
  overflow-wrap: anywhere;
}

.tree-table th[scope="col"] {
  color: var(--muted-night);
  font-weight: 600;
}

.tree-table .tree-chosen th,
.tree-table .tree-chosen td {
  color: var(--gold);
  font-weight: 700;
}

.tree-warning,
.tree-note {
  color: var(--gold);
  font-weight: 600;
}

/* ---------- Ugly Christmas sweater designer (/party/ugly-sweater) ---------- */

/* The sweater, a stitch a unit of its SVG, over the form; the colours as
   swatches (the colours of `sweater::YARN`), the other choices as chips that wrap. The sheet of ballots: 8 on the screen
   as paper, and printed (`@media print`) it is all there is – one page of A4 or Letter, 2 × 4 ballots to cut, each
   its categories with a box to tick and a line for the vote. */
.sweater-stage {
  display: grid;
  gap: 1.25rem;
}

.sweater-figure {
  margin: 0;
}

.sweater-picture {
  display: block;
  width: 100%;
  height: auto;
  image-rendering: pixelated;
}

.sweater-form {
  display: grid;
  gap: 0.75rem;
}

.sweater-field {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.sweater-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.sweater-field legend {
  margin-bottom: 0.35rem;
  color: var(--muted-night);
  font-weight: 700;
}

.sweater-swatch,
.sweater-option {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid rgb(244 248 251 / 0.25);
  border-radius: 999px;
  cursor: pointer;
}

.sweater-swatch:has(input:checked),
.sweater-option:has(input:checked) {
  border-color: var(--gold);
  color: var(--gold);
  font-weight: 700;
}

.sweater-swatch input,
.sweater-option input {
  accent-color: var(--gold);
  margin: 0;
}

.sweater-chip {
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  border: 1px solid rgb(244 248 251 / 0.6);
}

.sweater-c0 {
  background: #b31b2b;
}

.sweater-c1 {
  background: #1e6b3c;
}

.sweater-c2 {
  background: #1f2a52;
}

.sweater-c3 {
  background: #f0e4c4;
}

.sweater-c4 {
  background: #5e2b87;
}

.sweater-c5 {
  background: #6e452a;
}

.sweater-buttons {
  margin: 0.25rem 0 0;
}

.sweater-sheet {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.75rem;
  margin: 0 0 1.5rem;
}

.sweater-ballot {
  padding: 0.75rem 1rem;
  background: var(--snow);
  color: var(--ink);
  border: 1px dashed var(--muted-paper);
  font-size: 0.85rem;
  line-height: 1.3;
}

.sweater-ballot h3 {
  margin: 0 0 0.2rem;
  font-size: 1rem;
}

.sweater-how {
  margin: 0 0 0.35rem;
  color: var(--muted-paper);
}

.sweater-ballot ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.sweater-ballot li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.08rem 0;
}

.sweater-box {
  flex: none;
  width: 0.8em;
  height: 0.8em;
  border: 1.5px solid currentColor;
}

.sweater-vote {
  display: flex;
  align-items: flex-end;
  gap: 0.4rem;
  margin: 0.5rem 0 0;
  font-weight: 700;
}

.sweater-line {
  flex: 1;
  min-height: 1.2em;
  border-bottom: 1px solid currentColor;
}

@page sweater {
  size: portrait;
  margin: 1cm;
}

@media print {
  html:has(.sweater-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.sweater-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.sweater-sheet) > :not(main),
  body:has(.sweater-sheet) main > :not(.sweater-sheet) {
    display: none !important;
  }

  body:has(.sweater-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .sweater-sheet {
    page: sweater;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-auto-rows: 6.2cm;
    gap: 0;
    margin: 0;
    font: 9pt/1.25 var(--sans);
  }

  .sweater-ballot {
    box-sizing: border-box;
    height: 6.2cm;
    padding: 0.35cm 0.45cm;
    background: #fff;
    color: #000;
    border: 1px dashed #777;
    font-size: 9pt;
    break-inside: avoid;
    overflow: hidden;
  }

  .sweater-ballot h3 {
    font-size: 10.5pt;
  }

  .sweater-how {
    color: #333;
  }
}

/* ---------- Christmas tree decorator (/christmas-tree/decorate) ---------- */

/* The tree, a cell a unit of its SVG, on a night-blue backdrop over the form; the options as chips that wrap, as the
   ugly sweater's. */
.tdeco-stage {
  display: grid;
  gap: 1.25rem;
}

.tdeco-figure {
  width: 100%;
  max-width: 26rem;
  margin: 0 auto;
  box-sizing: border-box;
  padding: 0.75rem;
  background: linear-gradient(#273350, #1d2638);
  border-radius: 0.75rem;
}

.tdeco-picture {
  display: block;
  width: 100%;
  height: auto;
  image-rendering: pixelated;
}

.tdeco-form {
  display: grid;
  gap: 0.75rem;
}

.tdeco-field {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.tdeco-field legend {
  margin-bottom: 0.35rem;
  color: var(--muted-night);
  font-weight: 700;
}

.tdeco-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.tdeco-option {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid rgb(244 248 251 / 0.25);
  border-radius: 999px;
  cursor: pointer;
}

.tdeco-option:has(input:checked) {
  border-color: var(--gold);
  color: var(--gold);
  font-weight: 700;
}

.tdeco-option input {
  accent-color: var(--gold);
  margin: 0;
}

.tdeco-buttons {
  margin: 0.25rem 0 0;
}

/* ---------- Christmas dinner calculator (/christmas-dinner/) ---------- */

/* The form's fields side by side where there is room; the plan and the sides as tables of label and value. */
.dinner-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 1rem;
}

.dinner-check {
  margin: 1rem 0;
}

.dinner-table {
  width: 100%;
  border-collapse: collapse;
}

.dinner-table th,
.dinner-table td {
  text-align: left;
  vertical-align: top;
  padding: 0.4rem 0.75rem 0.4rem 0;
  border-bottom: 1px solid rgb(244 248 251 / 0.18);
  color: var(--snow);
  overflow-wrap: anywhere;
}

.dinner-table th[scope="col"] {
  color: var(--muted-night);
  font-weight: 600;
}

.dinner-result h3 {
  margin-top: 1.5rem;
}

.dinner-warning,
.dinner-note {
  color: var(--gold);
  font-weight: 600;
}

/* The Christmas jigsaw puzzle (`puzzles::jigsaw`, data-jigsaw): the pictures and the numbers of pieces as links, its
   tools, then the light area of the puzzle – the board (dashed) on top, the pieces in a tray under it (placed by
   app.js, `left`/`top`/`width`, which keep the area as wide as the page). Without JavaScript the board shows the whole
   picture and the pieces stay hidden; with it the picture shows only faintly, as a preview. */
.jigsaw-choice {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}

.jigsaw-thumb {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 4.2rem;
  padding: 0.3rem;
  border: 2px solid transparent;
  border-radius: 0.5rem;
  color: inherit;
  font-size: 0.75rem;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
}

.jigsaw-thumb svg {
  width: 2.6rem;
  height: 2.6rem;
  padding: 0.15rem;
  border-radius: 0.3rem;
  background: #fff;
}

.jigsaw-level {
  padding: 0.35rem 0.75rem;
  border: 2px solid var(--line);
  border-radius: 999px;
  color: inherit;
  font-size: 0.9rem;
  text-decoration: none;
}

.jigsaw-thumb[aria-current="true"],
.jigsaw-level[aria-current="true"] {
  border-color: var(--gold);
}

.jigsaw-level[aria-current="true"] {
  background: var(--gold);
  color: var(--ink);
}

.jigsaw-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.75rem;
}

.jigsaw-tools[hidden] {
  display: none;
}

.jigsaw-peek-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
}

.jigsaw-count {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.jigsaw-area {
  position: relative;
  overflow: hidden;
  padding: 0.75rem 0;
  border-radius: 0.75rem;
  background: #f4efe6;
  user-select: none;
  -webkit-user-select: none;
}

.jigsaw-board {
  max-width: 100%;
  width: 22rem;
  margin: 0 auto;
  outline: 2px dashed #a8957a;
  outline-offset: 0;
}

.jigsaw-picture {
  display: block;
  width: 100%;
  height: auto;
}

.jigsaw-on .jigsaw-picture {
  opacity: 0;
  transition: opacity 0.2s;
}

.jigsaw-on.jigsaw-peek .jigsaw-picture {
  opacity: 0.25;
}

.jigsaw-piece {
  position: absolute;
  top: 0;
  left: 0;
  overflow: visible;
  touch-action: none;
  cursor: grab;
  filter: drop-shadow(0 2px 2px rgb(29 38 56 / 0.35));
}

.jigsaw-piece:active {
  cursor: grabbing;
}

.jigsaw-edge {
  fill: none;
  stroke: rgb(29 38 56 / 0.45);
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
}

.jigsaw-piece.jigsaw-placed {
  cursor: default;
  filter: none;
}

.jigsaw-placed .jigsaw-edge {
  stroke: rgb(29 38 56 / 0.12);
}

.jigsaw-note,
.jigsaw-said {
  margin: 0.75rem 0 0;
  text-align: center;
}

.jigsaw-said:empty {
  display: none;
}

.jigsaw-share {
  margin: 0.5rem 0 0;
  text-align: center;
}

.jigsaw-share:has([hidden]) {
  display: none;
}

/* Alone on the full screen (`/puzzles/jigsaw/play`): the stage scrolls, as the crossword's does, instead of zooming the
   puzzle out (app.js) – the pieces stay as large as a finger and their moves as long as the finger's. */
.play-stage > .jigsaw {
  zoom: 1 !important;
}

/* ---------- Christmas word scramble (/puzzles/word-scramble) ---------- */

/* On the screen: two lists (`#kids`, `#family`), each word its mixed letters as tiles (`.scramble-tile`), its field
   and how many letters it has; a right word (`app.js`) gets a green outline and a ✓ (`.scramble-ok`). The answers in
   `.scramble-answer`, a `<details>`. The sheet to print (`.scramble-sheet`) is not on the screen; printed, it is all
   there is: the easy words on a page – tiles of 10 mm and a box a letter beside them –, the hard ones on the next –
   tiles of 9 mm over boxes of 7 mm, which fit A4 and US Letter –, the key of both on the third. */
.scramble-list {
  display: grid;
  gap: 0.5rem;
  list-style: decimal;
  margin: 0;
  padding-left: 1.6rem;
}

.scramble-list > li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.6rem;
  min-width: 0;
  padding: 0.35rem 0.5rem;
  border: 2px solid transparent;
  border-radius: 0.6rem;
}

.scramble-tiles {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin: 0;
  flex-basis: 100%;
}

.scramble-tile {
  display: inline-grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--line);
  border-radius: 0.35rem;
  background: #fff8e6;
  color: var(--ink);
  font-weight: 700;
}

.scramble-input {
  flex: 1 1 10rem;
  max-width: 18rem;
  min-width: 0;
  padding: 0.35rem 0.5rem;
  font: inherit;
  text-transform: uppercase;
}

.scramble-hint {
  opacity: 0.8;
  font-size: 0.9rem;
}

.scramble-list > li.scramble-ok {
  border-color: #7bd88f;
}

.scramble-list > li.scramble-ok .scramble-hint::after {
  content: " ✓";
  color: #7bd88f;
  font-weight: 700;
}

.scramble-answer {
  margin-top: 0.75rem;
}

.scramble-answer summary {
  cursor: pointer;
  font-weight: 600;
}

.scramble-key {
  columns: 2;
  margin: 0.5rem 0 0;
}

.scramble-count,
.scramble-said {
  margin: 0 0 0.4rem;
  font-weight: 600;
}

.scramble-sheet {
  display: none;
}

@page scramble {
  margin: 12mm;
}

@media print {
  html:has(.scramble-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.scramble-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.scramble-sheet) > :not(main),
  body:has(.scramble-sheet) main > :not(.scramble-sheet) {
    display: none !important;
  }

  body:has(.scramble-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .scramble-sheet {
    page: scramble;
    display: block;
    color: #000;
    font: 11pt/1.3 var(--sans);
  }

  .scramble-page,
  .scramble-key-page {
    break-inside: avoid;
  }

  .scramble-page {
    break-after: page;
  }

  .scramble-name {
    display: flex;
    align-items: baseline;
    gap: 2mm;
    margin: 0 0 3mm;
    font-size: 12pt;
  }

  .scramble-line {
    width: 70mm;
    border-bottom: 0.8pt solid #000;
  }

  .scramble-sheet h2 {
    margin: 0 0 4mm;
    font: 700 15pt/1.2 var(--sans);
    color: #000;
    text-align: center;
  }

  .scramble-rows {
    margin: 0;
    padding-left: 8mm;
  }

  .scramble-rows > li {
    display: flex;
    align-items: center;
    gap: 8mm;
    margin: 0 0 5mm;
    font-size: 12pt;
    break-inside: avoid;
  }

  .scramble-sheet .scramble-tiles,
  .scramble-boxes {
    display: flex;
    flex-wrap: nowrap;
    gap: 1mm;
    flex-basis: auto;
  }

  .scramble-sheet .scramble-tile,
  .scramble-box {
    width: 10mm;
    height: 10mm;
    border: 0.3mm solid #000;
    border-radius: 1.5mm;
    background: #fff;
    color: #000;
    font-size: 16pt;
  }

  .scramble-box {
    display: inline-block;
    border-radius: 0;
  }

  /* The hard words: up to 12 letters, the tiles over the boxes. */
  .scramble-page ~ .scramble-page .scramble-rows > li {
    flex-direction: column;
    align-items: flex-start;
    gap: 1mm;
    margin: 0 0 2mm;
  }

  /* The easy words: the boxes in one column, after tiles of up to 7 letters. */
  .scramble-page:first-child .scramble-tiles {
    width: 76mm;
  }

  .scramble-page ~ .scramble-page .scramble-tile {
    width: 9mm;
    height: 9mm;
    font-size: 14pt;
  }

  .scramble-page ~ .scramble-page .scramble-box {
    width: 7mm;
    height: 7mm;
  }

  .scramble-key-lists {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8mm;
  }

  .scramble-key-page h3 {
    margin: 0 0 2mm;
    font: 700 12pt/1.3 var(--sans);
  }

  .scramble-key-page ol {
    margin: 0;
    font-size: 12pt;
    line-height: 1.6;
  }

  .scramble-site {
    margin: 6mm 0 0;
    font-size: 9pt;
    text-align: right;
  }
}

/* The Christmas hangman (`puzzles::hangman`): the level and its switch, the snowman with the lives under it, the word
   as a row of boxes and the keyboard – each key a link of at least 44 × 44 px, wrapping on a phone of 390 px without
   scrolling sideways; the keys tried are plain boxes, green found, red not. */
.hangman {
  text-align: center;
}

.hangman-level {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.25rem 1rem;
  margin: 0 0 0.5rem;
  color: var(--muted-night);
}

.hangman-level a {
  color: inherit;
}

.hangman-stage {
  display: grid;
  justify-items: center;
  gap: 0.25rem;
}

.snowman-figure {
  margin: 0;
  width: min(14rem, 60vw);
}

.snowman {
  display: block;
  width: 100%;
  height: auto;
}

.hangman-lives {
  margin: 0;
  font-weight: 700;
  font-size: 1.125rem;
}

/* One row however long the word: the boxes get narrower. */
.hangman-word {
  display: flex;
  justify-content: center;
  gap: 0.375rem;
  margin: 1rem 0;
}

.hangman-cell {
  display: inline-grid;
  place-items: center;
  flex: 0 1 2.5rem;
  min-width: 0;
  height: 2.75rem;
  border-bottom: 3px solid var(--snow);
  font: 700 1.5rem/1 var(--sans);
  color: var(--snow);
}

.hangman-cell-lost {
  color: var(--dawn);
}

.hangman-end {
  margin: 0.5rem 0;
  font-size: 1.25rem;
  font-weight: 700;
}

.hangman-next {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin: 0.5rem 0 1rem;
}

.hangman-keys {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.375rem;
  max-width: 40rem;
  margin: 1rem auto 0;
}

.hangman-key {
  display: inline-grid;
  place-items: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 0.25rem;
  border: 1px solid var(--line);
  border-radius: 0.5rem;
  background: #fff8e6;
  color: var(--ink);
  font: 700 1.125rem/1 var(--sans);
  text-decoration: none;
}

a.hangman-key:hover,
a.hangman-key:focus-visible {
  background: var(--gold);
}

.hangman-key-hit {
  background: #cfe9d4;
  border-color: #3f8f55;
  color: #1f5a32;
}

.hangman-key-miss {
  background: transparent;
  border-color: var(--red);
  color: var(--muted-night);
  text-decoration: line-through;
}

.hangman-key-off {
  opacity: 0.5;
}

@media (max-width: 420px) {
  .hangman-keys {
    gap: 0.25rem;
  }

  .hangman-word {
    gap: 0.25rem;
  }

  .hangman-cell {
    font-size: 1.25rem;
  }
}

/* ---------- Christmas spot the difference (/puzzles/spot-the-difference) ---------- */

/* The Christmas spot the difference (`puzzles::spot`, data-spot): the pictures and the levels as links, the counter, then
   the picture and its changed copy side by side – one under the other on a phone, never wider than the page. The whole
   of each picture takes a tap; app.js draws the circles in it (they may reach past its edge, so it shows its overflow)
   and makes it blink on a miss (.spot-miss). The answers in `.spot-answer`, a `<details>`. The sheet to print
   (`.spot-sheet`) is not on the screen; printed, it is all there is: both pictures on the first page with a box for the
   number found, the answers on the second. */
.spot-choice {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}

.spot-thumb {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 4.2rem;
  padding: 0.3rem;
  border: 2px solid transparent;
  border-radius: 0.5rem;
  color: inherit;
  font-size: 0.75rem;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
}

.spot-thumb svg {
  width: 2.6rem;
  height: 2.6rem;
  padding: 0.15rem;
  border-radius: 0.3rem;
  background: #fff;
}

.spot-level {
  padding: 0.35rem 0.75rem;
  border: 2px solid var(--line);
  border-radius: 999px;
  color: inherit;
  font-size: 0.9rem;
  text-decoration: none;
}

.spot-thumb[aria-current="true"],
.spot-level[aria-current="true"] {
  border-color: var(--gold);
}

.spot-level[aria-current="true"] {
  background: var(--gold);
  color: var(--ink);
}

.spot-count,
.spot-note,
.spot-said {
  margin: 0 0 0.5rem;
  text-align: center;
}

.spot-count,
.spot-said {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.spot-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  padding: 1rem;
  border-radius: 0.75rem;
  background: #f4efe6;
}

.spot-picture,
.spot-solution {
  display: block;
  width: 100%;
  max-height: 70vh;
  overflow: visible;
  outline: 2px solid #d8ccb8;
  background: #fff;
  cursor: crosshair;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.spot-picture.spot-miss {
  outline-color: var(--red);
  animation: spot-shake 0.3s;
}

@keyframes spot-shake {
  25% {
    transform: translateX(-3px);
  }

  75% {
    transform: translateX(3px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .spot-picture.spot-miss {
    animation: none;
  }
}

.spot-end {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
}

.spot-end[hidden] {
  display: none;
}

.spot-answer {
  margin-top: 0.75rem;
}

.spot-answer summary {
  cursor: pointer;
  font-weight: 600;
}

.spot-solution {
  max-width: 22rem;
  margin: 1rem auto;
  cursor: default;
}

@media (max-width: 600px) {
  .spot-pair {
    grid-template-columns: 1fr;
    padding: 0.75rem;
  }

  .spot-picture {
    max-height: none;
  }
}

.spot-sheet {
  display: none;
}

@page spot {
  margin: 12mm;
}

@media print {
  html:has(.spot-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.spot-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.spot-sheet) > :not(main),
  body:has(.spot-sheet) main > :not(.spot-sheet) {
    display: none !important;
  }

  body:has(.spot-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .spot-sheet {
    page: spot;
    display: block;
    color: #000;
    font: 12pt/1.3 var(--sans);
    text-align: center;
  }

  .spot-page,
  .spot-key-page {
    break-inside: avoid;
  }

  .spot-page {
    break-after: page;
  }

  .spot-sheet h2 {
    margin: 0 0 4mm;
    font: 700 16pt/1.2 var(--sans);
    color: #000;
  }

  .spot-sheet svg {
    display: block;
    height: 108mm;
    max-width: 100%;
    margin: 0 auto 5mm;
    overflow: visible;
    outline: 0.3mm solid #000;
  }

  .spot-tally {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 2mm;
    margin: 0;
    font-size: 14pt;
  }

  .spot-box {
    display: inline-block;
    width: 12mm;
    height: 12mm;
    border: 0.4mm solid #000;
  }

  .spot-key-page svg {
    height: 150mm;
  }

  .spot-site {
    margin: 4mm 0 0;
    font-size: 9pt;
  }
}

/* The Christmas math worksheets of /printables/math-worksheets (`printables::math`): the levels and the pictures to
   pick (links, the chosen one `aria-current`), then the sheet on snow paper – the name line, the task, the legend of
   crayons (buttons `app.js` colors with, the pressed one ringed), „Check” (hidden until `app.js` runs) and the grid,
   a problem in each colored square, which scrolls in its own box on a phone. The answer key is on paper only. Printed
   (`@media print`, `@page mathw`), the sheet is all there is: page 1 the worksheet, squares of 9.5 mm and problems of
   2.66 mm (2.8 units; `math::sum_width` fits „88−79” in 8.4 of a square's 10), the grid whole on A4 and US Letter;
   page 2 the finished picture and the answers. */
.mathw-levels {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}

.mathw-levels a {
  display: block;
  padding: 0.5rem 0.875rem;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  color: inherit;
  text-decoration: none;
}

.mathw-levels a[aria-current="page"],
.mathw-pictures a[aria-current="page"] {
  border-color: var(--gold);
  box-shadow: inset 0 0 0 1.5px var(--gold);
  font-weight: 750;
}

.mathw-pictures {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
  gap: 0.5rem;
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}

.mathw-pictures a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.375rem;
  height: 100%;
  padding: 0.5rem;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  color: inherit;
  text-align: center;
  text-decoration: none;
  font-size: 0.875rem;
}

.mathw-thumb {
  width: 3.5rem;
  height: 4.25rem;
  background: #fff;
  border-radius: 4px;
}

.mathw-sheet {
  padding: 1rem;
  border-radius: 20px;
  background: var(--snow);
  color: var(--ink);
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

.mathw-page h2 {
  margin: 0 0 0.75rem;
  color: var(--ink);
  text-align: center;
}

.mathw-name {
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
  margin: 0 0 0.5rem;
  font-weight: 650;
}

.mathw-blank {
  flex: 0 1 16rem;
  height: 1.25em;
  border-bottom: 1.5px solid var(--ink);
}

.mathw-task {
  margin: 0 0 0.75rem;
}

.mathw-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1rem;
  margin: 0 0 0.75rem;
  padding: 0;
  list-style: none;
}

.mathw-legend li {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.mathw-crayon {
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--crayon);
  color: #fff;
  font: 800 1.125rem/1 var(--sans);
  text-shadow: 0 0 3px #000, 0 0 2px #000;
  cursor: pointer;
}

.mathw-crayon[aria-pressed="true"] {
  outline: 3px solid var(--red);
  outline-offset: 2px;
}

.mathw-crayon:focus-visible {
  outline: 3px solid var(--pen);
  outline-offset: 2px;
}

.mathw-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 1rem;
  margin: 0 0 0.75rem;
}

.mathw-tools[hidden] {
  display: none;
}

.mathw-said {
  margin: 0;
  font-weight: 800;
  color: var(--red-deep);
}

.mathw-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.mathw-grid {
  display: block;
  width: 100%;
  max-width: 48rem;
  height: auto;
  margin: 0 auto;
  background: #fff;
  overflow: visible;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* On a phone the problems keep a size to read and tap: the grid scrolls sideways in its box. */
@media (max-width: 40rem) {
  .mathw-grid {
    min-width: 36rem;
  }
}

.mathw-grid rect {
  fill: #fff;
  cursor: pointer;
}

.mathw-grid .mathw-wrong {
  stroke: #d62828;
  stroke-width: 1.4;
  stroke-dasharray: 2.2 1.4;
}

.mathw-lines {
  fill: none;
  stroke: #8a97ab;
  stroke-width: 0.5;
  pointer-events: none;
}

.mathw-grid text,
.mathw-key-grid text {
  font: 650 2.8px var(--sans);
  fill: #1d2638;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}

.mathw-key-grid text {
  font-size: 5px;
}

.mathw-key {
  display: none;
}

@page mathw {
  margin: 10mm;
}

@media print {
  html:has(.mathw-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.mathw-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.mathw-sheet) > :not(main),
  body:has(.mathw-sheet) main > :not(.mathw-sheet),
  .mathw-sheet [data-mathw-tools] {
    display: none !important;
  }

  body:has(.mathw-sheet) main {
    display: block;
    max-width: none;
    margin: 0;
    padding: 0;
  }

  .mathw-sheet {
    page: mathw;
    display: block;
    padding: 0;
    border-radius: 0;
    background: none;
    color: #000;
    font: 11pt/1.25 var(--sans);
  }

  .mathw-page {
    break-inside: avoid;
  }

  .mathw-key {
    display: block;
    break-before: page;
  }

  .mathw-page h2 {
    margin: 0 0 2mm;
    font-size: 13pt;
    color: #000;
  }

  .mathw-name {
    margin: 0 0 2mm;
    font-size: 12pt;
  }

  .mathw-blank {
    flex-basis: 80mm;
    border-bottom: 1pt solid #000;
  }

  .mathw-task {
    margin: 0 0 2mm;
    font-size: 10.5pt;
    text-align: center;
  }

  .mathw-legend {
    gap: 2mm 5mm;
    margin: 0 0 3mm;
    font-size: 10.5pt;
  }

  .mathw-crayon {
    width: 7mm;
    height: 7mm;
    border: 1pt solid #000;
    font-size: 11pt;
    outline: none !important;
  }

  .mathw-scroll {
    overflow: visible;
  }

  .mathw-grid {
    min-width: 0;
    max-width: none;
  }

  .mathw-grid[data-cols="14"] {
    width: 133mm;
  }

  .mathw-grid[data-cols="15"] {
    width: 142.5mm;
  }

  .mathw-grid[data-cols="16"] {
    width: 152mm;
  }

  .mathw-grid[data-cols="17"] {
    width: 161.5mm;
  }

  .mathw-grid[data-cols="18"] {
    width: 171mm;
  }

  .mathw-grid[data-cols="19"] {
    width: 180.5mm;
  }

  .mathw-grid[data-cols="20"] {
    width: 190mm;
  }

  .mathw-lines {
    stroke: #333;
    stroke-width: 0.4;
  }

  .mathw-grid text,
  .mathw-key-grid text {
    fill: #000;
  }

  .mathw-key-pictures {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    gap: 8mm;
  }

  .mathw-solution {
    width: 45mm;
    height: auto;
    border: 1pt solid #999;
  }

  .mathw-key-grid {
    width: 120mm;
    height: auto;
  }
}

/* Christmas drawing step by step of /printables/how-to-draw (`printables::how_to_draw`): the eight drawings to jump to
   (each its colored picture, name and level), then the sheet on snow paper – a section a drawing (`.htd-drawing`): its
   steps in a grid, each numbered, its picture (the steps before grey, its own black) and sentence, the drawing whole,
   the box to draw in with a line for the name and, on the screen only, the colored drawing. Printed (`@media print`,
   `@page htd` 10 mm), the sheet is all there is: a page a drawing (`.htd-page`), the steps 4 a row in squares of
   41 mm, the box to draw in 100 mm high – the same on A4 and US Letter. */
.htd-contents {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.htd-contents a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  height: 100%;
  padding: 0.5rem;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  color: inherit;
  text-align: center;
  text-decoration: none;
}

.htd-thumb {
  width: 4.5rem;
  height: 4.5rem;
  background: #fff;
  border-radius: 8px;
}

.htd-thumb-name {
  font-weight: 700;
}

.htd-level,
.htd-meta {
  font-size: 0.875rem;
  opacity: 0.8;
}

.htd-sheet {
  display: grid;
  gap: 1rem;
  padding: 1rem;
  border-radius: 20px;
  background: var(--snow);
  color: var(--ink);
}

.htd-drawing {
  scroll-margin-top: 1rem;
}

.htd-drawing h2 {
  margin: 0;
  color: var(--ink);
  text-align: center;
}

.htd-meta {
  margin: 0.25rem 0 0.75rem;
  text-align: center;
}

.htd-steps {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 0.5rem;
  margin: 0 0 0.75rem;
  padding: 0;
  list-style: none;
}

.htd-step {
  position: relative;
  padding: 0.375rem;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: #fff;
}

.htd-step p {
  margin: 0.25rem 0 0;
  font-size: 0.875rem;
  line-height: 1.3;
  text-align: center;
}

.htd-num {
  position: absolute;
  top: 0.375rem;
  left: 0.375rem;
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--red);
  color: #fff;
  font-weight: 800;
}

.htd-done .htd-num {
  background: var(--gold-deep);
}

.htd-art {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
}

.htd-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.htd-yours {
  flex: 1 1 16rem;
  min-height: 14rem;
  padding: 0.75rem;
  border: 2px dashed var(--line);
  border-radius: 12px;
  background: #fff;
}

.htd-name {
  display: flex;
  align-items: flex-end;
  gap: 0.5rem;
  margin: 0;
  font-weight: 650;
}

.htd-blank {
  flex: 0 1 14rem;
  height: 1.25em;
  border-bottom: 1.5px solid var(--ink);
}

.htd-yours-label {
  margin: 0.5rem 0 0;
  opacity: 0.6;
}

.htd-color {
  flex: 0 1 11rem;
  margin: 0 auto;
  text-align: center;
}

.htd-color .htd-art {
  background: #fff;
  border-radius: 12px;
}

.htd-color figcaption {
  font-size: 0.875rem;
}

@page htd {
  margin: 10mm;
}

@media print {
  html:has(.htd-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.htd-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.htd-sheet) > :not(main),
  body:has(.htd-sheet) main > :not(.htd-sheet),
  .htd-meta,
  .htd-color {
    display: none !important;
  }

  body:has(.htd-sheet) main {
    display: block;
    max-width: none;
    margin: 0;
    padding: 0;
  }

  .htd-sheet {
    page: htd;
    display: block;
    padding: 0;
    border-radius: 0;
    background: none;
    color: #000;
    font: 11pt/1.25 var(--sans);
  }

  .htd-page {
    break-inside: avoid;
    break-after: page;
  }

  .htd-page:last-child {
    break-after: auto;
  }

  .htd-drawing h2 {
    margin: 0 0 3mm;
    font-size: 15pt;
    color: #000;
  }

  .htd-steps {
    grid-template-columns: repeat(4, 45mm);
    justify-content: center;
    gap: 3mm;
    margin: 0 0 4mm;
  }

  .htd-step {
    padding: 1mm;
    border: 0.75pt solid #999;
    border-radius: 3mm;
    break-inside: avoid;
  }

  .htd-art {
    width: 41mm;
    height: 41mm;
    margin: 0 auto;
  }

  .htd-step p {
    margin: 1mm 0 0;
    font-size: 9pt;
  }

  .htd-num {
    top: 1mm;
    left: 1mm;
    width: 6mm;
    height: 6mm;
    border: 0.75pt solid #000;
    background: #fff !important;
    color: #000;
    font-size: 10pt;
  }

  .htd-yours {
    height: 100mm;
    min-height: 0;
    padding: 3mm 4mm;
    border: 1pt dashed #666;
    border-radius: 3mm;
  }

  .htd-name {
    font-size: 12pt;
  }

  .htd-blank {
    flex-basis: 70mm;
    border-bottom: 1pt solid #000;
  }

  .htd-yours-label {
    margin: 2mm 0 0;
    font-size: 10pt;
    color: #666;
    opacity: 1;
  }
}

/* ---------- Christmas tic-tac-toe (/puzzles/tic-tac-toe) ---------- */

/* The Christmas tic-tac-toe (`puzzles::tictactoe`, data-tictactoe): the modes and the levels as links (the chosen one
   gold), the status, then a square board of 3 × 3 squares – each at least 88 px on a phone, the whole board in 390 px
   without scrolling sideways; a free square a link with a ring when focused, a taken one its tree or snowman, the
   winning line gold. */
.ttt {
  text-align: center;
}

.ttt-switch {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.375rem 0.5rem;
  margin: 0 0 0.5rem;
  color: var(--muted-night);
}

.ttt-switch a {
  display: inline-block;
  min-height: 44px;
  padding: 0.6rem 0.875rem;
  border: 1px solid var(--muted-night);
  border-radius: 999px;
  color: var(--snow);
  line-height: 1.2;
  text-decoration: none;
}

.ttt-switch a:hover {
  border-color: var(--gold);
}

.ttt-switch a.ttt-on {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--ink);
  font-weight: 700;
}

.ttt > .ttt-status {
  margin: 0.75rem 0;
  color: var(--snow);
  font-size: 1.25rem;
  font-weight: 700;
}

.ttt-board {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  width: min(100%, 22rem);
  margin: 0 auto;
  padding: 8px;
  border-radius: 1rem;
  background: var(--night-up);
}

.ttt-cell {
  display: block;
  aspect-ratio: 1;
  min-width: 88px;
  padding: 8%;
  border-radius: 0.75rem;
  background: #e6f0f8;
}

a.ttt-cell:hover {
  background: #fff8e6;
}

a.ttt-cell:focus-visible {
  outline: 4px solid var(--gold);
  outline-offset: 2px;
  background: #fff8e6;
}

.ttt-mark {
  display: block;
  width: 100%;
  height: 100%;
}

.ttt-win {
  background: #f7dc8f;
  box-shadow: inset 0 0 0 4px var(--gold-deep);
}

.ttt-free {
  opacity: 0.6;
}

.ttt-next {
  margin: 1rem 0 0;
}

.ttt-next a:not(.button) {
  color: var(--snow);
}

/* ---------- Christmas sliding puzzle (/puzzles/sliding-puzzle) ---------- */
/* The pictures and the sizes are the jigsaw puzzle's links (`.jigsaw-choice`); then the switch of the numbers, „New
   game”, the moves and the time, and the light board – as wide as the page, at most 26rem, its tiles placed by app.js
   with a transform (`translate(col × 100%, row × 100%)`). Without JavaScript the board stays hidden and <noscript>
   shows the whole picture. */
.sliding-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.5rem;
}

.sliding-tools[hidden],
.sliding-stats[hidden],
.sliding-board[hidden] {
  display: none;
}

.sliding-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  cursor: pointer;
}

.sliding > .sliding-stats {
  margin: 0 0 0.6rem;
  color: var(--snow);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.sliding-solved > .sliding-stats {
  color: var(--gold);
  font-size: 1.1rem;
}

.sliding-board {
  position: relative;
  display: block;
  width: min(100%, 26rem);
  margin: 0 auto;
  overflow: hidden;
  border-radius: 0.5rem;
  background: #f4efe6;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.sliding-board:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
}

.sliding-tile {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 33.3333%;
  height: 33.3333%;
  outline: 1px solid rgb(29 38 56 / 0.35);
  outline-offset: -1px;
  cursor: pointer;
}

.sliding-k4 .sliding-tile {
  width: 25%;
  height: 25%;
}

.sliding-ready .sliding-tile {
  transition: transform 120ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
  .sliding-ready .sliding-tile {
    transition: none;
  }
}

.sliding-tile[data-empty] {
  visibility: hidden;
}

.sliding-solved .sliding-tile {
  outline-color: transparent;
  cursor: default;
}

.sliding-solved .sliding-tile[data-empty] {
  visibility: visible;
}

.sliding-number {
  display: none;
  fill: var(--ink);
  stroke: #fff;
  paint-order: stroke;
  font-family: inherit;
  font-weight: 700;
}

.sliding-numbers .sliding-number {
  display: inline;
}

.sliding-solved .sliding-number {
  display: none;
}

.sliding-picture {
  display: block;
  width: min(100%, 18rem);
  height: auto;
  margin: 0 auto;
  border-radius: 0.5rem;
  background: #f4efe6;
}

.sliding-note {
  margin: 0.75rem 0 0;
  text-align: center;
}

.sliding-share {
  margin: 0.75rem 0 0;
  text-align: center;
}

.sliding-share:has([hidden]) {
  display: none;
}

/* Alone on the full screen (`/puzzles/sliding-puzzle/play`): the board no taller than about two thirds of the screen. */
.play-stage .sliding-board {
  width: min(100%, 26rem, 58dvh);
}

/* ---------- Christmas nonogram (/puzzles/nonogram) ---------- */
/* The pictures and the levels are the jigsaw puzzle's links (`.jigsaw-choice`); then the tools – „Fill” / „Cross”
   (large on a phone), „Undo”, the full screen –, the time and the grid on light paper: a <table> with the numbers of
   the columns over it and of the rows to its left, a square at least 18 px (`--c`, from the columns `--w`), a thicker
   line after each fifth; a grid wider than a phone scrolls in its own box (`.nono-wrap`), not the page. A filled
   square is ink, a given one green-grey (never changed), a crossed one a red ×; a line that matches its numbers fades
   its clue. Solved, the filled squares turn Christmas red and green. Without JavaScript the game stays hidden and
   <noscript> says the print works without it. */
.nono-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.5rem;
}

.nono-tools[hidden],
.nono-stats[hidden],
.nono-wrap[hidden],
.nono-end[hidden] {
  display: none;
}

.nono-mode {
  display: inline-flex;
  gap: 0.4rem;
}

.nono-tool {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 2.75rem;
  padding: 0.35rem 1rem;
  border: 2px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.nono-tool[aria-pressed="true"] {
  border-color: var(--gold);
  background: var(--gold);
  color: var(--ink);
}

.nono-swatch {
  display: inline-grid;
  place-items: center;
  width: 1.1rem;
  height: 1.1rem;
  border: 1.5px solid currentColor;
  border-radius: 0.15rem;
  color: var(--red);
  font-weight: 700;
  line-height: 1;
}

.nono-tool[aria-pressed="true"] .nono-swatch {
  border-color: var(--ink);
}

.nono-swatch-fill {
  background: var(--ink);
  border-color: var(--snow);
}

.nono > .nono-stats {
  margin: 0 0 0.6rem;
  color: var(--snow);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.nono-wrap {
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.nono-grid {
  --c: clamp(18px, calc((min(100vw, var(--column)) - 6.5rem) / var(--w)), 28px);
  /* As wide as its squares: never squeezed under 18 px by a narrow box, which scrolls instead. */
  width: max-content;
  margin: 0 auto;
  border-collapse: collapse;
  background: #f4efe6;
  color: var(--ink);
  user-select: none;
  -webkit-user-select: none;
}

.nono-grid:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
}

.nono-grid th,
.nono-corner {
  padding: 0;
  font-size: max(11px, calc(var(--c) * 0.5));
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.nono-col {
  width: var(--c);
  padding: 0.25rem 0 0.15rem !important;
  vertical-align: bottom;
}

.nono-col span {
  display: block;
}

.nono-row {
  padding: 0 0.35rem 0 0.4rem !important;
  text-align: right;
  white-space: nowrap;
}

.nono-ok {
  color: rgb(29 38 56 / 0.35);
}

.nono-cell {
  width: var(--c);
  min-width: 18px;
  height: var(--c);
  min-height: 18px;
  padding: 0;
  border: 1px solid rgb(29 38 56 / 0.3);
  background: #fff;
  touch-action: none;
  cursor: pointer;
}

/* The thicker lines: after each fifth column (the row's clue is the first cell) and each fifth row, and round it. */
.nono-grid td:nth-child(5n + 6),
.nono-print td:nth-child(5n + 6) {
  border-right: 2px solid var(--ink);
}

.nono-grid tbody tr:nth-child(5n) td,
.nono-print tbody tr:nth-child(5n) td {
  border-bottom: 2px solid var(--ink);
}

.nono-grid tbody td:nth-child(2),
.nono-print tbody td:nth-child(2) {
  border-left: 2px solid var(--ink);
}

.nono-grid tbody tr:first-child td,
.nono-print tbody tr:first-child td {
  border-top: 2px solid var(--ink);
}

.nono-grid tbody td:last-child,
.nono-print tbody td:last-child {
  border-right: 2px solid var(--ink);
}

.nono-grid tbody tr:last-child td,
.nono-print tbody tr:last-child td {
  border-bottom: 2px solid var(--ink);
}

.nono-cell.nono-on {
  background: var(--ink);
}

.nono-cell.nono-given {
  background: #4f6b5a;
  cursor: default;
}

.nono-cell.nono-x {
  background-color: #fff;
  background-image: linear-gradient(45deg, transparent 42%, var(--red) 42% 58%, transparent 58%),
    linear-gradient(-45deg, transparent 42%, var(--red) 42% 58%, transparent 58%);
}

.nono-cell.nono-at {
  outline: 3px solid var(--gold);
  outline-offset: -3px;
}

.nono-solved .nono-cell {
  cursor: default;
}

.nono-solved .nono-cell.nono-x {
  background: #fff;
}

.nono-solved .nono-cell.nono-on:nth-child(odd),
.nono-solved .nono-cell.nono-given:nth-child(odd) {
  background: var(--red);
}

.nono-solved .nono-cell.nono-on:nth-child(even),
.nono-solved .nono-cell.nono-given:nth-child(even) {
  background: #2f8f5b;
}

.nono-solved .nono-ok {
  color: var(--ink);
}

.nono-end {
  margin-top: 0.75rem;
  text-align: center;
}

.nono > .nono-end > .nono-said {
  margin: 0 0 0.5rem;
  color: var(--gold);
  font-size: 1.15rem;
  font-weight: 700;
}

.nono-end p {
  margin: 0;
}

.nono-end:has([data-share-score][hidden]) .button-quiet {
  margin-bottom: 0.5rem;
}

.nono-note {
  margin: 0.75rem 0 0;
  text-align: center;
}

.nono-key-link {
  margin: -1.5rem 0 0;
  padding: 0 0.25rem;
}

/* The sheet to print: not on the screen, but the solution (`?key=1`), shown small on light paper. */
.nono-sheet {
  display: none;
}

.nono-sheet.nono-key {
  display: block;
  padding: 1rem;
  border-radius: 0.5rem;
  background: #fff;
  color: #000;
  text-align: center;
}

.nono-key h2 {
  color: #000;
}

.nono-key a {
  color: var(--pen);
}

.nono-print {
  margin: 0 auto;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.nono-print th,
.nono-print .nono-corner {
  padding: 0 0.2em;
  font-size: 0.7rem;
  line-height: 1.1;
}

.nono-print .nono-col {
  vertical-align: bottom;
}

.nono-print .nono-col span {
  display: block;
}

.nono-print .nono-row {
  text-align: right;
  white-space: nowrap;
}

.nono-pcell {
  width: 1rem;
  height: 1rem;
  padding: 0;
  border: 1px solid #999;
}

.nono-pcell.nono-on {
  background: #000;
}

.nono-pcell.nono-given {
  background: #bbb;
}

.nono-picture {
  display: block;
  width: 6rem;
  height: auto;
  margin: 1rem auto 0;
}

.nono-site {
  margin: 0.75rem 0 0;
  font-size: 0.85rem;
}

/* Alone on the full screen (`/puzzles/nonogram/play`): the pictures in one row that scrolls, the grid no taller than
   the screen leaves it (scrolling in its box past that), so the stage need not zoom the squares under 18 px. */
.play-stage .nono .jigsaw-choice {
  flex-wrap: nowrap;
  justify-content: flex-start;
  overflow-x: auto;
  margin-bottom: 0.4rem;
}

.play-stage .nono .jigsaw-thumb {
  position: relative;
  flex: none;
  width: auto;
}

/* The names stay for a screen reader only. */
.play-stage .nono .jigsaw-thumb span {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.play-stage .nono .jigsaw-level {
  padding: 0.25rem 0.6rem;
  font-size: 0.8rem;
}

.play-stage .nono-wrap {
  max-height: calc(100dvh - 22rem);
  overflow: auto;
}

.play-stage .nono-grid {
  --c: clamp(18px, min((100vw - 6.5rem) / var(--w), (100dvh - 16rem) / (var(--h) + 4)), 32px);
}

@page nono {
  margin: 12mm;
}

/* Printed (`@media print`), only the sheet, on one page of A4 (or US Letter): the title, the picture's name and the
   level, the grid with squares of 7.5 mm (the given ones grey) – at most 18 × 22 of them with their numbers. The
   solution (`?key=1`) the same grid, its squares black, and the small colored picture. */
@media print {
  html:has(.nono-sheet) {
    color-scheme: light;
    background: #fff;
  }

  body:has(.nono-sheet) {
    display: block;
    min-height: 0;
    background: #fff;
    color: #000;
  }

  body:has(.nono-sheet) > :not(main),
  body:has(.nono-sheet) main > :not(.nono-sheet) {
    display: none !important;
  }

  body:has(.nono-sheet) main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .nono-sheet,
  .nono-sheet.nono-key {
    page: nono;
    display: block;
    padding: 0;
    color: #000;
    font: 11pt/1.3 var(--sans);
    text-align: center;
    break-inside: avoid;
  }

  .nono-sheet h2 {
    margin: 0 0 2mm;
    font: 700 16pt/1.2 var(--sans);
    color: #000;
  }

  .nono-name {
    margin: 0 0 4mm;
    font-size: 12pt;
  }

  .nono-print th,
  .nono-print .nono-corner {
    font-size: 10pt;
  }

  .nono-print .nono-col {
    width: 7.5mm;
  }

  .nono-pcell {
    width: 7.5mm;
    height: 7.5mm;
    border: 0.25mm solid #555;
  }

  .nono-print td:nth-child(5n + 6),
  .nono-print tbody td:nth-child(2),
  .nono-print tbody td:last-child {
    border-right-color: #000;
  }

  .nono-print tbody tr:nth-child(5n) td,
  .nono-print tbody tr:first-child td,
  .nono-print tbody tr:last-child td {
    border-bottom-color: #000;
  }

  .nono-pcell.nono-given {
    background: #bbb;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  .nono-pcell.nono-on {
    background: #000;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  .nono-picture {
    width: 35mm;
    margin-top: 5mm;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  .nono-site,
  .nono-site a {
    color: #000;
    text-decoration: none;
  }
}

/* ---------- Christmas 2048 (/puzzles/2048) ---------- */
/* „New game”, „Undo” and the full screen, the score and the best one, then the board – as wide as the page, at most
   26rem, square: 16 dim squares in a grid and over them the tiles app.js places (`--x`, `--y`) with a transform, a
   step the tile and the gap. A tile: its picture (`<use>` of `#t48-N`) over its number, its colors by level
   (`.t48-v1` 2 … `.t48-v11` 2048, `.t48-v12` past it; twenty48::COLORS, each 4.5:1 or more). The pictures white with
   a dark outline, whatever art of the site they come from. The end (2048, or no move) over the board. Under it the
   names of the tiles; without JavaScript only they and the note show. */
.t48-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.t48-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.5rem;
}

.t48-tools[hidden],
.t48-stats[hidden],
.t48-wrap[hidden],
.t48-names[hidden],
.t48-end[hidden] {
  display: none;
}

.t48 > .t48-stats {
  margin: 0 0 0.6rem;
  color: var(--snow);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.t48-wrap {
  position: relative;
  width: min(100%, 26rem);
  margin: 0 auto;
}

.t48-board {
  --gap: 0.45rem;
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gap);
  aspect-ratio: 1;
  padding: var(--gap);
  border-radius: 0.6rem;
  background: #2b4162;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.t48-board:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
}

.t48-cell {
  border-radius: 0.4rem;
  background: rgb(255 255 255 / 0.12);
}

.t48-tile {
  position: absolute;
  top: var(--gap);
  left: var(--gap);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.1em;
  width: calc((100% - 5 * var(--gap)) / 4);
  height: calc((100% - 5 * var(--gap)) / 4);
  border-radius: 0.4rem;
  font-size: clamp(0.95rem, 5.4vw, 1.5rem);
  font-weight: 800;
  line-height: 1;
  transform: translate(calc(var(--x) * (100% + var(--gap))), calc(var(--y) * (100% + var(--gap))));
}

.t48-tile .t48-art {
  width: 58%;
  height: 52%;
}

.t48-d4 .t48-num {
  font-size: 0.82em;
}

.t48-d5 .t48-num,
.t48-d6 .t48-num {
  font-size: 0.68em;
}

.t48-ready .t48-tile {
  transition: transform 100ms ease-in-out;
}

.t48-new {
  animation: t48-in 100ms ease-out;
}

.t48-merged {
  animation: t48-pop 100ms ease-out;
}

@keyframes t48-in {
  from {
    scale: 0.2;
  }
}

@keyframes t48-pop {
  50% {
    scale: 1.12;
  }
}

@media (prefers-reduced-motion: reduce) {
  .t48-ready .t48-tile {
    transition: none;
  }

  .t48-new,
  .t48-merged {
    animation: none;
  }
}

.t48-v1 {
  background: #e3f2fd;
  color: #0d3b66;
}

.t48-v2 {
  background: #bbdefb;
  color: #0d3b66;
}

.t48-v3 {
  background: #90caf9;
  color: #0d2b4e;
}

.t48-v4 {
  background: #c8e6c9;
  color: #1b4d1e;
}

.t48-v5 {
  background: #81c784;
  color: #10301a;
}

.t48-v6 {
  background: #2e7d32;
  color: #ffffff;
}

.t48-v7 {
  background: #1b5e20;
  color: #ffffff;
}

.t48-v8 {
  background: #ffe082;
  color: #4a2c00;
}

.t48-v9 {
  background: #ffb300;
  color: #3a2000;
}

.t48-v10 {
  background: #bf360c;
  color: #ffffff;
}

.t48-v11 {
  background: #c62828;
  color: #ffffff;
}

.t48-v12 {
  background: #5d0b0b;
  color: #ffd54f;
}

.t48-art {
  display: block;
  overflow: visible;
}

.t48-lines path:first-child {
  stroke: #1d2638;
  stroke-width: 4;
}

.t48-lines path:last-child {
  stroke: #fff;
  stroke-width: 2;
}

.t48-ornament > path:first-child {
  stroke-width: 7;
}

.t48-solid path {
  stroke: #1d2638;
  stroke-width: 10;
  stroke-linejoin: round;
  paint-order: stroke;
}

.t48-coloring .cp-part,
.t48-coloring .cp-line {
  stroke: #1d2638;
  stroke-width: 9;
  cursor: inherit;
}

.t48-end {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 1rem;
  border-radius: 0.6rem;
  background: rgb(13 27 46 / 0.86);
  text-align: center;
}

.t48-end > .t48-said {
  margin: 0;
  color: var(--gold);
  font-size: 1.4rem;
  font-weight: 800;
}

.t48-legend {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
  gap: 0.4rem;
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
}

.t48-key {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0.6rem;
  border-radius: 0.4rem;
  font-size: 0.9rem;
  font-weight: 600;
}

.t48-key .t48-art {
  flex: none;
  width: 1.9rem;
  height: 1.9rem;
}

.t48-note {
  margin: 0.25rem 0 0;
  text-align: center;
}

/* Alone on the full screen (`/puzzles/2048/play`): the board, no names under it. */
.play-stage .t48-wrap {
  width: min(100%, 26rem, 62dvh);
}

.play-stage .t48-names {
  display: none;
}

/* ---------- Christmas Minesweeper (/puzzles/minesweeper) ---------- */
/* The levels, the mode („Uncover” / „Mark with a candy cane”, large for a thumb), „New game” and the full screen, the
   coal left and the time, then the field: as wide as the page, at most 2.4rem a square, so 16 × 16 still fits a phone
   of 360 px (about 20 px a square) without the page scrolling sideways. A square under the snow is a white drift with
   flakes; uncovered it is trodden snow (`minesweeper::OPEN`) with its number in the color of `.msw-n1`…`.msw-n8`
   (`minesweeper::NUMBERS`, each 4.5:1 or more on it). The candy cane and the coal are `<use>` of the page's symbols.
   The coal that ended a game on red; a candy cane where there was no coal faded. The end under the field. */
.msw-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.msw-tools {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.msw-tools[hidden],
.msw-stats[hidden],
.msw-wrap[hidden],
.msw-end[hidden] {
  display: none;
}

.msw-tools > p {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin: 0;
}

.msw-tool {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 3rem;
  padding: 0.4rem 1.1rem;
  border: 2px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 1.05rem;
  font-weight: 700;
  cursor: pointer;
}

.msw-tool[aria-pressed="true"] {
  border-color: var(--gold);
  background: var(--gold);
  color: var(--ink);
}

.msw-swatch {
  width: 1.2rem;
  height: 1.2rem;
  border: 1.5px solid #9fb4c8;
  border-radius: 0.2rem;
  background: linear-gradient(#ffffff, #d4e3f1);
}

.msw-tool .msw-art {
  width: 1.4rem;
  height: 1.4rem;
}

.msw > .msw-stats {
  margin: 0 0 0.6rem;
  color: var(--snow);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.msw-wrap {
  max-width: 100%;
}

.msw-easy {
  --w: 9;
}

.msw-medium {
  --w: 12;
}

.msw-hard {
  --w: 16;
}

.msw-board {
  container-type: inline-size;
  display: grid;
  grid-template-columns: repeat(var(--w), 1fr);
  gap: 2px;
  width: min(100%, calc(var(--w) * 2.4rem));
  margin: 0 auto;
  padding: 4px;
  border-radius: 0.5rem;
  background: #9fb4c8;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

.msw-row,
.msw-gc {
  display: contents;
}

.msw-cell {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background:
    radial-gradient(circle at 30% 30%, #ffffff 0 8%, transparent 9%),
    radial-gradient(circle at 70% 62%, #ffffff 0 6%, transparent 7%),
    linear-gradient(#ffffff, #d4e3f1);
  box-shadow: inset 0 -2px 0 #b3c7da;
  color: #1d2638;
  font: inherit;
  font-size: calc(100cqi / var(--w) * 0.55);
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
}

.msw-cell:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 0;
  position: relative;
  z-index: 1;
}

.msw-open {
  background: #eef3f8;
  box-shadow: none;
  cursor: default;
}

.msw-art {
  width: 78%;
  height: 78%;
  pointer-events: none;
}

.msw-hit {
  background: #f6c9c4;
}

.msw-wrong .msw-art {
  opacity: 0.35;
}

.msw-n1 {
  color: #1552a8;
}

.msw-n2 {
  color: #1d6b27;
}

.msw-n3 {
  color: #b3261e;
}

.msw-n4 {
  color: #4a2a9a;
}

.msw-n5 {
  color: #7a3410;
}

.msw-n6 {
  color: #00635a;
}

.msw-n7 {
  color: #263238;
}

.msw-n8 {
  color: #5b3a2e;
}

.msw-end {
  margin-top: 0.75rem;
  text-align: center;
}

.msw-end > p {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin: 0.4rem 0 0;
}

.msw-end > .msw-said {
  color: var(--gold);
  font-size: 1.3rem;
  font-weight: 800;
}

.msw-note {
  margin: 0.25rem 0 0;
  text-align: center;
}

/* Alone on the full screen (`/puzzles/minesweeper/play`): the field fits the screen's height too. */
.play-stage .msw-board {
  width: min(100%, calc(var(--w) * 2.4rem), 62dvh);
}

/* A phone: the field takes the screen's width past the page's margins (centered on it), its gaps thinner – 16 × 16
   squares of about 20 px on 360 px, still no sideways scroll. */
@media (max-width: 30rem) {
  .msw-board {
    position: relative;
    left: 50%;
    width: min(calc(100vw - 1.5rem), calc(var(--w) * 2.4rem));
    gap: 1px;
    padding: 2px;
    translate: -50% 0;
  }
}
