/* ─────────────────────────────────────────────────────────────
   studio — warm editorial
   Palette: cream paper, ink brown, terracotta + sage accents.
   Display: Fraunces (lowercase, tight). Body: Poppins.
   ───────────────────────────────────────────────────────────── */

:root {
  --paper:   #fdf7f2;
  --paper-2: #f8ebe8;
  --ink:     #2a1812;
  --ink-2:   #4d3329;
  --ink-3:   #6e5147;
  --muted:   #a98e82;
  --line:    #e7d3c9;
  --ember:   #d63b16;
  --ember-d: #8a2f15;
  --sage:    #627956;
  --white:   #fffdfb;

  --display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --sans:    "Poppins", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  --gut: clamp(24px, 5vw, 64px);
  --ease: cubic-bezier(.22, .61, .36, 1);
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  font-weight: 300;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}

h1, h2, p, ul, li { margin: 0; }
ul { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

:focus-visible { outline: 2px solid var(--ember); outline-offset: 4px; border-radius: 2px; }

/* ── Type ──────────────────────────────────────────────────── */

.micro {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}

.display {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-weight: 400;
  font-size: clamp(2.5rem, 6.2vw, 4.4rem);
  line-height: 1.02;
  letter-spacing: -0.022em;
  text-transform: lowercase;
  text-wrap: balance;
}
.display--sm { font-size: clamp(1.9rem, 4vw, 3rem); }

.lede {
  margin-top: 28px;
  max-width: 46ch;
  font-size: 17px;
  line-height: 1.66;
  color: var(--ink-3);
  text-wrap: pretty;
}
.lede--tight { margin-top: 18px; }
.lede strong { font-weight: 500; color: var(--ink); }

.foot {
  margin-top: 44px;
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--muted);
}

/* ── Chrome ────────────────────────────────────────────────── */

.wordmark {
  position: fixed;
  top: calc(var(--cdbar-h, 0px) + clamp(20px, 3vw, 34px));
  left: var(--gut);
  z-index: 20;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--display);
  font-size: 20px;
  letter-spacing: -0.01em;
  text-transform: lowercase;
}
.wordmark__mark {
  width: 26px;
  height: auto;
  display: block;
}
.wordmark__word { display: block; }

.cue {
  position: fixed;
  bottom: clamp(20px, 3vw, 32px);
  left: var(--gut);
  z-index: 20;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  letter-spacing: .06em;
  color: var(--muted);
  transition: color .2s var(--ease);
}
.cue:hover { color: var(--ink); }
.cue__arrow { display: inline-block; animation: nudge 2.4s var(--ease) infinite; }
@keyframes nudge {
  0%, 60%, 100% { transform: translateY(0); opacity: .55 }
  30%           { transform: translateY(3px); opacity: 1 }
}

/* ── Countdown bar ─────────────────────────────────────────── */

/* Sits above everything, including the fixed wordmark and menu, so the
   deadline is the first thing read on the page. */
.cdbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--ink);
  color: var(--paper);
  font-size: 12.5px;
}

.cdbar__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 6px 22px;
  padding: 9px var(--gut);
  min-height: 44px;
  transition: opacity .2s var(--ease);
}
.cdbar__inner:hover { opacity: .88; }

.cdbar__text {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 12px;
}
.cdbar__title { letter-spacing: .02em; }
.cdbar__sub {
  font-size: 11.5px;
  color: var(--muted);
}

.cdbar__timer {
  display: inline-flex;
  align-items: baseline;
  gap: 14px;
  font-variant-numeric: tabular-nums;
}
.cdbar__timer[hidden] { display: none; }
.cdbar__unit {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
}
.cdbar__num {
  font-family: var(--display);
  font-size: 17px;
  line-height: 1;
  letter-spacing: -0.01em;
}
.cdbar__legend {
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}

.cdbar__closed {
  font-style: italic;
  color: var(--paper-2);
}
.cdbar__closed[hidden] { display: none; }

/* Once the deadline passes the bar stops shouting: it stays, but muted. */
.cdbar.is-closed { background: var(--ink-2); }

@media (max-width: 620px) {
  .cdbar__sub { display: none; }
  .cdbar__timer { gap: 10px; }
}

/* ── Section menu ──────────────────────────────────────────── */
.menu {
  position: fixed;
  top: calc(var(--cdbar-h, 0px) + clamp(20px, 3vw, 34px));
  right: var(--gut);
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 4px 18px;
  max-width: 60vw;
  font-size: 12.5px;
  letter-spacing: .04em;
}
.menu a {
  color: var(--muted);
  text-transform: lowercase;
  padding: 4px 0;
  border-bottom: 1px solid transparent;
  transition: color .2s var(--ease), border-color .2s var(--ease);
}
.menu a:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* ── Panels ────────────────────────────────────────────────── */

.panel {
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding: clamp(88px, 12vh, 150px) var(--gut);
}
/* A fixed menu and countdown bar sit over the top of the page, so a section
   jump must stop clear of them or the heading lands underneath. */
.panel { scroll-margin-top: calc(var(--cdbar-h, 0px) + 76px); }
.panel__inner { width: 100%; max-width: 940px; margin-inline: auto; }
.panel__inner--wide { max-width: 1120px; }

.panel--work { background: var(--paper-2); }
.panel--archive { background: var(--paper-2); }
.panel--closing { background: var(--ink); color: var(--paper); }
.panel--closing .micro { color: var(--muted); }
.panel--closing .lede { color: #d9c8c1; }
.panel--closing .foot { color: var(--muted); }

/* ── Button ────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 40px;
  min-height: 48px;
  padding: 0 26px;
  border: 1px solid var(--ink);
  border-radius: 999px;
  font-size: 14px;
  letter-spacing: .01em;
  transition: background-color .22s var(--ease), color .22s var(--ease), border-color .22s var(--ease);
}
.btn:hover { background: var(--ink); color: var(--paper); }
.panel--closing .btn { border-color: var(--paper); }
.panel--closing .btn:hover { background: var(--paper); color: var(--ink); }

/* ── Tiles ─────────────────────────────────────────────────── */

.tiles {
  margin-top: clamp(36px, 5vw, 56px);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 20px);
}

.tile {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: 4px;
  overflow: hidden;
  /* Fallback gradient — shows until a photo loads, or if one is missing. */
  background:
    radial-gradient(120% 90% at 22% 18%, color-mix(in srgb, var(--a) 88%, white) 0%, transparent 58%),
    radial-gradient(110% 80% at 82% 84%, var(--b) 0%, transparent 62%),
    linear-gradient(158deg, var(--a) 0%, var(--b) 100%);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 14px;
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}

/* Uploaded photo fills the tile. Relative path = same folder as index.html. */
.tile__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  transition: transform .5s var(--ease);
}
.tile:hover .tile__img { transform: scale(1.04); }

/* If the file is missing the browser shows a broken icon — hide it and let
   the gradient stand in. Toggled by script.js on error. */
.tile__img.is-missing { display: none; }

.tile::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to top, rgba(42, 24, 18, .52), transparent 52%);
  opacity: 0;
  transition: opacity .3s var(--ease);
}
.tile:hover { transform: translateY(-4px); box-shadow: 0 18px 34px -22px rgba(42, 24, 18, .5); }
.tile:hover::after { opacity: 1; }

