/* Brick Books - the product site.

   Same palette and type as the program itself, so the site and the thing it
   sells feel like one product. Plain CSS, no build step, no framework: it has
   to upload to shared hosting as files and keep working untouched for years. */

:root {
  --ink: #060608;
  --surface: #0e0e13;
  --surface-2: #16161d;
  --surface-3: #1e1e28;
  --line: rgba(255, 255, 255, .09);
  --line-strong: rgba(255, 255, 255, .18);
  --white: #fff;
  --text: #ececf1;
  --muted: #9a9aa7;
  --muted-2: #6f6f7c;

  /* The wordmark blues from the blog. Everything else here already matched it
     token for token; these two carry the 3D lettering that is the blog's
     signature, so the site and the blog read as the same outfit. */
  --brand-blue: #1f63cf;
  --brand-blue-deep: #0e3a82;

  --c-blue: #2e7de0;
  --c-cyan: #16c6c9;
  --c-green: #74ce3c;
  --c-gold: #ffc61a;
  --c-orange: #ff7a1f;
  --c-red: #ee2b37;
  --c-pink: #ec1e8c;

  --rainbow: linear-gradient(90deg, var(--c-blue) 0%, var(--c-cyan) 17%, var(--c-green) 33%,
      var(--c-gold) 50%, var(--c-orange) 67%, var(--c-red) 83%, var(--c-pink) 100%);

  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-ui: "Space Grotesk", "Segoe UI", system-ui, sans-serif;
  --font-body: "Hanken Grotesk", "Segoe UI", system-ui, sans-serif;

  --radius: 16px;
  --radius-sm: 9px;
  --wrap: 1120px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: var(--c-cyan); }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 22px; }

/* ---------- top bar ---------- */
.top {
  position: sticky; top: 0; z-index: 50;
  background: rgba(6, 6, 8, .85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.top .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 18px; padding-top: 10px; padding-bottom: 10px;
}
/* The logo is the wordmark, so it has to be big enough to actually read the
   name - a 40px strip made "Brick Books" almost illegible. */
.top img { height: 62px; width: auto; }
.top nav { display: flex; align-items: center; gap: 22px; }
.top nav a {
  font-family: var(--font-ui); font-size: 14px; color: var(--muted);
  text-decoration: none;
}
.top nav a:hover { color: var(--white); }

/* ---------- buttons ---------- */
.btn {
  display: inline-block; font-family: var(--font-ui); font-weight: 600;
  font-size: 15px; padding: 12px 22px; border-radius: var(--radius-sm);
  text-decoration: none; border: 1px solid transparent; cursor: pointer;
  transition: transform .1s, background .15s;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--brand-blue); color: var(--white); }
.btn-primary:hover { background: var(--c-blue); }
.btn-ghost { border-color: var(--line-strong); color: var(--text); background: transparent; }
.btn-ghost:hover { background: var(--surface-2); }
.btn-row { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }

/* ---------- hero ---------- */
.hero { padding: 76px 0 64px; }

/* Words on the left, the minifig on the right. She is the same character the
   program uses on its empty screens, so the site and the app feel like one
   thing - and a page about bookkeeping needs all the warmth it can get. */
.hero-grid {
  display: grid; grid-template-columns: 1.25fr .75fr;
  gap: 40px; align-items: center;
}
.hero-art { position: relative; display: flex; justify-content: center; }
.hero-art img {
  width: 100%; max-width: 330px; height: auto;
  filter: drop-shadow(0 22px 46px rgba(0, 0, 0, .6));
  animation: float 6s ease-in-out infinite;
}
/* A soft rainbow bloom behind her, so she is not floating on flat black. */
.hero-art::before {
  content: ""; position: absolute; inset: 12% 6% 6% 6%;
  background: var(--rainbow); filter: blur(64px); opacity: .16;
  border-radius: 50%; z-index: -1;
}
@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-14px); }
}
.hero h1 {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(34px, 5.6vw, 62px); line-height: 1.08;
  margin: 0 0 20px; color: var(--white); letter-spacing: -.02em;
  /* Same stacked-blue lettering the blog masthead uses. Scaled up a little for
     the size, and dropped entirely on small screens where it turns to mud. */
  text-shadow:
    2px 2px 0 var(--brand-blue),
    4px 4px 0 var(--brand-blue),
    6px 6px 0 var(--brand-blue-deep);
}

/* The section headings get a lighter version of the same idea, so the family
   resemblance carries down the page without shouting. */
section > .wrap > h2 { text-shadow: 1px 1px 0 var(--brand-blue), 2px 2px 0 var(--brand-blue-deep); }
.stack .card h2 { text-shadow: 1px 1px 0 var(--brand-blue), 2px 2px 0 var(--brand-blue-deep); }
/* A short line above the headline, to say who this is for before they read
   anything else. */
.eyebrow {
  font-family: var(--font-ui); font-size: 12px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--c-cyan); margin: 0 0 14px;
}

/* The old headline, demoted. It is a good line but it is a follow-up, not the
   thing that tells a stranger what this is. */
.hero .lede-2 {
  font-family: var(--font-display); font-size: clamp(17px, 2.1vw, 22px);
  color: var(--white); margin: 0 0 30px; max-width: 34ch;
  padding-left: 16px; border-left: 3px solid var(--c-cyan);
}

.hero .lede {
  font-size: clamp(16px, 2vw, 20px); color: var(--muted);
  max-width: 54ch; margin: 0 0 30px;
}
.hero .under {
  font-family: var(--font-ui); font-size: 13px; color: var(--muted-2);
  margin-top: 16px;
}
.rainbow-rule { height: 3px; background: var(--rainbow); border: 0; margin: 0; }

/* Independence, said plainly on the page rather than only in the small print.
   Quiet enough not to shout, prominent enough that nobody could miss it. */
.independent {
  background: var(--surface); border-top: 1px solid var(--line);
  font-family: var(--font-ui); font-size: 12.5px; color: var(--muted);
  text-align: center;
}
.independent .wrap { padding-top: 13px; padding-bottom: 13px; }

/* The registered mark should be a mark, not a full-size character sitting on
   the baseline. */
sup { font-size: .58em; vertical-align: super; line-height: 0; }

/* What it runs on. Sits under the hero buttons because "will it even run on my
   machine" is the question people ask before any of the feature copy. */
.os {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--font-ui); font-size: 13px;
  color: var(--muted-2); margin: 12px 0 0;
}
.os svg { width: 15px; height: 15px; fill: currentColor; flex: 0 0 auto; }

/* ---------- the stacking cards ----------
   Panels that pin as you scroll, each sliding under the one before it.
   The descending z-index is the whole trick - without it the later cards
   cover the earlier ones and the effect reads backwards. Pure CSS. */
