/* ---------------------------------------------------------------------------
   The house style (issue 023).

   The house is paper and ink. It owns the typography, the rules, the night
   band and the layout, and it has no colour of its own: the one thing that
   varies per pack is `--accent`, set on <main> from the pack's content file
   (issue 018's discipline), and everything coloured on a page -- the button,
   the numerals, the eyebrow, the rules -- takes it. No token below belongs to
   any pack. A pack whose page sets no accent gets ink, which is the house
   wearing its own clothes.

   Mobile is the product, not a breakpoint. Everything is written at 375px
   first; the two media queries at the bottom are the only widening.

   Three faces. The display roman is Bodoni Moda, the display italic is
   Newsreader, and the text face is the system serif — the last because body
   copy in a Didone is unreadable at 17px on a phone, and because a font that
   blocks first paint costs more sales than Georgia costs taste. All three
   self-hosted, ~30-40 KB each, font-display: swap.

   Nothing in the display face is set below 600, and that is not a style
   preference. Bodoni is a Didone: its thin strokes are hairlines by design, and
   a hairline is roughly one device pixel. Anti-aliasing then renders it as a
   grey suggestion of a stroke rather than a stroke, so the letterform breaks up
   — worst on a standard-DPI screen. Weight is the only lever the subset gives
   us, because it carries a wght axis (400-800) and no opsz axis.

   The italic used to be Bodoni's too, and weight could not save it. A Didone's
   italic thins are thinner again than the roman's, and at 800 they still
   aliased away; worse, the italic capital W ends on a hairline, so the hero's
   `We've` read as `We're` at headline size. Newsreader is the answer: a
   screen-first transitional whose italic has enough contrast to still look
   like the house, and no stroke thin enough to disappear. Its opsz axis is
   baked at 20 rather than shipped live, which costs 58 KB less and biases the
   whole range sturdy — one file serves 16px tile wordmarks and 40px numerals,
   and a text cut scaled up reads better than a display cut scaled down.
   --------------------------------------------------------------------------- */

