/* =============================================================
   Margin — marginjournal.app
   Inherits RAJ Studios Natural Futurism palette (see
   /Users/rameezashraf/margin/raj-visual-identity.md) with one
   exception: the hero is fixed-dark because Margin's chassis is
   itself a dark frosted-glass case. The rest of the page returns
   to the warm earth palette.

   Sister file: ~/rajstudios-site/styles.css (full RAJ Studios
   palette + time-of-day system). Time-of-day toggle deferred to
   stage 2 of this site (see /Users/rameezashraf/margin/marketing.md §11).
   ============================================================= */

/* ----- Font ----- */
@font-face {
  font-family: 'Inter';
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  src: url('fonts/InterVariable.woff2') format('woff2-variations');
}

/* ----- Reset (minimal) ----- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
img, video { max-width: 100%; height: auto; display: block; }
button { font: inherit; cursor: pointer; background: none; border: 0; }
input { font: inherit; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============= PALETTE — natural futurism =============
   Mirror of rajstudios-site palette. Earth tones AND
   geological cools. Every color is something that appears
   in a soil core, a stone, a leaf, or water.
*/
:root {
  /* Warm earth */
  --concrete:    #F2ECE0;
  --sand:        #E8DCC8;
  --ochre:       #C89968;
  --rust:        #A66B43;
  --clay:        #8B4F35;
  --terracotta:  #B85742;
  --blush:       #DBA88E;

  /* Geological cools */
  --sage:        #A3A88A;
  --moss:        #6B7A5C;
  --dusty-teal:  #7A9B96;
  --slate:       #6E7480;

  /* Ink + light */
  --earth-base:  #2A1F18;
  --ink-soft:    #5C4A3D;
  --amber-glow:  #D9954B;
  --amber-soft:  #E8B878;

  /* Margin-specific: the dark chassis register.
     Not pure black — a warm-tinted near-black, the colour of
     the in-app dark chassis when seen through the frosted glass.
     Hero typography sits in white on top, so the chassis text
     tokens point at white — keeps the dark→white contrast clean
     across the seam. */
  --chassis-void:  #0A0805;
  --chassis-edge:  #14100A;   /* slightly lifted for subtle gradients */
  --chassis-ink:   #FFFFFF;
  --chassis-mute:  rgba(255, 255, 255, 0.62);
  --chassis-faint: rgba(255, 255, 255, 0.38);

  /* Margin rail accents — pulled from MarginKit TrackScope.accentHex
     (Solarized palette, identical across both Solarized themes).
     Used in the hero product-name "Margin" — one rail per letter,
     tying the website typography to the in-app rail colour language. */
  --rail-year:     #2AA198;   /* teal */
  --rail-quarter:  #268BD2;   /* blue */
  --rail-month:    #CB4B16;   /* orange */
  --rail-week:     #D33682;   /* pink */
  --rail-day:      #B58900;   /* yellow */

  /* =================================================================
     HERO THEME TOKENS — only the hero responds to the theme picker.
     Below-hero sections (manifesto / signup / footer) stay white in
     every theme per locked decision 2026-05-19. Default values here
     match the Dark theme; [data-theme="cream"] overrides them below.
     ================================================================= */
  --hero-bg:           var(--chassis-void);          /* the void around the chassis */
  --hero-text:         #FFFFFF;                       /* primary hero type */
  --hero-mute:         rgba(255, 255, 255, 0.62);     /* subhead */
  --hero-faint:        rgba(255, 255, 255, 0.38);     /* scroll cue, "when" caps */
  --hero-vignette-r:   var(--chassis-void);           /* right-half vignette colour */
  --hero-vignette-t:   rgba(10, 8, 5, 0.35);          /* top cinematic darkening */
  --hero-title-glow:   rgba(217, 149, 75, 0.18);      /* warm halo behind hero title */
  /* Bottom seam-blend uses a 7-stop gradient. Each theme defines its
     own ramp; defaults below match the Dark theme grey ramp. */
  --hero-seam-end:     #FFFFFF;                       /* terminal colour — always matches page bg */

  /* Page-level (non-hero) computed tokens.
     Margin's website default is WHITE (not the rajstudios-cream)
     — explicit brand decision: keep the dark→light contrast pure,
     no warm undertones below the hero. Cream is reserved as one
     of the optional Margin themes (light / cream / moss / dark /
     extra dark), not the default. */
  --bg:          #FFFFFF;
  --ink:         var(--earth-base);
  --surface:     #FFFFFF;
  --glow:        var(--amber-glow);
  --glow-soft:   var(--amber-soft);

  /* Typography scale (fluid clamps) */
  --hero-title-size:  clamp(2.75rem, 6.5vw, 5.5rem);
  --hero-sub-size:    clamp(1.0625rem, 1.4vw, 1.3125rem);
  --section-h-size:   clamp(1.75rem, 3.6vw, 2.625rem);
  --body-size:        clamp(1.0625rem, 1.15vw, 1.1875rem);
  --fine-size:        0.875rem;

  /* Rhythm */
  --section-pad-y:    clamp(5rem, 12vh, 10rem);
  --content-max:      640px;
}

