/* ---------------------------------------------------------------------------
   Cinematic hero section — ported from the 21st.dev "cinematic-landing-hero"
   (React + Tailwind + shadcn) to vanilla CSS, recoloured to HYREN:
   black ground, brand red #FF2233, Anton display type.
   GSAP class hooks (.text-track, .main-card, .phone-widget …) are preserved so
   the animation timeline ports across unchanged.
--------------------------------------------------------------------------- */

/* woff2 first: 12 KB vs the 161 KB raw TTF — same glyphs for this site's English
   uppercase display type. The TTF stays as the format fallback; any browser new
   enough to run this page (Chromium 79+) takes the woff2. Preloaded in index.html
   so the headline paints in Anton on first render instead of after a swap. */
@font-face {
  font-family: 'Anton';
  src: url('../vendor/fonts/Anton-latin.woff2') format('woff2'),
       url('../vendor/fonts/Anton.ttf') format('truetype');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
       U+02DC, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
  font-display: swap;
}

:root {
  --red: #FF2233;
  --red-deep: #7A0F18;
  --ink: #08080A;
  --fg: #F5F5F7;
  --muted: rgba(245, 245, 247, 0.55);
}

#cine {
  position: relative;
  z-index: 5;                       /* between the CRT canvas (z1) and the hands canvas (z10) */
  /* 100% not 100vw: for a fixed element 100vw INCLUDES a classic desktop scrollbar, so
     the whole cinematic layer sat ~8-17px right of the CRT and hands it overlays.
     svh not vh: on mobile, vh is the LARGE viewport (URL bar hidden), so with the bar
     showing the stage was taller than the visible area and the type centred low. */
  width: 100%;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;          /* naked — the live CRT + hands stay in view */
  color: var(--fg);
  perspective: 1500px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.gsap-reveal { visibility: hidden; }

/* ---- display type: brutalist. OUTSIDE the card = solid brand red.
   INSIDE the card = solid black. No gradients, no soft glows. ---- */
.text-3d-matte,                       /* hero line 1  (outside) */
.text-red-matte,                      /* hero line 2  (outside) */
.text-silver-matte {                  /* CTA heading  (outside) */
  color: var(--red);
  -webkit-text-fill-color: var(--red);
  text-shadow: 0 3px 0 rgba(0,0,0,0.55), 0 0 26px rgba(0,0,0,0.75);  /* legible over the mosaic */
}
.text-card-silver-matte {             /* wordmark     (inside → black) */
  color: #000;
  -webkit-text-fill-color: #000;
  text-shadow: none;
}
.display {
  font-family: 'Anton', 'Helvetica Neue', Impact, sans-serif;
  font-weight: 400;
  letter-spacing: -0.035em;           /* tight, like the reference */
  text-transform: uppercase;
}

/* ---- hero text / CTA layers ---- */
.hero-text-wrapper, .cta-wrapper {
  position: absolute; z-index: 10; width: 100%; padding: 0 1rem;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; will-change: transform;
}
/* huge, tightly-tracked, near-touching lines — the reference's "DAMN." scale */
.hero-text-wrapper h1 { line-height: 0.82; text-transform: uppercase; }
/* 0.82 is tighter than Anton's own ascender+descender, which is exactly the look —
   but it only works while each headline is ONE line. Below ~520px both headlines wrap
   to 3-4 lines and the wrapped lines collide into each other. Give wrapping room back
   on narrow screens only; nothing at or above 520px changes. */
