/* Mirror-only styles. Injected into every captured page by build_site.py.
   Everything here lives OUTSIDE the React tree or is a pseudo-element, so
   Gatsby hydration cannot undo it. Nothing here labels the page as a mirror:
   the site presents as itself. */

/* Greycliff CF was served from Adobe Fonts (Typekit kit thg0uhb) on the live
   site. The mirror self-hosts the company's own Greycliff files instead.

   The files are subset to Latin (U+0000-024F), General Punctuation, Currency
   and a handful of symbols -- the full fonts carried Cyrillic, Greek and IPA
   that an English site never draws, and dropping them took the five weights
   from 144KB to 84KB. The site's entire character inventory was checked
   against the subset before it shipped; the recipe is in the README. */
@font-face { font-family: greycliff-cf; font-weight: 300; font-style: normal; font-display: swap; src: url(/mirror/fonts/GreycliffCF-Light.woff2) format("woff2"); }
@font-face { font-family: greycliff-cf; font-weight: 400; font-style: normal; font-display: swap; src: url(/mirror/fonts/GreycliffCF-Regular.woff2) format("woff2"); }
@font-face { font-family: greycliff-cf; font-weight: 500; font-style: normal; font-display: swap; src: url(/mirror/fonts/GreycliffCF-Medium.woff2) format("woff2"); }
@font-face { font-family: greycliff-cf; font-weight: 600 700; font-style: normal; font-display: swap; src: url(/mirror/fonts/GreycliffCF-Bold.woff2) format("woff2"); }
@font-face { font-family: greycliff-cf; font-weight: 800 900; font-style: normal; font-display: swap; src: url(/mirror/fonts/GreycliffCF-Heavy.woff2) format("woff2"); }

/* What the text is drawn in for the moment before Greycliff arrives.

   The captured stylesheet says `body{font-family:greycliff-cf}` and nothing
   after it, so with `font-display:swap` the fallback was whatever the browser
   defaults to -- a serif. On a throttled phone that was a full second of Times
   New Roman across the hero before every line re-set itself in Greycliff.

   These faces are Arial (and its Helvetica/Liberation stand-ins) with their
   metrics overridden to Greycliff's, so the swap changes the letterforms and
   nothing else: no line re-wraps, no vertical creep, no layout shift.

   The numbers are measured, not guessed. ascent/descent/line-gap are
   Greycliff's own hhea values (1010 / -190 / 0 on a 1000 em), identical across
   all five weights. size-adjust is the ratio of the two fonts' advance widths
   over every word of visible text in the built site (236k characters), taken
   per weight with fontTools against Liberation Sans, which is metric-identical
   to Arial. Any one line can still break a word differently -- it is a
   different typeface -- but the average is right, so a paragraph keeps its
   height. The one exception is weight 500, which above the fold is drawn
   only by the quote console's short labels; those particular strings run
   narrower in Greycliff than the corpus does (95.6% for the longest), and
   at the corpus figure (97.8%) the fallback wrapped it onto a second line
   that vanished on swap -- so this weight is set to the strings that are
   actually on screen when the swap happens. A device with no Arial
   at all (Android) falls through to system-ui unadjusted, which is still
   better than the serif. */
@font-face { font-family: "greycliff-cf-fallback"; font-weight: 300; src: local("Arial"), local("ArialMT"), local("Helvetica"), local("Liberation Sans"); size-adjust: 101.7%; ascent-override: 101%; descent-override: 19%; line-gap-override: 0%; }
@font-face { font-family: "greycliff-cf-fallback"; font-weight: 400; src: local("Arial"), local("ArialMT"), local("Helvetica"), local("Liberation Sans"); size-adjust: 96.3%; ascent-override: 101%; descent-override: 19%; line-gap-override: 0%; }
@font-face { font-family: "greycliff-cf-fallback"; font-weight: 500; src: local("Arial"), local("ArialMT"), local("Helvetica"), local("Liberation Sans"); size-adjust: 95.5%; ascent-override: 101%; descent-override: 19%; line-gap-override: 0%; }
@font-face { font-family: "greycliff-cf-fallback"; font-weight: 600 700; src: local("Arial Bold"), local("Arial-BoldMT"), local("Helvetica Bold"), local("Liberation Sans Bold"); size-adjust: 98.7%; ascent-override: 101%; descent-override: 19%; line-gap-override: 0%; }
@font-face { font-family: "greycliff-cf-fallback"; font-weight: 800 900; src: local("Arial Bold"), local("Arial-BoldMT"), local("Helvetica Bold"), local("Liberation Sans Bold"); size-adjust: 97.4%; ascent-override: 101%; descent-override: 19%; line-gap-override: 0%; }