/* ----- Base body / typography ----- */
html {
  /* Smooth scroll for the in-page anchor jumps. */
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  font-weight: 400;
  font-size: var(--body-size);
  line-height: 1.65;
  font-feature-settings: 'cv11', 'ss01', 'ss03';
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.link {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: currentColor;
  transition: text-decoration-color 200ms ease, color 200ms ease;
}
.link:hover {
  text-decoration-color: var(--amber-glow);
  color: var(--amber-glow);
}

/* =============================================================
   HERO — the dark chassis composition.

   Desktop layout: video pinned to the left edge (~60% width),
   fading to chassis-void on its right via a CSS mask. Foreground
   typography sits right-of-centre over the void.

   Mobile (< 768px): stack — video at top (full width, capped
   height), typography below. The chassis-left signature gives
   up to readability.
   ============================================================= */

.hero {
  position: relative;
  min-height: 100svh;
  /* No static chassis poster — the multiple flash-mitigation
     attempts (CSS bg on video element, CSS bg on .hero) all
     produced visible artifacts. Worst case is a brief dark void
     before the video loads (~200ms typical, fine since the hero
     IS dark). The video is the only chassis source of truth. */
  background:
    radial-gradient(ellipse at 30% 50%,
      color-mix(in srgb, var(--hero-bg) 85%, #FFFFFF 15%),
      var(--hero-bg) 70%),
    var(--hero-bg);
  color: var(--hero-text);
  overflow: hidden;
  isolation: isolate;
  display: grid;
  /* Smooth theme transitions — the void colour, vignette, type,
     and gradient all shift together when the picker fires. */
  transition: background 320ms ease, color 320ms ease;
}

.hero__chassis {
  position: absolute;
  inset: 0;
  width: 60%;
  height: 100%;
  object-fit: cover;
  object-position: left center;
  z-index: 0;
  pointer-events: none;
  /* Right-edge dissolve so the video doesn't end on a hard seam.
     The mask gradient transitions to transparent so the void shows
     through cleanly. Top + bottom stay opaque. */
  -webkit-mask-image:
    linear-gradient(to right, #000 35%, transparent 95%);
  mask-image:
    linear-gradient(to right, #000 35%, transparent 95%);
  /* Slight saturation lift to push the warm-amber tones in the
     chassis glow a touch. Visible only in motion.
     Theme-aware override below for the Cream theme inverts the
     video so dark fog reads as white mist on the cream backdrop. */
  filter: saturate(1.05) contrast(1.02);
  transition: filter 320ms ease;
}

/* Theme-gated hero videos. Native cream animation replaces the
   previous CSS-invert hack now that the in-app Cream theme is
   captured directly. Only the matching theme's <video> is
   displayed; the other stays out of the layout entirely. */
.hero__chassis--cream                       { display: none; }
[data-theme="cream"] .hero__chassis--dark   { display: none; }
[data-theme="cream"] .hero__chassis--cream  { display: block; }

/* Right-edge vignette so the video always dissolves into the void
   regardless of what's actually on its right edge. Top has a very
   light darkening for cinematic framing. Bottom is INTENTIONALLY
   not darkened here — the seam-blend gradient (.hero::after) owns
   the bottom transition entirely; any bottom-darkening here would
   fight it. */
.hero__vignette {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    /* right-half cover that hides any video bleed past the mask.
       Colour shifts per theme via --hero-vignette-r. */
    linear-gradient(
      to right,
      transparent 50%,
      var(--hero-vignette-r) 78%,
      var(--hero-vignette-r) 100%
    ),
    /* light top-only framing */
    linear-gradient(
      to bottom,
      var(--hero-vignette-t) 0%,
      transparent 14%
    );
  transition: background 320ms ease;
}

/* =============================================================
   THEME OVERRIDES — hero-only.
   `data-theme` attribute on <html>. JS picker writes the value;
   inline script in <head> reads localStorage before paint to
   prevent FOTC (flash of the wrong colour).

   Per locked decision 2026-05-19, themes do NOT change anything
   below the hero — manifesto / signup / footer stay white in
   every theme. The hero is the themed surface; the page below
   is the always-white substrate.
   ============================================================= */

/* Dark — current/default. Matches the :root token values exactly,
   but stated explicitly so a user toggling AWAY and back doesn't
   get a partial revert. */
[data-theme="dark"] {
  --hero-bg:           var(--chassis-void);
  --hero-text:         #FFFFFF;
  --hero-mute:         rgba(255, 255, 255, 0.62);
  --hero-faint:        rgba(255, 255, 255, 0.38);
  --hero-vignette-r:   var(--chassis-void);
  --hero-vignette-t:   rgba(10, 8, 5, 0.35);
  --hero-title-glow:   rgba(217, 149, 75, 0.18);
}

/* Cream — chassis sits in a warm room. Dark chassis pops against
   the cream backdrop; deep warm brown ink replaces white type.
   Title glow zeroed out — the cream IS the warmth; an amber glow
   would just dissolve into the backdrop. */
[data-theme="cream"] {
  --hero-bg:           #EFE4D0;
  --hero-text:         var(--earth-base);
  --hero-mute:         rgba(42, 31, 24, 0.66);
  --hero-faint:        rgba(42, 31, 24, 0.42);
  --hero-vignette-r:   #EFE4D0;
  --hero-vignette-t:   rgba(120, 85, 55, 0.10);
  --hero-title-glow:   transparent;
}

/* Per-theme bottom seam-blend gradients. Both terminate in pure
   white (page bg). Dark uses the dramatic grey ramp; Cream uses a
   shorter warm-to-white ramp since less contrast to bridge. */
[data-theme="dark"] .hero::after,
:root:not([data-theme]) .hero::after {
  background: linear-gradient(
    to bottom,
    rgba(10, 8, 5, 0)         0%,
    rgba(30, 30, 32, 0.45)   18%,
    rgba(72, 72, 75, 0.62)   38%,
    rgba(130, 130, 132, 0.75) 58%,
    rgba(190, 190, 192, 0.88) 75%,
    rgba(230, 230, 232, 0.96) 90%,
    #FFFFFF                  100%
  );
}

[data-theme="cream"] .hero::after {
  background: linear-gradient(
    to bottom,
    rgba(239, 228, 208, 0)    0%,    /* cream, transparent */
    rgba(241, 230, 212, 0.45) 25%,
    rgba(246, 240, 226, 0.72) 50%,
    rgba(252, 250, 244, 0.92) 80%,
    #FFFFFF                  100%
  );
}

/* =============================================================
   HERO BOTTOM SEAM-BLEND.
   Pure greyscale ramp from chassis-void up to the cream page bg.
   Deliberately monochrome — no warm chromatic bridging — so the
   transition reads as "light returning" rather than "ember to
   dawn." Final stop matches .manifesto bg exactly so the seam
   dissolves without any hard line.

   The last two stops carry a faint warm tint (around 96-98%)
   so the cool greys terminate into the warm cream without an
   obvious chromatic shift right at the very end. The eye reads
   this as "shades of grey" but the chromatic warming-up is what
   prevents the cream from punching through as an alien hue.

   Sits at z-index 3 (above video and right-vignette) so it owns
   the bottom of the frame. Affects only the bottom 38% of the
   hero; the chassis's upper portion (rails / Now indicator /
   magnifier) stays untouched.
   ============================================================= */
.hero::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 38%;
  pointer-events: none;
  z-index: 3;
  /* `background` is set per-theme via [data-theme="..."] blocks
     above. This rule only owns the structural geometry. */
  transition: background 320ms ease;
}

.hero__content {
  position: relative;
  z-index: 2;
  align-self: center;
  justify-self: end;
  max-width: 36rem;
  padding: 2rem clamp(2rem, 6vw, 6rem) 2rem 2rem;
  text-align: left;
}

.hero__title {
  margin: 0 0 1.25rem;
  font-size: var(--hero-title-size);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -0.035em;
  color: var(--hero-text);
  /* Soft warm glow behind the type — the "hidden light" register
     from the visual identity. Imperceptible at small sizes,
     subtle warmth at hero scale. Glow color shifts per theme. */
  text-shadow: 0 1px 60px var(--hero-title-glow);
  transition: color 320ms ease, text-shadow 320ms ease;
}

/* Product name — each letter tinted with the in-app rail accent
   colour. Reads as "Journal in the [rainbow Margin]." and ties the
   website's typography to the five-track-rail visual language of
   the product. Per-letter spans are aria-hidden; the
   visually-hidden Margin label inside is what screen readers see,
   so it reads as one word, not letter by letter. */
.hero__title-product {
  /* Slightly tighter tracking on the product name so the colored
     letters read as one word, not as a row of beads. */
  letter-spacing: -0.04em;
  /* Each letter still inherits the per-letter color shadow from
     its own glow — without resetting text-shadow here we'd pick up
     the warm amber from .hero__title and mute the rail tints. */
  text-shadow: none;
}
/* Letter mapping: violet LEADS (reserved for a hypothetical Decade
   rail to the left of Year), all real rail colors cascade right.
   M=violet, a=Year teal, r=Quarter blue, g=Month orange,
   i=Week pink, n=Day yellow. See chat 2026-05-19 — pre-emptive
   layout for a possible 10-year scope in the minimap. */
.hero__title-product .m-y { color: #6C71C4;             } /* M — Solarized violet (Decade slot) */
.hero__title-product .m-q { color: var(--rail-year);    } /* a — Year teal */
.hero__title-product .m-m { color: var(--rail-quarter); } /* r — Quarter blue */
.hero__title-product .m-w { color: var(--rail-month);   } /* g — Month orange */
.hero__title-product .m-d { color: var(--rail-week);    } /* i — Week pink */
.hero__title-product .m-n { color: var(--rail-day);     } /* n — Day yellow */

.hero__sub {
  margin: 0 0 1rem;
  font-size: var(--hero-sub-size);
  line-height: 1.4;
  color: var(--hero-text);
  font-weight: 500;
  letter-spacing: -0.01em;
  transition: color 320ms ease;
}

.hero__explainer {
  margin: 0 0 2rem;
  max-width: 32rem;
  font-size: calc(var(--hero-sub-size) * 0.78);
  line-height: 1.55;
  color: var(--hero-mute);
  font-weight: 400;
  letter-spacing: -0.005em;
  transition: color 320ms ease;
}

.hero__when {
  margin: 0;
  font-size: 0.95rem;
  color: var(--hero-faint);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 1rem 1.5rem;
  transition: color 320ms ease;
}

.hero__when-status {
  letter-spacing: 0.02em;
  text-transform: uppercase;
  font-size: 0.78rem;
  font-weight: 500;
}

.hero__cta {
  color: var(--amber-soft);
  text-decoration: none;
  font-weight: 500;
  font-size: 0.95rem;
  letter-spacing: -0.005em;
  border-bottom: 1px solid rgba(232, 184, 120, 0.4);
  padding-bottom: 2px;
  transition: color 200ms ease, border-color 200ms ease;
}
.hero__cta:hover {
  color: var(--amber-glow);
  border-bottom-color: var(--amber-glow);
}

.hero__scroll-cue {
  position: absolute;
  z-index: 4;                 /* above the seam-blend overlay */
  bottom: 2rem;
  left: 50%;
  transform: translateX(-50%);
  /* Sits inside the warm-cream end of the seam-blend, so colour
     reads against light bg now, not the void. */
  color: rgba(42, 31, 24, 0.45);
  text-decoration: none;
  font-size: 1.25rem;
  line-height: 1;
  width: 2.5rem;
  height: 2.5rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  transition: color 200ms ease, transform 200ms ease;
  animation: scroll-cue-pulse 2.4s ease-in-out infinite;
}
.hero__scroll-cue:hover { color: var(--clay); }
.hero__scroll-cue:hover {
  color: var(--amber-glow);
  animation-play-state: paused;
}

@keyframes scroll-cue-pulse {
  0%, 100% { transform: translate(-50%, 0); opacity: 0.55; }
  50%      { transform: translate(-50%, 6px); opacity: 1; }
}

/* Reduced-motion: cut the bounce + autoplay-rely on poster image. */
@media (prefers-reduced-motion: reduce) {
  .hero__scroll-cue { animation: none; }
  .hero__chassis { display: none; }
  /* Poster image as static fallback via background. */
  .hero {
    background:
      url('assets/hero-chassis.jpg') left center / 60% 100% no-repeat,
      radial-gradient(ellipse at 30% 50%, var(--chassis-edge), var(--chassis-void) 70%),
      var(--chassis-void);
  }
}

/* Mobile stack — chassis becomes a banner at the top, type below. */
@media (max-width: 767px) {
  .hero {
    grid-template-rows: 50vh 1fr;
    min-height: 100svh;
  }
  .hero__chassis {
    position: relative;
    width: 100%;
    height: 100%;
    object-position: left top;
    -webkit-mask-image:
      linear-gradient(to bottom, #000 60%, transparent 100%);
    mask-image:
      linear-gradient(to bottom, #000 60%, transparent 100%);
  }
  /* Theme-aware bottom-of-chassis vignette. Previously hardcoded
     `var(--chassis-void)` (always dark) which broke the cream
     theme — chassis was fading into dark instead of cream below
     the fold. `--hero-vignette-r` is the same value (#0A0805) in
     dark, but switches to the cream tint (#EFE4D0) in cream, so
     chassis dissolves into the matching backdrop in both. */
  .hero__vignette {
    background:
      linear-gradient(
        to bottom,
        transparent 30%,
        var(--hero-vignette-r) 65%
      );
  }
  /* Shrink the bottom seam-blend on mobile from 38% → 14% of the
     hero. On desktop the seam-blend has room to gradiate gently
     because the content sits in the upper half — but on mobile
     the content fills the bottom half, so a 38% wash paints
     directly over the typography. Reducing to 14% keeps the
     graceful transition into the manifesto section but no longer
     reaches the text. */
  .hero::after {
    height: 14%;
  }
  /* Raise content above the seam-blend (z-index: 3) so the
     gradient never washes the typography even at the lower edge
     where they overlap slightly. */
  .hero__content {
    z-index: 4;
    justify-self: stretch;
    align-self: start;
    padding: 1rem 1.5rem 4rem;
    text-align: left;
  }
  .hero__scroll-cue { bottom: 1.25rem; }
}

/* =============================================================
   MANIFESTO — single-column, generous whitespace.
   Hard-cut from the dark hero into the warm cream of the page.
   The contrast is deliberate: dark chassis → bright paper. Same
   relationship as the product (dark chassis holds themed paper).
   ============================================================= */

.manifesto {
  padding: var(--section-pad-y) 1.5rem;
  background: var(--bg);
  color: var(--ink);
}

.manifesto__inner {
  max-width: var(--content-max);
  margin: 0 auto;
}

.manifesto p {
  margin: 0 0 1.5rem;
  font-size: clamp(1.125rem, 1.4vw, 1.375rem);
  line-height: 1.65;
  letter-spacing: -0.005em;
}

.manifesto p:last-child {
  margin-bottom: 0;
}

.manifesto em {
  font-style: italic;
  color: var(--ink-soft);
}

/* =============================================================
   SIGNUP — the conversion event. Form posts to Ghost magic-link.
   Single email field + button, matched rajstudios-site pattern.
   ============================================================= */

.signup {
  padding: var(--section-pad-y) 1.5rem;
  background: var(--bg);
  color: var(--ink);
}

.signup__inner {
  max-width: var(--content-max);
  margin: 0 auto;
  text-align: left;
}

.signup__heading {
  margin: 0 0 0.75rem;
  font-size: var(--section-h-size);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.025em;
}

.signup__sub {
  margin: 0 0 2rem;
  color: var(--ink-soft);
  font-size: 1.0625rem;
  line-height: 1.55;
}

.signup__form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1rem;
}

.signup__form input[type="email"] {
  flex: 1 1 18rem;
  min-width: 0;
  padding: 0.875rem 1rem;
  font-size: 1rem;
  color: var(--ink);
  background: #FFFFFF;
  border: 1px solid rgba(42, 31, 24, 0.22);
  border-radius: 6px;
  transition: border-color 200ms ease, box-shadow 200ms ease;
}

.signup__form input[type="email"]::placeholder {
  color: rgba(42, 31, 24, 0.45);
}

.signup__form input[type="email"]:focus {
  outline: none;
  border-color: var(--amber-glow);
  box-shadow: 0 0 0 3px rgba(217, 149, 75, 0.22);
}

.signup__form button {
  padding: 0.875rem 1.5rem;
  font-size: 1rem;
  font-weight: 500;
  color: #FFFFFF;
  background: var(--earth-base);
  border-radius: 6px;
  transition: background 200ms ease, transform 80ms ease;
  letter-spacing: -0.005em;
}

.signup__form button:hover {
  background: var(--clay);
}

.signup__form button:active {
  transform: translateY(1px);
}

.signup__status {
  margin: 0;
  min-height: 1.5rem;
  color: var(--ink-soft);
  font-size: 0.9375rem;
  line-height: 1.4;
}

/* =============================================================
   FOOTER — minimal. Margin links back to RAJ Studios.
   ============================================================= */

.footer {
  padding: 3rem 1.5rem 3.5rem;
  background: var(--bg);
  color: var(--ink-soft);
  border-top: 1px solid rgba(42, 31, 24, 0.08);
}

.footer__inner {
  max-width: var(--content-max);
  margin: 0 auto;
  display: grid;
  gap: 0.4rem;
}

.footer__product {
  margin: 0 0 0.5rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
}

.footer__by,
.footer__contact,
.footer__copyright {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.5;
}

.footer__copyright {
  margin-top: 1rem;
  font-size: 0.8125rem;
  color: rgba(92, 74, 61, 0.65);
}

/* =============================================================
   WORDMARK — floating top-left pill. Matches the theme picker's
   capsule chrome (same border, blur, background tokens) so the
   two corners read as a matched set. Reuses the six rail-accent
   letter colors from .hero__title-product so the wordmark is
   visually consistent with the H1 treatment in the hero.
   ============================================================= */
.wordmark {
  display: inline-flex;
  align-items: center;
  padding: 0.3125rem;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  background: rgba(20, 16, 10, 0.42);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  backdrop-filter: blur(14px) saturate(1.1);
  text-decoration: none;
  transition: background 180ms ease, border-color 180ms ease, transform 180ms ease;
}

.wordmark:hover {
  background: rgba(20, 16, 10, 0.55);
  border-color: rgba(255, 255, 255, 0.24);
}

.wordmark--floating {
  position: fixed;
  top: 1rem;
  left: 1rem;
  z-index: 50;          /* same stack as the theme picker */
}

/* Cream theme: invert the capsule chrome so it reads against the
   cream backdrop. Same treatment as .theme-picker in cream. */
[data-theme="cream"] .wordmark {
  background: rgba(255, 255, 255, 0.55);
  border-color: rgba(42, 31, 24, 0.18);
}
[data-theme="cream"] .wordmark:hover {
  background: rgba(255, 255, 255, 0.75);
  border-color: rgba(42, 31, 24, 0.28);
}

.wordmark__inner {
  padding: 0.5rem 1rem;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1;
}

/* Letter color mapping — must stay in sync with .hero__title-product
   so the corner wordmark and the hero H1 always agree. */
.wordmark__inner .m-y { color: #6C71C4;             } /* M — Solarized violet (Decade slot) */
.wordmark__inner .m-q { color: var(--rail-year);    } /* a — Year teal */
.wordmark__inner .m-m { color: var(--rail-quarter); } /* r — Quarter blue */
.wordmark__inner .m-w { color: var(--rail-month);   } /* g — Month orange */
.wordmark__inner .m-d { color: var(--rail-week);    } /* i — Week pink */
.wordmark__inner .m-n { color: var(--rail-day);     } /* n — Day yellow */

/* =============================================================
   THEME PICKER — floating top-right control. Matches the
   rajstudios.ca pattern (their TOD picker uses the same
   placement + pill shape). Sits above the hero with backdrop
   blur so it remains legible whether it's over the dark void
   or the cream backdrop. Hidden behind a translucent capsule
   so it never demands attention.
   ============================================================= */
.theme-picker {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.3125rem;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
  background: rgba(20, 16, 10, 0.42);
  -webkit-backdrop-filter: blur(14px) saturate(1.1);
  backdrop-filter: blur(14px) saturate(1.1);
  transition: background 320ms ease, border-color 320ms ease;
}

/* Floating placement variant — top-right on every viewport. */
.theme-picker--floating {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 50;          /* above hero seam-blend (z=3) and any overlays */
}

/* Cream theme: the picker capsule needs to invert its chrome so
   it remains visible against the cream backdrop in the top-right
   of the hero. Switches to dark-on-cream tokens. */
[data-theme="cream"] .theme-picker {
  background: rgba(255, 255, 255, 0.55);
  border-color: rgba(42, 31, 24, 0.18);
}

.theme-picker__option {
  font-size: 1rem;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.65);
  padding: 0.5rem 1rem;
  border-radius: 999px;
  line-height: 1;
  letter-spacing: -0.005em;
  transition: background 180ms ease, color 180ms ease;
}

.theme-picker__option:hover {
  color: #FFFFFF;
  background: rgba(255, 255, 255, 0.08);
}

.theme-picker__option[aria-pressed="true"] {
  color: #FFFFFF;
  background: rgba(255, 255, 255, 0.16);
}

/* Cream theme: invert button-chrome colors so they read against
   the cream-tinted capsule. */
[data-theme="cream"] .theme-picker__option              { color: var(--ink-soft); }
[data-theme="cream"] .theme-picker__option:hover        { color: var(--ink); background: rgba(42, 31, 24, 0.06); }
[data-theme="cream"] .theme-picker__option[aria-pressed="true"] {
  color: var(--ink);
  background: rgba(42, 31, 24, 0.10);
}

/* =============================================================
   HOVER PREVIEW — Concepts A and B.

   Both elements exist in the DOM; CSS gates visibility via the
   [data-hover-preview] attribute on <html>. They are hidden until
   the hero is scrolled past ([data-past-hero="true"]), since they
   re-engage Margin's chassis-at-edge visual language only AFTER
   the hero has already established that language explicitly.

   Proximity is a single --proximity CSS variable on :root (0..1),
   written by script.js on pointermove. 0 = cursor far from left
   edge or above hero; 1 = cursor flush to the left edge. All
   visual behaviour reads this one number, so the JS stays tiny.

   Suppressed in three cases:
     1. data-hover-preview="off"             (user opted out)
     2. viewport < 1024px                    (no real "hover" on touch)
     3. prefers-reduced-motion               (calm-by-default)
   ============================================================= */

:root {
  /* Cursor proximity to the left edge, 0..1. JS rewrites this on
     pointermove. Default 0 so the preview is invisible at first
     paint (and stays invisible if JS never runs). */
  --proximity: 0;
}

.hover-preview {
  position: fixed;
  left: 0;
  top: 0;
  bottom: 0;
  width: 0;                      /* doesn't itself occupy space */
  pointer-events: none;          /* never intercepts clicks */
  z-index: 40;                   /* below theme/hover toggles (z=50) */
  opacity: 0;                    /* hidden until activated */
  transition: opacity 240ms ease;
}

/* Activation: the chassis-UI tease is only active while the hero
   is on screen (data-in-hero="true"). Once the user scrolls past,
   the chassis language has already been established and re-
   revealing it further down the page is just noise. Cursor
   proximity drives the actual fade. */
html[data-in-hero="true"] .hover-preview--ui {
  opacity: 1;     /* wrapper stays at 1; the inner image carries the visual opacity */
}
html:not([data-in-hero="true"]) .hover-preview--ui {
  opacity: 0;
  pointer-events: none;
}

/* ----- Chassis UI tease: actual screenshot of the Margin app ----- */

.hover-preview--ui {
  /* Container is full-viewport so the image inside can size to
     viewport height. The image itself does the positioning. */
  width: auto;
  right: auto;
}

.hover-preview--ui .hover-preview__image {
  position: fixed;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  /* Size: scale image to viewport height, preserve aspect ratio.
     Image stays anchored to the left edge. Width auto-derives
     from the height + aspect ratio. */
  height: 95vh;
  width: auto;
  max-width: 40vw;     /* safety cap on extremely tall viewports */
  object-fit: contain;
  object-position: left center;
  /* THE core mechanic: invisible at rest (proximity = 0), fades
     up to a deliberate 50% ceiling at the left edge so the
     chassis always reads as a tease — never fully solid, even
     when the cursor is parked at x=0. */
  opacity: calc(0.0 + 0.50 * var(--proximity));
  /* Blur clears from 4px → 2px (half-cleared) at max proximity,
     so the chassis always retains some atmospheric softness.
     Pair with the 50% opacity cap to keep the effect ghostly. */
  filter: blur(calc(4px - 2px * var(--proximity)));
  /* Soft feather on all four edges so the image doesn't end in a
     hard rectangular boundary against the page. Two gradients
     intersected: right-edge fade + top/bottom fade. The
     intersection means a pixel is visible only where BOTH
     gradients say so, giving a clean rounded-vignette feel. */
  -webkit-mask-image:
    linear-gradient(
      to right,
      rgba(0, 0, 0, 1) 0%,
      rgba(0, 0, 0, 1) 70%,
      rgba(0, 0, 0, 0) 100%
    ),
    linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0) 0%,
      rgba(0, 0, 0, 1) 12%,
      rgba(0, 0, 0, 1) 88%,
      rgba(0, 0, 0, 0) 100%
    );
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(
      to right,
      rgba(0, 0, 0, 1) 0%,
      rgba(0, 0, 0, 1) 70%,
      rgba(0, 0, 0, 0) 100%
    ),
    linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0) 0%,
      rgba(0, 0, 0, 1) 12%,
      rgba(0, 0, 0, 1) 88%,
      rgba(0, 0, 0, 0) 100%
    );
          mask-composite: intersect;
  transition: opacity 320ms ease, filter 320ms ease;
  user-select: none;
  -webkit-user-drag: none;
}

/* Theme-gated chassis-ui swap. Only the matching theme's
   screenshot is displayed; the other stays out of the layout. */
.hover-preview__image--cream                       { display: none; }
[data-theme="cream"] .hover-preview__image--dark   { display: none; }
[data-theme="cream"] .hover-preview__image--cream  { display: block; }

/* ----- Affordance hint ("← sneak peek") -----
   Horizontal orientation so the arrow points the correct
   direction at the left edge. Resting: visible. Approaching:
   fades out as the chassis takes over visual focus. */

.hover-preview__hint {
  position: fixed;
  left: 22px;
  top: 50%;
  /* Reset button defaults so the element reads as a text label,
     not a browser-chrome button. */
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  font-family: inherit;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--chassis-mute);
  white-space: nowrap;
  cursor: pointer;
  /* Resting: clearly visible (65%) so visitors notice it.
     As cursor approaches, fades to 0 — chassis takes over. */
  opacity: calc(0.65 - 0.65 * var(--proximity));
  transition: opacity 280ms ease;
  /* Gentle horizontal bob to draw the eye toward the left edge. */
  animation: hint-bob 2.4s ease-in-out infinite;
  /* Desktop: hint is decorative only; cursor proximity reveals
     the chassis, so the button doesn't need to be clickable.
     Mobile rules below re-enable pointer-events. */
  pointer-events: none;
}

