/* Fit Legacy — one stylesheet, no framework, no build step.
   System fonts on purpose: a webfont is a render-blocking request on every page,
   and the old WordPress site's biggest speed problem was exactly that weight.

   Brand palette, as supplied:
     #241C63  deep indigo   — the father in the logo
     #FFFFFF  white
     #6A4F90  muted purple  — the child, and the wordmark

   Two grounds. Indigo carries the header, hero and footer, where the white
   logo sits and the brand should be loudest. White carries the reading
   surfaces, because there are 103 articles here and long-form text on a
   saturated indigo is punishing. --purple-lift is a tint of the brand purple,
   derived only because #6A4F90 on #241C63 is 1.9:1 — invisible. It is not a
   fourth brand colour; it is the same colour made legible on the dark ground. */

:root {
  --indigo:      #241C63;
  --indigo-deep: #1a1449;
  --indigo-soft: #2e2578;
  --white:       #ffffff;
  --purple:      #6a4f90;
  --purple-lift: #b6a0d4;   /* for use on indigo only — 7.4:1 there */
  --purple-wash: #f1ecfa;

  --paper:     #ffffff;
  --paper-alt: #f4f3f8;
  --sand:      #faf6f0;   /* warm band, so three surfaces read as three */
  --ink:       #1d1a2e;
  --night:     #100e1a;   /* the footer, dark enough to need white text */
  --ink-dim:   #5b5670;
  --line:      #e2dfeb;
  --line-dark: #3b3280;

  /* Amber, not the old lime. Amber sits opposite indigo on the wheel, so it is
     the loudest a single accent can be against this palette; lime is merely
     brighter, which on a refined indigo reads cheap rather than urgent. Indigo
     text on it measures 6.9:1 — comfortably AA, and AAA at button size. It also
     happens to echo the gold in "legacy". */
  --cta:        #f2a03d;
  --cta-ink:    #9a5c05;   /* the CTA orange, darkened to pass on paper */
  --cta-bright: #ffb257;

  --ok:  #2f7d51;
  --err: #b23b22;

  --measure: 38rem;
  --wide:    68rem;
  --radius:  10px;
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 1.0625rem/1.65 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

img, video { max-width: 100%; height: auto; display: block; }
a { color: var(--purple); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--indigo); }

h1, h2, h3, h4 {
  line-height: 1.14; letter-spacing: -0.022em; margin: 0 0 .5em;
  font-weight: 800; color: var(--indigo);
}
h1 { font-size: clamp(2rem, 5.5vw, 3.1rem); }
h2 { font-size: clamp(1.5rem, 3.4vw, 2.05rem); margin-top: 2em; }
h3 { font-size: 1.22rem; margin-top: 1.8em; }
p, ul, ol, blockquote, figure, table { margin: 0 0 1.15em; }
ul, ol { padding-left: 1.2em; }
li { margin-bottom: .35em; }
small { color: var(--ink-dim); font-size: .875rem; }
hr { border: 0; border-top: 1px solid var(--line); margin: 2.5rem 0; }

blockquote {
  border-left: 3px solid var(--purple);
  margin-left: 0; padding: .1rem 0 .1rem 1.1rem;
  color: var(--ink-dim); font-style: italic;
}

code {
  background: var(--purple-wash); border: 1px solid var(--line);
  padding: .1em .35em; border-radius: 4px; font-size: .9em;
}

.scroll-x { overflow-x: auto; margin-bottom: 1.15em; }
table { border-collapse: collapse; width: 100%; font-size: .95rem; }
th, td { text-align: left; padding: .55rem .7rem; border-bottom: 1px solid var(--line); }
th { color: var(--indigo); font-weight: 700; font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; }

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

.wrap { width: 100%; max-width: var(--wide); margin-inline: auto; padding-inline: 1.25rem; }
.prose { max-width: var(--measure); }
/* `class="wrap prose"` on one element used to centre the text column, because
   .wrap's auto margins applied to the narrow measure. Every other section
   starts at the container gutter, so this one looked misaligned. Keep the
   container width, constrain the children instead. */
.wrap.prose { max-width: var(--wide); }
.wrap.prose > * { max-width: var(--measure); }
.prose img { border-radius: var(--radius); margin: 1.5rem 0; }

/* Vertical rhythm. These were roomier and the page read as mostly gaps; a
   section needs enough air to separate from its neighbour and no more. */
.section { padding-block: clamp(2.5rem, 5.5vw, 3.75rem); }
.section--tight { padding-block: clamp(1.75rem, 3.5vw, 2.5rem); }

/* Four surfaces, each obviously different from the one above it: white,
   a lilac wash, a warm grey, and the brand indigo. Two off-whites a few
   percent apart just look like a rendering fault. */
