MOTION PALETTE
← すべてのデモ

Blueprint Build

HeroSVG / GSAP / Three.js

フルスクリーンで開く ↗

枠の中でスクロール・クリックして動きを試せます。端末指定は実寸表示です。幅が足りない場合は横にスクロールできます。

再現プロンプト

DATUMという架空の製品設計スタジオ。共通の部品データから図面とThree.jsの立体を描き、部品選択・向き・材質・分離表示を操作して、検討事項を保存できる。 配色・構成・動きの数値をまとめた指示書です。 お使いのAIに貼り、素材やお店の情報を伝えて実装してください。仕上がりは利用するAIと素材によって変わります。

Build a self-contained HTML page for DATUM, a fictional product-engineering studio. Use inline CSS and JavaScript, GSAP with ScrollTrigger and Three.js with RoundedBoxGeometry and RoomEnvironment addons via an ES-module import map. No backend is required. The page is a cyanotype drawing set: outlines become dimensions, then surfaces; the product study turns the drawing into something visitors can inspect and discuss.

## Editorial and art direction
Use English throughout. Ground #0B2A5C, recessed panels #081F45, cards #0E3269, text #DCE8FF, secondary text #BACDEC and accent #5C9DFF; selected components use #8DC1FF. Use a geometric sans for headings and body copy, and a system monospace for dimensions, part labels and sheet references. Headings are bold and tightly spaced, not decorative outlined type. A 24px minor / 120px major grid continues through the scrollable drawing sheet with white-blue lines at .05 / .1 opacity. Keep comfortable text contrast and at least 44px control targets.

The five sections are Hero, Capabilities, Concept studies, Explore UNIT-7 and Project brief. The nav contains DATUM, Capabilities, Projects, Explore UNIT-7, a Motion checkbox and Start a project. Show all section links on mobile in a second navigation row, keeping the Motion checkbox alongside the brand and CTA in the first row; use a 64px desktop nav and 112px compact nav, with matching content padding. Section links scroll to the real heading and transfer focus without a second scroll. The header Start a project opens the local project brief directly. Show a small SHEET 0N / 05 desktop HUD tied to actual section positions.

Hero headline: “Every product starts / as a set of tolerances.” Body: “A clear drawing makes a better conversation. Explore how form, controls and connections come together in a field-instrument concept, then define the questions your own product needs to answer.” An Explore UNIT-7 button leads to the inspector. Beside it, show front and right orthographic exterior drawings generated from the exact same component definitions as the 3D assembly below. The body is 128 × 86 × 34 mm, excluding all external hardware, feet, fins and antenna. Never use the old 148 × 72 mm portrait drawing.

## Common component data
One world unit equals 100 mm. The following array is the complete exterior assembly. Primitive kind and args map directly to Three.js RoundedBoxGeometry(width,height,depth,segments,radius), BoxGeometry(width,height,depth), CylinderGeometry(topRadius,bottomRadius,height,segments), TorusGeometry(radius,tube,radialSegments,tubularSegments) or SphereGeometry(radius,widthSegments,heightSegments). Positions, rotations and separation offsets use world units and radians. Do not invent a PCB, battery, hollow internal shell, watertight rating or manufacturing-ready CAD geometry. The product consists of 38 meshes in five semantic groups.

