/* ==========================================================================
   REPULSE UK — DESIGN TOKENS

   Light base with real range: white canvas, near-black authority bands, and
   violet gradient surfaces. The previous pass was all-white and had no tonal
   variety, which is why it read as empty. Every surface below exists so a
   section can change weight without changing system.

   Corners stay TIGHT (6px cards / 4px controls). A security brand should not
   look soft.

   Contrast verified against rendered pixels:
     #11111C on #FFFFFF ...... 18.74:1
     #9300D3 on #FFFFFF ....... 6.60:1   (violet works as text on light)
     #FFFFFF on #9300D3 ....... 6.60:1   (and as a fill under white text)
     #FFFFFF on #0D0D14 ...... 18.30:1   (dark bands)
     #B9B2C4 on #0D0D14 ....... 8.60:1   (muted text on dark)
   ========================================================================== */

:root {
  /* ---------- Brand (extracted from repulseuk.com) ---------- */
  --violet:        #9300D3;
  --violet-deep:   #451465;
  --violet-bright: #B44BEE;
  --ink:           #11111C;

  /* ---------- Light surfaces ---------- */
  --white:   #FFFFFF;
  --paper:   #FAF8FC;   /* faint violet-tinted band            */
  --paper-2: #F4F0F8;   /* second-level band                   */
  --wash:    #F6EAFD;   /* lightest violet surface             */
  --line:    #E6E1EC;   /* THE hairline border on light        */
  --line-2:  #D7CFE0;   /* stronger divider                    */

  /* ---------- Dark surfaces (authority bands + dark cards) ---------- */
  --night:    #0D0D14;  /* full-bleed dark band                */
  --night-2:  #16161F;  /* raised dark card                    */
  --night-3:  #21212C;  /* dark card hover / border            */
  --night-line: rgba(255, 255, 255, 0.10);

  /* ---------- Text ---------- */
  --t-strong:  #11111C;
  --t-body:    #4A4458;
  --t-muted:   #6E6780;
  --t-faint:   #8F87A0;
  --t-on-dark:        #FFFFFF;
  --t-on-dark-body:   #C9C3D4;
  --t-on-dark-muted:  #9A93A8;

  /* ---------- Gradients — the thing that gives cards life ---------- */
  --grad-violet:  linear-gradient(135deg, #9300D3 0%, #6A0A9B 55%, #451465 100%);
  --grad-night:   linear-gradient(150deg, #1A1226 0%, #0D0D14 60%, #0D0D14 100%);
  --grad-wash:    linear-gradient(140deg, #F6EAFD 0%, #FAF8FC 70%, #FFFFFF 100%);
  --grad-edge:    linear-gradient(90deg, transparent, var(--violet), transparent);

  /* ---------- Status ---------- */
  --signal: #0C7F53;
  --signal-on-dark: #35D89A;
  --danger: #C4283C;

  /* ---------- Typography ----------
     Archivo — a sturdy grotesque that echoes the geometric wordmark in the
     Repulse logo. Real weight range: headings carry 700, not a whisper. */
  --font: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;

  --fs-xs:      0.8125rem;  /* 13 */
  --fs-sm:      0.9375rem;  /* 15 */

  /* The header nav has its own size, for two reasons.
   *
   * Nav links used --fs-sm, which is shared with buttons, form labels, badges
   * and table text, so raising that to make the header more legible would
   * have moved several dozen unrelated things across the site.
   *
   * And the nav is at its tightest exactly where it first appears, at 1120px:
   * seven links, a phone number and a button on one line beside a 170px logo.
   * Measured, that row had 8px to spare before any of this. So the curve
   * starts at the size the nav already was and grows from there -- a small
   * laptop is unchanged, a real desktop gets the increase.
   *
   * 15px at 1120px, 21px at 1920px and above. Nothing else in the type scale
   * changes; this token is used only by .nav__link, .header__phone and the
   * header's own button. */
  --fs-nav:     clamp(0.9375rem, 0.4125rem + 0.75vw, 1.5rem);
  --fs-base:    1.0625rem;  /* 17 — above the iOS zoom floor */
  --fs-lg:      1.1875rem;  /* 19 */
  --fs-xl:      clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);
  --fs-h4:      clamp(1.125rem, 1.05rem + 0.4vw, 1.3125rem);
  --fs-h3:      clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
  --fs-h2:      clamp(1.875rem, 1.4rem + 2.1vw, 3rem);
  --fs-display: clamp(2.5rem, 1.5rem + 4.4vw, 4.5rem);
  --fs-stat:    clamp(2.5rem, 1.6rem + 3.6vw, 4rem);

  --lh-tight:   1.06;
  --lh-snug:    1.18;
  --lh-body:    1.6;

  --tr-display: -0.035em;
  --tr-head:    -0.025em;
  --tr-body:    -0.005em;
  --tr-label:   0.08em;

  /* ---------- Spacing ---------- */
  --sp-1: 0.25rem;  --sp-2: 0.5rem;   --sp-3: 0.75rem;  --sp-4: 1rem;
  --sp-5: 1.25rem;  --sp-6: 1.5rem;   --sp-8: 2rem;     --sp-10: 2.5rem;
  --sp-12: 3rem;    --sp-16: 4rem;    --sp-20: 5rem;

  /* Deliberately tighter than the previous pass — 96px gaps with no imagery
     read as an unfinished page rather than a confident one. */
  --section-y: clamp(3rem, 1.75rem + 3vw, 7rem);
  --gutter:    clamp(1.25rem, 0.5rem + 2.5vw, 5rem);

  /* The frame follows the screen instead of stopping at a laptop.
   *
   * This was a flat 1280px, so a 27" monitor showed the site in a 1280px
   * column with roughly 640px of dead margin down each side. It grows at half
   * the screen's rate rather than filling it -- taking the full width would
   * stretch card rows into unreadable lines -- and the ceiling is deliberate
   * for the same reason.
   *
   * Below 1280px the clamp floors and .container's own width:100% governs, so
   * nothing about narrow screens changes. The raised --gutter and --section-y
   * ceilings above only engage past roughly 1360px and 1470px, likewise. */
  --container: clamp(1280px, calc(50vw + 640px), 2400px);
  --narrow:    720px;

  /* ---------- Shape — tight on purpose ---------- */
  --r-card: 6px;
  --r-ctl:  4px;
  --r-pill: 999px;

  /* ---------- Elevation — neutral, subtle, never a coloured glow ---------- */
  --sh-1: 0 1px 2px rgba(17, 17, 28, 0.06);
  --sh-2: 0 4px 16px -6px rgba(17, 17, 28, 0.14);
  --sh-3: 0 18px 40px -18px rgba(17, 17, 28, 0.28);

  /* ---------- Motion ---------- */
  --d-fast: 160ms;
  --d-base: 280ms;
  --d-slow: 520ms;
  --e-out:  cubic-bezier(0.16, 1, 0.3, 1);
  --e-both: cubic-bezier(0.65, 0, 0.35, 1);

  /* ---------- Layering ---------- */
  --z-sticky: 40; --z-header: 60; --z-dropdown: 70;
  --z-modal: 90;  --z-widget: 95; --z-toast: 100;
}

/* ==========================================================================
   RESET
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5.5rem;
  /* `clip` rather than `hidden`: hidden makes this a scroll container, so the
     off-screen mobile drawer (translateX(100%)) still extends the scrollable
     area and reports a horizontal overflow. clip removes it from overflow
     entirely. Paired with `hidden` as the fallback on body. */
  overflow-x: clip;
}

body {
  background: var(--white);
  color: var(--t-body);
  font-family: var(--font);
  font-size: var(--fs-base);
  font-weight: 400;
  line-height: var(--lh-body);
  letter-spacing: var(--tr-body);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  overflow-x: clip;
  min-height: 100dvh;
}

img, picture, video, canvas, svg { display: block; max-width: 100%; }

/* Sprite <symbol>s have no intrinsic size — without this any icon missing an
   explicit size rule expands to fill its parent and visibly breaks the page. */
svg { width: 20px; height: 20px; flex: 0 0 auto; }

input, textarea, select { font: inherit; color: inherit; letter-spacing: inherit; }
button { font: inherit; letter-spacing: inherit; }
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }
ul, ol { list-style: none; padding: 0; }
a { color: inherit; text-decoration: none; }

