// cube-color.jsx — Octant Cube colour-scheme exploration
// Form is fixed (the 01 mark); only colour varies. Exports: SCHEMES, SchemeCard.

const _AX=[0.8660254,0.5], _AY=[-0.8660254,0.5], _AZ=[0,-1];
function ip(i,j,k,s,ox,oy){return [ox+(i*_AX[0]+j*_AY[0]+k*_AZ[0])*s, oy+(i*_AX[1]+j*_AY[1]+k*_AZ[1])*s];}
function pl(pts){return pts.map(p=>p[0].toFixed(2)+','+p[1].toFixed(2)).join(' ');}
function mxFaces(i0,j0,k0,d,s,ox,oy){
  const P=(i,j,k)=>ip(i,j,k,s,ox,oy); const i1=i0+d,j1=j0+d,k1=k0+d;
  return {
    top:  pl([P(i0,j0,k1),P(i1,j0,k1),P(i1,j1,k1),P(i0,j1,k1)]),
    right:pl([P(i1,j0,k0),P(i1,j0,k1),P(i1,j1,k1),P(i1,j1,k0)]),
    left: pl([P(i0,j1,k0),P(i0,j1,k1),P(i1,j1,k1),P(i1,j1,k0)]),
  };
}
// shade trio from an oklch base
function shades(L,C,H){
  return {
    t:`oklch(${(L+0.105).toFixed(3)} ${(C*0.9).toFixed(3)} ${H-2})`,
    r:`oklch(${L.toFixed(3)} ${C.toFixed(3)} ${H})`,
    l:`oklch(${(L-0.09).toFixed(3)} ${(C).toFixed(3)} ${H+5})`,
  };
}
// two-hue trio for gradient schemes (top hue -> bottom hue)
function shades2(L,C,H1,H2){
  return {
    t:`oklch(${(L+0.105).toFixed(3)} ${(C*0.9).toFixed(3)} ${H1})`,
    r:`oklch(${L.toFixed(3)} ${C.toFixed(3)} ${((H1+H2)/2).toFixed(0)})`,
    l:`oklch(${(L-0.09).toFixed(3)} ${C.toFixed(3)} ${H2})`,
  };
}

// The mark. Colours fully explicit.
function OctantCube({ px=120, w, h, vb, svgId, line, t, r, l, lw=2.4 }){
  const s=20.5, ox=60, oy=60;
  const P=(i,j,k)=>ip(i,j,k,s,ox,oy);
  const sil = pl([P(0,0,2),P(2,0,2),P(2,0,0),P(2,2,0),P(0,2,0),P(0,2,2)]);
  const lit = mxFaces(1,1,1,1,s,ox,oy);
  const E=(a,b)=><line x1={a[0]} y1={a[1]} x2={b[0]} y2={b[1]} stroke={line} strokeWidth={lw} strokeLinecap="round"/>;
  const G=(a,b)=><line x1={a[0]} y1={a[1]} x2={b[0]} y2={b[1]} stroke={line} strokeWidth={1.4}/>;
  return <svg id={svgId} viewBox={vb||"0 0 120 120"} width={w||px} height={h||px} style={{display:'block', overflow:'visible'}}>
    <g opacity="0.14">
      {G(P(1,0,2),P(1,2,2))}{G(P(0,1,2),P(2,1,2))}
      {G(P(2,0,1),P(2,2,1))}{G(P(2,1,0),P(2,1,2))}
      {G(P(0,2,1),P(2,2,1))}{G(P(1,2,0),P(1,2,2))}
    </g>
    <polygon points={lit.left}  fill={l} />
    <polygon points={lit.right} fill={r} />
    <polygon points={lit.top}   fill={t} />
    {E(P(2,2,2),P(2,0,2))}{E(P(2,2,2),P(0,2,2))}{E(P(2,2,2),P(2,2,0))}
    <polygon points={sil} fill="none" stroke={line} strokeWidth={lw} strokeLinejoin="round"/>
  </svg>;
}

const INK   = 'oklch(0.255 0.022 264)';
const PAPER = 'oklch(0.987 0.004 250)';

// The four finalists. base accent (L,C,H) + surfaces. flags: duotone, colorLines, grad.
const SCHEMES = [
  { id:'blue',     group:'keep', name:'Spatial Blue', spec:'oklch 0.60 · 0.15 · 252', L:0.60, C:0.152, H:252, darkBg:'oklch(0.205 0.025 262)' },
  { id:'slate',    group:'keep', name:'Slate Blue',   spec:'muted · calm',           L:0.585,C:0.085, H:252, darkBg:'oklch(0.205 0.018 258)' },
  { id:'steel',    group:'keep', name:'Steel',        spec:'blue-tinted mono',       L:0.55, C:0.045, H:255, darkBg:'oklch(0.205 0.012 258)' },
  { id:'sparkind', group:'keep', name:'Mono · Indigo spark', spec:'black brand, lit octant', L:0.6, C:0.155, H:276, duotone:true, darkBg:'oklch(0.195 0.03 276)' },
];