@font-face {
  font-family: "Bodoni Moda";
  src: url("../fonts/bodoni-moda.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Newsreader";
  src: url("../fonts/newsreader-italic.woff2") format("woff2");
  font-weight: 600 800;
  font-style: italic;
  font-display: swap;
}

:root {
  color-scheme: light;

  --paper: #fefcf6;
  --stone: #f3eee3;         /* tinted bands */
  --rule: #dcd3c3;
  --ink: #131c29;           /* text, and the night band's ground */
  --ink-soft: #4b5666;      /* secondary text; 7.2:1 on paper */
  --night: #131c29;
  --night-deep: #0c131d;
  --on-night: #f3efe6;
  --on-night-soft: #b9b1a3;

  --accent: var(--ink);     /* a pack sets this on <main>; the house has none */
  --on-accent: var(--paper);

  --display: "Bodoni Moda", "Bodoni 72", Didot, "Playfair Display", Georgia, serif;
  --display-italic: "Newsreader", "Iowan Old Style", Georgia, serif;
  --serif: Georgia, "Iowan Old Style", "Palatino Linotype", "Times New Roman",
           "Noto Serif", serif;
  /* Letterspaced caps are the house's one label style, and there is exactly
     one recipe for it: every eyebrow, nav link, footer line and spec line on
     the site is this size at this tracking. Six near-identical recipes read
     as sloppiness rather than as a system, which is what they were. */
  --caps-size: 0.72rem;
  --caps-track: 0.18em;

  --measure: 34rem;
  --wide: 62rem;
  --gutter: 1.25rem;
  --tap: 44px;              /* nothing tappable is ever smaller */
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 17px/1.6 var(--serif);
  overflow-wrap: break-word;
  font-variant-numeric: lining-nums;
}
body.has-buybar { padding-bottom: 5rem; }

h1, h2, h3 { margin: 0 0 0.6em; line-height: 1.12; }
h1, h2 { font-family: var(--display); font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: 2.2rem; }
h2 { font-size: 1.7rem; }
h3 { font-size: 1.15rem; font-weight: 700; }
p { margin: 0 0 1em; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
img { max-width: 100%; height: auto; }
strong { font-weight: 700; }
em { font-style: italic; }
::selection { background: var(--accent); color: var(--on-accent); }

:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

.small { font-size: 0.9rem; color: var(--ink-soft); }
.standfirst { font-size: 1.15rem; color: var(--ink-soft); }

/* Letterspaced caps with a trailing hairline: the one device the whole range
   shares, on the covers and on the site. Everything that speaks in caps takes
   `.caps` and changes only its colour and its box -- never its size or its
   tracking. */
.caps, .eyebrow, .site-header__link, .site-footer__line,
.lightbox__close, .tile__eyebrow {
  font-weight: 700;
  font-size: var(--caps-size);
  letter-spacing: var(--caps-track);
  text-transform: uppercase;
}
.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin: 0 0 1rem;
  color: var(--accent);
  font-family: var(--serif);
  line-height: 1;
}
.eyebrow::after { content: ""; flex: 1; height: 1px; background: var(--rule); }

.wordmark {
  font: italic 600 1.25rem/1 var(--display-italic);
  letter-spacing: 0.01em;
  text-decoration: none;
}

/* Pages owned by other blueprints (/thanks, /checkout/cancelled, /download/…)
   use a bare <main>. Give it a readable default; the storefront opts out. */
main {
  max-width: 40rem;
  margin: 0 auto;
  padding: 2rem var(--gutter) 3rem;
}
main.storefront, main.product { max-width: none; padding: 0; overflow-x: clip; }

/* --- header and footer --------------------------------------------------- */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.25rem var(--gutter) 0;
  min-height: var(--tap);
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
}
.site-header__brand, .site-header__link {
  display: flex;
  align-items: center;
  min-height: var(--tap);
  color: var(--ink);
  text-decoration: none;
}
.site-header__link {
  color: var(--ink-soft);
}

.site-footer {
  background: var(--night);
  color: var(--on-night-soft);
  padding: 3rem var(--gutter) 3.5rem;
  text-align: center;
}
.site-footer__brand { margin: 0; color: var(--on-night); font-size: 1.7rem; }
.site-footer__line {
  margin: 0.5rem 0 1.6rem;
}
.site-footer__nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.25rem 1.25rem;
}
.site-footer__nav a, .site-footer__contact {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  color: var(--on-night-soft);
  font-size: 0.95rem;
}
.site-footer__contact { margin: 0.5rem 0 0; justify-content: center; width: 100%; }

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

.hero { padding: 1.5rem var(--gutter) 2rem; }
.hero__copy { max-width: var(--measure); margin: 0 auto; }
.hero__headline {
  font-size: clamp(2.3rem, 10.4vw, 3.4rem);
  margin-bottom: 1rem;
}
.hero__headline--product {
  font-size: clamp(1.75rem, 7.6vw, 2.5rem);
  font-weight: 700;
  margin-bottom: 0.4rem;
}

/* One column on a phone: title, cover, subtitle, extent. The cover used to sit
   beside the words to save height, and it cost more than it saved -- the title,
   the subtitle and the extent line all shared a 201px second column, which is
   four words to a line and a two-line title, and it is most of what made this
   page feel cramped. Every line is at the full measure now and the cover is
   half again as wide, which is what a page whose job is the product should
   spend its space on.

   The height it costs is real but affordable: the button lands at 639px and
   "No printer? Still works tonight." at 756px, so an 812px phone gets the
   whole hero and a 667px one gets the button. The cover width is the dial --
   62% pushes the button past an SE's fold, 44% wastes the room -- and the
   source order is title-last inside .hero__title, so the reordering is grid
   rows on contents rather than markup. */
