/* ==========================================================================
   Aarav Sharma — Design Tokens
   Single source of truth for the design system. Framework-agnostic.
   Consume via var(--token). Do not hardcode values elsewhere.

   Typography, colour, radius, and button values are matched to
   fintechx-wbs.framer.website. See research/reference-fintechx.md for the
   measured source of every number here.

   Sizes are STEPPED at hard breakpoints (not fluid clamp), because the
   reference is stepped. Breakpoints: desktop >=1200, tablet 810-1199,
   mobile <=809. Type tokens are redefined per breakpoint at the bottom.
   ========================================================================== */


:root {
  /* Typefaces ------------------------------------------------------------ */
  /* Two families, no serif, no mono.
     Display  = Bricolage Grotesque, weight 600 only. Carries all personality.
     Sans     = Inter (the free equivalent of the reference's "Inter Display";
                its variable opsz axis does the same optical-display job).
     Set font-optical-sizing: auto on body so Inter picks the display cut. */
  --font-display: "Bricolage Grotesque", "Inter", system-ui, -apple-system, sans-serif;
  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;

  /* Inter character variants used by the reference on every text style. */
  --font-features: "cv09" on, "cv03" on, "cv04" on, "cv11" on;

  /* Color ---------------------------------------------------------------- */
  --bg: #FFFFFF;              /* page, every section, no banding */
  --surface: #EDF1F4;         /* cards, chips, eyebrow pills */
  --surface-dark: #1D1D1D;    /* dark cards and dark buttons */
  --ink: #14171D;             /* headings, eyebrows, captions (cool near-black) */
  --ink-muted: #4D585F;       /* ALL body copy. body text is never black */
  --ink-faint: #6B7684;       /* caps labels, dates, meta. 4.62:1 on white.
                                 Was #8D99A6, which measured 2.90:1 and failed
                                 AA on every byline and date on the site. */
  --ink-inverse: #FFFFFF;     /* text on dark and on coloured buttons */
  --hairline: #DDE5ED;        /* borders and dividers */
  --panel-border: #BABABA;    /* media frame border */

  --blue: #3B82F6;            /* accents: dots, ticks, rules, key phrases */
  --blue-aa: #2F6FE0;         /* the same blue where TEXT sits on it (4.70:1) */
  --blue-deep: #406AE4;       /* primary gradient end */
  --blue-light: #5290F4;      /* button border / highlight */
  --dark-grad-start: #323232; /* dark button gradient start */
  --dark-grad-end: #000000;   /* dark button gradient end */

  --overlay-white: rgba(255, 255, 255, 0.10);  /* surfaces on dark */
  --inner-glow: rgba(255, 255, 255, 0.30);     /* button inset highlight */

  /* Depth ---------------------------------------------------------------- */
  /* The flat white page reads cold on its own. These give sections air and
     a faint blue cast without introducing a second brand colour. */
  --wash: linear-gradient(180deg, #FFFFFF 0%, #F7FAFD 46%, #FFFFFF 100%);
  --wash-top: linear-gradient(180deg, #F6FAFD 0%, #FFFFFF 62%);
  --card-grad: linear-gradient(158deg, #F3F7FB 0%, #E8EFF6 100%);
  --card-grad-hover: linear-gradient(158deg, #EFF5FC 0%, #E1EBF7 100%);
  --glow-blue: radial-gradient(circle, rgba(59,130,246,0.16) 0%, rgba(59,130,246,0) 70%);
  --glow-soft: radial-gradient(circle, rgba(59,130,246,0.10) 0%, rgba(59,130,246,0) 70%);
  --accent-underline: linear-gradient(90deg, var(--blue) 0%, var(--blue-deep) 100%);
  /* Sky, used by the three landscape moments: hero, about, close. */
  --sky-deep: #C9E2F5;
  /* Starts at pure white so the section emerges out of the one above it with
     no seam, and lands on the same blue the close does, so the meadow has real
     sky behind it rather than a washed-out hole between the hills. */
  --sky-soft: linear-gradient(180deg, #FFFFFF 0%, #F2F8FD 18%, #E3F0FB 50%, #CFE4F6 100%);

  /* Section tint ---------------------------------------------------------- */
  /* One grammar, several temperatures (revision three). Every wash is a band
     that rises out of white and returns to it, so no boundary is ever hard.
     What changed from "one tint only": the page's five tinted sections all
     wore the same blue and blended into one another. Each now keeps the same
     paper strength but takes its own temperature from things the site already
     owns: the brand blue, the scene-accent violet, a neutral cool gray, and
     the meadow's green. Saturation stays low enough that content never
     competes with background. */
  --tint: #F1F7FD;          /* the blue paper: A note from me            */
  --tint-svc: #EDF4FB;      /* services: a half-step deeper studio blue  */
  --tint-violet: #F5F3FB;   /* field notes: the violet breath            */
  --tint-gray: #F2F5F8;     /* faq: cool gray, no blue at all            */
  --tint-green: #F1F7EE;
  --tint-stone: #F3F3F5;    /* process: the reference's neutral room */
  --stone-card: #ECECED;    /* the illustration card inside it */    /* process: the meadow as paper              */

  /* Glass ------------------------------------------------------------------ */
  /* Translucent white over REAL texture only: the nav over the hero photo,
     service cards over their colour field, the process stage over the blurred
     meadow, the cursor card over dimmed rows, chips over poster art. Never on
     flat white (translucency over nothing is just a dimmer white), and never
     as decoration. */
  --glass-bg: rgba(255, 255, 255, 0.58);
  --glass-bg-strong: rgba(255, 255, 255, 0.78);
  --glass-border: rgba(255, 255, 255, 0.78);
  --glass-blur: 18px;

  /* Accent ---------------------------------------------------------------- */
  /* ONE accent for the whole site, and it is the brand blue. It is never a
     per-section or per-project decoration: it marks the thing you can act on,
     the thing that is live, or the one phrase a sentence turns on.
     --a / --b   full strength, small elements only (badges, marks, rules)
     --t         ~5% plate tint, for panels the accent sits on
     --g         glow rgba, for shadows cast by accent elements */
  --a: #3B82F6;
  --b: #406AE4;
  --t: #EEF5FE;
  --g: rgba(59, 130, 246, 0.30);

  --focus: #3B82F6;           /* focus ring */
  --selection: rgba(59, 130, 246, 0.18);

  /* Scene accents (revision two) ------------------------------------------ */
  /* The one-accent rule stands for the INTERFACE: everything you can act on
     is blue, everywhere. Illustration is allowed a wider register: the
     process scenes each carry one supporting hue, tuned to the same
     saturation band as the brand blue, so the journey subtly travels the
     palette and returns home to blue. Never used on buttons, links, or any
     interactive element. */
  --sc-violet-a: #8B7CF7; --sc-violet-b: #6D5AE6; --sc-violet-t: #F2F0FE;
  --sc-amber-a: #F0A44B;  --sc-amber-b: #DF8B2E;  --sc-amber-t: #FDF3E7;
  --sc-teal-a: #34B8A0;   --sc-teal-b: #1F9E88;   --sc-teal-t: #E8F8F4;

  /* Type scale — DESKTOP (>=1200px) -------------------------------------- */
  /* Headings: Bricolage Grotesque 600. Negative tracking on H1/H2 only. */
  --text-h1: 100px;   --ls-h1: -1.4px;  --lh-h1: 1.0;
  --text-h2: 44px;    --ls-h2: -0.9px;  --lh-h2: 1.15;
  --text-h2-sm: 40px; --ls-h2-sm: -1px;
  --text-h3: 32px;    --ls-h3: -0.64px; --lh-h3: 1.2;
  --text-h3-sm: 28px;
  --text-h4: 24px;    --ls-h4: -0.48px; --lh-h4: 1.25;

  /* Body family: Inter. Letter-spacing is 0 and line-height 1.3 on ALL. */
  --text-lead: 20px;
  --text-body: 18px;
  --text-small: 16px;
  --text-caption: 14px;
  --text-stat: 86px;   --lh-stat: 0.72;   /* big numerals, set very tight */
  --lh-body: 1.5;      /* was 1.3. Represent runs body at 1.5 and it is
                          the difference between cramped and composed. */
  --ls-body: -0.01em;  /* their main-text tracking */

  --weight-regular: 400;
  --weight-medium: 500;    /* body copy sits at 500, not 400 */
  --weight-semibold: 600;  /* headings, buttons, nav, badges */
  --weight-bold: 700;      /* stat numbers only */

  --measure: 60ch;

  /* Spacing (8px base) --------------------------------------------------- */
  --space-1: 0.25rem;   /* 4  */
  --space-2: 0.5rem;    /* 8  */
  --space-3: 0.75rem;   /* 12 */
  --space-4: 1rem;      /* 16 */
  --space-5: 1.5rem;    /* 24 */
  --space-6: 2rem;      /* 32 */
  --space-7: 3rem;      /* 48 */
  --space-8: 4rem;      /* 64 */
  --space-9: 6rem;      /* 96 */
  --space-10: 8rem;     /* 128 */
  --space-11: 10rem;    /* 160 */
  --section-y: 120px;
  --gutter: 30px;

  /* Layout --------------------------------------------------------------- */
  --container: 1260px;       /* the reference's outer container */
  --container-inner: 1060px; /* the media / content column inside it */
  --container-text: 720px;
  --grid-cols: 12;
  --grid-gap: 30px;

  /* Radius --------------------------------------------------------------- */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;    /* media frames */
  --radius-xl: 20px;    /* cards */
  --radius-2xl: 24px;   /* large cards */
  --radius-pill: 100px; /* every button and chip */
  --radius-circle: 50%;

  --border-hairline: 1px;

  /* Buttons -------------------------------------------------------------- */
  /* The light stop is --blue-aa, not --blue: white 18px/600 on #3B82F6 measured
     4.33:1, under the 4.5 AA needs for text this size. #2F6FE0 is 4.70:1 and
     the gradient still reads as the same blue. --blue keeps its own value for
     dots, ticks and rules, where the ratio does not apply. */
  --btn-primary-grad: linear-gradient(110deg, var(--blue-aa) 0%, var(--blue-deep) 100%);
  --btn-dark-grad: linear-gradient(110deg, var(--dark-grad-start) 0%, var(--dark-grad-end) 100%);
  --btn-primary-shadow: 0 6px 18px rgba(58, 119, 229, 0.22);
  --btn-dark-shadow: 0 6px 18px rgba(9, 9, 17, 0.18);
  --btn-pad-primary: 12px 54px 12px 30px;  /* extra right padding for the icon */
  --btn-pad-dark: 10px 40px 10px 24px;
  --btn-pad-secondary: 18px 44px;
  --btn-halo-pad: 6px;      /* outer wrapper ring around the primary button */
  --btn-icon-inset: 8px;    /* the white circle is inset 8px top/bottom with
                               aspect-ratio 1, so it sizes off the button
                               height (31px on primary) rather than a fixed px */

  /* Button motion — measured off the reference by sampling the live hover
     frame by frame. The arrow flies right-to-left across the button while the
     label slides over to re-balance. No lift, no scale, no overshoot. */
  --dur-btn: 400ms;
  --ease-btn: cubic-bezier(0.42, 0, 0.58, 1);  /* best fit of the sampled curve */
  --btn-icon-spin: 45deg;    /* outgoing spins to +45, incoming from -45 to 0 */
  --btn-label-shift: 24px;   /* label slides right as the circle swaps sides */
  /* The incoming circle parks at left: -(diameter) so it is fully hidden, and
     both circles travel (diameter + inset) so it lands exactly at the inset.
     Diameter depends on button height, so each button sets its own --dot-d.
     On the reference that is d=31.4 and inset=8, giving the 40px measured. */

  /* Chips and cards ------------------------------------------------------ */
  --chip-bg: var(--surface);
  --chip-pad: 10px 20px;
  --card-bg: var(--surface);
  --card-pad: 90px 30px 30px;  /* deep top padding leaves room for a title */

  /* Elevation ------------------------------------------------------------ */
  --shadow-sm: 0 1px 2px rgba(29, 29, 29, 0.06);
  --shadow-md: 0 10px 30px rgba(29, 45, 72, 0.10);
  --shadow-lg: 0 40px 90px rgba(20, 40, 70, 0.22);

  /* Motion --------------------------------------------------------------- */
  --dur-1: 150ms;
  --dur-2: 200ms;
  --dur-3: 300ms;
  --dur-4: 500ms;
  --dur-5: 700ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.76, 0, 0.24, 1);
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --reveal-y: 12px;
  --reveal-stagger: 80ms;

  /* Page transitions. Slower and softer than any in-page motion, because they
     have to read as travel rather than as a state change. --ease-cine is a
     long, heavy tail: it leaves fast and lands almost imperceptibly. */
  --dur-leave: 520ms;
  --dur-arrive: 700ms;
  --ease-cine: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-cine-in: cubic-bezier(0.7, 0, 0.3, 1);

  /* Icons ---------------------------------------------------------------- */
  --icon-sm: 16px;
  --icon-md: 20px;
  --icon-lg: 24px;
  --icon-stroke: 1.5;

  /* Layering ------------------------------------------------------------- */
  --z-nav: 100;
  --z-overlay: 1000;
  --z-toast: 1100;
}

/* Type scale — TABLET (810px to 1199px) ---------------------------------- */
@media (max-width: 1199px) {
  :root {
    --text-h1: 60px;
    --text-h2: 44px;
    --text-h2-sm: 36px;
    --text-h3: 30px;
    --text-h3-sm: 20px;
    --text-h4: 22px;
    --text-lead: 18px;
    --text-body: 16px;
    --text-small: 15px;
    --text-stat: 72px;
    --section-y: 104px;
  }
}

/* Type scale — MOBILE (<=809px) ------------------------------------------ */
@media (max-width: 809px) {
  :root {
    --text-h1: 40px;
    --text-h2: 34px;
    --text-h2-sm: 32px;
    --text-h3: 24px;
    --text-h4: 20px;
    --text-stat: 60px;
    /* 0.63 of the desktop 120px. Represent's own tokens land mobile section
       padding at 0.53 to 0.60 of desktop and only hold a hero nearer 0.7, so
       84px (0.70) was reading as desktop rhythm on a phone. */
    --section-y: 76px;
    --gutter: 20px;
  }
}

/* Tap highlight ----------------------------------------------------------
   iOS and Android paint a translucent blue rectangle over whatever you tap.
   It ignores border-radius, so on a pill button it draws a RECTANGLE around
   the pill, which is what reads as a bug. Removing it costs nothing here
   because every interactive element on this site already answers a press with
   its own state, and it does not touch :focus-visible, so the keyboard focus
   ring is untouched. */
a, button, summary, label, input, select, textarea,
[role="button"], [tabindex] {
  -webkit-tap-highlight-color: transparent;
}

/* Base text style --------------------------------------------------------
   The system is a single light theme. The reference has no dark mode: the
   page is white everywhere and darkness is a card/button treatment, not a
   theme. Do not add a prefers-color-scheme override without a decision. */
body {
  background: var(--bg);
  color: var(--ink-muted);
  font-family: var(--font-sans);
  font-size: var(--text-body);
  font-weight: var(--weight-medium);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  font-optical-sizing: auto;
  font-feature-settings: var(--font-features);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  color: var(--ink);
  margin: 0;
}
h1 { font-size: var(--text-h1); letter-spacing: var(--ls-h1); line-height: var(--lh-h1); }
h2 { font-size: var(--text-h2); letter-spacing: var(--ls-h2); line-height: var(--lh-h2); }
h3 { font-size: var(--text-h3); letter-spacing: var(--ls-h3); line-height: var(--lh-h3); }
h4 { font-size: var(--text-h4); letter-spacing: var(--ls-h4); line-height: var(--lh-h4); }

::selection { background: var(--selection); }

/* Platform behaviour ------------------------------------------------------
   Four rules that belong to every page, not just the homepage. Before this
   they only existed inside index.html's inline <style>, so the case studies
   and the essays behaved differently from the homepage. */

/* One light theme, stated out loud. Without it, phones in dark mode re-tint
   scrollbars and native controls on a page that has no dark variant. */
:root { color-scheme: light; }

/* The focus ring, defined once. The essays and case pages were falling back
   to the browser's default ring. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 6px;
}

/* Drops the ~300ms Safari holds after every tap while it waits to see if a
   second tap is coming. */
a, button, summary, [role="button"] { touch-action: manipulation; }

/* The nav is fixed and 80px tall. Without this, following a link to a
   section parks that section's top edge underneath it. */
section[id], main[id], article[id] { scroll-margin-top: 104px; }

/* Sends keyboard users past the nav on the first Tab. Visually hidden until
   it takes focus, then it lands as a normal chip in the top-left. */
.skip-link {
  position: fixed; top: 20px; left: 20px; z-index: 200;
  padding: 11px 18px; border-radius: var(--radius-pill);
  background: var(--ink); color: #FFFFFF;
  font-size: var(--text-caption); font-weight: var(--weight-semibold);
  letter-spacing: -0.01em; text-decoration: none;
  transform: translateY(-160%);
  transition: transform var(--dur-2) var(--ease-standard);
}
/* :focus, not :focus-visible. A skip link has one job and it should appear
   on any focus, however that focus arrived. */
.skip-link:focus { transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
