/* =============================================================================
   FitnessFinder — DESIGN TOKENS
   -----------------------------------------------------------------------------
   The single source of truth for the site's look, loaded by every page before
   any other stylesheet.

   Every colour below is a value that was already hardcoded across the old
   stylesheets — nothing has been recoloured. What changed is that rules now
   point at a token instead of a literal, so the whole site can be retuned from
   this one block.

   Typography and shape ARE new: a condensed uppercase display face (Anton) for
   headings, a geometric sans (Outfit) for body copy, and a mono face for the
   small tracked-out labels above section headings.
   ========================================================================== */
:root {
  /* --- Brand ------------------------------------------------------------ */
  --ff-brand:          #00c2ee;   /* primary cyan */
  --ff-brand-light:    #00cffb;   /* the slightly brighter fill used on CTAs */
  --ff-brand-hover:    #00a8d9;
  --ff-brand-deep:     #0099bb;
  --ff-brand-tint:     #edfaff;   /* pale cyan wash behind eyebrows/pills */
  --ff-brand-tint-2:   #f0fbff;
  --ff-brand-soft:     #b3eeff;
  /* Cyan for TEXT. The bright brand cyan is only ~2:1 against white, so it is
     kept for fills, borders and icons, and any cyan words use this deeper shade
     (≥4.8:1 on white and on every tint surface above). */
  --ff-brand-text:     #007694;
  --ff-brand-text-hover: #005b73;
  --ff-brand-a10:      rgba(0, 194, 238, 0.10);
  --ff-brand-a18:      rgba(0, 194, 238, 0.18);
  --ff-brand-a28:      rgba(0, 194, 238, 0.28);
  --ff-brand-a40:      rgba(0, 194, 238, 0.40);

  /* --- Ink & text ------------------------------------------------------- */
  --ff-ink:            #1f1f1f;   /* headings, primary text */
  --ff-ink-deep:       #1a1a2e;
  --ff-text:           #1f1f1f;
  --ff-muted:          #555;
  --ff-muted-2:        #666;
  /* muted-3/4 were #888/#aaa (3.5:1 and 2.3:1 on white); darkened to the
     lightest greys that still read at 4.5:1 on the page's light surfaces.
     muted-5 stays light: it is only for borders and dividers now, never text. */
  --ff-muted-3:        #6b6b6b;
  --ff-muted-4:        #707070;
  --ff-muted-5:        #bbb;
  /* Text sitting on a brand fill. Ink, not white: white on the cyan is ~2.1:1,
     ink is ~7.8:1 (and still 4.9:1 on the deepest cyan, #0099bb). */
  --ff-on-brand:       #1f1f1f;

  /* --- Surfaces --------------------------------------------------------- */
  --ff-surface:        #ffffff;
  --ff-surface-2:      #f8f9fb;
  --ff-surface-3:      #f4f6f9;
  /* The page's original top-to-bottom wash, kept exactly as it was. */
  --ff-page-bg:        linear-gradient(to bottom, #ffffff, #f4f6f9);

  /* --- Lines ------------------------------------------------------------ */
  --ff-line:           #e8e8e8;
  --ff-line-soft:      #edf0f2;
  --ff-line-strong:    #e0e0e0;
  --ff-line-field:     #e6e9ec;
  --ff-line-faint:     #f0f0f0;

  /* --- Status ----------------------------------------------------------- */
  --ff-danger:         #e74c3c;
  --ff-danger-2:       #dc2626;
  --ff-success:        #27ae60;
  --ff-success-2:      #22c55e;
  --ff-success-3:      #16a34a;
  --ff-success-text:   #15803d;   /* green for words: the fills above fail as text */
  --ff-warn:           #f59e0b;
  --ff-warn-soft:      #fde68a;
  --ff-warn-deep:      #b45309;
  --ff-accent-purple:  #7c3aed;   /* was #8b5cf6, 4.2:1 — short of 4.5 as text and under white */

  /* --- Type ------------------------------------------------------------- */
  --ff-font-body:      'Outfit', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --ff-font-display:   'Anton', 'Arial Narrow', sans-serif; /* condensed, uppercase */
  --ff-font-mono:      'JetBrains Mono', ui-monospace, monospace;
  /* Montserrat is loaded for the header lockup only — the tagline that sits
     beside the logo. Deliberately not used anywhere else in the type system. */
  --ff-font-tagline:   'Montserrat', 'Outfit', system-ui, sans-serif;

  /* Display headings run uppercase with a hair of tracking. Anton is a
     single-weight face, so weight is always 400 and size does the work. */
  --ff-display-tt:     uppercase;
  --ff-display-ls:     0.015em;
  --ff-display-fw:     400;

  /* Micro-labels: mono, uppercase, widely tracked. */
  --ff-label-fs:       0.68rem;
  --ff-label-ls:       0.14em;

  /* --- Shape ------------------------------------------------------------ */
  --ff-r-pill:         999px;
  --ff-r-card:         14px;
  --ff-r-card-lg:      20px;
  --ff-r-tile:         11px;
  --ff-r-input:        12px;

  /* --- Page rhythm -------------------------------------------------------
     Vertical spacing shared by every public page, so heroes and sections sit
     the same distance apart wherever you are on the site. Horizontal gutters
     stay at 6% (the value every page already used). */
  --ff-space-hero-top:    64px;   /* page hero, top */
  --ff-space-hero-bottom: 52px;   /* page hero, bottom */
  --ff-space-page-y:      56px;   /* main content block under a page hero */
  --ff-space-section-y:   76px;   /* stacked marketing sections (home, about) */

  /* --- Elevation --------------------------------------------------------
     Tighter and cooler than the old flat rgba(0,0,0,.1) drops. */
  --ff-shadow-xs:      0 1px 2px rgba(16, 24, 40, 0.04);
  --ff-shadow-sm:      0 2px 10px rgba(16, 24, 40, 0.06);
  --ff-shadow-md:      0 6px 24px rgba(16, 24, 40, 0.08);
  --ff-shadow-lg:      0 16px 48px rgba(16, 24, 40, 0.12);
  --ff-shadow-brand:   0 4px 16px rgba(0, 194, 238, 0.28);

  /* --- Motion ----------------------------------------------------------- */
  --ff-ease:           cubic-bezier(0.4, 0, 0.2, 1);
  --ff-t-fast:         0.14s var(--ff-ease);
  --ff-t:              0.2s var(--ff-ease);
}

/* =============================================================================
   BASE TYPE
   Headings switch to the condensed uppercase face. Anything that needs to stay
   sentence-case (long prose headings, legal copy, form legends) opts out with
   .u-plain, which returns it to the body face.
   ========================================================================== */
h1, h2, h3, h4 {
  font-family: var(--ff-font-display);
  font-weight: var(--ff-display-fw);
  text-transform: var(--ff-display-tt);
  letter-spacing: var(--ff-display-ls);
  line-height: 1.08;
  color: var(--ff-ink);
}
h5, h6 {
  font-family: var(--ff-font-body);
  font-weight: 700;
  color: var(--ff-ink);
}

/* Opt-out: body face, normal casing. Used for long-form and legal pages. */
.u-plain,
h1.u-plain, h2.u-plain, h3.u-plain, h4.u-plain {
  font-family: var(--ff-font-body);
  font-weight: 700;
  text-transform: none;
  letter-spacing: -0.01em;
  line-height: 1.25;
}

/* Mono micro-label — the "eyebrow" that sits above a section heading. */
.u-label {
  display: inline-block;
  font-family: var(--ff-font-mono);
  font-size: var(--ff-label-fs);
  font-weight: 600;
  letter-spacing: var(--ff-label-ls);
  text-transform: uppercase;
  color: var(--ff-brand-text);
}

/* Form controls inherit the body face rather than the browser default. */
input, textarea, select, button {
  font-family: var(--ff-font-body);
}

/* Anton ships a single weight. Without this, any leftover `font-weight: 700`
   on a display heading makes the browser fake a bold and the letterforms smear.
   Outfit and JetBrains Mono load real weights, so nothing else is affected.

   `style` is deliberately still permitted: none of these families ship an
   italic file, so forbidding style synthesis too would silently render every
   <em> and italic caption upright. */
* {
  font-synthesis: style;
  font-synthesis-weight: none;
}

/* In-page jumps glide rather than snap. The reduced-motion block below turns
   this back to `auto`, so anyone who has asked for less movement still gets an
   instant jump. */
html { scroll-behavior: smooth; }

/* Every button floats on hover. Many buttons (especially ones built in JS) are styled
   with inline style="" attributes, which cannot carry a :hover state, so they had no
   feedback at all. This baseline lifts any button 2px, darkens it and casts a soft cyan glow
   shadow, easing in; pressing sets it back down, darker still.

   - The lift uses the standalone `translate` property, not `transform`. The two
     compose, so a button that is positioned with a transform (centred slideshow
     arrows, absolutely placed close buttons…) keeps its placement and still floats
     by exactly the same 2px as every other button. It is !important so every
     button moves the same way; bespoke per-button hover lifts/scales were removed.
   - The shadow is a drop-shadow FILTER, not box-shadow: it follows what is actually
     painted, so a text-only or icon-only button gets a shadow under its glyph rather
     than a grey rectangle around an invisible box.
   - The transition is !important because most buttons declare their own
     `transition: background …`, which would otherwise make the lift snap. The
     reduced-motion block below comes later and still wins.
   - Hover is for pointer devices only, so a tap on a phone doesn't leave a button
     stuck in the raised state. */
:where(button, input[type="submit"], input[type="button"], [role="button"],
       a[class*="btn"], a[class*="button"]) {
  transition-property: translate, transform, filter, box-shadow, background-color, background, color, border-color, opacity !important;
  transition-duration: 0.22s !important;
  transition-timing-function: cubic-bezier(0.34, 1.4, 0.64, 1) !important;   /* slight overshoot = "float" */
}
@media (hover: hover) {
  :where(button, input[type="submit"], input[type="button"], [role="button"],
         a[class*="btn"], a[class*="button"]):not(:disabled):not([aria-disabled="true"]):hover {
    translate: 0 -2px !important;
    /* Same cyan glow as a service card on hover (provider.css .price-card:hover). */
    filter: brightness(0.95) drop-shadow(0 6px 14px rgba(0, 194, 238, 0.38)) !important;
  }
  /* Light cyan border, as on the service cards. Wholly inside :where() so it has zero
     specificity: a button that sets its own hover border (red "remove", etc.) keeps it. */
  :where(:is(button, input[type="submit"], input[type="button"], [role="button"],
         a[class*="btn"], a[class*="button"]):not(:disabled):not([aria-disabled="true"]):hover) {
    border-color: var(--ff-brand-soft);
  }
}
:where(button, input[type="submit"], input[type="button"], [role="button"],
       a[class*="btn"], a[class*="button"]):not(:disabled):not([aria-disabled="true"]):active {
  translate: 0 0 !important;
  filter: brightness(0.9) drop-shadow(0 2px 5px rgba(0, 194, 238, 0.3)) !important;
  transition-duration: 0.08s !important;
}

/* Consistent focus ring everywhere, replacing the browser default outline. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--ff-brand);
  outline-offset: 2px;
  border-radius: 4px;
}

@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;
  }
  /* Keep the colour change, drop the movement. Same selector weight as the hover
     rule above (both !important), so this later rule wins. */
  :where(button, input[type="submit"], input[type="button"], [role="button"],
         a[class*="btn"], a[class*="button"]):not(:disabled):not([aria-disabled="true"]):hover,
  :where(button, input[type="submit"], input[type="button"], [role="button"],
         a[class*="btn"], a[class*="button"]):not(:disabled):not([aria-disabled="true"]):active {
    translate: none !important;
  }
}
