/* ─────────────────────────────────────────────────────────────────────────
   پلکان — temporary landing page.

   Hand-written CSS on purpose: this is one static page with no build step, so
   pulling in Tailwind would buy nothing. What it DOES share with the dashboard
   is the design system itself — the token names and values below are copied
   verbatim from `dashboard/src/index.css`, the radius scale from
   `tailwind.config.js`, and the type is the same self-hosted IranYekanX.
   Change a token there, change it here.

   Two deliberate notes on that copy:
   - `--muted-foreground` is identical to `--foreground` in the light theme
     (that is what the dashboard ships). Body copy therefore softens with an
     alpha on the token rather than a second colour, so it still follows the
     theme in dark mode where the two DO differ.
   - `--brand` (#0048EC) is the logo's own blue and must NOT flip with the
     theme — same rule as the dashboard's `brand` tailwind colour. Only the
     logo mark uses it.
   ───────────────────────────────────────────────────────────────────────── */

:root {
  color-scheme: light;
  --background: 0 0% 100%;
  --foreground: 240 10% 20%;
  --card: 0 0% 100%;
  --primary: 225 84% 49%;
  --primary-foreground: 0 0% 100%;
  --secondary: 220 15% 95%;
  --muted: 220 15% 95%;
  --muted-foreground: 240 10% 20%;
  --accent: 220 15% 92%;
  /* Semantic status colour, same value and same rule as the dashboard: chosen
     to clear AA on its own `/12` tint, which is how the stock badge uses it.
     Never state-colour with a raw palette hex. */
  --success: 142 72% 25%;
  --border: 220 13% 90%;
  --ring: 225 84% 49%;
  --radius: 0.5rem;
  --brand: #0048ec;

  --radius-lg: var(--radius);
  --radius-md: calc(var(--radius) - 2px);
  --radius-sm: calc(var(--radius) - 4px);
  --radius-xl: calc(var(--radius) * 2);
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --background: 225 17% 7%;
    --foreground: 222 16% 92%;
    --card: 226 17% 11%;
    --primary: 225 84% 60%;
    --primary-foreground: 0 0% 100%;
    --secondary: 228 16% 16%;
    --muted: 228 16% 16%;
    --muted-foreground: 222 11% 65%;
    --accent: 228 16% 19%;
    --success: 142 72% 48%;
    --border: 225 16% 20%;
    --ring: 243 75% 62%;
  }
}

/* ── Reset ───────────────────────────────────────────────────────────────── */

*,
*::before,
*::after {
  box-sizing: border-box;
  border: 0 solid hsl(var(--border));
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  /* The full-bleed marquee is sized in `vw`, which overshoots by the scrollbar
     width. `clip` swallows that without creating a scroll container, so the
     sticky header keeps working (`hidden` would break it). */
  overflow-x: clip;
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  font-family: "iran-yekan-xvf", "iran-yekan-x", "Vazirmatn", ui-sans-serif,
    system-ui, sans-serif;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.85;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  /* The dashboard caps its weight scale at 500 (`fontWeight` override in
     tailwind.config.js) — headings get their hierarchy from size, not weight. */
  margin: 0;
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: -0.01em;
}

p {
  margin: 0;
}

/* `ol` belongs here as much as `ul`: the steps list is ordered, and without
   this it keeps the UA's 40px `padding-inline-start` — which under RTL is a
   40px hole down the right edge of every step card. */
ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}

svg {
  display: block;
}

:focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.icon {
  width: 1rem;
  height: 1rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Latin identifiers (@handles, urls) inside RTL text. Mirrors the dashboard's
   `.mono` utility. */
.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  direction: ltr;
  unicode-bidi: plaintext;
}

.container {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: 1.5rem;
}

/* ── Brand mark ──────────────────────────────────────────────────────────── */

/* Colour comes from context, never a hard-coded hex at the call site: the
   logotype paints with `currentColor` (so it follows the theme) while the icon
   holds the fixed brand blue. Same contract as `lib/brand.tsx`. */
.brand-logo {
  height: 1.75rem;
  width: auto;
  color: hsl(var(--foreground));
}

.brand-icon {
  fill: var(--brand);
}