/* Same selector and specificity as the captured `body{font-family}` rule; this
   sheet is linked after the inlined one, so it wins on order alone. Every
   component in the capture inherits from here (the only other font-family in
   the whole stylesheet is `inherit`), so one line covers the site. */
body { font-family: greycliff-cf, "greycliff-cf-fallback", system-ui, -apple-system, "Segoe UI", sans-serif; }

/* --- the mobile header ----------------------------------------------------
   Two things the captured build does on a phone that make it feel assembled
   rather than built. Neither changes a pixel at rest.

   1. The menu panel. It slides in by animating `right` from -100% to 0 over
      ONE SECOND, ease-in-out. Animating `right` re-runs layout on every frame
      of that second, and a second is long enough to reach for the button
      again. It now moves on `transform`, which the compositor animates
      without touching layout, over 0.42s on a decelerating curve -- fast out
      of the gate, soft into the wall, the way a drawer actually stops.
      `right:0` plus `translateX(100%)` is the same off-screen resting place
      as `right:-100%` for a panel whose width is a percentage of the same
      viewport, so the closed state is geometrically identical; the shadow
      travels with it as before. The hamburger's three lines were on the same
      one-second clock and follow the panel.

   2. The two icons. The hamburger and the phone are 36px squares, under the
      44px a thumb needs. Each becomes a 48px target without moving a pixel,
      by a different route, because after hydration they are different kinds
      of element:

      - the phone is an <a> (tel:) around an <img>. A pseudo-element bled 6px
        past every edge is its hit area -- no box in the layout, so nothing
        around it moves; the anchor is already `position:relative`.
      - the hamburger is an inline <svg> with React's onClick on the svg
        itself, and SVG elements cannot carry generated content. It gets 6px
        of padding on a content-box instead, with margins pulled in by the
        same 6px so it occupies exactly the space it did. It is the last
        item in the header row, so its negative right margin meets nothing;
        and in the `position:fixed` state the open menu puts it in, `right:`
        places the margin edge and the negative margin cancels the padding
        the same way. Chrome hit-tests an outer <svg>'s padding as the svg.

   Stem-matched on the CSS-module names: the trailing hash is a content hash
   that changes on re-capture. Attribute
   selectors carry class specificity, so these outrank the captured rules on
   order alone, and the open-state override sits after the closed one. */
@media (max-width: 63.99em) {
  [class*="HeaderMenu-module--menu--"] {
    right: 0;
    transform: translateX(100%);
    transition: transform .42s cubic-bezier(.32, .72, 0, 1);
  }
  [class*="HeaderMenu-module--menu--"][class*="--mobile-menu-open--"] { transform: none; }
  a[class*="Header-module--mobile-icon--"]::before {
    content: "";
    position: absolute;
    inset: -6px;
  }
  /* Two attribute selectors, not one: the captured rule that sets this
     element's margin-left is `.header .mobile-icon` (0,2,0), and a single
     attribute (0,1,1) loses to it -- which left the padding applied and the
     margin not, and moved the phone icon 6px. */
  svg[class*="Header-module--mobile-icon--"][class*="Header-module--hamburger--"] {
    box-sizing: content-box;
    padding: 6px;
    margin: -6px -6px -6px calc(var(--spacing-base) - 6px);
  }
}
@media (prefers-reduced-motion: reduce) {
  [class*="HeaderMenu-module--menu--"] { transition: none; }
}

/* Every form on the mirror is inert (mirror.js disables the fields and
   swallows submit). A greyed-out form with no explanation reads as broken, so
   it still carries a one-line notice -- but in the site's own voice, not the
   mirror's: it says the form is unavailable, not why. A pseudo-element so it
   survives React re-rendering the form. */
form { position: relative; }
form::before {
  content: "This form is currently unavailable.";
  display: block; margin: 0 0 16px; padding: 10px 14px;
  background: #f6f6fb; color: #24244d; border-left: 3px solid #24244d; border-radius: 0 4px 4px 0;
  font: 600 14px/1.4 greycliff-cf, system-ui, sans-serif;
}
form[data-mirror-disabled] input,
form[data-mirror-disabled] textarea,
form[data-mirror-disabled] select,
form[data-mirror-disabled] button { opacity: .55; cursor: not-allowed; }
