/* Billkeep — the public pages.

   Loaded after base.css, which carries the tokens, the type ramp and the
   buttons. Nothing in this file is used by the app itself, so the app does not
   download it.

   The look, in one paragraph: a warm off-white page with two soft violet
   washes behind it, generous vertical rhythm, cards with no outline and a
   whisper of a shadow, one saturated gradient panel per page as the loud
   moment, and the product drawn as real HTML rather than shown as a
   screenshot wherever that is possible. */

/* Page atmosphere --------------------------------------------------------- */

body {
  position: relative;
  overflow-x: clip;
}

/* Two fixed washes rather than a gradient on the body: they stay put while the
   page scrolls, which reads as depth instead of as a painted background. */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(60vw 46vw at 78% -8%, var(--glow-a), transparent 62%),
    radial-gradient(46vw 38vw at 4% 18%, var(--glow-b), transparent 60%);
}

/* Header ------------------------------------------------------------------ */

.site-header {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--page) 78%, transparent);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid transparent;
  transition: border-color .25s ease, background .25s ease;
}
.site-header.is-stuck {
  border-bottom-color: var(--line);
  background: color-mix(in srgb, var(--page) 90%, transparent);
}
.site-header .wrap {
  display: flex; align-items: center; gap: 14px;
  min-height: 74px;
}

/* .brand and .brand .mark live in base.css — the app uses them too. */

.nav { margin-left: auto; display: flex; align-items: center; gap: 2px; }
.nav a {
  color: var(--ink-soft); font-weight: 600; font-size: .96rem;
  padding: 9px 14px; border-radius: var(--r-pill);
  transition: background .18s ease, color .18s ease;
}
.nav a:hover { background: var(--sunken); color: var(--ink); text-decoration: none; }
.nav a[aria-current="page"] {
  color: var(--brand-ink);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
}
/* The account link. Signed in it carries an address, which is longer than a
   nav word, so it gets a dot rather than growing the row. */
.nav-account.is-signed-in {
  display: inline-flex; align-items: center; gap: 8px;
  max-width: 20ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nav-account.is-signed-in::before {
  content: ""; flex: 0 0 auto;
  width: 7px; height: 7px; border-radius: var(--r-pill); background: var(--paid);
}

.nav .btn { margin-left: 8px; }
/* `.nav a` outranks `.btn-primary` on specificity, so the call to action has to
   restate its own colours or it inherits ink on violet in the dark theme. */
.nav a.btn-primary { color: var(--on-brand); background: var(--brand); }
.nav a.btn-primary:hover { background: color-mix(in srgb, var(--brand) 88%, #000); }

/* Theme toggle ------------------------------------------------------------ */

/* The theme toggle moved to base.css — the app uses the same button now, and
   the app deliberately never downloads this sheet. */

/* Mobile navigation ------------------------------------------------------- */

.nav-toggle {
  margin-left: auto; display: none;
  width: 44px; height: 44px; border: 0; border-radius: 13px;
  background: var(--sunken); color: var(--ink); cursor: pointer;
  position: relative;
}
.nav-toggle i, .nav-toggle i::before, .nav-toggle i::after {
  display: block; width: 18px; height: 2px; background: currentColor;
  border-radius: 2px; content: "";
  transition: transform .2s var(--ease-move), opacity .15s ease;
}
.nav-toggle i { margin: 0 auto; position: relative; }
.nav-toggle i::before { position: absolute; top: -6px; left: 0; }
.nav-toggle i::after { position: absolute; top: 6px; left: 0; }
.nav-toggle[aria-expanded="true"] i { background: transparent; }
.nav-toggle[aria-expanded="true"] i::before { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] i::after { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 960px) {
  .nav-toggle { display: block; order: 3; }
  .theme-toggle { order: 2; margin-left: auto; }
  .nav {
    position: fixed; inset: 74px 0 auto; margin: 0; order: 4;
    flex-direction: column; align-items: stretch; gap: 2px;
    background: var(--card); padding: 16px 24px 26px;
    box-shadow: var(--shadow-md);
    max-height: calc(100dvh - 74px); overflow-y: auto;
    transform: translateY(-12px); opacity: 0; pointer-events: none;
    /* `visibility`, not opacity alone: a menu that is only transparent keeps
       its place in the tab order, so keyboard focus walked into six invisible
       links before reaching the page. Transitioned, so the fade out still
       plays before it goes. */
    visibility: hidden;
    transition: opacity .2s ease, transform .22s var(--ease-in), visibility .22s;
  }
  .nav.is-open { transform: none; opacity: 1; pointer-events: auto; visibility: visible; }
  .nav a { padding: 13px 14px; font-size: 1.04rem; }
  .nav .btn { margin: 12px 0 0; }
}

/* Sections ---------------------------------------------------------------- */

section { padding: clamp(58px, 7vw, 104px) 0; }
section.tight { padding: clamp(36px, 4vw, 58px) 0; }

.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 15px; border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--brand) 13%, transparent);
  color: var(--brand-ink); font-weight: 700; font-size: .8rem;
  letter-spacing: .08em; text-transform: uppercase;
  margin-bottom: 18px;
}
.eyebrow svg { width: 15px; height: 15px; }
.eyebrow.is-quiet { background: var(--sunken); color: var(--muted); }

