/* ==========================================================================
   Gravitational Radiation — design tokens
   The single source of truth for colour, type, spacing and motion.
   Every page links this file first and reads only from these properties.
   Rules and rationale: brand/index.html · summary: brand.md
   ========================================================================== */

/* Inter, self-hosted. Variable font: weight 100–900, optical size 14–32.
   The URL resolves relative to this file, so any page that links
   tokens.css gets the font. No external requests. */
@font-face {
  font-family: "Inter";
  src: url("fonts/InterVariable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ---- Colour: black, white, three grays. No accent colours, ever. ---- */
  --gr-black: #000000;
  --gr-white: #FFFFFF;
  --gr-gray-100: #E6E6E6;  /* dividers and hairlines on light           */
  --gr-gray-400: #A3A3A3;  /* secondary text on dark   (8.33:1 on black) */
  --gr-gray-600: #666666;  /* secondary text on light  (5.74:1 on white),
                              dividers on dark                            */

  /* Semantic roles. Components read these, not the raw values above. */
  --gr-bg: var(--gr-white);
  --gr-fg: var(--gr-black);
  --gr-fg-muted: var(--gr-gray-600);
  --gr-rule: var(--gr-gray-100);
  --gr-inverse-bg: var(--gr-black);
  --gr-inverse-fg: var(--gr-white);
  --gr-inverse-fg-muted: var(--gr-gray-400);
  --gr-inverse-rule: var(--gr-gray-600);

  /* ---- Type families and weights ---- */
  --gr-font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --gr-weight-light: 350;     /* "RADIATION" in the wordmark; large quiet text */
  --gr-weight-regular: 400;   /* body                                          */
  --gr-weight-medium: 500;    /* captions, labels                              */
  --gr-weight-semibold: 600;  /* headlines                                     */
  --gr-weight-bold: 720;      /* "GRAVITATIONAL" in the wordmark; display      */
  --gr-opsz-wordmark: 32;

  /* ---- Type scale: size / weight / line height / letter spacing ---- */
  --gr-display-size: clamp(3rem, 1.6rem + 6.4vw, 7.5rem);
  --gr-display-weight: var(--gr-weight-bold);
  --gr-display-leading: 0.98;
  --gr-display-tracking: -0.04em;

  --gr-headline-size: clamp(1.75rem, 1.35rem + 1.8vw, 3rem);
  --gr-headline-weight: var(--gr-weight-semibold);
  --gr-headline-leading: 1.1;
  --gr-headline-tracking: -0.025em;

  --gr-body-size: 1.125rem;     /* 18px */
  --gr-body-weight: var(--gr-weight-regular);
  --gr-body-leading: 1.6;
  --gr-body-tracking: -0.011em;

  --gr-small-size: 0.9375rem;   /* 15px */
  --gr-small-weight: var(--gr-weight-regular);
  --gr-small-leading: 1.5;
  --gr-small-tracking: -0.006em;

  --gr-caption-size: 0.8125rem; /* 13px */
  --gr-caption-weight: var(--gr-weight-medium);
  --gr-caption-leading: 1.4;
  --gr-caption-tracking: 0.01em;

  --gr-measure: 64ch;           /* longest comfortable line of body text */

  /* ---- Spacing: a 4px base, growing toward generous whitespace ---- */
  --gr-space-1: 0.25rem;   /*   4px */
  --gr-space-2: 0.5rem;    /*   8px */
  --gr-space-3: 0.75rem;   /*  12px */
  --gr-space-4: 1rem;      /*  16px */
  --gr-space-5: 1.5rem;    /*  24px */
  --gr-space-6: 2rem;      /*  32px */
  --gr-space-7: 3rem;      /*  48px */
  --gr-space-8: 4rem;      /*  64px */
  --gr-space-9: 6rem;      /*  96px */
  --gr-space-10: 8rem;     /* 128px */
  --gr-space-11: 12rem;    /* 192px */

  /* ---- Layout grid ---- */
  --gr-grid-max: 75rem;                            /* 1200px content width */
  --gr-grid-columns: 4;                            /* mobile               */
  --gr-grid-gutter: var(--gr-space-4);
  --gr-grid-margin: clamp(1rem, 5vw, 4rem);
  --gr-section-gap: clamp(var(--gr-space-9), 12vw, var(--gr-space-11));

  /* ---- Logo ---- */
  --gr-logo-min-horizontal: 140px;
  --gr-logo-min-stacked: 96px;
  --gr-logo-min-symbol: 16px;
  /* Clear space X = cap height of "GRAVITATIONAL", as a fraction of the
     supplied file's width. Each file already contains 10 units of padding;
     the -extra values are what to add around the file to reach X. */
  --gr-logo-x-horizontal: 0.0666;
  --gr-logo-x-horizontal-extra: 0.0494;
  --gr-logo-x-stacked: 0.0899;
  --gr-logo-x-stacked-extra: 0.0667;
  --gr-logo-x-wordmark: 0.0899;
  --gr-logo-x-wordmark-extra: 0.0667;

  /* ---- Motion: things orbit, converge and ripple. Nothing bounces. ----
     Every curve stays inside 0–1 on both axes, so nothing overshoots. */
  --gr-duration-fast: 300ms;    /* state changes: hover, focus          */
  --gr-duration-base: 700ms;    /* elements arriving or leaving         */
  --gr-duration-slow: 1400ms;   /* large type, section reveals          */
  --gr-duration-ripple: 5600ms; /* one wave travelling outward          */
  --gr-duration-orbit: 24s;     /* one full revolution                  */

  --gr-ease-orbit: linear;                             /* constant revolution */
  --gr-ease-converge: cubic-bezier(0.22, 1, 0.36, 1);  /* settles, no overshoot */
  --gr-ease-ripple: cubic-bezier(0.33, 0, 0.2, 1);     /* spreads, then thins   */
  --gr-ease-standard: cubic-bezier(0.37, 0, 0.63, 1);  /* symmetrical in-out    */
}

@media (min-width: 40rem) {
  :root {
    --gr-grid-columns: 8;
    --gr-grid-gutter: var(--gr-space-5);
  }
}

@media (min-width: 64rem) {
  :root {
    --gr-grid-columns: 12;
  }
}

/* Dark scheme: the same system, inverted. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --gr-bg: var(--gr-black);
    --gr-fg: var(--gr-white);
    --gr-fg-muted: var(--gr-gray-400);
    --gr-rule: var(--gr-gray-600);
    --gr-inverse-bg: var(--gr-white);
    --gr-inverse-fg: var(--gr-black);
    --gr-inverse-fg-muted: var(--gr-gray-600);
    --gr-inverse-rule: var(--gr-gray-100);
  }
}
:root[data-theme="dark"] {
  --gr-bg: var(--gr-black);
  --gr-fg: var(--gr-white);
  --gr-fg-muted: var(--gr-gray-400);
  --gr-rule: var(--gr-gray-600);
  --gr-inverse-bg: var(--gr-white);
  --gr-inverse-fg: var(--gr-black);
  --gr-inverse-fg-muted: var(--gr-gray-600);
  --gr-inverse-rule: var(--gr-gray-100);
}

/* Motion is opt-out for anyone who asks. Durations collapse to near zero,
   so any JS listening for animationend still fires. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --gr-duration-fast: 1ms;
    --gr-duration-base: 1ms;
    --gr-duration-slow: 1ms;
  }
}
