/* ============================================================================
   ARV Coin — Sterling
   ----------------------------------------------------------------------------
   Silver on black. The feel comes from space, weight and material rather than
   motion: brushed-metal gradients, hairline rules, generous whitespace, one
   serif for display and one sans for everything else.

   There is no 3D scene. Removing it took 1.3 MB off the critical path, which a
   phone on a slow connection feels immediately — and a rotating object behind a
   balance was never helping anyone read it.

   Colour discipline: silver is the brand, green and red mean market direction and
   nothing else. Nothing decorative is ever green or red, so when a number is
   coloured it means something.
   ============================================================================ */

:root {
  /* Black, warmed very slightly so it reads as ink rather than a dead screen */
  --k-0: #07070a;
  --k-1: #0c0c10;
  --k-2: #121218;
  --k-3: #1a1a22;
  --k-4: #24242e;
  --k-5: #2f2f3b;

  /* Silver */
  --s-0: #f6f7fa;
  --s-1: #dfe2e9;
  --s-2: #b9bec9;
  --s-3: #8f95a3;
  --s-4: #676d7c;
  --s-5: #454b58;

  /* Brushed metal. Used on the wordmark, primary buttons and hairline edges. */
  --brushed: linear-gradient(135deg, #ffffff 0%, #d8dbe3 22%, #9aa0ae 48%, #eef0f4 68%, #b0b6c2 100%);
  --brushed-dim: linear-gradient(135deg, #c8ccd6 0%, #8f95a3 45%, #dfe2e9 70%, #7c8290 100%);
  --edge: linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,.02) 40%, rgba(255,255,255,0));

  /* Glass */
  --glass: rgba(18, 18, 24, 0.66);
  --glass-2: rgba(26, 26, 34, 0.82);
  --line: rgba(255, 255, 255, 0.07);
  --line-2: rgba(255, 255, 255, 0.12);
  --line-3: rgba(255, 255, 255, 0.2);

  /* Text */
  --tx-0: #f4f5f8;
  --tx-1: #c3c8d2;
  --tx-2: #8b91a0;
  --tx-3: #5d636f;

  /* Market direction — reserved. Nothing decorative is ever green or red, so a
     coloured number always means something. */
  --up: #3ecf8e;
  --up-dim: rgba(62, 207, 142, 0.12);
  --down: #f0616d;
  --down-dim: rgba(240, 97, 109, 0.12);
  --flat: var(--tx-2);

  /* Asset identity. Each is the coin's own colour, desaturated enough to sit on
     a silver-and-black plate without turning the page into a rainbow — Bitcoin
     amber especially, which at full strength fights everything near it. */
  --btc: #f7931a;
  --btc-soft: #c9822a;
  --btc-dim: rgba(247, 147, 26, 0.13);
  --eth: #8f9ad4;
  --eth-dim: rgba(143, 154, 212, 0.13);
  --sol: #4fd6b0;
  --sol-dim: rgba(79, 214, 176, 0.13);

  /* Semantic */
  --warn: #e0b055;
  --warn-dim: rgba(224, 176, 85, 0.11);
  --info: #7fa8d8;
  --info-dim: rgba(127, 168, 216, 0.11);

  /* Type */
  --serif: 'Cormorant Garamond', 'Iowan Old Style', Georgia, serif;
  --sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --mono: 'JetBrains Mono', 'SF Mono', ui-monospace, Menlo, monospace;

  /* Rhythm */
  --r-xs: 6px; --r-sm: 10px; --r: 14px; --r-lg: 20px; --r-xl: 28px;
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 72px; --sp-9: 112px;

  --sh-1: 0 1px 2px rgba(0,0,0,.5);
  --sh-2: 0 10px 30px -8px rgba(0,0,0,.7);
  --sh-3: 0 30px 70px -20px rgba(0,0,0,.85);
  --glow: 0 0 40px -10px rgba(223, 226, 233, 0.22);

  --nav-h: 66px;
  --wrap: 1280px;
  --ease: cubic-bezier(.4, 0, .2, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* ------------------------------------------------------------------ reset -- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--k-0);
  color: var(--tx-0);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  min-height: 100vh;
}

/* A single fixed wash instead of per-section gradients — one paint, no scroll
   cost, and it stops the page reading as flat black. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 80% 50% at 50% -12%, rgba(223,226,233,.075), transparent 68%),
    radial-gradient(ellipse 60% 45% at 100% 8%, rgba(150,158,175,.05), transparent 70%),
    radial-gradient(ellipse 70% 40% at 0% 92%, rgba(120,128,145,.04), transparent 70%);
}
.page, .nav, .foot { position: relative; z-index: 1; }

/* Tabular figures on every number that changes. Without this a live price
   shifts the layout sideways each time a digit changes width, which is the
   difference between a trading screen and a broken one. */
.num, .price, td.num, th.num, .mono {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1, 'zero' 1;
  letter-spacing: -.012em;
}

h1, h2, h3, h4, h5 { margin: 0 0 var(--sp-3); line-height: 1.14; }
h1, h2 { font-family: var(--serif); font-weight: 500; letter-spacing: -.015em; }
h1 { font-size: clamp(2.4rem, 6vw, 4.4rem); }
h2 { font-size: clamp(1.7rem, 3.4vw, 2.6rem); }
h3 { font-size: 1.15rem; font-weight: 600; letter-spacing: -.02em; }
h4 { font-size: .98rem; font-weight: 620; letter-spacing: -.01em; }
h5 {
  font-size: .72rem; font-weight: 650; text-transform: uppercase;
  letter-spacing: .1em; color: var(--tx-3);
}

