"""
Type stubs for `scene` — Pythonista-compatible 2D scene API (SpriteKit bridge).
"""

from __future__ import annotations

__all__ = [
    'Scene', 'Node', 'SpriteNode', 'LabelNode', 'ShapeNode', 'EffectNode', 'EmitterNode',
    'Action', 'Texture', 'Shader', 'SceneView',
    'Touch', 'Vector2', 'Vector3', 'Size', 'Rect', 'Point', 'EdgeInsets',
    'PhysicsBody', 'PhysicsWorld', 'Contact',
    'PinJoint', 'SpringJoint', 'RopeJoint',
    'run', 'get_screen_size', 'get_screen_scale', 'gravity', 'play_effect',
    'get_image_path', 'get_controllers', 'get_safe_area_insets',
    'background', 'fill', 'no_fill', 'stroke', 'no_stroke', 'stroke_weight',
    'tint', 'no_tint', 'rect', 'ellipse', 'line', 'image', 'text',
    'translate', 'rotate', 'scale', 'push_matrix', 'pop_matrix',
    'blend_mode', 'use_shader', 'load_image', 'load_image_file', 'load_pil_image',
    'render_text', 'unload_image', 'image_quad', 'triangle_strip',
    'BLEND_NORMAL', 'BLEND_ADD', 'BLEND_MULTIPLY',
    'DEFAULT_ORIENTATION', 'PORTRAIT', 'LANDSCAPE',
    'TIMING_LINEAR', 'TIMING_EASE_IN', 'TIMING_EASE_IN_2',
    'TIMING_EASE_OUT', 'TIMING_EASE_OUT_2', 'TIMING_EASE_IN_OUT',
    'TIMING_SINODIAL',
    'TIMING_EASE_BACK_IN', 'TIMING_EASE_BACK_OUT', 'TIMING_EASE_BACK_IN_OUT',
    'TIMING_ELASTIC_IN', 'TIMING_ELASTIC_OUT', 'TIMING_ELASTIC_IN_OUT',
    'TIMING_BOUNCE_IN', 'TIMING_BOUNCE_OUT', 'TIMING_BOUNCE_IN_OUT',
    'FILTERING_LINEAR', 'FILTERING_NEAREST',
]

from typing import (
    Any,
    Callable,
    Dict,
    Iterator,
    List,
    Optional,
    Sequence,
    Tuple,
    Union,
    overload,
)
from typing_extensions import Self

ColorLike = Union[str, Tuple[float, ...], List[float], float]
"""Color: name string, RGBA tuple, RGB list, or gray float."""

# --- Constants ---

DEFAULT_ORIENTATION: int
PORTRAIT: int
LANDSCAPE: int

BLEND_NORMAL: int
BLEND_ADD: int
BLEND_MULTIPLY: int

TIMING_LINEAR: int
TIMING_EASE_IN: int
TIMING_EASE_IN_2: int
TIMING_EASE_OUT: int
TIMING_EASE_OUT_2: int
TIMING_EASE_IN_OUT: int
TIMING_SINODIAL: int
TIMING_ELASTIC_IN: int
TIMING_ELASTIC_OUT: int
TIMING_ELASTIC_IN_OUT: int
TIMING_BOUNCE_IN: int
TIMING_BOUNCE_OUT: int
TIMING_BOUNCE_IN_OUT: int
TIMING_EASE_BACK_IN: int
TIMING_EASE_BACK_OUT: int
TIMING_EASE_BACK_IN_OUT: int

FILTERING_LINEAR: int
FILTERING_NEAREST: int

# --- Geometry ---

class Vector2:
    __slots__: Tuple[str, ...]
    x: float
    y: float

    def __init__(self, x: float, y: float) -> None: ...
    def __getitem__(self, i: int) -> float: ...
    def __iter__(self) -> Iterator[float]: ...
    def __add__(self, other: Any) -> Vector2: ...
    def __sub__(self, other: Any) -> Vector2: ...
    def __mul__(self, other: Any) -> Vector2: ...
    def __truediv__(self, other: Any) -> Vector2: ...
    def __radd__(self, other: Any) -> Any: ...
    def __rsub__(self, other: Any) -> Any: ...
    def __rmul__(self, other: Any) -> Any: ...
    def __iadd__(self, other: Any) -> Self: ...
    def __isub__(self, other: Any) -> Self: ...
    def __imul__(self, other: Any) -> Self: ...
    def __itruediv__(self, other: Any) -> Self: ...
    def __neg__(self) -> Self: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __hash__(self) -> int: ...
    def __abs__(self) -> float: ...
    def __len__(self) -> int: ...
    def __repr__(self) -> str: ...
    def __bool__(self) -> bool: ...