@media (max-width: 520px) {
  .hero-text-wrapper h1 { line-height: 0.95; }
  .cta-wrapper h2 { line-height: 0.95; }
  /* Both headlines wrap here, so the 0.02em set for two single lines leaves the
     comma of "RACE," sitting on top of "NOT JUST THE". Separate the blocks by a
     real gap once they are multi-line; above 520px nothing changes. */
  .text-track { margin-bottom: 0.16em; }
}
.text-track { font-size: clamp(3rem, 10.5vw, 9.5rem); margin-bottom: 0.02em; }
.text-days  { font-size: clamp(3rem, 10.5vw, 9.5rem); }
.cta-wrapper { pointer-events: auto; }
.cta-wrapper h2 {
  font-size: clamp(2.8rem, 9vw, 8rem); margin-bottom: 1.1rem; text-transform: uppercase; line-height: 0.84;
}
.cta-wrapper p {
  color: var(--red); font-size: clamp(1rem, 1.4vw, 1.2rem); font-weight: 600;
  line-height: 1.6; max-width: 36rem; margin: 0 auto 2.6rem;
  text-transform: uppercase; letter-spacing: 0.02em;
  text-shadow: 0 2px 10px rgba(0,0,0,0.85);            /* legible over the live mosaic */
}
.cta-actions { display: flex; flex-direction: column; align-items: center; gap: 1.1rem; }
@media (min-width: 640px) { .cta-actions { flex-direction: row; } }

/* SHORT viewports (a phone held landscape is ~390px tall). Every display size above
   is driven by vw alone, so a wide-but-short screen renders type sized for a desktop
   into a third of the height and the closing block runs off the top. Below this
   height, size the display type by the height instead. No effect on any viewport
   taller than 540px, so the desktop reference is untouched. */
@media (max-height: 540px) {
  .text-track, .text-days { font-size: clamp(1.9rem, 9vh, 4.2rem); }
  .cta-wrapper h2 { font-size: clamp(1.8rem, 8.5vh, 3.6rem); margin-bottom: 0.6rem; }
  .cta-wrapper p { font-size: 0.85rem; line-height: 1.45; max-width: 30rem; margin-bottom: 1.2rem; }
  .btn-modern-light, .btn-modern-dark { padding: 0.6rem 1.1rem; gap: 0.5rem; }
  .btn-modern-light svg, .btn-modern-dark svg { width: 1.4rem; height: 1.4rem; }
  .btn-main { font-size: 1rem; }
}

/* ---- tactile store buttons ---- */
/* outside the card → solid brutalist red / black. Flat, hard edges. */
.btn-modern-light, .btn-modern-dark {
  display: flex; align-items: center; justify-content: center; gap: 0.75rem;
  padding: 0.95rem 1.8rem; border-radius: 3px; text-decoration: none;
  transition: transform 0.18s ease, background 0.18s ease;
  border: 0; font: inherit; cursor: pointer;
}
.btn-modern-light {                       /* primary: solid red, black type */
  background: var(--red); color: #000;
  box-shadow: 0 14px 30px -8px rgba(0,0,0,0.8);
}
.btn-modern-light:hover  { transform: translateY(-3px); }
.btn-modern-light:active { transform: translateY(1px); }
.btn-modern-dark {                        /* secondary: solid black, red type */
  background: #000; color: var(--red);
  box-shadow: 0 14px 30px -8px rgba(0,0,0,0.8), inset 0 0 0 2px var(--red);
}
.btn-modern-dark:hover  { transform: translateY(-3px); background: #0d0d0f; }
.btn-modern-dark:active { transform: translateY(1px); }
.btn-modern-light svg, .btn-modern-dark svg { width: 1.9rem; height: 1.9rem; flex: none; }
.btn-sub { font-size: 0.62rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; opacity: 0.6; }
.btn-main { font-size: 1.2rem; font-weight: 700; line-height: 1; letter-spacing: -0.01em; }
.btn-txt { text-align: left; }

/* ---- the red hero card ---- */
.card-layer {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 20; display: flex;
  align-items: center; justify-content: center; pointer-events: none; perspective: 1500px;
}
/* fixed-size panel between the hands — FLAT solid brand red, no gradient */
.main-card {
  position: relative; overflow: hidden; pointer-events: auto;
  display: flex; align-items: center; justify-content: center;
  width: min(88vw, 480px); height: min(72vh, 560px); border-radius: 4px;
  background: var(--red);
  box-shadow: 0 40px 100px -20px rgba(0,0,0,0.9), 0 20px 40px -20px rgba(0,0,0,0.75);
  border: none;
}
@media (min-width: 768px) { .main-card { width: min(46vw, 560px); height: min(76vh, 640px); } }

}
.card-sheen { display: none; }        /* no soft gloss — keep the red flat */

