/* ===========================================================================
   SplitGoGo landing page composition.

   Loaded ONLY by marketing/landing.html, on top of styles.css. Tokens, type,
   buttons, header, footer and form fields come from there; this file holds
   nothing but the layout of the eight landing sections.

   Section order, and the layout family each one uses. No family repeats,
   which is what stops the page reading as a stack of identical card rows:

     1. hero        asymmetric split, ink surface
     2. proofline   single centred line between hairlines
     3. stakes      editorial two-column prose, oversized lead
     4. gets        asymmetric bento, 3 cells, mixed fills
     5. partner     full-bleed media with an offset caption
     6. handled     numbered stack, hairline separated, no cards
     7. audience    two-column, one live and one upcoming
     8. close       ink surface, split heading and form

   The page sells outcomes. There is deliberately no code, no endpoint, no
   SDK snippet and no schema on it: the buyer is deciding whether their users
   should ever have to leave their product to settle up, and the API surface
   is what they read in the docs AFTER that decision. Keep it that way.
   =========================================================================== */

/* ------------------------------------------------------------------ hero -- */
/* The hero pulls itself up by the header's exact height so the dark surface
   runs edge to edge behind a transparent header, then pays the height back as
   top padding. Without this the header would sit ABOVE the hero in normal
   flow and a transparent header would reveal the white page behind it, not
   the hero. */
.hero {
  position: relative;
  overflow: hidden;
  margin-top: calc(-1 * var(--header-h));
  padding: calc(var(--header-h) + clamp(56px, 6vw, 88px)) 0 clamp(72px, 8vw, 104px);
}

/* Structure first, light second.

   A dot grid on the dark field gives the hero a measurable surface, which is
   what the comparable sites use (Ramp draws one on a canvas) instead of the
   coloured glow that reads as image-generation residue. Of eighteen fintech
   and infrastructure homepages surveyed, none used a coloured glow behind
   hero content.

   The mint wash survives at roughly a third of its first strength: enough to
   keep continuity with the launch film, not enough to be the effect. */
