// v4/lesson-template.jsx — Reusable lesson page layout (for Chapter I free lessons). function V4LessonTemplate({ num, // '1.02' title, // 'Value vs price vs worth' brief, // one-line intro readMins, // 6 body, // ReactNode — the article content (preview when locked) pullQuote, // string takeaway, // ReactNode for summary box prevHref, prevTitle, prevNum, nextHref, nextTitle, nextNum, // Chapter context (defaults to Chapter I, free) chapterRoman = 'I', chapterTitle = 'The Nature of Value', chapterHref = 'chapter-01.html', lessonsInChapter, // [[num, title, href], ...] locked = false, // member-only preview state lockedBundled, // bundled materials list shown above paywall memberBody, // ReactNode — the rest of the lesson, shown only when isMember }) { // Paid lessons unlock with a Deal Pack / Complete access code (access.js). // 🔴 The paid text still ships in the public JS bundle: this is a reading-convenience gate, not DRM. const access = window.useVCAccess(); const isMember = !!(access && access.lessons); const [copied, setCopied] = React.useState(false); // When in member preview mode, unlock the content const effectiveLocked = locked && !isMember; const v4 = window.v4; const accent = v4.yellow; const accent2 = v4.red; const liveTag = effectiveLocked ? `● PAID LESSON · ${num} · Preview shown below` : (locked && isMember) ? `● ${access.name.toUpperCase()} · ${num} · Full lesson` : `● FREE LESSON · ${num} · No card · No email`; const sidebarLessons = lessonsInChapter || [ ['1.01', 'Why this is not a math problem', 'lesson-1-01.html'], ['1.02', 'Value vs price vs worth', 'lesson-1-02.html'], ['1.03', 'Why listed methods miss SMEs', 'lesson-1-03.html'], ['1.04', 'Bias · uncertainty · complexity', 'lesson-1-04.html'], ['1.05', 'The role of the valuer', 'lesson-1-05.html'], ['1.06', 'When to refuse a valuation', 'lesson-1-06.html'], ['1.07', 'The map of the rest', 'lesson-1-07.html'], ]; return (
{/* Member preview toggle band — only visible on locked lessons */} {locked && (
{isMember ? `● Unlocked with ${access.name}${access.until ? ' · until ' + access.until : ''}` : '⚠ Paid lesson · public preview below · Deal Pack NZD 249 or Complete NZD 490'}
)} {/* Breadcrumb */}
Keelvalue / § {chapterRoman} · {chapterTitle} / Lesson {num}{locked && isMember ? ' · unlocked' : ''}
{/* HERO */}
LESSON {num} {locked ? {isMember ? 'PAID · UNLOCKED' : 'PAID'} : FREE} · {readMins} min read · Chapter {chapterRoman}

{title}

{brief}

{/* ARTICLE */}
{/* Left rail — lesson list */} {/* Article */}
{body} {locked && isMember && memberBody} {effectiveLocked && (
{/* fade-out preview */}
{/* paywall card */}
Continue · Paid lesson

The rest of {num} continues here.

The rest of this lesson is in the Deal Pack (NZD 249, 90 days) and in Complete (NZD 490, no expiry). The preview above stays free.

{lockedBundled && (
{lockedBundled.map((b, i) => (
{b.tag}
{b.t}
))}
)} Already bought? Enter your access code →
Deal Pack NZD 249 · Complete NZD 490 · one payment
)} {pullQuote && !effectiveLocked && (
↘ Take this away

{pullQuote}

)} {takeaway && !effectiveLocked && (
Summary · {num}
{takeaway}
)} {/* Foot */}
Filed under · Chapter {chapterRoman} · {locked ? 'Paid' : 'Free'}
{[ ['Copy link', () => { const done = () => { setCopied(true); setTimeout(() => setCopied(false), 1600); }; const fallback = () => { try { const ta = document.createElement('textarea'); ta.value = location.href; document.body.appendChild(ta); ta.select(); const ok = document.execCommand('copy'); ta.remove(); if (ok) done(); } catch (e) {} }; try { navigator.clipboard.writeText(location.href).then(done, fallback); } catch (e) { fallback(); } }], ['Email', () => { location.href = `mailto:?subject=${encodeURIComponent(document.title)}&body=${encodeURIComponent(location.href)}`; }], ['LinkedIn', () => { window.open(`https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(location.href)}`, '_blank', 'noopener'); }], ['Print', () => window.print()], ].map(([s, fn]) => ( ))}
{/* Right rail */}
{/* Prev / Next */}
←
Previous · {prevNum || '—'}
{prevTitle || '— start of chapter —'}
{nextHref ? `Next · ${nextNum}` : `End of chapter ${chapterRoman}`}
{nextTitle || `Back to chapter overview`}
→
); } window.V4LessonTemplate = V4LessonTemplate; // Reusable drop-cap paragraph helper. window.V4DropCap = function V4DropCap({ letter, children }) { const v4 = window.v4; return (

{letter} {children}

); }; window.V4H2 = function V4H2({ children }) { const v4 = window.v4; return

{children}

; };