/* ============================================================
   Cosmic Nisi — Interactive features
   - ConstellationHero: stars connect into a sigil on cursor proximity
   - DailyTarot: deterministic daily card, 3D flip on click
   - MoonPhase: live, computed from today
   - BirthdateTool: sun sign + a personal word
   ============================================================ */

const { useState: useStateI, useEffect: useEffectI, useMemo, useRef: useRefI } = React;

/* ============================================================
   Constellation hero — cursor-aware
   ============================================================ */
function ConstellationHero() {
  const ref = useRefI(null);
  useEffectI(() => {
    const canvas = ref.current; if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    let w = 0, h = 0, raf;
    let mx = -9999, my = -9999;
    const stars = [];

    // hand-placed constellation points (relative coords)
    // representing a soft, asymmetric sigil — moon phases & a guiding star
    const sigil = [
      [0.18, 0.32], [0.28, 0.22], [0.40, 0.30],
      [0.52, 0.18], [0.62, 0.30], [0.74, 0.24],
      [0.84, 0.36],
      [0.30, 0.62], [0.42, 0.74], [0.52, 0.66],
      [0.62, 0.78], [0.74, 0.66],
      [0.50, 0.50], // central guiding star
    ];
    const lines = [
      [0,1],[1,2],[2,3],[3,4],[4,5],[5,6],
      [7,8],[8,9],[9,10],[10,11],
      [3,12],[12,9],
    ];

    const resize = () => {
      w = canvas.clientWidth; h = canvas.clientHeight;
      canvas.width = w * dpr; canvas.height = h * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      stars.length = 0;
      // sigil stars
      sigil.forEach(([fx, fy], i) => {
        stars.push({
          x: fx * w, y: fy * h, r: i === 12 ? 2.4 : 1.6 + Math.random() * 0.6,
          a: i === 12 ? 0.9 : 0.55 + Math.random() * 0.2, tw: Math.random() * 6.28,
          isSigil: true, idx: i,
        });
      });
      // scattered field
      const extra = Math.floor((w * h) / 14000);
      for (let i = 0; i < extra; i++) {
        stars.push({
          x: Math.random() * w, y: Math.random() * h,
          r: Math.random() * 1.0 + 0.2, a: Math.random() * 0.4 + 0.2,
          tw: Math.random() * 6.28, isSigil: false,
        });
      }
    };
    resize();
    window.addEventListener('resize', resize);

    const onMove = (e) => {
      const rect = canvas.getBoundingClientRect();
      mx = e.clientX - rect.left; my = e.clientY - rect.top;
    };
    const onLeave = () => { mx = -9999; my = -9999; };
    canvas.addEventListener('pointermove', onMove);
    canvas.addEventListener('pointerleave', onLeave);

    let t0 = performance.now();
    const draw = (t) => {
      const dt = (t - t0) / 1000; t0 = t;
      ctx.clearRect(0, 0, w, h);

      // proximity-aware drawing of constellation lines
      // when cursor near any sigil star, lines fade in
      const sigilStars = stars.filter(s => s.isSigil);
      let proximity = 0;
      for (const s of sigilStars) {
        const dx = s.x - mx, dy = s.y - my;
        const d = Math.hypot(dx, dy);
        proximity = Math.max(proximity, Math.max(0, 1 - d / 320));
      }
      // smooth proximity
      ConstellationHero._p = (ConstellationHero._p ?? 0) + (proximity - (ConstellationHero._p ?? 0)) * 0.08;
      const p = ConstellationHero._p;

      ctx.lineWidth = 0.7;
      for (const [a, b] of lines) {
        const sa = sigilStars[a], sb = sigilStars[b];
        ctx.strokeStyle = `rgba(242, 110, 154, ${0.05 + p * 0.45})`;
        ctx.beginPath();
        ctx.moveTo(sa.x, sa.y);
        ctx.lineTo(sb.x, sb.y);
        ctx.stroke();
      }

      // draw stars
      for (const s of stars) {
        s.tw += dt * 1.2;
        const flick = (Math.sin(s.tw) * 0.5 + 0.5) * 0.5 + 0.5;
        let a = s.a * flick;
        let r = s.r;
        if (s.isSigil) {
          a = Math.min(1, a + p * 0.35);
          r = s.r + p * 1.2;
        }
        ctx.beginPath();
        ctx.fillStyle = s.isSigil
          ? `rgba(242, 110, 154, ${a})`
          : `rgba(251, 237, 235, ${a})`;
        ctx.arc(s.x, s.y, r, 0, Math.PI * 2);
        ctx.fill();
        if (s.isSigil && r > 1.5) {
          ctx.globalAlpha = a * 0.4;
          ctx.fillRect(s.x - 5, s.y - 0.4, 10, 0.8);
          ctx.fillRect(s.x - 0.4, s.y - 5, 0.8, 10);
          ctx.globalAlpha = 1;
        }
      }
      raf = requestAnimationFrame(draw);
    };
    raf = requestAnimationFrame(draw);

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('resize', resize);
      canvas.removeEventListener('pointermove', onMove);
      canvas.removeEventListener('pointerleave', onLeave);
    };
  }, []);
  return <canvas ref={ref} className="cn-hero__canvas" aria-hidden="true"/>;
}