.section-head { max-width: 68ch; margin-bottom: clamp(34px, 4vw, 52px); }
.section-head.is-centred { margin-left: auto; margin-right: auto; text-align: center; }
.section-head.is-centred .lede { margin-left: auto; margin-right: auto; }

/* A number that labels the section, sitting in the margin on wide screens. */
/* Also used as an <h2> where a section needs a heading in the outline but a
   full-size one on the page would shout. */
.rule {
  display: flex; align-items: center; gap: 16px;
  margin: 0 0 26px; color: var(--muted); line-height: 1.4;
  font-size: .78rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
}
.rule::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--line); }

/* Hero -------------------------------------------------------------------- */

.hero { padding-top: clamp(38px, 5vw, 74px); padding-bottom: clamp(48px, 6vw, 92px); }
.hero-grid {
  display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  gap: clamp(32px, 4vw, 64px); align-items: center;
}
@media (max-width: 1000px) { .hero-grid { grid-template-columns: 1fr; gap: 40px; } }
.hero h1 { margin-bottom: .3em; }
.hero .lede { margin-bottom: 28px; font-size: clamp(1.1rem, 1rem + .55vw, 1.38rem); }
.hero-note { margin-top: 20px; font-size: .9rem; color: var(--muted); }
.hero-note strong { color: var(--ink-soft); }

.hero-points {
  list-style: none; margin: 26px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 8px 20px;
  font-size: .93rem; font-weight: 600; color: var(--ink-soft);
}
.hero-points li { display: inline-flex; align-items: center; gap: 8px; }
.hero-points li::before {
  content: ""; width: 7px; height: 7px; border-radius: var(--r-pill);
  background: var(--paid); flex: 0 0 auto;
}

/* The invoice, drawn ------------------------------------------------------ */
/* The hero shows the thing the app makes rather than a picture of the app
   making it: real text, crisp at any size, and it says what the product is
   before a word of copy has been read. */

.doc-stage { position: relative; }
.doc {
  background: var(--card); border-radius: var(--r-xl);
  box-shadow: var(--shadow-lg);
  padding: clamp(22px, 2.6vw, 34px);
  font-size: .93rem;
  position: relative; overflow: hidden;
}
.doc::before {
  /* The hairline that makes a card look lit rather than pasted on. */
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: inset 0 1px 0 var(--hairline); pointer-events: none;
}
.doc-top { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 26px; }
.doc-logo {
  width: 44px; height: 44px; border-radius: 13px; flex: 0 0 auto;
  background: linear-gradient(150deg, var(--panel-a), var(--panel-b));
  color: #fff; display: grid; place-items: center; font-weight: 800; font-size: 1rem;
}
/* `min-width: 0` lets this column shrink, which is what keeps the flex row
   from setting the card's width — but an email address has no break
   opportunity, so on a phone it ran straight out of its box and under the
   invoice number on the right. Let it break instead. */
.doc-who { min-width: 0; overflow-wrap: anywhere; }
.doc-who .name { font-weight: 800; letter-spacing: -.02em; }
.doc-title { margin-left: auto; text-align: right; }
.doc-title .k { font-size: .72rem; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); font-weight: 800; }
.doc-title .v { font-weight: 800; font-size: 1.05rem; letter-spacing: -.02em; }

.doc-meta { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-bottom: 22px; }
.doc-meta .k { font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); font-weight: 800; }
.doc-meta .v { font-weight: 700; font-size: .92rem; }