.hero__lead {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  margin-bottom: 1.4rem;
}
.hero__title { display: contents; }
.hero__headline--product { grid-row: 1; }
.hero__lead .hero__art { grid-row: 2; width: 54%; margin: 0.5rem 0 1.1rem; }
.hero__lead .hero__subhead { grid-row: 3; }
.hero__lead .hero__meta { grid-row: 4; margin-top: 0.6rem; }
.hero__art { position: relative; z-index: 0; display: block; }
.hero__lead .hero__subhead { margin: 0; }
.hero__subhead { color: var(--ink-soft); font-size: 1.05rem; }
.hero__meta { margin: 0.5rem 0 0; color: var(--ink-soft); font-size: 0.92rem; }
.hero__title .hero__subhead { margin-bottom: 0; }
.hero__price {
  font: 600 2rem/1 var(--display);
  margin: 0 0 0.9rem;
  color: var(--ink);
}
.hero__printer {
  margin: 1.1rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule);
  font-size: 1.1rem;
}

/* The cover as a stack of sheets. */
.stack { position: relative; display: block; }
.stack::before, .stack::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--paper);
  border: 1px solid var(--rule);
}
.stack::before { transform: rotate(-3deg) translate(-3px, 4px); }
.stack::after { transform: rotate(2deg) translate(4px, -2px); }
.stack .cover {
  display: block;
  width: 100%;
  border: 1px solid rgba(19, 28, 41, 0.12);
  box-shadow: 0 14px 34px rgba(19, 28, 41, 0.24), 0 1px 2px rgba(19, 28, 41, 0.12);
}

/* --- the front door ------------------------------------------------------ */

/* The house speaks in ink: the eyebrow and the headline take no accent. The
   lead pack under them arrives in its own colour. */
.hero--front { padding: 1.75rem var(--gutter) 2.5rem; }
.hero--front .hero__copy { --accent: var(--ink); margin-bottom: 1.4rem; }
/* The three names do not fit a phone line, and every way of wrapping them is
   worse than the last: broken mid-name it invents a line called "Brilliant
   Child", and kept whole it is three lines of eleven-pixel caps stacked above
   the headline -- a taxonomy in a whisper, in front of a parent who has ten
   minutes. "What we make" says the same three names a screen below, each with
   its positioning line, which is where a range is actually explained. So the
   phone does without it and the desk, where it fits one line, keeps it. */
.hero--front .hero__copy .eyebrow { display: none; }
.eyebrow__name { white-space: nowrap; }
/* The copy is three sentences and is written as three lines. At 7.9vw the
   first two each wrapped, so the phone got a five-line block of Didone that
   read as a wall and pushed the buy button a screen and a half down. Sized by
   vw rather than by rem so that the fit travels: the sentence and the column
   it sits in both scale with the viewport, and 5.85vw clears the longer of
   the two sentences with about 7% to spare at 360px. */
.hero--front .hero__headline {
  font-size: clamp(1.3rem, 5.85vw, 2.75rem);
  font-weight: 700;
  line-height: 1.24;
  letter-spacing: -0.01em;
  margin: 0 0 1.2rem;
}
/* Insurance for a narrower phone or a longer headline: if a sentence does
   wrap, it wraps into two balanced lines rather than one long and one short. */
.hero__line { display: block; text-wrap: balance; }
/* The turn is the one line in the display italic, so it names the face. */
.hero__line--turn {
  font-family: var(--display-italic);
  font-style: italic;
  font-weight: 700;
  margin-top: 0.12em;
}
/* docs/copy/landing.md ranks order above everything on this page -- headline,
   price, buy button, then "no printer" -- and names the subhead as the thing
   to cut if the button will not clear the fold. On a phone it did not: five
   more lines of body copy put the button at about 990px on an 812px screen.
   It stays in the markup, and comes back the moment there is a column for it. */
.hero--front .hero__subhead { display: none; }
@media (min-width: 40rem) {
  .hero--front .hero__subhead {
    display: block;
    font-size: 1.08rem;
    margin: 0;
    max-width: 30rem;
  }
}

/* The object: the cover in front, real pages fanned behind. Each sheet has a
   resting angle in --r and settles into it on load. */
