/* nxxs-kinetic.css - the site-wide entrance, press and surface layer.
   Reference: wallet.coinbase.com, October 2026. Its grammar is three moves
   on one exponential ease: headings arrive word by word, copy and controls
   rise a short distance, plates rise further and settle from a slight
   shrink. Nothing loops, nothing scrubs, nothing moves twice. Every page on
   the site reads this sheet, so every page shares one rhythm.

   Loaded last in the chain. Owns motion and the press feel of controls only:
   it sets no colour of its own, no spacing and no layout. Removing it leaves
   every page intact and still. Every value is declared once under :root and
   read with var(). Flexbox only, no pseudo-elements carry anything visible,
   no positioning of any kind.

   How the entrance works. The head gate in functions.php writes
   data-k="on" to <html> at the top of the page when motion is allowed, and
   clears it again after a short wait unless nxxs-kinetic.js has reported in
   with data-k="live". So the waiting state below only ever applies while a
   script is present to resolve it. The script writes data attributes only:
   data-k-state (wait, in, skip), data-k-kind (card, words) and data-k-i
   (the element's place in the group that entered with it). */

:root {
  --k-ease:          cubic-bezier(0.16, 1, 0.3, 1);
  --k-t-word:        700ms;
  --k-t-block:       600ms;
  --k-t-card:        800ms;
  --k-t-btn:         320ms;
  --k-t-header:      280ms;
  --k-d-word:        0.4em;
  --k-d-block:       14px;
  --k-d-card:        40px;
  --k-sc-card:       0.96;
  --k-stagger:       60ms;
  --k-stagger-word:  36ms;
  --k-offset:        0ms;
  --k-lift-btn:      -2px;
  --k-sc-press:      0.97;
  --k-x-arrow:       4px;
  --k-op-wait:       0;
  --k-op-in:         1;
  --k-shadow-header: 0 1px 0 rgba(16, 32, 58, 0.06), 0 12px 32px rgba(16, 32, 58, 0.07);
  --k-shadow-none:   0 0 0 rgba(16, 32, 58, 0);
  --k-w-scrollbar:   thin;
}

