# Skua
Form-first UI components for Phoenix LiveView (1.1+) on Phoenix 1.8+:
rich select, date picker, OTP input, dialogs, menus, tables, toasts and
top-layer panels — server-authoritative, viewport-aware, themeable from 12 CSS
tokens, with **zero third-party JavaScript** (one JS import, ~9 KB min+gzip).
A daisyUI replacement you install and manage through `mix` tasks built on
Igniter — including `--strip-daisy` to remove Phoenix 1.8's bundled daisyUI.
## Install
**One command** — Igniter adds the dep and wires everything (CSS, JS hooks,
component imports, flash → Skua toasts, strips the default Phoenix navbar, and
scaffolds an editable starter home at `/`):
```bash
# existing app
mix igniter.install skua
# brand-new app — one-time: install the project-generator archive first
mix archive.install hex igniter_new
mix igniter.new my_app --with phx.new --install skua
```
(`igniter.new` and `phx.new` are Mix *archives*, not built-in tasks — if either
reports "could not be found", install it once with `mix archive.install hex
igniter_new` / `mix archive.install hex phx_new`. Or skip archives entirely and
use the plain-Mix path below.)
Skua replaces daisyUI, so the installer **removes Phoenix 1.8's bundled daisyUI
by default** — it deletes the vendored files and bridges daisy's color utilities
(`bg-base-100`, `text-error`, …) to Skua tokens so existing markup keeps
resolving. Keep daisyUI instead with `--no-strip-daisy`:
```bash
mix igniter.install skua --no-strip-daisy
```
(If your daisyUI config was customized with nested rules, the installer leaves
it alone and prints a manual step rather than risk mangling it.)
**Without Igniter** — add the dep and run the plain Mix task (Igniter is
optional; the task still works):
```elixir
# mix.exs
{:skua, "~> 0.5.0"}
```
```bash
mix deps.get
mix skua.install # --strip-daisy optional
mix phx.server # open /
```
Every step is idempotent — re-run any time after `mix deps.update skua`. The
installer degrades to printed manual steps if your app diverges from the default
layout. Local-testing notes in [guides/local-testing.md](guides/local-testing.md).
## Authentication
`mix skua.gen.auth` runs `mix phx.gen.auth` and then applies a flow on top. The
generated code is yours to edit.
```bash
mix skua.gen.auth --auth magic_link # default — Phoenix's passwordless flow
mix skua.gen.auth --auth otp # one-time-code login (no passwords)
mix skua.gen.auth --auth password_otp # password + OTP on one login screen
mix skua.gen.auth --auth custom # stock phx.gen.auth, nothing added
```
The **`otp`** and **`password_otp`** flows ship a production-grade one-time-code
login: CSPRNG codes (unique every time, never `:rand`), SHA-256-hashed storage,
single-use under concurrency (`FOR UPDATE` + transaction), constant-time compare,
a session-fixation guard, enumeration-safe responses, and built-in
[Hammer](https://hexdocs.pm/hammer) rate limiting on both the request and verify
steps — all tunable in the generated `config/config.exs`. Code length and expiry
are flags:
```bash
mix skua.gen.auth --auth otp --otp-length 8 --otp-expiry 5
```
All three login flows (`magic_link`, `otp`, `password_otp`) wire a Resend
production mailer so the link/code actually delivers off-box (dev/test keep
Swoosh's local mailbox; prod reads `RESEND_API_KEY` at runtime — see the
generated `.env.example`). Run `mix deps.get && mix ecto.migrate` afterwards.
## Pages
`mix skua.gen.pages` scaffolds editable starter pages and wires their routes (run
it after `skua.install`, and after `skua.gen.auth` for the auth-aware nav and the
dashboard's auth gate):
```bash
mix skua.gen.pages
```
- a shared `SiteNav` injected into `Layouts.app` — section links plus auth-aware
links (a signed-in user's email + Log out, otherwise Register / Sign in),
- `HomeLive` at `/` — a hero with the live Phoenix + Skua version badges and a
showcase of real Skua components,
- `DashboardLive` at `/dashboard` — an authenticated page with a sidebar
(Dashboard / Settings + Log out) and Skua stat cards.
Everything generated is yours to edit; re-running overwrites the pages and leaves
the routes and the `Layouts.app` nav injection in place.
## Repository layout
- `PLAN.md` — the full project plan (architecture decisions, installer spec,
strip-daisy design, release pipeline, roadmap).
- `assets/css/skua.css` — the token + component CSS layer (the stable artifact).
- `lib/` — components, the install mix tasks (`Skua.Install.Patches` holds the
shared install logic), and supporting modules.
- `_component_defaults/` — reference prototypes the library is being built
from (styled-layer HTML demo, LiveView hook/component prototypes, and the
skua.sh brand system). Not shipped in the hex package.
## License
MIT — see [LICENSE.md](LICENSE.md).