# AtlantisThemeContext

## What this owns

`AtlantisThemeContext` is the native Atlantis boundary for theme semantics and
token resolution.

It owns:

- the selected theme (`"system" | "light" | "dark"`)
- the effective theme used to resolve tokens (`"light" | "dark"`)
- mapping the selected theme to the current platform token set
- subtree overrides for Atlantis-owned surfaces that need fixed visual tokens

It does **not** own:

- preference persistence
- settings UI
- product rollout or split configuration

Those concerns belong to the consuming app.

## Selected theme vs effective theme

The `theme` value represents the user's selected preference. It may be
`"system"`, which means "follow the OS setting".

The `effectiveTheme` value is the resolved runtime theme Atlantis uses to choose
tokens. This is always `"light"` or `"dark"`.

Consumers that need to persist or display the user's choice should use `theme`.
Consumers that need to style non-Atlantis surfaces should usually use
`effectiveTheme`.

## Platform token composition

Native themes start with the current platform's iOS or Android token set and
then apply dark theme overrides. An override must preserve the native token's
runtime shape. If a dark override is a primitive but the platform token is an
object, the provider keeps the platform value.

This matters for shadows: web dark shadow tokens are CSS strings, while native
shadow tokens are React Native style objects. Keeping the platform object means
consumers can safely continue to spread `tokens["shadow-base"]` in both themes.

## Controlled vs uncontrolled usage

`AtlantisThemeContextProvider` supports both controlled and uncontrolled usage.

- Use `theme` and `onThemeChange` when the app owns the selected theme state.
- Omit `theme` when the provider should manage theme locally.

App-level providers should generally be controlled so the selected preference
can be stored outside Atlantis.

## Forced theme subtrees

`dangerouslyOverrideTheme` forces the subtree to render with a specific
effective theme. This is useful for portals, overlays, or any Atlantis-owned
surface that visually leaves the normal React subtree.

Important: a forced subtree preserves the selected theme semantics from the
nearest non-forced provider. Calling `setTheme` inside the forced subtree still
updates the upstream selected theme; only the rendered tokens stay forced.

## Themed style cache

`buildThemedStyles` returns a module-scope `useStyles` hook. Each generated hook
owns a `WeakMap` keyed by the `tokens` object from the nearest Atlantis theme
context, so repeated component instances under the same theme reuse the same
`StyleSheet.create` result.

Call `buildThemedStyles` at module scope, keep the style factory pure over its
`tokens` argument, and treat the returned styles as immutable. If the active
theme changes and the context returns a different `tokens` object, the generated
hook creates and caches a separate style object for that token identity.
