/* ============================================================================
   Funnlr polish layer — added 2026-08-16.

   Ibrahim, after pointing at yoco.com/za and optimawebai.com: "I like my
   current landing page. Every page, I like how it is, but I would prefer it to
   be a bit more smoother… I'm just asking for those fine details."

   So this file changes NO copy, NO layout and NO structure. It only touches
   motion, depth, radius and type scale. Every page keeps its own stylesheet;
   this is loaded after it, so it wins on the handful of properties it sets.

   It is one file linked from each page on purpose: one place to tune, and
   rolling the whole thing back is deleting one <link> per page.

   Rules followed here:
   - Animate transform and opacity only. Anything else runs on the main thread
     and makes a cheap Android phone stutter, which is the opposite of smooth.
   - Nothing here may change a colour token. --text and --ink are the same
     value on this site, so a "harmless" colour tweak can make text vanish
     inside a dark panel.
   - Everything decorative stops under prefers-reduced-motion.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   1. One easing curve, one set of durations.
   The pages had a mix of `ease` and var(--ease); a page feels inconsistent when
   two elements answer the same gesture at different speeds. --ease is already
   defined per page as cubic-bezier(.2,.8,.2,1); this only fills the gap where
   it is missing so the file is safe to load anywhere.
   ------------------------------------------------------------------------ */
:root{
  --ease: cubic-bezier(.2,.8,.2,1);
  --ease-out: cubic-bezier(.16,1,.3,1);   /* long, settling — for reveals */
  --t-fast: .18s;
  --t-mid: .28s;
  --t-slow: .5s;
}

/* ---------------------------------------------------------------------------
   2. Anchor jumps.
   Every page has a sticky header, so #plans / #products / #industries landed
   with their first line hidden underneath it. This is the single most
   noticeable "unfinished" detail on the site.
   ------------------------------------------------------------------------ */
html{ scroll-behavior:smooth; scroll-padding-top:96px }
@media(max-width:900px){ html{ scroll-padding-top:78px } }

/* ---------------------------------------------------------------------------
   3. Type rendering.
   Small, free wins that make Syne and DM Sans sit better — the difference
   between "a website" and "a designed website" at a glance.
   ------------------------------------------------------------------------ */
body{
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
}
h1,h2,h3,.h1,.h2,.price,.pkg-price{ font-kerning:normal; font-variant-ligatures:common-ligatures }
/* Long paragraphs read better without a single orphaned word on the last line. */
p{ text-wrap:pretty }
h1,h2,h3,.h1,.h2{ text-wrap:balance }

