/* YourThesisDiploma · the page IS the sheet.

   Rebuilt after the first round: no travelling world, no header bar, no
   chapters. A dark warm wall, one lamp, and the product hanging under it at
   full size. Scrolling walks down the paper. The only chrome on the page is
   the language switcher and the start button, both floating top right.

   bg #141210 · ink #EAE4D8 · muted #A49C8E · brass #C9A254 (locked action)
   paper #F2EBDB · paper ink #191510 */

:root {
  color-scheme: only dark;
  --bg: #141210;
  --ink: #EAE4D8;
  --muted: #A49C8E;
  --brass: #C9A254;
  /* The deadline tone. Brass warmed towards ember: it reads as pressure on a
     dark wall without turning the shop into a sale rack. Never red. */
  --ember: #D9915E;
  --brass-lit: #DDB86A;
  --brass-pressed: #AE8B3D;
  --brass-deep: #8C6B22;
  --paper: #F2EBDB;
  --paper-ink: #191510;
  --paper-muted: #5C5443;
  --paper-rule: #BCAE91;

  --serif: "EB Garamond", Georgia, serif;
  --sans: "Space Grotesk", system-ui, sans-serif;

  --edge: clamp(1rem, 4vw, 3rem);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --mx: 50%;
  --my: 30%;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: clamp(0.98rem, 0.95rem + 0.15vw, 1.05rem);
  line-height: 1.6;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
a { color: inherit; }
::selection { background: var(--brass); color: #16120A; }
:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; }

.skip-link {
  position: fixed; top: 0; left: 0; z-index: 90;
  transform: translateY(-140%);
  background: var(--brass); color: #16120A;
  padding: 0.7rem 1.1rem; font-weight: 600; text-decoration: none;
}
.skip-link:focus { transform: none; }

/* ---------- The room: a wall, and a lamp above the paper ---------- */

.room {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(46% 34% at 50% 6%, rgba(255, 228, 172, 0.20), rgba(20, 18, 16, 0) 72%),
    radial-gradient(90% 60% at 50% 42%, rgba(58, 48, 38, 0.55), rgba(20, 18, 16, 0) 72%),
    linear-gradient(180deg, #1A1714 0%, #141210 46%, #100E0C 100%);
}
/* A faint grain so the wall is a surface and not a gradient. */
.room::after {
  content: ""; position: absolute; inset: 0; opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
}

/* ---------- The action bar: fixed, blurred, always within reach ---------- */

.actionbar {
  position: fixed; z-index: 65; inset: auto 0 0 0;
  display: flex; align-items: center; justify-content: center; gap: clamp(0.8rem, 2vw, 1.6rem);
  padding: 0.85rem var(--edge) calc(0.85rem + env(safe-area-inset-bottom));
  background: rgba(20, 18, 16, 0.62);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border-top: 1px solid rgba(234, 228, 216, 0.14);
}
.actionbar-note {
  margin: 0; font-size: 0.78rem; color: var(--muted);
  display: flex; align-items: baseline; gap: 0.5rem;
}
.actionbar-note b { color: var(--brass); font-weight: 700; }
.actionbar-note s { color: var(--muted); opacity: 0.8; }
.actionbar .btn { flex: none; }

/* ---------- The language switcher, alone at the top ---------- */

.controls {
  position: fixed; z-index: 60;
  top: calc(env(safe-area-inset-top) + 0.75rem); right: var(--edge);
  display: flex; align-items: center; gap: 0.5rem;
}

.lang { position: relative; }
.lang-btn {
  display: flex; align-items: center; gap: 0.45rem;
  background: rgba(20, 18, 16, 0.72); color: var(--ink);
  border: 1px solid rgba(234, 228, 216, 0.2); border-radius: 2px;
  padding: 0.42rem 0.6rem; font: inherit; font-size: 0.8rem; cursor: pointer;
  min-height: 38px;
  transition: border-color 0.25s var(--ease);
}
.lang-btn:hover { border-color: var(--brass); }
.flag { width: 20px; height: 14px; display: block; flex: none; border: 1px solid rgba(0, 0, 0, 0.4); }
.lang-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 61;
  margin: 0; padding: 0.3rem; list-style: none; min-width: 190px;
  background: #1B1815; border: 1px solid rgba(234, 228, 216, 0.16); border-radius: 2px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.6);
}
.lang-menu li { margin: 0; }
.lang-menu button {
  display: flex; align-items: center; gap: 0.55rem; width: 100%;
  background: transparent; border: 0; color: var(--ink);
  font: inherit; font-size: 0.86rem; text-align: left;
  padding: 0.45rem 0.55rem; cursor: pointer; border-radius: 2px;
}
.lang-menu button:hover, .lang-menu button:focus-visible { background: rgba(201, 162, 84, 0.16); }
.lang-menu button[aria-selected="true"] { color: var(--brass); }

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  font-family: var(--sans); font-size: 0.9rem; font-weight: 600;
  padding: 0.78rem 1.4rem; border-radius: 2px; border: 1px solid transparent;
  text-decoration: none; cursor: pointer; min-height: 44px;
  /* Stated, not inherited: a <button> is given line-height:normal by the
     browser while a <label> dressed as a button inherits the page's, which
     made the file-choosing door five pixels taller than the one beside it. */
  line-height: 1.2;
  transition: background-color 180ms var(--ease), border-color 180ms var(--ease), color 180ms var(--ease),
              opacity 180ms var(--ease);
}
/* A button that cannot be pressed has to look like one. Print and Download
   stand beside the sheet while it is still being written, and until now they
   were merely inert: full brass, full weight, and nothing happened when a
   buyer pressed them. */
.btn:disabled, .btn[disabled] {
  opacity: 0.34; cursor: default; pointer-events: none;
}
/* A button answers the pointer with colour and nothing else. It never moves,
   never follows the cursor: it lights under the hand and darkens when pressed,
   the way a button on any page does. */
.btn-solid { background: var(--brass); color: #16120A; }
.btn-solid:hover, .btn-solid:focus-visible { background: var(--brass-lit); }
.btn-solid:active { background: var(--brass-pressed); }
.btn-line { background: transparent; color: var(--ink); border-color: rgba(234, 228, 216, 0.32); }
.btn-line:hover, .btn-line:focus-visible { border-color: var(--brass); color: var(--brass); }
.btn-line:active { border-color: var(--brass-lit); color: var(--brass-lit); background: rgba(201, 162, 84, 0.1); }
.btn-sm { padding: 0.5rem 0.95rem; font-size: 0.8rem; min-height: 38px; }
.btn-wide { width: 100%; }
.btn-big { padding: 1.05rem 2.6rem; font-size: 1.02rem; }

.linkbtn {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: var(--brass); text-decoration: underline;
  text-underline-offset: 3px;
}
.linkbtn:hover { color: var(--brass-lit); }

/* ---------- The exhibit ---------- */

main { position: relative; z-index: 1; }

/* The exhibit answers a click with another specimen. */
#sheet { cursor: pointer; }

.show {
  position: relative;
  padding: clamp(2.6rem, 4.4vh, 3.6rem) var(--edge) clamp(2.2rem, 5vh, 3.6rem);
  display: flex; flex-direction: column; align-items: center;
}

/* The offer line floats in the space above the title instead of standing in
   the column, so the sheet sits as high as it can and nothing shifts when the
   line fades in after the first seconds. */
.ticker {
  position: absolute; top: 0.85rem; left: 50%; transform: translateX(-50%);
  width: min(100%, 46rem); padding: 0 var(--edge);
  display: flex; align-items: baseline; flex-wrap: wrap; justify-content: center;
  gap: 0.35rem 1.1rem; margin: 0; text-align: center;
  font-size: 0.76rem;
}
.ticker > b {
  color: var(--brass); font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
}
.ticker-price em { font-style: normal; font-weight: 700; color: var(--ink); }
.ticker-price s { color: var(--muted); margin-left: 0.35rem; }
.ticker-clock { display: inline-flex; align-items: baseline; gap: 0.28rem; font-variant-numeric: tabular-nums; color: var(--muted); }
.ticker-clock b { color: var(--ink); font-weight: 700; }
.ticker-clock i { font-style: normal; margin-right: 0.45rem; font-size: 0.68rem; }

h1 {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.5rem, 1.2rem + 1.3vw, 2.3rem);
  line-height: 1.15; letter-spacing: 0.005em;
  margin: 0 0 clamp(1.5rem, 3.4vh, 2.5rem); text-align: center; text-wrap: balance;
  color: var(--ink); max-width: 24ch;
}

/* The subtitle is the title's own voice, one size down. */
.hero-sub {
  margin: -0.7rem 0 clamp(5.4rem, 9vh, 7.4rem);
  text-align: center; text-wrap: balance;
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1rem, 0.86rem + 0.6vw, 1.4rem);
  line-height: 1.2; letter-spacing: 0.005em; color: var(--ink);
}