.doc-lines { width: 100%; border-collapse: collapse; }
.doc-lines th {
  text-align: left; font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); font-weight: 800; padding: 0 0 8px;
  border-bottom: 1px solid var(--line);
}
.doc-lines td { padding: 11px 0; border-bottom: 1px solid var(--line); font-size: .9rem; }
.doc-lines .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.doc-lines tbody tr:last-child td { border-bottom: 0; }

/* Six columns in a card this narrow only work if the money columns stop
   competing with the description for width. The rate is the narrowest thing on
   the row and should never wrap; the description is the only column allowed to. */
.doc-lines .rate { white-space: nowrap; color: var(--muted); font-size: .82rem; padding-left: 16px; }
.doc-lines th.num, .doc-lines td.num { padding-left: 10px; }
/* A left-aligned header straight after a right-aligned numeric one has nothing
   between the two words — "Qty" and "Tax" were touching in the hero invoice.
   The body cells below already get this inset from `.rate`. */
.doc-lines th.num + th { padding-left: 16px; }
.doc-lines th:first-child, .doc-lines td:first-child { width: 38%; }
/* ⚠ Six columns do not fit a phone, and hiding two of them makes the hero show
   a simpler document than the product produces — the thing this change existed
   to stop. So it scrolls inside the card, exactly as the real document does.
   Every ancestor of a scroller needs `min-width: 0`, or the table sets the page
   width and the whole hero goes wide. */
.doc-lines-scroll { overflow-x: auto; min-width: 0; }
.doc-stage, .doc, .doc-lines-scroll { min-width: 0; }
@media (max-width: 560px) {
  /* ⚠ Scoped to the scroller. `.doc-lines` is used on /features and /books too,
     and those tables have nothing to scroll them — an unscoped min-width made
     both pages 110px wider than a 390px phone. */
  .doc-lines-scroll .doc-lines { min-width: 420px; }
  .doc-lines td, .doc-lines th { font-size: .8rem; }
}

.doc-sums { margin-top: 14px; margin-left: auto; width: min(280px, 100%); display: grid; gap: 7px; }
.doc-sums .row { display: flex; justify-content: space-between; gap: 16px; font-size: .9rem; color: var(--muted); }
.doc-sums .row.total {
  margin-top: 8px; padding-top: 12px; border-top: 1.5px solid var(--line);
  color: var(--ink); font-weight: 800; font-size: 1.18rem; letter-spacing: -.025em;
}

.doc-pay {
  margin-top: 24px; padding: 16px 18px; border-radius: var(--r-md);
  background: var(--sunken);
  display: flex; align-items: center; gap: 16px;
}
.doc-pay .qr { width: 62px; height: 62px; flex: 0 0 auto; border-radius: 9px; background: #fff; padding: 5px; }
.doc-pay .qr svg { width: 100%; height: 100%; }
.doc-pay .label { font-weight: 800; letter-spacing: -.02em; }
.doc-pay .host { font-size: .84rem; color: var(--muted); word-break: break-all; }

/* The chips that float beside the document. */
.doc-chip {
  position: absolute; z-index: 2;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 11px 16px; border-radius: var(--r-pill);
  background: var(--card); box-shadow: var(--shadow-md);
  font-size: .88rem; font-weight: 700; letter-spacing: -.01em;
  white-space: nowrap;
}
.doc-chip .dot { width: 9px; height: 9px; border-radius: var(--r-pill); flex: 0 0 auto; }
.doc-chip.paid { left: -22px; top: 14%; animation: float-a 7s var(--ease-move) infinite; }
.doc-chip.paid .dot { background: var(--paid); }
.doc-chip.late { right: -18px; bottom: 16%; animation: float-b 8.5s var(--ease-move) infinite; }
.doc-chip.late .dot { background: var(--late); }
@media (max-width: 1200px) {
  .doc-chip.paid { left: -8px; }
  .doc-chip.late { right: -6px; }
}
@media (max-width: 560px) { .doc-chip { display: none; } }

@keyframes float-a {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-9px); }
}
@keyframes float-b {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(8px); }
}

/* Cards and grids --------------------------------------------------------- */

.grid { display: grid; gap: 20px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1000px) { .grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 660px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } }

/* The card itself is in base.css; these are the marketing-only additions. */
.card { transition: transform .3s var(--ease-in), box-shadow .3s ease; }
.card p { color: var(--muted); }
.card.is-lifting:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }

.card-icon {
  width: 46px; height: 46px; border-radius: 15px;
  display: grid; place-items: center; margin-bottom: 18px;
  background: color-mix(in srgb, var(--accent, var(--brand)) 15%, transparent);
  color: var(--accent, var(--brand));
}
.card-icon svg { width: 23px; height: 23px; }

.card-flat { background: var(--sunken); box-shadow: none; }
.card-flat::before { box-shadow: none; }

/* A wide card that leads a grid. */
.card-wide { grid-column: span 2; }
@media (max-width: 660px) { .card-wide { grid-column: span 1; } }

.split {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(30px, 4vw, 60px); align-items: center;
}
.split.is-flipped > :first-child { order: 2; }
@media (max-width: 960px) {
  .split { grid-template-columns: 1fr; gap: 32px; }
  .split.is-flipped > :first-child { order: 0; }
}

/* The gradient panel — one per page, the loud moment. */
.panel {
  position: relative; overflow: hidden;
  background: linear-gradient(148deg, var(--panel-a), var(--panel-b));
  color: #fff; border-radius: var(--r-xl);
  padding: clamp(32px, 5vw, 64px);
  box-shadow: var(--shadow-lg);
}
.panel::after {
  /* A slow highlight across the top corner, so the flat fill has a light source. */
  content: ""; position: absolute; width: 60%; aspect-ratio: 1; right: -12%; top: -34%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, .18), transparent);
  pointer-events: none;
}
.panel h2, .panel h3, .panel h4 { color: #fff; }
.panel p, .panel .lede { color: rgba(255, 255, 255, .93); }
.panel a { color: #fff; text-decoration: underline; }
/* Darkened rather than lightened: a white tint over the panel raises the
   ground under white text to about 3.7:1. */
.panel .eyebrow { background: rgba(18, 8, 56, .26); color: #fff; }
.panel code { background: rgba(18, 8, 56, .32); color: #fff; padding: 2px 7px; border-radius: 7px; }
.panel .btn-primary { background: #fff; color: var(--brand-deep); box-shadow: 0 12px 30px rgba(0, 0, 0, .22); }
.panel .btn-primary:hover { background: #fff; }
.panel > * { position: relative; z-index: 1; }


/* Facts -------------------------------------------------------------------- */
/* Four figures under the hero. Divided by rules rather than boxed, because a
   card around a number is chrome standing in for confidence. */
.facts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  margin: 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.facts > div {
  padding: clamp(18px, 2vw, 26px) clamp(14px, 2vw, 30px);
  border-left: 1px solid var(--line);
}
.facts > div:first-child { border-left: 0; padding-left: 0; }
.facts dt {
  font-size: clamp(1.35rem, 1.05rem + 1.1vw, 1.9rem);
  font-weight: 800;
  letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
}
.facts dd {
  margin: 4px 0 0;
  font-size: .86rem;
  color: var(--muted);
  max-width: 24ch;
}
@media (max-width: 820px) {
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* On two columns the third item starts a new row, so it needs the left edge
     back and the row above needs a rule under it. */
  .facts > div:nth-child(odd) { border-left: 0; padding-left: 0; }
  .facts > div:nth-child(n+3) { border-top: 1px solid var(--line); }
}

/* Feature rows ------------------------------------------------------------- */
/* Replaces a three-column grid of icon cards, which is the most recognisable
   generated-landing-page layout there is: six identical white boxes, each with
   a pastel rounded square at the top left. Nothing about that arrangement says
   anything about *this* product.
   
   These are hairline-separated rows instead — the name set large in a narrow
   left column, the explanation in a measured one beside it. Closer to a
   contents page than to a brochure, which is the right register for a tool
   somebody is deciding whether to trust with their books. */

.feature-rows { border-top: 1px solid var(--line); }

.feature-row {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 9fr);
  gap: clamp(16px, 4vw, 56px);
  padding: clamp(24px, 3vw, 38px) 0;
  border-bottom: 1px solid var(--line);
  align-items: start;
}
@media (max-width: 760px) {
  .feature-row { grid-template-columns: 1fr; gap: 10px; padding: 22px 0; }
}

.feature-row h3 {
  margin: 0;
  font-size: clamp(1.18rem, 1rem + .7vw, 1.6rem);
  letter-spacing: -.028em;
  line-height: 1.18;
}
.feature-row p { margin: 0; color: var(--muted); max-width: 60ch; }

/* The index number, in the margin. Quiet enough to scan past, and it gives the
   column a left edge to hang from. */
.feature-row .n {
  display: block;
  font-size: .74rem;
  font-weight: 800;
  letter-spacing: .16em;
  color: var(--muted);
  margin-bottom: 10px;
  font-variant-numeric: tabular-nums;
}

/* Steps -------------------------------------------------------------------- */
/* The numeral carries the sequence on its own. A filled brand circle with a
   glow behind every step is decoration doing a job the number already did. */
.steps.is-plain .step::before {
  background: none;
  color: color-mix(in srgb, var(--brand) 45%, var(--muted));
  box-shadow: none;
  width: auto; height: auto;
  font-size: clamp(1.9rem, 1.4rem + 1.6vw, 2.9rem);
  font-weight: 800;
  letter-spacing: -.05em;
  line-height: .9;
  min-width: 1.4em;
  font-variant-numeric: tabular-nums;
}
.steps.is-plain .step { gap: clamp(14px, 2vw, 26px); align-items: baseline; }

/* A band, for pacing ------------------------------------------------------- */
/* Ten sections of white with cards on them is a flat read. A recessed band
   every few sections gives the page a pulse without a second colour, and
   without the dark-section-in-a-light-page jolt. */
.band { background: var(--sunken); }
.band + .band { border-top: 1px solid var(--line); }

/* Grain -------------------------------------------------------------------- */
/* A very slight tooth over the whole page. Flat vector fields read as sterile
   at large sizes, and this is the cheapest way to give the ground a surface.
   Fixed, non-interactive, and switched off for anyone who asked for less. */
.grain {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.035'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion: reduce) { .grain { opacity: .3; } }
@media print { .grain { display: none; } }

/* Stats and tiles --------------------------------------------------------- */

.tile { background: var(--sunken); border-radius: var(--r-md); padding: 20px 22px; }
.tile .k { font-size: .74rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); font-weight: 800; }
.tile .v { font-size: 1.45rem; font-weight: 800; letter-spacing: -.03em; margin-top: 2px; }
.panel .tile { background: rgba(255, 255, 255, .13); }
.panel .tile .k { color: rgba(255, 255, 255, .78); }
.panel .tile .v { color: #fff; }

/* Steps ------------------------------------------------------------------- */

.steps { counter-reset: step; display: grid; gap: 26px; }
.step { display: flex; gap: 20px; align-items: flex-start; }
.step::before {
  counter-increment: step; content: counter(step);
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: var(--r-pill);
  background: var(--brand); color: var(--on-brand);
  display: grid; place-items: center; font-weight: 800; font-size: .98rem;
  box-shadow: var(--shadow-brand);
}
.step h3 { margin-bottom: .2em; }
.step p { margin: 0; color: var(--muted); }

/* Screenshot strip -------------------------------------------------------- */

.shots {
  display: grid; grid-auto-flow: column; grid-auto-columns: min(248px, 64vw);
  gap: 20px; overflow-x: auto; padding: 8px 2px 26px;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
}
.shots figure { margin: 0; scroll-snap-align: center; }
.shots img { border-radius: var(--r-lg); box-shadow: var(--shadow-md); }
.shots figcaption { margin-top: 14px; font-size: .89rem; color: var(--muted); text-align: center; }

.phone {
  position: relative; margin: 0 auto; width: min(300px, 74vw);
  border-radius: 42px; padding: 10px;
  background: linear-gradient(158deg, var(--brand), var(--brand-alt));
  box-shadow: var(--shadow-lg);
}
.phone img { border-radius: 33px; }

/* Lists ------------------------------------------------------------------- */

/* .ticks lives in base.css — the app's front door uses it too. */
.crosses li::before {
  background: color-mix(in srgb, var(--late) 22%, transparent);
  box-shadow: inset 0 0 0 4px var(--late);
}
.panel .ticks li::before { background: rgba(255, 255, 255, .25); box-shadow: inset 0 0 0 4px #fff; }

/* Plans ------------------------------------------------------------------- */

/* Three plans, three columns. This said `repeat(4, …)` from a time when there
   was a fourth: above 1080px the row carried an empty column on the right and
   squeezed the three real cards into three quarters of the width, which made
   them ~100px taller than they are at 1000px in two columns. */
.plans { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; align-items: start; }
@media (max-width: 1080px) { .plans { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .plans { grid-template-columns: 1fr; } }

.plan { display: flex; flex-direction: column; height: 100%; }
.plan .tier { font-size: .78rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 800; color: var(--brand-ink); }
.plan .price { display: flex; align-items: baseline; gap: 6px; margin: 12px 0 2px; }
.plan .price .amount { font-size: 2.1rem; font-weight: 800; letter-spacing: -.04em; }
.plan .price .per { font-size: .9rem; color: var(--muted); font-weight: 600; }
.plan .price-note { font-size: .84rem; color: var(--muted); min-height: 1.4em; }
.plan .ticks { margin-top: 20px; }
.plan .btn { margin-top: 22px; width: 100%; }
.plan .plan-foot { margin-top: auto; }
.plan.is-featured {
  box-shadow: var(--shadow-md), inset 0 0 0 2px var(--brand);
}
.plan.is-featured::before { box-shadow: none; }

.badge {
  display: inline-block; padding: 4px 12px; border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--brand) 14%, transparent);
  color: var(--brand-ink); font-size: .74rem; font-weight: 800;
  letter-spacing: .06em; text-transform: uppercase;
}
.badge.paid { background: color-mix(in srgb, var(--paid) 16%, transparent); color: var(--paid-ink); }

/* The monthly / yearly switch. */
.period {
  display: inline-flex; padding: 5px; border-radius: var(--r-pill);
  background: var(--sunken); gap: 4px; margin-bottom: 30px;
}
.period button {
  border: 0; background: transparent; color: var(--muted);
  padding: 9px 20px; border-radius: var(--r-pill);
  font-weight: 700; font-size: .93rem; cursor: pointer;
  transition: background .2s ease, color .2s ease;
}
.period button[aria-pressed="true"] { background: var(--card); color: var(--ink); box-shadow: var(--shadow-sm); }
.period .save { color: var(--paid-ink); font-weight: 800; font-size: .8rem; margin-left: 6px; }

/* Tables ------------------------------------------------------------------ */

.table-scroll {
  overflow-x: auto; border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm); background: var(--card);
}
table { width: 100%; border-collapse: collapse; }
/* Only a table inside the scroller gets a floor width. Left on `table` itself
   it also hit the little tables drawn inside cards, which then overflowed
   their own card by 130px. */
.table-scroll table { min-width: 660px; }
th, td { padding: 15px 20px; text-align: left; border-bottom: 1px solid var(--line); font-size: .95rem; }
thead th { font-size: .76rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); font-weight: 800; }
tbody tr:last-child td { border-bottom: 0; }
tbody th { font-weight: 700; }
td.yes, th.yes { color: var(--paid-ink); font-weight: 700; }
td.no { color: var(--muted); }
td.num, th.num { text-align: right; }

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

.faq { display: grid; gap: 12px; }
details.qa {
  background: var(--card); border-radius: var(--r-md);
  padding: 2px 24px; box-shadow: var(--shadow-sm);
}
details.qa summary {
  cursor: pointer; list-style: none; padding: 19px 0;
  font-weight: 700; letter-spacing: -.015em;
  display: flex; align-items: center; gap: 14px;
}
details.qa summary::-webkit-details-marker { display: none; }
details.qa summary::after {
  content: ""; margin-left: auto; flex: 0 0 auto;
  width: 12px; height: 12px;
  border-right: 2.5px solid var(--brand); border-bottom: 2.5px solid var(--brand);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .22s var(--ease-move);
}
details.qa[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
details.qa > *:not(summary) { color: var(--muted); }
details.qa > *:last-child { padding-bottom: 18px; }

/* Prose — legal pages and the help centre --------------------------------- */

.prose { max-width: 72ch; }
.prose h2 { margin-top: 1.9em; font-size: 1.5rem; }
.prose h3 { margin-top: 1.6em; font-size: 1.12rem; }
.prose ul, .prose ol { padding-left: 22px; }
.prose li { margin: 7px 0; }
.prose li::marker { color: var(--brand); }
.prose table { min-width: 0; }
.prose code {
  background: var(--sunken); padding: 2px 7px; border-radius: 7px;
  font-size: .9em; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.prose blockquote {
  margin: 22px 0; padding: 2px 0 2px 22px;
  border-left: 3px solid var(--brand); color: var(--muted);
}

.callout {
  background: var(--card); border-radius: var(--r-md); padding: 22px 26px;
  box-shadow: var(--shadow-sm); margin: 24px 0;
}
.callout h3 { margin-top: 0; }
.callout.brand { background: color-mix(in srgb, var(--brand) 11%, var(--card)); }
.callout.warn { background: color-mix(in srgb, var(--draft) 14%, var(--card)); }
/* A callout sits on a tint, which costs a link about half a point of
   contrast — enough to drop --brand under 4.5:1 on the amber one. */
.callout a { color: var(--brand-ink); }

.page-head { padding: clamp(48px, 7vw, 84px) 0 8px; }
.page-head .lede { margin-bottom: 0; }

/* Help centre layout ------------------------------------------------------ */

.docs {
  display: grid; grid-template-columns: 246px minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px); align-items: start;
}
@media (max-width: 900px) { .docs { grid-template-columns: 1fr; } }

.docs-nav {
  position: sticky; top: 96px;
  background: var(--card); border-radius: var(--r-lg);
  padding: 20px; box-shadow: var(--shadow-sm);
}
@media (max-width: 900px) { .docs-nav { position: static; } }
.docs-nav .group {
  font-size: .74rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin: 18px 0 8px; line-height: 1.3;
}
.docs-nav .group:first-child { margin-top: 0; }
.docs-nav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.docs-nav a {
  display: block; padding: 8px 12px; border-radius: 11px;
  color: var(--ink-soft); font-size: .93rem; font-weight: 600;
}
.docs-nav a:hover { background: var(--sunken); color: var(--ink); text-decoration: none; }
.docs-nav a[aria-current="page"] {
  background: color-mix(in srgb, var(--brand) 13%, transparent); color: var(--brand-ink);
}

.crumbs { font-size: .88rem; color: var(--muted); margin-bottom: 14px; }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--brand); }

.doc-next {
  display: flex; flex-wrap: wrap; gap: 14px; justify-content: space-between;
  margin-top: 48px; padding-top: 26px; border-top: 1px solid var(--line);
}

/* Free tools -------------------------------------------------------------- */

.calc {
  display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, .95fr);
  gap: clamp(18px, 2.4vw, 30px); align-items: start;
}
@media (max-width: 980px) { .calc { grid-template-columns: 1fr; } }

.calc-result { position: sticky; top: 96px; }
@media (max-width: 980px) { .calc-result { position: static; } }

/* Description grows; the three figures are fixed so the columns line up down
   the page, which is the whole reason to use a grid here rather than a table. */
.calc-head, .calc-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 74px 104px 92px 36px;
  gap: 8px; align-items: center;
}
.calc-head {
  font-size: .7rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); font-weight: 800; padding: 0 2px 8px;
}
.calc-head .num, .calc-row .num { text-align: right; }
.calc-row { margin-bottom: 8px; }
.calc-row input, .calc-rate input {
  font: inherit; color: var(--ink); background: var(--sunken);
  border: 0; border-radius: 12px; padding: 10px 12px; width: 100%;
  min-width: 0; font-size: .94rem;
}
.calc-row input.num { text-align: right; font-variant-numeric: tabular-nums; }