.fan {
  position: relative;
  isolation: isolate;
  aspect-ratio: 4 / 3;
  max-width: var(--measure);
  margin: 0 auto 1.75rem;
}
/* A faint pool of shade under the sheets, so they sit on the paper rather
   than float over it. */
.fan::before {
  content: "";
  position: absolute;
  inset: 12% -8% -14%;
  z-index: -1;
  background: radial-gradient(closest-side, rgba(19, 28, 41, 0.07), transparent 72%);
}
.fan__page, .fan__cover {
  position: absolute;
  display: block;
  transform: rotate(var(--r, 0deg));
  animation: settle 720ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.fan__image {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid rgba(19, 28, 41, 0.14);
}
.fan__page { width: 42%; box-shadow: 0 14px 30px -14px rgba(19, 28, 41, 0.5); }
.fan__page--1 { --r: -9deg; left: 4%; top: 9%; animation-delay: 80ms; }
.fan__page--2 { --r: 8deg; right: 4%; top: 7%; animation-delay: 160ms; }
.fan__page--3 { --r: -2deg; left: 31%; top: -1%; width: 38%; animation-delay: 0ms; }
.fan__cover {
  --r: 1.5deg;
  left: 26%;
  top: 5%;
  width: 48%;
  box-shadow: 0 28px 50px -18px rgba(19, 28, 41, 0.55), 0 2px 6px rgba(19, 28, 41, 0.12);
  animation-delay: 240ms;
}
@keyframes settle {
  from { opacity: 0; transform: translateY(18px) rotate(0deg); }
  to { opacity: 1; transform: translateY(0) rotate(var(--r, 0deg)); }
}
@media (prefers-reduced-motion: reduce) {
  .fan__page, .fan__cover { animation: none; }
}

/* The lead pack: a card in the pack's colour under the house's words. */
.lead {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 1.5rem 1.35rem 1.6rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-top: 3px solid var(--accent);
  box-shadow: 0 22px 44px -30px rgba(19, 28, 41, 0.45);
}
.lead .eyebrow { margin-bottom: 0.6rem; }
.lead__title { font: 600 1.4rem/1.15 var(--display); letter-spacing: -0.01em; margin: 0 0 0.4rem; }
.lead__title a { color: var(--ink); text-decoration: none; }
.lead__subtitle { color: var(--ink-soft); margin: 0 0 0.7rem; }
/* Price, extent, delivery. The copy calls this the second most important
   thing on the page after the headline, so it is set to be read rather than
   as an eleven-pixel letterspaced whisper that wrapped onto two lines. */
.lead__meta { margin: 0 0 1.1rem; color: var(--ink-soft); font-size: 0.95rem; }
.lead .hero__printer { margin-top: 1rem; }

/* --- buy button ---------------------------------------------------------- */

.buy { margin: 0; }
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 0.7rem 1.4rem;
  border: 1px solid var(--accent);
  border-radius: 3px;
  background: var(--accent);
  color: var(--on-accent);
  font: 700 1.05rem/1.2 var(--serif);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: transform 120ms ease, box-shadow 120ms ease;
}
.button:active { transform: translateY(1px); }
.button--buy { width: 100%; font-size: 1.15rem; box-shadow: 0 8px 22px -10px var(--accent); }
.button[disabled] { background: var(--ink-soft); border-color: var(--ink-soft); cursor: not-allowed; box-shadow: none; }
.button--quiet, .button--tile {
  background: transparent;
  color: var(--accent);
  min-height: var(--tap);
  font-size: 1rem;
  box-shadow: none;
}
.button--notify { width: 100%; min-height: var(--tap); font-size: 1rem; }
.buy__helper { margin: 0.6rem 0 0; font-size: 0.9rem; color: var(--ink-soft); }
.buy__consent { margin: 0 0 0.9rem; font-size: 0.95rem; }
.buy__consent label { display: flex; gap: 0.6rem; align-items: flex-start; }
.buy__consent input { width: 22px; height: 22px; margin-top: 0.2rem; flex: none; accent-color: var(--accent); }
.buy__consent-note { display: block; margin-top: 0.4rem; font-size: 0.85rem; opacity: 0.85; }