p { margin: 0 0 var(--sp-4); color: var(--tx-1); }
a { color: var(--s-1); text-decoration: none; transition: color .15s var(--ease); }
a:hover { color: var(--s-0); }
::selection { background: rgba(223,226,233,.22); color: #fff; }
:focus-visible { outline: 1px solid var(--s-2); outline-offset: 3px; border-radius: 3px; }
hr { border: 0; border-top: 1px solid var(--line); margin: var(--sp-5) 0; }

/* The wordmark and any display text that should look milled rather than printed */
.metal {
  background: var(--brushed);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ---------------------------------------------------------------- helpers -- */

.up { color: var(--up); } .down { color: var(--down); } .flat { color: var(--flat); }
.muted { color: var(--tx-2); } .dim { color: var(--tx-3); }
.small { font-size: .85rem; } .tiny { font-size: .76rem; }
.right { text-align: right; } .center { text-align: center; }
.nowrap { white-space: nowrap; } .hidden { display: none !important; }
.strong { font-weight: 620; } .serif { font-family: var(--serif); }

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

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 var(--sp-5); }
.wrap-narrow { max-width: 760px; } .wrap-mid { max-width: 1020px; } .wrap-wide { max-width: 1560px; }

.stack > * + * { margin-top: var(--sp-4); }
.stack-lg > * + * { margin-top: var(--sp-5); }
.row { display: flex; align-items: center; gap: var(--sp-3); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.row-wrap { flex-wrap: wrap; }
.spacer { flex: 1; }

/* Tracks are minmax(0, 1fr), never a bare 1fr.
   `1fr` is shorthand for `minmax(auto, 1fr)`, and that `auto` floor is the
   min-content width of whatever is inside. One nowrap formula or one wide table
   in a cell therefore inflates the whole track past its container and the page
   scrolls sideways on a phone — with the overflow appearing on innocent siblings,
   which makes it maddening to trace. The explicit 0 floor removes the whole
   class of bug, and `min-width: 0` on the children does the same for flex and
   grid items that scroll internally. */
.grid { display: grid; gap: var(--sp-4); }
.grid > * { min-width: 0; }
.g-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.g-auto { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

/* Page-level splits: a wide main column and a narrower rail.
   Declared here rather than as an inline style on each page, because an inline
   `grid-template-columns` beats every media query — which is exactly how a phone
   ends up scrolling sideways with no obvious cause. */
.split {
  display: grid; gap: var(--sp-4); align-items: start;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
}
.split-hero {
  display: grid; gap: var(--sp-7); align-items: center;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
}
.split > *, .split-hero > * { min-width: 0; }

/* A row of figures that sizes to its content on a wide screen. */
.stat-strip { display: grid; grid-template-columns: repeat(4, auto); gap: var(--sp-5); }
.stat-strip > * { min-width: 0; }

@media (max-width: 980px) {
  .split, .split-hero { grid-template-columns: minmax(0, 1fr); }
  .split-hero { align-items: start; gap: var(--sp-5); }
}
@media (max-width: 560px) {
  .stat-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-4); }
}

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

.nav {
  position: sticky; top: 0; z-index: 100; height: var(--nav-h);
  display: flex; align-items: center;
  background: rgba(7,7,10,.8);
  backdrop-filter: blur(22px) saturate(140%);
  -webkit-backdrop-filter: blur(22px) saturate(140%);
  border-bottom: 1px solid var(--line);
}
.nav .wrap { display: flex; align-items: center; gap: var(--sp-5); }

.brand {
  display: flex; align-items: center; gap: var(--sp-3);
  font-family: var(--serif); font-size: 1.3rem; font-weight: 600;
  letter-spacing: .02em; flex-shrink: 0; color: var(--tx-0);
}
.brand:hover { color: var(--tx-0); }
.brand-mark {
  width: 30px; height: 30px; flex-shrink: 0; border-radius: 8px;
  background: var(--brushed);
  display: grid; place-items: center;
  font-family: var(--sans); font-size: .78rem; font-weight: 800;
  color: #0a0a0d;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.6), 0 2px 10px -2px rgba(0,0,0,.7);
}

.nav-links { display: flex; gap: 2px; flex: 1; }
.nav-links a {
  padding: 7px 13px; border-radius: var(--r-sm);
  color: var(--tx-2); font-size: .88rem; font-weight: 500;
  transition: all .15s var(--ease); white-space: nowrap;
}
.nav-links a:hover { background: var(--k-3); color: var(--tx-0); }
.nav-links a.on { background: var(--k-3); color: var(--s-0); box-shadow: inset 0 0 0 1px var(--line-2); }

.nav-toggle {
  display: none; width: 38px; height: 38px; cursor: pointer;
  background: none; border: 1px solid var(--line-2); border-radius: var(--r-sm);
  color: var(--tx-1); font-size: 1.05rem;
}

.nav-ticker {
  display: flex; align-items: baseline; gap: var(--sp-2);
  padding: 5px 12px; border-radius: var(--r-sm);
  background: var(--k-2); border: 1px solid var(--line);
  font-size: .85rem;
}
/* An author `display` beats the UA stylesheet's rule for [hidden], so the ticker
   would sit there showing two em-dashes until a price arrived. It stays out of
   the layout until it has something to say. */
.nav-ticker[hidden] { display: none; }
.nav-ticker .k {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .09em; color: var(--tx-3);
}

/* --------------------------------------------------------------- surfaces -- */

.card {
  position: relative;
  background: var(--glass);
  backdrop-filter: blur(18px) saturate(125%);
  -webkit-backdrop-filter: blur(18px) saturate(125%);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  box-shadow: var(--sh-2);
}
/* A lit top edge. This is what makes a flat rectangle read as a machined
   surface rather than a div. */
.card::before {
  content: ''; position: absolute; inset: 0 0 auto; height: 1px;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: var(--edge);
  pointer-events: none;
}
.card-solid { background: var(--k-1); backdrop-filter: none; }
.card-tight { padding: var(--sp-4); }
.card-flush { padding: 0; overflow: hidden; }
.card-lift { transition: transform .45s var(--ease-out), border-color .3s var(--ease), box-shadow .45s var(--ease-out); }
.card-lift:hover { transform: translateY(-3px); border-color: var(--line-2); box-shadow: var(--sh-3); }

.card-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding-bottom: var(--sp-4); margin-bottom: var(--sp-4);
  border-bottom: 1px solid var(--line);
}
.card-head h3, .card-head h4 { margin: 0; }

/* ------------------------------------------------------------------ hero --- */

/* ============================================================================
   Hero — machined metal, in four layers
   ----------------------------------------------------------------------------
   No video, no images, no canvas. A background video costs a megabyte or two
   before a single word is readable, and on a phone it is the fastest way to make
   a site feel cheap. Everything below is a gradient, so the hero paints on the
   first frame and adds nothing to the page weight.

   Layer order matters:
     .hero-plate   deep charcoal, lit from above
     .hero-engine  fine concentric engine-turning, as on a milled plate
     .hero-sweep   a specular highlight drifting across, like light on steel
     .hero-grain   faint noise, so large flat areas do not read as plastic

   Only .hero-sweep animates, and only on transform and opacity, so it stays on
   the compositor and never triggers layout.
   ============================================================================ */

.hero { position: relative; overflow: hidden; padding: var(--sp-9) 0 var(--sp-8); }
.hero-media { position: absolute; inset: 0; z-index: 0; overflow: hidden; }

/* The plate. Two overlapping radials give a surface with a light source rather
   than a flat fill, and the bottom fade hands off to the page background so the
   hero has no visible seam. */
.hero-plate {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 90% 60% at 50% -20%, rgba(233,236,242,.15), transparent 62%),
    radial-gradient(ellipse 50% 40% at 82% 10%, rgba(176,184,200,.09), transparent 68%),
    linear-gradient(180deg, #14141b 0%, #0d0d12 46%, var(--k-0) 100%);
}

