/* Oak — marketing site.
 *
 * Plain CSS, no build step, no framework, so Albert can change a sentence or a colour without
 * running anything. The palette and the type pairing are lifted from src/styles.css on purpose:
 * the site and the product should feel like one thing to somebody who sees the page and then the
 * login screen ten seconds later.
 *
 * Fonts are self-hosted and preloaded rather than pulled from Google, because the audience is on
 * Tanzanian mobile data and a blocking round-trip to fonts.gstatic.com is the slowest thing on
 * an otherwise very small page.
 *
 * ⚠️ Every HTML page links this file as `style.css?v=20260830`, not `style.css`. That query
 * string is a ONE-TIME cache-bust, not a convention to keep up — see Caddyfile.site for the real
 * fix. Until 2026-08-30 this file was served with `Cache-Control: immutable, max-age=31536000`
 * (the same rule meant for fonts/screenshots, which never change), so a browser that had ever
 * loaded the site could sit on stale CSS for up to a year after any redeploy, no ordinary reload
 * fixing it. The header is now short-lived like the HTML, so future edits reach people within
 * minutes on their own — do NOT bump this query string again for a normal style change; it did
 * its one job forcing already-cached browsers off the old immutable copy the day this was fixed.
 */

@font-face {
  font-family: 'Manrope';
  src: url('fonts/manrope-latin-400-normal.woff2') format('woff2');
  font-weight: 400; font-display: swap; font-style: normal;
}
@font-face {
  font-family: 'Manrope';
  src: url('fonts/manrope-latin-700-normal.woff2') format('woff2');
  font-weight: 700; font-display: swap; font-style: normal;
}
@font-face {
  font-family: 'Fraunces';
  src: url('fonts/fraunces-latin-600-normal.woff2') format('woff2');
  font-weight: 600; font-display: swap; font-style: normal;
}

:root {
  --primary: #23262F;
  --sidebar: #1C1F27;
  --primary-soft: #31353F;   /* the app's own chip background — see .lang */
  --accent: #C9A24B;
  --accent-light: #E0BC6B;
  --accent-tint: #EFDFAE;   /* icon-badge background — deliberately NOT --ivory: a badge the same
                                 colour as the section behind it (.strip, .why) would disappear */
  --ivory: #F2ECDD;
  --bg: #F5F4F0;
  --ink: #23262F;
  --muted: #767C88;
  --line: #E6E4DE;
  --card: #fff;
  --ok: #2E7D5B;
  /* A second, sparing accent — used only for the "without Oak" side of the before/after
     comparison in .problem. Never competes with gold as the page's primary colour. */
  --clay: #9B4A34;
  --clay-tint: #F0DBCE;
  --shadow-lg: 0 20px 44px -26px rgba(35, 38, 47, .38);
  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-body: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --wrap: 1100px;
}

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

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

h1, h2, h3 { font-family: var(--font-display); font-weight: 600; line-height: 1.15; margin: 0 0 .5em; }
h1 { font-size: clamp(2rem, 5.5vw, 3.4rem); letter-spacing: -0.02em; }
h2 { font-size: clamp(1.5rem, 3.6vw, 2.2rem); }
h3 { font-size: 1.15rem; }
p { margin: 0 0 1em; }
a { color: var(--ink); }

.wrap { width: min(var(--wrap), 100% - 2.5rem); margin-inline: auto; }
section { padding: clamp(2.5rem, 7vw, 5rem) 0; }
.lead { font-size: 1.15rem; color: var(--muted); max-width: 42ch; }
.muted { color: var(--muted); }

/* Focus rings stay visible. This costs nothing and the app is held to the same standard. */
a:focus-visible, .btn:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

/* ---------- header ---------- */
.site-head {
  display: flex; align-items: center; gap: 1rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--line);
  background: var(--bg);
}
.brand { display: flex; align-items: center; gap: .6rem; text-decoration: none; margin-right: auto; }
.brand img { width: 38px; height: 38px; display: block; }
.brand b { font-family: var(--font-display); font-size: 1.5rem; line-height: 1; }
.brand span { display: block; font-size: .68rem; color: var(--muted); letter-spacing: .02em; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .62rem 1.15rem;
  border-radius: 8px;
  font-weight: 700;
  font-size: .95rem;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  /* "Log in" broke across two lines in a 360px header, which reads as a mistake before anyone
     has read a word of the copy. A button label is one line or it is nothing. */
  white-space: nowrap;
}
.btn svg { width: 1.05em; height: 1.05em; flex-shrink: 0; }

