/* Landing page — the public front door.
 *
 * Every colour and font below arrives as a custom property written by
 * tools/build_landing.py from landing/config/brand.json. Nothing here
 * names a brand, and the identity is not decided yet (the page says YOUR
 * BRAND on purpose): choosing one later is a change to that JSON file
 * and a rebuild, never an edit to this stylesheet.
 *
 * Animation policy, once, for the whole file: things move with transform
 * and opacity only. No animated width/height/top/left anywhere — those
 * force layout on every frame and are exactly what makes a parallax page
 * stutter on the phone this is mostly read on. `prefers-reduced-motion`
 * at the bottom removes the motion and keeps every word.
 */

/* ---- tokens ---------------------------------------------------------- */

:root {
  /* colours are injected above this file by the generator */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 24px; --s-6: 32px; --s-8: 48px; --s-10: 64px;
  --s-12: 96px; --s-16: 128px; --s-20: 160px;

  --radius: 14px;
  --radius-lg: 22px;

  --shadow-sm: 0 1px 2px rgba(11, 18, 32, .06), 0 1px 3px rgba(11, 18, 32, .04);
  --shadow-md: 0 8px 24px rgba(11, 18, 32, .08), 0 2px 6px rgba(11, 18, 32, .04);
  --shadow-lg: 0 32px 64px rgba(11, 18, 32, .12), 0 8px 20px rgba(11, 18, 32, .06);

  --nav-h: 68px;
  --max: 1200px;
  --measure: 62ch;
}

/* ---- reset ----------------------------------------------------------- */

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

html {
  /* The brief asks for smooth scrolling. It belongs on the root and
     nowhere else, so the reduced-motion block below can switch off the
     whole page's motion in one declaration. */
  scroll-behavior: smooth;
  /* Anchor targets must clear the fixed navbar, or "Pricing" lands with
     its heading hidden underneath it. */
  scroll-padding-top: calc(var(--nav-h) + var(--s-5));
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-ink);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, p, figure, blockquote { margin: 0; }
img, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

/* One visible focus treatment for everything interactive. Keyboard users
   are a minority of visitors and 100% of the ones who cannot get past a
   page without it. */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--c-accent);
  outline-offset: 3px;
  border-radius: 6px;
}

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

.skip-link {
  position: absolute; left: var(--s-4); top: -100px;
  z-index: 100; background: var(--c-ink); color: var(--c-bg);
  padding: var(--s-3) var(--s-5); border-radius: var(--radius);
  transition: top .15s ease;
}
.skip-link:focus { top: var(--s-4); }

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

.shell { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 var(--s-6); }

section { position: relative; }

.section-pad { padding: var(--s-20) 0; }

.eyebrow {
  display: inline-block;
  font-size: 13px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--c-accent);
  margin-bottom: var(--s-4);
}

.display {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1.04;
  font-size: clamp(2.4rem, 6.2vw, 4.4rem);
}

.display-sm {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: 1.1;
  font-size: clamp(1.9rem, 4.2vw, 3rem);
}

.lede {
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  color: var(--c-ink-muted);
  max-width: var(--measure);
}

.muted { color: var(--c-ink-muted); }

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

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-2);
  padding: 14px 26px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-weight: 600; font-size: 16px;
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease, background-color .18s ease;
  will-change: transform;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn-primary {
  background: var(--c-ink); color: var(--c-bg);
  box-shadow: var(--shadow-md);
}
.btn-primary:hover { box-shadow: var(--shadow-lg); }

.btn-ghost {
  background: transparent; color: var(--c-ink);
  border-color: var(--c-line);
}
.btn-ghost:hover { background: var(--c-bg-alt); }

.btn-sm { padding: 10px 20px; font-size: 15px; }

/* ---- navbar ---------------------------------------------------------- */

.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  height: var(--nav-h);
  display: flex; align-items: center;
  /* Transparent over the hero, solid once the page moves — the class is
     toggled by landing.js, not by a scroll listener that repaints. */
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color .25s ease, border-color .25s ease, backdrop-filter .25s ease;
}
.nav.is-stuck {
  background: color-mix(in srgb, var(--c-bg) 82%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom-color: var(--c-line);
}

.nav-inner { display: flex; align-items: center; gap: var(--s-6); width: 100%; }

.brand { display: flex; align-items: center; gap: var(--s-3); font-weight: 700; letter-spacing: -.01em; }
/* ---- the brand tagline -------------------------------------------------
   Under the logo, never instead of a headline. One rule set for all seven
   languages, which is the constraint that matters: German runs to 56
   characters where Italian runs to 33, and they have to look like the
   same element at both lengths.

   So the size is clamped rather than fixed, the line is allowed to wrap
   and balanced when it does, and the width is capped in ch — a measure in
   characters is the one that means the same thing in every language. No
   ellipsis and no nowrap anywhere: clipping a tagline is worse than
   wrapping one. */
.brand-tagline {
  margin: var(--s-3) 0 0;
  font-size: clamp(10px, 0.78vw, 11.5px);
  font-weight: 700;
  letter-spacing: .16em;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--c-ink-muted);
  max-width: 34ch;
  text-wrap: balance;
}
/* The AI of the language, in the colours of the mark above it. The solid
   colour is not a fallback nobody sees: it is what prints, what a forced
   -colours mode shows, and what any browser without background-clip:text
   renders. */
.tagline-ai {
  color: var(--c-brand-via);
  background-image: linear-gradient(100deg, var(--c-brand-from), var(--c-brand-via), var(--c-brand-to));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .tagline-ai { -webkit-text-fill-color: currentColor; background-image: none; }
}
@media (forced-colors: active) {
  .tagline-ai { -webkit-text-fill-color: currentColor; background-image: none; }
}

.footer .brand-tagline { color: rgba(255,255,255,.62); max-width: 30ch; }

/* The symbol, when there is one. Height-constrained and width-auto: the
   wAItress mark is wider than it is tall, so fixing the width would crop
   it against the name. */
.brand-logo { height: 26px; width: auto; display: block; flex: none; }
.footer .brand-logo { height: 24px; }

.brand-mark {
  width: 30px; height: 30px; border-radius: 9px;
  display: grid; place-items: center;
  background: var(--c-ink); color: var(--c-bg);
  font-size: 12px; font-weight: 800; letter-spacing: 0;
}

