/* SyxVPN — the public page.
 *
 * One stylesheet for both languages. No CDN and no third-party script: this
 * page is read from networks where fonts.googleapis.com is a gamble, and a
 * page that waits on a blocked host is a page nobody sees.
 *
 * The one font it does load is served from this same origin, so it is exactly
 * as reachable as the page asking for it — see the @font-face below.
 *
 * Near-black ground, one lime accent, and a warmer gold used as light rather
 * than as paint. Four treatments carry the whole page, and every one of them is
 * a gradient — nothing here downloads an image:
 *
 *   .arc     a wide flat band with a bright thin edge, as if a lit sphere were
 *            rising past the bottom of the section above it.
 *   .lit     a card with that light spilling over its own top corner rather
 *            than clipped by it. Clipped, it is a gradient painted on a panel;
 *            spilling, the panel is an object with something bright behind it.
 *   .label   a section's name in wide-tracked capitals, a rule running out from
 *            either side.
 *   .chip    a round icon well with a lime rim.
 *
 * The light has to fall away fast. Spread over a card's full width and half its
 * height it stops reading as light and becomes a muddy olive wash, which is the
 * one failure mode this look has.
 */
:root {
  --bg: #0a0a0a;
  --surface: #141414;
  --surface-high: #1b1b1b;
  --border: #262626;
  --text: #f4f4f4;
  --dim: #909090;
  --faint: #6a6a6a;
  --accent: #d8f83a;
  --accent-ink: #0e1400;
  --gold: #d9b021;
  --gold-soft: #f0e07a;
  --radius: 26px;
  --max: 1120px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

/* Persian, in a face drawn for Persian.
 *
 * The stack used to start with system-ui, which meant the Persian text was
 * always drawn by whatever the device happened to default to — Tahoma on
 * Windows, something else on Android — and Vazirmatn, sitting fourth, was never
 * reached even on a machine that had it. A stack is not a preference list if
 * the first entry always matches.
 *
 * So the face is served rather than hoped for. Three things keep that honest:
 *
 *   it is on this origin, not a CDN, so it is reachable wherever the page is;
 *   `unicode-range` is Persian only, so the English page never downloads it and
 *     Latin keeps the system's own grotesque, which is what the design wants;
 *   `swap` means the text is readable from the first paint in the fallback and
 *     changes face when the file lands — never invisible while waiting.
 *
 * One variable file, 48KB, every weight from 100 to 900. Vazirmatn 33.0.3,
 * SIL Open Font License 1.1 — the licence ships beside it in public/fonts/.
 */
@font-face {
  font-family: "Vazirmatn Web";
  src: url("/fonts/vazirmatn-nl-var.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  /* Arabic script, Arabic-Indic and Persian digits, presentation forms — plus
     U+200C, the zero-width non-joiner, which Persian cannot be set without. */
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+200C-200F,
                 U+FB50-FDFF, U+FE70-FEFF;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* The face is asked for on the Persian page only. `unicode-range` alone was not
   enough: the English page carries the word فارسی in its language switcher, and
   a browser downloads a 48KB file for one nav link as readily as for a whole
   page of text. There, that word can have the system's own Arabic fallback.

   Persian also sits lower and looser than Latin at the same size: set to a
   Latin line height its descenders and its dots collide. Corrected here too,
   so both belong to the same rule and cannot drift apart. */
[dir="rtl"] body {
  font-family: "Vazirmatn Web", system-ui, -apple-system, "Segoe UI", sans-serif;
  line-height: 1.85;
}
[dir="rtl"] h1, [dir="rtl"] h2 { line-height: 1.45; letter-spacing: 0; }
[dir="rtl"] .card h3, [dir="rtl"] .plan-head .term { letter-spacing: 0; }
/* The head of a price card sits on the leading edge, so the light belongs on
   the other one — which swaps sides with the direction. */
[dir="rtl"] .plan::before { --gx: 12%; }
[dir="rtl"] .plans .plan:nth-child(2)::before { --gx: 18%; }
[dir="rtl"] .plans .plan:nth-child(3)::before { --gx: 6%; }

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }

.wrap { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 20px; }

/* ------------------------------------------------------------------ header */

.top {
  position: sticky; top: 0; z-index: 40;
  background: rgba(10, 10, 10, .82);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
.top .wrap { position: relative; display: flex; align-items: center; gap: 16px; height: 68px; }
/* The mark alone: the name is no longer set as type beside it. The glow is the
   one from the reference icon, in the site's accent rather than its blue. */
.brand { display: flex; align-items: center; }
.brand svg { display: block; }
/* Light around the tile rather than a line drawn on it: two shadows, a tight
   one for the edge and a wide one for the bloom. */
.brand .mark {
  filter: drop-shadow(0 0 4px rgba(216, 248, 58, .55)) drop-shadow(0 0 13px rgba(216, 248, 58, .3));
}
.brand:hover .mark {
  filter: drop-shadow(0 0 5px rgba(216, 248, 58, .7)) drop-shadow(0 0 18px rgba(216, 248, 58, .42));
}
.nav { display: flex; gap: 24px; margin-inline-start: auto; align-items: center; }
.nav a { color: var(--dim); font-size: 14px; }
.nav a:hover { color: var(--text); }
.nav .btn { padding: 10px 20px; font-size: 14px; }

/* Language switcher: a <details>, so it opens with JavaScript off. */
.langsel { position: relative; margin-inline-start: 4px; }
.langsel > summary {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 3px 2px; font-size: 13px; color: var(--dim);
  list-style: none; user-select: none;
}
.langsel > summary::-webkit-details-marker { display: none; }
.langsel > summary::after {
  content: ""; width: 6px; height: 6px; margin-inline-start: 2px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
}
.langsel[open] > summary, .langsel > summary:hover { color: var(--text); }
.langsel > summary:focus { outline: none; }
.langsel > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 8px; }

.langsel .menu, .menubtn .menu {
  position: absolute; inset-inline-end: 0; top: calc(100% + 10px);
  min-width: 168px; padding: 6px;
  background: var(--surface-high);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .55);
  z-index: 30;
  transform-origin: top var(--menu-origin, right);
}
[dir="rtl"] .langsel .menu, [dir="rtl"] .menubtn .menu { --menu-origin: left; }
.langsel[open] .menu, .menubtn[open] .menu { animation: menu-in .16s cubic-bezier(.2, .7, .3, 1); }
@keyframes menu-in {
  from { opacity: 0; transform: translateY(-6px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
.langsel .menu a, .menubtn .menu a {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 10px; border-radius: 9px;
  font-size: 14px; line-height: 1.3; color: var(--dim); white-space: nowrap;
}
.langsel .menu a:hover, .menubtn .menu a:hover { background: var(--surface); color: var(--text); }
.langsel .menu a[aria-current="true"] { color: var(--accent); }
.langsel .menu .tick { width: 14px; text-align: center; opacity: 0; }
.langsel .menu a[aria-current="true"] .tick { opacity: 1; }

.menubtn { position: static; border: 0; background: none; padding: 0; display: none; }
.menubtn > summary {
  display: flex; align-items: center; justify-content: center;
  /* 20% up from 36. line-height: 0 so no stray text baseline can push the
     glyph off centre inside the square. */
  /* The same tile as the mark beside it: 42px, and a radius of 11.34 because
     the mark's rounded rect is rx 27 in a 100 viewBox drawn at 42. */
  width: 42px; height: 42px; border-radius: 11.34px; line-height: 0;
  /* No outline on the tile — the same light the mark throws, in the same two
     shadows: a tight one for the edge, a wide one for the bloom. The border
     stays as a transparent hairline so the box keeps its measured size. */
  border: 1px solid transparent; background: #0d0d0d;
  box-shadow: 0 0 4px rgba(216, 248, 58, .55), 0 0 13px rgba(216, 248, 58, .3);
  color: var(--accent); cursor: pointer; list-style: none; user-select: none;
}
.menubtn > summary svg { display: block; width: 26.5px; height: 26.5px; }
.menubtn > summary::-webkit-details-marker { display: none; }
.menubtn > summary:focus { outline: none; }
.menubtn > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.menubtn[open] > summary, .menubtn > summary:hover {
  box-shadow: 0 0 5px rgba(216, 248, 58, .7), 0 0 18px rgba(216, 248, 58, .42);
}
.menubtn > summary .ico-close { display: none; }
.menubtn[open] > summary .ico-open { display: none; }
.menubtn[open] > summary .ico-close { display: block; }
.menubtn[open] .menu {
  position: fixed; inset: 68px 12px auto; min-width: 0;
  border: 1px solid var(--border); border-radius: 22px;
  background: var(--surface-high); padding: 8px;
  box-shadow: 0 26px 60px rgba(0, 0, 0, .6);
  animation: sheet-in .18s cubic-bezier(.2, .7, .3, 1);
  z-index: 60;
}
.menubtn[open] .menu a { padding: 15px 14px; border-radius: 14px; font-size: 17px; font-weight: 600; color: var(--text); }
.menubtn[open] .menu a:active { background: var(--surface); }
.menubtn[open] .menu a:last-child {
  margin-top: 6px; padding-top: 16px;
  border-top: 1px solid var(--border); border-radius: 0 0 14px 14px;
  color: var(--accent);
}
@keyframes sheet-in {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: none; }
}
.top:has(.menubtn[open])::after {
  content: ""; position: fixed; inset: 68px 0 0;
  background: rgba(0, 0, 0, .6); z-index: 50;
}
.top:has(.menubtn[open]) .brand { position: relative; z-index: 70; }
html:has(.menubtn[open]) { overflow: hidden; }
@media (max-width: 860px) { .menubtn { display: block; } .nav .hide-sm { display: none; } }

/* ------------------------------------------------------------------- light */

.arc { position: relative; height: 190px; margin: 0 auto -56px; max-width: 820px; pointer-events: none; }
.arc::before, .arc::after { content: ""; position: absolute; inset-inline: 0; top: 0; }
.arc::before {
  height: 190px;
  background: radial-gradient(58% 100% at 50% 0%, rgba(217, 176, 33, .36), rgba(216, 248, 58, .10) 42%, transparent 72%);
  filter: blur(16px);
}
.arc::after {
  height: 130px;
  border-radius: 50% 50% 0 0 / 100% 100% 0 0;
  background: linear-gradient(180deg, rgba(240, 224, 122, .9), rgba(217, 176, 33, .2) 12%, transparent 34%);
  -webkit-mask-image: radial-gradient(70% 100% at 50% 0%, #000 30%, transparent 72%);
  mask-image: radial-gradient(70% 100% at 50% 0%, #000 30%, transparent 72%);
}

.label {
  display: flex; align-items: center; gap: 18px; margin: 0 0 22px;
  color: var(--accent); font-size: 12px; font-weight: 600;
  letter-spacing: .34em; text-transform: uppercase; direction: ltr;
}
.label::before, .label::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, transparent, rgba(216, 248, 58, .35)); }
.label::after { background: linear-gradient(90deg, rgba(216, 248, 58, .35), transparent); }
.label.center { justify-content: center; }
.label.start::before { display: none; }
[dir="rtl"] .label.start::before { display: block; }
[dir="rtl"] .label.start::after { display: none; }

/* ------------------------------------------------------------------ typography */

section { padding: 92px 0; scroll-margin-top: 76px; }
h1 {
  font-size: clamp(40px, 8.6vw, 84px); font-weight: 300;
  line-height: 1.06; margin: 24px 0 0; letter-spacing: -.03em; text-wrap: balance;
}
/* Kept whole. Left to itself the accented phrase breaks across the line and
   leaves its last word stranded, which reads as a mistake rather than a break. */
h1 .on { color: var(--accent); white-space: nowrap; }
h2 {
  font-size: clamp(28px, 5vw, 46px); font-weight: 300;
  line-height: 1.16; margin: 0 0 16px; letter-spacing: -.025em; text-wrap: balance;
}
h3 { font-weight: 400; }
.lede { color: var(--dim); font-size: clamp(15px, 2.4vw, 18px); line-height: 1.7; max-width: 560px; margin: 26px auto 0; text-wrap: pretty; }
.sub { color: var(--dim); margin: 0 0 44px; max-width: 620px; line-height: 1.7; }
.note { color: var(--faint); font-size: 13px; margin-top: 18px; }

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

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  border-radius: 999px; padding: 15px 32px; font-weight: 600; font-size: 15px;
  border: 1px solid transparent; cursor: pointer;
}
.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { filter: brightness(1.07); }
/* The gold outline, filled with a trace of its own colour — the reference's
   second button, and the reason the pair does not read as one button and one
   link. */
.btn-gold {
  border-color: rgba(217, 176, 33, .55); color: var(--text);
  background: rgba(217, 176, 33, .07);
}
.btn-gold:hover { border-color: var(--gold); background: rgba(217, 176, 33, .13); }
.btn-ghost { background: transparent; border-color: var(--border); color: var(--text); }
.btn-ghost:hover { border-color: var(--faint); }
.btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }
/* The pair is one decision offered twice, so the two buttons are the same size.
   A flex row sizes each to its own words — "Get started" next to "See all
   plans" comes out lopsided, which reads as a main button and an afterthought.
   Two equal grid tracks hold them level at every width; the max-width keeps
   them from stretching across a desktop column. */
.cta {
  display: grid; gap: 14px; margin: 36px auto 0; max-width: 430px;
  /* Side by side, in two equal tracks. The 150px floor is the narrowest a
     button gets before a pair stops being readable — at 360px the tracks come
     out at 157 — and only below that does the row fall to one column. A long
     label ("Download for Android") takes two lines inside its track rather than
     breaking the row, which is how this pair already read and is fine. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr));
}
/* Narrower than a free-standing button: at 360px each track is about 160px, and
   the label needs the room more than the padding does. */
.cta > .btn { padding-inline: 18px; }
/* The one-button row in the about section, which should hug its words and sit
   against the start edge rather than stretch to the full track. */
.cta.start {
  display: flex; justify-content: flex-start; flex-wrap: wrap;
  max-width: none; margin-inline: 0;
}

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

.hero { position: relative; overflow: hidden; padding: 64px 0 72px; text-align: center; }
.hero > .wrap { position: relative; z-index: 1; }
/* The ground: a faint dot field standing in for the reference's dotted world
   map, faded out in every direction so it never becomes a texture. */
.hero::before {
  content: ""; position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, .16) 1px, transparent 1px);
  background-size: 22px 22px;
  -webkit-mask-image: radial-gradient(120% 85% at 50% 12%, #000 12%, transparent 68%);
  mask-image: radial-gradient(120% 85% at 50% 12%, #000 12%, transparent 68%);
  opacity: .5; pointer-events: none;
}
.hero::after {
  content: ""; position: absolute; inset: auto 0 -46% 0; height: 540px;
  background: radial-gradient(50% 60% at 50% 100%, rgba(217, 176, 33, .22), rgba(216, 248, 58, .05) 45%, transparent 72%);
  pointer-events: none; animation: glow 9s ease-in-out infinite;
}
@keyframes glow {
  0%, 100% { opacity: .7; transform: translateY(0) scale(1); }
  50%      { opacity: 1;  transform: translateY(-14px) scale(1.04); }
}
.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--border); background: var(--surface);
  border-radius: 999px; padding: 7px 16px; font-size: 13px; color: var(--dim);
}
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }

/* ------------------------------------------------------- the proof band */

/* Big number, quiet label. Every row here has to be something a reader could
   check: this is the exact shape a page uses to say "seventy-two million
   users", and wearing that shape without the truth behind it is how a product
   starts lying before it has shipped. */
/* Tiles, in the page's own material. This row used to be a number beside a
   caption set in wide-tracked capitals — which reads as a caption only while it
   stays on one line. At 430px it wrapped to four ragged lines beside a number
   with nothing to line up against, so the row meant to look checkable looked
   like a mistake instead. Stacked in a card, in ordinary sentence case, it
   reads. */
.proof {
  display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  margin-top: 52px; text-align: start;
}
.proof-item {
  display: flex; flex-direction: column; gap: 7px;
  padding: 22px 24px;
  border: 1px solid var(--border); border-radius: 20px;
  background: var(--surface);
}
.proof-item b {
  font-size: clamp(26px, 4.2vw, 38px); font-weight: 300; letter-spacing: -.03em;
  line-height: 1.15; text-wrap: balance;
}
.proof-item span { color: var(--dim); font-size: 13px; line-height: 1.6; }

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

.grid { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

.card {
  position: relative; overflow: hidden;
  padding: 30px; min-height: 236px;
  display: flex; flex-direction: column;
  /* Not a flat fill: the surface lifts slightly at the top, which is what makes
     the glow read as light landing on glass rather than paint applied to it. */
  background: linear-gradient(180deg, #1b1b1b, #121212 62%);
  border: 1px solid var(--border); border-radius: var(--radius);
  transition: border-color .2s ease, box-shadow .2s ease;
}

/* The light inside the card.
 *
 * Measured off the reference rather than guessed, because the two things that
 * make it work are both easy to get wrong: it is saturated — a gold near
 * #d5c00d, not a pale cream, which is what a blurred white turns into and what
 * makes a knock-off of this look washed out — and it is *large*, its core
 * sitting anywhere from a fifth to half way down the card.
 *
 * It is clipped by the card. That matters: cut by the rounded corner it reads
 * as light inside a glass box, and the corner itself becomes the brightest
 * edge. (The featured price card is the one exception, and spills deliberately.)
 *
 * The core moves from card to card — right, centre, centre-left, left. Four
 * identical cards lit identically read as one card stamped four times; this is
 * the cheapest possible fix for that and the reference does exactly it.
 */
.card::before {
  content: ""; position: absolute; z-index: 0;
  /* A corner light, and it must be spent before it reaches a word.
     The reference's cards are tall and mostly empty, so a core at 43% of their
     height still sits far above their title. These cards are shorter and
     text-dense — at 430px the headings start between 40 and 95px down — and the
     same proportions put the light squarely behind the heading, which is the one
     place it may never be. So the band is short, measured in pixels rather than
     as a fraction of a height that varies, and masked to nothing at its foot so
     there is no edge where it stops. */
  inset: 0 0 auto 0; height: 108px;
  -webkit-mask-image: linear-gradient(180deg, #000 0, #000 34%, transparent 92%);
  mask-image: linear-gradient(180deg, #000 0, #000 34%, transparent 92%);
  --gx: 92%; --gy: 30px;
  background:
    radial-gradient(24% 62% at var(--gx) var(--gy), rgba(240, 216, 14, .96), transparent 72%),
    radial-gradient(48% 116% at var(--gx) var(--gy), rgba(202, 158, 18, .34), transparent 76%),
    radial-gradient(92% 190% at var(--gx) var(--gy), rgba(124, 96, 20, .17), transparent 80%);
  /* Enough blur to lose the gradient's banding, not enough to eat the peak: at
     22px the core measured barely half the reference's brightness. */
  filter: blur(13px);
  pointer-events: none; opacity: var(--lit);
  transition: opacity .25s ease;
}
.grid .card:nth-child(4n + 2)::before { --gx: 56%; --gy: 34px; }
.grid .card:nth-child(4n + 3)::before { --gx: 72%; --gy: 24px; }
.grid .card:nth-child(4n + 4)::before { --gx: 18%; --gy: 36px; }
/* A card that is only a statement carries no icon, so its heading begins at the
   padding and there is no clear zone above it to light. It goes unlit — not
   every card has to be, and a row of plain claims reads better without. */
.grid-2 .card::before { display: none; }

.card > * { position: relative; z-index: 1; }
.card:hover { border-color: var(--faint); box-shadow: 0 14px 34px rgba(0, 0, 0, .45); }
.card h3 { margin: auto 0 10px; font-size: 20px; letter-spacing: -.01em; }
.card p { margin: 0; color: var(--dim); font-size: 14px; }

/* The icon well. */
.chip {
  width: 56px; height: 56px; border-radius: 50%;
  /* Translucent, so the glow behind it tints the well instead of being hidden
     by it — in the reference the disc is olive wherever the light passes under
     it, and neutral grey everywhere else. */
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(216, 248, 58, .55);
  display: flex; align-items: center; justify-content: center; color: var(--accent);
  transition: transform .2s ease;
}
.card:hover .chip { transform: translateY(-2px); }
.chip-sq { border-radius: 15px; border-color: rgba(217, 176, 33, .5); color: var(--gold); }

/* --------------------------------------------------------------- split row */

.split { display: grid; gap: 48px; grid-template-columns: 1fr; align-items: start; }
@media (min-width: 861px) { .split { grid-template-columns: 1fr 1fr; gap: 64px; } }
/* Beside a paragraph in a half-width column, one tile per row — two of them
   side by side there would be about a hundred pixels each. */
.split .proof { margin-top: 0; grid-template-columns: 1fr; }

/* ------------------------------------------------------------ trust marks */

/* The reference puts a wall of client logos here. This product has no clients
   to name, so the row names what it is built out of instead — which is both
   true and, for anybody who recognises the words, more convincing. */
.marks {
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; align-items: center;
  padding: 10px 0 0;
}
/* Chips rather than bare words. Six wide-tracked capitals floating in a row wrap
   into something that looks spilled rather than listed; an outline around each
   one gives the wrap somewhere to happen and matches the chip already used under
   the big call to action. */
.marks span {
  font-size: 12px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--dim); direction: ltr;
  padding: 9px 15px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface);
}

/* ------------------------------------------------------------------- bars */

.bars { display: grid; gap: 28px; }
.bar-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 12px; }
.bar-head h4 { margin: 0; font-size: 17px; font-weight: 400; }
.bar-head b { color: var(--gold); font-size: 14px; font-weight: 500; letter-spacing: .18em; direction: ltr; }
.bar-track { height: 9px; border-radius: 999px; background: var(--surface-high); overflow: hidden; }
.bar-fill {
  /* An <i> is inline, and width does nothing to an inline box: the JS was
     setting the width all along and the track stayed empty. */
  display: block;
  height: 100%; border-radius: 999px; width: 0;
  background: linear-gradient(90deg, var(--gold), var(--gold-soft));
  transition: width 1.4s cubic-bezier(.2, .7, .3, 1);
}

/* ---------------------------------------------------------------- pricing */

.plans { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.plan {
  position: relative; overflow: hidden;
  padding: 30px 28px; display: flex; flex-direction: column; gap: 4px;
  background: linear-gradient(180deg, #1b1b1b, #121212 62%);
  border: 1px solid var(--border); border-radius: var(--radius);
  transition: border-color .2s ease, box-shadow .2s ease;
}
.plan::before {
  content: ""; position: absolute; z-index: 0;
  inset: 0 0 auto 0; height: 86px;
  -webkit-mask-image: linear-gradient(180deg, #000 0, #000 30%, transparent 94%);
  mask-image: linear-gradient(180deg, #000 0, #000 30%, transparent 94%);
  --gx: 88%; --gy: 16px;
  background:
    radial-gradient(17% 68% at var(--gx) var(--gy), rgba(236, 212, 14, .80), transparent 70%),
    radial-gradient(34% 128% at var(--gx) var(--gy), rgba(202, 158, 18, .40), transparent 74%),
    radial-gradient(62% 210% at var(--gx) var(--gy), rgba(124, 96, 20, .22), transparent 78%);
  filter: blur(13px); pointer-events: none; opacity: var(--lit);
}
.plans .plan:nth-child(2)::before { --gx: 82%; --gy: 24px; }
.plans .plan:nth-child(3)::before { --gx: 94%; --gy: 14px; }
.plan > * { position: relative; z-index: 1; }
.plan:hover { border-color: var(--faint); box-shadow: 0 14px 34px rgba(0, 0, 0, .45); }
.plan.best { border-color: rgba(216, 248, 58, .42); }
/* The featured card is lit from underneath as well — the reference's one piece
   of asymmetry, and what makes it read as raised rather than merely outlined. */
.plan.best { overflow: visible; }
.plan.best::after {
  content: ""; position: absolute; z-index: 0;
  inset-inline: 6%; bottom: -34px; height: 90px;
  background: radial-gradient(50% 60% at 50% 30%, rgba(245, 232, 150, .5), rgba(217, 176, 33, .22) 45%, transparent 75%);
  filter: blur(14px); pointer-events: none;
}
.plan .tag {
  align-self: flex-start; margin-bottom: 12px;
  background: var(--accent); color: var(--accent-ink);
  font-size: 11px; font-weight: 700; padding: 4px 12px; border-radius: 999px;
}
.plan-head { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
.plan-head .chip-sq { width: 50px; height: 50px; flex: none; }
.plan-head .term { font-size: 19px; font-weight: 500; line-height: 1.3; }
.plan-head .for { color: var(--dim); font-size: 13px; }
.plan .price { font-size: 42px; font-weight: 300; letter-spacing: -.035em; color: var(--gold); line-height: 1.2; }
/* The unit is a word, not part of the figure: set tight against the digits it
   reads as "2USDT". A margin on both sides survives either direction. */
.plan .price span { font-size: 15px; font-weight: 500; color: var(--dim); margin: 0 8px; letter-spacing: 0; }
.plan .per { color: var(--faint); font-size: 12px; min-height: 18px; }

/* What the plan actually buys.
 *
 * A tick is a claim, so the two marks have to mean different things: `+` for
 * what this plan includes, a filled `×` for what it does not. The only row that
 * is ever crossed out is the product tab a plan does not unlock — which is real,
 * comes from the plan's own record, and is exactly the thing somebody asks for
 * a refund over when a card failed to say it.
 */
.plan .feat { list-style: none; margin: 22px 0 0; padding: 0; display: grid; gap: 13px; }
.plan .feat li { display: flex; align-items: flex-start; gap: 12px; font-size: 14px; line-height: 1.5; }
.plan .feat li::before {
  content: "+"; flex: none;
  width: 20px; height: 20px; margin-top: 1px;
  display: flex; align-items: center; justify-content: center;
  color: var(--gold); font-size: 17px; line-height: 1;
}
.plan .feat li.no { color: var(--faint); }
.plan .feat li.no::before {
  content: "\00d7";
  background: var(--gold); color: var(--accent-ink);
  border-radius: 5px; font-size: 13px; font-weight: 700;
  width: 18px; height: 18px; margin-top: 2px;
}

.plan .buy { margin-top: auto; padding-top: 26px; }
.plan .buy a { display: block; text-align: center; border-radius: 999px; padding: 13px; border: 1px solid var(--border); font-weight: 600; font-size: 14px; }
.plan.best .buy a { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.plan .buy a:hover { border-color: var(--faint); }
.plan.best .buy a:hover { border-color: var(--accent); filter: brightness(1.07); }
.plans-note { color: var(--faint); font-size: 13px; margin-top: 22px; }
.plans-empty { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 30px; color: var(--dim); font-size: 14px; }
.plans-empty a { color: var(--accent); }


/* --------------------------------------------------------------- big call */

/* A card the width of the page with the light behind its top edge, the one
   place on the page where the type goes really large. */
.callout {
  position: relative; overflow: hidden; text-align: center;
  background: var(--surface); border: 1px solid var(--border); border-radius: 34px;
  padding: 72px 30px;
}
.callout::before {
  content: ""; position: absolute; inset-inline: 18%; top: -90px; height: 240px;
  background: radial-gradient(50% 60% at 50% 70%, rgba(245, 232, 150, .34), rgba(217, 176, 33, .18) 45%, transparent 74%);
  filter: blur(26px); pointer-events: none;
}
.callout > * { position: relative; z-index: 1; }
.callout h2 { font-size: clamp(32px, 6.4vw, 60px); max-width: 15ch; margin-inline: auto; }
.callout .sub { margin-inline: auto; margin-bottom: 0; }
.guarantee {
  display: inline-flex; align-items: center; gap: 10px; margin-top: 34px;
  color: var(--dim); font-size: 14px;
}
.guarantee .chip { width: 34px; height: 34px; }
.guarantee .chip svg { width: 16px; height: 16px; }

/* ----------------------------------------------------------- testimonials */

.quote {
  position: relative; padding: 30px; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
}
.quote::before {
  content: "\201D"; display: block;
  font-size: 86px; line-height: .7; color: var(--faint); opacity: .45;
  margin-bottom: 18px; font-family: Georgia, "Times New Roman", serif;
}
.quote p { margin: 0 0 26px; color: var(--dim); font-size: 15px; line-height: 1.75; }
.quote cite { margin-top: auto; color: var(--gold); font-size: 14px; font-style: normal; }

/* ---------------------------------------------------------------- media */

/* A 16:9 well for a screenshot or a clip. It carries its own gradient, so the
   section is not broken by a missing file — this page ships with no photography
   and should not look like it is waiting for some. */
.media {
  position: relative; border-radius: var(--radius); overflow: hidden;
  aspect-ratio: 16 / 10; max-width: 100%;
  background:
    radial-gradient(70% 90% at 70% 8%, rgba(217, 176, 33, .22), transparent 62%),
    linear-gradient(160deg, var(--surface-high), #0d0d0d 70%);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
}
.media img { width: 100%; height: 100%; object-fit: cover; }
.media .play {
  position: absolute; width: 66px; height: 66px; border-radius: 50%;
  background: var(--accent); color: var(--accent-ink);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 12px rgba(216, 248, 58, .12);
}

/* ------------------------------------------------------------------ faq */

#faq details { background: var(--surface); border: 1px solid var(--border); border-radius: 20px; padding: 20px 24px; margin-bottom: 12px; }
#faq details[open] { border-color: rgba(217, 176, 33, .32); }
#faq summary { cursor: pointer; font-weight: 500; font-size: 16px; list-style: none; }
#faq summary::-webkit-details-marker { display: none; }
#faq summary::after { content: "+"; float: inline-end; color: var(--accent); font-weight: 400; font-size: 22px; line-height: 1.1; }
#faq details[open] summary::after { content: "–"; }
#faq details p { color: var(--dim); font-size: 14px; margin: 14px 0 0; }

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

footer { border-top: 1px solid var(--border); padding: 68px 0 60px; color: var(--faint); font-size: 13px; }
.foot-top { display: grid; gap: 40px; grid-template-columns: 1fr; margin-bottom: 48px; }
@media (min-width: 861px) { .foot-top { grid-template-columns: minmax(240px, 1.5fr) repeat(3, minmax(120px, 1fr)); } }
.foot-brand .brand { margin-bottom: 18px; }
.foot-brand p { color: var(--dim); max-width: 320px; margin: 0 0 26px; line-height: 1.75; }
.signup h4 { margin: 0 0 12px; font-size: 17px; font-weight: 400; color: var(--text); letter-spacing: 0; text-transform: none; }
.signup form { display: flex; flex-direction: column; gap: 12px; max-width: 320px; }
.signup input {
  width: 100%; padding: 14px 20px; border-radius: 999px;
  background: rgba(217, 176, 33, .06); border: 1px solid rgba(217, 176, 33, .5);
  color: var(--text); font: inherit; font-size: 14px;
}
.signup input::placeholder { color: var(--gold); opacity: .8; }
.signup input:focus { outline: none; border-color: var(--gold); }
.signup .btn { align-self: flex-start; }
.signup .said { color: var(--accent); font-size: 13px; min-height: 20px; }
.foot-col h4 { margin: 0 0 16px; font-size: 12px; font-weight: 600; color: var(--accent); letter-spacing: .2em; text-transform: uppercase; direction: ltr; }
/* `direction: ltr` above is there to give the Latin heading its tracking. On
   the RTL page it also drags the heading to the left edge while its own links
   stay right-aligned, so the direction has to come back with the rest. */
[dir="rtl"] .foot-col h4 {
  direction: rtl; letter-spacing: normal; text-transform: none; font-size: 13px;
}
.foot-col a { display: block; color: var(--dim); padding: 6px 0; }
.foot-col a:hover { color: var(--text); }
.foot { display: flex; gap: 20px; flex-wrap: wrap; align-items: center; padding-top: 28px; border-top: 1px solid var(--border); }
.foot a { color: var(--dim); }
.foot a:hover { color: var(--text); }
.foot .spacer { margin-inline-start: auto; }

/* --------------------------------------------------------------- badges */

.store { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 34px; }
.badge {
  display: inline-flex; align-items: center; gap: 11px;
  min-height: 56px; padding: 9px 18px; border-radius: 13px; border: 1px solid transparent;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.badge .b-ico { flex: none; display: flex; }
.badge .b-txt { text-align: start; }
.badge .b-txt small { display: block; font-size: 11px; font-weight: 600; line-height: 1.45; opacity: .68; }
.badge .b-txt strong { display: block; font-size: 18px; font-weight: 700; line-height: 1.2; letter-spacing: -.3px; }
.badge-store {
  width: 150px; height: 52px; min-height: 0; padding: 0 12px; gap: 9px;
  justify-content: flex-start; border-radius: 12px;
  /* Store badges keep their own direction on the RTL page: mirrored, the icon
     lands on the wrong side of a name that is Latin text either way. */
  direction: ltr;
  background: #ffffff; color: #0a0a0a; border-color: #0a0a0a;
}
.badge-store .b-ico svg { width: 24px; height: 24px; }
.badge-store .b-txt small { font-size: 9px; line-height: 1.35; opacity: .8; }
.badge-store .b-txt strong { font-size: 15px; letter-spacing: -.2px; }
.badge-store .b-txt small, .badge-store .b-txt strong { white-space: nowrap; }
.badge-store:hover { transform: translateY(-2px); box-shadow: 0 12px 26px rgba(255, 255, 255, .13); }
.badge[aria-disabled="true"] { cursor: not-allowed; }
.badge[aria-disabled="true"]:hover { transform: none; }
@media (max-width: 359px) {
  .store { gap: 8px; }
  .badge-store { width: 132px; padding: 0 8px; gap: 6px; }
  .badge-store .b-ico svg { width: 20px; height: 20px; }
  .badge-store .b-txt small { font-size: 8px; }
  .badge-store .b-txt strong { font-size: 13px; }
}

/* --------------------------------------------------------------- motion */

@media (max-width: 860px) {
  section { padding: 60px 0; }
  .hero { padding: 32px 0 44px; }
  .arc { height: 130px; margin-bottom: -40px; }
  .arc::before { height: 130px; }
  .arc::after { height: 90px; }
  .callout { padding: 52px 22px; border-radius: 28px; }
}

/* ------------------------------------------------------------ the lamp
 *
 * In the reference the cards are not lit equally: a card low in the viewport is
 * nearly dark and brightens as it rises, continuously, so the whole page feels
 * like it is moving under a light rather than playing an animation.
 *
 * Measured off the recording, tracking one card's brightest pixel while the
 * page scrolled: at 63% down the viewport its peak read #667327, at 51% #9a8e14,
 * at 16% #c2b517. A smooth ramp, not a trigger — which is why a one-shot fade
 * cannot reproduce it and why this uses a scroll timeline.
 *
 * `view()` ties the animation to the element's own travel through the viewport,
 * runs off the main thread, and needs no scroll listener. Where it is not
 * supported the glow simply sits at full strength, which is the state every
 * frame of this animation is heading towards — so nothing is lost, and nothing
 * is hidden waiting for a feature to exist.
 */
/* The value the light is turned up by. Registered, because an unregistered
   custom property is a string and CSS cannot interpolate a string. */
@property --lit {
  syntax: "<number>";
  inherits: true;
  /* Full, so anything that never runs the animation shows a fully lit card. */
  initial-value: 1;
}
@keyframes lamp {
  from { --lit: .3; }
  to   { --lit: 1; }
}

/* The sections themselves, likewise: a rise that tracks the scroll instead of
   firing once. Short travel — far enough to feel like weight, not so far that
   the page appears to assemble itself. */
@keyframes rise {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* The lamp goes on the card, not on its ::before. The card sets
       `overflow: hidden` to clip the glow, which makes it a scroll container —
       and `view()` resolves against the nearest one, so an animation on the
       pseudo-element would be measuring its travel through the card it lives
       in, which is none. The card's nearest scroller is the page, so the
       timeline lives here and reaches the glow through an inherited property.

       A card carries this instead of the rise below, and that is the honest
       reading of the reference: its cards do not visibly travel. The light
       coming up on them is the motion. */
    /* Where the lamp runs, the observer's one-shot fade on a card would be a
       second motion on the same object, on its own clock. Its transition is
       dropped so the scroll-linked pair below is the only thing moving. */
    .js .card.reveal { transition: none; }

    /* Two scroll-linked animations on one element: the light coming up, and the
       card itself arriving. The rise runs a touch longer than the lamp so the
       card settles into place a moment after it is fully lit. */
    .card, .plan {
      animation: lamp linear both, rise cubic-bezier(.22, .7, .3, 1) both;
      animation-timeline: view(), view();
      /* Dim as it appears, full by the time it is a third of the way up. */
      animation-range: entry 0% cover 26%, entry 0% cover 32%;
    }

    /* A row of cards should not light as one slab. Each column comes up a
       little later than the one before it — which on a phone, where they are
       stacked, costs nothing, because they are already apart. */
    .grid > .card:nth-child(2), .plans > .plan:nth-child(2) { animation-range: entry 5% cover 31%, entry 5% cover 37%; }
    .grid > .card:nth-child(3), .plans > .plan:nth-child(3) { animation-range: entry 10% cover 36%, entry 10% cover 42%; }
    .grid > .card:nth-child(4) { animation-range: entry 15% cover 41%, entry 15% cover 47%; }

    /* Everything that is not a card keeps a rise, now tracking the scroll
       rather than firing once — so a reader who scrolls back up sees it again
       instead of finding the page already assembled. `:not(.card)` matters:
       cards match both rules, and the more specific one would take the
       animation away from them. */
    .js .reveal:not(.card) {
      opacity: 1; transform: none;
      animation: rise cubic-bezier(.22, .7, .3, 1) both;
      animation-timeline: view();
      animation-range: entry 10% cover 26%;
      transition: none;
    }
  }
}

/* Guarded by the `js` class the page sets on <html> before anything renders:
   with scripting off nothing is ever hidden, so the page cannot arrive blank. */
.js .reveal { opacity: 0; transform: translateY(18px); }
.js .reveal.in {
  opacity: 1; transform: none;
  transition: opacity .6s cubic-bezier(.2, .7, .3, 1), transform .6s cubic-bezier(.2, .7, .3, 1);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; }
  .hero::after { animation: none; }
  .bar-fill { transition: none; }
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}