@media (prefers-color-scheme: dark) {
  /* Brand blue reaches only ~2.7:1 on the dark surface — the kit's "Icon W"
     sheet is the dark-mode answer, exactly as the dashboard sidebar does it. */
  .brand-icon {
    fill: #fff;
  }
}

/* ── Buttons ─────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  height: 2.5rem;
  padding-inline: 1rem;
  border-radius: var(--radius-md);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease,
    border-color 0.15s ease, box-shadow 0.2s ease, transform 0.15s ease;
}

.btn-sm {
  height: 2.25rem;
  padding-inline: 0.875rem;
}

.btn-lg {
  height: 3rem;
  padding-inline: 2rem;
  font-size: 1rem;
}

.btn-primary {
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  box-shadow: 0 6px 20px -8px hsl(var(--primary) / 0.7);
}

.btn-primary:hover {
  background: hsl(var(--primary) / 0.9);
}

.btn-outline {
  border: 1px solid hsl(var(--border));
  background: transparent;
  color: hsl(var(--foreground));
}

.btn-outline:hover {
  background: hsl(var(--accent));
}

.btn-lg:hover {
  transform: translateY(-1px);
}

/* ── Header ──────────────────────────────────────────────────────────────── */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid hsl(var(--border) / 0.7);
  background: hsl(var(--background) / 0.75);
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  height: 4rem;
}

.brand {
  display: flex;
  align-items: center;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 1.75rem;
  font-size: 0.875rem;
  color: hsl(var(--muted-foreground) / 0.75);
}

/* Logo and nav sit together at the inline start (the right, under RTL); the
   auto margin banishes the CTA to the far end. */
.header-inner .btn {
  margin-inline-start: auto;
}

.site-nav a {
  transition: color 0.15s ease;
}

.site-nav a:hover {
  color: hsl(var(--foreground));
}

@media (max-width: 1000px) {
  .site-nav {
    display: none;
  }
}

/* ── Hero ────────────────────────────────────────────────────────────────── */

.hero {
  position: relative;
  overflow: hidden;
  padding-block: 5.5rem 4rem;
}

.hero-bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.hero-grid {
  position: absolute;
  inset: 0;
  background-image: linear-gradient(hsl(var(--foreground) / 0.05) 1px, transparent 1px),
    linear-gradient(90deg, hsl(var(--foreground) / 0.05) 1px, transparent 1px);
  background-size: 56px 56px;
  /* Fade the grid out well before the section edges so it reads as texture,
     not as a table. */
  -webkit-mask-image: radial-gradient(ellipse 70% 55% at 50% 32%, #000 0%, transparent 100%);
  mask-image: radial-gradient(ellipse 70% 55% at 50% 32%, #000 0%, transparent 100%);
}

.hero-glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
}

.hero-glow-a {
  top: -14rem;
  left: 50%;
  width: 46rem;
  height: 34rem;
  transform: translateX(-50%);
  background: hsl(var(--primary) / 0.22);
}

.hero-glow-b {
  top: 6rem;
  right: 8%;
  width: 26rem;
  height: 24rem;
  background: hsl(var(--primary) / 0.1);
}

@media (prefers-color-scheme: dark) {
  .hero-glow-a {
    background: hsl(var(--primary) / 0.28);
  }
}

.hero-inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.875rem;
  border: 1px solid hsl(var(--primary) / 0.25);
  border-radius: 999px;
  background: hsl(var(--primary) / 0.08);
  color: hsl(var(--primary));
  font-size: 0.8125rem;
  line-height: 1.6;
}

.hero-mark {
  margin-top: 2.5rem;
  color: var(--brand);
}

.hero-mark svg {
  width: 4rem;
  height: 4rem;
  fill: currentColor;
  filter: drop-shadow(0 8px 28px hsl(var(--primary) / 0.45));
}

@media (prefers-color-scheme: dark) {
  .hero-mark {
    color: #fff;
  }
}

.hero-title {
  max-width: 22ch;
  margin-top: 1.75rem;
  font-size: clamp(2rem, 5.2vw, 3.5rem);
  line-height: 1.35;
}

.hero-title-accent {
  color: hsl(var(--primary));
}