.tile__name, .tile__meta {
  position: relative;
  z-index: 2;
  color: var(--white);
  opacity: 0;
  transform: translateY(5px);
  transition: opacity .28s var(--ease), transform .28s var(--ease);
}
.tile__name {
  font-family: var(--display);
  font-size: 17px;
  letter-spacing: -0.01em;
  text-transform: lowercase;
  text-shadow: 0 1px 12px rgba(42, 24, 18, .55);
}
.tile__meta {
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  opacity: 0;
  margin-top: 3px;
  text-shadow: 0 1px 10px rgba(42, 24, 18, .55);
}
.tile:hover .tile__name { opacity: 1; transform: none; }
.tile:hover .tile__meta { opacity: .72; transform: none; }

/* ── Pairing ───────────────────────────────────────────────── */

.pairing {
  margin-top: clamp(32px, 4vw, 46px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}

.swatches { display: flex; flex-wrap: wrap; gap: 10px; }

.swatch {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 15px 7px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  font-size: 13px;
  letter-spacing: .01em;
  transition: border-color .2s var(--ease), transform .2s var(--ease);
}
.swatch:hover { border-color: var(--muted); transform: translateY(-1px); }
.swatch.is-on { border-color: var(--ink); }

.swatch__chip {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 1px solid rgba(42, 24, 18, .12);
  background: var(--c);
  box-shadow: inset -4px -4px 0 0 var(--t);
}
.swatch__label { text-transform: lowercase; }

.pairing__side { display: flex; flex-wrap: wrap; gap: 10px; }

.swap {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 15px;
  border: 1px dashed var(--line);
  border-radius: 999px;
  font-size: 12.5px;
  color: var(--ink-3);
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.swap:hover { border-color: var(--ink); color: var(--ink); }

/* ── Preview ───────────────────────────────────────────────── */

.preview { margin-top: clamp(34px, 4.5vw, 54px); }

.preview__card {
  position: relative;
  background: var(--bg);
  color: var(--fg);
  border-radius: 8px;
  padding: clamp(30px, 5vw, 62px);
  min-height: clamp(220px, 32vh, 320px);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  box-shadow: 0 26px 60px -34px rgba(42, 24, 18, .5);
  transition: background-color .45s var(--ease), color .45s var(--ease);
}

.preview__micro {
  font-size: 10px;
  letter-spacing: .2em;
  text-transform: uppercase;
  opacity: .6;
}

.preview__line {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.6rem, 4.2vw, 2.9rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  text-transform: lowercase;
  text-wrap: balance;
  max-width: 22ch;
  transition: opacity .3s var(--ease);
}
.preview__line.is-swapping { opacity: 0; }

.preview__mark {
  width: 34px; height: 1px;
  background: currentColor;
  opacity: .35;
}

.preview__caption {
  margin-top: 14px;
  font-size: 12px;
  letter-spacing: .05em;
  color: var(--muted);
  text-transform: lowercase;
}

/* ── Portfolio series (collapsible) ────────────────────────── */

.series-nav {
  margin-top: 30px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
}

.series-nav a {
  display: inline-block;
  padding: 7px 15px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 13px;
  letter-spacing: .01em;
  color: var(--ink-2);
  text-transform: lowercase;
  transition: border-color .2s var(--ease), color .2s var(--ease), background-color .2s var(--ease);
}
.series-nav a:hover {
  border-color: var(--ink);
  color: var(--paper);
  background: var(--ink);
}

.series-list { margin-top: clamp(28px, 3.6vw, 42px); }

.series { border-top: 1px solid var(--line); scroll-margin-top: 80px; }
.series:last-child { border-bottom: 1px solid var(--line); }

/* Collapsed bar — the whole row is the toggle. */
.series__bar {
  display: flex;
  align-items: center;
  gap: clamp(16px, 3vw, 32px);
  width: 100%;
  padding: clamp(16px, 2.2vw, 24px) 0;
  text-align: left;
  transition: padding-left .3s var(--ease);
}
.series__bar:hover { padding-left: 8px; }
.series__bar:focus-visible { outline: 2px solid var(--ember); outline-offset: 3px; }

.series__info { flex: 1 1 auto; min-width: 0; }

.series__title {
  display: block;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.3rem, 2.3vw, 1.65rem);
  letter-spacing: -0.012em;
  text-transform: lowercase;
}

.series__note {
  display: block;
  margin-top: 4px;
  font-size: 13.5px;
  color: var(--ink-3);
  text-wrap: pretty;
}

/* Thumbnail strip — a preview of what's inside. */
.series__thumbs {
  flex: 0 0 auto;
  display: flex;
  gap: 6px;
}
.series__thumb {
  width: 46px;
  height: 58px;
  object-fit: cover;
  border-radius: 3px;
  background: var(--line);
  /* No file yet → the img is hidden by script.js and the box reads as a
     muted slot rather than a broken icon. */
}
.series__thumb.is-missing {
  display: block;
  background: linear-gradient(158deg, var(--line) 0%, var(--muted) 100%);
}

.series__meta {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 14px;
}

.series__count {
  font-size: 12px;
  letter-spacing: .06em;
  color: var(--muted);
  text-transform: lowercase;
  white-space: nowrap;
}

.series__chev {
  width: 10px; height: 10px;
  border: solid var(--ink);
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
  transition: transform .3s var(--ease);
  margin-top: -4px;
}
.series__bar[aria-expanded="true"] .series__chev {
  transform: rotate(-135deg);
  margin-top: 4px;
}

/* Expanded body */
.series__body { padding-bottom: clamp(28px, 4vw, 48px); }
.series__body[hidden] { display: none; }

/* ── Portfolio (works) ─────────────────────────────────────── */

.works {
  margin-top: clamp(36px, 5vw, 56px);
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 2.6vw, 34px);
}

.work__frame {
  margin: 0;
  aspect-ratio: 4 / 5;
  border-radius: 4px;
  overflow: hidden;
  background: var(--paper);
  box-shadow: 0 20px 44px -30px rgba(42, 24, 18, .55);
}

/* Placeholder gradient behind each work — shows until its photo loads,
   so an un-filled slot still reads as a colour study. */
