/**
 * FIRST Metrology — design tokens + `bd-*` chrome/button CSS.
 *
 * Transcribed verbatim from the design-system export at
 * `sample/FIRST Metrology website design/_ds/first-metrology-design-system-*` `/tokens/`
 * (colors.css, typography.css, spacing.css, effects.css, fonts.css) — see
 * .superpowers/sdd/2026-07-28-port-first-pages/task-2-brief.md for the scope
 * decision behind this file: plain CSS custom properties, no Tailwind v4
 * `@theme {}` build step (that pipeline, described in docs/architecture.md
 * §6.2, does not exist in this repo yet and is out of scope here).
 *
 * Loaded before assets/css/first.css (see functions.php) so these semantic
 * tokens and `bd-*` component classes are available first; first.css's own
 * `fm-*` classes and its own (separately-declared, pre-existing) token
 * subset are untouched by this file.
 */

/* --------------------------------------------------------------- fonts -- */
/*
 * The Inter webfont USED to be pulled in here with the export's verbatim
 * `@import url('https://fonts.googleapis.com/css2?family=Inter…&display=swap')`.
 * It is now SELF-HOSTED: the woff2 files are in assets/fonts/ and the
 * `@font-face` rules are declared in theme.json's
 * `settings.typography.fontFamilies[].fontFace`, which WordPress emits inline
 * in the head for both the front end and the editor.
 *
 * Why the `@import` had to go: it is only discovered once tokens.css itself has
 * been downloaded and parsed, and the preload scanner cannot see it in the
 * HTML. That serialised three round trips before a single glyph could be
 * requested — tokens.css, then the Google Fonts CSS, then the woff2 — all three
 * render-blocking.
 *
 * Why self-hosting rather than a `<link>` + `preconnect` to Google: a `<link>`
 * still costs a DNS + TCP + TLS handshake to a second origin before the CSS
 * arrives, and the woff2 is a *third* origin after that. Self-hosted, the
 * `@font-face` is inline (zero requests) and the woff2 comes off the connection
 * already open for the document. It also removes a third-party availability
 * dependency and the privacy exposure of every visitor hitting Google.
 *
 * Do not put the `@import` — or a Google Fonts `<link>` — back. To change the
 * font, replace the files in assets/fonts/ and the `fontFace` block in
 * theme.json.
 */

/* ----------------------------------------------------------------- base -- */
/*
 * From tokens/base.css line 1 — the one rule of the export's reset this theme
 * actually depends on, and the only part of that file worth carrying over
 * (the rest of base.css is element defaults WordPress already provides).
 *
 * It was missing, and that is why every section sat 24px wider than the
 * mockup: `.bd-container` and friends declare `max-width: 1280px` *plus*
 * `padding: 0 24px`, which under the default `content-box` means 1328px of
 * total width, so the content column started 24px further out on each side
 * than the design's. Layouts ported from an export written against a
 * border-box reset have to be read under that reset.
 */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/*
 * The second rule of that reset worth carrying over, added 2026-08-12.
 *
 * The export's base.css sets `text-wrap: balance` on headings and `pretty` on
 * paragraphs. WordPress provides no equivalent — it is not expressible in
 * theme.json's `styles.elements` — so without this every block sheet that
 * wanted it declared it again, and blocks that never thought about it wrapped
 * with an orphaned last word.
 *
 * `pretty` for both, where the export splits the two: it keeps the first line
 * full and only lifts a word to avoid a one-word last line, which is what
 * headings and body copy both want here. `balance` evens the line lengths
 * instead, which on a two-line strapline ends the first line early and reads
 * like a centred pull-quote.
 *
 * Firefox implements neither value (it has `text-wrap` but not `pretty` or
 * `balance`) and falls back to normal greedy wrapping — the rendering
 * everything had before 2023. Nothing here depends on the lift.
 */
h1,
h2,
h3,
h4,
h5,
h6,
p {
  text-wrap: pretty;
}