class EdgeInsets:
    """Edge insets (top, bottom, left, right) for safe area."""
    __slots__: Tuple[str, ...]
    top: float
    bottom: float
    left: float
    right: float

    def __init__(
        self,
        top: float = 0.0,
        bottom: float = 0.0,
        left: float = 0.0,
        right: float = 0.0,
    ) -> None: ...
    def __repr__(self) -> str: ...


class Vector3:
    """3D vector for gravity sensors etc."""
    __slots__: Tuple[str, ...]
    x: float
    y: float
    z: float

    def __init__(self, x: float = 0.0, y: float = 0.0, z: float = 0.0) -> None: ...
    def __getitem__(self, i: int) -> float: ...
    def __iter__(self) -> Iterator[float]: ...
    def __len__(self) -> int: ...
    def __repr__(self) -> str: ...


class Point(Vector2):
    """Position (x, y)."""

    def __add__(self, other: Any) -> Point: ...
    def __sub__(self, other: Any) -> Point: ...
    def __mul__(self, other: Any) -> Point: ...
    def __truediv__(self, other: Any) -> Point: ...
    def __repr__(self) -> str: ...


class Size(Vector2):
    """Size (w, h). w/h as aliases for x/y."""
    __slots__: Tuple[str, ...]

    @property
    def w(self) -> float: ...
    @w.setter
    def w(self, v: float) -> None: ...
    @property
    def h(self) -> float: ...
    @h.setter
    def h(self, v: float) -> None: ...

    def __add__(self, other: Any) -> Size: ...
    def __sub__(self, other: Any) -> Size: ...
    def __mul__(self, other: Any) -> Size: ...
    def __truediv__(self, other: Any) -> Size: ...
    def __repr__(self) -> str: ...


class Rect:
    """Rect (x, y, w, h). Origin lower-left."""
    __slots__: Tuple[str, ...]
    x: float
    y: float
    w: float
    h: float

    def __init__(self, x: float, y: float, w: float, h: float) -> None: ...
    @property
    def width(self) -> float: ...
    @property
    def height(self) -> float: ...
    @property
    def origin(self) -> Point: ...
    @property
    def size(self) -> Size: ...
    @property
    def min_x(self) -> float: ...
    @property
    def max_x(self) -> float: ...
    @property
    def min_y(self) -> float: ...
    @property
    def max_y(self) -> float: ...
    def center(self, p: Optional[Point] = None) -> Point: ...
    def contains_point(self, p: Point) -> bool: ...
    def contains_rect(self, other: Rect) -> bool: ...
    def intersects(self, other: Rect) -> bool: ...
    def intersection(self, other: Rect) -> Rect: ...
    def union(self, other: Rect) -> Rect: ...
    def inset(
        self,
        top: float,
        left: float,
        bottom: Optional[float] = None,
        right: Optional[float] = None,
    ) -> Rect: ...
    def __getitem__(self, i: int) -> float: ...
    def __iter__(self) -> Iterator[float]: ...
    def translate(self, x: float, y: float) -> Rect: ...
    def __contains__(self, point: Any) -> bool: ...
    def __repr__(self) -> str: ...
    def __len__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __hash__(self) -> int: ...


class Touch:
    """Touch event: location, prev_location, touch_id."""
    __slots__: Tuple[str, ...]
    touch_id: int

    def __init__(
        self,
        x: float,
        y: float,
        prev_x: float,
        prev_y: float,
        touch_id: int,
    ) -> None: ...
    @property
    def location(self) -> Point: ...
    @property
    def prev_location(self) -> Point: ...


