/* The shared theme every landing site is built from. No framework. Mobile
   first: most of this page's traffic is a phone in the Meta feed, and desktop
   is the minority that has to be good rather than the majority that has to be
   great.

   THE CONTRACT: every colour, font, radius, shadow and measure is a custom
   property declared ONCE in `:root` below, and nowhere else in this file is a
   literal value of any of those kinds. build.py reads that block to learn the
   theme keys a site.yaml `theme:` may override, and appends the site's override
   block after this file, so a site can re-colour the whole page without
   touching a selector. Class names are the other half of the contract: a site's
   own styles.css may restyle them and must never rename them, because the
   shared partials, cta.js and the test suites all address them by name.

   TYPE: two system stacks, no web font. The story runs in the serif so it reads
   as an article rather than a landing page, and every interface surface (top
   bar, product card, FAQ, buttons) runs in the sans so it reads as a control.
   Georgia is on effectively every phone and desktop we take traffic from, which
   buys the editorial voice for zero bytes and zero render-blocking requests. */

:root {
  --ink: #191713;
  --ink-soft: #5e564b;
  /* 4.7:1 on the page ground. Every use is small text (the top bar label, the
     editor's note, captions, the footer), so it has to clear AA on its own. */
  --ink-faint: #756c5e;
  --paper: #f7f3ec;
  --paper-raised: #fffdf9;
  --line: #e2d9cb;
  --line-soft: #ece4d8;
  /* One accent, used for every CTA and nothing else. A deep cobalt-navy reads
     as trustworthy at button size; a warmer or brighter one reads as a sale. */
  --accent: #23407c;
  --accent-deep: #1a3060;
  --accent-ink: #fdfbf7;
  /* The offer strip on the card: the accent at 6%, so it reads as the same
     colour as the button rather than a second one. */
  --accent-tint: rgba(35, 64, 124, 0.06);
  /* The product shots carry their own white ground, and the card image and the
     end-on figure are cropped, so the ground has to be painted behind them. */
  --card-image-bg: #ffffff;
  --shadow: 0 1px 2px rgba(25, 23, 19, 0.14);
  --shadow-sticky: 0 -6px 18px rgba(25, 23, 19, 0.07);
  --serif: Georgia, "Iowan Old Style", "Times New Roman", Times, serif;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --radius: 0.5rem;
  --radius-sm: 0.375rem;
  --radius-lg: 0.75rem;
  --measure: 34rem;
  /* 62 to 66 characters of Georgia at the desktop story size. Wider and the
     eye loses the line return, which is what kills long-copy read-through. */
  --measure-wide: 36rem;
  --rail-width: 22rem;
  --bar-height: 5.25rem;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 1.0625rem/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

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

/* `viewport-fit=cover` puts the document under the rounded corners and the
   landscape sensor housing, so every full-bleed surface has to pay the side
   insets itself. Without these, a phone held sideways clips the top bar's CTA
   and the first character of every line of the story. */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.625rem max(1.25rem, env(safe-area-inset-right)) 0.625rem
    max(1.25rem, env(safe-area-inset-left));
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}

