// tweaks-app.jsx
// Tweaks panel for the CAFE workshop mock.
// All values flow through CSS custom properties on :root so changes are
// instant and don't require re-rendering DOM.

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "classic",
  "bg": "#F6F1E8",
  "text": "#2A2520",
  "heading": "#1F1A14",
  "accent": "#9A6B3F",
  "rule": "#D9CDB8",
  "footerBg": "#1F1A14",
  "fontPair": "serifSans",
  "baseSize": 16,
  "headingWeight": 500,
  "headingTracking": -2,
  "logoTracking": 32,
  "contentWidth": 1080,
  "sectionGap": 6,
  "radius": 4,
  "heroHeight": 560,
  "heroMono": 0,
  "heroDim": 35,
  "heroAlign": "center",
  "kicker": "since 2018  /  est. local",
  "heroTitle": "ゆっくりと、",
  "heroTitleEm": "好きなだけ。",
  "heroSub": "豆の香りと静かな時間。今日の一杯を、心地よい場所で。",
  "menuRule": "dotted",
  "menuRowGap": 14,
  "cardOpacity": 100
}/*EDITMODE-END*/;

const PALETTES = {
  classic: { bg:"#F6F1E8", text:"#2A2520", heading:"#1F1A14", accent:"#9A6B3F", rule:"#D9CDB8", footerBg:"#1F1A14" },
  cream:   { bg:"#FBF6EC", text:"#3B2F22", heading:"#2A1E10", accent:"#C68A4E", rule:"#E8DBC2", footerBg:"#2A1E10" },
  mist:    { bg:"#EFEEEA", text:"#2D2E2C", heading:"#16181A", accent:"#5C6B66", rule:"#D2D3CE", footerBg:"#16181A" },
  moss:    { bg:"#EEF0E7", text:"#26302A", heading:"#1A2620", accent:"#5E7A4A", rule:"#CFD6BF", footerBg:"#1A2620" },
  dark:    { bg:"#16140F", text:"#D9D2C4", heading:"#F2EBDB", accent:"#D4A36A", rule:"#3A342A", footerBg:"#0E0C09" },
};

const FONT_PAIRS = {
  serifSans: { display: "'Fraunces', serif", body: "'Inter', sans-serif" },
  serif:     { display: "'Fraunces', serif", body: "'Fraunces', serif" },
  sans:      { display: "'Inter', sans-serif", body: "'Inter', sans-serif" },
  mincho:    { display: "'Shippori Mincho', serif", body: "'Shippori Mincho', serif" },
};