.hero::before {
  content: "";
  position: absolute;
  inset: -20% -10% auto -10%;
  height: 130%;
  pointer-events: none;
  background-image:
    radial-gradient(circle, rgba(233, 245, 242, 0.13) 1px, transparent 1px),
    radial-gradient(46% 40% at 24% 16%, rgba(87, 196, 163, 0.09), transparent 66%),
    radial-gradient(40% 44% at 82% 62%, rgba(87, 196, 163, 0.05), transparent 70%),
    radial-gradient(60% 50% at 50% 108%, rgba(6, 32, 28, 0.7), transparent 72%);
  background-size: 26px 26px, 100% 100%, 100% 100%, 100% 100%;
  /* the grid fades out before it reaches the edges, so it never reads as tiling */
  mask-image: radial-gradient(72% 62% at 50% 42%, #000 30%, transparent 100%);
  -webkit-mask-image: radial-gradient(72% 62% at 50% 42%, #000 30%, transparent 100%);
}

/* A whisper of grain. Flat dark fields band badly on wide gradients; this
   breaks the banding without reading as texture. Fixed and pointer-events
   none so it never repaints on scroll. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.16;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

.hero .wrap {
  position: relative;
  z-index: 1;
}

.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
  gap: clamp(40px, 5vw, 72px);
  align-items: center;
}

/* The measure, not the column, decides where this headline breaks. Capping it
   in ch is what the comparable sites do (they run 14-24ch and let it fall to
   two or three deliberate lines) and it is what lets the size go back up
   without the headline sprawling to four ragged lines. */
.hero h1 {
  font-size: clamp(2.5rem, 1.5rem + 3.4vw, 4rem);
  max-width: 17ch;
  margin-bottom: 24px;
}

/* The headline stays monochrome. Tinting one phrase of it accent is a gesture
   the peer set does not make: they keep the display type one colour and spend
   the accent on the call to action, which is also what keeps the page at the
   roughly 95:5 neutral-to-accent ratio those sites hold. */
.hero .lead {
  color: var(--ink-text-muted);
  max-width: 40ch;
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 34px;
}

/* --------------------------------------------------------------- resolve -- */
/* The hero figure. It shows the OUTPUT the product computes: a group who could
   owe each other ten different ways, reduced to the three payments that
   actually settle it.

   This is a figure, not a simulated screenshot. It has no window chrome, no
   fake nav and no invented product UI, because SplitGoGo is headless by
   design (docs/DECISIONS.md) and drawing an app it does not ship would be a
   lie told in CSS. Every number is real: the five balances net to zero and
   the three transfers are the settlement plan the demo ledger returned.

   It is a left-to-right convergence, and it has to stay one. The previous
   version put five nodes on a circle and drew all ten pairs between them,
   which is the construction of a pentagram inscribed in a pentagon; a
   point-up apex node with a blurred accent halo behind it completed the
   read. Anything that returns this figure to a ring, a closed polygon, or a
   radial arrangement around a haloed centre brings that back. */
.resolve {
  margin: 0;
}

.resolve__svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* the three payments. Width carries the amount, so these are filled paths
   rather than strokes, and the shared gradient makes each one gain weight as
   it approaches the settlement. */
.resolve__flow path {
  fill: url(#resolveFlow);
}

.resolve__name {
  fill: var(--ink-text);
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 560;
  letter-spacing: -0.014em;
}

/* every figure the ledger computed is mono and tabular, here as everywhere
   else on the page, so money never jitters between rows */
.resolve__owes {
  fill: var(--ink-text-muted);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-size: 12.5px;
  letter-spacing: -0.02em;
}

/* a hairline ring seats each portrait on the ink field. Without it the
   light-background crops bleed into the surface and the dark ones vanish. */
.resolve__ring {
  fill: none;
  stroke: rgba(233, 245, 242, 0.28);
  stroke-width: 1.5;
}

/* the one participant who is already square: dashed ring plus a dimmed
   portrait, stated by shape and value rather than colour, so it survives
   greyscale and colour-blind viewing */
/* Greyscale as well as dimmed. Opacity alone left the light-background crop
   reading as a bright disc that pulled more attention than the three rows
   that actually owe something, which is backwards. */
.resolve__person--square image {
  opacity: 0.38;
  filter: grayscale(1);
}

.resolve__person--square .resolve__ring {
  stroke-dasharray: 4 4;
  stroke: rgba(233, 245, 242, 0.42);
}

.resolve__person--square .resolve__name,
.resolve__person--square .resolve__owes {
  fill: var(--ink-text-muted);
}

/* the participant everyone ends up paying: the only accent ring in the figure */
.resolve__person--receiver .resolve__ring {
  stroke: var(--accent);
  stroke-width: 2;
}

.resolve__person--receiver .resolve__name {
  font-size: 16px;
  font-weight: 600;
}

/* the total arriving, so the ribbons resolve to a number and not just a face */
.resolve__in {
  fill: var(--ink-text);
  font-size: 13px;
}

/* the before and after, stated once. The three amounts already live on the
   ribbons, so repeating them as a table underneath would be the same fact
   printed twice. */
.resolve__sum {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid var(--ink-border);
  font-size: 0.875rem;
}

.resolve__sum p {
  margin: 0;
}

.resolve__sum-from {
  color: var(--ink-text-muted);
}

/* the arrow is drawn, not typed, so it cannot be read aloud as "right arrow"
   between two noun phrases that already scan as a sentence */
.resolve__sum-from::after {
  content: "";
  display: inline-block;
  width: 26px;
  height: 1px;
  margin: 0 0 4px 12px;
  background: var(--ink-border);
  vertical-align: middle;
}

.resolve__sum-to {
  color: var(--ink-text);
  font-weight: 560;
}

.resolve__cap {
  margin-top: 14px;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--ink-text-muted);
  max-width: 42ch;
}

/* ------------------------------------------------------------- proofline -- */
/* One real partner, stated plainly. A four-logo "trusted by" wall would be
   the honest-looking lie here: there is exactly one embed partner today, so
   the section says one. */
.proofline {
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}

.proofline .wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 14px;
  padding-top: 30px;
  padding-bottom: 30px;
  text-align: center;
}

.proofline p {
  font-size: 0.9375rem;
  color: var(--text-muted);
  margin: 0;
}

.proofline strong {
  color: var(--text);
  font-weight: 600;
}

/* ---------------------------------------------------------------- stakes -- */
/* The argument, in prose, at a size you cannot skim past. Two columns of
   running text with no card, no icon and no illustration: the point is the
   sentence, and boxing it would only dilute it. */
.stakes {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: start;
}

.stakes__claim {
  font-size: clamp(1.5rem, 1.1rem + 1.7vw, 2.125rem);
  line-height: 1.24;
  letter-spacing: -0.03em;
  font-weight: 560;
  text-wrap: balance;
  margin: 0;
}

.stakes__claim em {
  font-style: normal;
  color: var(--accent-text);
}

.stakes__body p + p {
  margin-top: 18px;
}

.stakes__body p {
  color: var(--text-muted);
  max-width: 54ch;
}

/* ------------------------------------------------------------------ gets -- */
/* Three outcomes, three differently-shaped cells. The lead cell spans the
   full width and carries the figure; the two below it are half-width. Cell
   count matches item count exactly, so there is no filler tile. */
.gets {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  margin-top: 52px;
}

.gets__cell {
  border: 1px solid var(--border);
  border-radius: var(--r-surface);
  padding: clamp(26px, 3vw, 38px);
  background: var(--surface);
}

.gets__cell--lead {
  grid-column: span 2;
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  gap: clamp(28px, 4vw, 56px);
  align-items: center;
  background: var(--surface-2);
}

.gets__cell p {
  color: var(--text-muted);
  max-width: 46ch;
}

/* --- the two supporting cells each carry a small real figure, so the grid is
   not one figure cell plus two boxes of prose --- */
.mini {
  margin-top: 22px;
  border-top: 1px solid var(--border);
}

.mini__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.875rem;
}

