# The model

> The model

Page: https://fframes-kit.pages.dev/docs/basics/the-model/

- A component is a props struct. `ui.show(component)` renders it at the current time and
  returns an `Svgr`, so it goes anywhere `{expr}` is allowed in `svgr!`.
- Build a `Ui` once at the top of `render_frame`: `Ui::new(frame, ctx, &self.theme)` in a
  video, `Ui::for_scene(frame, ctx, &self.theme, self)` in a scene. Scenes get the video's
  context, so only `for_scene` knows the scene's length that exit animations end with.
- **Time is local.** A component has no start time. Its parent places it with a
  `Sequence { from, duration, children }`; inside, `ui.seconds()` starts at 0 and
  `ui.duration` is the sequence's length in frames. Sequences nest and their offsets add up.
- **Props are plain data**: numbers, `&str`/`String`, `Color`, `Transform`, enums, `Option`,
  `Anim<T>` (a fixed value or a stored `timeline!`) and `children` closures.
- **Defaults come from the theme**: set what you need and finish with `..ui.defaults()`.
- **SVG ids** (clip paths, gradients, filters) come from `ui.id(key, index, kind)`: from a
  `key: Option<&str>` prop when given, else from the item index. Never from a counter.
- Children are a closure that receives the container's own `Ui`: `children(|ui| ...)`.

```rust
use fframes_kit::prelude::*;

fn card<'a>(ui: &mut Ui<'a, '_, '_>) -> Svgr<'a> {
    let fade = FadeIn { shift: (0.0, -40.0), delay: 0.2, ..ui.defaults() };
    let accent = ui.theme.colors.accent;
    fade.apply(ui, svgr!(<rect x="100" y="100" width="400" height="200" fill={accent} />))
}

fn layout<'a>(ui: &mut Ui<'a, '_, '_>) -> Svgr<'a> {
    // `card` starts at 1s and lasts 3s; inside it, time starts at 0
    ui.show(Sequence { from: 1.0, duration: Some(3.0), children: children(card) })
}
```
