/* =============================================================
   RAJ Studios — site styles
   Visual identity: Natural futurism (locked 2026-05-16).
   Spec: /Users/rameezashraf/margin/raj-visual-identity.md
   Site spec: /Users/rameezashraf/margin/raj-studios-site.md
   ============================================================= */

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

/* =============================================================
   @property registrations — the key to smooth mode transitions.

   Without these, CSS custom properties are treated as opaque
   strings and CANNOT smoothly interpolate during transitions.
   That's what caused the strata gradient and the fade overlay
   to "snap" while the body bg and text color faded — same
   variable, different rendering paths, different animatability.

   Registering each as <color> tells the browser these values
   are colors and can be interpolated frame-by-frame, even when
   used inside gradients and color-mix expressions.
   ============================================================= */

@property --bg          { syntax: '<color>'; inherits: true; initial-value: #F2ECE0; }
@property --ink         { syntax: '<color>'; inherits: true; initial-value: #2A1F18; }
@property --surface     { syntax: '<color>'; inherits: true; initial-value: #E8DCC8; }
@property --glow        { syntax: '<color>'; inherits: true; initial-value: #D9954B; }
@property --glow-soft   { syntax: '<color>'; inherits: true; initial-value: #E8B878; }
@property --hero-light  { syntax: '<color>'; inherits: true; initial-value: rgba(255, 220, 160, 0.32); }
@property --veil-color  { syntax: '<color>'; inherits: true; initial-value: rgba(255, 248, 235, 0.18); }
@property --forest-glow { syntax: '<color>'; inherits: true; initial-value: rgba(163, 168, 138, 0.18); }
@property --forest-deep { syntax: '<color>'; inherits: true; initial-value: rgba(107, 122, 92, 0.14); }

@property --strata-1 { syntax: '<color>'; inherits: true; initial-value: #F6F0E4; }
@property --strata-2 { syntax: '<color>'; inherits: true; initial-value: #DBA88E; }
@property --strata-3 { syntax: '<color>'; inherits: true; initial-value: #A3A88A; }
@property --strata-4 { syntax: '<color>'; inherits: true; initial-value: #DBA88E; }
@property --strata-5 { syntax: '<color>'; inherits: true; initial-value: #7A9B96; }
@property --strata-6 { syntax: '<color>'; inherits: true; initial-value: #B85742; }
@property --strata-7 { syntax: '<color>'; inherits: true; initial-value: #C89968; }
@property --strata-8 { syntax: '<color>'; inherits: true; initial-value: #A66B43; }
@property --strata-9 { syntax: '<color>'; inherits: true; initial-value: #8B4F35; }

/* ----- Reset (minimal) ----- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
img { 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 =============
   Earth tones AND geological cools. Every color is something
   that appears in a soil core, a stone, a leaf, or water.
   No synthetic colors. See raj-visual-identity.md.
*/
: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;
  --clay-blue:   #93A4A8;

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

  /* --------- Computed mode tokens (overridden per [data-tod]) --------- */
  --bg:          var(--concrete);
  --ink:         var(--earth-base);
  --surface:     var(--sand);
  --glow:        var(--amber-glow);
  --glow-soft:   var(--amber-soft);

  /* Rammed earth strata — 7 stops, top to bottom (light → dark).
     Default = Day mode: brightest, most chromatic. */
  --strata-1:    #F6F0E4;   /* near-cream sky band */
  --strata-2:    var(--blush);
  --strata-3:    var(--sage);
  --strata-4:    var(--blush);
  --strata-5:    var(--dusty-teal);
  --strata-6:    var(--terracotta);
  --strata-7:    var(--ochre);
  --strata-8:    var(--rust);
  --strata-9:    var(--clay);

  /* Hero hidden-light tint */
  --hero-light:  rgba(255, 220, 160, 0.32);

  /* Veil over hero (frosted-glass finish) */
  --veil-color:  rgba(255, 248, 235, 0.18);

  /* Layout + motion */
  --measure:        38rem;
  --gutter:         1.5rem;
  --section-gap:    clamp(5rem, 12vh, 9rem);

  --type-body: 1.0625rem;
  --type-fine: 0.875rem;
  --type-h2:   1.5rem;
  --type-h3:   1.25rem;
  --type-hero: clamp(2.75rem, 7vw, 5rem);

  --ease:      cubic-bezier(0.4, 0, 0.2, 1);
  --tod-fade:  1800ms;  /* Generous duration so the cross-hue
                           interpolation (e.g. Dawn peach → Day sage)
                           has enough on-screen time for the eye to
                           read it as gradual evolution rather than a
                           snap. Trade-off: button click feels less
                           instant. If too laggy, drop back to
                           1400ms or switch --ease to a curve that's
                           faster at start, slower at end (e.g.
                           cubic-bezier(0.2, 0.6, 0.4, 1)). */
}

/* --------- DAWN: soft awakening (pure warm — no green) --------- */
[data-tod="dawn"] {
  --bg:        #F9F1E5;
  --ink:       #3A2A1F;
  --surface:   #F0E4CE;
  --glow:      #F0BA8A;
  --glow-soft: #F8D4B0;
  --hero-light: rgba(255, 200, 180, 0.30);
  --veil-color: rgba(255, 240, 220, 0.22);

  /* Pure warm — pink/peach/cream/blush — the wall in sunrise light.
     Positions 2, 3, 5 are very subtly desaturated/cooled (still read
     as warm cream in isolation) to give the Dawn→Day transition a
     shorter hue distance at the positions where Day has sage/moss/teal.
     The cool undertones are at the threshold of perception — Dawn
     should still look beautiful, the transition just becomes less of
     a hue leap. (See "Path B" decision 2026-05-16.) */
  --strata-1:  #F9F1E5;          /* pale sky cream */
  --strata-2:  #EFDAC8;          /* pale blush (slightly less peachy, very subtly cooler) */
  --strata-3:  #E2CDBA;          /* warm pale cream (less yellow than before) */
  --strata-4:  #E8C9B2;          /* soft peach (anchor — unchanged) */
  --strata-5:  #D6B59E;          /* dusty cream (slightly less rose, very faint cool hint) */
  --strata-6:  #D9A988;          /* warm blush (anchor — unchanged) */
  --strata-7:  #C39676;          /* dusty terracotta-light */
  --strata-8:  #B07F5E;          /* warm soft ochre */
  --strata-9:  #95684A;          /* warm soft clay */
}

/* --------- DAY: bright, alive, most chromatic, moss prominent --------- */
[data-tod="day"] {
  --bg:        #F8F2E6;
  --ink:       #221812;
  --surface:   #ECE0CA;
  --glow:      #D9954B;
  --glow-soft: #E8B878;
  --hero-light: rgba(255, 230, 180, 0.38);
  --veil-color: rgba(255, 250, 240, 0.16);

  /* INVERTED (2026-05-16 experiment) — blues at top, greens at bottom,
     reds unchanged. Lost clay at position 9; replaced with moss. */
  --strata-1:  #F8F2E6;          /* cream sky */
  --strata-2:  #93A4A8;          /* clay-blue (top blue — was sage) */
  --strata-3:  #7A9B96;          /* dusty teal (top blue — was moss) */
  --strata-4:  #DBA88E;          /* blush */
  --strata-5:  #A3A88A;          /* sage (middle green — was dusty teal) */
  --strata-6:  #B85742;          /* terracotta */
  --strata-7:  #C89968;          /* ochre */
  --strata-8:  #A66B43;          /* rust */
  --strata-9:  #6B7A5C;          /* moss (bottom green — was clay) */
}

/* --------- DUSK: sunset sky — pinks, mauves, plums over deep earth ---------
   Reworked: previous version was "fire" (heavy terracotta + rust). Real
   sunsets are sky colors — dusty rose, mauve, plum, lavender — fading to
   deep wine and warm shadow at the bottom. Forest greens stay as the
   "trees at twilight" anchor; the warm bands shift purple/mauve. */
[data-tod="dusk"] {
  --bg:        #E5D0BA;
  --ink:       #1F140E;
  --surface:   #D6BFA0;
  --glow:      #C26A28;
  --glow-soft: #DC9555;
  --hero-light: rgba(255, 170, 130, 0.38);
  --veil-color: rgba(245, 200, 180, 0.14);

  /* INVERTED (2026-05-16 experiment) */
  --strata-1:  #E8D5B8;          /* honey sky */
  --strata-2:  #6E7480;          /* slate (top blue — was dusty olive) */
  --strata-3:  #5C7878;          /* deep dusty teal (top blue — was deep moss) */
  --strata-4:  #B47A85;          /* dusty rose-mauve */
  --strata-5:  #7A8078;          /* dusty olive (middle — was deep teal) */
  --strata-6:  #803A55;          /* deep plum */
  --strata-7:  #7A5548;          /* mauve-brown */
  --strata-8:  #5A2E2A;          /* deep wine */
  --strata-9:  #4C5C46;          /* deep moss (bottom green — was deep clay) */
}

/* --------- NIGHT: mocha-dominant, wood-paneled room, hints of forest + wine ---------
   Predominantly warm dark mocha (the room itself). Two accent bands
   only: ONE muted forest green and ONE dark wine red. Everything else
   is the wood-and-earth-at-night register. Forest atmosphere at the
   viewport edges is what carries the "deep green outside" suggestion,
   not the wall itself. */
[data-tod="night"] {
  --bg:        #2A2017;
  --ink:       #F0E2C9;
  --surface:   #3A2C20;
  --glow:      #F0B266;
  --glow-soft: #C68850;
  --hero-light: rgba(240, 178, 102, 0.35);
  --veil-color: rgba(30, 22, 14, 0.25);

  /* INVERTED (2026-05-16 experiment) — introduced slate at top
     (Night had no blue previously), pushed forest band to bottom. */
  --strata-1:  #3A2C20;          /* near-black wood */
  --strata-2:  #2D3940;          /* slate dark (top blue — NEW) */
  --strata-3:  #4A3525;          /* deep mocha (displaced from 2) */
  --strata-4:  #5C3A28;          /* warm deep mocha */
  --strata-5:  #5A2D3A;          /* wine-purple */
  --strata-6:  #3F2D1F;          /* mocha wood */
  --strata-7:  #2E2330;          /* deep aubergine */
  --strata-8:  #2A1E13;          /* midnight clay */
  --strata-9:  #3A4A3F;          /* muted forest (bottom green — was black-earth) */
}

/* ============= PAGE ============= */
html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: var(--type-body);
  font-weight: 400;
  line-height: 1.7;
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'cv11', 'ss01', 'ss03';
  transition: background var(--tod-fade) var(--ease), color var(--tod-fade) var(--ease);
}

/* Polished-concrete grain — extremely subtle.
   Pure SVG noise embedded as background-image. Always on.
   Refined, not rough. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 100;
  opacity: 0.04;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.16  0 0 0 0 0.12  0 0 0 0 0.09  0 0 0 0.9 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

/* Ambient forest layer — green as ENVIRONMENT, not surface.
   Soft moss/sage radial gradients at the four viewport edges,
   suggesting trees / plant life just outside the window.
   The reference is the FIVESOLIDOS jungle house: neutral
   architecture + ambient green from the surroundings.
   Per-mode tinting via --forest-glow and --forest-deep. */
:root {
  --forest-glow: rgba(163, 168, 138, 0.18);
  --forest-deep: rgba(107, 122, 92, 0.14);
}

/* DAWN — no green; warm peachy ambient instead.
   Green at dawn made the wall read as "spring-fresh cheap"
   against the pale peach palette. Dawn is now pure warm-soft. */
[data-tod="dawn"] {
  --forest-glow: rgba(245, 215, 195, 0.10);   /* very pale peach */
  --forest-deep: rgba(232, 200, 180, 0.08);   /* near-nothing */
}

/* DAY — sage + moss, strongest natural green presence */
[data-tod="day"] {
  --forest-glow: rgba(163, 168, 138, 0.22);
  --forest-deep: rgba(107, 122, 92, 0.16);
}

/* DUSK — moderate moss, golden-hour green tilt */
[data-tod="dusk"] {
  --forest-glow: rgba(107, 122, 92, 0.20);
  --forest-deep: rgba(76, 92, 70, 0.16);
}

/* NIGHT — quiet hint of deep forest at the edges.
   Pulled way back: the room is mocha, the forest is just a SUGGESTION
   at the periphery (like dark trees barely visible through the window). */
[data-tod="night"] {
  --forest-glow: rgba(54, 78, 68, 0.14);      /* muted forest, half opacity */
  --forest-deep: rgba(42, 55, 47, 0.16);      /* deeper but still quiet */
}

html::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background:
    radial-gradient(ellipse 40% 35% at -5% 5%,
      var(--forest-glow) 0%, transparent 60%),
    radial-gradient(ellipse 35% 30% at 105% 8%,
      var(--forest-deep) 0%, transparent 60%),
    radial-gradient(ellipse 45% 40% at -8% 105%,
      var(--forest-deep) 0%, transparent 55%),
    radial-gradient(ellipse 40% 35% at 108% 100%,
      var(--forest-glow) 0%, transparent 60%);
  transition: background var(--tod-fade) var(--ease);
}

/* ============= SECTIONS (general) ============= */
section, footer {
  padding: var(--section-gap) var(--gutter);
  max-width: var(--measure);
  margin: 0 auto;
  position: relative;
}

.section__heading {
  font-size: var(--type-h2);
  font-weight: 600;
  margin: 0 0 1.75rem;
  letter-spacing: -0.02em;
  color: var(--ink);
}

p { margin: 0 0 1.25rem; }
p:last-child { margin-bottom: 0; }

a.link {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  text-decoration-color: rgba(166, 107, 67, 0.5);  /* rust at 50% */
  transition: text-decoration-color 0.3s var(--ease), color 0.3s var(--ease);
}
a.link:hover {
  text-decoration-color: var(--glow);
  color: var(--clay);
}
[data-tod="night"] a.link:hover { color: var(--glow); }

/* ============= STRATA DIVIDER ============= */
/* Echoes the rammed earth horizontal layering between sections.
   Three thin lines that pick up the per-mode strata palette
   (including the moss/sage bands), with a soft moss vignette
   behind them — the "garden between rooms." */
.strata-divider {
  max-width: 100%;
  margin: 0 auto;
  padding: 1.5rem var(--gutter);
  display: flex;
  flex-direction: column;
  gap: 7px;
  align-items: center;
  position: relative;
  isolation: isolate;
}
.strata-divider::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(ellipse 60% 100% at 50% 50%,
    color-mix(in srgb, var(--moss) 14%, transparent) 0%,
    transparent 70%);
  transition: background var(--tod-fade) var(--ease);
}
[data-tod="dawn"] .strata-divider::before {
  /* No moss vignette at dawn — would clash with the pure-warm palette. */
  background: radial-gradient(ellipse 60% 100% at 50% 50%,
    color-mix(in srgb, var(--blush) 10%, transparent) 0%,
    transparent 70%);
}
[data-tod="dusk"] .strata-divider::before {
  background: radial-gradient(ellipse 60% 100% at 50% 50%,
    color-mix(in srgb, var(--moss) 18%, transparent) 0%,
    transparent 70%);
}
[data-tod="night"] .strata-divider::before {
  /* Quiet warm-mocha vignette with the faintest forest tint —
     matches the new mocha-dominant night palette. */
  background: radial-gradient(ellipse 60% 100% at 50% 50%,
    rgba(58, 70, 60, 0.14) 0%,
    transparent 70%);
}
.strata-divider span {
  display: block;
  height: 1px;
  width: min(var(--measure), 100%);
  opacity: 0.55;
  transition: background var(--tod-fade) var(--ease);
}
.strata-divider span:nth-child(1) { background: var(--strata-2); opacity: 0.50; }   /* sage/moss band */
.strata-divider span:nth-child(2) { background: var(--strata-5); opacity: 0.55; }
.strata-divider span:nth-child(3) { background: var(--strata-7); opacity: 0.45; }

/* ============= HERO — rammed earth wall ============= */
.hero {
  min-height: 100vh;
  max-width: none;
  padding: var(--gutter);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

/* The rammed earth wall, layered + blurred + frosted.
   Lots of layers, each with soft falloff, so the strata BLEND.
   This is the brand statement in one element. */
.hero__earth {
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(ellipse 70% 50% at 65% 22%,
      var(--hero-light) 0%,
      transparent 60%),
    radial-gradient(ellipse 50% 35% at 18% 75%,
      var(--hero-light) 0%,
      transparent 70%),
    radial-gradient(ellipse 120% 30% at 50% 0%,
      var(--glow-soft) 0%,
      transparent 50%),
    /* Stop positions: original (red bands NOT compressed). The green
       at the bottom is expanded by giving --strata-9 a HOLD — it
       anchors at 94% and stays solid through 100%, creating a real
       6% band of solid moss/green/etc at the bottom instead of just
       a fading edge that never quite resolves. Adjust the 94% earlier
       (e.g. 90%) for more green, later (e.g. 97%) for less. */
    linear-gradient(178deg,
      var(--strata-1)  0%,
      var(--strata-2) 13%,
      var(--strata-3) 27%,
      var(--strata-4) 40%,
      var(--strata-5) 53%,
      var(--strata-6) 65%,
      var(--strata-7) 77%,
      var(--strata-8) 89%,
      var(--strata-9) 94%,
      var(--strata-9) 100%
    );
  transition: background var(--tod-fade) var(--ease);
}

/* Subtle horizontal-grain texture across the rammed earth.
   Suggests the compacted-layers feel of real rammed earth without
   ever being visibly stripey. Very low opacity. */
.hero__earth::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.10;
  mix-blend-mode: multiply;
  background-image:
    repeating-linear-gradient(
      178deg,
      transparent 0px,
      transparent 3px,
      rgba(50, 30, 20, 0.18) 3px,
      transparent 5px,
      transparent 9px
    );
  filter: blur(1.5px);
}

/* Frosted-glass veil over the rammed earth — softens everything,
   adds the "refined product" finish over the natural palette. */
.hero__veil {
  position: absolute;
  inset: 0;
  z-index: -1;
  backdrop-filter: blur(28px) saturate(1.05);
  -webkit-backdrop-filter: blur(28px) saturate(1.05);
  background: var(--veil-color);
  pointer-events: none;
  transition: background var(--tod-fade) var(--ease);
}

/* Hidden-perimeter glow at bottom corners (architectural lighting register) */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(ellipse 50% 35% at 0% 90%,
      rgba(217, 149, 75, 0.18) 0%, transparent 70%),
    radial-gradient(ellipse 50% 35% at 100% 90%,
      rgba(217, 149, 75, 0.18) 0%, transparent 70%);
  transition: background var(--tod-fade) var(--ease);
}
[data-tod="night"] .hero::before {
  background:
    radial-gradient(ellipse 50% 35% at 0% 90%,
      rgba(240, 178, 102, 0.28) 0%, transparent 70%),
    radial-gradient(ellipse 50% 35% at 100% 90%,
      rgba(240, 178, 102, 0.28) 0%, transparent 70%);
}

/* Hero bottom fade — dissolves the rammed earth into the page bg.
   IMPORTANT: uses solid background-color + a CSS mask for the fade
   SHAPE. The previous implementation used a linear-gradient with
   color-mix(var(--bg)) inside it — gradients-with-vars snap during
   transitions, causing a visible band exactly where the seam was.
   This approach lets the color animate as a smooth single-color
   transition while the mask handles the fade purely as opacity. */
.hero::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 36%;
  pointer-events: none;
  z-index: 0;
  background-color: var(--bg);
  mask: linear-gradient(180deg,
    transparent 0%,
    rgba(0, 0, 0, 0.25) 30%,
    rgba(0, 0, 0, 0.70) 60%,
    rgba(0, 0, 0, 1.00) 100%);
  -webkit-mask: linear-gradient(180deg,
    transparent 0%,
    rgba(0, 0, 0, 0.25) 30%,
    rgba(0, 0, 0, 0.70) 60%,
    rgba(0, 0, 0, 1.00) 100%);
  transition: background-color var(--tod-fade) var(--ease);
}

.hero__title {
  position: relative;
  z-index: 1;
  font-size: var(--type-hero);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.08;
  margin: 0 auto;
  /* Line break is forced via <br> in the markup: "Fewer things."
     over "Better reasons to keep them." Width is wide enough that
     the second line never wraps on its own. */
  max-width: 32ch;
  text-align: center;
  color: var(--ink);
  /* Soft contact-shadow with the wall behind it */
  text-shadow: 0 1px 0 rgba(255, 248, 235, 0.25);
  /* Word-by-word arrival */
  opacity: 0;
  animation: hero-arrive 1400ms var(--ease) 200ms forwards;
}

/* Hero content wrapper — stacks the headline + explainer as one
   centered block, mirroring the marginjournal.app hero (big title
   over a quieter sub-line). */
.hero__content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}

.hero__sub {
  margin: 0;
  /* Wide enough to hold the explainer on a single line on desktop;
     still wraps gracefully on narrow viewports. */
  max-width: 60ch;
  font-size: clamp(1.0625rem, 2vw, 1.5rem);
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: -0.01em;
  text-align: center;
  /* Theme-aware ink at 80% alpha (not the static --ink-soft brown,
     which read too faint/grey in Dusk). Tracks each time-of-day's
     ink so it stays a vibrant, readable softer-than-title tone in
     every palette. Alpha lives in the color so the opacity-based
     arrival animation can still settle at full strength. */
  color: color-mix(in srgb, var(--ink) 80%, transparent);
  /* Same gentle arrival as the title, a beat later. */
  opacity: 0;
  animation: hero-arrive 1400ms var(--ease) 450ms forwards;
}
[data-tod="night"] .hero__sub { color: color-mix(in srgb, var(--ink) 85%, transparent); }
[data-tod="night"] .hero__title {
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
}

@keyframes hero-arrive {
  from { opacity: 0; transform: translateY(8px); filter: blur(4px); }
  to   { opacity: 1; transform: translateY(0);   filter: blur(0);  }
}

.hero__scroll {
  position: absolute;
  bottom: 2.5rem;
  z-index: 1;
  color: var(--ink);
  opacity: 0.45;
  text-decoration: none;
  font-size: 1.25rem;
  animation: hero-scroll-pulse 2.6s ease-in-out infinite 2s;
}
@keyframes hero-scroll-pulse {
  0%, 100% { transform: translateY(0);   opacity: 0.35; }
  50%      { transform: translateY(6px); opacity: 0.7;  }
}

/* ============= MANIFESTO — polished concrete floor ============= */
.manifesto {
  position: relative;
}
/* Note: removed the manifesto::before amber-halo (was extending 3rem
   into the hero's bottom edge, creating a visible seam in Night mode
   where amber-on-dark read as a stripe). The hero's bottom fade now
   does all the seam-blending work alone. */

.manifesto p {
  line-height: 1.85;
  font-size: 1.0625rem;
}
.manifesto p strong { font-weight: 600; color: var(--clay); }
[data-tod="night"] .manifesto p strong { color: var(--amber-glow); }
.manifesto p em { font-style: italic; }
/* Bold + italic emphasis that stays in full ink (no clay tint that
   <strong> would add). Italic is inherited from the rule above. */
.manifesto p em.emph-ink { font-weight: 600; color: var(--ink); }
[data-tod="night"] .manifesto p em.emph-ink { color: var(--ink); }
/* Italic clause that matches the clay color of <strong>, so the
   bold lead and its italic continuation read as one tinted phrase. */
.manifesto p em.emph-clay { color: var(--clay); }
[data-tod="night"] .manifesto p em.emph-clay { color: var(--amber-glow); }

/* ============= WHO WE ARE ============= */
.who p { line-height: 1.8; }

/* ============= WHAT WE MAKE ============= */
.work .product {
  margin-top: 2rem;
  padding: 2.5rem;
  border-radius: 8px;
  background: linear-gradient(180deg,
    var(--surface) 0%,
    color-mix(in srgb, var(--surface) 70%, var(--sand) 30%) 100%);
  position: relative;
  overflow: hidden;
  transition: background var(--tod-fade) var(--ease);
}

/* Hidden perimeter glow inside the card */
.work .product::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 80% 30% at 50% 0%,
      rgba(217, 149, 75, 0.15), transparent 70%);
  pointer-events: none;
}

/* Margin preview — a miniature of the marginjournal.app hero.
   Always dark (the Margin chassis void) so it reads as a product
   window no matter the RAJ time-of-day palette around it. */
.product__preview {
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: 6px;
  margin-bottom: 2rem;
  position: relative;
  overflow: hidden;
  background: #0A0805;            /* Margin chassis void */
  display: flex;
  align-items: center;
}

/* The smoky chassis loop, pinned to the left edge and faded out
   toward the right so it dissolves into the void behind the
   wordmark — same treatment as the live Margin hero. */
.product__preview-chassis {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: auto;
  max-width: 58%;
  object-fit: cover;
  object-position: left center;
  -webkit-mask-image:
    linear-gradient(to right, #000 0%, #000 45%, transparent 92%);
  mask-image:
    linear-gradient(to right, #000 0%, #000 45%, transparent 92%);
}

.product__preview-content {
  position: relative;
  z-index: 1;
  margin-left: auto;
  width: 62%;
  padding-right: 7%;
  text-align: left;
}

.product__preview-title {
  margin: 0 0 0.4rem;
  font-size: clamp(1.1rem, 2.6vw, 1.7rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: #FFFFFF;
}

.product__preview-sub {
  margin: 0;
  font-size: clamp(0.78rem, 1.4vw, 1rem);
  font-weight: 400;
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.62);
}

/* Per-letter rail colors — must match marginjournal.app exactly.
   M violet, a teal, r blue, g orange, i pink, n yellow. */
.margin-wordmark { letter-spacing: -0.03em; }
.margin-wordmark .m-y { color: #6C71C4; }   /* M — violet */
.margin-wordmark .m-q { color: #2AA198; }   /* a — Year teal */
.margin-wordmark .m-m { color: #268BD2; }   /* r — Quarter blue */
.margin-wordmark .m-w { color: #CB4B16; }   /* g — Month orange */
.margin-wordmark .m-d { color: #D33682; }   /* i — Week pink */
.margin-wordmark .m-n { color: #B58900; }   /* n — Day yellow */

.product__when {
  margin: 0 0 1.75rem;
  color: var(--ink-soft);
  font-size: var(--type-fine);
}
[data-tod="night"] .product__when { color: var(--amber-soft); opacity: 0.7; }

.product__cta {
  display: flex;
  gap: 1.75rem;
  flex-wrap: wrap;
}

/* ============= NEWSLETTER ============= */
.newsletter {
  text-align: left;
}

.newsletter__heading {
  font-size: var(--type-h2);
  font-weight: 600;
  margin: 0 0 0.75rem;
  letter-spacing: -0.02em;
}

.newsletter__sub {
  color: var(--ink-soft);
  margin: 0 0 2rem;
}
[data-tod="night"] .newsletter__sub { color: var(--amber-soft); opacity: 0.7; }

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

.newsletter__form input[type="email"] {
  flex: 1 1 16rem;
  min-width: 0;
  padding: 0.95rem 1.1rem;
  border: 1px solid color-mix(in srgb, var(--ink) 15%, transparent);
  border-radius: 4px;
  background: color-mix(in srgb, var(--surface) 60%, transparent);
  color: var(--ink);
  font-size: var(--type-body);
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.newsletter__form input[type="email"]::placeholder { color: var(--ink-soft); opacity: 0.5; }
.newsletter__form input[type="email"]:focus {
  outline: none;
  border-color: var(--glow);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--glow) 25%, transparent);
}

.newsletter__form button[type="submit"] {
  padding: 0.95rem 1.75rem;
  background: var(--ink);
  color: var(--bg);
  border-radius: 4px;
  font-weight: 500;
  letter-spacing: 0.005em;
  transition: background 0.3s var(--ease), transform 0.15s var(--ease);
  position: relative;
  overflow: hidden;
}
.newsletter__form button[type="submit"]:hover {
  background: var(--clay);
  box-shadow: 0 0 24px color-mix(in srgb, var(--glow) 40%, transparent);
}
.newsletter__form button[type="submit"]:active { transform: translateY(1px); }
.newsletter__form button[type="submit"]:focus-visible {
  outline: 2px solid var(--glow);
  outline-offset: 2px;
}
[data-tod="night"] .newsletter__form button[type="submit"] {
  background: var(--glow);
  color: var(--earth-base);
}
[data-tod="night"] .newsletter__form button[type="submit"]:hover {
  background: var(--amber-soft);
}

.newsletter__fine-print {
  color: var(--ink-soft);
  font-size: var(--type-fine);
  margin: 0 0 0.5rem;
}

.newsletter__status {
  font-size: var(--type-fine);
  color: var(--ink-soft);
  min-height: 1.25rem;
  margin: 0;
}

/* ============= FOOTER ============= */
.footer {
  padding-top: 3rem;
  padding-bottom: 3rem;
  color: var(--ink-soft);
  font-size: var(--type-fine);
}
.footer p { margin: 0 0 0.5rem; }
.footer__name { font-weight: 600; color: var(--ink); }
.footer__contact { margin-bottom: 1rem; }
.footer__copyright {
  margin-top: 1.5rem;
  opacity: 0.7;
}
.footer__contact a.link { color: var(--ink); }

/* ============= TIME-OF-DAY CONTROL ============= */
.tod-control {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  font-size: var(--type-fine);
  color: var(--ink-soft);
}
/* (.tod-control__label removed 2026-05-16 — the buttons are
   self-explanatory together as a time-of-day vocabulary.
   The aria-label on the parent still tells screen readers
   what the group is for.) */
.tod-control__group {
  display: inline-flex;
  gap: 0;
  border-radius: 999px;
  /* Frosted-glass styling moved here from the outer wrapper —
     the inner button pill is now the only visible element. */
  background: color-mix(in srgb, var(--bg) 65%, transparent);
  backdrop-filter: blur(18px) saturate(1.1);
  -webkit-backdrop-filter: blur(18px) saturate(1.1);
  padding: 3px;
  border: 1px solid color-mix(in srgb, var(--ink) 8%, transparent);
  box-shadow:
    0 1px 0 color-mix(in srgb, var(--ink) 5%, transparent) inset,
    0 8px 24px -8px color-mix(in srgb, var(--clay) 20%, transparent),
    0 2px 6px -2px color-mix(in srgb, var(--ink) 10%, transparent);
  transition: background var(--tod-fade) var(--ease),
              box-shadow var(--tod-fade) var(--ease);
}
.tod-control__option {
  padding: 0.4rem 0.85rem;
  border-radius: 999px;
  color: var(--ink-soft);
  font-size: 0.8125rem;
  letter-spacing: 0.01em;
  position: relative;
  transition: background 0.3s var(--ease), color 0.3s var(--ease);
}
.tod-control__option:hover { color: var(--ink); }
.tod-control__option[aria-pressed="true"] {
  background: var(--ink);
  color: var(--bg);
}
[data-tod="night"] .tod-control__option[aria-pressed="true"] {
  background: var(--glow);
  color: var(--earth-base);
}

/* Auto-applied indicator — small amber dot in the top-right corner of
   the mode currently being applied via Auto. Lets the user see at a
   glance which mode the clock has chosen. Only renders when Auto is
   the active preference AND this button matches the current mode. */
.tod-control__option[data-auto-applied="true"]::after {
  content: '';
  position: absolute;
  top: 5px;
  right: 7px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--glow);
  box-shadow: 0 0 4px color-mix(in srgb, var(--glow) 70%, transparent);
}

/* Floating variant — pure positioning wrapper now. All visual
   styling lives on the inner .tod-control__group pill so there's
   only one visible container, not a pill-inside-a-pill. */
.tod-control--floating {
  position: fixed;
  top: 1.25rem;
  right: 1.25rem;
  z-index: 200;
}
/* Night-mode-specific styling moved from outer wrapper to inner pill. */
[data-tod="night"] .tod-control--floating .tod-control__group {
  background: color-mix(in srgb, var(--earth-base) 65%, transparent);
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--glow) 15%, transparent) inset,
    0 8px 32px -6px color-mix(in srgb, var(--glow) 25%, transparent),
    0 2px 8px -2px rgba(0, 0, 0, 0.4);
}

/* ============= RESPONSIVE NUDGES ============= */
@media (max-width: 640px) {
  .tod-control--floating .tod-control__option { padding: 0.35rem 0.6rem; font-size: 0.75rem; }
}

@media (max-width: 480px) {
  :root {
    --section-gap: clamp(3.5rem, 10vh, 6rem);
    --gutter: 1.25rem;
  }
  .hero__scroll { bottom: 2rem; }
  .work .product { padding: 1.5rem; }
  .tod-control--floating { top: 0.75rem; right: 0.75rem; }
}

/* ============= VIEW TRANSITIONS — the actual mode-fade ============= */
/* CSS-only gradient interpolation has fundamental limits: even with
   @property color registrations, browsers don't repaint complex
   multi-stop gradients on every frame during a transition (the
   compositor drops intermediate frames to stay within a render
   budget). Result: visible "chunking" no matter the duration.

   The View Transitions API sidesteps this entirely. Browser takes
   a snapshot of the page in the old state, our JS applies the
   mode change, browser takes a snapshot of the new state, and
   crossfades the two SNAPSHOTS via GPU bitmap blending. No
   gradient recomputation happens during the fade — it's pure
   opacity interpolation on two pre-rendered images. Smooth at
   any complexity. */
::view-transition-old(root),
::view-transition-new(root) {
  /* Click-driven crossfade is 700ms — short enough that the UI
     feels responsive on click, long enough to read as a fade.
     Note: this is INDEPENDENT from --tod-fade (1800ms) which
     governs the per-minute Auto-tick interpolation. Clicks are
     interactive moments and want quick feedback; Auto-tick
     interpolations are atmospheric and want gradual evolution. */
  animation-duration: 700ms;
  animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
/* Stack both snapshots so they're visible simultaneously during the fade */
::view-transition-old(root) { z-index: 1; }
::view-transition-new(root) { z-index: 2; }

/* Exclude the floating toggle from the page-wide crossfade. Without
   this, the button visuals would be locked inside the 1.8s snapshot
   crossfade, making clicks feel laggy. With its own view-transition
   group set to zero animation, the toggle snaps directly to its new
   visual state while the underlying page does the smooth crossfade.
   The buttons' own 300ms CSS transitions still apply (pressed-state
   color change, etc.), so they look responsive. */
.tod-control--floating {
  view-transition-name: tod-control;
}
::view-transition-group(tod-control) {
  animation-duration: 0ms;
}
::view-transition-old(tod-control) {
  animation: none;
  opacity: 0;
}
::view-transition-new(tod-control) {
  animation: none;
  opacity: 1;
}

/* ============= REDUCED MOTION ============= */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition: none !important;
    animation: none !important;
  }
  .hero__title, .hero__sub { opacity: 1; }
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: 0.001ms;
  }
}