class Contact:
    """Collision contact for physics callbacks."""
    __slots__: Tuple[str, ...]
    node_a: Node
    node_b: Node
    contact_point: Point
    collision_impulse: float
    body_a: Node
    body_b: Node

    def __init__(
        self,
        node_a: Node,
        node_b: Node,
        px: float,
        py: float,
        impulse: float,
    ) -> None: ...


class SceneView:
    """Embeddable Scene container (pairs with `ui.View`)."""

    def __init__(self) -> None: ...
    @property
    def view(self) -> Any: ...
    @property
    def scene(self) -> Optional[Scene]: ...
    @scene.setter
    def scene(self, value: Optional[Scene]) -> None: ...
    @property
    def paused(self) -> bool: ...
    @paused.setter
    def paused(self, value: bool) -> None: ...
    @property
    def frame_interval(self) -> int: ...
    @frame_interval.setter
    def frame_interval(self, value: int) -> None: ...
    @property
    def anti_alias(self) -> bool: ...
    @anti_alias.setter
    def anti_alias(self, value: bool) -> None: ...
    @property
    def shows_fps(self) -> bool: ...
    @shows_fps.setter
    def shows_fps(self, value: bool) -> None: ...


class Scene:
    """Base scene: override setup(), update(), draw(), touch handlers, etc."""

    def __init__(self) -> None: ...
    @property
    def frame_count(self) -> int: ...
    @property
    def touches(self) -> Dict[int, Touch]: ...
    @property
    def t(self) -> float: ...
    @property
    def dt(self) -> float: ...
    @property
    def background_color(self) -> Tuple[float, float, float, float]: ...
    @background_color.setter
    def background_color(self, value: Any) -> None: ...
    @property
    def children(self) -> List[Node]: ...
    @property
    def physics_world(self) -> PhysicsWorld: ...
    @property
    def safe_area_insets(self) -> EdgeInsets: ...
    @property
    def effects_enabled(self) -> bool: ...
    @effects_enabled.setter
    def effects_enabled(self, value: bool) -> None: ...
    @property
    def crop_rect(self) -> Any: ...
    @crop_rect.setter
    def crop_rect(self, value: Any) -> None: ...
    @property
    def view(self) -> Any: ...
    @property
    def presented_scene(self) -> Optional[Scene]: ...
    @property
    def presenting_scene(self) -> Optional[Scene]: ...
    def setup(self) -> None: ...
    def update(self) -> None: ...
    def draw(self) -> None: ...
    def did_evaluate_actions(self) -> None: ...
    def touch_began(self, touch: Touch) -> None: ...
    def touch_moved(self, touch: Touch) -> None: ...
    def touch_ended(self, touch: Touch) -> None: ...
    def did_change_size(self) -> None: ...
    def controller_changed(self, key: str, value: Any) -> None: ...
    def present_modal_scene(self, other: Scene) -> None: ...
    def dismiss_modal_scene(self) -> None: ...
    def pause(self) -> None: ...
    def resume(self) -> None: ...
    def stop(self) -> None: ...
    def add_child(self, node: Node) -> None: ...
    def remove_all_children(self) -> None: ...


def run(
    scene: Scene,
    *,
    orientation: int = ...,
    frame_interval: int = ...,
    anti_alias: bool = ...,
    show_fps: bool = ...,
    multi_touch: bool = ...,
    _mode: str = ...,
) -> None: ...


def get_screen_size() -> Size: ...
def get_screen_scale() -> float: ...
def gravity() -> Vector3: ...
def get_safe_area_insets() -> EdgeInsets: ...
def play_effect(name: str, volume: float = ..., pitch: float = ...) -> None: ...
def get_image_path(name: str) -> Optional[str]: ...
def get_controllers() -> List[Dict[str, Any]]: ...


class Texture:
    """Bitmap texture for sprites (name, file path, or image object)."""

    def __init__(self, name_or_image: Any) -> None: ...
    @property
    def size(self) -> Size: ...
    @property
    def filtering_mode(self) -> int: ...
    @filtering_mode.setter
    def filtering_mode(self, value: int) -> None: ...
    def subtexture(self, rect: Union[Rect, Sequence[float]]) -> Texture: ...