.work__frame {
  background:
    radial-gradient(120% 90% at 22% 18%, color-mix(in srgb, var(--a, #e7d3c9) 88%, white) 0%, transparent 58%),
    radial-gradient(110% 80% at 82% 84%, var(--b, #a98e82) 0%, transparent 62%),
    linear-gradient(158deg, var(--a, #e7d3c9) 0%, var(--b, #a98e82) 100%);
}
.work__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .6s var(--ease);
}
.work__img.is-missing { display: none; }
.work:hover .work__img { transform: scale(1.03); }

.work__meta { padding-top: 16px; }
.work__title {
  font-family: var(--display);
  font-weight: 400;
  font-size: 21px;
  letter-spacing: -0.012em;
  text-transform: lowercase;
}
.work__detail {
  margin-top: 5px;
  font-size: 13px;
  color: var(--ink-3);
}
.work__price {
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13.5px;
  color: var(--ink);
}
.work__tag {
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sage);
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 2px 9px;
}

/* ── Mail club ─────────────────────────────────────────────── */

.panel--club {
  background: var(--paper-2);
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

/* Faint butterfly drifting behind the club copy. */
.club-decor {
  position: absolute;
  top: 50%;
  right: -6%;
  width: min(760px, 62vw);
  transform: translateY(-50%) rotate(-8deg);
  opacity: .07;
  pointer-events: none;
  z-index: -1;
}
.club-decor img {
  display: block;
  width: 100%;
  height: auto;
}

/* The closing note under the club copy — the "stay as long as it works" line,
   set smaller and apart so it reads as a footnote to the offer. */
.club__why-note {
  margin-top: 14px;
  max-width: 52ch;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--muted);
}

/* ── The archive ───────────────────────────────────────────── */

.archive__note {
  margin-top: 20px;
  max-width: 54ch;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--muted);
}
.archive__foot {
  margin-top: clamp(28px, 3.4vw, 40px);
  font-size: 12.5px;
  letter-spacing: .03em;
  color: var(--muted);
}
/* Three past editions read better as a wider row than the 4-up default. */
.panel--archive .tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); }

@media (max-width: 720px) {
  .panel--archive .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Handwritten club lockup, straight from the artist's ink. */
.club-mark {
  display: block;
  width: min(340px, 72vw);
  height: auto;
  margin: 18px 0 4px;
}

/* Butterfly illustration standing in for the club headline. */
.club-art {
  margin: 8px 0 0;
  line-height: 0;
}
.club-art img {
  display: block;
  width: min(320px, 68vw);
  height: auto;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Shipping included per plan. */
.plan__ship {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line-soft);
  display: grid;
  gap: 5px;
  font-size: 12.5px;
  color: var(--ink-3);
}
.plan__ship li {
  display: grid;
  grid-template-columns: 12px 1fr;
  gap: 8px;
}
.plan__ship li::before {
  content: "";
  width: 5px; height: 5px;
  margin-top: 7px;
  border-radius: 50%;
  background: var(--sage);
  opacity: .7;
}

/* ── Shipping options ──────────────────────────────────────── */

.ship { margin-top: clamp(26px, 3.4vw, 38px); }

.ship__title {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}

.ship__opts {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.ship__opt {
  flex: 1 1 210px;
  text-align: left;
  padding: 13px 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.ship__opt:hover { border-color: var(--ink); }
.ship__opt[aria-pressed="true"] {
  border-color: var(--ink);
  background: var(--paper);
  box-shadow: inset 0 0 0 1px var(--ink);
}

.ship__name {
  display: block;
  font-size: 14px;
  font-weight: 500;
}
.ship__note {
  display: block;
  margin-top: 3px;
  font-size: 12.5px;
  color: var(--ink-3);
}

.ship__hint {
  margin-top: 12px;
  font-size: 12.5px;
  color: var(--muted);
  text-wrap: pretty;
}

.plans {
  margin-top: clamp(32px, 4vw, 44px);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  max-width: 660px;
}

.plan {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  padding: 22px 24px;
}
.plan--lead { border-color: var(--ink); }

.plan__flag {
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ember);
  margin-bottom: 10px;
}
.plan:not(.plan--lead) .plan__flag { display: none; }

.plan__name {
  font-family: var(--display);
  font-size: 18px;
  text-transform: lowercase;
  letter-spacing: -0.01em;
}
.plan__price {
  margin-top: 10px;
  font-family: var(--display);
  font-size: 30px;
  letter-spacing: -0.02em;
  line-height: 1;
}
.plan__price span {
  font-family: var(--sans);
  font-size: 13px;
  color: var(--muted);
  margin-left: 6px;
}
.plan__note {
  margin-top: 12px;
  font-size: 13.5px;
  color: var(--ink-3);
  text-wrap: pretty;
}

/* ── Signup form ───────────────────────────────────────────── */

.signup { margin-top: clamp(34px, 4.5vw, 48px); max-width: 560px; }

.signup__label {
  display: block;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}

.signup__row { display: flex; flex-wrap: wrap; gap: 10px; }

.signup__input {
  flex: 1 1 260px;
  min-width: 0;
  min-height: 48px;
  padding: 0 16px;
  font: inherit;
  font-size: 15px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 999px;
  transition: border-color .2s var(--ease);
}
.signup__input::placeholder { color: var(--muted); }
.signup__input:focus { outline: none; border-color: var(--ink); }
.signup__input[aria-invalid="true"] { border-color: var(--ember); }

.signup__btn {
  min-height: 48px;
  padding: 0 26px;
  font-size: 14px;
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  transition: background-color .22s var(--ease), color .22s var(--ease);
}
.signup__btn:hover { background: var(--ember); border-color: var(--ember); color: var(--white); }

.signup__note {
  margin-top: 12px;
  font-size: 12.5px;
  color: var(--muted);
}
.signup__note.is-ok { color: var(--sage); }
.signup__note.is-err { color: var(--ember-d); }

/* ── Selectable mosaic tiles ───────────────────────────────── */

.tiles--pick { list-style: none; }
.tiles--pick li { display: flex; }

/* The tile is a <button>: reset the UA styles, keep the tile look. */
button.tile {
  width: 100%;
  font: inherit;
  text-align: left;
  cursor: pointer;
  border: 0;
  padding: 14px;
}
button.tile:focus-visible { outline: 2px solid var(--ember); outline-offset: 3px; }

.tile__price {
  position: absolute;
  top: 12px; left: 12px;
  z-index: 2;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(253, 247, 242, .92);
  color: var(--ink);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .04em;
  transition: background-color .25s var(--ease), color .25s var(--ease);
}

/* Selection check, top-right. */
.tile__check {
  position: absolute;
  top: 12px; right: 12px;
  z-index: 2;
  width: 24px; height: 24px;
  border-radius: 50%;
  border: 1.5px solid rgba(253, 247, 242, .85);
  background: rgba(42, 24, 18, .28);
  opacity: 0;
  transform: scale(.8);
  transition: opacity .25s var(--ease), transform .25s var(--ease), background-color .25s var(--ease);
}
.tile__check::after {
  content: "";
  position: absolute;
  left: 8px; top: 4px;
  width: 5px; height: 10px;
  border: solid var(--ink);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

button.tile:hover .tile__check { opacity: .55; transform: none; }

button.tile[aria-pressed="true"] {
  box-shadow: 0 0 0 2px var(--ink), 0 18px 34px -22px rgba(42, 24, 18, .5);
}
button.tile[aria-pressed="true"] .tile__check {
  opacity: 1;
  transform: none;
  background: var(--paper);
  border-color: var(--paper);
}
button.tile[aria-pressed="true"] .tile__price {
  background: var(--ink);
  color: var(--paper);
}
button.tile[aria-pressed="true"] .tile__name,
button.tile[aria-pressed="true"] .tile__meta { opacity: 1; transform: none; }
button.tile[aria-pressed="true"]::after { opacity: 1; }

/* ── Choose-one bar ────────────────────────────────────────── */

.pick {
  margin-top: clamp(28px, 3.6vw, 40px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 20px 22px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper);
}
.pick.is-chosen { border-color: var(--ink); }

.pick__info { min-width: 0; }

.pick__line {
  font-family: var(--display);
  font-size: 19px;
  letter-spacing: -0.01em;
  text-transform: lowercase;
}

.pick__gift {
  margin-top: 6px;
  font-size: 13.5px;
  color: var(--ink-3);
  text-wrap: pretty;
}
.pick__gift strong { font-weight: 500; color: var(--ink); }
.pick__gift-mark { color: var(--ember); margin-right: 4px; }

.pick__btn {
  flex: 0 0 auto;
  min-height: 48px;
  padding: 0 26px;
  font-size: 14px;
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  transition: background-color .22s var(--ease), border-color .22s var(--ease), color .22s var(--ease), opacity .22s var(--ease);
}
.pick__btn:hover:not(:disabled) { background: var(--ember); border-color: var(--ember); }
.pick__btn:disabled { opacity: .38; cursor: not-allowed; }

/* ── Gift callout (mail club) ──────────────────────────────── */

.gift {
  margin-top: 26px;
  max-width: 54ch;
  padding: 14px 18px;
  border: 1px dashed var(--ember);
  border-radius: 8px;
  background: rgba(214, 59, 22, .05);
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
  text-wrap: pretty;
}
.gift strong { font-weight: 500; color: var(--ink); }
.gift__mark { color: var(--ember); margin-right: 4px; }

/* ── Where you are (country search) ──────────────────────────
   The only currency control on the page. Sits alone at the bottom right,
   with room to breathe now that the IDR/USD pill is gone. */

.geo {
  position: fixed;
  bottom: clamp(22px, 3vw, 32px);
  right: var(--gut);
  z-index: 25;
  font-size: 12.5px;
}

.geo__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink-3);
  letter-spacing: .02em;
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.geo__btn:hover { border-color: var(--ink); color: var(--ink); }
.geo__flag { font-size: 14px; line-height: 1; }
.geo__caret {
  width: 0; height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  opacity: .55;
}
.geo__btn[aria-expanded="true"] .geo__caret { transform: rotate(180deg); }

.geo__panel {
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0;
  width: min(320px, calc(100vw - 2 * var(--gut)));
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper);
  box-shadow: 0 30px 70px -34px rgba(42, 24, 18, .55);
  overflow: hidden;
}
.geo__panel[hidden] { display: none; }

.geo__search {
  width: 100%;
  padding: 12px 14px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
  font: inherit;
  font-size: 13px;
  color: var(--ink);
}
.geo__search:focus { outline: none; }
.geo__search::placeholder { color: var(--muted); }

.geo__list {
  max-height: 260px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.geo__item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 14px;
  text-align: left;
  color: var(--ink-2);
  transition: background-color .15s var(--ease);
}
.geo__item:hover { background: var(--paper-2); }
.geo__item.is-on { color: var(--ink); }
.geo__item.is-on::after { content: "✓"; margin-left: auto; color: var(--ember); }
.geo__item-flag { font-size: 14px; line-height: 1; }
.geo__item-name { flex: 1 1 auto; min-width: 0; }
.geo__item-cur {
  flex: 0 0 auto;
  font-size: 11px;
  letter-spacing: .06em;
  color: var(--muted);
}
.geo__item.is-on .geo__item-cur { margin-left: 6px; }

.geo__empty {
  padding: 14px;
  font-size: 12.5px;
  color: var(--muted);
}
.geo__empty[hidden] { display: none; }

@media (max-width: 620px) {
  .geo { bottom: clamp(20px, 4vw, 32px); }
  .geo__label { max-width: 42vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* ── Checkout sheet ────────────────────────────────────────── */

.sheet {
  width: min(520px, calc(100vw - 32px));
  max-height: min(88vh, 900px);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 40px 90px -40px rgba(42, 24, 18, .6);
  overflow: hidden;
}
.sheet::backdrop { background: rgba(42, 24, 18, .45); }

/* The basket, address, email and pay blocks together outgrow a laptop
   viewport, so the sheet scrolls rather than clipping the pay buttons. */
.sheet__inner {
  position: relative;
  padding: 28px 26px 24px;
  max-height: min(88vh, 900px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.sheet__close {
  position: absolute;
  top: 14px; right: 16px;
  width: 34px; height: 34px;
  font-size: 22px;
  line-height: 1;
  color: var(--muted);
  border-radius: 50%;
  transition: color .2s var(--ease), background-color .2s var(--ease);
}
.sheet__close:hover { color: var(--ink); background: var(--paper-2); }

.sheet__title {
  margin-top: 12px;
  font-family: var(--display);
  font-weight: 400;
  font-size: 27px;
  letter-spacing: -0.015em;
  text-transform: lowercase;
}

.sheet__line {
  margin-top: 8px;
  font-size: 15px;
  color: var(--ink-2);
  text-wrap: pretty;
}

/* Itemised basket inside the sheet. */
.sheet__order {
  margin-top: 18px;
  padding: 14px 16px;
  border-radius: 8px;
  background: var(--paper-2);
}
.sheet__order[hidden] { display: none; }

.sheet__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  font-size: 14px;
  color: var(--ink-2);
}
.sheet__row + .sheet__row { margin-top: 8px; }
.sheet__row span:last-child { font-variant-numeric: tabular-nums; }

.sheet__row--total {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font-weight: 500;
  color: var(--ink);
}

.sheet__free { color: var(--sage); }

.sheet__block { margin-top: 24px; }

.sheet__label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}

.pay {
  display: block;
  width: 100%;
  text-align: left;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.pay + .pay { margin-top: 10px; }
.pay:hover { border-color: var(--ink); }
.pay[aria-pressed="true"] {
  border-color: var(--ink);
  background: var(--paper-2);
}

.pay__name {
  display: block;
  font-size: 15px;
  font-weight: 500;
}
.pay__note {
  display: block;
  margin-top: 3px;
  font-size: 12.5px;
  color: var(--ink-3);
}

.pay__detail {
  margin-top: 12px;
  padding: 14px 16px;
  border-radius: 8px;
  background: var(--paper-2);
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-2);
  text-wrap: pretty;
}
.pay__detail strong { font-weight: 500; color: var(--ink); }

.sheet__foot {
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
  font-size: 12px;
  color: var(--muted);
  text-wrap: pretty;
}

/* ── Mosaic add-on (mail club) ─────────────────────────────── */

.addon {
  margin-top: clamp(32px, 4vw, 46px);
  padding: 20px 22px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px 24px;
}
.addon.has-choice { border-color: var(--ember); }

.addon__text { min-width: 0; }

.addon__title {
  font-family: var(--display);
  font-size: 19px;
  letter-spacing: -0.01em;
  text-transform: lowercase;
}
.addon__mark { color: var(--ember); margin-right: 4px; }

.addon__note {
  margin-top: 6px;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-3);
  max-width: 62ch;
  text-wrap: pretty;
}
.addon__note strong { font-weight: 500; color: var(--ink); }

.addon__slot {
  grid-column: 1 / -1;
  padding: 12px 14px;
  border-radius: 8px;
  background: var(--paper-2);
  font-size: 13.5px;
}
.addon__empty { color: var(--muted); }
.addon__chosen { color: var(--ink); }
.addon__chosen strong { font-weight: 500; }

.addon__btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 48px;
  padding: 0 24px;
  border: 1px solid var(--ink);
  border-radius: 999px;
  font-size: 14px;
  white-space: nowrap;
  transition: background-color .22s var(--ease), color .22s var(--ease);
}
.addon__btn:hover { background: var(--ink); color: var(--paper); }

/* ── Checkout bar ──────────────────────────────────────────── */

.checkout {
  margin-top: 16px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 24px;
  padding: 20px 22px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper);
  transition: border-color .25s var(--ease);
}
.checkout:has(.checkout__btn:not(:disabled)) { border-color: var(--ink); }

.checkout__info { min-width: 0; }

.checkout__label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}

.checkout__line {
  font-family: var(--display);
  font-size: 17px;
  letter-spacing: -0.01em;
  text-transform: lowercase;
  color: var(--ink-2);
  text-wrap: pretty;
}

.checkout__btn {
  flex: 0 0 auto;
  min-height: 48px;
  padding: 0 30px;
  font-size: 14px;
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  transition: background-color .22s var(--ease), border-color .22s var(--ease), opacity .22s var(--ease);
}
.checkout__btn:hover:not(:disabled) { background: var(--ember); border-color: var(--ember); }
.checkout__btn:disabled { opacity: .35; cursor: not-allowed; }

/* Multiple chosen mosaics stack inside the add-on slot. */
.addon__item { display: block; }
.addon__item + .addon__item { margin-top: 4px; }

/* Discount markers in the basket. */
.sheet__off {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 3px;
  background: rgba(98, 121, 86, .16);
  color: var(--sage);
  font-size: 10.5px;
  letter-spacing: .06em;
}
.sheet__row--save { color: var(--sage); }

.sheet__form { margin-bottom: 4px; }
.sheet__form .signup__input { width: 100%; }

/* The postage line under the basket — a statement, not a control. */
.sheet__shipnote {
  margin-top: 12px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
  text-wrap: pretty;
}

/* ── Address form (in the checkout sheet) ──────────────────── */

.addr { display: grid; gap: 12px; }

.addr__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.addr__field { display: block; min-width: 0; }
.addr__field[hidden] { display: none; }

.addr__key {
  display: block;
  margin-bottom: 5px;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Lowercase so it reads as a quiet aside, not part of the uppercase label. */
.addr__opt {
  margin-left: 5px;
  font-size: 11px;
  letter-spacing: .02em;
  text-transform: lowercase;
  color: var(--ink-3);
  opacity: .85;
}
.addr__opt::before { content: "· "; }

.addr__input {
  width: 100%;
  min-height: 46px;
  padding: 11px 14px;
  font: inherit;
  font-size: 15px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 9px;
  transition: border-color .2s var(--ease);
}
.addr__input::placeholder { color: var(--muted); }
.addr__input:focus { outline: none; border-color: var(--ink); }
.addr__input[aria-invalid="true"] { border-color: var(--ember); }
.addr__input--area { resize: vertical; min-height: 62px; line-height: 1.5; }

.addr__note {
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
}
.addr__note.is-err { color: var(--ember); }

/* ── Pay block, locked until the address is complete ───────── */

.pay__locked {
  margin-bottom: 10px;
  padding: 12px 15px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-3);
  background: var(--paper-2);
  border: 1px dashed var(--line);
  border-radius: 9px;
  text-wrap: pretty;
}
.pay__locked[hidden] { display: none; }

/* A payment method that does not belong to this market is taken out of the
   form entirely (script sets hidden), not merely dimmed. */
.pay[hidden] { display: none; }

/* Why only one method is showing. */
.pay__why {
  margin-top: 12px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
}
.pay__why:empty { display: none; }

.pay-block.is-locked .pay,
[data-pay-block].is-locked .pay {
  opacity: .42;
  pointer-events: none;
}

@media (max-width: 560px) {
  .addr__row { grid-template-columns: 1fr; }
}

/* ── Steps ─────────────────────────────────────────────────── */

.step { margin-top: clamp(30px, 4vw, 44px); }

.step__num {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ember);
  margin-bottom: 6px;
}

