{
    # ---------- plakat scenario sample ----------
    # Run with:
    #   export DEEPSEEK_API_KEY=sk-...
    #   plakat scenario examples/scenario.hjson
    #
    # Validate without generating or calling the enhancer:
    #   plakat scenario examples/scenario.hjson --dry-run
    # --------------------------------------------

    # === generation parameters (override CLI defaults) ===
    model: stable-diffusion-v1-5/stable-diffusion-v1-5

    # device options: auto | cuda[:N] | metal | cpu
    device: metal

    # SD 1.5 was trained at 512². Use 512x512 for best fidelity.
    size: 512x512
    # aspect/base are an alternative to size:
    # aspect: 3:2
    # base: 512

    # images per task
    count: 2

    steps: 28
    guidance: 7.0

    # base seed — per-task seeds are seed, seed+count, seed+2*count, …
    seed: 1000
    out: ./out/scenario

    # scheduler options: default | ddim | euler-a | unipc
    scheduler: euler-a

    # extra polish denoise steps appended after the main loop (same model)
    refine: 6
    # polish strength 0..1; lower = subtler
    refine-strength: 0.3

    # === optional real SDXL refiner (SDXL/SDXL-Turbo only) ===
    # If true, runs the last (1 - refiner-frac) of the schedule on the
    # stable-diffusion-xl-refiner-1.0 UNet. Adds ~6 GB download on first run.
    # Independent of `refine` above — both can be enabled simultaneously.
    refiner: false
    refiner-frac: 0.8

    # === optional post-generate upscale ===
    # If `upscale: true` and a task has `style`, the styled image is upscaled.
    # If `upscale: true` and no `style`, the original generated image is upscaled.
    # method options:
    #   classical (uses `scale`): nearest | bilinear | bicubic | lanczos
    #   ML (ignores `scale`):     real-esrgan-x2 | real-esrgan-x4 | real-esrgan-anime-x4
    upscale:
    {
        upscale: false
        scale: 2.0
        method: lanczos
    }

    # === LoRA stacking ===
    loras:
    [
        # SD 1.5 watercolor LoRA — single .safetensors auto-discovered.
        # `:0.8` is the per-LoRA scale (multiplied by `lora-scale` below).
        Arczisan/ink-watercolor:0.8
    ]
    lora-scale: 1.0

    # === prompt assembly ===
    #
    # The final per-task prompt is assembled as:
    #     lora-header + ENHANCED(prompt-header + scene + weather + task + prompt-footer) + lora-footer
    #
    # Stray leading/trailing commas in each fragment are normalized.

    # Inserted AFTER the enhancer — these are LoRA trigger tokens that the
    # enhancer should not rewrite.
    lora-header: "colorful inkpainting, watercolor,"
    lora-footer: ", masterpiece, high detail"

    # Inserted BEFORE the enhancer — global style/quality cues.
    prompt-header: "fantasy art,"
    prompt-footer: ", soft natural lighting, painterly composition"

    # `enhancer` is REQUIRED — currently: deepseek (uses DEEPSEEK_API_KEY)
    # or gemini (uses GEMINI_API_KEY)
    enhancer: deepseek

    negative: "blurry, low quality, deformed anatomy, watermark, text, signature, jpeg artifacts"

    # === catalogs: scenes ===
    # Each entry: { name: <ref>, prompt: <multiline-supported> }
    scene:
    [
        {
            name: town
            prompt:
                '''
                a medieval European town with cobblestone streets,
                tiled clay rooftops, hanging wooden signs above shop fronts,
                stone-walled houses with timber framing,
                people in period clothing walking the streets
                '''
        }
        {
            name: harbor
            prompt:
                '''
                a fishing harbor at dawn, wooden piers extending into still water,
                tall-masted ships at anchor, nets drying on racks,
                gulls wheeling overhead, lanterns reflecting on dark water
                '''
        }
        {
            name: forest
            prompt:
                '''
                an ancient temperate forest with twisted oaks and birches,
                mossy stones along a winding path,
                shafts of light cutting through the canopy,
                a small clearing with wildflowers
                '''
        }
    ]

    # === catalogs: weather ===
    weather:
    [
        {
            name: rain
            prompt:
                '''
                heavy summer rain, dark grey clouds overhead,
                glistening puddles on the ground, rain falling in visible streaks,
                damp atmosphere
                '''
        }
        {
            name: snow
            prompt:
                '''
                fresh snowfall under a pale winter sky,
                soft drifts on rooftops and ground,
                breath visible in cold air, muffled quiet ambience
                '''
        }
        {
            name: golden_hour
            prompt:
                '''
                late afternoon golden hour, warm low sunlight,
                long soft shadows, dust motes in the air,
                colors saturated and warm
                '''
        }
    ]

    # === catalogs: personas ===
    # Named identities a task can pull in via its own `personas` list.
    # Each persona is a reference photo + identity-adapter settings;
    # tasks that name a persona route through the SD 1.5 portrait
    # pipeline (IP-Adapter-Plus-Face) instead of the scenario's main
    # pipeline.
    #
    # Per-persona fields:
    #   name:           required, unique within the file.
    #   photo:          reference photo path (head-and-shoulders crop works best).
    #   identity:       optional, defaults to `plus-face` (SD 1.5).
    #                   `plus-face-sdxl` is also supported (SDXL portrait pipeline,
    #                   reuses the same CLIP-H encoder). FaceID / InstantID are roadmap.
    #                   All personas in one scenario must agree on the same strategy.
    #   face-strength:  0..2, default 0.8. Scales the image-token contribution.
    #   negative:       persona-only negative (e.g. "no glasses, no beard"); prepended.
    personas:
    [
        # {
        #     name: alice
        #     photo: ./references/alice.jpg
        #     face-strength: 0.85
        #     negative: "smiling, mustache"
        # }
        # {
        #     name: bob
        #     photo: ./references/bob.jpg
        #     face-strength: 0.7
        # }
    ]

    # === tasks: scene × weather combinations to render ===
    #
    # Optional per-task fields:
    #   style:          path to a reference image. If set, every generated
    #                   image is also run through IP-Adapter stylize using
    #                   this reference. Original AND styled both persist.
    #   style-strength: 0..1 (default 0.6) — higher = closer to REF.
    #
    #   personas:       list referencing the top-level `personas` catalog.
    #                   Two forms accepted (don't mix in one task):
    #                     [alice]                                  ← single persona, whole image.
    #                     [ {name:alice, bbox:[x0,y0,x1,y1]}, ... ] ← multi-persona, region-masked compositing.
    #                   Either form routes through the SD 1.5 portrait
    #                   pipeline; outputs land as plakat-portrait-<seed>.png.
    tasks:
    [
        {
            name: town_rainy
            scene: town
            weather: rain
            prompt: "merchants under awnings, children splashing in puddles"
            # style: ./references/watercolor.jpg
            # style-strength: 0.65
        }
        {
            name: harbor_golden
            scene: harbor
            weather: golden_hour
            prompt: "fishermen mending nets, a boy with a wooden boat at the water's edge"
        }
        {
            name: forest_snow
            scene: forest
            weather: snow
            prompt: "a lone traveler in a hooded cloak with a lantern"
        }
        # {
        #     # Single persona, whole image.
        #     name: alice_in_forest
        #     scene: forest
        #     weather: golden_hour
        #     prompt: "walking along the mossy path, lantern in hand"
        #     personas:
        #     [
        #         alice
        #     ]
        # }
        # {
        #     # Multi-persona compositing via region masks.
        #     # 16:9 aspect helps each bbox fit a recognisable face.
        #     name: alice_and_bob_harbour
        #     scene: harbor
        #     weather: golden_hour
        #     prompt: "two friends watching the boats come in, three-quarter angle"
        #     size: 1024x576
        #     personas:
        #     [
        #         {
        #             name: alice
        #             bbox: [0.05, 0.10, 0.48, 0.95]
        #         }
        #         {
        #             name: bob
        #             bbox: [0.52, 0.10, 0.95, 0.95]
        #         }
        #     ]
        # }
    ]
}
