/** * Detail-leveled camera / lighting / grade emitters. * * Pure, deterministic prompt-fragment builders. No I/O, no network. * Each emitter turns a structured spec into a human/provider-readable * string whose density scales with the requested {@link DetailLevel}: * - terse: evocative words only, no numbers * - standard: key numeric anchors (lens, Kelvin, ratio) * - rich: full numeric detail (velocity, fill/rim, hue/sat splits) */ export type DetailLevel = 'terse' | 'standard' | 'rich'; export type CameraMovement = 'push-in' | 'pull-out' | 'dolly' | 'orbit' | 'pan' | 'tilt' | 'track' | 'handheld' | 'locked-off'; export interface CameraMove { shot: string; lens: number; angle: string; movement: CameraMovement; velocityFtPerSec?: number; } export { lightingSpec, twoTemperatureClause, gradeSpec, lightingProse, gradeProse } from './lighting-grade-register.js'; export { HOOK_PATTERN_IDS, resolveHookPattern, hookBeat } from './hook-register.js'; export type { HookPatternId } from './hook-register.js'; export { specularKillClause, subsurfaceScatteringClause, strandHairClause, contrastCurveClause, moistureMatteClause, flatteringRealismClause, volumetricHaze, captureRealismBlock, phoneCaptureBlock, volumetricHazeThreePlane, backgroundPlate } from './realism-register.js'; export type { HazeDensity, CaptureRealismOpts, PhoneCaptureOpts, ThreePlaneHazeOpts, PlateKind } from './realism-register.js'; export { DYNAMIC_REGISTER_IDS, dynamicRegister, dynamicRegisterClause, strobeBlock } from './dynamic-register.js'; export type { DynamicRegisterId, DynamicRegister } from './dynamic-register.js'; /** * Build a camera-move prompt fragment at the requested detail level. */ export declare function cameraSpec(m: CameraMove, d: DetailLevel): string; /** * Build a PROSE camera fragment for a {@link CameraMovement} at the requested * detail level. KEEPS focal length mm (and any fps/shutter the caller adds) — * those are real optical numerals — but carries NO Kelvin / key-angle degrees / * contrast ratio. Unknown movements fall back to a handheld description. */ export declare function cameraProse(move: CameraMovement, d: DetailLevel): string; /** * A fully-specified cinema mode: the camera-worldbuilder backbone. * * Each field is a self-contained prompt fragment describing one axis of * the look, so a caller can assemble a mode into a coherent shot recipe. */ export interface ModeSpec { camera: string; lens: string; movement: string; filtration: string; grade: string; } /** * The five canonical cinema modes. Order is intentional (narrative first, * as the safe fallback); tests assert the sorted set. */ export declare const CINEMA_MODE_IDS: readonly ["narrative", "studio", "action", "performance", "atmospheric"]; export type CinemaModeId = (typeof CINEMA_MODE_IDS)[number]; /** * Resolve a cinema mode by id, falling back to `narrative` for unknown * ids rather than throwing. */ export declare function cinemaMode(id: CinemaModeId): ModeSpec; /** * Map a {@link CategoryDescriptor} `cameraVocab` token onto a {@link ModeSpec}. * * `orbit` resolves to a synthesized orbit spec; other known tokens map to a * canonical mode. Unknown tokens fall back to `narrative` rather than throwing. */ export declare function resolveCameraVocab(vocab: string): ModeSpec; /** * One stacked shot in a multi-world intercut sequence: a single shot that * carries its OWN cinema-mode {@link ModeSpec} and a rendered camera `block`. */ export interface StackedShot { modeId: CinemaModeId; spec: ModeSpec; block: string; } /** * Stack cinema modes for a multi-world intercut sequence. * * Returns one {@link StackedShot} per input mode id, preserving input order * AND duplicates. Each shot keeps its OWN {@link cinemaMode} spec and rendered * camera block — adjacent modes are never averaged, merged, or collapsed into * a single register, so intercutting between worlds stays visually distinct. */ export declare function stackModes(modeIds: CinemaModeId[]): StackedShot[]; /** * Resolve a category audio profile to a layered sound-design line. Pure and * deterministic; defaults to the `standard` detail level. */ export declare function soundDesign(profile: 'diegetic' | 'ad-mix', detail?: DetailLevel): string; /** * Per-genre look defaults: concrete color / lighting / cut-rate anchors a * caller can seed a shot plan with before any per-shot overrides. * * `keyLightId` references an id understood by {@link lightingSpec} * (e.g. `'neutral-studio'`, `'golden-hour'`, `'hard-dawn'`, `'night-fire'`). */ export interface GenreDefaults { paletteHue: number; saturationPct: number; cutRatePerSec: number; keyLightId: string; } /** * Resolve per-genre look defaults. Case-insensitive; unknown genres fall * back to a neutral default rather than throwing. */ export declare function genreDefaults(genre: string): GenreDefaults; /** * A single ordered beat in a structured shot timeline. Beats are contiguous: * the first `start` is 0 and the last `end` is the clip duration, with no gaps. */ export interface Beat { start: number; end: number; label: string; direction: string; } /** * The beat-structure templates a shot plan can be scaffolded from. Mirrors the * `BeatTemplate` union in {@link ../category-registry}. */ export type BeatTemplateId = 'three-act' | 'ad-hook-feature-cta' | 'turntable' | 'lookbook' | 'song-structure' | 'tension-release' | 'social-2s-hook' | 'panel-sequence'; /** * Generate an ordered, contiguous set of {@link Beat}s for a beat template. * * The first beat always starts at 0 and the last beat always ends at * `durationSeconds`, with no gaps between adjacent beats. * * - `three-act`: setup → inciting → rising → climax → resolve. * - `ad-hook-feature-cta`: a HOOK beat `[0, hookSeconds]` (defaulting to a short * 2s hook, clamped below the duration, when `hookSeconds` is 0), then * feature/benefit beats, ending with a CTA beat. * - `turntable`: a "Hero angle" open and a "Hero angle (return)" close bracketing * rotation beats. * - `lookbook`: a sequence of pose-change beats. */ export declare function beats(template: BeatTemplateId, durationSeconds: number, hookSeconds: number): Beat[]; /** * Precise orbit/turntable camera grammar. Product-360 categories need exact * terms — a generic "orbit" conflates three distinct motions: * - `product-rotation`: the object spins; the camera stays locked/static. * - `camera-orbit`: the camera circles a static subject. * - `parallax-orbit`: the camera arcs with foreground/background depth parallax. * * Order is intentional and stable; tests assert the sorted set. */ export declare const ORBIT_KINDS: readonly ["product-rotation", "camera-orbit", "parallax-orbit"]; export type OrbitKind = (typeof ORBIT_KINDS)[number]; /** * Resolve a precise camera-direction string for an {@link OrbitKind}. Unknown * kinds fall back to the `camera-orbit` grammar rather than throwing. */ export declare function orbitGrammar(kind: OrbitKind): string; /** * Build an audio-mix prompt fragment at the requested detail level. * - terse: evocative words only, no numbers * - standard: brief layer naming * - rich: an explicit dB hierarchy with a silence/re-entry beat */ export declare function audioMix(d: DetailLevel): string; /** * Beat-aligned audio direction for music videos. Positive tempo phrasing only * (negative direction like "no slow motion" does not work on these models). */ export declare function musicSyncLine(bpm: number | undefined, d: DetailLevel): string; /** * FOV degree anchor ladder (Joey 3.0 Worldbuilder). Seedance latches onto FOV * in DEGREES as a discrete snap value — degrees read as instruction where a * bare millimetre reads as suggestion, and multishot sequences that only name * mm drift lens character between beats. Only these anchor steps exist; an * off-ladder value (e.g. 23°) is a hard error, never rounded silently. */ export interface FovAnchor { /** FOV in degrees — the value the model actually snaps to. */ deg: number; /** Canonical full-frame mm equivalent, written as a reader aid only. */ mm: number; /** The lens feel, written into the prompt after the degree token. */ feel: string; /** What the step is for (operator guidance; not emitted). */ useFor: string; } export declare const FOV_ANCHORS: readonly FovAnchor[]; export declare const FOV_ANCHOR_DEGREES: readonly number[]; /** * The short FOV anchor token for a ladder degree — `"47° (50mm) eye-level * neutral"`. Throws on any off-ladder degree (the ladder is the contract; a * non-anchor value drifts, so it is refused rather than rounded). */ export declare function fovAnchor(deg: number): string; /** * Full prompt line for the FOV anchor, with the hold-the-lens clause that stops * multishot lens drift (the failure the degree ladder exists to fix). */ export declare function fovAnchorLine(deg: number): string; /** * Cuts & timing precision scale (Joey 3.0 Worldbuilder). Four registers, * most-to-least precise; pick the tightest level the shot actually requires. * Whenever cuts exist, the clause closes the door on unintended edits. */ export declare const CUTS_PRECISION_IDS: readonly ["oner", "sequential", "timed", "freestyle"]; export type CutsPrecision = (typeof CUTS_PRECISION_IDS)[number]; /** Cut-trigger vocabulary these models recognise inside Movement beats. */ export declare const CUT_VOCABULARY: readonly ["HARD CUT", "SMASH CUT", "MATCH CUT", "INSERT CUT", "REVERSE CUT", "WHIP CUT"]; /** * The edit-precision clause for a cuts register. Continuity across any internal * cut is the caller's job (same subject set, same left/right geometry, same * eyeline, light, wardrobe, and prop states) — this clause locks the edit * COUNT and timing, not the continuity. */ export declare function cutsClause(precision: CutsPrecision): string; /** * The LOCKED FLAT GRADE close for character plates and sheets (Joey 3.0 Banana * Pro). A character plate is a reference, not a finished frame: any shadow * baked into it — a cheek triangle, a nose shadow, a contact shadow, a backdrop * falloff — is inherited and amplified by every downstream generation and * fights whatever lighting the actual scene wants. So the plate carries ZERO * lighting information. Three mandatory elements, always together: a flat * backdrop (one uniform value), shadowless illumination (matched fill on all * sides), and zero cast shadow. Distinct from {@link backgroundPlate} (the * lean plate clause) — this is the full relight-from-scratch close. Black has * no flat-grade variant (a flat black plate cannot hold the no-falloff * contract), so the kind is narrowed to mid-gray | white. */ export declare function flatGradeClose(kind: 'mid-gray' | 'white', d: DetailLevel): string; //# sourceMappingURL=cinematography.d.ts.map