/* --------------------------------------------------------------- colors -- */
/* Verbatim from tokens/colors.css. */
:root {
  /* ---- Brand: FIRST blue (primary, the "I·S·T" of the wordmark) ---- */
  --first-blue-050: #E9F4FA;
  --first-blue-100: #CCE6F4;
  --first-blue-200: #99CDE9;
  --first-blue-300: #4FA8D8;
  --first-blue:     #0080C8;  /* core brand blue */
  --first-blue-700: #0068A6;  /* hover */
  --first-blue-800: #00527F;  /* pressed */
  --first-blue-900: #003A5A;

  /* ---- ZEISS partner blues (secondary + deep) ---- */
  --zeiss-blue:     #0050A0;  /* ZEISS logo box / secondary accent */
  --zeiss-blue-700: #013E7D;
  --indigo:         #023878;  /* deep section / overlay navy */
  --indigo-900:     #011E45;  /* deepest navy */

  /* ---- Ink + white ---- */
  --ink:   #111318;  /* near-black — FIRST wordmark black, headlines on light */
  --white: #FFFFFF;

  /* ---- Neutral (cool industrial gray) ---- */
  --gray-50:  #F6F8FA;
  --gray-100: #EDF1F5;
  --gray-200: #DDE3EA;
  --gray-300: #C4CDD6;
  --gray-400: #9AA6B2;
  --gray-500: #6B7683;
  --gray-600: #4C555F;
  --gray-700: #343B43;
  --gray-800: #22272D;
  --gray-900: #14181C;

  /* ---- Semantic status ---- */
  --success: #2E9E5B;
  --warning: #E8A33D;
  --danger:  #D64545;
  --info:    var(--first-blue);

  /* ---- Data-viz: deviation spectrum (ZEISS INSPECT-style color map) ---- */
  --dev-neg:  #2F53A0;  /* below nominal */
  --dev-low:  #29A3C9;
  --dev-ok:   #37A85A;  /* in tolerance */
  --dev-warn: #E2C93B;
  --dev-high: #E4632A;
  --dev-pos:  #C6362E;  /* above nominal */

  /* ---- Semantic aliases ---- */
  --color-primary:        var(--first-blue);
  --color-primary-hover:  var(--first-blue-700);
  --color-primary-active: var(--first-blue-800);
  --color-accent:         var(--zeiss-blue);

  --text-primary:   var(--ink);
  --text-secondary: var(--gray-600);
  --text-muted:     var(--gray-500);
  --text-inverse:   var(--white);

  /*
   * Text on a dark surface — four steps, and they are the only four.
   *
   * There were ELEVEN alphas in use across the stylesheets (0.4, 0.5, 0.55,
   * 0.6, 0.62, 0.66, 0.7, 0.72, 0.8, 0.82, 0.84), none of them tokenised and
   * no two sections agreeing. They collapse into three clusters; each step
   * below is the weighted-commonest value of its cluster, so the swap moves
   * the fewest pixels:
   *
   *   0.80 / 0.82 / 0.84  (21 uses) → secondary
   *   0.60 … 0.72         (44 uses) → muted
   *   0.40 / 0.50 / 0.55  (10 uses) → subtle
   *
   * If a component needs a fifth, it is wrong — reach for a step, not a new
   * alpha. That is exactly how the eleven happened.
   */
  --text-on-dark:           var(--white);
  --text-on-dark-secondary: rgba(255,255,255,0.82);  /* body copy on dark */
  --text-on-dark-muted:     rgba(255,255,255,0.66);  /* supporting text */
  --text-on-dark-subtle:    rgba(255,255,255,0.5);   /* meta, captions */
  --text-link:      var(--first-blue);
  --text-link-hover:var(--first-blue-700);

  --surface-page:   var(--white);
  --surface-subtle: var(--gray-50);
  --surface-muted:  var(--gray-100);
  --surface-inset:  var(--gray-100);
  --surface-dark:   var(--ink);
  --surface-indigo: var(--indigo);

  --border:        var(--gray-200);
  --border-strong: var(--gray-300);
  --border-focus:  var(--first-blue);
  --focus-ring:    0 0 0 3px rgba(0,128,200,0.35);
}