class PhysicsWorld:
    """Scene physics world (gravity)."""

    def __init__(self, scene: Scene) -> None: ...
    @property
    def gravity(self) -> Vector2: ...
    @gravity.setter
    def gravity(self, v: Sequence[float]) -> None: ...


class PhysicsBody:
    """Physics body attached to a node."""

    type: str
    size: Tuple[float, float]

    def __init__(
        self,
        type: str = ...,
        size: Optional[Tuple[float, float]] = None,
    ) -> None: ...
    @classmethod
    def rectangle(
        cls,
        width: float = ...,
        height: float = ...,
        w: float = ...,
        h: float = ...,
    ) -> PhysicsBody: ...
    @classmethod
    def circle(cls, radius: float = ..., r: float = ...) -> PhysicsBody: ...
    @property
    def affected_by_gravity(self) -> bool: ...
    @affected_by_gravity.setter
    def affected_by_gravity(self, v: bool) -> None: ...
    @property
    def allows_rotation(self) -> bool: ...
    @allows_rotation.setter
    def allows_rotation(self, v: bool) -> None: ...
    @property
    def dynamic(self) -> bool: ...
    @dynamic.setter
    def dynamic(self, v: bool) -> None: ...
    @property
    def restitution(self) -> float: ...
    @restitution.setter
    def restitution(self, v: float) -> None: ...
    @property
    def friction(self) -> float: ...
    @friction.setter
    def friction(self, v: float) -> None: ...
    @property
    def linear_damping(self) -> float: ...
    @linear_damping.setter
    def linear_damping(self, v: float) -> None: ...
    @property
    def angular_damping(self) -> float: ...
    @angular_damping.setter
    def angular_damping(self, v: float) -> None: ...
    @property
    def mass(self) -> float: ...
    @mass.setter
    def mass(self, v: float) -> None: ...
    @property
    def density(self) -> float: ...
    @density.setter
    def density(self, v: float) -> None: ...
    @property
    def angular_velocity(self) -> float: ...
    @angular_velocity.setter
    def angular_velocity(self, v: float) -> None: ...
    @property
    def velocity(self) -> Vector2: ...
    @velocity.setter
    def velocity(self, v: Sequence[float]) -> None: ...
    @overload
    def apply_impulse(self, impulse: Sequence[float]) -> None: ...
    @overload
    def apply_impulse(self, dx: float, dy: float) -> None: ...
    @overload
    def apply_force(self, force: Sequence[float]) -> None: ...
    @overload
    def apply_force(self, fx: float, fy: float) -> None: ...
    @property
    def category_bitmask(self) -> int: ...
    @category_bitmask.setter
    def category_bitmask(self, v: int) -> None: ...
    @property
    def collision_bitmask(self) -> int: ...
    @collision_bitmask.setter
    def collision_bitmask(self, v: int) -> None: ...
    @property
    def contact_test_bitmask(self) -> int: ...
    @contact_test_bitmask.setter
    def contact_test_bitmask(self, v: int) -> None: ...


class Joint:
    """Base class for physics joints (implementation detail for Pin/Spring/Rope)."""
    node_a: Node
    node_b: Node

    def __init__(self, node_a: Node, node_b: Node) -> None: ...


class PinJoint(Joint):
    def __init__(
        self,
        node_a: Node,
        node_b: Node,
        anchor: Tuple[float, float],
    ) -> None: ...


class SpringJoint(Joint):
    def __init__(
        self,
        node_a: Node,
        node_b: Node,
        anchor_a: Tuple[float, float],
        anchor_b: Tuple[float, float],
        *,
        damping: float = ...,
        frequency: float = ...,
    ) -> None: ...


class RopeJoint(Joint):
    def __init__(
        self,
        node_a: Node,
        node_b: Node,
        anchor_a: Tuple[float, float],
        anchor_b: Tuple[float, float],
    ) -> None: ...


class Shader:
    """Custom fragment shader for nodes."""

    source: str

    def __init__(self, source: str) -> None: ...
    def set_uniform(self, name: str, value: Any) -> None: ...
    def get_uniform(self, name: str) -> Optional[float]: ...
    def get_uniform_vec(self, name: str) -> Optional[Tuple[float, ...]]: ...


