/* ==========================================================================
   Gizie for Business — motion layer

   Loaded AFTER business-v2.css. It never changes a resting value: every rule
   here is either an initial state that JS clears, a transition, or a hover /
   pressed state. With JS off (no .js on <html>) nothing below applies except
   the hover transitions, so the static Figma layout is untouched.

   Budget: transform + opacity + clip-path only. No layout properties are
   animated anywhere on this page.
   ========================================================================== */

:root {
  /* easings */
  --e-out:    cubic-bezier(0.22, 0.61, 0.36, 1);   /* general entrances     */
  --e-soft:   cubic-bezier(0.16, 1, 0.30, 1);      /* long, expensive moves */
  --e-spring: cubic-bezier(0.34, 1.20, 0.48, 1);   /* settle with overshoot */
  --e-press:  cubic-bezier(0.4, 0, 0.2, 1);        /* tactile feedback      */

  --t-fast: 180ms;
  --t-mid:  520ms;
  --t-slow: 820ms;
}

/* ------------------------------------------------------------- reveals --- */
/* Initial states only exist when JS is running, so the page is fully visible
   for crawlers and no-JS visitors. */

.js [data-r],
.js [data-load],
.js [data-load-group] > * {
  opacity: 0;
  transition:
    opacity var(--t-mid) var(--e-out),
    transform var(--t-slow) var(--e-soft);
}
/* the hero's own copy always rises — it is on a load timeline, not a scroll */
.js [data-load],
.js [data-load-group] > * { transform: translate3d(0, 18px, 0); }
.js [data-load="logo"] { transform: translate3d(-10px, 0, 0); }
.js [data-load].is-in,
.js [data-load-group] > .is-in { opacity: 1; transform: none; }
.js [data-r="up"]     { transform: translate3d(0, 22px, 0); }
.js [data-r="up-sm"]  { transform: translate3d(0, 12px, 0); }
.js [data-r="rise"]   { transform: translate3d(0, 30px, 0) scale(0.985); }
.js [data-r="left"]   { transform: translate3d(-26px, 0, 0); }
.js [data-r="right"]  { transform: translate3d(26px, 0, 0); }
.js [data-r="pop"]    { transform: scale(0.92); }
.js [data-r="fade"]   { transform: none; }

.js [data-r].is-in {
  opacity: 1;
  transform: none;
}
/* released once the entrance is over. It must NOT null `transition` — these
   elements own hover transitions too. */
.js [data-r].is-settled { will-change: auto; }

/* Elements the rAF loop owns (float / parallax / pointer). JS writes their
   transform directly, so they must not carry a CSS transition. */
.js [data-live] {
  opacity: 0;
  transition: none;
  will-change: transform, opacity;
}
.js [data-live].is-rest { will-change: auto; }

/* ------------------------------------------------------- hero load seq --- */
/* The hero waits for its own key art to decode; until then it is simply
   invisible rather than half-drawn. No spinner, no artificial delay. */
.js .hero__media-inner { opacity: 1; }

/* --------------------------------------------------------------- nav ----- */

.logo,
.logo__mark,
.logo__word,
.logo__tag {
  transition:
    transform 420ms var(--e-soft),
    opacity 260ms var(--e-out);
}
@media (hover: hover) {
  .logo:hover .logo__mark { transform: scale(1.06) rotate(-2deg); }
  .logo:hover .logo__word { transform: translateX(1px); }
  .logo:hover .logo__tag  { opacity: 0.72; }
}
.logo:active .logo__mark { transform: scale(0.98); transition-duration: 120ms; }

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

.btn,
.store,
.js .btn[data-r],
.js .store[data-r] {
  transition:
    transform 300ms var(--e-out),
    box-shadow 320ms var(--e-out),
    background-color 220ms var(--e-press),
    border-color 220ms var(--e-press),
    color 220ms var(--e-press),
    opacity 420ms var(--e-out);
}