.stack { padding: 40px 0 80px; }
.stack .card {
  position: sticky;
  display: grid; grid-template-columns: 1fr 1fr; gap: 34px; align-items: center;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 40px;
  overflow: hidden;
  box-shadow: 0 -18px 40px rgba(0, 0, 0, .55);
  /* Every card the same height, so a short one in front never shows a taller one behind it. The
     exact height is measured by a small script on the page; this is the fallback without it. */
  min-height: 660px;
}

/* Each card pins slightly lower than the last and sits slightly HIGHER in the
   stack, so a new one slides up and covers the one before while leaving its top
   edge showing. Ascending z-index is what makes it read as a deck being dealt;
   descending would hide each new card behind the first, which looks broken.

   The tall margin under each card is the scroll distance between them - without
   it the whole sequence is over in a flick of the wheel. */
.stack .card:nth-child(1) { top: 92px;  z-index: 1; margin-bottom: 300px; }
.stack .card:nth-child(2) { top: 110px; z-index: 2; margin-bottom: 300px; }
.stack .card:nth-child(3) { top: 128px; z-index: 3; margin-bottom: 300px; }
.stack .card:nth-child(4) { top: 146px; z-index: 4; margin-bottom: 300px; }
.stack .card:nth-child(5) { top: 164px; z-index: 5; margin-bottom: 40px; }
.stack .card h2 {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(24px, 3vw, 34px); margin: 0 0 14px; color: var(--white);
}
.stack .card p { color: var(--muted); margin: 0 0 18px; }
.stack .card .tag {
  display: inline-block; font-family: var(--font-ui); font-size: 11px;
  font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  padding: 4px 10px; border-radius: 5px; margin-bottom: 14px;
}

/* Where a screenshot goes. Styled so the page reads properly before the real
   images exist, rather than collapsing into an empty box. */
.shot {
  aspect-ratio: 16 / 13; border-radius: var(--radius-sm);
  border: 1px dashed var(--line-strong); background: var(--surface-2);
  display: flex; align-items: center; justify-content: center;
  color: var(--muted-2); font-family: var(--font-ui); font-size: 13px;
  text-align: center; padding: 20px; overflow: hidden;
}
.shot img { border-radius: var(--radius-sm); }

/* ---------- generic sections ---------- */
section { padding: 78px 0; }
section > .wrap > h2 {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(26px, 3.4vw, 40px); color: var(--white);
  margin: 0 0 14px; letter-spacing: -.01em;
}
/* The line under each section heading. No max-width: every one of these is a
   sentence or two sitting directly above a row of boxes, and stopping short of
   the boxes' right edge reads as a mistake rather than a measure. Long-form prose
   on this site lives in the guides, which keep their own narrower measure. */
section > .wrap > .dek {
  color: var(--muted); margin: 0 0 38px; font-size: 17px;
}
.alt { background: var(--surface); border-block: 1px solid var(--line); }

.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.tile {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 26px;
}
.tile h3 {
  font-family: var(--font-ui); font-size: 16px; color: var(--white);
  margin: 0 0 8px;
}
.tile p { color: var(--muted); margin: 0; font-size: 15px; }
.tile .num {
  font-family: var(--font-display); font-size: 30px; color: var(--c-cyan);
  line-height: 1; margin-bottom: 12px;
}

/* ---------- pricing ---------- */
/* Two cards side by side: the demo and the real thing. The demo goes on the
   left so it is read first, because "try it free" is the easier yes and it is
   what the paid card's own footnote tells you to do. */
.price-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 22px; max-width: 940px; margin: 0 auto; align-items: stretch;
}
.price-grid .price-card { max-width: none; margin: 0; display: flex; flex-direction: column; }
.price-grid .price-card ul { flex: 1 1 auto; }
/* The demo card is deliberately quieter: plain top edge instead of the rainbow,
   ghost button instead of the blue one. Both are offers, only one is the offer. */
.price-card.demo::before { background: var(--line-strong); }
.price-card.demo { border-color: var(--line); }
.price-plan {
  font-family: var(--font-ui); font-size: 11.5px; letter-spacing: .15em;
  text-transform: uppercase; color: var(--muted-2); margin: 0;
}
/* The try-first offer sits last, under a rule, with the trial and demo as small buttons. */
.price-under {
  color: var(--muted-2); font-size: 13px;
  margin: 16px 0 0; padding-top: 16px; border-top: 1px solid var(--line);
}
.price-under p { margin: 0; }
.price-try { display: flex; gap: 10px; justify-content: center; margin-top: 12px; }
.btn-sm { font-size: 13px; padding: 7px 18px; }
/* The dagger explained, straight under the Buy button. Deliberately readable rather than
   fine print: a footnote that hides something is worse than no footnote. */
.price-footnote {
  color: var(--muted-2); font-size: 12.5px; line-height: 1.5; margin: 14px 0 0;
}

.price-card {
  max-width: 460px; margin: 0 auto; text-align: center;
  background: var(--surface-2); border: 1px solid var(--line-strong);
  border-radius: var(--radius); padding: 40px 34px; position: relative;
  overflow: hidden;
}
.price-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--rainbow);
}
.price {
  font-family: var(--font-display); font-size: 54px; color: var(--white);
  line-height: 1; margin: 10px 0 4px;
}
/* The number is the thing the eye lands on, so it gets the size and the centre.
   The currency sign and the unit ride above the baseline at a fraction of it,
   and the terms sit underneath rather than trailing off to the right, which was
   what pulled the whole line visually off centre. */
.price .cur {
  font-size: .40em; vertical-align: super; margin-right: 1px;
  font-family: var(--font-body); color: var(--muted);
}
.price .unit {
  font-size: .28em; vertical-align: super; margin-left: 9px;
  font-family: var(--font-body); color: var(--muted); letter-spacing: .06em;
  display: inline-block; width: 0; overflow: visible; white-space: nowrap;
}
/* Green, the same green as the ticks below it, so the one-time terms read as
   part of what you get rather than as small print. */
.price small {
  display: block; font-size: 15px; color: var(--c-green);
  font-family: var(--font-body); margin-top: 10px; letter-spacing: .01em;
}
.price-tax { color: var(--muted-2); font-size: 14px; margin: 8px 0 0; }
.price-tax-note { color: var(--muted-2); font-size: 12px; margin: 4px 0 0; }
.price-card ul { list-style: none; padding: 0; margin: 24px 0 28px; text-align: left; }
.price-card li {
  padding: 8px 0 8px 28px; position: relative; color: var(--text); font-size: 15px;
  border-bottom: 1px solid var(--line);
}
.price-card li:last-child { border-bottom: 0; }
.price-card li::before {
  content: "✓"; position: absolute; left: 4px; color: var(--c-green); font-weight: 700;
}

