/* flow.css - the portal's shared surface and motion language. One file, every page.
 *
 * THIS FILE IS PUBLIC and carries no internal names, paths or notes. No client name appears here.
 *
 * 🚨 EVERY ANIMATION HERE IS HAND-ROLLED CSS, and that is policy rather than preference. The
 * portal's CSP is script-src 'self' with no CDN origin, so GSAP, Lenis, ScrollTrigger and every
 * other motion library are unavailable to this portal by construction. Movement is transitions
 * and keyframes; "as you reach it" is one IntersectionObserver in flow.js adding a class.
 *
 * IT ADDS, IT DOES NOT OVERRIDE. Nothing here targets a bare element or an existing shopfront
 * class, so a page can load this file and change nothing until it opts in by using the classes.
 * That matters because this ships to every page at once and a page nobody has converted must look
 * exactly as it did.
 *
 * THE FOUR IDEAS, and the rest is detail:
 *   1. blocks ARRIVE as you reach them, once, from a consistent direction;
 *   2. surfaces LIFT under the cursor, so what is interactive is obvious without a border;
 *   3. one solid button per screen, so there is never a question about what to press;
 *   4. all of it switches off under prefers-reduced-motion, fully drawn and completely still.
 */

/* ---------------------------------------------------------------- 1. arriving */
.flow-reveal{opacity:0;transform:translateY(24px);
  transition:opacity .7s cubic-bezier(.2,.8,.2,1),transform .7s cubic-bezier(.2,.8,.2,1)}
.flow-reveal.flow-in{opacity:1;transform:none}
/* Direction modifiers, for pages that want a rhythm rather than one column rising. */
.flow-reveal.from-left{transform:translateX(-26px)}
.flow-reveal.from-right{transform:translateX(26px)}
.flow-reveal.from-left.flow-in,.flow-reveal.from-right.flow-in{transform:none}
/* A stagger without a per-child rule in every stylesheet: put these on siblings in order. */
.flow-d1{transition-delay:.06s} .flow-d2{transition-delay:.12s} .flow-d3{transition-delay:.18s}
.flow-d4{transition-delay:.24s} .flow-d5{transition-delay:.30s} .flow-d6{transition-delay:.36s}

/* ---------------------------------------------------------------- 2. surfaces */
.flow-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
  padding:18px;box-shadow:0 2px 10px rgba(10,32,63,.05);
  transition:transform .2s cubic-bezier(.2,.8,.2,1),box-shadow .2s,border-color .2s}
.flow-card:hover{transform:translateY(-3px);box-shadow:0 14px 34px rgba(10,32,63,.12);
  border-color:var(--sf-line-strong)}
/* A panel is a card that shows something rather than doing something: no pointer, softer lift. */
.flow-panel{background:var(--sf-canvas);border:1px solid var(--border);border-radius:14px;
  padding:16px;box-shadow:0 8px 26px rgba(10,32,63,.07);position:relative;overflow:hidden;
  transition:transform .25s cubic-bezier(.2,.8,.2,1),box-shadow .25s}

/* ---------------------------------------------------------------- 3. the one button */
.flow-cta{display:inline-flex;align-items:center;gap:10px;background:var(--sf-blue);
  color:var(--sf-on-blue);font-weight:650;font-size:17px;padding:14px 26px;border-radius:999px;
  text-decoration:none;border:0;cursor:pointer;box-shadow:0 10px 26px rgba(33,169,238,.32);
  transition:transform .18s cubic-bezier(.2,.8,.2,1),box-shadow .18s,filter .18s}
.flow-cta:hover{transform:translateY(-2px);box-shadow:0 16px 34px rgba(33,169,238,.42);
  filter:saturate(1.08)}
.flow-cta:active{transform:translateY(0)}
.flow-cta .flow-arrow{transition:transform .18s cubic-bezier(.2,.8,.2,1)}
.flow-cta:hover .flow-arrow{transform:translateX(4px)}

/* The quiet one. Every screen that has a solid button may have exactly one; everything else that
   navigates uses this, so the eye is never asked to choose between two equals. */
.flow-ghost{display:inline-flex;align-items:center;gap:8px;color:var(--sf-ink-2);font-weight:600;
  font-size:15px;text-decoration:none;padding:9px 14px;border-radius:999px;border:1px solid
  transparent;transition:background .18s,border-color .18s,color .18s,transform .18s}
.flow-ghost:hover{background:var(--surface);border-color:var(--border);color:var(--sf-navy)}

/* 🚨 THE BACK CONTROL. Its arrow moves LEFT on hover, the opposite of the forward one, because
   an affordance that moves the wrong way is worse than one that does not move at all. */