/* ============================================================
   Daily Tarot — deterministic by date
   ============================================================ */
const TAROT = [
  { num: '0', name: 'Der Narr', msg: 'Ein neuer Anfang. Du musst nicht wissen, wohin — nur, dass du gehst.' },
  { num: 'I', name: 'Der Magier', msg: 'Du hast schon, was du brauchst. Nichts fehlt. Nur die Erlaubnis, es zu nutzen.' },
  { num: 'II', name: 'Die Hohepriesterin', msg: 'Hör nach innen. Die Stimme, die flüstert, weiß mehr als die, die schreit.' },
  { num: 'III', name: 'Die Herrscherin', msg: 'Was du nährst, wächst. Auch die Sanftheit ist eine Form von Macht.' },
  { num: 'IV', name: 'Der Herrscher', msg: 'Struktur ist kein Käfig. Manchmal ist sie das Geländer auf dem Heimweg.' },
  { num: 'V', name: 'Der Hierophant', msg: 'Tradition prüfen, ohne sie zu verachten. Was darf bleiben? Was nicht?' },
  { num: 'VI', name: 'Die Liebenden', msg: 'Wahl, die zwei Räume verbindet. Die Antwort kommt aus dem Bauch, nicht aus dem Kopf.' },
  { num: 'VII', name: 'Der Wagen', msg: 'Beide Pferde gehören dir. Halte beide Zügel. Du fährst.' },
  { num: 'VIII', name: 'Die Kraft', msg: 'Sanft, aber unbeugsam. Der Löwe legt sich zu dir, weil du ihn nicht bekämpfst.' },
  { num: 'IX', name: 'Der Eremit', msg: 'Rückzug ist kein Verstecken. Manchmal hat das Licht nur Platz im Alleinsein.' },
  { num: 'X', name: 'Das Rad', msg: 'Etwas wendet sich. Du musst nicht alles verstehen — nur dabei bleiben.' },
  { num: 'XI', name: 'Gerechtigkeit', msg: 'Die Wahrheit, ehrlich gesagt, ist immer noch die freundlichste Antwort.' },
  { num: 'XII', name: 'Der Gehängte', msg: 'Eine andere Perspektive kostet dich nichts — außer dem alten Blickwinkel.' },
  { num: 'XIII', name: 'Der Tod', msg: 'Etwas darf gehen. Nicht aus Härte. Aus Treue zu dem, was kommt.' },
  { num: 'XIV', name: 'Die Mäßigung', msg: 'Mische langsam. Das Heilende braucht Zeit, nicht Druck.' },
  { num: 'XV', name: 'Der Teufel', msg: 'Die Kette ist offen. Du hast sie nur lange genug getragen, um sie zu vergessen.' },
  { num: 'XVI', name: 'Der Turm', msg: 'Was wackelt, war nie wirklich tragend. Vertrau dem Riss.' },
  { num: 'XVII', name: 'Der Stern', msg: 'Hoffnung — ruhig, nicht laut. Sie wartet, dass du wieder atmest.' },
  { num: 'XVIII', name: 'Der Mond', msg: 'Nicht alles muss schon klar sein. Manche Wahrheiten zeigen sich nur im Halbdunkel.' },
  { num: 'XIX', name: 'Die Sonne', msg: 'Heute darf es leicht sein. Du musst dich nicht dafür rechtfertigen.' },
  { num: 'XX', name: 'Das Gericht', msg: 'Etwas in dir ruft. Antworten heißt nicht: erklären. Antworten heißt: hingehen.' },
  { num: 'XXI', name: 'Die Welt', msg: 'Ein Kreis schließt sich. Bevor der nächste beginnt, halte einen Atemzug inne.' },
];