class Node:
    """Base node: transform, hierarchy, actions, physics."""

    def __init__(
        self,
        position: Tuple[float, float] = ...,
        *,
        z_position: float = ...,
        scale: float = ...,
        x_scale: float = ...,
        y_scale: float = ...,
        alpha: float = ...,
        parent: Optional[Node] = None,
        **kwargs: Any,
    ) -> None: ...
    @property
    def position(self) -> Point: ...
    @position.setter
    def position(self, value: Any) -> None: ...
    @property
    def rotation(self) -> float: ...
    @rotation.setter
    def rotation(self, value: float) -> None: ...
    @property
    def x_scale(self) -> float: ...
    @x_scale.setter
    def x_scale(self, value: float) -> None: ...
    @property
    def y_scale(self) -> float: ...
    @y_scale.setter
    def y_scale(self, value: float) -> None: ...
    @property
    def children(self) -> List[Node]: ...
    @property
    def parent(self) -> Optional[Any]: ...
    @property
    def scale(self) -> float: ...
    @scale.setter
    def scale(self, value: float) -> None: ...
    @property
    def alpha(self) -> float: ...
    @alpha.setter
    def alpha(self, value: float) -> None: ...
    @property
    def shader(self) -> Optional[Shader]: ...
    @shader.setter
    def shader(self, value: Optional[Shader]) -> None: ...
    @property
    def z_position(self) -> float: ...
    @z_position.setter
    def z_position(self, value: float) -> None: ...
    @property
    def physics_body(self) -> Optional[PhysicsBody]: ...
    @physics_body.setter
    def physics_body(self, value: Optional[PhysicsBody]) -> None: ...
    def add_child(self, node: Node) -> None: ...
    def remove_from_parent(self) -> None: ...
    def remove_all_children(self) -> None: ...
    def convert_point(self, point: Any, to_node: Node) -> Point: ...
    def run_action(self, action: Action, key: Optional[str] = None) -> None: ...
    def remove_action(self, key: str) -> None: ...
    def remove_all_actions(self) -> None: ...
    @property
    def frame(self) -> Rect: ...
    @property
    def bbox(self) -> Rect: ...
    @property
    def blend_mode(self) -> int: ...
    @blend_mode.setter
    def blend_mode(self, value: int) -> None: ...
    @property
    def speed(self) -> float: ...
    @speed.setter
    def speed(self, value: float) -> None: ...
    @property
    def paused(self) -> bool: ...
    @paused.setter
    def paused(self, value: bool) -> None: ...
    @property
    def scene(self) -> Optional[Scene]: ...
    def point_to_scene(self, point: Any) -> Point: ...
    def point_from_scene(self, point: Any) -> Point: ...
    def render_to_texture(self, crop_rect: Any = None) -> Texture: ...


class SpriteNode(Node):
    def __init__(
        self,
        texture: Any = None,
        position: Tuple[float, float] = ...,
        *,
        z_position: float = ...,
        scale: float = ...,
        x_scale: float = ...,
        y_scale: float = ...,
        alpha: float = ...,
        speed: float = ...,
        parent: Optional[Node] = None,
        size: Optional[Sequence[float]] = None,
        color: Optional[ColorLike] = ...,
        blend_mode: int = ...,
        **kwargs: Any,
    ) -> None: ...
    @property
    def size(self) -> Size: ...
    @size.setter
    def size(self, value: Any) -> None: ...
    @property
    def texture(self) -> Any: ...
    @texture.setter
    def texture(self, value: Any) -> None: ...
    @property
    def color_blend_factor(self) -> float: ...
    @color_blend_factor.setter
    def color_blend_factor(self, value: float) -> None: ...
    @property
    def anchor_point(self) -> Point: ...
    @anchor_point.setter
    def anchor_point(self, value: Sequence[float]) -> None: ...
    @property
    def color(self) -> Any: ...
    @color.setter
    def color(self, value: Any) -> None: ...