.nav-links { display: flex; align-items: center; gap: var(--s-5); margin-left: auto; }
.nav-link {
  font-size: 15px; font-weight: 500; color: var(--c-ink-muted);
  padding: 6px 2px; position: relative;
  transition: color .15s ease;
}
.nav-link:hover { color: var(--c-ink); }
.nav-link::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--c-accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform .2s ease;
}
.nav-link:hover::after { transform: scaleX(1); }

.nav-actions { display: flex; align-items: center; gap: var(--s-3); }

/* ---- language selector ----------------------------------------------- */

.lang { position: relative; }
.lang-btn {
  display: inline-flex; align-items: center; gap: var(--s-2);
  background: transparent; border: 1px solid var(--c-line);
  border-radius: 999px; padding: 8px 14px;
  font-size: 14px; font-weight: 500; cursor: pointer;
  transition: background-color .15s ease;
}
.lang-btn:hover { background: var(--c-bg-alt); }
.lang-caret { transition: transform .2s ease; }
.lang-btn[aria-expanded="true"] .lang-caret { transform: rotate(180deg); }

.lang-menu {
  position: absolute; right: 0; top: calc(100% + 8px);
  min-width: 190px; padding: var(--s-2);
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  display: grid; gap: 2px;
}
.lang-menu[hidden] { display: none; }
.lang-option {
  display: block; padding: 9px 12px; border-radius: 9px;
  font-size: 15px; color: var(--c-ink);
  transition: background-color .12s ease;
}
.lang-option:hover { background: var(--c-bg-alt); }
.lang-option[aria-current="true"] { font-weight: 600; background: var(--c-bg-alt); }

/* ---- mobile menu ----------------------------------------------------- */

.nav-toggle { display: none; background: transparent; border: 0; padding: 8px; cursor: pointer; }
.nav-toggle span {
  display: block; width: 22px; height: 2px; background: var(--c-ink);
  border-radius: 2px; transition: transform .2s ease, opacity .2s ease;
}
.nav-toggle span + span { margin-top: 5px; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.mobile-menu {
  position: fixed; inset: var(--nav-h) 0 auto 0; z-index: 49;
  background: var(--c-bg); border-bottom: 1px solid var(--c-line);
  padding: var(--s-5) var(--s-6) var(--s-8);
  display: grid; gap: var(--s-2);
  box-shadow: var(--shadow-lg);
}
.mobile-menu[hidden] { display: none; }
.mobile-menu a { padding: 12px 0; font-size: 18px; font-weight: 500; border-bottom: 1px solid var(--c-line); }
.mobile-menu .btn { margin-top: var(--s-4); }

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

.hero {
  position: relative;
  padding: calc(var(--nav-h) + var(--s-16)) 0 var(--s-16);
  overflow: hidden;
}

/* The glow is one element, moved by transform only. A background-position
   animation here would repaint a full-viewport gradient every frame. */
.hero-glow {
  position: absolute; z-index: 0;
  top: -30%; left: 50%; width: 1100px; height: 1100px;
  margin-left: -550px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%,
    color-mix(in srgb, var(--c-accent) 20%, transparent) 0%,
    color-mix(in srgb, var(--c-accent) 6%, transparent) 42%,
    transparent 68%);
  pointer-events: none;
  will-change: transform;
}

.hero-grid {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1.05fr .95fr;
  gap: var(--s-12); align-items: center;
}

.hero-copy .display { margin-bottom: var(--s-5); }
.hero-copy .lede { margin-bottom: var(--s-8); }
.hero-cta { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; }
.hero-trust { margin-top: var(--s-4); font-size: 14px; color: var(--c-ink-muted); }

/* ---- hero product visual --------------------------------------------- */

/* Built from elements, not a screenshot: it stays sharp on every screen,
   weighs nothing, and is translated with the rest of the page. */
/* Two rows, not three hand-placed offsets.
   The cards used to be positioned absolutely — chat at top/right, order
   at bottom/left, metric at bottom 20% — which is correct for exactly as
   long as their text is the length it was when those numbers were
   chosen. It was not. German and French run a line longer than
   Portuguese, so the chat card grew downwards into the metric card
   sitting behind it. Measured at 1440px before this: the chat covered
   the metric by 56px in English, 36px in German and French, 15px in
   Spanish, Italian and Dutch. Portuguese was the only clean one, which
   is why it was the one the owner said looked right. At 1100px nothing
   was clean, Portuguese included.

   The chat owns the first row and the other two share the second, so no
   translation can make one cover another: the row heights come from the
   content. The layered look survives as one negative margin, and that
   overlap is bounded by construction — the order card tucks exactly that
   far under the chat, in every language, at every width. */
.stage {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  column-gap: var(--s-4);
  align-items: start;
  /* Small enough to be padding on the card beneath it and never a word.
     Checked by measuring the tucked card's heading against the chat's
     bottom edge, not by eye. */
  --stage-tuck: 14px;
}

.card-float {
  position: relative;
  background: var(--c-bg);
  border: 1px solid var(--c-line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--s-5);
  will-change: transform;
}

/* The three cards are placed so that none covers another's text. The
   first arrangement had the metric at 44% on the right, directly behind
   the order card — its number was invisible at every width, which is a
   card that costs bytes and says nothing. Chat top-right, order
   bottom-left, metric in the gap bottom-right. */
/* min-height reserves the three bubbles' space before they arrive: they
   fade in one after another (a conversation assembling itself rather than
   a screenshot of one), and without it the card would grow twice while
   the reader is looking straight at it. */
.chat {
  grid-column: 1 / -1; grid-row: 1;
  justify-self: end; width: min(340px, 100%);
  min-height: 214px; z-index: 3;
}
.order {
  grid-column: 1; grid-row: 2;
  margin-top: calc(var(--stage-tuck) * -1);
  z-index: 2;
}
/* Dropped a little further than the order card, so the two in this row
   read as scattered rather than as a pair of columns. */
.metric {
  grid-column: 2; grid-row: 2;
  margin-top: var(--s-6);
  padding: var(--s-4); z-index: 1;
}

.bubble {
  padding: 10px 14px; border-radius: 14px;
  font-size: 14.5px; line-height: 1.45;
  max-width: 88%; margin-bottom: var(--s-2);
}
.bubble-them { background: var(--c-bg-alt); border-bottom-left-radius: 5px; }
.bubble-us {
  background: var(--c-ink); color: var(--c-bg);
  margin-left: auto; border-bottom-right-radius: 5px;
}