/* ---------- faq ---------- */
.faq { max-width: 780px; }
.faq details {
  border-bottom: 1px solid var(--line); padding: 4px 0;
}
.faq summary {
  cursor: pointer; padding: 16px 0; font-family: var(--font-ui);
  font-size: 16px; color: var(--white); list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::before { content: "+ "; color: var(--c-cyan); font-weight: 700; }
.faq details[open] summary::before { content: "− "; }
.faq details p { color: var(--muted); margin: 0 0 18px; padding-left: 18px; }
.faq details ul { color: var(--muted); margin: -6px 0 18px; padding-left: 40px; }
.faq details li { margin-bottom: 4px; }

/* ---------- contact ---------- */
.form { max-width: 560px; }
.form label {
  display: block; font-family: var(--font-ui); font-size: 13px;
  color: var(--muted); margin: 16px 0 6px;
}
.form input, .form textarea {
  width: 100%; background: var(--surface-2); color: var(--text);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  padding: 11px 13px; font-family: var(--font-body); font-size: 15px;
}
.form input { height: 44px; }
.form textarea { min-height: 130px; resize: vertical; }
.form input:focus, .form textarea:focus {
  outline: none; border-color: var(--c-cyan);
}
.form .btn { margin-top: 20px; }

/* ---------- footer ---------- */
footer {
  border-top: 1px solid var(--line); padding: 40px 0 56px;
  color: var(--muted-2); font-family: var(--font-ui); font-size: 13px;
}
footer .wrap { display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
footer a { color: var(--muted); text-decoration: none; }
footer a:hover { color: var(--white); }

/* ---------- narrow screens ----------
   The stacking effect needs height to work. On a phone there is not enough of
   it, so the cards become ordinary stacked blocks instead of pinning - which
   is the honest fallback rather than a broken-looking pile. */
/* Anyone who would rather things held still. */
@media (prefers-reduced-motion: reduce) {
  .hero-art img { animation: none; }
  html { scroll-behavior: auto; }
}

@media (max-width: 900px) {
  /* Stack, and centre the words above her. */
  .hero-grid { grid-template-columns: 1fr; text-align: center; }
  .hero .lede { margin-left: auto; margin-right: auto; }
  .hero .lede-2 {
    margin-left: auto; margin-right: auto;
    border-left: 0; padding-left: 0;
    border-top: 3px solid var(--c-cyan); padding-top: 14px;
  }
  .hero .btn-row { justify-content: center; }
  .hero .os { justify-content: center; }
  .hero-art img { max-width: 240px; }

  /* At small sizes the stacked lettering closes up and reads as a smudge. */
  .hero h1 { text-shadow: 1px 1px 0 var(--brand-blue), 2px 2px 0 var(--brand-blue-deep); }

  .stack .card {
    grid-template-columns: 1fr; position: static; padding: 28px;
    margin-bottom: 20px; box-shadow: none; min-height: 0;
  }
  .grid-3 { grid-template-columns: 1fr; }
  .price-grid { grid-template-columns: 1fr; max-width: 460px; }
.contact-grid { grid-template-columns: 1fr; }
  .contact-art { margin-bottom: 0; }
  .contact-art img { max-width: 220px; }
  .top nav { display: none; }
  .top img { height: 46px; }
  .hero { padding: 60px 0 48px; }
  section { padding: 56px 0; }
}

/* Lifted out of the 900px media query, where these had been pasted by
   mistake. Everything here is meant to apply at every width: the 404 was
   only centred on a phone, and on a desktop it fell back to a left aligned
   column with bulleted links. */
  /* The 404. Centred, because there is nothing else on the page competing with
   it, and a single column of short lines reads better than a two column layout
   built for content that does not exist here. */
/* Every other page gets its top spacing from .guide-head, which this one does
   not have, so without this the heading sat under the sticky header. */
.notfound { max-width: 520px; margin: 0 auto; padding: 54px 0 10px; text-align: center; }
.notfound h1 { margin: 0 0 26px; }
.notfound .eyebrow { margin-bottom: 12px; }
.notfound-fig {
  display: block; margin: 0 auto 28px; height: auto;
  filter: drop-shadow(0 16px 34px rgba(0, 0, 0, .5));
}
/* The links read as a row of destinations rather than a bulleted list, which
   on a dead end is the useful thing to show. */
.notfound-links {
  list-style: none; padding: 0; margin: 18px 0 24px;
  display: flex; flex-wrap: wrap; gap: 10px 26px; justify-content: center;
}
.notfound-links a { font-family: var(--font-ui); font-weight: 600; }

/* A minifigure beside a block of content. Deliberately small: these are an
   accent next to the words, not the subject of the section. The width and
   height attributes in the HTML carry the same display size, so a figure is
   never briefly enormous while the stylesheet is still arriving. */
.with-fig {
  display: grid; grid-template-columns: 1fr auto; gap: 34px; align-items: center;
}
.fig { display: flex; justify-content: center; }
.fig img {
  width: auto; max-width: 100%; height: auto;
  filter: drop-shadow(0 14px 30px rgba(0, 0, 0, .5));
}
@media (max-width: 760px) {
  /* Stacked, the figure sits under the words at a size that reads as a
     flourish rather than something to scroll past. */
  .with-fig { grid-template-columns: 1fr; gap: 20px; justify-items: center; }
  .fig img { max-width: 140px; }
}



/* ---------- what it plugs into ----------
   Deliberately typographic rather than a wall of third-party logos: other
   people's marks need permission, change without warning, and would be the
   only thing on the page not drawn in this palette. */
.integrations { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.int-group {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 26px;
}
.int-group h3 {
  font-family: var(--font-ui); font-size: 15px; color: var(--white); margin: 0 0 6px;
}
.int-note { color: var(--muted); font-size: 14px; margin: 0 0 20px; }
.int-row { display: flex; gap: 14px; flex-wrap: wrap; }

/* Grow to share a row, but never past what two-across would give you. Without
   the cap, a third tile wrapping onto its own line stretches to the full width
   of the box and reads as a different kind of thing entirely. */
.int {
  flex: 1 1 150px; max-width: calc(50% - 7px);
  display: flex; flex-direction: column; align-items: center;
  gap: 7px; padding: 18px 12px; border-radius: var(--radius-sm);
  background: var(--surface); border: 1px solid var(--line);
}
.int-mark {
  width: 46px; height: 46px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-ui); font-weight: 700; font-size: 16px;
  color: var(--int); background: color-mix(in srgb, var(--int) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--int) 40%, transparent);
}
.int-name { font-family: var(--font-ui); font-size: 14px; color: var(--white); }
.int-state {
  font-family: var(--font-ui); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--c-green);
}
/* No max-width here on purpose. Body copy elsewhere on the page is held to a
   comfortable measure, but this line sits directly under the two group boxes and
   is read as part of them - stopping short of their right edge looks like a
   mistake rather than a typographic choice. It is two lines either way. */
.int-foot {
  color: var(--muted); font-size: 14px; margin: 24px 0 0;
}

