# #117 Animation Guide

## 1. Responsibility
#117 Animation は独立した Motion UI です。Target UI 自身へAnimation実装を埋め込まず、Animation UI Number / Target UI Number / Target Part KEY のRelationで対象を指定します。

Relation Key: `animationUiNo::targetUiNo::targetPart`

## 2. HTML Functional Class
`bf-animation` は **Animation対象DOM自身へ付けるClassではありません**。Animation Relationを宣言する非表示の Relation Controller 要素です。Targetは `data-ui-no` と `data-ui-part` で公開します。任意CSS selectorは使いません。

```html
<button data-ui-no="UI-BUTTON-001">
  <span data-ui-part="button-text">保存</span>
</button>
<div class="bf-animation"
  data-animation-ui-no="UI-117-001"
  data-target-ui-no="UI-BUTTON-001"
  data-target-part="button-text"
  data-animation="pulse"
  data-speed="normal"
  data-loop="true"
  data-loop-wait-ms="300"
  data-autoplay="true"></div>
```

## 3. 正式Animation 7種
- `move` — straight axis motion and return; numeric `distance` in px.
- `bounce` — distinct from Move: jump, landing squash, and decaying rebound. Configure numeric `bounceHeight` and `bounceCount`.
- `pulse` — scale pulse.
- `spin` — restores the original self-rotation. Inside and outside use the same `rotate()` motion; configure numeric `spinDegrees`. Inside clips to the Target UI, outside is unclipped.
- `blink` — glyph / surface opacity blink.
- `slide` — inside-only. `slideMode=in|out`, default `in`. Both modes are clipped by the Target UI and use numeric `distance` only.
- `zoom` — inside and outside use the same large `1.0 → zoomScale → 1.0` Zoom motion. Inside clips to the Target UI; outside shows the same motion without clipping. Default is `outside`.

## 4. Flow Preset 4種
- `flow`
- `shimmer`
- `glow-sweep`
- `breathing-glow`

Button内文字 / Text / Label / Icon では Flow / Shimmer / Glow Sweep は四角いOverlayを重ねず、glyph foregroundにgradientを流します。Button全体 / Panel / Box / Fill / Thumbではsurface表示を使用します。

## 5. Property
- `animationUiNo`: `UI-...`
- `targetUiNo`: `UI-...`
- `targetPart`: `whole / button-text / text / label / icon / panel / box / fill / thumb`
- `animation`: 正式7種 + Flow Preset 4種
- `direction`: `forward / reverse`
- `axis`: `horizontal / vertical`
- `speed`: `slow / normal / fast`
- `distance`: 0–10000. Move / Slide distance in px. Slide does not add target size.
- `bounceHeight`: 1–2000px / Default `48`
- `bounceCount`: integer 1–6 / Default `2`
- `spinScope`: `inside | outside` / Default `inside`
- `spinDegrees`: 1–3600deg / Default `360`
- `slideMode`: `in | out` / Default `in`
- `zoomScope`: `inside | outside` / Default `outside`
- `zoomScale`: 1.01–5.00 / Default `1.80`
- `loop`: boolean / Default `true`
- `loopWaitMs`: 0–60000ms / Default `300`
- `respectReducedMotion`: boolean / Default `true`
- `autoplay`: boolean / Default `false`

## 6. Target分離
Button wholeは背景・Border・Contentを含むButton全体を動かします。Button textはButton本体を固定して文字DOMだけを動かします。Text/Labelは文字、IconはIcon、Panel/BoxはSurface、FillはProgress Fill、ThumbはSlider Thumbだけを対象にします。

## 7. Lifecycle
`play()` / `pause()` / `resume()` / `stop()` / `restart()` / `destroy()`。`attach()`を別Targetへ再実行した場合は旧Targetの一時styleとFlow layerをcleanupしてからretargetします。Animation種類の`update()`でも旧Flow styleを残しません。

## 8. #117 Loop WAIT
1 cycle終了 → `loop=true` の場合 `state=waiting` → `loopWaitMs` 後に次cycle。WAIT中Pauseは `paused-wait`、Resumeは残りWAIT時間から再開します。Stop / Destroyは予約済みtimerも解除します。