.card-head {
  display: flex; align-items: center; gap: var(--s-2);
  font-size: 12px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--c-ink-muted);
  margin-bottom: var(--s-3);
}
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--c-accent); }

.line-item { display: flex; justify-content: space-between; font-size: 14.5px; padding: 5px 0; }
.line-total {
  display: flex; justify-content: space-between;
  font-weight: 700; font-size: 16px;
  border-top: 1px solid var(--c-line); margin-top: var(--s-2); padding-top: var(--s-3);
}

.metric-value {
  font-size: 30px; font-weight: 800; letter-spacing: -.02em; line-height: 1;
  /* Tabular figures on everything that counts up: proportional digits
     change width as the number climbs, and the card jitters for the whole
     animation. */
  font-variant-numeric: tabular-nums;
}
.metric-label { font-size: 13px; color: var(--c-ink-muted); margin-top: 6px; }

.demo-tag {
  display: inline-block; margin-top: var(--s-3);
  font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--c-ink-muted); background: var(--c-bg-alt);
  border-radius: 999px; padding: 3px 9px;
  white-space: nowrap;
}

/* ---- problem --------------------------------------------------------- */

.problem { background: var(--c-bg-alt); }

.problem-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-12);
  align-items: start;
}

/* The headline stays while the scenes move past it — the parallax is
   carrying the argument, not decorating it: the claim holds still and
   the evidence accumulates against it. */
.problem-sticky { position: sticky; top: calc(var(--nav-h) + var(--s-10)); }
.problem-sticky .display-sm { margin-bottom: var(--s-5); }

.scenes { display: grid; gap: var(--s-4); }

.scene {
  background: var(--c-bg);
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  padding: var(--s-5);
  box-shadow: var(--shadow-sm);
  will-change: transform, opacity;
}
.scene-label {
  font-size: 12px; font-weight: 700; letter-spacing: .08em;
  color: var(--c-accent); margin-bottom: var(--s-2);
  font-variant-numeric: tabular-nums;
}
.scene h3 { font-size: 18px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 4px; }
.scene p { font-size: 15px; color: var(--c-ink-muted); }

.problem-closing {
  margin-top: var(--s-8);
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  font-weight: 600; letter-spacing: -.02em;
  max-width: 34ch;
}

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

.footer {
  background: var(--c-ink); color: var(--c-bg);
  padding: var(--s-12) 0 var(--s-8);
}
.footer .brand-mark { background: var(--c-bg); color: var(--c-ink); }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--s-8); }
.footer-note { font-size: 14.5px; opacity: .72; max-width: 46ch; margin-top: var(--s-3); }
.footer-note code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .92em; background: rgba(255,255,255,.1);
  padding: 2px 6px; border-radius: 5px;
}
.footer-bottom {
  margin-top: var(--s-10); padding-top: var(--s-5);
  border-top: 1px solid rgba(255,255,255,.14);
  display: flex; flex-wrap: wrap; gap: var(--s-4);
  justify-content: space-between; font-size: 14px; opacity: .66;
}
.footer-social { display: flex; gap: var(--s-4); }

/* ---- scroll-triggered entrance --------------------------------------- */

/* Set by landing.js through IntersectionObserver. The starting state is
   applied by the script too, never in this file: if the script fails or
   is blocked, every element must already be visible rather than stuck
   invisible forever. */
.reveal { opacity: 0; transform: translate3d(0, 22px, 0); }
.reveal.is-in {
  opacity: 1; transform: translate3d(0, 0, 0);
  transition: opacity .6s cubic-bezier(.2,.7,.3,1), transform .6s cubic-bezier(.2,.7,.3,1);
}

/* ---- responsive ------------------------------------------------------ */

@media (max-width: 1200px) {
  :root { --max: 1040px; --s-20: 128px; }
  .hero-grid { gap: var(--s-8); }
}

@media (max-width: 1024px) {
  :root { --s-20: 112px; --s-16: 96px; }
  .hero-grid { grid-template-columns: 1fr; gap: var(--s-10); }
  .stage { max-width: 520px; }
  .problem-grid { grid-template-columns: 1fr; gap: var(--s-8); }
  .problem-sticky { position: static; }
}

@media (max-width: 768px) {
  body { font-size: 16px; }
  :root { --s-20: 88px; --s-16: 72px; --s-12: 64px; }
  .shell { padding: 0 var(--s-5); }
  .nav-links { display: none; }
  .nav-actions .btn-primary { display: none; }
  .nav-toggle { display: block; margin-left: auto; }
  .lang-btn .lang-name { display: none; }
  .footer-grid { grid-template-columns: 1fr; gap: var(--s-6); }
}

/* Paper does not scroll, so nothing would ever trigger. Everything that
   enters on scroll is simply there, in place, at full opacity. The same
   rule covers a reader who prints mid-animation. */
@media print {
  [data-reveal], .turn, .reveal { opacity: 1 !important; transform: none !important; }
}

@media (max-width: 480px) {
  /* The floating cards stop floating and become a stack. Overlapping
     cards at this width hide each other's text, and the point of the
     visual is that it is readable. */
  .stage { grid-template-columns: 1fr; gap: var(--s-4); max-width: none; }
  .card-float { width: auto; margin-top: 0; }
  .chat, .order, .metric { grid-column: 1; grid-row: auto; width: auto; justify-self: stretch; }
  .chat { min-height: 0; }
  .metric { display: none; }
  .hero { padding-top: calc(var(--nav-h) + var(--s-10)); }
  .hero-cta { display: grid; }
  .hero-cta .btn { width: 100%; }
}

@media (max-width: 360px) {
  .shell { padding: 0 var(--s-4); }
  .brand span:not(.brand-mark) { font-size: 15px; }
}

/* ---- reduced motion --------------------------------------------------- */

/* The brief is explicit: reduce the motion, keep the functionality.
   below removes movement without removing a single word or control. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .reveal, .reveal.is-in { opacity: 1; transform: none; }
  .btn:hover { transform: none; }
  /* The parallax layers are held at their resting position; landing.js
     also stops writing transforms to them. */
  .hero-glow, .card-float, .scene { transform: none !important; }
}

/* ---- opportunity ------------------------------------------------------ */

.opportunity-head { max-width: 46rem; margin-bottom: var(--s-10); }
.opportunity-head .display-sm { margin-bottom: var(--s-4); }

/* The conversation is an ordered list, because that is what it is: a
   sequence where the order carries the meaning. A screen reader announces
   it as seven items in order, which is the argument intact. */
