# Animations & Interactions

## Animations & Interactions

**Files:** `src/config/config.toml`, section content files · **Skill level:** Beginner

Margo's motion is calm on purpose: headlines fade in when a page opens, content rises in a short distance as it scrolls into view, headings appear word by word, and numbers count up. Some sections add scroll effects such as parallax. Every animation respects the visitor's **reduce motion** setting, and phones get a lighter version by default.

### Animation Settings
```toml
# src/config/config.toml
[settings.animation]
  enable               = true
  respectReducedMotion = true
  intro                = true
  reveal               = true
  scroll               = true
  webgl                = true
  mobile               = "lite"   # full | lite | off
  pageTransitions      = true
  easing               = "expo"   # expo | quart | cubic, or any CSS timing function
  duration             = 0.9      # reveal duration in seconds
  stagger              = 0.08     # delay between items of a group, in seconds
  distance             = "1.25rem"
  rootMargin           = "0px 0px -10% 0px"
  threshold            = 0.15
```

| Setting | What it does |
| --- | --- |
| `enable` | `false` shows every page still and fully visible, with no animation at all |
| `respectReducedMotion` | `true` gives visitors who ask for reduced motion a still page. Keep it on |
| `intro` | The headline of the hero and the page header fades in when the page first appears |
| `reveal` | Content fades and rises in on scroll, headings appear word by word, numbers count up |
| `scroll` | Effects tied to the scroll position: parallax, images and text that change as you scroll, and the hero project cards flying into the projects grid (the hero `stack` layout with `flyTarget: true` on the projects grid) |
| `webgl` | Lets the animated backgrounds run on the surfaces that ask for one (see below). `false` keeps the still dots |
| `mobile` | Below 768px: `full` (everything), `lite` (reveals, counters, and moving rows, no scroll effects), or `off` (no motion) |
| `pageTransitions` | Fades between pages and moves a project's image into its page as it opens |
| `easing` | The feel of the movement. Avoid springy or overshooting curves |
| `duration` | How long a reveal takes, in seconds |
| `stagger` | The delay between items that appear one after another, in seconds |
| `distance` | How far content rises while fading in. Keep it small for a calm feel |
| `rootMargin`, `threshold` | When a reveal starts: how far into the screen and how much of the element must be visible |

The scroll effects load their library (GSAP) only on pages that use them, on screens 768px and wider (unless `mobile = "full"`), and never with reduced motion. Content that is already on screen when the page loads appears without waiting for a scroll.

### Page Transitions
With `pageTransitions = true`, the page fades as visitors move between pages, and a project's image moves into the project page when they open it. It uses the browser's own page transitions, which work in Chrome and in Safari 18.2 and later. Other browsers change page normally. There is no transition with reduced motion.

### Animated Backgrounds
A few surfaces can show a moving background drawn with WebGL. Each one ships set to `none`, so nothing runs until you choose one:

| Where | Setting | Values |
| --- | --- | --- |
| Hero (`stack` and `panel` layouts) | `options.webgl` in `src/content/sections/<language>/hero-section.md` or a page's `heroSection` block | `dots`, `flow`, `none` |
| Call to action (`band` layout) | `options.webgl` in `call-to-action.md` or a page's `ctaSection` block | `dots`, `flow`, `none` |
| Footer (`wordmark` layout) | `webgl` at the top of `footer.md` | `dots`, `flow`, `none` |

The background loads only when its section comes near the screen, runs on desktop only with `mobile = "lite"`, and stops with reduced motion. `[settings.animation] webgl = false` turns them all off.

### Cursor Label
```toml
[settings.cursor]
  enable = true
```

Over project, team, and journal cards, a small label ("View", "Read") follows the pointer. It shows with a mouse or trackpad only, never on touch screens. The words are `cursor.view` and `cursor.read` in `src/i18n/<language>.json`. Set `enable = false` to turn it off.

### Edge Blur
```toml
[settings.edgeBlur]
  enable = false
```

With `enable = true`, a band along the bottom edge of the screen softens the page as it scrolls under it. It shows from 1024px wide with a mouse or trackpad, hides for visitors who ask for reduced transparency, and slides away near the end of the page. It ships off because it makes the computer redraw the blur on every scroll; if you turn it on, check that your pages still scroll smoothly on a slower computer.

### Frame Lines And Colour Fields
`frame` and `aurora` in `[settings.layout]` set the thin ruled lines at the edges of the page and the soft colour fields behind it. They don't move, so they aren't affected by the settings above. See [Colors & Fonts](/margo/customization/colors-fonts/).

### Smooth Scrolling
Margo ships with smooth scrolling on, powered by Lenis, for mouse and trackpad scrolling only. It is off on touch screens, with reduced motion, and when `[settings.animation] enable = false`. [Smooth Scroll](/margo/features/smooth-scroll/) explains every key of `[settings.smoothScroll]`.

### Other Interactions
| Where | What it does |
| --- | --- |
| Buttons | `hoverEffect` sets the hover: `text-flip`, `creative-fill`, `magnetic`, or `magnetic-text-flip`. The magnetic effects follow a mouse or trackpad only |
| Moving rows (the `marquee` layouts of logos, tools, and testimonials) | Slow down and stop on hover and keyboard focus. Without JavaScript or with reduced motion, they are a still row you can scroll sideways |
| Accordions (FAQ, services `list`, experience) | Slide open and closed |
| Header | Turns into a compact pill after you scroll down (see [Header](/margo/customization/header/)) |

<Aside type="note">
  With reduced motion on, or `[settings.animation] enable = false`, every page
  is still and fully visible: no intro, no reveals, numbers show their final
  value, no scroll effects or animated backgrounds, no page transitions, and the
  browser's own scrolling.
</Aside>

### Do It With AI
```text
Make the animations on my Margo site [calmer | lighter on phones | off]: in [settings.animation]
of src/config/config.toml, [set duration to 0.6 and distance to "0.75rem" | set mobile = "off" |
set enable = false]. Keep respectReducedMotion = true and don't change [settings.smoothScroll].
Then tell me which pages to check.
```