/* ----------------------------------------------------------- typography -- */
/* Verbatim from tokens/typography.css. Single family: Inter. */
:root {
  --font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Weights */
  --fw-regular:   400;
  --fw-medium:    500;
  --fw-semibold:  600;
  --fw-bold:      700;
  --fw-extrabold: 800;

  /*
   * Font sizes — one fluid ladder, eleven steps, no exceptions.
   *
   * Every step interpolates between its value at a 390px viewport and its
   * value at 1440px, then clamps. Below 390 it floors, above 1440 it holds:
   * the design is not drawn wider than 1440, and letting display type keep
   * growing to 1920 makes the hero overrun every time.
   *
   * The `rem + vw` form is deliberate over plain `vw`. The rem term means the
   * text still responds to the reader's own font-size setting; a pure-vw
   * clamp silently defeats browser zoom.
   *
   * This replaced 35 rendered sizes with 11. The theme previously declared
   * this scale AND ignored it in ~80 places — twelve `15px`, seven `13.5px`,
   * and sixteen one-off `clamp()`s that between them produced 16.48px,
   * 0.96875rem and 0.906rem. If you need a size that is not here, the answer
   * is a different step, not a new value: `docs/html-to-wordpress-guide.md`
   * §3.1 explains why a component that opts out of the scale is a bug even
   * when it looks right on the page it was written for.
   *
   * Thirteen steps, chosen by counting how many elements in the export land on
   * each one — not by picking a ratio. The export's 41 sizes over 570 elements
   * are extremely lopsided: 12/14/16/18 alone carry 482 of them (85%), and
   * everything from 20px up is a long tail of 25 sizes over 83 elements.
   *
   * Ladders between 12 and 18 steps were scored against that distribution and
   * came out within 0.2% of each other on weighted relative error, so the extra
   * steps buy nothing. Dropped as noise: 22 (8 uses, and only 9% from 24 —
   * too close to read as hierarchy at all), 28 (3), 50 (1), 54 (3). Kept
   * despite looking thin: 36 (14 uses) and 44 (12) are real h2 steps, and
   * `display` at 64 has exactly ONE caller — the hero h1, the largest text on
   * the site. Thin is not the same as unimportant.
   *
   * `display` caps at 64 because that is the export's hero. An earlier 72 was
   * obvious side by side: 8px on a 64px headline is 12.5%, and it re-wrapped
   * the line.
   *
   * `xxs` is the one step that is NOT fluid. 10px is the floor of comfortable
   * legibility, so there is nowhere for it to shrink to at 390px; a clamp
   * would either do nothing or make it worse.
   *
   *                                            390px  →  1440px
   */
  --fs-xxs:     0.625rem;                                          /* 10, flat */
  --fs-xs:      clamp(0.6875rem, 0.6643rem + 0.0952vw, 0.75rem);   /* 11 → 12 */
  --fs-sm:      clamp(0.8125rem, 0.7893rem + 0.0952vw, 0.875rem);  /* 13 → 14 */
  --fs-base:    clamp(0.9375rem, 0.9143rem + 0.0952vw, 1rem);      /* 15 → 16 */
  --fs-md:      clamp(1rem,      0.9536rem + 0.1905vw, 1.125rem);  /* 16 → 18 */
  --fs-lg:      clamp(1.125rem,  1.0786rem + 0.1905vw, 1.25rem);   /* 18 → 20 */
  --fs-xl:      clamp(1.25rem,   1.1571rem + 0.3810vw, 1.5rem);    /* 20 → 24 */
  --fs-2xl:     clamp(1.5rem,    1.3607rem + 0.5714vw, 1.875rem);  /* 24 → 30 */
  --fs-3xl:     clamp(1.625rem,  1.3929rem + 0.9524vw, 2.25rem);   /* 26 → 36 */
  --fs-4xl:     clamp(1.875rem,  1.5500rem + 1.3333vw, 2.75rem);   /* 30 → 44 */
  --fs-5xl:     clamp(2rem,      1.6286rem + 1.5238vw, 3rem);      /* 32 → 48 */
  --fs-6xl:     clamp(2.25rem,   1.7857rem + 1.9048vw, 3.5rem);    /* 36 → 56 */
  --fs-display: clamp(2.5rem,    1.9429rem + 2.2857vw, 4rem);      /* 40 → 64 */

  /*
   * Line heights — Tailwind's ladder, with one deliberate difference.
   *
   * Tailwind's `leading-tight` is 1.25. That is right for body-sized text and
   * wrong for display: this theme's h1 renders at 48-56px, where 1.25 adds
   * ~11px of leading per line and the hero stops fitting. So `tight` is 1.1
   * and the rest are Tailwind's.
   *
   * Everything that was on 1.05/1.06/1.08 is now `tight`; 1.2/1.3 → `snug`;
   * 1.4 → `normal`; 1.55/1.6/1.65/1.7/1.72/1.75 → `relaxed`.
   */
  --lh-none:    1;      /* buttons, badges, bare numerals */
  --lh-tight:   1.1;    /* display, h1 */
  --lh-snug:    1.25;   /* h2, h3, card titles */
  --lh-normal:  1.5;    /* sub-heads, UI, dense lists */
  --lh-relaxed: 1.625;  /* body copy */
  --lh-loose:   2;      /* wide-measure prose */

  /*
   * Letter spacing — Tailwind's ladder plus `snug`.
   *
   * Tailwind jumps -0.025em → -0.05em, which leaves nothing for a 20-24px
   * card title: -0.025em is visibly over-tight at that size and 0 is the bug
   * this replaces (25 headings across the site had no tracking at all).
   * `--ls-caps` is gone; its callers want `--ls-widest`.
   */
  --ls-tighter: -0.05em;
  --ls-tight:   -0.025em;  /* display, h1, h2 */
  --ls-snug:    -0.015em;  /* h3, card titles */
  --ls-normal:  0;
  --ls-wide:    0.025em;
  --ls-wider:   0.05em;
  --ls-widest:  0.1em;     /* eyebrows, caps labels */

  /* Semantic roles */
  --type-display-size:   var(--fs-display);
  --type-display-weight: var(--fw-extrabold);
  --type-display-lh:     var(--lh-tight);
  --type-display-ls:     var(--ls-tight);

  --type-h1-size: var(--fs-4xl);
  --type-h2-size: var(--fs-3xl);
  --type-h3-size: var(--fs-2xl);
  --type-h4-size: var(--fs-xl);
  --type-heading-weight: var(--fw-bold);
  --type-heading-lh:     var(--lh-snug);

  --type-body-size:   var(--fs-base);
  --type-body-lh:     var(--lh-relaxed);
  --type-body-weight: var(--fw-regular);

  --type-label-size:   var(--fs-sm);
  --type-label-weight: var(--fw-semibold);

  --type-eyebrow-size:   var(--fs-xs);
  --type-eyebrow-weight: var(--fw-bold);
  --type-eyebrow-ls:     var(--ls-widest);
}