.turns {
  list-style: none; margin: 0 auto; padding: 0;
  max-width: 44rem;
  /* Close together, like a conversation. An earlier version pushed these
     64px apart so each turn got its own stretch of scroll; it read as a
     chat torn into pieces down the page. What sells the sequence is the
     ENTRANCE below, not the distance. */
  display: grid; gap: var(--s-4);
  --turn-slide: 36px;
  will-change: transform;
}

.turn {
  display: grid; gap: 6px;
  padding: var(--s-4) var(--s-5);
  border-radius: var(--radius-lg);
  /* min-width as well as max: a three-word answer ("Yes — three.") was
     rendering as a chip barely wider than its own stage label, which
     read as a fragment rather than a reply. */
  min-width: min(230px, 100%);
  max-width: 82%;
  box-shadow: var(--shadow-sm);
  will-change: transform, opacity;
}
.turn-customer {
  background: var(--c-bg); border: 1px solid var(--c-line);
  justify-self: start; border-bottom-left-radius: 6px;
}
.turn-ai {
  background: var(--c-ink); color: var(--c-primary-contrast);
  justify-self: end; border-bottom-right-radius: 6px;
}

/* Naming the stage beside each turn is the point of the section: six
   friendly messages ARE a sale being assembled, and the labels are what
   make that visible. */
.turn-stage {
  font-size: 11px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--c-accent);
}
.turn-ai .turn-stage { color: var(--c-accent-soft); }
.turn-text { font-size: 16.5px; line-height: 1.5; }

.opportunity-closing {
  max-width: 44rem; margin: var(--s-10) auto 0;
  text-align: center;
  font-size: clamp(1.1rem, 1.9vw, 1.4rem);
  font-weight: 600; letter-spacing: -.02em;
}

/* ---- product reveal --------------------------------------------------- */

.reveal-section { background: var(--c-bg-alt); }
.reveal-head { max-width: 46rem; margin-bottom: var(--s-10); }
.reveal-head .display-sm { margin-bottom: var(--s-4); }

.channels-title {
  font-size: 13px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--c-ink-muted);
  margin-bottom: var(--s-4);
}

.channels {
  list-style: none; margin: 0 0 var(--s-5); padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--s-3);
}

/* Name above, state below — not side by side. Side by side, a long
   channel name ("Sua página de pedidos") wrapped onto three lines while
   its neighbours sat on one, and the row came out ragged. Stacking makes
   the card the same shape in all seven languages, which is the only way
   to lay this out once. */
.channel {
  display: grid; gap: var(--s-2); justify-items: start; align-content: start;
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius); padding: var(--s-4) var(--s-5);
  box-shadow: var(--shadow-sm);
}
.channel-name { font-weight: 600; }
.channel-state {
  font-size: 12px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; white-space: nowrap;
  color: var(--c-accent);
  background: color-mix(in srgb, var(--c-accent) 12%, transparent);
  border-radius: 999px; padding: 4px 10px;
}
/* A channel that is not connected looks unfinished on purpose. Nothing
   is sold before it works. */
.channel-soon { opacity: .62; }
.channel-soon .channel-state {
  color: var(--c-ink-muted);
  background: color-mix(in srgb, var(--c-ink-muted) 12%, transparent);
}

.channels-honesty { font-size: 14.5px; color: var(--c-ink-muted); max-width: 50ch; }

/* ---- how it works ----------------------------------------------------- */

.how-grid { display: grid; grid-template-columns: .9fr 1.1fr; gap: var(--s-12); align-items: start; }
.how-sticky { position: sticky; top: calc(var(--nav-h) + var(--s-10)); }
.how-sticky .display-sm { margin-bottom: var(--s-6); }

.how-track { display: flex; align-items: center; gap: var(--s-5); }
.track-n {
  font-family: var(--font-display);
  font-size: clamp(3.6rem, 8vw, 6rem); font-weight: 800;
  letter-spacing: -.04em; line-height: 1;
  color: var(--c-accent);
  font-variant-numeric: tabular-nums;
}
.track-dots { display: grid; gap: 8px; }
.track-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--c-line);
  transition: background-color .25s ease, transform .25s ease;
}
.track-dot.is-on { background: var(--c-accent); transform: scale(1.35); }

.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-5); }
.step {
  display: grid; grid-template-columns: auto 1fr; gap: var(--s-5);
  align-items: start;
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius); padding: var(--s-5) var(--s-6);
  box-shadow: var(--shadow-sm);
  transition: border-color .25s ease, box-shadow .25s ease;
}
.step.is-current { border-color: var(--c-accent); box-shadow: var(--shadow-md); }
.step-n {
  font-size: 13px; font-weight: 700; letter-spacing: .08em;
  color: var(--c-ink-muted); font-variant-numeric: tabular-nums;
  padding-top: 3px;
}
.step.is-current .step-n { color: var(--c-accent); }
.step h3 { font-size: 19px; font-weight: 700; letter-spacing: -.015em; margin-bottom: 4px; }
.step p { font-size: 15.5px; color: var(--c-ink-muted); }

@media (max-width: 1024px) {
  .how-grid { grid-template-columns: 1fr; gap: var(--s-8); }
  .how-sticky { position: static; }
  .how-track { display: none; }   /* the tracker needs a sticky column to track against */
  .turn { max-width: 90%; }
}

@media (max-width: 480px) {
  .turn { max-width: 100%; }
  .step { grid-template-columns: 1fr; gap: var(--s-2); padding: var(--s-5); }
  .channels { grid-template-columns: 1fr; }
}

/* ---- six selling acts -------------------------------------------------- */

.acts-head { max-width: 46rem; margin-bottom: var(--s-10); }
.acts-head .display-sm { margin-bottom: var(--s-4); }

.acts-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--s-4);
}

.act {
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius-lg); padding: var(--s-6);
  box-shadow: var(--shadow-sm);
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
  will-change: transform, opacity;
}
/* The microinteraction §18 asks for: a card that answers when you point
   at it, without moving anything around it. */
.act:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: color-mix(in srgb, var(--c-accent) 40%, var(--c-line));
}
.act-k {
  display: inline-block; margin-bottom: var(--s-3);
  font-size: 11.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--c-accent);
}
.act h3 { font-size: 19px; font-weight: 700; letter-spacing: -.015em; margin-bottom: 6px; }
.act p { font-size: 15.5px; color: var(--c-ink-muted); }

/* ---- conversion engine ------------------------------------------------- */