class LabelNode(Node):
    def __init__(
        self,
        text: Union[str, int, float] = ...,
        font: Union[Tuple[str, float], Sequence[Any]] = ...,
        position: Tuple[float, float] = ...,
        *,
        z_position: float = ...,
        scale: float = ...,
        x_scale: float = ...,
        y_scale: float = ...,
        alpha: float = ...,
        speed: float = ...,
        parent: Optional[Node] = None,
        **kwargs: Any,
    ) -> None: ...
    @property
    def color(self) -> Any: ...
    @color.setter
    def color(self, value: Any) -> None: ...
    @property
    def text(self) -> str: ...
    @text.setter
    def text(self, value: str) -> None: ...
    @property
    def font(self) -> Tuple[str, float]: ...
    @font.setter
    def font(self, value: Tuple[str, float]) -> None: ...
    @property
    def alignment(self) -> Tuple[int, int]: ...
    @alignment.setter
    def alignment(self, value: Tuple[int, int]) -> None: ...


class ShapeNode(Node):
    def __init__(
        self,
        path: Any = None,
        fill_color: Optional[ColorLike] = ...,
        stroke_color: Optional[ColorLike] = ...,
        shadow: Any = None,
        position: Tuple[float, float] = ...,
        *,
        z_position: float = ...,
        scale: float = ...,
        x_scale: float = ...,
        y_scale: float = ...,
        alpha: float = ...,
        speed: float = ...,
        parent: Optional[Node] = None,
        **kwargs: Any,
    ) -> None: ...
    @property
    def path(self) -> Any: ...
    @path.setter
    def path(self, value: Any) -> None: ...
    def set_path(self, path: Any) -> None: ...
    @property
    def line_width(self) -> float: ...
    @line_width.setter
    def line_width(self, value: float) -> None: ...
    @property
    def stroke_width(self) -> float: ...
    @stroke_width.setter
    def stroke_width(self, value: float) -> None: ...
    @property
    def fill_color(self) -> Any: ...
    @fill_color.setter
    def fill_color(self, value: Any) -> None: ...
    @property
    def stroke_color(self) -> Any: ...
    @stroke_color.setter
    def stroke_color(self, value: Any) -> None: ...
    @property
    def shadow(self) -> Any: ...
    @shadow.setter
    def shadow(self, value: Any) -> None: ...


class EffectNode(Node):
    def __init__(
        self,
        position: Tuple[float, float] = ...,
        *,
        z_position: float = ...,
        scale: float = ...,
        x_scale: float = ...,
        y_scale: float = ...,
        alpha: float = ...,
        speed: float = ...,
        parent: Optional[Node] = None,
        **kwargs: Any,
    ) -> None: ...
    @property
    def effects_enabled(self) -> bool: ...
    @effects_enabled.setter
    def effects_enabled(self, value: bool) -> None: ...
    @property
    def crop_rect(self) -> Any: ...
    @crop_rect.setter
    def crop_rect(self, value: Any) -> None: ...


class EmitterNode(Node):
    def __init__(
        self,
        file_named: Optional[str] = None,
        position: Tuple[float, float] = ...,
        *,
        z_position: float = ...,
        scale: float = ...,
        x_scale: float = ...,
        y_scale: float = ...,
        alpha: float = ...,
        speed: float = ...,
        parent: Optional[Node] = None,
        **kwargs: Any,
    ) -> None: ...