function Tile({ bg, rounded, children, label }){
  return <div style={{display:'flex', flexDirection:'column', alignItems:'center', gap:9}}>
    <div style={{width:118, height:118, borderRadius:rounded?27:10, background:bg,
      display:'flex', alignItems:'center', justifyContent:'center',
      border: bg===PAPER ? '1px solid oklch(0 0 0/0.07)':'none',
      boxShadow: rounded?'0 2px 6px rgba(0,0,0,0.12)':'none'}}>
      {children}
    </div>
    <span style={{fontFamily:'"Space Mono",monospace', fontSize:8.5, letterSpacing:'0.13em',
      color:'oklch(0.52 0.01 262)', textTransform:'uppercase'}}>{label}</span>
  </div>;
}

function Wordmark({ scale=1, color=INK, sub=true }){
  return <div style={{display:'flex', flexDirection:'column', gap:6*scale}}>
    <div style={{fontFamily:'Sora, sans-serif', fontWeight:700, fontSize:22*scale,
      letterSpacing:'0.01em', color, display:'flex', gap:'0.42em', lineHeight:1}}>
      <span>OCTANT</span><span style={{fontWeight:300}}>SYSTEMS</span>
    </div>
    {sub && <div style={{fontFamily:'"Space Mono", monospace', fontSize:8*scale, letterSpacing:'0.2em',
      color, opacity:0.6, textTransform:'uppercase', lineHeight:1.5}}>
      The operating system for spatial intelligence
    </div>}
  </div>;
}

function SchemeCard({ s, lockup }){
  const acc = s.grad ? shades2(s.L, s.C, s.grad[0], s.grad[1]) : shades(s.L, s.C, s.H);
  const base = `oklch(${s.L} ${s.C} ${s.H})`;
  const whiteTrio = { t:'oklch(1 0 0/0.96)', r:'oklch(1 0 0/0.66)', l:'oklch(1 0 0/0.42)' };
  const accDark = s.grad ? shades2(Math.min(0.8,s.L+0.07), s.C, s.grad[0], s.grad[1])
                         : shades(Math.min(0.78,s.L+0.07), s.C, s.H);
  const lineLight = s.colorLines ? `oklch(${(s.L-0.07).toFixed(3)} ${s.C} ${s.H})` : INK;
  // third tile: duotone -> black icon with a lit octant; else solid-accent icon.
  const thirdBg = s.duotone ? 'oklch(0.205 0.022 262)' : base;
  return (
    <div style={{background:PAPER, height:'100%', display:'flex', flexDirection:'column',
      fontFamily:'Sora, sans-serif', color:INK}}>
      <div style={{padding:'18px 22px 16px', borderBottom:'1px solid oklch(0 0 0/0.07)',
        display:'flex', alignItems:'baseline', justifyContent:'space-between'}}>
        <span style={{fontSize:17, fontWeight:600, letterSpacing:'-0.01em'}}>{s.name}</span>
        <span style={{fontFamily:'"Space Mono",monospace', fontSize:9.5, color:'oklch(0.52 0.01 262)'}}>{s.spec}</span>
      </div>
      <div style={{padding:'26px 22px 24px', display:'flex', gap:18, justifyContent:'center'}}>
        <Tile bg={PAPER} label="on light">
          <OctantCube px={92} line={lineLight} t={acc.t} r={acc.r} l={acc.l} />
        </Tile>
        <Tile bg={s.darkBg} label="on dark">
          <OctantCube px={92} line={PAPER} t={accDark.t} r={accDark.r} l={accDark.l} />
        </Tile>
        <Tile bg={thirdBg} rounded label={s.duotone?'app icon':'app icon'}>
          {s.duotone
            ? <OctantCube px={86} line={'oklch(1 0 0/0.95)'} t={accDark.t} r={accDark.r} l={accDark.l} />
            : <OctantCube px={86} line={'oklch(1 0 0/0.95)'} t={whiteTrio.t} r={whiteTrio.r} l={whiteTrio.l} />}
        </Tile>
      </div>
      {lockup && (
        <div style={{borderTop:'1px solid oklch(0 0 0/0.07)', padding:'20px 24px 22px',
          display:'flex', alignItems:'center', gap:16}}>
          <OctantCube px={50} line={lineLight} t={acc.t} r={acc.r} l={acc.l} />
          <Wordmark scale={0.96} />
        </div>
      )}
    </div>
  );
}

Object.assign(window, { SCHEMES, SchemeCard, OctantCube, Wordmark, shades, shades2, OC_INK: INK, OC_PAPER: PAPER });