.step__title {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  letter-spacing: -0.012em;
  text-transform: lowercase;
}

.step__note {
  margin-top: 8px;
  max-width: 56ch;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-3);
  text-wrap: pretty;
}

/* ── Plan picker ───────────────────────────────────────────── */

.plans--pick { margin-top: 18px; }

.plan--pick {
  display: block;
  width: 100%;
  text-align: left;
  cursor: pointer;
  font: inherit;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease), background-color .2s var(--ease);
}
.plan--pick:hover { border-color: var(--ink); }
.plan--pick.is-on {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}
.plan--pick .plan__name {
  display: block;
  font-size: 20px;
}
.plan--pick .plan__price {
  display: block;
  margin-top: 8px;
  font-size: 27px;
}
/* The per-letter figure — the number that actually sells a prepay. */
.plan__per {
  display: block;
  margin-top: 4px;
  font-size: 12.5px;
  letter-spacing: .02em;
  color: var(--ember);
}
.plan--pick .plan__note {
  display: block;
  margin-top: 8px;
  min-height: 0;
}
.plan--pick .plan__flag {
  display: block;
  margin-bottom: 8px;
}

/* Three plans need a little more room than two before they stack. */
@media (max-width: 720px) {
  .plans { grid-template-columns: 1fr; }
}