.calc-rate {
  display: grid; grid-template-columns: minmax(0, 1fr) 92px auto 36px;
  gap: 8px; align-items: center; margin-bottom: 8px;
}
.calc-rate input.num { text-align: right; }

@media (max-width: 560px) {
  /* Five columns on a phone is four too many. The header goes, and each field
     carries its own label instead. */
  .calc-head { display: none; }
  .calc-row { grid-template-columns: minmax(0, 1fr) 36px; }
  .calc-row input[data-field="quantity"] { grid-column: 1; }
  .calc-row input[data-field="price"] { grid-column: 1; }
  .calc-row input[data-field="discount"] { grid-column: 1; }
  .calc-row input.num { text-align: left; }
  .calc-row { padding-bottom: 12px; border-bottom: 1px solid var(--line); }
  .calc-rate { grid-template-columns: minmax(0, 1fr) 36px; }
  .calc-rate input.num { grid-column: 1; text-align: left; }
  /* The checkbox label is inline-flex and does not shrink, so left in a 1fr
     column it pushed the page 17px wider than the phone. */
  .calc-rate .calc-check { grid-column: 1 / -1; }
}

.calc-settings { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; align-items: end; }
@media (max-width: 560px) { .calc-settings { grid-template-columns: 1fr; } }
.calc-settings select, .calc-settings input {
  font: inherit; color: var(--ink); background: var(--sunken);
  border: 0; border-radius: 12px; padding: 11px 13px; width: 100%;
}