.topbar__label {
  margin: 0;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.topbar__link {
  /* 48px tap target without a 48px-looking button: the padding does the work
     and the negative margin keeps it from pushing the bar taller. */
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  margin: -0.5rem -0.5rem -0.5rem 0;
  padding: 0 0.5rem;
  color: var(--accent);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
  border-bottom: none;
}

/* ----- layout ------------------------------------------------------------ */

.wrap {
  padding: 0 max(1.25rem, env(safe-area-inset-right)) 0 max(1.25rem, env(safe-area-inset-left));
}

.layout {
  max-width: var(--measure);
  margin: 0 auto;
}

/* ----- the lede ---------------------------------------------------------- */

/* The bottom padding is what used to be the hero figure's top margin. With the
   photo moved into the story, the disclosure line and the opening sentence sat
   flush against each other and read as one paragraph. */
.lede {
  padding: 2.25rem 0 1.25rem;
}

.lede__headline {
  margin: 0 0 1rem;
  font-family: var(--serif);
  font-size: clamp(1.875rem, 7.5vw, 2.5rem);
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

.lede__dek {
  margin: 0 0 1.25rem;
  font-family: var(--serif);
  font-size: 1.1875rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.lede__byline {
  margin: 0 0 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.lede__disclosure {
  margin: 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-faint);
}

/* ----- figures ----------------------------------------------------------- */

.figure {
  margin: 1.75rem 0 0;
}

.figure img {
  width: 100%;
  border-radius: var(--radius-sm);
  /* The product shots carry their own white ground, which would otherwise bleed
     into the cream page with no edge. */
  border: 1px solid var(--line-soft);
}

/* Cropped, not letterboxed: the source is a 1:1 export and a square block of
   pillow inside the story is a long scroll past a photo the reader has already
   read. The crop takes empty bedding off the top and bottom, not the pillow. */
.figure--break {
  margin: 2rem 0;
}

.figure--break img {
  aspect-ratio: 5 / 4;
  object-fit: cover;
}

/* Matches the file's own aspect, so the end-on profile is never clipped: the
   raised ends ARE the point of the shot and a cover crop eats them first. */
.figure--mech img {
  aspect-ratio: 1294 / 752;
  object-fit: cover;
  background: var(--card-image-bg);
}

.figure figcaption {
  margin-top: 0.625rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-faint);
}

/* ----- the story --------------------------------------------------------- */

/* 17px, not 18px. Georgia runs large for its point size, and at 18/1.7 a 390px
   screen took about 44 characters a line, which turns a 1000-word story into a
   scroll nobody finishes. 17/1.65 buys back roughly a line in six. */
.story {
  font-family: var(--serif);
  font-size: 1.0625rem;
  line-height: 1.65;
}

.story p {
  margin: 0 0 1.25rem;
}

.story__opening {
  font-size: 1.25rem;
  line-height: 1.6;
}

.story h2 {
  margin: 2.25rem 0 0.875rem;
  font-size: 1.1875rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.005em;
}

.quote {
  margin: 1.75rem 0;
  padding: 0 0 0 1.25rem;
  border-left: 3px solid var(--accent);
  color: var(--ink-soft);
}

.quote p:last-child {
  margin-bottom: 0;
}

.story__signoff {
  font-style: italic;
  color: var(--ink-soft);
}

.story__note {
  margin: 2rem 0 0;
  font-family: var(--sans);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--ink-faint);
}

.story__note + .story__cta {
  margin-top: 0.875rem;
}

.story__cta {
  margin: 2rem 0;
  padding: 1.5rem 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  font-family: var(--sans);
  text-align: center;
}

/* ----- mechanism --------------------------------------------------------- */

.mech {
  margin-top: 2.75rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
}

.mech__title {
  margin: 0 0 1.25rem;
  font-family: var(--serif);
  font-size: 1.375rem;
  font-weight: 700;
  line-height: 1.25;
}

.mech__steps {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: mech;
}

.mech__steps li {
  display: flex;
  gap: 0.875rem;
  padding: 0.875rem 0;
  border-top: 1px solid var(--line-soft);
  counter-increment: mech;
}

.mech__steps li:first-child {
  border-top: none;
}

/* The number IS the illustration. No icons, no diagram: three counted lines
   are the least that can carry a three-step mechanism. */
.mech__steps li::before {
  content: counter(mech);
  flex: 0 0 auto;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 0.875rem;
  font-weight: 700;
  line-height: 1.75rem;
  text-align: center;
}

.mech__step {
  line-height: 1.55;
}

/* ----- product card ------------------------------------------------------ */

.layout__aside {
  margin-top: 2.75rem;
}

.card {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--paper-raised);
}

.card__image {
  width: 100%;
  /* The file is already cropped to the pillow, so this aspect matches its own
     and nothing is clipped. */
  aspect-ratio: 1226 / 613;
  object-fit: cover;
  background: var(--card-image-bg);
  border-bottom: 1px solid var(--line-soft);
}

.card__body {
  padding: 1.125rem;
}

.card__title {
  margin: 0 0 0.5rem;
  font-family: var(--serif);
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1.25;
}