.mini__who {
  color: var(--text-muted);
}

.mini__val {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: -0.02em;
  color: var(--text);
}

.mini__val--owed {
  color: var(--accent-text);
  font-weight: 500;
}

.mini__val--square {
  color: var(--text-muted);
}

/* planned against actual, as two stacked rules rather than a filled track */
.budget {
  margin-top: 24px;
  display: grid;
  gap: 14px;
}

.budget__line {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  font-size: 0.8125rem;
}

.budget__label {
  color: var(--text-muted);
}

.budget__bar {
  height: 8px;
  border-radius: var(--r-pill);
  width: var(--w, 100%);
  background: var(--accent);
  opacity: 0.5;
}

.budget__line--actual .budget__bar {
  background: var(--ink-surface);
  opacity: 0.85;
}

.budget__val {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: -0.02em;
  color: var(--text);
}

/* The multi-currency figure: four currencies landing on one settled total.
   It carries the lead cell so that cell is not text-on-tint like the other
   two, which is what stops the grid reading as three identical boxes. */
.fx {
  display: grid;
  gap: 10px;
}

.fx__row {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 11px 16px;
  border-radius: var(--r-control);
  background: var(--surface);
  border: 1px solid var(--border);
}

.fx__code {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--text-muted);
}

/* The bar is the currency's SHARE of the group total once converted, set per
   row via --w. It is not decoration: a row can carry the largest raw number
   on the page (18,400 JPY) and the shortest bar, which is precisely the
   argument the cell is making. An equal-width bar on every row would encode
   nothing and would just be a progress bar cosplaying as data. */
.fx__track {
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--accent);
  opacity: 0.5;
  width: var(--w, 50%);
}

.fx__amount {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-size: 0.875rem;
  color: var(--text);
  letter-spacing: -0.02em;
}

.fx__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  margin-top: 4px;
  padding: 14px 16px;
  border-radius: var(--r-control);
  background: var(--ink-surface);
  color: #ffffff;
}

.fx__total-label {
  font-size: 0.875rem;
  color: var(--ink-text-muted);
}

.fx__total-value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-size: 1.0625rem;
  font-weight: 500;
  letter-spacing: -0.02em;
}

/* --------------------------------------------------------------- partner -- */
/* Real footage of the real embed, shown wide. This is the one place a
   partner's brand belongs: the claim is "it is live in someone's product",
   and only their product can prove it. */
.partner__head {
  max-width: 58ch;
  margin-bottom: clamp(34px, 4vw, 52px);
}

.demo-video {
  position: relative;
  border-radius: var(--r-surface);
  overflow: hidden;
  background: var(--ink-surface);
  border: 1px solid var(--ink-border);
  box-shadow: var(--shadow-lg);
  line-height: 0;
}