/* Engine-turning. Two sets of very fine lines at opposing angles, plus a slow
   concentric ring — the same idea as the guilloché on a watch dial or a share
   certificate. Kept under 4% opacity: it should be felt rather than seen, and
   anything stronger fights the type on top of it. */
.hero-engine {
  position: absolute; inset: 0;
  opacity: .55;
  background-image:
    repeating-linear-gradient(115deg,
      rgba(255,255,255,.030) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(65deg,
      rgba(255,255,255,.016) 0 1px, transparent 1px 7px),
    repeating-radial-gradient(circle at 50% -10%,
      rgba(255,255,255,.022) 0 1px, transparent 1px 22px);
  /* Fade out towards the bottom so the texture does not run under body copy. */
  -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0,0,0,.5) 55%, transparent 92%);
  mask-image: linear-gradient(180deg, #000 0%, rgba(0,0,0,.5) 55%, transparent 92%);
}

/* The specular sweep. A wide, soft, off-axis highlight that drifts across the
   plate. This is the one thing that makes the surface read as metal rather than
   paint — real metal has a moving hotspot. */
.hero-sweep {
  position: absolute; inset: -40%;
  background: conic-gradient(from 200deg at 50% 50%,
    transparent 0deg,
    rgba(255,255,255,.05) 40deg,
    rgba(214,217,224,.13) 78deg,
    rgba(255,255,255,.03) 120deg,
    transparent 180deg,
    rgba(150,158,175,.07) 260deg,
    transparent 340deg);
  filter: blur(70px);
  animation: sweep var(--sweep, 18s) linear infinite;
  will-change: transform;
  pointer-events: none;
}
@keyframes sweep { to { transform: rotate(360deg); } }

/* Grain. An inline SVG turbulence — about 200 bytes, no request, and it stops
   the large dark areas looking like flat vector fill. */
.hero-grain {
  position: absolute; inset: 0;
  opacity: .05;
  mix-blend-mode: overlay;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* A hairline at the very bottom of the hero, brightest in the middle — the
   machined edge of the plate. */
.hero::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; z-index: 1;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.14) 30%,
              rgba(255,255,255,.22) 50%, rgba(255,255,255,.14) 70%, transparent);
}

.hero-inner { position: relative; z-index: 2; }
.hero-eyebrow {
  font-size: .74rem; text-transform: uppercase; letter-spacing: .22em;
  color: var(--tx-3); margin-bottom: var(--sp-4);
}

/* Display type with a light source travelling through it, so the wordmark reads
   as engraved rather than filled. Paused under reduced-motion below. */
.hero h1 { position: relative; }
.metal-lit {
  background: linear-gradient(100deg,
    #8f95a3 0%, #d8dbe3 18%, #ffffff 30%, #eef0f4 38%,
    #a8aeba 55%, #d8dbe3 76%, #7c8290 100%);
  background-size: 260% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: lit 9s ease-in-out infinite;
}
@keyframes lit {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

/* -------------------------------------------------------------- stat tile -- */

.stat { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.stat-k {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--tx-3); font-weight: 600;
}
.stat-v {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 1.5rem; font-weight: 600; letter-spacing: -.03em; line-height: 1.1;
}
.stat-v-lg { font-size: 2.2rem; }
.stat-sub { font-size: .8rem; color: var(--tx-2); }

/* ------------------------------------------------------------------ price -- */

.price-hero { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; }
.price-hero .v {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: clamp(2.2rem, 6.5vw, 3.8rem);
  font-weight: 620; letter-spacing: -.04em; line-height: 1;
}

/* A tick flash is the single most useful affordance on a live price — it tells
   you the number is alive. Kept brief so a fast tape does not strobe. */
@keyframes flash-up   { from { background: var(--up-dim); }   to { background: transparent; } }
@keyframes flash-down { from { background: var(--down-dim); } to { background: transparent; } }
.tick-up   { animation: flash-up .5s var(--ease) 1; border-radius: 4px; }
.tick-down { animation: flash-down .5s var(--ease) 1; border-radius: 4px; }

.chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 9px; border-radius: 100px;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: .78rem; font-weight: 600;
  background: var(--k-3); color: var(--tx-1);
}
.chip.up { background: var(--up-dim); color: var(--up); }
.chip.down { background: var(--down-dim); color: var(--down); }
.chip.flat { background: var(--k-3); color: var(--flat); }

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: var(--r-xs);
  font-size: .68rem; font-weight: 640; text-transform: uppercase; letter-spacing: .07em;
  background: var(--k-3); color: var(--tx-2); border: 1px solid var(--line);
}
.badge.ok { background: var(--up-dim); color: var(--up); border-color: transparent; }
.badge.bad { background: var(--down-dim); color: var(--down); border-color: transparent; }
.badge.warn { background: var(--warn-dim); color: var(--warn); border-color: transparent; }
.badge.info { background: var(--info-dim); color: var(--info); border-color: transparent; }
.badge.metal { background: var(--brushed-dim); color: #0c0c10; border-color: transparent; font-weight: 700; }

.live-dot {
  width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
  background: var(--up); box-shadow: 0 0 0 0 rgba(62,207,142,.55);
  animation: pulse 2.4s infinite;
}
.live-dot.stale { background: var(--warn); animation: none; }
.live-dot.off { background: var(--tx-3); animation: none; }
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(62,207,142,.5); }
  70% { box-shadow: 0 0 0 7px rgba(62,207,142,0); }
  100% { box-shadow: 0 0 0 0 rgba(62,207,142,0); }
}

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

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  padding: 11px 20px; border: 1px solid transparent; border-radius: var(--r-sm);
  background: var(--k-3); color: var(--tx-0);
  font-family: var(--sans); font-size: .9rem; font-weight: 600;
  cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: all .16s var(--ease);
}
.btn:hover { background: var(--k-4); color: var(--tx-0); transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn:disabled, .btn[aria-disabled='true'] { opacity: .38; cursor: not-allowed; transform: none; }

.btn-primary {
  background: var(--brushed); color: #0a0a0d; font-weight: 700;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.65), 0 4px 18px -6px rgba(223,226,233,.35);
}
.btn-primary:hover {
  color: #0a0a0d; filter: brightness(1.06);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.75), 0 8px 26px -8px rgba(223,226,233,.5);
}
.btn-ghost { background: transparent; border-color: var(--line-2); color: var(--tx-1); }
.btn-ghost:hover { background: var(--k-2); border-color: var(--line-3); color: var(--tx-0); }
.btn-buy { background: var(--up-dim); color: var(--up); border-color: rgba(62,207,142,.3); }
.btn-buy:hover { background: rgba(62,207,142,.2); color: var(--up); }
.btn-sell { background: var(--down-dim); color: var(--down); border-color: rgba(240,97,109,.3); }
.btn-sell:hover { background: rgba(240,97,109,.2); color: var(--down); }
.btn-danger { background: var(--down-dim); color: var(--down); border-color: rgba(240,97,109,.28); }
.btn-sm { padding: 7px 13px; font-size: .82rem; }
.btn-lg { padding: 15px 30px; font-size: .98rem; }
.btn-block { width: 100%; }

/* ---------------------------------------------------------------- inputs --- */

.field { display: flex; flex-direction: column; gap: 7px; }
.field label { font-size: .8rem; font-weight: 620; color: var(--tx-1); }
.field .hint { font-size: .76rem; color: var(--tx-3); line-height: 1.45; }
.field .err { font-size: .78rem; color: var(--down); }

input, select, textarea {
  width: 100%; padding: 11px 13px;
  background: var(--k-1); border: 1px solid var(--line);
  border-radius: var(--r-sm); color: var(--tx-0);
  font-family: var(--sans); font-size: .95rem;
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--s-3);
  box-shadow: 0 0 0 3px rgba(223,226,233,.09);
}
input::placeholder { color: var(--tx-3); }
input[aria-invalid='true'] { border-color: var(--down); }
input:disabled { opacity: .5; cursor: not-allowed; }