.hero-sub {
  max-width: 60ch;
  margin-top: 1.25rem;
  color: hsl(var(--muted-foreground) / 0.78);
  font-size: 1.0625rem;
}

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 2.25rem;
}

.hero-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.5rem;
  margin-top: 1.75rem;
  color: hsl(var(--muted-foreground) / 0.7);
  font-size: 0.875rem;
}

.hero-meta li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.hero-meta li::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: hsl(var(--primary) / 0.65);
}

/* ── Chat preview (decorative product visual) ────────────────────────────── */

.chat-preview {
  width: 100%;
  max-width: 22rem;
  margin-top: 4rem;
  overflow: hidden;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-xl);
  background: hsl(var(--card));
  text-align: right;
  box-shadow: 0 32px 64px -24px hsl(225 84% 20% / 0.35),
    0 2px 8px hsl(225 40% 20% / 0.06);
}

@media (prefers-color-scheme: dark) {
  .chat-preview {
    box-shadow: 0 32px 64px -24px rgb(0 0 0 / 0.7);
  }
}

.chat-head {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.875rem 1rem;
  background: linear-gradient(135deg, var(--brand), #2a6bf5);
  color: #fff;
}

.chat-avatar {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-sm);
  background: rgb(255 255 255 / 0.18);
}

.chat-avatar svg {
  width: 1rem;
  height: 1rem;
  fill: #fff;
}

.chat-head-text {
  display: flex;
  flex-direction: column;
  line-height: 1.4;
}

.chat-head-text b {
  font-size: 0.875rem;
  font-weight: 500;
}

.chat-head-text i {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.6875rem;
  font-style: normal;
  opacity: 0.85;
}

/* Fixed green, not the `--success` token: this dot sits on the brand-blue
   gradient in both themes, so it must not follow the theme. Same call the
   widget's own header makes. */
.chat-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #22c55e;
}

.chat-body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem;
  background: hsl(var(--muted) / 0.5);
}

.bubble {
  max-width: 85%;
  padding: 0.5rem 0.75rem;
  font-size: 0.8125rem;
  line-height: 1.75;
}

.bubble-bot {
  align-self: flex-start;
  border-radius: var(--radius-lg) var(--radius-lg) var(--radius-lg) var(--radius-sm);
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
}

.bubble-user {
  align-self: flex-end;
  border-radius: var(--radius-lg) var(--radius-lg) var(--radius-sm) var(--radius-lg);
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
}

.bubble-typing {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 2rem;
}

.bubble-typing span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: hsl(var(--muted-foreground) / 0.5);
  animation: dot 1.3s ease-in-out infinite;
}

.bubble-typing span:nth-child(2) {
  animation-delay: 0.18s;
}

.bubble-typing span:nth-child(3) {
  animation-delay: 0.36s;
}

@keyframes dot {
  0%,
  60%,
  100% {
    transform: translateY(0);
    opacity: 0.55;
  }
  30% {
    transform: translateY(-5px);
    opacity: 1;
  }
}

.chat-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  border-top: 1px solid hsl(var(--border));
  background: hsl(var(--card));
  color: hsl(var(--muted-foreground) / 0.55);
  font-size: 0.8125rem;
}

.chat-foot .icon {
  color: hsl(var(--primary));
}

/* ── Sections ────────────────────────────────────────────────────────────── */

.section {
  padding-block: 5rem;
  scroll-margin-top: 4rem;
}

.section-muted {
  border-block: 1px solid hsl(var(--border) / 0.7);
  background: hsl(var(--muted) / 0.4);
}

/* Headings align to the inline start (the right, under RTL). Only the hero and
   the footer are centred; a centred column everywhere else made the whole page
   read as one long ribbon. */
.section-head {
  max-width: 62ch;
}

.eyebrow {
  display: block;
  margin-bottom: 0.75rem;
  color: hsl(var(--primary));
  font-size: 0.8125rem;
}

.section-head h2,
.split-text h2 {
  font-size: clamp(1.5rem, 3vw, 2rem);
}

.section-head p,
.split-text p {
  margin-top: 1rem;
  color: hsl(var(--muted-foreground) / 0.78);
}

