/* =============================================================
   FALMIS DESIGN SYSTEM — TOKENS
   Dark mode only. Single source of truth.
   Steps locked: 01 colour · 02 type · 03 geometry · 04 surfaces
   ============================================================= */

:root{

  /* -----------------------------------------------------------
     TIER 1 — PRIMITIVES
     Literal values. Components must not read these directly.
     ----------------------------------------------------------- */

  --fm-violet-300:#C4B5FD;
  --fm-violet-400:#A78BFA;
  --fm-violet-500:#8B5CF6;
  --fm-violet-600:#7C3AED;
  --fm-violet-700:#6D28D9;

  --fm-fuchsia-400:#E879F9;
  --fm-fuchsia-500:#D946EF;
  --fm-fuchsia-600:#C026D3;
  --fm-fuchsia-700:#A21CAF;

  --fm-indigo-600:#4F46E5;
  --fm-lavender-200:#E9D5FF;

  --fm-slate-050:#F1F5F9;
  --fm-slate-300:#CBD5E1;
  --fm-slate-400:#94A3B8;
  --fm-slate-450:#78889C;
  --fm-slate-500:#64748B;

  --fm-ink-900:#08050F;
  --fm-ink-800:#0B0716;
  --fm-ink-700:#100B19;
  --fm-ink-600:#161020;

  --fm-mint-400:#2DD4A7;
  --fm-gold-400:#E8B84B;
  --fm-rose-400:#F0567A;
  --fm-azure-400:#60A5FA;


  /* -----------------------------------------------------------
     TIER 2 — SEMANTIC
     This is the layer components read.
     ----------------------------------------------------------- */

  /* surfaces */
  --fm-surface-0:var(--fm-ink-900);   /* page */
  --fm-surface-1:var(--fm-ink-800);   /* section */
  --fm-surface-2:var(--fm-ink-700);   /* card, input */
  --fm-surface-3:var(--fm-ink-600);   /* modal, dropdown */

  /* text */
  --fm-text-primary:var(--fm-slate-050);
  --fm-text-body:var(--fm-slate-300);
  --fm-text-muted:var(--fm-slate-400);
  --fm-text-accent:var(--fm-lavender-200);
  --fm-text-disabled:var(--fm-slate-450);   /* 5.14:1 — was slate-500 at 3.91:1 */
  --fm-text-on-brand:#FFFFFF;

  /* brand */
  --fm-brand:var(--fm-violet-600);
  --fm-brand-hover:var(--fm-violet-500);
  --fm-brand-active:var(--fm-violet-700);
  --fm-accent:var(--fm-fuchsia-600);
  --fm-accent-hover:var(--fm-fuchsia-500);

  /* state */
  --fm-success:var(--fm-mint-400);
  --fm-warning:var(--fm-gold-400);
  --fm-error:var(--fm-rose-400);
  --fm-info:var(--fm-azure-400);
  --fm-success-bg:rgba(45,212,167,.12);
  --fm-warning-bg:rgba(232,184,75,.12);
  --fm-error-bg:rgba(240,86,122,.12);
  --fm-info-bg:rgba(96,165,250,.12);

  /* borders */
  --fm-border-subtle:rgba(255,255,255,.08);
  --fm-border:rgba(255,255,255,.12);
  --fm-border-strong:rgba(255,255,255,.18);
  --fm-border-accent:rgba(196,181,253,.35);
  --fm-border-input:rgba(255,255,255,.34);  /* 3.02:1 — an input border is an affordance */
  --fm-border-error:rgba(240,86,122,.45);
  --fm-border-success:rgba(45,212,167,.40);

  /* overlays */
  --fm-overlay-scrim:rgba(8,5,15,.72);
  --fm-tint-violet:rgba(124,58,237,.13);
  --fm-tint-fuchsia:rgba(192,38,211,.08);
  --fm-highlight-top:rgba(255,255,255,.14);

  /* focus */
  --fm-focus-ring:var(--fm-violet-400);
  --fm-focus-shadow:0 0 0 3px rgba(167,139,250,.45);


  /* -----------------------------------------------------------
     GRADIENTS
     aurora = bright, for buttons and small accents.
     deep   = dark atmospheric field, for surfaces behind text.
     Never swap one for the other.
     ----------------------------------------------------------- */

  --fm-aurora-angle:110deg;

  /* Full ramp. For large surfaces, where the spread has room. */
  --fm-gradient-aurora:linear-gradient(var(--fm-aurora-angle),
    var(--fm-indigo-600), var(--fm-violet-600), var(--fm-fuchsia-600));

  /* Small surfaces — buttons, chips, toggles.
     The end stops sit outside 0-100%, so the extremes fall off the
     visible box. On a 44px pill the full ramp gets crushed into
     ~160px and the endpoints land on the rounded caps, reading as
     a blue sliver and a pink sliver instead of a gradient. */
  --fm-gradient-button:linear-gradient(var(--fm-aurora-angle),
    var(--fm-indigo-600) -22%,
    var(--fm-violet-600) 42%,
    var(--fm-fuchsia-600) 122%);

  --fm-gradient-deep:
    radial-gradient(1100px 720px at 74% 6%,  rgba(124,58,237,.30), transparent 66%),
    radial-gradient(920px 640px  at 99% 86%, rgba(192,38,211,.22), transparent 64%),
    radial-gradient(820px 620px  at 34% 108%,rgba(79,70,229,.20),  transparent 68%),
    linear-gradient(112deg, var(--fm-ink-900) 0%, var(--fm-ink-800) 52%, var(--fm-ink-700) 100%);

  --fm-gradient-deep-soft:
    radial-gradient(1100px 720px at 74% 6%,  rgba(124,58,237,.18), transparent 68%),
    radial-gradient(920px 640px  at 99% 86%, rgba(192,38,211,.12), transparent 66%),
    linear-gradient(112deg, var(--fm-ink-900) 0%, var(--fm-ink-800) 55%, var(--fm-ink-700) 100%);

  --fm-gradient-deep-rich:
    radial-gradient(1000px 700px at 66% 0%,  rgba(124,58,237,.42), transparent 62%),
    radial-gradient(880px 620px  at 102% 78%,rgba(192,38,211,.32), transparent 60%),
    radial-gradient(760px 600px  at 26% 112%,rgba(79,70,229,.28),  transparent 66%),
    linear-gradient(112deg, var(--fm-ink-900) 0%, var(--fm-ink-800) 48%, var(--fm-ink-600) 100%);


  /* -----------------------------------------------------------
     TYPOGRAPHY
     Vazirmatn only. Latin digits. Four weights.
     ----------------------------------------------------------- */

  --fm-font:'Vazirmatn',Tahoma,system-ui,sans-serif;

  --fm-text-2xs:11px;  --fm-lh-2xs:1.5;
  --fm-text-xs:12px;   --fm-lh-xs:1.6;
  --fm-text-sm:13px;   --fm-lh-sm:1.7;
  --fm-text-base:15px; --fm-lh-base:1.8;
  --fm-text-md:17px;   --fm-lh-md:1.7;
  --fm-text-lg:20px;   --fm-lh-lg:1.5;
  --fm-text-xl:24px;   --fm-lh-xl:1.4;
  --fm-text-2xl:30px;  --fm-lh-2xl:1.35;
  --fm-text-3xl:38px;  --fm-lh-3xl:1.25;
  --fm-text-4xl:48px;  --fm-lh-4xl:1.2;

  --fm-weight-regular:400;
  --fm-weight-medium:500;
  --fm-weight-bold:700;
  --fm-weight-display:800;

  --fm-tracking:0;   /* never positive — it breaks the Persian script */


  /* -----------------------------------------------------------
     SPACING — base 4px, name is the multiple of 4
     ----------------------------------------------------------- */

  --fm-space-1:4px;    --fm-space-2:8px;    --fm-space-3:12px;
  --fm-space-4:16px;   --fm-space-5:20px;   --fm-space-6:24px;
  --fm-space-8:32px;   --fm-space-10:40px;  --fm-space-12:48px;
  --fm-space-16:64px;  --fm-space-20:80px;  --fm-space-24:96px;


  /* -----------------------------------------------------------
     RADIUS
     ----------------------------------------------------------- */

  --fm-radius-sm:8px;      /* chips, badges */
  --fm-radius-md:12px;     /* inputs, square buttons */
  --fm-radius-lg:16px;     /* cards */
  --fm-radius-xl:24px;     /* modals, banners, large panels */
  --fm-radius-full:999px;  /* pills, avatars */


  /* -----------------------------------------------------------
     LAYOUT
     ----------------------------------------------------------- */

  --fm-container-sm:640px;   /* reading column, forms */
  --fm-container-md:960px;   /* app screens */
  --fm-container-lg:1200px;  /* marketing pages */
  --fm-gutter:16px;          /* every breakpoint */

  --fm-control-sm:36px;      /* dense desktop rows only */
  --fm-control-md:44px;      /* minimum touch target */
  --fm-control-lg:52px;

  --fm-z-base:0;
  --fm-z-sticky:100;
  --fm-z-drawer:200;
  --fm-z-modal:300;
  --fm-z-toast:400;
  --fm-z-tooltip:500;

  --fm-section-y:var(--fm-space-16);
  --fm-block-y:var(--fm-space-8);


  /* -----------------------------------------------------------
     GLASS
     ----------------------------------------------------------- */

  --fm-glass-blur-sm:8px;
  --fm-glass-blur-md:16px;
  --fm-glass-blur-lg:24px;

  --fm-glass-1-bg:rgba(255,255,255,.04);
  --fm-glass-1-border:var(--fm-border-subtle);

  --fm-glass-2-bg:rgba(255,255,255,.07);
  --fm-glass-2-border:var(--fm-border);

  --fm-glass-3-bg:linear-gradient(135deg,
    rgba(124,58,237,.18), rgba(192,38,211,.10), rgba(255,255,255,.05));
  --fm-glass-3-border:var(--fm-border-accent);


  /* -----------------------------------------------------------
     SHADOW AND GLOW
     Shadow means depth. Glow means importance.
     Never put both on one element.
     ----------------------------------------------------------- */

  --fm-shadow-sm:0 4px 16px rgba(0,0,0,.20);
  --fm-shadow-md:0 12px 34px rgba(0,0,0,.30);
  --fm-shadow-lg:0 24px 64px rgba(0,0,0,.44);

  --fm-glow-violet:0 16px 50px rgba(124,58,237,.24);
  --fm-glow-fuchsia:0 16px 50px rgba(192,38,211,.22);
  --fm-glow-aurora:0 18px 66px rgba(124,58,237,.22),
                   0 10px 42px rgba(192,38,211,.18);


  /* -----------------------------------------------------------
     MOTION

     COMPLETED BY IMPLEMENTATION — see DESIGN_SYSTEM.md Part 3.6.

     The shipped token file carried only fast/base/slow and a
     single --fm-ease, marked "draft, step 05 will finalise".
     But 14 of the 16 component sheets already reference
     --fm-ease-out, --fm-ease-in, --fm-ease-inout, --fm-ease-snap,
     --fm-ease-ambient, --fm-dur-instant, --fm-dur-reveal,
     --fm-dur-oracle and --fm-dur-ambient.

     An undefined custom property makes the whole declaration
     invalid at computed-value time, so every transition naming
     one of them was being dropped entirely. Buttons did not lift,
     cards did not raise, the navbar glass snapped in with no fade.

     Durations below are the values in Part 3.6 of the spec.
     fast/base/slow are left at the values this file already
     shipped (120/220/400) rather than the spec's 140/240/400 —
     the CSS is the stated source of truth, and the difference is
     imperceptible. Flagged for the designer.

     The easing curves are NOT specified anywhere in the system;
     only their names and jobs are. These are chosen to match the
     described intent and are the one place here that needs a
     designer's eye.
     ----------------------------------------------------------- */

  --fm-dur-instant:80ms;    /* colour, focus ring */
  --fm-dur-fast:120ms;      /* hover, press */
  --fm-dur-base:220ms;      /* dropdown, tab, every exit */
  --fm-dur-slow:400ms;      /* modal, drawer, toast entrance */
  --fm-dur-reveal:700ms;    /* ordinary entrances */
  --fm-dur-oracle:950ms;    /* card flip and reading reveal only */
  --fm-dur-ambient:14s;     /* field drift */

  --fm-ease:cubic-bezier(.4,0,.2,1);

  --fm-ease-out:cubic-bezier(.16,1,.3,1);       /* arriving */
  --fm-ease-in:cubic-bezier(.4,0,1,1);          /* leaving */
  --fm-ease-inout:cubic-bezier(.65,0,.35,1);    /* moving */
  --fm-ease-snap:cubic-bezier(.34,1.56,.64,1);  /* overshoots — press only */
  --fm-ease-ambient:cubic-bezier(.45,0,.55,1);  /* loops */
}


