import { lightenHex } from './bannerStyle.js'; import type { PageModel } from './store.js'; export { lightenHex }; /** Host-declared description of one canvas section. */ export interface SectionHeaderDef { /** Section name exactly as the frames carry it — the join key. */ section: string; /** Short handle shown large, e.g. "02". */ code: string; /** Section title, e.g. "care". */ title: string; /** Secondary clause after the title: what kind of group this is. */ kind?: string; /** One line a planner needs: what the section covers. */ purpose: string; /** Accent colour for the rule and the category pill. */ accent: string; /** Category shown in the pill. */ pill?: string; } /** * Words for the facts the core counts. Defaults are English; a host renders * its own language by declaring them, which is how the band stays localized * without the core carrying any copy of its own. */ export interface SectionHeaderLabels { /** Caption above the code. Default "SECTION". */ code?: string; /** Unit for the frame count. Default "frames". */ frames?: string; /** Unit for folded state variants. Default "folded". */ folded?: string; /** Unit for the scenario count. Default "scenarios". */ scenarios?: string; /** Unit for the flow list. Default "flows". */ flows?: string; } export interface SectionHeaderDiagnostic { severity: 'error' | 'warning'; section: string; message: string; } export interface SectionHeaderFacts { /** Every frame that belongs to the section, folded variants included. */ frameCount: number; /** Members parked behind a slot holder rather than shown on the canvas. */ foldedCount: number; /** Distinct canonical scenario ids among the members. */ scenarioCount: number; /** Distinct flows, only worth showing when a section spans more than one. */ flows: string[]; /** Authored viewport shared by the members, or null when there is no one answer. */ viewport: string | null; } export declare function resolveSectionHeaderLabels(labels: SectionHeaderLabels | undefined): Required; export declare function validateSectionHeaders(defs: readonly SectionHeaderDef[], context: { sections: readonly string[]; }): SectionHeaderDiagnostic[]; /** * What the core can see about a section without being told. `isShown` marks * the members holding a canvas slot; the rest are folded state variants. */ export declare function sectionHeaderFacts(pages: readonly PageModel[], options?: { isShown?: (page: PageModel) => boolean; }): SectionHeaderFacts; /** * The derived line, in the order a reviewer scans it. Facts that would only * repeat the title are left out: a single flow is always the section itself, * and a section with no scenarios has nothing to say about coverage. */ export declare function sectionHeaderFactLine(facts: SectionHeaderFacts, labels: Required): string; export declare const SECTION_HEADER_STYLE: { readonly radius: 12; readonly pillRadius: 999; readonly ruleWidth: 6; readonly gap: 24; readonly paddingY: 20; readonly paddingRight: 32; readonly captionSize: 12; readonly codeSize: 40; readonly titleSize: 32; readonly metaSize: 15; readonly pillSize: 12; readonly pillPaddingY: 6; readonly pillPaddingX: 14; readonly surface: "#343441"; readonly pillSurface: "#2e2c3a"; readonly caption: "#a1a1b3"; readonly code: "#ffffff"; readonly title: "#e7e7f0"; readonly titleMuted: "#a1a1b3"; readonly meta: "#bebecb"; readonly purpose: "#c4ccd8"; }; /** * Room the band needs above a section box, in canvas units. Sections used to * stack 120px apart with 28px of box padding at each end, leaving 64px — less * than half a band — so the layout reserves this instead. Both the renderer * and the layout read it from here so they cannot drift apart. * * Sized for a purpose line that wraps once at section width; a purpose long * enough to take three lines is an authoring problem, not a layout one. */ export declare const SECTION_HEADER_RESERVE = 176; /** * Widest a band is allowed to be, in canvas units. * * A band spanning its section reached 4333px on the care canvas, which put the * category pill several screens to the right of the code it belongs to — the * identity stopped reading as one object. A banner is a label, so it takes a * measure a reader can take in at once and stops. */ export declare const SECTION_HEADER_MAX_WIDTH = 1280; /** One editor's declared section headers and their labels. */ export declare function createSectionHeaders(): { setSectionHeaders: (defs: readonly SectionHeaderDef[], labels?: SectionHeaderLabels) => void; getSectionHeaders: () => readonly SectionHeaderDef[]; getSectionHeaderLabels: () => SectionHeaderLabels | undefined; sectionHeaderFor: (section: string) => SectionHeaderDef | null; }; export type SectionHeaders = ReturnType;