// Uri Padel — Tweaks panel.
// Lets the user adjust a handful of live knobs. Persists via the host bridge.
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"accent": "ink",
"heroLine1": "In Korea,",
"heroLine2": "we say Uri.",
"manifestoHeading": "Built\nfor Korea.",
"showManifestoDetail": true,
"wordmarkTracking": 0
}/*EDITMODE-END*/;
function applyTweaks(t) {
// Accent: ink (default) or inverted hero
document.body.dataset.accent = t.accent;
// Hero lines
const leadEl = document.querySelector('.hero-sub .lead');
if (leadEl) leadEl.innerHTML = `${t.heroLine1}
${t.heroLine2}`;
// Manifesto heading
const manEl = document.querySelector('#manifesto .section-head h2');
if (manEl) manEl.innerHTML = t.manifestoHeading.replace(/\n/g, '
');
// Operational detail paragraph
const detailEl = document.querySelector('#manifesto p[data-detail]');
if (detailEl) detailEl.style.display = t.showManifestoDetail ? '' : 'none';
// Wordmark tracking
const wordEl = document.querySelector('.hero-wordmark .word');
if (wordEl) wordEl.style.letterSpacing = `${t.wordmarkTracking}em`;
}
let current = { ...TWEAK_DEFAULTS };
function TweaksPanel({ visible, onChange }) {
const [state, setState] = React.useState(current);
const set = (k, v) => {
const next = { ...state, [k]: v };
setState(next);
current = next;
applyTweaks(next);
onChange(next);
};
if (!visible) return null;
return (
);
}
const Row = ({ label, children }) => (
);
const inputStyle = {
width: '100%', background: 'rgba(245,243,237,0.06)', border: '1px solid rgba(245,243,237,0.2)',
color: '#f5f3ed', padding: '6px 8px', fontSize: 11,
fontFamily: 'JetBrains Mono, monospace', letterSpacing: '0.04em'
};
const selectStyle = { ...inputStyle };
// Accent: inverted adds class to hero
const accentCSS = document.createElement('style');
accentCSS.textContent = `
body[data-accent="inverted"] .hero { background: #0a0a0a; color: #f5f3ed; }
body[data-accent="inverted"] .hero .label { color: rgba(245,243,237,0.55); }
body[data-accent="inverted"] .hero-wordmark img { filter: invert(1); }
body[data-accent="inverted"] .nav { background: #0a0a0a; color: #f5f3ed; border-bottom-color: rgba(245,243,237,0.16); }
body[data-accent="inverted"] .nav a { color: #f5f3ed; }
body[data-accent="inverted"] .nav-cta { border-color: #f5f3ed; }
body[data-accent="inverted"] .nav-cta:hover { background: #f5f3ed; color: #0a0a0a; }
body[data-accent="inverted"] .nav-logo img { filter: invert(1); }
`;
document.head.appendChild(accentCSS);
// Tag the operational detail paragraph so Tweaks can hide it
requestAnimationFrame(() => {
const paras = document.querySelectorAll('#manifesto p');
paras.forEach(p => {
if (p.textContent.includes('premium infrastructure')) p.setAttribute('data-detail', '');
});
applyTweaks(TWEAK_DEFAULTS);
});
// Mount edit mode
(function mountTweaks() {
const host = document.createElement('div');
document.body.appendChild(host);
const root = ReactDOM.createRoot(host);
let visible = false;
const render = () => root.render(
{
window.parent.postMessage({ type: '__edit_mode_set_keys', edits }, '*');
}}/>
);
window.addEventListener('message', (e) => {
if (e.data?.type === '__activate_edit_mode') { visible = true; render(); }
if (e.data?.type === '__deactivate_edit_mode') { visible = false; render(); }
});
render();
window.parent.postMessage({ type: '__edit_mode_available' }, '*');
})();