input.num-input {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 1.3rem; font-weight: 600; letter-spacing: -.02em;
}
.amount-input { position: relative; }
.amount-input .cur {
  position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
  color: var(--tx-2); font-family: var(--mono); font-size: 1.15rem; pointer-events: none;
}
.amount-input input { padding-left: 34px; }
.quick { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

.check {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-3); cursor: pointer;
  background: var(--k-1); border: 1px solid var(--line); border-radius: var(--r-sm);
  font-size: .86rem; color: var(--tx-1);
  transition: border-color .15s var(--ease);
}
.check:hover { border-color: var(--line-2); }
.check input { width: auto; flex-shrink: 0; margin-top: 3px; accent-color: var(--s-2); }

/* OTP entry — six characters, spaced so they read as separate digits */
.otp-input {
  font-family: var(--mono); font-size: 1.7rem; font-weight: 600;
  letter-spacing: .5em; text-align: center; padding: 14px 13px 14px 26px;
}

/* ------------------------------------------------------------------ table -- */

/* `min-width: 0` is what actually makes this scroll instead of stretching its
   parent. Without it the wrapper's min-content is the table's, and a nine-column
   tax table drags the whole page wider than the phone. */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; min-width: 0; }
table.data { width: 100%; border-collapse: collapse; font-size: .87rem; }
table.data th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; padding: 10px var(--sp-4);
  font-size: .68rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--tx-3); font-weight: 650; white-space: nowrap;
  background: var(--k-1); border-bottom: 1px solid var(--line);
}
table.data td {
  padding: 11px var(--sp-4); color: var(--tx-1);
  border-bottom: 1px solid rgba(255,255,255,.03);
}
table.data tbody tr { transition: background .12s var(--ease); }
table.data tbody tr:hover { background: rgba(255,255,255,.018); }
table.data td.num, table.data th.num { text-align: right; }
table.data tfoot td {
  font-weight: 650; color: var(--tx-0); background: var(--k-1);
  border-top: 1px solid var(--line-2); border-bottom: none;
}

/* --------------------------------------------------------------- ledger ---- */

/* The itemised fee and tax list. Its job is to make every deduction impossible
   to miss, so nothing here is collapsed, greyed out or behind a tooltip. */
.ledger-list { display: flex; flex-direction: column; gap: 1px; }
.ledger-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-4); padding: 10px var(--sp-4);
  background: var(--k-1); font-size: .89rem; flex-wrap: wrap;
}
.ledger-row:first-child { border-radius: var(--r-sm) var(--r-sm) 0 0; }
.ledger-row:last-child { border-radius: 0 0 var(--r-sm) var(--r-sm); }
.ledger-row .l { color: var(--tx-1); }
.ledger-row .a {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-weight: 600; white-space: nowrap; margin-left: auto;
}
.ledger-row .note {
  flex-basis: 100%; font-size: .75rem; color: var(--tx-3);
  margin-top: 3px; line-height: 1.45;
}
.ledger-row.k-gross { background: var(--k-2); }
.ledger-row.k-gross .a { font-size: 1.02rem; }
.ledger-row.k-charge .a, .ledger-row.k-tds .a { color: var(--warn); }
.ledger-row.k-net { background: var(--up-dim); border-left: 2px solid var(--up); }
.ledger-row.k-net .l { color: var(--tx-0); font-weight: 640; }
.ledger-row.k-net .a { color: var(--up); font-size: 1.1rem; font-weight: 700; }
.ledger-row.k-pnl .a { font-weight: 700; }
.ledger-row.k-liability { background: rgba(224,176,85,.05); }
.ledger-row.k-liability .a { color: var(--warn); }
.ledger-row.k-liability-total { background: var(--warn-dim); border-left: 2px solid var(--warn); }
.ledger-row.k-liability-total .l { color: var(--tx-0); font-weight: 640; }
.ledger-row.k-liability-total .a { color: var(--warn); font-size: 1.02rem; font-weight: 700; }
.ledger-row.k-warning { background: var(--down-dim); border-left: 2px solid var(--down); }
.ledger-row.k-warning .note { color: var(--tx-1); }
.ledger-divider { height: var(--sp-4); }

/* ------------------------------------------------------------------ notes -- */

.note-box {
  padding: var(--sp-4); border-radius: var(--r-sm);
  border-left: 2px solid var(--info); background: var(--info-dim);
  font-size: .86rem; color: var(--tx-1);
}
.note-box.warn { border-color: var(--warn); background: var(--warn-dim); }
.note-box.bad { border-color: var(--down); background: var(--down-dim); }
.note-box.ok { border-color: var(--up); background: var(--up-dim); }
.note-box strong { color: var(--tx-0); }
.note-box p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- toasts --- */

.toast-host {
  position: fixed; bottom: var(--sp-5); right: var(--sp-5); z-index: 900;
  display: flex; flex-direction: column; gap: var(--sp-2);
  max-width: min(400px, calc(100vw - 32px));
}
.toast {
  display: flex; gap: var(--sp-3); padding: var(--sp-4);
  background: var(--glass-2);
  backdrop-filter: blur(22px); -webkit-backdrop-filter: blur(22px);
  border: 1px solid var(--line-2); border-left: 2px solid var(--info);
  border-radius: var(--r-sm); box-shadow: var(--sh-3);
  font-size: .87rem; animation: toast-in .3s var(--ease-out);
}
.toast.ok { border-left-color: var(--up); }
.toast.bad { border-left-color: var(--down); }
.toast.warn { border-left-color: var(--warn); }
.toast.out { animation: toast-out .24s var(--ease) forwards; }
@keyframes toast-in { from { opacity: 0; transform: translateX(22px); } }
@keyframes toast-out { to { opacity: 0; transform: translateX(22px); } }