/* The lamp: the paper is lit from above and stands off the wall. */
.lamp {
  position: relative;
  width: min(820px, 100%);
  --fr: clamp(8px, 1.25vw, 15px);
  --mat: clamp(7px, 1.15vw, 15px);
  /* walnut, until a variant is drawn for this visit */
  --sT: #6B563C; --sL: #5A4832; --sR: #392B1D; --sB: #2C2116;
  --matc: #DFD6C2; --fillet: rgba(104, 82, 40, 0.7); --railline: rgba(0, 0, 0, 0.35);
}
/* Three mouldings, all of them brown wood — light, mid and dark — and every
   one of them darker than the sheet.
   The mount is a shade below the paper as well: a framer never cuts a mount
   in the colour of what it holds, because then the work has no edge. */
.lamp.fr-walnut { --sT: #6B563C; --sL: #5A4832; --sR: #392B1D; --sB: #2C2116; --matc: #DFD6C2; --fillet: rgba(104, 82, 40, 0.7); --railline: rgba(0, 0, 0, 0.35); }
.lamp.fr-oak    { --sT: #C4A97F; --sL: #B2966B; --sR: #8A6E48; --sB: #75593A; --matc: #E2D8C3; --fillet: rgba(110, 80, 40, 0.65); --railline: rgba(0, 0, 0, 0.26); }
.lamp.fr-wenge  { --sT: #4A3626; --sL: #3C2B1D; --sR: #241810; --sB: #1B120B; --matc: #DCD4C0; --fillet: rgba(96, 74, 38, 0.65); --railline: rgba(0, 0, 0, 0.45); }

/* ---------- The frame, put on while the visitor scrolls ----------
   Four rails just outside the paper and a wire above it. They start apart and
   close in as the page is scrolled, so the visitor watches the sheet being
   framed and hung rather than being told that it can be. */

/* One object: the moulding is the border, the mount is the padding it holds,
   and the corners mitre at forty five degrees the way a framer cuts them.
   Light falls from the upper left, so the top and left sides are the lit ones. */
.frame {
  position: absolute; inset: calc(-1 * (var(--fr) + var(--mat)));
  pointer-events: none; z-index: 0; opacity: 0;
  border: var(--fr) solid transparent;
  border-image: conic-gradient(from 45deg,
    var(--sR) 0 25%, var(--sB) 0 50%, var(--sL) 0 75%, var(--sT) 0) 1;
  background: var(--matc); background-clip: padding-box;
  box-shadow:
    0 30px 60px rgba(0, 0, 0, 0.62),
    0 8px 18px rgba(0, 0, 0, 0.45);
}
/* the lip where the moulding meets the mount */
.frame::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 0 1px var(--railline), inset 0 1px 3px rgba(0, 0, 0, 0.22);
}
/* the cut of the mount, a fine line just outside the paper */
.frame::after {
  content: ""; position: absolute; pointer-events: none;
  inset: calc(var(--fr) + var(--mat) - 3px);
  border: 1px solid var(--fillet);
  box-shadow: 0 0 6px rgba(0, 0, 0, 0.07);
}

/* Which way a click will page, shown only while the pointer is on the paper. */
.pager {
  position: absolute; top: 50%; z-index: 2; pointer-events: none;
  width: 26px; height: 26px; margin-top: -13px;
  opacity: 0; transition: opacity 260ms ease;
  background: no-repeat center / 12px 20px;
}
.pager.prev {
  left: calc((-1 * (var(--fr) + var(--mat))) - 30px);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20' fill='none' stroke='%23EAE4D8' stroke-width='1.4'%3E%3Cpath d='M10 1L2 10l8 9'/%3E%3C/svg%3E");
}
.pager.next {
  right: calc((-1 * (var(--fr) + var(--mat))) - 30px);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 20' fill='none' stroke='%23EAE4D8' stroke-width='1.4'%3E%3Cpath d='M2 1l8 9-8 9'/%3E%3C/svg%3E");
}
.lamp.show-prev:not(.at-first) .pager.prev { opacity: 0.8; }
.lamp.show-next:not(.at-last) .pager.next { opacity: 0.8; }

.frame-hang {
  position: absolute; z-index: 0; pointer-events: none;
  left: 14%; right: 14%; top: calc(-1 * (var(--fr) + var(--mat)) - 26px); height: 26px;
  color: rgba(234, 228, 216, 0.46); opacity: 0;
}
.frame-hang svg { width: 100%; height: 100%; display: block; }
.lamp.is-framed .frame { opacity: 1; transform: none; }
.lamp.is-framed .frame-hang { opacity: 1; }

.frame-hang .nail {
  position: absolute; left: 50%; top: -2px;
  width: 7px; height: 7px; margin-left: -3.5px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #C9BFAE, #55493C 70%, #2A231C 100%);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

.sheet {
  position: relative;
  background: var(--paper);
  color: var(--paper-ink);
  font-family: var(--serif);
  padding: clamp(2.4rem, 5.6vw, 4.6rem) clamp(1.7rem, 6vw, 4.6rem);
  box-shadow: 0 50px 120px rgba(0, 0, 0, 0.68), 0 4px 14px rgba(0, 0, 0, 0.4);
  background-image:
    radial-gradient(130% 40% at 50% 0%, rgba(255, 248, 226, 0.9), rgba(242, 235, 219, 0) 58%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.86' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
}
/* The sheen: the paper catches the light where the visitor is looking. This
   is the one moving thing on the page, and it makes it read as an object. */
.sheet::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(520px circle at var(--mx) var(--my), rgba(255, 250, 232, 0.62), rgba(255, 250, 232, 0) 62%);
  mix-blend-mode: soft-light;
}
/* The engraved double frame of a diploma, drawn, not imported. */
.sheet::after {
  content: ""; position: absolute; inset: clamp(0.7rem, 1.6vw, 1.3rem);
  border: 1px solid var(--paper-rule);
  outline: 1px solid var(--paper-rule); outline-offset: 5px;
  pointer-events: none; opacity: 0.7;
}

/* The engraved corners: four filigree quarters inside the frame. */
.sheet-corner {
  position: absolute; display: block; color: var(--brass-deep); opacity: 0.55;
  width: clamp(26px, 4.4vw, 46px); height: clamp(26px, 4.4vw, 46px);
  pointer-events: none;
}
.sheet-corner svg { width: 100%; height: 100%; display: block; }
.sheet-corner.tl { top: clamp(1.1rem, 2.4vw, 1.9rem); left: clamp(1.1rem, 2.4vw, 1.9rem); }
.sheet-corner.tr { top: clamp(1.1rem, 2.4vw, 1.9rem); right: clamp(1.1rem, 2.4vw, 1.9rem); transform: scaleX(-1); }
.sheet-corner.bl { bottom: clamp(1.1rem, 2.4vw, 1.9rem); left: clamp(1.1rem, 2.4vw, 1.9rem); transform: scaleY(-1); }
.sheet-corner.br { bottom: clamp(1.1rem, 2.4vw, 1.9rem); right: clamp(1.1rem, 2.4vw, 1.9rem); transform: scale(-1, -1); }

.sheet-orn {
  display: block; width: min(240px, 58%); height: auto;
  margin: clamp(1.1rem, 2.6vw, 1.8rem) auto; color: var(--brass-deep); opacity: 0.75;
}

/* The house: an engraved elevation of the university, drawn behind the whole
   sheet. No real university mark is reproduced, because those are protected. */
.sheet-house {
  position: absolute; z-index: 0; pointer-events: none;
  top: clamp(1.6rem, 4vw, 3rem); left: 4%; width: 92%;
  color: var(--brass-deep); opacity: 0.13;
}
.sheet-house svg { width: 100%; height: auto; display: block; }

.sheet-kind, .sheet-name, .sheet-place, .sheet-field, .sheet-title,
.sheet-body, .sheet-line, .sheet-people, .sheet-foot, .sheet-orn {
  position: relative; z-index: 1;
}

.sheet-kind {
  margin: 0 0 0.55rem; text-align: center;
  font-family: var(--sans); font-size: 0.66rem; font-weight: 600;
  letter-spacing: 0.26em; text-transform: uppercase; color: var(--paper-muted);
}
.sheet-name {
  margin: 0 0 0.5rem; text-align: center;
  font-size: clamp(1.9rem, 1.25rem + 2.4vw, 3.1rem); font-weight: 500;
  line-height: 1.03; letter-spacing: 0.005em;
}
.sheet-place { margin: 0 0 0.35rem; text-align: center; font-size: 1.02rem; color: var(--paper-muted); }
.sheet-field {
  margin: 0; text-align: center; font-family: var(--sans);
  font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--paper-muted);
}
.sheet-title {
  margin: 0 auto; text-align: center; max-width: 42ch;
  font-style: italic; font-size: 1.28rem; line-height: 1.36;
}

/* The body is set in two columns like a real document, which is what makes a
   dense page read as elaborate instead of merely long. */
.sheet-body {
  column-count: 2; column-gap: clamp(1.4rem, 3vw, 2.6rem);
  column-rule: 1px solid rgba(188, 174, 145, 0.45);
  font-size: calc(0.845rem * var(--fit, 1));
  margin-top: 0.4rem;
}
.sheet-sec { break-inside: avoid; margin: 0 0 calc(0.95rem * var(--fit, 1)); }
.sheet-sec h4 {
  margin: 0 0 0.3rem;
  font-size: 0.6rem; font-family: var(--sans); font-weight: 600;
  letter-spacing: 0.19em; text-transform: uppercase; color: var(--paper-muted);
  display: flex; gap: 0.45rem; align-items: baseline;
}
.sheet-sec h4 i { font-style: normal; color: var(--brass-deep); }
.sheet-sec p { margin: 0; line-height: 1.52; text-align: left; hyphens: manual; }
/* German words are long and the columns are narrow, so German alone is
   hyphenated, which is what a German reader expects anyway. */
html[lang="de"] .sheet-sec p, html[lang="de"] .sheet-col li span { hyphens: auto; }
/* A drop capital opens the document, as it would on an engraved certificate. */
.sheet-sec:first-child p::first-letter {
  float: left; font-size: 3.05em; line-height: 0.82;
  padding: 0.06em 0.1em 0 0; color: var(--brass-deep);
}

/* The line of the work: what led here, and what this led to. */
.sheet-line {
  margin: 2.2rem 0 0; padding-top: 1.6rem;
  border-top: 1px solid rgba(188, 174, 145, 0.45);
}
.sheet-line { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.2rem, 3vw, 2.4rem); }
.sheet-col h4 {
  margin: 0 0 1rem; text-align: center;
  font-family: var(--sans); font-size: 0.66rem; font-weight: 600;
  letter-spacing: 0.26em; text-transform: uppercase; color: var(--paper-muted);
}
.sheet-col ol {
  list-style: none; margin: 0 auto; padding: 0 0 0 1.6rem;
  border-left: 1px solid rgba(188, 174, 145, 0.7);
  max-width: 46rem;
}
.sheet-col li {
  position: relative; display: grid; grid-template-columns: 4.4rem 1fr;
  gap: 0.9rem; padding: 0.26rem 0; font-size: calc(0.86rem * var(--fit, 1)); line-height: 1.42;
}
.sheet-col li::before {
  content: ""; position: absolute; left: calc(-1.6rem - 4px); top: 0.72em;
  width: 7px; height: 7px; transform: rotate(45deg);
  border: 1px solid rgba(140, 107, 34, 0.8); background: var(--paper);
}
.sheet-col b { font-weight: 500; color: var(--paper-muted); font-variant-numeric: lining-nums; }
.sheet-col li.is-this { font-weight: 600; }
.sheet-col li.is-this b { color: var(--brass-deep); }
.sheet-col li.is-this::before {
  left: calc(-1.6rem - 5.5px); top: 0.66em;
  width: 10px; height: 10px; background: var(--brass-deep); border-color: var(--brass-deep);
}

/* The table of contents of the work itself, in a column of its own that runs
   the whole height of the page beside the text and both lines. It is the first
   page of the bound copy, kept in the margin: number, chapter, page. */
.sheet-main {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: var(--toc, 150px) 1fr;
  gap: clamp(1rem, 2.4vw, 1.8rem);
}
.sheet-flow { min-width: 0; }
.sheet-toc {
  min-width: 0; padding-right: clamp(0.9rem, 2vw, 1.4rem);
  border-right: 1px solid rgba(188, 174, 145, 0.55);
}
.sheet-toc { display: flex; flex-direction: column; }
.sheet-toc h4 {
  margin: 0 0 1rem;
  font-family: var(--sans); font-size: 0.6rem; font-weight: 600;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--paper-muted);
}
.sheet-toc ol {
  list-style: none; margin: 0; padding: 0;
  flex: 1; display: flex; flex-direction: column; justify-content: space-between;
}
/* One line per entry: number, chapter, leader, page. Chapters, their sections
   and their subsections are told apart by indent and by weight, exactly as on
   the first page of the bound copy. */