[{"id":"body-0","partId":"body","primitive":{"kind":"rounded","args":[1.28,0.86,0.34,4,0.07]},"material":"alu","pos":[0,0.45,0],"wireSrc":{"kind":"box","args":[1.28,0.86,0.34]},"explode":[0,0,0]},{"id":"display-1","partId":"display","primitive":{"kind":"rounded","args":[0.94,0.5,0.05,3,0.02]},"material":"aludark","pos":[0,0.585,0.155],"wireSrc":{"kind":"box","args":[0.94,0.5,0.05]},"explode":[0,0,0.48]},{"id":"display-2","partId":"display","primitive":{"kind":"box","args":[0.82,0.4,0.03]},"material":"screen","pos":[0,0.585,0.175],"explode":[0,0,0.48]},{"id":"controls-3","partId":"controls","primitive":{"kind":"cylinder","args":[0.13,0.13,0.07,32]},"material":"alu","pos":[0.38,0.17,0.19],"rot":[1.5707963267948966,0,0],"wireThreshold":20,"explode":[0,-0.04,0.8]},{"id":"controls-4","partId":"controls","primitive":{"kind":"cylinder","args":[0.045,0.045,0.09,24]},"material":"accent","pos":[0.38,0.17,0.195],"rot":[1.5707963267948966,0,0],"wireSrc":null,"explode":[0,-0.04,0.8]},{"id":"controls-5","partId":"controls","primitive":{"kind":"torus","args":[0.13,0.014,12,40]},"material":"aludark","pos":[0.38,0.17,0.226],"wireSrc":null,"explode":[0,-0.04,0.8]},{"id":"controls-6","partId":"controls","primitive":{"kind":"box","args":[0.16,0.07,0.03]},"material":"aludark","pos":[-0.33,0.17,0.18],"explode":[0,-0.04,0.8]},{"id":"controls-7","partId":"controls","primitive":{"kind":"box","args":[0.16,0.07,0.03]},"material":"aludark","pos":[-0.11,0.17,0.18],"explode":[0,-0.04,0.8]},{"id":"body-8","partId":"body","primitive":{"kind":"cylinder","args":[0.022,0.022,0.03,16]},"material":"aludark","pos":[-0.56,0.09,0.165],"rot":[1.5707963267948966,0,0],"wireSrc":null,"explode":[0,0,0]},{"id":"body-9","partId":"body","primitive":{"kind":"cylinder","args":[0.022,0.022,0.03,16]},"material":"aludark","pos":[0.56,0.09,0.165],"rot":[1.5707963267948966,0,0],"wireSrc":null,"explode":[0,0,0]},{"id":"body-10","partId":"body","primitive":{"kind":"cylinder","args":[0.022,0.022,0.03,16]},"material":"aludark","pos":[-0.56,0.81,0.165],"rot":[1.5707963267948966,0,0],"wireSrc":null,"explode":[0,0,0]},{"id":"body-11","partId":"body","primitive":{"kind":"cylinder","args":[0.022,0.022,0.03,16]},"material":"aludark","pos":[0.56,0.81,0.165],"rot":[1.5707963267948966,0,0],"wireSrc":null,"explode":[0,0,0]},{"id":"body-12","partId":"body","primitive":{"kind":"box","args":[0.025,0.006,0.002]},"material":"rubber","pos":[-0.56,0.09,0.181],"wireSrc":null,"explode":[0,0,0]},{"id":"body-13","partId":"body","primitive":{"kind":"box","args":[0.025,0.006,0.002]},"material":"rubber","pos":[0.56,0.09,0.181],"wireSrc":null,"explode":[0,0,0]},{"id":"body-14","partId":"body","primitive":{"kind":"box","args":[0.025,0.006,0.002]},"material":"rubber","pos":[-0.56,0.81,0.181],"wireSrc":null,"explode":[0,0,0]},{"id":"body-15","partId":"body","primitive":{"kind":"box","args":[0.025,0.006,0.002]},"material":"rubber","pos":[0.56,0.81,0.181],"wireSrc":null,"explode":[0,0,0]},{"id":"thermal-16","partId":"thermal","primitive":{"kind":"box","args":[0.085,0.07,0.24]},"material":"fin","pos":[-0.45,0.905,0],"explode":[0,0.42,0]},{"id":"thermal-17","partId":"thermal","primitive":{"kind":"box","args":[0.085,0.07,0.24]},"material":"fin","pos":[-0.27,0.905,0],"explode":[0,0.42,0]},{"id":"thermal-18","partId":"thermal","primitive":{"kind":"box","args":[0.085,0.07,0.24]},"material":"fin","pos":[-0.09000000000000002,0.905,0],"explode":[0,0.42,0]},{"id":"thermal-19","partId":"thermal","primitive":{"kind":"box","args":[0.085,0.07,0.24]},"material":"fin","pos":[0.09000000000000002,0.905,0],"explode":[0,0.42,0]},{"id":"thermal-20","partId":"thermal","primitive":{"kind":"box","args":[0.085,0.07,0.24]},"material":"fin","pos":[0.26999999999999996,0.905,0],"explode":[0,0.42,0]},{"id":"thermal-21","partId":"thermal","primitive":{"kind":"box","args":[0.085,0.07,0.24]},"material":"fin","pos":[0.4499999999999999,0.905,0],"explode":[0,0.42,0]},{"id":"connections-22","partId":"connections","primitive":{"kind":"cylinder","args":[0.018,0.024,0.34,12]},"material":"aludark","pos":[-0.55,1.02,0],"wireThreshold":20,"explode":[0,0.45,0]},{"id":"connections-23","partId":"connections","primitive":{"kind":"sphere","args":[0.032,16,12]},"material":"accent","pos":[-0.55,1.21,0],"wireSrc":null,"explode":[0,0.45,0]},{"id":"connections-24","partId":"connections","primitive":{"kind":"rounded","args":[0.05,0.52,0.24,2,0.015]},"material":"side","pos":[0.645,0.45,0],"wireSrc":{"kind":"box","args":[0.05,0.52,0.24]},"explode":[0.48,0,0]},{"id":"connections-25","partId":"connections","primitive":{"kind":"cylinder","args":[0.05,0.05,0.05,20]},"material":"side","pos":[0.675,0.62,0.055],"rot":[0,0,1.5707963267948966],"wireSrc":null,"explode":[0.48,0,0]},{"id":"connections-26","partId":"connections","primitive":{"kind":"cylinder","args":[0.05,0.05,0.05,20]},"material":"side","pos":[0.675,0.62,-0.055],"rot":[0,0,1.5707963267948966],"wireSrc":null,"explode":[0.48,0,0]},{"id":"connections-27","partId":"connections","primitive":{"kind":"box","args":[0.05,0.1,0.16]},"material":"side","pos":[0.67,0.3,0],"explode":[0.48,0,0]},{"id":"connections-28","partId":"connections","primitive":{"kind":"cylinder","args":[0.033,0.033,0.002,24]},"material":"rubber","pos":[0.701,0.62,-0.055],"rot":[0,0,1.5707963267948966],"wireSrc":null,"explode":[0.48,0,0]},{"id":"connections-29","partId":"connections","primitive":{"kind":"cylinder","args":[0.033,0.033,0.002,24]},"material":"rubber","pos":[0.701,0.62,0.055],"rot":[0,0,1.5707963267948966],"wireSrc":null,"explode":[0.48,0,0]},{"id":"connections-30","partId":"connections","primitive":{"kind":"box","args":[0.002,0.055,0.12]},"material":"rubber","pos":[0.696,0.3,0],"wireSrc":null,"explode":[0.48,0,0]},{"id":"thermal-31","partId":"thermal","primitive":{"kind":"box","args":[0.6,0.025,0.02]},"material":"aludark","pos":[0,0.72,-0.175],"wireSrc":null,"explode":[0,0,-0.48]},{"id":"thermal-32","partId":"thermal","primitive":{"kind":"box","args":[0.6,0.025,0.02]},"material":"aludark","pos":[0,0.6599999999999999,-0.175],"wireSrc":null,"explode":[0,0,-0.48]},{"id":"thermal-33","partId":"thermal","primitive":{"kind":"box","args":[0.6,0.025,0.02]},"material":"aludark","pos":[0,0.6,-0.175],"wireSrc":null,"explode":[0,0,-0.48]},{"id":"thermal-34","partId":"thermal","primitive":{"kind":"box","args":[0.6,0.025,0.02]},"material":"aludark","pos":[0,0.54,-0.175],"wireSrc":null,"explode":[0,0,-0.48]},{"id":"thermal-35","partId":"thermal","primitive":{"kind":"box","args":[0.6,0.025,0.02]},"material":"aludark","pos":[0,0.48,-0.175],"wireSrc":null,"explode":[0,0,-0.48]},{"id":"body-36","partId":"body","primitive":{"kind":"box","args":[1.06,0.035,0.09]},"material":"rubber","pos":[0,0.017,0.09],"wireSrc":null,"explode":[0,-0.18,0]},{"id":"body-37","partId":"body","primitive":{"kind":"box","args":[1.06,0.035,0.09]},"material":"rubber","pos":[0,0.017,-0.09],"wireSrc":null,"explode":[0,-0.18,0]}]