/* --------------------------------------------------------------- loading --- */

.skeleton {
  background: linear-gradient(90deg, var(--k-2) 25%, var(--k-3) 50%, var(--k-2) 75%);
  background-size: 200% 100%; animation: shimmer 1.4s infinite;
  border-radius: var(--r-sm); color: transparent !important;
}
@keyframes shimmer { to { background-position: -200% 0; } }

.spinner {
  width: 15px; height: 15px; flex-shrink: 0;
  border: 2px solid var(--line-2); border-top-color: var(--s-2);
  border-radius: 50%; animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.empty { padding: var(--sp-7) var(--sp-4); text-align: center; color: var(--tx-3); }
.empty .icon { font-size: 1.8rem; opacity: .35; margin-bottom: var(--sp-3); }

/* ------------------------------------------------------------------- tabs -- */

.tabs {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--k-1); border: 1px solid var(--line); border-radius: var(--r-sm);
}
.tab {
  padding: 6px 12px; border: none; background: none; cursor: pointer;
  color: var(--tx-2); font-family: var(--mono); font-size: .8rem; font-weight: 600;
  border-radius: var(--r-xs); transition: all .15s var(--ease);
}
.tab:hover { color: var(--tx-0); }
.tab.on { background: var(--k-3); color: var(--s-0); box-shadow: inset 0 0 0 1px var(--line-2); }

/* Buy/sell segmented control */
.side-toggle { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; padding: 3px;
  background: var(--k-1); border: 1px solid var(--line); border-radius: var(--r-sm); }
.side-toggle button {
  padding: 10px; border: 0; background: none; cursor: pointer;
  color: var(--tx-2); font-weight: 650; font-size: .9rem;
  border-radius: var(--r-xs); transition: all .15s var(--ease);
}
.side-toggle button.on[data-side='buy'] { background: var(--up-dim); color: var(--up); }
.side-toggle button.on[data-side='sell'] { background: var(--down-dim); color: var(--down); }

/* ------------------------------------------------------------------ chart -- */

.chart-shell {
  position: relative; background: var(--k-1);
  border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden;
}
.chart-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap; padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
}
.chart-canvas { width: 100%; height: 430px; position: relative; }
.chart-canvas.tall { height: 560px; }
.chart-canvas.short { height: 250px; }
.chart-legend {
  display: flex; gap: var(--sp-4); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--line); font-size: .78rem;
}
.legend-item { display: flex; align-items: center; gap: 6px; color: var(--tx-2); }
.legend-swatch { width: 10px; height: 2px; border-radius: 2px; flex-shrink: 0; }

.ohlc-readout {
  display: flex; gap: var(--sp-4); flex-wrap: wrap;
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: .78rem; color: var(--tx-2);
}
.ohlc-readout b { color: var(--tx-0); font-weight: 600; }

.chart-overlay-msg {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: rgba(12,12,16,.72); backdrop-filter: blur(3px);
  font-size: .88rem; color: var(--tx-2); text-align: center;
  padding: var(--sp-5); z-index: 3;
}

/* ------------------------------------------------------------------- tape -- */

/* Recent trades. Monospaced and dense — a tape is meant to be glanced at, not
   read, and any padding here costs a row of information. */
.tape { display: flex; flex-direction: column; max-height: 320px; overflow-y: auto; }
.tape-row {
  display: grid; grid-template-columns: 1fr auto auto;
  gap: var(--sp-3); padding: 5px var(--sp-4);
  font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: .78rem;
  border-bottom: 1px solid rgba(255,255,255,.025);
}
.tape-row.new { animation: tape-in .4s var(--ease-out); }
@keyframes tape-in { from { opacity: 0; transform: translateY(-6px); background: rgba(255,255,255,.05); } }
.tape-row .t { color: var(--tx-3); }
.tape-head {
  display: grid; grid-template-columns: 1fr auto auto; gap: var(--sp-3);
  padding: 8px var(--sp-4);
  font-size: .66rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--tx-3); border-bottom: 1px solid var(--line);
}

/* ------------------------------------------------------------------ depth -- */

/* There is no bid/ask ladder because there is no spread — every fill settles at
   the index price. What matters instead is how much wants in and out, so depth
   is drawn as two opposing bars. */
.depth { display: flex; flex-direction: column; gap: var(--sp-3); }
.depth-bar { height: 8px; border-radius: 4px; background: var(--k-3); overflow: hidden; }
.depth-bar span { display: block; height: 100%; }
.depth-bar.buy span { background: linear-gradient(90deg, var(--up), rgba(62,207,142,.4)); }
.depth-bar.sell span { background: linear-gradient(90deg, var(--down), rgba(240,97,109,.4)); }

/* -------------------------------------------------------------------- QR --- */

.qr-panel {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-4);
  padding: var(--sp-5); background: var(--k-1);
  border: 1px solid var(--line); border-radius: var(--r-lg);
}
.qr-frame { padding: var(--sp-4); background: #fff; border-radius: var(--r); line-height: 0; box-shadow: var(--sh-2); }
.qr-frame svg, .qr-frame canvas, .qr-frame img { display: block; width: 216px; height: 216px; }
.qr-unconfigured {
  width: 216px; height: 216px; display: grid; place-items: center; text-align: center;
  padding: var(--sp-4); background: var(--k-2);
  border: 1px dashed var(--line-2); border-radius: var(--r);
  color: var(--tx-3); font-size: .78rem; line-height: 1.5;
}
.qr-vpa {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 9px 14px; background: var(--k-2);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  font-family: var(--mono); font-size: .92rem; color: var(--tx-0);
}

/* ------------------------------------------------------------------ steps -- */

.steps { display: flex; gap: 0; margin-bottom: var(--sp-5); }
.step {
  flex: 1; display: flex; flex-direction: column; gap: 5px;
  padding: var(--sp-3) var(--sp-4); border-top: 1px solid var(--k-4);
  color: var(--tx-3); font-size: .8rem;
}
.step.on { border-top-color: var(--s-2); color: var(--s-0); }
.step.done { border-top-color: var(--up); color: var(--up); }
.step .n { font-family: var(--mono); font-size: .68rem; font-weight: 700; letter-spacing: .06em; }
.step .t { font-weight: 620; }

/* ----------------------------------------------------------------- timer --- */

/* Deposit and withdrawal both promise a window, so the countdown is real rather
   than a spinner that means nothing. */
.timer {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-4); background: var(--k-2);
  border: 1px solid var(--line); border-radius: var(--r-sm);
}
.timer-ring {
  width: 44px; height: 44px; flex-shrink: 0; border-radius: 50%;
  background: conic-gradient(var(--s-2) var(--pct, 0%), var(--k-4) 0);
  display: grid; place-items: center; position: relative;
}
.timer-ring::after {
  content: ''; position: absolute; inset: 4px; border-radius: 50%; background: var(--k-2);
}
.timer-ring b {
  position: relative; z-index: 1;
  font-family: var(--mono); font-size: .7rem; font-weight: 700; color: var(--tx-0);
}
.timer.overdue { border-color: rgba(224,176,85,.35); background: var(--warn-dim); }