::selection{ background:#c8f04a; color:#050507 }

/* ---------------------------------------------------------------------------
   4. Focus states.
   The site had browser-default focus rings. A visible, branded ring is both an
   accessibility requirement and one of those details that reads as finished.
   :focus-visible only, so it never shows on a mouse click.
   ------------------------------------------------------------------------ */
a:focus-visible, button:focus-visible, input:focus-visible,
textarea:focus-visible, select:focus-visible, [tabindex]:focus-visible{
  outline:2px solid #a9d22f;
  outline-offset:3px;
  border-radius:6px;
}

/* ---------------------------------------------------------------------------
   5. Scroll reveal.
   The existing .rv is opacity + translateY(34px) over .7s. Yoco's version also
   carries a whisper of scale, which is what stops a reveal reading as a block
   sliding and starts it reading as something settling into place. The distance
   is reduced slightly because a shorter travel at a longer ease feels calmer
   than a long travel.
   ------------------------------------------------------------------------ */
.rv{
  opacity:0;
  transform:translateY(26px) scale(.988);
  transition:opacity .8s var(--ease-out), transform .8s var(--ease-out);
  will-change:transform, opacity;
}
.rv.in{ opacity:1; transform:none; will-change:auto }

/* ---------------------------------------------------------------------------
   6. Buttons.
   A press should be felt. Scale down on :active is the cheapest way to make a
   button feel physical, and it is what both reference sites do.
   ------------------------------------------------------------------------ */
.btn, .fp-send, .pay-btn, .co-pay, .buy-btn, .add-btn, .btn-lime, .btn-ghost{
  transition:background var(--t-mid) var(--ease),
             border-color var(--t-mid) var(--ease),
             color var(--t-mid) var(--ease),
             transform var(--t-fast) var(--ease),
             box-shadow var(--t-mid) var(--ease);
}
.btn:hover, .fp-send:hover, .pay-btn:hover, .buy-btn:hover, .btn-lime:hover{
  transform:translateY(-1px);
}
.btn:active, .fp-send:active, .pay-btn:active, .co-pay:active,
.buy-btn:active, .add-btn:active, .btn-lime:active{
  transform:translateY(0) scale(.978);
}

/* ---------------------------------------------------------------------------
   7. Cards and panels.
   Softer, larger, lower-opacity shadows. The site used tight dark shadows,
   which read as "drop shadow"; a wide diffuse one reads as depth. Two layers:
   a tight one for the contact edge, a wide one for the ambient.
   ------------------------------------------------------------------------ */
.plan, .card, .product-card, .sh-card, .fp-card, .fp-box, .ck-card, .ck-sum,
.co-card, .co-sum, .pcard{
  transition:transform var(--t-slow) var(--ease),
             box-shadow var(--t-slow) var(--ease),
             border-color var(--t-mid) var(--ease);
}
.plan:hover, .card:hover, .product-card:hover, .sh-card:hover{
  transform:translateY(-5px);
  box-shadow:0 2px 6px rgba(0,0,0,.05), 0 22px 44px -12px rgba(0,0,0,.18);
}
/* The dark "Most chosen" plan needs a deeper shadow to lift off a light
   section at all — the same values disappear against #141416. */
.plan.best:hover{
  box-shadow:0 2px 8px rgba(0,0,0,.2), 0 26px 50px -12px rgba(0,0,0,.45);
}

/* ---------------------------------------------------------------------------
   8. Images.
   Ibrahim: "some of the images blend. Like, if it's an image, there will be
   like a floating coming on top."

   Two things: consistent rounding, and a soft scrim at the foot of the image
   so anything sitting over it stays readable and the photo melts into the
   panel instead of ending on a hard edge. The scrim is a pseudo-element on the
   CONTAINER, never on the <img>, so it cannot cover a control.
   ------------------------------------------------------------------------ */
.shot, .hero-img, .pl-art, .card-img, .accp, .pcard .shot{
  position:relative;
  overflow:hidden;
  border-radius:18px;
}
.shot img, .hero-img img, .pl-art img, .card-img img, .accp img{
  display:block;
  width:100%;
  height:100%;
  object-fit:cover;
  /* A very slow drift on hover. Scale only — no filter, which would repaint. */
  transition:transform 1.1s var(--ease);
}
.shot:hover img, .card-img:hover img, .pl-art:hover img{ transform:scale(1.035) }

/* The scrim. Deliberately weak: at full strength it reads as a broken gradient
   rather than as light falling off. Skipped on the shop's product shots, which
   are cut-outs on white and would just look dirty. */
.shot::after, .hero-img::after, .pl-art::after{
  content:"";
  position:absolute;
  inset:auto 0 0 0;
  height:42%;
  pointer-events:none;
  background:linear-gradient(180deg, rgba(5,5,7,0) 0%, rgba(5,5,7,.28) 100%);
}

/* ---------------------------------------------------------------------------
   9. Sticky header.
   It already goes solid on scroll; this only makes the change settle instead of
   snapping, and adds the frosted blur both reference sites use.
   ------------------------------------------------------------------------ */
.hdr{
  transition:background var(--t-slow) var(--ease),
             box-shadow var(--t-slow) var(--ease),
             backdrop-filter var(--t-slow) var(--ease);
}
.hdr.solid{ backdrop-filter:blur(14px) saturate(1.4); -webkit-backdrop-filter:blur(14px) saturate(1.4) }

/* Nav links: underline that grows from the left rather than appearing. */
.nlink{ position:relative; transition:color var(--t-mid) var(--ease) }
.nlink::after{
  content:""; position:absolute; left:0; right:0; bottom:-4px; height:1.5px;
  background:currentColor; transform:scaleX(0); transform-origin:left;
  transition:transform var(--t-mid) var(--ease);
}
.nlink:hover::after{ transform:scaleX(1) }

/* ---------------------------------------------------------------------------
   10. Mobile type scale — the "zoomed in" look.
   Yoco's mobile hero is enormous relative to the viewport; that confidence with
   size is most of what reads as premium on a phone. This nudges the top of the
   scale only, and only under 640px. Body copy is untouched: growing that would
   reflow real layout, which Ibrahim asked me not to do.
   ------------------------------------------------------------------------ */
@media(max-width:640px){
  .h1, h1.h1{ font-size:clamp(2.45rem, 10.2vw, 3.3rem); line-height:1.02; letter-spacing:-.035em }
  .h2, h2.h2{ font-size:clamp(1.95rem, 7.6vw, 2.5rem); line-height:1.06; letter-spacing:-.03em }
  .sp-h1, .fp-head .h1{ letter-spacing:-.035em }
  /* Slightly more air under a big heading so it does not crowd its lead. */
  .sec-head p, .fp-head .lead{ margin-top:14px }
}

/* ---------------------------------------------------------------------------
   11. Shop.
   Ibrahim: "the shop page, you must also make it premium."
   Structure and copy untouched — this is depth, rounding and motion only.
   ------------------------------------------------------------------------ */
.product-card, .sh-card{
  border-radius:22px;
  overflow:hidden;
  box-shadow:0 1px 2px rgba(0,0,0,.04), 0 10px 26px -14px rgba(0,0,0,.14);
}
.product-card .card-img, .sh-card .card-img{
  border-radius:0;              /* it is flush inside a rounded card now */
  background:#f6f6f7;           /* cut-outs sit on a tint, not stark white */
}
.product-card .card-img img{ transition:transform 1.1s var(--ease) }
.product-card:hover .card-img img{ transform:scale(1.05) }
/* The badge reads as a physical tag rather than a flat rectangle. */
.card-badge{ box-shadow:0 4px 12px rgba(0,0,0,.16); backdrop-filter:blur(6px) }

/* The buy button fills rather than just changing colour. */
.buy-btn, .add-btn{ position:relative; overflow:hidden }

/* ---------------------------------------------------------------------------
   12. Forms.
   A focused field should feel like it woke up.
   ------------------------------------------------------------------------ */
.fp-input, .field, .sp-input, input, textarea, select{
  transition:border-color var(--t-mid) var(--ease),
             box-shadow var(--t-mid) var(--ease),
             background var(--t-mid) var(--ease);
}

/* ---------------------------------------------------------------------------
   13. Reduced motion.
   Everything above that moves is decoration. All of it goes.
   ------------------------------------------------------------------------ */
@media(prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto }
  .rv{ opacity:1; transform:none; transition:none }
  .btn:hover, .btn:active, .plan:hover, .card:hover,
  .product-card:hover, .sh-card:hover{ transform:none }
  .shot:hover img, .card-img:hover img, .pl-art:hover img,
  .product-card:hover .card-img img{ transform:none }
  .nlink::after{ transition:none }
  *,*::before,*::after{ animation-duration:.001ms !important; animation-iteration-count:1 !important }
}