.card__desc {
  margin: 0 0 0.875rem;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.card__points {
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
  font-size: 0.9375rem;
  line-height: 1.5;
}

.card__points li {
  position: relative;
  padding: 0.4375rem 0 0.4375rem 1.375rem;
  border-top: 1px solid var(--line-soft);
}

.card__points li::before {
  content: "";
  position: absolute;
  left: 0.25rem;
  top: 1rem;
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: var(--accent);
}

.card__offer {
  margin: 0 0 0.875rem;
  padding: 0.625rem 0.75rem;
  border-radius: var(--radius-sm);
  background: var(--accent-tint);
  color: var(--accent-deep);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.45;
}


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

.btn {
  display: block;
  min-height: 3rem;
  padding: 0.875rem 1.5rem;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
}

.btn--primary {
  box-shadow: var(--shadow);
}

.btn__note {
  display: block;
  margin-top: 0.75rem;
  font-size: 0.8125rem;
  color: var(--ink-faint);
}

.btn--ghost {
  display: inline-block;
  min-height: 0;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
}

.btn--sticky {
  flex: 0 0 auto;
  min-height: 2.875rem;
  padding: 0.75rem 1.125rem;
  font-size: 1rem;
  white-space: nowrap;
}

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

.faq {
  margin-top: 2.75rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
}

.faq__title {
  margin: 0 0 1rem;
  font-family: var(--serif);
  font-size: 1.375rem;
  font-weight: 700;
}

.faq__item {
  border-top: 1px solid var(--line-soft);
}

.faq__item:last-of-type {
  border-bottom: 1px solid var(--line-soft);
}

.faq__item summary {
  display: flex;
  align-items: center;
  min-height: 3rem;
  padding: 0.75rem 1.75rem 0.75rem 0;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  position: relative;
}

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

.faq__item summary::after {
  content: "";
  position: absolute;
  right: 0.375rem;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 2px solid var(--ink-faint);
  border-bottom: 2px solid var(--ink-faint);
  transform: translateY(-0.15rem) rotate(45deg);
}

.faq__item[open] summary::after {
  transform: translateY(0.1rem) rotate(225deg);
}

.faq__item p {
  margin: 0 0 1rem;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

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

/* Hidden with visibility rather than a transform alone: a bar that is merely
   moved off screen still takes clicks meant for the footer under it. */
.sticky {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  visibility: hidden;
  opacity: 0;
  transform: translateY(100%);
  padding: 0.625rem max(1.25rem, env(safe-area-inset-right))
    calc(0.625rem + env(safe-area-inset-bottom)) max(1.25rem, env(safe-area-inset-left));
  background: var(--paper-raised);
  border-top: 1px solid var(--line);
  box-shadow: var(--shadow-sticky);
  transition:
    transform 0.18s ease,
    opacity 0.18s ease,
    visibility 0s linear 0.18s;
}

.sticky.is-visible {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition-delay: 0s;
}

.sticky__inner {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  max-width: var(--measure);
  margin: 0 auto;
}

.sticky__thumb {
  flex: 0 0 auto;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: var(--radius);
  object-fit: cover;
}

/* min-width 0 so the name can ellipsise instead of pushing the button off the
   right edge; the button keeps its full label, the name gives way. */
.sticky__text {
  flex: 1 1 auto;
  min-width: 0;
}

.sticky__name {
  margin: 0;
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1.25;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sticky__note {
  margin: 0.125rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.3;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

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

}

/* ----- footer ------------------------------------------------------------ */

.footer {
  border-top: 1px solid var(--line);
  margin-top: 3rem;
  padding: 2rem max(1.25rem, env(safe-area-inset-right)) 2rem
    max(1.25rem, env(safe-area-inset-left));
  /* Room for the sticky bar so it can never sit over the privacy link, which
     is the one link on the page a person actually has to be able to reach. */
  padding-bottom: calc(2rem + var(--bar-height) + env(safe-area-inset-bottom));
  color: var(--ink-faint);
  font-size: 0.8125rem;
  line-height: 1.5;
  text-align: center;
}

.footer a {
  color: var(--ink-soft);
}

.footer__links,
.footer__note {
  margin: 0 auto 0.5rem;
  max-width: 30rem;
}

/* ----- the shared /privacy/ page ---------------------------------------- */

/* Same side insets as the story page: /privacy/ is served under the same
   `viewport-fit=cover` head, and it is the page carrying the contact address
   and the operating business, so it is the last one that may clip. */
.page {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 2rem max(1.25rem, env(safe-area-inset-right)) 0 max(1.25rem, env(safe-area-inset-left));
}

.page h1 {
  font-family: var(--serif);
  font-size: 1.75rem;
  line-height: 1.2;
}

.page table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
  margin: 1rem 0;
}

.page th,
.page td {
  text-align: left;
  vertical-align: top;
  padding: 0.5rem 0.5rem 0.5rem 0;
  border-bottom: 1px solid var(--line-soft);
}

.page h2 {
  margin: 2rem 0 0.5rem;
  font-size: 1.0625rem;
}

.page__cta {
  margin-top: 2rem;
}

/* ----- desktop ----------------------------------------------------------- */

/* The story keeps a reading measure and the product card moves into a sticky
   right column, so the offer never scrolls away from a desktop reader. The
   sticky bottom bar is then redundant and would only cover the footer. */
@media (min-width: 60rem) {
  .layout {
    display: grid;
    max-width: 65rem;
    grid-template-columns: minmax(0, 1fr) var(--rail-width);
    grid-template-areas:
      "top aside"
      "bottom aside";
    align-items: start;
    column-gap: 3.5rem;
  }

  .layout__top {
    grid-area: top;
    min-width: 0;
  }

  .layout__bottom {
    grid-area: bottom;
    min-width: 0;
  }

  .layout__aside {
    grid-area: aside;
    align-self: start;
    position: sticky;
    /* Clear of the top bar with a little air, so the card lands high enough
       that its CTA sits above the fold on a 1280x800 screen. */
    top: 1.5rem;
    margin-top: 0.5rem;
  }

  .lede {
    padding-top: 2.75rem;
  }

  .lede__headline {
    font-size: 2.75rem;
  }

  .story {
    max-width: var(--measure-wide);
  }

  .story__opening {
    font-size: 1.3125rem;
  }

  /* Pinned to the story's own measure. The grid column is wider than the
     measure the story keeps, so an unconstrained mechanism and FAQ stepped out
     past the left-hand text edge they are meant to read as a continuation of. */
  .mech,
  .faq {
    max-width: var(--measure-wide);
  }

  .sticky {
    display: none;
  }

  .footer {
    padding-bottom: 2rem;
  }
}
