// tweaks-app.jsx — Tweaks panel for the Cafe Mock site.
// All adjustments flow through CSS custom properties on :root,
// updated via document.documentElement.style.setProperty().

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "classic",
  "bg": "#F6F1E8",
  "text": "#2A2622",
  "heading": "#231C16",
  "accent": "#8C6A3F",
  "rule": "#D8CDB8",
  "footerBg": "#1F1A14",
  "fontPair": "serifSans",
  "baseSize": 16,
  "headingWeight": 500,
  "headingTracking": -2,
  "logoTracking": 36,
  "contentWidth": 1120,
  "sectionGap": 6,
  "radius": 8,
  "heroHeight": 620,
  "heroMono": 0,
  "heroDark": 30,
  "heroAlign": "center",
  "kickerText": "Modern coffee, quiet hours",
  "titleText": "A small room <em>for</em> coffee, light, and time.",
  "subText": "ワークショップ用のサンプルカフェ。落ち着いた一杯と、丁寧な食卓を、毎日の延長線として。",
  "menuRule": "dotted",
  "menuRowHeight": 1.7,
  "cardOpacity": 60
}/*EDITMODE-END*/;

const PALETTES = {
  classic: { bg: "#F6F1E8", text: "#2A2622", heading: "#231C16", accent: "#8C6A3F", rule: "#D8CDB8", footerBg: "#1F1A14" },
  cream:   { bg: "#FBF6EC", text: "#3D2F22", heading: "#2C1F12", accent: "#B07B3E", rule: "#E6D9BF", footerBg: "#2C1F12" },
  mist:    { bg: "#EEF0EC", text: "#2A2E2C", heading: "#1B201E", accent: "#5C7268", rule: "#CFD6CF", footerBg: "#1B201E" },
  moss:    { bg: "#EBE9DC", text: "#2A2C20", heading: "#1E2117", accent: "#5E6A2C", rule: "#CDC9B0", footerBg: "#1E2117" },
  dark:    { bg: "#191613", text: "#D8D2C5", heading: "#F1EAD8", accent: "#C9A36A", rule: "#3A332B", footerBg: "#0E0C0A" },
};

const FONT_PAIRS = {
  serifSans: { heading: "'Fraunces', 'Shippori Mincho', Georgia, serif",  body: "'Inter', system-ui, -apple-system, 'Hiragino Kaku Gothic ProN', sans-serif" },
  serif:     { heading: "'Fraunces', 'Shippori Mincho', Georgia, serif",  body: "'Fraunces', Georgia, 'Shippori Mincho', serif" },
  sans:      { heading: "'Inter', system-ui, sans-serif",                 body: "'Inter', system-ui, -apple-system, 'Hiragino Kaku Gothic ProN', sans-serif" },
  mincho:    { heading: "'Shippori Mincho', 'Fraunces', serif",           body: "'Shippori Mincho', 'Inter', serif" },
};