/* Astra writes `a:hover { color: … }` from its Customizer settings, and that
   out-specifies the rule above. Every link in the design that relies on
   inheriting its colour was therefore repainted Astra's link colour on hover:
   measured across the whole design, nine of them, including the mobile call
   bar and the menu drawer, where the substituted grey is almost invisible on
   the dark ground.

   The compiled site has no bare `a:hover` anywhere -- a link that does not
   define a hover colour simply does not change -- and this restores exactly
   that. Declared at the same specificity as Astra's rule but in a stylesheet
   that loads after it, so it wins here, while every deliberate hover in the
   design (.nav__link, .breadcrumb a, .footer__list a) is either equally
   specific in a later file or more specific, and still wins over this in turn.

   Classes that set a colour of their own restate it for hover beside their own
   rule; see .btn and .link in components.css. */
a:hover,
a:focus { color: inherit; }

/* ==========================================================================
   TYPE
   ========================================================================== */

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font);
  color: var(--t-strong);
  font-weight: 700;
  line-height: var(--lh-snug);
  letter-spacing: var(--tr-head);
}
h1 { font-size: var(--fs-display); line-height: var(--lh-tight); letter-spacing: var(--tr-display); }
h2 { font-size: var(--fs-h2);      line-height: var(--lh-tight); letter-spacing: var(--tr-display); }
h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h4); }

