/* GoalFi landing page — 1:1 implementation of Figma "Desktop - 2" (2780:5511).
   The design is a fixed 1440 x 5250 canvas; every node keeps its exact Figma
   coordinates and the whole stage is uniformly scaled below 1440px. */

:root {
  --background-base: #071019;
  --text-primary: #f1f9ff;
  --brand-green: #00e676;
  --brand-lime: #d4ff00;
  --overlay-cyan-10: rgba(0, 207, 255, 0.1);
  --overlay-green-10: rgba(0, 230, 118, 0.1);
  --overlay-lime-10: rgba(212, 255, 0, 0.1);
  --overlay-white-20: rgba(241, 249, 255, 0.2);
  --radius-14: 14px;
}

* { margin: 0; padding: 0; box-sizing: content-box; }

html { background: var(--background-base); }

body {
  background: var(--background-base);
  font-family: 'Oxanium', 'Segoe UI', system-ui, -apple-system, sans-serif;
  color: var(--text-primary);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: inherit; text-decoration: none; }

img { display: block; max-width: none; }

p { margin: 0; }

/* ── scaled stage ──────────────────────────────────────────────── */

.viewport {
  position: relative;
  width: 1440px;
  height: 5250px;
  margin: 0 auto;
  overflow: hidden;
}

/* Two Figma frames, two fixed canvases: Desktop - 2 (1440x5250, node 2780:5511)
   and Frame 280 (390x7103, node 2819:6919). scale.js shows one and scales it. */
.stage {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: top left;
  overflow: hidden;
}

.stage-d { width: 1440px; height: 5250px; }
.stage-m { width: 390px;  height: 7103px; }

/* default to desktop until scale.js decides, so no-JS still renders something */
.stage-m { display: none; }

/* ── primitives ────────────────────────────────────────────────── */

/* every Figma node is absolutely placed at its canvas coordinates */
.a { position: absolute; }

.bg-base {
  left: 0;
  top: 0;
  width: 1440px;
  height: 5657px;
  background: var(--background-base);
}

.bg-base-m {
  left: 0;
  top: 0;
  width: 390px;
  height: 7103px;
  background: var(--background-base);
}