.flow-back{margin-bottom:14px}
.flow-back .flow-arrow{transition:transform .18s cubic-bezier(.2,.8,.2,1)}
.flow-back:hover .flow-arrow{transform:translateX(-4px)}

/* ---------------------------------------------------------------- page furniture */
.flow-hero{position:relative;padding:48px 0 34px;overflow:hidden}
.flow-hero h1{font-size:clamp(30px,4.4vw,50px);line-height:1.06;letter-spacing:-.02em;
  color:var(--sf-navy);margin:0 0 14px;max-width:16ch}
.flow-lede{font-size:clamp(16px,1.6vw,20px);line-height:1.5;color:var(--sf-ink-2);max-width:52ch;
  margin:0 0 26px}
.flow-lede b{color:var(--sf-navy);font-weight:650}
/* The wash sits ENTIRELY inside its container. Hung off a corner on negative insets it gets
   clipped by overflow:hidden while still opaque, and draws a hard-edged rectangle: a soft thing
   cut by a straight edge stops being soft. */
.flow-hero::before{content:"";position:absolute;top:-30px;right:-10px;width:420px;height:420px;
  background:radial-gradient(circle at 50% 50%,rgba(33,169,238,.20),rgba(33,169,238,.07) 42%,
    rgba(33,169,238,0) 66%);
  pointer-events:none;animation:flow-drift 20s ease-in-out infinite alternate}
@keyframes flow-drift{from{transform:translate3d(0,0,0) scale(1)}
  to{transform:translate3d(-26px,20px,0) scale(1.06)}}

.flow-num{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;
  border-radius:50%;background:var(--sf-navy);color:#fff;font-weight:700;font-size:15px;
  transition:transform .25s cubic-bezier(.2,.8,.2,1),background .25s}

/* A progress rail: how far along something is, as a shape rather than a sentence. */
.flow-rail{display:flex;gap:4px;margin:10px 0 12px}
.flow-pip{height:4px;flex:1;border-radius:999px;background:var(--sf-line-2);transition:background .3s}
.flow-pip.done{background:var(--sf-blue)}
.flow-pip.now{background:var(--sf-navy)}

/* ---------------------------------------------------------------- the wait itself
   🚨 A SHAPE, NOT A SPINNER. A spinner says "wait"; a shape says "something is arriving and it
   looks roughly like this", and it stops the layout jumping when the real content lands. Shown
   the moment the frame paints, so the only thing anybody ever waits for is the content itself. */
.flow-skel{display:block;padding:6px 0}
.flow-skel-bar,.flow-skel-card{display:block;border-radius:8px;
  background:linear-gradient(90deg,var(--sf-line-2) 25%,#f4f7fb 37%,var(--sf-line-2) 63%);
  background-size:400% 100%;animation:flow-shimmer 1.4s ease-in-out infinite}
.flow-skel-bar{height:13px;margin-bottom:12px}
.flow-skel-card{height:104px;border-radius:var(--radius);margin-bottom:14px}
@keyframes flow-shimmer{from{background-position:100% 0}to{background-position:0 0}}

/* ---------------------------------------------------------------- 4. motion off
   Every animated element's resting state here is its FINAL state. Resting at the first frame
   would leave the page blank for anyone who has asked for less movement, which is the opposite
   of a kindness. */
@media (prefers-reduced-motion:reduce){
  .flow-reveal,.flow-reveal.flow-in,.flow-reveal.from-left,.flow-reveal.from-right{
    opacity:1 !important;transform:none !important;transition:none !important}
  .flow-card,.flow-panel,.flow-cta,.flow-ghost,.flow-num,.flow-pip{transition:none !important}
  .flow-card:hover,.flow-panel:hover,.flow-cta:hover{transform:none !important}
  .flow-hero::before{animation:none !important}
  /* The placeholder stays VISIBLE and stops shimmering. Hiding it would replace a moving wait
     with a blank one, which is not what somebody asking for less motion wanted. */
  .flow-skel-bar,.flow-skel-card{animation:none !important;background:var(--sf-line-2)}
}

/* ---- page to page without a white flash (15/09/2026) ----------------------------------------
 * Every click here is a full page load, so the browser used to blank the screen between pages.
 * This asks it (Chrome/Edge 126+, Safari 18.2+) to hold the old page on screen until the new
 * one has drawn, then swap in a fraction of a second. CSS only: no script, nothing for the
 * Content-Security-Policy to allow, and browsers without it simply load the page as before.
 * Kept very short on purpose: this is about the page feeling instant, not about animating. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 90ms; }
}
