/* ═══════════════════════════════════════════════════════════════════════
   maju-enhancements.css
   maju.me · Confident Amber 2026

   Load order: LAST in <head>, after hero-legibility-patch.css
   <link rel="stylesheet" href="maju-enhancements.css">
═══════════════════════════════════════════════════════════════════════ */


/* ── 1. GRAIN ──────────────────────────────────────────────────────── */

body::after {
  content: "";
  position: fixed;
  inset: -50%;
  width: 200%;
  height: 200%;
  z-index: 9999;
  pointer-events: none;
  opacity: .04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.88' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23g)' opacity='0.5'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 200px 200px;
  animation: maju-grain 8s steps(12) infinite;
}
html[data-theme="dark"] body::after { opacity: .055; }

@keyframes maju-grain {
  0%  { transform: translate(0,0); }   10% { transform: translate(-2%,3%); }
  20% { transform: translate(3%,-2%); } 30% { transform: translate(-1%,-3%); }
  40% { transform: translate(2%,2%); }  50% { transform: translate(-3%,1%); }
  60% { transform: translate(1%,-2%); } 70% { transform: translate(-2%,-1%); }
  80% { transform: translate(3%,3%); }  90% { transform: translate(-1%,2%); }
  100%{ transform: translate(0,0); }
}
@media (prefers-reduced-motion: reduce) { body::after { animation: none; } }


/* ── 2. SELECTION ──────────────────────────────────────────────────── */

::selection                        { background: var(--amber);      color: var(--steel); }
html[data-theme="dark"]::selection { background: var(--amber-lift); color: var(--steel); }


/* ── 3. HERO H1 ────────────────────────────────────────────────────────

   PHILOSOPHY CHANGE — text is ALWAYS visible.
   No opacity:0, no fade-in, no stagger delay.
   The heading renders at full opacity immediately from HTML.
   JS wraps words and breathing begins — the animation enriches
   already-visible text rather than revealing hidden text.

   Arrival effect: weight rise only.
   Words start at wght 300, animate to wght 500 over 0.6s.
   Text is readable at wght 300 — never invisible.
   No stagger — all words rise together, cleaner and faster.

   Line 2: already at wght 300 from inline style. No arrival
   animation needed — it's visible from the start.

   Breathing and cursor spring-loop unchanged.
═══════════════════════════════════════════════════════════════════════ */

/* ─ Word spans — always visible, rAF drives weight via --hw ───────── */
.hero-line-1 .hw {
  display: inline;
  font-variation-settings: 'wght' var(--hw, 500);
  /* No opacity manipulation. No transition — rAF spring is the easing. */
}

/* ─ Weight-rise arrival — runs once on .hw-arriving ─────────────── */
/* Text is readable throughout — wght 300 is visible, 500 is resting */
@keyframes hw-arrive {
  from { font-variation-settings: 'wght' 300; }
  to   { font-variation-settings: 'wght' 500; }
}
.hero-line-1 .hw.hw-arriving {
  animation: hw-arrive 0.6s cubic-bezier(0.22, 1, 0.36, 1) forwards;
  /* No delay — all words rise together immediately */
}
.hero-line-1 .hw.hw-ready {
  animation: none;
  opacity: 1;
}

/* ─ Breathing — design (3.5s) ────────────────────────────────────── */
@keyframes breathe-design {
  0%, 100% { font-variation-settings: 'wght' 500; }
  50%       { font-variation-settings: 'wght' 720; }
}
.hw-breathe-design {
  animation: breathe-design 3.5s cubic-bezier(0.45, 0, 0.55, 1) infinite !important;
}

/* ─ Breathing — people (5.2s) ────────────────────────────────────── */
@keyframes breathe-people {
  0%, 100% { font-variation-settings: 'wght' 500; }
  50%       { font-variation-settings: 'wght' 720; }
}
.hw-breathe-people {
  animation: breathe-people 5.2s cubic-bezier(0.45, 0, 0.55, 1) infinite !important;
}
/* 5.2 ÷ 3.5 = 1.486 — irrational, never resolves to a common beat */

/* ─ Line 2 — visible from load, no animation needed ─────────────── */
/* The inline style already sets color:var(--charcoal); font-weight:300.
   JS adds .hero-line-2 for the spring-loop CSS hook only. */
.hero-line-2 {
  display: inline-block;
  font-variation-settings: 'wght' 300;
  /* No arrival animation — it's already visible */
}

/* ─ Reduced motion ───────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .hero-line-1 .hw,
  .hero-line-1 .hw.hw-arriving,
  .hero-line-1 .hw.hw-ready,
  .hw-breathe-design,
  .hw-breathe-people {
    animation: none !important;
    font-variation-settings: 'wght' 500 !important;
  }
  .hero-line-2 {
    font-variation-settings: 'wght' 300 !important;
  }
}
