# SealShare on Livewire Material (2.0.0) > The package itself — its decisions, the wave plan (Phases 1–10) and its tests — moved to > the package repo on 2026-09-13: [noNameWEB/livewire-material · docs/plans/livewire-material.md](https://gitea.nonameweb.ch/noNameWEB/livewire-material/src/branch/main/docs/plans/livewire-material.md). > This file keeps what SealShare does once the package reaches `1.0.0`. ## Goal SealShare's UI is maryUI 2.9 on daisyUI 5 — a generic web-page look. After this change it runs on **`nonameweb/livewire-material` `^1.0`**: a clean, calm indigo Material 3 Expressive app with a top app bar, light / dark / system theme, and two Expressive moments — the upload drop zone and "link ready" — shipped as SealShare 2.0.0. ## Context **Stacks.** SealShare: Laravel 13.31, Livewire 4.4, maryUI 2.9.10 (no prefix), daisyUI 5.7, Tailwind 4.3, Pest 5.1, Octane on FrankenPHP, PHP 8.5; public on GitHub under MIT, image published to `ghcr.io/surtic86/sealshare`. ReStride: same Laravel / Livewire / Tailwind / Pest, private on `gitea.nonameweb.ch`, CI through Gitea act_runner. **SealShare's UI surface** (inventory, 2026-09-13): - maryUI tags: `button` 30, `input` 18, `password` 16, `icon` 14, `card` 9 (6 `actions` slots), `menu`/`menu-item` 1/4 (settings nav), `theme-toggle` 3, `toggle` 2, `select` 2, `modal` 2, `table` 1 (`:headers :rows :sort-by with-pagination`, `@scope`), `textarea` 1, `toast` 1 (never triggered). - Raw daisyUI: `btn` (+ `-primary/-ghost/-sm/-xs/-error/-outline/-disabled`), `alert` ×6, `card`/`card-body` (4 admin stat tiles), `join` (2 copy fields), `progress` ×2, `loading` ×2, `badge-success/-error`, `divider`, `link link-primary` ×5, `label`, `file-input`, `checkbox`; tokens `bg-base-*`, `border-base-300`, `text-error/success`, `border-primary(/50)`, `bg-primary/5`; raw `text-green-600`, `bg-white` (QR code). Secondary text is `opacity-50/60/70`. - 20 Heroicons (outline), through `blade-heroicons` pulled in transitively by maryUI. - No `Mary\` PHP coupling. Admin settings flashes `session('message')` into an alert (`AdminSettings.php:116,128,135`). 3 `wire:confirm`. - Layouts: `layouts/app` → `app/sidebar` (centered `max-w-5xl` + footer nav), used by the Livewire pages and all settings SFCs (`config/livewire.php:47`); `layouts/auth` → `auth/simple`. The theme script sits *outside* `
` and hard-codes dark, while maryUI's toggle defaults from the OS. `partials/head` loads Instrument Sans from fonts.bunny.net. - Dead: `/dashboard` (starter placeholder, and Fortify's `home`), `welcome`, `pages/auth/register` (still referenced by `Fortify::registerView`, `FortifyServiceProvider.php:52`), `layouts/app/header`, `layouts/auth/{card,split}`, `components/app-logo`, `components/desktop-user-menu`, `components/placeholder-pattern`; the `alpinejs` npm dependency; the Flux credentials step in `tests.yml` and `docker.yml`. - Settings `profile` and `password` show "Saved." through `components/action-message`, listening for `profile-updated` / `password-updated`; `partials/settings-heading` uses a daisyUI `divider`. The 3 `wire:confirm` are admin settings (remove logo, clear system password) and admin dashboard (delete share). `AdminDashboard::headers()` exists only for maryUI's table. - Tests assert text only, never markup; no browser tests. - Docker: the image's caches run in `docker/entrypoint.sh` (`config:cache`, `route:cache`, `view:cache`); `docker/dev-entrypoint.sh` runs `npm run build` against the host's mounted `vendor/` without a `composer install`. The Flux credentials step is in `tests.yml`, `docker.yml` **and** `lint.yml`. - Screens: setup, system password, upload, share created, share download, admin dashboard, admin settings, settings (profile, password, appearance, two-factor), Fortify pages (login, forgot, reset, 2FA challenge, confirm, verify email). Stock Laravel error pages and mails. **Constraints found.** - SealShare's `Dockerfile` builds assets (stage 1) **before** `composer install` (stage 2); CSS imported from `vendor/` needs the order swapped. - Laravel **replaces** the `errors` view namespace at render time with `config('view.paths')` + `/errors` and the framework's own (`Illuminate/Foundation/Exceptions/RegisterErrorViewPaths.php`), so error views a package adds with `addNamespace('errors', …)` are wiped; only a path in `view.paths` survives. - The package lives at `https://gitea.nonameweb.ch/noNameWEB/livewire-material.git` (public, anonymous reads verified 2026-09-13). ## Decisions The package's decisions are in its own plan. SealShare's: - **Converts after `1.0.0`, in one pass, by hand** (~150 tags; no codemod), on branch `material`, released as **2.0.0**. - **Moving SealShare to Gitea is a separate plan** — this plan works wherever it is hosted. - **Seed `#4f46e5` (the favicon's indigo), Vibrant** — chosen after comparing it with Tonal Spot on the upload page in both themes (2026-09-13): Tonal Spot read grey-lavender on this seed. - **Theme default `system`**, storage key `sealshare-theme`, legacy `mary-theme` adopted once. Appearance is a Light / Dark / System connected button group. - **One top app bar everywhere** — logo and site title; a theme toggle for guests, an avatar account menu (Upload, Admin dashboard, Admin settings, Settings, theme, Log out) for users; centered content; Admin and Settings sub-pages as secondary tabs (menu picker on a phone); auth pages a centered card under the same bar. No rail, no bottom bar. - **Expressive components plus two hero moments** — an Expressive shape behind the upload icon that morphs while files are dragged over, the wavy progress indicator for uploads, a shape-backed check when the link is ready; admin stats count up once. Instant under `prefers-reduced-motion`. - **The public download page uses no anchored components** (no menus, no tooltips) — it must work for recipients on iOS below 18.4. - **Starter-kit cleanup during the conversion** — delete the placeholder `/dashboard`, point Fortify `home` at the admin dashboard, delete the unused views and the `registerView` binding, drop `alpinejs` from npm and the Flux step from CI. - **Confirmations become M3 basic dialogs** (the 3 `wire:confirm`) — the browser's native confirm cannot be themed and reads as a different app. *(Not asked in the interview; object in review if you prefer the native confirm.)* - **Save feedback becomes a snackbar** through the package's `Toasts` concern — admin settings' flashed `session('message')` alert and settings' "Saved." `action-message` alike. *(Follows from the snackbar; not asked separately.)* - **The font is self-hosted** — the fonts.bunny.net request goes, which also suits a privacy-minded self-hosted app. - **Tests: updated feature tests, the package's guard as `DesignLanguageTest`, Livewire tests for changed behaviour, and four browser tests** with `pestphp/pest-plugin-browser` (new dev dependency, approved). ## Out of scope - ReStride adopting the package — its own plan, after `1.0.0`. - Moving SealShare's repository, CI and image registry to Gitea — its own plan. - Everything the package plan puts out of scope. - Changes to SealShare's features, routes or information architecture beyond the cleanup above. ## Implementation steps Step numbers continue the original plan's, so references elsewhere stay valid. ### Phase 11 — SealShare 2.0.0 (after `1.0.0`) 34. **Branch** `material` from `main`; open the PR so CI runs. 35. **Dependencies.** Add the `vcs` repository and `composer require nonameweb/livewire-material:^1.0`; `composer remove robsontenorio/mary` (drops `blade-heroicons` with it); `npm remove daisyui alpinejs`; `composer require --dev pestphp/pest-plugin-browser`. maryUI goes **first** because its class components would shadow the package's same-named anonymous ones; the branch is therefore red from here until step 44, which is accepted — it merges once, green (Decisions: one pass). 36. **CI and Docker.** Remove the Flux credentials step from `.github/workflows/tests.yml`, `docker.yml` and `lint.yml`; install Playwright browsers in `tests.yml`. `Dockerfile`: run the Composer stage first and `COPY --from=vendor /app/vendor ./vendor` into the Node stage before `npm run build`. `docker/dev-entrypoint.sh`: run `composer install` when `vendor/` is missing, before `npm run build`. No `icons:cache` anywhere: the package draws its symbols without blade-icons. 37. **Styles and scheme.** `resources/css/app.css`: `@import 'tailwindcss'`, the package entry from `vendor/`, `./material-scheme.css`, `@source '../views'` and the package's views; drop the daisyUI plugin, maryUI and pagination `@source`s and the swap safelist. `resources/js/app.js` imports the package JS. Run `php artisan material:scheme "#4f46e5" --variant=vibrant` (chosen over Tonal Spot after comparing both on the upload page in both themes). 38. **Head and theme.** `partials/head`: remove fonts.bunny.net; include `