.sheet-toc li {
  display: grid; grid-template-columns: var(--tn, 1.5rem) 1fr auto;
  gap: 0.2rem; font-size: calc(0.74rem * var(--fit, 1)); line-height: 1.28;
}
.sheet-toc li b { font-weight: 500; color: var(--brass-deep); font-variant-numeric: lining-nums; }
.sheet-toc li span { display: flex; align-items: baseline; gap: 0.25rem; min-width: 0; }
.sheet-toc li span i {
  flex: 1 1 auto; min-width: 0.35rem; transform: translateY(-0.24em);
  border-bottom: 1px dotted rgba(140, 107, 34, 0.5);
}
.sheet-toc li em {
  font-style: normal; color: var(--paper-muted);
  font-variant-numeric: lining-nums tabular-nums;
}
.sheet-toc li.d0 { font-weight: 600; }
.sheet-toc li.d1 { padding-left: 0.5rem; }
.sheet-toc li.d2 { padding-left: 1rem; color: var(--paper-muted); }
.sheet-toc li.d2 b { color: var(--paper-muted); }

.sheet-people {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.75rem clamp(1.4rem, 3vw, 2.6rem);
  margin: 0; font-size: calc(0.9rem * var(--fit, 1));
}
.sheet-people dt {
  font-family: var(--sans); font-size: 0.62rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--paper-muted);
  margin-bottom: 0.1rem;
}
.sheet-people dd { margin: 0; }

.sheet-foot {
  margin: 1.5rem 0 0; font-family: var(--sans);
  font-size: 0.65rem; line-height: 1.5; color: var(--paper-muted); text-align: center;
}
.sheet-foot span { display: block; }


/* The withdrawal notice, and the two lines under the button.
   The tick is the one control on this step that must be impossible to miss
   and impossible to tick by accident, so it is set at reading size with the
   box beside it rather than as fine print under it. */
#pay[disabled] { opacity: 0.45; cursor: not-allowed; }
#pay[disabled]:hover { background: var(--brass); }

/* And the one line for a failure, which speaks only when there is one. */
.pay-error {
  margin: 0; padding: 1rem 1.1rem;
  font-size: 0.84rem; line-height: 1.5; color: var(--ember); text-align: left;
  border: 1px solid rgba(217, 145, 94, 0.35); border-radius: 3px;
  background: rgba(217, 145, 94, 0.07);
}


/* Stripe's form, in the page. It brings its own look; what this side owes it
   is room, a light ground to sit on and nothing on top of it. */
/* Stripe's form draws its own surface and follows the reader's own light or
   dark setting, so it already arrives dark on a dark screen. The white board
   this used to sit on was therefore a bright frame around a dark thing: a
   rectangle of the wrong colour drawn around the one part of the page that
   belongs to somebody else. Nothing is drawn under it now. It sits on the
   shop's own wall, with the same thin rule the rest of the panel uses, and
   the two read as one surface. */
.checkout {
  margin: 0; padding: 0;
  background: transparent;
  /* Inlaid, not applied. A warm hairline the colour of the wall's own brass,
     the corners barely rounded the way the rest of the shop rounds them, and
     a shadow that falls INWARD so the panel reads as set into the wall rather
     than resting on it. */
  border: 1px solid rgba(201, 162, 84, 0.22);
  border-radius: 3px;
  box-shadow: inset 0 1px 0 rgba(234, 228, 216, 0.06),
              0 14px 34px -18px rgba(0, 0, 0, 0.8);
  overflow: hidden;
  min-height: 320px;
}
.checkout[hidden] { display: none; }

/* ---------- Three lines ---------- */

.steps-strip {
  padding: clamp(2rem, 5vh, 3.4rem) var(--edge);
  border-top: 1px solid rgba(234, 228, 216, 0.1);
  border-bottom: 1px solid rgba(234, 228, 216, 0.1);
  text-align: center;
}
.steps {
  list-style: none; margin: 0 auto; padding: 0;
  display: flex; justify-content: center; flex-wrap: wrap;
  gap: clamp(1.2rem, 5vw, 3.6rem);
  max-width: 1000px;
}
.steps li {
  display: flex; align-items: baseline; gap: 0.6rem;
  font-family: var(--serif); font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.35rem);
}
.steps i { font-style: normal; color: var(--brass); font-size: 0.85em; }

/* ---------- The numbers, dead centre ---------- */

.offer {
  padding: clamp(3rem, 7vh, 5rem) var(--edge) clamp(2.4rem, 6vh, 4rem);
  display: flex; flex-direction: column; align-items: center; text-align: center;
}
.offer-name {
  margin: 0 0 1.2rem; color: var(--brass);
  font-size: 0.8rem; font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase;
}
.price-now {
  margin: 0; font-family: var(--serif); color: var(--ink);
  font-size: clamp(4rem, 2rem + 11vw, 9rem); line-height: 0.92; letter-spacing: -0.02em;
}
.price-was { margin: 0.4rem 0 0; }
.price-was s { color: var(--muted); font-size: clamp(1.1rem, 1rem + 0.5vw, 1.5rem); }