@media (max-width: 900px) {
  .integrations { grid-template-columns: 1fr; }
}

/* ---------- guides ----------
   Long-form instructions. Wider line height and a narrower measure than the
   marketing page, because these are read rather than skimmed. */
.guide-wrap { max-width: 820px; margin: 0 auto; padding: 0 22px; }
.guide-head { padding: 54px 0 30px; }
/* The reader on the guides contents page. Floated so the intro line wraps
   around her rather than sitting in a column of her own, which is what made her
   look stranded between the heading and the Start here box.
   flow-root on the wrap contains the float without clipping anything. */
.guide-head .guide-wrap { display: flow-root; }
.head-fig {
  float: right; width: 150px; height: auto;
  /* Level with the top of the title. The float sits before the heading in the
     markup, so both the title and the intro line flow around it. */
  margin: 2px 0 0 28px;
  filter: drop-shadow(0 14px 30px rgba(0, 0, 0, .5));
}
/* She is taller than the two lines beside her, so without this the contained
   float left a band of empty black between the intro and the Start here box. */
.guide-head:has(.head-fig) { padding-bottom: 8px; }
@media (max-width: 620px) {
  /* Too narrow to wrap around: it would leave two-word lines. */
  .head-fig { float: none; display: block; margin: 12px auto 0; width: 130px; }
}
.guide-head .crumb {
  font-family: var(--font-ui); font-size: 13px; color: var(--muted); margin: 0 0 14px;
}
.guide-head .crumb a { color: var(--muted); text-decoration: none; }
.guide-head .crumb a:hover { color: var(--white); }
.guide-head h1 {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(30px, 4.4vw, 46px); line-height: 1.12;
  margin: 0 0 14px; color: var(--white);
  text-shadow: 2px 2px 0 var(--brand-blue), 4px 4px 0 var(--brand-blue-deep);
}
.guide-head .sub { color: var(--muted); font-size: 18px; margin: 0; }

.guide { padding-bottom: 80px; line-height: 1.75; }
.guide h2 {
  font-family: var(--font-display); font-weight: 600; font-size: 26px;
  color: var(--white); margin: 46px 0 14px;
  padding-top: 22px; border-top: 1px solid var(--line);
}
.guide h3 {
  font-family: var(--font-ui); font-size: 17px; color: var(--white); margin: 28px 0 8px;
}
.guide p { color: var(--text); margin: 0 0 16px; }
.guide ul, .guide ol { color: var(--text); padding-left: 22px; margin: 0 0 18px; }
.guide li { margin-bottom: 9px; }
.guide strong { color: var(--white); }

/* A step, numbered down the side. */
.steps { list-style: none; padding: 0; counter-reset: step; }
.steps > li {
  position: relative; padding-left: 52px; margin-bottom: 26px; counter-increment: step;
}
.steps > li::before {
  content: counter(step);
  position: absolute; left: 0; top: 0;
  width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-ui); font-weight: 700; font-size: 15px;
  color: var(--white); background: var(--brand-blue);
}
.steps > li h3 { margin-top: 2px; }

/* Where to click, styled like the thing you click. */
.ui {
  font-family: var(--font-ui); font-size: .92em; font-weight: 600;
  background: var(--surface-3); color: var(--white);
  padding: 2px 8px; border-radius: 5px; border: 1px solid var(--line-strong);
  white-space: nowrap;
}

.callout {
  border-left: 3px solid var(--c-cyan); background: var(--surface);
  padding: 16px 20px; border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  margin: 0 0 20px;
}
.callout.warn { border-left-color: var(--c-gold); }
.callout.good { border-left-color: var(--c-green); }
.callout p:last-child { margin-bottom: 0; }
.callout .label {
  display: block; font-family: var(--font-ui); font-size: 11px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--c-cyan);
  margin-bottom: 6px;
}
.callout.warn .label { color: var(--c-gold); }
.callout.good .label { color: var(--c-green); }

.guide-nav {
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  border-top: 1px solid var(--line); padding-top: 26px; margin-top: 46px;
}

/* ---------- the guides index ---------- */
.guide-list { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.guide-card {
  display: block; text-decoration: none; padding: 24px;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--radius); transition: border-color .14s, background .14s;
}
.guide-card:hover { border-color: var(--line-strong); background: var(--surface-3); }
.guide-card .n {
  font-family: var(--font-ui); font-size: 11px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--c-cyan);
}
.guide-card h3 {
  font-family: var(--font-display); font-size: 21px; color: var(--white); margin: 8px 0 8px;
}
.guide-card p { color: var(--muted); margin: 0; font-size: 15px; }

@media (max-width: 900px) {
  .guide-list { grid-template-columns: 1fr; }
  .guide h2 { font-size: 22px; }
}

/* ---- integration logos ----
   Each tile shows the official logo, or falls back to the lettered mark it
   shipped with if the file is missing, so the page is never broken.

   The logos sit straight on the tile with no plate behind them. That means the
   white background has to be gone from the file itself, not hidden under a
   panel - the two that arrived with white baked in had it flood-filled out from
   the edges rather than keyed globally, so the white inside Stripe's wordmark
   and PayPal's letterforms survived.

   The plate hugs its logo instead of being a fixed square: BrickLink's mark is
   square and the others are not, and one shared shape would either crop them or
   strand them in empty space. */
.int-mark {
  width: auto; min-width: 0; max-width: 150px; height: 66px;
  padding: 0; box-sizing: border-box;
}
.int-mark:has(img) {
  background: none; border: 0; border-radius: 0;
}
.int-mark img {
  display: block; height: 100%; width: auto;
  max-width: 100%; object-fit: contain;
}
.int-mark b { display: none; }

/* No logo file: back to the square lettered mark, exactly as it was. */
.int-mark.no-logo {
  width: 46px; max-width: none; height: 46px; border-radius: 11px;
}
.int-mark.no-logo b { display: block; }

/* The tiles no longer share a mark height, so pin the names to a common line. */
.int { justify-content: flex-start; }
.int-mark { flex: 0 0 auto; margin-bottom: 2px; }

/* Closer to its heading than other sections. Everywhere else the standard 38px
   sits above a row of boxes that fills the width; here the form is narrow and
   the figure beside it starts lower, so the same gap reads as a hole. Scoped to
   this section rather than changing the rule every heading uses. */
#contact > .wrap > .dek { margin-bottom: 16px; }

/* She holds a phone with this very form on it, so the two sit side by side and
   the joke lands. Form first in the markup: it is the thing being asked for. */
.contact-grid {
  display: grid; grid-template-columns: 1fr .62fr; gap: 40px; align-items: end;
}
/* Bottom aligned, then lifted by roughly the height of the Send button, so her
   feet land on the bottom edge of the message box rather than dangling past it.
   Centred she floated; aligned to the very bottom she stood level with the
   button, which reads as an accident. */
