# #122 KeyFrame Guide

## 0. Document Information
- UI ID: `UI-122`
- DOC ID: `DOC-0122`
- Component: `#122 KeyFrame`
- Runtime: `BoneKeyFrame 1.0.0`
- Status: Development Candidate

This guide covers normal use of #122 KeyFrame, its Property editor, Preview, connections, Security, OUT WAIT / BLOCKED, Smoke / Validation, and the HTML Functional Class.

## 1. Role of KeyFrame
#122 KeyFrame defines and stores the **state at individual points of Animation progress**. The five formal state groups are:

- **Position** — X / Y position
- **Rotation** — rotation angle
- **Scale** — enlargement or reduction factor
- **Opacity** — opacity
- **Color** — color

#122 does not play Animation. It also does not interpolate between states or decide how many seconds the motion takes.

## 2. When to Use It
Use KeyFrame when a start state and an end state are not enough and you need detailed intermediate motion states.

Example: to change gradually from white to red over two seconds, responsibilities are separated as follows:

- #121 Timeline: `Duration = 2 seconds`
- #122 KeyFrame: `0% = white`, `100% = red`
- #118 Transition: interpolate the intermediate colors between white and red

If more detail is needed, add an intermediate point such as `0% = white / 50% = pink / 100% = red`.

## 3. Component Responsibility Boundaries
### #117 Animation
Owns the actual Animation behavior and playback.

### #118 Transition
Owns state-change interpolation between KeyFrames.

### #121 Timeline
Owns Delay / Duration / Loop / Repeat / Sequence / Parallel.

### #122 KeyFrame
Defines and stores only Position / Rotation / Scale / Opacity / Color at each percentage point.

Do not add `seconds after start` or `Duration` as #122 Property fields.

## 4. Property Editor
The Property editor is on the left side of the page and is used together with the Preview on the right.

### 4.1 Property Language
Use **日本語 / English** at the top of Property to switch Property headings, field labels, descriptions, and Preview labels. Changing language does not modify KeyFrame values.

### 4.2 Point (%)
Specify a value from `0` through `100`. This is a point on overall Animation progress, not a duration in seconds.

Example: if #121 Timeline Duration is four seconds, a #122 KeyFrame at 50% represents the state reached two seconds after start.

### 4.3 Position
Set `X` and `Y`. These values are the position at the selected KeyFrame point.

### 4.4 Rotation
Set the rotation angle in degrees.

### 4.5 Scale
Set the scale factor. `1` means the original size.

### 4.6 Opacity
Specify a value from `0` through `1`. `0` is fully transparent and `1` is fully opaque.

### 4.7 Color
Select color through the official #040 ColorPicker Runtime 1.0.18 Caller. #118 BoneTransition Runtime 1.0.3 is loaded only as a #040 Caller dependency; this does not give #122 interpolation ownership. #122 does not implement a separate ColorPicker UI.

### 4.8 Save / Delete KeyFrame
**Save KeyFrame** stores the current Property values at the specified percentage point. Saving an existing percentage updates that point.

**Delete KeyFrame** removes the currently specified percentage point.

## 5. Combined Preview
The right-side Combined Preview displays the state of one selected KeyFrame only.

It shows:
- Offset
- Position
- Rotation / Scale
- Opacity
- Color
- Total KeyFrame count
- Safe data for the selected state

There is no playback button in this Preview. Playback belongs to #117, timing belongs to #121, and interpolation belongs to #118.

## 6. Connection Image
The Connection Image follows the same normal/abnormal matrix used by #017 Text. Evaluation, lines, endpoints, and abnormal markers are delegated to the public API of #002 Bone Joint 1.1.36; #122 does not invent its own Joint rendering.

Five cases are shown:
1. Normal connection (IN / OUT) — `Timeline.progress (Number) -> KeyFrame.offset (Number)` and `KeyFrame.state (Object) -> Animation.state (Object)`.
2. IN Target Field missing — `Timeline.progress -> KeyFrame.missing`, rendered with the official #002 missing-field abnormal display.
3. OUT Target Field missing — `KeyFrame.state -> Animation.missing`, rendered with the official #002 missing-field abnormal display.
4. Type mismatch (IN) — `Timeline.progress (Number) -> KeyFrame.color (String)`.
5. Type mismatch (OUT) — `KeyFrame.color (String) -> Animation.progress (Number)`.

Every card shows Source Field Exists, Target Field Exists, Compatibility, and Joint State so the result is not conveyed by color alone.

## 7. Untrusted IN / Security Test
The Security Test verifies that #122:

- rejects accessor/getter/setter properties without executing them
- rejects an out-of-range Offset
- rejects out-of-range Position values
- rejects an out-of-range Scale
- rejects an out-of-range Opacity
- rejects duplicate Offsets
- rejects unsafe Color data containing executable values
- preserves the existing Preview when an untrusted input is rejected

## 8. OUT WAIT / BLOCKED - #002 Joint v1.1.36 Integration
This area follows the formal OUT WAIT / BLOCKED structure used by #017 Text and uses #002 Bone Joint 1.1.36 `createDeliveryChannel()` / `evaluate()` / `drawLine()`. It does not invent a WAIT spinner, BLOCKED icon, or Joint line.

The screen uses one wide card that connects `KeyFrame OUT` to `Target` with #002 Joint. Under the flow it shows exactly four status items: `Joint State`, `Target`, `Queue`, and `Delivered`, followed by one log line and two visual-confirmation checkboxes. There are only three operations:

- `▶ WAIT / FIFO Run`
- `⛔ BLOCKED Run`
- `↻ Reset`

There is no manual Target READY/BUSY selector, Payload A/B selector, or separate FIFO button.

The two visual-confirmation checkboxes keep independent state. Switching to BLOCKED does not clear an already confirmed WAIT/FIFO checkbox, and switching to WAIT/FIFO does not clear an already confirmed BLOCKED checkbox. `↻ Reset` is the explicit operation that initializes both confirmations.

### WAIT → READY → FIFO
The WAIT test makes the Target BUSY and queues A and B in input order. The connection remains established while waiting, and the official #002 spinner is rendered at the Target endpoint. After the visual observation interval, the Target returns to READY and A then B are delivered automatically in FIFO order, leaving Queue at 0. This observation interval belongs only to the test UI; it is not a #122 KeyFrame timing Property or responsibility.

### BLOCKED
The BLOCKED test rejects delivery through the guard. The connection remains established, the official #002 ban marker / beat-fade is rendered at the Target endpoint, and nothing is delivered to the Target, so Delivered remains 0.

`createDeliveryChannel().getState()` is used only for `state`, `targetReady`, `queueLength`, and `historyLength`. The `connectionEstablished` contract is not fabricated from Delivery Channel state; it is verified separately through `BoneJoint.evaluate(... state:"waiting" / "blocked")`.

Layering is Joint line = z-index 1, Source / Target node = z-index 2, and official #002 WAIT/BLOCKED marker = z-index 3.

## 9. Smoke Test / Validation Report
The test area follows the same overall structure used by #017 Text and displays Smoke Test and Validation separately.

- **Smoke Test** checks Runtime identity, the exact five formal states, Functional Class, #002, #040, Connection Image, WAIT/FIFO, BLOCKED, Security, Preview, Property language switching, and DOC controls.
- **Validation** checks invalid ranges, duplicate Offsets, accessor safety, responsibility boundaries, Property structure, Completion structure, duplicate IDs, and related contracts.

Reports can be saved as JSON or Markdown.

## 10. Completion
Package-local tests alone do not make #122 Completed. All of the following are required:

1. Smoke Test succeeds
2. Validation succeeds
3. KeyFrame Property / Preview is visually confirmed on localhost
4. #002 Joint normal/abnormal Connection Image is visually confirmed on localhost
5. WAIT → READY → FIFO delivery is visually confirmed on localhost
6. BLOCKED Target non-delivery is visually confirmed on localhost
7. #040 ColorPicker Caller is visually confirmed on localhost

Before user confirmation, do not treat the component as Completed or Specification Frozen.

## 11. HTML Functional Class
The normal-use class is `bf-keyframe` as a Development Candidate.

```html
<div class="bf-keyframe">
  <div class="bf-keyframe-point"
       data-offset="0"
       data-x="0"
       data-y="0"
       data-rotation="0"
       data-scale="1"
       data-opacity="1"
       data-color="#FFFFFF"></div>

  <div class="bf-keyframe-point"
       data-offset="100"
       data-x="180"
       data-y="0"
       data-rotation="360"
       data-scale="1"
       data-opacity="1"
       data-color="#FF0000"></div>
</div>
```

`bf-keyframe` converts declarative KeyFrame points into BoneKeyFrame Runtime state. It does not perform playback, timing control, or interpolation.

## 12. Confirmation URLs
- Test: `http://localhost/boneflow/test/bone-keyframe.html`
- Cumulative Regression: `http://localhost/boneflow/test/bone-development-order.html`