.section-head p b,
.split-text p b {
  color: hsl(var(--foreground));
  font-weight: 500;
}

/* ── Two-column section layout ───────────────────────────────────────────── */

.split {
  display: grid;
  gap: 2.5rem;
  align-items: center;
}

@media (min-width: 900px) {
  .split {
    grid-template-columns: 1.05fr 0.95fr;
    gap: 4rem;
  }

  /* Puts the visual column at the inline start instead, so consecutive split
     sections alternate rather than stacking into one rail. */
  .split-reverse > .split-text {
    order: 2;
  }
}

.split-text .btn {
  margin-top: 1.75rem;
}

.split-visual {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

.split-visual-note {
  max-width: 24rem;
  color: hsl(var(--muted-foreground) / 0.6);
  font-size: 0.8125rem;
  text-align: center;
}

/* ── Steps (چطور کار می‌کند) ──────────────────────────────────────────────── */

.steps,
.benefits {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.steps li,
.benefits li {
  display: flex;
  gap: 1rem;
  padding: 1.25rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-lg);
  background: hsl(var(--card));
}

.step-num {
  display: grid;
  place-items: center;
  flex: none;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary));
  font-size: 0.875rem;
}

.benefit-icon {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-md);
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary));
}

.benefit-icon .icon {
  width: 1.125rem;
  height: 1.125rem;
}

.step-body,
.benefits li > span:last-child {
  display: flex;
  flex-direction: column;
  color: hsl(var(--muted-foreground) / 0.78);
  font-size: 0.875rem;
  line-height: 1.8;
}

.step-body b,
.benefits li b {
  margin-bottom: 0.125rem;
  color: hsl(var(--foreground));
  font-size: 0.9375rem;
  font-weight: 500;
}

/* ── Tick list ───────────────────────────────────────────────────────────── */

.ticks {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  margin-top: 1.75rem;
  color: hsl(var(--muted-foreground) / 0.85);
  font-size: 0.9375rem;
}

.ticks li {
  position: relative;
  padding-inline-start: 1.75rem;
}

/* Tint disc + a CSS-drawn check. Drawn rather than an inline SVG so the mark
   inherits `--primary` in both themes. */
.ticks li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 0.55rem;
  width: 1.05rem;
  height: 1.05rem;
  border-radius: 50%;
  background: hsl(var(--primary) / 0.14);
}

.ticks li::after {
  content: "";
  position: absolute;
  inset-inline-start: 0.4rem;
  top: 0.8rem;
  width: 0.24rem;
  height: 0.46rem;
  border: solid hsl(var(--primary));
  border-width: 0 1.6px 1.6px 0;
  transform: rotate(45deg);
}

/* ── Product card (decorative) ───────────────────────────────────────────── */

.product-card {
  width: 100%;
  max-width: 20rem;
  overflow: hidden;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-lg);
  background: hsl(var(--card));
  box-shadow: 0 24px 48px -24px hsl(225 84% 20% / 0.35);
}

@media (prefers-color-scheme: dark) {
  .product-card {
    box-shadow: 0 24px 48px -24px rgb(0 0 0 / 0.7);
  }
}

.product-media {
  display: grid;
  place-items: center;
  height: 9rem;
  background: linear-gradient(
    135deg,
    hsl(var(--primary) / 0.16),
    hsl(var(--primary) / 0.04)
  );
  color: hsl(var(--primary) / 0.7);
}

.product-media .icon {
  width: 2.5rem;
  height: 2.5rem;
}

.product-body {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1rem;
}

.product-cat {
  color: hsl(var(--muted-foreground) / 0.6);
  font-size: 0.75rem;
}

.product-name {
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.7;
}

.product-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.product-price {
  color: hsl(var(--primary));
  font-size: 0.9375rem;
}

.badge {
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  line-height: 1.7;
}

.badge-ok {
  background: hsl(var(--success) / 0.12);
  color: hsl(var(--success));
}

/* ── Feature cards ───────────────────────────────────────────────────────── */

/* ── Feature marquee ─────────────────────────────────────────────────────── */