/* a Figma text frame: fixed box, contents vertically centred */
.t {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.row {
  display: flex;
  gap: 13.061px;
  align-items: center;
  width: 100%;
}

/* gradient-filled type — the fill is the exact bitmap Figma exports */
.grad {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ── buttons ───────────────────────────────────────────────────── */

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  text-align: center;
  white-space: nowrap;
  transition: filter .18s ease, transform .18s ease;
}

.btn:hover { filter: brightness(1.08); transform: translateY(-1px); }

/* the stroke is the brand green→lime gradient, which Figma codegen flattens to a
   flat #00e676 — sampled off the exported gradient fills instead */
.btn-outline {
  position: relative;
  background: var(--overlay-green-10);
}

/* 2px gradient ring, drawn as a masked overlay so the fill stays translucent */
.btn-outline::before {
  content: '';
  position: absolute;
  inset: 0;
  box-sizing: border-box;
  border-radius: inherit;
  padding: 2px;
  background: linear-gradient(82.5deg, #00e676, #d4ff00);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

/* ── cards ─────────────────────────────────────────────────────── */

/* dual-value-proposition card (Component 5 / 6) */
.card-dv {
  display: flex;
  align-items: center;
  padding: 32px 48px;
  box-sizing: border-box;
  background: var(--overlay-cyan-10);
  border-radius: var(--radius-14);
  box-shadow: 0 5px 26.3px 0 rgba(19, 29, 38, 0.7);
}

/* how-it-works / staking card */
.card-hiw {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 17.415px 19.592px;
  box-sizing: border-box;
  background: var(--overlay-cyan-10);
  border-radius: 10.884px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.icon-box {
  position: relative;
  flex-shrink: 0;
  overflow: hidden;
  background: var(--overlay-lime-10);
}

.pill {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  flex-shrink: 0;
}

/* section chip (HOW IT WORKS / $GOAL & STAKING PREVIEW / ECOSYSTEM) */
.chip {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  box-sizing: border-box;
  background: var(--overlay-cyan-10);
  border-radius: 10px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* small chip (roadmap milestones, footer column headers) */
.chip-sm {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 18px;
  box-sizing: border-box;
  background: var(--overlay-cyan-10);
  border-radius: 10px;
  flex-shrink: 0;
}

/* ── roadmap ───────────────────────────────────────────────────── */

.rot {
  display: flex;
  align-items: center;
  justify-content: center;
}

.rot-i {
  transform: rotate(-90deg);
  flex: none;
}

.ctrl {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ── footer links ──────────────────────────────────────────────── */

.viewport a:not(.btn):hover { color: var(--brand-green); }

header nav a { transition: opacity .18s ease; }
header nav a:hover { opacity: .75; }

/* cropped app screenshots — the exported PNG already carries the 1px frame border */
.shot {
  position: absolute;
  overflow: hidden;
  box-shadow: 0 2px 32px 15px rgba(4, 20, 27, 0.6);
}
.shot img { position: absolute; }


/* ── mobile ────────────────────────────────────────────────────── */

/* a Figma frame that centres a rotated child (the vertical roadmap spine,
   the rotated background group) */
.rot-box {
  display: flex;
  align-items: center;
  justify-content: center;
}

#m-menu-btn:hover { opacity: .75; }

/* the dropdown behind the header's kebab. Styled by class, never inline: an inline
   display would outrank the UA rule for [hidden] and the menu would render open. */
.m-menu {
  position: absolute;
  top: 74px;
  right: 16px;
  width: 230px;
  padding: 12px 0;
  border-radius: 10px;
  background: rgba(7, 16, 25, 0.96);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 8px 24px rgba(4, 20, 27, 0.7);
  display: flex;
  flex-direction: column;
}

.m-menu[hidden] { display: none; }

.m-menu a {
  padding: 8px 18px;
  font-size: 16px;
  line-height: 28px;
  color: var(--brand-green);
}

.m-menu a:hover { color: var(--brand-lime); }



/* ── hero card stack ───────────────────────────────────────────── */

/* Three app screens on one shared keyframe track, each offset by a third of the
   cycle, so exactly one card holds the front slot at any moment:

     front ──(slides out, fades)──> back ──> mid ──> front

   The only teleport is out → back, and it happens at opacity 0. Depth is real
   translateZ read through the stack's inline perspective — that is what scales
   and foreshortens the cards — while z-index does the paint ordering. Ordering
   is deliberately not left to transform-style: preserve-3d, which the reveal's
   own opacity would switch off for the length of the fade.

   Every offset is a variable so the mobile frame can restate the same figures
   at 0.7 and share one set of keyframes. */

.shot-stack {
  --fx:  80px;  --fy:  70px;              /* front */
  --mz: -90px;                            /* mid: depth only, centred */
  --bx: -90px;  --by: -79px; --bz: -180px; /* back — x/y pre-divided by the
                                              0.886 the perspective will apply */
  --ox: 130px;  --oy: 112px; --oz:   80px; /* out: toward the viewer, fading */
}

.stage-m .shot-stack {
  --fx:  56px;  --fy:  49px;
  --mz: -63px;
  --bx: -63px;  --by: -55px; --bz: -126px;
  --ox:  91px;  --oy:  78px; --oz:   56px;
}

.shot-stack .shot {
  animation: shot-cycle 6s ease-in-out infinite;
  will-change: transform, opacity;
}

/* -2s steps through the 6s cycle, so the front card changes every two seconds:
   parlay holds the front on load, exactly as the Figma frame has it, then the
   feed screen, then the match screen. The extra -2/3s lands all three inside a
   hold rather than mid-transition, so the stack is settled and all three cards
   are readable the moment the page opens.

   These have to outweigh the `animation` shorthand above, which resets
   animation-delay to 0s at (0,2,0) — at a lower weight all three cards run in
   lockstep on the same slot and the stack collapses into one blurred pile. */
.shot-stack .shot-parlay { animation-delay: -0.666s; }
.shot-stack .shot-market { animation-delay: -2.666s; }
.shot-stack .shot-feed   { animation-delay: -4.666s; }

/* let a reader stop the carousel on the card they want to look at */
.shot-stack:hover .shot { animation-play-state: paused; }

@keyframes shot-cycle {
  0%, 26%  { transform: translate3d(var(--fx), var(--fy), 0) rotateY(0deg);
             opacity: 1;   z-index: 3; }
  31%      { transform: translate3d(var(--ox), var(--oy), var(--oz)) rotateY(-12deg);
             opacity: 0;   z-index: 3; }
  34%      { transform: translate3d(var(--bx), var(--by), var(--bz)) rotateY(11deg);
             opacity: 0;   z-index: 1; }
  40%, 60% { transform: translate3d(var(--bx), var(--by), var(--bz)) rotateY(11deg);
             opacity: .62; z-index: 1; }
  67%, 93% { transform: translate3d(0, 0, var(--mz)) rotateY(6deg);
             opacity: .92; z-index: 2; }
  100%     { transform: translate3d(var(--fx), var(--fy), 0) rotateY(0deg);
             opacity: 1;   z-index: 3; }
}

/* Fallback: scale.js sets this when card-feed.png will not load. Two cards can't
   fill a three-slot cycle without rotating a hole through the front, so the
   stack just holds the original composition instead. */
.shot-stack.is-static .shot { animation: none; }
.shot-stack.is-static .shot-feed { display: none; }

.shot-stack.is-static .shot-parlay {
  transform: translate3d(var(--fx), var(--fy), 0);
  opacity: 1;
  z-index: 3;
}

.shot-stack.is-static .shot-market {
  transform: translate3d(0, 0, var(--mz)) rotateY(6deg);
  opacity: .92;
  z-index: 2;
}

/* no cycling without motion — the three cards just sit in their slots */
@media (prefers-reduced-motion: reduce) {
  .shot-stack .shot { animation: none; }

  .shot-stack .shot-parlay {
    transform: translate3d(var(--fx), var(--fy), 0);
    opacity: 1;
    z-index: 3;
  }
  .shot-stack .shot-feed {
    transform: translate3d(0, 0, var(--mz)) rotateY(6deg);
    opacity: .92;
    z-index: 2;
  }
  .shot-stack .shot-market {
    transform: translate3d(var(--bx), var(--by), var(--bz)) rotateY(11deg);
    opacity: .62;
    z-index: 1;
  }
}

/* ── motion ────────────────────────────────────────────────────── */

/* Every node is an absolutely positioned Figma layer, so animating opacity and
   transform can never disturb the canvas geometry, and the stage's own scale()
   carries the travel with it — the motion shrinks with the page. scale.js adds
   these classes and skips the whole system under prefers-reduced-motion. */

.fx { opacity: 0; }
.fx-up { transform: translateY(28px); }

.fx.is-in {
  opacity: 1;
  transform: none;
  transition: opacity .7s cubic-bezier(.22, .61, .36, 1),
              transform .7s cubic-bezier(.22, .61, .36, 1);
  transition-delay: var(--fx-delay, 0ms);
}

/* the two nodes carrying an inline transform:scaleX(-1) keep it — an inline
   style outranks .fx-up, so those arrows fade in without travelling */

/* header drops in once, on load */
.fx-header { animation: fx-drop .6s cubic-bezier(.22, .61, .36, 1) both; }

@keyframes fx-drop {
  from { opacity: 0; transform: translateY(-100%); }
  to   { opacity: 1; transform: none; }
}

/* ambient float — starts from transform:none, so it takes over seamlessly
   when the reveal transition has finished */
.fx-float {
  animation: fx-float 7s ease-in-out infinite;
  animation-delay: var(--fx-float-delay, 1s);
}
.fx-float-slow {
  animation: fx-float-slow 11s ease-in-out infinite;
  animation-delay: var(--fx-float-delay, 1s);
}

@keyframes fx-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

@keyframes fx-float-slow {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-14px) rotate(-1.2deg); }
}

/* the logo's glow layer breathes behind the mark */
.fx-glow { animation: fx-glow 4.5s ease-in-out infinite; }

@keyframes fx-glow {
  0%, 100% { opacity: .75; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.06); }
}

/* primary CTA: a slow halo, so the button reads as the live target */
.fx-cta { animation: fx-cta 3.4s ease-in-out 1.4s infinite; }

@keyframes fx-cta {
  0%, 100% { box-shadow: 0 0 0 0 rgba(0, 230, 118, 0); }
  50%      { box-shadow: 0 0 30px 2px rgba(0, 230, 118, .38); }
}

/* the roadmap progress bar draws itself in. clip-path leaves the SVG's own
   geometry alone, so the line grows instead of stretching. On mobile the image
   is rotated 90deg by its wrapper, so the same inset reveals top-to-bottom. */
img.fx-draw { clip-path: inset(0 100% 0 0); }

img.fx-draw.is-in {
  clip-path: inset(0 0 0 0);
  transition: clip-path 1.2s cubic-bezier(.22, .61, .36, 1);
  transition-delay: calc(var(--fx-delay, 0ms) + 250ms);
}

/* ── hover ─────────────────────────────────────────────────────── */

/* after .fx.is-in these share its transform transition; both selectors weigh
   the same, so these have to stay below the reveal block to win on hover */
.card-dv, .card-hiw { transition: transform .3s ease, box-shadow .3s ease, background-color .3s ease; }

.card-dv:hover {
  transform: translateY(-6px);
  box-shadow: 0 18px 42px 0 rgba(4, 20, 27, .8);
}

.card-hiw:hover {
  transform: translateY(-5px);
  background: rgba(0, 207, 255, .17);
}

.shot { transition: box-shadow .35s ease; }
.shot:hover { box-shadow: 0 10px 44px 18px rgba(4, 20, 27, .7); }

@media (prefers-reduced-motion: reduce) {
  .btn:hover, .card-dv:hover, .card-hiw:hover { transform: none; }
}

/* Set by an inline script in <head>, cleared by scale.js once the layers are
   classed. Without it the document is long enough to paint once before the
   script at the end of <body> runs, and the page would flash in at full opacity
   and then rewind. No JS, no class, no hiding. */
.pre-fx .stage > *:not([data-bg]) { opacity: 0; }