Use the same definitions for the SVG and 3D. For the front drawing, horizontal position comes from X; for the right drawing it comes from negative Z. Vertical position comes from Y. Project each primitive's extents, including its quarter-turn rotation. Sort parts back to front by Z for the front view and X for the right view. Use circles/ellipses for front-facing cylinders, torus silhouettes and spheres, and rectangles for other projected exterior silhouettes. A 640 × 410 viewBox uses 155px per world unit, front origin X=205, right origin X=490 and Y=320-worldY×155. Dimension lines refer to the body's actual bounds, with 128 mm under the front, 86 mm beside it and 34 mm under the right. Label these explicitly as body dimensions, excluding external hardware. This is an orthographic exterior drawing, not a hidden-line CAD export.

On the hero drawing, stroke-draw geometry via getTotalLength()/strokeDashoffset over .9 seconds with .015-second stagger; reveal dimension groups over .45 seconds with .25-second overlap, then fill over .65 seconds with .15-second overlap. Trigger once at top 90%. Keep a completed flag. Scope the whole timeline in a GSAP context and revert it on unmount or a live motion-preference change. With motion off, show complete drawings immediately. Do not leave essential text hidden while waiting for an animation.

## Capabilities and concept studies
Show four capability sheets, each with a small inline SVG schematic and a Plan a [discipline] study button. Structural: bracket geometry, load paths and fastener patterns. Thermal: fin spacing, airflow and heat-load testing; label the arrow “Airflow study”, not a measured temperature improvement. Electronics: board keep-outs and enclosure fit, explicitly a separate illustrative schematic. Enclosure: gasket compression, draft and protection requirements to review. Dimensions and callouts remain visible on touch devices. All four buttons preselect Engineering study and include the selected discipline and its review focus in the brief.

