/* ==========================================================================
   PRIVACY SWAP - landing
   ========================================================================== */

/* fixed WebGL stage sitting behind every section.
   The gradient is the fallback: it stays if the canvas never mounts. It also
   carries the violet and jade washes that the whole page sits on. */
.stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(120% 95% at 16% 88%, rgba(27,106,97,0.52) 0%, transparent 60%),
    radial-gradient(90% 80% at 84% 6%, rgba(123,106,168,0.38) 0%, transparent 64%),
    radial-gradient(70% 55% at 62% 46%, rgba(217,184,124,0.10) 0%, transparent 72%),
    #0A0C14;
}
.stage canvas { width: 100%; height: 100%; }

/* very fine grain, keeps large dark fields from banding */
.grain {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.16;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

/* darkens the environment behind type, weighted to the left where copy sits */
/* Scrim behind the copy. It was heavy enough to erase the environment it sits
   on: the sculpture area measured 13 out of 255, effectively black. It now
   darkens only where text actually lands and lets the rest of the frame
   through. */
.vig {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(100deg, rgba(7,8,13,0.97) 0%, rgba(7,8,13,0.92) 36%,
                    rgba(7,8,13,0.34) 50%, rgba(7,8,13,0.05) 62%,
                    rgba(7,8,13,0.16) 100%),
    radial-gradient(130% 95% at 50% 45%, transparent 42%,
                    rgba(7,8,13,0.28) 84%, rgba(7,8,13,0.66) 100%);
}

main { position: relative; z-index: 2; }

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

.hero {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-bottom: clamp(28px, 5vh, 64px);
  position: relative;
}
.hero__top { padding-top: calc(var(--nav-h) + clamp(20px, 5vh, 64px)); }

.hero__title {
  font-size: clamp(40px, 6.2vw, 92px);
  max-width: 17ch;
  margin-top: clamp(18px, 2.6vh, 30px);
  line-height: 1.03;
}
/* the emphasised word carries the only gradient in the type system */
.hero__title em {
  font-style: italic;
  background: linear-gradient(96deg, var(--jade-soft) 0%, var(--jade) 46%, var(--gold) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero__foot {
  margin-top: clamp(26px, 4.2vh, 52px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 26px 56px;
  align-items: end;
}
.hero__lede { max-width: 48ch; }
.hero__cta { display: flex; gap: 12px; flex-wrap: wrap; }

@media (max-width: 820px) {
  .hero__foot { grid-template-columns: 1fr; }
}

.hero__scroll {
  margin-top: clamp(26px, 5vh, 62px);
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.hero__scroll i {
  display: block;
  width: 52px;
  height: 1px;
  background: linear-gradient(90deg, var(--gold), transparent);
  animation: sweep 2.8s var(--ease-io) infinite;
  transform-origin: left;
}
@keyframes sweep {
  0%   { transform: scaleX(0); opacity: 0; }
  35%  { transform: scaleX(1); opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}

/* ------------------------------------------------------------------ blocks */

.section {
  padding: clamp(88px, 15vh, 190px) 0;
  position: relative;
}
.section--tight { padding: clamp(60px, 9vh, 110px) 0; }

.sechead {
  display: grid;
  grid-template-columns: 200px minmax(0, 1fr);
  gap: 24px 40px;
  align-items: start;
  margin-bottom: clamp(40px, 6vh, 74px);
}
@media (max-width: 880px) {
  .sechead { grid-template-columns: 1fr; gap: 14px; }
}

.statement {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: clamp(26px, 3.5vw, 54px);
  line-height: 1.2;
  letter-spacing: -0.004em;
  max-width: 26ch;
  text-wrap: balance;
}
.statement .dim { color: var(--text-faint); }

/* --------------------------------------------------------------- the route */

.route {
  display: grid;
  gap: 0;
  border: 1px solid var(--edge);
  border-radius: var(--r-lg);
  overflow: hidden;
  background:
    linear-gradient(180deg, rgba(237,232,224,0.03), rgba(237,232,224,0) 30%),
    linear-gradient(180deg, rgba(20,24,38,0.72), rgba(10,12,19,0.78));
  box-shadow: var(--lift-2);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.route__row {
  display: grid;
  grid-template-columns: 78px 1fr minmax(0, 1.15fr);
  gap: 24px 40px;
  align-items: baseline;
  padding: 26px 30px;
  border-bottom: 1px solid var(--line);
  position: relative;
  transition: background 0.6s var(--ease);
}
.route__row:last-child { border-bottom: 0; }
.route__row:hover { background: var(--jade-wash); }
.route__row::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: linear-gradient(180deg, var(--jade), var(--gold));
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.9s var(--ease);
}
.route__row.is-in::before { transform: scaleY(1); }

.route__idx {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.14em;
  color: var(--gold);
  opacity: 0.8;
}
.route__name {
  font-size: clamp(19px, 2vw, 26px);
  font-weight: 400;
  letter-spacing: -0.004em;
  display: flex;
  align-items: center;
  gap: 14px;
}
/* official marks of the networks on the route */
.route__logo {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  object-fit: contain;
  flex-shrink: 0;
}
.route__logo--glyph {
  color: var(--gold);
  opacity: 0.7;
  padding: 2px;
  box-sizing: border-box;
}
.route__row.is-in .route__logo { animation: logoin 0.9s var(--ease) both; }
@keyframes logoin {
  from { opacity: 0; transform: scale(0.8); }
  to   { opacity: 1; transform: none; }
}

.route__meta {
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.8;
  color: var(--text-dim);
}
@media (max-width: 820px) {
  .route__row { grid-template-columns: 48px 1fr; }
  .route__meta { grid-column: 2; }
}

.route__row[data-tone="evm"] .route__name { color: var(--jade); }

/* --------------------------------------------------------------- artifact */

.artifact {
  position: relative;
  min-height: 240vh;
}
.artifact__sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.artifact__copy {
  position: relative;
  z-index: 2;
  max-width: 30ch;
  pointer-events: none;
}
.artifact__caption {
  margin-top: 24px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.95;
  letter-spacing: 0.02em;
  color: var(--text-faint);
}

/* ---------------------------------------------------------------- metrics */

.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: clamp(12px, 1.3vw, 18px);
}
.metric {
  padding: 30px 26px 34px;
  border: 1px solid var(--edge);
  border-radius: var(--r-lg);
  background:
    url("../img/tex-obsidian.jpg") center / 420px repeat,
    linear-gradient(180deg, rgba(237,232,224,0.045), rgba(237,232,224,0) 46%),
    linear-gradient(180deg, rgba(20,24,38,0.9), rgba(10,12,19,0.9));
  background-blend-mode: soft-light, normal, normal;
  box-shadow: var(--lift-2);
  position: relative;
  overflow: hidden;
  transition: transform 0.7s var(--ease), border-color 0.7s var(--ease);
}
.metric:hover {
  transform: translateY(-4px);
  border-color: var(--edge-gold);
}
.metric::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(237,232,224,0.18), transparent);
}
.metric__v {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: clamp(34px, 4.4vw, 56px);
  line-height: 1.05;
  letter-spacing: -0.015em;
  color: var(--text);
}
.metric__v em {
  font-style: normal;
  color: var(--jade);
}
/* a word reads much wider than a numeral, so it takes a smaller step */
.metric__v--text {
  font-size: clamp(24px, 2.5vw, 36px);
  letter-spacing: -0.008em;
  line-height: 1.15;
}
.metric__k {
  margin-top: 14px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
}
.metric__n {
  margin-top: 10px;
  font-size: 14px;
  color: var(--text-dim);
  line-height: 1.65;
}

/* ----------------------------------------------------------------- phases */

.phases { display: grid; gap: clamp(12px, 1.3vw, 18px); }
.phase {
  background:
    url("../img/tex-obsidian.jpg") center / 420px repeat,
    linear-gradient(180deg, rgba(237,232,224,0.035), rgba(237,232,224,0) 46%),
    linear-gradient(180deg, rgba(20,24,38,0.9), rgba(10,12,19,0.9));
  background-blend-mode: soft-light, normal, normal;
  border: 1px solid var(--edge);
  border-radius: var(--r-lg);
  box-shadow: var(--lift-1);
  display: grid;
  grid-template-columns: 130px minmax(0, 1fr) 170px;
  gap: 20px 36px;
  padding: 26px 28px 28px;
  align-items: baseline;
  transition: border-color 0.7s var(--ease), transform 0.7s var(--ease);
}
.phase:hover { border-color: var(--edge-gold); transform: translateY(-3px); }
@media (max-width: 880px) {
  .phase { grid-template-columns: 1fr; gap: 10px; }
}
.phase__tag {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--jade);
}
.phase__tag[data-state="next"] { color: var(--text-faint); }
.phase__body h3 {
  font-size: 19.5px;
  margin-bottom: 7px;
  letter-spacing: -0.004em;
}
.phase__body p {
  font-size: 14.5px;
  color: var(--text-dim);
  max-width: 62ch;
  line-height: 1.68;
}
.phase__when {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-faint);
  text-align: right;
}
@media (max-width: 880px) { .phase__when { text-align: left; } }

/* -------------------------------------------------------------------- cta */

.cta {
  text-align: center;
  padding: clamp(96px, 17vh, 210px) 0;
  position: relative;
  isolation: isolate;
}
/* caustic filaments drifting behind the closing statement */
.cta::before {
  content: "";
  position: absolute;
  inset: -10% 0;
  z-index: -1;
  background: url("../img/tex-caustics.jpg") center / cover no-repeat;
  opacity: 0.26;
  mix-blend-mode: screen;
  pointer-events: none;
  animation: drift 34s var(--ease-io) infinite alternate;
}
@keyframes drift {
  from { transform: translate3d(-2%, 0, 0) scale(1.04); }
  to   { transform: translate3d(2%, -1.5%, 0) scale(1.1); }
}
.cta__title {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: clamp(38px, 6.4vw, 92px);
  line-height: 1.06;
  letter-spacing: -0.012em;
  max-width: 18ch;
  margin-inline: auto;
  text-wrap: balance;
}
.cta__actions {
  margin-top: 40px;
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

/* --------------------------------------------------------------- hairline */

.hairline {
  position: relative;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--edge-gold), transparent);
  overflow: hidden;
}
.hairline::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--jade-glow), transparent);
  transform: translateX(-100%);
  animation: travel 7s var(--ease-io) infinite;
}
@keyframes travel {
  0%   { transform: translateX(-100%); }
  60%  { transform: translateX(100%); }
  100% { transform: translateX(100%); }
}