/* Language switch — deliberately the SAME control the product uses.
 *
 * Copied from `.sidebar .lang-toggle` in src/styles.css rather than reinvented: two separate
 * dark chips with a small gap, and the active one marked by a GOLD OUTLINE and gold text, not by
 * a filled background. The first version here was a joined segmented bar with a solid gold fill,
 * which worked but looked like a different product's control — and the whole point of matching
 * the palette and the type is that somebody who sees this page and then the login screen ten
 * seconds later recognises the same software.
 */
.lang {
  display: inline-flex;
  gap: 6px;
  flex: 0 0 auto;
}
.lang a {
  /* Flex-centred with an explicit height so the chips line up with the buttons beside them.
     The app's sit alone in a sidebar and are 33px; dropped into a header next to 46px buttons
     that 13px difference reads as a mistake, so the app's COLOURS, radius, weights and gold
     outline are kept and only the box is sized to its new neighbours. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 46px;
  /* The app's chips are flex:1 inside a fixed-width sidebar, so both come out the same size.
     A header has no such width to divide, so an equal min-width does the same job — otherwise
     "SW" renders wider than "EN" and the pair looks lopsided. */
  min-width: 46px;
  text-align: center;
  padding: 0 8px;
  border: 1px solid transparent;
  border-radius: 5px;
  background: var(--primary-soft);
  color: var(--ivory);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.35;
  text-decoration: none;
  transition: border-color .15s ease, color .15s ease;
}
.lang a:hover { color: var(--accent-light); }
.lang a.on { border-color: var(--accent); color: var(--accent-light); font-weight: 700; }

/* The header CTA carries its full label where there is room and a short one where there is not.
   Measured: at 360px the full labels overflowed by 13px in English and 41px in Swahili, where
   "Omba maonyesho" is half again as long as "Book a demo" — a header that runs off the side of
   the page is the first thing a visitor sees go wrong. */
.narrow-only { display: none; }

/* At 360px the wordmark, the tagline, a language switch and two buttons cannot all fit. The
   tagline is the part nobody needs in order to act, so it is the first to go, and the CTA drops
   to its short label. */
@media (max-width: 460px) {
  .brand span span { display: none; }
  .brand b { font-size: 1.3rem; }
  .site-head .btn { padding: .55rem .7rem; font-size: .85rem; }
  .site-head .wrap { gap: .4rem !important; }
  .lang a { min-width: 40px; height: 41px; padding: 0 6px; font-size: 13px; }
  .wide-only { display: none; }
  .narrow-only { display: inline; }
}

/* 320px is a real phone, not a hypothetical one — an old iPhone SE or a cheap Android is exactly
   the device this audience has. Eight pixels of overflow there is still a page that slides
   sideways under the thumb. */
@media (max-width: 359px) {
  .wrap { width: calc(100% - 1.5rem); }
  .brand img { width: 32px; height: 32px; }
  .brand b { font-size: 1.15rem; }
  .site-head .btn { padding: .5rem .55rem; font-size: .8rem; }
  .lang a { min-width: 36px; height: 38px; padding: 0 5px; font-size: 12.5px; }
}
.btn { transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease, border-color .15s ease; }
.btn.primary { background: var(--accent); color: var(--sidebar); }
.btn.primary:hover { background: var(--accent-light); transform: translateY(-1px); box-shadow: 0 10px 22px -12px rgba(201, 162, 75, .55); }
.btn.ghost { border-color: var(--line); color: var(--ink); background: var(--card); }
.btn.ghost:hover { border-color: var(--accent); transform: translateY(-1px); }
.btn.lg { padding: .85rem 1.6rem; font-size: 1.05rem; }
.btn.sm { padding: .5rem .9rem; font-size: .87rem; }
/* WhatsApp's own brand green — the one place on the site a colour outside the gold/ink palette
   is deliberate, because a green WhatsApp button is instantly recognisable in a way a gold one
   wouldn't be, and that recognisability is the whole point of the button existing. */