/* ==========================================================================
   Entrances
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {

  /* ---- Waiting ----------------------------------------------------------
     Elementor widgets carry data-k-state="wait" from the server, so they
     never paint before their entrance. Theme surfaces are listed here and
     wait until the script takes them over; the :not() is what hands them
     over, because once the script has written any state the list stops
     applying and the state rules below take charge. */

  html[data-k] [data-k-state="wait"],
  html[data-k] [data-k-state="wait"] .k-word,
  html[data-k] .section-head > *:not([data-k-state]),
  html[data-k] .prose > *:not([data-k-state]),
  html[data-k] .guard-hero-copy > *:not([data-k-state]),
  html[data-k] .guard-hero-art:not([data-k-state]),
  html[data-k] .stage-foot > *:not([data-k-state]),
  html[data-k] .shop-title:not([data-k-state]),
  html[data-k] .shop-lede:not([data-k-state]),
  html[data-k] .banner-note:not([data-k-state]),
  html[data-k] .shop-jumps:not([data-k-state]),
  html[data-k] .flow-head:not([data-k-state]),
  html[data-k] .doc-head:not([data-k-state]),
  html[data-k] .doc-group:not([data-k-state]),
  html[data-k] .why-pillar:not([data-k-state]),
  html[data-k] .why-fact:not([data-k-state]),
  html[data-k] .why-test-row:not([data-k-state]),
  html[data-k] .footer-proof:not([data-k-state]),
  html[data-k] .footer-brand > *:not([data-k-state]),
  html[data-k] .footer-col:not([data-k-state]),
  html[data-k] .ruo-band:not([data-k-state]),
  html[data-k] .footer-base:not([data-k-state]) {
    opacity: var(--k-op-wait);
  }

  /* A heading whose words carry the entrance stays visible itself. */
  html[data-k] [data-k-state="wait"][data-k-kind="words"] {
    opacity: var(--k-op-in);
  }

  /* Surfaces that own their own entrance are never held back: the film
     hero, the catalogue reel and the specimen stage. A widget inside them
     may still carry the server attribute, so it is released here. */
  html[data-k] .nxxs-hero-slot [data-k-state="wait"],
  html[data-k] .home-hero [data-k-state="wait"],
  html[data-k] .hero-fill [data-k-state="wait"],
  html[data-k] .shop [data-k-state="wait"],
  html[data-k] .cinema [data-k-state="wait"],
  html[data-k] [data-k-state="skip"] {
    opacity: var(--k-op-in);
  }

  /* ---- Arriving ---------------------------------------------------------
     backwards fill, never both: the element holds its first frame through
     its delay, plays, and then returns to its own styles so a hover lift or
     a press is free to move it again. */

  [data-k-state="in"] {
    animation: k-rise var(--k-t-block) var(--k-ease) var(--k-offset) backwards;
  }

  [data-k-state="in"][data-k-kind="card"] {
    animation-name: k-rise-plate;
    animation-duration: var(--k-t-card);
  }

  [data-k-state="in"][data-k-kind="words"] {
    animation: none;
  }

  [data-k-state="in"][data-k-kind="words"] .k-word {
    animation: k-rise-word var(--k-t-word) var(--k-ease) var(--k-offset) backwards;
  }

  /* ---- Order ------------------------------------------------------------
     Elements that enter the viewport together arrive in reading order,
     one step apart. The step is carried on an inherited property so a
     heading's words take their place in the sequence after it. */

  [data-k-i="1"]  { --k-offset: calc(var(--k-stagger) * 1); }
  [data-k-i="2"]  { --k-offset: calc(var(--k-stagger) * 2); }
  [data-k-i="3"]  { --k-offset: calc(var(--k-stagger) * 3); }
  [data-k-i="4"]  { --k-offset: calc(var(--k-stagger) * 4); }
  [data-k-i="5"]  { --k-offset: calc(var(--k-stagger) * 5); }
  [data-k-i="6"]  { --k-offset: calc(var(--k-stagger) * 6); }
  [data-k-i="7"]  { --k-offset: calc(var(--k-stagger) * 7); }
  [data-k-i="8"]  { --k-offset: calc(var(--k-stagger) * 8); }
  [data-k-i="9"]  { --k-offset: calc(var(--k-stagger) * 9); }
  [data-k-i="10"] { --k-offset: calc(var(--k-stagger) * 10); }
  [data-k-i="11"] { --k-offset: calc(var(--k-stagger) * 11); }
  [data-k-i="12"] { --k-offset: calc(var(--k-stagger) * 12); }

  .k-word[data-k-i="1"]  { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 1); }
  .k-word[data-k-i="2"]  { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 2); }
  .k-word[data-k-i="3"]  { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 3); }
  .k-word[data-k-i="4"]  { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 4); }
  .k-word[data-k-i="5"]  { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 5); }
  .k-word[data-k-i="6"]  { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 6); }
  .k-word[data-k-i="7"]  { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 7); }
  .k-word[data-k-i="8"]  { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 8); }
  .k-word[data-k-i="9"]  { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 9); }
  .k-word[data-k-i="10"] { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 10); }
  .k-word[data-k-i="11"] { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 11); }
  .k-word[data-k-i="12"] { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 12); }
  .k-word[data-k-i="13"] { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 13); }
  .k-word[data-k-i="14"] { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 14); }
  .k-word[data-k-i="15"] { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 15); }
  .k-word[data-k-i="16"] { animation-delay: calc(var(--k-offset) + var(--k-stagger-word) * 16); }
}

/* A word is a box so it can rise without disturbing the line. It inherits
   everything, so a split heading reads exactly as an unsplit one. */
.k-word { display: inline-block; }

@keyframes k-rise {
  from { opacity: var(--k-op-wait); transform: translateY(var(--k-d-block)); }
  to   { opacity: var(--k-op-in);   transform: none; }
}

@keyframes k-rise-plate {
  from { opacity: var(--k-op-wait); transform: translateY(var(--k-d-card)) scale(var(--k-sc-card)); }
  to   { opacity: var(--k-op-in);   transform: none; }
}

@keyframes k-rise-word {
  from { opacity: var(--k-op-wait); transform: translateY(var(--k-d-word)); }
  to   { opacity: var(--k-op-in);   transform: none; }
}