function applyTweaks(t) {
  const r = document.documentElement.style;
  const p = PALETTES[t.palette] || PALETTES.classic;
  // Palette wins for color slots, but individual pickers override per key.
  // We always write through the t.* values (which the App syncs with palette changes).
  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);
  r.setProperty('--footer-text', t.bg);

  const fp = FONT_PAIRS[t.fontPair] || FONT_PAIRS.serifSans;
  r.setProperty('--font-heading', fp.heading);
  r.setProperty('--font-body', fp.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-dark', (t.heroDark / 100));
  r.setProperty('--hero-align', t.heroAlign === 'top' ? 'flex-start' : t.heroAlign === 'bottom' ? 'flex-end' : 'center');

  r.setProperty('--menu-rule-style', t.menuRule === 'none' ? 'none' : t.menuRule);
  r.setProperty('--menu-row-height', String(t.menuRowHeight));
  r.setProperty('--card-opacity', String(t.cardOpacity / 100));
}

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

  // Whenever a tweak changes, reflect it to CSS variables.
  React.useEffect(() => { applyTweaks(t); }, [t]);

  // Reflect editable hero copy into the live DOM.
  React.useEffect(() => {
    const k = document.querySelector('[data-hero-kicker]');
    const ti = document.querySelector('[data-hero-title]');
    const s = document.querySelector('[data-hero-sub]');
    if (k) k.textContent = t.kickerText;
    if (ti) ti.innerHTML = t.titleText;
    if (s) s.textContent = t.subText;
  }, [t.kickerText, t.titleText, t.subText]);

  // Palette preset → push its 6 colors into the individual pickers.
  const choosePalette = (name) => {
    const p = PALETTES[name];
    if (!p) return;
    setTweak({
      palette: name,
      bg: p.bg, text: p.text, heading: p.heading,
      accent: p.accent, rule: p.rule, footerBg: p.footerBg,
    });
  };

  return (
    <TweaksPanel title="Tweaks">
      <TweakSection label="Color preset" />
      <TweakSelect
        label="Palette"
        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={choosePalette}
      />

      <TweakSection label="Individual colors" />
      <TweakColor label="Background"    value={t.bg}        onChange={(v) => setTweak('bg', v)} />
      <TweakColor label="Body text"     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 / border" 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="Type 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} step={1} unit="px"  onChange={(v) => setTweak('baseSize', v)} />
      <TweakSlider label="Heading weight"  value={t.headingWeight}   min={300} max={700} step={100}        onChange={(v) => setTweak('headingWeight', v)} />
      <TweakSlider label="Heading tracking" value={t.headingTracking} min={-3} max={15} step={1} unit="/100em" onChange={(v) => setTweak('headingTracking', v)} />
      <TweakSlider label="Logo tracking"   value={t.logoTracking}    min={0} max={80} step={1} unit="/100em"   onChange={(v) => setTweak('logoTracking', v)} />

      <TweakSection label="Layout" />
      <TweakSlider label="Content width"   value={t.contentWidth} min={720} max={1280} step={10} 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="Corner radius"   value={t.radius}       min={0} max={28} step={1} unit="px"      onChange={(v) => setTweak('radius', v)} />

      <TweakSection label="Hero" />
      <TweakSlider label="Hero height"     value={t.heroHeight} min={320} max={820} step={10} unit="px" onChange={(v) => setTweak('heroHeight', v)} />
      <TweakSlider label="Mono"            value={t.heroMono}   min={0} max={100} step={1} unit="%"     onChange={(v) => setTweak('heroMono', v)} />
      <TweakSlider label="Darken"          value={t.heroDark}   min={0} max={75} step={1} unit="%"      onChange={(v) => setTweak('heroDark', v)} />
      <TweakRadio
        label="Copy align"
        value={t.heroAlign}
        options={[
          { value: 'top',    label: 'Top' },
          { value: 'center', label: 'Center' },
          { value: 'bottom', label: 'Bottom' },
        ]}
        onChange={(v) => setTweak('heroAlign', v)}
      />
      <TweakText label="Kicker"   value={t.kickerText} onChange={(v) => setTweak('kickerText', v)} />
      <TweakText label="Headline" value={t.titleText}  onChange={(v) => setTweak('titleText', v)} />
      <TweakText label="Subcopy"  value={t.subText}    onChange={(v) => setTweak('subText', v)} />

      <TweakSection label="Menu" />
      <TweakRadio
        label="Row rule"
        value={t.menuRule}
        options={[
          { value: 'dotted', label: 'Dot' },
          { value: 'dashed', label: 'Dash' },
          { value: 'solid',  label: 'Line' },
          { value: 'none',   label: 'None' },
        ]}
        onChange={(v) => setTweak('menuRule', v)}
      />
      <TweakSlider label="Row height"   value={t.menuRowHeight} min={1.2} max={2.6} step={0.05}        onChange={(v) => setTweak('menuRowHeight', v)} />
      <TweakSlider label="Card opacity" value={t.cardOpacity}   min={0} max={100} step={1} unit="%"    onChange={(v) => setTweak('cardOpacity', v)} />
    </TweaksPanel>
  );
}

const root = ReactDOM.createRoot(document.getElementById('tweaks-root'));
root.render(<App />);