/* ------------------------------------------------------------------ tiers -- */

.tier-row {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--k-1);
}
.tier-row.earned { border-color: var(--line-3); background: var(--k-2); }
.tier-row.earned .tier-name { background: var(--brushed); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.tier-name { font-family: var(--serif); font-size: 1.05rem; font-weight: 600; min-width: 92px; }
.progress { height: 4px; border-radius: 2px; background: var(--k-3); overflow: hidden; }
.progress span { display: block; height: 100%; background: var(--brushed-dim); }

/* ------------------------------------------------------------------ legal -- */

/* Two columns on a desktop, one on a phone. The contents list stops being
   sticky when it stacks — a sticky block above the content it indexes just eats
   the screen. */
.legal-layout {
  display: grid; grid-template-columns: 200px minmax(0, 1fr);
  gap: var(--sp-6); align-items: start;
}
.legal-layout > * { min-width: 0; }

.toc { position: sticky; top: 80px; }
.toc ul { list-style: none; margin: 0; padding: 0; line-height: 2; }
.toc a { color: var(--tx-2); text-decoration: none; display: block;
  padding-left: 9px; border-left: 1px solid transparent; transition: all .15s var(--ease); }
.toc a:hover { color: var(--tx-0); }
.toc a.on { color: var(--s-0); border-left-color: var(--s-2); }

@media (max-width: 860px) {
  .legal-layout { grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); }
  .toc { position: static; }
  .toc ul { columns: 2; column-gap: var(--sp-4); line-height: 1.9; }
}

/* ----------------------------------------------------------------- footer -- */

.foot {
  margin-top: var(--sp-8); padding: var(--sp-6) 0 var(--sp-5);
  border-top: 1px solid var(--line); background: rgba(7,7,10,.6);
  font-size: .84rem; color: var(--tx-2);
}
.foot-grid { display: grid; gap: var(--sp-5); grid-template-columns: 1.6fr repeat(3, 1fr); margin-bottom: var(--sp-5); }
.foot ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.foot a { color: var(--tx-2); }
.foot a:hover { color: var(--s-1); }
.foot-bottom {
  padding-top: var(--sp-4); border-top: 1px solid var(--line);
  display: flex; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap;
  font-size: .78rem; color: var(--tx-3);
}
.risk-line { font-size: .78rem; color: var(--tx-3); line-height: 1.55; max-width: 72ch; }
.feed-status {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: .74rem; color: var(--tx-3);
}

/* ------------------------------------------------------------- responsive -- */

@media (max-width: 1080px) {
  .g-4 { grid-template-columns: repeat(2, 1fr); }
  .foot-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 880px) {
  .nav-links {
    position: fixed; inset: var(--nav-h) 0 auto 0; display: none;
    flex-direction: column; gap: 2px; padding: var(--sp-4);
    background: rgba(7,7,10,.97);
    backdrop-filter: blur(22px); -webkit-backdrop-filter: blur(22px);
    border-bottom: 1px solid var(--line);
  }
  .nav-links.open { display: flex; }
  .nav-links a { padding: 12px 14px; }
  .nav-toggle { display: grid; place-items: center; }
  .nav .wrap { gap: var(--sp-3); }
  .nav-ticker { display: none; }
}

@media (max-width: 660px) {
  :root { --sp-5: 16px; --sp-6: 24px; --sp-7: 32px; --sp-8: 48px; --sp-9: 64px; }
  body { font-size: 14.5px; }
  .wrap { padding: 0 var(--sp-4); }
  .g-2, .g-3, .g-4, .g-auto { grid-template-columns: minmax(0, 1fr); }
  .wallet-split { grid-template-columns: minmax(0, 1fr); }
  .wallet-split .divider { height: 1px; }
  .identity { grid-template-columns: minmax(0, 1fr); text-align: center; }

  /* Segmented controls hold more labels than a 390px screen has room for, so they
     scroll rather than push the page sideways. */
  .tabs, .side-toggle { max-width: 100%; overflow-x: auto; }
  .tabs { scrollbar-width: none; }
  .tabs::-webkit-scrollbar { display: none; }

  /* Flex items default to min-width: auto, which is min-content — so a row
     holding a scrollable tab strip or a long label still refuses to shrink and
     pushes past the screen edge. Same fix as the grid tracks, applied where the
     layout is flex. */
  .row > *, .row-between > *, .chart-bar > *, .card-head > * { min-width: 0; }
  .card { padding: var(--sp-4); border-radius: var(--r); }
  .stat-v { font-size: 1.3rem; }
  .stat-v-lg { font-size: 1.85rem; }
  .chart-canvas { height: 310px; }
  .chart-canvas.tall { height: 370px; }
  .foot-grid { grid-template-columns: 1fr; }
  .toast-host { left: var(--sp-4); right: var(--sp-4); bottom: var(--sp-4); max-width: none; }
  .steps { flex-direction: column; gap: 2px; }
  .step { border-top: none; border-left: 1px solid var(--k-4); }
  .step.on { border-left-color: var(--s-2); }
  .step.done { border-left-color: var(--up); }

  /* A 70px blur animating behind the fold is the most expensive thing on the
     page and the least noticed. The plate, engine-turning and grain all stay —
     those are static and free — so the hero still looks machined, it just stops
     moving. */
  .hero-sweep { animation: none; filter: blur(46px); opacity: .7; }
  .metal-lit { animation: none; background-position: 30% 50%; }
  .hero-engine { opacity: .4; }
}

/* --------------------------------------------------------- accessibility -- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
  /* Motion off, material intact. Someone who has asked their system to stop
     animations still deserves the finished surface, not a bare rectangle. */
  .hero-sweep { animation: none; }
  .metal-lit { animation: none; background-position: 30% 50%; }
  .card-lift:hover { transform: none; }
  .live-dot { animation: none; }
  .tape-row.new { animation: none; }
}