/* ==========================================================================
   Controls: one press, one lift, every button on the site
   ========================================================================== */

.button-primary,
.button-secondary,
.button-quiet,
.elementor-button,
.footer-cta,
.hero-cta,
.hero-link,
.why-cta,
.guard-act,
.shop-buy,
.button-buy,
.flow-buy,
.size-add,
.shop-jump,
.footer-top-link,
.stage-woo .button,
.stage-woo button.button,
.stage-woo a.button,
.wc-block-components-button,
.wc-block-cart__submit-button,
.wc-block-components-checkout-place-order-button {
  transition:
    transform var(--k-t-btn) var(--k-ease),
    box-shadow var(--k-t-btn) var(--k-ease),
    background-color var(--t-fast) var(--ease),
    border-color var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .button-primary:hover,
  .button-secondary:hover,
  .elementor-button:hover,
  .footer-cta:hover,
  .hero-cta:hover,
  .hero-link:hover,
  .why-cta:hover,
  .guard-act:hover,
  .shop-buy:hover,
  .flow-buy:hover,
  .shop-jump:hover,
  .stage-woo .button:hover,
  .stage-woo button.button:hover,
  .stage-woo a.button:hover,
  .wc-block-components-button:hover,
  .wc-block-cart__submit-button:hover,
  .wc-block-components-checkout-place-order-button:hover {
    transform: translateY(var(--k-lift-btn));
    box-shadow: var(--shadow-2);
  }

  /* The arrow on a link that goes somewhere leans the way it is going. */
  .footer-cta-arrow,
  .guard-arrow,
  .buy-arrow {
    transition: transform var(--k-t-btn) var(--k-ease);
  }
  .footer-cta:hover .footer-cta-arrow {
    transform: translateX(var(--k-x-arrow));
  }
}

.button-primary:active,
.button-secondary:active,
.button-quiet:active,
.elementor-button:active,
.footer-cta:active,
.hero-cta:active,
.hero-link:active,
.why-cta:active,
.guard-act:active,
.shop-buy:active,
.button-buy:active,
.flow-buy:active,
.size-add:active,
.shop-jump:active,
.tool-button:active,
.stage-woo .button:active,
.stage-woo button.button:active,
.stage-woo a.button:active,
.wc-block-components-button:active,
.wc-block-cart__submit-button:active,
.wc-block-components-checkout-place-order-button:active {
  transform: scale(var(--k-sc-press));
  transition-duration: var(--t-press);
  box-shadow: var(--shadow-1);
}

/* ==========================================================================
   Surfaces
   ========================================================================== */

/* The header earns its shadow only once something is moving under it. */
.site-header {
  transition: box-shadow var(--k-t-header) var(--k-ease);
  box-shadow: var(--k-shadow-none);
}
.site-header[data-k-scrolled="true"] {
  box-shadow: var(--k-shadow-header);
}

/* Sections on the Elementor pages are separated by one full-width hairline,
   the way the reference separates its bands. A section that already draws
   its own top rule is left alone so no line ever doubles. */
.nxxs-elementor-home > .e-con + .e-con:not(:has(.home-facts)),
.nxxs-why-page > .e-con + .e-con,
[data-elementor-type="wp-page"] > .e-parent + .e-parent {
  border-top: var(--bw-1) solid var(--c-line);
}

/* The browser surfaces the design did not draw still carry its palette. */
html {
  scrollbar-width: var(--k-w-scrollbar);
  scrollbar-color: var(--c-line-strong) var(--c-bg);
  caret-color: var(--c-action);
}

@media (prefers-reduced-motion: reduce) {
  .button-primary,
  .button-secondary,
  .elementor-button,
  .footer-cta,
  .hero-cta,
  .why-cta,
  .shop-buy,
  .flow-buy,
  .site-header {
    transition: none;
  }
  .button-primary:hover,
  .button-secondary:hover,
  .elementor-button:hover,
  .footer-cta:hover,
  .hero-cta:hover,
  .why-cta:hover,
  .shop-buy:hover,
  .flow-buy:hover {
    transform: none;
  }
}