.notice {
  margin: 0 0 1rem;
  padding: 0.75rem 1rem;
  border-left: 3px solid var(--accent);
  background: var(--stone);
  font-size: 0.95rem;
}

/* --- the sticky bar ------------------------------------------------------ */

.buybar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 20;
  padding: 0.6rem var(--gutter) calc(0.6rem + env(safe-area-inset-bottom));
  background: rgba(254, 252, 246, 0.94);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--rule);
  animation: buybar-rise 220ms ease-out;
}
.buybar[hidden] { display: none; }
.buybar__inner {
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: var(--wide);
  margin: 0 auto;
}
.buybar__title {
  flex: 1;
  min-width: 0;
  margin: 0;
  font: italic 600 1.1rem/1.2 var(--display-italic);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.buybar__price { display: block; font: 700 0.9rem/1.3 var(--serif); color: var(--ink-soft); }
.buybar form { margin: 0; }
.button--bar { flex: none; min-height: var(--tap); padding: 0.5rem 1.2rem; font-size: 1rem; }
@keyframes buybar-rise { from { transform: translateY(100%); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .buybar { animation: none; } }

/* --- sections ------------------------------------------------------------ */

/* One column, centred, capped at a readable measure. A grid rather than auto
   margins on each child: `.steps { margin: 0 }` would otherwise un-centre the
   very lists it tidies up. */
.section {
  display: grid;
  justify-items: center;
  padding: 2.75rem var(--gutter);
}
.section > * { width: 100%; max-width: var(--measure); }
.section--tinted { background: var(--stone); }
.section--close { background: var(--stone); text-align: center; }
.section--close .buy { max-width: var(--measure); margin: 0 auto; }
.section--quiet { text-align: center; }
.section__close {
  margin-top: 1.2rem;
  font-style: italic;
  color: var(--ink-soft);
}
.section--intro { padding-bottom: 0.5rem; }
.section--prose h3 { margin-top: 1.6rem; font-family: var(--display); font-weight: 600; font-size: 1.3rem; }

/* A short rule in the accent under every heading: the house's device. */
.section h2::after {
  content: "";
  display: block;
  width: 2.5rem;
  height: 2px;
  margin: 0.8rem 0 1.2rem;
  background: var(--accent);
}
.section--close h2::after, .section--quiet h2::after { margin-left: auto; margin-right: auto; }

/* The night band. Reversing the page for one block is the rhythm of the whole
   site -- paper, night, paper -- and inside it the accent is the paper, so a
   pack's red never has to fight a navy ground. */
.band--night {
  --accent: var(--on-night);
  --on-accent: var(--night);
  --rule: rgba(243, 239, 230, 0.2);
  --ink-soft: var(--on-night-soft);
  background: var(--night);
  color: var(--on-night);
}
.band--night h2 { color: var(--on-night); }

/* --- numbered steps ------------------------------------------------------ */

.steps { margin: 0; padding: 0; list-style: none; counter-reset: step; }
.steps li {
  position: relative;
  counter-increment: step;
  padding: 0.2rem 0 1.15rem 3.1rem;
}
.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: -0.45rem;
  font: italic 600 2.5rem/1 var(--display-italic);
  color: var(--accent);
  font-variant-numeric: lining-nums;
}

/* --- three ways to run it: a swipe on a phone, a row on a desk ----------- */

.section--ways { padding-right: 0; }
.section--ways > h2, .section--ways > .section__close { padding-right: var(--gutter); }
.cards {
  display: flex;
  gap: 0.9rem;
  max-width: none;
  padding: 0.25rem var(--gutter) 0.75rem 0;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.cards::-webkit-scrollbar { display: none; }
.card {
  flex: 0 0 auto;
  width: 76vw;
  max-width: 20rem;
  scroll-snap-align: start;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-top: 3px solid var(--accent);
  padding: 1.1rem 1.1rem 0.5rem;
}
.card h3 { font: italic 600 1.35rem/1.15 var(--display-italic); color: var(--ink); }

/* --- what's inside ------------------------------------------------------- */

.inside { margin: 0; }
.inside dt { font-weight: 700; margin-top: 1.2rem; }
.inside dt:first-child { margin-top: 0; }
.inside dd { margin: 0.3rem 0 0; color: var(--ink-soft); }

.contact-sheet { margin: 2rem 0 0; text-align: center; }
.contact-sheet img { border: 1px solid var(--rule); }
.contact-sheet figcaption { margin-top: 0.7rem; }

/* --- gallery: a swipe, not a click-through ------------------------------- */

.section--gallery { padding-right: 0; }
.section--gallery > .small, .section--gallery > h2 { padding-right: var(--gutter); }
.gallery {
  display: flex;
  gap: 1rem;
  margin: 1.2rem 0 0;
  padding: 0 var(--gutter) 1rem 0;
  max-width: none;
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.gallery__item { flex: 0 0 auto; width: 68vw; max-width: 260px; scroll-snap-align: start; }
.gallery__link { display: block; color: var(--ink); text-decoration: none; }
.gallery__image {
  width: 100%;
  height: auto;
  border: 1px solid var(--rule);
  background: #fff;
  box-shadow: 0 10px 24px -14px rgba(19, 28, 41, 0.5);
}
.gallery__caption {
  display: block;
  padding: 0.6rem 0;
  min-height: var(--tap);
  font-size: 0.9rem;
  color: var(--ink-soft);
}
.section--gallery .contact-sheet { padding-right: var(--gutter); }

.lightbox {
  width: 100%;
  max-width: 100vw;
  max-height: 100vh;
  border: 0;
  padding: 0;
  background: var(--night-deep);
}
.lightbox::backdrop { background: rgba(12, 19, 29, 0.9); }
.lightbox img { display: block; margin: 0 auto; max-height: 88vh; width: auto; }
.lightbox__close {
  display: block;
  min-height: var(--tap);
  margin-left: auto;
  padding: 0 var(--gutter);
  border: 0;
  background: transparent;
  color: var(--on-night);
  font-family: var(--serif);
  line-height: 1;
  cursor: pointer;
}

/* --- FAQ ----------------------------------------------------------------- */

.faq details { border-top: 1px solid var(--rule); }
.faq details:last-child { border-bottom: 1px solid var(--rule); }
.faq summary {
  display: flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0.8rem 2rem 0.8rem 0;
  font-weight: 700;
  cursor: pointer;
  list-style: none;
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  position: absolute;
  right: 0.25rem;
  color: var(--accent);
  font: 400 1.5rem/1 var(--display);
}
.faq details[open] summary::after { content: "–"; }
.faq p { color: var(--ink-soft); }

.refund-line { margin-top: 1.5rem; font-size: 0.95rem; }

/* --- the range: lines and tiles ------------------------------------------ */

.section--line { padding-top: 2rem; }
.line__positioning { color: var(--ink-soft); margin: -0.6rem 0 0.2rem; }
.line__when { margin: 0 0 1.2rem; color: var(--ink-soft); font-size: 0.92rem; }

/* The shelf on the front door: each line a swipeable row of tiles. */
.section--shelf { padding-right: 0; }
.section--shelf > h2, .section--shelf > .standfirst { padding-right: var(--gutter); }
.section--shelf .line { max-width: none; min-width: 0; margin-top: 1.5rem; }
.section--shelf .line > p, .section--shelf .line > h3 { padding-right: var(--gutter); }
.section--shelf .line:first-of-type { margin-top: 0.5rem; }
.line__title { font: italic 600 1.5rem/1.1 var(--display-italic); margin-bottom: 0.4rem; }
.shelf {
  display: flex;
  gap: 0.9rem;
  margin: 0;
  padding: 0.25rem var(--gutter) 0.5rem 0;
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.shelf::-webkit-scrollbar { display: none; }
.tile--shelf { flex: 0 0 auto; width: 36vw; max-width: 10.5rem; scroll-snap-align: start; }
.tile--shelf .tile__art { display: block; margin-bottom: 0.5rem; }
.tile--shelf .tile__title { margin: 0; font-size: 0.95rem; font-weight: 700; line-height: 1.25; }
.tile--shelf .tile__meta { margin: 0.15rem 0 0; font-size: 0.85rem; }
.tile--shelf.tile--soon .tile__title { color: var(--ink-soft); }

/* The catalogue tiles. */
.tiles { display: grid; gap: 1.25rem; padding: 0; list-style: none; }
.tiles .tile {
  display: grid;
  grid-template-columns: 118px 1fr;
  grid-template-areas: "art body" "form form";
  gap: 0.8rem 1rem;
  align-items: start;
  border-top: 1px solid var(--rule);
  padding-top: 1.25rem;
}
.tile__art { grid-area: art; display: block; }
.tile__body { grid-area: body; min-width: 0; }
/* The capture form gets the full width of the tile: a button that wraps to two
   lines in a 220px column is the one thing on this page anyone is asked to do. */
.tile__form { grid-area: form; }
.tile__image { width: 100%; height: auto; border: 1px solid var(--rule); box-shadow: 0 8px 20px -12px rgba(19, 28, 41, 0.5); }
.tile__art--type {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.5rem;
  aspect-ratio: 400 / 565;
  padding: 0.75rem 0.6rem;
  background: var(--accent);
  color: var(--paper);
  text-align: center;
}
.tile__eyebrow { --caps-size: 0.58rem; opacity: 0.8; }
.tile__wordmark { font: italic 600 1rem/1.15 var(--display-italic); }
.tiles .tile__title { margin-bottom: 0.2rem; }
.tile__title a { color: var(--ink); text-decoration: none; }
.tile__meta { color: var(--ink-soft); font-size: 0.92rem; margin-bottom: 0.7rem; }
.tile__thanks { color: var(--accent); font-size: 0.95rem; }

.notify__summary {
  display: flex;
  align-items: center;
  min-height: var(--tap);
  color: var(--accent);
  cursor: pointer;
  list-style: none;
}
.notify__summary::-webkit-details-marker { display: none; }
.notify__summary::before { content: "▸ "; margin-right: 0.4rem; }
.notify[open] .notify__summary::before { content: "▾ "; }
.notify__form { padding-bottom: 0.5rem; }
.notify__label { position: absolute; left: -9999px; }
.notify__input {
  width: 100%;
  min-height: var(--tap);
  padding: 0.5rem 0.7rem;
  margin-bottom: 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 3px;
  background: #fff;
  color: var(--ink);
  font: 1rem var(--serif);
}
.notify__consent { margin: 0.6rem 0 0; font-size: 0.82rem; color: var(--ink-soft); }
.notify__error { color: var(--accent); font-size: 0.9rem; }
.notify__trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* --- long-form pages (legal, generated from docs/legal) ------------------ */

.page { max-width: var(--measure); }
.page--legal h1 { font-size: 1.9rem; }
.page__meta {
  color: var(--ink-soft);
  font-size: 0.9rem;
  font-style: italic;
  margin-bottom: 1.6rem;
}
.prose h2 { font-size: 1.35rem; margin-top: 2rem; }
.prose h3 { margin-top: 1.5rem; }
.prose ul, .prose ol { padding-left: 1.2rem; }
.prose li { margin-bottom: 0.5rem; }
.table-scroll { overflow-x: auto; margin: 0 0 1.5rem; }
.prose table { border-collapse: collapse; width: 100%; font-size: 0.92rem; }
.prose th, .prose td {
  border-bottom: 1px solid var(--rule);
  padding: 0.6rem 0.75rem 0.6rem 0;
  text-align: left;
  vertical-align: top;
}

/* --- wider screens: the layout falls out of the mobile one --------------- */

@media (min-width: 40rem) {
  body { font-size: 18px; }
  .hero { padding: 3.5rem 2rem 3.5rem; }
  /* The cover leaves the flow and sits to the right of the copy, vertically
     centred on it. Out of the flow, so that its height is never shared out
     between the copy rows: the title, price and button keep their spacing. */
  .hero__copy {
    position: relative;
    max-width: var(--wide);
    min-height: 27rem;
    padding-right: 21rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .hero__lead { display: contents; }
  .hero__title { display: block; }
  .hero__lead .hero__art, .hero__art {
    position: absolute;
    top: 50%;
    right: 0;
    width: 17rem;
    margin: 0;
    transform: translateY(-50%);
  }
  .hero__lead .hero__subhead { margin-bottom: 1.4rem; }
  .hero__title { margin-bottom: 0.6rem; }
  .hero__headline { font-size: clamp(3rem, 5.2vw, 4.2rem); }

  /* The front door: words and the lead card on the left, the fan on the right,
     the fan spanning both rows. It is shorter than the two together, so no
     row has to stretch to fit it. */
  .hero--front {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(18rem, 21rem);
    column-gap: 3rem;
    align-items: center;
    max-width: 72rem;
    margin: 0 auto;
    padding: 4rem 2rem 4.5rem;
  }
  .hero--front .hero__copy, .hero--front .lead {
    grid-column: 1;
    margin: 0;
    padding-right: 0;
    min-height: 0;
    display: block;
    position: static;
  }
  /* A wider column than the reading measure, and the type sized to it, so
     that each sentence of the headline holds its own line: Bodoni Moda at
     600 runs to about 0.6em a character. */
  .hero--front .hero__copy { max-width: 48rem; margin-bottom: 2rem; }
  .hero--front .lead { max-width: 36rem; }
  .lead__title { font-size: 1.7rem; }
  .hero--front .hero__headline { font-size: clamp(2.1rem, 3.3vw, 2.6rem); }
  .hero--front .hero__copy .eyebrow {
    display: flex;
    white-space: nowrap;
    margin-bottom: 1.1rem;
  }
  .hero--front .fan { grid-column: 2; grid-row: 1 / span 2; margin: 0; align-self: center; }
  .hero__headline--product { font-size: clamp(2.4rem, 4.2vw, 3.2rem); }
  .hero__printer { max-width: 30rem; }
  .stack::before { transform: rotate(-4deg) translate(-6px, 6px); }
  .stack::after { transform: rotate(2.5deg) translate(7px, -3px); }
  .section { padding: 3.5rem 2rem; }
  .section--ways { padding-right: 2rem; }
  .section--ways > h2, .section--ways > .section__close { padding-right: 0; }
  .cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    max-width: var(--wide);
    padding: 0;
    overflow: visible;
  }
  .card { width: auto; max-width: none; padding: 1.4rem 1.3rem 0.8rem; }
  .button--buy { width: auto; min-width: 20rem; }
  .gallery__item { width: 240px; }
  .section--shelf { padding-right: 2rem; }
  .section--shelf > h2, .section--shelf > .standfirst { padding-right: 0; }
  .section--shelf .line { padding-right: 0; max-width: var(--wide); }
  .shelf { flex-wrap: wrap; margin: 0; padding: 0.25rem 0 0.5rem; overflow: visible; }
  .tile--shelf { width: 9.5rem; }
  .tiles {
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    max-width: var(--wide);
  }
  .tiles .tile { grid-template-columns: 1fr; grid-template-areas: "art" "body" "form"; gap: 0.9rem; }
  .section--gallery .gallery { max-width: var(--wide); }
  .buybar { padding-left: 2rem; padding-right: 2rem; }
}

@media (min-width: 64rem) {
  .hero { padding: 5rem 2rem; }
  .hero__copy { padding-right: 25rem; min-height: 31rem; }
  .hero__lead .hero__art, .hero__art { width: 20rem; }
  .contact-sheet img { max-width: 34rem; }
}