.calc-check {
  display: inline-flex; align-items: center; gap: 10px; min-width: 0;
  font-size: .93rem; font-weight: 600; cursor: pointer;
}
.calc-check span { min-width: 0; }
.calc-check input { width: 20px; height: 20px; accent-color: var(--brand); flex: 0 0 auto; }

.icon-x {
  width: 36px; height: 36px; border: 0; border-radius: 11px;
  background: transparent; color: var(--muted); cursor: pointer;
  font-size: 1.3rem; line-height: 1; display: grid; place-items: center;
  transition: background .18s ease, color .18s ease;
}
.icon-x:hover { background: color-mix(in srgb, var(--late) 14%, transparent); color: var(--late-ink); }

.bad-ink { color: var(--late-ink); }

/* The big answer on the single-figure tools. */
.answer {
  font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem);
  font-weight: 800; letter-spacing: -.04em; line-height: 1.05;
  margin: 4px 0 2px;
}
.answer-label {
  font-size: .74rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); font-weight: 800;
}
.answer-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-top: 20px; }
@media (max-width: 480px) { .answer-grid { grid-template-columns: 1fr; } }

.qr-out { display: grid; place-items: center; gap: 16px; }
.qr-out .qr-frame {
  background: #fff; padding: 16px; border-radius: var(--r-md);
  box-shadow: var(--shadow-sm); line-height: 0;
}
.qr-out .qr-frame svg { width: min(260px, 60vw); height: auto; }