.clock-big {
  display: flex; justify-content: center; gap: clamp(1rem, 4vw, 2.6rem);
  margin: clamp(1.6rem, 4vh, 2.6rem) 0 0.9rem;
  font-variant-numeric: tabular-nums;
}
.clock-big span { display: flex; flex-direction: column; align-items: center; gap: 0.2rem; }
.clock-big b {
  font-family: var(--serif); font-size: clamp(2rem, 1.2rem + 3vw, 3.4rem);
  line-height: 1; color: var(--brass);
}
.clock-big i {
  font-style: normal; font-size: 0.66rem; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--muted);
}
.after { margin: 0 0 2rem; font-size: 0.84rem; color: var(--muted); }

/* ---------- When the clock is a deadline, not a date ----------
   Two states, both set from the one absolute instant in main.js. `is-soon`
   warms the numbers and lets the seconds breathe; `no-days` takes the days
   cell out on the last day so the clock reads hours, minutes, seconds. */

.ticker-clock.no-days .cd,
.clock-big.no-days .cd { display: none; }

.ticker-clock.is-soon b { color: var(--ember); }
.clock-big.is-soon b { color: var(--ember); }
.clock-big.is-soon { gap: clamp(1.1rem, 4.4vw, 2.9rem); }
.clock-big.is-soon b {
  font-size: clamp(2.3rem, 1.3rem + 3.6vw, 4rem);
  text-shadow: 0 0 26px rgba(217, 145, 94, 0.22);
}
.clock-big.is-soon i { color: #8E8073; }

/* The seconds carry the pulse alone. One beat a second, barely there: it is
   the page having a heartbeat, not a banner flashing. */
.clock-big.is-soon span:last-child b { animation: beat 1s steps(1, end) infinite; }
@keyframes beat {
  0%, 55% { opacity: 1; }
  56%, 100% { opacity: 0.72; }
}

/* The offer heading goes with them. */
.offer:has(.clock-big.is-soon) .offer-name { color: var(--ember); }

@media (prefers-reduced-motion: reduce) {
  .clock-big.is-soon span:last-child b { animation: none; }
}


/* The band at the foot is the space between its own rule and the action bar.
   The address stands in the middle of it, with the same air above and below. */
.footer {
  position: relative; z-index: 1;
  --air: clamp(3.4rem, 6vh, 5rem);
  padding: var(--air) var(--edge) calc(var(--barh, 76px) + var(--air) + env(safe-area-inset-bottom));
  border-top: 1px solid rgba(234, 228, 216, 0.1);
  color: var(--muted); font-size: 0.76rem;
  display: grid; gap: 0.5rem; justify-items: center; text-align: center;
}
.footer p { margin: 0; max-width: 58ch; }
/* One address, so nobody has to hunt for a way to reach a person. */
.footer-legal {
  margin: 0.9rem 0 0; display: flex; flex-wrap: wrap; justify-content: center;
  gap: 0.4rem 1.4rem; font-size: 0.76rem;
}
.footer-legal a { color: var(--muted); text-decoration: none; }
.footer-legal a:hover { color: var(--brass); text-decoration: underline; text-underline-offset: 3px; }

.footer-mail a {
  color: var(--brass); text-decoration: underline; text-underline-offset: 3px;
  white-space: nowrap;
}
.footer-mail a:hover { color: var(--brass-lit); }

/* The language the document is issued in, asked on the paying step. */
.doclang { margin: 0 0 1.4rem; text-align: center; }
.doclang-label { margin: 0 0 0.7rem; font-size: 0.92rem; color: var(--ink); }
.doclang-row { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; }
.doclang-btn {
  display: inline-flex; align-items: center; gap: 0.45rem;
  background: transparent; color: var(--muted);
  border: 1px solid rgba(234, 228, 216, 0.22); border-radius: 2px;
  padding: 0.45rem 0.7rem; font: inherit; font-size: 0.82rem; cursor: pointer;
  min-height: 38px;
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
}
.doclang-btn:hover { border-color: var(--brass); color: var(--ink); }
.doclang-btn[aria-pressed="true"] {
  border-color: var(--brass); color: var(--brass); background: rgba(201, 162, 84, 0.12);
}
.doclang-note { margin: 0.7rem 0 0; font-size: 0.78rem; color: var(--muted); }
/* The finished sheet, at the full width of the panel: it is what the visitor
   just bought, so it fills the room it is shown in. */
.done-writing {
  margin: 0 0 1.4rem; color: var(--muted);
  font-family: var(--serif); font-size: 1.05rem;
}
/* Not an alarm and not decoration: one line, in the ember the shop uses for
   things a visitor has to act on, set apart by a rule rather than a box. */
.done-hold {
  margin: 0 0 1.4rem; padding-left: 0.9rem;
  border-left: 2px solid rgba(217, 145, 94, 0.55);
  font-size: 0.86rem; line-height: 1.5; color: var(--ember);
}
.done-hold[hidden] { display: none; }

.done-writing::after {
  content: ""; display: inline-block; width: 1.2em; text-align: left;
  animation: writingdots 1.4s steps(4, end) infinite;
}
@keyframes writingdots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "..."; } }
.done-paper { width: 100%; }
.done-paper .sheet--page { transform-origin: top left; box-shadow: 0 16px 34px rgba(0, 0, 0, 0.5); }

/* ---------- The page: exactly A4, on screen and on paper ----------
   794 x 1123 px is A4 at 96dpi. The sheet is built at that size and simply
   scaled to the available width, so what the visitor reads is the page that
   comes out of the printer, to the millimetre. */

.sheet--page {
  width: 794px; min-height: 1123px;
  padding: 74px 38px 34px;
  transform-origin: top left;
  box-shadow: 0 40px 90px rgba(0, 0, 0, 0.62);

  /* NOTHING INSIDE THE PAPER MAY ASK HOW WIDE THE WINDOW IS.
  
     The sheet is a fixed object, 794 by 1123, and every size in it is set in
     pixels for that reason. Three things were still reaching past it to the
     browser window, and they moved the layout by a few pixels on every
     different screen — enough that the contents column, the colophon, the
     stamp and the people row all sat at slightly different heights on a
     phone than on a desktop, and different again on paper.
  
     The inherited size is the first: the page's body type is fluid, and
     anything in the sheet measured in em or ch followed it. It is pinned
     here to the value that size has at the paper's own width, 794px, which
     is the width the printer lays the sheet out at — so the screen now
     agrees with the paper rather than the other way round. */
  font-size: 16.391px;
}
/* And the two gaps that were still written in vw and never overridden. Both
   are the value they take at 794px, for the same reason. */
.sheet--page .sheet-colophon { gap: 19.85px; }
.sheet--page .sheet-line { gap: 23.82px; }

.sheet--page .sheet-kind { font-size: 7.6px; letter-spacing: 0.26em; margin-bottom: 3px; }
.sheet--page .sheet-name { font-size: 29px; margin-bottom: 2px; }
.sheet--page .sheet-place { font-size: 11.5px; margin-bottom: 2px; }
.sheet--page .sheet-field { font-size: 8px; }
.sheet--page .sheet-title { font-size: 15px; max-width: 46ch; line-height: 1.24; }
.sheet--page .sheet-orn { width: 150px; margin: 4px auto; }
.sheet--page .sheet-name { margin-bottom: 2px; }
.sheet--page .sheet-colophon { margin-top: 9px; }
/* The body is the product. It is set as small as it can be set and still
   read on paper, because every millimetre freed here is another sentence
   about the work itself.

   These are the sizes at --fit 1. The page measures itself once it is laid
   out and moves that number until what is on it reaches the foot: see
   fitSheet() in main.js. Everything the reader reads scales together, so the
   sheet stays one object rather than a body that grew out of its margins. */
.sheet--page .sheet-body { font-size: calc(7.35px * var(--fit, 1)); column-count: 2; column-gap: 20px; margin-top: 2px; }
.sheet--page .sheet-sec { margin-bottom: calc(7px * var(--fit, 1)); }
.sheet--page .sheet-sec h4 { font-size: calc(8.2px * var(--fit, 1)); letter-spacing: 0.18em; margin-bottom: 4px; gap: 5px; }
.sheet--page .sheet-sec p { line-height: 1.5; }
.sheet--page .sheet-sec:first-child p::first-letter { font-size: 2.8em; }
.sheet--page .sheet-line { margin-top: 12px; padding-top: 10px; }
.sheet--page .sheet-col h4 { font-size: 7.6px; margin-bottom: 7px; }
.sheet--page .sheet-col ol { padding-left: 16px; }
.sheet--page .sheet-col li { grid-template-columns: 44px 1fr; gap: 7px; font-size: calc(8.4px * var(--fit, 1)); padding: 1px 0; line-height: 1.26; }
.sheet--page .sheet-main { --toc: 146px; gap: 15px; }
.sheet--page .sheet-toc { padding-right: 12px; }
.sheet--page .sheet-toc h4 { font-size: 7px; margin-bottom: 8px; letter-spacing: 0.2em; }
.sheet--page .sheet-toc li { --tn: 19px; font-size: calc(7.3px * var(--fit, 1)); line-height: 1.26; gap: 3px; }
.sheet--page .sheet-toc li.d1 { padding-left: 6px; }
.sheet--page .sheet-toc li.d2 { padding-left: 12px; }
.sheet--page .sheet-col li::before { left: -20px; width: 6px; height: 6px; }
.sheet--page .sheet-col li.is-this::before { left: -21px; width: 8px; height: 8px; }
.sheet--page .sheet-people { font-size: calc(9.4px * var(--fit, 1)); gap: 7px 16px; grid-template-columns: repeat(3, 1fr); }
.sheet--page .sheet-people dt { font-size: 6.2px; }
.sheet--page .sheet-foot { font-size: 7.4px; margin-top: 9px; }
.sheet--page .sheet-corner { width: 24px; height: 24px; }
/* The fine rule inside the paper's edge sat at 16px here and at 6mm in the
   print block, which wins on paper by coming later. So the preview carried a
   tighter margin than the sheet that comes out of the printer — the one
   place left where what the visitor saw was not what they would receive. The
   screen is moved to the paper's value, never the other way round: the
   printed sheet is the product and is not changed to suit a screen. */