class Action:
    """Factory for SpriteKit-style actions."""

    duration: float
    timing_mode: int

    def __init__(self) -> None: ...
    @staticmethod
    def move_to(
        x: float,
        y: float,
        duration: float = ...,
        timing_mode: int = ...,
    ) -> Action: ...
    @staticmethod
    def move_by(
        dx: float,
        dy: float,
        duration: float = ...,
        timing_mode: int = ...,
    ) -> Action: ...
    @staticmethod
    def sequence(*actions: Action) -> Action: ...
    @staticmethod
    def group(*actions: Action) -> Action: ...
    @staticmethod
    def repeat(action: Action, count: int) -> Action: ...
    @staticmethod
    def repeat_forever(action: Action) -> Action: ...
    @staticmethod
    def wait(duration: float) -> Action: ...
    @staticmethod
    def remove() -> Action: ...
    @staticmethod
    def rotate_to(
        angle: float,
        duration: float = ...,
        timing_mode: int = ...,
    ) -> Action: ...
    @staticmethod
    def rotate_by(
        angle: float,
        duration: float = ...,
        timing_mode: int = ...,
    ) -> Action: ...
    @staticmethod
    def scale_to(
        scale: float,
        duration: float = ...,
        timing_mode: int = ...,
    ) -> Action: ...
    @staticmethod
    def scale_by(
        scale: float,
        duration: float = ...,
        timing_mode: int = ...,
    ) -> Action: ...
    @staticmethod
    def scale_x_to(
        scale: float,
        duration: float = ...,
        timing_mode: int = ...,
    ) -> Action: ...
    @staticmethod
    def scale_y_to(
        scale: float,
        duration: float = ...,
        timing_mode: int = ...,
    ) -> Action: ...
    @staticmethod
    def fade_to(
        alpha: float,
        duration: float = ...,
        timing_mode: int = ...,
    ) -> Action: ...
    @staticmethod
    def fade_by(
        alpha: float,
        duration: float = ...,
        timing_mode: int = ...,
    ) -> Action: ...
    @staticmethod
    def set_uniform(
        name: str,
        value: Any,
        duration: float = ...,
        timing_mode: int = ...,
    ) -> Action: ...
    @staticmethod
    def call(
        callback: Callable[..., Any],
        duration: float = ...,
        scene: Optional[Scene] = None,
    ) -> Action: ...


# --- scene_drawing re-exports (lazy-loaded at runtime) ---

def background(r: float = ..., g: float = ..., b: float = ...) -> None: ...
def fill(r: float = ..., g: float = ..., b: float = ..., a: float = ...) -> None: ...
def no_fill() -> None: ...
def stroke(r: float, g: float, b: float, a: float = ...) -> None: ...
def no_stroke() -> None: ...
def stroke_weight(line_width: float) -> None: ...
def tint(r: float = ..., g: float = ..., b: float = ..., a: float = ...) -> None: ...
def no_tint() -> None: ...
def rect(
    x: float = ...,
    y: float = ...,
    w: float = ...,
    h: float = ...,
    corner_radius: float = ...,
) -> None: ...
def ellipse(x: float = ..., y: float = ..., w: float = ..., h: float = ...) -> None: ...
def line(x1: float, y1: float, x2: float, y2: float) -> None: ...
def image(
    name: str,
    x: float = ...,
    y: float = ...,
    w: float = ...,
    h: float = ...,
    from_x: Optional[float] = None,
    from_y: Optional[float] = None,
    from_w: Optional[float] = None,
    from_h: Optional[float] = None,
) -> None: ...
def text(
    txt: str,
    font_name: str = ...,
    font_size: float = ...,
    x: float = ...,
    y: float = ...,
    alignment: int = ...,
) -> None: ...
def translate(x: float, y: float) -> None: ...
def rotate(deg: float) -> None: ...
def scale(x: float, y: float) -> None: ...
def push_matrix() -> None: ...
def pop_matrix() -> None: ...
def blend_mode(mode: int) -> None: ...
def use_shader(shader: Any) -> None: ...
def load_image(image_name: str) -> None: ...
def load_image_file(image_path: str) -> Optional[str]: ...
def load_pil_image(pil_image: Any) -> Optional[str]: ...
def render_text(
    txt: str,
    font_name: str = ...,
    font_size: float = ...,
) -> Tuple[Optional[str], Size]: ...
def unload_image(image_name: str) -> None: ...
def image_quad(
    name: str,
    x1: float,
    y1: float,
    x2: float,
    y2: float,
    x3: float,
    y3: float,
    x4: float,
    y4: float,
    from_x1: Optional[float] = None,
    from_y1: Optional[float] = None,
    from_x2: Optional[float] = None,
    from_y2: Optional[float] = None,
    from_x3: Optional[float] = None,
    from_y3: Optional[float] = None,
    from_x4: Optional[float] = None,
    from_y4: Optional[float] = None,
) -> None: ...
def triangle_strip(
    points: Sequence[Tuple[float, float]],
    tex_coords: Optional[Sequence[Tuple[float, float]]] = None,
    image_name: Optional[str] = None,
) -> None: ...