Use four native details/summary project cards with diagrams, category, Concept study label and a Study brief +/− affordance. Opening a card exposes its purpose, a review question and Plan a similar study. These are fictional concept exercises, not shipped work with invented dates:
• Fathom-2 Dive Computer: a wrist-mounted display and secure strap; ask about underwater readability, pressure and gloved use.
• Rundown Bracket Kit: compact mounting in limited space; ask about load cases, fastener access and mating-surface tolerances.
• Vaultline Rack Module: indicators and ventilation in a serviceable rack front; ask about cooling, cable routing and module replacement.
• Coriolis Flow Sensor: an in-line instrument housing with accessible flanges; ask which fluid, pressure and installation conditions apply to the sensing mechanism and enclosure.
Each project CTA preselects Product concept and carries that project's name, purpose and review question. Do not attach unrelated UNIT-7 selection to these project briefs.

Small capability and project SVGs draw their outlines over .9 seconds with .12-second stagger, then annotations over .45 seconds and fills over .65 seconds. Use a single owned once-only ScrollTrigger timeline per diagram, never accumulate hover-created timelines or reverse-hide the text when scrolling backwards. Only main headings use a short grid alignment entrance: opacity .75→1 and Y 8→0 over .5 seconds, back.out(2.4), once at top 92%. Paragraphs, buttons, cards and notes are always available.