.sheet--page::after { inset: 6mm; outline-offset: 4px; }

/* The first sentence of the work, set as an epigraph. */
.sheet-epigraph {
  position: relative; z-index: 1;
  margin: 0 auto; max-width: 52ch; text-align: center;
  font-style: italic; line-height: 1.45; color: var(--paper-ink);
  padding: 0 1.5rem;
}
.sheet-epigraph span {
  display: block; font-family: var(--sans); font-style: normal;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--paper-muted);
  margin-bottom: 0.4rem;
}

/* The red inked stamp of the issuing office, set slightly askew as a real one is. */
.sheet-red {
  position: absolute; z-index: 1; pointer-events: none;
  top: 34px; right: 34px; width: 104px; height: 104px;
  color: #9B2C2C; opacity: 0.72; transform: rotate(-9deg);
  mix-blend-mode: multiply;
}
.sheet-red svg { width: 100%; height: 100%; display: block; font-family: var(--sans); }

/* The file reference, top left, the way an archive marks a document. */
.sheet-ref {
  position: absolute; z-index: 1; top: 38px; left: 40px; margin: 0;
  font-family: var(--sans); font-size: 8px; letter-spacing: 0.14em;
  color: var(--paper-muted); text-transform: uppercase;
}
.sheet-ref i { display: block; font-style: normal; font-size: 6.4px; letter-spacing: 0.24em; opacity: 0.8; }

/* The square under the file reference: point a phone at it and the place the
   copy is kept opens. Small, quiet, and the same ink as the rest of the page. */
.sheet-qr {
  position: absolute; z-index: 1; top: 72px; left: 40px;
  width: 72px; text-align: left;
}
.sheet-qr a { display: block; line-height: 0; }
.sheet-qr svg { width: 100%; height: auto; display: block; opacity: 0.88; }
.sheet-qr i {
  display: block; margin-top: 5px; font-style: normal;
  font-family: var(--sans); font-size: 7px; font-weight: 600; letter-spacing: 0.18em;
  color: var(--paper-muted); line-height: 1.3; white-space: nowrap;
}

/* When it was drawn up, and under which number. */
.sheet-issue {
  position: relative; z-index: 1; margin: 14px 0 0;
  display: flex; justify-content: space-between; gap: 1rem;
  border-top: 1px solid var(--paper-rule); padding-top: 5px;
  font-family: var(--sans); font-size: 7px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--paper-muted);
}

/* The second drawing: what the work was about, behind the lower half. */
.sheet-motif {
  position: absolute; z-index: 0; pointer-events: none;
  left: 50%; transform: translateX(-50%);
  bottom: 7%; width: 46%;
  color: var(--brass-deep); opacity: 0.13;
}
.sheet-motif svg { width: 100%; height: auto; display: block; }

/* The century, with the year of the work marked on it. */

/* The colophon and the stamp share one row, so the stamp costs no height. */
.sheet-colophon { position: relative; z-index: 1; display: flex; align-items: center; gap: clamp(1rem, 2.5vw, 1.8rem); }
.sheet-colophon .sheet-people { flex: 1; }

/* Where on earth it happened, stamped like a notary's mark. */
.sheet-stamp {
  position: relative; z-index: 1; flex: none;
  width: 88px; text-align: center; color: var(--brass-deep);
  display: grid; justify-items: center; gap: 1px;
}
.sheet-stamp svg { width: 46px; height: 46px; opacity: 0.8; margin: 0 auto; }
.sheet-stamp b {
  font-family: var(--sans); font-size: 7.5px; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
}
.sheet-stamp i { font-family: var(--sans); font-style: normal; font-size: 6.4px; color: var(--paper-muted); letter-spacing: 0.06em; }

/* ---------- The purchase flow ---------- */

.flow {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(10, 8, 7, 0.9);
  display: grid; place-items: center;
  padding: clamp(0.6rem, 2vw, 2rem);
  overflow-y: auto;
}
.flow[hidden] { display: none; }
.flow-panel {
  width: min(940px, 100%); max-height: 94dvh; overflow-y: auto;
  background: #1A1714;
  border: 1px solid rgba(234, 228, 216, 0.16);
  padding: clamp(1.2rem, 3vw, 2.4rem);
  position: relative;
}
.flow-head { margin-bottom: 1.4rem; padding-right: 3rem; }
.flow-head h2 { margin: 0; font-family: var(--serif); font-weight: 500; font-size: clamp(1.7rem, 1.3rem + 1.6vw, 2.6rem); }
.flow-close {
  position: absolute; top: 0.7rem; right: 0.7rem;
  width: 44px; height: 44px; display: grid; place-items: center;
  background: transparent; border: 1px solid rgba(234, 228, 216, 0.22);
  color: var(--ink); font-size: 1.4rem; line-height: 1; cursor: pointer; border-radius: 2px;
}
.flow-close:hover { border-color: var(--brass); color: var(--brass); }

.paths { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.path {
  border: 1px solid rgba(234, 228, 216, 0.14);
  padding: clamp(1.1rem, 2.4vw, 1.8rem);
  display: flex; flex-direction: column; gap: 0.6rem; align-items: flex-start;
}
.path h3 { font-family: var(--serif); font-weight: 500; font-size: 1.35rem; margin: 0; }
.path p { margin: 0 0 0.5rem; color: var(--muted); font-size: 0.92rem; }
/* The two doors are equals, and their copy is not the same length in every
   language. Sending each button to the foot of its own box puts both on one
   line whatever the text does above it. */
.path .btn { margin-top: auto; }

/* A conversation behaves the way every other conversation does: the messages
   scroll, the field stays under them, and the heading gets out of the way. */
.chat {
  display: flex; flex-direction: column; gap: 0.7rem;
  max-height: 58vh; overflow-y: auto; overscroll-behavior: contain;
  padding-right: 0.4rem; margin-bottom: 1.1rem; scroll-behavior: smooth;
}
.flow.is-chat .flow-head { margin-bottom: 0.4rem; }
.flow.is-chat .flow-head h2 { display: none; }
.flow.is-chat .flow-panel { padding-top: clamp(2.4rem, 4vw, 3rem); }
/* The chat speaks in the voice of the rest of the page, not in the voice of a
   support widget: the serif, a size up, and room around the words. */
.msg {
  max-width: 54ch; padding: 0.85rem 1.1rem; line-height: 1.45;
  font-family: var(--serif); font-size: 1.12rem; letter-spacing: 0.005em;
}
.msg-bot { background: rgba(234, 228, 216, 0.07); border: 1px solid rgba(234, 228, 216, 0.16); align-self: flex-start; }
.msg-you { background: rgba(201, 162, 84, 0.14); border: 1px solid rgba(201, 162, 84, 0.32); align-self: flex-end; }
.msg-think { color: var(--muted); font-style: italic; }
.msg-think b { display: inline-block; width: 1.2em; text-align: left; font-weight: 400; }

.candidate { border-top: 1px solid rgba(234, 228, 216, 0.14); padding-top: 1.1rem; margin-bottom: 1.1rem; }
.candidate-kicker { margin: 0 0 0.7rem; font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--brass); }
.candidate-card {
  background: var(--paper); color: var(--paper-ink);
  font-family: var(--serif); padding: 1.1rem 1.3rem; margin-bottom: 0.9rem;
}
.candidate-card b { display: block; font-size: 1.35rem; font-weight: 500; }
.candidate-card span { display: block; font-size: 0.95rem; color: var(--paper-muted); }
.candidate-card em { display: block; margin-top: 0.5rem; }
.candidate-ask { margin: 0 0 0.8rem; font-family: var(--serif); font-size: 1.25rem; }
.acts { display: flex; flex-wrap: wrap; gap: 0.7rem; }

