The site now has one services page, six public cases, and no MySpa or calendar-scaffold strings. Co-authored-by: Cursor <cursoragent@cursor.com>
259 lines
7.0 KiB
TypeScript
259 lines
7.0 KiB
TypeScript
import { type RouteId } from '../routing/route-ids';
|
|
|
|
/**
|
|
* Copy roles stay separate on purpose:
|
|
* - headline is the serious heading used for SEO and page structure
|
|
* - proof is only ever a verifiable statement
|
|
* - playfulLine is an optional wordplay hook that is never a capability claim
|
|
* - cta lives on CtaCopy so action labels stay swappable
|
|
*/
|
|
export interface CopyBlock {
|
|
readonly headline: string;
|
|
readonly proof?: string;
|
|
readonly playfulLine?: string;
|
|
readonly body?: readonly string[];
|
|
}
|
|
|
|
export interface CtaCopy {
|
|
readonly label: string;
|
|
readonly routeId?: RouteId;
|
|
readonly href?: string;
|
|
readonly external?: boolean;
|
|
readonly fragment?: string;
|
|
}
|
|
|
|
export interface SectionCopy extends CopyBlock {
|
|
readonly id: string;
|
|
}
|
|
|
|
export interface PageCopy {
|
|
readonly routeId: RouteId;
|
|
readonly title: string;
|
|
readonly description: string;
|
|
readonly hero: CopyBlock;
|
|
readonly sections: readonly SectionCopy[];
|
|
readonly ctas: readonly CtaCopy[];
|
|
}
|
|
|
|
export type CaseStudyId = 'innofocus' | 'roesterei' | 'bannier' | 'elbwaerme' | 'hdi' | 'devdays';
|
|
|
|
export const CASE_STUDY_IDS: readonly CaseStudyId[] = [
|
|
'innofocus',
|
|
'roesterei',
|
|
'bannier',
|
|
'elbwaerme',
|
|
'hdi',
|
|
'devdays',
|
|
];
|
|
|
|
export interface MetricCopy {
|
|
readonly id: string;
|
|
readonly value: string;
|
|
readonly label: string;
|
|
readonly note?: string;
|
|
readonly caseId?: CaseStudyId;
|
|
}
|
|
|
|
export interface ProcessStepCopy {
|
|
readonly id: string;
|
|
readonly title: string;
|
|
readonly body: string;
|
|
}
|
|
|
|
export interface CaseStudyCopy {
|
|
readonly id: CaseStudyId;
|
|
readonly client: string;
|
|
readonly role: string;
|
|
readonly period: string;
|
|
readonly domain: string;
|
|
readonly headline: string;
|
|
readonly summary: string;
|
|
readonly responsibility: string;
|
|
readonly situation: string;
|
|
readonly approach: readonly string[];
|
|
readonly outcome: readonly string[];
|
|
readonly metrics: readonly MetricCopy[];
|
|
readonly stack: readonly string[];
|
|
readonly tags: readonly string[];
|
|
readonly linkLabel: string;
|
|
readonly transparencyNote?: string;
|
|
readonly teaser: string;
|
|
readonly externalUrl?: string;
|
|
readonly externalLabel?: string;
|
|
}
|
|
|
|
export type OfferingStatus = 'delivered' | 'offer';
|
|
|
|
export interface OfferingCopy {
|
|
readonly id: string;
|
|
readonly title: string;
|
|
readonly body: string;
|
|
readonly status: OfferingStatus;
|
|
readonly referenceCaseId?: CaseStudyId;
|
|
}
|
|
|
|
export interface ServiceEvidenceCopy {
|
|
readonly id: string;
|
|
readonly heading: string;
|
|
readonly note: string;
|
|
readonly caseIds: readonly CaseStudyId[];
|
|
}
|
|
|
|
export type ServiceSectionId =
|
|
'infrastructure-network' | 'platform-operations' | 'software-data' | 'ai-workflows';
|
|
|
|
export const SERVICE_SECTION_IDS: readonly ServiceSectionId[] = [
|
|
'infrastructure-network',
|
|
'platform-operations',
|
|
'software-data',
|
|
'ai-workflows',
|
|
];
|
|
|
|
export interface ServiceSectionCopy {
|
|
readonly id: ServiceSectionId;
|
|
readonly title: string;
|
|
readonly lead: string;
|
|
readonly situation: SectionCopy;
|
|
readonly diagnosis: SectionCopy;
|
|
readonly implementation: SectionCopy;
|
|
readonly operation: SectionCopy;
|
|
readonly offerings: readonly OfferingCopy[];
|
|
readonly evidence: ServiceEvidenceCopy;
|
|
readonly inquiry: SectionCopy;
|
|
}
|
|
|
|
export interface ServicesPageCopy extends PageCopy {
|
|
readonly serviceSections: readonly ServiceSectionCopy[];
|
|
readonly sectionsHeading: string;
|
|
readonly deliveredOfferingsHeading: string;
|
|
readonly offerOfferingsHeading: string;
|
|
readonly offeringCaseBackedLabel: string;
|
|
readonly evidenceHeading: string;
|
|
readonly inquiryHeading: string;
|
|
readonly systemsMap: { readonly heading: string; readonly intro: string };
|
|
}
|
|
|
|
export interface HomeServiceAreaCopy {
|
|
readonly id: ServiceSectionId;
|
|
readonly title: string;
|
|
readonly body: string;
|
|
readonly routeId: RouteId;
|
|
readonly fragment: ServiceSectionId;
|
|
}
|
|
|
|
export interface HomePageCopy extends PageCopy {
|
|
readonly serviceAreas: readonly HomeServiceAreaCopy[];
|
|
readonly serviceAreasHeading: string;
|
|
readonly process: readonly ProcessStepCopy[];
|
|
readonly processHeading: string;
|
|
readonly proofCaseId: CaseStudyId;
|
|
readonly proofHeading: string;
|
|
readonly proofNote: string;
|
|
readonly featuredCaseIds: readonly CaseStudyId[];
|
|
}
|
|
|
|
export interface PitchTimelineEntryCopy {
|
|
readonly id: string;
|
|
readonly period: string;
|
|
readonly role: string;
|
|
readonly body: string;
|
|
}
|
|
|
|
export interface PitchPageCopy extends PageCopy {
|
|
readonly profile: readonly string[];
|
|
readonly metrics: readonly MetricCopy[];
|
|
readonly timeline: readonly PitchTimelineEntryCopy[];
|
|
readonly coreStack: readonly StackGroupCopy[];
|
|
readonly featuredCaseIds: readonly CaseStudyId[];
|
|
readonly timelineHeading: string;
|
|
readonly stackHeading: string;
|
|
}
|
|
|
|
export interface ServicesOverviewPageCopy extends PageCopy {
|
|
readonly systemsMap: { readonly heading: string; readonly intro: string };
|
|
}
|
|
|
|
export type ContactFieldId =
|
|
'name' | 'email' | 'company' | 'projectType' | 'situation' | 'timeframe';
|
|
|
|
export interface ContactFieldOption {
|
|
readonly value: string;
|
|
readonly label: string;
|
|
}
|
|
|
|
export interface ContactFieldCopy {
|
|
readonly id: ContactFieldId;
|
|
readonly control: 'text' | 'email' | 'select' | 'textarea';
|
|
readonly label: string;
|
|
readonly hint?: string;
|
|
readonly required: boolean;
|
|
readonly options?: readonly ContactFieldOption[];
|
|
}
|
|
|
|
export interface ContactPageCopy extends PageCopy {
|
|
readonly fields: readonly ContactFieldCopy[];
|
|
readonly mailSubject: string;
|
|
readonly mailIntro: string;
|
|
readonly mailSignature: string;
|
|
readonly submitLabel: string;
|
|
readonly incompleteHint: string;
|
|
readonly requiredMarkerLabel: string;
|
|
readonly directEmailLabel: string;
|
|
readonly noBackendNote: string;
|
|
}
|
|
|
|
export interface LegalSectionCopy {
|
|
readonly id: string;
|
|
readonly title: string;
|
|
readonly body: readonly string[];
|
|
}
|
|
|
|
export interface LegalPageCopy extends PageCopy {
|
|
readonly reviewNotice: string;
|
|
readonly reviewTodos: readonly string[];
|
|
readonly legalSections: readonly LegalSectionCopy[];
|
|
}
|
|
|
|
export interface StackGroupCopy {
|
|
readonly id: string;
|
|
readonly title: string;
|
|
readonly body?: string;
|
|
}
|
|
|
|
export interface StackPageCopy extends PageCopy {
|
|
readonly groups: readonly StackGroupCopy[];
|
|
readonly evidenceNote: string;
|
|
}
|
|
|
|
export interface CaseStudyLabels {
|
|
readonly situation: string;
|
|
readonly approach: string;
|
|
readonly outcome: string;
|
|
readonly metrics: string;
|
|
readonly stack: string;
|
|
readonly tags: string;
|
|
}
|
|
|
|
export interface ProjectsPageCopy extends PageCopy {
|
|
readonly caseLabels: CaseStudyLabels;
|
|
}
|
|
|
|
export interface SiteSeoCopy {
|
|
readonly jobTitle: string;
|
|
readonly professionalServiceName: string;
|
|
readonly professionalServiceDescription: string;
|
|
}
|
|
|
|
export interface SiteContent {
|
|
readonly pages: Record<RouteId, PageCopy>;
|
|
readonly home: HomePageCopy;
|
|
readonly pitch: PitchPageCopy;
|
|
readonly services: ServicesPageCopy;
|
|
readonly cases: Record<CaseStudyId, CaseStudyCopy>;
|
|
readonly contact: ContactPageCopy;
|
|
readonly projects: ProjectsPageCopy;
|
|
readonly stack: StackPageCopy;
|
|
readonly legal: Record<'imprint' | 'privacy', LegalPageCopy>;
|
|
readonly seo: SiteSeoCopy;
|
|
}
|