.demo-video video,
.demo-video__fallback {
  display: block;
  width: 100%;
  height: auto;
}

.demo-video__toggle {
  position: absolute;
  right: 14px;
  bottom: 14px;
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1;
  padding: 9px 16px;
  min-height: 36px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: var(--r-pill);
  background: rgba(8, 32, 29, 0.72);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: #ffffff;
  cursor: pointer;
  transition:
    background-color 0.18s var(--ease),
    border-color 0.18s var(--ease);
}

.demo-video__toggle:hover {
  background: rgba(8, 32, 29, 0.9);
  border-color: var(--accent);
}

.partner__cap {
  margin-top: 18px;
  font-size: 0.875rem;
  color: var(--text-muted);
  max-width: 62ch;
}

/* --------------------------------------------------------------- handled -- */
/* The hard parts, as a hairline-separated stack rather than a card grid.
   Each row is a thing the partner would otherwise have to build, own and get
   right forever. Numbers are counted for the reader, not decorative. */
.handled {
  margin-top: clamp(34px, 4vw, 52px);
  border-top: 1px solid var(--border);
}

.handled__row {
  display: grid;
  grid-template-columns: 48px minmax(0, 0.9fr) minmax(0, 1.3fr);
  gap: clamp(16px, 3vw, 40px);
  align-items: baseline;
  padding: clamp(22px, 2.6vw, 32px) 0;
  border-bottom: 1px solid var(--border);
}

.handled__n {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--accent-text);
  letter-spacing: 0.02em;
}

.handled__row h3 {
  margin: 0;
}

.handled__row p {
  color: var(--text-muted);
  margin: 0;
  max-width: 56ch;
}

/* -------------------------------------------------------------- audience -- */
.audience {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  margin-top: 52px;
}

.audience__card {
  border: 1px solid var(--border);
  border-radius: var(--r-surface);
  padding: clamp(26px, 3vw, 38px);
  background: var(--surface);
}

.audience__card p {
  color: var(--text-muted);
}

.audience__card--soon {
  background: var(--surface-2);
  border-style: dashed;
}

/* The accent wash is a fill, not a text background: --accent-text on it only
   reached 2.8:1 in light and 1.2:1 in dark. Ink on the wash clears AA in both,
   and the tag keeps its accent identity through the fill and the border. */
.tag {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 5px 12px;
  border-radius: var(--r-pill);
  background: var(--accent-wash-strong);
  border: 1px solid var(--accent-wash-strong);
  color: var(--text);
  margin-bottom: 18px;
}

.tag--soon {
  background: var(--surface-3);
  border-color: var(--border);
  color: var(--text-muted);
}

.soon-note {
  margin-top: 16px;
  font-size: 0.875rem;
  color: var(--text-muted);
}

/* ----------------------------------------------------------------- trust -- */
/* Four columns separated by hairline rules rather than four more cards. Every
   claim here is one the repo can back: no payment rail exists (SYSTEM_DESIGN
   lists money movement as out of scope), tenancy scoping is enforced at the
   query boundary, and the DPA and sub-processor list are already public pages.
   Nothing here claims a certification SplitGoGo does not hold. */
.trust {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  margin-top: clamp(34px, 4vw, 52px);
  border-top: 1px solid var(--border);
}

.trust__item {
  padding: 30px clamp(18px, 2vw, 28px) 8px;
  border-left: 1px solid var(--border);
}

.trust__item:first-child {
  padding-left: 0;
  border-left: 0;
}

.trust__item h3 {
  margin-bottom: 10px;
}

.trust__item p {
  color: var(--text-muted);
  font-size: 0.9375rem;
  line-height: 1.6;
}

.trust__links {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  font-size: 0.875rem;
}

/* ----------------------------------------------------------------- close -- */
/* The page closes on ink, mirroring the open. */
.close-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
  gap: clamp(36px, 5vw, 72px);
  align-items: start;
}

.close-grid h2 {
  margin-bottom: 16px;
}

.form-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-surface);
  padding: clamp(26px, 3vw, 36px);
  box-shadow: var(--shadow-lg);
}

.form-card .btn {
  width: 100%;
}