/* compact vertical stack: brand on top, phone centre, copy below */
.card-grid {
  position: relative; width: 100%; height: 100%; margin: 0 auto;
  padding: 1.4rem 1.2rem 1.2rem; z-index: 10;
  display: flex; flex-direction: column; align-items: center; justify-content: space-between;
}

/* everything sitting ON the red card is BLACK */
/* wordmark bleeds to the card edges (cancels the grid's 1.2rem side padding) */
.card-right-text {
  order: 1; display: block; z-index: 20;
  width: calc(100% + 2.4rem); margin: 0 -1.2rem;
}
/* viewBox is cropped to the cap-height ink so there's no dead space above/below;
   overflow:visible guards against any clipping if the metrics differ slightly */
.wordmark { display: block; width: 100%; height: auto; overflow: visible; }
.wordmark text {
  font-family: 'Anton', Impact, sans-serif;
  font-size: 250px; fill: #000; dominant-baseline: alphabetic;
}
.card-left-text { order: 3; display: flex; flex-direction: column; justify-content: center; text-align: center; width: 100%; z-index: 20; padding: 0 0.6rem; }
.card-left-text h3 {
  color: #000; font-size: clamp(1.05rem, 1.7vw, 1.45rem); font-weight: 800;
  letter-spacing: -0.02em; margin-bottom: 0.35rem; line-height: 1.1; text-transform: uppercase;
}
/* Always shown. It used to be gated on viewport height, which meant the card's only
   piece of body copy silently vanished on phones — the card looked empty below the
   mockup. The gate existed because the copy had nowhere to go; that is no longer true
   now that .mockup-scroll-wrapper can actually shrink (min-height:0) and fitCard()
   scales the phone to whatever room is left, so the copy takes its space first. */
.card-left-text p {
  color: #000; font-size: clamp(0.78rem, 0.95vw, 0.9rem); font-weight: 600;
  line-height: 1.5; max-width: 24rem; margin: 0 auto;
}
/* on a very short stage drop to the headline alone — below this there is not enough
   card left for the mockup to survive the copy */
@media (max-height: 480px) { .card-left-text p { display: none; } }

/* ---- iPhone mockup ---- */
/* min-height:0 is load-bearing. A flex item's automatic minimum size resolves to its
   specified size, so `height:300px; flex:1 1 auto` could never shrink below 300px —
   on any short viewport the stack overflowed the card and, because .card-grid is
   space-between (which behaves as flex-start when free space is negative), 100% of
   the overflow left through the BOTTOM and ate the headline. */
.mockup-scroll-wrapper {
  order: 2; position: relative; width: 100%; height: 300px; z-index: 10; flex: 1 1 auto;
  min-height: 0;
  display: flex; align-items: center; justify-content: center; perspective: 1000px;
}
/* the scale is set by fitCard() in cinematic.js — a transform cannot be derived from a
   length in CSS, and the phone must scale to whatever height the card actually has.
   These two rules are the starting value and the no-JS fallback. */
.mockup-inner {
  position: relative; width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center; transform: scale(0.5);
}
@media (min-width: 768px)  { .mockup-inner { transform: scale(0.58); } }