.section--alt   { background: var(--paper-alt); border-block: 1px solid var(--line); }
.section--wash  { background: var(--purple-wash); border-block: 1px solid #e6e0f1; }
.section--proof { background: var(--sand); border-block: 1px solid #e9e1d6; }

/* The first heading in a section already has the section's own padding above
   it; the 2em top margin on h2 was doubling it. */
.section > .wrap > .prose > h2:first-child,
.section > .wrap > .prose > *:first-child { margin-top: 0; }

/* Indigo surfaces: anything inside inverts. */
.section--brand, .hero {
  background: var(--indigo); color: rgba(255,255,255,.88);
}
.section--brand h1, .section--brand h2, .section--brand h3,
.hero h1, .hero h2, .hero h3 { color: var(--white); }
.section--brand a, .hero a { color: var(--purple-lift); }
.section--brand a:hover, .hero a:hover { color: var(--white); }

/* ---------- header ----------
   White at rest with the colour logo; indigo with the white logo once the page
   scrolls. Both marks sit in the DOM and swap by opacity inside a fixed-height
   box, so neither the swap nor the image load moves anything. */

.site-head {
  position: sticky; top: 0; z-index: 50;
  background: var(--white);
  border-bottom: 1px solid var(--line);
  transition: background-color .25s ease, border-color .25s ease;
}
.site-head__inner {
  display: flex; align-items: center; gap: 1.5rem;
  min-height: 64px; padding-block: .55rem;
}

/* The colour mark stays in flow so it gives .brand its width; only the white
   one is lifted out and overlaid. Absolutely positioning both collapses the
   anchor to zero width and the logo disappears entirely. */
.brand { display: block; flex: none; position: relative; }
.brand .mark { display: block; transition: opacity .25s ease; }
.brand .mark--white { position: absolute; inset: 0; opacity: 0; }
.brand img { height: 34px; width: auto; display: block; }

.nav { margin-left: auto; display: flex; flex-wrap: wrap; gap: 1.1rem; align-items: center; }
.nav a {
  color: var(--indigo); text-decoration: none; font-size: .95rem; font-weight: 600;
  transition: color .25s ease;
}
.nav a:hover { color: var(--purple); }
.nav a[aria-current="page"] { color: var(--purple); text-decoration: underline;
  text-decoration-thickness: 2px; text-underline-offset: 6px; }

/* Scrolled */
.site-head.is-scrolled {
  background: rgba(36,28,99,.94);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom-color: var(--line-dark);
}
.site-head.is-scrolled .mark--colour { opacity: 0; }
.site-head.is-scrolled .mark--white  { opacity: 1; }
.site-head.is-scrolled .nav a { color: rgba(255,255,255,.78); }
.site-head.is-scrolled .nav a:hover,
.site-head.is-scrolled .nav a[aria-current="page"] { color: var(--white); }

@media (prefers-reduced-motion: reduce) {
  .site-head, .brand .mark, .nav a { transition: none; }
}

/* ---------- mobile nav ----------
   The bar stays one row on a phone; the links move behind a toggle. Hidden
   with [hidden] rather than display:none in a class, so it stays closed for
   anyone without JavaScript and the button is never shown to them either. */

.nav-toggle {
  display: none; margin-left: auto;
  width: 44px; height: 44px;              /* 44px is the smallest comfortable tap target */
  padding: 0; border: 0; background: none; cursor: pointer;
  align-items: center; justify-content: center;
}
.nav-toggle__bars, .nav-toggle__bars::before, .nav-toggle__bars::after {
  display: block; width: 22px; height: 2px; border-radius: 2px;
  background: var(--indigo); transition: transform .2s ease, opacity .2s ease, background-color .25s ease;
}
.nav-toggle__bars::before, .nav-toggle__bars::after { content: ""; position: absolute; }
.nav-toggle__bars::before { transform: translateY(-7px); }
.nav-toggle__bars::after  { transform: translateY(7px); }
.site-head.is-scrolled .nav-toggle__bars,
.site-head.is-scrolled .nav-toggle__bars::before,
.site-head.is-scrolled .nav-toggle__bars::after { background: var(--white); }

/* Open: the middle bar disappears and the outer two cross. */
.nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after  { transform: rotate(-45deg); }

@media (max-width: 44rem) {
  .site-head__inner { min-height: 56px; }
  .nav-toggle { display: flex; position: relative; }
  .brand img { height: 28px; }

  /* The base rule sets .nav{display:flex}, and an author declaration beats the
     browser's built in [hidden]{display:none}. Without this the panel stayed
     open however the attribute was set, which is exactly what went wrong. */
  .nav[hidden] { display: none; }

  .nav {
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 0;
    margin: 0; padding: .5rem 1.25rem 1.25rem;
    background: var(--white);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 12px 28px rgba(36,28,99,.14);
  }
  .nav a {
    padding: .85rem 0; font-size: 1.05rem;
    border-bottom: 1px solid var(--line);
  }
  .nav a:last-child { border-bottom: 0; }
  .nav a[aria-current="page"] { text-decoration: none; }

  /* Scrolled, the panel matches the bar rather than staying white. */
  .site-head.is-scrolled .nav { background: var(--indigo); border-bottom-color: var(--line-dark); }
  .site-head.is-scrolled .nav a { border-bottom-color: rgba(255,255,255,.14); }
}

@media (min-width: 44.0625rem) {
  .nav[hidden] { display: flex; }   /* the toggle's state must not leak to desktop */
}

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

.hero { padding-block: clamp(3.5rem, 10vw, 6.5rem); }
.hero h1 { max-width: 17ch; }
.hero__lede { font-size: clamp(1.1rem, 2.2vw, 1.3rem); color: rgba(255,255,255,.82); max-width: 46ch; }
.eyebrow {
  text-transform: uppercase; letter-spacing: .14em; font-size: .75rem;
  color: var(--purple-lift); font-weight: 700; margin-bottom: 1rem;
}
.section .eyebrow { color: var(--purple); }

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

/* The CTA colour is the one thing on the page that means "act", so it appears
   on buttons and nowhere else — the moment it also decorates a heading or a
   border it stops being a signal. Indigo text on it, never white: #241C63 on
   #F2A03D measures 6.9:1, white would be 2.1:1 and unreadable. */
.btn {
  display: inline-block; padding: .8rem 1.55rem; border-radius: var(--radius);
  background: var(--cta); color: var(--indigo); font-weight: 700; font-size: 1rem;
  text-decoration: none; border: 0; cursor: pointer; line-height: 1.3;
  transition: background .15s ease, transform .1s ease;
}
.btn:hover { background: var(--cta-bright); color: var(--indigo); }
.btn:active { transform: translateY(1px); }

/* `.hero a` and `.section--brand a` are (0,1,1) and beat a bare `.btn` (0,1,0),
   so on indigo the button inherited the link colour and the label vanished into
   the fill. These restate it at equal specificity. */
.hero .btn, .section--brand .btn { color: var(--indigo); }
.hero .btn:hover, .section--brand .btn:hover { color: var(--indigo); }

.btn--ghost { background: transparent; color: var(--indigo); border: 1px solid var(--line); }
.btn--ghost:hover { background: var(--purple-wash); color: var(--indigo); }
.hero .btn--ghost, .section--brand .btn--ghost {
  background: transparent; color: var(--white); border-color: rgba(255,255,255,.45);
}
.hero .btn--ghost:hover, .section--brand .btn--ghost:hover {
  background: rgba(255,255,255,.1); color: var(--white);
}
.btn--wide { width: 100%; text-align: center; }
.btn[disabled] { opacity: .6; cursor: progress; }

/* ---------- cards ---------- */

.grid { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
.card {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.4rem;
}
.section--alt .card,
.section--wash .card,
.section--proof .card { background: var(--paper); }
.card h3 { margin-top: 0; }
.card p:last-child { margin-bottom: 0; }
.card--link { text-decoration: none; color: inherit; display: block; transition: border-color .15s, box-shadow .15s; }
.card--link:hover { border-color: var(--purple); box-shadow: 0 2px 14px rgba(36,28,99,.09); color: inherit; }

.price { font-size: 1.6rem; font-weight: 800; letter-spacing: -.02em; color: var(--indigo); }
.price small { display: block; font-weight: 400; font-size: .85rem; color: var(--ink-dim); }

/* ---------- opt-in form ---------- */

.optin {
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.5rem;
  box-shadow: 0 4px 24px rgba(36,28,99,.13);
}
.optin label { display: block; font-size: .85rem; color: var(--ink-dim); margin-bottom: .3rem; }
.optin input[type="email"], .optin input[type="text"] {
  width: 100%; padding: .75rem .85rem; margin-bottom: .9rem;
  background: var(--paper-alt); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius); font-size: 1rem;
}
.optin input:focus-visible, .btn:focus-visible, a:focus-visible {
  outline: 2px solid var(--purple); outline-offset: 2px;
}
.hero a:focus-visible, .site-head a:focus-visible { outline-color: var(--purple-lift); }
.optin__note { margin: .8rem 0 0; font-size: .8rem; color: var(--ink-dim); }
.form-msg { margin-top: .9rem; font-size: .9rem; }
.form-msg--ok  { color: var(--ok); }
.form-msg--err { color: var(--err); }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---------- post list ---------- */

.post-list { list-style: none; padding: 0; margin: 0; }
.post-list li { border-bottom: 1px solid var(--line); }
.post-list a { display: block; padding: 1rem 0; text-decoration: none; color: var(--indigo); font-weight: 600; }
.post-list a:hover { color: var(--purple); }
.post-list time { display: block; font-size: .8rem; color: var(--ink-dim); margin-top: .2rem; font-weight: 400; }

.post-meta { color: var(--ink-dim); font-size: .9rem; margin-bottom: 2rem; }

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

/* Near black, not another indigo. Stacked under an indigo band and an indigo
   header, three shades of the same colour read as a rendering fault rather
   than as three sections. */
.site-foot {
  background: var(--night); color: rgba(255,255,255,.72);
  padding-block: 3rem; font-size: .9rem;
  border-top: 1px solid rgba(255,255,255,.08);
}
.site-foot strong { color: var(--white); }
.site-foot a { color: rgba(255,255,255,.7); text-decoration: none; }
.site-foot a:hover { color: var(--white); text-decoration: underline; }
.site-foot__cols { display: flex; flex-wrap: wrap; gap: 2rem 3rem; }
.site-foot ul { list-style: none; padding: 0; margin: 0; }
.site-foot li { margin-bottom: .4rem; }
.site-foot img { height: 40px; width: auto; margin-bottom: .8rem; }

.skip {
  position: absolute; left: -9999px;
  background: var(--purple); color: var(--white); padding: .6rem 1rem; border-radius: 0 0 var(--radius) 0;
}
.skip:focus { left: 0; top: 0; z-index: 100; }

/* ---------- imagery ---------- */

/* Home hero: text and photograph side by side, stacking on a phone with the
   image first so the page does not open on a wall of words. */
.hero__grid {
  display: grid; gap: 2.5rem;
  grid-template-columns: 1fr;
  align-items: center;
}
.hero__media picture, .hero__media img { display: block; width: 100%; }
.hero__media img {
  border-radius: var(--radius);
  aspect-ratio: 3 / 2; object-fit: cover;
}
@media (min-width: 52rem) {
  .hero__grid { grid-template-columns: 1.05fr .95fr; gap: 3.5rem; }
}
@media (max-width: 52rem) {
  .hero--split .hero__media { order: -1; }
}

/* A banner across the top of a content page. */
.page-banner img {
  width: 100%; border-radius: var(--radius);
  aspect-ratio: 16 / 7; object-fit: cover;
}

/* The transformation grid is wide and detailed; let it run full width of the
   container and keep its own proportions rather than being cropped hard. */
.proof-grid { display: block; margin-top: 1.75rem; }
.proof-grid img {
  width: 100%; border-radius: var(--radius);
  border: 1px solid var(--line);
}

/* Featured image at the top of a migrated post. The old site had one on every
   article, so without it they look stripped next to what Google indexed.

   No forced aspect ratio here, deliberately. These are designed banners with
   the article title set into the artwork, roughly 8:3; cropping them to 16:9
   cut the words in half. They keep their own proportions. */
.post-hero { display: block; margin: 0 0 2rem; }
.post-hero img { width: 100%; height: auto; border-radius: var(--radius); }

/* ---------- proof ---------- */

.stats {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  text-align: center;
}
.stats li { margin: 0; }
.stats strong {
  display: block; font-size: clamp(2rem, 5vw, 2.8rem); font-weight: 800;
  color: var(--indigo); letter-spacing: -.03em; line-height: 1.05;
}
.stats span { display: block; margin-top: .4rem; color: var(--ink-dim); font-size: .95rem; }

/* A member's own words, set apart from the page rather than dropped into it. */
.quote {
  position: relative;
  margin: 2rem auto 0; max-width: 44rem;
  background: var(--paper); border: 1px solid var(--line);
  border-left: 4px solid var(--purple);
  border-radius: var(--radius); padding: 2rem 2rem 1.5rem;
}
/* An actual quotation mark. Set in a serif because the body face has no
   convincing one at this size, and pushed out of the flow so it does not
   indent the first line. */
.quote::before {
  content: "\201C";
  position: absolute; top: .35rem; left: 1.1rem;
  font: 700 3.6rem/1 Georgia, "Times New Roman", serif;
  color: var(--purple-lift); pointer-events: none;
}
.quote blockquote {
  margin: 0; padding: 0; border: 0; font-style: normal;
  font-size: 1.1rem; line-height: 1.6; color: var(--ink);
}
/* No inline marks as well: the display glyph above is the quotation mark,
   and doing both reads as a typo. */
.quote figcaption { margin-top: 1rem; color: var(--ink-dim); font-size: .9rem; font-weight: 600; }

/* ---------- blog index ---------- */

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

.blog-search input {
  width: 100%; max-width: 26rem; padding: .8rem 1rem;
  font-size: 1rem; color: var(--ink);
  background: var(--paper-alt); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.blog-search input:focus-visible { outline: 2px solid var(--purple); outline-offset: 2px; }

.chips { display: flex; flex-wrap: wrap; gap: .5rem; }
.chip {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .35rem .75rem; border-radius: 999px;
  font: 600 .85rem/1.4 inherit; color: var(--purple);
  background: var(--purple-wash); border: 1px solid transparent;
  text-decoration: none; cursor: pointer;
}
.chip span { color: var(--ink-dim); font-weight: 400; }
.chip--filter:hover { border-color: var(--purple); }
.chip--filter.is-on { background: var(--indigo); color: var(--white); }
.chip--filter.is-on span { color: rgba(255,255,255,.7); }
.post-meta .chip { margin-left: .5rem; }

.blog-count { color: var(--ink-dim); font-size: .9rem; margin: 0 0 1.75rem; }
.blog-empty { color: var(--ink-dim); }
.linkish {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--purple); font: inherit; text-decoration: underline;
}

.post-grid {
  display: grid; gap: 1.5rem;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
}
.post-card {
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: var(--paper);
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.post-card:hover { border-color: var(--purple); box-shadow: 0 4px 20px rgba(36,28,99,.1); transform: translateY(-2px); }
.post-card__link { display: block; text-decoration: none; color: inherit; height: 100%; }
.post-card__img img { width: 100%; aspect-ratio: 8 / 3; object-fit: cover; }
.post-card__body { padding: 1.1rem 1.2rem 1.4rem; }
.post-card__meta { color: var(--ink-dim); font-size: .8rem; margin: 0 0 .4rem; }
.post-card h3 { margin: 0 0 .5rem; font-size: 1.05rem; line-height: 1.3; }
.post-card p:last-child { margin: 0; font-size: .92rem; color: var(--ink-dim); line-height: 1.5; }

/* The end of an article is the only place a reader is definitely paying
   attention, and for 103 posts it previously led nowhere at all. */
.post-tail h2 { font-size: 1.5rem; }
.post-tail .grid { grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.post-tail .card h3 { font-size: 1rem; }

/* ---------- proof, used on several pages ---------- */

.quotes { display: grid; gap: 1.25rem; margin-top: 2rem; }
@media (min-width: 60rem) {
  .quotes { grid-template-columns: repeat(3, 1fr); align-items: start; }
  .quotes .prose { grid-column: 1 / -1; }
}
.quotes .quote { margin: 0; max-width: none; padding: 2.25rem 1.5rem 1.25rem; }
.quotes .quote::before { top: .1rem; left: 1.2rem; font-size: 3rem; }
.quotes .quote blockquote { font-size: .98rem; line-height: 1.55; }

/* Thumbnails of real screenshots, opening the original in a new tab. A tall
   phone capture is unreadable inline but perfectly good full size. */
.proof-tiles {
  display: grid; gap: 1rem; margin-top: 1.75rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.proof-tiles--messages { grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }
.proof-tiles--squares  { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.proof-tile {
  display: block; position: relative; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--paper); text-decoration: none;
  transition: border-color .15s ease, transform .15s ease;
}
.proof-tile:hover { border-color: var(--purple); transform: translateY(-2px); }
/* Each gallery is built from screenshots that share one shape, so the ratio
   here is the screenshots' own and nothing is ever cropped. A grid mixing
   shapes reads as broken however good the individual images are, which is why
   the CalorieBot captures are laid out one per row instead. */
.proof-tile img { width: 100%; display: block; }
.proof-tiles--messages .proof-tile img { aspect-ratio: 2 / 1; }
.proof-tiles--squares  .proof-tile img,
.proof-tile--square img { aspect-ratio: 1 / 1; }
.proof-tile span {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: .75rem .9rem .6rem;
  font-size: .8rem; font-weight: 600; color: var(--white);
  background: linear-gradient(to top, rgba(10,8,30,.9), rgba(10,8,30,0));
}

.proof-demo { max-width: 26rem; margin: 2.5rem auto; text-align: center; }
.proof-demo img { width: 100%; border: 1px solid var(--line); border-radius: var(--radius); }
.proof-demo p { margin-top: .75rem; }

/* ---------- lead magnet offers inside an article ---------- */

/* A free guide, offered partway down a post where the reader has already
   decided the writing is worth their time. Deliberately not styled as an ad:
   it is the same card language as the rest of the site, one shade warmer. */
.magnet {
  margin: 2.5rem 0; padding: 1.5rem 1.6rem 1.25rem;
  background: var(--sand); border: 1px solid #e9e1d6;
  border-left: 4px solid var(--cta);
  border-radius: var(--radius);
}
.magnet h3 { margin: .15rem 0 .5rem; font-size: 1.2rem; }
.magnet p { margin: 0 0 .75rem; }
.magnet ul { margin: 0 0 1.1rem; padding-left: 1.1rem; font-size: .95rem; color: var(--ink-dim); }
.magnet li { margin-bottom: .25rem; }
.magnet__eyebrow {
  font: 700 .72rem/1 inherit; letter-spacing: .12em; text-transform: uppercase;
  color: var(--cta-ink); margin: 0 0 .5rem;
}

/* The same offer, arriving on its own once the reader is clearly reading.
   Bottom right on a desktop, a full-width strip across the foot of a phone,
   where a floating box would cover the text being read. */
.flyin {
  position: fixed; z-index: 60;
  right: 1.25rem; bottom: 1.25rem; width: min(21rem, calc(100vw - 2.5rem));
  padding: 1.25rem 1.35rem 1rem;
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--line); border-top: 4px solid var(--cta);
  border-radius: var(--radius);
  box-shadow: 0 12px 40px rgba(29,26,46,.22);
  transform: translateY(1.5rem); opacity: 0;
  transition: transform .3s ease, opacity .3s ease;
}
.flyin.is-in { transform: none; opacity: 1; }
.flyin h3 { margin: .1rem 0 .4rem; font-size: 1.05rem; }
.flyin p { margin: 0 0 .9rem; font-size: .92rem; color: var(--ink-dim); }
.flyin__close {
  position: absolute; top: .3rem; right: .4rem;
  width: 2rem; height: 2rem; padding: 0; cursor: pointer;
  background: none; border: 0; border-radius: 50%;
  font: 400 1.5rem/1 inherit; color: var(--ink-dim);
}
.flyin__close:hover { background: var(--paper-alt); color: var(--ink); }
@media (max-width: 34rem) {
  .flyin { left: .6rem; right: .6rem; bottom: .6rem; width: auto; padding: 1rem 1.1rem .9rem; }
}
@media (prefers-reduced-motion: reduce) {
  .flyin { transition: none; transform: none; }
}

/* ---------- small copy details ---------- */

.hero__note { margin-top: 1rem; font-size: .85rem; color: rgba(255,255,255,.62); }
.section .hero__note { color: var(--ink-dim); }

/* Cards that lead somewhere should say so; a card with no verb on it reads
   as a paragraph in a box. */
.card__go { margin-top: .9rem; font-weight: 700; color: var(--purple); }
.card__go::after { content: " \2192"; }
.card--link:hover .card__go { color: var(--indigo); }

/* Transformation photographs: portrait, so they want their own row shape and
   no caption strip over the bottom of the image. */
.proof-tiles--photos { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.proof-tiles--photos { align-items: start; }

/* Feature rows: one screenshot beside the sentence it proves, alternating
   sides. The captures are every shape imaginable, so each one keeps its own
   proportions and never has to agree with a neighbour. */
.features { display: grid; gap: clamp(2.5rem, 6vw, 4rem); margin-top: 2.5rem; }
.feature {
  display: grid; gap: 1.5rem 3rem; align-items: center;
  grid-template-columns: 1fr;
}
.feature__text h3 { margin-top: 0; font-size: 1.35rem; }
.feature__text p { margin-bottom: 0; max-width: 34ch; }
.feature__shot {
  display: block; position: relative; justify-self: start;
  max-width: 22rem; width: 100%;
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: var(--paper); text-decoration: none;
  transition: border-color .15s ease, transform .15s ease;
}
.feature__shot:hover { border-color: var(--purple); transform: translateY(-2px); }
.feature__shot img { width: 100%; height: auto; display: block; }
@media (min-width: 50rem) {
  .feature { grid-template-columns: 1fr 22rem; }
  .feature:nth-child(even) { grid-template-columns: 22rem 1fr; }
  .feature:nth-child(even) .feature__text { order: 2; }
  .feature:nth-child(even) .feature__shot { order: 1; justify-self: end; }
}
.proof-tile--tall img { aspect-ratio: auto; height: auto; }

/* ---------- article furniture ---------- */

/* A pulled-out point in the middle of a long article. Used sparingly and by
   hand, on the posts that actually get read. */
.callout {
  margin: 2rem 0; padding: 1.25rem 1.4rem;
  background: var(--purple-wash); border-left: 4px solid var(--purple);
  border-radius: var(--radius);
}
.callout p:last-child { margin-bottom: 0; }
.callout strong { color: var(--indigo); }

/* What to do and what not to, side by side, because the contrast is the
   point and a reader scanning will take both in at once. */
.do-dont { display: grid; gap: 1rem; margin: 2rem 0; }
@media (min-width: 42rem) { .do-dont { grid-template-columns: 1fr 1fr; } }
.do-dont > div {
  padding: 1.25rem 1.4rem; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--paper);
}
.do-dont h4 { margin: 0 0 .6rem; font-size: 1rem; }
.do-dont ul { margin: 0; padding-left: 1.1rem; }
.do-dont li { margin-bottom: .4rem; }
.do-dont li:last-child { margin-bottom: 0; }
.do-dont .do    { border-left: 4px solid var(--ok); }
.do-dont .dont  { border-left: 4px solid var(--err); }
.do-dont .do h4   { color: var(--ok); }
.do-dont .dont h4 { color: var(--err); }

/* The short version, at the top, for the large share of readers who will
   never reach the bottom. */
.takeaways {
  margin: 0 0 2rem; padding: 1.35rem 1.5rem 1.1rem;
  background: var(--paper-alt); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.takeaways h2 {
  margin: 0 0 .7rem !important; font-size: .78rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-dim);
}
.takeaways ul { margin: 0; padding-left: 1.15rem; }
.takeaways li { margin-bottom: .45rem; }
.takeaways li:last-child { margin-bottom: 0; }

/* Numbers a reader can take in without reading a sentence. */
.keynums {
  list-style: none; margin: 2rem 0; padding: 0;
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
}
.keynums li {
  margin: 0; padding: 1.1rem 1.2rem; text-align: center;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper);
}
.keynums strong {
  display: block; font-size: 1.7rem; font-weight: 800; letter-spacing: -.02em;
  color: var(--indigo); line-height: 1.1;
}
.keynums span { display: block; margin-top: .3rem; font-size: .85rem; color: var(--ink-dim); }

/* ---------- narrow screens ---------- */

/* Two buttons side by side do not fit on a phone, and the second one carries
   an inline left margin from the template, so it wrapped and sat indented.
   Stack them full width instead. !important is here to beat that inline
   style, which is the one place on the site where it is the lesser evil. */
@media (max-width: 30rem) {
  .hero .btn, .section .btn, .post-tail .btn {
    display: block; width: 100%; text-align: center;
    margin-left: 0 !important;
  }
  .hero .btn + .btn, .section .btn + .btn, .post-tail .btn + .btn {
    margin-top: .6rem;
  }
  /* The quote glyph takes a whole line's worth of space at this width. */
  .quote { padding: 1.75rem 1.25rem 1.1rem; }
  .quote::before { font-size: 2.8rem; left: .9rem; }
  .takeaways, .magnet { padding-inline: 1.1rem; }
}


/* ---------- the closing call to action ---------- */

/* Sits between a white section and the near black footer, so it is deliberately
   light and warm: three surfaces, three obviously different colours, and the
   orange button has something to stand on. */
.section--close {
  background: var(--sand);
  border-top: 1px solid #e9e1d6;
  text-align: center;
}
.section--close .wrap > * { margin-inline: auto; }
.section--close h2 { margin-top: 0; font-size: clamp(1.6rem, 4vw, 2.4rem); }
.section--close p { color: var(--ink-dim); }
.section--close .btn-row { margin-top: 1.75rem; justify-content: center; }

/* ---------- carousel ---------- */

/* A horizontal strip of proof. Scroll snapping does the work, so it is fully
   usable by swipe, trackpad and keyboard with no JavaScript at all; the arrows
   are added by script and only help a mouse user. */
.carousel { position: relative; margin-top: 1.75rem; }
.carousel__track {
  display: grid; grid-auto-flow: column;
  grid-auto-columns: min(24rem, 82vw);
  gap: 1rem; overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-padding-inline: 0;
  padding-bottom: .75rem;
  scrollbar-width: thin;
}
.carousel__track > * { scroll-snap-align: start; }
.carousel__btn {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 2.75rem; height: 2.75rem; border-radius: 50%;
  display: none; place-items: center; cursor: pointer;
  background: var(--paper); color: var(--indigo);
  border: 1px solid var(--line); box-shadow: 0 3px 14px rgba(29,26,46,.18);
  font: 700 1.1rem/1 inherit; z-index: 2;
}
.carousel__btn:hover { background: var(--purple-wash); }
.carousel__btn[disabled] { opacity: .35; cursor: default; }
.carousel__btn--prev { left: -1.1rem; }
.carousel__btn--next { right: -1.1rem; }
.carousel.has-buttons .carousel__btn { display: grid; }
@media (max-width: 52rem) { .carousel.has-buttons .carousel__btn { display: none; } }
.carousel .proof-tile { margin: 0; }
.carousel--square .carousel__track { grid-auto-columns: min(14rem, 52vw); }

/* ---------- lightbox ---------- */

/* Opening a screenshot in a new tab loses the page the reader was on and
   dumps them in front of a bare image with the site's chrome gone. This keeps
   them here. The markup stays a plain <a href> to the full size file, so with
   JavaScript off it still works, just as a navigation. */
.lightbox {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center;
  /* `display: grid` here beats the user agent's [hidden] { display: none },
     so without the rule below the closed overlay stays in the layout at
     opacity 0, covering the whole viewport and swallowing every click on the
     page behind it. Same trap as the mobile nav. */
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(16, 14, 26, .92);
  opacity: 0; transition: opacity .2s ease;
}
.lightbox[hidden] { display: none; }
.lightbox.is-open { opacity: 1; }
.lightbox img {
  max-width: 100%; max-height: 100%;
  border-radius: var(--radius); background: var(--paper);
  box-shadow: 0 24px 80px rgba(0,0,0,.5);
}
.lightbox__bar {
  position: absolute; top: 0; left: 0; right: 0;
  display: flex; align-items: center; gap: .75rem;
  padding: .75rem 1rem; color: rgba(255,255,255,.8); font-size: .85rem;
}
.lightbox__count { margin-right: auto; }
.lightbox__btn {
  width: 2.75rem; height: 2.75rem; flex: none;
  display: grid; place-items: center; cursor: pointer;
  background: rgba(255,255,255,.1); color: var(--white);
  border: 0; border-radius: 50%; font: 700 1.2rem/1 inherit;
}
.lightbox__btn:hover { background: rgba(255,255,255,.22); }
.lightbox__btn[disabled] { opacity: .3; cursor: default; }
.lightbox__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 3.25rem; height: 3.25rem;
}
.lightbox__nav--prev { left: clamp(.4rem, 2vw, 1.5rem); }
.lightbox__nav--next { right: clamp(.4rem, 2vw, 1.5rem); }
body.lightbox-open { overflow: hidden; }
@media (prefers-reduced-motion: reduce) { .lightbox { transition: none; } }


/* ---------- copy details ---------- */

/* Two buttons on one line, with the gap in the stylesheet rather than an
   inline margin on the second one. */
.btn-row { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 2rem; }
.section .btn-row, .prose .btn-row { margin-top: 1.75rem; }

.section__more { margin-top: 1.75rem; font-weight: 600; }

/* A testimonial that links to the screenshot it was taken from. A quote a
   reader can check is worth several they cannot. */
.quote figcaption { display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem; }
.quote__proof {
  font-weight: 600; font-size: .82rem; color: var(--purple);
  text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}
.quote__proof::before { content: "\2197\00a0"; text-decoration: none; }
.quote__proof:hover { color: var(--indigo); }

/* ---------- blog index ---------- */

/* The topic filter used to be a row of chips above the grid, which on a phone
   pushed every article below the fold before anyone had asked to filter
   anything. It is a sidebar where there is room and a single disclosure line
   where there is not. */
.blog-layout { display: grid; gap: 2rem; }
@media (min-width: 62rem) {
  .blog-layout { grid-template-columns: 15rem 1fr; gap: 3rem; align-items: start; }
  .blog-side { position: sticky; top: 5.5rem; }
}
.blog-side { display: grid; gap: 1rem; align-content: start; }

.topics > summary {
  cursor: pointer; list-style: none;
  padding: .7rem .9rem; border-radius: var(--radius);
  background: var(--paper-alt); border: 1px solid var(--line);
  font-weight: 600; color: var(--indigo);
}
.topics > summary::-webkit-details-marker { display: none; }
.topics > summary::after { content: " \25be"; float: right; }
.topics[open] > summary::after { content: " \25b4"; }
.topics__list { display: grid; gap: .25rem; margin-top: .6rem; }
@media (min-width: 62rem) {
  .topics > summary { background: none; border: 0; padding: 0 0 .4rem;
    font-size: .78rem; letter-spacing: .1em; text-transform: uppercase;
    color: var(--ink-dim); cursor: default; }
  .topics > summary::after { content: ""; }
}
.topic {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  width: 100%; padding: .5rem .75rem; cursor: pointer;
  background: none; border: 1px solid transparent; border-radius: var(--radius);
  font: 600 .92rem/1.3 inherit; color: var(--indigo); text-align: left;
}
.topic span { font-weight: 400; color: var(--ink-dim); font-size: .82rem; }
.topic:hover { background: var(--purple-wash); }
.topic.is-on { background: var(--indigo); color: var(--white); }
.topic.is-on span { color: rgba(255,255,255,.7); }

/* ---------- lead magnets ---------- */

.optin-grid {
  display: grid; gap: 2.5rem;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  align-items: start;
}
.magnet-shot img, .card--shot img, .magnet-lead img {
  width: 100%; display: block; aspect-ratio: 3 / 2; object-fit: cover;
}
.magnet-shot { display: block; margin-top: 2rem; }
.magnet-shot img { border-radius: var(--radius); }

.grid--shots .card--shot { padding: 0; overflow: hidden; }
.card--shot .card__body { padding: 1.2rem 1.35rem 1.4rem; }
.card--shot h3 { margin-top: 0; }

/* The guide most people want, given the room that deserves. */
.magnet-lead {
  display: grid; gap: 0; text-decoration: none; color: inherit;
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: var(--paper);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.magnet-lead:hover { border-color: var(--purple); box-shadow: 0 4px 20px rgba(36,28,99,.1); color: inherit; }
.magnet-lead > div { padding: 1.75rem 1.9rem; align-self: center; }
.magnet-lead h2 { margin: .2rem 0 .6rem; font-size: clamp(1.3rem, 2.6vw, 1.75rem); }
.magnet-lead p { margin: 0; }
@media (min-width: 46rem) {
  .magnet-lead { grid-template-columns: 1fr 1fr; }
  .magnet-lead img { height: 100%; aspect-ratio: auto; }
}

/* ---------- products ---------- */

.compare { display: grid; gap: 1.25rem; }
@media (min-width: 46rem) { .compare { grid-template-columns: 1fr 1fr; align-items: stretch; } }
.compare__col {
  padding: 1.75rem 1.9rem; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--paper);
}
.compare__col h2 { margin: 0 0 .75rem; font-size: 1.25rem; }
.compare__col--lead { border: 2px solid var(--indigo); box-shadow: 0 8px 30px rgba(36,28,99,.12); }
.ticks { list-style: none; padding: 0; margin: 1.25rem 0 0; }
.ticks li { position: relative; padding-left: 1.75rem; margin-bottom: .6rem; }
.ticks .tick::before  { content: "\2713"; position: absolute; left: 0; color: var(--ok); font-weight: 700; }
.ticks .cross::before { content: "\2715"; position: absolute; left: 0; color: var(--ink-dim); }
.ticks .cross { color: var(--ink-dim); }

.buys { list-style: none; padding: 0; margin: 1.75rem 0 0; }
.buy {
  display: grid; gap: 1rem; align-items: center;
  padding: 1.25rem 0; border-top: 1px solid var(--line);
}
.buy:last-child { border-bottom: 1px solid var(--line); }
.buy h3 { margin: 0 0 .3rem; font-size: 1.1rem; }
.buy p { margin: 0; color: var(--ink-dim); font-size: .95rem; max-width: 52ch; }
/* Price and button are their own columns, not a flex row. As a flex row the
   price lands wherever the button width leaves it, so "Get the programme"
   and "Get the book" pushed the prices out of line with each other. A fixed
   button column makes the whole right hand side read as one column. */
.buy__buy { display: flex; align-items: center; gap: 1rem; }
.buy__price {
  font-weight: 800; font-size: 1.2rem; color: var(--indigo);
  font-variant-numeric: tabular-nums;
}
@media (min-width: 46rem) {
  .buy { grid-template-columns: 1fr auto; gap: 2rem; }
  .buy__buy {
    display: grid; grid-template-columns: 4.5rem 12rem;
    align-items: center; gap: 1rem;
  }
  .buy__price { text-align: right; }
  .buy__buy .btn, .buy__buy .buy-btn {
    width: 100%; text-align: center; white-space: nowrap;
  }
}

/* ---------- text beside a picture ---------- */

/* A photograph of a person belongs in a frame at a readable size, not bled
   across the full width where the crop takes their head off. */
.split { display: grid; gap: 2rem; align-items: center; }
@media (min-width: 52rem) {
  .split { grid-template-columns: 1fr 20rem; gap: 3.5rem; }
  .split--flip { grid-template-columns: 20rem 1fr; }
  .split--flip .split__text { order: 2; }
  .split--flip .split__media { order: 1; }
}
.split__media { margin: 0; }
.split__media img {
  width: 100%; height: auto; display: block;
  border-radius: var(--radius); border: 1px solid var(--line);
}
.split__media figcaption {
  margin-top: .6rem; font-size: .85rem; color: var(--ink-dim); text-align: center;
}

/* ---------- sitemap ---------- */

.sitemap-list { list-style: none; padding: 0; margin: 0 0 1.5rem; columns: 2; column-gap: 2rem; }
.sitemap-list li { margin-bottom: .45rem; break-inside: avoid; }
@media (max-width: 40rem) { .sitemap-list { columns: 1; } }

/* Four guide cards below the lead one: two by two, so the row never ends
   with a single orphan. */
.grid--shots { grid-template-columns: 1fr; }
@media (min-width: 46rem) { .grid--shots { grid-template-columns: 1fr 1fr; } }

/* ---------- staged galleries ---------- */

/* Hidden only once the script has run: without it every tile is simply
   visible, which is the right no-script behaviour and what a crawler sees. */
.reveal.is-ready .proof-tile.is-extra { display: none; }
.reveal__more { margin-top: 1.5rem; text-align: center; }
.reveal__more[hidden] { display: none; }

/* ---------- pricing tiers ---------- */

.tiers { display: grid; gap: 1.25rem; margin-top: 2rem; align-items: start; }
@media (min-width: 58rem) {
  .tiers { grid-template-columns: repeat(3, 1fr); }
  /* Without the $39 tier configured there are only two columns; centre
     them rather than leaving a gap where the third should be. */
  .tiers--two { grid-template-columns: repeat(2, minmax(0, 22rem)); justify-content: center; }
}
.tier {
  position: relative; padding: 1.75rem 1.75rem 1.5rem;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.tier h3 { margin: 0 0 .6rem; font-size: 1.2rem; }
.tier .price { margin-bottom: 1rem; }
.tier .ticks li { font-size: .95rem; }
.tier .btn-row { margin-top: 1.5rem; }

/* The middle column is the one to take, so it looks like it. */
.tier--lead {
  border: 2px solid var(--indigo);
  box-shadow: 0 10px 34px rgba(36,28,99,.14);
}
@media (min-width: 58rem) { .tier--lead { margin-block: -1rem; padding-block: 2.75rem 2.5rem; } }
.tier__flag {
  position: absolute; top: 0; left: 50%; transform: translate(-50%, -50%);
  margin: 0; padding: .3rem .85rem; white-space: nowrap;
  background: var(--indigo); color: var(--white); border-radius: 999px;
  font: 700 .72rem/1.4 inherit; letter-spacing: .06em; text-transform: uppercase;
}
.tiers__note { margin-top: 1.25rem; text-align: center; color: var(--ink-dim); font-size: .9rem; }

/* A wide screenshot that earns the full column width, with a caption. */
.shot-wide { margin: 2.5rem 0 0; }
.shot-wide .proof-tile { display: block; }
.shot-wide img { width: 100%; height: auto; display: block; }
.shot-wide figcaption {
  margin-top: .85rem; font-size: .88rem; color: var(--ink-dim);
  text-align: center; max-width: 60ch; margin-inline: auto;
}


/* ---------- the checkout on a sales page ---------- */

/* Stripe renders the card form in an iframe inside .checkout, so this is a
   container for something whose height is not ours to know: no fixed height,
   no overflow hidden, or the form gets clipped mid payment. */
.checkout {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.25rem; background: #fff; position: sticky; top: 1.5rem;
}
.checkout__head { display: flex; align-items: baseline; gap: .6rem; margin-bottom: .9rem; }
.checkout__price { font-size: 2rem; font-weight: 800; color: var(--indigo); line-height: 1; }
.checkout__note { color: var(--ink-dim); font-size: .85rem; }
.checkout__trust { margin: .9rem 0 0; font-size: .8rem; color: var(--ink-dim); line-height: 1.45; }
.checkout .buy-msg { margin: .7rem 0 0; font-size: .88rem; }
#checkout-mount { margin-top: 1rem; }
@media (max-width: 46rem) { .checkout { position: static; } }