.notfound {
  border: 1px solid rgba(201, 162, 84, 0.3); background: rgba(201, 162, 84, 0.07);
  padding: 1rem 1.2rem; margin-bottom: 1.1rem; font-size: 0.94rem;
}
.notfound p { margin: 0; }
/* The paragraph ends in an offer, so the offer has to be reachable. */
.notfound-act { margin-top: 0.9rem; }

/* A proposal inside the conversation: the record as a card, the question, and
   the two answers. It stays in the transcript once it has been answered. */
.msg-records { max-width: 54ch; }
.rec-kicker {
  margin: 0 0 0.6rem; font-family: var(--sans); font-size: 0.68rem;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--brass);
}
.rec-card {
  background: var(--paper); color: var(--paper-ink);
  padding: 0.8rem 0.95rem; margin-bottom: 0.6rem;
  display: grid; gap: 0.15rem;
}
.rec-card b { font-size: 1.05rem; }
.rec-card span { font-size: 0.86rem; color: var(--paper-muted); }
.rec-card em { font-size: 0.92rem; }
.rec-card .btn { justify-self: start; margin-top: 0.45rem; }
.rec-ask { margin: 0.2rem 0 0.6rem; font-size: 1rem; }
.msg-records .acts { display: flex; gap: 0.6rem; flex-wrap: wrap; }