/* --------------------------------------------------------------- spacing -- */
/* Verbatim from tokens/spacing.css. 4px base grid. */
:root {
  --space-0:  0;
  --space-1:  0.25rem;  /* 4 */
  --space-2:  0.5rem;   /* 8 */
  --space-3:  0.75rem;  /* 12 */
  --space-4:  1rem;     /* 16 */
  --space-5:  1.25rem;  /* 20 */
  --space-6:  1.5rem;   /* 24 */
  --space-8:  2rem;     /* 32 */
  --space-10: 2.5rem;   /* 40 */
  --space-12: 3rem;     /* 48 */
  --space-16: 4rem;     /* 64 */
  --space-20: 5rem;     /* 80 */
  --space-24: 6rem;     /* 96 */
  --space-32: 8rem;     /* 128 */

  --container-sm: 640px;
  --container-md: 860px;
  --container-lg: 1120px;
  /*
   * 1280px, matching every `max-width: 1280px` wrapper in the design export
   * (index.dc.html, SiteHeader.dc.html, SiteFooter.dc.html — all of them).
   * This was 1320px, which pushed every section 20px wider than the mockup on
   * both sides and made a side-by-side comparison misalign on every page.
   */
  --container-xl: 1280px;
  --gutter: var(--space-6);
}

