// P5 SPECTRAL + P9 BIKEBEAR components
const { useState, useEffect, useRef } = React;

const _svcs = [
  {n:"01",name:"アプリ開発",desc:"業務に特化したWebアプリや社内ツールのお困りごと。要件整理から運用まで一貫してサポートします。",tags:["Webアプリ","社内ツール","API連携"]},
  {n:"02",name:"業務効率化DX",desc:"手作業・属人化・紙業務を見直し、デジタルで自動化。無理のない変革で現場の負担を減らします。",tags:["業務自動化","RPA","DX推進","人材育成"]},
  {n:"03",name:"AI活用",desc:"ChatGPTや生成AIを実務で使いこなす仕組みを構築。プロンプト設計から業務フローへの統合まで対応。",tags:["生成AI導入","AIエージェント","AI人材育成"]},
  {n:"04",name:"セミナー・研修",desc:"AI・DX・ノーコードをテーマにしたワークショップ・セミナーを企業・団体向けに開催。初心者にもわかりやすく。",tags:["企業研修","ワークショップ","オンライン可"]},
];
const _rsns = [
  {n:"01",t:"現場目線で考える",tx:"技術先行ではなく、人材・業務の実態から課題を整理します。現場の方が本当に使えるものの作り方を一緒に考えます。"},
  {n:"02",t:"スモールスタートOK",tx:"まず小さく試して、効果を確認しながら広げる進め方を提案。大きな投資の前に未来を見せます。"},
  {n:"03",t:"伴走型のサポート",tx:"納品して終わりではなく、継続的に改善・運用をサポート。人と職場を一緒に育てていく関係を大切にします。"},
];

function _useNav(cls){
  useEffect(()=>{
    const n=document.querySelector('.'+cls);
    if(!n)return;
    const fn=()=>n.classList.toggle('sc',window.scrollY>40);
    window.addEventListener('scroll',fn,{passive:true});
    return()=>window.removeEventListener('scroll',fn);
  },[]);
}
function _useSR(){
  useEffect(()=>{
    const els=document.querySelectorAll('.sr');
    const io=new IntersectionObserver(e=>{
      e.forEach(x=>{if(x.isIntersecting){x.target.classList.add('visible');io.unobserve(x.target);}});
    },{threshold:.1});
    els.forEach(el=>io.observe(el));
    return()=>io.disconnect();
  });
}
const Frm=({cls,btnCls,btnLabel="送信する →"})=>{
  const[s,setS]=useState(false);
  if(s)return<p style={{opacity:.45,fontSize:14,paddingTop:16,fontFamily:"'Noto Sans JP',sans-serif"}}>ありがとうございます！3営業日以内にご連絡いたします。</p>;
  return(
    <form className={`${cls}-form`} onSubmit={e=>{e.preventDefault();setS(true);}}>
      <div className="fr"><label>お名前</label><input type="text" placeholder="山田 太郎" required/></div>
      <div className="fr"><label>会社名</label><input type="text" placeholder="株式会社〇〇"/></div>
      <div className="fr"><label>メールアドレス</label><input type="email" placeholder="your@email.com" required/></div>
      <div className="fr"><label>お問い合わせ種別</label>
        <select><option>選択してください</option><option>アプリ開発について</option><option>業務効率化・DXについて</option><option>AI活用について</option><option>セミナー・研修について</option><option>その他</option></select>
      </div>
      <div className="fr"><label>お問い合わせ内容</label><textarea placeholder="ざっくりした内容で大丈夫です..."></textarea></div>
      <button type="submit" className={btnCls}>{btnLabel}</button>
    </form>
  );
};