function applyVars(t) {
  const r = document.documentElement.style;
  r.setProperty('--bg', t.bg);
  r.setProperty('--text', t.text);
  r.setProperty('--heading', t.heading);
  r.setProperty('--accent', t.accent);
  r.setProperty('--rule', t.rule);
  r.setProperty('--footer-bg', t.footerBg);

  const f = FONT_PAIRS[t.fontPair] || FONT_PAIRS.serifSans;
  r.setProperty('--font-display', f.display);
  r.setProperty('--font-body', f.body);

  r.setProperty('--base-size', t.baseSize + 'px');
  r.setProperty('--heading-weight', String(t.headingWeight));
  r.setProperty('--heading-tracking', (t.headingTracking / 100) + 'em');
  r.setProperty('--logo-tracking', (t.logoTracking / 100) + 'em');

  r.setProperty('--content-width', t.contentWidth + 'px');
  r.setProperty('--section-gap', t.sectionGap + 'rem');
  r.setProperty('--radius', t.radius + 'px');

  r.setProperty('--hero-height', t.heroHeight + 'px');
  r.setProperty('--hero-mono', (t.heroMono / 100));
  r.setProperty('--hero-dim', (t.heroDim / 100));
  const align = t.heroAlign === 'top' ? 'flex-start'
              : t.heroAlign === 'bottom' ? 'flex-end' : 'center';
  r.setProperty('--hero-align', align);

  r.setProperty('--menu-rule', t.menuRule === 'none' ? 'none' : t.menuRule);
  r.setProperty('--menu-row-gap', t.menuRowGap + 'px');
  r.setProperty('--card-opacity', (t.cardOpacity / 100));
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // Apply CSS variables on every change.
  React.useEffect(() => { applyVars(t); }, [t]);

  // Apply preset → also overwrite individual color values so pickers reflect.
  const applyPreset = (name) => {
    const p = PALETTES[name];
    if (!p) return;
    setTweak({ palette: name, ...p });
  };

  // Hero text is rendered into the existing markup so the editorial layout
  // and CSS stay declarative.
  React.useEffect(() => {
    const set = (id, txt) => { const el = document.getElementById(id); if (el) el.textContent = txt; };
    set('hero-kicker', t.kicker);
    set('hero-title', t.heroTitle);
    set('hero-title-em', t.heroTitleEm);
    set('hero-sub', t.heroSub);
  }, [t.kicker, t.heroTitle, t.heroTitleEm, t.heroSub]);

  return (
    <TweaksPanel title="Tweaks">
      <TweakSection label="Palette" />
      <TweakSelect label="Preset" value={t.palette}
        options={[
          {value:'classic', label:'Classic'},
          {value:'cream',   label:'Cream'},
          {value:'mist',    label:'Mist'},
          {value:'moss',    label:'Moss'},
          {value:'dark',    label:'Dark'},
        ]}
        onChange={applyPreset} />
      <TweakColor label="Background" value={t.bg}      onChange={(v)=>setTweak('bg', v)} />
      <TweakColor label="Body"       value={t.text}    onChange={(v)=>setTweak('text', v)} />
      <TweakColor label="Heading"    value={t.heading} onChange={(v)=>setTweak('heading', v)} />
      <TweakColor label="Accent"     value={t.accent}  onChange={(v)=>setTweak('accent', v)} />
      <TweakColor label="Rule"       value={t.rule}    onChange={(v)=>setTweak('rule', v)} />
      <TweakColor label="Footer bg"  value={t.footerBg} onChange={(v)=>setTweak('footerBg', v)} />

      <TweakSection label="Typography" />
      <TweakRadio label="Pair" value={t.fontPair}
        options={[
          {value:'serifSans', label:'Serif+Sans'},
          {value:'serif',     label:'Serif'},
          {value:'sans',      label:'Sans'},
          {value:'mincho',    label:'明朝'},
        ]}
        onChange={(v)=>setTweak('fontPair', v)} />
      <TweakSlider label="Base size"   value={t.baseSize}        min={13} max={20} unit="px"
                   onChange={(v)=>setTweak('baseSize', v)} />
      <TweakSlider label="Heading wt"  value={t.headingWeight}   min={300} max={700} step={100}
                   onChange={(v)=>setTweak('headingWeight', v)} />
      <TweakSlider label="Heading trk" value={t.headingTracking} min={-3} max={15} unit="/100em"
                   onChange={(v)=>setTweak('headingTracking', v)} />
      <TweakSlider label="Logo trk"    value={t.logoTracking}    min={0} max={80} unit="/100em"
                   onChange={(v)=>setTweak('logoTracking', v)} />

      <TweakSection label="Layout" />
      <TweakSlider label="Content width" value={t.contentWidth} min={720} max={1280} unit="px"
                   onChange={(v)=>setTweak('contentWidth', v)} />
      <TweakSlider label="Section gap"   value={t.sectionGap}   min={3} max={12} step={0.5} unit="rem"
                   onChange={(v)=>setTweak('sectionGap', v)} />
      <TweakSlider label="Radius"        value={t.radius}       min={0} max={28} unit="px"
                   onChange={(v)=>setTweak('radius', v)} />

      <TweakSection label="Hero" />
      <TweakSlider label="Height"      value={t.heroHeight} min={320} max={820} unit="px"
                   onChange={(v)=>setTweak('heroHeight', v)} />
      <TweakSlider label="Monochrome"  value={t.heroMono}   min={0} max={100} unit="%"
                   onChange={(v)=>setTweak('heroMono', v)} />
      <TweakSlider label="Dim"         value={t.heroDim}    min={0} max={75} unit="%"
                   onChange={(v)=>setTweak('heroDim', v)} />
      <TweakRadio  label="Align" value={t.heroAlign}
        options={[{value:'top',label:'Top'},{value:'center',label:'Mid'},{value:'bottom',label:'Btm'}]}
        onChange={(v)=>setTweak('heroAlign', v)} />
      <TweakText label="Kicker"   value={t.kicker}      onChange={(v)=>setTweak('kicker', v)} />
      <TweakText label="Title"    value={t.heroTitle}   onChange={(v)=>setTweak('heroTitle', v)} />
      <TweakText label="Title em" value={t.heroTitleEm} onChange={(v)=>setTweak('heroTitleEm', v)} />
      <TweakText label="Sub"      value={t.heroSub}     onChange={(v)=>setTweak('heroSub', v)} />

      <TweakSection label="Menu" />
      <TweakRadio  label="Rule" value={t.menuRule}
        options={[
          {value:'dotted', label:'Dot'},
          {value:'dashed', label:'Dash'},
          {value:'solid',  label:'Solid'},
          {value:'none',   label:'None'},
        ]}
        onChange={(v)=>setTweak('menuRule', v)} />
      <TweakSlider label="Row height"  value={t.menuRowGap}  min={6} max={28} unit="px"
                   onChange={(v)=>setTweak('menuRowGap', v)} />
      <TweakSlider label="Card opacity" value={t.cardOpacity} min={40} max={100} unit="%"
                   onChange={(v)=>setTweak('cardOpacity', v)} />
    </TweaksPanel>
  );
}

// Mount panel into a sibling container so it doesn't disturb the document flow.
const __mount = document.getElementById('tweaks-root');
ReactDOM.createRoot(__mount).render(<App />);

// Apply once at boot so reload restores persisted state immediately.
applyVars(TWEAK_DEFAULTS);