## UNIT-7 product inspector
Heading: “From drawing / to understanding.” Intro: “UNIT-7 is a field-instrument concept. Explore its exterior, isolate a design question and take that question into your next review.” Place the large 3D viewport on the left and the controls / selected-part notes on the right. Use a restrained radial blue ground and a small UNIT-7 / REV A caption. Desktop viewport height clamps between 280 and 480px at 48% of the local scrolling viewport. On compact screens, place it above the controls, sticky beneath the 112px nav, with a 210–340px height at 34% of the scroll viewport. Disable sticky positioning in short landscape viewports. All controls and notes must remain reachable at 320px and larger text sizes.

Five explicit part buttons correspond to these exact notes and preferred view angles:
{"body":{"name":"Enclosure","dimension":"128 × 86 × 34 mm","description":"Body envelope only. The feet, antenna, fins and front / side hardware extend beyond it. Blue anodized aluminium is the proposed finish.","question":"Confirm wall thickness, mounting points and the assembly tolerance before a manufacturing review.","yaw":28,"elevation":12},"display":{"name":"Display","dimension":"82 × 40 mm visible face","description":"A glass panel and a separate bezel define the front display area. The drawing and model share these dimensions.","question":"Select a display module, then evaluate outdoor readability and front-panel protection.","yaw":0,"elevation":0},"controls":{"name":"Controls","dimension":"26 mm dial body · two keys","description":"A grip dial, centre cap and raised lip sit beside two setting keys. The lip extends beyond the dial body.","question":"Check spacing, reach and grip with a physical mock-up, including use with gloves.","yaw":-18,"elevation":8},"thermal":{"name":"Ventilation","dimension":"6 top fins · 18 mm pitch","description":"Six top fins and five rear slats form an airflow study. Their positions are visible in the separated view.","question":"Define heat loads and airflow, then test thermal performance. Cooling and ingress protection are not established by this model.","yaw":150,"elevation":28},"connections":{"name":"Connections","dimension":"Two round ports · one rectangular port","description":"The side plate, connector faces and antenna show a proposed connection layout.","question":"Select the connectors and antenna, then review cable clearance, sealing and service access.","yaw":-72,"elevation":12}}

Selecting a button or tapping a mesh uses its semantic partId, highlights only that group, switches to its preferred yaw/elevation and stops automatic turning. The chosen part is announced politely and stays selected until another part or Reset is chosen. Do not associate the enclosure note with the side connectors. Each part shows its dimension, description and an open review question.

Front / Right / Rear / Above buttons set yaw/elevation to [0,0], [-90,0], [180,0], [28,55] degrees. Left and Right 15° buttons offer keyboard equivalents to dragging. Horizontal pointer dragging changes yaw at .45 degrees per pixel from the captured starting pose. Use primary pointers only, a 5px movement threshold to distinguish a tap from a drag, pointer capture, pointercancel and lostpointercapture cleanup. Preserve native vertical scrolling with touch-action:pan-y. Raycast only actual component meshes, excluding helper lines.

Two native range controls expose Surface 0–100% and Separation 0–100%, step 1, with visible values and Drawing/Material and Assembled/Separated endpoints. Surface directly controls mesh opacity and wire intensity; separation moves each component from pos to pos + explode×value/100. This is exterior separation for inspection, not a validated disassembly sequence. Interacting with the model, selecting a view or adjusting a slider pauses automatic turning. All direct controls redraw while motion is off; no animation is required to inspect a part. Reset restores yaw 28°, elevation 12°, surface 100%, separation 0 and no selected part, keeping automatic motion paused.

Initially automatic turning advances 20 degrees per second. A scroll transition from the viewport's top at 95% to 40% of the scroller materialises the surface from drawing to metal. The first user interaction takes ownership and stops subsequent scroll changes from overwriting the sliders. When motion is switched off before any direct interaction, finish the surface transition immediately. Do not change user-authored slider values when motion is disabled later.