/* ------------------------------------------------- supported technology band
   The networks are disclosed here as infrastructure. They are deliberately not
   what the product's route monitor shows: there, each step is one of our own
   agents, and the mapping from agent to network is never printed. */

.band {
  padding: clamp(46px, 8vh, 92px) 0;
  border-top: 1px solid var(--edge);
  border-bottom: 1px solid var(--edge);
  background: linear-gradient(180deg, rgba(123,106,168,0.05), rgba(27,106,97,0.05));
  overflow: hidden;
}
.band__note {
  margin-top: 14px;
  max-width: 62ch;
  font-size: 15px;
  line-height: 1.65;
  color: var(--text-dim);
}
.band__viewport {
  margin-top: clamp(26px, 4vh, 44px);
  position: relative;
  overflow: hidden;
  /* tepi kiri dan kanan dilebur, supaya pita tidak terpotong mendadak */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 11%, #000 89%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 11%, #000 89%, transparent);
}
.band__track {
  display: flex;
  align-items: center;
  gap: clamp(40px, 5vw, 76px);
  width: max-content;
  animation: bands 42s linear infinite;
}
.band:hover .band__track { animation-play-state: paused; }
@keyframes bands {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
.tech {
  display: inline-flex;
  align-items: center;
  gap: 13px;
  white-space: nowrap;
  font-size: 15.5px;
  color: var(--text-dim);
  transition: color 0.4s var(--ease);
}
.tech:hover { color: var(--text); }
.tech img {
  width: 27px;
  height: 27px;
  border-radius: 50%;
  object-fit: contain;
  flex-shrink: 0;
}
.tech b { font-weight: 400; letter-spacing: 0.005em; }

/* penanda mesh: sigil agen sedikit lebih kecil dari logo jaringan */
.route__logo--agent { width: 28px; height: 28px; }

@media (prefers-reduced-motion: reduce) {
  .band__track { animation: none; }
}


/* ------------------------------------------------------- the hero statement

   One paragraph, two colours. The first half states the problem, the second
   half states what changes. They are inline so the sentence still reads as one
   thought, and the colour change carries the turn. */

.lede__bad  { color: var(--tone-bad); }
.lede__good { color: var(--tone-good); }

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

   The eyebrow carries the positioning claim, so the claim is set apart from
   the network it applies to rather than run together with it. */

.hero__eyebrow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}
.eyebrow__flag {
  color: var(--gold-soft);
  font-weight: 500;
}
.eyebrow__sep {
  display: inline-block;
  width: 26px;
  height: 1px;
  background: linear-gradient(90deg, var(--gold), rgba(217,184,124,0.15));
  flex-shrink: 0;
}
/* no full stop here: the rule that follows already separates the two halves */

