/* ==========================================================================
   StarKey — homepage styles
   Built from design-system/style-guide.html. Token names match that file
   one to one, so a change there maps directly here.

   Handoff note for Supra engineering: this is plain CSS with no build step
   and no dependencies. Every colour, radius and type setting is a custom
   property on :root, so porting to styled-components, CSS modules or
   Tailwind theme values is a copy of the :root block.
   ========================================================================== */

:root{
  /* Brand */
  --sk-gold:#FEBF4E;
  --sk-pink:#FC4CD2;
  --sk-signature:linear-gradient(90deg,#FEBF4E 0%,#FC4CD2 72%);
  --sk-violet:#7424F6;
  /* Lilac carries the everyday accent work: eyebrows, icons, small labels.
     Sampled from the live starkey.app, so it is already the brand's own.
     The gold-to-pink signature was being used on eyebrows, icons, step
     numbers, FAQ text, buttons, headlines and all the artwork at once, which
     stopped it reading as a signature at all. It is now reserved for the
     headline accent, the scroll resolve, primary buttons and the logo. */
  --sk-lilac:#DA8FFF;

  /* Surfaces */
  --sk-void:#0B0A12;
  --sk-panel:#14121F;
  --sk-panel-2:#1C1929;
  --sk-line:#241F35;
  --sk-line-soft:rgba(255,255,255,.07);

  /* Text ramp */
  --sk-ink-1:#FBF8FF;
  --sk-ink-2:rgba(251,248,255,.72);
  --sk-ink-3:rgba(251,248,255,.48);

  /* State */
  --sk-ok:#3DD68C;

  /* Geometry */
  --sk-r-pill:999px;
  --sk-r-panel:20px;
  --sk-r-tile:16px;
  --sk-r-field:12px;

  /* Type — one family, axes do the differentiating */
  --sk-type:'Roboto Flex',system-ui,-apple-system,sans-serif;
  --sk-label-wdth:125;
  --sk-label-wght:700;
  --sk-h1-wdth:151;
  --sk-h1-wght:1000;
  /* h2 sits just inside the h1 so there is still a hierarchy, but it is
     the same species of type. Sentence-case h2s made the lower half of
     the page read as a different, quieter website. */
  --sk-h2-wdth:140;
  --sk-h2-wght:900;

  /* Layout */
  --sk-wrap:1180px;
  --sk-gutter:24px;
  --sk-section:112px;
}

*{box-sizing:border-box}

html{
  font-family:var(--sk-type);
  scroll-behavior:smooth;
  -webkit-text-size-adjust:100%;
  /* The header is sticky, so an anchor jump would otherwise park the
     section's first line UNDER it -- measured at a 73px header against an
     eyebrow landing at 67.7px. scroll-padding on the scroll container is the
     fix that works for every anchor at once, including a pasted #agents URL,
     rather than a scroll-margin on each target. */
  scroll-padding-top:88px;
}

body{
  margin:0;
  background:var(--sk-void);
  color:var(--sk-ink-2);
  font-size:16px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

/* Atmosphere. Violet and pink glow, never structural.
   Fixed so it does not scroll, pointer-events none so it never blocks. */
body::before{
  content:'';
  position:fixed;
  inset:0;
  z-index:0;
  pointer-events:none;
  background:
    radial-gradient(60rem 40rem at 12% -6%, rgba(116,36,246,.20), transparent 60%),
    radial-gradient(50rem 36rem at 92% 12%, rgba(252,76,210,.13), transparent 60%),
    radial-gradient(44rem 30rem at 50% 104%, rgba(116,36,246,.12), transparent 60%);
}

img,svg{max-width:100%;display:block}
a{color:inherit}

.wrap{
  position:relative;
  z-index:1;
  max-width:var(--sk-wrap);
  margin:0 auto;
  padding:0 var(--sk-gutter);
}

.visually-hidden{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

/* Skip link — keyboard users land here first */
.skip{
  position:absolute;left:var(--sk-gutter);top:-100px;z-index:100;
  background:var(--sk-ink-1);color:var(--sk-void);
  padding:12px 20px;border-radius:var(--sk-r-pill);font-weight:700;
  transition:top .16s;
}
.skip:focus{top:12px}

/* ==========================================================================
   Type
   ========================================================================== */

.h1{
  font-variation-settings:'wdth' var(--sk-h1-wdth),'wght' var(--sk-h1-wght),'opsz' 36;
  font-weight:900;
  text-transform:uppercase;
  letter-spacing:-.005em;
  line-height:.94;
  font-size:clamp(34px,6vw,72px);
  margin:0;
  color:var(--sk-ink-1);
}

.hl{
  background:var(--sk-signature);
  -webkit-background-clip:text;
  background-clip:text;
  color:transparent;
}

h2{
  font-variation-settings:'wdth' var(--sk-h2-wdth),'wght' var(--sk-h2-wght),'opsz' 32;
  font-weight:900;
  text-transform:uppercase;
  letter-spacing:-.005em;
  line-height:.98;
  font-size:clamp(29px,4.4vw,54px);
  margin:0;
  color:var(--sk-ink-1);
}

h3{
  font-weight:600;
  font-size:20px;
  line-height:1.3;
  letter-spacing:-.01em;
  margin:0 0 8px;
  color:var(--sk-ink-1);
}

.eyebrow{
  font-variation-settings:'wdth' var(--sk-label-wdth),'wght' var(--sk-label-wght);
  font-size:11px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--sk-lilac);
  margin:0 0 16px;
}

.lead{
  font-size:clamp(17px,1.6vw,19px);
  line-height:1.55;
  color:var(--sk-ink-2);
  margin:18px 0 0;
  max-width:60ch;
}

.blurb{
  font-size:17px;
  color:var(--sk-ink-2);
  margin:16px 0 0;
  max-width:62ch;
}

.fineprint{
  font-size:13px;
  color:var(--sk-ink-3);
  margin:18px 0 0;
}

/* ==========================================================================
   Buttons

   background-origin:border-box is load-bearing. .btn carries a 1px
   transparent border so every variant matches height, but the default
   padding-box origin makes a gradient repeat into that ring, leaving a
   pink sliver on the left edge and a gold one on the right. It must be
   declared AFTER the background shorthand, which resets it.
   ========================================================================== */

.btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:9px;
  font-family:var(--sk-type);
  font-weight:600;
  font-size:15px;
  border-radius:var(--sk-r-pill);
  padding:15px 28px;
  border:1px solid transparent;
  background-origin:border-box;
  cursor:pointer;
  text-decoration:none;
  line-height:1;
  white-space:nowrap;
  transition:transform .12s cubic-bezier(.2,.8,.3,1),box-shadow .18s,background .18s,color .18s,border-color .18s;
}

.btn-primary{
  background:var(--sk-signature);
  background-origin:border-box;
  color:#14060F;
  font-weight:700;
  box-shadow:0 12px 34px -14px rgba(252,76,210,.85);
}
.btn-primary:hover{transform:translateY(-2px);box-shadow:0 20px 44px -14px rgba(252,76,210,.95)}
.btn-primary:active{transform:translateY(0)}

.btn-ghost{background:transparent;border-color:var(--sk-line);color:var(--sk-ink-1)}
.btn-ghost:hover{border-color:var(--sk-pink);background:rgba(252,76,210,.07)}

.btn-sm{font-size:13px;padding:11px 20px}

.btn:focus-visible,
a:focus-visible,
button:focus-visible,
summary:focus-visible{
  outline:2px solid var(--sk-pink);
  outline-offset:3px;
}

.cta-row{display:flex;gap:12px;flex-wrap:wrap;align-items:center;margin-top:28px}

/* A download button that repeats down the page, with context under it */
.cta-block{margin-top:40px;display:flex;gap:14px;align-items:center;flex-wrap:wrap}
.cta-block .note{font-size:13px;color:var(--sk-ink-3)}

/* ==========================================================================
   Pills
   ========================================================================== */

.pill{
  display:inline-flex;align-items:center;gap:7px;
  font-variation-settings:'wdth' var(--sk-label-wdth),'wght' var(--sk-label-wght);
  font-size:11px;letter-spacing:.09em;text-transform:uppercase;
  border:1px solid var(--sk-line);border-radius:var(--sk-r-pill);
  padding:7px 14px;color:var(--sk-ink-2);
}
.pill-live{border-color:rgba(61,214,140,.4);color:var(--sk-ok);background:rgba(61,214,140,.07)}
/* A FILLED status badge, not an outlined one.

   The default .pill is a 1px border in --sk-line, which measures about
   1.3:1 against these backgrounds -- the same token that turned out to be
   invisible on the nav separator. On a pill the effect is worse than faint:
   you read the words with no shape around them, so "Coming soon" looks like
   an indented stray line rather than a badge.

   Solid violet rather than the brand pink: pink is what the buttons are
   made of, and a status marker should not read as something to click. */
.pill-soon{
  border-color:transparent;
  background:var(--sk-violet);
  color:#fff;
}
.dot{
  width:6px;height:6px;border-radius:50%;background:var(--sk-ok);
  box-shadow:0 0 0 0 rgba(61,214,140,.7);
  animation:pulse 2s infinite;
}
@keyframes pulse{70%{box-shadow:0 0 0 7px rgba(61,214,140,0)}100%{box-shadow:0 0 0 0 rgba(61,214,140,0)}}

/* ==========================================================================
   Banner — Phantom / Sui migration. Dismissible, removed after 24 Sep.
   ========================================================================== */

.banner{
  position:relative;z-index:3;
  background:linear-gradient(90deg,rgba(254,191,78,.12),rgba(252,76,210,.12));
  border-bottom:1px solid var(--sk-line);
  font-size:14px;
}
/* NOT flex-wrap:wrap. The close button carries margin-left:auto, so once the
   paragraph wrapped to its own line the button dropped to a second row and
   the auto margin stranded it in empty space -- the same failure the mobile
   nav toggle had. nowrap keeps the two in one row and lets the paragraph
   itself do the wrapping, which is what should have been wrapping all along. */
.banner-inner{
  max-width:var(--sk-wrap);margin:0 auto;padding:12px var(--sk-gutter);
  display:flex;align-items:flex-start;gap:14px;flex-wrap:nowrap;
}
.banner p{margin:0;color:var(--sk-ink-2)}
.banner a{color:var(--sk-ink-1);font-weight:600;text-decoration:underline;text-underline-offset:3px}
.banner-close{
  margin-left:auto;background:none;border:0;cursor:pointer;
  color:var(--sk-ink-3);font-size:20px;line-height:1;padding:4px 8px;border-radius:8px;
  /* Never let the button be the thing that shrinks: it is one glyph, and a
     squeezed one is unclickable. The paragraph absorbs the width instead. */
  flex:0 0 auto;
  /* Nudged up and out so the glyph's optical centre sits on the first line of
     text rather than its box hanging below the cap height, and so the padding
     below does not push it off the gutter. */
  margin:-8px -8px 0 0;
  /* 36px target. The glyph stays 20px; the padding is the hit area. Was 28px,
     under the 24px WCAG floor once you account for it being a corner control
     people jab at. */
  display:inline-flex;align-items:center;justify-content:center;
  width:36px;height:36px;padding:0;
}
.banner-close:hover{color:var(--sk-ink-1);background:rgba(255,255,255,.06)}
.banner[hidden]{display:none}

/* ==========================================================================
   Nav
   ========================================================================== */

.nav{
  position:sticky;top:0;z-index:5;
  background:rgba(11,10,18,.82);
  backdrop-filter:saturate(160%) blur(14px);
  -webkit-backdrop-filter:saturate(160%) blur(14px);
  border-bottom:1px solid var(--sk-line);
}
.nav-inner{
  max-width:var(--sk-wrap);margin:0 auto;padding:14px var(--sk-gutter);
  display:flex;align-items:center;gap:28px;
}
.nav .logo{flex:0 0 auto}
.nav .logo svg{height:28px;width:auto}
.nav-links{display:flex;gap:26px;margin-left:8px}
.nav-links a{
  text-decoration:none;color:var(--sk-ink-2);font-size:14px;font-weight:500;
  transition:color .16s;
}
.nav-links a:hover{color:var(--sk-ink-1)}

/* The section you are currently reading. Pink rather than white, so it reads
   as position rather than as another hover state. */
.nav-links a.is-current{color:var(--sk-pink)}

/* Rule between the in-page links and the one that leaves the site. Negative
   margins because the flex gap would otherwise give it 26px of air on both
   sides and it would read as a column break rather than a separator. */
.nav-sep{
  align-self:center;
  width:1px;height:15px;
  /* NOT var(--sk-line). That token is tuned for long borders on large
     panels; on a 1x15px sliver over the header it measured 1.32:1 and
     simply did not render. */
  background:rgba(251,248,255,.22);
  margin:0 -8px;
}

.nav-ext{display:inline-flex;align-items:center;gap:6px}
/* The arrow sits back from the label: it is a signpost, not part of the
   word. It comes up to full strength with the link on hover. */
.nav-ext svg{opacity:.5;transition:opacity .16s}
.nav-ext:hover svg{opacity:1}

/* Visually hidden, still announced. */
.sr-only{
  position:absolute;width:1px;height:1px;
  padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);
  white-space:nowrap;border:0;
}
/* The toggle only exists below 1000px; above it the links are inline and it
   would be a second, redundant control. Ordered AFTER .nav .btn so the
   margin-left:auto below still pushes the Download button right. */
.nav-toggle{display:none}
.nav .btn{margin-left:auto}

/* ==========================================================================
   Sections
   ========================================================================== */

.section{padding:var(--sk-section) 0}

/* The heading gets a wide measure so it lands on two lines, the blurb keeps
   a normal reading measure. They cannot share one max-width: at this size a
   heading needs roughly 70% of the column, and body copy at 70% of 1180px
   would be an unreadable line length. */
.section-head{max-width:none}
/* 78% lands every section heading on two lines at the current copy lengths.
   text-wrap:balance evens the two lines out instead of leaving an orphan. */
.section-head h2{max-width:78%;text-wrap:balance}
.section-head .blurb,.section-head .lead{max-width:58ch}
.section-head h2 + .blurb{margin-top:20px}

.divider{border:0;border-top:1px solid var(--sk-line);margin:0}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero{padding:clamp(48px,7vw,88px) 0 clamp(18px,2.2vw,30px)}
.hero-grid{
  display:grid;grid-template-columns:1fr minmax(320px,0.8fr);gap:clamp(28px,3.5vw,56px);
  align-items:center;
}
.hero .h1{max-width:16ch}
/* The headline is split into words so they can arrive one at a time.
   inline-block because a plain inline span cannot be transformed.

   Each gradient word carries its own .hl rather than sharing one across the
   pair. A transform on a DESCENDANT of a background-clip:text element leaves
   the gradient behind and the text renders as nothing, which is verifiable
   in two seconds: put a translateY on a span inside .hl and the word
   disappears. Transforming the element that owns the gradient is fine, which
   is why the split has to be one .hl per word. The trade is that each word
   now runs its own gold-to-pink sweep instead of the pair sharing one. */
.hero .h1 .hw{display:inline-block}
.ministat{font-size:13px;color:var(--sk-ink-3);margin:20px 0 0}
/* Hero product shot. Unlike the section artwork this one keeps its own
   lighting and reflective surface, so it is not keyed transparent. Its
   background is already near-black; a soft edge mask melts the rectangle
   into the canvas so there is no visible photo edge.
   A mask is safe here where mix-blend-mode was not: masks are not affected
   by the stacking context that .wrap creates. */
/* Sized by height, not width, so the phone stands as tall as the copy beside
   it. Width follows from the aspect ratio and the grid column is set wide
   enough to take it. */