.iphone-bezel {
  position: relative; flex: none; width: 280px; height: 580px; border-radius: 3rem;
  background-color: #111; display: flex; flex-direction: column;
  will-change: transform; transform-style: preserve-3d;
  box-shadow: inset 0 0 0 2px #52525B, inset 0 0 0 7px #000,
              0 40px 80px -15px rgba(0,0,0,0.9), 0 15px 25px -5px rgba(0,0,0,0.7);
}
.hardware-btn {
  position: absolute; z-index: 0; width: 3px;
  background: linear-gradient(90deg, #404040 0%, #171717 100%);
  box-shadow: -2px 0 5px rgba(0,0,0,0.8), inset -1px 0 1px rgba(255,255,255,0.15), inset 1px 0 2px rgba(0,0,0,0.8);
}
.hw-l { left: -3px; border-radius: 3px 0 0 3px; }
.hw-r { right: -3px; border-radius: 0 3px 3px 0; transform: scaleX(-1); }

.phone-screen {
  position: absolute; top: 7px; right: 7px; bottom: 7px; left: 7px; border-radius: 2.5rem; overflow: hidden;
  background: #0A0A0C; color: #fff; z-index: 10;
  box-shadow: inset 0 0 15px rgba(0,0,0,1);
}
.screen-glare {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 40; pointer-events: none;
  background: linear-gradient(110deg, rgba(255,255,255,0.08) 0%, rgba(255,255,255,0) 45%);
}
.dynamic-island {
  position: absolute; top: 5px; left: 50%; transform: translateX(-50%);
  width: 100px; height: 28px; border-radius: 999px; background: #000; z-index: 50;
  display: flex; align-items: center; justify-content: flex-end; padding-right: 0.75rem;
  box-shadow: inset 0 -1px 2px rgba(255,255,255,0.1);
}
.island-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--red); box-shadow: 0 0 8px rgba(255,34,51,0.9); }

.app-ui { position: relative; width: 100%; height: 100%; padding: 3rem 1.25rem 2rem; display: flex; flex-direction: column; }
.app-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem; }
.app-head .lbl { font-size: 0.6rem; color: rgba(255,255,255,0.45); text-transform: uppercase; letter-spacing: 0.14em; font-weight: 700; margin-bottom: 0.2rem; display: block; }
.app-head .val { font-size: 1.25rem; font-weight: 700; letter-spacing: -0.02em; }
.avatar { width: 2.25rem; height: 2.25rem; border-radius: 50%; background: rgba(255,255,255,0.06);
  display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.8rem;
  border: 1px solid rgba(255,255,255,0.12); }

.ring-wrap { position: relative; width: 11rem; height: 11rem; margin: 0 auto 2rem;
  display: flex; align-items: center; justify-content: center;
  filter: drop-shadow(0 15px 25px rgba(0,0,0,0.8)); }
.ring-wrap svg { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%; }
.progress-ring { transform: rotate(-90deg); transform-origin: center;
  stroke-dasharray: 402; stroke-dashoffset: 402; stroke-linecap: round; }
.ring-txt { position: relative; z-index: 10; display: flex; flex-direction: column; align-items: center; }
.counter-val { font-size: 2.4rem; font-weight: 800; letter-spacing: -0.04em; line-height: 1; }
.ring-lbl { font-size: 0.5rem; color: rgba(255,255,255,0.5); text-transform: uppercase; letter-spacing: 0.12em; font-weight: 700; margin-top: 0.3rem; }

.widgets { display: flex; flex-direction: column; gap: 0.75rem; }
.widget-depth {
  border-radius: 1rem; padding: 0.75rem; display: flex; align-items: center;
  background: linear-gradient(180deg, rgba(255,255,255,0.04) 0%, rgba(255,255,255,0.01) 100%);
  box-shadow: 0 10px 20px rgba(0,0,0,0.3), inset 0 1px 1px rgba(255,255,255,0.05), inset 0 -1px 1px rgba(0,0,0,0.5);
  border: 1px solid rgba(255,255,255,0.04);
}
.widget-icon { width: 2.5rem; height: 2.5rem; border-radius: 0.75rem; margin-right: 0.75rem; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, rgba(255,34,51,0.22), rgba(255,34,51,0.05));
  border: 1px solid rgba(255,34,51,0.28); }