/* ═══════════════════════════════════════════
   P5 SPECTRAL
   Chromatic mesh canvas · custom cursor
   DM Serif Display + Outfit
═══════════════════════════════════════════ */
const P5Spectral = ({ cta, tagline }) => {
  const cursorDot = useRef(null);
  const cursorRing = useRef(null);
  _useNav('p5x-nav'); _useSR();

  // Custom cursor
  useEffect(() => {
    const dot = cursorDot.current;
    const ring = cursorRing.current;
    if (!dot || !ring) return;
    let rx=0,ry=0,mx=0,my=0,raf;
    const move = e => { mx=e.clientX; my=e.clientY; };
    window.addEventListener('mousemove', move);
    const tick = () => {
      rx += (mx-rx)*.18; ry += (my-ry)*.18;
      if(dot){ dot.style.transform=`translate(${mx}px,${my}px)`; }
      if(ring){ ring.style.transform=`translate(${rx}px,${ry}px)`; }
      raf=requestAnimationFrame(tick);
    };
    tick();
    const on = () => ring && ring.classList.add('hover');
    const off = () => ring && ring.classList.remove('hover');
    document.querySelectorAll('button,a').forEach(el=>{el.addEventListener('mouseenter',on);el.addEventListener('mouseleave',off);});
    return () => { cancelAnimationFrame(raf); window.removeEventListener('mousemove',move); };
  }, []);

  // Canvas: flowing chromatic mesh
  useEffect(() => {
    const cv = document.getElementById('p5x-cv');
    if (!cv) return;
    const ctx = cv.getContext('2d');
    let raf, t=0, W, H, mx=0.5, my=0.5, tmx=0.5, tmy=0.5;
    const rs = () => { W=cv.width=cv.offsetWidth; H=cv.height=cv.offsetHeight; };
    rs();
    const ro = new ResizeObserver(rs); ro.observe(cv);
    window.addEventListener('mousemove', e=>{ mx=e.clientX/window.innerWidth; my=e.clientY/window.innerHeight; });

    // Grid of mesh points
    const COLS=14, ROWS=9;
    const pts = [];
    for(let r=0;r<=ROWS;r++) for(let c=0;c<=COLS;c++)
      pts.push({bx:c/COLS, by:r/ROWS, ph:Math.random()*Math.PI*2, phY:Math.random()*Math.PI*2,
        fx:.6+Math.random()*.8, fy:.5+Math.random()*.7, ax:.018+Math.random()*.014, ay:.012+Math.random()*.012});

    // Color palette: chromatic
    const palettes = [
      [[60,20,120],[120,20,180],[200,60,200],[60,120,220]],  // violet
      [[20,80,160],[40,160,220],[20,200,200],[80,100,220]],  // cyan
      [[80,20,160],[160,20,120],[220,60,180],[120,20,200]],  // magenta
    ];
    let palIdx=0, palT=0;

    const lerp=(a,b,t)=>a+(b-a)*t;
    const lerpCol=(a,b,t)=>a.map((v,i)=>Math.round(lerp(v,b[i],t)));

    const draw = () => {
      t+=.006; palT+=.003;
      tmx+=(mx-tmx)*.04; tmy+=(my-tmy)*.04;
      ctx.clearRect(0,0,W,H);
      // Vignette
      const vg=ctx.createRadialGradient(W*.5,H*.5,0,W*.5,H*.5,Math.max(W,H)*.75);
      vg.addColorStop(0,'rgba(2,2,2,0)'); vg.addColorStop(1,'rgba(2,2,2,.95)');
      ctx.fillStyle=vg; ctx.fillRect(0,0,W,H);

      // Animated mesh quads
      const palA=palettes[palIdx%3]; const palB=palettes[(palIdx+1)%3];
      const pt=Math.sin(palT)*.5+.5;
      for(let r=0;r<ROWS;r++){
        for(let c=0;c<COLS;c++){
          const i=r*(COLS+1)+c;
          const get=(idx)=>{
            const p=pts[idx];
            const mx2=(tmx-.5)*.04, my2=(tmy-.5)*.04;
            return{
              x:(p.bx+Math.sin(t*p.fx+p.ph)*p.ax+mx2)*W,
              y:(p.by+Math.cos(t*p.fy+p.phY)*p.ay+my2)*H
            };
          };
          const tl=get(i), tr=get(i+1), bl=get(i+COLS+1), br=get(i+COLS+2);
          const fi=(r/ROWS+c/COLS+t*.15)%(1);
          const ci=Math.floor(fi*palA.length)%palA.length;
          const ci2=(ci+1)%palA.length;
          const cf=fi*palA.length-Math.floor(fi*palA.length);
          const col1=lerpCol(lerpCol(palA[ci],palB[ci],pt),lerpCol(palA[ci2],palB[ci2],pt),cf);
          const alp=(Math.sin(t*.3+r*.6+c*.4)*.5+.5)*.28+.04;
          ctx.beginPath();
          ctx.moveTo(tl.x,tl.y); ctx.lineTo(tr.x,tr.y);
          ctx.lineTo(br.x,br.y); ctx.lineTo(bl.x,bl.y);
          ctx.closePath();
          const cx2=(tl.x+br.x)/2, cy2=(tl.y+br.y)/2;
          const grd=ctx.createRadialGradient(cx2,cy2,0,cx2,cy2,Math.max(W/COLS,H/ROWS));
          grd.addColorStop(0,`rgba(${col1[0]},${col1[1]},${col1[2]},${alp})`);
          grd.addColorStop(1,`rgba(${col1[0]},${col1[1]},${col1[2]},0)`);
          ctx.fillStyle=grd; ctx.fill();
        }
      }
      if(palT>Math.PI) { palIdx++; palT=0; }

      // Bright lines connecting mesh points
      for(let r=0;r<=ROWS;r++){
        for(let c=0;c<=COLS;c++){
          const i=r*(COLS+1)+c; const p=pts[i];
          const mx2=(tmx-.5)*.04, my2=(tmy-.5)*.04;
          const x=(p.bx+Math.sin(t*p.fx+p.ph)*p.ax+mx2)*W;
          const y=(p.by+Math.cos(t*p.fy+p.phY)*p.ay+my2)*H;
          if(c<COLS){
            const ni=i+1; const p2=pts[ni];
            const x2=(p2.bx+Math.sin(t*p2.fx+p2.ph)*p2.ax+mx2)*W;
            const y2=(p2.by+Math.cos(t*p2.fy+p2.phY)*p2.ay+my2)*H;
            ctx.beginPath(); ctx.moveTo(x,y); ctx.lineTo(x2,y2);
            ctx.strokeStyle='rgba(240,236,232,.045)'; ctx.lineWidth=.5; ctx.stroke();
          }
          if(r<ROWS){
            const ni2=i+COLS+1; const p3=pts[ni2];
            const x3=(p3.bx+Math.sin(t*p3.fx+p3.ph)*p3.ax+mx2)*W;
            const y3=(p3.by+Math.cos(t*p3.fy+p3.phY)*p3.ay+my2)*H;
            ctx.beginPath(); ctx.moveTo(x,y); ctx.lineTo(x3,y3);
            ctx.strokeStyle='rgba(240,236,232,.045)'; ctx.lineWidth=.5; ctx.stroke();
          }
          // Dot at intersection
          const gl=ctx.createRadialGradient(x,y,0,x,y,5);
          gl.addColorStop(0,'rgba(240,236,232,.25)'); gl.addColorStop(1,'transparent');
          ctx.beginPath(); ctx.arc(x,y,5,0,Math.PI*2); ctx.fillStyle=gl; ctx.fill();
        }
      }
      raf=requestAnimationFrame(draw);
    };
    draw();
    return()=>{ cancelAnimationFrame(raf); ro.disconnect(); };
  }, []);

  const mq = [..._svcs.map(s=>s.name),'IT・AIソリューション','伴走型サポート','スモールスタート','ゆるくしっかり'];
  const mqI = [...mq,...mq];

  return (
    <div className="p5x">
      {/* Custom cursor */}
      <div className="p5x-cursor">
        <div ref={cursorDot} className="p5x-cursor-dot"></div>
        <div ref={cursorRing} className="p5x-cursor-ring"></div>
      </div>

      <nav className="p5x-nav">
        <div className="p5x-logo">ゆるハックラボ</div>
        <div className="p5x-nl"><a href="#">Services</a><a href="#">About</a><a href="#">Contact</a><a href="#" className="p5x-cta">{cta}</a></div>
      </nav>

      {/* HERO: Chromatic mesh canvas */}
      <section className="p5x-hero">
        <canvas id="p5x-cv"></canvas>
        <div className="p5x-hero-overlay"></div>
        <div className="p5x-hero-content">
          <div className="p5x-pretitle">YuruHack Lab — 2025</div>
          <div className="p5x-title">
            <div className="p5x-tl"><span className="p5x-tw">ゆるく、</span></div>
            <div className="p5x-tl"><span className="p5x-tw italic">でもしっかり</span></div>
            <div className="p5x-tl"><span className="p5x-tw">ハックする</span></div>
          </div>
          <p className="p5x-sub">{tagline}。アプリ開発・業務DX・AI活用・セミナーを通じて、あなたのビジネスをアップデートします。</p>
          <div className="p5x-btns">
            <button className="p5x-btn">{cta}</button>
            <button className="p5x-bto">SERVICES ↓</button>
          </div>
        </div>
        <div className="p5x-scroll-hint">
          <span className="p5x-scroll-lbl">SCROLL</span>
          <div className="p5x-scroll-line"></div>
        </div>
      </section>

      {/* MARQUEE */}
      <div className="p5x-mq">
        <div className="p5x-mq-inner">
          {mqI.map((t,i)=><span key={i} className="p5x-mq-item">{t}<span className="p5x-mq-dot"> · </span></span>)}
        </div>
      </div>

      {/* SERVICES */}
      <section className="p5x-svc">
        <div className="p5x-svch sr">
          <div><div className="p5x-stag">SERVICES</div><div className="p5x-stitle">あなたの会社にあった<br/><em>IT・AI活用</em></div></div>
          <div style={{fontFamily:"'Noto Sans JP',sans-serif",fontSize:13,color:'rgba(240,236,232,.28)',lineHeight:2,maxWidth:260,textAlign:'right'}}>小さなツールから本格的なシステムまで。ビジネスの課題に合わせて柔軟に対応します。</div>
        </div>
        <div className="p5x-sg">
          {_svcs.map((s,i)=>(
            <div key={s.n} className={`p5x-sc sr sr-d${i+1}`}>
              <div className="p5x-sc-num">{s.n}</div>
              <div className="p5x-sc-name">{s.name}</div>
              <div className="p5x-sc-desc">{s.desc}</div>
              <div className="p5x-sc-tags">{s.tags.map(t=><span key={t} className="p5x-sc-tag">{t}</span>)}</div>
            </div>
          ))}
        </div>
      </section>

      {/* WHY */}
      <section className="p5x-why">
        <div className="p5x-why-top sr">
          <div className="p5x-why-title">ゆるハックラボが<br/>選ばれる<em>理由</em></div>
          <div className="p5x-why-sub">技術よりも人への向き合い方が、私たちの強みです。</div>
        </div>
        <div className="p5x-wg">
          {_rsns.map((r,i)=>(
            <div key={r.n} className={`p5x-wc sr sr-d${i+1}`}>
              <div className="p5x-wbg">{r.n}</div>
              <div className="p5x-wn">{r.n}</div>
              <div className="p5x-wt">{r.t}</div>
              <div className="p5x-wtx">{r.tx}</div>
            </div>
          ))}
        </div>
      </section>

      {/* CONTACT */}
      <section className="p5x-ct">
        <div className="p5x-ctag sr">CONTACT</div>
        <h2 className="sr sr-d1">まず、<em>話して</em>みませんか</h2>
        <p className="sr sr-d2">ざっくりした相談でも大歓迎です。フォームからお気軽にどうぞ。</p>
        <div className="p5x-cti sr sr-d3"><Frm cls="p5x" btnCls="p5x-btn"/></div>
      </section>
      <footer className="p5x-ft">
        <span className="p5x-ftl">ゆるハックラボ</span>
        <span className="p5x-ftc">© 2025 YuruHack Lab. All rights reserved.</span>
      </footer>
    </div>
  );
};

