stateDiagram-v2
    direction TB
    record_replay: Record & Replay App
    init: Initialization
    app_loaded: Built-in App Mode – select target app via SDK load_app interface
    ext_ctrl: External Control Mode – switch control modes via SDK switch_mode interface

    self_check: Self-check in progress
    calibration_needed: Zero-point calibration required
    offline_idle: Self-check done, USB disconnected
    offline_connected: USB connected, waiting for control service
    state self_check_result <>
    failure: Initialization failed

    state init {
      direction LR
      self_check --> self_check_result: self-check finished
      self_check_result --> calibration_needed: calibration required
      self_check_result --> offline_idle: self-check passed
      self_check_result --> failure: unrecoverable error
      calibration_needed --> offline_idle: calibration done
    }

    state ext_ctrl {
      direction TB
      [*] --> planning_pos
      planning_pos: Position control (trajectory)
      servo_pos_joint: Position servo – joint space
      servo_pos_cart: Position servo – Cartesian space
      servo_vel_joint: Velocity servo – joint space
      servo_vel_cart: Velocity servo – Cartesian space
      gravity_comp: Gravity compensation
    }

    state app_loaded {
      direction LR
      state record_replay {
        direction TB
        replay_waiting: Replay idle
        replay_ready: Replay ready
        replaying: Replaying
        replay_paused: Replay paused
        idle: Idle
        record_sub: Recording subgraph
        replay_sub: Replay subgraph
        drag: Drag mode active
        recording: Recording trajectory
        state record_sub {
          direction LR
          idle --> drag: end-button [long press]
          drag --> idle: end-button [long press]
          drag --> recording: base-button [short press]
          recording --> drag: base-button [short press]
        }
        state replay_sub {
          direction LR
          replay_waiting --> replay_ready: base-button [short press]
          replay_ready --> replaying: base-button [short press], start replay
          replaying --> replay_paused: base-button [short press]
          replay_paused --> replaying: base-button [short press]
          replaying --> replay_ready: replay finished
          replay_waiting --> idle: base-button [double press]
          idle --> replay_waiting: end-button [double press]
        }
        [*] --> idle: initialize
      }
    }

    [*] --> self_check: power on
    offline_idle --> offline_connected: USB attached
    offline_connected --> ext_ctrl: control service started
    ext_ctrl --> record_replay: base-button [long press]
    app_loaded --> ext_ctrl: SDK call [unload_app]
    record_replay --> ext_ctrl: base-button [long press]
    ext_ctrl --> app_loaded: SDK call [load_app]

    classDef cyan fill:#00FFFF,stroke:#007F7F,stroke-width:2px,color:#000;
    classDef blue fill:#7F7FFF,stroke:#3F3F7F,stroke-width:2px,color:#000;
    classDef red fill:#FF7F7F,stroke:#7F3F3F,stroke-width:2px,color:#000;
    classDef purple fill:#FF7FFF,stroke:#7F3F7F,stroke-width:2px,color:#000;
    classDef green fill:#7FFF7F,stroke:#3F7F3F,stroke-width:2px,color:#000;
    classDef yellow fill:#FFFF3F,stroke:#7F7F3F,stroke-width:2px,color:#000;
    classDef light_grey fill:#BBBBBB,stroke:#777777,stroke-width:2px,color:#000;

    class idle cyan
    class idle breathing
    class drag blue
    class recording blue
    class recording flowing
    class replay_waiting purple
    class replay_waiting flashing
    class replay_ready purple
    class replaying purple
    class replaying breathing
    class replay_paused purple
    class replay_paused flashing

    class planning_pos green
    class servo_pos_joint green
    class servo_pos_cart green
    class servo_vel_joint green
    class servo_vel_cart green
    class gravity_comp green

    class self_check yellow
    class calibration_needed yellow
    class calibration_needed flashing
    class offline_idle light_grey
    class offline_connected light_grey
    class offline_connected breathing
    class failure red