#117 Loop WAIT is separate from #002 Joint WAIT / FIFO / BLOCKED. It is an internal Animation cycle wait and is not mixed into the #002 Delivery Channel.

## 9. Relation / #002 Joint
The connection image uses the formal #002 Bone Joint API and displays Source → #117 Animation → Target as IN / OUT. `targetPart` remains Target Field/Part information, not a separate node. The formal five cases are normal connection, IN Target Field missing, OUT Target Field missing, IN type mismatch, and OUT type mismatch. The normal case must report both fields as true, Compatibility=OK, and Joint State=CONNECTED from the actual evaluation result.

### OUT WAIT / BLOCKED - #002 Joint v1.1.36 Integration
#117 Animation owns Animation output generation. #002 Joint owns Target Busy, WAIT queue, FIFO, BLOCK decision, and delivery stop. This uses a dedicated Delivery Channel separate from Preview and #117 Loop WAIT.

- WAIT: Target BUSY → queue output → keep connection + spinner → Target READY → automatic FIFO delivery → READY.
- BLOCKED: while Target is READY, Guard blocks dangerous output → keep connection + fa-ban / beat-fade → Target delivery count does not increase.
- Visual confirmation: WAIT must keep the line and auto-deliver after READY; BLOCKED must keep the line and must not deliver dangerous output to Target.

## 10. Security
Arbitrary CSS selectors are prohibited. Allow-list: UI Number / targetPart / animation / direction / axis / speed / distance / bounceHeight / bounceCount / spinScope / spinDegrees / slideMode / zoomScope / zoomScale / loop / loopWaitMs / reduced-motion / autoplay. The Security Test rejects NaN, Infinity, negative invalid values, unknown Animation, unknown Part, unknown Direction, unknown Axis, invalid Target UI, CSS-selector-like Target values, and accessors. The Security sandbox is independent from Preview.

## 11. Public API
`defaults()` / `normalizeOptions()` / `validateOptions()` / `inspectUntrustedOptions()` / `resolveRelationKey()` / `durationForSpeed()` / `buildPlan()` / `create()` / `isInstance()` / `attach()` / `update()` / `play()` / `pause()` / `resume()` / `stop()` / `restart()` / `getState()` / `getOutput()` / `destroy()` / `getAvailableAnimations()` / `getFormalAnimations()` / `getFlowAnimations()`

## 12. Motion責務分離
- #118 Transition: 状態A→状態BのENTER/EXIT補間。#117 continuous Animationとは別。
- #120 Trigger: start condition。
- #121 Timeline: 複数MotionのDelay / Duration / Repeat / Sequence / Parallel orchestration。
- #122 KeyFrame: 任意keyframe authoring。

## 13. reduced motion
`respectReducedMotion=true` かつOSがreduceの場合、Motionを開始せず `state=reduced-motion` を記録します。

## 14. Completion
Smoke / Validation ALL PASS、Animation目視、Button全体、Button内文字、Flow glyph、Loop WAIT、Joint状態、Guide確認が揃った後だけCompletion可能です。ユーザーlocalhost確認前はDevelopmentです。


## 15. Move / Bounce / Spin / Slide / Zoom settings

### Move vs Bounce
Move is straight translation. Bounce is a separate jump motion with landing squash and decaying rebounds. Configure `bounceHeight` and `bounceCount` numerically.

### Spin
Spin restores the original self-rotation. Inside and outside both use `rotate(0deg) → rotate(spinDegrees)`. Inside clips to the Target UI; outside shows the same rotation without clipping. No external pivot is used.

### Slide
Slide is inside-only. Default `slideMode=in` moves `-distance → 0`; OUT moves `0 → +distance`. Part targets are clipped by the Target UI. There is no outside scope and target size is not added.

### Zoom
Inside and outside use the same large Zoom motion: `1.0 → zoomScale → 1.0`. The only difference is containment: inside clips to the Target UI, outside remains visible beyond it. Default is `outside / 1.80`.
