/* ==========================================================================
   HERO — the homepage load sequence
   CLAUDE.md §3 (the conch) and §4 (the load sequence).

   ARCHITECTURE NOTE, read before editing:
   The resolved state is the DEFAULT. Nothing here is hidden until an
   .hero-animate class is put on <html>, and removing that class at any
   moment snaps straight to the finished hero. That inversion is what makes
   the three hard requirements in §4 cheap instead of fragile:

     - never block content   — if JS never runs, the hero is simply there
     - play once per session — the class is only added on a fresh session
     - dismiss on scroll     — remove the class, done, no teardown

   The alternative (hide by default, reveal with JS) puts the content behind
   a script, which is the failure mode §4 explicitly forbids.
   ========================================================================== */

/* --- Timeline ------------------------------------------------------------
   Every beat derives from --t-base, so the whole sequence retimes from one
   number. §4 asks for a single continuous moment: the name starts while the
   curve is still drawing, not after it. */

/* THE TWO CONCHES NOW DRAW AT THE SAME SPEED. The footer's mark sweeps the
   same 1000-unit path in --t-slow; the hero's took --t-draw, which is 2.8x
   --t-base against the footer's 1.3x — the same gesture at less than half the
   rate. Same path, same duration, same speed.

   THE BEATS ARE SCALED, NOT LEFT WHERE THEY WERE. The name used to land at
   43.6% of the draw and the tagline at 64.3%; against a 1.27s draw those old
   absolute delays would have put the name 78ms before the curve finished and
   the tagline well after it, which breaks §4's one continuous moment. The
   ratios are preserved instead: 0.57 and 0.84 of --t-base land at 43.8% and
   64.6% of the new draw. The opening is faster; it is not re-choreographed. */
.hero {
  --draw:         var(--t-slow);                    /* ~1.27s, as the footer */
  --name-in:      calc(var(--t-base) * 0.57);       /* ~0.56s, 44% of draw   */
  /* The Malayalam mark used to hold a beat here. It now lives in About, so
     the tagline inherits it rather than arriving after a silent one. */
  --tag-in:       calc(var(--t-base) * 0.84);       /* ~0.82s, 65% of draw   */
  --reveal-dur:   var(--t-slow);
}


/* --- Shell ---------------------------------------------------------------- */

.hero {
  position: relative;
  z-index: var(--z-content);
  min-height: 100svh;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: clamp(var(--sp-s), 3vh, var(--sp-l));
  text-align: center;

  /* The masthead is fixed, so it takes no space in flow — but align-content:
     center measures against the full 100svh, and any overflow spills equally
     top and bottom. With the name at its old size the stack was 164px taller
     than the viewport, and the half that went upward put the conch behind the
     bar. Reserving the bar's height here means centring happens in the space
     that is actually visible. */
  padding-block: calc(var(--masthead-h) + var(--sp-m)) var(--sp-xl);
  padding-inline: var(--gutter);
}


/* --- The conch -----------------------------------------------------------
   A centred stack: the conch sits above the name at a medium size, and the
   name, Malayalam mark and tagline centre beneath it.

   THIS PERMANENTLY RETIRES THE COLLISION PROBLEM. Every previous approach —
   hand-tuned crops, a clipped corridor, a measured-DOM solver — existed to
   keep an overlapping stroke off overlapping type. Stacked, they occupy
   different rows and cannot overlap at any viewport, so there is nothing left
   to solve. js/hero-conch.js is deleted; do not reintroduce a solver here.

   The conch is no longer cropped or bled. It is a whole object at a
   deliberate size, which is also what lets the draw read start to finish. */

.hero { --conch-opacity: 1; }

/* The box now matches the cropped viewBox, so the width below is the width
   the conch actually draws at — it used to be the width of a square that the
   mark sat inside at 63%. Sized off the smaller of the two axes: vh because
   this is a stack and height is what runs out, vw so it does not swell on a
   wide short window. */
.hero__conch {
  display: block;
  width: clamp(92px, min(15vh, 13vw), 156px);
  aspect-ratio: 666 / 908;
  pointer-events: none;
}

.hero__conch svg {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  overflow: visible;
  opacity: var(--conch-opacity);
}