// Full card illustrations — index-aligned with TAROT above (0 = Der Narr … 21 = Die Welt)
const TAROT_IMG = [
  'assets/tarot/00-der-narr.png',
  'assets/tarot/01-der-magier.png',
  'assets/tarot/02-die-hohepriesterin.png',
  'assets/tarot/03-die-herrscherin.png',
  'assets/tarot/04-der-herrscher.png',
  'assets/tarot/05-der-hierophant.png',
  'assets/tarot/06-die-liebenden.png',
  'assets/tarot/07-der-wagen.png',
  'assets/tarot/08-die-kraft.png',
  'assets/tarot/09-der-eremit.png',
  'assets/tarot/10-das-rad-des-schicksals.png',
  'assets/tarot/11-die-gerechtigkeit.png',
  'assets/tarot/12-der-gehaengte.png',
  'assets/tarot/13-der-tod.png',
  'assets/tarot/14-die-maessigkeit.png',
  'assets/tarot/15-der-teufel.png',
  'assets/tarot/16-der-turm.png',
  'assets/tarot/17-der-stern.png',
  'assets/tarot/18-der-mond.png',
  'assets/tarot/19-die-sonne.png',
  'assets/tarot/20-das-gericht.png',
  'assets/tarot/21-die-welt.png',
];

const TAROT_ART = {
  'Der Stern':  (
    <g stroke="currentColor" strokeWidth="1.2" fill="none" strokeLinejoin="round">
      <path d="M50 10 L54 44 L88 50 L54 56 L50 90 L46 56 L12 50 L46 44 Z"/>
      <circle cx="50" cy="50" r="3" fill="currentColor"/>
    </g>
  ),
  'Der Mond': (
    <g stroke="currentColor" strokeWidth="1.2" fill="none" strokeLinejoin="round">
      <path d="M65 18 A32 32 0 1 0 65 82 A24 24 0 1 1 65 18 Z"/>
      <circle cx="20" cy="34" r="1" fill="currentColor"/>
      <circle cx="32" cy="74" r="1" fill="currentColor"/>
    </g>
  ),
  'Die Sonne': (
    <g stroke="currentColor" strokeWidth="1.2" fill="none">
      <circle cx="50" cy="50" r="18"/>
      {Array.from({length:12}).map((_,i)=>{
        const a = i*Math.PI*2/12; const x1 = 50 + Math.cos(a)*24, y1 = 50 + Math.sin(a)*24;
        const x2 = 50 + Math.cos(a)*36, y2 = 50 + Math.sin(a)*36;
        return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2}/>;
      })}
    </g>
  ),
};
const DEFAULT_ART = (
  <g stroke="currentColor" strokeWidth="1.2" fill="none" strokeLinejoin="round">
    <circle cx="50" cy="50" r="30"/>
    <path d="M50 22 L52 48 L78 50 L52 52 L50 78 L48 52 L22 50 L48 48 Z"/>
  </g>
);

function dayIndex(d) {
  const epoch = new Date(2025, 0, 1);
  const diff = Math.floor((d - epoch) / 86400000);
  // mix to scatter consecutive days
  return ((diff * 7 + 3) % TAROT.length + TAROT.length) % TAROT.length;
}