/* Three rows drifting in alternating directions. This replaces a plain grid,
   which collapsed to one card per row on a phone and left the section reading
   as a single narrow column. Cards keep a fixed width here, so the row is a
   continuous band at every viewport instead of a stack. */
.marquee-rows {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-top: 3rem;
  /* Full-bleed out of the container so the strip runs edge to edge. */
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  /* Fade both ends instead of cutting cards off at a hard edge. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6rem, #000 calc(100% - 6rem), transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6rem, #000 calc(100% - 6rem), transparent);
}

/* Clipped, not scrollable: the row is a display band, and the visitor's own
   scrolling used to fight the loop for the same position. */
.marquee {
  overflow: hidden;
}

/* Only reachable by hand in the one case the loop never starts (no JS, or
   reduced motion), where a clipped row would hide most of the cards. */
.marquee:not(:has(> [data-marquee-ready])) {
  overflow-x: auto;
  scrollbar-width: none;
}

.marquee:not(:has(> [data-marquee-ready]))::-webkit-scrollbar {
  display: none;
}

.marquee-track {
  display: flex;
  gap: 1rem;
  width: max-content;
}

/* `--shift` and the duration are measured and set by the script: the shift is
   one repeating unit plus one gap, in pixels, so the loop lands exactly on the
   duplicate. It was a `50%`-based figure before, which is only equal to that
   distance when the track holds exactly two copies; on a wide desktop it needs
   more, and the percentage then drifted off the seam and opened a gap. */
.marquee-track[data-marquee-ready] {
  animation: marquee var(--marquee-duration, 60s) linear infinite;
}

.marquee[data-marquee="reverse"] .marquee-track[data-marquee-ready] {
  animation-direction: reverse;
}

/* The offset is POSITIVE, which looks wrong until you account for direction.
   The track is a block box under `dir=rtl`, so its right edge pins to the
   container's right edge and the overflow hangs off to the LEFT; the cards
   waiting to be shown sit at negative x. Moving them into view therefore means
   translating RIGHT. A negative offset (the LTR reflex) shoves the whole track
   further off-screen and the row renders blank. */
@keyframes marquee {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(var(--shift));
  }
}

.marquee-rows:hover .marquee-track[data-marquee-ready] {
  animation-play-state: paused;
}

.marquee .card {
  width: 19rem;
  flex: none;
}

@media (max-width: 640px) {
  .marquee .card {
    width: 15.5rem;
    padding: 1.25rem;
  }

  .marquee-rows {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 2rem, #000 calc(100% - 2rem), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 2rem, #000 calc(100% - 2rem), transparent);
  }
}

/* Desktop drops the marquee entirely: three rows of nine cards meant the same
   card appeared several times across a wide viewport, which read as padding
   rather than as motion. `display: contents` dissolves the row and track boxes
   so the nine original cards become grid items directly, restoring the plain
   3x3 grid. The script skips cloning at this width, so there are no duplicates
   to hide.

   KEEP THIS BLOCK LAST. `width: auto` below has the same specificity as the
   `.marquee .card` rules above it, so only source order stops the marquee's
   fixed 19rem from winning and leaving every card short of its grid cell. */
@media (min-width: 900px) {
  .marquee-rows {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    width: auto;
    margin-inline: 0;
    -webkit-mask-image: none;
    mask-image: none;
  }

  .marquee,
  .marquee-track {
    display: contents;
  }

  .marquee .card {
    width: auto;
  }
}

.card {
  padding: 1.5rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-lg);
  background: hsl(var(--card));
  box-shadow: 0 1px 2px hsl(225 20% 20% / 0.04);
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

.card:hover {
  border-color: hsl(var(--primary) / 0.4);
  box-shadow: 0 12px 28px -18px hsl(var(--primary) / 0.6);
  transform: translateY(-2px);
}

.card-icon {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-bottom: 1rem;
  border-radius: var(--radius-md);
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary));
}

.card-icon .icon {
  width: 1.25rem;
  height: 1.25rem;
}

.card h3 {
  font-size: 1rem;
}

.card p {
  margin-top: 0.5rem;
  color: hsl(var(--muted-foreground) / 0.78);
  font-size: 0.875rem;
}

/* ── Demo request ────────────────────────────────────────────────────────── */