.contact-art { display: flex; justify-content: center; margin-bottom: 74px; }
.contact-art img {
  width: 100%; max-width: 300px; height: auto;
  filter: drop-shadow(0 22px 46px rgba(0, 0, 0, .6));
}

/* ---------- legal pages ----------
   Same shell as the guides. Only three things are new. */
.guide-head .updated {
  font-family: var(--font-ui); font-size: 12.5px; color: var(--muted-2);
  margin: 14px 0 0;
}
.legal-foot {
  margin-top: 40px; padding-top: 22px; border-top: 1px solid var(--line);
  color: var(--muted); font-size: 15px;
}
/* Details only the owner can supply. Rendered loudly on purpose - a legal page
   with a silent wrong answer in it is worse than one with a visible gap, and
   these have to be impossible to miss before launch. */
.todo {
  background: rgba(224, 182, 74, .16); color: var(--c-gold);
  border: 1px dashed var(--c-gold); border-radius: 4px;
  padding: 1px 7px; font-family: var(--font-ui); font-size: .88em;
  font-weight: 600;
}

/* ---------- updates (the release history) ----------
   A running sheet: version and date at the head of each block, then what
   changed. Grouped by release rather than one flat table, because a release is
   the unit people actually care about ("am I on 1.2 yet"), and a table repeats
   the version and date on every single row. */
.release { padding: 26px 0 6px; border-top: 1px solid var(--line); }
.release:first-of-type { border-top: 0; padding-top: 6px; }
.rel-head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.rel-head h2 {
  font-family: var(--font-display); font-weight: 600; font-size: 26px;
  color: var(--white); margin: 0;
}
.rel-date {
  font-family: var(--font-ui); font-size: 13px; color: var(--muted-2); margin: 0;
}
.rel-latest {
  font-family: var(--font-ui); font-size: 10.5px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; vertical-align: middle;
  color: var(--c-green); background: rgba(116, 206, 60, .14);
  border-radius: 5px; padding: 3px 8px; margin-left: 8px;
}
.rel-summary { color: var(--muted); margin: 10px 0 0; }
.rel-list { list-style: none; padding: 0; margin: 18px 0 0; }
.rel-list li {
  display: flex; gap: 12px; align-items: baseline;
  padding: 9px 0; border-bottom: 1px solid var(--line);
  color: var(--text); font-size: 15px; line-height: 1.6;
}
.rel-list li:last-child { border-bottom: 0; }
/* Fixed width so the text starts on the same column all the way down. */
.rel-list span[class^="tag-"] {
  flex: 0 0 74px; text-align: center;
  font-family: var(--font-ui); font-size: 10.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  border-radius: 5px; padding: 4px 0;
}
.tag-new      { color: var(--c-green); background: rgba(116, 206, 60, .14); }
.tag-improved { color: var(--c-cyan);  background: rgba(22, 198, 201, .14); }
.tag-fixed    { color: var(--c-gold);  background: rgba(224, 182, 74, .14); }

@media (max-width: 620px) {
  .rel-list li { flex-direction: column; gap: 6px; }
  .rel-list span[class^="tag-"] { flex: 0 0 auto; align-self: flex-start; padding: 4px 9px; }
}

/* ---- The honest bits -------------------------------------------------------

   Two additions from the 27 Aug audit. The SmartScreen note is deliberately
   NOT styled as a warning: it is reassurance, and a red box would achieve the
   opposite of what the words are for. Gold hairline, same weight as a tile. */

.honest-note {
  margin-top: 28px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--c-gold);
  border-radius: var(--radius-sm);
  padding: 24px 26px;
}
.honest-note h3 {
  font-family: var(--font-ui); font-size: 16px; font-weight: 600;
  margin: 0 0 10px; color: var(--text);
}
.honest-note p { color: var(--muted); margin: 0; font-size: 15px; line-height: 1.6; }
.honest-note p + p { margin-top: 10px; }
.honest-note b { color: var(--text); font-weight: 600; }


/* The ABN, linked to the public register. A one-person software business asking
   for $79 up front has almost no trust signals available to it; a registered
   entity anyone can look up in one click is one of the few real ones, and it
   costs nothing. Small, not hidden. */
.abn { font-size: 12px; color: var(--muted-2); }
.abn a { color: var(--muted); text-decoration: underline; text-underline-offset: 2px; }
.abn a:hover { color: var(--text); }

/* ---- Download page ---------------------------------------------------------

   The button and what it costs you, first. The fingerprint is folded away in a
   disclosure: publishing it is what makes a swapped file detectable, but a wall
   of hex on the page frightens people who came here to do their books. */

.dl-box {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 30px; margin: 0 0 26px;
  text-align: center;
}
.dl-btn { display: inline-block; min-width: 260px; font-size: 16px; }
.dl-meta {
  font-family: var(--font-ui); font-size: 13px; color: var(--muted-2);
  margin: 16px 0 0; font-variant-numeric: tabular-nums;
}
/* Left aligned, not centred. The box is centred and so are the button and the
   version line, but four lines of centred prose go ragged on both edges and are
   noticeably harder to read than the same words set flush left. */
.dl-note {
  color: var(--muted); font-size: 14.5px; line-height: 1.6;
  margin: 20px auto 0; max-width: 56ch; text-align: left;
}

.dl-verify {
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: 4px 0; margin: 34px 0;
}
.dl-verify summary {
  cursor: pointer; list-style: none; padding: 14px 0;
  font-family: var(--font-ui); font-size: 14.5px; font-weight: 500;
  color: var(--muted);
}
.dl-verify summary::-webkit-details-marker { display: none; }
.dl-verify summary::before { content: "+ "; color: var(--c-cyan); font-weight: 700; }
.dl-verify[open] summary::before { content: "\2212 "; }
.dl-verify summary:hover { color: var(--text); }
.dl-verify p {
  color: var(--muted); font-size: 14.5px; margin: 0 0 12px; padding-left: 18px;
}
.dl-verify p:last-child { padding-bottom: 16px; }

/* The hash itself: monospace, wrapping, and quiet. It has to be selectable and
   comparable, not admired. */
.dl-hash {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 12.5px; line-height: 1.7; word-break: break-all;
  color: var(--text); background: var(--surface-2);
  border-radius: var(--radius-sm); padding: 12px 14px;
  margin-left: 18px !important;
}

/* The bracket on the fingerprint disclosure: says "skip me" without being rude
   about it. Quieter than the summary it sits inside. */
.dl-nerd { color: var(--muted-2); font-weight: 400; }

/* The console window illustration. Full width of the column, and it keeps its
   own dark background whatever the surroundings, because it is depicting a
   black terminal window. */
.dl-shot {
  display: block; width: 100%; height: auto;
  margin: 16px 0 4px; border-radius: var(--radius-sm);
}