/* --------------------------------------------------------------- effects -- */
/* Verbatim from tokens/effects.css. Radii, borders, shadows, motion. */
:root {
  /* Corner radii */
  --radius-none: 0;
  --radius-xs:   2px;
  --radius-sm:   4px;
  --radius-md:   6px;   /* default control radius (buttons, inputs) */
  --radius-lg:   10px;  /* cards */
  --radius-xl:   16px;
  --radius-pill: 999px;

  /* Border widths */
  --border-width: 1px;
  --border-width-2: 2px;
  --border-accent-width: 3px;

  /* Shadows — cool-tinted, subtle */
  --shadow-xs: 0 1px 2px rgba(17,19,24,0.06);
  --shadow-sm: 0 1px 3px rgba(17,19,24,0.08), 0 1px 2px rgba(17,19,24,0.04);
  --shadow-md: 0 4px 12px rgba(17,19,24,0.10), 0 1px 3px rgba(17,19,24,0.06);
  --shadow-lg: 0 12px 32px rgba(17,19,24,0.14), 0 4px 10px rgba(17,19,24,0.08);
  --shadow-focus: var(--focus-ring);

  /* Motion */
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --ease-out:      cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in:       cubic-bezier(0.4, 0, 1, 1);
  --dur-fast:   120ms;
  --dur-base:   180ms;
  --dur-slow:   280ms;
  --transition-base: all var(--dur-base) var(--ease-standard);
}

/* ------------------------------------------------------------- bd chrome -- */
/*
 * Section-chrome classes emitted by the plugin's resolve_chrome_classes()
 * (inc/chrome.php). Every `bd/*` block's wrapper carries exactly one
 * `bd-bg-*` and one `bd-spacing-*` class, plus `bd-divider` when requested.
 * Additive only — does not touch any `fm-*` class in first.css.
 */

.bd-bg-page   { background: var(--surface-page); }
.bd-bg-subtle { background: var(--surface-subtle); }
.bd-bg-brand  { background: var(--color-primary); color: var(--text-inverse); }
.bd-bg-dark   { background: var(--surface-dark); color: var(--text-on-dark); }

/*
 * `.bd-bg-image` has no companion image attribute yet (per the
 * block-registration-foundation plan handoff) — falling back to the dark
 * treatment is a reasonable placeholder that at least keeps text legible on
 * an as-yet-unrendered background image, rather than left unstyled.
 */
.bd-bg-image  { background: var(--surface-dark); color: var(--text-on-dark); }

/*
 * Vertical rhythm, calibrated against the design export rather than picked
 * off the spacing scale on its own (FIR-006: "padding top and bottom of each
 * section different"). In index.dc.html every full section is `padding: 96px
 * 0` (the industries band is 92px, close enough to share the step) and the
 * dense stats strip is `padding: 40px 24px`. `loose` was 128px and `compact`
 * 48px, which is why each section on the real site sat visibly taller than
 * the same section in the mockup and the drift compounded down the page.
 *
 *   compact — dense strips (stats)            → 40px
 *   normal  — mid-weight sections             → 64px
 *   loose   — the standard full section       → 96px
 */
.bd-spacing-compact { padding-top: var(--space-10); padding-bottom: var(--space-10); }
.bd-spacing-normal  { padding-top: var(--space-16); padding-bottom: var(--space-16); }
.bd-spacing-loose   { padding-top: var(--space-24); padding-bottom: var(--space-24); }

.bd-divider {
  border-top: var(--border-width) solid var(--border);
}