.widget-icon svg { width: 1rem; height: 1rem; color: var(--red); }
.widget-icon.alt { background: linear-gradient(135deg, rgba(255,255,255,0.14), rgba(255,255,255,0.03)); border-color: rgba(255,255,255,0.18); }
.widget-icon.alt svg { color: #fff; }
.bar { border-radius: 999px; box-shadow: inset 0 1px 2px rgba(0,0,0,0.4); }
.bar-a { height: 8px; width: 5rem; background: rgba(255,255,255,0.85); margin-bottom: 0.5rem; }
.bar-b { height: 6px; width: 3rem; background: rgba(255,255,255,0.3); }
.home-ind { position: absolute; bottom: 0.5rem; left: 50%; transform: translateX(-50%);
  width: 120px; height: 4px; border-radius: 999px; background: rgba(255,255,255,0.22); }

/* ---- floating glass badges ---- */
/* solid black chips on the red card — no glass, no blur */
.floating-ui-badge {
  position: absolute; z-index: 30; display: flex; align-items: center; gap: 0.9rem;
  padding: 0.85rem 1rem; border-radius: 3px;
  background: #000;
  box-shadow: 0 25px 50px -12px rgba(0,0,0,0.85);
}
/* Hug the phone so they stay inside the compact card. These live in the UNSCALED
   coordinate space of .mockup-inner, so the offset has to shrink along with the
   mockup scale or they land outside the card and get cut off by its overflow:hidden.
   fitCard() in cinematic.js keeps --badge-out at the largest value that still fits;
   300px (the tuned desktop value) is the cap and the fallback. */
.badge-a { top: 30px; left: calc(50% - var(--badge-out, 300px)); }
.badge-b { bottom: 46px; right: calc(50% - var(--badge-out, 300px)); }
.badge-ico { width: 2.25rem; height: 2.25rem; border-radius: 2px; flex: none;
  display: flex; align-items: center; justify-content: center; font-size: 1.05rem;
  background: var(--red); }
.badge-ico.neutral { background: var(--red); }
/* Black glyph on the red chip — the same black-on-red the hero card runs on.
   Replaces the emoji pair (🔥/⚡): a flame reads as a streak badge, and HYREN
   deliberately has no streaks (they punish rest and back-off days). */
.badge-ico svg { width: 1.15rem; height: 1.15rem; color: #000; }
.badge-t { color: var(--red); font-size: 0.78rem; font-weight: 800; letter-spacing: 0.01em; text-transform: uppercase; }
.badge-s { color: rgba(255,255,255,0.55); font-size: 0.66rem; font-weight: 600; }

/* SHORT VIEWPORTS — landscape phones and any window under ~560px tall.
   .main-card is a fixed-height box with overflow:hidden, so once the viewport is
   shorter than the stack inside it (wordmark + phone mockup + copy) the bottom is
   simply cut. Measured by test/test_layout.py: 105-124px lost at 667x375, 844x390
   and 932x430, and 107px at 390x420. fitCard() in cinematic.js already scales the
   mockup to its wrapper, so giving the card more of the screen and tightening the
   padding lets the whole stack fit rather than cropping it.
   NOTE: this block MUST stay at the end of the file. .mockup-scroll-wrapper is
   redefined further up at equal specificity, and CSS source order decides — a
   first attempt placed this block above that rule and the display:none silently
   did nothing. */
/* NARROW PORTRAIT — 320-480px wide. Taller than the 560px rule below, so it was
   not covered, and the card's stack still overran its box by 7-20px (measured at
   320x568, 360x640, 375x667). Buying the padding back is enough; fitCard() then
   rescales the mockup into the space. */
@media (max-width: 480px) {
  .card-grid { padding: 1rem 1rem 0.85rem; }
}

@media (max-height: 560px) {
  .main-card { height: min(94vh, 560px); }
  .card-grid { padding: 0.6rem 0.9rem 0.7rem; }
  /* fitCard() scales the mockup correctly (measured 97px at 844x390) — the problem
     is POSITION, not size: the flex column overflows, so the wrapper is laid out
     starting at the card's bottom edge and everything below it is cut. At this
     height a 97px phone render carries no information anyway, so drop it and let
     the wordmark and copy have the card. */
  .mockup-scroll-wrapper { display: none; }
  .card-left-text h3 { font-size: 1rem; margin-bottom: .3rem; }
  .card-left-text p { font-size: .78rem; line-height: 1.35; }
  .floating-badge { display: none; }