Use one material per component so highlights cannot leak to an unrelated group. Aluminium/fin #9AB2D6, dark hardware #3A5686, side plate #46639A, screen #081F45, accent #5C9DFF and rubber #0A1830. Use MeshPhysicalMaterial: aluminium metalness .9, roughness .32 (dark hardware .38), clearcoat .5 and clearcoatRoughness .2; glass screen metalness 0, roughness .08, clearcoat 1/.08; rubber metalness 0, roughness .95 and no clearcoat. Emissive colour #5C9DFF; selected group intensity .48, otherwise screen .12 and other parts 0. Surface=value/100 drives a world-space clipping plane with normal [0,−1,0]. Its constant lerps from .001 below the lowest component to .001 above the highest at current separation. Keep material opacity 1, transparent false, depthWrite true, clipShadows true and alphaToCoverage true; enable renderer.localClippingEnabled and use the antialiased default framebuffer. This bottom-to-top solid reveal avoids alpha-hash grain and transparent sorting while preserving the line-to-surface control. EdgesGeometry uses wireSrc when provided, actual geometry otherwise, and is absent only when wireSrc is null; scale edges by 1.004. Unselected wire opacity=1−.88×surface; selected wire opacity=1 and colour #8DC1FF. Keep the screw slots and dark connector openings defined in the component array so the hardware reads at an oblique angle.

Use an alpha, antialiased WebGLRenderer, SRGB output, ACES tone mapping, exposure 1.05 and device pixel ratio at most 2 (at most 1 in an explicitly opted-in embedded TOP preview). Use 2048² PCFShadowMap (the r185 replacement for deprecated PCFSoftShadowMap), radius 2, bias −.0005 and normalBias .02. Add an 8×8 ShadowMaterial floor, opacity .16×surface, following .015 below the lowest component at the current separation. No screen-space AO or composer. Render cylinders with at least 64 radial segments, spheres with at least 64×32 and tori with at least 32×64; preserve all dimensions and wire geometry. A RoomEnvironment PMREM at blur .04 and intensity .7 lights the metal. White key light intensity 2.2 at [2.4,3.4,2.2], blue rim intensity 2.2 at [-2.6,1.4,-2.6], hemisphere #DCE8FF/#081F45 at .7. Perspective camera FOV 30°, near .1, far 40 looks at [0,.55,0]. Fit all components at the current separation/elevation through a complete rotation with a 10% margin. Keep the distance constant during a full turn so the camera does not breathe. Validate bounds at narrow and wide aspect ratios, both assembled and separated.

## Completion and recovery
Discuss this part opens the blue project dialog, preselects Engineering study and includes the exact selected UNIT-7 part, dimension, description and review question. Save part notes requests a UTF-8 text file named datum-unit-7-[part].txt containing the same information and the exterior-concept limitation. Do not label these notes a CAD download. Keep the choice intact when the dialog is closed or its fields edited. The dialog uses paper #081F45, text #DCE8FF, accent #8DC1FF and a legible pale-red error colour. The shared action specification below defines the required project-focus choices, validation and review/save flow. The generic header/footer CTA opens a generic brief.

Allocate the renderer only after its actual host has a nonempty visible intersection and the document is visible. Resize and render the first frame before attaching its canvas or claiming readiness. Preserve the checkpoint and settings while releasing GPU resources off screen or when the document becomes hidden. Recreate on re-entry at delta 0; clamp later frame deltas to .05 seconds. Suspend drawing while the project dialog is open. Do not advance rotation for hidden time.

Catch renderer, environment, shader, resize and render failures, including context loss during construction. Release partial resources and retain the HTML notes and a labelled SVG reference drawing. Provide Retry 3D view after a failure. Keep part selection available, but disable GPU-only view and slider controls until a real frame succeeds; do not present inert controls as functioning. A failed download retains selectable text and exposes retry, never a false success. Dispose all geometry, per-part materials, edge resources, temporary RoomEnvironment, PMREM generator, environment target, shadow maps and renderer; disconnect observers and listeners and cancel RAF. Ignore stale loss callbacks from disposed scenes.