/* ═══════════════════════════════════════════
   P9 BIKE BEAR INSPIRED
   Mouse-reactive canvas · Yellow accent
   Syne 800 + Noto Sans JP
═══════════════════════════════════════════ */
const P9BikeBear = ({ cta, tagline }) => {
  _useSR();

  // Mouse-reactive canvas
  useEffect(()=>{
    const cv=document.getElementById('p9bb-cv');
    if(!cv) return;
    const ctx=cv.getContext('2d');
    let raf, t=0, mx=0.4, my=0.4, tmx=0.4, tmy=0.4;
    const rs=()=>{ cv.width=cv.offsetWidth; cv.height=cv.offsetHeight; };
    rs(); const ro=new ResizeObserver(rs); ro.observe(cv);

    const onM=e=>{ const r=cv.getBoundingClientRect(); mx=(e.clientX-r.left)/r.width; my=(e.clientY-r.top)/r.height; };
    cv.parentElement.addEventListener('mousemove',onM);

    // Morph blobs
    const blobs=[
      {bx:.72,by:.38,spd:.008,al:.18,size:.38,col:'255,229,0',ph:0},
      {bx:.65,by:.65,spd:.006,al:.12,size:.28,col:'255,229,0',ph:1.2},
      {bx:.82,by:.52,spd:.011,al:.09,size:.22,col:'255,200,0',ph:2.4},
      {bx:.55,by:.3, spd:.007,al:.07,size:.18,col:'255,229,0',ph:3.6},
    ];

    const draw=()=>{
      const W=cv.width,H=cv.height; t+=.014;
      tmx+=(mx-tmx)*.055; tmy+=(my-tmy)*.055;
      ctx.clearRect(0,0,W,H);
      blobs.forEach((b,i)=>{
        const dx=(tmx-b.bx)*(.6+i*.12), dy=(tmy-b.by)*(.6+i*.12);
        const cx=(b.bx+dx+Math.sin(t*b.spd*8+b.ph)*.04)*W;
        const cy=(b.by+dy+Math.cos(t*b.spd*6+b.ph)*.03)*H;
        const r=b.size*Math.min(W,H)*(1+Math.sin(t*.8+b.ph)*.08);
        // Morph blob with multiple radial layers
        for(let layer=0;layer<3;layer++){
          const lr=r*(1-layer*.22);
          const la=b.al*(1-layer*.3);
          const ang=t*b.spd*3+layer*1.2+b.ph;
          const ox=Math.cos(ang)*lr*.18, oy=Math.sin(ang*1.3)*lr*.14;
          const grd=ctx.createRadialGradient(cx+ox,cy+oy,0,cx+ox,cy+oy,lr);
          grd.addColorStop(0,`rgba(${b.col},${la})`);
          grd.addColorStop(.5,`rgba(${b.col},${la*.5})`);
          grd.addColorStop(1,`rgba(${b.col},0)`);
          ctx.beginPath();
          // Morph ellipse
          ctx.save(); ctx.translate(cx+ox,cy+oy);
          ctx.scale(1+Math.sin(t*.7+b.ph)*.12, 1+Math.cos(t*.9+b.ph)*.1);
          ctx.arc(0,0,lr,0,Math.PI*2);
          ctx.fillStyle=grd; ctx.fill(); ctx.restore();
        }
      });
      // Floating particles
      for(let i=0;i<40;i++){
        const px=(Math.sin(t*.3+i*2.1)*0.4+0.5)*W;
        const py=(Math.cos(t*.25+i*1.7)*0.35+0.5)*H;
        const pr=Math.sin(t*.5+i)*.5+1.5;
        const pa=Math.abs(Math.sin(t*.4+i*.5))*.18+.04;
        ctx.beginPath(); ctx.arc(px,py,pr,0,Math.PI*2);
        ctx.fillStyle=`rgba(255,229,0,${pa})`; ctx.fill();
      }
      raf=requestAnimationFrame(draw);
    };
    draw();
    return()=>{ cancelAnimationFrame(raf); ro.disconnect(); cv.parentElement.removeEventListener('mousemove',onM); };
  },[]);

  const mq=[..._svcs.map(s=>s.name),'AI活用','DX推進','ノーコード','RPA','生成AI','ChatGPT','伴走型','スモールスタート'];
  const mqI=[...mq,...mq,...mq];

  return(
    <div className="p9bb">
      <nav className="p9bb-nav">
        <div className="p9bb-logo">ゆるハックラボ</div>
        <div className="p9bb-nl"><a href="#">Services</a><a href="#">About</a><a href="#">Contact</a><a href="#" className="p9bb-cta">{cta}</a></div>
      </nav>

      {/* HERO: Mouse-reactive canvas */}
      <section className="p9bb-hero">
        <canvas id="p9bb-cv" style={{position:'absolute',inset:0,width:'100%',height:'100%',zIndex:0,pointerEvents:'none'}}></canvas>
        <div className="p9bb-hero-content">
          <div className="p9bb-kicker">AI × DX × アプリ開発 — 2025</div>
          <div className="p9bb-title">
            ゆるく、
            <span className="p9bb-title-accent">ハックする</span>
          </div>
          <div className="p9bb-sub">{tagline}。あなたが本来するべきことに、時間を使えるように。</div>
          <div className="p9bb-hbtns">
            <button className="p9bb-btn">{cta}</button>
            <button className="p9bb-bto">SERVICES ↓</button>
          </div>
        </div>
        <div className="p9bb-hero-counter">
          <div className="p9bb-hc-val">2025</div>
          <div className="p9bb-hc-label">SINCE LAUNCH</div>
        </div>
      </section>

      {/* MARQUEE */}
      <div className="p9bb-mq">
        <div className="p9bb-mqi">{mqI.map((t,i)=><span key={i} className="p9bb-mqitem">{t}<span className="p9bb-mqdot"> ✦ </span></span>)}</div>
      </div>

      {/* SERVICES */}
      <section className="p9bb-svc">
        <div className="p9bb-svch sr">
          <h2>IT・AI<br/>SERVICES</h2>
          <p>小さなツールから本格的なシステムまで。ビジネスの課題に合わせて柔軟に対応します。</p>
        </div>
        <div className="p9bb-sg">
          {_svcs.map((s,i)=>(
            <div key={s.n} className={`p9bb-sc sr sr-d${i+1}`}>
              <div className="p9bb-sc-hover-bg"></div>
              <div className="p9bb-sc-num">{s.n}</div>
              <div className="p9bb-sc-name">{s.name}</div>
              <div className="p9bb-sc-desc">{s.desc}</div>
              <div className="p9bb-sc-arrow">→</div>
            </div>
          ))}
        </div>
      </section>

      {/* WHY */}
      <section className="p9bb-why">
        <div className="p9bb-wh">
          <div>
            <div className="p9bb-wh-tag">WHY US</div>
            <h2>選ばれる<br/>理由</h2>
          </div>
          <div className="p9bb-wh-accent"></div>
        </div>
        {_rsns.map((r,i)=>(
          <div key={r.n} className={`p9bb-wi sr sr-d${i+1}`}>
            <div className="p9bb-wn">{r.n}</div>
            <div className="p9bb-wt">{r.t}</div>
            <div className="p9bb-wtx">{r.tx}</div>
          </div>
        ))}
      </section>

      {/* CONTACT */}
      <section className="p9bb-ct">
        <div className="p9bb-ctl sr">
          <h2>まず、話して<br/>みませんか</h2>
          <p>ざっくりした相談でも大歓迎です。フォームからお気軽にどうぞ。</p>
        </div>
        <div className="p9bb-ctr sr sr-d2"><Frm cls="p9bb" btnCls="p9bb-bsub"/></div>
      </section>
      <footer className="p9bb-ft">
        <span className="p9bb-ftl">ゆるハックラボ</span>
        <span className="p9bb-ftc">© 2025 YuruHack Lab. All rights reserved.</span>
      </footer>
    </div>
  );
};

Object.assign(window, { P5Spectral, P9BikeBear });