.chat-form label {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.chat-row { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.chat-row input {
  flex: 1 1 16rem; min-width: 0;
  color-scheme: only dark;
  background: rgba(16, 14, 12, 0.9); color: var(--ink);
  border: 1px solid rgba(234, 228, 216, 0.24); border-radius: 2px;
  padding: 0.75rem 0.9rem; font: inherit; font-size: 0.95rem;
}
.chat-row input::placeholder { color: #918878; }
.chat-row input:focus-visible { border-color: var(--brass); }

/* ---------- What the document turned out to be ----------
   Three steps share this look: the reading, the refusal, and the work no
   archive holds. Each is one short thing said to one person, so it is set as
   prose at reading width rather than as a panel of interface. Nothing here
   moves on hover; the buttons answer in colour, as they do everywhere else. */

/* ---------- One step becoming another ----------
   The arriving step rises a little and comes up out of nothing, and the panel
   carries its own change of height instead of snapping to it. Together they
   turn what read as the page stalling into something closer to a page being
   turned. Every part of it is off under prefers-reduced-motion. */
@keyframes stepping-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.fstep.stepping-in { animation: stepping-in 460ms var(--ease) both; }
.flow-panel.is-resizing {
  overflow: hidden;
  transition: height 560ms var(--ease);
}
/* The heading changes with the step, so it is given the same breath. */
.flow-head h2 { transition: opacity 300ms var(--ease); }

@media (prefers-reduced-motion: reduce) {
  .fstep.stepping-in { animation: none; }
  .flow-panel.is-resizing { transition: none; }
}

.fstep-say { max-width: 60ch; }
.fstep-say[hidden] { display: none; }
/* The step brings its own heading, so the dialog's general one gets out of
   the way. Hidden from the eye and not from a screen reader: it is still what
   names this dialog. */
.flow.is-said .flow-head h2 {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.flow.is-said .flow-panel { padding-top: clamp(2.4rem, 4vw, 3rem); }
.say-title {
  font-family: var(--serif); font-weight: 500; font-size: clamp(1.5rem, 3vw, 2rem);
  margin: 0 0 0.9rem; line-height: 1.15;
}
.say-lead {
  font-family: var(--serif); font-size: 1.18rem; line-height: 1.5;
  margin: 0 0 0.9rem;
}
.say-note { margin: 0 0 1.4rem; color: var(--muted); font-size: 0.94rem; line-height: 1.55; }
.say-note[hidden] { display: none; }
/* the work as the visitor's own title page gives it, on paper, so it reads as
   a record and not as a message about one */
.say-work {
  background: var(--paper); color: var(--paper-ink); font-family: var(--serif);
  padding: 1rem 1.2rem; margin: 0 0 1.2rem; display: grid; gap: 0.25rem;
}
.say-work b { font-size: 1.2rem; font-weight: 500; }
.say-work span { font-size: 0.9rem; color: var(--paper-muted); }
.say-acts { display: flex; flex-wrap: wrap; gap: 0.7rem; }
/* the reading itself: three marks that fill and fade, the same beat as the
   line of dots in the conversation */
.say-wait { display: flex; gap: 0.45rem; margin-top: 0.4rem; }
.say-wait i { width: 7px; height: 7px; border-radius: 50%; background: var(--brass); opacity: 0.25; }
.say-wait i { animation: saywait 1.25s var(--ease) infinite; }
.say-wait i:nth-child(2) { animation-delay: 0.18s; }
.say-wait i:nth-child(3) { animation-delay: 0.36s; }
@keyframes saywait { 0%, 100% { opacity: 0.22; } 45% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .say-wait i { animation: none; opacity: 0.6; } }

/* ---------- The till, all of it on one screen ----------
   Stripe's form is around 870 pixels tall by itself, which is taller than the
   window the shop sits in, so nothing may stand above or below it: the three
   things a buyer needs — what they are buying, what they are choosing, and how
   they pay — stand side by side, and the height of the page is the height of
   the tallest one. Before that they were stacked and the buyer had to scroll
   past the sheet and the price to reach the card. */
.fstep[data-step="pay"] {
  display: grid;
  gap: clamp(1.1rem, 2.4vw, 2rem);
  grid-template-columns: minmax(0, 1fr) minmax(360px, 0.82fr);
  align-items: start;
}
.fstep[data-step="pay"][hidden] { display: none; }

/* The panel widens for this one step, because three columns need the room and
   every other step is happier narrow. Its padding comes in too: every line of
   it is a line the till has to give back. */
.flow.is-till .flow-panel {
  width: min(1340px, 100%);
  padding: clamp(0.7rem, 1.2vw, 1.1rem);
}
/* And the heading gives back what it can: at the till the sheet is the thing
   being looked at, and every line the heading keeps is a line the card form
   has to find somewhere else. */
.flow.is-till .flow-head { margin-bottom: 0.35rem; }
.flow.is-till .flow-head h2 { font-size: clamp(1.15rem, 1rem + 0.55vw, 1.4rem); }

/* None of the three may set the height of the page. Stripe's form grows and
   shrinks with what it manages to load — the wallets, the list of methods —
   and on a tall render it used to push the whole panel into a scroll, so the
   buyer was back to scrolling past the sheet to reach the card. Each column
   is capped at the room the window has, and if one of them still runs over it
   scrolls inside itself. The page does not move. */
.pay-preview, .pay-till {
  min-width: 0;
  max-height: calc(94dvh - 6.5rem);
}
.pay-till { overflow-y: auto; overscroll-behavior: contain; }

/* ---------- The apparatus of the till ----------
   The sheet marks its own chapters with a roman numeral, a rule and a line of
   small brass capitals. The till borrows exactly that, so the two things left
   to do read as the last two chapters of the document rather than as a form
   bolted to the side of it. A payment box dropped onto a page looks bought in;
   the same box at the foot of a numbered apparatus looks like it belongs. */
.till-mark {
  display: flex; align-items: baseline; gap: 0.7rem;
  margin: 0 0 0.75rem;
  font-size: 0.68rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--brass);
}
.till-mark i {
  font-style: normal; font-family: var(--serif); font-size: 0.9rem;
  letter-spacing: 0.06em; color: var(--brass-deep);
  min-width: 1.3em;
}
/* The rule runs from the end of the words to the far edge, which is what the
   sheet does above every one of its own chapters. */
.till-mark::after {
  content: ""; flex: 1; height: 1px; align-self: center;
  background: linear-gradient(90deg, rgba(201, 162, 84, 0.45), rgba(201, 162, 84, 0.06));
}
.till-mark + .doclang { margin: 0 0 1.5rem; }

/* Five buttons, and they have to look pressable.
   The underlined version that stood here read as a row of labels: elegant, and
   it left a visitor unsure whether English was a choice he had made or one the
   shop had made for him. So each one is a button again — but a struck one, in
   the shop's own brass, not the little grey rectangles that made this corner
   look like a form. The one in force is FILLED: brass ground, brass rule, dark
   type, and it sits a hair lower, the way a key that has been pressed does.
   Nothing else on this panel is filled, so the eye finds it at once. */
.pay-till .doclang-row { justify-content: flex-start; gap: 0.4rem; }
.pay-till .doclang-btn {
  border: 1px solid rgba(234, 228, 216, 0.2);
  border-radius: 2px;
  background: rgba(234, 228, 216, 0.03);
  padding: 0.5rem 0.8rem; min-height: 38px;
  font-size: 0.82rem; color: var(--muted);
  transition: background-color 0.22s var(--ease), border-color 0.22s var(--ease),
              color 0.22s var(--ease), transform 0.22s var(--ease);
}
.pay-till .doclang-btn .flag { opacity: 0.7; transition: opacity 0.22s var(--ease); }
.pay-till .doclang-btn:hover {
  color: var(--ink);
  border-color: rgba(201, 162, 84, 0.65);
  background: rgba(201, 162, 84, 0.09);
}
.pay-till .doclang-btn:hover .flag { opacity: 1; }
.pay-till .doclang-btn:active { transform: translateY(1px); }
.pay-till .doclang-btn[aria-pressed="true"] {
  background: var(--brass);
  border-color: var(--brass);
  color: #191510;
  font-weight: 600;
  transform: translateY(1px);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.28);
}
.pay-till .doclang-btn[aria-pressed="true"] .flag { opacity: 1; }
.pay-till .doclang-btn[aria-pressed="true"]:hover {
  background: var(--brass-lit); border-color: var(--brass-lit);
}

/* The form takes a second or two to arrive from Stripe. Three lines of the
   shape it will have stand in its place meanwhile, so the column is never a
   hole, and they breathe rather than sit still. */
/* The stand-in and the form share one frame, so the first can lie exactly
   over the second and step aside without anything moving. */
.till-box { position: relative; min-height: 300px; }
.till-wait {
  position: absolute; inset: 0; z-index: 2;
  display: grid; gap: 0.7rem; align-content: start;
  padding: 0.9rem;
  background: #1A1714;
  border: 1px solid rgba(201, 162, 84, 0.22);
  border-radius: 3px;
}
.till-wait span {
  display: block; height: 46px; border-radius: 4px;
  background: linear-gradient(100deg, rgba(234,228,216,0.05) 30%,
    rgba(234,228,216,0.11) 50%, rgba(234,228,216,0.05) 70%);
  background-size: 280% 100%;
  animation: till-waiting 1.5s var(--ease) infinite;
}
.till-wait span:nth-child(2) { height: 120px; animation-delay: 0.12s; }
.till-wait span:nth-child(3) { height: 64px; animation-delay: 0.24s; }
@keyframes till-waiting {
  from { background-position: 140% 0; }
  to   { background-position: -40% 0; }
}
.till-wait[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .till-wait span { animation: none; } }

/* If a column does run over, the buyer has to be able to SEE that it does.
   Stripe's form is a different height for every buyer — the wallets it offers,
   the currency chooser, the list of methods — so on some renders the Pay
   button sits below the edge, and a column that hides it silently is worse
   than one that scrolls. A thin rule on the right, and the ground fading out
   at the foot, say there is more without putting a grey bar on the wall. */
.pay-till { scrollbar-width: thin; scrollbar-color: rgba(201, 162, 84, 0.45) transparent; }
.pay-till::-webkit-scrollbar { width: 6px; }
.pay-till::-webkit-scrollbar-track { background: transparent; }
.pay-till::-webkit-scrollbar-thumb { background: rgba(201, 162, 84, 0.45); border-radius: 3px; }
.pay-till::-webkit-scrollbar-thumb:hover { background: rgba(201, 162, 84, 0.7); }

/* The fade sits inside the column, pinned to its foot, and it only shows when
   the form is taller than the room. It is drawn on the shop's own ground, not
   on Stripe's white, so it reads as the wall ending rather than as a smudge on
   the form. */
.pay-till { position: relative; }
.pay-till::after {
  content: ""; position: sticky; z-index: 2;
  display: block; bottom: 0; height: 46px; margin-top: -46px;
  background: linear-gradient(180deg, rgba(26, 23, 20, 0) 0%, rgba(26, 23, 20, 0.85) 78%, #1A1714 100%);
  pointer-events: none;
}

@media (max-width: 860px) {
  .fstep[data-step="pay"] { grid-template-columns: 1fr; }
}
/* the whole page, scaled down, with everything worth reading blurred out */
.pay-preview { position: relative; }
.pay-paper { position: relative; width: 100%; overflow: hidden; }
/* Capped to the room the till leaves, so the sheet can never be what makes
   the page scroll. What is cut off is the foot of a page that is blurred and
   locked in the first place. The subtracted band is the panel's own padding
   plus the heading above it. */
.pay-preview { overflow: hidden; }
.pay-paper .sheet--page { transform-origin: top left; box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5); }
.pay-preview .sheet-sec p,
.pay-preview .sheet-col li span,
.pay-preview .sheet-toc li,
.pay-preview .sheet-people dd,
.pay-preview .sheet-foot { filter: blur(3.4px); user-select: none; }
.pay-lock {
  position: absolute; inset: auto 0 0 0; height: 34%;
  display: grid; place-items: center;
  background: linear-gradient(180deg, rgba(26, 23, 20, 0) 0%, rgba(26, 23, 20, 0.78) 55%, rgba(26, 23, 20, 0.95) 100%);
}
/* What holds the sheet shut until it is paid for: the same engraved ring as
   before, with a lock drawn inside it in the red of the archival stamp, thin
   and half transparent so it sits on the paper rather than on top of it. */
.brand-seal {
  width: 62px; height: 62px; display: block;
  color: #B0574E; opacity: 0.72;
}

.pay-source {
  margin: 0 0 0.6rem; font-family: var(--sans); font-size: 0.76rem;
  letter-spacing: 0.06em; color: var(--muted);
}


/* The till. Nothing typed here goes anywhere: it is the shape of a checkout,
   and the live shop hands the real one to the payment provider. */
.till { display: flex; flex-direction: column; gap: 0.7rem; }
.pay-way:hover { border-color: var(--brass); color: var(--ink); }
.way-mark {
  width: 22px; height: 15px; border-radius: 2px; display: grid; place-items: center;
  font-size: 10px; font-weight: 700; color: #16120A; background: var(--muted);
}
.way-mark.card { background: linear-gradient(135deg, #C9A254 0%, #8C6B22 100%); }
.way-mark.paypal { background: #BFC9D8; }
.way-mark.apple { background: #DDD8CE; }

.fld { display: flex; flex-direction: column; gap: 0.25rem; font-size: 0.74rem; color: var(--muted); }
.fld.wide { grid-column: 1 / -1; }
.fld input, .fld select {
  background: rgba(10, 9, 8, 0.6); color: var(--ink);
  border: 1px solid rgba(234, 228, 216, 0.2); border-radius: 2px;
  padding: 0.6rem 0.7rem; font: inherit; font-size: 0.92rem; min-height: 42px;
}
.fld input::placeholder { color: #6E675C; }
.fld input:focus-visible, .fld select:focus-visible { border-color: var(--brass); outline: none; }
.pay-price { margin: 0; font-family: var(--serif); font-size: 2.8rem; line-height: 1; color: var(--brass); }
.pay-price s { font-size: 1.1rem; color: var(--muted); margin-left: 0.5rem; }
.pay-note { margin: 0; font-size: 0.84rem; color: var(--muted); }

.done-acts { display: flex; gap: 0.7rem; flex-wrap: wrap; margin-bottom: 1.6rem; }

.sheet-mini { padding: 1.7rem 1.5rem; box-shadow: none; }
.sheet-mini .sheet-name { font-size: 1.65rem; }
.sheet-mini .sheet-title { font-size: 1rem; margin-bottom: 1rem; }
.sheet-mini .sheet-sec p { font-size: 0.8rem; }
.sheet-mini .sheet-body { column-count: 1; }
.sheet-mini .sheet-corner { display: none; }

/* ---------- Printing: only the sheet goes on paper ---------- */

.print-only { display: none; }

@media print {
  body { background: #fff; }
  .room, .controls, .actionbar, .footer, main, .flow, .skip-link { display: none !important; }
  /* Stripe.js hangs its own helper frames straight off the body, one pixel
     tall, and sets their display inline with !important — which beats any
     rule written here. On screen they are nothing; on paper that one pixel
     sat just below the sheet and became a second, empty page.
     A stylesheet cannot win against an inline !important, so they are put
     away in the page itself, on the two paths that print: see hideHelpers()
     in main.js. What is left here is the belt to that pair of braces. */
  html, body { height: 1123px !important; overflow: hidden !important; }
  .print-only { display: block; box-shadow: none; margin: 0; transform: none !important; }
  /* On paper the light in the room means nothing: the sheen, the warm glow
     from the lamp and the grain are all a screen's business. What is printed
     is flat paper with ink on it. */
  .sheet::before { display: none; }
  .sheet { background: #fff; background-image: none; }
  .sheet::after { inset: 6mm; }
  @page { size: A4 portrait; margin: 0; }
}

/* ---------- Responsive ---------- */

/* THE DOCUMENT KEEPS ITS PROPORTIONS ON EVERY SCREEN.
 
   Below 860px the sheet used to be RE-LAID-OUT rather than made smaller:
   full width instead of 794px, one column instead of two, type in rem and vw
   instead of the fixed pixel sizes the paper is set in, the contents moved
   from beside the text to above it, the stamp moved under the colophon. It
   read well on a phone and it was a different document from the one the
   buyer receives.
 
   That is not what this shop sells. It sells ONE sheet, and a visitor
   deciding whether to buy it has to be looking at that sheet, not at a
   version of it arranged for their handset. So the paper keeps its 794 by
   1123 everywhere and is SCALED to the width available — the same page,
   smaller — which is what fitPage() in main.js now does at every width
   rather than only above 860px.
 
   What stays below is the FRAME around it, which is furniture and may shrink
   to suit the room. */
@media screen and (max-width: 860px) {
  .lamp { --fr: 6px; --mat: 5px; }
}

@media screen and (max-width: 720px) {
  /* On a phone the two controls dock at the bottom, so they need a ground of
     their own or the certificate text runs under them. */
  .controls { top: calc(env(safe-area-inset-top) + 0.6rem); right: 0.7rem; }
  .actionbar { padding: 0.7rem 0.8rem calc(0.7rem + env(safe-area-inset-bottom)); }
  .actionbar-note { font-size: 0.72rem; }
  /* the offer line floats above the title and wraps on a phone, so the
     space it needs is reserved here once and for all */
  .show { padding-top: 4.6rem; padding-bottom: 5.5rem; }
  .fstep[data-step="pay"] { grid-template-columns: 1fr; }
  .steps { flex-direction: column; align-items: center; gap: 0.9rem; }
  .flow-panel { padding-bottom: 5rem; }
}

@media (min-width: 1600px) {
  .lamp { width: min(880px, 100%); }
}

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
  .sheet::before { display: none; }
}

/* =====================================================================
   THE PHONE
   =====================================================================

   The whole shop was built and looked at on a desktop, and most of what it
   sells will be bought on a phone. Measured on 16 September 2026 across nine
   screens from a folded Galaxy at 280px to a 1920px desktop, with the whole
   purchase driven through to the till on each.

   The page was 418px wide inside a 393px iPhone. One element did that: the
   two chevrons beside the frame sit OUTSIDE it on purpose, at a negative
   offset, which is right at a desk where there is room either side and wrong
   on a phone where there is none. Everything else followed from it — the
   language button lost its last letters off the right edge, the price line
   ran under it, the buy button's right edge sat at 405px.
   -------------------------------------------------------------------- */

/* Nothing may ever widen the page again. `clip` rather than `hidden`,
   because `hidden` would silently turn the body into a scroll container and
   break every `position: sticky` in the page. */
html, body { overflow-x: clip; }

@media (max-width: 900px) {
  /* A finger needs more than a pointer does. The chevrons used to be hidden
     here as well; they are drawn inside the mount now instead, further down. */
  .lang-btn { min-height: 44px; }
}

@media (max-width: 860px) {
  /* THE TILL HAS TO BE REACHABLE — and now it is, without cutting anything.
     The preview used to be capped at 46vh because the sheet reflowed into a
     full A4 page's worth of scrolling. Scaled instead of reflowed, the whole
     sheet on a 393px phone is 556px tall, so it is shown entire and the card
     fields sit right under it. */
  .pay-preview { max-height: none; }
}

@media (max-width: 720px) {
  /* The chevrons are a desk affordance: they live outside the frame, they
     cannot be tapped (pointer-events: none) and a phone turns pages by
     swiping anyway. They are what made the page wider than the screen. */
  /* The bar carries a price and the one button that starts the purchase.
     Side by side they needed 405px of a 393px screen, so the button now
     takes the width it needs and the price sits above it. */
  .actionbar { flex-wrap: wrap; justify-content: center; gap: 0.5rem 1rem; }
  .actionbar .btn { flex: 1 1 100%; max-width: 22rem; }
  .actionbar-note { flex: 1 1 100%; justify-content: center; }

  /* Room for a thumb. A link 16px tall is a link that gets missed twice
     before it is hit. */
  .footer-legal a, .footer-mail a { display: inline-block; padding: 0.7rem 0; }
  .footer-legal { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.2rem 1.1rem; }
}

@media (max-width: 720px) {
  /* THE OFFER LINE AND THE LANGUAGE BUTTON WERE SHARING ONE EDGE.
     The line is centred across the full width and the button is fixed to the
     top right, so on a phone the button sat on top of the line's right end:
     the old struck-through price disappeared behind a German flag and the
     seconds were cut in half. Rather than squeeze the line into what is left,
     it now starts BELOW the button, where it has the whole width to itself
     and reads as one row. What the page owes it in space is reserved here. */
  .ticker { top: calc(env(safe-area-inset-top) + 3.9rem); }
  .show { padding-top: 7.2rem; }
}

@media (max-width: 420px) {
  .lang-btn { padding: 0.38rem 0.5rem; font-size: 0.74rem; }
}

@media (max-width: 340px) {
  /* A folded phone, 280px across.
  
     The language NAME used to be dropped here and the flag left to speak for
     it. That was wrong twice over. It is the one thing on the page that says
     the shop is in his language and can be changed, and a flag is a poor way
     to say either — Spanish is not one country and English is not one flag.
     And a browser set to enlarge a page reports a NARROWER page, so a visitor
     on an ordinary phone who reads a little larger fell into this rule and
     was shown a lone flag. It stays, one size smaller.
     
     The sheet's two-column entries stack instead: at this width the label
     column alone left the text nowhere to go and it ran off the edge. */
  #lang-label { font-size: 0.68rem; }
  .lang-btn { padding: 0.3rem 0.4rem; gap: 0.3rem; }
  .flag { width: 16px; height: 11px; }
}

/* A FINGER IS A FINGER AT ANY WIDTH.
   Tap sizes were keyed to how wide the screen is, and a phone turned
   sideways is 852px wide: it was being handed the sizes meant for a mouse.
   An iPad in landscape, 1024px, the same. What decides this is the pointer,
   not the width, so it is asked directly. */
@media (hover: none) and (pointer: coarse) {
  .lang-btn { min-height: 44px; }

  /* The five language buttons at the till stood 39px tall, just under what a
     thumb reliably hits, and the short legal links were 24px wide. The
     capability is the same on every device; being able to USE it has to be
     too. */
  .pay-till .doclang-btn { min-height: 44px; }
  .footer-legal a { min-width: 3.4rem; text-align: center; }

  /* And a flag that only brightens under a mouse pointer stays dim forever on
     a screen that has none. */
  .pay-till .doclang-btn .flag { opacity: 1; }
  .footer-legal a, .footer-mail a { display: inline-block; padding: 0.7rem 0; }
  .footer-legal { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.2rem 1.1rem; }
}

/* A PHONE HELD SIDEWAYS IS 393px TALL.
   The flow is a dialog with its own scroll; in landscape it had the height
   of a letterbox and the heading, the sheet and the till all wanted room at
   once. The heading gives back its margins and the capped preview gives back
   most of its height, so what stays on screen is the part that matters. */
@media (max-height: 460px) and (orientation: landscape) {
  .flow-head { padding-top: 0.5rem; padding-bottom: 0.5rem; }
  .flow-panel { padding-top: 0.6rem; }
  .pay-preview { max-height: 38vh; }
  .show { padding-top: 6rem; }
}


/* =====================================================================
   NOTHING IS DROPPED BECAUSE THE SCREEN IS SMALL
   =====================================================================

   He opened the shop on his own iPhone and the picture was not hanging from
   anything. Three things had been switched off below 860px and the reason
   was always the same one: they are positioned against the sheet, and a
   sheet that reflows to a phone has no room around it. Switching them off is
   the cheapest answer and the wrong one — the frame being hung, the
   watermark on the paper and the two chevrons are the whole idea of the
   page, not decoration on top of it. They are made to fit instead.
   -------------------------------------------------------------------- */

@media screen and (max-width: 860px) {
  /* THE WIRE AND THE NAIL. The picture hangs from something again. The wire
     is shorter and pulled in, because 26px of wire above a 6px moulding
     reads as a rope; the nail keeps its size, being a nail. */
  .frame-hang {
    display: block;
    left: 22%; right: 22%;
    top: calc(-1 * (var(--fr) + var(--mat)) - 17px); height: 17px;
  }

  /* THE WATERMARK. It sits behind the text at z-index 0 and is 13% opaque,
     so it never competed with anything; it was dropped because it is
     anchored to the bottom of a sheet whose height changes completely when
     the page reflows. Anchored a little higher and drawn a little wider, it
     lands on the paper here the way it does on the wide one. */
  /* Nothing to adjust any more: the sheet is the same sheet here, so the
     watermark lands where it lands on the wide one. It is only un-hidden. */
  .sheet-motif { display: block; }

  /* THE CHEVRONS. They were hung OUTSIDE the frame, which is what made the
     page wider than the phone. Inside the mount they cost nothing, and since
     a touch screen has no hover to reveal them they simply stay, quietly,
     which is also the only hint on a phone that the sheet can be tapped for
     another. */
  .pager { display: block; width: 22px; height: 22px; margin-top: -11px; }
  .pager.prev { left: calc(var(--mat) + 2px); }
  .pager.next { right: calc(var(--mat) + 2px); }
}

@media (hover: none) and (pointer: coarse) {
  .pager { display: block; }
  .lamp:not(.at-first) .pager.prev,
  .lamp:not(.at-last) .pager.next { opacity: 0.5; }
}