.engine { background: var(--c-bg-alt); }
.engine-grid { display: grid; grid-template-columns: 1fr .85fr; gap: var(--s-12); align-items: center; }
.engine-copy .display-sm { margin-bottom: var(--s-4); }
.engine-note { margin-top: var(--s-5); font-size: 14px; color: var(--c-ink-muted); max-width: 46ch; }

.basket {
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius-lg); padding: var(--s-6);
  box-shadow: var(--shadow-lg);
  will-change: transform;
}
.basket-head { display: flex; justify-content: flex-end; margin-bottom: var(--s-4); }
.basket-head .demo-tag { margin-top: 0; }

.basket-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-1); }
.basket-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 10px 0; font-size: 16px;
  border-bottom: 1px solid var(--c-line);
  will-change: transform, opacity;
}
/* The three lines the conversation added, marked so the eye can see at a
   glance which part of the total was not in the original order. */
.basket-added { color: var(--c-accent); font-weight: 600; }
/* The + belongs to the NAME, not to the row. As a pseudo-element on the
   row it became a third flex child, and space-between then pushed the
   dish name into the middle of the line while the untouched rows stayed
   left-aligned — a ragged list that looked like a rendering fault. */
.basket-added > span:first-child::before {
  content: '+'; margin-right: 8px; font-weight: 700;
}
.basket-price { font-variant-numeric: tabular-nums; }

.basket-compare {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4);
  margin-top: var(--s-5); padding-top: var(--s-5);
  border-top: 2px solid var(--c-ink);
}
.basket-compare > div { display: grid; gap: 4px; }
.basket-label {
  font-size: 11.5px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--c-ink-muted);
}
.basket-was {
  font-size: 22px; font-weight: 600; color: var(--c-ink-muted);
  text-decoration: line-through; font-variant-numeric: tabular-nums;
}
.basket-now {
  font-size: 30px; font-weight: 800; letter-spacing: -.02em;
  color: var(--c-accent); font-variant-numeric: tabular-nums;
  /* Reserved so the row does not resize while the total climbs. */
  min-width: 5ch; display: inline-block;
}

/* ---- analytics --------------------------------------------------------- */

.metrics-head { max-width: 46rem; margin-bottom: var(--s-8); }
.metrics-head .display-sm { margin-bottom: var(--s-4); }

.dashboard {
  background: var(--c-ink); color: var(--c-primary-contrast);
  border-radius: var(--radius-lg); padding: var(--s-6);
  box-shadow: var(--shadow-lg);
  will-change: transform;
}
.dashboard-head { display: flex; justify-content: flex-end; margin-bottom: var(--s-5); }
.dashboard .demo-tag {
  margin-top: 0; color: var(--c-primary-contrast);
  background: rgba(255,255,255,.14);
}

.tiles {
  display: grid;
  /* Four columns, stated, not auto-fit.
     auto-fit put six across and left the seventh alone underneath, and it
     sizes columns to fit the track minimum — which meant the revenue
     figure, the longest string anywhere on the page, filled its column
     edge to edge and read as if it were touching the conversion rate
     beside it. Nothing was overlapping; it just looked like it was, which
     on a dashboard is the same problem.
     Four and three is the only way seven divides without leaving one tile
     on its own, and at four the widest value in the widest language still
     has a third of its column to spare. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-5);
}
.tile {
  display: grid; gap: 6px; align-content: start;
  min-width: 0;
  padding: var(--s-4) 0;
  border-top: 1px solid rgba(255,255,255,.16);
  will-change: transform, opacity;
}
.tile-value {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.4vw, 2rem); font-weight: 800;
  letter-spacing: -.02em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.tile-label { font-size: 13.5px; opacity: .7; }

.metrics-note {
  margin-top: var(--s-5); font-size: 14px;
  color: var(--c-ink-muted); max-width: 56ch;
}

@media (max-width: 1024px) {
  .engine-grid { grid-template-columns: 1fr; gap: var(--s-8); }
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 480px) {
  .acts-grid { grid-template-columns: 1fr; }
  .basket-compare { grid-template-columns: 1fr; gap: var(--s-3); }
  .tiles { grid-template-columns: 1fr 1fr; gap: var(--s-4); }
}

/* ---- ecosystem --------------------------------------------------------- */

.ecosystem { background: var(--c-bg-alt); }
.eco-head { max-width: 46rem; margin-bottom: var(--s-10); }
.eco-head .display-sm { margin-bottom: var(--s-4); }

/* Three columns with the platform in the middle, which is the claim: not
   a tool bolted to the side of the restaurant, a layer everything passes
   through. The arrows are borders rather than images — they scale with
   the text and cost nothing. */
.eco-diagram {
  /* The chevrons are absolutely positioned OUTSIDE the circle, so the gap
     around it has to be at least as big as they reach. Both numbers live
     here, together, for one reason: the first version set the offset from
     the circle and took the clearance from --s-12, and --s-12 shrinks
     from 96px to 64px below 768px. The arrows kept their size, the gap
     lost a third of its own, and they landed on the heading below —
     visible only between 481px and 768px, which is why it survived a
     check at 390 and at 1440.
     `reach` is the offset plus the chevron's rotated half-diagonal (24px)
     plus room to breathe. */
  --eco-chevron: 34px;
  /* Half the box, and the half-diagonal of the rotated box — 0.7071 * 34.
     Both are written out because CSS cannot do the trigonometry and both
     are needed below. */
  --eco-chevron-half: 17px;
  --eco-chevron-ink: 24px;

  /* The gap the eye actually sees: circle edge to the nearest stroke of
     the chevron, and it is the SAME number on both sides. It needs two
     different offsets to produce that, and the reason is the second
     thing this file has now been caught by:

     a chevron is a square with two borders on it, rotated 45 degrees.
     Rotating does not move the box, but it moves the ink: the corner
     where the two borders meet swings out to the pointing side and the
     two free ends swing back to the middle, so all the ink ends up in
     the forward half of the rotated box and the other half is empty.
     Position both chevrons the same distance from the circle and the one
     pointing towards it sits 24px closer than the one pointing away —
     which is exactly what the page showed: 15px of gap on the left
     against 39px on the right, on a diagram whose whole job is to look
     symmetrical.

     So the incoming chevron is pushed out by its own ink and the
     outgoing one is not. */
  --eco-arrow-gap: 28px;
  --eco-arrow-in: calc((var(--eco-chevron-half) + var(--eco-chevron-ink) + var(--eco-arrow-gap)) * -1);
  --eco-arrow-out: calc((var(--eco-chevron-half) + var(--eco-arrow-gap)) * -1);

  /* How far the ink reaches past the circle, on either side: the gap plus
     the half-diagonal. The grid gap has to clear it. */
  --eco-arrow-reach: 96px;

  display: grid; grid-template-columns: 1fr auto 1fr;
  /* stretch, not center: the two columns hold four and five items, so
     centring each on its own height put their headings at different
     heights — the first thing the eye notices and reads as carelessness.
     Stretched, both start at the same line and the circle centres itself
     against them. */
  gap: var(--eco-arrow-reach); align-items: stretch;
  will-change: transform;
}
/* Capped, and pushed to the middle: at full column width the cards
   stretched across half the screen with three words in them, which read
   as a layout accident rather than a list. */
.eco-column {
  width: 100%; max-width: 330px;
  /* The heading pins to the top and the list takes the rest, so both
     columns line up however many items each holds. */
  display: flex; flex-direction: column;
}
.eco-column ul { flex: 1; align-content: center; }
.eco-in { justify-self: end; }
.eco-out { justify-self: start; }

.eco-column h3 {
  font-size: 12px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--c-ink-muted);
  margin-bottom: var(--s-4);
}
.eco-column ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.eco-column li {
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius); padding: var(--s-3) var(--s-4);
  font-size: 15.5px; font-weight: 500;
  box-shadow: var(--shadow-sm);
}
/* Both columns read left-to-right. Mirroring the right one was meant
   to suggest flowing outward and instead just looked unaligned: the
   text sat at the far edge of a wide card with nothing beside it.
   The chevrons already carry the direction. */