/* -------------------------------------------------------------
   MOBILE — only the four largest type sizes step down.
   Body text never shrinks.
   ------------------------------------------------------------- */

/* -------------------------------------------------------------
   RTL

   A gradient angle is physical — 110deg runs the same way no
   matter the text direction. Left unflipped, the brand gradient
   runs backwards against Persian reading order. Mirroring the
   angle keeps indigo at the start of the line and fuchsia at the
   end, in both languages.
   ------------------------------------------------------------- */

[dir="rtl"]{ --fm-aurora-angle:250deg; }


@media (max-width:640px){
  :root{
    --fm-text-4xl:32px;
    --fm-text-3xl:27px;
    --fm-text-2xl:23px;
    --fm-text-xl:20px;
  }
}

@media (min-width:961px){
  :root{
    --fm-section-y:var(--fm-space-24);
  }
}


/* -------------------------------------------------------------
   BASE
   ------------------------------------------------------------- */

/* Without this, width:100% plus padding overflows every container. */
*,*::before,*::after{ box-sizing:border-box; }

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

body{
  margin:0;
  background:var(--fm-surface-0);
  color:var(--fm-text-body);
  font-family:var(--fm-font);
  font-size:var(--fm-text-base);
  line-height:var(--fm-lh-base);
  letter-spacing:var(--fm-tracking);
  -webkit-font-smoothing:antialiased;
}

/* Persian has no italic form. The browser fakes it by slanting. */
i,em,cite,address,dfn{ font-style:normal; }

/* Every price, timer, and table cell holds a fixed digit width. */
.fm-num{ font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1; }

:focus-visible{
  outline:2px solid var(--fm-focus-ring);
  outline-offset:3px;   /* NEVER 0 — on a brand fill the ring measures 1.73:1 */
}

/* Persian has no uppercase. This silently damages any Latin run mixed in. */
[lang="fa"] *{ text-transform:none; }

/* Isolate Latin runs and numbers inside Persian text. */
.fm-ltr{ direction:ltr; unicode-bidi:isolate; }
