// App composer for ColaFish — light editorial direction.
window.cfScrollTo = function (id) {
const el = document.getElementById(id);
if (!el) return;
const y = el.getBoundingClientRect().top + window.pageYOffset - 60;
window.scrollTo({ top: y, behavior: 'smooth' });
};
// Earth-tone phase progression — never falls to black.
const PHASE_COLORS = {
hero: '#FAF7F1', // cream
pilares: '#F4EFE6', // paper
marcas: '#E8DFCD', // sand
metrics: '#EFE8DA', // mist
contact: '#EFE8DA', // mist
footer: '#DCD3BF', // stone
};
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"pillarLayout": "editorial",
"accent": "#7a8c6f",
"showRail": true,
"showCue": true,
"showTextures": false,
"typeSystem": "newsreader"
}/*EDITMODE-END*/;
const ACCENT_OPTIONS = [
'#a8825a', // bronze
'#7a8c6f', // moss
'#6e8a96', // ocean
'#9c6a55', // clay
];
const TYPE_OPTIONS = [
{ value: 'instrument', label: 'Instrument' },
{ value: 'bodoni', label: 'Bodoni' },
{ value: 'newsreader', label: 'Newsreader' },
{ value: 'bricolage', label: 'Bricolage' },
];
function App() {
const [activeSection, setActiveSection] = React.useState('hero');
const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
// Accent CSS variable
React.useEffect(() => {
document.documentElement.style.setProperty('--accent', tweaks.accent);
}, [tweaks.accent]);
// Typography system — toggles via data-type attribute
React.useEffect(() => {
document.documentElement.setAttribute('data-type', tweaks.typeSystem);
}, [tweaks.typeSystem]);
// Phase tint driver — drives the underlying #phase-tint background.
// Each section has its own surface color too, so this is a fallback for
// areas between sections and the canvas blending.
React.useEffect(() => {
const tint = document.getElementById('phase-tint');
if (!tint) return;
tint.style.backgroundColor = PHASE_COLORS[activeSection] || PHASE_COLORS.hero;
}, [activeSection]);
React.useEffect(() => {
document.body.classList.toggle('hide-cue', !tweaks.showCue);
}, [tweaks.showCue]);
// Observe sections
React.useEffect(() => {
const ids = ['hero', 'pilares', 'marcas', 'contact'];
const map = new Map();
const obs = new IntersectionObserver((entries) => {
for (const e of entries) map.set(e.target.id, e.intersectionRatio);
let best = 'hero', bestR = 0;
for (const [id, r] of map) if (r > bestR) { bestR = r; best = id; }
if (bestR > 0.18) setActiveSection(best);
}, { threshold: [0, 0.18, 0.35, 0.6, 0.85] });
ids.forEach(id => {
const el = document.getElementById(id);
if (el) obs.observe(el);
});
return () => obs.disconnect();
}, []);
return (
);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render();