/* Deliberately NOT a [data-reveal] element, and this is load-bearing.
   The two chevrons below hang off this circle by absolute positioning, so
   anything that moves the circle moves them into whatever is next to it —
   and .reveal starts at translateY(22px). Stacked on a phone that put the
   lower arrow straight through the heading beneath it for the whole
   length of the entrance animation: measured at 74px of clearance during
   the reveal against 95px after it, needing 80px.
   The rule generalises: decoration positioned outside an element must not
   hang off one that animates. */
.eco-core {
  align-self: center;
  display: grid; place-items: center;
  width: 190px; height: 190px; border-radius: 50%;
  background: var(--c-ink); color: var(--c-primary-contrast);
  box-shadow: var(--shadow-lg);
  position: relative;
}
/* The two chevrons pointing into and out of the core. Pure CSS, and
   aria-hidden by virtue of being decoration on a container whose meaning
   is already carried by the two lists' headings. */
.eco-core::before, .eco-core::after {
  content: ''; position: absolute; top: 50%;
  width: var(--eco-chevron); height: var(--eco-chevron);
  border-top: 2px solid var(--c-accent);
  border-right: 2px solid var(--c-accent);
}
.eco-core::before { left: var(--eco-arrow-in); transform: translateY(-50%) rotate(45deg); }
.eco-core::after  { right: var(--eco-arrow-out); transform: translateY(-50%) rotate(45deg); }

.eco-core-label {
  font-size: 14px; font-weight: 700; letter-spacing: .04em;
  text-align: center; padding: 0 var(--s-4); line-height: 1.3;
}

/* ---- benefits ----------------------------------------------------------- */

.benefits-grid {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--s-4);
}
.benefit-n {
  display: block; margin-bottom: var(--s-3);
  font-family: var(--font-display);
  font-size: 26px; font-weight: 800; letter-spacing: -.03em;
  color: var(--c-accent); font-variant-numeric: tabular-nums;
}

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

.proof { background: var(--c-bg-alt); }
.proof-inner { max-width: 46rem; }
.proof-inner .display-sm { margin: 0 0 var(--s-4); }
.proof-inner .lede { margin-bottom: var(--s-6); }

/* The honest empty space. A dashed slot rather than a fake card: it reads
   as a place being kept, which is what it is. */
.proof-slot {
  display: grid; place-items: center;
  border: 2px dashed var(--c-line); border-radius: var(--radius-lg);
  padding: var(--s-10) var(--s-6); margin-bottom: var(--s-6);
  background: var(--c-bg);
}
.proof-slot-label {
  font-size: 15px; font-weight: 600; color: var(--c-ink-muted);
  text-align: center;
}

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

.pricing-head { max-width: 46rem; margin-bottom: var(--s-6); }
.pricing-head .display-sm { margin-bottom: var(--s-4); }

.billing-toggle {
  display: inline-flex; gap: 2px; margin-bottom: var(--s-8);
  background: var(--c-bg-alt); border: 1px solid var(--c-line);
  border-radius: 999px; padding: 4px;
}
.billing-option {
  display: inline-flex; align-items: center; gap: var(--s-2);
  border: 0; background: transparent; cursor: pointer;
  border-radius: 999px; padding: 9px 18px;
  font-size: 14.5px; font-weight: 600; color: var(--c-ink-muted);
  transition: background-color .18s ease, color .18s ease;
}
.billing-option.is-active { background: var(--c-bg); color: var(--c-ink); box-shadow: var(--shadow-sm); }
.billing-save {
  font-size: 11.5px; font-weight: 700; letter-spacing: .04em;
  color: var(--c-accent);
  background: color-mix(in srgb, var(--c-accent) 14%, transparent);
  border-radius: 999px; padding: 2px 8px;
}

.plans {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  /* stretch, not start: the plans hold different numbers of features, and
     left to themselves the three buttons land at three different heights
     — which reads as a broken grid rather than as three plans. */
  gap: var(--s-4); align-items: stretch;
}
.plan {
  position: relative;
  /* The feature list absorbs the slack (1fr), so the buttons line up at
     the bottom of all three cards whatever each one lists. */
  display: grid; gap: var(--s-4);
  grid-template-rows: auto auto auto 1fr auto;
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius-lg); padding: var(--s-6);
  box-shadow: var(--shadow-sm);
  will-change: transform, opacity;
}
/* The middle plan stands out by a border and a lift, not by being bigger:
   a taller card in a row of three breaks the grid on every narrow screen. */
.plan-featured { border-color: var(--c-accent); box-shadow: var(--shadow-md); }
.plan-badge {
  position: absolute; top: calc(var(--s-3) * -1); left: var(--s-6);
  font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--c-primary-contrast); background: var(--c-accent);
  border-radius: 999px; padding: 4px 11px;
}
.plan h3 { font-size: 20px; font-weight: 700; letter-spacing: -.015em; }
.plan-blurb { font-size: 15px; color: var(--c-ink-muted); margin-top: calc(var(--s-3) * -1); }