.btn.whatsapp { background: #25D366; color: #08331B; }
.btn.whatsapp:hover { background: #22c15e; transform: translateY(-1px); box-shadow: 0 10px 22px -12px rgba(37, 211, 102, .55); }
@media (prefers-reduced-motion: reduce) { .btn { transition: none; } .btn:hover { transform: none; } }

/* The two quiet, one-tap contact options below the demo form — a phone call and a WhatsApp
   message, side by side, in place of a single easy-to-miss text link. */
.hero-contact-row { display: flex; gap: .6rem; margin-top: .9rem; }
.hero-contact-row .btn { flex: 1; }

/* ---------- hero ---------- */
.hero {
  position: relative; overflow: hidden; padding-top: clamp(2.5rem, 6vw, 4.5rem);
  background: radial-gradient(60% 55% at 88% 0%, rgba(201, 162, 75, .10), transparent 70%), var(--bg);
}
/* A thin kanga/shuka-stripe rule instead of a plain hairline — used exactly once, at the very top
   of the page, so it reads as a considered detail rather than wallpaper. */
.hero::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 5px;
  background: repeating-linear-gradient(90deg, var(--accent) 0 3px, transparent 3px 20px, var(--clay) 20px 23px, transparent 23px 40px);
  opacity: .55;
}
.hero h1 { max-width: 16ch; }
.hero .lead { font-size: 1.22rem; max-width: 48ch; }

/* The form beside the pitch, not a click away — see the comment in index.html for why. Single
   column (form stacks below the pitch) until there is real room for both side by side; a form
   squeezed into a narrow left-over sliver is worse than one that is simply below the fold. */
.hero-grid { display: grid; gap: 2rem; align-items: start; }
@media (min-width: 900px) { .hero-grid { grid-template-columns: 1.6fr 1fr; gap: 2.5rem; } }
.hero-form-card {
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  padding: 1.35rem 1.4rem; box-shadow: var(--shadow-lg);
  max-width: 340px; margin-left: auto;
}
@media (max-width: 899px) { .hero-form-card { max-width: none; margin-left: 0; } }
/* Sticky, but only within the hero itself — a sticky element can never travel further than its
   own parent's height, and the hero section ends where the pitch text does, not at the bottom
   of the homepage. So this keeps the form in view while the (slightly taller, on most screens)
   pitch column finishes scrolling past within the hero, not for the whole page below it — an
   honest, small effect, not a page-long sticky sidebar. Below 900px the form is simply part of
   the normal flow, stacked under the pitch. */
@media (min-width: 900px) { .hero-form-card { position: sticky; top: 1.25rem; } }
.hero-shot {
  margin-left: 0; margin-right: 0;
  margin-top: clamp(1.8rem, 4vw, 2.8rem);
  border-radius: 12px;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  background: var(--card);
}
.hero-shot img { display: block; width: 100%; height: auto; }

.eyebrow {
  font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); margin-bottom: .6rem;
}

/* ---------- breadcrumbs ----------
   Only on pages one level under the homepage — which is every sub-page this site has, so the
   trail is always exactly "Oak / Page Name". Sits above the eyebrow, small and quiet: it's a
   navigation aid and a crawl signal, not something meant to compete with the H1 for attention. */
.breadcrumbs { font-size: .85rem; color: var(--muted); margin-bottom: 1rem; }
.breadcrumbs a { color: var(--muted); text-decoration: none; }
.breadcrumbs a:hover { color: var(--accent); text-decoration: underline; }
.breadcrumbs .sep { margin: 0 .45rem; opacity: .5; }
.breadcrumbs [aria-current] { color: var(--ink); font-weight: 600; }

/* The four things a hotelier is buying, above the fold. Ticks rather than bullets: this is a
   list of what they get, not a paragraph broken up. */
.hero-points {
  list-style: none; padding: 0; margin: 1.25rem 0 1.75rem;
  display: grid; gap: .7rem .8rem;
}
@media (min-width: 720px) { .hero-points { grid-template-columns: 1fr 1fr; max-width: 46rem; } }
/* Each benefit gets its own icon — feature-relevant (channel sync, booking engine, night audit,
   housekeeping, mobile money, on-site support) rather than a repeated generic checkmark, using
   the same icon-badge treatment as .tag/.why-item elsewhere on the page for consistency. */
