/* global React, ReactDOM, lucide */
/* ============================================================
App — router + tweaks + page dispatch + per-route metadata
============================================================ */
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"beamIntensity": 0.55,
"spacingDensity": "regular",
"typeScale": "regular",
"atmosphere": "regular",
"motion": "restrained",
"asymmetry": "asymmetric",
"diagnosticPacing": "measured",
"imageOpacity": 0.95,
"editorialDensity": "regular"
}/*EDITMODE-END*/;
/* ============================================================
Per-route metadata
============================================================ */
const SITE_NAME = 'The Daniel Pledger';
const SITE_BASE_URL = 'https://thedanielpledger.com'; // placeholder canonical origin
const ROUTE_META = {
'/': {
title: 'The Daniel Pledger — Identity Holding Under Pressure',
desc: 'Private executive authority advisory. For senior leaders who have outgrown the performance and need their signal to carry when the room is loudest.',
},
'/audit': {
title: 'The Executive Authority Signal Audit — The Daniel Pledger',
desc: 'A private diagnostic for senior leaders. Ten questions. A short reading of where authority leaks under consequence.',
},
'/audit/flow': {
title: 'The Audit — In progress — The Daniel Pledger',
desc: 'The Executive Authority Signal Audit. Held in confidence.',
},
'/audit/results': {
title: 'The Reading — The Executive Authority Signal Audit',
desc: 'Your private reading. One dominant signature. One secondary. Held in confidence.',
},
'/conversation': {
title: 'Request a Private Conversation — The Daniel Pledger',
desc: 'A short note about the room you are trying to hold is usually enough. Daniel responds personally within a week.',
},
'/insights': {
title: 'Field Notes — The Daniel Pledger',
desc: 'Short, deliberate writing on identity, authority, and what the senior room actually reads.',
},
'/perspective': {
title: 'Perspective — The Daniel Pledger',
desc: 'I do not coach performance. I work on identity. A position on what private executive advisory is, and is not.',
},
'/speaking': {
title: 'Speaking — The Daniel Pledger',
desc: 'Closed-room conversations on authority under consequence. Founder cohorts, board offsites, leadership intensives.',
},
'/privacy': {
title: 'Privacy Policy — The Daniel Pledger',
desc: 'What is collected when you use this site, why, and how it is held.',
},
'/terms': {
title: 'Terms of Service — The Daniel Pledger',
desc: 'The terms that apply to this site, its writing, and the Executive Authority Signal Audit.',
},
};
function getRouteMeta(path) {
if (ROUTE_META[path]) return ROUTE_META[path];
// /insights/:slug
const m = matchRoute(path, '/insights/:slug');
if (m) {
const i = (window.INSIGHTS || []).find((x) => x.slug === m.slug);
if (i) {
return {
title: `${i.title} — The Daniel Pledger`,
desc: i.excerpt,
};
}
}
return {
title: SITE_NAME,
desc: ROUTE_META['/'].desc,
};
}
/* Update
and meta tags imperatively for SPA route changes */
function applyRouteMeta(path) {
const meta = getRouteMeta(path);
const canonical = SITE_BASE_URL + path;
document.title = meta.title;
setMeta('description', meta.desc);
// Open Graph
setMetaProperty('og:title', meta.title);
setMetaProperty('og:description', meta.desc);
setMetaProperty('og:type', 'website');
setMetaProperty('og:site_name', SITE_NAME);
setMetaProperty('og:url', canonical);
setMetaProperty('og:image', SITE_BASE_URL + '/og-default.jpg');
// Twitter
setMeta('twitter:card', 'summary_large_image');
setMeta('twitter:title', meta.title);
setMeta('twitter:description', meta.desc);
setMeta('twitter:image', SITE_BASE_URL + '/og-default.jpg');
// Canonical
setLink('canonical', canonical);
}
function setMeta(name, content) {
let el = document.querySelector(`meta[name="${name}"]`);
if (!el) { el = document.createElement('meta'); el.setAttribute('name', name); document.head.appendChild(el); }
el.setAttribute('content', content || '');
}
function setMetaProperty(prop, content) {
let el = document.querySelector(`meta[property="${prop}"]`);
if (!el) { el = document.createElement('meta'); el.setAttribute('property', prop); document.head.appendChild(el); }
el.setAttribute('content', content || '');
}
function setLink(rel, href) {
let el = document.querySelector(`link[rel="${rel}"]`);
if (!el) { el = document.createElement('link'); el.setAttribute('rel', rel); document.head.appendChild(el); }
el.setAttribute('href', href);
}
/* ============================================================
Map tweak values to CSS variables on :root
============================================================ */
function applyTweaksToRoot(t) {
const r = document.documentElement;
r.style.setProperty('--tdp-beam', String(t.beamIntensity));
const dens = { compact: 0.72, regular: 1.0, generous: 1.35 }[t.spacingDensity] || 1;
r.style.setProperty('--tdp-density', String(dens));
const ts = { smaller: 0.88, regular: 1.0, larger: 1.12 }[t.typeScale] || 1;
r.style.setProperty('--tdp-type-scale', String(ts));
const mo = { still: 0, restrained: 1.0, lively: 1.6 }[t.motion] || 1;
r.style.setProperty('--tdp-motion', String(mo));
r.style.setProperty('--tdp-img-opacity', String(t.imageOpacity));
const ed = { sparse: 0.86, regular: 1.0, dense: 1.16 }[t.editorialDensity] || 1;
r.style.setProperty('--tdp-edit-density', String(ed));
const atm = {
lighter: { bg: 'var(--c-admiral-ink)', deep: 'var(--c-imperial-indigo)' },
regular: { bg: 'var(--c-imperial-indigo)', deep: 'var(--c-nightfall)' },
deeper: { bg: 'var(--c-nightfall)', deep: '#06080d' },
}[t.atmosphere] || { bg: 'var(--c-imperial-indigo)', deep: 'var(--c-nightfall)' };
document.body.style.background = atm.bg;
r.style.setProperty('--bg', atm.bg);
r.style.setProperty('--bg-deep', atm.deep);
}
/* ============================================================
Page dispatcher — reads router path, applies metadata
============================================================ */
function Page() {
const { path } = useRouter();
// Apply per-route metadata on every path change
React.useEffect(() => { applyRouteMeta(path); }, [path]);
if (path === '/' || path === '') return ;
if (path === '/audit') return ;
if (path === '/audit/flow') return ;
if (path === '/audit/results') return ;
if (path === '/conversation') return ;
if (path === '/insights') return ;
const m = matchRoute(path, '/insights/:slug');
if (m) return ;
if (path === '/perspective') return ;
if (path === '/speaking') return ;
if (path === '/privacy') return ;
if (path === '/terms') return ;
return (