strong, b { color: var(--t-strong); font-weight: 600; }
::selection { background: var(--violet); color: #fff; }

/* Small tracked label — used sparingly, above section headings on dark bands */
.kicker {
  display: inline-block;
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--violet);
  margin-bottom: var(--sp-4);
}
.on-dark .kicker { color: var(--violet-bright); }

/* ==========================================================================
   A11Y
   ========================================================================== */

:focus-visible { outline: 2px solid var(--violet); outline-offset: 3px; border-radius: var(--r-ctl); }
:focus:not(:focus-visible) { outline: none; }
.on-dark :focus-visible { outline-color: var(--violet-bright); }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; top: 0; left: var(--sp-4);
  z-index: var(--z-toast);
  padding: var(--sp-3) var(--sp-5);
  background: var(--violet); color: #fff;
  font-size: var(--fs-sm); font-weight: 600;
  border-radius: 0 0 var(--r-ctl) var(--r-ctl);
  transform: translateY(-110%);
  transition: transform var(--d-fast) var(--e-out);
}
.skip-link:focus { transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   LAYOUT
   ========================================================================== */

.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.container--narrow { max-width: var(--narrow); }

.section { padding-block: var(--section-y); position: relative; }
.section--paper { background: var(--paper); }
.section--tight { padding-block: clamp(2.5rem, 1.5rem + 3vw, 4rem); }

/* Full-bleed dark authority band. Every reference site has one; it is what
   stops a light page reading as weightless. */
.section--night {
  background: var(--grad-night);
  color: var(--t-on-dark-body);
}
.section--night h1, .section--night h2, .section--night h3, .section--night h4 { color: #fff; }
.section--night strong { color: #fff; }

.sec-head { max-width: 640px; margin-bottom: clamp(2rem, 1.2rem + 2.4vw, 3.25rem); }
.sec-head__title { margin-bottom: var(--sp-4); }
.sec-head__text  { font-size: var(--fs-lg); color: var(--t-muted); line-height: 1.55; max-width: 56ch; }
.section--night .sec-head__text { color: var(--t-on-dark-body); }

.sec-head--split {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  justify-content: space-between; gap: var(--sp-6); max-width: none;
}
.sec-head--split > div { max-width: 620px; }

.rule { height: 1px; border: 0; background: var(--line); }