/* ── When it ships (club panel) ────────────────────────────── */

.club__ship {
  margin-top: 22px;
  max-width: 62ch;
  padding: 16px 20px;
  border-left: 2px solid var(--ember);
  background: rgba(214, 59, 22, .05);
  font-size: 14px;
  line-height: 1.62;
  color: var(--ink-3);
  text-wrap: pretty;
}
.club__ship strong { font-weight: 500; color: var(--ink); }

/* ── Free mosaic bar ───────────────────────────────────────── */

.freebar {
  margin-top: clamp(26px, 3.4vw, 38px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px 24px;
  padding: 18px 22px;
  border: 1px dashed var(--ember);
  border-radius: 10px;
  background: rgba(214, 59, 22, .05);
}

.freebar__slot { font-size: 14px; }
.freebar__empty { color: var(--muted); }
.freebar__chosen strong { font-weight: 500; color: var(--ink); }

.freebar__btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-height: 46px;
  padding: 0 24px;
  border: 1px solid var(--ink);
  border-radius: 999px;
  font-size: 14px;
  white-space: nowrap;
  transition: background-color .22s var(--ease), color .22s var(--ease);
}
.freebar__btn:hover { background: var(--ink); color: var(--paper); }

/* ── Mode banner (mosaic section) ──────────────────────────── */

.modebar {
  margin-top: clamp(26px, 3.4vw, 38px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 24px;
  padding: 18px 22px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--paper-2);
}

.modebar__title {
  font-family: var(--display);
  font-size: 20px;
  letter-spacing: -0.012em;
  text-transform: lowercase;
}

.modebar__note {
  margin-top: 5px;
  max-width: 64ch;
  font-size: 13.5px;
  color: var(--ink-3);
  text-wrap: pretty;
}

