// Shared shell: Nav, Footer, Placeholder, SectionHeader, helpers const { useState, useEffect, useRef, useMemo } = React; // expose hooks globally so separately-compiled babel scripts can use them window.useState = React.useState; window.useEffect = React.useEffect; window.useRef = React.useRef; window.useMemo = React.useMemo; window.useLayoutEffect = React.useLayoutEffect; const useLayoutEffect = React.useLayoutEffect; // ---------- helpers ---------- // Reveal uses a pure CSS entrance animation (.reveal in index.html) that always // ends visible — no scroll / IntersectionObserver dependency, so content can never // stay blank in any rendering context. function useReveal() { return useRef(null); } function Reveal({ children, delay = 0, as: Tag = 'div', className = '', style = {}, ...rest }) { return ( {children} ); } // ---------- placeholder visuals ---------- // Subtly-striped SVG placeholders, no AI-illustrated content function Placeholder({ label = 'editorial visual', tone = 'light', ratio = 1.25, style = {}, dense = false }) { // tone: light | dark | mid const palette = tone === 'dark' ? { bg: '#1A1A1A', stripe: 'rgba(255,255,255,0.045)', text: '#9A9CA0' } : tone === 'mid' ? { bg: '#2A2A2A', stripe: 'rgba(255,255,255,0.05)', text: '#B0B2B6' } : { bg: '#EFEEEA', stripe: 'rgba(0,0,0,0.04)', text: '#5E646B' }; const lineGap = dense ? 8 : 14; const lines = []; for (let i = 0; i < 60; i++) { lines.push(); } return (
{lines} {/* corner brackets */} {/* caption */}
↳ {label}
IMG / 01
); } function Bracket({ pos, color }) { const size = 14; const offset = 14; const styles = { tl: { top: offset, left: offset, borderTop: `1px solid ${color}`, borderLeft: `1px solid ${color}` }, tr: { top: offset, right: offset, borderTop: `1px solid ${color}`, borderRight: `1px solid ${color}` }, bl: { bottom: offset, left: offset, borderBottom: `1px solid ${color}`, borderLeft: `1px solid ${color}` }, br: { bottom: offset, right: offset, borderBottom: `1px solid ${color}`, borderRight: `1px solid ${color}` }, }; return
; } // editorial gridline visual — pure geometric, no graphics function GridArt({ tone = 'dark', label = 'visual structure', code = 'FIG. 01' }) { const isDark = tone === 'dark'; const bg = isDark ? '#1A1A1A' : '#EFEEEA'; const line = isDark ? 'rgba(255,255,255,0.10)' : 'rgba(0,0,0,0.10)'; const ink = isDark ? '#9A9CA0' : '#5E646B'; return (
{/* horizontal rules */} {[80, 200, 360, 540, 700].map(y => ( ))} {/* vertical column rules */} {[40, 160, 300, 440, 560].map(x => ( ))} {/* a single emphasized box */} {/* a thin diagonal accent */} {/* tiny circle marker */}
{code}
↳ {label}
N · 28°36′ E · 77°12′
); } // ---------- Logo ---------- function Logo({ size = 18, tone = 'ink' }) { const color = tone === 'ink' ? 'var(--ink)' : 'var(--ivory)'; const d = Math.round(size * 0.42); return (
); } // ---------- Nav ---------- function Nav({ route, navigate }) { const [open, setOpen] = useState(false); const [scrolled, setScrolled] = useState(false); const [expandedExpertise, setExpandedExpertise] = useState(false); const [expandedIndustries, setExpandedIndustries] = useState(false); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 8); onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); const items = [ { id: 'home', label: 'Home' }, { id: 'about', label: 'About' }, { id: 'expertise', label: 'Expertise', hasMega: 'expertise' }, { id: 'industries', label: 'Industries', hasMega: 'industries' }, { id: 'insights', label: 'Insights' }, { id: 'contact', label: 'Contact' }, ]; return ( <>
navigate({ name: 'home' })} style={{ cursor: 'pointer' }}>
info@tdc.business
{/* Mega menu */} {(expandedExpertise || expandedIndustries) && (
{ setExpandedExpertise(false); setExpandedIndustries(false); }} style={{ position: 'absolute', top: 72, left: 0, right: 0, background: 'var(--ivory)', borderTop: '1px solid var(--hairline)', borderBottom: '1px solid var(--hairline)', animation: 'pageEnter .25s ease both', }} >
{expandedExpertise ? '001' : '002'}
{expandedExpertise ? 'Expertise' : 'Industries'}

{expandedExpertise ? 'Specialised practice areas across cross-border tax, regulatory and advisory matters.' : 'Sector-specific advisory for globally connected businesses and capital.'}

)}
{/* Mobile drawer */} {open && (
{items.map((it, i) => ( { navigate({ name: it.id }); setOpen(false); }} style={{ display: 'flex', alignItems: 'baseline', gap: 12, padding: '20px 0', borderTop: '1px solid var(--hairline)' }}> {String(i + 1).padStart(2, '0')} {it.label} ))}
)} ); } // ---------- Footer ---------- function Footer({ navigate }) { return ( ); } // ---------- Section primitives ---------- function SectionHead({ num, kicker, title, lede, align = 'left' }) { return (
{num}
{kicker}