/* ---- Buying ----------------------------------------------------------------

   One card rather than two. Two equally weighted choices, one of them free, is a
   decision to make rather than an action to take, and the free one wins. The
   trial is still offered, just underneath the button. */

.price-under a { color: var(--c-cyan); text-underline-offset: 2px; }

/* What happens after the payment, because "then what" is the question sitting
   behind a lot of abandoned checkouts. */
.buy-steps {
  list-style: none; padding: 0; max-width: 560px;
  margin: 30px auto 0; display: flex; flex-direction: column; gap: 10px;
}
.buy-steps li {
  display: flex; gap: 14px; align-items: baseline;
  color: var(--muted); font-size: 14.5px; line-height: 1.55;
}
.buy-steps span {
  flex: 0 0 auto; width: 24px; height: 24px; border-radius: 50%;
  background: var(--surface-2); color: var(--c-blue);
  font-family: var(--font-ui); font-size: 12px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}

/* Somebody who has just paid lands on the download page too, and it opens by
   talking about a free trial. One line so they know they have not gone wrong. */
.dl-bought {
  background: var(--surface-2); border-left: 3px solid var(--c-green);
  border-radius: var(--radius-sm); padding: 14px 18px; margin: 0 0 22px;
  color: var(--muted); font-size: 14.5px; line-height: 1.6;
}
.dl-bought strong { color: var(--text); }

/* The one action at the end of the trial page. Separated from the text above it
   so it reads as "now do this" rather than another paragraph. */
