// app.jsx — Root for Repos site.
// Wires the section components together and exposes tweaks (palette, type, service display).
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"palette": ["#F6F1E8", "#8F9D85", "#B89A6F"],
"typePair": "mincho",
"serviceMode": "cards"
}/*EDITMODE-END*/;
// Palette options — each is [bg, accent (soft), accent-2 (warm)].
// Variables derived from these set --bg, --bg-2, --bg-3, --paper, --accent, --accent-2.
const PALETTES = [
["#F6F1E8", "#8F9D85", "#B89A6F"], // warm cream + sage (default)
["#F2EEE7", "#A89E8B", "#8A6E52"], // greige + tan
["#EFE9DD", "#9DB0A8", "#C09573"], // ivory + dusty teal
["#EAE4D6", "#6E7A60", "#9D7A4F"], // sand + olive
];
// Type pair options — each maps to font-family vars.
const TYPE_PAIRS = {
mincho: {
label: "Mincho × Gothic",
serifJp: `"Shippori Mincho", "Hiragino Mincho ProN", "Yu Mincho", serif`,
sansJp: `"Zen Kaku Gothic New", "Hiragino Sans", "Yu Gothic", system-ui, sans-serif`,
serifEn: `"Italiana", "Shippori Mincho", serif`,
sansEn: `"Jost", "Zen Kaku Gothic New", system-ui, sans-serif`,
},
old: {
label: "Old Mincho × Maru",
serifJp: `"Zen Old Mincho", "Hiragino Mincho ProN", serif`,
sansJp: `"Zen Maru Gothic", "Hiragino Sans", system-ui, sans-serif`,
serifEn: `"Cormorant Garamond", "Zen Old Mincho", serif`,
sansEn: `"Jost", "Zen Maru Gothic", system-ui, sans-serif`,
},
modern: {
label: "Modern Gothic",
serifJp: `"Zen Kaku Gothic New", "Hiragino Sans", sans-serif`,
sansJp: `"Zen Kaku Gothic New", "Hiragino Sans", system-ui, sans-serif`,
serifEn: `"Jost", system-ui, sans-serif`,
sansEn: `"Jost", system-ui, sans-serif`,
},
};
// Load Google Fonts for the alt pairs the first time they're picked.
function ensureFontsLoaded(pair) {
const tag = "fonts-extra";
if (document.getElementById(tag)) return;
const el = document.createElement("link");
el.id = tag;
el.rel = "stylesheet";
el.href = "https://fonts.googleapis.com/css2?family=Zen+Old+Mincho:wght@400;500;600&family=Zen+Maru+Gothic:wght@400;500;700&family=Cormorant+Garamond:wght@400;500&display=swap";
document.head.appendChild(el);
}
function App() {
const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
// Apply CSS variables when tweaks change.
React.useEffect(() => {
const [bg, accent, accent2] = t.palette;
const root = document.documentElement.style;
root.setProperty("--bg", bg);
root.setProperty("--bg-2", mix(bg, "#000", .055));
root.setProperty("--bg-3", mix(bg, "#000", .12));
root.setProperty("--paper", mix(bg, "#fff", .35));
root.setProperty("--accent", accent);
root.setProperty("--accent-2", accent2);
const tp = TYPE_PAIRS[t.typePair] || TYPE_PAIRS.mincho;
if (t.typePair !== "mincho") ensureFontsLoaded(t.typePair);
root.setProperty("--serif-jp", tp.serifJp);
root.setProperty("--sans-jp", tp.sansJp);
root.setProperty("--serif-en", tp.serifEn);
root.setProperty("--sans-en", tp.sansEn);
}, [t.palette, t.typePair]);
return (
<>
LINEで予約・相談する
setTweak("palette", v)}
/>
setTweak("typePair", v)}
/>
>
);
}
// Tiny hex color mixer — `mix(a, b, t)` returns `a` blended toward `b` by t (0..1).
// Good enough for deriving bg-2/bg-3/paper variants from the chosen background.
function mix(a, b, w) {
const [ar, ag, ab] = hex(a);
const [br, bg, bb] = hex(b);
const r = Math.round(ar + (br - ar) * w);
const g = Math.round(ag + (bg - ag) * w);
const bl = Math.round(ab + (bb - ab) * w);
return `rgb(${r},${g},${bl})`;
}
function hex(h) {
const s = h.replace("#", "");
const x = s.length === 3 ? s.replace(/./g, (c) => c + c) : s;
return [parseInt(x.slice(0, 2), 16), parseInt(x.slice(2, 4), 16), parseInt(x.slice(4, 6), 16)];
}
ReactDOM.createRoot(document.getElementById("root")).render();