The OS reduced-motion preference is live and takes precedence over the visible Motion switch. Off means no automatic rotation, scroll materialisation, heading entrances or smooth scrolling. Direct part selection and controls still work. All navigation, project disclosures, brief creation and notes remain usable without WebGL.

Footer: “Bring us / a rough sketch.” Invite visitors to describe use, constraints and unresolved decisions, then review and save the brief. Disclose DATUM as a fictional engineering studio. Do not promise tool costs, measured cooling, water ingress ratings, battery weight, a supplied hardware device or completed production engineering.

## Acceptance
Check all five part mappings against actual rendered geometry and raycasting; front/right/rear/above, drag cancellation, keyboard turn, slider values, automatic pause/reset and live OS/manual motion changes. Check drawn/solid correspondence, the 128×86×34 body measurement, 82×40 display face, six fins and port counts. Complete all project / discipline / part briefing routes through review, edit and save. Inspect mobile and landscape sticky layout, enlarged text, focus return, download failure, hidden-tab return, context loss and retry. Node geometry/lifecycle/markup checks cannot establish real GPU paint quality or complete browser acceptance.

## Action flow and content

Implement the following local planning experience for the primary CTA, in the visual language of the page. Use a real button opening a labelled modal dialog. Choosing a pricing card must preselect that exact plan. A navigation link may move to another section; a planning CTA must lead to its review flow.

Use this content for the dialog, including the option details and notes:

{
  "slug": "blueprint-build",
  "brand": "DATUM",
  "accent": "#8dc1ff",
  "title": "From rough sketch to a product brief",
  "intro": "Clarify the use, constraints and questions before the first drawing.",
  "facts": [
    [
      "Starting point",
      "Choose a focus, describe the audience and keep a scope brief."
    ],
    [
      "Review",
      "Scope, supplied material, timing and the intended use."
    ],
    [
      "Handover to discuss",
      "Drawings, an assembly concept and a list of questions to resolve before production."
    ]
  ],
  "groups": [
    {
      "label": "Project focus",
      "options": [
        {
          "title": "Product concept",
          "detail": "Usage scenarios, form studies and a dimensional concept to review."
        },
        {
          "title": "Engineering study",
          "detail": "A component and assembly study, with open manufacturing and testing questions recorded."
        }
      ]
    }
  ],
  "brief": "Describe the audience, the intended result, the material you already have and any timing constraints.",
  "notes": [
    "This is a local project brief. Scope, availability and any fee would be agreed in a separate conversation."
  ],
  "paper": "#081f45",
  "ink": "#dce8ff",
  "colorScheme": "dark"
}

- Explain before input that this is a fictional brand sample: choices can be reviewed and saved, with no external submission, booking, payment or registration. Use each brand's language. Do not launch a mail client or present an installer for a fictional product.
- Give every option group a legend, inputs explicit labels and errors linked descriptions. Validate options against the allowed values, requested dates as actual dates from today onward, and free text as 10–2,000 trimmed characters. Blank spaces alone must fail. Tracking accepts the sample reference TG-2048 only.
- Focus the first invalid field and preserve every entered value. On success, show the selected option WITH its full detail, requested date or brief, relevant facts and notes. An edit action returns to the preserved form. Do not claim a real reservation, purchase or account has succeeded.
- Save the complete review as UTF-8 text. A browser download request is not proof of a file being written. On download failure, retain the full text in a labelled, selectable textarea and offer retry. Do not show a false success state.
- Constrain modal content to the viewport with internal scrolling. Support keyboard and touch, trap focus while open, close on Escape and restore focus to the exact initiating control. Keep these operations available with motion disabled.
- If a separate project-contact CTA is present, let it collect a project brief and review it locally; a product selection CTA must retain the product choice. Verify both flows independently.