added site modes

This commit is contained in:
2026-05-18 13:51:33 +02:00
parent c3aa52ddfd
commit 86f855493b
18 changed files with 538 additions and 52 deletions
+99
View File
@@ -0,0 +1,99 @@
// Site presentation mode. The atelier skin (fonts, cybersigil/breakcore
// themes, paper grain, CyberFx) is identical in both modes — only the *focus*
// flips: `atelier` puts images first (justified gallery plates, "plates"
// count), `blog` puts writing first (stacked rows, excerpts, reading time).
//
// Resolved server-side from the SITE_MODE env var. React islands cannot read
// process.env in the browser, so pages pass the resolved mode down as a prop;
// islands then look up COPY by mode.
export type SiteMode = 'blog' | 'atelier';
/** Server-side only. Defaults to atelier for any unset/unknown value. */
export function getSiteMode(): SiteMode {
const v = typeof process !== 'undefined' ? process.env.SITE_MODE : undefined;
return v === 'blog' ? 'blog' : 'atelier';
}
/**
* Mode-keyed user-facing strings. Atelier keeps the gallery voice; blog
* neutralises it. Anything not voice-flavoured (e.g. "Search", "Cancel")
* stays out of here so there's no needless duplication.
*/
export const COPY = {
atelier: {
indexTitle: 'Catalogue',
backHome: 'Back to catalogue',
adminBack: 'Back to the catalogue',
adminEyebrow: "Artist's desk",
footerEnd: 'end of catalogue',
loadingMore: 'arranging more…',
draftShort: 'Sketch',
draftLong: 'Sketch · unpublished',
searchPlaceholder: 'Search the catalogue…',
searchAria: 'Search the catalogue',
searchFetching: 'Fetching the catalogue…',
searchEmpty: 'The catalogue is empty.',
searchNoMatch: 'No works match.',
deleteListTitle: 'Take this off the wall?',
deleteListMsg: (t: string) =>
`${t}” will be removed from the catalogue. This cannot be undone.`,
deleteListConfirm: 'Remove',
deleteListCancel: 'Keep',
deletePostTitle: 'Delete this work?',
deletePostMsg: (t: string) => `${t}” will be permanently removed. This cannot be undone.`,
postNotFound: 'Work not found in the catalogue',
returnHome: 'Return to the catalogue',
notFoundTitle: 'Not in the catalogue',
notFoundDesc: "The work you're looking for is not on view.",
notFoundRule: 'Pardon — the gallery has misplaced this work',
notFoundHead: 'This piece is not on view.',
notFoundBody:
'The room you reached for has either been re-hung, withdrawn,|or never made it to the wall in the first place.',
editorTitlePh: 'Untitled (charcoal on paper)',
editorSlugPh: 'untitled-charcoal-on-paper',
editorDraftLabel: 'Sketch (draft)',
editorSummaryPh: 'A short caption for the catalogue index...',
editorSummaryLabel: 'Caption (optional)',
editorTagsPh: 'oil, paper, 2026, study',
},
blog: {
indexTitle: 'Posts',
backHome: 'Back to posts',
adminBack: 'Back to posts',
adminEyebrow: 'Dashboard',
footerEnd: 'end of posts',
loadingMore: 'loading more…',
draftShort: 'Draft',
draftLong: 'Draft · unpublished',
searchPlaceholder: 'Search posts…',
searchAria: 'Search posts',
searchFetching: 'Loading posts…',
searchEmpty: 'No posts yet.',
searchNoMatch: 'No posts match.',
deleteListTitle: 'Delete this post?',
deleteListMsg: (t: string) => `${t}” will be permanently deleted. This cannot be undone.`,
deleteListConfirm: 'Delete',
deleteListCancel: 'Cancel',
deletePostTitle: 'Delete this post?',
deletePostMsg: (t: string) => `${t}” will be permanently deleted. This cannot be undone.`,
postNotFound: 'Post not found',
returnHome: 'Return to posts',
notFoundTitle: 'Post not found',
notFoundDesc: "The post you're looking for doesn't exist.",
notFoundRule: 'This page could not be found',
notFoundHead: 'Nothing here.',
notFoundBody:
'The post you reached for has either moved, been unpublished,|or never existed in the first place.',
editorTitlePh: 'Post title',
editorSlugPh: 'post-slug',
editorDraftLabel: 'Draft',
editorSummaryPh: 'A short summary for the index...',
editorSummaryLabel: 'Summary (optional)',
editorTagsPh: 'essay, notes, 2026',
},
} as const satisfies Record<SiteMode, Record<string, unknown>>;
export function copy(mode: SiteMode) {
return COPY[mode];
}