/** * 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; } /** * Build a camera-move prompt fragment at the requested detail level. */ export declare function cameraSpec(m: CameraMove, d: DetailLevel): string; /** * Build a lighting prompt fragment at the requested detail level. * Unknown ids fall back to a neutral string rather than throwing. */ export declare function lightingSpec(id: string, d: DetailLevel): string; /** * The camera-bible "two-temperature technique": a warm key against a cool fill * (or the reverse). Two temperatures in one shot read as depth, complexity, and * dimension; a single temperature reads flat. Resolves the warm/cool Kelvin * from the {@link LIGHTING} registry (unknown ids fall back to a warm * golden-hour key / cool moonlight fill rather than throwing). Pure. */ export declare function twoTemperatureClause(warmId: string, coolId: string, d: DetailLevel): string; /** * Build a color-grade prompt fragment at the requested detail level. * Unknown ids fall back to a neutral string rather than throwing. */ export declare function gradeSpec(id: string, d: DetailLevel): string; /** * Build a PROSE lighting fragment at the requested detail level. Carries NO * Kelvin / degrees / ratio numerals (use {@link lightingSpec} for those). * Unknown ids fall back to a neutral description rather than throwing. */ export declare function lightingProse(id: string, d: DetailLevel): string; /** * Build a PROSE grade fragment at the requested detail level. Carries NO * hue° / sat% / lift-gamma numerals (use {@link gradeSpec} for those). * Unknown ids fall back to a neutral description rather than throwing. */ export declare function gradeProse(id: string, 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[]; /** * The named 2-second hook patterns: scroll-stopping opening beats. Order is * intentional and stable; callers may iterate {@link HOOK_PATTERN_IDS}. */ export declare const HOOK_PATTERN_IDS: readonly ["black-to-light", "silence-to-sound", "reverse-motion", "beat-drop", "match-cut-in", "whip-reveal", "speed-ramp", "first-person-rush", "impact-freeze", "title-burn-in", "slow-reveal", "snap-zoom", "scale-reveal", "particle-materialize", "impossible-angle", "kinetic-decompose", "smash-zoom", "rubber-hose-stretch", "color-pop-burst", "fourth-wall-wink", "weapon-clash-spark", "ground-slam-shockwave", "blade-unsheath-flash", "speed-line-burst", "power-up-aura", "sakura-gust", "cross-impact-flash", "hi-hat-flash-cuts", "synth-glitch", "harmonic-color-shift", "downbeat-reveal", "impossible-scale", "half-reveal", "wait-for-it", "ladder-reveal"]; export type HookPatternId = (typeof HOOK_PATTERN_IDS)[number]; /** * 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; /** * Resolve a named opening-hook pattern id to its directive description. * * Like {@link hookBeat}, an unknown id THROWS rather than falling back — hooks * must be explicit. Exported so CLI surfaces can prepend the directive without * re-deriving the table. */ export declare function resolveHookPattern(pattern: HookPatternId): string; /** * Render a named 2-second opening hook as a timecoded beat. * * Returns `"[00:00 - 00:0N] "` where `N` is `hookSeconds` * (zero-padded, assumed < 60). Unlike the cinema-mode resolvers, an unknown * pattern id THROWS rather than falling back — hooks must be explicit. */ export declare function hookBeat(pattern: HookPatternId, hookSeconds: number): 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; /** * Anti-plastic physics clauses (banana-pro-director). Each is a standalone * exported string helper so callers can compose them individually before the * full captureRealismBlock lands. Per-zone specular naming is required — * "matte skin" alone is too weak and gets overridden by the model default. */ export declare function specularKillClause(): string; export declare function subsurfaceScatteringClause(): string; export declare function strandHairClause(): string; export declare function contrastCurveClause(): string; export declare function moistureMatteClause(): string; export declare function flatteringRealismClause(): string; export type HazeDensity = 'thin' | 'light' | 'heavy'; /** * Volumetric depth ("lighting the air") — the single biggest anti-plastic * depth lever. Exposed standalone; previously reachable only inside the * `atmospheric` cinema mode's filtration field. */ export declare function volumetricHaze(density: HazeDensity, d: DetailLevel): string; export interface CaptureRealismOpts { /** Emit the moisture-matte clause (skipped when false/omitted). */ wet?: boolean; /** Haze density for the depth clause (default 'light'). */ haze?: HazeDensity; /** Film-grain stock descriptor (default '35mm'). */ grainStock?: string; } /** * The keystone anti-AI-look block: physics-vs-hardware separation that does not * exist anywhere else in the codebase. Composes per-zone specular kill, * subsurface scattering, strand hair, contrast-curve-three-ways, volumetric * haze, optional moisture, the flattering-realism ceiling, and film grain. * Pure and deterministic; density scales with DetailLevel. */ export declare function captureRealismBlock(opts: CaptureRealismOpts, d: DetailLevel): string; export interface PhoneCaptureOpts { /** Emit the flattering-skin clause (default true; set false to drop it). */ flatteringSkin?: boolean; } /** * The amateur / anti-AI phone-capture register — the UGC sibling of * {@link captureRealismBlock}. Where captureRealismBlock describes high-end * cinema hardware (anamorphic glass, diffusion, film grain), THIS register * deliberately strips all of that and reads as an unstaged smartphone clip: * available light, computational-HDR flatness, slight phone-lens softness, and * the casual imperfection that signals "not an ad." This is a NEW sibling * register — the phone/UGC voice is NOT part of Joey's 2.0 skills (those are * cinema-only); it is inspired by Joey's anti-AI / "avoid commercial gloss" * philosophy rather than lifted from his wording. * * A flattering-skin clause is kept by default (good UGC still flatters the * subject); that clause IS from banana-pro-director-2.0. The cinema gear — film * grain, anamorphic, diffusion bloom — is dropped. Pure and deterministic; * density scales with DetailLevel. */ export declare function phoneCaptureBlock(opts: PhoneCaptureOpts, d: DetailLevel): string; export interface ThreePlaneHazeOpts { /** Haze density (default 'light'). */ density?: HazeDensity; /** Foreground plane label — what sits sharpest/most-saturated nearest camera. */ foreground?: string; /** Midground plane label — the softening transitional plane. */ midground?: string; /** Background plane label — softest, most desaturated, lowest-contrast. */ background?: string; } /** * Three-plane volumetric haze: the depth-staging extension of * {@link volumetricHaze}. When given foreground / midground / background plane * labels it emits the explicit three-plane relationship — the foreground sharp * and saturated, the midground softening, the background softest, most * desaturated, and lowest-contrast — so the haze reads as real staged depth * rather than a flat wash. * * Backward-compatible: with NO plane labels it returns exactly today's * single-register {@link volumetricHaze} string. Carries no Kelvin / degrees / * ratio numerals. Pure and deterministic. */ export declare function volumetricHazeThreePlane(opts: ThreePlaneHazeOpts, d: DetailLevel): string; export type PlateKind = 'mid-gray' | 'white' | 'black'; /** * Backdrop plate spec. Mid-gray is the locked default for ALL character work — * it lowers subject-to-background contrast so downstream video inherits cleaner * edges. White/black are explicit opt-ins. */ export declare function backgroundPlate(kind: PlateKind, 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; //# sourceMappingURL=cinematography.d.ts.map