/* The form sits on ink, so its own labels and help text must resolve against
   the CARD, not the section. Reset the inherited ink colours. */
.close .form-card,
.close .form-card p,
.close .form-card label {
  color: var(--text);
}

.close .form-card .form-note,
.close .form-card .field label {
  color: var(--text);
}

.close .form-card .form-note {
  color: var(--text-muted);
}

/* ---------------------------------------------------------------- motion -- */
/* One-shot hero choreography. It narrates the single idea the figure exists
   to carry: the tangle of everything that COULD be owed collapsing into the
   three payments that settle it. That is the product's whole value in four
   seconds, which is why this animation earns its place and the decorative
   ones were cut.

   It ends at 4.3s. Staying under five seconds keeps it outside WCAG 2.2.2,
   so it needs no pause control. Crucially the RESTING state is the
   stylesheet default above, and the keyframes only ever animate TOWARD it,
   so reduced-motion, no-JS, print and screenshot capture all get the
   resolved figure rather than a blank box. */
@media (prefers-reduced-motion: no-preference) {
  /* the four on the left arrive first, top to bottom */
  .resolve__person {
    animation: node-in 0.6s var(--ease) backwards;
  }

  .resolve__person:nth-child(1) {
    animation-delay: 0.1s;
  }

  .resolve__person:nth-child(2) {
    animation-delay: 0.24s;
  }

  .resolve__person:nth-child(3) {
    animation-delay: 0.38s;
  }

  .resolve__person:nth-child(4) {
    animation-delay: 0.52s;
  }

  /* the receiver lands after the ribbons have reached it, not before */
  .resolve__person--receiver {
    animation-delay: 2.5s;
  }

  /* The payment itself: the clip rect opens left to right, so the three
     ribbons travel toward the settlement rather than fading in on the spot.
     Resting width is the full 448 set as an attribute in the markup, so a
     browser that will not animate an SVG geometry property through CSS gets
     the finished figure instead of an empty corridor. */
  .resolve__wipe {
    animation: flow-wipe 1.5s var(--ease) 1.1s backwards;
  }

  .resolve__sum,
  .resolve__cap {
    animation: row-in 0.6s var(--ease) backwards;
  }

  .resolve__sum {
    animation-delay: 3s;
  }

  .resolve__cap {
    animation-delay: 3.3s;
  }

  @keyframes flow-wipe {
    from {
      width: 190px;
    }
    to {
      width: 448px;
    }
  }

  @keyframes node-in {
    from {
      opacity: 0;
      transform: scale(0.82);
    }
    to {
      opacity: 1;
      transform: none;
    }
  }

  @keyframes row-in {
    from {
      opacity: 0;
      transform: translateY(8px);
    }
    to {
      opacity: 1;
      transform: none;
    }
  }
}

/* portraits scale about their own centre, not the SVG origin */
.resolve__person {
  transform-box: fill-box;
  transform-origin: center;
}

/* ------------------------------------------------------------ responsive -- */
@media (max-width: 1000px) {
  .hero-grid,
  .close-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .hero-grid {
    gap: 44px;
  }

  .hero .lead {
    max-width: none;
  }

  .gets__cell--lead {
    grid-template-columns: minmax(0, 1fr);
    gap: 28px;
  }
}

@media (max-width: 1000px) {
  /* two up, and the third item restarts the left edge */
  .trust {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .trust__item:nth-child(3) {
    padding-left: 0;
    border-left: 0;
  }
}

@media (max-width: 860px) {
  .stakes {
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
  }

  .handled__row {
    grid-template-columns: 32px minmax(0, 1fr);
    row-gap: 8px;
  }

  /* the number keeps its own column; the body drops beneath the heading */
  .handled__row p {
    grid-column: 2;
  }
}

@media (max-width: 760px) {
  .gets,
  .audience,
  .trust {
    grid-template-columns: minmax(0, 1fr);
  }

  /* stacked, the vertical rules become horizontal ones */
  .trust__item {
    padding: 24px 0 4px;
    border-left: 0;
    border-bottom: 1px solid var(--border);
  }

  .trust__item:last-child {
    border-bottom: 0;
  }

  .gets__cell--lead {
    grid-column: span 1;
  }

  .resolve__sum {
    margin-top: 18px;
  }
}
