/* ==========================================================================
   Design Wall — quiltdesignwall.com
   Everything visual lives here. All the words live in content.json.

   Browser support: Chrome/Edge 90+, Firefox 90+, Safari 15+ (2021 onward).
   Nothing here needs a build step, a preprocessor or a polyfill.
   ========================================================================== */

/* --- fonts --------------------------------------------------------------- */
/* Served from the site itself, so no visitor's browser connects to a font host. They are the app's
   own fonts (QuiltDesignSystem/Resources), cut down to Latin text and converted to WOFF2 by
   tools/make-fonts.sh; the OFL licence for each sits beside it in fonts/. These URLs carry no
   fingerprint, so a font that changes is given a new file name rather than replaced under the old
   one. Outfit is a variable font: one file covers every weight the page uses. */
@font-face {
  font-family: Outfit;
  src: url("fonts/Outfit.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/IBMPlexMono-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* --- tokens -------------------------------------------------------------- */
:root {
  /* the app icon's own two colour runs */
  --lime: #c9dd6d;  --green: #90df8e;  --mint: #53dbb2;  --turq: #1ad1d1;
  --orange: #fb7a39; --coral: #f75e50; --rose: #ed446b;  --magenta: #db2c87;
  --hearth: #720041;

  --ink: #341c35;
  --ink-70: rgba(52, 28, 53, .74);
  --ink-50: rgba(52, 28, 53, .54);
  --ink-12: rgba(52, 28, 53, .12);

  --calico: #f4f2ea;
  --paper: #fffdf7;
  --page: #faf8f2;
  --cream: #f4f2ea;

  --sash: 18px;              /* sashing width; the narrow field halves it */
  --wrap: 1180px;
  --radius: 0px;             /* piecing has no rounded corners. cards neither. */

  --shadow-card: 0 26px 62px rgba(52, 28, 53, .30);
  --shadow-lift: 0 20px 50px rgba(52, 28, 53, .18);

  --font: Outfit, "Avenir Next", "Segoe UI", system-ui, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
}

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

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

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; letter-spacing: -.032em; line-height: 1; }
p { margin: 0; }
img { max-width: 100%; height: auto; display: block; }

a { color: var(--hearth); text-decoration: none; }
a:hover { color: var(--magenta); }

button, input, select { font: inherit; }

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

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

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 20;
  background: var(--hearth); color: #fff; padding: 12px 18px; font-weight: 600;
}
.skip:focus { left: 0; color: #fff; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }
.mono { font-family: var(--mono); }

.eyebrow {
  font-family: var(--mono); font-weight: 500; font-size: 11px;
  letter-spacing: .18em; text-transform: uppercase; color: var(--ink-50);
}

.lede { font-size: 19px; line-height: 1.55; color: var(--ink-70); }

/* --- the app icon, drawn in CSS ------------------------------------------ */
.icon {
  position: relative; display: block; flex: 0 0 auto;
  width: 88px; height: 88px; border-radius: 19.5px; /* iOS squircle ≈ 22.4% */
  overflow: hidden; box-shadow: 0 8px 22px rgba(52, 28, 53, .28);
}
.icon i { position: absolute; display: block; }
/* The nav is now the only place the mark appears, so it carries a little more
   weight than a nav icon usually would. */
.icon-sm { width: 50px; height: 50px; border-radius: 11px; box-shadow: 0 3px 10px rgba(0, 0, 0, .28); }
.icon-xs { width: 28px; height: 28px; border-radius: 6.5px; box-shadow: none; }

/* --- pieced blocks -------------------------------------------------------- */
/* Each .blk is one quilt block: a ground (--g) and a patch colour (--a).
   The <i> children are the patches, cut with clip-path. */
.blk { position: relative; background: var(--g); }
.blk i { position: absolute; inset: 0; display: block; background: var(--a); }

.blk .hst { -webkit-clip-path: polygon(0 0, 100% 0, 0 100%); clip-path: polygon(0 0, 100% 0, 0 100%); }
.blk .q1  { -webkit-clip-path: polygon(0 0, 0 50%, 50% 50%); clip-path: polygon(0 0, 0 50%, 50% 50%); }
.blk .q2  { -webkit-clip-path: polygon(50% 0, 100% 0, 50% 50%); clip-path: polygon(50% 0, 100% 0, 50% 50%); }
.blk .q3  { -webkit-clip-path: polygon(0 100%, 50% 100%, 50% 50%); clip-path: polygon(0 100%, 50% 100%, 50% 50%); }
.blk .q4  { -webkit-clip-path: polygon(50% 50%, 100% 50%, 100% 100%); clip-path: polygon(50% 50%, 100% 50%, 100% 100%); }
.blk .dia { -webkit-clip-path: polygon(50% 8%, 92% 50%, 50% 92%, 8% 50%); clip-path: polygon(50% 8%, 92% 50%, 50% 92%, 8% 50%); }
.blk .g1  { -webkit-clip-path: polygon(50% 0, 100% 50%, 0 50%); clip-path: polygon(50% 0, 100% 50%, 0 50%); }
.blk .g2  { -webkit-clip-path: polygon(50% 50%, 100% 100%, 0 100%); clip-path: polygon(50% 50%, 100% 100%, 0 100%); }
.blk .qtr { -webkit-clip-path: circle(96% at 0 100%); clip-path: circle(96% at 0 100%); }

/* two-colour pinwheel, used for the sample quilts */
.blk .q2b { background: var(--b); -webkit-clip-path: polygon(50% 0, 100% 0, 50% 50%); clip-path: polygon(50% 0, 100% 0, 50% 50%); }
.blk .q4b { background: var(--b); -webkit-clip-path: polygon(50% 50%, 100% 50%, 100% 100%); clip-path: polygon(50% 50%, 100% 50%, 100% 100%); }

/* --- the sashed field ----------------------------------------------------- */
/* Sashing is part of the grid rather than a gap: odd tracks are blocks, even
   tracks are sashing. That makes cornerstones real cells, so nothing has to be
   positioned by hand and the whole field stays exact at any width. */
/* Track lists are written inline by build.mjs — see sashedField(). */
.field { display: grid; background: var(--page); }
.sash { background: var(--page); }
.stone { display: block; }

.field-narrow { display: none; }

/* --- nav ------------------------------------------------------------------ */
.nav { background: var(--hearth); }
.nav-inner { display: flex; align-items: center; gap: 24px; min-height: 92px; }
.brand { display: flex; align-items: center; gap: 14px; margin-right: auto; }
.brand:hover { color: inherit; }
.wordmark { font-weight: 800; letter-spacing: -.028em; }
.nav .wordmark { font-size: 27px; color: #fff; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  font-weight: 700; border: 0; cursor: pointer; text-align: center;
  min-height: 46px; padding: 0 24px; border-radius: 999px;
  transition: filter .15s ease;
}
.btn:hover { filter: brightness(1.06); }
.btn-lime { background: var(--lime); color: var(--ink); }
.btn-lime:hover { color: var(--ink); }
.btn-hearth { background: var(--hearth); color: #fff; }
.btn-hearth:hover { color: #fff; }
.btn-hearth[disabled] { opacity: .45; cursor: not-allowed; filter: none; }
.btn-store { background: var(--hearth); color: #fff; min-height: 58px; padding: 0 28px; }
.btn-store:hover { color: #fff; }
.btn-store span { display: flex; flex-direction: column; line-height: 1.15; text-align: left; }
.btn-store small { font-size: 11px; font-weight: 500; opacity: .8; }
.btn-store strong { font-size: 17.5px; font-weight: 700; }

/* --- hero ----------------------------------------------------------------- */
.hero { position: relative; background: var(--page); padding: var(--sash) 0; }
.hero .field-wide { height: 720px; }
.hero-wrap { position: absolute; inset: 0; display: flex; align-items: center; }

.card { background: var(--paper); padding: 50px 46px; box-shadow: var(--shadow-card); }
.hero-card { width: min(630px, 100%); display: flex; flex-direction: column; gap: 22px; }
.hero-card h1 { font-weight: 800; font-size: clamp(34px, 4.4vw, 58px); line-height: .98; text-wrap: balance; }

/* Two openers for the hero card, one shown at a time — see the media queries.
   Wide: the full lockup, because the card is floating over a large field and
   the nav is visually far away. Narrow: the tagline alone, because the card
   sits directly under the nav and the lockup would repeat it. */
.lockup { display: flex; align-items: center; gap: 18px; }
.lockup-words { display: flex; flex-direction: column; gap: 4px; }
.lockup .wordmark { font-size: clamp(30px, 3.4vw, 44px); line-height: 1; }
.tagline {
  font-family: var(--mono); font-weight: 500; font-size: 11px;
  letter-spacing: .18em; text-transform: uppercase; color: var(--hearth);
  line-height: 1.5;
}
.hero-kicker { display: none; color: var(--hearth); margin-bottom: -8px; }

.hero-cta { display: flex; flex-direction: column; gap: 10px; }
.hero-cta-row { flex-direction: row; align-items: center; gap: 18px; flex-wrap: wrap; }

.capture-heading { font-weight: 700; font-size: 19px; letter-spacing: -.02em; }
.capture-body { font-size: 16px; line-height: 1.5; color: var(--ink-70); }
.capture { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.capture-field {
  flex: 1 1 240px; min-height: 46px; padding: 0 16px;
  border: 1px solid var(--ink-12); border-radius: 999px;
  background: #fff; color: var(--ink);
}
.capture-field::placeholder { color: var(--ink-50); }
.capture-field[disabled] { background: rgba(52, 28, 53, .05); cursor: not-allowed; }
.capture-note { font-family: var(--mono); font-size: 11px; color: var(--ink-50); }

.rating { display: flex; flex-direction: column; gap: 4px; }
.stars { display: flex; gap: 3px; }
.stars span {
  width: 16px; height: 16px; background: var(--orange);
  -webkit-clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
.rating-num { font-weight: 700; font-size: 14.5px; }
.rating-note { font-family: var(--mono); font-size: 10.5px; color: var(--ink-50); }

/* --- the app, lifted off the piecing -------------------------------------- */
.device-band { background: var(--page); padding: 64px 0 88px; }
.device {
  max-width: 960px; margin: 0 auto; background: #241226; padding: 13px;
  border-radius: 26px; box-shadow: 0 34px 76px rgba(52, 28, 53, .32);
}
.device-bar {
  background: #ece9e0; border-radius: 14px 14px 0 0; padding: 12px 16px;
  font-weight: 600; font-size: 13px;
}
.device-empty .quilt { border-radius: 0 0 14px 14px; overflow: hidden; }
.device-note {
  margin-top: 12px; color: rgba(255, 255, 255, .72); font-size: 13px;
  display: flex; flex-direction: column; gap: 4px; padding: 0 4px 4px;
}
.device-note em { font-family: var(--mono); font-size: 10.5px; color: rgba(255, 255, 255, .48); font-style: normal; }

/* --- sample quilts -------------------------------------------------------- */
.quilt { display: grid; grid-template-columns: repeat(var(--cols), 1fr); }
.quilt .blk { aspect-ratio: 1 / 1; }
.demo { transition: filter .3s ease; }
.demo.is-value { filter: grayscale(1) contrast(1.02); }

/* --- feature slots -------------------------------------------------------- */
.slot { padding: 88px 0; }
.slot-1 { background: var(--turq); }
.slot-2 { background: var(--lime); }
.slot-3 { background: var(--magenta); }
.slot-3 h2, .slot-3 .lede { color: #fff; }
.slot-3 .eyebrow { color: rgba(255, 255, 255, .75); }

.slot-inner { display: flex; gap: 60px; align-items: center; }
.slot-2 .slot-inner { flex-direction: row-reverse; }
.slot-text { flex: 0 0 452px; display: flex; flex-direction: column; gap: 18px; }
.slot-text h2 { font-weight: 800; font-size: clamp(30px, 3.6vw, 52px); text-wrap: balance; }
.slot-text .lede { color: rgba(52, 28, 53, .82); }
.slot-figure { flex: 1 1 auto; min-width: 0; }

.panel { background: var(--paper); padding: 26px; box-shadow: var(--shadow-lift); }

.toggle {
  display: inline-flex; padding: 4px; border-radius: 999px;
  background: rgba(52, 28, 53, .12); margin-bottom: 18px;
}
.toggle button {
  min-height: 42px; padding: 0 24px; border: 0; border-radius: 999px;
  background: transparent; color: var(--ink-70); font-weight: 600; cursor: pointer;
}
.toggle button.is-on { background: var(--paper); color: var(--ink); }

.caption { margin-top: 16px; font-size: 15px; line-height: 1.55; font-weight: 500; color: var(--ink-70); min-height: 3em; }

/* the cutting chart */
.chart { padding: 0; }
.chart-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 16px 20px; background: #ece9e0; font-weight: 600; font-size: 13px;
}
.chart-head .mono { font-size: 10.5px; color: var(--ink-50); font-weight: 500; }
.chart-row {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 15px 20px; border-bottom: 1px solid rgba(52, 28, 53, .07);
}
.chip { width: 26px; height: 26px; flex: 0 0 auto; border: 1px solid var(--ink-12); }
.chart-unit { flex: 1 1 160px; font-weight: 500; font-size: 14.5px; }
.chart-rule { font-size: 11.5px; color: var(--ink-50); }
.chart-cut { font-size: 14.5px; font-weight: 500; margin-left: auto; }
.chart-foot { padding: 14px 20px; font-size: 10.5px; color: var(--ink-50); background: rgba(52, 28, 53, .035); }

/* screenshot placeholders */
.shot-empty {
  display: flex; flex-direction: column; justify-content: center; gap: 10px;
  aspect-ratio: 3 / 2; padding: 28px; text-align: center;
  border: 2px dashed rgba(114, 0, 65, .3); color: var(--ink-70);
}
.shot-empty em { font-family: var(--mono); font-size: 11px; font-style: normal; color: var(--ink-50); }

/* --- proof ---------------------------------------------------------------- */
.proof { background: var(--hearth); padding: 72px 0; }
.proof-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 36px; }
.proof-num { font-weight: 800; font-size: clamp(38px, 3.8vw, 52px); letter-spacing: -.04em; line-height: 1; }
.proof-label { margin-top: 9px; font-size: 14.5px; line-height: 1.45; color: rgba(255, 255, 255, .8); }

/* --- closing -------------------------------------------------------------- */
.closing { position: relative; background: var(--page); padding: var(--sash) 0; }
.closing .field-wide { height: 560px; }
.closing-wrap { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.closing-card {
  width: min(700px, 100%); display: flex; flex-direction: column;
  align-items: center; gap: 20px; text-align: center;
}
.closing-card h2 { font-weight: 800; font-size: clamp(30px, 3.8vw, 52px); text-wrap: balance; }
.closing-card .lede { max-width: 470px; }
.closing-cta { display: flex; flex-direction: column; align-items: center; gap: 10px; width: 100%; }
.closing-cta .capture { justify-content: center; max-width: 460px; width: 100%; }
.closing-note { font-family: var(--mono); font-size: 11.5px; color: var(--ink-50); }

/* --- footer --------------------------------------------------------------- */
.foot { background: var(--ink); padding: 44px 0; }
.foot-inner { display: flex; align-items: center; gap: 32px; flex-wrap: wrap; }
.foot-brand { display: flex; align-items: center; gap: 11px; margin-right: auto; }
.foot-words { display: flex; flex-direction: column; gap: 2px; }
.foot .wordmark { font-size: 16px; color: var(--calico); }
.foot-domain { font-size: 10.5px; color: rgba(244, 242, 234, .52); }
.foot-links { display: flex; gap: 26px; flex-wrap: wrap; font-size: 14px; }
.foot-links a { color: rgba(244, 242, 234, .7); }
.foot-links a:hover { color: #fff; }
.foot-copy { font-size: 11px; color: rgba(244, 242, 234, .45); }
.foot-social { display: flex; gap: 6px; }
.foot-social a { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 8px; color: rgba(244, 242, 234, .7); }
.foot-social a:hover { color: #fff; }
.foot-social svg { width: 20px; height: 20px; display: block; }

/* --- legal pages: privacy.html, terms.html ---------------------------------
   Built from docs/shipping/legal/*.md. These are reading pages, so the measure is
   narrow and body text is full ink rather than the homepage's 70%: people
   come here to find one particular sentence and read it closely. */
.legal-page { padding: 56px 0 96px; }
.legal { max-width: 800px; }
.legal h1 { font-size: clamp(34px, 6vw, 52px); font-weight: 800; line-height: 1.05; margin-bottom: 14px; }
.legal h1 + p { font-family: var(--mono); font-size: 12px; color: var(--ink-50); margin-bottom: 26px; }
.legal h1 + p strong { font-weight: 500; }
.legal h2 { font-size: 27px; font-weight: 700; line-height: 1.15; letter-spacing: -.02em; margin-bottom: 16px; }
.legal h3 { font-size: 19px; font-weight: 700; line-height: 1.3; letter-spacing: -.01em; margin: 30px 0 10px; }
.legal p, .legal ul, .legal ol, .legal blockquote { margin: 0 0 14px; }
.legal ul, .legal ol { padding-left: 1.3em; }
.legal li { margin-bottom: 8px; }
.legal li::marker { color: var(--magenta); }
.legal strong { font-weight: 600; }
.legal a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.legal h3, .legal-section { scroll-margin-top: 16px; }
.legal-section { margin-top: 44px; padding-top: 40px; border-top: 1px solid var(--ink-12); }

/* The short version is the part most people read, so it gets the homepage's
   card, with a strip of the icon's colour runs along the top like a binding. */
#the-short-version {
  position: relative; margin-top: 32px; padding: 34px 32px 18px; border-top: 0;
  background: var(--paper); box-shadow: var(--shadow-lift);
}
#the-short-version::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 6px;
  background: linear-gradient(90deg,
    var(--lime) 0 12.5%, var(--green) 0 25%, var(--mint) 0 37.5%, var(--turq) 0 50%,
    var(--orange) 0 62.5%, var(--coral) 0 75%, var(--rose) 0 87.5%, var(--magenta) 0);
}

.legal-toc { margin-top: 44px; }
.legal-toc ul { list-style: none; padding: 0; margin: 12px 0 0; columns: 2 280px; column-gap: 32px; }
.legal-toc li { margin: 0 0 6px; break-inside: avoid; }
.legal-toc a { text-decoration: none; font-weight: 500; }

.table-scroll { overflow-x: auto; margin: 4px 0 18px; }
.legal table { width: 100%; border-collapse: collapse; font-size: 15px; line-height: 1.45; }
.legal th {
  text-align: left; vertical-align: bottom; padding: 0 16px 10px 0; border-bottom: 2px solid var(--ink);
  font-family: var(--mono); font-weight: 500; font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-50);
}
.legal td { vertical-align: top; padding: 12px 16px 12px 0; border-bottom: 1px solid var(--ink-12); }
.legal th:last-child, .legal td:last-child { padding-right: 0; }

/* A placeholder nobody has filled in yet. Loud on purpose: it must not be
   possible to publish one of these pages without noticing. */
.legal mark.todo {
  background: #ffe58a; color: var(--ink); padding: 1px 4px;
  font-family: var(--mono); font-size: .86em;
}

/* --- beta page: beta.html --------------------------------------------------
   The homepage's hero, closing and Colour / Value slot, reused as they are.
   What is its own: the sign-up form, the binding strip that marks a card as
   a sign-up, and the two sections a tester needs before saying yes. */
.beta-card { position: relative; }
.beta-card::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 8px;
  background: linear-gradient(90deg,
    var(--lime) 0 12.5%, var(--green) 0 25%, var(--mint) 0 37.5%, var(--turq) 0 50%,
    var(--orange) 0 62.5%, var(--coral) 0 75%, var(--rose) 0 87.5%, var(--magenta) 0);
}
.beta .hero-card { gap: 20px; }

.beta-kicker { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.beta-kicker .eyebrow { color: var(--hearth); }
.stamp {
  font-family: var(--mono); font-weight: 500; font-size: 11px; letter-spacing: .16em;
  text-transform: uppercase; background: var(--hearth); color: #fff; padding: 5px 10px;
}

.beta-form { display: flex; flex-direction: column; gap: 12px; width: 100%; }
.beta-form .capture { margin-top: 0; }

/* The device choice: radio buttons dressed as the Colour / Value toggle, so
   it reads as one pick of three rather than as a form to fill in. */
.pick { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 0; padding: 0; border: 0; min-width: 0; }
.pick legend { float: left; margin-right: 4px; }
.pick label { position: relative; cursor: pointer; }
.pick input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.pick span {
  display: inline-flex; align-items: center; min-height: 38px; padding: 0 18px;
  border-radius: 999px; background: rgba(52, 28, 53, .07); color: var(--ink-70);
  font-weight: 600; font-size: 15px;
}
.pick input:checked + span { background: var(--ink); color: #fff; }
.pick input:focus-visible + span { outline: 3px solid var(--hearth); outline-offset: 2px; }
.pick[disabled] label, .pick[disabled] input { cursor: not-allowed; }
.pick[disabled] span { opacity: .55; }

.closing-card .beta-form { align-items: center; max-width: 460px; }

/* Name and "how did you hear about us", both optional, in the email field's
   shape. The "Other" box shows only once Other is chosen; a browser without
   :has() never shows it, and the choice alone still arrives. */
.names, .source { display: flex; gap: 10px; flex-wrap: wrap; width: 100%; }
.names .capture-field, .source .capture-field { flex: 1 1 160px; }
.source select.capture-field {
  appearance: none; -webkit-appearance: none; cursor: pointer; padding-right: 40px;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23341c35' stroke-width='2'/%3E%3C/svg%3E") no-repeat right 18px center;
}
.source select.capture-field:has(option[value=""]:checked) { color: var(--ink-50); }
.source-other { display: none; }
.source:has(option:last-child:checked) .source-other { display: block; }

/* A field no person sees or tabs to; a script that fills it in is refused by /api/beta. */
.honey { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

/* How the sign-up went, in the note under the form. */
.capture-note.is-done {
  font-family: var(--font); font-size: 17px; font-weight: 600; color: var(--hearth);
  border-left: 6px solid var(--mint); padding: 6px 0 6px 14px;
}
.closing-card .capture-note.is-done { border-left: 0; padding-left: 0; }
.capture-note.is-error { font-family: var(--font); font-size: 14px; color: #b3261e; }
.cf-turnstile:empty { display: none; }
.closing-card .pick { justify-content: center; }

/* the Colour / Value slot, with three short promises under the lede */
.peek-list { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.peek-list li { position: relative; padding-left: 26px; font-weight: 500; color: var(--ink); }
.peek-list li::before {
  content: ""; position: absolute; left: 0; top: .38em; width: 12px; height: 12px;
  background: var(--hearth);
}

/* what testing involves: three blocks, each with a band of its own colour */
.deal { background: var(--lime); padding: 88px 0; }
.deal h2, .faq h2 { font-weight: 800; font-size: clamp(30px, 3.6vw, 52px); margin-top: 14px; text-wrap: balance; }
.deal-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sash); margin-top: 40px; }
.deal-card {
  background: var(--paper); box-shadow: var(--shadow-lift);
  padding: 30px 28px 26px; border-top: 12px solid var(--band);
}
.deal-card h3 { font-weight: 700; font-size: 22px; letter-spacing: -.02em; line-height: 1.15; }
.deal-card ul { list-style: none; margin: 18px 0 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.deal-card li { position: relative; padding-left: 22px; font-size: 16px; line-height: 1.45; color: var(--ink-70); }
.deal-card li::before {
  content: ""; position: absolute; left: 0; top: .42em; width: 10px; height: 10px;
  background: var(--band);
}

/* the beta page's link to the sneak peek */
.peek-link { align-self: flex-start; font-weight: 700; color: var(--hearth); border-bottom: 2px solid currentColor; }
.peek-link:hover { color: var(--ink); }

/* --- sneak peek: peek.html -------------------------------------------------
   A design wall, not a copy of the homepage. The ground is the grey flannel
   most quilters hang for one (Robert Kaufman's Framework "Design Wall" in
   Grey): mid grey with a lighter grid of 2-inch squares, drawn here at 50px so
   a pinned block reads as about 6 inches. Blocks and screens are pinned to it
   a little off square, with paper tags for labels, in the homepage's colours
   and type. #5c5b60 keeps white text at 6.7:1 and the 92% body text at 6.0:1. */
.peek-page {
  --flannel: #5c5b60;
  background-color: var(--flannel); color: #fff;
  background-image:
    linear-gradient(rgba(255, 255, 255, .2) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .2) 1px, transparent 1px),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .025) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, .05) 0 1px, transparent 1px 4px);
  background-size: 50px 50px, 50px 50px, auto, auto;
}

.peek-intro { padding: 96px 0 80px; }
.peek-intro-inner { display: grid; grid-template-columns: 1.05fr 1fr; gap: 56px; align-items: center; }
.peek-intro-words { display: flex; flex-direction: column; gap: 22px; }
.peek-intro h1 { font-weight: 800; font-size: clamp(40px, 5.6vw, 76px); line-height: .96; text-wrap: balance; }
.peek-intro .lede { color: rgba(255, 255, 255, .92); max-width: 520px; }
.peek-intro .beta-kicker .eyebrow { color: var(--lime); }
.peek-intro .stamp { background: var(--lime); color: var(--ink); }

.pinned { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px 22px; padding: 10px; }
.pinned-block {
  position: relative; display: block; transform: rotate(var(--turn));
  box-shadow: 0 14px 28px rgba(0, 0, 0, .35);
}
.pinned-block .blk { aspect-ratio: 1; }
.pin {
  position: absolute; z-index: 1; top: -7px; left: 50%; width: 14px; height: 14px; margin-left: -7px;
  border-radius: 50%; box-shadow: 0 3px 5px rgba(0, 0, 0, .45), inset -2px -2px 0 rgba(0, 0, 0, .18);
}

.stop { padding: 40px 0 96px; }
.stop .wrap { max-width: 1060px; }
.stop-tag {
  display: inline-flex; align-items: center; gap: 10px; margin-bottom: 22px;
  background: var(--calico); color: var(--ink); padding: 8px 16px 8px 12px;
  font-family: var(--mono); font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  transform: rotate(-1.5deg); box-shadow: 0 6px 14px rgba(0, 0, 0, .3);
}
.stop-tag span { background: var(--magenta); color: #fff; padding: 2px 7px; letter-spacing: .06em; }
.stop-right .stop-tag { transform: rotate(1.2deg); }
.stop-right .stop-tag span { background: var(--turq); color: var(--ink); }
.stop-frame { transform: rotate(-.4deg); }
.stop-right .stop-frame { transform: rotate(.4deg); }
.stop-frame .window { box-shadow: 0 34px 80px rgba(0, 0, 0, .5); border-color: rgba(0, 0, 0, .3); }
.stop-frame .ill-note { color: rgba(255, 255, 255, .85); }
.stop-words { display: grid; grid-template-columns: 1fr 1.1fr; gap: 40px; margin-top: 34px; align-items: start; }
.stop-words h2 { font-weight: 800; font-size: clamp(28px, 3.4vw, 46px); text-wrap: balance; }
.stop-words .lede { color: rgba(255, 255, 255, .92); }
.stop-right .stop-words h2 { order: 2; }
.stop + .stop { border-top: 1px dashed rgba(255, 255, 255, .3); }

.peek-closing { background: var(--page); color: var(--ink); padding: 0 0 88px; }
.peek-closing .binding { margin-bottom: 64px; }
.peek-closing .closing-card { margin: 0 auto; }

.window {
  background: var(--paper); border-radius: 12px; overflow: hidden;
  box-shadow: 0 28px 64px rgba(52, 28, 53, .32); border: 1px solid rgba(52, 28, 53, .14);
}
.window-bar {
  display: flex; align-items: center; gap: 7px; padding: 11px 14px;
  background: #ece9e0; border-bottom: 1px solid rgba(52, 28, 53, .1);
}
.window-bar i { width: 11px; height: 11px; border-radius: 50%; background: #d6d1c6; }
.window-bar i:nth-child(1) { background: #f26b5b; }
.window-bar i:nth-child(2) { background: #f5c04e; }
.window-bar i:nth-child(3) { background: #5bc46a; }
.window-bar span { margin-left: 8px; font-weight: 600; font-size: 13px; color: var(--ink-70); }
.window-body img { width: 100%; }
/* The screenshots are full-screen iPad captures with square corners and no edge of their own, so
   each sits in a dark bezel with rounded corners and casts its shadow onto the flannel. */
.peek-shot-img {
  display: block; width: 100%; height: auto; box-sizing: border-box;
  border: 8px solid #231a24; border-radius: 22px;
  box-shadow: 0 28px 64px rgba(52, 28, 53, .32);
}

/* The sneak peek's teaser on the beta page: a strip of the same flannel with
   the app's screens pinned across it. On a phone only the middle one (the
   quilt) stays, at a size that can still be read. */
.peek-teaser { padding: 72px 0 84px; }
.peek-teaser-inner { display: grid; grid-template-columns: 300px 1fr; gap: 48px; align-items: center; }
.peek-teaser-words { display: flex; flex-direction: column; align-items: flex-start; gap: 18px; }
.peek-teaser .eyebrow { color: var(--lime); }
.peek-teaser h2 { font-weight: 800; font-size: clamp(30px, 3.6vw, 46px); line-height: 1; text-wrap: balance; }
.peek-teaser-shots { display: flex; gap: 26px; align-items: flex-start; }
.peek-teaser-shot { position: relative; display: block; flex: 1 1 0; min-width: 0; transform: rotate(var(--turn)); }
.peek-teaser-shot .pin { top: -4px; }

.ill-note { margin-top: 12px; font-family: var(--mono); font-size: 11px; color: rgba(52, 28, 53, .7); }
.slot-3 .ill-note { color: rgba(255, 255, 255, .8); }

/* The illustrations stand in for screenshots, so each is laid out like its screen. */
.ill { padding: 18px; }
.ill-fabrics { display: grid; grid-template-columns: repeat(10, 1fr); gap: 8px; }
.swatch { display: flex; flex-direction: column; gap: 4px; }
.swatch i { display: block; aspect-ratio: 1; border: 1px solid rgba(52, 28, 53, .08); }
.swatch b, .tile b, .role b { display: block; height: 4px; width: 70%; background: rgba(52, 28, 53, .14); }

.ill-pattern { display: flex; gap: 16px; align-items: flex-start; background: #8a8390; }
.ill-pattern .quilt { flex: 1 1 auto; }
.ill-roles {
  flex: 0 0 22%; display: flex; flex-direction: column; gap: 10px;
  background: var(--paper); padding: 12px; align-self: stretch;
}
.role { display: flex; align-items: center; gap: 8px; }
.role i { flex: 0 0 auto; width: 22px; height: 22px; border: 1px solid rgba(52, 28, 53, .12); }

.ill-blocks { display: grid; grid-template-columns: repeat(6, 1fr); gap: 14px; background: #efedf1; }
.tile { display: flex; flex-direction: column; gap: 8px; background: var(--paper); padding: 8px; border: 1px solid rgba(52, 28, 53, .1); }
.tile .blk { aspect-ratio: 1; }

/* questions, answered without JavaScript */
.faq { background: var(--page); padding: 88px 0; }
.faq-inner { display: flex; gap: 60px; align-items: flex-start; }
.faq-head { flex: 0 0 380px; }
.faq-list { flex: 1 1 auto; min-width: 0; border-top: 1px solid var(--ink-12); }
.faq details { border-bottom: 1px solid var(--ink-12); }
.faq summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between;
  gap: 16px; min-height: 64px; padding: 14px 0; font-weight: 600; font-size: 19px; letter-spacing: -.01em;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; flex: 0 0 auto; width: 14px; height: 14px; background: var(--magenta);
  -webkit-clip-path: polygon(0 0, 100% 0, 50% 100%); clip-path: polygon(0 0, 100% 0, 50% 100%);
  transition: transform .2s ease;
}
.faq details[open] summary::after { transform: rotate(180deg); }
.faq details p { padding: 0 0 22px; max-width: 620px; color: var(--ink-70); }
.faq details a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }

/* ==========================================================================
   Responsive. Three steps: the card stops floating over the piecing, the
   slots stack, then everything goes single column.
   ========================================================================== */

@media (max-width: 1080px) {
  .hero .field-wide { height: 620px; }
  .slot-text { flex-basis: 380px; }
  .slot-inner { gap: 40px; }
}

@media (max-width: 900px) {
  .peek-teaser { padding: 56px 0 64px; }
  .peek-teaser-inner { grid-template-columns: 1fr; gap: 32px; }
  /* The hero card stops being an overlay and sits under a shallow band of
     piecing. Absolute positioning over a field is a desktop luxury. */
  .hero, .closing { padding: 0; }
  .hero .field-wide, .closing .field-wide { display: none; }
  .field-narrow { display: grid; height: 220px; --sash: 10px; }
  .hero-wrap, .closing-wrap { position: static; display: block; padding-top: 0; }
  /* No negative margin here. Overlapping the field is a desktop move: at this
     size the card's top edge slices the bottom row of blocks in half, which
     reads as a rendering fault rather than as depth. Flush is deliberate. */
  .hero-card, .closing-card { width: auto; margin: 0 24px 48px; padding: 36px 28px; }

  /* Below here the card sits right under the nav, so the lockup would put the
     name and mark on screen twice. Swap it for the tagline alone. */
  .hero-lockup { display: none; }
  .hero-kicker { display: block; }
  .closing-card { margin-bottom: 0; }
  .closing { padding-bottom: 56px; }
  .wrap.hero-wrap, .wrap.closing-wrap { padding: 0; }

  .slot { padding: 64px 0; }
  .slot-inner, .slot-2 .slot-inner { flex-direction: column; align-items: stretch; gap: 32px; }
  .slot-text { flex-basis: auto; }

  .proof-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px; }
  .device-band { padding: 40px 0 64px; }

  .deal, .faq { padding: 64px 0; }
  .ill-fabrics { grid-template-columns: repeat(8, 1fr); gap: 6px; }
  .peek-intro { padding: 56px 0 48px; }
  .peek-intro-inner { grid-template-columns: 1fr; gap: 40px; }
  .pinned { max-width: 460px; }
  .stop { padding: 32px 0 64px; }
  .stop-words { grid-template-columns: 1fr; gap: 14px; margin-top: 24px; }
  .stop-right .stop-words h2 { order: 0; }
  .stop-frame, .stop-right .stop-frame { transform: none; }
  .peek-closing .binding { margin-bottom: 40px; }
  .ill-fabrics .swatch:nth-child(10n+9), .ill-fabrics .swatch:nth-child(10n) { display: none; }
  .deal-grid { grid-template-columns: 1fr; margin-top: 28px; }
  /* Stretch, not the wide layout's flex-start: in a column that would size the list to its longest
     question and leave its right edge short of the page margin. */
  .faq-inner { flex-direction: column; align-items: stretch; gap: 24px; }
  .faq-head { flex-basis: auto; }
}

/* --- phones --------------------------------------------------------------
   The band of piecing gets SHORTER and its blocks get SMALLER, not bigger.
   Three fat blocks read as three random shapes; twelve small ones read as a
   quilt. Same rule the brand package gives for the wall — what makes a woven
   field look like cloth is how many repetitions are in view, not how large
   each one is. The band is decoration, and it must not push the headline off
   the first screen. */
@media (max-width: 560px) {
  .peek-teaser-shot:not(.is-lead) { display: none; }
  body { font-size: 16px; }
  .lede { font-size: 17px; }

  .nav-inner { min-height: 64px; gap: 12px; }
  .nav .wordmark { font-size: 19px; }
  .icon-sm { width: 34px; height: 34px; border-radius: 7.5px; }
  .btn { padding: 0 18px; font-size: 15px; min-height: 44px; }

  /* Height is chosen so the blocks come out square at a typical phone width:
     6 columns and a 6px sash across ~400px gives a ~62px block, so two rows
     plus one sash is ~130. */
  .field-narrow { height: 130px; --sash: 6px; }

  .hero-card, .closing-card { margin: 0 14px 36px; padding: 26px 20px; gap: 16px; }
  .hero-card h1 { overflow-wrap: break-word; }
  .hero-kicker { letter-spacing: .14em; }

  .wrap { padding: 0 16px; }
  .panel { padding: 16px; }
  .chart-row { gap: 10px; padding: 13px 16px; }
  .chart-rule { display: none; }          /* the rule column is the first to go */
  .chart-head, .chart-foot { padding: 13px 16px; }
  .chart-head { font-size: 12px; }

  .device { padding: 8px; border-radius: 18px; }
  .device-bar { padding: 10px 12px; font-size: 12px; border-radius: 10px 10px 0 0; }
  .device-note { font-size: 12px; }

  /* Touch targets — a 20px-tall link is a coin toss with a thumb. 44px is
     Apple's floor, not a target. Repeated here so narrow windows on a laptop
     get the same treatment as an actual phone. */
  .toggle button { min-height: 44px; }
  .foot-links a { display: inline-flex; align-items: center; min-height: 44px; }
  .brand { min-height: 44px; }
  .pick span { min-height: 44px; }

  /* The smallest labels come up a little. The mono kicker stays small on
     purpose — it is the brand's own section-label style — but 9.5px of
     letterspaced caps is asking a lot of a phone. */
  .chart-foot, .foot-domain { font-size: 11.5px; }
  .chart-head .mono { font-size: 11px; }

  .proof { padding: 56px 0; }
  .proof-grid { grid-template-columns: 1fr; gap: 24px; }
  .foot { padding: 36px 0; }
  .foot-inner { gap: 16px; }
  /* On its own line the row starts at the text edge: the glyph, not its tap box, lines up. */
  .foot-social { margin-left: -8px; }
  .foot-links { gap: 4px 20px; font-size: 14px; }

  /* Once the form stacks, the main axis is vertical — so flex-basis would be
     read as a HEIGHT and blow the field up to 240px tall. Reset it. */
  .capture { flex-direction: column; }
  .capture-field, .capture .btn { flex: 0 0 auto; width: 100%; }
  .names, .source { flex-direction: column; }
  .names .capture-field, .source .capture-field { flex: 0 0 auto; width: 100%; }

  .ill { padding: 12px; }
  .ill-pattern { flex-direction: column; }
  .ill-pattern .quilt { width: 100%; }
  .ill-roles { flex-direction: row; flex-wrap: wrap; align-self: auto; width: 100%; }
  .ill-blocks { grid-template-columns: repeat(3, 1fr); gap: 8px; }
  .ill-blocks .tile:nth-child(n+7) { display: none; }

  /* The label takes its own line so the three choices stay on one. */
  .pick { gap: 8px; }
  .pick legend { float: none; width: 100%; margin: 0 0 2px; }
  .closing-card .pick legend { text-align: center; }

  .legal-page { padding: 36px 0 64px; }
  .legal h2 { font-size: 23px; }
  .legal-section { margin-top: 32px; padding-top: 28px; }
  #the-short-version { padding: 28px 20px 12px; }
  .legal table { font-size: 14px; }
  .legal td { padding: 10px 12px 10px 0; }
  .legal-toc a { display: inline-flex; align-items: center; min-height: 44px; }
  .legal-toc li { margin: 0; }
}

/* Small phones — iPhone SE is 375, the 12/13 mini 360. */
@media (max-width: 400px) {
  .hero-card, .closing-card { margin-left: 10px; margin-right: 10px; padding: 22px 18px; }
  .wrap { padding: 0 12px; }
  .field-narrow { height: 120px; }
  .nav .wordmark { font-size: 18px; }
  .icon-sm { width: 32px; height: 32px; border-radius: 7px; }
}

/* --- touch ----------------------------------------------------------------
   Hit areas are about the input device, not the window width: an iPad in
   landscape is 1024px wide and still driven by a thumb. Keyed off pointer
   rather than a breakpoint so tablets are covered too. */
@media (pointer: coarse) {
  .toggle button { min-height: 44px; }
  .foot-social a { width: 44px; height: 44px; }
  .foot-links a { display: inline-flex; align-items: center; min-height: 44px; }
  .brand { min-height: 44px; }
  .pick span { min-height: 44px; }
  .legal-toc a { display: inline-flex; align-items: center; min-height: 44px; }
  .legal-toc li { margin: 0; }
}
@media (pointer: coarse) and (max-width: 560px) {
  .foot-social { margin-left: -12px; }
}

/* --- respect the reader --------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

@media print {
  .nav, .field, .toggle, .skip { display: none; }
  body { background: #fff; }
  .card { box-shadow: none; border: 1px solid #ccc; }
  .legal-toc { display: none; }
  #the-short-version { box-shadow: none; border: 1px solid #ccc; }
}