@media (hover: hover) {
  .btn--primary:hover {
    transform: translate3d(0, -1.5px, 0) scale(1.02);
    box-shadow: 0 10px 24px -8px rgba(255, 116, 70, 0.55);
  }
  .btn--ghost:hover {
    transform: translate3d(0, -1.5px, 0) scale(1.02);
    border-color: var(--ink);
    box-shadow: 0 8px 20px -10px rgba(26, 23, 20, 0.28);
  }
  .btn--white:hover {
    transform: translate3d(0, -1.5px, 0) scale(1.02);
    box-shadow: 0 10px 24px -10px rgba(26, 23, 20, 0.3);
  }
  .store:hover {
    transform: translate3d(0, -2px, 0) scale(1.02);
    box-shadow: 0 14px 28px -12px rgba(26, 23, 20, 0.45);
  }
  /* the text-only hero link gets an underline that grows from the left */
  .btn--text { position: relative; }
  .btn--text::after {
    content: "";
    position: absolute;
    left: 14px;
    right: 14px;
    bottom: 18px;
    height: 1.5px;
    background: currentColor;
    border-radius: 2px;
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 380ms var(--e-soft);
  }
  .btn--text:hover::after { transform: scaleX(1); }
}

.btn:active,
.store:active {
  transform: scale(0.97);
  transition-duration: 90ms;
}

/* the scan icon nudges on hover — tiny hint that the button opens a scanner */
.btn__icon { transition: transform 320ms var(--e-spring); }
@media (hover: hover) {
  .btn--primary:hover .btn__icon { transform: scale(1.1) rotate(3deg); }
}

/* the gradient word arrives a beat after the line it sits in */
.js .hero__title .grad-text {
  display: inline-block;
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition:
    opacity 480ms var(--e-out),
    transform 760ms var(--e-soft);
}
.js .hero__title .grad-text.is-in { opacity: 1; transform: none; }

/* the mark inside "Why (mark) Gizie ?" pops with the heading */
.js .why__title.is-in .logo__mark { animation: mark-pop 640ms var(--e-spring) 180ms both; }
@keyframes mark-pop {
  0%   { transform: scale(0.5) rotate(-10deg); }
  65%  { transform: scale(1.07) rotate(3deg); }
  100% { transform: scale(1) rotate(0); }
}

/* a lazily fetched illustration fades in rather than snapping into a card */
.js .card__art img,
.js .band-cta__art img {
  transition:
    transform 700ms var(--e-soft),
    opacity 420ms var(--e-out);
}
.js img[loading="lazy"]:not(.is-loaded) { opacity: 0; }
.js img[loading="lazy"].is-loaded { opacity: 1; }