function DailyTarot() {
  const today = useMemo(() => new Date(), []);
  const [flipped, setFlipped] = useStateI(false);
  const [offset, setOffset] = useStateI(0);
  const idx = (dayIndex(today) + offset) % TAROT.length;
  const card = TAROT[idx];
  const img = TAROT_IMG[idx];
  const stageRef = useRefI(null);

  // preload the active illustration so the flip reveals it instantly
  useEffectI(() => {
    if (!img) return;
    const pre = new Image();
    pre.src = img;
  }, [img]);

  // subtle 3D tilt on cursor
  useEffectI(() => {
    const stage = stageRef.current; if (!stage) return;
    const onMove = (e) => {
      const r = stage.getBoundingClientRect();
      const fx = (e.clientX - r.left) / r.width - 0.5;
      const fy = (e.clientY - r.top) / r.height - 0.5;
      const card = stage.querySelector('.cn-tarot__card');
      if (!card) return;
      const yRot = flipped ? 180 + fx * 8 : fx * 12;
      card.style.setProperty('--card-y', yRot + 'deg');
      card.style.setProperty('--card-x', (-fy * 8) + 'deg');
    };
    const onLeave = () => {
      const card = stage.querySelector('.cn-tarot__card');
      if (!card) return;
      card.style.setProperty('--card-y', flipped ? '180deg' : '0deg');
      card.style.setProperty('--card-x', '0deg');
    };
    stage.addEventListener('pointermove', onMove);
    stage.addEventListener('pointerleave', onLeave);
    return () => {
      stage.removeEventListener('pointermove', onMove);
      stage.removeEventListener('pointerleave', onLeave);
    };
  }, [flipped]);

  const formatted = today.toLocaleDateString('de-AT', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' });

  const playRustle = () => {
    try {
      const Ctx = window.AudioContext || window.webkitAudioContext;
      if (!Ctx) return;
      const ctx = new Ctx();
      const buf = ctx.createBuffer(1, ctx.sampleRate * 0.5, ctx.sampleRate);
      const data = buf.getChannelData(0);
      for (let i = 0; i < data.length; i++) {
        data[i] = (Math.random() * 2 - 1) * Math.exp(-i / (ctx.sampleRate * 0.18));
      }
      const src = ctx.createBufferSource(); src.buffer = buf;
      const filt = ctx.createBiquadFilter(); filt.type = 'highpass'; filt.frequency.value = 2500;
      const g = ctx.createGain(); g.gain.value = 0.06;
      src.connect(filt); filt.connect(g); g.connect(ctx.destination);
      src.start();
      setTimeout(() => ctx.close(), 700);
    } catch(e) {}
  };

  const onClickCard = () => {
    setFlipped(f => !f);
    playRustle();
  };
  const redraw = (e) => {
    e.stopPropagation();
    setFlipped(false);
    setTimeout(() => { setOffset(o => o + 1); setFlipped(true); playRustle(); }, 500);
  };

  return (
    <section className="cn-tarot" id="tarot">
      <div className="cn-tarot__inner">
        <div className="cn-tarot__copy">
          <div className="cn-tarot__date">Karte des Tages · {formatted}</div>
          <h2>Eine Karte<br/><em>für heute.</em></h2>
          <p>
            Eine kleine Geste vor dem Tag. Klick auf die Karte — sie zeigt dir,
            was gerade in der Luft liegt. Keine Vorhersage. Ein Spiegel.
          </p>
          <button className="cn-tarot__redraw" onClick={redraw}>
            Neue Karte ziehen →
          </button>
        </div>
        <div className="cn-tarot__stage" ref={stageRef}>
          <div className={`cn-tarot__card ${flipped ? 'is-flipped' : ''}`} onClick={onClickCard}>
            <div className="cn-tarot__face cn-tarot__back">
              <div className="cn-tarot__back-art">
                <svg viewBox="0 0 100 100" width="140" height="140">
                  <g stroke="currentColor" strokeWidth="0.9" fill="none">
                    <circle cx="50" cy="50" r="36"/>
                    <circle cx="50" cy="50" r="28"/>
                    <path d="M50 14 L52 48 L86 50 L52 52 L50 86 L48 52 L14 50 L48 48 Z"/>
                    {Array.from({length:8}).map((_,i)=>{
                      const a = i*Math.PI*2/8; const x = 50+Math.cos(a)*42, y = 50+Math.sin(a)*42;
                      return <circle key={i} cx={x} cy={y} r="1.2" fill="currentColor"/>;
                    })}
                  </g>
                </svg>
              </div>
              <div style={{position:'absolute', bottom: 18, left: 0, right: 0, textAlign:'center', fontFamily:'var(--font-body)', fontSize:11, letterSpacing:'0.22em', textTransform:'uppercase', color:'var(--bronze-soft)', opacity:0.7}}>
                Klick zum Aufdecken
              </div>
            </div>
            <div className="cn-tarot__face cn-tarot__front">
              <img className="cn-tarot__img" src={img} alt={`${card.num} — ${card.name}`} draggable="false"/>
            </div>
          </div>
          <div className={`cn-tarot__reveal ${flipped ? 'is-visible' : ''}`} aria-hidden={!flipped}>
            „{card.msg}“
          </div>
        </div>
      </div>
    </section>
  );
}

/* ============================================================
   Live moon phase
   ============================================================ */
function moonPhase(date) {
  // Conway's algorithm — approximate (good enough for one decimal day)
  const y = date.getFullYear();
  const m = date.getMonth() + 1;
  const d = date.getDate();
  let r = y % 100;
  r %= 19; if (r > 9) r -= 19;
  r = (r * 11) % 30 + m + d;
  if (m < 3) r += 2;
  r -= (y < 2000 ? 4 : 8.3);
  r = ((r % 30) + 30) % 30; // 0..29.5 ish
  // age in days, 0 = new
  return { age: r, frac: r / 29.5305882 };
}

const PHASE_COPY = [
  { name: 'Neumond',         italic: 'Neumond',          meaning: 'Säen, was noch keinen Namen hat. Der leise Anfang.' },
  { name: 'Zunehmende Sichel', italic: 'zunehmende Sichel', meaning: 'Etwas wagt sich heraus. Schütze die zarte Form.' },
  { name: 'Zunehmender Halbmond', italic: 'erstes Viertel', meaning: 'Eine Entscheidung steht an. Halt die Richtung.' },
  { name: 'Zunehmender Mond', italic: 'zunehmender Mond', meaning: 'Aufbau, Tempo, Vertrauen. Gehe weiter.' },
  { name: 'Vollmond',         italic: 'Vollmond',          meaning: 'Alles ist sichtbar — auch das, was du übersehen hast.' },
  { name: 'Abnehmender Mond', italic: 'abnehmender Mond', meaning: 'Loslassen, was du nicht weitertragen willst.' },
  { name: 'Abnehmender Halbmond', italic: 'letztes Viertel', meaning: 'Innehalten. Was bleibt, was darf gehen?' },
  { name: 'Abnehmende Sichel', italic: 'abnehmende Sichel', meaning: 'Stille. Vorbereitung auf den nächsten Anfang.' },
];
function phaseIndex(frac) {
  const ranges = [0.03, 0.22, 0.28, 0.47, 0.53, 0.72, 0.78, 0.97];
  for (let i = 0; i < ranges.length; i++) if (frac < ranges[i]) return i;
  return 0;
}

function MoonSVG({ frac }) {
  // illumination: 0..1, where 0 = new, 0.5 = full
  // build a moon by combining a full disc with a clipping circle
  const r = 70;
  const cx = 80, cy = 80;
  // shadow circle position based on phase
  // For simplicity: draw a soft body, then a shadow circle that moves L→R
  // frac 0 => shadow centered (new), frac 0.5 => no shadow (full), 1 => centered again
  const t = frac < 0.5 ? frac * 2 : (1 - frac) * 2; // 0..1, 1 at full
  const shadowOffset = (frac < 0.5 ? -1 : 1) * (1 - t) * (r * 1.1);
  const shadowX = cx + shadowOffset;
  return (
    <svg viewBox="0 0 160 160" className="cn-moon__svg" aria-hidden="true">
      <defs>
        <radialGradient id="moonBody" cx="40%" cy="35%" r="70%">
          <stop offset="0%" stopColor="#F4EDE0"/>
          <stop offset="80%" stopColor="#E0D2B8"/>
          <stop offset="100%" stopColor="#B89F7A"/>
        </radialGradient>
        <radialGradient id="moonShadow" cx="50%" cy="50%" r="60%">
          <stop offset="0%" stopColor="#0C0309" stopOpacity="0.96"/>
          <stop offset="100%" stopColor="#0C0309" stopOpacity="0.85"/>
        </radialGradient>
      </defs>
      {/* halo */}
      <circle cx={cx} cy={cy} r={r + 8} fill="rgba(168,123,79,0.10)"/>
      {/* moon body */}
      <circle cx={cx} cy={cy} r={r} fill="url(#moonBody)"/>
      {/* craters — hand placed */}
      <g fill="#A78F6A" opacity="0.35">
        <circle cx={cx - 22} cy={cy - 14} r="6"/>
        <circle cx={cx + 8} cy={cy + 18} r="9"/>
        <circle cx={cx + 22} cy={cy - 22} r="4"/>
        <circle cx={cx - 12} cy={cy + 28} r="3.5"/>
      </g>
      {/* shadow disc, clipped to moon */}
      <clipPath id="moonClip"><circle cx={cx} cy={cy} r={r}/></clipPath>
      <g clipPath="url(#moonClip)">
        <circle cx={shadowX} cy={cy} r={r} fill="url(#moonShadow)"/>
      </g>
      {/* outer hairline */}
      <circle cx={cx} cy={cy} r={r} fill="none" stroke="rgba(16,20,31,0.18)" strokeWidth="0.6"/>
    </svg>
  );
}

function MoonPhase() {
  const today = useMemo(() => new Date(), []);
  const { age, frac } = useMemo(() => moonPhase(today), [today]);
  const idx = phaseIndex(frac);
  const phase = PHASE_COPY[idx];
  const illum = Math.round((1 - Math.abs(0.5 - frac) * 2) * 100);
  const formatted = today.toLocaleDateString('de-AT', { day: 'numeric', month: 'long', year: 'numeric' });

  return (
    <section className="cn-moon" id="mond">
      <div className="cn-moon__visual">
        <div className="cn-moon__halo"/>
        <MoonSVG frac={frac}/>
      </div>
      <div className="cn-moon__copy">
        <div className="cn-moon__phase">Mondphase · heute</div>
        <h2 className="cn-moon__name">Wir sind im <em>{phase.italic}</em>.</h2>
        <div className="cn-moon__meaning">{phase.meaning}</div>
        <div className="cn-moon__meta">
          <span>{formatted}</span>
          <span>{illum}% beleuchtet</span>
          <span>Tag {age.toFixed(1)} im Zyklus</span>
        </div>
      </div>
    </section>
  );
}

/* ============================================================
   Birthdate sun-sign mini tool
   ============================================================ */
const SIGNS = [
  { name: 'Steinbock',  start: [12,22], end: [1,19],  word: 'Du baust dir Berge — manchmal, um nicht hinzusehen, was im Tal wartet.' },
  { name: 'Wassermann', start: [1,20],  end: [2,18],  word: 'Du gehörst überall hin und nirgendwo. Dein Zuhause ist die Idee.' },
  { name: 'Fische',     start: [2,19],  end: [3,20],  word: 'Du fühlst, was andere tragen. Lerne, wo du aufhörst und sie anfangen.' },
  { name: 'Widder',     start: [3,21],  end: [4,19],  word: 'Du brennst zuerst — und schaust dann, was leuchtet, was verbrannt ist.' },
  { name: 'Stier',      start: [4,20],  end: [5,20],  word: 'Du brauchst Wurzeln, um die Welt zu spüren. Verschwende keine Tiefe an Hektik.' },
  { name: 'Zwillinge',  start: [5,21],  end: [6,20],  word: 'Du denkst in Brücken. Pass auf, dass du sie auch überquerst.' },
  { name: 'Krebs',      start: [6,21],  end: [7,22],  word: 'Du trägst die Geschichten anderer in dir. Frage dich öfter, welche deine ist.' },
  { name: 'Löwe',       start: [7,23],  end: [8,22],  word: 'Du bist gemacht zum Leuchten. Es ist okay, gesehen werden zu wollen.' },
  { name: 'Jungfrau',   start: [8,23],  end: [9,22],  word: 'Du suchst Reinheit, weil du ahnst, wie zerbrechlich Schönheit ist.' },
  { name: 'Waage',      start: [9,23],  end: [10,22], word: 'Du wiegst — auch dich selbst. Lege manchmal die Waage hin und atme.' },
  { name: 'Skorpion',   start: [10,23], end: [11,21], word: 'Du gehst in die Tiefe, weil du dort Wahrheit findest. Vergiss nicht aufzutauchen.' },
  { name: 'Schütze',    start: [11,22], end: [12,21], word: 'Du fragst nach dem Größeren. Vergiss nicht, dass auch das Kleine dich braucht.' },
];
const SIGN_GLYPH = {
  Steinbock:  'M30 24 q-6 0 -8 8 q-2 8 4 12 q-6 -2 -10 6 q-4 12 8 14',
  Wassermann: 'M14 26 q4 -4 8 0 q4 4 8 0 q4 -4 8 0 M14 38 q4 -4 8 0 q4 4 8 0 q4 -4 8 0',
  Fische:     'M14 26 q6 8 14 0 M38 26 q-6 8 -14 0 M22 26 q4 4 6 0',
  Widder:     'M14 22 q4 -8 12 -2 q8 -6 12 2 M14 24 q-2 6 0 12 M40 24 q2 6 0 12',
  Stier:      'M14 22 q6 -6 18 0 q6 -6 12 0 M26 30 a8 8 0 1 0 0 0.1',
  Zwillinge:  'M14 16 v24 M40 16 v24 M14 18 h26 M14 38 h26',
  Krebs:      'M14 22 a8 6 0 1 0 0 -0.1 M40 38 a8 6 0 1 0 0 0.1 M22 22 h12 M22 38 h12',
  Löwe:       'M22 36 a10 10 0 1 0 4 -18 q4 -2 8 2 q4 4 0 8',
  Jungfrau:   'M14 24 v16 M22 24 v16 M30 24 v16 q0 6 6 6 q4 0 6 -4',
  Waage:      'M14 36 h28 M16 30 a12 8 0 0 1 24 0',
  Skorpion:   'M14 22 v18 M22 22 v18 M30 22 v18 q0 4 4 4 q4 0 4 -4 l-3 -3',
  Schütze:    'M14 40 l24 -24 M30 16 h8 v8',
};
function findSign(d) {
  if (!d) return null;
  const m = d.getMonth() + 1, day = d.getDate();
  for (const s of SIGNS) {
    const [sm, sd] = s.start, [em, ed] = s.end;
    if (sm > em) {
      // wraps year (Capricorn)
      if ((m === sm && day >= sd) || (m === em && day <= ed)) return s;
    } else {
      if ((m === sm && day >= sd) || (m === em && day <= ed) || (m > sm && m < em)) return s;
    }
  }
  return null;
}

function BirthdateTool() {
  const [val, setVal] = useStateI('');
  const [result, setResult] = useStateI(null);
  const submit = (e) => {
    e.preventDefault();
    if (!val) return;
    const d = new Date(val);
    if (isNaN(d.getTime())) return;
    setResult(findSign(d));
  };
  return (
    <section className="cn-birth" id="geburtsdatum">
      <div className="cn-birth__inner">
        <div className="eyebrow">Ein erstes Wort</div>
        <h2 className="cn-birth__title">Was sagt der Himmel<br/><em>am Tag deiner Geburt?</em></h2>
        <p className="cn-birth__sub">Trag dein Geburtsdatum ein — du bekommst dein Sonnenzeichen und einen Satz dazu. Klein. Persönlich. Anfang einer Reise.</p>
        <form className="cn-birth__form" onSubmit={submit}>
          <input
            type="date" className="cn-birth__inp"
            value={val} onChange={(e) => setVal(e.target.value)}
            max="2025-12-31" min="1920-01-01"
            aria-label="Geburtsdatum"
          />
          <button type="submit" className="cn-birth__btn">Lesen →</button>
        </form>
        {result && (
          <div className="cn-birth__result" key={result.name}>
            <svg viewBox="0 0 54 54" className="cn-birth__glyph">
              <path d={SIGN_GLYPH[result.name]} fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
            <div>
              <div className="cn-birth__sign-eb">Dein Sonnenzeichen</div>
              <div className="cn-birth__sign-name">{result.name}</div>
              <div className="cn-birth__word">„{result.word}"</div>
            </div>
          </div>
        )}
      </div>
    </section>
  );
}

Object.assign(window, { ConstellationHero, DailyTarot, MoonPhase, BirthdateTool, SIGN_GLYPH });