/* Contact form ------------------------------------------------------------ */

.field { display: grid; gap: 7px; margin-bottom: 18px; }
.field label { font-weight: 700; font-size: .92rem; }
.field input, .field textarea, .field select {
  font: inherit; color: var(--ink); background: var(--sunken);
  border: 0; border-radius: var(--r-sm); padding: 14px 16px; width: 100%;
}
.field textarea { min-height: 160px; resize: vertical; }
.field .hint { font-size: .84rem; color: var(--muted); }

/* Call to action band ----------------------------------------------------- */

.cta-band { padding-bottom: clamp(58px, 7vw, 104px); }

/* Footer ------------------------------------------------------------------ */

.site-footer {
  background: var(--card); margin-top: 40px;
  padding: 62px 0 34px; border-top: 1px solid var(--line);
}
/* Three columns, not six. A six-column link farm is a footer nobody reads and
   a maintenance surface that goes stale — these are grouped by what somebody is
   trying to do: use it, learn it, or check who is behind it. */
.footer-grid { display: grid; grid-template-columns: 1.6fr repeat(3, minmax(0, 1fr)); gap: clamp(24px, 3vw, 48px); }
@media (max-width: 1000px) { .footer-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 640px) { .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.footer-brand { max-width: 34ch; }
.footer-brand p { color: var(--muted); font-size: .93rem; margin-top: 14px; }
@media (max-width: 640px) { .footer-brand { grid-column: 1 / -1; } }
.site-footer .col-title {
  font-size: .74rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 14px; line-height: 1.3;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.site-footer ul a { color: var(--ink-soft); font-size: .94rem; }
.site-footer ul a:hover { color: var(--brand); }
.footer-bottom {
  margin-top: 44px; padding-top: 22px; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between;
  color: var(--muted); font-size: .88rem;
}

/* WhatsApp — the button itself is styled in base.css, which the app loads
   too. On a phone it folds to the disc; this keeps it off the footer's last
   line. */
@media (max-width: 640px) {
  .footer-bottom { padding-bottom: 66px; }
}

/* Print — the legal pages get read on paper more than anything else here. */
@media print {
  .site-header, .site-footer, .nav, .theme-toggle, .cta-band, .doc-chip, .wa-float { display: none !important; }
  body::before { display: none; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .wrap { max-width: none; padding: 0; }
}