/* -------------------------------------------------------------- bd-btn -- */
/*
 * Rendered by the plugin's bd_buttons() (inc/render-helpers.php):
 * <div class="bd-buttons"><a class="bd-btn bd-btn--primary|ghost">…</a></div>
 */

.bd-buttons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

.bd-btn {
  --bd-btn-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  height: var(--bd-btn-height);
  padding: 0 var(--space-6);
  border-radius: var(--radius-md);
  border: var(--border-width) solid transparent;
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  /*
   * `--lh-none` looks right on a button and is fine while the button owns a
   * fixed height — flex centring hides the leading entirely. It stops being
   * fine the moment a caller sets `--bd-btn-height: auto`, which
   * `.bd-rich-section .bd-btn--ghost` does: the box collapsed to 16px against
   * the export's 25px and the arrow sat hard against the cap-height.
   *
   * `--lh-normal` is correct in both cases and invisible in the fixed one.
   */
  line-height: var(--lh-normal);
  text-decoration: none;
  cursor: pointer;
  transition: var(--transition-base);
}

.bd-btn--primary {
  background: var(--color-primary);
  color: var(--text-inverse);
  border-color: var(--color-primary);
}

.bd-btn--primary:hover {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
}

.bd-btn--ghost {
  background: transparent;
  color: inherit;
  border-color: var(--border-strong);
}

.bd-btn--ghost:hover {
  background: var(--color-primary);
  color: var(--text-inverse);
  border-color: var(--color-primary);
}

/*
 * On a dark surface the light-gray `--border-strong` outline the ghost button
 * uses on a white page reads as a washed-out box (FIR-003: the hero's "Explore
 * systems" next to "Request a demo"). The export gives every ghost button
 * sitting on dark its own treatment — a translucent white fill with a
 * brighter translucent border and a blur behind it — so re-express that here
 * and let each dark surface opt in by class.
 */
.bd-hero--dark .bd-btn--ghost,
.bd-bg-dark .bd-btn--ghost,
.bd-bg-brand .bd-btn--ghost,
.bd-site-footer .bd-btn--ghost,
.bd-industry-tabs--pills .bd-btn--ghost {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.28);
  color: var(--white);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.bd-hero--dark .bd-btn--ghost:hover,
.bd-bg-dark .bd-btn--ghost:hover,
.bd-bg-brand .bd-btn--ghost:hover,
.bd-site-footer .bd-btn--ghost:hover,
.bd-industry-tabs--pills .bd-btn--ghost:hover {
  background: rgba(255, 255, 255, 0.18);
  border-color: rgba(255, 255, 255, 0.42);
  color: var(--white);
}

/* -------------------------------------------------------- arrow affordance -- */
/*
 * Every primary call to action in the design carries a trailing `arrow-right`
 * (hero "Request a demo", header "Contact us", footer "Request a
 * consultation"), and so do the section links and card CTAs. The label markup
 * for buttons comes from the plugin's shared `bd_buttons()` helper, which this
 * theme does not author the inside of, so the arrow is drawn in CSS off a
 * masked copy of the same Lucide path `inc/icons.php` renders inline
 * elsewhere. `mask` + `currentColor` means it inherits the link's colour and
 * its hover state for free.
 */
:root {
  --icon-arrow-right: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M5%2012h14%22%2F%3E%3Cpath%20d%3D%22m12%205%207%207-7%207%22%2F%3E%3C%2Fsvg%3E");
}

.bd-arrow::after,
.bd-btn--primary::after {
  content: "";
  flex: none;
  width: 1.125em;
  height: 1.125em;
  background: currentColor;
  mask: var(--icon-arrow-right) center / contain no-repeat;
  -webkit-mask: var(--icon-arrow-right) center / contain no-repeat;
  transition: transform var(--dur-base) var(--ease-standard);
}

/* The arrow nudges right on hover, matching `.fm-arrow-link:hover .fm-arr`. */
.bd-arrow:hover::after,
.bd-btn--primary:hover::after {
  transform: translateX(4px);
}