@media print {
  body::before, .nav, .foot, .toast-host, .btn, .hero-media { display: none !important; }
  body { background: #fff; color: #000; }
  .card { border: 1px solid #ccc; background: #fff; box-shadow: none; }
  * { color: #000 !important; }

  /* Anything still waiting to be revealed would print as a blank block, so the
     animation's starting state is overridden rather than relied upon. */
  [data-reveal] { opacity: 1 !important; transform: none !important; filter: none !important; }

  /* The tax statement is the page people actually print, and it is mostly
     tables. Without borders and a repeated header a multi-page table is
     unreadable on paper. */
  table.data { border: 1px solid #999; }
  table.data thead { display: table-header-group; }
  table.data th, table.data td { border-bottom: 1px solid #ccc; background: #fff !important; }
  table.data tr, .card, .ledger-row { break-inside: avoid; }
  .ledger-row { border-bottom: 1px solid #eee; }
  .badge, .chip { border: 1px solid #999 !important; background: #fff !important; }
  .progress { border: 1px solid #999; }
  .progress span { background: #999 !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .7em; }
}


/* ============================================================================
   Scroll reveal
   ----------------------------------------------------------------------------
   Content arrives as you reach it, one element at a time. The grammar is
   deliberately narrow — a long ease-out, a short rise, a little defocus
   resolving — because that reads as considered, whereas varied directions and
   bounces read as a template.

   Three rules keep it feeling expensive rather than busy:

     Slow out, never in. 900ms on a cubic-bezier(.16,1,.3,1) decelerates almost
     to a stop, which is what makes movement feel weighted instead of springy.

     One direction only. Everything rises. Nothing slides in from the side, and
     nothing scales up from nothing.

     Reveal once. Elements do not re-animate when scrolled back past — an element
     that keeps replaying is a distraction, not a delight.

   Only opacity, transform and filter are animated, so this stays on the
   compositor and never triggers layout.
   ============================================================================ */

[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 20px, 0);
  filter: blur(5px);
  transition:
    opacity .9s var(--ease-out),
    transform .9s var(--ease-out),
    filter .9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}
[data-reveal].shown {
  opacity: 1;
  transform: none;
  filter: blur(0);
}
/* Released after the transition so hundreds of revealed nodes are not all
   holding a compositor layer for the rest of the session. */
[data-reveal].settled { will-change: auto; transition: none; }

/* Quieter variant for dense areas — table rows, tape lines, list items — where
   a 20px rise on every row would look like the page is loading badly. */
[data-reveal='soft'] { transform: translate3d(0, 10px, 0); filter: blur(3px); }

/* For a figure that should feel like it lands. Slightly further, slightly
   slower. Used on the price and the headline numbers. */
[data-reveal='weighty'] {
  transform: translate3d(0, 30px, 0);
  filter: blur(8px);
  transition-duration: 1.15s;
}

/* Stagger. A parent sets data-reveal-group and each child gets its index, so a
   row of cards resolves left to right rather than all at once. */
[data-reveal-group] > [data-reveal] {
  --reveal-delay: calc(var(--i, 0) * 80ms);
}
[data-reveal-group='tight'] > [data-reveal] {
  --reveal-delay: calc(var(--i, 0) * 45ms);
}

/* A hairline that draws itself. Section rules and card underlines use this —
   it is the single most "engraved" gesture available for the cost of a scaleX. */
.rule {
  height: 1px; border: 0; margin: var(--sp-5) 0;
  background: linear-gradient(90deg, rgba(255,255,255,.16), rgba(255,255,255,.05) 55%, transparent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1.2s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.rule.shown { transform: scaleX(1); }

/* A silver underline that grows beneath a heading as it arrives. */
.underline-draw { position: relative; display: inline-block; padding-bottom: 10px; }
.underline-draw::after {
  content: ''; position: absolute; left: 0; bottom: 0; height: 1px; width: 100%;
  background: var(--brushed-dim);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 1.1s var(--ease-out) .18s;
}
.underline-draw.shown::after { transform: scaleX(1); }

/* Section spacing. Generous, and the reason the reveals have room to read as
   separate moments rather than one wave. */
.section { padding: var(--sp-8) 0; position: relative; }
.section-lg { padding: var(--sp-9) 0; }
.section-head { max-width: 68ch; margin-bottom: var(--sp-6); }
.section-num {
  font-family: var(--mono); font-size: .7rem; letter-spacing: .18em;
  color: var(--tx-3); margin-bottom: var(--sp-3);
}

/* A number that counts up to its value on reveal. The digits are tabular already,
   so the width does not jump while it runs. */
.count-up { font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  /* Everything visible immediately, no movement. Not "animated faster" —
     genuinely off, because the point is the absence of motion. */
  [data-reveal] {
    opacity: 1 !important; transform: none !important; filter: none !important;
    transition: none !important;
  }
  .rule { transform: scaleX(1) !important; transition: none !important; }
  .underline-draw::after { transform: scaleX(1) !important; transition: none !important; }
}


/* ============================================================================
   Crypto furniture
   ----------------------------------------------------------------------------
   The market motifs: candles, asset rows, sparklines, the tracking identity.
   Asset colour is used as a thin accent — a rail, a swatch, a glyph — never as a
   fill, so the page stays silver and black with the coins as highlights.
   ============================================================================ */

/* -------------------------------------------------------------- asset rows -- */

.asset-row {
  display: grid;
  grid-template-columns: 34px 1fr auto auto;
  align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid rgba(255,255,255,.035);
  transition: background .15s var(--ease);
}
.asset-row:last-child { border-bottom: 0; }
.asset-row:hover { background: rgba(255,255,255,.02); }

/* The coin glyph. A ring in the asset's colour with its ticker inside — reads as
   a coin without needing an image request per asset. */
.coin {
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--mono); font-size: .6rem; font-weight: 700; letter-spacing: -.02em;
  border: 1px solid currentColor;
  position: relative;
}
.coin::after {
  content: ''; position: absolute; inset: -1px; border-radius: 50%;
  background: currentColor; opacity: .09;
}
.coin span { position: relative; z-index: 1; color: var(--tx-0); }
.coin.btc { color: var(--btc); }
.coin.eth { color: var(--eth); }
.coin.sol { color: var(--sol); }
.coin.arv { color: var(--s-1); }
.coin.arv::after { opacity: .14; }

.asset-name { min-width: 0; }
.asset-name .t { font-weight: 620; font-size: .92rem; }
.asset-name .s { font-size: .72rem; color: var(--tx-3); text-transform: uppercase; letter-spacing: .06em; }

/* A left rail in the asset colour, so a row is identifiable at a glance. */
.asset-row.railed { border-left: 2px solid transparent; padding-left: calc(var(--sp-4) - 2px); }
.asset-row.railed.btc { border-left-color: var(--btc); }
.asset-row.railed.eth { border-left-color: var(--eth); }
.asset-row.railed.sol { border-left-color: var(--sol); }
.asset-row.railed.arv { border-left-color: var(--s-2); }

/* ---------------------------------------------------------------- candles --- */

/* A decorative candlestick run, drawn in CSS. Used in the hero and as section
   punctuation — it says "market" without loading a chart library above the fold. */
.candles {
  display: flex; align-items: flex-end; gap: 3px; height: 64px;
}
/* Full height so the wick spans the range and the body is a percentage of it.
   Without an explicit height the flex item collapses to its content — and since
   the body starts at zero height for the reveal, the whole run would be
   invisible. */
.candle {
  position: relative; width: 6px; height: 100%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
}
/* The wick */
.candle::before {
  content: ''; position: absolute; width: 1px; top: 0; bottom: 0;
  background: currentColor; opacity: .45;
}
/* The body */
.candle::after {
  content: ''; position: relative; width: 100%;
  height: var(--body, 50%);
  background: currentColor;
  border-radius: 1px;
  opacity: .85;
}
.candle.up { color: var(--up); }
.candle.down { color: var(--down); }
.candle.neutral { color: var(--s-4); }

/* Hero candles: taller, dimmer, and they grow on reveal so the hero has one
   piece of market motion that is not the price itself. */
.candles-hero { height: 96px; gap: 5px; opacity: .55; }
.candles-hero .candle { width: 7px; }
.candles-hero .candle::after {
  height: 0;
  transition: height 1.1s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 55ms);
}
.candles-hero.shown .candle::after { height: var(--body, 50%); }

/* -------------------------------------------------------------- sparkline -- */

.spark { width: 84px; height: 26px; display: block; flex-shrink: 0; }
.spark path { fill: none; stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.spark.up path { stroke: var(--up); }
.spark.down path { stroke: var(--down); }
.spark .fill { stroke: none; opacity: .12; }
.spark.up .fill { fill: var(--up); }
.spark.down .fill { fill: var(--down); }

/* --------------------------------------------------------------- identity -- */

/* The tracking identity panel — ARV's percentage beside Bitcoin's rupee
   percentage. They are the same number by construction, and showing both is what
   lets a reader check that rather than take it on trust. */
.identity {
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: var(--sp-4);
  padding: var(--sp-5); border-radius: var(--r-lg);
  background: var(--k-1); border: 1px solid var(--line);
}
.identity-side { text-align: center; }
.identity-side .k {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--tx-3); margin-bottom: 6px;
}
.identity-side .v {
  font-family: var(--mono); font-size: 1.5rem; font-weight: 620; letter-spacing: -.03em;
}
.identity-eq {
  font-family: var(--serif); font-size: 1.6rem; color: var(--s-3);
  padding: 0 var(--sp-2);
}
.identity.agrees .identity-eq { color: var(--up); }
.identity.diverges { border-color: rgba(240,97,109,.35); }
.identity.diverges .identity-eq { color: var(--down); }

/* ------------------------------------------------------------- formula ----- */

.formula {
  font-family: var(--mono); font-size: 1rem; line-height: 2.1;
  white-space: nowrap; overflow-x: auto;
  padding: var(--sp-4) var(--sp-5);
  background: var(--k-1); border: 1px solid var(--line); border-radius: var(--r);
  color: var(--tx-1);
}
.formula .arv { color: var(--s-0); }
.formula .btc { color: var(--btc); }
.formula .op { color: var(--tx-3); }

/* ------------------------------------------------------------- wallet card - */

/* Two balances, one card. Rupees and ARV are different kinds of thing and the
   split is load-bearing — a user needs to see instantly which one they can spend
   and which one is exposure. */
.wallet-split {
  display: grid; grid-template-columns: 1fr 1px 1fr; gap: var(--sp-5);
  align-items: stretch;
}
.wallet-split .divider { background: var(--line); }
.wallet-locked {
  font-size: .74rem; color: var(--warn);
  display: inline-flex; align-items: center; gap: 4px;
}

@media (max-width: 660px) {
  .identity { grid-template-columns: 1fr; gap: var(--sp-3); }
  .identity-eq { transform: rotate(90deg); }
  .wallet-split { grid-template-columns: 1fr; }
  .wallet-split .divider { height: 1px; }
  .asset-row { grid-template-columns: 30px 1fr auto; }
  .asset-row .spark { display: none; }
  .candles-hero { height: 68px; gap: 4px; }
}


/* ---------------------------------------------------------------- chevrons -- */

/* Drawn with borders rather than typed as an arrow character.
   Google Fonts serves the latin subset by default, which has no U+2192, so a
   literal → falls back — and on a device with no font carrying it, that is a
   tofu box. A border chevron always renders, at any size, in any font. */
.arrow::after {
  content: '';
  display: inline-block;
  width: .42em; height: .42em;
  margin-left: .5em;
  border-right: 1.5px solid currentColor;
  border-top: 1.5px solid currentColor;
  transform: rotate(45deg) translateY(-.06em);
  transition: transform .2s var(--ease);
}
.arrow:hover::after { transform: rotate(45deg) translate(.1em, -.06em); }

/* Downward, for a scroll cue. */
.arrow-down::after { transform: rotate(135deg) translateX(-.06em); }


/* ============================================================================
   SIGN IN WITH GOOGLE
   ============================================================================

   Google renders its own button inside an iframe and will not accept our CSS, by
   design — it has to look like Google's button or it is not trustworthy. So the
   work here is confining it: giving it a slot the right width, and a divider
   above it that belongs to this palette rather than to Google's.

   `filled_black` is the theme chosen in auth.js. It is the only one that does not
   sit on this page like a white sticker. */

/* A general hint, not only the one inside a .field. The Google block needs a
   caption that lives outside a form field. */
.hint {
  font-size: .76rem;
  color: var(--tx-3);
  line-height: 1.45;
}
.hint.warn { color: var(--warn); }

/* "or", with a hairline through it. */
.or-rule {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-5) 0 var(--sp-4);
  color: var(--tx-3);
  font-size: .7rem;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.or-rule::before,
.or-rule::after {
  content: '';
  flex: 1;
  height: 1px;
  /* Fades out towards the word so the line does not appear to collide with it. */
  background: linear-gradient(90deg, transparent, var(--line-2), transparent);
}

/* The slot Google draws into.
   Centred, and given a minimum height so the card does not jump when the button
   finally appears — the script is third-party and can take a moment. */
.google-slot {
  display: flex;
  justify-content: center;
  min-height: 44px;
}
/* Google sets an inline width on its own iframe; this keeps it from overflowing a
   narrow card on a phone. */
.google-slot > div,
.google-slot iframe {
  max-width: 100% !important;
}