.hero-shot{display:flex;justify-content:center;align-items:center}
.hero-shot img{
  height:clamp(400px,44vw,620px);
  width:auto;max-width:none;
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 4%,#000 88%,transparent),
                     linear-gradient(to right,transparent,#000 18%,#000 82%,transparent);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(to bottom,transparent,#000 4%,#000 88%,transparent),
             linear-gradient(to right,transparent,#000 18%,#000 82%,transparent);
  mask-composite:intersect;
}

/* ==========================================================================
   Hero entrance

   The hero is above the fold, so it does not wait for an intersection: it
   plays once on load, as a sequence rather than everything arriving at once.
   The copy leads, the product shot follows it in and settles a beat later,
   and the chain strip draws itself last.

   Same safety rule as the scroll reveal: the page is visible by default and
   only .hero-ready hides anything, so no JS, a blocked script or reduced
   motion all leave the hero fully readable. The script adds .hero-ready and
   then .hero-go on the next frame, which is what starts the transition.

   The h1 animates as one element. Its second half carries .hl, and a
   transform on a descendant of a background-clip:text element leaves the
   gradient behind, so the two halves cannot be staggered separately.
   ========================================================================== */

.hero-ready .nav,
.hero-ready .hero .h1 .hw,
.hero-ready .hero .lead,
.hero-ready .hero .cta-row,
.hero-ready .hero .ministat,
.hero-ready .hero-shot,
.hero-ready .chainstrip-row li{
  opacity:0;
  transform:translateY(20px);
  transition:
    opacity .7s cubic-bezier(.22,.68,.3,1),
    transform .8s cubic-bezier(.22,.68,.3,1);
  transition-delay:var(--hero-delay,0ms);
  will-change:transform,opacity;
}
/* The nav slides down rather than up, and the strip's marks travel less. */
.hero-ready .nav{transform:translateY(-14px)}
.hero-ready .chainstrip-row li{transform:translateY(12px)}
/* The shot comes in a touch further and a touch slower, so it settles into
   place after the copy has landed rather than racing it. */
.hero-ready .hero-shot{
  transform:translateY(28px) scale(.97);
  transition-duration:.9s,1s;
}
/* The rules draw outward from the centre. */
.hero-ready .chainstrip .rule{
  transform:scaleX(0);
  transform-origin:50% 50%;
  transition:transform .9s cubic-bezier(.22,.68,.3,1);
  transition-delay:var(--hero-delay,0ms);
}

.hero-ready.hero-go .nav,
.hero-ready.hero-go .hero .h1 .hw,
.hero-ready.hero-go .hero .lead,
.hero-ready.hero-go .hero .cta-row,
.hero-ready.hero-go .hero .ministat,
.hero-ready.hero-go .hero-shot,
.hero-ready.hero-go .chainstrip-row li,
.hero-ready.hero-go .chainstrip .rule{
  opacity:1;
  transform:none;
  will-change:auto;
}

/* ==========================================================================
   Scroll reveal

   Content is visible by default. The reveal script adds .reveal-ready to
   <html> before it starts observing, and only then does anything hide. So a
   failed script, a blocked script, no JS at all, or an old browser without
   IntersectionObserver all leave the page fully readable. Never invert this.

   The script does not run at all under prefers-reduced-motion, which is why
   there is no reduced-motion override here: nothing is ever hidden.

   Elements are picked up by a selector list in the script rather than tagged
   in the markup, with [data-reveal] available to opt anything else in.
   ========================================================================== */

.reveal-ready [data-reveal]{
  opacity:0;
  /* Rises and grows into place. 16px and no scale was too quiet to register
     as movement at all; the scale is what makes it read as arriving rather
     than just appearing. Origin at the bottom so things grow upward out of
     where they sit instead of swelling from their middle. */
  transform:translateY(30px) scale(.965);
  transform-origin:50% 100%;
  transition:
    opacity .6s cubic-bezier(.22,.68,.3,1),
    transform .78s cubic-bezier(.2,.72,.26,1);
  transition-delay:var(--reveal-delay,0ms);
  will-change:transform,opacity;
}
.reveal-ready [data-reveal].is-in{
  opacity:1;
  transform:none;
}
/* Once it has arrived it stops being a moving part. Leaving will-change on
   every revealed element pins a compositor layer for the life of the page. */
.reveal-ready [data-reveal].is-in{will-change:auto}

/* ==========================================================================
   Chain strip — the five networks, ruled top and bottom.

   The rules are the only place the signature runs as a hairline rather than
   as type or a button fill. They fade out at both ends so they read as a
   light under the hero rather than two hard borders across the page.
   ========================================================================== */

.chainstrip{padding:0 0 clamp(40px,5.4vw,72px)}
.rule{
  border:0;height:1px;margin:0;
  background:linear-gradient(90deg,
    transparent 0%,
    rgba(254,191,78,.55) 14%,
    rgba(252,76,210,.9) 62%,
    rgba(252,76,210,.5) 86%,
    transparent 100%);
}
/* The strip is a marquee, sharing the review row's machinery: same two-copy
   clone, same .is-marquee class, same reduced-motion fallback. The JS that
   builds both is one function in js/home.js -- do not fork it.

   nowrap, not wrap: nine chains plus their clones must stay on ONE line or
   the track's width stops being one copy plus a gap and the loop tears. */
.chainstrip-viewport{
  overflow:hidden;
  /* Same edge fade as the reviews, so marks enter and leave rather than
     appearing at a hard boundary. */
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 8%,#000 92%,transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 8%,#000 92%,transparent 100%);
}
.chainstrip-row{
  list-style:none;margin:0;padding:clamp(18px,2.4vw,26px) 0;
  display:flex;flex-wrap:nowrap;justify-content:center;
  gap:clamp(20px,4.4vw,58px);
  width:max-content;
}
/* Only animates once JS has cloned the set; without the clone the row would
   scroll away into empty space. 68s against the reviews' 52s -- these items
   are far narrower, and matching the speeds makes this row feel frantic. */
.chainstrip-viewport.is-marquee .chainstrip-row{
  animation:sk-chainmarquee 68s linear infinite;
  justify-content:flex-start;
}
.chainstrip-viewport.is-marquee:hover .chainstrip-row,
.chainstrip-viewport.is-marquee:focus-within .chainstrip-row{animation-play-state:paused}
@keyframes sk-chainmarquee{
  from{transform:translate3d(0,0,0)}
  /* One copy plus half a gap, as the reviews. The gap is a clamp() here, so
     it is halved with the same clamp rather than a fixed pixel value. */
  to{transform:translate3d(calc(-50% - clamp(10px,2.2vw,29px)),0,0)}
}
/* No clone, no animation -- reduced motion, or JS off. It is then a row that
   overflows, so let people drag it, and let it centre when it fits. */
.chainstrip-viewport:not(.is-marquee){overflow-x:auto;scrollbar-width:none}
/* The chain row is static (five chains fit), so the marquee's
   edge fade would only eat the first and last marks when it wraps on a phone. */
#chainMarquee:not(.is-marquee){-webkit-mask-image:none;mask-image:none}
.chainstrip-viewport:not(.is-marquee)::-webkit-scrollbar{display:none}
.chainstrip-viewport:not(.is-marquee) .chainstrip-row{
  width:100%;flex-wrap:wrap;justify-content:center;
}
.chainstrip-row li{
  display:flex;align-items:center;gap:10px;
  font-variation-settings:'wdth' var(--sk-label-wdth),'wght' var(--sk-label-wght);
  font-size:13px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--sk-ink-3);
}


/* Masked box, not an <img>, so the fill is ours. Same reason as the chains
   artwork: the silhouette stays exact and cannot drift. Flat ink here,
   because the brushed chrome belongs on the 3D tokens, not on a hairline.
   --k is the optical-mass factor from assets/chains/README.md: matched
   widths make Ethereum's diamond read much smaller than Solana's bars. */
/* The five chain marks, inlined as data URIs rather than linked as files.

   They are used as CSS masks, and Chrome refuses to load an external SVG
   into a mask from a file:// document -- the page is an opaque origin, the
   fetch is blocked, and the marks vanish. That matters because this site
   gets zipped and opened off a desktop for review, where there is no
   server. Inlining also drops five requests in production.

   ~10KB of CSS for the set. Regenerate from assets/chains/*.svg, which stay
   the source of truth, if any mark changes. */
.chainmark.is-supra{--glyph:url("data:image/svg+xml,%3Csvg viewBox='0 0 2000 1999' fill='none' xmlns='http://www.w3.org/2000/svg' role='img' aria-label='Supra'%3E%3Cpath d='M1572.37 518.599C1547.78 458.033 1508.04 403.144 1462.63 359.612C1415.33 314.188 1358.56 280.119 1299.91 255.514C1260.17 240.372 1220.43 229.016 1178.81 225.231C1029.33 204.411 872.28 249.836 758.751 363.398C626.301 495.887 580.889 687.049 639.546 866.855V868.748C603.595 891.461 569.536 917.958 539.262 950.134C493.85 997.452 456.007 1054.23 433.302 1114.8C408.704 1177.26 399.243 1239.72 399.243 1305.96C399.243 1370.31 412.488 1436.56 438.978 1495.23C463.576 1555.8 503.311 1610.69 548.723 1654.22C596.026 1699.64 652.791 1733.71 711.447 1758.32C770.104 1782.92 834.437 1792.39 898.77 1792.39C889.309 1792.39 879.848 1792.39 872.28 1792.39C1006.62 1799.96 1144.75 1750.75 1246.93 1648.54C1379.38 1516.05 1424.79 1324.89 1368.02 1148.87C1407.76 1126.16 1443.71 1097.76 1473.98 1063.7C1519.39 1016.38 1557.24 959.598 1579.94 899.031C1604.54 836.572 1614 774.113 1614 707.869C1614 643.517 1598.86 577.273 1572.37 518.599ZM1140.96 554.56C1137.18 539.419 1135.29 522.384 1135.29 507.243C1152.32 511.028 1171.24 514.814 1188.27 522.384C1212.87 531.848 1233.68 548.882 1248.82 567.809C1263.95 586.736 1279.09 607.556 1286.66 632.161C1294.23 656.766 1298.01 679.478 1298.01 704.083C1294.23 749.508 1275.31 793.04 1243.14 825.216L1140.96 554.56ZM1258.28 863.07C1262.06 859.285 1263.95 857.392 1267.74 853.607C1288.55 832.787 1301.8 808.182 1313.15 781.684C1324.5 755.186 1326.4 724.903 1326.4 698.405C1326.4 668.122 1318.83 643.517 1307.47 618.912C1296.12 594.307 1277.2 573.487 1260.17 554.56C1241.25 537.526 1218.54 522.384 1193.94 514.814C1176.92 509.136 1157.99 505.35 1139.07 505.35C1139.07 473.174 1148.53 442.891 1161.78 416.393C1182.59 420.179 1205.3 427.749 1224.22 437.213C1262.06 454.247 1290.44 476.96 1316.93 503.457C1341.53 533.741 1362.35 564.024 1375.59 599.985C1388.84 634.054 1394.51 671.908 1394.51 709.762C1394.51 747.616 1386.94 785.469 1369.91 815.753C1356.67 849.821 1335.86 880.104 1309.37 902.817C1299.91 910.388 1292.34 917.958 1280.98 923.636L1258.28 863.07ZM1294.23 957.705C1307.47 948.242 1320.72 936.885 1333.96 923.636C1360.45 893.353 1385.05 857.392 1398.3 819.538C1415.33 779.791 1419.11 738.152 1419.11 700.298C1419.11 660.551 1409.65 620.805 1392.62 582.951C1377.48 548.882 1352.89 512.921 1324.5 486.423C1294.23 459.925 1263.95 439.106 1226.11 425.857C1205.3 418.286 1182.59 414.501 1161.78 410.715C1171.24 393.681 1182.59 378.539 1195.84 363.398C1207.19 352.042 1218.54 342.578 1231.79 335.007C1241.25 338.793 1250.71 342.578 1260.17 346.363C1305.58 365.29 1347.21 393.681 1383.16 431.535C1417.22 465.603 1443.71 512.921 1462.63 556.453C1481.55 603.77 1489.12 654.873 1489.12 702.191C1487.23 757.079 1475.87 804.396 1456.95 849.821C1438.03 891.461 1409.65 931.207 1373.7 967.169C1354.78 986.095 1335.86 1001.24 1315.04 1014.49L1294.23 957.705ZM773.888 1675.04C766.32 1671.25 758.751 1669.36 751.182 1665.57C705.771 1646.65 664.144 1618.26 628.193 1580.4C594.134 1546.33 567.644 1499.02 548.723 1455.48C529.801 1408.17 522.233 1357.06 522.233 1309.75C524.125 1258.64 535.478 1211.33 554.399 1165.9C573.32 1124.26 601.703 1084.52 637.654 1048.55C654.683 1031.52 673.604 1016.38 692.526 1005.02L713.339 1061.8C701.987 1071.27 688.742 1080.73 679.281 1092.09C652.791 1122.37 628.193 1158.33 614.948 1196.19C597.918 1235.93 594.134 1277.57 594.134 1315.43C594.134 1355.17 603.595 1394.92 620.624 1432.77C635.761 1466.84 660.359 1502.8 688.742 1529.3C719.016 1555.8 749.29 1576.62 787.133 1589.87C806.055 1597.44 824.976 1601.22 845.79 1605.01C836.329 1622.04 824.976 1637.18 811.731 1650.43C800.378 1658 787.133 1667.47 773.888 1675.04ZM789.025 1580.4C751.182 1563.37 722.8 1540.66 696.31 1514.16C671.712 1483.88 650.899 1453.59 637.654 1417.63C624.408 1383.56 618.732 1345.71 618.732 1307.85C618.732 1270 626.301 1232.15 643.33 1201.86C656.575 1167.79 677.389 1137.51 703.879 1114.8C711.447 1109.12 719.016 1101.55 726.584 1095.87L749.29 1156.44C747.398 1158.33 745.506 1160.22 743.614 1162.12C722.8 1182.94 709.555 1207.54 698.202 1234.04C686.849 1260.54 684.957 1290.82 684.957 1317.32C684.957 1347.6 692.526 1372.21 703.879 1396.81C715.232 1421.42 734.153 1442.24 751.182 1461.16C770.104 1478.2 792.81 1493.34 817.408 1500.91C832.545 1506.59 851.466 1508.48 868.496 1510.37C866.603 1542.55 859.035 1572.83 843.898 1599.33C826.868 1593.65 807.947 1587.97 789.025 1580.4ZM866.603 1459.27C870.388 1474.41 870.388 1491.45 870.388 1506.59C853.358 1502.8 838.221 1499.02 823.084 1491.45C798.486 1481.98 777.672 1464.95 762.535 1446.02C747.398 1427.09 732.261 1406.27 724.692 1381.67C715.232 1357.06 713.339 1334.35 713.339 1309.75C715.232 1266.21 734.153 1222.68 764.427 1192.4L866.603 1459.27ZM560.075 1646.65C514.664 1601.22 482.497 1548.23 457.9 1489.55C437.086 1434.67 425.733 1370.31 425.733 1307.85C429.517 1247.29 442.762 1184.83 465.468 1129.94C490.066 1073.16 526.017 1023.95 569.536 980.417C596.026 953.92 624.408 933.1 656.575 914.173L673.604 957.705C649.006 974.739 624.408 991.774 605.487 1014.49C567.644 1054.23 539.262 1099.66 520.34 1150.76C501.419 1201.86 493.85 1254.86 493.85 1307.85C497.635 1360.85 507.095 1413.85 527.909 1461.16C548.723 1508.48 580.889 1553.91 618.732 1587.97C656.575 1622.04 700.094 1652.33 749.29 1671.25C756.859 1673.15 762.535 1676.93 770.104 1678.82C737.937 1697.75 703.879 1707.21 666.036 1709.11C652.791 1709.11 639.546 1707.21 626.301 1705.32C601.703 1686.39 580.889 1667.47 560.075 1646.65ZM1545.88 883.89C1521.29 940.671 1485.34 989.881 1441.82 1033.41C1415.33 1059.91 1383.16 1084.52 1349.1 1103.44L1333.96 1061.8C1360.45 1044.77 1386.94 1025.84 1407.76 1001.24C1445.6 961.49 1473.98 916.066 1492.9 864.963C1511.83 813.86 1519.39 760.864 1519.39 707.869C1515.61 654.873 1506.15 601.878 1485.34 554.56C1464.52 507.243 1432.36 461.818 1394.51 427.749C1356.67 393.681 1313.15 363.398 1263.95 344.471C1254.49 340.685 1245.03 338.793 1237.46 335.007C1282.88 308.509 1335.86 300.939 1386.94 310.402C1411.54 327.436 1434.25 346.363 1453.17 369.076C1498.58 414.501 1530.75 467.496 1555.35 526.17C1576.16 581.058 1587.51 645.41 1587.51 707.869C1581.84 766.543 1568.59 829.002 1545.88 883.89Z' fill='%23FFFFFF'/%3E%3C/svg%3E")}
.chainmark.is-sui{--glyph:url("data:image/svg+xml,%3Csvg fill='%23FFFFFF' role='img' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ctitle%3ESui%3C/title%3E%3Cpath d='M17.636 10.009a7.16 7.16 0 0 1 1.565 4.474 7.2 7.2 0 0 1-1.608 4.53l-.087.106-.023-.135a7 7 0 0 0-.07-.349c-.502-2.21-2.142-4.106-4.84-5.642-1.823-1.034-2.866-2.278-3.14-3.693-.177-.915-.046-1.834.209-2.62.254-.787.631-1.446.953-1.843l1.05-1.284a.46.46 0 0 1 .713 0l5.28 6.456zm1.66-1.283L12.26.123a.336.336 0 0 0-.52 0L4.704 8.726l-.023.029a9.33 9.33 0 0 0-2.07 5.872C2.612 19.803 6.816 24 12 24s9.388-4.197 9.388-9.373a9.32 9.32 0 0 0-2.07-5.871zM6.389 9.981l.63-.77.018.142q.023.17.055.34c.408 2.136 1.862 3.917 4.294 5.297 2.114 1.203 3.345 2.586 3.7 4.103a5.3 5.3 0 0 1 .109 1.801l-.004.034-.03.014A7.2 7.2 0 0 1 12 21.67c-3.976 0-7.2-3.218-7.2-7.188 0-1.705.594-3.27 1.587-4.503z'/%3E%3C/svg%3E")}
.chainmark.is-aptos{--glyph:url("data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E%3C!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E%3Csvg version='1.1' id='a' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 479.3 481.2' style='enable-background:new 0 0 479.3 481.2;' xml:space='preserve'%3E%3Cpath d='M371.2,161h-42.4c-4.9,0-9.6-2.1-12.9-5.8l-17.2-19.4c-2.6-2.9-6.2-4.6-10.1-4.6s-7.5,1.7-10.1,4.6l-14.8,16.7 c-4.8,5.4-11.8,8.6-19,8.6H12.6C6,179.8,1.7,199.7,0,220.4h219.1c3.9,0,7.5-1.6,10.2-4.4l20.4-21.3c2.5-2.7,6.1-4.2,9.7-4.2h0.8 c3.9,0,7.5,1.7,10.1,4.6l17.2,19.4c3.3,3.7,8,5.8,12.9,5.8h178.8c-1.7-20.6-6-40.6-12.6-59.4L371.2,161L371.2,161z'/%3E%3Cpath d='M132.6,345.2c3.9,0,7.5-1.6,10.2-4.4l20.4-21.3c2.6-2.7,6.1-4.2,9.8-4.2h0.8c3.9,0,7.6,1.7,10.1,4.5l17.2,19.4 c3.3,3.7,8,5.8,12.9,5.8h242.4c9.1-18.8,15.7-38.9,19.7-60H243.4c-4.9,0-9.6-2.1-12.9-5.8L213.3,260c-2.6-2.9-6.2-4.5-10.1-4.5 s-7.6,1.7-10.1,4.5l-14.8,16.7c-4.8,5.5-11.8,8.6-19.1,8.6H3.3c4,21.1,10.6,41.2,19.7,60L132.6,345.2L132.6,345.2z'/%3E%3Cpath d='M304.5,96.1c3.9,0,7.5-1.6,10.2-4.4l20.4-21.3c2.5-2.7,6.1-4.2,9.8-4.2h0.8c3.9,0,7.5,1.7,10.1,4.6L373,90.3 c3.3,3.7,8,5.8,12.9,5.8H432C388.1,37.7,318.3,0,239.7,0S91.2,37.7,47.3,96.1H304.5z'/%3E%3Cpath d='M212,404.7h-63c-4.9,0-9.6-2.1-12.9-5.8l-17.2-19.4c-2.6-2.9-6.2-4.5-10.1-4.5s-7.6,1.7-10.1,4.5l-14.8,16.7 c-4.8,5.5-11.8,8.6-19.1,8.6h-1c43.9,47,106.4,76.5,175.9,76.5s131.9-29.5,175.9-76.5L212,404.7L212,404.7z'/%3E%3C/svg%3E")}
.chainmark.is-ethereum{--glyph:url("data:image/svg+xml,%3Csvg fill='%23FFFFFF' role='img' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ctitle%3EEthereum%3C/title%3E%3Cpath d='M11.944 17.97L4.58 13.62 11.943 24l7.37-10.38-7.372 4.35h.003zM12.056 0L4.69 12.223l7.365 4.354 7.365-4.35L12.056 0z'/%3E%3C/svg%3E")}
.chainmark.is-solana{--glyph:url("data:image/svg+xml,%3Csvg fill='%23FFFFFF' role='img' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Ctitle%3ESolana%3C/title%3E%3Cpath d='m23.8764 18.0313-3.962 4.1393a.9201.9201 0 0 1-.306.2106.9407.9407 0 0 1-.367.0742H.4599a.4689.4689 0 0 1-.2522-.0733.4513.4513 0 0 1-.1696-.1962.4375.4375 0 0 1-.0314-.2545.4438.4438 0 0 1 .117-.2298l3.9649-4.1393a.92.92 0 0 1 .3052-.2102.9407.9407 0 0 1 .3658-.0746H23.54a.4692.4692 0 0 1 .2523.0734.4531.4531 0 0 1 .1697.196.438.438 0 0 1 .0313.2547.4442.4442 0 0 1-.1169.2297zm-3.962-8.3355a.9202.9202 0 0 0-.306-.2106.941.941 0 0 0-.367-.0742H.4599a.4687.4687 0 0 0-.2522.0734.4513.4513 0 0 0-.1696.1961.4376.4376 0 0 0-.0314.2546.444.444 0 0 0 .117.2297l3.9649 4.1394a.9204.9204 0 0 0 .3052.2102c.1154.049.24.0744.3658.0746H23.54a.469.469 0 0 0 .2523-.0734.453.453 0 0 0 .1697-.1961.4382.4382 0 0 0 .0313-.2546.4444.4444 0 0 0-.1169-.2297zM.46 6.7225h18.7815a.9411.9411 0 0 0 .367-.0742.9202.9202 0 0 0 .306-.2106l3.962-4.1394a.4442.4442 0 0 0 .117-.2297.4378.4378 0 0 0-.0314-.2546.453.453 0 0 0-.1697-.196.469.469 0 0 0-.2523-.0734H4.7596a.941.941 0 0 0-.3658.0745.9203.9203 0 0 0-.3052.2102L.1246 5.9687a.4438.4438 0 0 0-.1169.2295.4375.4375 0 0 0 .0312.2544.4512.4512 0 0 0 .1692.196.4689.4689 0 0 0 .2518.0739z'/%3E%3C/svg%3E")}
/* BNB Chain, official Symbol (white) from bnbchain.org/en/brand-guidelines. */
.chainmark.is-bnb{--glyph:url("data:image/svg+xml,%3Csvg viewBox='0 0 96 96' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M22.8814 14.7044L48.1429 0L73.4043 14.7044L64.117 20.1366L48.1429 10.8644L32.1687 20.1366L22.8814 14.7044ZM73.4043 33.2488L64.117 27.8166L48.1429 37.0888L32.1687 27.8166L22.8814 33.2488V44.1132L38.8555 53.3854V71.9297L48.1429 77.362L57.4302 71.9297V53.3854L73.4043 44.1132V33.2488ZM73.4043 62.6576V51.7932L64.117 57.2254V68.0898L73.4043 62.6576ZM79.9984 66.4976L64.0243 75.7698V86.6341L89.2857 71.9297V42.521L79.9984 47.9532V66.4976ZM70.7111 23.9766L79.9984 29.4088V40.2732L89.2857 34.841V23.9766L79.9984 18.5444L70.7111 23.9766ZM38.8555 79.7034V90.5678L48.1429 96L57.4302 90.5678V79.7034L48.1429 85.1356L38.8555 79.7034ZM22.8814 62.6576L32.1687 68.0898V57.2254L22.8814 51.7932V62.6576ZM38.8555 23.9766L48.1429 29.4088L57.4302 23.9766L48.1429 18.5444L38.8555 23.9766ZM16.2873 29.4088L25.5746 23.9766L16.2873 18.5444L7 23.9766V34.841L16.2873 40.2732V29.4088ZM16.2873 47.9532L7 42.521V71.9297L32.2615 86.6341V75.7698L16.2873 66.4976V47.9532Z'/%3E%3C/svg%3E")}
/* Base, official "The Square" (white) from brand.base.org/base-brand.zip.
   IT IS A BLANK ROUNDED SQUARE, and that is the real asset, not a broken
   export: Base's square is a container that normally has the wordmark set
   inside it, which a single-colour mask cannot reproduce. The Basemark
   (the four-block wordmark, Base_basemark_white.svg in the same brand zip)
   does survive masking and is the swap if a plain box is not wanted. */
.chainmark.is-base{--glyph:url("data:image/svg+xml,%3Csvg viewBox='0 0 1280 1280' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M0,101.12c0-34.64,0-51.95,6.53-65.28,6.25-12.76,16.56-23.07,29.32-29.32C49.17,0,66.48,0,101.12,0h1077.76C1213.51,0,1230.84,0,1244.16,6.53c12.75,6.25,23.06,16.56,29.32,29.32,6.52,13.32,6.52,30.64,6.52,65.28v1077.76c0,34.63,0,51.96-6.52,65.28-6.26,12.75-16.57,23.06-29.32,29.32-13.32,6.52-30.65,6.52-65.28,6.52H101.12c-34.64,0-51.95,0-65.28-6.52-12.76-6.26-23.07-16.57-29.32-29.32-6.53-13.32-6.53-30.65-6.53-65.28V101.12Z'/%3E%3C/svg%3E")}
/* Polygon, icon taken from the mark on polygon.technology's own nav (their
   downloadable kit is behind a Google Drive folder). Their rules: the icon
   ships in purple, black or WHITE only, and "don't alter the colors",
   "don't apply gradients", "don't add strokes", "don't put the logo in a
   container". A flat white mask satisfies all four. */
.chainmark.is-polygon{--glyph:url("data:image/svg+xml,%3Csvg viewBox='0 0 25 26' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M17.41 1.22363L10.5949 5.13771V17.3537L6.8346 19.5335L3.05135 17.352V12.9906L6.8346 10.8303L9.2672 12.241V8.71235L6.81339 7.31926L0 11.2775V19.1075L6.83637 23.0445L13.6498 19.1075V6.89321L17.433 4.71165L21.2145 6.89321V11.2351L17.433 13.4361L14.9792 12.013V15.524L17.41 16.9259L24.2906 13.0118V5.13771L17.41 1.22363Z'/%3E%3C/svg%3E")}
/* Arbitrum, official one-colour white logomark, arbitrum.io/brandkit/
   icon_white.svg, unmodified. Their don't-list explicitly includes removing
   the fill and outlining the icon, so the SOLID white version is the
   compliant one -- do not swap it for an outline. */
.chainmark.is-arbitrum{--glyph:url("data:image/svg+xml,%3Csvg viewBox='0 0 151 172' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M144.518 39.2113L82.214 3.03438C80.1932 1.87961 77.9919 1.28418 75.7545 1.28418C73.5352 1.28418 71.3158 1.87961 69.3311 3.03438L7.00937 39.2474C3.05788 41.5569 0.585938 45.8151 0.585938 50.4162V122.842C0.585938 127.443 3.05788 131.756 7.00937 134.047L18.2143 140.561L34.5616 150.052L38.2243 139.965L71.8932 47.1143C72.2 46.2121 71.5504 45.2378 70.54 45.2378H54.752C53.5792 45.2378 52.4966 45.9775 52.1177 47.0782L21.8951 130.474L12.2961 124.899C11.5743 124.484 11.1232 123.708 11.1232 122.878V50.4162C11.1232 49.5862 11.5743 48.8103 12.2961 48.3953L74.6178 12.1824C74.9606 11.9658 75.3756 11.8756 75.7725 11.8756C76.1875 11.8756 76.5665 11.9839 76.9454 12.1824L139.285 48.3953C140.007 48.8103 140.458 49.5862 140.458 50.4162V122.842C140.458 123.672 140.007 124.448 139.285 124.863L129.794 130.384L104.822 61.4768C104.371 60.2137 102.639 60.2137 102.188 61.4768L93.9602 84.1392C93.7257 84.7707 93.7257 85.4744 93.9602 86.0879L113.447 139.875L106.969 143.646L91.0192 99.6023C90.5681 98.3393 88.8359 98.3393 88.3848 99.6023L80.1571 122.265C79.9225 122.896 79.9225 123.6 80.1571 124.213L90.6403 153.137L76.9634 161.094C76.6206 161.311 76.2056 161.401 75.7906 161.401C75.3756 161.401 74.9967 161.293 74.6178 161.094L61.1033 153.227L99.5537 47.1323C99.8965 46.1941 99.2108 45.2017 98.2365 45.2017H82.4486C81.2758 45.2017 80.1932 45.9414 79.8142 47.0421L44.756 143.718L41.0932 153.805L57.4405 163.295L69.3672 170.224C71.3519 171.379 73.5713 171.974 75.7906 171.974C78.0099 171.974 80.2292 171.379 82.214 170.224L144.554 134.011C148.541 131.701 150.977 127.443 150.977 122.806V50.4162C150.977 45.8151 148.505 41.5028 144.554 39.2113H144.518Z'/%3E%3C/svg%3E")}

/* Avalanche: the mark avax.network serves as its own
   favicon (assets/chains/avalanche.svg, red, unmodified), knocked out white
   here like every other mark in the set. */
/* Robinhood Chain: the feather path from Robinhood's official
   Robinhood_Chain_Logo_White.svg, unmodified, framed to the symbol
   (assets/chains/robinhood-feather.svg). */
.chainmark.is-robinhood{--glyph:url("data:image/svg+xml,%3Csvg viewBox='0 0 205 207' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M379.05,72.29c-28.08,0-45.28,18.27-45.28,50.39s17.21,50.25,45.28,50.25,45.14-18.27,45.14-50.25-16.79-50.39-45.14-50.39ZM379.05,158.26c-17.76,0-24.91-14.67-24.91-35.44.14-21.04,7.16-35.58,24.91-35.58s24.91,14.54,24.91,35.44-7.16,35.58-24.91,35.58ZM303.49,109.39c-1.51-.55-2.07-1.52-2.07-2.77,0-.97.83-2.08,1.93-2.77,10.74-5.26,17.21-15.09,17.21-28.66,0-23.81-14.86-38.21-44.73-38.21h-51.48v134.15h20.37v-55.38h32.9c15.55,0,20.78,6.65,21.2,17.44l1.93,37.93h20.1l-2.06-39.32c-.83-13.01-5.92-18.97-15.28-22.43l-.02.02ZM274.45,99.84h-29.73v-46.52h29.73c15.42,0,24.91,7.61,24.91,23.26s-9.5,23.26-24.91,23.26ZM1056.63,81.99c0,1.94-1.1,2.91-2.47,2.91-.97,0-1.79-.55-2.48-1.38,0,0-.14-.14-.41-.14-6.88-7.34-14.32-11.08-26.02-11.08-20.78,0-37.71,16.06-37.71,50.39s16.93,50.25,37.71,50.25c12.12,0,20.24-4.02,26.98-12.04l.41-.42c.83-.83,1.52-1.38,2.48-1.38,1.38,0,2.48.97,2.48,2.91v9.14h18.3V32.42h-19.27v49.56h0ZM1032.55,158.26c-17.76,0-24.91-14.67-24.91-35.44s7.15-35.44,24.91-35.44,24.91,14.54,24.91,35.44-7.02,35.44-24.91,35.44ZM667.26,108.01v63.27h-19.27v-58.14c0-17.17-6.74-25.06-20.37-25.06-14.45,0-23.67,12.32-23.67,29.62v53.44h-19.27v-96.91h18.17v11.63c0,1.94,1.1,2.91,2.48,2.91s2.06-.97,2.89-1.94c6.06-8.17,14.18-14.54,28.08-14.54,20.92,0,30.97,13.43,30.97,35.72h0ZM770.22,108.01v63.27h-19.27v-58.15c0-17.17-6.74-25.06-20.37-25.06-14.45,0-23.67,12.32-23.67,29.63v53.44h-19.27V32.42h19.27v52.05c0,1.94,1.1,2.91,2.48,2.91s2.07-.97,2.89-1.94c5.64-7.34,14.04-13.15,26.98-13.15,20.92,0,30.97,13.43,30.97,35.72h0ZM830.36,72.29c-28.08,0-45.28,18.27-45.28,50.39s17.21,50.25,45.28,50.25,45.14-18.27,45.14-50.25c-.14-32.12-16.79-50.39-45.14-50.39ZM830.36,158.26c-17.76,0-24.91-14.67-24.91-35.44s7.16-35.44,24.91-35.44,24.91,14.54,24.91,35.44c-.14,20.63-7.16,35.44-24.91,35.44ZM931.39,72.29c-28.08,0-45.28,18.27-45.28,50.39s17.21,50.25,45.28,50.25,45.14-18.27,45.14-50.25-16.79-50.39-45.14-50.39ZM931.39,158.26c-17.76,0-24.91-14.67-24.91-35.44s7.16-35.44,24.91-35.44,24.91,14.54,24.91,35.44-7.16,35.44-24.91,35.44ZM544.49,74.23h19.27v96.91h-19.27s0-96.91,0-96.91ZM543.67,32.42h20.65v22.15h-20.65v-22.15ZM490.68,72.29c-11.97,0-19.27,3.74-26.01,10.8l-.41.42c-.83.83-1.51,1.38-2.48,1.38-1.38,0-2.48-.97-2.48-2.91v-49.56h-19.27v138.72h18.17v-9.14c0-1.94,1.1-2.91,2.48-2.91.96,0,1.79.55,2.48,1.38l.41.42c6.88,7.89,14.86,12.04,27.11,12.04,20.65,0,37.57-15.92,37.57-50.25s-16.93-50.39-37.57-50.39h0ZM483.24,158.26c-17.76,0-24.91-14.67-24.91-35.44s7.16-35.44,24.91-35.44,24.91,14.54,24.91,35.44c-.14,20.63-7.29,35.44-24.91,35.44ZM102.68,48.62c-23.4,26.03-60.7,69.5-94.97,157.27-.41.69-1.1,1.11-1.93,1.11H1.24c-.96,0-1.51-.55-1.1-1.66,4.54-16.89,10.74-35.58,20.51-63.13v-38.21c0-7.34,1.1-12.46,5.51-18l30-37.38c.96-1.38,2.34-1.94,3.85-1.94h41.84c1.38,0,1.79.83.83,1.94ZM152.23,5.57c7.3,7.75,8.26,26.44,6.61,38.62-1.24,8.31-2.61,10.11-7.16,16.06l-27.94,36.69c-.83,1.25-1.93.83-1.93-.55v-52.61c0-4.29-2.48-6.78-6.74-6.78h-46.38c-1.38,0-1.79-.97-.83-1.94,7.85-8.31,16.1-16.75,28.49-27.41,2.75-2.49,4.13-2.77,6.74-4.01,13.49-5.26,42.67-4.98,49.14,1.94h0ZM112.04,58.03v52.88c0,.69-.14,1.66-.55,2.49l-19.13,31.7c-2.34,3.88-5.09,6.09-9.91,7.34l-42.94,13.29c-1.24.41-1.93-.42-1.38-1.52,20.78-40.84,43.22-74.76,71.98-107.01.96-1.11,1.93-.55,1.93.83h0ZM1576,108.67v62.6h-11.37v-61.26c0-17.99-8.15-26.61-21.8-26.61-16.67,0-27.28,13.97-27.28,32.74v55.14h-11.37v-96.87h10.61v12.44c0,1.15.57,1.91,1.51,1.91s1.33-.38,2.09-1.53c5.49-8.42,14.21-14.55,26.72-14.55,20.46,0,30.89,13.21,30.89,35.99h0ZM1462.29,35.73h15.92v16.08h-15.92s0-16.08,0-16.08ZM1464.56,74.4h11.37v96.87h-11.37s0-96.87,0-96.87ZM1402.76,72.67c-18.2,0-33.92,8.42-34.68,28.53h11.75c.94-13.98,10.23-18.19,22.93-18.19,14.4,0,24.06,6.89,24.06,18.76,0,7.08-3.6,9.38-15.73,11.49l-14.02,2.49c-18.57,3.25-32.21,11.29-32.21,30.25s12.88,26.99,29.94,26.99c13.64,0,23.87-7.27,28.99-13.21,1.14-1.34,1.71-1.72,2.46-1.72s1.52.58,1.52,1.92v11.29h10.61v-67.58c0-21.82-15.73-31.01-35.62-31.01h0ZM1427.77,132.21c0,18.95-15.35,30.44-32.78,30.44-12.51,0-18.38-7.47-18.38-16.46,0-10.91,6.44-17.61,23.49-20.68l10.62-1.91c8.52-1.53,14.59-3.26,17.05-5.74v14.36h0ZM1344.47,108.67v62.6h-11.37v-61.26c0-17.99-8.15-26.61-21.79-26.61-16.68,0-27.29,13.97-27.29,32.74v55.14h-11.37V32.28h11.37v53.8c0,1.15.57,1.91,1.51,1.91s1.33-.38,2.09-1.53c4.74-7.08,12.32-13.78,25.77-13.78,20.66,0,31.08,13.21,31.08,35.99h0ZM1153.22,104.07c0,37.33,18.19,58.39,44.91,58.39,24.63,0,36.57-16.27,39.04-35.23h12.31c-2.65,27.76-20.84,46.33-51.16,46.33-34.3,0-57.61-26.42-57.61-69.49s23.31-69.49,57.61-69.49c30.32,0,48.51,18.57,51.16,46.33h-12.31c-2.47-18.95-14.41-35.23-39.04-35.23-26.91,0-44.91,21.25-44.91,58.39h0Z'/%3E%3C/svg%3E")}
.chainmark.is-avalanche{--glyph:url("data:image/svg+xml,%3Csvg viewBox='4 5 24 21' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M19.0194 25.9801H27.0466C27.7549 25.9801 28.1981 25.2197 27.8435 24.6119L23.8299 17.7207C23.4753 17.1129 22.5907 17.1129 22.2361 17.7207L18.2225 24.6119C17.8679 25.2197 18.3111 25.9801 19.0194 25.9801Z'/%3E%3Cpath fill='%23fff' d='M20.0223 11.1854L16.7235 5.52006C16.3904 4.94741 15.5561 4.94741 15.223 5.52006L4.12838 24.5699C3.76351 25.1972 4.21983 25.9798 4.94958 25.9798H11.5555C12.2601 25.9798 12.9105 25.607 13.2623 25.0029L20.0223 13.3955C20.4207 12.7119 20.4207 11.8691 20.0223 11.1854Z'/%3E%3C/svg%3E")}
/* Optical-mass factors (--k) per chain. These lived in style="" attributes
   on each mark; they sit here so the CSP needs no 'unsafe-inline' for
   styles. Chains not listed use the default of 1. */
.chainmark.is-ethereum,.chainmark.is-sui{--k:1.115}
.chainmark.is-solana{--k:.923}
.chainmark.is-base{--k:.78}
.chainmark.is-arbitrum{--k:.95}
.chainmark.is-polygon{--k:1.06}
.chainmark.is-avalanche{--k:1.05}
.chainmark{
  width:calc(clamp(22px,2.3vw,27px) * var(--k,1));
  aspect-ratio:1;
  background:rgba(251,248,255,.78);
  -webkit-mask:var(--glyph) center/contain no-repeat;
  mask:var(--glyph) center/contain no-repeat;
}

/* Supra is the one mark that wants its disc: a bare glyph is not how anyone
   recognises it. Two mask layers subtracted rather than a second file, so a
   white disc comes back with the S knocked out of it.

   The glyph layer is supra.svg at its natural size, and its viewBox is the
   same 2000x1999 canvas the official Supra-Red-Dark-Symbol.svg uses, so the
   glyph lands at exactly the size and position Supra's own mark puts it.
   The circle needs closest-side; the default farthest-corner puts the radius
   at the box corner and fills the whole square.

   Sized by eye to match Aptos, not from the coverage table. The table
   predicts a solid disc and would shrink this; with the S knocked out it is
   the outer edge rather than the ink that sets how big the mark reads.

   NOTE: the official dark-background symbol is the inverse of this, a RED
   disc with a white S. This is a knocked-out white version. If it
   has to be the official artwork, assets/chains/supra-symbol.svg is that
   file, unmodified, and wants an <img> rather than a mask. */
.chainmark.is-disc{
  -webkit-mask:
    var(--glyph) center/contain no-repeat,
    radial-gradient(circle closest-side at 50% 50%, #000 97%, transparent 100%) center/100% 100% no-repeat;
  mask:
    var(--glyph) center/contain no-repeat,
    radial-gradient(circle closest-side at 50% 50%, #000 97%, transparent 100%) center/100% 100% no-repeat;
  mask-composite:exclude;
  -webkit-mask-composite:xor;
}

/* ==========================================================================
   Scroll sequence — the showcase

   Sticky, never scroll-jacked: the reader can scroll past at normal speed.
   Progress is read from scroll position and mapped to a beat index in JS.
   Mobile and reduced-motion collapse to a static stack, see the queries at
   the foot of this file.
   ========================================================================== */

.seq{position:relative;height:300vh}
.seq-stage{
  position:sticky;top:0;height:100vh;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;
  /* Top padding is the nav's height: the nav floats over this stage, and
     without it the first beat sits behind the nav on a short laptop. */
  padding:66px var(--sk-gutter) 0;
  overflow:hidden;
}
.seq-glow{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(38rem 26rem at 50% 50%, rgba(252,76,210,.16), transparent 65%);
  opacity:0;transition:opacity .6s ease;
}
.seq-stage.is-lit .seq-glow{opacity:1}
.seq-beats{display:flex;flex-direction:column;gap:clamp(8px,1.1vw,14px);position:relative;z-index:1}
/* Uppercase and wide, one axis step below the resolve, so the beats have
   weight of their own without competing with the line they build to.
   Three states, driven from the scroll handler: a beat not yet reached is
   absent, the current one flies into its slot, and the ones behind it stay
   on screen dimmed so the stack accumulates as you scroll. The slots never
   move, so nothing reflows as lines arrive. */
.beat{
  font-variation-settings:'wdth' var(--sk-h2-wdth),'wght' var(--sk-h2-wght),'opsz' 32;
  font-weight:900;
  text-transform:uppercase;
  font-size:clamp(20px,3.4vw,40px);
  letter-spacing:0;
  line-height:1.06;
  margin:0;
  color:var(--sk-ink-3);
  opacity:0;
  transform:translateY(.62em);
  filter:blur(7px);
  transition:
    opacity .34s ease,
    color .4s ease,
    filter .34s ease,
    transform .52s cubic-bezier(.18,.86,.24,1.18);
  will-change:transform,opacity,filter;
}
/* Landed, but behind the current line. */
.beat.is-in{opacity:.32;transform:none;filter:blur(0)}
/* The line being read. */
.beat.is-on{color:var(--sk-ink-1);opacity:1;transform:none;filter:blur(0)}

/* The last beat is the turn before the payoff, so it steps up in size and
   takes a little more air above it. Keyed to the last child rather than a
   class: whichever line ends the run is the one that should carry this. */
.beat:last-child{
  font-size:clamp(28px,4.9vw,58px);
  margin-top:clamp(6px,.9vw,12px);
}

/* The resolve is the largest type on the site, deliberately larger than the
   hero h1, so the repeated line reads as arrival rather than duplication. */
.resolve{
  font-variation-settings:'wdth' var(--sk-h1-wdth),'wght' var(--sk-h1-wght),'opsz' 36;
  font-weight:900;text-transform:uppercase;letter-spacing:-.005em;line-height:.94;
  /* Sized so that "More possibilities." holds one line across the desktop
     range. The <br> after "Your crypto." only reads as a break if the
     second half does not wrap again underneath it. */
  font-size:clamp(34px,6.7vw,86px);
  margin:clamp(20px,3vw,36px) 0 0;
  position:relative;z-index:1;
}
/* Each line carries its own .hl, rather than one gradient across the block.
   A transform on a descendant of a background-clip:text element leaves the
   gradient behind at the untransformed position, so the two lines can only
   move independently if each one owns its gradient. */
.resolve > span{
  display:block;
  /* The line starts oversized and over-tracked and settles into place, which
     is the arrival this section has been building to. Letter-spacing is the
     one property here that is not compositor-friendly, so it relayouts each
     frame: acceptable for two short lines that animate once, not something to
     copy onto anything that animates often.

     nowrap matters. At the starting track "More possibilities." is wider than
     its column, so without it the line rewraps to two during the animation
     and snaps back. It overflows instead, which is invisible because the
     stage clips and the line is still blurred and transparent at that point.
     The stacked fallbacks put wrapping back, since nothing animates there. */
  white-space:nowrap;
  opacity:0;
  letter-spacing:.13em;
  transform:scale(1.06) translateY(.14em);
  filter:blur(12px);
  transition:
    opacity .45s ease,
    filter .5s ease,
    letter-spacing .8s cubic-bezier(.16,.84,.26,1),
    transform .8s cubic-bezier(.16,.84,.26,1);
  will-change:transform,opacity,filter;
}
/* -.005em is .resolve's own tracking, so it lands exactly where it sat. */
.resolve > span.is-on{
  opacity:1;
  letter-spacing:-.005em;
  transform:none;
  filter:blur(0);
}
.seq-cta{margin-top:30px;opacity:0;transition:opacity .5s ease .1s;position:relative;z-index:1}
.seq-cta.is-on{opacity:1}

/* ==========================================================================
   Tiles
   ========================================================================== */

.tiles{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:16px;
  margin-top:44px;
}
/* Four tiles in the three-column grid leave one orphaned on its own row.
   2x2 pairs them instead, which also suits longer partner copy: these tiles
   carry a paragraph each rather than the homepage's single line. */
.tiles-4{grid-template-columns:repeat(2,1fr)}
.tile{
  border:1px solid var(--sk-line);
  border-radius:var(--sk-r-tile);
  background:var(--sk-panel);
  padding:28px;
  transition:border-color .2s,transform .2s,background .2s;
}
.tile:hover{border-color:rgba(252,76,210,.4);transform:translateY(-3px);background:var(--sk-panel-2)}
.tile .ti{margin-bottom:16px;color:var(--sk-lilac)}
.tile p{margin:0;font-size:15px;color:var(--sk-ink-2)}

/* Steps — numbered, for the iAssets flow.
   The labels are the skim layer, so they carry the wide uppercase treatment
   rather than sitting as small pink eyebrows above the real content. */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:44px}
/* Single stacked column, used inside a split layout. */
.steps.steps-stack{grid-template-columns:1fr;margin-top:0;gap:12px}
.step{
  border:1px solid var(--sk-line);border-radius:var(--sk-r-tile);
  background:var(--sk-panel);padding:28px;
}
.step .num{
  display:flex;align-items:baseline;gap:10px;margin-bottom:12px;
  font-variation-settings:'wdth' var(--sk-h2-wdth),'wght' var(--sk-h2-wght),'opsz' 32;
  font-size:clamp(24px,2.6vw,34px);
  line-height:1;letter-spacing:-.005em;text-transform:uppercase;
  color:var(--sk-ink-1);
}
.step .num i{
  font-style:normal;
  font-variation-settings:'wdth' var(--sk-label-wdth),'wght' var(--sk-label-wght);
  font-size:12px;letter-spacing:.12em;
  color:var(--sk-lilac);
}
.step p{margin:0;font-size:15px;color:var(--sk-ink-2)}

/* ==========================================================================
   Numbers — the audience figures, PARTNERS PAGE ONLY
   ========================================================================== */

/* Audience figures, used on /partners only. The .section wrapper provides
   the spacing the old .numbers rule used to.

   Quiet by design. These are big claims and they do not need big decoration
   to land; a row of tinted cards would make them read as marketing furniture
   rather than as measurements. Hairlines and type only. */
.numgrid{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(20px,3vw,40px);
}
.numgrid-3{grid-template-columns:repeat(3,1fr)}
/* On the homepage the band stands alone, so its margin is the section's.
   Inside a .section it follows a .section-head whose bottom margin is 0, and
   the figures would start on the heading's last line. */
.section .numgrid{margin-top:clamp(28px,3.4vw,44px)}
.numgrid li{
  display:flex;flex-direction:column;gap:6px;
  padding-left:20px;
  border-left:1px solid var(--sk-line);
}
.numval{
  font-size:clamp(28px,3.6vw,42px);
  font-weight:700;line-height:1;color:var(--sk-ink-1);
  font-variant-numeric:tabular-nums;
  letter-spacing:-.02em;
}
.numlab{
  font-size:13px;line-height:1.4;color:var(--sk-ink-3);
  font-variation-settings:'wdth' var(--sk-label-wdth),'wght' var(--sk-label-wght);
}
/* A second row of figures on the partners page. Same grid, just spaced off
   the one above rather than starting a new block, so the eight read as one
   table of measurements and not as two competing claims. */
.numgrid-second{margin-top:clamp(20px,3vw,40px)}
/* The date and the measurement caveat are part of the claim, not a
   disclaimer to be hidden. Small, but present and never removed. */
.numnote{
  margin:22px 0 0;font-size:12.5px;line-height:1.5;color:var(--sk-ink-3);
  max-width:74ch;opacity:.82;
}

/* ==========================================================================
   For projects — the partner strip before the close
   ========================================================================== */

/* A panel, not a section. This is the one block on the page addressed to a
   project rather than to an end user, and as a plain .section it read as one
   more feature block at the bottom of the page -- which is how a reader skips
   it. The card, the violet wash and the gold button exist to break that
   pattern deliberately. */
.partners-strip{padding:0 0 clamp(70px,8vw,110px)}
.partners-card{
  position:relative;
  isolation:isolate;
  overflow:hidden;
  border:1px solid rgba(116,36,246,.42);
  border-radius:var(--sk-r-panel);
  /* Violet rather than the page's pink: pink is the product's own colour and
     carries every user-facing CTA, so a pink card here would read as more of
     the same. The wash runs left to right, behind the copy, and fades out
     under the artwork so the render sits on near-black as it was made to. */
  background:
    linear-gradient(100deg, rgba(116,36,246,.20), rgba(116,36,246,.05) 52%, transparent 78%),
    var(--sk-panel);
  display:grid;
  grid-template-columns:1.15fr .85fr;
  align-items:center;
  gap:clamp(24px,4vw,56px);
  padding:clamp(34px,4.4vw,60px);
}
.partners-copy .eyebrow{margin-top:0}
.partners-copy h2{margin:0 0 14px;max-width:18ch}
.partners-copy .blurb{margin:0 0 30px;max-width:54ch}

/* The artwork floats, it does not sit in a box: the PNG is keyed transparent,
   same rule as every other render on the page. Do NOT give this a background
   or a border.

   Portrait render in a landscape slot, so it is centred and capped rather
   than stretched to the column, and it overhangs the panel's padding a little
   at top and bottom so it reads as placed rather than fitted. */
.partners-art{
  display:flex;align-items:center;justify-content:center;
  margin:calc(-1 * clamp(18px,2.2vw,32px)) 0;
}
/* Near-square globe rather than the portrait render this slot first held, so
   it takes a wider cap: at 300px the sphere read small against the headline
   beside it. */
.partners-art img{display:block;width:100%;max-width:360px;height:auto}

/* Gold, and gold appears nowhere else as a button. The one control on the
   page that is not aimed at the end user should not look like the six that
   are. Dark ink on it for contrast, same as .btn-primary. */
.btn-gold{
  background:linear-gradient(92deg,var(--sk-gold),#FFD98A);
  background-origin:border-box;
  color:#1A1206;
  font-weight:700;
  box-shadow:0 12px 34px -14px rgba(254,191,78,.8);
}
.btn-gold:hover{transform:translateY(-2px);box-shadow:0 20px 44px -14px rgba(254,191,78,.92)}
.btn-gold:active{transform:translateY(0)}

/* ==========================================================================
   Chains
   ========================================================================== */

/* LOGO WALL. Replaced the five-token render and the colour-dot
   chips. Eleven chain tiles plus a twelfth, "+ any other EVM network", which
   fills a 4x3 grid on desktop and a 3x4 grid on a phone with no gaps.

   Tiles are pure #000: Robinhood's guidelines allow its marks only white on
   #000000, and every tile matching keeps that one from being a special case. */
.art-chainwall{width:min(520px,100%);margin-inline:auto}
.chainwall{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(4,1fr);gap:10px;
}
.chainwall li{
  aspect-ratio:1;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;
  background:#000;border:1px solid var(--sk-line);border-radius:16px;
  font-variation-settings:'wdth' var(--sk-label-wdth),'wght' var(--sk-label-wght);
  font-size:11px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--sk-ink-2);text-align:center;
}
.chainwall .chainmark{width:calc(clamp(28px,3vw,38px) * var(--k,1));background:#fff}
/* The twelfth tile is a claim, not a chain: dashed, dimmer, no mark. */
.chainwall li.cw-more{
  background:transparent;border-style:dashed;color:var(--sk-ink-3);
  padding:0 10px;line-height:1.5;
}
@media (max-width:560px){
  .chainwall{grid-template-columns:repeat(3,1fr);gap:8px}
  .chainwall li{gap:9px;font-size:10px;border-radius:14px}
}

/* ==========================================================================
   Security — featured recovery block with the video
   ========================================================================== */

.feature{
  display:grid;grid-template-columns:1fr 1fr;gap:44px;align-items:center;
  margin-top:44px;padding:36px;
  border:1px solid var(--sk-line);border-radius:var(--sk-r-panel);
  background:
    radial-gradient(30rem 22rem at 100% 0%, rgba(252,76,210,.1), transparent 62%),
    var(--sk-panel);
}
.feature h3{font-size:clamp(23px,2.6vw,30px);margin-bottom:14px}
.feature p{margin:0 0 14px;color:var(--sk-ink-2)}
.feature p:last-child{margin-bottom:0}

/* Video facade. The Vidyard iframe and its script only load on click, so
   the embed costs nothing until someone asks for it. */
.video{
  position:relative;aspect-ratio:16/9;border-radius:var(--sk-r-tile);
  overflow:hidden;background:var(--sk-void);border:1px solid var(--sk-line);
}
.video img{width:100%;height:100%;object-fit:cover}
.video iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.video-play{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:rgba(11,10,18,.35);border:0;cursor:pointer;padding:0;
  transition:background .2s;
}
.video-play:hover{background:rgba(11,10,18,.2)}
.video-play-icon{
  width:66px;height:66px;border-radius:50%;
  background:var(--sk-signature);background-origin:border-box;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 14px 40px -12px rgba(252,76,210,.9);
  transition:transform .2s;
}
.video-play:hover .video-play-icon{transform:scale(1.07)}
.video-play svg{margin-left:4px}
/* Title and running time sit on the thumbnail, inside the play button, so
   they go away with it once the embed loads. The scrim only darkens the
   bottom edge, where the text is. */
.video-meta{
  position:absolute;left:0;right:0;bottom:0;
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:clamp(14px,2.4vw,24px) clamp(16px,2.8vw,28px);
  background:linear-gradient(to top,rgba(11,10,18,.85),rgba(11,10,18,0));
  text-align:left;pointer-events:none;
}
.video-title{
  font-family:var(--sk-type);font-size:clamp(13px,1.5vw,16px);
  font-weight:600;color:var(--sk-ink-1);
}
.video-dur{
  flex:none;font-family:var(--sk-type);font-size:12px;font-weight:600;
  font-variant-numeric:tabular-nums;color:var(--sk-ink-1);
  background:rgba(11,10,18,.7);border:1px solid var(--sk-line);
  border-radius:var(--sk-r-pill);padding:4px 10px;
}
/* On a phone the thumbnail is under 200px tall, so the full-size play button
   would run into the title bar. */
@media (max-width:640px){
  .video-play-icon{width:52px;height:52px}
  .video-play-icon svg{width:24px;height:24px}
  .video-meta{padding:12px 14px}
}

/* ==========================================================================
   Platforms
   ========================================================================== */

.platforms{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:44px}
.platform{
  border:1px solid var(--sk-line);border-radius:var(--sk-r-tile);
  background:var(--sk-panel);padding:28px;
  display:flex;flex-direction:column;
}
.platform .ti{color:var(--sk-lilac);margin-bottom:16px}
.platform p{margin:0 0 20px;font-size:15px;color:var(--sk-ink-2);flex:1}
/* .rating is gone from the platform tiles on purpose: Google Play and the
   App Store both personalise ratings by country, so there is no single
   figure to print. The markup above .platforms has the numbers. */

/* --- The big rating, leading the platforms section ---------------------
   A half-star has to be drawn, not written: 4.6 is not four stars and it is
   not five. Two identical star rows stacked, the top one clipped to 92%
   (4.6/5), which is exact at any font size and needs no images.

   The clip is width + overflow, NOT background-clip:text -- the gold fill is
   a flat colour here precisely so this stays simple. */
.bigrating{
  display:flex;align-items:baseline;flex-wrap:wrap;gap:0 14px;
  margin:6px 0 14px;
}
.starbar{position:relative;display:inline-block;white-space:nowrap}
.starbar-bg,.starbar-fg{
  font-size:clamp(30px,4.4vw,46px);line-height:1;letter-spacing:.04em;
}
.starbar-bg{color:rgba(254,191,78,.22)}
.starbar-fg{
  position:absolute;inset:0;overflow:hidden;
  width:92%;                    /* 4.6 of 5 */
  color:var(--sk-gold);
}
.bigscore{
  font-size:clamp(34px,5vw,54px);line-height:1;
  font-variation-settings:'wdth' var(--sk-h2-wdth),'wght' 900;
  color:var(--sk-ink-1);
}
/* The attribution is not fineprint. It is the thing that makes the number
   above it true, so it sits on the same line at readable size. */
.bigsrc{font-size:15px;color:var(--sk-ink-2)}
@media (max-width:560px){
  .bigrating{gap:0 10px}
  .bigsrc{flex-basis:100%;margin-top:4px}
}

/* --- Review marquee ----------------------------------------------------
   Six verbatim store reviews on one row, scrolling continuously. Kept
   visually quiet: they are corroboration under the rating, not testimonial
   cards competing with the section head.

   A marquee rather than a stepped carousel on purpose. There is nothing to
   page through and no position to indicate, so it needs no dots, no arrows
   and no JS to drive it -- and the motion itself does the work, saying
   "there are a lot of these" in a way a static row of three cannot.

   The loop is the two-copy trick: the track holds the six figures twice and
   travels exactly one copy's width, so the seam never shows. That distance
   is NOT -50%. The flex gap sits between the two copies as well, so it is
   -50% minus half a gap. Get it wrong and the row stutters once per cycle.

   The clone is built in JS rather than written into the markup, so the six
   reviews exist once in the source. See the note by #quotesTrack. ------ */
.quotes{
  margin-top:36px;
  overflow:hidden;
  /* Edges fade rather than ending on a hard crop, so cards enter and leave
     instead of appearing at a boundary. */
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
}
.quotes-track{display:flex;gap:16px;width:max-content}
.quote{
  flex:0 0 min(340px,78vw);
  margin:0;padding:22px 24px;
  border:1px solid var(--sk-line-soft);border-radius:var(--sk-r-tile);
  background:rgba(255,255,255,.02);
  display:flex;flex-direction:column;
}
/* Equal-height cards, captions pinned to the bottom: the quotes are very
   different lengths and ragged captions read as broken. */
.quote blockquote{flex:1}
.quote blockquote{
  margin:0 0 14px;font-size:15px;line-height:1.55;color:var(--sk-ink-1);
}
.quote blockquote::before{content:'“'}
.quote blockquote::after{content:'”'}
.quote figcaption{
  font-size:13px;color:var(--sk-ink-3);
  display:flex;align-items:center;gap:8px;
}
.quote figcaption span{
  padding-left:8px;border-left:1px solid var(--sk-line);
}

/* Only animates once JS has cloned the set; without the clone the track would
   scroll away into empty space. */
.quotes.is-marquee .quotes-track{animation:sk-marquee 52s linear infinite}
/* Pause so a reader can finish one, by pointer or by keyboard. */
.quotes.is-marquee:hover .quotes-track,
.quotes.is-marquee:focus-within .quotes-track{animation-play-state:paused}
@keyframes sk-marquee{
  from{transform:translate3d(0,0,0)}
  to{transform:translate3d(calc(-50% - 8px),0,0)}   /* one copy + half the gap */
}

/* No clone, no animation -- reduced motion, or JS off. It is then just a row
   that overflows, so let people drag it. */
.quotes:not(.is-marquee){overflow-x:auto;scrollbar-width:none}
.quotes:not(.is-marquee)::-webkit-scrollbar{display:none}

/* ==========================================================================
   FAQ — native details/summary, no JS, keyboard and screen-reader safe
   ========================================================================== */

/* Each question is its own panel rather than a hairline row, and opening one
   tints it. As plain rows in grey-on-white-on-black it read as a support
   page, not an invitation. The open state used to carry a gradient bar down
   the left edge as well, which was one signal too many next to the tint and
   the border. */
.faq{margin-top:44px;display:flex;flex-direction:column;gap:10px}
.faq details{
  border:1px solid var(--sk-line);
  border-radius:var(--sk-r-tile);
  background:var(--sk-panel);
  position:relative;overflow:hidden;
  transition:border-color .2s,background .2s;
}
.faq details:hover{border-color:rgba(252,76,210,.34)}
.faq details[open]{
  border-color:rgba(252,76,210,.42);
  background:
    linear-gradient(90deg, rgba(116,36,246,.10), transparent 42%),
    var(--sk-panel-2);
}

.faq summary{
  display:flex;align-items:center;justify-content:space-between;gap:20px;
  padding:22px 24px;cursor:pointer;list-style:none;
  font-size:clamp(16px,1.8vw,19px);font-weight:600;color:var(--sk-ink-1);
  transition:color .2s;
}
.faq summary::-webkit-details-marker{display:none}
.faq details[open] summary{
  color:var(--sk-ink-1);
}
.faq summary .chev{
  flex:0 0 auto;color:var(--sk-ink-3);transition:transform .25s,color .25s;
}
.faq details[open] summary .chev{transform:rotate(135deg);color:var(--sk-pink)}
.faq .answer{margin:0;padding:0 24px 24px;color:var(--sk-ink-2);max-width:72ch}
.faq .answer a{color:var(--sk-pink);text-underline-offset:3px}

/* ==========================================================================
   Supra + close + footer
   ========================================================================== */


.close{
  position:relative;
  isolation:isolate;
  overflow:hidden;
  text-align:center;
  /* Near full-height, so arriving at the end of the page is arriving
     somewhere rather than reaching the last block. Capped in px as well, so
     it does not become a scroll marathon on a very tall window, and it can
     still grow past that if the content needs it.
     The bottom padding is lighter than the top: the footer follows straight
     on, and matching the top left an empty band above it that read as
     footer and was just extra scroll. */
  min-height:min(80vh, 760px);
  display:flex;
  align-items:center;
  padding:clamp(110px,14vw,180px) 0 clamp(64px,7vw,96px);
}
/* The wrap is a flex item now, so it has to be told to fill the line. */
.close .wrap{width:100%}
/* Photographic galaxy behind the closing CTA.

   Parallax is background-attachment:fixed rather than a transform on a
   scroll handler, and that is a correction worth recording. The transform
   version moved the layer about 100px across the whole scroll, which is
   invisible. Getting real travel out of it meant making the layer hundreds
   of pixels taller than the section, and because the background covers that
   oversized box, it zoomed deep into the middle of the image and brought the
   blur back. Fixed attachment sizes the image to the viewport instead: the
   sky holds still, the section scrolls over it, no oversized layer and no
   zoom.

   Nothing in this section may carry a transform, a filter or
   will-change:transform. Any of them makes an ancestor a containing block
   for fixed backgrounds, and the sky silently starts scrolling along.

   Served as JPEG, not PNG: a full-bleed photograph with no transparency.
   2560px wide so it stays sharp on a 2x display, and still only 71KB because
   a calm sky compresses well. */
.close-sky{position:absolute;inset:0;z-index:-2;pointer-events:none}
.close-sky .sky{
  position:absolute;inset:0;
  background:url(assets/art/sky.jpg?v=6) center center no-repeat;
  background-attachment:fixed;
  /* The push-in is driven by background-size, NOT by a transform. A transform
     here would make this element a containing block for its own fixed
     background and the parallax would quietly die. Changing the size does not.

     max(100vw, 100vh * --sky-ar) is the cover width for a fixed background,
     worked out by hand because `cover` cannot be multiplied. The positioning
     area of a fixed background is the viewport, so vw/vh are the right units.
     1.02 keeps a hairline of slack for the scrollbar. */
  --sky-ar:1.785;   /* 2560 / 1434 */
  --sky-zoom:1;
  background-size:calc(max(100vw, 100vh * var(--sky-ar)) * 1.02 * var(--sky-zoom)) auto;
}
/* iOS Safari handles fixed attachment badly, and it is the wrong effect on a
   phone anyway. Same 700px line the rest of the page's motion uses. Back to
   plain cover here: with scroll attachment the positioning area is the
   element, so the viewport-unit maths above no longer describes it. */
@media (max-width:700px){
  .close-sky .sky{background-attachment:scroll;background-size:cover}
}

/* The photo now runs at full brightness: no wash over it, no pool behind the
   copy. The only overlay left is a short fade at the very top and bottom so
   the frame does not butt-join the void above and below it.

   That puts the burden of legibility on the artwork, which is why the sky was
   regenerated calm in the first place. If a future, busier sky goes in here,
   the copy will need its own local contrast again rather than a wash over the
   whole frame -- darkening everything is what flattened the earlier one into
   a dirty screen. */
.close::before{
  content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,
    var(--sk-void) 0%,
    transparent 14%,
    transparent 86%,
    var(--sk-void) 100%);
}

.close .wrap{position:relative;z-index:1}
/* The maker's credit. Small, quiet, after the ask. */
.signoff{
  margin:clamp(30px,4vw,44px) auto 0;
  max-width:52ch;
  font-size:13px;
  line-height:1.6;
  /* ink-2 rather than ink-3: this one sits on a photograph, not flat panel. */
  color:var(--sk-ink-2);
}
/* Carries .h1 and .hl in the markup, so it inherits the hero's axes, casing
   and gradient. Sized a step above the hero: this is the last thing on the
   page and it is the ask. Transform on it is safe because it is the element
   that owns the gradient, not a descendant. */
.close h2{font-size:clamp(42px,7.4vw,92px);max-width:none}

/* Arrives the way the scroll sequence's payoff line does: oversized and
   over-tracked, settling into place. Same reasoning as there, and the same
   nowrap requirement, since at the starting track the line is wider than its
   column and would otherwise rewrap mid-animation and snap back.

   Only above 700px. At phone widths the headline is already at its minimum
   size and nowrap pushes it past the viewport, where .close's overflow:hidden
   clips it mid-word. Below that it uses the page's ordinary reveal and wraps
   normally. */
@media (min-width:701px){
  .reveal-ready .close h2{
    white-space:nowrap;
    letter-spacing:.13em;
    transform:translateY(24px) scale(1.06);
    transform-origin:50% 100%;
    transition:
      opacity .5s ease,
      letter-spacing .85s cubic-bezier(.16,.84,.26,1),
      transform .85s cubic-bezier(.16,.84,.26,1);
    transition-delay:var(--reveal-delay,0ms);
  }
  .reveal-ready .close h2.is-in{
    letter-spacing:-.005em;
    transform:none;
  }
}
.close .cta-row{justify-content:center;margin-top:clamp(28px,3.4vw,40px)}
/* The hero tagline, repeated as a subhead under the close headline.

   Borrows h2's type settings rather than being an h2, because the section
   already has its heading and a second one would be wrong in the outline.
   Held a step below the real h2 scale so the pink headline above it stays
   the largest thing in the section. */
.close-tag{
  margin:clamp(14px,1.8vw,22px) auto 0;
  font-variation-settings:'wdth' var(--sk-h2-wdth),'wght' var(--sk-h2-wght),'opsz' 32;
  font-weight:900;
  text-transform:uppercase;
  letter-spacing:-.005em;
  line-height:1.02;
  font-size:clamp(22px,3.2vw,40px);
  color:var(--sk-ink-1);
  max-width:20ch;
  text-wrap:balance;
}
.close .blurb{margin-left:auto;margin-right:auto}

.footer{border-top:1px solid var(--sk-line);padding:26px 0 30px;font-size:13px}
/* A single bar: mark, the legal line, the two links that matter and the
   social icons, all on one baseline. Everything aligns to centre rather than
   flex-start, which is what made the old three-block version look unaligned. */
.footer-bar{
  display:flex;align-items:center;gap:clamp(14px,2vw,28px);
  flex-wrap:wrap;
}
.footer-bar .legal{margin:0;color:var(--sk-ink-3)}
.footer-bar nav{margin-left:auto}
/* Negative margin cancels the links' own padding, so the ICONS keep the 14px
   optical gap they had while each link's touch area is 44px. Without this the
   row would visually spread by the padding on both sides. */
/* The padding on each link IS the spacing now, so gap is 0 and the negative
   margin pulls the row back flush right and stops the padding adding height
   to the footer bar. 7px a side puts 14px between adjacent icons, which is
   exactly the gap the row had before it was made tappable. */
.footer .social{display:flex;align-items:center;gap:0;margin:-12px -7px -12px 0}
.footer .social a{
  display:inline-flex;align-items:center;justify-content:center;color:var(--sk-ink-3);
  transition:color .16s ease,transform .16s ease;
  /* Touch area around a ~15px icon. 7px horizontally keeps the icons at the
     14px rhythm the row was designed with; 12px vertically takes the target
     over WCAG 2.2's 24px floor without the wide Discord box forcing the
     footer bar taller. Padding rather than width/height, so the box grows
     around whatever the optical sizing below settles on. */
  padding:12px 7px;
}
.footer .social a:hover{color:var(--sk-ink-1);transform:translateY(-1px)}
/* Optically sized, not matched boxes. Same problem the chain marks have and
   the same fix: these three glyphs fill their 24x24 viewBoxes very
   differently, so one shared width makes them read as three different sizes.

   Measured ink at a 16px box, via getBBox():
     X         97.9% wide x 100%  tall  -> 16.4px of ink. Reads BIG: it is a
                                          dense glyph running edge to edge.
     Telegram  100%        x 100%  tall  -> 16.4px, but a disc, so the corners
                                          are empty and it reads mid.
     Discord   100%        x  76.2% tall -> 12.5px. Reads SMALL: the mark is
                                          inherently wide and short.

   --si is the per-icon factor that lands them all on ~15.4px of visible ink.
   If you swap an icon, measure it the same way rather than guessing. */
.footer .social svg{
  width:calc(16px * var(--si,1));
  height:calc(16px * var(--si,1));
  display:block;
}
.footer .social .is-x{--si:.94}        /* dense square glyph, pull it in */
.footer .social .is-telegram{--si:.97} /* disc, near the middle already */
.footer .social .is-discord{--si:1.23} /* wide and short, push it out */
.footer .logo svg{height:26px;width:auto;opacity:.85}
.footer nav{display:flex;gap:20px;flex-wrap:wrap}
.footer a{color:var(--sk-ink-3);text-decoration:none;transition:color .16s}
.footer a:hover{color:var(--sk-ink-1)}

/* ==========================================================================
   Capability showcase — the main selling point

   Sticky two-column stage. The list advances on the left while the phone
   swaps screens on the right. Same scroll model as the hero sequence:
   a tall section with a pinned stage, progress read from scroll position,
   never scroll-jacked.
   ========================================================================== */

.showcase{position:relative;height:500vh}
/* Narrower than the page wrapper on purpose. At full width the phone and the
   copy sat at opposite edges of the viewport and read as two separate things.
   Phone on the left, copy left-aligned beside it, both near the centre. */
.showcase-sticky{
  position:sticky;top:0;min-height:100vh;
  /* Explicit width on the phone column. With `auto` the column sizes to its
     content while .phone sizes to a percentage of the column, which is
     circular and collapses the track to nothing. */
  display:grid;grid-template-columns:clamp(280px,36vw,470px) 1fr;
  gap:clamp(24px,3vw,44px);
  align-items:center;justify-content:center;
  max-width:1040px;margin:0 auto;padding:0 var(--sk-gutter);
}

/* Step nav. Doubles as the progress indicator, so there is no separate bar. */
.showcase-nav{
  list-style:none;margin:0 0 clamp(24px,3vw,38px);padding:0;
  display:flex;gap:26px;flex-wrap:wrap;
}
.showcase-nav li{
  font-variation-settings:'wdth' var(--sk-label-wdth),'wght' var(--sk-label-wght);
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--sk-ink-3);position:relative;padding-bottom:8px;
  transition:color .35s ease;
}
.showcase-nav li::after{
  content:'';position:absolute;left:0;bottom:0;height:2px;width:0;
  background:var(--sk-signature);border-radius:2px;
  transition:width .45s cubic-bezier(.2,.8,.3,1);
}
.showcase-nav li.is-on{color:var(--sk-ink-1)}
.showcase-nav li.is-on::after{width:100%}
/* The item is a button so it can be clicked and tabbed to. All the styling
   stays on the li, which owns the underline, so the button is stripped back
   to bare text that inherits everything. */
.showcase-nav button{
  appearance:none;-webkit-appearance:none;
  background:none;border:0;padding:0;margin:0;
  font:inherit;letter-spacing:inherit;text-transform:inherit;
  font-variation-settings:inherit;color:inherit;
  cursor:pointer;
}
.showcase-nav li:hover{color:var(--sk-ink-2)}

/* Panels share one grid cell, so only one is visible and the column does
   not resize as they swap. */
.showcase-panels{display:grid}
.showcase-panel{
  grid-area:1/1;
  pointer-events:none;
}
/* The panel itself no longer moves. It flips visibility for its children and
   they arrive in sequence: icon, title, blurb, button.

   The delay lives in the .is-on rule, not the base rule, so it applies on the
   way in only. With it on the base rule the outgoing panel staggers out as
   well, and the swap reads as a lag rather than a handover.

   The title gets its own move, a little more travel and a touch of scale, so
   it lands as the thing the panel is about rather than as the second row of a
   list. Scale rather than tracking: these panels re-animate on every pass
   through the section, and letter-spacing relayouts every frame. */
.showcase-panel.is-on{pointer-events:auto}

.showcase-panel > *{
  opacity:0;
  transform:translateY(16px);
  transition:
    opacity .4s ease,
    transform .5s cubic-bezier(.2,.8,.25,1);
}
.showcase-panel.is-on > *{
  opacity:1;
  transform:none;
  transition-delay:var(--panel-delay,0ms);
}
.showcase-panel .ti{--panel-delay:40ms}
.showcase-panel h2{
  --panel-delay:120ms;
  transform:translateY(22px) scale(1.05);
  transform-origin:0 50%;
  transition:
    opacity .45s ease,
    transform .65s cubic-bezier(.18,.84,.26,1);
}
.showcase-panel p{--panel-delay:260ms}
.showcase-panel .btn{--panel-delay:360ms}

/* One word, so it can carry far more size than a normal section heading. */
.showcase-panel h2{
  font-variation-settings:'wdth' var(--sk-h1-wdth),'wght' var(--sk-h1-wght),'opsz' 36;
  font-size:clamp(46px,6.6vw,92px);
  line-height:.92;
  max-width:none;
  margin:0 0 18px;
}
.showcase-panel p{
  margin:0;font-size:clamp(16px,1.7vw,19px);line-height:1.55;
  color:var(--sk-ink-2);max-width:46ch;
}
.showcase-panel .ti{color:var(--sk-lilac);margin-bottom:18px}
/* Availability footnote inside a panel. Its own stagger delay so it lands
   between the body copy (260ms) and the CTA (360ms) instead of arriving on
   top of the paragraph it qualifies. Two classes so it beats .showcase-panel
   p, which sets the body size and zero margin. */
.showcase-panel .panel-note{
  --panel-delay:310ms;
  margin:14px 0 0;
  font-size:13px;
  line-height:1.5;
  color:var(--sk-ink-3);
  max-width:46ch;
}
/* A CTA per panel. A single button under the section read as floating,
   because by then the reader has scrolled past the thing it belonged to.
   Ghost rather than primary: four filled buttons down one section was the
   same ask four times over, and the section's job here is to explain.

   Full .btn size, not .btn-sm. These used to be small, which read as a
   tertiary link next to a 92px heading. Quiet is the job of the ghost
   treatment; small was just hard to hit. */
.showcase-panel .btn{margin:26px 0 0}

/* A light travelling around the button's outline. The panel CTA is a quiet
   ghost button by design, and this gives the eye something to catch without
   turning it back into a second primary.

   Built as a ring rather than a glow: a conic gradient on a pseudo-element,
   masked so only the 1px border shows. Two mask layers subtracted, the same
   technique as the Supra disc in the chain strip.

   The angle is a registered custom property, which is what makes it
   animatable at all: a plain --angle in a conic-gradient interpolates as a
   string and simply jumps. Where @property is unsupported the gradient still
   renders, it just sits still, which is a static pink accent rather than a
   broken button.

   Scoped to the showcase panels on purpose. The other ghost buttons on the
   page are destinations, not the repeated CTA this section leans on. */
@property --sk-sheen{
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}
.showcase-panel .btn-ghost{
  position:relative;
  /* Pink label rather than white. 6.7:1 on the section's background, so it
     clears AA for body text at this size, not only for large text. */
  color:var(--sk-pink);
}
.showcase-panel .btn-ghost::before{
  content:'';
  position:absolute;
  inset:0;
  border-radius:inherit;
  padding:1px;
  background:conic-gradient(
    from var(--sk-sheen),
    transparent 0deg,
    transparent 230deg,
    rgba(252,76,210,.85) 292deg,
    rgba(251,248,255,.55) 322deg,
    transparent 360deg);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite:exclude;
  animation:sk-sheen 4.5s linear infinite;
  pointer-events:none;
}
@keyframes sk-sheen{ to{ --sk-sheen:360deg } }
/* Hovering already lights the whole border, so the travelling light would
   just be noise on top of it. */
.showcase-panel .btn-ghost:hover::before{opacity:0}


/* The showcase artwork. Five renders of the same phone with different props
   around it, crossfaded as the panel advances. The device is registered to
   the same spot in every frame, so the phone appears to stand still while the
   objects beside it change.

   Everything happens to the LEFT of the phone in every render, because the
   copy column sits to the right of this one. If these are ever regenerated,
   that constraint has to hold or the artwork will crowd the text.

   The old CSS phone frame and its .ph-* placeholder screens are gone: the
   phone is inside the artwork now. .phone-glow went with them, which also
   fixes the 14px horizontal overflow it caused at 375px. */
.phone-wrap{display:flex;justify-content:center;align-items:center;position:relative}
.shots{position:relative;width:100%;aspect-ratio:832/1041}
.shot{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:contain;
  opacity:0;
  transition:opacity .5s ease;
}
.shot.is-on{opacity:1}

/* Stacked-layout copy of the artwork, one per panel.
   The pinned layout keeps all four in .shots and crossfades them in the left
   column. Once the section unpins, that column is gone and every panel is on
   screen at once, so a single crossfading image would strand three panels
   without art. These carry the same src, so they cost a cache hit rather
   than a download.

   They live inside the panel rather than replacing .shots outright because
   .showcase-panel carries a transform, which would make it the containing
   block and drag the artwork through the panel's slide. */
.panel-shot{display:none}

/* ==========================================================================
   Section artwork — earn and chains

   Both are original illustrations built from brand primitives, not stock
   and not generated. They are placeholders in the sense that a product
   screenshot would be better, but they are finished enough to ship.
   ========================================================================== */

/* Section artwork floats directly on the page: no panel, no border, no
   background.

   The PNGs carry real alpha, keyed from the renders' black background, so no
   blend mode is needed. mix-blend-mode was tried first and does not work
   here: it blends only within its own stacking context, and .wrap creates one,
   so the artwork's black stayed visible as a box. */
.art-earn,.art-chains,.art-devices{
  position:relative;
  display:flex;align-items:center;justify-content:center;
}
.art-earn img,.art-chains img,.art-devices img{
  width:100%;height:auto;
}
.art-earn img{max-width:430px}
.art-chains img{max-width:480px}

/* Chain logos sit in the five blank tokens of the constellation render.
   Positioned as percentages of the image, so they track it at any size.
   Real vendor SVGs, not generated: an earlier render invented its own
   near-miss versions of these marks, which is why the tokens were left
   empty. Forced to white with a filter so five logos from four different
   sources read as one set on the dark tokens. */
/* The container must shrink-wrap the render. The logos are positioned as
   percentages of THIS box, so if it is wider than the image they drift
   outward in proportion to their distance from the centre. */
.art-chains{position:relative;width:min(480px,100%);margin-inline:auto}
/* The marks are part of the render now, not overlaid. The five chain logos
   and the centre StarKey mark used to be SVGs positioned on top of a blank
   render; they were generated into the artwork instead so they carry the
   same chrome, highlights and reflections as the tokens they sit in.
   chains-ALT-svg-overlays.png is the blank-token version if that is ever
   wanted back, along with the .chain-logo coordinates in git history. */
.art-chains img{width:100%;max-width:none}
/* This one leads its section rather than sitting under the headline, so the
   space goes below it. Smaller than it was: at 820px it took 551px of height
   on its own and pushed the headline and the tiles more than a screen apart. */
/* Pulled up rather than spaced out. The render carries about 36px of its own
   glow falloff below the laptop at this size, so a normal margin on top of
   that read as a hole between the artwork and the headline. The negative
   value eats part of that padding instead of adding to it. Cropping the glow
   out of the PNG would leave a hard edge; it fades too gently for that. */
.art-devices{margin:0 0 clamp(-24px,-1.5vw,-4px)}
.art-devices img{max-width:660px}

/* Slow float, so the artwork is not completely static. Cheap: one transform.
   The chains version animates the CONTAINER, not the image. The logos are
   .art-chains img too, so animating that selector overwrites the
   translate(-50%,-50%) that centres them on their tokens and they drift
   down-right. Animating the container also keeps them locked to the render. */
.art-earn img{animation:float 7s ease-in-out infinite}
.art-chains{animation:float 9s ease-in-out infinite}
@keyframes float{
  0%,100%{transform:translateY(0)}
  50%{transform:translateY(-10px)}
}

/* Two-up layout for sections that pair copy with artwork */
.split{
  display:grid;grid-template-columns:0.92fr 1fr;gap:clamp(22px,2.6vw,40px);
  align-items:center;margin-top:48px;
}
.split.reverse .split-art{order:-1}

/* ==========================================================================
   Security — restructured. One headline, one blurb, a full-width video,
   then three tiles. The previous version nested a second title and blurb
   inside the section, which is what made it read as dense.
   ========================================================================== */

.video-wide{
  margin-top:clamp(36px,5vw,56px);
  border-radius:var(--sk-r-panel);
  overflow:hidden;
  border:1px solid var(--sk-line);
  position:relative;
  aspect-ratio:16/9;
  background:var(--sk-void);
  box-shadow:0 50px 120px -60px rgba(252,76,210,.55);
}
.video-wide img{width:100%;height:100%;object-fit:cover}
.video-wide iframe{position:absolute;inset:0;width:100%;height:100%;border:0}

/* ==========================================================================
   Store badges

   Apple and Google both require their own official badge artwork with
   fixed proportions and clear space; keep to those assets when changing
   these.
   ========================================================================== */

.store{
  display:inline-flex;align-items:center;gap:11px;
  background:#000;border:1px solid rgba(255,255,255,.22);
  border-radius:11px;padding:9px 16px;text-decoration:none;
  transition:border-color .16s,transform .16s;
  min-width:180px;
}
.store:hover{border-color:rgba(255,255,255,.45);transform:translateY(-2px)}
.store svg{flex:0 0 auto;color:#fff}
.store .txt{display:flex;flex-direction:column;line-height:1.15;color:#fff}
.store .txt small{font-size:9px;letter-spacing:.06em;opacity:.8;text-transform:uppercase}
.store .txt strong{font-size:15px;font-weight:600}

/* --- Download rows in the closing section ------------------------------
   This section is now the only place on the page that answers "how do I get
   it", so it carries the real destinations rather than one more button.

   Browser marks are monochrome on purpose. Four full-colour logos over a
   photographic galaxy is four competing focal points, and the section's own
   focal point is the headline. */
.getrow{margin-top:30px}
.getlabel{
  margin:0 0 12px;
  font-size:12px;letter-spacing:.14em;text-transform:uppercase;
  font-variation-settings:'wdth' var(--sk-label-wdth),'wght' var(--sk-label-wght);
  color:var(--sk-ink-3);
}
/* --- Agents section head ----------------------------------------------
   The only section with no product to show, so it carried a short headline
   across a full-width block and read flat. The render fills the right side.

   Deliberately smaller than the other section artwork: it is a garnish on a
   Coming soon block, not the subject of it, so it must not out-weigh the
   three tiles underneath that carry the actual content. */
/* Fixed text column, not a fraction.

   With fractional columns the text side was 683px wide while the blurb caps
   at 548px for readability and the headline at 78% of its box -- so 144px of
   the gap between copy and render was dead space INSIDE the text column,
   before the grid gap even started. Measured 183px from the end of the blurb
   to the edge of the image. Sizing the column to the copy it actually holds
   is what closes that; widening the gap or nudging the image does not. */
.agents-head{
  display:grid;grid-template-columns:minmax(0,560px) 1fr;
  gap:clamp(20px,3vw,48px);align-items:center;
}
.agents-head .section-head{margin:0}
/* The 78% cap is for a full-width head. Here the column is already the
   constraint, so the cap only pulls the headline in further. */
.agents-head .section-head h2{max-width:none}
/* Left-aligned, not centred: centred in its column it drifted out toward the
   page edge and read as unrelated to the headline it belongs to. Larger than
   before, so the space it was freed from does not just reopen on its right. */
.agents-art{justify-self:start;max-width:400px}
.agents-art img{width:100%;height:auto;display:block}

@media (max-width:860px){
  /* Stacks below the copy rather than above it. Above, it would push the
     headline down the screen for a section the reader has not been sold on
     yet. */
  .agents-head{grid-template-columns:1fr;gap:28px}
  /* Centred, and justify-self overridden. The desktop rule left-aligns it so
     it reads as belonging to the headline beside it; stacked there is no
     headline beside it, and start-alignment left the wallet hard against the
     gutter with most of the row empty (measured 0px left, 335px right at
     390px wide). */
  .agents-art{max-width:230px;justify-self:center}
}

.bicons{display:flex;flex-wrap:wrap;justify-content:center;gap:10px}
.bicon{
  display:inline-flex;flex-direction:column;align-items:center;gap:8px;
  width:92px;padding:16px 8px 14px;
  border:1px solid var(--sk-line);border-radius:var(--sk-r-tile);
  background:rgba(11,10,18,.55);
  text-decoration:none;color:var(--sk-ink-2);
  transition:border-color .16s,color .16s,transform .16s,background .16s;
}
.bicon svg{width:28px;height:28px}
.bicon span{font-size:13px;font-weight:600}
.bicon:hover{
  border-color:var(--sk-pink);color:var(--sk-ink-1);
  background:rgba(252,76,210,.08);
  transform:translateY(-2px);
}
.badges{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;gap:12px}
/* Official store badges. The files are the stores' own artwork and must not be
   restyled -- no filters, borders or recolouring -- so only the link moves. */
.store-badge{display:inline-block;border-radius:8px;transition:transform .2s ease}
.store-badge:hover{transform:translateY(-2px)}
.store-badge img{display:block;height:48px;width:auto}

@media (max-width:560px){
  .bicon{width:calc(50% - 5px);flex-direction:row;justify-content:center;padding:14px 8px}
  .store{min-width:0;flex:1 1 160px;justify-content:center}
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width:1000px){
  :root{--sk-section:88px}

  /* The 78% measure exists to stop headings running the full width of a
     wide desktop column. On a narrow column it just wastes space and adds
     lines, so headings take the full width here. */
  .section-head h2{max-width:none}

  .tiles,.steps,.platforms{grid-template-columns:repeat(2,1fr)}
  /* Two up rather than four: at four across the numerals shrink to the size
     of their own labels and stop reading as the headline figures they are. */
  .numgrid{grid-template-columns:repeat(2,1fr);gap:26px 20px}
  /* Three figures in two columns would leave a hole, so the lead figure
     takes the full first row (/partners). */
  .numgrid-lead > li:first-child{grid-column:1 / -1}
  /* Card stacks, artwork leads. Same order as .split.reverse elsewhere. */
  .partners-card{grid-template-columns:1fr;gap:28px}
  .partners-art{order:-1;margin:0}
  .partners-art img{max-width:260px}
  .feature{grid-template-columns:1fr;gap:32px;padding:28px}
  /* ---- Mobile menu -------------------------------------------------
     The links used to be `display:none` here with nothing in their place,
     so every section anchor -- Agents included -- was unreachable on a
     phone.

     Same <nav> as the desktop one, revealed as a panel under the header
     rather than duplicated, so the scroll spy keeps working and the two
     menus cannot drift apart.

     The panel is display:none when closed rather than just transparent:
     a hidden-but-present menu is still in the tab order and still read by
     screen readers, which is the classic accessible-menu bug. */
  .nav-toggle{
    display:inline-flex;align-items:center;justify-content:center;
    /* FLUSH LEFT, before the logo.

       It used to carry margin-left:auto -- but .nav .btn carries one too, so
       the two autos split the free space between them and the burger came to
       rest stranded in the middle of the bar. Order instead of margin: the
       DOM stays logo -> toggle -> nav -> Download, so the desktop tab order
       is untouched and only the visual order changes here.

       -12px left margin cancels the button's own padding so the BARS line up
       with the page gutter, not the invisible edge of the tap target. */
    order:-1;
    width:44px;height:44px;margin-left:-12px;
    background:none;border:0;padding:0;cursor:pointer;color:var(--sk-ink-1);
  }
  /* The logo follows the toggle and the Download button still takes the right
     edge, so the bar reads burger / logo ......... Download. */
  .nav .logo{order:0}
  .nav .btn{order:1;margin-left:auto}
  /* Three bars drawn from one element: the bar itself plus its two
     pseudo-elements, so the markup stays a single empty span. */
  .nav-burger,
  .nav-burger::before,
  .nav-burger::after{
    display:block;width:19px;height:1.5px;border-radius:2px;
    background:currentColor;
    transition:transform .24s ease,opacity .18s ease;
  }
  .nav-burger{position:relative}
  .nav-burger::before,.nav-burger::after{content:'';position:absolute;left:0}
  .nav-burger::before{top:-6px}
  .nav-burger::after{top:6px}
  /* Open: the middle bar fades and the outer two cross into an X. They are
     translated to the centre first, or they rotate about their own offset
     positions and the X sits lopsided. */
  [aria-expanded="true"] .nav-burger{background:transparent}
  [aria-expanded="true"] .nav-burger::before{transform:translateY(6px) rotate(45deg)}
  [aria-expanded="true"] .nav-burger::after{transform:translateY(-6px) rotate(-45deg)}

  .nav-inner{flex-wrap:wrap;gap:0 16px}
  .nav-links{
    display:none;
    /* Full width of the header, below the logo row. */
    order:3;flex-basis:100%;
    flex-direction:column;align-items:stretch;
    gap:0;margin:0;
    padding:6px 0 10px;
    border-top:1px solid var(--sk-line);
  }
  .nav-links.is-open{display:flex}
  .nav-links a{
    font-size:16px;
    /* Full-width rows: the whole line is the target, not just the words. */
    padding:13px 2px;
  }
  /* The desktop separator is a vertical sliver; in a stacked list it reads
     as a stray mark. The Docs row gets a top border instead, which does the
     same job in this direction. */
  .nav-sep{display:none}
  .nav-ext{padding-top:15px;border-top:1px solid var(--sk-line)}
  .split{grid-template-columns:1fr;gap:36px}
  .split.reverse .split-art{order:0}

  /* Showcase unpins. The phone leads, then all four panels read as a
     stacked list rather than one at a time. */
  .showcase{height:auto;padding:var(--sk-section) 0}
  .showcase-sticky{position:static;min-height:0;grid-template-columns:1fr;gap:40px}
  .phone-wrap{order:-1}
  .showcase-nav{display:none}
  .showcase-panels{display:flex;flex-direction:column;gap:44px}
  .showcase-panel{opacity:1;transform:none;pointer-events:auto}
  .showcase-panel > *,
  .showcase-panel h2{opacity:1;transform:none}
  .showcase-panel h2{font-size:clamp(38px,11vw,56px)}
  .phone-wrap{display:none}
  .panel-shot{display:block;width:100%;max-width:420px;height:auto;margin:0 auto 4px}
}

/* The hero needs roughly 400px for the copy and 270px for the phone, so it
   collapses before the other two-column layouts do. */
@media (max-width:820px){
  .hero-grid{grid-template-columns:1fr;gap:40px}
  /* Centred once the grid is one column. It used to be flex-start, which is
     right beside a copy column but leaves the phone jammed against the left
     gutter with dead space to its right when the layout stacks. */
  .hero-shot{justify-content:center}
  .hero-shot img{height:clamp(340px,70vw,460px)}
}

@media (max-width:640px){
  :root{--sk-section:68px;--sk-gutter:20px}
  .tiles,.steps,.platforms{grid-template-columns:1fr}
  .cta-row .btn,.cta-block .btn{width:100%}
  .banner-inner{font-size:13px}

  /* The bar cannot be one line at this width. Stack it left-aligned with even
     gaps rather than letting margin-left:auto strand the links on their own
     row away from everything else. */
  .footer-bar{gap:14px}
  .footer-bar nav{margin-left:0;width:100%}
  .footer-bar .legal{width:100%}

  /* The showcase does not pin on small screens. Pinned parallax is where
     these sections break on mid-range phones, and a large share of a wallet
     audience is on mid-range Android. Static stack instead. */
  .seq{height:auto;padding:68px 0}
  .seq-stage{position:static;height:auto;padding:0 var(--sk-gutter)}
  /* No colour on .resolve or its spans here. They carry .hl, which needs
     color:transparent for the gradient to show through the text. */
  .beat,.resolve,.resolve > span,.seq-cta{opacity:1;transform:none;filter:none}
  .resolve > span{white-space:normal;letter-spacing:inherit}
  .beat{color:var(--sk-ink-2)}
  .seq-glow{opacity:1}
}

/* Reduced motion: no pinning, no transitions, resolved state shown at once.
   The copy is real content, so it must be readable without any animation. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms!important;
    animation-iteration-count:1!important;
    transition-duration:.001ms!important;
  }
  .seq{height:auto;padding:var(--sk-section) 0}
  .seq-stage{position:static;height:auto}
  .beat{opacity:1;color:var(--sk-ink-2);transform:none;filter:none}
  .resolve,.resolve > span,.seq-cta{opacity:1;transform:none;filter:none}
  .resolve > span{white-space:normal;letter-spacing:inherit}
  .seq-glow{opacity:1}

  .showcase{height:auto;padding:var(--sk-section) 0}
  .showcase-sticky{position:static;min-height:0}
  .showcase-nav{display:none}
  .showcase-panels{display:flex;flex-direction:column;gap:44px}
  .showcase-panel{opacity:1;transform:none;pointer-events:auto}
  .showcase-panel > *,
  .showcase-panel h2{opacity:1;transform:none}
  .phone-wrap{display:none}
  .panel-shot{display:block;width:100%;max-width:420px;height:auto;margin:0 auto 4px}
  .coin,.chain-node{animation:none}
  .showcase-panel .btn-ghost::before{display:none}
}

/* No JavaScript: the sequence must still read as content. */
.no-js .seq{height:auto;padding:var(--sk-section) 0}
.no-js .seq-stage{position:static;height:auto}
.no-js .beat{opacity:1;color:var(--sk-ink-2);transform:none;filter:none}
.no-js .resolve,.no-js .resolve > span,.no-js .seq-cta{opacity:1;transform:none;filter:none}
.no-js .resolve > span{white-space:normal;letter-spacing:inherit}
.no-js .showcase{height:auto;padding:var(--sk-section) 0}
.no-js .showcase-sticky{position:static;min-height:0}
.no-js .showcase-nav{display:none}
.no-js .showcase-panels{display:flex;flex-direction:column;gap:44px}
.no-js .showcase-panel{opacity:1;transform:none;pointer-events:auto}
.no-js .showcase-panel > *,
.no-js .showcase-panel h2{opacity:1;transform:none}
.no-js .phone-wrap{display:none}
.no-js .panel-shot{display:block;width:100%;max-width:420px;height:auto;margin:0 auto 4px}

/* ==========================================================================
   Subpages — /sui, /privacy, /terms

   These reuse the homepage shell wholesale: same nav, same footer, same
   tokens, same .tile / .step / .section-head components. Only the pieces
   below are new, and they exist because a subpage opens on a heading rather
   than on a hero with artwork beside it.
   ========================================================================== */

/* No phone shot to balance against, so the hero is a single measured column
   rather than a two-up grid. Narrower than the page, because a headline the
   full width of .wrap with nothing beside it reads as a stretched banner. */
.page-hero{padding:clamp(56px,8vw,104px) 0 clamp(10px,2vw,24px)}
/* 22ch, not 16: the Sui page's headline has a 20-character line in it and
   a tighter measure broke it into four. */
.page-hero .h1{max-width:22ch}
.page-hero .lead{max-width:62ch;margin-top:22px}
/* The deadline, sitting between the H1 and the lead. A heading in the
   outline, but typographically between the two: large enough to be read
   before the paragraph, quiet enough not to compete with the H1 above it. */
.hero-sub{
  margin:18px 0 0;
  /* Sentence case, against the H1's uppercase. Two uppercase blocks stacked
     read as one shouted paragraph, and this line is the calm statement of
     fact under the headline. */
  text-transform:none;
  letter-spacing:0;
  font-size:clamp(18px,2.2vw,26px);
  line-height:1.3;
  font-variation-settings:'wdth' 110,'wght' 620;
  color:var(--sk-ink-1);
  max-width:32ch;
}
.hero-sub + .lead{margin-top:14px}
.page-hero .cta-row{margin-top:30px}

/* A dated, time-bound marker. Amber rather than the default pill, so a
   deadline does not read like a feature badge. */
.pill-warn{
  border-color:rgba(254,191,78,.42);
  color:var(--sk-gold);
  background:rgba(254,191,78,.08);
}

/* Phone render on a subpage. Same treatment as the homepage hero shot, but
   it sits in a .split rather than the hero grid, so it needs its own cap --
   at full width it dwarfed the three points beside it. */
/* Copy on the left, art on the right, and the copy gets the larger share.
   The default .split is 0.92fr 1fr, which suits a wide render; a tall
   portrait phone given half the row just floats in its own whitespace. */
.split-copy{grid-template-columns:1fr 0.85fr;align-items:center}
.split-copy .section-head{margin:0}
/* The global 78% cap assumes a full-width section head. In a split column it
   is a second constraint on top of the column itself, and it was breaking a
   hard-wrapped two-line headline into three. */
.split-copy .section-head h2{max-width:none}
/* This rule lives AFTER the `@media (max-width:1000px){ .split{1fr} }` that
   collapses splits on narrow screens, and at the same specificity, so it was
   winning everywhere -- at 375px the row stayed two-up and squeezed the
   phone to 114px. It needs its own collapse. Anything else added down here
   that restyles a component defined further up has the same problem. */
@media (max-width:1000px){
  .split-copy{grid-template-columns:1fr}
}

/* hero-phone.png is NOT alpha-keyed -- it is a phone on a black rectangle,
   and on any background but pure black you can see the box. The homepage
   hero solves this with a radial mask rather than by re-keying the file,
   and this is the same mask. Do not swap it for mix-blend-mode: that blends
   only within its stacking context, and .wrap creates one.

   Sized by height, like the hero, so it reads as tall as the copy beside
   it. max-width:100% is the safety rail -- without it a height-driven
   portrait image happily overflows its grid column. */
.art-phone{display:flex;justify-content:center}
.art-phone img{
  height:clamp(420px,48vw,720px);
  width:auto;max-width:100%;
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 4%,#000 88%,transparent),
                     linear-gradient(to right,transparent,#000 18%,#000 82%,transparent);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(to bottom,transparent,#000 4%,#000 88%,transparent),
             linear-gradient(to right,transparent,#000 18%,#000 82%,transparent);
  mask-composite:intersect;
}
.art-phone img{width:100%;height:auto;display:block}

/* The safety panel.

   Deliberately the loudest block on the page. Everything else is a marketing
   argument; this is the part that stops somebody being robbed, and on a page
   whose whole request is "type your recovery phrase into our wallet" it has
   to outrank the sell. Gold rather than pink so it reads as a caution and
   not as brand. */
.warn{
  border:1px solid rgba(254,191,78,.3);
  border-radius:var(--sk-r-panel);
  background:linear-gradient(180deg, rgba(254,191,78,.05), rgba(254,191,78,.015));
  padding:clamp(26px,3.6vw,46px);
}
.warn h2{font-size:clamp(24px,3.2vw,40px);max-width:24ch;margin-bottom:16px}
.warn > p{margin:0;color:var(--sk-ink-2);max-width:66ch;font-size:16px;line-height:1.6}
.warn-list{
  margin:26px 0 0;padding:0;list-style:none;
  display:grid;gap:14px;max-width:72ch;
}
.warn-list li{
  position:relative;padding-left:26px;
  color:var(--sk-ink-2);font-size:15px;line-height:1.6;
}
.warn-list li::before{
  content:'';position:absolute;left:0;top:.55em;
  width:8px;height:8px;border-radius:50%;
  background:var(--sk-gold);
}
.warn-list strong{color:var(--sk-ink-1);font-weight:700}

/* --- Legal documents --------------------------------------------------
   Long-form prose, which nothing else on this site is. The homepage is
   built out of short blocks in wide containers; a privacy policy set the
   same way is unreadable, so this is the one place with a real measure and
   ordinary sentence case. */
/* The measure lives on the wrap, not on the text, so the hero and the policy
   share one centred column. A measure on the text alone left it pinned to
   the left of a 1180px wrap with the right half of the page empty. 680px is
   about 75 characters of the 15px body copy. */
.page-hero-doc .wrap,
.section-doc .wrap{max-width:calc(680px + 2 * var(--sk-gutter))}
/* The title may run past the column's right edge, out to the page gutter,
   so it stays on one line while its left edge still lines up with the text.
   Resolves to 0 once the viewport is no wider than the column. */
.page-hero-doc .h1{
  max-width:none;
  margin-right:min(0px, calc(340px + var(--sk-gutter) - 50vw));
}
.page-hero-doc .lead{max-width:none}
.section-doc{padding-top:clamp(20px,3vw,40px)}
.legal-doc h2{
  /* Sentence case, not the uppercase display treatment the marketing
     headings use. These are clause titles, not billboards. */
  text-transform:none;
  font-variation-settings:'wdth' 110,'wght' 750,'opsz' 20;
  font-size:clamp(19px,2vw,24px);
  line-height:1.25;
  letter-spacing:0;
  margin:clamp(36px,4vw,52px) 0 14px;
  max-width:none;
}
.legal-doc h2:first-child{margin-top:0}
.legal-doc p{
  margin:0 0 16px;
  font-size:15px;line-height:1.7;color:var(--sk-ink-2);
}
.legal-doc ul{
  margin:0 0 16px;padding:0;list-style:none;
  display:grid;gap:10px;
}
.legal-doc li{
  position:relative;padding-left:22px;
  font-size:15px;line-height:1.7;color:var(--sk-ink-2);
}
.legal-doc li::before{
  content:'';position:absolute;left:2px;top:.62em;
  width:6px;height:6px;border-radius:50%;
  background:var(--sk-lilac);opacity:.7;
}
.legal-doc strong{color:var(--sk-ink-1);font-weight:700}
.legal-doc a{color:var(--sk-pink);text-decoration:underline;text-underline-offset:3px}
.legal-doc a:hover{color:var(--sk-ink-1)}

/* An external link inside running prose, rather than in the nav. Same arrow
   treatment, but it has to sit on the text baseline and wrap with the
   sentence, so it cannot be the nav's inline-flex. */
.inline-ext{
  display:inline;
  color:var(--sk-pink);
  text-decoration:underline;text-underline-offset:3px;
  white-space:nowrap;
}
.inline-ext svg{
  display:inline-block;vertical-align:-1px;margin-left:5px;opacity:.6;
}
.inline-ext:hover{color:var(--sk-ink-1)}
.inline-ext:hover svg{opacity:1}

/* Reasons, not steps. .step is numbered and reads as an ordered procedure,
   which is wrong for a list of three independent points -- and the page
   already has a real numbered procedure further down. Full sentences, one
   per box, no fragment headings. */
.points{
  margin:26px 0 0;padding:0;list-style:none;
  display:grid;gap:10px;
}
.points li{
  display:flex;align-items:flex-start;gap:13px;
  padding:16px 20px;
  border:1px solid var(--sk-line);border-radius:var(--sk-r-tile);
  background:var(--sk-panel);
  font-size:15px;line-height:1.6;color:var(--sk-ink-2);
}
/* A real check rather than a bullet: these are things you get, not list
   items. Drawn as an inline SVG like every other icon on the site, not a
   text glyph -- the tick character renders at a different weight and
   baseline in every font it falls back to.

   flex-shrink:0 so it never squashes, and a small top nudge to sit on the
   first line's cap height instead of its box. */
.pt-check{
  flex:0 0 auto;
  margin-top:3px;
  color:var(--sk-pink);
}

/* Step number above the label instead of beside it.

   .step .num is a baseline-aligned flex ROW, which works for the homepage's
   one-word steps (Deposit / Hold / Use) and falls apart on longer ones: the
   label wraps to a second line while the small number stays pinned to the
   first, leaving a ragged gap down the left of the card.

   Opt-in rather than a change to .step, so the homepage keeps the inline
   treatment its short labels are built for. */
.steps-numtop .num{
  flex-direction:column;
  align-items:flex-start;
  gap:9px;
}

/* The safety panel as two columns: the argument on the left, the checklist
   on the right. As one column the list was capped at 72ch for readability
   and left a third of the panel empty to its right. */
.warn-split{
  display:grid;
  grid-template-columns:0.82fr 1fr;
  gap:clamp(26px,3.6vw,56px);
  align-items:start;
}
.warn-split .warn-head h2{max-width:none}
.warn-split .warn-head > p{max-width:42ch}
/* Both caps come off: the grid track is the measure now, and leaving them
   on would column-in-a-column the text. */
.warn-split .warn-list{margin-top:0;max-width:none}

@media (max-width:860px){
  .warn-split{grid-template-columns:1fr;gap:24px}
  .warn-split .warn-head > p{max-width:none}
}

/* A status badge on its own line under a tile heading.

   TWO CLASSES, and that is the point. `.tile p{margin:0}` is (0,1,1) and
   plain `.tile-tag` is (0,1,0), so the lower-specificity rule lost and the
   margin here silently did nothing -- which is why the badge sat a few
   pixels off the heading however the value was tuned. Later in the file
   does not beat more specific.

   It was above the heading for a while, to stop an inline pill dangling off
   a wrapped headline. With the badge filled it is legible in either place,
   so it reads better under the title it belongs to. */
.tile .tile-tag{margin:14px 0 18px;line-height:1}
.tile .tile-tag .pill{padding:5px 11px;font-size:10px}

/* ==========================================================================
   Get in touch dialog (partners page)

   Native <dialog>, so the browser handles the focus trap, Escape and the
   top layer. Fields reuse the panel surfaces and --sk-r-field; the error
   colour is the brand pink so it reads as ours, not a system red.
   ========================================================================== */
.contact{
  width:min(560px,calc(100% - 32px));
  max-height:calc(100dvh - 32px);
  margin:auto;
  padding:36px 32px 32px;
  border:1px solid var(--sk-line);
  border-radius:var(--sk-r-panel);
  background:var(--sk-panel);
  color:var(--sk-ink-1);
  font-family:var(--sk-type);
  overflow:auto;
  box-shadow:0 40px 90px -30px rgba(0,0,0,.8);
}
.contact::backdrop{background:rgba(11,10,18,.72);backdrop-filter:blur(6px)}
.contact[open]{animation:sk-contact-in .22s cubic-bezier(.2,.8,.3,1)}
@keyframes sk-contact-in{from{opacity:0;transform:translateY(12px) scale(.98)}}
@media (prefers-reduced-motion:reduce){.contact[open]{animation:none}}

.contact-x{
  position:absolute;top:14px;right:14px;
  display:grid;place-items:center;
  width:36px;height:36px;padding:0;
  border:0;border-radius:var(--sk-r-pill);
  background:transparent;color:var(--sk-ink-2);cursor:pointer;
  transition:background .16s,color .16s;
}
.contact-x:hover{background:var(--sk-panel-2);color:var(--sk-ink-1)}

.contact-title{
  margin:0 0 8px;
  font-size:28px;line-height:1.1;
  font-variation-settings:'wdth' var(--sk-h2-wdth);
  font-weight:var(--sk-h2-wght);
}
.contact-sub{margin:0 0 26px;color:var(--sk-ink-2);font-size:15px;line-height:1.5;max-width:44ch}

.contact-form .field{display:flex;flex-direction:column;gap:7px;margin-bottom:16px;min-width:0}
.contact-form .field-row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.contact-form label{font-size:13px;font-weight:600;color:var(--sk-ink-2)}
.contact-form .req{color:var(--sk-pink)}

.contact-form input,
.contact-form textarea{
  width:100%;
  padding:13px 14px;
  border:1px solid var(--sk-line);
  border-radius:var(--sk-r-field);
  background:var(--sk-void);
  color:var(--sk-ink-1);
  font:inherit;font-size:15px;
  transition:border-color .16s,box-shadow .16s;
}
.contact-form textarea{resize:vertical;min-height:120px;line-height:1.5}
.contact-form input::placeholder{color:var(--sk-ink-3)}
.contact-form input:focus,
.contact-form textarea:focus{
  outline:none;
  border-color:var(--sk-lilac);
  box-shadow:0 0 0 3px rgba(218,143,255,.18);
}
.contact-form [aria-invalid="true"]{border-color:var(--sk-pink)}
.contact-form .field-err{margin:0;font-size:13px;color:var(--sk-pink)}

.form-status{
  margin:4px 0 16px;padding:12px 14px;
  border:1px solid rgba(252,76,210,.4);border-radius:var(--sk-r-field);
  background:rgba(252,76,210,.08);
  font-size:14px;color:var(--sk-ink-1);
}
.contact-submit{width:100%;margin-top:6px}
.contact-submit:disabled{opacity:.6;cursor:progress;transform:none}
.contact-done:focus{outline:none}

@media (max-width:640px){
  .contact{padding:30px 20px 22px}
  .contact-form .field-row{grid-template-columns:1fr;gap:0}
}
/* Honeypot field: off-screen rather than display:none, which some bots skip. */
.contact-form .hp{position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden}

/* /dApps store hand-off page: the logo stands in for the nav. */
.dapps-logo{display:inline-block;margin-bottom:40px}
