diff --git a/README.md b/README.md
index a22ee00..7a20f83 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@ This documentation now uses the corrected legacy/source folders:
4. `rebuild-progress.md`
5. `phase-1-foundation.md`
6. `phase-2-api.md`
+7. `phase-3-website.md`
## Note
diff --git a/app/app/Http/Controllers/Web/SiteController.php b/app/app/Http/Controllers/Web/SiteController.php
new file mode 100644
index 0000000..be75023
--- /dev/null
+++ b/app/app/Http/Controllers/Web/SiteController.php
@@ -0,0 +1,71 @@
+ $match,
+ ]);
+ }
+}
+
diff --git a/app/resources/views/site/api-docs.blade.php b/app/resources/views/site/api-docs.blade.php
new file mode 100644
index 0000000..50bb6e2
--- /dev/null
+++ b/app/resources/views/site/api-docs.blade.php
@@ -0,0 +1,49 @@
+@extends('site.layout')
+
+@section('title', 'API Docs - Dewemoji')
+
+@section('content')
+
+ API Docs
+ Current extension-compatible endpoints exposed by the rebuild app.
+
+ Base URL
+ {{ url('/') }}/v1
+
+ Endpoints
+
+ GET /v1/categories - category + subcategory map
+ GET /v1/emojis - paginated emoji list/search
+ POST /v1/license/verify - license validation contract
+
+
+ Example: emojis
+GET /v1/emojis?q=love&category=Smileys%20%26%20Emotion&page=1&limit=20
+
+ Example response
+{
+ "items": [
+ {
+ "emoji": "😀",
+ "name": "grinning face",
+ "slug": "grinning-face",
+ "category": "Smileys & Emotion",
+ "subcategory": "face-smiling",
+ "supports_skin_tone": false,
+ "summary": "A happy smiling face."
+ }
+ ],
+ "total": 1,
+ "page": 1,
+ "limit": 20
+}
+
+ Try it quickly
+
+ Open categories JSON
+ ·
+ Open emojis JSON
+
+
+@endsection
+
diff --git a/app/resources/views/site/emoji-detail.blade.php b/app/resources/views/site/emoji-detail.blade.php
new file mode 100644
index 0000000..9f66c58
--- /dev/null
+++ b/app/resources/views/site/emoji-detail.blade.php
@@ -0,0 +1,53 @@
+@extends('site.layout')
+
+@section('title', ($emoji['name'] ?? 'Emoji').' - Dewemoji')
+
+@section('content')
+
+ ← Back to emoji list
+
+
+
{{ $emoji['emoji'] ?? '' }}
+
+
{{ $emoji['name'] ?? '' }}
+
{{ $emoji['category'] ?? '' }} / {{ $emoji['subcategory'] ?? '' }}
+
{{ $emoji['description'] ?? '' }}
+
+
+
+
+
+
+ Slug: {{ $emoji['slug'] ?? '' }}
+ @if(!empty($emoji['unified']))
+ Unified: {{ $emoji['unified'] }}
+ @endif
+
+
+
+ @if(!empty($emoji['keywords_en']) && is_array($emoji['keywords_en']))
+ Keywords (EN)
+
+ @foreach($emoji['keywords_en'] as $kw)
+ {{ $kw }}
+ @endforeach
+
+ @endif
+
+@endsection
+
+@push('scripts')
+
+@endpush
+
diff --git a/app/resources/views/site/home.blade.php b/app/resources/views/site/home.blade.php
new file mode 100644
index 0000000..b692135
--- /dev/null
+++ b/app/resources/views/site/home.blade.php
@@ -0,0 +1,169 @@
+@extends('site.layout')
+
+@section('title', 'Dewemoji - Emoji Browser')
+
+@section('content')
+
+
+
+
+ Results
+ 0 / 0
+
+
+
+
+
+
+
+
+@endsection
+
+@push('scripts')
+
+@endpush
+
diff --git a/app/resources/views/site/layout.blade.php b/app/resources/views/site/layout.blade.php
new file mode 100644
index 0000000..5c36151
--- /dev/null
+++ b/app/resources/views/site/layout.blade.php
@@ -0,0 +1,92 @@
+
+
+
+
+
+ @yield('title', 'Dewemoji')
+
+ @stack('head')
+
+
+
+
+
+ @yield('content')
+
+
+
+ @stack('scripts')
+
+
+
diff --git a/app/resources/views/site/pricing.blade.php b/app/resources/views/site/pricing.blade.php
new file mode 100644
index 0000000..fd23950
--- /dev/null
+++ b/app/resources/views/site/pricing.blade.php
@@ -0,0 +1,11 @@
+@extends('site.layout')
+
+@section('title', 'Pricing - Dewemoji')
+
+@section('content')
+
+ Pricing
+ Phase 3 placeholder page. We will wire real pricing content and purchase flow in a later phase.
+
+@endsection
+
diff --git a/app/resources/views/site/privacy.blade.php b/app/resources/views/site/privacy.blade.php
new file mode 100644
index 0000000..dbcd82e
--- /dev/null
+++ b/app/resources/views/site/privacy.blade.php
@@ -0,0 +1,11 @@
+@extends('site.layout')
+
+@section('title', 'Privacy - Dewemoji')
+
+@section('content')
+
+ Privacy
+ Phase 3 placeholder page. We will migrate the full privacy text from legacy content in a later pass.
+
+@endsection
+
diff --git a/app/resources/views/site/terms.blade.php b/app/resources/views/site/terms.blade.php
new file mode 100644
index 0000000..7e18114
--- /dev/null
+++ b/app/resources/views/site/terms.blade.php
@@ -0,0 +1,11 @@
+@extends('site.layout')
+
+@section('title', 'Terms - Dewemoji')
+
+@section('content')
+
+ Terms
+ Phase 3 placeholder page. We will migrate complete terms content from legacy sources in a later pass.
+
+@endsection
+
diff --git a/app/routes/web.php b/app/routes/web.php
index 86a06c5..b675c0f 100644
--- a/app/routes/web.php
+++ b/app/routes/web.php
@@ -1,7 +1,12 @@
name('home');
+Route::get('/api-docs', [SiteController::class, 'apiDocs'])->name('api-docs');
+Route::get('/emoji/{slug}', [SiteController::class, 'emojiDetail'])->name('emoji-detail');
+
+Route::get('/pricing', [SiteController::class, 'pricing'])->name('pricing');
+Route::get('/privacy', [SiteController::class, 'privacy'])->name('privacy');
+Route::get('/terms', [SiteController::class, 'terms'])->name('terms');
diff --git a/app/tests/Feature/SitePagesTest.php b/app/tests/Feature/SitePagesTest.php
new file mode 100644
index 0000000..9106fc5
--- /dev/null
+++ b/app/tests/Feature/SitePagesTest.php
@@ -0,0 +1,37 @@
+set('dewemoji.data_path', base_path('tests/Fixtures/emojis.fixture.json'));
+ }
+
+ public function test_core_pages_are_available(): void
+ {
+ $this->get('/')->assertOk();
+ $this->get('/api-docs')->assertOk();
+ $this->get('/pricing')->assertOk();
+ $this->get('/privacy')->assertOk();
+ $this->get('/terms')->assertOk();
+ }
+
+ public function test_emoji_detail_page_works_with_valid_slug(): void
+ {
+ $this->get('/emoji/grinning-face')
+ ->assertOk()
+ ->assertSee('grinning face');
+ }
+
+ public function test_emoji_detail_page_returns_404_for_unknown_slug(): void
+ {
+ $this->get('/emoji/unknown-slug')->assertNotFound();
+ }
+}
+
diff --git a/phase-3-website.md b/phase-3-website.md
new file mode 100644
index 0000000..61a4d72
--- /dev/null
+++ b/phase-3-website.md
@@ -0,0 +1,42 @@
+# Phase 3 Website Delivery
+
+## Implemented routes
+
+In `app/routes/web.php`:
+
+- `GET /` (home)
+- `GET /emoji/{slug}` (detail)
+- `GET /api-docs`
+- `GET /pricing`
+- `GET /privacy`
+- `GET /terms`
+
+## Implemented pages
+
+In `app/resources/views/site/`:
+
+- `layout.blade.php`
+- `home.blade.php`
+- `emoji-detail.blade.php`
+- `api-docs.blade.php`
+- `pricing.blade.php`
+- `privacy.blade.php`
+- `terms.blade.php`
+
+## Behavior
+
+- Home page fetches categories and emojis from the new APIs:
+ - `/v1/categories`
+ - `/v1/emojis`
+- Supports search/category/subcategory filtering and pagination via "Load more".
+- Emoji cards link to server-rendered detail page by slug.
+
+## Controller
+
+- `app/app/Http/Controllers/Web/SiteController.php`
+ - Handles page rendering and slug-based emoji lookup from configured dataset.
+
+## Test coverage
+
+- `app/tests/Feature/SitePagesTest.php`
+- Validates core pages, valid emoji detail, and 404 for invalid slug.
diff --git a/rebuild-progress.md b/rebuild-progress.md
index 005700c..2135dfa 100644
--- a/rebuild-progress.md
+++ b/rebuild-progress.md
@@ -34,7 +34,7 @@
- [x] Support both `q` and `query` inputs.
### Phase 3 - Website rebuild
-- [ ] Build website pages in new app (index, emoji detail, api docs, legal pages).
+- [x] Build website pages in new app (index, emoji detail, api docs, legal pages).
- [ ] Replace scaffold in `dewemoji-site` via new NativePHP output.
### Phase 4 - Extension integration
@@ -57,3 +57,10 @@
- Routes are now available at `/v1/*` (no `/api` prefix) for extension compatibility.
- License verification is currently environment-driven (`DEWEMOJI_LICENSE_ACCEPT_ALL` / `DEWEMOJI_PRO_KEYS`) as a safe stub before real provider integration.
- Test coverage added for `v1` endpoints in `app/tests/Feature/ApiV1EndpointsTest.php`.
+
+## Implementation notes (Phase 3)
+
+- Added website routes/pages in Laravel app:
+ - `/`, `/emoji/{slug}`, `/api-docs`, `/pricing`, `/privacy`, `/terms`
+- Home page now consumes `/v1/categories` and `/v1/emojis` directly.
+- Added page tests in `app/tests/Feature/SitePagesTest.php`.