/* THE TAPER IS THE ARTWORK, NOT A RECONSTRUCTION.
   conch-outline.svg is the visible element — a filled path with the real
   taper already drawn into it. conch-stroke.svg is never seen; it is the
   mask, a uniform wide stroke swept along the same spine by
   stroke-dashoffset. As the mask advances it uncovers the tapered shape
   underneath, so every width transition is the illustrator's curve rather
   than something CSS approximates.

   (The earlier approach stacked strokes at decreasing widths. Every width
   change was a hard ledge — stacking cannot produce a continuous taper.)

   Both files share the 1000x1000 viewBox and both begin at M537.262,337.691,
   so they are co-registered and need no transform to align.

   MASK WIDTH — measured, not guessed. Sampling the outline's fill along 400
   normals to the stroke spine gives a spindle profile, thin at both ends and
   thickest in the middle:

     fraction  0.0  0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9  1.0
     width       0    8   14   18   20   21   20   18   14    8    0

   Peak full width is 21 user units (half-width 10.5). The mask is set to 32
   — comfortably over the peak so nothing clips at the waist, with margin for
   the slight registration drift between two independently drawn Beziers.
   Wider would be safe too but sloppier: the round cap leads the reveal by
   half the stroke width, so an over-wide mask pushes a visible bulge ahead
   of the drawing point. At 32 that lead is 16 units on a 3353-unit path,
   under half a percent. */

.hero__conch-art {
  fill: var(--kumkumam);
}

.hero__conch-mask {
  fill: none;
  stroke: #fff;                 /* mask luminance: white reveals */
  stroke-width: 32;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1000 1000;  /* pathLength normalised to 1000 */
  stroke-dashoffset: 0;         /* resolved state: fully revealed */
}


/* --- Type ----------------------------------------------------------------- */

.hero__type {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: min(var(--w-wide), 46rem);
  margin-inline: auto;
}

.hero__name {
  font-family: var(--font-display);
  font-size: var(--type-mega);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-mega);
  font-weight: 400;
  margin: 0;
}

/* Each line gets its own clipping window so the words rise from behind a
   hard edge — §4's "mask from below a line". */
.hero__line {
  display: block;
  overflow: hidden;
  padding-block: 0.06em;   /* room for descenders inside the mask */
}

.hero__line > span { display: block; }

.hero__tagline {
  /* auto side margins, not just text-align: the block is narrower than its
     parent, so centring the text inside a left-hugging box still leaves the
     box off-centre. */
  margin: var(--sp-m) auto 0;
  max-width: 44ch;
  font-size: var(--type-lead);
  line-height: var(--lh-snug);
  color: var(--ink-muted);
  text-wrap: balance;
}


/* ==========================================================================
   THE SEQUENCE
   Applies only while <html> carries .hero-animate. Everything above is the
   resolved state.
   ========================================================================== */

/* The conch draws from bare paper — one mask, one sweep.
   Linear, not --ease. --ease is cubic-bezier(0.16, 1, 0.30, 1), which puts
   roughly 80% of the curve down in the first 30% of the time and then
   crawls; a drawn line wants a steady hand, not an arrival. */
.hero-animate .hero__conch-mask {
  stroke-dashoffset: 1000;
  animation: conch-draw var(--draw) linear forwards;
}

@keyframes conch-draw {
  to { stroke-dashoffset: 0; }
}

/* Name — starts at ~1.2s, while the curve is still drawing. */
.hero-animate .hero__line > span {
  transform: translateY(110%);
  animation: rise var(--reveal-dur) var(--ease) forwards;
  animation-delay: var(--name-in);
}

/* The second-line delay that lived here is GONE with the second line. It
   staggered "Nair" behind "Prateek" by --t-base * 0.065; the name is one line
   now, so the rule matched nothing and a stagger has nothing to stagger. */

@keyframes rise {
  to { transform: translateY(0); }
}

/* Malayalam mark, then tagline. Both fade up rather than mask — the name is
   the only element that gets the hard edge, so it stays the loudest moment. */
.hero-animate .hero__tagline {
  opacity: 0;
  animation: fade-up var(--t-base) var(--ease) forwards;
}

.hero-animate .hero__tagline { animation-delay: var(--tag-in); }

@keyframes fade-up {
  from { opacity: 0; transform: translateY(0.6em); }
  to   { opacity: 1; transform: translateY(0); }
}


/* --- Reduced motion -------------------------------------------------------
   Belt and braces. hero.js already refuses to add .hero-animate when the
   preference is set, but if the class arrives by any other route the
   sequence is neutralised here rather than merely sped up. The resolved
   state is what remains, which is the bypass §4 asks for. */

@media (prefers-reduced-motion: reduce) {
  .hero-animate .hero__conch-mask,
  .hero-animate .hero__line > span,
  .hero-animate .hero__tagline {
    animation: none;
    opacity: 1;
    transform: none;
    stroke-dashoffset: 0;
  }
}