.plan-price { display: flex; align-items: baseline; gap: var(--s-2); flex-wrap: wrap; }
.plan-price[hidden] { display: none; }
.plan-amount {
  font-family: var(--font-display);
  font-size: 40px; font-weight: 800; letter-spacing: -.03em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.plan-period { font-size: 15px; color: var(--c-ink-muted); }
/* The installation fee, under the monthly. Its own line because it is a
   different kind of number — charged once, per shop — and reading it as
   part of the monthly is the misunderstanding worth preventing. */
.plan-setup {
  /* A flex item, so `display:block` alone would still leave it on the
     price's own line — it needs the whole row to sit under the amount. */
  flex-basis: 100%; margin-top: var(--s-1);
  font-size: 13px; color: var(--c-ink-muted);
}
/* No price yet, and the card says so at the size a price would have been
   — the space is held rather than collapsed, so publishing one later does
   not change the layout. */
.plan-soon {
  font-size: 22px; font-weight: 700; letter-spacing: -.02em;
  color: var(--c-ink-muted);
}

.plan-features { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.plan-features li {
  position: relative; padding-left: var(--s-5);
  font-size: 15px; color: var(--c-ink-muted);
}
.plan-features li::before {
  content: ''; position: absolute; left: 0; top: .52em;
  width: 9px; height: 5px;
  border-left: 2px solid var(--c-accent);
  border-bottom: 2px solid var(--c-accent);
  transform: rotate(-45deg);
}
.plan-cta { width: 100%; }

/* ---- faq ---------------------------------------------------------------- */

/* details/summary, so the accordion works with JavaScript switched off and
   is keyboard-operable without a line of ARIA. */
.faq-list { display: grid; gap: var(--s-2); max-width: 52rem; }
.faq-item {
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius); padding: var(--s-4) var(--s-5);
  will-change: transform, opacity;
}
.faq-item summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  cursor: pointer; list-style: none;
  font-size: 17px; font-weight: 600; letter-spacing: -.01em;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: ''; flex: none;
  width: 10px; height: 10px;
  border-right: 2px solid var(--c-ink-muted);
  border-bottom: 2px solid var(--c-ink-muted);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .2s ease;
}
.faq-item[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.faq-item[open] summary { color: var(--c-accent); }
.faq-item p {
  margin-top: var(--s-3); font-size: 15.5px; line-height: 1.65;
  color: var(--c-ink-muted); max-width: 62ch;
}

/* ---- final cta ---------------------------------------------------------- */

.final-cta { overflow: hidden; text-align: center; }
.final-cta-inner { position: relative; z-index: 1; max-width: 42rem; margin: 0 auto; }
.final-cta .display { margin-bottom: var(--s-5); }
.final-cta .lede { margin: 0 auto var(--s-8); }
.final-cta .hero-cta { justify-content: center; }
.final-cta .hero-glow { top: -40%; }

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

.footer-grid { grid-template-columns: 1.3fr .7fr 1fr; }
.footer-title {
  font-size: 12px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; opacity: .6; margin-bottom: var(--s-3);
}
.footer-links { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.footer-links a { font-size: 14.5px; opacity: .8; }
.footer-links a:hover { opacity: 1; text-decoration: underline; }

/* ---- responsive: the new sections --------------------------------------- */

@media (max-width: 1024px) {
  /* The diagram becomes a column: arrows pointing sideways make no sense
     once the three parts are stacked, so they are turned to point down. */
  /* Wider gap than the desktop row needs: stacked, the chevrons point
     DOWN into the gap, and at --s-8 the lower one landed on the heading
     of the column beneath it. */
  .eco-diagram { grid-template-columns: 1fr; justify-items: center; gap: var(--eco-arrow-reach); }
  .eco-column { max-width: 420px; }
  .eco-in, .eco-out { justify-self: center; }
  .eco-core::before, .eco-core::after {
    top: auto; left: 50%; right: auto;
  }
  /* Same correction turned through 90 degrees: at 135deg the ink sits in
     the bottom half of the box, so the chevron above the circle needs the
     extra push and the one below it does not. */
  .eco-core::before { bottom: auto; top: var(--eco-arrow-in); transform: translateX(-50%) rotate(135deg); }
  .eco-core::after { top: auto; bottom: var(--eco-arrow-out); transform: translateX(-50%) rotate(135deg); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 480px) {
  .benefits-grid, .plans { grid-template-columns: 1fr; }
  .eco-core { width: 150px; height: 150px; }
  .billing-toggle { width: 100%; }
  .billing-option { flex: 1; justify-content: center; }
  .footer-grid { grid-template-columns: 1fr; }
}

/* ---- testimonials ------------------------------------------------------- */

/* Unused until a real restaurant has agreed to be quoted — the section
   renders nothing at all before then (see tools/build_landing.py's
   proof()). Written now so the first real quote is a data change. */
.quotes {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--s-4);
}
.quote {
  margin: 0;
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius-lg); padding: var(--s-6);
  box-shadow: var(--shadow-sm);
  display: grid; gap: var(--s-4); align-content: start;
}
.quote blockquote {
  margin: 0; font-size: 17px; line-height: 1.6;
  letter-spacing: -.01em;
}
.quote blockquote::before { content: '\201C'; }
.quote blockquote::after { content: '\201D'; }
.quote figcaption { display: grid; gap: 2px; font-size: 14px; }
.quote figcaption span { color: var(--c-ink-muted); }

/* ---- founding restaurants ---------------------------------------------- */

/* Dark, and the only dark section besides the dashboard and the footer.
   It stands where testimonials would stand and has to read as an offer
   rather than as a gap being covered — the contrast is what makes it
   arrive as a proposition instead of as more page. */
.founding {
  background: var(--c-ink); color: var(--c-primary-contrast);
  overflow: hidden;
}
.found-head { max-width: 46rem; margin-bottom: var(--s-10); }
.found-head .display-sm { margin-bottom: var(--s-4); }
.found-head .lede { color: rgba(255,255,255,.72); }

/* The seal itself. Deliberately a badge and not a graphic: it is a claim
   about terms, so it has to be legible, translatable and printable at any
   size — none of which an image of a seal would be. */
.found-badge {
  display: inline-flex; align-items: center; gap: var(--s-2);
  margin-bottom: var(--s-5);
  padding: 7px 15px 7px 11px;
  border: 1px solid color-mix(in srgb, var(--c-accent-soft) 45%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--c-accent) 22%, transparent);
  font-size: 12.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--c-accent-soft);
}
.found-badge-mark { font-size: 13px; line-height: 1; }

