- Read-only share page: a calm paper-toned page rendered natively (no iframe), with outline tabs, Print / PDF, numbered points with accent numerals, type tags, notes and verse quotes; works on phones - Printable / PDF page restyled to match (serif, hanging numerals, tidy spacing, footer) - Word outline restyled: eyebrow + title block, bold main points, accent numerals, set-off verse quotes, tidy margins Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
56 lines
3.5 KiB
React
56 lines
3.5 KiB
React
// An outline laid out for reading (not editing): numbered points, small type tags, notes, verse text. Used
|
|
// by the read-only share page. Styled to match the printed / PDF page.
|
|
import { labelFor } from '../utils/outlineLabels.js';
|
|
import { kindLabel } from '../utils/outlineLabels.js';
|
|
|
|
function Points({ nodes, depth }) {
|
|
return (
|
|
<ul className={depth === 0 ? '' : 'ml-6 sm:ml-10'}>
|
|
{nodes.map((n, i) => {
|
|
const main = depth === 0;
|
|
const mins = Number.isFinite(n.minutes) && n.minutes > 0;
|
|
return (
|
|
<li key={n.id} className={main ? 'mt-7 first:mt-5' : 'mt-2.5'}>
|
|
<div className="flex gap-3">
|
|
<span className={`shrink-0 font-semibold tabular-nums text-[var(--r-accent)] ${main ? 'w-9 text-lg' : 'w-8'}`}>{labelFor(depth, i)}</span>
|
|
<div className="min-w-0 flex-1">
|
|
<p className={`leading-snug ${main ? 'text-xl font-semibold' : 'text-[1.05rem]'}`}>
|
|
{n.kind && <span className="mr-2 inline-block -translate-y-px rounded-full border border-[#e4b9a3] px-2 py-0.5 align-middle font-sans text-[10px] font-semibold uppercase tracking-widest text-[var(--r-accent)]">{kindLabel(n.kind)}</span>}
|
|
{n.text.trim() || <span className="text-[var(--r-sub)]">(untitled)</span>}
|
|
{n.ref && <span className="ml-2 whitespace-nowrap font-sans text-[0.8rem] font-normal text-[var(--r-sub)]">{n.ref}</span>}
|
|
{mins && <span className="ml-2 whitespace-nowrap font-sans text-[0.8rem] font-normal text-[var(--r-sub)]">{n.minutes} min</span>}
|
|
</p>
|
|
{n.note.trim() && <p className="mt-1 whitespace-pre-line text-[0.95rem] italic leading-relaxed text-[var(--r-sub)]">{n.note.trim()}</p>}
|
|
{n.scripture?.text && (
|
|
<blockquote className="mt-2 border-l-[3px] border-[#e4b9a3] pl-4 italic leading-relaxed">
|
|
“{n.scripture.text}” <span className="whitespace-nowrap font-sans text-[0.8rem] not-italic text-[var(--r-sub)]">— {n.scripture.ref}</span>
|
|
</blockquote>
|
|
)}
|
|
{n.attachments.length > 0 && (
|
|
<p className="mt-1.5 font-sans text-[0.8rem] leading-relaxed text-[var(--r-sub)]">
|
|
{n.attachments.map((a, k) => <span key={a.id || k}>{k > 0 && ' · '}{a.type === 'word' ? 'Word' : 'See'}: {a.label}{a.detail ? ` — ${a.detail}` : ''}</span>)}
|
|
</p>
|
|
)}
|
|
{n.children.length > 0 && <Points nodes={n.children} depth={depth + 1} />}
|
|
</div>
|
|
</div>
|
|
</li>
|
|
);
|
|
})}
|
|
</ul>
|
|
);
|
|
}
|
|
|
|
export default function OutlineDocument({ title, meta, tree }) {
|
|
return (
|
|
<article className="mx-auto max-w-[44rem] px-5 pb-20 pt-10 font-serif text-[var(--r-text)] sm:px-8 sm:pt-14">
|
|
<p className="font-sans text-[11px] font-semibold uppercase tracking-[0.18em] text-[var(--r-accent)]">Outline</p>
|
|
<h1 className="mt-3 text-3xl font-semibold leading-tight tracking-tight sm:text-[2.1rem]">{title}</h1>
|
|
{meta && <p className="mt-2 font-sans text-sm text-[var(--r-sub)]">{meta}</p>}
|
|
<hr className="mb-1 mt-6 border-[var(--r-line)]" />
|
|
{tree.length > 0 ? <Points nodes={tree} depth={0} /> : <p className="mt-8 text-[var(--r-sub)]">Nothing in this outline yet.</p>}
|
|
<p className="mt-14 border-t border-[var(--r-line)] pt-4 text-center font-sans text-[11px] tracking-wide text-[var(--r-sub)]">Bible Study Project</p>
|
|
</article>
|
|
);
|
|
}
|