.modebar__cart {
  flex: 0 0 auto;
  font-size: 13px;
  color: var(--sage);
  white-space: nowrap;
}
.modebar__cart[hidden] { display: none; }

/* ── Cart bar ──────────────────────────────────────────────
   Sits out of the way until the buyer has picked their free mosaic, then
   slides up so checkout is always one tap away. */

.cartwrap {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  padding: 12px var(--gut) calc(12px + env(safe-area-inset-bottom, 0px));
  background: color-mix(in srgb, var(--paper-2) 93%, transparent);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--line);
  transform: translateY(115%);
  transition: transform .34s var(--ease);
  pointer-events: none;
}

body.has-cart .cartwrap {
  transform: translateY(0);
  pointer-events: auto;
}

/* Room for the bar so the closing panel is never covered. */
body.has-cart { padding-bottom: 108px; }

/* When the checkout bar is showing, lift the country/currency picker above
   it — both are fixed to the bottom-right and would otherwise collide, with
   the bar (z-index 60) sitting on top and swallowing the picker's clicks. */
body.has-cart .geo { bottom: calc(104px + clamp(22px, 3vw, 32px)); }

.cart {
  max-width: 1120px;
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 24px;
  padding: 13px 22px;
  border: 1px solid var(--ink);
  border-radius: 12px;
  background: var(--paper);
  box-shadow: 0 8px 30px rgba(38, 32, 28, .14);
}

.cart__label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}

.cart__line {
  font-family: var(--display);
  font-size: 17px;
  letter-spacing: -0.01em;
  color: var(--ink-2);
  text-wrap: pretty;
}

.cart__btn {
  flex: 0 0 auto;
  min-height: 50px;
  padding: 0 34px;
  font-size: 15px;
  color: var(--paper);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  transition: background-color .22s var(--ease), border-color .22s var(--ease), opacity .22s var(--ease);
}
.cart__btn:hover:not(:disabled) { background: var(--ember); border-color: var(--ember); }
.cart__btn:disabled { opacity: .35; cursor: not-allowed; }

/* ── Reveal ────────────────────────────────────────────────── */

.reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
}

/* ── Responsive ────────────────────────────────────────────── */

@media (max-width: 900px) {
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .works { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .works .work:last-child { grid-column: 1 / -1; max-width: 50%; }
}

@media (max-width: 720px) {
  .menu {
    position: static;
    max-width: none;
    justify-content: flex-start;
    gap: 2px 14px;
    padding: 0 var(--gut);
    margin-top: 76px;
    font-size: 12px;
  }
  .wordmark { position: static; padding: var(--gut) var(--gut) 0; margin-left: calc(-1 * var(--gut)); }
  /* The first panel needs no full-screen hero treatment on a phone. */
  main > section:first-child { padding-top: 40px; min-height: auto; }

  /* Series bar: stack into two rows so the title keeps full width. */
  .series__bar {
    flex-wrap: wrap;
    align-items: flex-start;
    row-gap: 12px;
  }
  .series__info { flex: 1 1 100%; }
  .series__thumbs { flex: 1 1 auto; flex-wrap: wrap; gap: 5px; }
  .series__thumb { width: 38px; height: 48px; }
  .series__meta { flex: 0 0 auto; margin-left: auto; }
}

@media (max-width: 620px) {
  body { font-size: 16px; }
  .panel { padding: 84px var(--gut) 96px; }
  .cue { display: none; }
  .pairing { flex-direction: column; align-items: flex-start; }
  .btn { width: 100%; justify-content: center; }
  .tile__name, .tile__meta { opacity: 1; transform: none; }
  .tile::after { opacity: 1; }
  .works { grid-template-columns: minmax(0, 1fr); }
  .works .work:last-child { max-width: none; }
  .plans { grid-template-columns: minmax(0, 1fr); }
  .signup__input, .signup__btn { flex: 1 1 100%; width: 100%; }
}

/* ── Mosaics of home · blank A6 sheet ──────────────────────────
   100 tiles, 10 rows × 10 columns. Each tile is A6 (105 × 148 mm) and is
   itself the control: click one to choose it, click again to let it go —
   the check mark in the corner shows the state. Tile codes:
   mosaic-001 … mosaic-100 — drop dist/mosaic-NNN.jpg in and it fills
   that tile. */

.blanksheet {
  --tile-w: 105mm;          /* A6 short edge */
  --tile-h: 148mm;          /* A6 long edge  */
  --tile-gap: 3mm;
  margin-top: clamp(36px, 5vw, 56px);
}

.blanksheet__head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-bottom: 16px;
}

.blanksheet__title {
  font-family: var(--display);
  font-weight: 400;
  font-size: 20px;
  letter-spacing: -0.01em;
  text-transform: lowercase;
}

.blanksheet__meta {
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Scroll viewport. The sheet itself is laid out at true A6 millimetres and
   scaled down with a CSS transform, so proportions stay exact. */
.blanksheet__scroll {
  overflow: auto;
  max-height: 78vh;
  padding: 2px 0 14px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  -webkit-overflow-scrolling: touch;
}

.mtiles {
  --scale: 1;
  display: grid;
  grid-template-columns: repeat(10, var(--tile-w));
  grid-auto-rows: var(--tile-h);
  gap: var(--tile-gap);
  width: max-content;
  margin: 0 auto;
  padding: 12px;
  /* `zoom` rather than `transform: scale()`: a transform is a paint-time
     effect, so the element's LAYOUT box stays at the full 1000mm grid and the
     scroll container reserves ~5700px of height for a 1560px sheet — you
     scroll three screens past the last mosaic. `zoom` changes layout size,
     so the scroll area ends where the tiles end. */
  zoom: var(--scale);
}

/* One blank tile = one A6 sheet. The code sits on the paper so you can see
   which image belongs where before anything is added. */
.mtile {
  position: relative;
  width: var(--tile-w);
  height: var(--tile-h);
  /* .tile sets padding/font for the 4-up sheet; a button needs its box reset
     to A6 here (see also the button.tile rules further up). */
  padding: 0;
  font: inherit;
  text-align: center;
  border: 0;
  cursor: pointer;
  overflow: hidden;
  border-radius: 3px;
  background: var(--paper);
  box-shadow: inset 0 0 0 1px var(--line);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
}

.mtile__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}
.mtile__img.is-missing { display: none; }

.mtile__num {
  position: relative;
  z-index: 1;
  font-family: var(--display);
  font-size: 46px;
  line-height: 1;
  color: var(--line);
  letter-spacing: -0.02em;
}