.trial-cta {
  margin: 40px 0 0; padding: 28px; text-align: center;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.trial-cta .btn { min-width: 240px; font-size: 16px; }
.trial-cta p {
  margin: 16px 0 0; font-size: 14.5px; color: var(--muted-2);
}
.trial-cta a:not(.btn) { color: var(--c-cyan); }

/* ---- Report a problem ------------------------------------------------------ */

/* The honeypot. Off screen rather than display:none, because some bots skip
   anything hidden outright and the point is that they DO fill it in. Hidden
   from assistive technology as well, so it never reaches a real person. */
.hp {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden;
}
.form textarea {
  width: 100%; min-height: 140px; resize: vertical;
  font-family: var(--font-body); font-size: 15px; line-height: 1.6;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  padding: 12px 14px;
}
.form textarea:focus-visible,
.form input:focus-visible { outline: 2px solid var(--c-cyan); outline-offset: 2px; }
.opt {
  font-family: var(--font-body); font-weight: 400; font-size: 12.5px;
  color: var(--muted-2); text-transform: none; letter-spacing: 0;
}
.field-hint {
  font-size: 13px; color: var(--muted-2); margin: 6px 0 18px; max-width: 62ch;
}

/* A screenshot that has not been taken yet leaves the dashed placeholder rather
   than a broken image icon, the same way the marketplace logos do. */
.shot:has(img) {
  aspect-ratio: auto; border: 0; background: none; padding: 0; display: block;
}

/* What the screenshot would have shown. Only visible when there is not one yet,
   so it describes the gap rather than sitting alongside the picture explaining
   what you can already see. */
.shot-note { display: none; }
.shot.no-shot .shot-note { display: block; }
.shot img { width: 100%; height: auto; object-fit: contain; display: block; }
.shot.no-shot { display: block; }

/* Drawings inside a guide. Full width of the reading column, and they keep their
   own light background because they depict Windows dialogs. */
/* A diagram on the home page. Wider than body text on purpose: these are read
   at a glance rather than followed line by line, and a picture squeezed into a
   text column reads as an afterthought. */
.explain { margin: 0 auto; max-width: 860px; padding: 0 0 6px; }
.explain img { display: block; width: 100%; height: auto; border-radius: var(--radius-sm); }
/* The sentence under a diagram. Held to a readable measure rather than the
   figure's full width: 860px of prose is about 110 characters a line, which is
   roughly twice what anyone reads comfortably. */
.explain-note {
  max-width: 62ch; margin: 18px auto 0; text-align: center;
  color: var(--muted); font-size: 15px; line-height: 1.65;
}
.explain-note + .explain-note { margin-top: 10px; }


.guide-shot {
  display: block; width: 100%; height: auto;
  margin: 18px 0 6px; border-radius: var(--radius-sm);
}

/* ---------- download page: the choices, the download panel ---------- */
.dl-choices { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 0 0 18px; }
.dl-choice {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px 22px;
}
.dl-choice p { margin: 0; color: var(--muted); font-size: 15px; line-height: 1.6; }
.dl-choice .dl-choice-title {
  font-family: var(--font-ui); font-size: 16px; font-weight: 600; color: var(--white);
  margin: 0 0 8px;
}
.dl-box.dl-main { padding: 34px 30px 30px; border-color: var(--line-strong); }
.dl-main .dl-btn { min-width: 300px; font-size: 18px; padding-top: 15px; padding-bottom: 15px; }
.guide .dl-after { color: var(--muted); font-size: 15px; line-height: 1.6; margin: 18px auto 0;
  max-width: 46ch; text-align: center; text-wrap: balance; }
.guide .dl-main .dl-meta { margin-top: 18px; }
.guide .dl-extra { color: var(--muted); font-size: 15px; line-height: 1.6; margin: 0 0 8px; }
@media (max-width: 640px) {
  .dl-choices { grid-template-columns: 1fr; }
  .dl-main .dl-btn { min-width: 0; width: 100%; box-sizing: border-box; }
}

/* ---- Home page hero: the real Dashboard in a framed, tilted window ----
   Replaced the drawn character on 4 Oct 2026. .hshot, not .shot: .shot is the
   feature-panel screenshot frame further down the page. */
.hero-grid { grid-template-columns: .95fr 1.2fr; }
.hero-shot { perspective: 1600px; padding: 30px 10px 40px; }
.hero-shot::before { inset: 4% 0 0 4%; opacity: .26; filter: blur(70px); }
.hshot {
  margin: 0; position: relative; width: 100%; max-width: 720px;
  border-radius: 14px; padding: 3px;                      /* the rainbow edge */
  background: linear-gradient(135deg, var(--c-blue), var(--c-cyan) 25%, var(--c-green) 42%,
              var(--c-gold) 58%, var(--c-orange) 72%, var(--c-red) 86%, var(--c-pink));
  transform: rotateY(-11deg) rotateX(5deg) rotateZ(.6deg);
  transform-origin: 60% 50%;
  box-shadow: 0 40px 80px -20px rgba(0,0,0,.85), 0 0 60px -10px rgba(46,125,224,.45),
              -18px 18px 60px -30px rgba(236,30,140,.45);
  transition: transform .6s cubic-bezier(.2,.7,.2,1);
}
.hero-shot:hover .hshot { transform: rotateY(-4deg) rotateX(2deg); }
.hshot-bar {
  display: flex; align-items: center; gap: 6px; height: 28px; padding: 0 12px;
  background: #121218; border-radius: 12px 12px 0 0;
}
.hshot-bar .dot { width: 9px; height: 9px; border-radius: 50%; background: #2a2a35; }
.hshot-bar .dot:nth-child(1) { background: var(--c-red); }
.hshot-bar .dot:nth-child(2) { background: var(--c-gold); }
.hshot-bar .dot:nth-child(3) { background: var(--c-green); }
.shot-title { margin-left: 8px; font: 600 11px var(--font-ui); color: var(--muted); letter-spacing: .04em; }
.hshot img {
  display: block; width: 100%; height: auto; border-radius: 0 0 12px 12px;
  animation: none; filter: none; max-width: none;
}
/* a glassy sheen across the top corner */
.hshot::after {
  content: ""; position: absolute; inset: 2px; border-radius: 12px; pointer-events: none;
  background: linear-gradient(115deg, rgba(255,255,255,.10), transparent 28%);
}
.chip {
  position: absolute; z-index: 2; padding: 9px 14px; border-radius: 999px;
  font: 500 13px var(--font-ui); color: var(--text); white-space: nowrap;
  background: rgba(14,14,19,.86); backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 14px 30px -10px rgba(0,0,0,.8);
  animation: bob 6s ease-in-out infinite;
}
.chip b { color: var(--white); }
.chip-a { left: -18px; bottom: 34px; border-color: rgba(116,206,60,.55); }
.chip-a b:first-child { color: var(--c-green); }
.chip-b { right: -6px; top: 6px; border-color: rgba(255,198,26,.55); animation-delay: -3s; }
.chip-b b { color: var(--c-gold); }
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
/* three little brick studs, in brand colours, scattered behind */
.stud { position: absolute; z-index: -1; width: 26px; height: 26px; border-radius: 50%;
        box-shadow: inset 0 -4px 0 rgba(0,0,0,.25), inset 0 3px 0 rgba(255,255,255,.25); }
.s1 { background: var(--c-cyan); left: 2%; top: 4%; }
.s2 { background: var(--c-pink); right: 6%; bottom: 2%; width: 20px; height: 20px; }
.s3 { background: var(--c-gold); right: -2%; top: 46%; width: 16px; height: 16px; }
@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hshot { transform: none; max-width: 560px; margin: 0 auto; }
  .chip { font-size: 12px; }
  .chip-a { left: 0; bottom: 6px; }
  .chip-b { right: 0; top: -4px; }
}
@media (prefers-reduced-motion: reduce) { .chip { animation: none; } .hshot { transition: none; } }

/* ---- Home page contact panel, beside the form ---- */
/* Top edge level with the name box, bottom edge level with the message box. */
.contact-art { align-self: start; align-items: flex-start; margin: 43px 0 0; }
.contact-card { height: 315px; display: flex; flex-direction: column; justify-content: center; }
.contact-card { position: relative; width: 100%; max-width: 360px; padding: 18px 28px;
  border-radius: 16px; background: #121218; text-align: center;
  box-shadow: 0 30px 60px -24px rgba(0,0,0,.8), 0 0 50px -14px rgba(46,125,224,.35); }
.contact-card::before { content: ""; position: absolute; inset: 0; border-radius: 16px; padding: 2px;
  background: linear-gradient(135deg, var(--c-blue), var(--c-cyan) 25%, var(--c-green) 42%,
              var(--c-gold) 58%, var(--c-orange) 72%, var(--c-red) 86%, var(--c-pink));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none; }
.contact-card img { width: 128px; height: auto; margin: -10px auto 0; display: block;
  filter: none; max-width: none; }
.contact-card p { margin: 0 0 6px; }
.cc-lead { color: var(--text); font-size: 16px; line-height: 1.5; margin-bottom: 18px !important; }
.cc-label { color: var(--muted); font: 600 12px var(--font-ui); letter-spacing: .08em;
  text-transform: uppercase; margin-top: 14px !important; }
.contact-card a { color: var(--c-cyan); }
@media (max-width: 900px) {
  .contact-grid { grid-template-columns: 1fr; align-items: start; }
  .contact-art { margin-top: 0; }
  .contact-card { margin: 8px auto 0; height: auto; }
  .contact-card img { width: 130px; }
}

/* ---- Landing pages (build-landing.py): one page per search a seller might make ----
   Built from the home page's own pieces (section, .wrap, .tile, .hshot) so they read
   as part of the same site, with a few additions below. */
.lp-hero { padding: 64px 0 56px; }
.lp-hero .wrap { display: grid; grid-template-columns: 1fr 1.15fr; gap: 48px; align-items: center; }
.lp-hero .crumb { font-size: 13px; color: var(--muted-2); margin: 0 0 14px; }
.lp-hero .crumb a { color: var(--muted); }
.lp-hero h1 {
  font-family: var(--font-display); font-size: clamp(34px, 4.4vw, 52px); line-height: 1.08;
  margin: 0 0 18px; color: var(--white);
  text-shadow: 2px 2px 0 var(--brand-blue), 4px 4px 0 var(--brand-blue-deep);
}
.lp-hero .lead { font-size: 19px; color: var(--muted); margin: 0 0 26px; max-width: 34em; }
.lp-hero .btn-row { margin-bottom: 14px; }
.lp-hero .small { font-size: 13.5px; color: var(--muted-2); margin: 0; }
.lp-shot { perspective: 1600px; }
.lp-shot .hshot { transform: rotateY(-9deg) rotateX(4deg) rotateZ(.5deg); }
.lp-icon {
  width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center;
  margin-bottom: 16px; background: var(--surface-3); border: 1px solid var(--line-strong);
}
.lp-icon svg { width: 22px; height: 22px; fill: none; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; }
.lp-split { display: grid; grid-template-columns: 1fr 1.1fr; gap: 48px; align-items: center; }
.lp-split.flip > :first-child { order: 2; }
.lp-split h2 { font-family: var(--font-display); font-size: 32px; color: var(--white); margin: 0 0 14px; }
.lp-split p { color: var(--muted); margin: 0 0 14px; }
.lp-split .hshot { transform: none; }
/* The worked example: one order, split the way Brick Books records it. */
.lp-order {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 22px 24px; font-family: var(--font-ui);
}
.lp-order .hdr { display: flex; justify-content: space-between; color: var(--muted);
  font-size: 13px; letter-spacing: .06em; text-transform: uppercase; margin-bottom: 12px; }
.lp-order .row { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 0; border-top: 1px solid var(--line); font-size: 15px; }
.lp-order .tag { font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.lp-order .in { color: var(--c-green); font-weight: 600; }
.lp-order .out { color: var(--text); font-weight: 600; }
.lp-order .total { border-top: 2px solid var(--line-strong); font-weight: 700; color: var(--white); }
.lp-order .total .in { font-size: 18px; }
.lp-order .note { margin: 12px 0 0; font-size: 12.5px; color: var(--muted-2); }
.t-sale { background: rgba(46,125,224,.16); color: #7fb2f0; }
.t-post { background: rgba(22,198,201,.14); color: var(--c-cyan); }
.t-fee  { background: rgba(160,120,240,.16); color: #b9a2f2; }
.t-ship { background: rgba(255,122,31,.15); color: var(--c-orange); }
.lp-checks { list-style: none; padding: 0; margin: 0; display: grid;
  grid-template-columns: repeat(2, 1fr); gap: 12px; }
.lp-checks li { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 14px 16px 14px 46px; position: relative; color: var(--text); }
.lp-checks li::before { content: ""; position: absolute; left: 16px; top: 17px; width: 18px; height: 18px;
  border-radius: 50%; background: var(--c-green); }
.lp-checks li::after { content: ""; position: absolute; left: 21.5px; top: 21px; width: 5px; height: 9px;
  border: solid #0e0e13; border-width: 0 2.5px 2.5px 0; transform: rotate(45deg); }
.lp-steps { counter-reset: lp; list-style: none; padding: 0; margin: 0; display: grid;
  grid-template-columns: repeat(3, 1fr); gap: 22px; }
.lp-steps li { counter-increment: lp; }
.lp-steps li::before { content: counter(lp); display: grid; place-items: center; width: 36px; height: 36px;
  border-radius: 50%; background: var(--brand-blue); color: #fff; font-weight: 700; margin-bottom: 14px; }
.lp-price { text-align: center; max-width: 620px; margin: 0 auto; }
.lp-price .big { font-family: var(--font-display); font-size: 64px; color: var(--white); line-height: 1; }
.lp-price .big small { font-size: 22px; color: var(--muted); font-family: var(--font-ui); margin-left: 6px; }
.lp-price p { color: var(--muted); }
.lp-cta { text-align: center; }
.lp-cta h2 { margin-bottom: 10px; }
.lp-cta .btn-row { justify-content: center; margin-top: 22px; }
.lp-cta .small { color: var(--muted-2); font-size: 14px; margin-top: 14px; }
.lp-more { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 26px; }
@media (max-width: 900px) {
  .lp-hero .wrap, .lp-split { grid-template-columns: 1fr; gap: 32px; }
  .lp-split.flip > :first-child { order: 0; }
  .lp-shot .hshot { transform: none; }
  .lp-checks, .lp-steps, .lp-more { grid-template-columns: 1fr; }
}
.lp-cta h2, .lp-price h2 {
  font-family: var(--font-display); font-size: clamp(30px, 3.4vw, 40px); color: var(--white);
  margin: 0 0 12px; text-shadow: 1px 1px 0 var(--brand-blue), 2px 2px 0 var(--brand-blue-deep);
}
@media (max-width: 600px) { .lp-order .tag { display: none; } }

/* The BrickLink and Brick Owl tiles on the home page link to their landing pages. */
a.int { text-decoration: none; transition: border-color .15s, transform .15s; }
a.int:hover { border-color: var(--line-strong); transform: translateY(-2px); }
/* "Brick Books for" row in every footer, pointing at the landing pages. */
.foot-for { margin-top: 14px; font-size: 13px; color: var(--muted-2); }
.foot-for span { margin-right: 8px; }
.foot-for a { color: var(--muted); }
footer .wrap.foot-for { display: block; text-align: right; margin-top: 10px; }
@media (max-width: 900px) { footer .wrap.foot-for { text-align: left; } }
/* Landing heroes carry the home hero's trial line and Windows note, styled the same. */
.lp-hero .under { font-family: var(--font-ui); font-size: 13px; color: var(--muted-2); margin: 16px 0 0; max-width: 46em; }
.lp-hero .lead + .lead { margin-top: -14px; }
.lp-order .row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr) auto; gap: 14px; }
.lp-order .row .tag { justify-self: start; }
.lp-order .row > span:last-child { text-align: right; }
.lp-order .row.total > span:first-child { grid-column: 1 / 3; }
@media (max-width: 600px) { .lp-order .row { grid-template-columns: minmax(0, 1fr) auto; } }
@media (max-width: 600px) { .lp-order .row.total > span:first-child { grid-column: auto; } }
/* The caption straight under the stocktake diagram on the home page. */
.explain-note.explain-lead { color: var(--text); }
.explain-note.explain-lead strong { color: var(--white); }
.int-foot + .int-foot { margin-top: 8px; }

/* ---------- Reviews (/reviews/, 15 Oct 2026) ----------
   Testimonial cards in the style of the stacking cards: dark surface, rainbow top edge,
   logo or initials, the store's country, the review, and a link to the store. */
.rv-wrap { max-width: 1040px; }
.rv-grid {
  display: grid; gap: 18px; margin: 8px 0 26px;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.rv-card {
  position: relative; display: flex; flex-direction: column;
  background: var(--surface-2); border: 1px solid var(--line-strong);
  border-radius: var(--radius); padding: 22px 22px 18px; overflow: hidden;
}
.rv-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px; background: var(--rainbow);
}
.rv-top { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.rv-top h3 { margin: 0; font-size: 18px; }
.rv-logo {
  width: 56px; height: 56px; flex: 0 0 56px; border-radius: 12px; object-fit: contain;
  background: #fff; border: 1px solid var(--line-strong);
}
.rv-initials {
  display: grid; place-items: center; background: var(--brand-blue-deep); color: #fff;
  font-family: var(--font-ui); font-weight: 700; font-size: 20px;
}
.rv-where { font-family: var(--font-ui); font-size: 13px; color: var(--muted); margin-top: 2px; }
.rv-card blockquote { margin: 0 0 12px; font-size: 15.5px; line-height: 1.6; flex: 1; }
.rv-card blockquote p { margin: 0 0 8px; }
.rv-by { margin: 0; font-family: var(--font-ui); font-size: 14px; font-weight: 600; }
.rv-facts { margin: 4px 0 0; font-family: var(--font-ui); font-size: 13px; color: var(--muted); }
.rv-visit {
  align-self: flex-start; margin-top: 14px; font-family: var(--font-ui); font-size: 14px;
  font-weight: 600; color: var(--c-cyan); text-decoration: none;
}
.rv-visit:hover { text-decoration: underline; }
.rv-note { font-size: 14px; color: var(--muted); margin: 6px 0 34px; }
.form select {
  width: 100%; height: 44px; background: var(--surface-2); color: var(--text);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  padding: 0 11px; font-family: var(--font-body); font-size: 15px;
}
.form input[type="file"] { height: auto; padding: 9px 11px; }
.form label.rv-consent {
  display: flex; gap: 10px; align-items: flex-start; margin-top: 20px;
  font-family: var(--font-body); font-size: 14px; color: var(--text);
}
.form label.rv-consent input { width: 18px; height: 18px; flex: 0 0 18px; margin-top: 2px; }