.found-slots {
  display: inline-block; margin-top: var(--s-5);
  font-size: 14px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--c-accent-soft);
  border-top: 2px solid color-mix(in srgb, var(--c-accent) 55%, transparent);
  padding-top: var(--s-2);
}

.found-grid {
  list-style: none; margin: 0 0 var(--s-10); padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--s-6);
}
.found-item {
  border-top: 1px solid rgba(255,255,255,.16);
  padding-top: var(--s-4);
  will-change: transform, opacity;
}
.found-item h3 {
  font-size: 18px; font-weight: 700; letter-spacing: -.015em;
  margin-bottom: 6px;
}
.found-item p { font-size: 15.5px; line-height: 1.6; color: rgba(255,255,255,.7); }

.found-foot { display: grid; gap: var(--s-4); justify-items: start; }
.found-foot .btn-primary {
  background: var(--c-bg); color: var(--c-ink);
}
.found-note {
  font-size: 14px; color: rgba(255,255,255,.6); max-width: 54ch;
}

@media (max-width: 480px) {
  .found-grid { grid-template-columns: 1fr; gap: var(--s-5); }
  .found-foot .btn { width: 100%; justify-content: center; }
}


/* ---- the conversation's entrance ---------------------------------------- */

/* Each turn slides in from its own side and settles, rather than fading
   up like everything else on the page. Two reasons it is worth the extra
   rules: the generic fade was imperceptible at this size — the owner's
   words were "quase imperceptível" — and a message arriving from the
   speaker's own side is what a chat looks like. The overshoot in the
   easing is the whole effect: it lands, rather than stopping. */
/* How far a turn travels before it lands. It is a variable because it
   has to shrink: at 36px on a 390px phone the un-revealed turns sat
   outside the viewport, and an element outside the viewport is a
   horizontal scrollbar on the whole page — measured at 5px of overflow,
   on every page, for as long as anything was still hidden. Nobody would
   have reported it as an animation bug: the symptom is a page that
   wobbles sideways under the thumb.
   14px is inside the page's own side padding at that width, so nothing
   ever leaves the box. */
.turn.reveal { opacity: 0; }
.turn-customer.reveal { transform: translate3d(calc(var(--turn-slide) * -1), 8px, 0) scale(.94); }
.turn-ai.reveal       { transform: translate3d(var(--turn-slide), 8px, 0) scale(.94); }

.turn.reveal.is-in {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
  transition: opacity .28s ease-out,
              transform .52s cubic-bezier(.22, 1.2, .36, 1);
}

/* Here, and not up with the other phone rules, on purpose: this file's
   @media (max-width: 768px) block sits ABOVE the .turns rule that defines
   --turn-slide, and two declarations of equal specificity are settled by
   which comes last. The override was written up there first and lost
   silently — the measurement did not move at all, which is the only
   reason it was caught. */
@media (max-width: 768px) {
  .turns { --turn-slide: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  .turn.reveal, .turn.reveal.is-in { opacity: 1; transform: none; }
}


/* ---- the interest form -------------------------------------------------- */

/* Its own page, so its own header: the site navbar is five anchors into
   the landing page and every one of them would be dead here. */
.page-contact { background: var(--c-bg-alt); }
.lead-head { background: var(--c-bg); border-bottom: 1px solid var(--c-line); }
.lead-head-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); padding: var(--s-4) 0;
}
.lead-back { font-size: 14.5px; font-weight: 600; color: var(--c-ink-muted); text-decoration: none; }
.lead-back:hover { color: var(--c-ink); }

.lead-main { padding: var(--s-10) 0 var(--s-12); }
.lead-shell { max-width: 46rem; }
.lead-shell .display-sm { margin: var(--s-3) 0 var(--s-4); }
.lead-shell .lede { margin-bottom: var(--s-8); }

/* WhatsApp first when there is a number, because it is the faster of the
   two and pretending otherwise helps nobody. */
.lead-whatsapp { margin-bottom: var(--s-8); }
.lead-note { margin: var(--s-3) 0 0; font-size: 14px; color: var(--c-ink-muted); }
.lead-or {
  margin: var(--s-6) 0 0; font-size: 12px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--c-ink-muted);
}

.lead-form {
  display: grid; gap: var(--s-5);
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius-lg); padding: var(--s-6);
  box-shadow: var(--shadow-sm);
}
.lead-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4); }
.lead-row-3 { grid-template-columns: 1fr 1fr .7fr; }
.lead-field { display: grid; gap: 6px; min-width: 0; }
.lead-label { font-size: 13.5px; font-weight: 600; }
.lead-opt { font-weight: 500; color: var(--c-ink-muted); }
.lead-field input, .lead-field textarea {
  width: 100%; box-sizing: border-box;
  font: inherit; font-size: 15.5px; color: var(--c-ink);
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius); padding: var(--s-3);
}
.lead-field textarea { resize: vertical; min-height: 96px; }
.lead-field input:focus, .lead-field textarea:focus {
  outline: 2px solid var(--c-accent); outline-offset: 1px; border-color: transparent;
}
.lead-hint, .lead-privacy {
  margin: calc(var(--s-4) * -1) 0 0; font-size: 13.5px; color: var(--c-ink-muted);
}
.lead-privacy { margin: 0; }
.lead-error {
  margin: 0; padding: var(--s-3) var(--s-4);
  border: 1px solid var(--c-line); border-radius: var(--radius);
  background: var(--c-bg-alt); font-size: 14.5px; font-weight: 600;
}
.btn-wide { justify-content: center; width: 100%; }

/* Off-screen, not display:none, and never in the tab order. */
.lead-trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.lead-done {
  background: var(--c-bg); border: 1px solid var(--c-line);
  border-radius: var(--radius-lg); padding: var(--s-8);
  box-shadow: var(--shadow-sm); outline: none;
}
.lead-done .display-sm { margin: 0 0 var(--s-4); }
.lead-done .lede { margin-bottom: var(--s-6); }

@media (max-width: 640px) {
  .lead-row, .lead-row-3 { grid-template-columns: 1fr; }
}