.hero-points li { display: flex; align-items: center; gap: .6rem; font-weight: 600; }
.hero-points li svg {
  box-sizing: content-box; width: 1.05em; height: 1.05em; padding: .34em;
  background: var(--accent-tint); border-radius: 7px; color: var(--accent); flex-shrink: 0;
}

/* A coverage line, not a customer-count claim — see the comment beside it in index.html for why
   that distinction matters. Quiet on purpose: smaller and lighter than the ticks above it, so it
   reads as a footnote to the pitch rather than competing with it for attention. */
.hero-coverage { font-size: .87rem; color: var(--muted); margin: 0; }

/* ---------- the value strip ---------- */
.strip { background: var(--ivory); padding: clamp(2rem, 5vw, 3rem) 0; }
.strip-grid { display: grid; gap: 1.5rem; }
@media (min-width: 640px) { .strip-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .strip-grid { grid-template-columns: repeat(4, 1fr); } }
.strip-grid b { display: flex; align-items: center; gap: .6rem; margin-bottom: .3rem; }
.strip-grid b svg { color: var(--accent); flex-shrink: 0; }
.strip-grid p { margin: 0; color: var(--muted); font-size: .95rem; }

/* Feature sub-points. The thing a comparison shopper actually reads. */
.ticks { list-style: none; padding: 0; margin: 1rem 0 0; }
.ticks li {
  position: relative; padding-left: 1.5rem; margin-bottom: .45rem;
  color: var(--ink); font-size: .97rem;
}
.ticks li::before {
  content: "✓"; position: absolute; left: 0; color: var(--accent); font-weight: 700;
}