.demo-card {
  position: relative;
  overflow: hidden;
  padding: 3rem 2rem;
  border: 1px solid hsl(var(--primary) / 0.2);
  border-radius: var(--radius-xl);
  background: radial-gradient(
      ellipse 80% 130% at 85% 0%,
      hsl(var(--primary) / 0.12),
      transparent 70%
    ),
    hsl(var(--card));
}

.channels {
  display: grid;
  gap: 1rem;
}

.channel {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  padding: 1rem 1.25rem;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-lg);
  background: hsl(var(--background));
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

.channel:hover {
  border-color: hsl(var(--primary) / 0.5);
  box-shadow: 0 12px 28px -18px hsl(var(--primary) / 0.7);
  transform: translateY(-2px);
}

.channel-icon {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  flex: none;
  border-radius: var(--radius-md);
  background: hsl(var(--primary) / 0.1);
  color: hsl(var(--primary));
}

.channel-icon .icon {
  width: 1.125rem;
  height: 1.125rem;
}

.channel-text {
  display: flex;
  flex-direction: column;
  line-height: 1.6;
}

.channel-text b {
  font-size: 0.9375rem;
  font-weight: 500;
}

.channel-text .mono {
  color: hsl(var(--muted-foreground) / 0.7);
  font-size: 0.8125rem;
}

.channel-arrow {
  margin-inline-start: auto;
  color: hsl(var(--muted-foreground) / 0.45);
  transition: transform 0.2s ease, color 0.2s ease;
}

.channel:hover .channel-arrow {
  color: hsl(var(--primary));
  transform: translateX(-3px);
}

/* ── Contact ─────────────────────────────────────────────────────────────── */

.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: 1rem;
  margin-top: 2.5rem;
}

.contact-card p {
  font-size: 0.9375rem;
  color: hsl(var(--muted-foreground) / 0.78);
}

.contact-phone {
  color: hsl(var(--foreground));
  font-size: 1.125rem;
  /* A phone number is one unbroken LTR run even inside RTL prose. */
  direction: ltr;
  unicode-bidi: plaintext;
  display: inline-block;
  letter-spacing: 0.02em;
  transition: color 0.15s ease;
}

.contact-phone:hover {
  color: hsl(var(--primary));
}

.developed-by {
  max-width: 62ch;
  margin-top: 2rem;
  padding-inline-start: 1rem;
  border-inline-start: 2px solid hsl(var(--primary) / 0.35);
  color: hsl(var(--muted-foreground) / 0.7);
  font-size: 0.875rem;
}

.developed-by b {
  color: hsl(var(--foreground));
  font-weight: 500;
}

/* ── Footer ──────────────────────────────────────────────────────────────── */

.site-footer {
  padding-block: 2.5rem;
  border-top: 1px solid hsl(var(--border));
}

.footer-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.625rem;
  text-align: center;
}

.footer-logo {
  height: 1.5rem;
  opacity: 0.9;
}

.footer-note {
  color: hsl(var(--muted-foreground) / 0.7);
  font-size: 0.875rem;
}

.footer-copy {
  color: hsl(var(--muted-foreground) / 0.55);
  font-size: 0.8125rem;
}

.footer-copy a {
  color: hsl(var(--muted-foreground) / 0.8);
  transition: color 0.15s ease;
}

.footer-copy a:hover {
  color: hsl(var(--primary));
}

/* ── Entrance animation ──────────────────────────────────────────────────── */

@keyframes reveal {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.reveal {
  animation: reveal 0.6s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.reveal-1 { animation-delay: 0.05s; }
.reveal-2 { animation-delay: 0.12s; }
.reveal-3 { animation-delay: 0.19s; }
.reveal-4 { animation-delay: 0.26s; }
.reveal-5 { animation-delay: 0.33s; }
.reveal-6 { animation-delay: 0.4s; }
.reveal-7 { animation-delay: 0.5s; }

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .reveal,
  .bubble-typing span,
  .marquee-track {
    animation: none;
  }

  .btn,
  .card,
  .channel,
  .channel-arrow {
    transition: none;
  }

  .btn-lg:hover,
  .card:hover,
  .channel:hover {
    transform: none;
  }
}