.mtile__slot {
  position: relative;
  z-index: 1;
  font-size: 13px;
  letter-spacing: .1em;
  text-transform: lowercase;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* Empty-tile plate: keeps the code readable if a photo ever sits behind it. */
.mtile:has(.mtile__img:not(.is-missing)) .mtile__num,
.mtile:has(.mtile__img:not(.is-missing)) .mtile__slot {
  color: var(--white);
  text-shadow: 0 1px 10px rgba(42, 24, 18, .7);
}

/* ── On-screen scaling ────────────────────────────────────────
   The sheet is laid out at true A6 millimetres and scaled with a CSS
   transform, so proportions stay exact: 10 A6 columns fitted to the
   available width. Click a tile to see it on its own at full size. */
/* Fallback first: some mobile browsers have no container queries, and without
   this the sheet would render at a literal 105mm per tile (one giant tile per
   screen). Then the container-query version takes over where supported. */
.blanksheet__scroll > .mtiles {
  --scale: calc((100vw - 48px) / (10 * 105mm + 9 * 3mm));
}
@supports (container-type: inline-size) {
  .blanksheet__scroll { container-type: inline-size; }
  .blanksheet__scroll > .mtiles {
    --scale: calc((100cqw - 24px) / (10 * 105mm + 9 * 3mm));
  }
}

/* ── The hundred: A6 tiles that are also the picker ────────────
   Same markup contract as the old 4-up sheet (button.tile + data-mosaic +
   data-price + data-idr), so script.js selection, currency switching and the
   Butterfly Effect add-on all keep working — just at A6 scale. */

/* Everything inside a tile is laid out in true A6 millimetres and then the
   whole sheet is scaled by --scale. To get a mark that is a predictable size
   ON SCREEN regardless of that scale, divide the wanted pixel size by
   --scale — a plain px value would be shrunk along with everything else
   (a 13px check on a phone rendered as 4px). */
.mtile {
  --check-px: 20px;   /* desired on-screen size of the corner check */
}

/* The tile is a <button>: reset the UA box, keep the paper look. */
button.tile.mtile {
  padding: 0;
  border: 0;
  border-radius: 3px;
  font: inherit;
  text-align: center;
  width: var(--tile-w);
  height: var(--tile-h);
  box-shadow: inset 0 0 0 1px var(--line);
}
button.tile.mtile:focus-visible { outline: 2px solid var(--ember); outline-offset: 2px; }
button.tile.mtile:hover { transform: none; box-shadow: inset 0 0 0 1px var(--line); }
button.tile.mtile:hover .mtile__img { transform: none; }

/* Price pill + check, sized for a 105mm tile. */
.mtile .tile__price {
  top: 3mm; left: 3mm;
  padding: 1.6mm 3.4mm;
  font-size: 3.1mm;
}
/* Check mark: sized so it lands at --check-px on screen.
   Unchosen = an empty ring. Chosen = a filled circle with a check inside.
   The tick itself is hidden until chosen, otherwise the ring's own glyph
   reads as "already selected" and the state is ambiguous. */
.mtile .tile__check {
  top: calc(var(--tile-w) * 0.05);
  right: calc(var(--tile-w) * 0.05);
  width: calc(var(--check-px) / var(--scale, 1));
  height: calc(var(--check-px) / var(--scale, 1));
  border-width: calc(2px / var(--scale, 1));
  opacity: .75;
  background: rgba(42, 24, 18, .18);
  border-color: rgba(253, 247, 242, .9);
}
.mtile .tile__check::after {
  left: 30%;
  top: 10%;
  width: 30%;
  height: 58%;
  border-width: 0 calc(2.4px / var(--scale, 1)) calc(2.4px / var(--scale, 1)) 0;
  /* The tick only shows once the tile is chosen. */
  opacity: 0;
}

button.tile.mtile[aria-pressed="true"] {
  box-shadow: inset 0 0 0 calc(2.4px / var(--scale, 1)) var(--ink);
}
button.tile.mtile[aria-pressed="true"] .tile__check {
  opacity: 1; transform: none;
  background: var(--paper); border-color: var(--paper);
}
button.tile.mtile[aria-pressed="true"] .tile__check::after { opacity: 1; }
button.tile.mtile[aria-pressed="true"] .tile__price {
  background: var(--ink); color: var(--paper);
}
/* Unchosen tiles keep their code visible; the photo still shows behind it. */
button.tile.mtile[aria-pressed="true"] .mtile__num,
button.tile.mtile[aria-pressed="true"] .mtile__slot { opacity: .35; }

/* A grid of A6 tiles needs more than the 940px text column. */
#mosaics .panel__inner--wide { max-width: 1600px; }

/* ── "look" button on each tile ─────────────────────────────────
   A sibling of the tile button, laid over the tile's bottom-left corner so
   it is reachable without stealing the tile's own click. Sized with the
   --scale divisor like the check mark, since the whole sheet is zoomed. */

.mtiles li { position: relative; }

.mtile__view {
  position: absolute;
  left: calc(var(--tile-w) * 0.05);
  bottom: calc(var(--tile-w) * 0.05);
  z-index: 3;
  padding: calc(3px / var(--scale, 1)) calc(9px / var(--scale, 1));
  font-family: inherit;
  font-size: calc(11px / var(--scale, 1));
  line-height: 1.5;
  letter-spacing: .08em;
  text-transform: lowercase;
  color: var(--ink);
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  border: calc(1px / var(--scale, 1)) solid var(--line);
  border-radius: 999px;
  opacity: .8;
  cursor: pointer;
  transition: opacity .2s var(--ease), background-color .2s var(--ease);
}
.mtile__view:hover,
.mtile__view:focus-visible { opacity: 1; background: var(--paper); border-color: var(--ink); }

/* On a phone the tiles are ~31px wide; a pill would cover the artwork. */
@media (max-width: 640px) {
  .mtile__view { display: none; }
}

/* ── Look at one mosaic (dialog) ─────────────────────────────── */

.zoom {
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 40px 90px -40px rgba(42, 24, 18, .6);
}
.zoom::backdrop { background: rgba(42, 24, 18, .62); }

.zoom__inner {
  position: relative;
  padding: 26px 24px 22px;
  text-align: center;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
}

.zoom__close {
  position: absolute;
  top: 12px; right: 14px;
  width: 34px; height: 34px;
  font-size: 22px;
  line-height: 1;
  color: var(--muted);
  border-radius: 50%;
}
.zoom__close:hover { color: var(--ink); background: var(--paper-2); }

.zoom__frame {
  position: relative;
  width: min(300px, 74%);
  aspect-ratio: 105 / 148;
  margin: 6px auto 0;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--paper-2);
  overflow: hidden;
}
.zoom__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.zoom__img[hidden] { display: none; }

.zoom__placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  letter-spacing: .14em;
  color: var(--muted);
}
.zoom__placeholder[hidden] { display: none; }

.zoom__code {
  margin-top: 16px;
  font-family: var(--display);
  font-size: 21px;
  letter-spacing: -0.01em;
}