@keyframes hint-bob {
  0%, 100% { transform: translate(0, -50%); }
  50%      { transform: translate(-4px, -50%); }
}

/* Cream theme: hint over a cream chassis — switch to ink token. */
[data-theme="cream"] .hover-preview__hint {
  color: var(--ink-soft);
}

/* ----- Suppression rules ----- */

/* User opted out. */
html[data-hover-preview="off"] .hover-preview {
  display: none;
}

/* Mobile / narrow viewports: no cursor proximity, so the sneak
   peek runs on a tap-to-toggle model instead. The hint pill at
   the left edge becomes a real tap target; tapping it flips the
   `--proximity` CSS variable (set by JS) between 0 and 1, which
   the chassis image's existing opacity calc picks up unchanged.
   Layout: chassis overlays the hero content at ~50% opacity when
   revealed (same ceiling as desktop). No reflow, no layout shift. */
@media (max-width: 1023px) {
  /* Promote the hint from a passive label into a real touch
     target. Larger font + padding for the 44pt minimum touch
     area, a capsule background so it reads as a button, and
     pointer-events back on so taps land. */
  .hover-preview__hint {
    left: 0;
    font-size: 0.75rem;
    padding: 0.625rem 0.875rem 0.625rem 1rem;
    background: rgba(20, 16, 10, 0.55);
    -webkit-backdrop-filter: blur(14px) saturate(1.1);
    backdrop-filter: blur(14px) saturate(1.1);
    border: 1px solid rgba(255, 255, 255, 0.16);
    border-left: 0;
    border-radius: 0 999px 999px 0;
    color: rgba(255, 255, 255, 0.9);
    pointer-events: auto;
    /* Always visible on mobile — the user needs to find the tap
       target. The desktop proximity-fade behaviour is bypassed. */
    opacity: 0.9;
  }
  /* Cream theme: invert the pill chrome so it reads against the
     cream backdrop. */
  [data-theme="cream"] .hover-preview__hint {
    background: rgba(255, 255, 255, 0.7);
    border-color: rgba(42, 31, 24, 0.18);
    color: var(--ink-soft);
  }
  /* When the chassis is revealed (data-peek-revealed="true" on
     <html>, set by JS on tap), swap the hint label affordance —
     the same button now indicates "tap to dismiss". */
  html[data-peek-revealed="true"] .hover-preview__hint {
    opacity: 0.5;
  }
}

/* Calm-by-default: no animated edge bait if the user signaled
   they want reduced motion. */
@media (prefers-reduced-motion: reduce) {
  .hover-preview { display: none; }
}

/* =============================================================
   STAGE 2 SECTION SCAFFOLDS — pre-baked classes so the additive
   reveal needs zero CSS restructuring. Uncomment + style further
   when those sections light up.
   =============================================================

   .features         {  ...  }
   .themes           {  ...  }
   .pricing          {  ...  }
   .trust            {  ...  }
   .compare          {  ...  }
*/

/* =============================================================
   Print: not really intended for print, but be civilized about it.
   ============================================================= */
@media print {
  .hero { min-height: auto; padding: 2rem 0; background: white; color: black; }
  .hero__chassis, .hero__vignette, .hero__scroll-cue { display: none; }
  .hero__content { justify-self: start; padding: 0; }
  .hero__title, .hero__sub, .hero__explainer, .hero__when { color: black; }
  .signup, .footer { background: white; color: black; }
}
