/* ═══════════════════════════════════════════════════════════════════════
   Hound.css — everything specific to the GitHound page.

   Loads LAST, after Dark.css, and that is deliberate: it overrides shared
   geometry (the windows group, the mobile hero's spacing), the page colours
   in BOTH schemes, and adds its own dark block at the end. Nothing in here
   is used by the myPod page.

   Every number is traced from Eddy's mockup at 1440 wide (732px image,
   ×1.967) or from the app's Swift source — SearchBarView, ScoreView,
   GitHoundApp. Where a measurement and the source disagreed, the source won
   for the window and the mockup won for the page.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── The digits font ────────────────────────────────────────────────────
   SF Rounded Semibold, subset to 0–9 (2 KB) — see CLAUDE.md for how it was
   made. ⚠️ This rule is what connects the family name to the file; without
   it every browser silently falls back and only Safari happens to still
   show a rounded face (via ui-rounded). Shipped once with the rule missing;
   Firefox showed plain SF and Chrome's console said "preloaded but never
   used". `font-display: block`: the file is tiny and preloaded, and a flash
   of square digits before it lands is worse than a blank 100ms.
   ───────────────────────────────────────────────────────────────────── */
@font-face{
  font-family: "SF Rounded Digits";
  src: url('/Assets/Fonts/SFRounded-Semibold-Digits.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: block;
  unicode-range: U+30-39;
}

:root{
  /* Every rounded face the system might have, in order of preference, for
     the moment the shipped file is unavailable: Safari's ui-rounded, the
     SF Pro / SF Compact Rounded families designers install, then Arial
     Rounded (macOS, and Windows with Office). Plain SF is the last resort. */
  --font-rounded: "SF Rounded Digits", ui-rounded, "SF Pro Rounded",
                  "SF Compact Rounded", "Arial Rounded MT Bold", var(--font);

  /* The page is pure white here, not myPod's #F5F5F7 — measured off the
     mockup. The footer steps down to #F2F2F2 the same way. */
  --page-bg:   #FFFFFF;
  --footer-bg: #F2F2F2;

  /* The windows group: the 640-wide app window at (0,0) and the signup card
     hanging off its lower right at (466, 87). Main.js reads the box size
     from .Windows itself, so these only need to be right here. */
  --group-w: 796px;
  --group-h: 446px;

  /* The Figma frame's corner radius; myPod's recede goes to 30. */
  --hero-radius-max: 20px;

  /* The app's score colours. The window replicates the app in its dark
     appearance (the wallpaper is near-black), so it uses the dark-scheme
     system colours; the big score in module 1 uses the greens drawn in the
     mockup, with the system orange/red beside them. */
  --hound-green:  #30D158;
  --score-green:  #01D200;
  --score-orange: #FF9500;
  --score-red:    #FF3B30;
}


/* ═══════════════════════════════════════════════════════════════════════
   The hero
   ═══════════════════════════════════════════════════════════════════════ */

/* The wallpaper. A soft blurred-stripe image, so the 1512px source holds up
   on a 2× display; it compresses to ~68 KB as WebP because of that softness.
   The flat colour behind it is the image's own black, for the moment before
   it arrives. */
.Wallpaper{
  background-color: #0A0A0C;
  background-image: url('/Assets/Images/Wallpaper-GitHound-v1.webp');
}

/* ── The glow and the stroke ────────────────────────────────────────────
   Two pseudo-elements on .Hero, one behind the desktop and one in front.
   Both are SIBLINGS of .Desktop — never ancestors — which is what makes it
   safe to give them a box-shadow and a mask: the glass inside the desktop
   only dies when a filter/mask/opacity lands on something ABOVE it in the
   tree. Both mirror the desktop's recede (same scale, same radius) so they
   hug its edge at every scroll position.

   The glow is deliberately heavier below than beside: the mockup reads
   ~34% red right under the desktop's bottom edge, fading out over ~240px,
   but only ~10% at the sides and nothing at all above. A downward-offset
   shadow gives exactly that shape.

   `overflow: visible` on .Hero is what lets the glow bleed into module 1,
   as drawn. Page.css clips the hero to stop stray shadows spilling; here
   the spill IS the design. Nothing else in the hero can overflow — the
   desktop scales down, never up.
   ───────────────────────────────────────────────────────────────────── */
.Hero{ overflow: visible; }

.Hero::before{
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  transform: scale(var(--hero-scale, 1));
  transform-origin: center center;
  border-radius: calc(var(--hero-radius, 0px) / var(--hero-scale, 1));
  box-shadow:
    0 64px 180px rgba(255,64,78,.50),
    0 0 70px rgba(255,64,78,.14);
}

/* The stroke, straight from the Figma inspector: 1px, outside, 50% opacity,
   a vertical gradient from DB404C at 0% alpha to FA8D95 at 100%. The
   gradient's top handle sits two thirds of the way down the frame, so the
   top of the ring is invisible and only the lower third fades in.

   Drawn as a ring: a padded box whose content area is masked OUT, leaving
   a 1px frame. The 1px is divided by the recede scale so it stays 1px on
   screen while the whole thing is scaled with the desktop. */
.Hero::after{
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  transform: scale(var(--hero-scale, 1));
  transform-origin: center center;
  margin: calc(-1px / var(--hero-scale, 1));
  padding: calc(1px / var(--hero-scale, 1));
  border-radius: calc((var(--hero-radius, 0px) + 1px) / var(--hero-scale, 1));
  background: linear-gradient(to bottom, rgba(219,64,76,0) 67%, rgba(250,141,149,1) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  opacity: .5;
}

/* ── Where the windows sit ──────────────────────────────────────────────
   The mockup centres the APP WINDOW on the screen, not the group — the
   signup card hangs off its lower right. .Windows is the whole group, so
   its centre is pushed right by half the overhang (796 − 640) / 2 = 78px,
   scaled with the group. Vertically the mockup sits low (data-anchor on
   .Windows, read by Main.js); the 66% is as low as it can go and still
   fit at 1440×900 without shrinking the window.
   ───────────────────────────────────────────────────────────────────── */
.Windows{
  left: calc(50% + 78px * var(--stage-scale, 1));
  top: 66%;
}
.Signup{
  left: 466px;
  top: 87px;
}


/* ═══════════════════════════════════════════════════════════════════════
   The GitHound window — ContentView in its "done" state
   ═══════════════════════════════════════════════════════════════════════ */

/* GitHoundApp: .frame(width: 640), .glassEffect in a continuous-corner
   RoundedRectangle(18), no title bar, floating. Over this wallpaper the
   glass reads as dark smoked glass: sampled at ~35–42% of the wallpaper's
   brightness behind it, with a hairline white rim and a 0.5px lighter edge
   on top. */
.Hound{
  position: absolute;
  top: 0; left: 0;
  width: 640px;
  border-radius: 18px;
  background: rgba(0,0,0,.6);
  -webkit-backdrop-filter: blur(30px) saturate(150%);
          backdrop-filter: blur(30px) saturate(150%);
  border: .5px solid rgba(255,255,255,.26);
  box-shadow:
    inset 0 .5px 0 rgba(255,255,255,.08),
    0 24px 70px rgba(0,0,0,.5),
    0 4px 16px rgba(0,0,0,.3);
  color: #fff;
  cursor: default;
  /* Dark appearance throughout: .secondary in dark macOS is white at 55%. */
  --secondary: rgba(255,255,255,.55);
}

/* SearchBarView: HStack(spacing: 12), .padding(.horizontal, 20), height 60. */
.Hound-bar{
  display: flex;
  align-items: center;
  gap: 12px;
  height: 60px;
  padding: 0 20px;
}
/* Image("GitHoundGlyph") 18×18, .primary — the 70% is inside the SVG. */
.Hound-glyph{ width: 18px; height: 18px; flex: none; color: #fff; }
/* TextField, .system(size: 20), frame(height: 28). */
.Hound-url{
  flex: 1 1 auto;
  min-width: 0;
  font-size: 20px;
  font-weight: 400;
  line-height: 28px;
  letter-spacing: 0;
  white-space: nowrap;
  overflow: hidden;
}
/* xmark.circle.fill at 16pt, clock.arrow.circlepath and gearshape at 14pt
   medium, all .secondary. Sized by each symbol's own box, matched on
   height. The clock gets the 16×16 frame the app gives it. */
.Hound-icon{ flex: none; color: var(--secondary); }
.Hound-icon--reset   { width: 16px;   height: 16px; }
.Hound-icon--history { width: 16px;   height: 14.5px; }
.Hound-icon--settings{ width: 15px;   height: 15px; }

/* Divider().opacity(0.2) — a hairline at about 10% white once the dark
   separator's own alpha is folded in. */
.Hound-divider{ height: 1px; background: rgba(255,255,255,.1); }

/* ScoreView: HStack(spacing: 16), .padding(.vertical, 14) .padding(.horizontal, 20). */
.Hound-score{
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 20px;
}
/* .system(size: 44, weight: .semibold, design: .rounded), monospacedDigit(). */
.Hound-number{
  font-family: var(--font-rounded);
  font-size: 44px;
  font-weight: 600;
  line-height: 1.19;
  font-variant-numeric: tabular-nums;
  color: var(--hound-green);
}
.Hound-verdict{
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.Hound-label{ font-size: 15px; font-weight: 600; line-height: 1.2; color: var(--hound-green); }
.Hound-sub  { font-size: 12px; font-weight: 400; line-height: 1.2; color: var(--secondary); }
/* chevron.down 13pt semibold, .secondary, at 0.5 opacity until hovered. */
.Hound-chevron{
  flex: none;
  margin-left: auto;
  width: 11.5px;
  height: 6.5px;
  color: var(--secondary);
  opacity: .5;
}


/* ═══════════════════════════════════════════════════════════════════════
   Module 1 — the score
   ═══════════════════════════════════════════════════════════════════════ */

/* Everything in this module is sized from the watermark disc, which is
   480px at 1440 and scales with the viewport below that. The mockup's
   positions, as fractions of the disc: a 280px SF Rounded Semibold number
   (its "87" measures 311×203 — SF Rounded's own 1.53 width-to-height) with
   its ink starting .717 in and .242 down, baseline at .66; a 44px label
   right-aligned 13px inside the number's right edge, its cap top 37px
   below the baseline. Box offsets below fold in the fonts' side bearings
   and line-box geometry (line-height 1: digit tops sit .15em down).

   ⚠️ Measure the GREEN, not "anything that isn't white": the hero's glow
   tints this whole region pink, and a near-white threshold reads the tint
   as ink and inflates the number by 40%. */
.Module--score{
  --disc: min(480px, 33.3vw);
  padding-bottom: 0;
}
/* Page.css gives the first module after the hero extra top padding; the
   mockup has exactly 102px between the hero's bottom edge and the disc. */
.Hero + .Module--score{ padding-top: 102px; }

.Module--score .Module-inner{
  grid-template-columns: calc(var(--disc) * 1.602) minmax(0, 1fr);
  gap: 0;
  align-items: center;
}

/* The composition is the disc plus the number overhanging its right side:
   1.45 discs wide in all. Sizing the box to that (rather than to the disc)
   is what lets it be centred as one unit on phones. */
.Score{
  position: relative;
  width: calc(var(--disc) * 1.45);
  height: var(--disc);
  margin-left: calc(var(--disc) * .05);
}
.Score-mark{
  position: absolute;
  top: 0; left: 0;
  width: var(--disc);
  height: var(--disc);
  display: block;
}
.Score-mark img{ width: 100%; height: 100%; }

/* The number is the anchor; the label hangs off its bottom-right corner
   and grows LEFTWARDS when a longer verdict comes round. The first version
   let "Review before using" push the digits 40px right.

   ⚠️ Geometry goes on the wrappers (.Score-numberBox / .Score-labelBox),
   never on .Score-number / .Score-label themselves: Torph sets its host to
   `display: inline-block; position: relative`, which turned an earlier
   `right:` on the label into a relative nudge and dropped it in flow beside
   the number. The hosts only carry type. */
.Score-value{
  position: absolute;
  left: calc(var(--disc) * .694);
  top: calc(var(--disc) * .154);
  white-space: nowrap;
  color: var(--score-color, var(--score-green));
  transition: color .6s ease;
}
.Score-value[data-verdict="clean"]  { --score-color: var(--score-green); }
.Score-value[data-verdict="caution"]{ --score-color: var(--score-orange); }
.Score-value[data-verdict="avoid"]  { --score-color: var(--score-red); }

/* The one thing on the site in a shipped font: SF Rounded Semibold, subset
   to the ten digits (2 KB). Tabular figures so 11 and 99 are the same width
   and the morph doesn't shuffle the label as it counts. */
.Score-numberBox{
  display: block;
  font-family: var(--font-rounded);
  font-size: calc(var(--disc) * .583);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.Score-labelBox{
  position: absolute;
  /* Tabular digits give the 7 a wide cell, so the number's box runs ~22px
     past its ink; this lands the label's right edge 13px inside the ink. */
  right: calc(var(--disc) * .09);
  top: calc(var(--disc) * (.583 - .021));
  font-size: calc(var(--disc) * .0917);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -.02em;
}
/* The label is Torph's host: inherit everything, add nothing. */
.Score-label{ font: inherit; letter-spacing: inherit; color: inherit; }

/* ── The odometer ───────────────────────────────────────────────────────
   Hound.js replaces the number's text with one column per digit. Each
   column is a 1em-tall window over a strip of 0–9 repeated; moving to a new
   digit always rolls FORWARD at least one full turn, so every digit visibly
   spins through the others on its way, and the columns finish at different
   times (the ones column last) like a real odometer. Tabular figures keep
   every column the same width, so the number's box never changes size.
   ───────────────────────────────────────────────────────────────────── */
.Score-number{
  display: inline-flex;
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
}
/* Apple-style rather than a hard-edged window (SwiftUI's numericText is
   the reference): digits fade out toward the top and bottom of their
   column instead of being sliced off, and blur while they move.

   Each row is 1.4em tall with the digit centred in it, and the column is
   one row tall, pulled back to a 1em layout box by -0.2em margins — so a
   neighbouring digit is never inside the window at rest, and the 22% fades
   at each end only ever touch digits in motion. A resting digit's ink sits
   at roughly 24–76% of the row, clear of both fades. */
.Odo-col{
  display: block;
  height: 1.4em;
  margin: -.2em 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 22%, #000 78%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 22%, #000 78%, transparent 100%);
}
.Odo-strip{
  display: block;
  transform: translateY(calc(var(--pos, 0) * -1.4em));
  transition: transform var(--odo-ms, 1200ms) cubic-bezier(.2, .85, .25, 1);
}
.Odo-strip.is-snapping{ transition: none; }
.Odo-strip span{
  display: block;
  height: 1.4em;
  line-height: 1.4;
}
/* Motion blur that peaks while the strip is moving fastest (early — the
   roll eases out) and clears as it settles. Hound.js restarts it per roll. */
.Odo-strip.is-rolling{ animation: Odo-blur var(--odo-ms, 1200ms) cubic-bezier(.2, .85, .25, 1); }
@keyframes Odo-blur{
  0%  { filter: blur(0); }
  15% { filter: blur(.045em); }
  55% { filter: blur(.02em); }
  100%{ filter: blur(0); }
}

/* Torph wraps each glyph in its own span while morphing; they must inherit
   the colour and never pick up a stray underline or spacing. */
.Score-number span,
.Score-label span{ color: inherit; }

/* The copy's centre sits 18px below the disc's in the mockup; a top margin
   inside a centred block moves the visible text by half of itself. */
.Module--score .Module-text{
  margin: 12px 0 0;
  padding-left: 0;
}

/* <h2> keeps the browser's own 0.83em top margin on this site (Base.css
   resets h1/p/ul but not h2, and myPod's layouts absorb it). The paddings
   in this file are measured to the headline's box, so it's zeroed here. */
.Module--score .Module-title,
.Module--scan .Module-title,
.Module--models .Module-title,
.Module--raycast .Module-title{ margin-top: 0; }


/* ═══════════════════════════════════════════════════════════════════════
   Module 2 — the expanded result, running off the right edge
   ═══════════════════════════════════════════════════════════════════════ */

/* The render has no transparent padding on its right side — the card is
   cut by the image's own edge — so the bleed is made by parking the image's
   right edge at the viewport's. Its width is a fraction of the viewport
   (884px at 1440) for that reason, and it starts 440px into the content
   box, past the copy's column. */
.Module--scan{
  padding-top: 210px;
  padding-bottom: 0;
}
.Module--scan .Module-inner{
  /* 387px of 1240 − 53px padding: the percentage is of the padded box. */
  grid-template-columns: 32.6% minmax(0, 1fr);
  gap: 0;
  padding-left: 4.3%;
  align-items: center;
}
/* The copy is centred on the CARD, not the render's box: the card sits in
   rows 135–715 of the 920-tall render, so its centre is 3.8% of the
   render's height above the box's centre. A bottom margin of twice that
   lifts the centred copy by exactly it, at every width (the render is
   61.4vw wide, so 30.4vw tall). The mockup had the headline hugging the
   card's top edge; Eddy asked for it lower once he saw it on a wide screen,
   where that gap grows with the card. */
.Module--scan .Module-text{
  margin-bottom: 2.3vw;
  padding-top: 0;
}
.Module-media--scan{
  max-width: none;
  overflow: visible;
}
.Module-media--scan img{
  width: 61.4vw;
  max-width: none;
  height: auto;
}


/* ═══════════════════════════════════════════════════════════════════════
   Module 3 — bring your own model
   ═══════════════════════════════════════════════════════════════════════ */
.Module--models{
  padding-top: 175px;
  padding-bottom: 0;
  overflow: hidden;              /* the marquee runs past both edges */
}
.Module--models .Module-title--center{ margin-bottom: 0; }

.Module-sub{
  margin: 42px auto 0;
  max-width: 38em;              /* one line at 1440, as drawn */
  text-align: center;
  font-size: 17px;
  line-height: 1.5;
  color: var(--ink-soft);
  letter-spacing: -.006em;
}

/* Logos are 150px on a 289px pitch at 1440 (measured), so the gap is 139. */
.Models{
  --logo: 150px;
  --logo-gap: 139px;
  margin-top: 73px;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  /* Logos fade in and out at the viewport's edges rather than being cut
     off. A mask here is safe: nothing inside the marquee uses
     backdrop-filter, and it's nowhere near the hero's glass. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
}
.Models-track{
  display: flex;
  width: max-content;
  animation: Models-scroll 60s linear infinite;
}
.Models-set{
  display: flex;
  gap: var(--logo-gap);
  padding-right: var(--logo-gap);     /* the gap between the two sets */
}
.Models-logo{
  display: block;
  width: var(--logo);
  height: var(--logo);
  flex: none;
}
.Models-logo img{ width: 100%; height: 100%; }
/* One full set's width: six logos and six gaps. When the track has moved
   that far the second set is exactly where the first began, so the jump
   back to 0 is invisible. */
@keyframes Models-scroll{
  to{ transform: translateX(calc(-6 * (var(--logo) + var(--logo-gap)))); }
}


/* ═══════════════════════════════════════════════════════════════════════
   Module 4 — Raycast
   ═══════════════════════════════════════════════════════════════════════ */
.Module--raycast{
  padding-top: 202px;
  padding-bottom: 71px;
}
/* The render is 2600×962 and fades to nothing from 41% down (y 394),
   reaching full transparency at y≈620 (alpha < 2) — the rest is empty
   canvas. The box is cropped at 640 so the caption can sit a fixed
   distance under the fade's true end. ⚠️ Not 566: that's where the fade
   drops below 60/255, and cropping there visibly chops the last of it. */
.Raycast{
  width: min(1325px, 92vw);
  margin: 0 auto;
  aspect-ratio: 2600 / 640;
  overflow: hidden;
}
.Raycast picture{ display: block; }
.Raycast img{ width: 100%; height: auto; }

/* 76px under the old 566 crop line, measured off the mockup; the box now
   runs 74 render-px further (2.6vw at the 92vw width), taken back here so
   the caption lands in the same place. */
.Module--raycast .Module-title--center{
  margin: calc(76px - 2.6vw) auto 0;
  max-width: none;
}


/* ═══════════════════════════════════════════════════════════════════════
   Footer
   ═══════════════════════════════════════════════════════════════════════ */
/* myPod's footer sits under an overhanging album scatter and pads for it.
   Nothing overhangs here, so this is the plain measured gap. */
.Footer{ padding-top: 106px; }
.Footer-signup{ max-width: 484px; }
.Footer-app{ font-weight: 700; color: var(--ink); margin-right: 2px; }
/* The idle button is drawn pale blue in the mockup rather than grey. */
.SignupForm--footer .SignupForm-button{
  background: #C6DCF0;
  color: #fff;
}
.SignupForm--footer.is-ready .SignupForm-button{ background: #0a84ff; }


/* ═══════════════════════════════════════════════════════════════════════
   Tablet: stack the two split modules, as Page.css does for myPod's
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 960px){
  /* ⚠️ minmax(0, 1fr), not 1fr. A bare 1fr won't shrink below its widest
     child, and the result card is 110–125vw wide on purpose — so the column,
     and the copy in it, grew to that width and ran off the screen. */
  .Module--score .Module-inner,
  .Module--scan .Module-inner{
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
    padding-left: 0;
  }
  /* The whole composition (1.45 discs wide) has to fit between the gutters. */
  .Module--score{ --disc: min(480px, calc((100vw - 2 * var(--gutter)) / 1.45)); }
  .Score{ margin: 0 auto; }
  .Module--score .Module-text,
  .Module--scan .Module-text{ padding-top: 0; margin-bottom: 0; }

  .Module--scan{ padding-top: 120px; }
  .Module-media--scan img{ width: 110vw; }

  .Module--models{ padding-top: 120px; }
  .Models{ --logo: 120px; --logo-gap: 100px; margin-top: 56px; }
  .Module--raycast{ padding-top: 140px; }
}


/* ═══════════════════════════════════════════════════════════════════════
   Phones — built to the mobile mockup at 390×844
   ═══════════════════════════════════════════════════════════════════════ */
@media (max-width: 768px){
  /* Square corners. (The mockup's rounded top was the phone frame it was
     drawn in, not part of the page.)

     ⚠️ The wallpaper is painted by .Mobile here, not .Hero. The beta tag
     and the field's text blend with plus-lighter, and a blend only sees
     what's inside its nearest stacking context — .Mobile is one (it has a
     z-index), so with the wallpaper on .Hero, outside it, the blend had
     nothing to brighten and quietly did nothing. .Hero keeps the same
     image underneath for the moment before .Mobile lays out. */
  .Hero,
  .Mobile{
    background: #0A0A0C url('/Assets/Images/Wallpaper-GitHound-v1.webp') center center / cover no-repeat;
  }

  /* The window: 1.535× life size, its left edge 78pt in, running off the
     right of the screen — centred vertically in the box myPod's window
     would fill. .MobileWindow keeps Responsive.css's height (myPod's box),
     which is what puts the name, field and rail exactly where myPod's are.
     142 is this window's unscaled height. */
  .Mobile{ --m-art-scale: 1.535; }
  .MobileWindow .Hound{
    left: 78px;
    top: calc((566px * var(--m-win-scale) - 142px * var(--m-art-scale)) / 2);
    transform: scale(var(--m-art-scale));
    transform-origin: 0 0;
  }

  /* ── Name, beta tag, field: white + plus-lighter ──────────────────────
     myPod's hero hard-codes pale blues sampled off ITS wallpaper; on this
     red they read as stickers. Here the tag and the field's text are white
     at partial alpha, blended plus-lighter so they pick up the wallpaper's
     colour the way macOS vibrancy does.

     Two stacking changes make that possible (with the wallpaper move
     above): .MobileIntro loses its z-index, because a stacking context
     isolates its children and would hide the wallpaper from the blend;
     and the rail drops to z-index -1 inside .Mobile instead, which keeps
     the field painting — and taking taps — above the rail's invisible
     headroom, the job .MobileIntro's z-index used to do. */
  .MobileIntro{ z-index: auto; }
  .AppRail{ z-index: -1; }

  .BetaTag{
    border-color: rgba(255,255,255,.5);
    mix-blend-mode: plus-lighter;
  }
  .BetaTag-icon,
  .BetaTag-platform{ color: rgba(255,255,255,.9); }
  .BetaTag-label   { color: rgba(255,255,255,.6); }

  /* ── The rotating platform ────────────────────────────────────────────
     Two [logo + word] units stacked in one grid cell. The visible one is
     .is-on; changing it sends the old unit up and out through a blur while
     the new one rises in from below — the same motion as the score's digits
     and SwiftUI's numericText. They swap as WHOLE units: an earlier version
     morphed letter by letter with Torph, and because "macOS" and "Raycast"
     share a few letters it looked like random letters shuffling.
     Hound.js sets the slot's width to the active unit's so the capsule
     eases between the two sizes, growing leftwards. The 3.6px gap before
     "Beta Coming Soon" is myPod's, moved from the word to the slot. */
  .BetaTag-swap{
    display: grid;
    align-items: center;
    justify-items: start;
    height: 100%;
    margin-right: 3.6px;
    transition: width .55s cubic-bezier(.4, 0, .2, 1);
  }
  .BetaTag-plat{
    grid-area: 1 / 1;
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
    opacity: 0;
    transform: translateY(55%);
    filter: blur(2.5px);
    transition:
      opacity   .5s cubic-bezier(.4, 0, .2, 1),
      transform .55s cubic-bezier(.3, 1.25, .5, 1),
      filter    .5s cubic-bezier(.4, 0, .2, 1);
  }
  .BetaTag-plat.is-on{
    opacity: 1;
    transform: none;
    filter: blur(0);
  }
  .BetaTag-plat.is-off{ transform: translateY(-55%); }
  .BetaTag-plat .BetaTag-platform{ margin-right: 0; }

  /* The field's dark fill, hairline and focus ring move to the wrapper,
     so the input itself carries only text and can blend: plus-lighter on
     a dark fill would add nothing and the fill would vanish, and on the
     blue ring it would turn magenta. 56 + two .5px borders = myPod's 57. */
  .SignupForm--mobile .SignupForm-field{
    border: .5px solid rgba(255,255,255,.22);
    border-radius: 10px;
    background: rgba(0,0,0,.2);
    transition: border-color .15s ease, box-shadow .15s ease;
  }
  .SignupForm--mobile .SignupForm-input,
  .SignupForm--mobile .SignupForm-input:hover,
  .SignupForm--mobile .SignupForm-input:focus,
  .SignupForm--mobile.is-ready .SignupForm-input:focus,
  .SignupForm--mobile.is-invalid .SignupForm-input{
    height: 56px;
    border: 0;
    border-radius: 10px;
    background: transparent;
    box-shadow: none;
  }
  .SignupForm--mobile .SignupForm-input{
    color: #fff;
    caret-color: #fff;           /* a blue caret would blend to magenta */
    mix-blend-mode: plus-lighter;
  }
  .SignupForm--mobile .SignupForm-input::placeholder{ color: rgba(255,255,255,.6); }
  .SignupForm--mobile .SignupForm-input:focus::placeholder{ color: rgba(255,255,255,.4); }

  /* The current-page dot: white, plus-lighter, drawn on the hero layer
     (see the markup) and placed by MobileHero.js. 4pt, as on myPod. */
  .AppRail-dot--free{
    top: 0;
    left: 0;
    margin: 0;
    background: rgba(255,255,255,.75);
    mix-blend-mode: plus-lighter;
    transform: translate(var(--dot-x, -99px), var(--dot-y, 0px));
    pointer-events: none;
  }

  .SignupForm--mobile .SignupForm-field:focus-within{
    border-color: #007BFF;
    box-shadow: 0 0 0 1.5px #007BFF;
  }
  .SignupForm--mobile.is-ready .SignupForm-field:focus-within{
    border-color: rgba(255,255,255,.22);
    box-shadow: none;
  }
  .SignupForm--mobile.is-invalid .SignupForm-field{
    border-color: #FF6B60;
    box-shadow: 0 0 0 1.5px #FF6B60;
  }

  /* Modules: no phone mockup exists for these, so they follow myPod's
     phone rules — stacked, text first, bleeds kept to one edge. */
  .Hero + .Module--score{ padding-top: 72px; }
  /* ⚠️ myPod's phone text inset (the module's gutter + 14px, 34px at 390)
     has to be restated here: the desktop rule above zeroes this copy's
     left padding to line it up beside the disc, and that rule is more
     specific than Page.css's phone padding, so it won on phones too. */
  .Module--score .Module-text{ padding-left: 14px; padding-right: 14px; }
  .Module--score{ --disc: calc((100vw - 48px) / 1.45); }
  .Module--scan{ padding-top: 72px; }
  .Module-media--scan img{ width: 125vw; }
  .Module--models{ padding-top: 88px; }
  .Module-sub{ margin-top: 20px; font-size: 16px; padding: 0 14px; }
  .Models{ --logo: 96px; --logo-gap: 72px; margin-top: 44px; }
  .Module--raycast{ padding-top: 96px; padding-bottom: 56px; }
  /* Centred on the SCREEN, not the content box: -2vw alone left it off by
     the module's gutter (20px at 390), pushing it right. The render's
     canvas is padded symmetrically (187 / 188px of 2600), so centring the
     box centres the window too. */
  .Raycast{ width: 104vw; margin-left: calc(50% - 52vw); }
  .Module--raycast .Module-title--center{ margin-top: calc(48px - 3vw); }
  .Footer{ padding-top: 88px; }
}


/* ═══════════════════════════════════════════════════════════════════════
   Reduced motion
   ═══════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce){
  .BetaTag-swap,
  .BetaTag-plat{ transition: none; }
  .Models-track{ animation: none; }
  .Score-value{ transition: none; }
  .Odo-strip{ transition: none; }
  .Odo-strip.is-rolling{ animation: none; }
}


/* ═══════════════════════════════════════════════════════════════════════
   Dark — colours only, same rules as Dark.css
   ═══════════════════════════════════════════════════════════════════════ */
@media (prefers-color-scheme: dark){
  :root{
    --page-bg:   #171717;          /* as asked — not myPod's near-black */
    --footer-bg: #202020;          /* a step lighter, mirroring light mode */
  }
  .Footer-app{ color: var(--ink); }
  .SignupForm--footer .SignupForm-button{
    background: rgba(198,220,240,.28);
    color: rgba(255,255,255,.7);
  }
  .SignupForm--footer.is-ready .SignupForm-button{ background: #0a84ff; color: #fff; }
}
