@font-face {
  font-family: "DM Sans";
  src: url("/assets/fonts/dm-sans-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 100 1000;
  font-display: swap;
}

@font-face {
  font-family: "Cormorant Garamond";
  src: url("/assets/fonts/cormorant-garamond-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
}

@font-face {
  font-family: "Cormorant Garamond";
  src: url("/assets/fonts/cormorant-garamond-italic-latin.woff2") format("woff2");
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
}

:root {
  color-scheme: light;
  --ground: #f0ebe1;
  --panel: #fff9ef;
  --card: #ffffff;
  --ink: #1c1c18;
  --muted: #68685f;
  --accent: #b8820f;
  --accent-dark: #916407;
  --accent-hover: #704b03;
  --forest: #1b4332;
  --forest-deep: #102c20;
  --border: #e2d8c8;
  --shadow: 0 20px 60px rgba(31, 38, 28, 0.09);
  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --sans: "DM Sans", "Segoe UI", Arial, sans-serif;
  /* Header height is a token because both hero paddings clear it. Hard-coding
     it means changing the wordmark slides headlines under the nav. */
  --header-h: 82px;
  /* Every hero is this tall, homepage and interior alike. Both read the
     token rather than repeating a number, because the two drifted apart
     (640 vs 460) and nothing said which was intended. */
  --hero-h: min(640px, 86vh);
  /* Focus rings must contrast with the surface behind them, so the dark blocks
     below re-declare this rather than relying on one global colour. */
  --focus: #14301f;
}

* { box-sizing: border-box; }
/* The header is fixed, so an anchored jump has to clear it or the heading it
   targets lands underneath the nav. Applies to the skip link on every page. */
html { scroll-padding-top: var(--header-h); }
body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; }
img { display: block; max-width: 100%; height: auto; }
button, input, textarea, select { font: inherit; }
.shell { width: min(1180px, calc(100% - 40px)); margin-inline: auto; }
.skip-link { position: fixed; top: 12px; left: 12px; z-index: 999; padding: 10px 16px; background: var(--card); color: var(--forest); transform: translateY(-150%); }
.skip-link:focus { transform: none; }

/* Neither self-hosted font subset contains U+2192 or U+2713, so every arrow and
   tick used to fall back to a system symbol font at a different weight. They are
   inline SVG now; `.i` is the shared sizing for them. */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.i { flex: none; width: 19px; height: 12px; }

/* Fixed, not sticky. Sticky would put the header in flow and push the hero
   photograph down by its own height, and the hero is designed to run behind
   it - every hero already reserves the space with a `calc(var(--header-h) +
   ...)` top padding, so out-of-flow is the shape this layout expects.

   It has to carry its own background now. This site ships no JavaScript by
   design, so there is no scroll listener to add a "scrolled" class with: the
   header passes over the dark hero and then over cream sections, and a
   transparent bar with white text is invisible on the second. One translucent
   dark bar reads correctly on both - over cream it composites to about
   #384e44, which holds white text comfortably - and the blur is a progressive
   enhancement, because .82 alpha is already opaque enough to read without it. */
.site-header { position: fixed; inset: 0 0 auto; z-index: 20; color: #fff; background: rgba(16, 44, 33, .82); border-bottom: 1px solid rgba(255,255,255,.16); --focus: #edc86f; }

/* The blur is desktop-only, and not for taste. `backdrop-filter` makes an
   element a containing block for its `position: fixed` descendants, and the
   mobile menu's dismiss layer is exactly that - `.mobile-nav[open]
   summary::after` is a fixed, full-viewport backdrop that closes the menu when
   you tap beside it. Inside a blurred header its `inset: 0` would resolve
   against the header instead of the viewport, shrinking it to the nav bar, and
   tapping the page would stop closing the menu. Above 901px `.mobile-nav` is
   `display: none`, so that layer does not exist and the blur is free. */
@media (min-width: 901px) {
  .site-header { backdrop-filter: saturate(140%) blur(12px); -webkit-backdrop-filter: saturate(140%) blur(12px); }
}
.nav-shell { width: min(1240px, calc(100% - 40px)); min-height: var(--header-h); margin-inline: auto; display: flex; align-items: center; gap: 36px; }
/* The wordmark is one image - kudu, HUNTBOOK and SOUTH AFRICA together - not a
   mark beside live text, so the site presents the same logo the app does.
   Sized by height because that is what has to clear --header-h; the width
   follows the 640x193 intrinsic ratio, and the width/height attributes on the
   img keep the box reserved before it decodes. */
.wordmark { display: inline-flex; align-items: center; text-decoration: none; }
.wordmark-image { width: auto; height: 54px; }
.wordmark-image-footer { height: 60px; }
.desktop-nav { display: flex; gap: 28px; margin-left: auto; }
.desktop-nav a, .text-link { color: rgba(255,255,255,.82); text-decoration: none; font-size: 14px; font-weight: 650; }
.desktop-nav a:hover, .desktop-nav a:focus-visible, .text-link:hover, .text-link:focus-visible { color: #fff; }
.desktop-nav a[aria-current="page"] { color: #fff; box-shadow: inset 0 -2px #e6bd5d; }
.desktop-actions { display: flex; align-items: center; gap: 22px; }
.mobile-nav { display: none; margin-left: auto; position: relative; }
.mobile-nav summary { position: relative; z-index: 1; width: 42px; height: 42px; list-style: none; display: grid; align-content: center; gap: 5px; cursor: pointer; }
.mobile-nav summary::-webkit-details-marker { display: none; }
.mobile-nav summary span { display: block; width: 24px; height: 2px; margin-inline: auto; background: currentColor; transition: transform .2s ease, opacity .2s ease; }
/* Without JavaScript the only way to dismiss the menu by tapping the page is a
   full-viewport pseudo-element on the summary: a tap anywhere toggles it shut. */
.mobile-nav[open] summary::after { content: ""; position: fixed; inset: 0; z-index: -1; }
.mobile-nav[open] summary span:first-child { transform: translateY(7px) rotate(45deg); }
.mobile-nav[open] summary span:nth-child(2) { opacity: 0; }
.mobile-nav[open] summary span:last-child { transform: translateY(-7px) rotate(-45deg); }
.mobile-nav nav { position: absolute; top: 48px; right: 0; z-index: 2; width: min(310px, calc(100vw - 32px)); padding: 18px; display: grid; gap: 4px; border-radius: 14px; background: var(--panel); color: var(--ink); box-shadow: var(--shadow); --focus: #14301f; }
.mobile-nav nav a { padding: 9px 10px; text-decoration: none; }

.button { display: inline-flex; min-height: 50px; align-items: center; justify-content: center; gap: 12px; padding: 0 22px; border: 1px solid var(--accent-dark); border-radius: 7px; background: var(--accent-dark); color: #fff; text-decoration: none; font-size: 14px; font-weight: 750; box-shadow: 0 10px 28px rgba(184,130,15,.24); transition: background .2s ease, border-color .2s ease, transform .2s ease; }
.button:hover, .button:focus-visible { background: var(--accent-hover); border-color: var(--accent-hover); transform: translateY(-1px); }
.button-small { min-height: 42px; padding-inline: 18px; }
.button-ghost { border-color: rgba(255,255,255,.45); background: rgba(255,255,255,.06); box-shadow: none; }
.button-ghost:hover, .button-ghost:focus-visible { background: rgba(255,255,255,.14); border-color: #fff; }
.button-light { background: var(--panel); border-color: var(--panel); color: var(--forest); box-shadow: none; }
.button-light:hover, .button-light:focus-visible { background: #fff; border-color: #fff; }

.hero { position: relative; min-height: var(--hero-h); display: grid; align-items: center; overflow: hidden; background: var(--forest-deep); color: #fff; --focus: #edc86f; }
.hero-art, .hero-scrim { position: absolute; inset: 0; }
/* The same photograph the social card uses, graded to survive the scrim.
   See scripts/derive-site-images.py. */
.hero-art { background: var(--hero-art) center 72% / cover no-repeat, var(--forest-deep); }
/* Three layers, each doing one job: the horizontal ramp keeps the headline
   readable, the top band keeps the transparent header off the bright haze, and
   the bottom band grounds the section edge. */
.hero-scrim { background: linear-gradient(90deg, rgba(9,32,23,.80) 0%, rgba(9,32,23,.55) 45%, rgba(9,32,23,.22) 75%, rgba(9,32,23,.10) 100%), linear-gradient(180deg, rgba(5,18,13,.55), transparent calc(var(--header-h) + 60px)), linear-gradient(0deg, rgba(5,18,13,.35), transparent 40%); }
.hero-content { position: relative; z-index: 1; padding: calc(var(--header-h) + 68px) 0 82px; }
.eyebrow { margin: 0 0 18px; color: var(--accent-dark); font-size: 12px; line-height: 1.2; font-weight: 800; letter-spacing: .18em; text-transform: uppercase; }
.eyebrow.light { color: #edc86f; }
h1, h2, h3 { text-wrap: balance; }
h1 { max-width: 760px; margin: 0; font: 700 clamp(2.9rem, 5.6vw, 4.6rem)/.99 var(--serif); letter-spacing: -.03em; }
h1 em { color: #edc86f; font-style: italic; font-weight: 400; }
.hero-copy { max-width: 620px; margin: 26px 0 0; color: rgba(255,255,255,.88); font-size: clamp(1.05rem, 2vw, 1.2rem); line-height: 1.6; }
.button-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 32px; }
.trust-list { display: flex; flex-wrap: wrap; gap: 12px 28px; margin: 32px 0 0; padding: 0; list-style: none; color: rgba(255,255,255,.82); font-size: 14px; }
.trust-list li { display: flex; align-items: center; gap: 9px; }
.trust-list .i, .check-list .i { width: 15px; height: 15px; }
.trust-list .i { color: #edc86f; }

.section { padding: 96px 0; }
/* Two light sections in a row otherwise stack 192px of empty cream between
   them, which reads as a missing block rather than a deliberate gap. */
.section + .section { padding-top: 0; }
.section-heading { max-width: 700px; margin-bottom: 44px; }
.section-heading.centre { margin-inline: auto; text-align: center; }
.section-heading h2, .band-cta h2 { margin: 0; font: 700 clamp(2rem, 3.6vw, 2.9rem)/1.05 var(--serif); letter-spacing: -.025em; }
.section-heading > p:last-child { margin: 18px 0 0; color: var(--muted); font-size: 18px; }

/* Two-audience fork. A two-sided marketplace has to route the visitor on the
   homepage; the navigation alone leaves both audiences reading generic copy. */
.audience-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.audience-card { display: grid; align-content: start; padding: 40px; border: 1px solid var(--border); border-radius: 14px; background: var(--card); box-shadow: 0 8px 30px rgba(30,30,24,.04); }
.audience-card h3 { margin: 0 0 14px; font: 700 clamp(1.7rem, 2.6vw, 2.2rem)/1.08 var(--serif); letter-spacing: -.02em; }
.audience-card > p { margin: 0 0 20px; color: var(--muted); }
.audience-card .check-list { margin: 0 0 26px; }
.audience-card .arrow-link { justify-self: start; }
.audience-card.farmer-card { background: var(--forest); border-color: var(--forest); color: #fff; --focus: #edc86f; }
.farmer-card > p, .farmer-card .check-list li { color: rgba(255,255,255,.78); }
.farmer-card .check-list .i { color: #edc86f; }
.farmer-card .arrow-link { color: #edc86f; }

.step-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; align-items: stretch; }
.step-card { position: relative; min-height: 265px; padding: 34px; border: 1px solid var(--border); border-radius: 12px; background: var(--card); box-shadow: 0 8px 30px rgba(30,30,24,.04); }
/* A real lift: the card grows into the space above and below its neighbours
   rather than being translated out of a row it still occupies. */
.step-card.featured { margin-block: -14px; padding-block: 48px; background: var(--forest); color: #fff; box-shadow: var(--shadow); --focus: #edc86f; }
.step-number { display: block; margin-bottom: 46px; color: var(--accent); font: italic 500 28px/1 var(--serif); }
.featured .step-number { color: #edc86f; }
.step-card h3 { margin: 0 0 12px; font: 700 25px/1.15 var(--serif); }
.step-card p { margin: 0; color: var(--muted); }
.step-card.featured p { color: rgba(255,255,255,.78); }

/* Dark band. Long cream pages need a tonal break or every section reads the
   same weight. */
.section-dark { padding: 88px 0; background: var(--forest-deep); color: #fff; --focus: #edc86f; }
.section-dark .section-heading h2 { color: #fff; }
.section-dark .section-heading > p:last-child { color: rgba(255,255,255,.74); }
.stat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 46px; }
.stat-grid div { padding-top: 24px; border-top: 1px solid rgba(255,255,255,.18); }
.stat-grid strong { display: block; font: 700 clamp(2.6rem, 5vw, 3.6rem)/1 var(--serif); letter-spacing: -.03em; color: #edc86f; }
.stat-grid span { display: block; margin-top: 12px; color: rgba(255,255,255,.76); font-size: 15px; }
.status-note { margin: 42px 0 0; padding: 20px 24px; border-left: 2px solid #edc86f; color: rgba(255,255,255,.78); font-size: 15px; }

/* Pricing teaser. Any price shown outside pricing.html is a second copy of a
   number that lives in billingPlans.ts, so scripts/test-site.mjs pins these too. */
.teaser { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 32px; padding: 42px 46px; border: 1px solid var(--border); border-radius: 16px; background: var(--panel); }
.teaser h2 { margin: 0 0 10px; font: 700 clamp(1.7rem, 3vw, 2.3rem)/1.1 var(--serif); letter-spacing: -.02em; }
.teaser p { margin: 0; color: var(--muted); }
.teaser b { color: var(--ink); font-weight: 750; }

.band-cta { padding: 72px 0; background: var(--forest); color: #fff; --focus: #edc86f; }
.split-cta { display: flex; align-items: center; justify-content: space-between; gap: 48px; }
.band-cta h2 { max-width: 760px; font-size: clamp(1.9rem, 3.4vw, 2.7rem); }

.site-footer { padding: 72px 0 28px; background: var(--forest-deep); color: rgba(255,255,255,.74); --focus: #edc86f; }
.footer-shell { width: min(1180px, calc(100% - 40px)); margin-inline: auto; display: grid; grid-template-columns: 1.65fr 1fr 1fr 1.25fr; gap: 50px; }
.footer-brand p { max-width: 280px; margin: 20px 0 0; }
.site-footer nav, .footer-contact { display: grid; align-content: start; gap: 10px; }
.site-footer strong { margin-bottom: 8px; color: #fff; font-size: 13px; letter-spacing: .08em; text-transform: uppercase; }
.site-footer nav a { width: fit-content; text-decoration: none; }
.site-footer nav a:hover, .site-footer nav a:focus-visible { color: #fff; text-decoration: underline; text-underline-offset: 4px; }
.footer-contact p { margin: 0; }
.footer-contact a { width: fit-content; color: inherit; text-decoration: none; overflow-wrap: anywhere; }
.footer-contact a:hover, .footer-contact a:focus-visible { color: #fff; text-decoration: underline; text-underline-offset: 4px; }
.footer-base { width: min(1180px, calc(100% - 40px)); margin: 55px auto 0; padding-top: 24px; display: flex; justify-content: space-between; gap: 20px; border-top: 1px solid rgba(255,255,255,.12); font-size: 13px; }
.footer-base p { margin: 0; }

:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; } }

@media (max-width: 900px) {
  .desktop-nav, .desktop-actions { display: none; }
  .mobile-nav { display: block; }
  .hero-scrim { background: linear-gradient(90deg, rgba(9,32,23,.88), rgba(9,32,23,.62)), linear-gradient(0deg, rgba(5,18,13,.5), transparent 45%); }
  .audience-grid, .step-grid, .stat-grid { grid-template-columns: 1fr; }
  .step-card { min-height: auto; }
  .step-card.featured { margin-block: 0; padding-block: 34px; }
  .step-number { margin-bottom: 26px; }
  .footer-shell { grid-template-columns: 1.4fr 1fr 1fr; }
  .footer-contact { grid-column: 1 / -1; }
}

@media (max-width: 620px) {
  :root { --header-h: 70px; --hero-h: min(620px, 88vh); }
  .shell, .nav-shell, .footer-shell, .footer-base { width: min(100% - 32px, 1180px); }
  .wordmark-image { height: 44px; }
  .wordmark-image-footer { height: 50px; }
  .hero-content { padding: calc(var(--header-h) + 52px) 0 58px; }
  .hero-copy { margin-top: 20px; }
  .button-row { flex-direction: column; align-items: stretch; }
  .trust-list { display: grid; gap: 10px; }
  .section { padding: 72px 0; }
  .section-dark { padding: 68px 0; }
  .step-card, .audience-card { padding: 28px; }
  .teaser { padding: 30px 26px; }
  .split-cta { align-items: flex-start; flex-direction: column; }
  .footer-shell { grid-template-columns: 1fr 1fr; gap: 42px 24px; }
  .footer-brand, .footer-contact { grid-column: 1 / -1; }
  .footer-base { flex-direction: column; }
}

/* Interior pages */
.page-hero { position: relative; min-height: var(--hero-h); display: grid; align-items: center; padding: calc(var(--header-h) + 76px) 0 84px; background: linear-gradient(125deg, var(--forest-deep), var(--forest)); color: #fff; --focus: #edc86f; }
.page-hero h1 { max-width: 900px; font-size: clamp(2.6rem, 5vw, 4rem); }
.page-hero > .shell > p:not(.eyebrow) { max-width: 660px; margin: 24px 0 0; color: rgba(255,255,255,.82); font-size: 19px; }
.page-hero .button { margin-top: 30px; }
/* The last layer is an opaque colour, not decoration. Without it the only
   thing under the scrim until the WebP decodes is the page's cream body, so
   the band paints as a green-to-cream wash on first load and then snaps to the
   photograph - which reads as two different pictures rather than as an image
   arriving. `.hero-art` on the homepage has always ended in `--forest-deep`
   for this reason; the interior heroes did not, which is why only they showed
   it. Any layered background over a network image needs an opaque base in the
   same shorthand. */
.photo-hero { background: linear-gradient(90deg, rgba(9,32,23,.88) 0%, rgba(9,32,23,.62) 55%, rgba(9,32,23,.30) 100%), var(--hero-art) center 60% / cover, var(--forest-deep); }

/* One photograph per page, each in its own file, so replacing a hero is a
   file swap and nothing else - drop a new 1800x1013 WebP over the named
   asset and the page picks it up. This map is the only place a hero file is
   named; `--hero-art` is read by `.hero-art` on the homepage and by
   `.photo-hero` everywhere else. A page whose class is missing here gets an
   invalid `background` shorthand, so it falls back to `.page-hero`'s plain
   gradient rather than breaking - and scripts/test-site.mjs fails, because a
   silently gradient hero is exactly the kind of thing nobody notices. */
.hero-home { --hero-art: url('/assets/hero-home.webp'); }
.hero-how-it-works { --hero-art: url('/assets/hero-how-it-works.webp'); }
.hero-for-hunters { --hero-art: url('/assets/hero-for-hunters.webp'); }
.hero-for-farmers { --hero-art: url('/assets/hero-for-farmers.webp'); }
.hero-pricing { --hero-art: url('/assets/hero-pricing.webp'); }
.hero-about { --hero-art: url('/assets/hero-about.webp'); }
.hero-contact { --hero-art: url('/assets/hero-contact.webp'); }
.journey-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.journey-card { padding: 42px; border: 1px solid var(--border); border-radius: 14px; background: var(--card); box-shadow: var(--shadow); }
.farmer-journey { background: var(--forest); color: #fff; border-color: var(--forest); --focus: #edc86f; }
.journey-heading { display: flex; align-items: center; gap: 18px; padding-bottom: 30px; border-bottom: 1px solid var(--border); }
.farmer-journey .journey-heading { border-color: rgba(255,255,255,.15); }
.journey-icon { display: grid; place-items: center; flex: 0 0 52px; width: 52px; height: 52px; border-radius: 50%; background: #f8edd4; color: var(--accent-hover); font: 700 20px/1 var(--serif); }
.farmer-journey .journey-icon { background: rgba(255,255,255,.1); color: #edc86f; }
.journey-heading .eyebrow { margin-bottom: 6px; }
.journey-heading h2 { margin: 0; font: 700 30px/1.08 var(--serif); }
.timeline { margin: 34px 0; padding: 0; list-style: none; }
.timeline li { position: relative; display: grid; grid-template-columns: 44px 1fr; gap: 18px; padding: 0 0 30px; }
.timeline li:last-child { padding-bottom: 0; }
.timeline li::before { content: ""; position: absolute; left: 20px; top: 35px; bottom: 4px; width: 1px; background: var(--border); }
.farmer-journey .timeline li::before { background: rgba(255,255,255,.16); }
.timeline li > span { position: relative; z-index: 1; display: grid; place-items: center; width: 42px; height: 42px; border: 1px solid var(--border); border-radius: 50%; background: var(--card); color: var(--accent-hover); font-size: 11px; font-weight: 800; }
.farmer-journey .timeline li > span { border-color: rgba(255,255,255,.22); background: var(--forest); color: #edc86f; }
.timeline h3 { margin: 3px 0 7px; font: 700 21px/1.15 var(--serif); }
.timeline p { margin: 0; color: var(--muted); }
.farmer-journey .timeline p { color: rgba(255,255,255,.72); }
.arrow-link { display: inline-flex; align-items: center; gap: 10px; color: var(--accent-hover); font-weight: 750; text-decoration: none; }
.arrow-link:hover, .arrow-link:focus-visible { text-decoration: underline; text-underline-offset: 4px; }
.farmer-journey .arrow-link { color: #edc86f; }
.feature-list { display: grid; gap: 96px; }
.feature-row { display: grid; grid-template-columns: 56px 1fr 1.1fr; gap: 38px; align-items: center; }
.feature-row.reverse { grid-template-columns: 56px 1.1fr 1fr; }
.feature-row.reverse .feature-copy { order: 3; }
.feature-row.reverse .feature-panel { order: 2; }
.feature-number { align-self: start; color: var(--accent); font: italic 500 26px/1 var(--serif); }
.feature-copy h2, .split-content h2 { margin: 0; font: 700 clamp(1.9rem, 3.2vw, 2.7rem)/1.06 var(--serif); letter-spacing: -.025em; }
.feature-copy > p:not(.eyebrow) { color: var(--muted); font-size: 17px; }
.fine-print { padding-left: 18px; border-left: 2px solid var(--accent); font-size: 14px !important; }

/* Illustrative panels. These are drawn, not photographed - they stand in for
   real product screenshots, which are the intended content here. Swapping one
   in means replacing the panel's children with a `.product-shot` figure; the
   capture list is in docs/marketing-site-implementation.md. */
.feature-panel { min-height: 340px; padding: 34px; display: grid; align-content: center; border: 1px solid var(--border); border-radius: 16px; background: var(--panel); box-shadow: var(--shadow); }
.product-shot { margin: 0; padding: 0; border-radius: 10px; overflow: hidden; border: 1px solid var(--border); background: var(--card); }
.product-shot img { width: 100%; }
.product-shot figcaption { padding: 12px 16px; color: var(--muted); font-size: 13px; }
.fake-label { margin-bottom: 10px; color: var(--muted); font-size: 12px; font-weight: 750; letter-spacing: .1em; text-transform: uppercase; }
.fake-search { padding: 17px 18px; border: 1px solid var(--border); border-radius: 9px; background: var(--card); font-weight: 650; }
.result-chip { margin-top: 20px; padding: 22px; display: grid; border-radius: 10px; background: var(--forest); color: #fff; }
.result-chip span { margin-top: 7px; color: rgba(255,255,255,.7); font-size: 13px; }
.chat-panel { gap: 14px; background: #e8dfcf; }
.message { max-width: 84%; padding: 16px 18px; border-radius: 14px; }
.message p { margin: 0; }
.user-message { justify-self: end; border-bottom-right-radius: 4px; background: var(--forest); color: #fff; }
.assistant-message { display: flex; gap: 12px; border-bottom-left-radius: 4px; background: var(--card); }
.mini-mark { flex: 0 0 30px; width: 30px; height: 30px; border-radius: 7px; }
.saved-panel { position: relative; background: var(--forest); color: #fff; }
.saved-card { padding: 26px; display: grid; gap: 8px; border: 1px solid rgba(255,255,255,.16); border-radius: 12px; background: rgba(255,255,255,.08); }
.saved-card span, .saved-card small { color: rgba(255,255,255,.68); }
.saved-card strong { font: 700 25px/1.1 var(--serif); }
.bookmark-shape { position: absolute; top: 22px; right: 22px; display: grid; place-items: center; width: 42px; height: 42px; border-radius: 50%; background: #edc86f; color: var(--forest); }
.bookmark-shape .i { width: 17px; height: 17px; }
.contact-panel { gap: 10px; }
.contact-panel > span { color: var(--muted); }
.contact-panel > strong { font: 700 30px/1.1 var(--serif); }
.contact-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 22px; }
.contact-actions i { padding: 13px; border: 1px solid var(--border); border-radius: 7px; background: var(--card); color: var(--forest); text-align: center; font-style: normal; font-size: 13px; font-weight: 750; }
.check-list { padding: 0; list-style: none; }
.check-list li { display: flex; align-items: flex-start; gap: 11px; margin: 10px 0; }
.check-list .i { margin-top: .32em; color: var(--accent-hover); }
.benefit-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.benefit-grid article { padding: 32px; border: 1px solid var(--border); border-radius: 12px; background: var(--card); }
.line-icon, .value-grid span { display: block; margin-bottom: 34px; color: var(--accent); font: italic 500 24px/1 var(--serif); }
.benefit-grid h3, .value-grid h3, .faq-grid h3 { margin: 0 0 10px; font: 700 23px/1.18 var(--serif); }
.benefit-grid p, .value-grid p, .faq-grid p { margin: 0; color: var(--muted); }
.quote-band { padding: 84px 0; background: var(--panel); text-align: center; }
.quote-band p { max-width: 860px; margin: 0 auto; font: italic 500 clamp(1.9rem, 3.6vw, 3rem)/1.14 var(--serif); color: var(--forest); }
.quote-band span { display: block; margin-top: 24px; color: var(--muted); font-size: 13px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.compact-section { padding-block: 80px; }
.split-content { display: grid; grid-template-columns: .9fr 1.1fr; gap: 90px; align-items: start; }
.split-content > div:last-child > p { margin-top: 0; color: var(--muted); font-size: 18px; }
.split-content .arrow-link { margin-top: 16px; }
.pricing-group + .pricing-group { margin-top: 92px; }
.pricing-group-heading { margin-bottom: 34px; }
.pricing-group-heading h2 { margin: 0; font: 700 clamp(1.9rem, 3.2vw, 2.6rem)/1.08 var(--serif); }
.pricing-grid { display: grid; gap: 18px; }
.pricing-grid.two-up { grid-template-columns: repeat(2, 1fr); }
.price-card { position: relative; display: grid; align-content: start; padding: 38px; border: 1px solid var(--border); border-radius: 14px; background: var(--card); }
.price-card.highlighted { border: 2px solid var(--forest); box-shadow: var(--shadow); }
.plan-badge { position: absolute; top: 20px; right: 20px; padding: 6px 10px; border-radius: 999px; background: #f5ead0; color: var(--accent-hover); font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; }
.plan-audience { margin: 0; color: var(--muted); font-size: 12px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.price-card h3 { margin: 6px 0 20px; font: 700 32px/1 var(--serif); }
.price { display: flex; align-items: baseline; gap: 4px; margin: 0; font: 700 56px/1 var(--serif); }
.price > span { font: 700 22px/1 var(--sans); }
.price small { color: var(--muted); font: 500 14px/1 var(--sans); }
.plan-summary { color: var(--muted); }
.price-card .check-list { margin: 0; padding: 18px 0; border-top: 1px solid var(--border); }
.price-card .button { width: 100%; }
/* Subgrid aligns the price, summary and feature list across cards from their
   real content. The min-heights this replaces were guesses at copy length. */
@supports (grid-template-rows: subgrid) {
  .pricing-grid.two-up { grid-template-rows: repeat(6, auto); }
  .pricing-grid.two-up > .price-card { grid-row: span 6; grid-template-rows: subgrid; }
}
.button-outline { background: transparent; color: var(--forest); border-color: var(--forest); box-shadow: none; }
.button-outline:hover, .button-outline:focus-visible { background: var(--forest); border-color: var(--forest); color: #fff; }
.pricing-note { max-width: 760px; margin: 40px auto 0; color: var(--muted); text-align: center; font-size: 13px; }
.faq-section, .values-section { padding: 90px 0; background: var(--panel); }
.faq-grid, .value-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.faq-grid article, .value-grid article { padding: 30px; border-top: 2px solid var(--accent); background: var(--card); }
.about-story p { margin-top: 0; }
.contact-section { background: var(--ground); }
.contact-card { padding: 34px; border: 1px solid var(--border); border-radius: 14px; background: var(--card); box-shadow: var(--shadow); }
.contact-card > div { display: grid; gap: 4px; padding: 18px 0; border-bottom: 1px solid var(--border); }
.contact-card > div:first-child { padding-top: 0; }
.contact-card span { color: var(--muted); font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.contact-card a { color: var(--accent-hover); font-weight: 700; text-decoration: none; overflow-wrap: anywhere; }
.contact-card a:hover, .contact-card a:focus-visible { text-decoration: underline; text-underline-offset: 4px; }
.contact-card p { margin: 22px 0 0 !important; font-size: 13px !important; }
.contact-form { display: grid; gap: 8px; }
.contact-form label { color: var(--muted); font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.contact-form input, .contact-form textarea { width: 100%; margin-bottom: 14px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 7px; background: var(--panel); color: var(--ink); font: inherit; font-size: 16px; }
.contact-form textarea { resize: vertical; min-height: 160px; }
.contact-form input:focus-visible, .contact-form textarea:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-color: var(--accent-dark); }
.contact-form .button { justify-self: start; margin-top: 6px; font: inherit; font-size: 14px; font-weight: 750; cursor: pointer; }
.contact-form textarea { margin-bottom: 4px; }
/* One line that never wraps: the count is short and uses fixed-width digits,
   so typing cannot change the row's height and make the button jump. */
.contact-hint { display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: 12px; min-height: 1.5em; margin: 0 0 14px !important; color: var(--muted); font-size: 13px !important; line-height: 1.5; }
.contact-card .contact-hint span { color: inherit; font-size: inherit; font-weight: 400; letter-spacing: normal; text-transform: none; }
.contact-card .contact-hint [data-message-count] { font-variant-numeric: tabular-nums; white-space: nowrap; }
.contact-card .contact-hint .is-short { color: var(--accent-hover); font-weight: 700; }
.contact-form .button:disabled { opacity: .5; cursor: not-allowed; transform: none; box-shadow: none; }
.contact-trap { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.contact-section a:not(.button) { color: var(--accent-hover); }
.not-found { min-height: min(640px, 80vh); padding: calc(var(--header-h) + 96px) 0 92px; display: grid; align-items: center; background: radial-gradient(circle at 75% 35%, rgba(184,130,15,.22), transparent 25%), var(--forest-deep); color: #fff; --focus: #edc86f; }
.not-found .shell { text-align: center; }
.not-found h1 { max-width: none; margin-inline: auto; }
.not-found p:not(.eyebrow,.error-code) { color: rgba(255,255,255,.78); font-size: 18px; }
.not-found .button { margin-top: 20px; }
.error-code { margin: 0 0 10px; color: rgba(237,200,111,.20); font: 700 clamp(6rem, 17vw, 11rem)/.7 var(--serif); }

@media (max-width: 900px) {
  .journey-grid, .pricing-grid.two-up { grid-template-columns: 1fr; }
  @supports (grid-template-rows: subgrid) {
    .pricing-grid.two-up { grid-template-rows: none; }
    .pricing-grid.two-up > .price-card { grid-row: auto; grid-template-rows: none; }
  }
  .feature-row, .feature-row.reverse { grid-template-columns: 42px 1fr; gap: 24px; }
  .feature-row .feature-copy, .feature-row.reverse .feature-copy { order: initial; }
  .feature-row .feature-panel, .feature-row.reverse .feature-panel { order: initial; grid-column: 2; }
  .benefit-grid, .faq-grid, .value-grid { grid-template-columns: repeat(2, 1fr); }
  .split-content { gap: 45px; }
}

@media (max-width: 620px) {
  .page-hero { padding: calc(var(--header-h) + 54px) 0 64px; }
  .journey-card { padding: 28px; }
  .journey-heading { align-items: flex-start; }
  .feature-list { gap: 72px; }
  .feature-row, .feature-row.reverse { grid-template-columns: 1fr; }
  .feature-number { margin-bottom: -12px; }
  .feature-row .feature-panel, .feature-row.reverse .feature-panel { grid-column: auto; min-height: 300px; padding: 24px; }
  .benefit-grid, .faq-grid, .value-grid, .split-content { grid-template-columns: 1fr; }
  .split-content { gap: 28px; }
  .pricing-group + .pricing-group { margin-top: 72px; }
  .price-card { padding: 28px; }
  .plan-badge { position: static; justify-self: start; margin-bottom: 20px; }
  .not-found { min-height: min(560px, 82vh); padding: calc(var(--header-h) + 68px) 0 72px; }
}

/* ---------------------------------------------------------------------------
   Narrow desktop and short windows.

   The same two facts the app's `lib/shared/layout/viewport.dart` is built on.
   Windows display scaling divides the logical viewport, so a 1080p monitor at
   125% reports 1536x864 and a 1366x768 laptop at 125% reports 1093x614 - and
   1366x768 itself is one of the most common resolutions in South Africa. This
   file was fluid horizontally already; what it had no answer for was a window
   between 901 and 1180 wide, and a window under 820 tall.

   Chrome gives way before content does: padding, band heights and card insets
   shrink, and nothing changes column count or drops a section. See
   docs/desktop-viewport-spec.md.
   --------------------------------------------------------------------------- */

/* The tier between the phone layout and the full-width design. Three step
   cards at 34px of padding inside a 1053px shell leave 245px of readable
   width each; the same cards at 26px leave 261px and stop touching. */
@media (min-width: 901px) and (max-width: 1180px) {
  /* Six links, Log in and Get started have to share one row down to 901px.
     Tighten the chrome rather than let a label wrap onto two lines. */
  .nav-shell { gap: 18px; }
  .desktop-nav { gap: 16px; }
  .desktop-nav a, .desktop-actions a { white-space: nowrap; }
  .desktop-actions { gap: 14px; }
  .desktop-actions .button-small { padding-inline: 14px; }
  .section { padding: 76px 0; }
  .section-dark { padding: 70px 0; }
  .band-cta { padding: 60px 0; }
  .audience-card { padding: 30px; }
  .step-card { min-height: 240px; padding: 26px; }
  .step-number { margin-bottom: 34px; }
  .journey-card { padding: 32px; }
  .feature-panel { min-height: 300px; padding: 28px; }
  .teaser { padding: 34px 32px; }
  .section-heading { margin-bottom: 36px; }
  .site-footer { padding: 60px 0 26px; }
  .footer-shell { gap: 36px; }
}

/* Short windows. A 768px laptop has roughly 638 logical pixels once browser
   chrome is subtracted, so the hero's own padding is what decides whether
   anything below it is visible on first paint. Guarded above the phone
   breakpoint so it cannot fight the 620px block. */
@media (max-height: 820px) and (min-width: 621px) {
  :root { --header-h: 72px; }
  .wordmark-image { height: 48px; }
  .hero-content { padding: calc(var(--header-h) + 40px) 0 52px; }
  .hero-copy { margin-top: 18px; }
  .trust-list { margin-top: 22px; }
  .page-hero { padding: calc(var(--header-h) + 46px) 0 54px; }
  .page-hero > .shell > p:not(.eyebrow) { margin-top: 18px; }
  .section { padding: 72px 0; }
  .section-dark { padding: 64px 0; }
  .band-cta { padding: 56px 0; }
  .not-found { padding: calc(var(--header-h) + 60px) 0 60px; }
}