/* ------------------------------------------------------------- stats ---- */
/* Digits are tabular while counting so the labels underneath never jitter. */
.stat__value { font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------- bento cards -- */

.card,
.card--soft,
.js .card[data-r],
.js .card--soft[data-r] {
  transition:
    transform 560ms var(--e-soft),
    box-shadow 420ms var(--e-out),
    opacity 520ms var(--e-out);
}
.card__art img { transition: transform 700ms var(--e-soft); }

@media (hover: hover) and (min-width: 1000px) {
  .card:hover,
  .card--soft:hover {
    transform: translate3d(0, -4px, 0);
    box-shadow: 0 18px 40px -22px rgba(26, 23, 20, 0.3);
  }
  .card:hover .card__art img,
  .card--soft:hover .card__art img { transform: scale(1.018); }
}

/* --------------------------------------------------------- chart wipe --- */
/* A card-coloured overlay retreating left→right, so the plotted line appears
   to draw itself. Invisible at rest — the design is untouched. */
.chart-wipe {
  position: absolute;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(
    to right,
    rgba(255, 255, 255, 0) 0,
    #fff 22px,
    #fff 100%
  );
  /* default is fully retracted, so with JS off the chart is simply visible */
  clip-path: inset(0 0 0 100%);
  transition: clip-path 1.25s var(--e-soft);
}
.js .chart-wipe { clip-path: inset(0 0 0 0); }
.js .chart-wipe.is-drawn { clip-path: inset(0 0 0 100%); }

.js .hero__chart { overflow: hidden; }
.hero__chart img { width: 100%; height: 100%; border-radius: inherit; }
.hero__chart .chart-wipe { left: 54px; top: 20px; right: -2px; bottom: 30px; }
.card--insights .chart-wipe { left: 48px; top: 16px; right: -2px; bottom: 34px; }

/* -------------------------------------------------------- fill down ----- */
/* The calendar mockups populate top-to-bottom, the way a day fills up. */
.js .fill-down { clip-path: inset(0 0 100% 0); }
.js .fill-down.is-filled { clip-path: inset(0 0 0 0); }

/* the hero calendar is owned by the rAF loop, so it may only ever transition
   clip-path — a CSS transition on transform would fight the loop's writes */
.js .hero__calendar.fill-down { transition: clip-path 1.1s var(--e-soft); }

.js .card__art img.fill-down {
  transition:
    clip-path 1.1s var(--e-soft),
    transform 700ms var(--e-soft),
    opacity 420ms var(--e-out);
}

/* ------------------------------------------------------------ panels ---- */
/* Real accordions. Height animates through a 0fr→1fr grid track — far cheaper
   than animating `height`, and it needs no measured pixel values.
   Both resting states reproduce the Figma geometry exactly:
     listing  open 413px / closed 101px      faq  open 158px / closed 92px   */

.js .panel {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0;
  transition:
    padding 460ms var(--e-soft),
    box-shadow 360ms var(--e-out),
    opacity var(--t-mid) var(--e-out),
    transform var(--t-slow) var(--e-soft);
}

.js .listing .panel[data-open="true"]  { padding: 36px 66px 36px 24px; }
.js .listing .panel[data-open="false"] { padding: 24px 66px 24px 24px; }
.js .faq .panel[data-open="true"]      { padding: 36px 66px 36px 24px; }
.js .faq .panel[data-open="false"]     { padding: 29px 66px 29px 24px; }

/* the question is the button; the button adds no box of its own */
.js .panel__btn {
  all: unset;
  display: block;
  width: 100%;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.js .panel__btn:focus-visible {
  outline: 2.5px solid var(--orange);
  outline-offset: 6px;
  border-radius: 6px;
}

/* listing headings keep the two Figma sizes and travel between them */
.js .listing .panel .panel__q {
  transition:
    font-size 420ms var(--e-soft),
    letter-spacing 420ms var(--e-soft);
}
.js .listing .panel[data-open="true"]  .panel__q { font-size: 24px; letter-spacing: -0.96px; }
.js .listing .panel[data-open="false"] .panel__q { font-size: 20px; letter-spacing: -0.8px; }

/* faq headings are one size in both states — 34px box, centred */
.js .faq .panel h3 {
  height: 34px;
  display: flex;
  align-items: center;
  line-height: normal;
}

.js .panel__drawer {
  display: grid;
  grid-template-rows: 1fr;
  min-height: 0;
  transition: grid-template-rows 460ms var(--e-soft);
}
.js .panel__drawer > .panel__drawer-in {
  min-height: 0;
  overflow: hidden;
  transition: opacity 320ms var(--e-out) 90ms;
}
.js .panel[data-open="false"] .panel__drawer { grid-template-rows: 0fr; }
.js .panel[data-open="false"] .panel__drawer > .panel__drawer-in {
  opacity: 0;
  transition-delay: 0ms;
}
/* the gaps the design puts between title and body live inside the drawer, so
   they collapse with it instead of jumping */
.js .listing .panel__drawer-in {
  display: flex;
  flex-direction: column;
  gap: 37px;
}
.js .listing .panel__drawer-in > :first-child { margin-top: 37px; }
.js .faq .panel__drawer-in > :first-child { margin-top: 16px; }

/* × and + are both absolutely placed, and cross-fade with a quarter turn */
.js .panel__toggle,
.js .panel__plus {
  position: absolute;
  transition: transform 460ms var(--e-spring), opacity 300ms var(--e-out);
}
.js .panel__toggle { right: 26px; width: 40px; height: 36px; }
.js .panel__plus   { right: 19px; width: 44px; height: 44px; }
.js .listing .panel[data-open="true"]  .panel__toggle { top: 37.4px; }
.js .faq .panel[data-open="true"]      .panel__toggle { top: 32.2px; }
.js .panel[data-open="false"] .panel__toggle { top: 32px; }
.js .panel__plus { top: 50%; margin-top: -22px; }

.js .panel[data-open="false"] .panel__toggle { transform: rotate(-90deg) scale(0.8); opacity: 0; }
.js .panel[data-open="true"]  .panel__plus   { transform: rotate(135deg) scale(0.8); opacity: 0; }

@media (hover: hover) {
  .js .panel[data-open="false"]:hover {
    box-shadow: 0 12px 30px -20px rgba(26, 23, 20, 0.35);
  }
  .js .panel[data-open="false"]:hover .panel__plus { transform: rotate(90deg); }
}

/* the faq band may grow if a longer answer is opened — it never shrinks */
.js .faq { height: auto; min-height: 732px; }

/* checklist rows arrive one after another once the panel opens */
.js .check {
  opacity: 0;
  transform: translate3d(0, 10px, 0);
  transition:
    opacity 380ms var(--e-out),
    transform 480ms var(--e-soft);
}
.js .check.is-in { opacity: 1; transform: none; }
.check img { transition: transform 420ms var(--e-spring); }
.js .check.is-in img { animation: tick-pop 520ms var(--e-spring) both; }

@keyframes tick-pop {
  0%   { transform: scale(0.4); opacity: 0; }
  60%  { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* the progress rail fills to its designed 76.7% when the panel opens */
.progress span { transform-origin: left center; }
.js .progress span { transform: scaleX(0); }
.js .progress.is-filling span {
  transform: scaleX(1);
  transition: transform 1.1s var(--e-soft) 120ms;
}

/* ------------------------------------------------- roles: drawn diagram -- */

.roles__lines { overflow: visible; }

.js .rl-line {
  stroke-dasharray: 1 1;
  stroke-dashoffset: -1;
}
.js .roles.is-drawing .rl-line {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1000ms var(--e-out) var(--d, 0ms);
}
.js .roles.is-drawing .rl-line--dash {
  transition-duration: 880ms;
}

.js .rl-dot {
  opacity: 0;
  transform: scale(0.2);
  transform-box: fill-box;
  transform-origin: center;
}
.js .roles.is-drawing .rl-dot {
  opacity: 1;
  transform: scale(1);
  transition:
    opacity 260ms var(--e-out) var(--d, 0ms),
    transform 460ms var(--e-spring) var(--d, 0ms);
}

/* role clusters: identity first, then its permission pills */
.js .role { opacity: 0; }
.js .role.is-in { opacity: 1; transition: opacity 420ms var(--e-out); }
.js .role__id {
  opacity: 0;
  transform: translate3d(0, 10px, 0) scale(0.94);
  transition:
    opacity 420ms var(--e-out),
    transform 620ms var(--e-spring);
}
.js .role.is-in .role__id { opacity: 1; transform: none; }
.js .role .pill {
  opacity: 0;
  transform: translate3d(0, 6px, 0);
  transition:
    opacity 340ms var(--e-out) var(--d, 0ms),
    transform 420ms var(--e-soft) var(--d, 0ms);
}
.js .role.is-in .pill { opacity: 1; transform: none; }

/* --------------------------------------------- steps: drawn arrow flow --- */

.js .sa-line {
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
}
.js .steps.is-drawing .sa-line {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1100ms var(--e-out) 100ms;
}
.js .sa-head {
  opacity: 0;
  transform: scale(0.5);
  transform-box: fill-box;
  transform-origin: center;
}
.js .steps.is-drawing .sa-head {
  opacity: 1;
  transform: scale(1);
  transition:
    opacity 220ms var(--e-out) var(--d, 0ms),
    transform 420ms var(--e-spring) var(--d, 0ms);
}

/* the icon in each step card gives a small acknowledgement as the card lands */
.js .step.is-in .step__icon { animation: icon-in 620ms var(--e-spring) 120ms both; }
@keyframes icon-in {
  0%   { transform: scale(0.6) rotate(-8deg); opacity: 0; }
  70%  { transform: scale(1.06) rotate(2deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}
.js .step[data-r] {
  transition:
    transform 560ms var(--e-soft),
    opacity 520ms var(--e-out);
}
@media (hover: hover) and (min-width: 1000px) {
  .step:hover { transform: translate3d(0, -3px, 0); }
}

/* -------------------------------------------------------------- links --- */

.footer__col a {
  transition: color 220ms var(--e-press), transform 320ms var(--e-soft);
  display: inline-block;
}
@media (hover: hover) {
  .footer__col a:hover { transform: translateX(3px); }
}

/* --------------------------------------------------------------- QR ----- */
.cta__qr img { transition: transform 600ms var(--e-soft); }
@media (hover: hover) {
  .cta__qr:hover img { transform: scale(1.04); }
}

/* ======================================================= reduced motion == */
/* Everything still works; it simply arrives instead of travelling. */

@media (prefers-reduced-motion: reduce) {
  .js [data-r],
  .js [data-load],
  .js [data-load-group] > *,
  .js [data-live],
  .js .hero__title .grad-text,
  .js img[loading="lazy"],
  .js .check,
  .js .role,
  .js .role__id,
  .js .role .pill {
    opacity: 1 !important;
    transform: none !important;
    transition: opacity 1ms linear !important;
    animation: none !important;
  }
  .js .rl-line,
  .js .sa-line {
    stroke-dashoffset: 0 !important;
    transition: none !important;
  }
  .js .rl-dot,
  .js .sa-head {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .js .chart-wipe { display: none; }
  .js .fill-down { clip-path: none !important; transition: none !important; }
  .js .progress span { transform: scaleX(1) !important; transition: none !important; }
  .js .check.is-in img,
  .js .why__title.is-in .logo__mark,
  .js .step.is-in .step__icon { animation: none !important; }

  /* keep the accordions usable, just quick */
  .panel__drawer { transition-duration: 1ms; }
  .panel__drawer > .panel__drawer-in { transition-duration: 1ms; }
  .panel__toggle,
  .panel__plus { transition-duration: 1ms; }

  /* interaction feedback stays, movement goes */
  .btn, .store, .card, .card--soft, .step, .footer__col a, .logo__mark {
    transition-duration: 120ms !important;
  }
  .btn:hover, .store:hover, .card:hover, .card--soft:hover,
  .step:hover, .footer__col a:hover, .logo:hover .logo__mark {
    transform: none !important;
  }
  .btn:active, .store:active { transform: scale(0.98) !important; }
  .btn--text::after { transition: none !important; }
}

/* ============================================================== mobile == */

@media (max-width: 999.98px) {
  /* shorter travel, so nothing drifts far on a small screen */
  .js [data-r="up"]    { transform: translate3d(0, 14px, 0); }
  .js [data-r="rise"]  { transform: translate3d(0, 18px, 0) scale(0.99); }
  .js [data-r="left"]  { transform: translate3d(-14px, 0, 0); }
  .js [data-r="right"] { transform: translate3d(14px, 0, 0); }
  .js [data-r] {
    transition-duration: 420ms, 560ms;
  }
  .panel__btn { -webkit-tap-highlight-color: transparent; }

  /* the accordions need a tighter box and a wrapping question on a phone */
  .js .listing .panel[data-open="true"],
  .js .faq .panel[data-open="true"]   { padding: 26px 56px 26px 22px; }
  .js .listing .panel[data-open="false"],
  .js .faq .panel[data-open="false"]  { padding: 22px 56px 22px 22px; }
  .js .faq .panel h3 { height: auto; min-height: 34px; }
  .js .listing .panel[data-open="true"]  .panel__q { font-size: 20px; letter-spacing: -0.6px; }
  .js .listing .panel[data-open="false"] .panel__q { font-size: 18px; letter-spacing: -0.4px; }
  .js .panel__toggle { right: 16px; width: 32px; height: 29px; top: 24px; }
  .js .panel__plus   { right: 14px; width: 36px; height: 36px; margin-top: -18px; }
  .js .listing .panel[data-open="true"] .panel__toggle,
  .js .faq .panel[data-open="true"] .panel__toggle { top: 26px; }
  .js .listing .panel__drawer-in { gap: 22px; }
  .js .listing .panel__drawer-in > :first-child { margin-top: 22px; }
  .js .faq .panel__drawer-in > :first-child { margin-top: 12px; }
}