{title}

{lede && (

{lede}

)}
); } // page hero shared between expertise/industry detail pages function DetailHero({ kicker, num, title, lede, meta, keywords }) { return (
{num} / {kicker}

{title}

{lede && (

{lede}

)} {keywords && keywords.length > 0 && (
{keywords.map((k, i) => ( {k} ))}
)} {meta && (
{meta.map(([k, v]) => (
{k}
{v}
))}
)}
); } // ---------- Keyword chips ---------- function KeywordChips({ items = [], onDark = false, firstSolid = true, style = {} }) { return (
{items.map((k, i) => ( {k} ))}
); } // ---------- Jurisdiction-flow visual (meaningful, replaces some grid art) ---------- function JurisdictionFlow({ corridors = [], tone = 'dark', title = 'Cross-border corridors', code = 'STRUCT // 01' }) { const dark = tone === 'dark'; const bg = dark ? 'var(--ink)' : 'var(--ivory-2)'; const ink = dark ? '#E9E6E2' : 'var(--ink)'; const sub = dark ? '#8A9099' : 'var(--graphite)'; const line = dark ? 'rgba(233,230,226,0.22)' : 'rgba(26,26,26,0.18)'; return (
{code}
N 28°36′ · E 77°12′
{corridors.map((c, ci) => (
{c.label}
{c.nodes.map((n, ni) => ( {n} {ni < c.nodes.length - 1 && ( )} ))}
))}
↳ {title}
); } // ---------- Big-number authority metrics band ---------- function MetricsBand({ metrics = [], tone = 'dark' }) { const dark = tone === 'dark'; return (
By way of evidence
{metrics.map((m, i) => (
{m.v}{m.suffix}
{m.k}
{m.note}
))}
); } // ---------- Doctrine wall (the "wow" thought-leadership moment) ---------- function DoctrineWall({ terms = [], tone = 'wine' }) { const wine = tone === 'wine'; const bg = wine ? 'var(--wine-deep)' : 'var(--ink)'; return (
The vocabulary of the work

The frameworks our clients are actually being assessed against.

{terms.map((t, i) => ( {t} {String(i + 1).padStart(2, '0')} ))}
); } // ---------- Photo (real imagery with cohesive burgundy duotone + graceful fallback) ---------- function Photo({ src, alt = '', label, code, seed = 'tdc', objectPosition = 'center', style = {}, overlay = true }) { const onErr = (e) => { if (e.target.dataset.fb) return; e.target.dataset.fb = '1'; e.target.src = `https://picsum.photos/seed/${seed}/1280/960`; }; return (
{alt} {overlay && (
)} {code && (
{code}
)} {label && (
↳ {label}
)}
); } // ---------- Expose ---------- Object.assign(window, { useReveal, Reveal, Placeholder, GridArt, Bracket, Logo, Nav, Footer, Photo, SectionHead, DetailHero, KeywordChips, JurisdictionFlow, MetricsBand, DoctrineWall, });