/* ---------- the problem ---------- */
.problem { background: var(--sidebar); color: var(--ivory); }
.problem h2 { color: var(--ivory); }
.problem p { max-width: 60ch; color: #CFCBC1; }
.problem strong { color: var(--accent-light); }

/* Before/after comparison — the same story the three paragraphs above already tell, in a shape
   that can be read in five seconds by someone who skims before they commit to reading. */
.pain-cols { display: grid; gap: 1.25rem; margin-top: 2.25rem; max-width: 60rem; }
@media (min-width: 760px) { .pain-cols { grid-template-columns: 1fr 1fr; } }
.pain-card { border-radius: 12px; padding: 1.4rem 1.5rem; border: 1px solid; }
.pain-card.before { background: rgba(155, 74, 52, .14); border-color: rgba(155, 74, 52, .35); }
.pain-card.after { background: rgba(201, 162, 75, .14); border-color: rgba(201, 162, 75, .4); }
.pain-card .label {
  font-weight: 700; font-size: .76rem; letter-spacing: .07em; text-transform: uppercase;
  margin-bottom: .9rem; display: block;
}
.pain-card.before .label { color: #E39C86; }
.pain-card.after .label { color: var(--accent-light); }
.pain-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .7rem; }
.pain-steps li { display: flex; gap: .6rem; font-size: .95rem; font-weight: 600; color: var(--ivory); }
.pain-steps .n {
  width: 1.4rem; height: 1.4rem; border-radius: 50%; display: grid; place-items: center;
  font-size: .76rem; flex-shrink: 0; font-family: var(--font-display); font-weight: 700;
}
.pain-card.before .n { background: rgba(227, 156, 134, .22); color: #E39C86; }
.pain-card.after .n { background: rgba(224, 188, 107, .25); color: var(--accent-light); }

/* ---------- feature blocks ---------- */
.features { display: grid; gap: clamp(2rem, 5vw, 3.5rem); }
.feature { display: grid; gap: 1.5rem; align-items: center; }
@media (min-width: 820px) {
  .feature { grid-template-columns: 1fr 1.25fr; }
  .feature.flip .feature-text { order: 2; }
}
.feature img {
  display: block; width: 100%; height: auto;
  border-radius: 10px; border: 1px solid var(--line);
  background: var(--card);
}
.feature-text p { color: var(--muted); margin-bottom: 0; }
.tag {
  display: inline-flex; align-items: center; gap: .4rem; font-size: .72rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--accent); margin-bottom: .35rem;
}
/* Icon size stays in em off the tag's own font-size, so it scales with the label instead of
   needing its own breakpoint. currentColor picks up the tag's gold, matching how these render in
   the app itself (src/components/Icons.jsx) rather than introducing a second, unrelated colour. */
.tag svg { width: 1.15em; height: 1.15em; flex-shrink: 0; }

/* ---------- icon badge ----------
   The three places an app icon sits next to a label (.tag on a feature block, .why-item's
   heading, .strip-grid's value strip) share one treatment: a small tinted rounded-square behind
   the glyph instead of a bare line icon. Pure CSS on the existing <svg> — background/padding/
   radius work on an inline SVG exactly like they would on any other replaced element, so this
   needed no HTML change across the four files these classes are shared with. */
.tag svg, .why-item h3 svg, .strip-grid b svg {
  box-sizing: content-box; padding: .34em; background: var(--accent-tint); border-radius: 7px;
}
.why-item h3 svg, .strip-grid b svg { width: 1.05em; height: 1.05em; }

/* ---------- why oak ---------- */
.why { background: var(--ivory); }
.why-grid { display: grid; gap: 1rem; margin-top: 1.5rem; }
@media (min-width: 700px) { .why-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .why-grid { grid-template-columns: repeat(3, 1fr); } }
.why-item {
  background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 1.1rem 1.25rem;
}
.why-item { transition: transform .15s ease, box-shadow .15s ease; }
.why-item:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.why-item h3 { display: flex; align-items: center; gap: .55rem; margin-bottom: .25rem; }
.why-item h3 svg { color: var(--accent); flex-shrink: 0; }
.why-item p { margin: 0; color: var(--muted); font-size: .97rem; }
@media (prefers-reduced-motion: reduce) { .why-item { transition: none; } .why-item:hover { transform: none; } }
.why-punch {
  margin-top: 1.5rem; padding: 1.25rem 1.5rem;
  border-left: 4px solid var(--accent); background: var(--card);
  font-family: var(--font-display); font-size: clamp(1.1rem, 2.4vw, 1.4rem); line-height: 1.4;
}

/* ---------- testimonials ----------
   Ready to use the moment there are real quotes — see the commented-out block in index.html /
   index-sw.html for why it isn't live yet, and how to activate it. */
.testimonials-grid { display: grid; gap: 1.25rem; margin-top: 1.5rem; }
@media (min-width: 700px) { .testimonials-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .testimonials-grid { grid-template-columns: repeat(3, 1fr); } }
.testimonial {
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  padding: 1.4rem 1.5rem; display: flex; flex-direction: column; gap: 1rem;
}
.testimonial blockquote {
  margin: 0; font-family: var(--font-display); font-size: 1.05rem; line-height: 1.5;
  font-weight: 600; color: var(--ink);
}
.testimonial blockquote::before { content: "“"; color: var(--accent); }
.testimonial blockquote::after { content: "”"; color: var(--accent); }
.testimonial-who { display: flex; align-items: center; gap: .75rem; }
.testimonial-avatar {
  width: 42px; height: 42px; border-radius: 50%; background: var(--ivory);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 700; color: var(--accent); flex: 0 0 auto;
}
.testimonial-who b { display: block; font-size: .92rem; }
.testimonial-who span { display: block; font-size: .82rem; color: var(--muted); }

/* ---------- pricing ---------- */
.price-scroll { overflow-x: auto; margin-top: 1.5rem; }
table.prices { border-collapse: collapse; width: 100%; min-width: 480px; background: var(--card); }
table.prices th, table.prices td { padding: .8rem 1rem; text-align: left; border-bottom: 1px solid var(--line); }
table.prices th { font-size: .78rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
table.prices td.amount { text-align: right; font-weight: 700; white-space: nowrap; }
table.prices tr:last-child td { border-bottom: 0; }

/* Cards, not a table — a room-count comparison reads faster as four things placed side by side
   than as rows in a table nobody scans past the second column. table.prices above is kept, unused
   for now, in case a dense side-by-side comparison is ever wanted again. */
.price-cards { display: grid; gap: 1rem; margin-top: 1.5rem; }
@media (min-width: 760px) { .price-cards { grid-template-columns: repeat(4, 1fr); } }
.price-card {
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  padding: 1.4rem 1.3rem; display: flex; flex-direction: column;
  transition: transform .15s ease, box-shadow .15s ease;
}
.price-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.price-card .plan { font-family: var(--font-display); font-weight: 600; font-size: 1.1rem; }
.price-card .rooms { font-size: .82rem; color: var(--muted); margin-top: .1rem; }
.price-card .amount {
  font-family: var(--font-body); font-weight: 800; font-size: 1.7rem;
  margin: .9rem 0 0; font-variant-numeric: tabular-nums;
}
.price-card .amount sup { font-size: .5em; font-weight: 700; color: var(--muted); margin-left: .15em; }
.price-card .per { display: block; font-size: .78rem; color: var(--muted); margin: .15rem 0 1.1rem; }
.price-card ul { list-style: none; padding: 0; margin: 0 0 1.2rem; flex-grow: 1; }
.price-card li {
  position: relative; padding-left: 1.4rem; margin-bottom: .5rem; font-size: .86rem; color: var(--ink);
}
.price-card li::before { content: "✓"; position: absolute; left: 0; color: var(--accent); font-weight: 700; }
.price-card.enterprise { background: var(--sidebar); border-color: #2C303A; }
.price-card.enterprise .plan, .price-card.enterprise .amount { color: var(--ivory); }
.price-card.enterprise .rooms, .price-card.enterprise .per { color: #9CA0AC; }
.price-card.enterprise li { color: #CFCBC1; }
@media (prefers-reduced-motion: reduce) { .price-card { transition: none; } .price-card:hover { transform: none; } }

.addon {
  margin-top: 1rem; padding: 1rem 1.25rem; background: var(--card);
  border: 1px solid var(--line); border-left: 4px solid var(--accent); border-radius: 8px;
}
.addon b { display: block; }
.addon p { margin: .25rem 0 0; color: var(--muted); font-size: .95rem; }
/* One row per plan, priced with it — not a wall of text explaining that OTA Connect costs
   different amounts, just showing the four numbers the way the plan cards above already show
   theirs. */
.addon-tiers {
  list-style: none; margin: .9rem 0 0; padding: .8rem 0 0; border-top: 1px solid var(--line);
  display: grid; gap: .4rem;
}
@media (min-width: 480px) { .addon-tiers { grid-template-columns: repeat(4, 1fr); gap: .6rem; } }
.addon-tiers li { display: flex; justify-content: space-between; gap: .5rem; font-size: .88rem; }
@media (min-width: 480px) { .addon-tiers li { flex-direction: column; gap: .1rem; } }
.addon-tiers li span:first-child { font-weight: 700; color: var(--ink); }
.addon-tiers li span:last-child { color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------- cta + footer ---------- */
.cta { text-align: center; }
.cta h2 { max-width: 20ch; margin-inline: auto; }
.cta p { max-width: 46ch; margin-inline: auto; color: var(--muted); }

.site-foot {
  background: var(--sidebar); color: #CFCBC1;
  padding: 2.5rem 0; font-size: .95rem;
}
.site-foot a { color: var(--ivory); }
.foot-grid { display: grid; gap: 1.5rem; }
@media (min-width: 700px) { .foot-grid { grid-template-columns: 1.3fr 1fr 1fr; } }
.site-foot h3 { color: var(--ivory); font-size: .95rem; margin-bottom: .5rem; }
.site-foot ul { list-style: none; margin: 0; padding: 0; }
.site-foot li { margin-bottom: .3rem; }
.foot-legal { margin-top: 2rem; padding-top: 1.25rem; border-top: 1px solid #2C303A; font-size: .85rem; }

/* ---------- lead-capture form (contact page) ----------
   Plain HTML form fields styled to match the app's own input treatment (border, radius, focus
   ring in --accent) — no framework, no JS, just labelled inputs. */
.lead-form { display: flex; flex-direction: column; gap: 1rem; }
.field { display: flex; flex-direction: column; gap: .35rem; font-size: .92rem; font-weight: 600; }
.field input {
  font: inherit; font-weight: 400; font-size: 1rem;
  padding: .65rem .8rem; border: 1px solid var(--line); border-radius: 8px;
  background: var(--card); color: var(--ink);
}
.field input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.contact-alt { border-top: 1px solid var(--line); padding-top: 1rem; margin-top: 1rem; }

/* ---------- prose (privacy) ---------- */
.prose { max-width: 68ch; }
.prose h2 { margin-top: 2rem; }
.prose ul { padding-left: 1.2rem; }
.prose li { margin-bottom: .4rem; }