.zoom__price {
  margin-top: 4px;
  font-size: 14px;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.zoom__state {
  margin-top: 10px;
  font-size: 12.5px;
  letter-spacing: .04em;
  color: var(--sage);
}

.zoom__choose { margin-top: 12px; width: 100%; }

.zoom__note {
  margin-top: 12px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
}

/* ── Phones & small tablets ────────────────────────────────────
   Ten A6 columns squeezed into a phone screen is unreadable, so below 900px
   the sheet becomes a normal grid of tiles at their true A6 proportions:
   3 across on a tablet, 2 across on a phone. Tap any tile for the full-size
   zoom (same dialog as desktop) and buy from there. */
@media (max-width: 900px) {
  .blanksheet__scroll {
    max-height: none;
    overflow: visible;
    padding: 0;
    border: 0;
  }
  .mtiles {
    --scale: 1;
    width: auto;
    margin: 0;
    padding: 0;
    transform: none;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-auto-rows: auto;
    gap: 12px;
  }
  .mtile,
  button.tile.mtile {
    width: auto;
    height: auto;
    aspect-ratio: 105 / 148;   /* A6 proportions, at whatever size fits */
  }
  .mtile__num { font-size: 34px; }
  .mtile__slot { font-size: 11px; }
  .mtile .tile__price { top: 9px; left: 9px; padding: 4px 10px; font-size: 11px; }
  .mtile .tile__check { top: 9px; right: 9px; width: 22px; height: 22px; }
  .mtile .tile__check::after { left: 7px; top: 3px; width: 5px; height: 10px; border-width: 0 2px 2px 0; }
  button.tile.mtile[aria-pressed="true"] { box-shadow: inset 0 0 0 3px var(--ink); }
}

@media (max-width: 560px) {
  .mtiles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
}

/* The zoom is the only way to see a piece properly on a phone, so make the
   hint visible there and give the photo as much room as the screen allows. */
.blanksheet__hint { display: none; }

@media (max-width: 900px) {
  .blanksheet__hint {
    display: block;
    margin-top: 8px;
    font-size: 12.5px;
    color: var(--muted);
  }
  .zoom__frame { width: min(340px, 78vw); }
  .zoom__code { font-size: 21px; }
  .zoom__inner { padding: 22px 18px 20px; }
}

/* ── Free phone wallpaper ────────────────────────────────────
   A free download, kept visually distinct from the shop tiles so it never
   reads as another thing to buy. The preview is a live composite: the real
   painting plus a CSS filter, so no pre-rendered export is needed per
   painting per texture. */

.panel--wallpaper { background: var(--paper-2); }

.wp-source {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 26px;
}

.wp-source__btn {
  padding: 9px 18px;
  font: inherit;
  font-size: 13.5px;
  color: var(--ink-3);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  transition: border-color .2s var(--ease), color .2s var(--ease), background-color .2s var(--ease);
}
.wp-source__btn:hover { border-color: var(--ink); color: var(--ink); }
.wp-source__btn.is-on {
  color: var(--paper);
  background: var(--ink);
  border-color: var(--ink);
}

.wp-grid {
  margin-top: 18px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 12px;
}
.wp-grid[hidden] { display: none; }

.wp-tile {
  display: block;
  width: 100%;
  padding: 0;
  font: inherit;
  text-align: left;
  background: none;
  border: 0;
  cursor: pointer;
}

/* Portrait, because the wallpaper is for a phone. */
.wp-tile__art {
  position: relative;
  display: block;
  aspect-ratio: 9 / 16;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: linear-gradient(160deg, var(--a, #f8ebe8), var(--b, #e7d3c9));
  transition: box-shadow .2s var(--ease), border-color .2s var(--ease);
}
.wp-tile__art img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.wp-tile__art img.is-missing { display: none; }

.wp-tile:hover .wp-tile__art { border-color: var(--ink); }
.wp-tile[aria-pressed="true"] .wp-tile__art {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 2px var(--ink);
}

.wp-tile__name {
  display: block;
  margin-top: 7px;
  font-size: 12px;
  color: var(--ink-3);
}
.wp-tile[aria-pressed="true"] .wp-tile__name { color: var(--ink); font-weight: 500; }

/* ── Textures ──────────────────────────────────────────────── */

.wp-texs {
  margin-top: 18px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
}

.wp-tex {
  display: grid;
  grid-template-columns: 46px 1fr;
  grid-template-areas: "swatch name"
                       "swatch note";
  gap: 2px 12px;
  align-items: center;
  padding: 12px 14px;
  font: inherit;
  text-align: left;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.wp-tex:hover { border-color: var(--ink); }
.wp-tex[aria-pressed="true"] {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

.wp-tex__swatch {
  grid-area: swatch;
  width: 46px;
  height: 62px;
  border-radius: 5px;
  border: 1px solid var(--line);
  /* A miniature of the texture: the same filter the preview uses, over a
     warm base so the tint reads at this size. */
  background:
    linear-gradient(160deg, rgba(253, 247, 242, .9), rgba(231, 211, 201, .75)),
    var(--wp-tex-base, #fdf7f2);
}
.wp-tex__name { grid-area: name; font-size: 14px; color: var(--ink); }
.wp-tex__note { grid-area: note; font-size: 11.5px; line-height: 1.45; color: var(--muted); }

/* Each texture: a filter + optional tint layer applied in the preview. */
.wp-tex--paper  { --wp-tex-base: #fdf7f2; }
.wp-tex--warm   { --wp-tex-base: #f0c9a0; }
.wp-tex--dusk   { --wp-tex-base: #4b4568; }
.wp-tex--sage   { --wp-tex-base: #9fb08f; }
.wp-tex--ember  { --wp-tex-base: #d9764a; }
.wp-tex--mono   { --wp-tex-base: #d8d2cc; }

/* ── Preview + save ────────────────────────────────────────── */

.wp-make {
  margin-top: 30px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 26px;
  padding: 22px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 12px;
}

/* A phone-shaped preview, 9:19.5 like a modern handset. */
.wp-preview__screen {
  position: relative;
  width: 148px;
  aspect-ratio: 9 / 19.5;
  border-radius: 16px;
  overflow: hidden;
  background: var(--paper-2);
  box-shadow: 0 18px 40px -22px rgba(42, 24, 18, .5);
  border: 1px solid var(--line);
}
.wp-preview__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: filter .28s var(--ease);
}
.wp-preview__img[hidden] { display: none; }

/* The tint sits over the image and follows the chosen texture. */
.wp-preview__screen::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--wp-tint, transparent);
  mix-blend-mode: var(--wp-tint-mode, normal);
  opacity: var(--wp-tint-op, 0);
  transition: background-color .28s var(--ease), opacity .28s var(--ease);
  pointer-events: none;
}

.wp-preview__empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 14px;
  text-align: center;
  font-size: 12px;
  color: var(--muted);
}
.wp-preview__empty[hidden] { display: none; }

.wp-preview__clock {
  position: absolute;
  top: 12px;
  left: 0;
  right: 0;
  z-index: 2;
  text-align: center;
  font-family: var(--display);
  font-size: 20px;
  color: var(--white);
  text-shadow: 0 1px 10px rgba(42, 24, 18, .5);
  pointer-events: none;
}

.wp-make__side { flex: 1 1 260px; }

.wp-make__line {
  font-family: var(--display);
  font-size: 17px;
  letter-spacing: -0.01em;
  color: var(--ink-2);
  text-wrap: pretty;
}

.wp-make__btn { margin-top: 14px; }

.wp-make__note {
  margin-top: 10px;
  font-size: 12px;
  line-height: 1.55;
  color: var(--muted);
  text-wrap: pretty;
}

@media (max-width: 560px) {
  .wp-grid { grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); }
  .wp-texs { grid-template-columns: 1fr; }
  .wp-make { gap: 18px; }
  .wp-preview__screen { width: 118px; }
}
