From 8d97dcbd0f7468603d284e7f27c0e31ffc7d1afd Mon Sep 17 00:00:00 2001 From: m105 Date: Thu, 30 Jul 2026 21:10:43 +0300 Subject: [PATCH] Add Filament admin panel and creative public portfolio site Adds a Filament admin (Profile settings page plus CRUD resources for Education, Experience, Projects, and Posts) backing a public-facing personal site: hero/about/timeline home page, project showcase, and blog, styled with a dark editorial theme (Fraunces + Instrument Sans). Co-Authored-By: Claude Sonnet 5 --- .gitignore | 3 + app/Filament/Pages/ManageProfile.php | 80 + .../Resources/Education/EducationResource.php | 48 + .../Education/Pages/CreateEducation.php | 11 + .../Education/Pages/EditEducation.php | 19 + .../Education/Pages/ListEducation.php | 19 + .../Education/Schemas/EducationForm.php | 30 + .../Education/Tables/EducationTable.php | 54 + .../Experiences/ExperienceResource.php | 48 + .../Experiences/Pages/CreateExperience.php | 11 + .../Experiences/Pages/EditExperience.php | 19 + .../Experiences/Pages/ListExperiences.php | 19 + .../Experiences/Schemas/ExperienceForm.php | 34 + .../Experiences/Tables/ExperiencesTable.php | 57 + .../Resources/Posts/Pages/CreatePost.php | 11 + .../Resources/Posts/Pages/EditPost.php | 19 + .../Resources/Posts/Pages/ListPosts.php | 19 + app/Filament/Resources/Posts/PostResource.php | 48 + .../Resources/Posts/Schemas/PostForm.php | 41 + .../Resources/Posts/Tables/PostsTable.php | 50 + .../Projects/Pages/CreateProject.php | 11 + .../Resources/Projects/Pages/EditProject.php | 19 + .../Resources/Projects/Pages/ListProjects.php | 19 + .../Resources/Projects/ProjectResource.php | 48 + .../Projects/Schemas/ProjectForm.php | 50 + .../Projects/Tables/ProjectsTable.php | 53 + app/Http/Controllers/HomeController.php | 53 + app/Http/Controllers/PostController.php | 26 + app/Http/Controllers/ProjectController.php | 25 + app/Models/Education.php | 23 + app/Models/Experience.php | 25 + app/Models/Post.php | 51 + app/Models/Profile.php | 35 + app/Models/Project.php | 48 + app/Models/User.php | 9 +- app/Providers/Filament/AdminPanelProvider.php | 59 + bootstrap/providers.php | 5 +- composer.json | 4 +- composer.lock | 2123 ++++++++++++++++- ...026_07_30_175543_create_profiles_table.php | 35 + ...26_07_30_175544_create_education_table.php | 34 + ..._07_30_175545_create_experiences_table.php | 35 + ...026_07_30_175546_create_projects_table.php | 37 + .../2026_07_30_175547_create_posts_table.php | 34 + database/seeders/DatabaseSeeder.php | 81 +- package-lock.json | 1923 +++++++++++++++ package.json | 1 + resources/css/app.css | 16 + .../views/components/layouts/app.blade.php | 30 + .../views/components/site/footer.blade.php | 19 + resources/views/components/site/nav.blade.php | 16 + .../filament/pages/manage-profile.blade.php | 9 + resources/views/home.blade.php | 146 ++ resources/views/posts/index.blade.php | 30 + resources/views/posts/show.blade.php | 26 + resources/views/projects/index.blade.php | 42 + resources/views/projects/show.blade.php | 42 + .../vendor/pagination/tailwind.blade.php | 44 + resources/views/welcome.blade.php | 223 -- routes/web.php | 13 +- tests/Feature/ExampleTest.php | 4 +- vite.config.js | 4 + 62 files changed, 5933 insertions(+), 237 deletions(-) create mode 100644 app/Filament/Pages/ManageProfile.php create mode 100644 app/Filament/Resources/Education/EducationResource.php create mode 100644 app/Filament/Resources/Education/Pages/CreateEducation.php create mode 100644 app/Filament/Resources/Education/Pages/EditEducation.php create mode 100644 app/Filament/Resources/Education/Pages/ListEducation.php create mode 100644 app/Filament/Resources/Education/Schemas/EducationForm.php create mode 100644 app/Filament/Resources/Education/Tables/EducationTable.php create mode 100644 app/Filament/Resources/Experiences/ExperienceResource.php create mode 100644 app/Filament/Resources/Experiences/Pages/CreateExperience.php create mode 100644 app/Filament/Resources/Experiences/Pages/EditExperience.php create mode 100644 app/Filament/Resources/Experiences/Pages/ListExperiences.php create mode 100644 app/Filament/Resources/Experiences/Schemas/ExperienceForm.php create mode 100644 app/Filament/Resources/Experiences/Tables/ExperiencesTable.php create mode 100644 app/Filament/Resources/Posts/Pages/CreatePost.php create mode 100644 app/Filament/Resources/Posts/Pages/EditPost.php create mode 100644 app/Filament/Resources/Posts/Pages/ListPosts.php create mode 100644 app/Filament/Resources/Posts/PostResource.php create mode 100644 app/Filament/Resources/Posts/Schemas/PostForm.php create mode 100644 app/Filament/Resources/Posts/Tables/PostsTable.php create mode 100644 app/Filament/Resources/Projects/Pages/CreateProject.php create mode 100644 app/Filament/Resources/Projects/Pages/EditProject.php create mode 100644 app/Filament/Resources/Projects/Pages/ListProjects.php create mode 100644 app/Filament/Resources/Projects/ProjectResource.php create mode 100644 app/Filament/Resources/Projects/Schemas/ProjectForm.php create mode 100644 app/Filament/Resources/Projects/Tables/ProjectsTable.php create mode 100644 app/Http/Controllers/HomeController.php create mode 100644 app/Http/Controllers/PostController.php create mode 100644 app/Http/Controllers/ProjectController.php create mode 100644 app/Models/Education.php create mode 100644 app/Models/Experience.php create mode 100644 app/Models/Post.php create mode 100644 app/Models/Profile.php create mode 100644 app/Models/Project.php create mode 100644 app/Providers/Filament/AdminPanelProvider.php create mode 100644 database/migrations/2026_07_30_175543_create_profiles_table.php create mode 100644 database/migrations/2026_07_30_175544_create_education_table.php create mode 100644 database/migrations/2026_07_30_175545_create_experiences_table.php create mode 100644 database/migrations/2026_07_30_175546_create_projects_table.php create mode 100644 database/migrations/2026_07_30_175547_create_posts_table.php create mode 100644 package-lock.json create mode 100644 resources/views/components/layouts/app.blade.php create mode 100644 resources/views/components/site/footer.blade.php create mode 100644 resources/views/components/site/nav.blade.php create mode 100644 resources/views/filament/pages/manage-profile.blade.php create mode 100644 resources/views/home.blade.php create mode 100644 resources/views/posts/index.blade.php create mode 100644 resources/views/posts/show.blade.php create mode 100644 resources/views/projects/index.blade.php create mode 100644 resources/views/projects/show.blade.php create mode 100644 resources/views/vendor/pagination/tailwind.blade.php delete mode 100644 resources/views/welcome.blade.php diff --git a/.gitignore b/.gitignore index 7be55e2..fad3ce2 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,11 @@ /auth.json /node_modules /public/build +/public/css/filament /public/fonts-manifest.dev.json +/public/fonts/filament /public/hot +/public/js/filament /public/storage /storage/*.key /storage/pail diff --git a/app/Filament/Pages/ManageProfile.php b/app/Filament/Pages/ManageProfile.php new file mode 100644 index 0000000..3805bc2 --- /dev/null +++ b/app/Filament/Pages/ManageProfile.php @@ -0,0 +1,80 @@ +|null + */ + public ?array $data = []; + + public function mount(): void + { + $this->form->fill(Profile::query()->first()?->toArray() ?? []); + } + + public function defaultForm(Schema $schema): Schema + { + return $schema->statePath('data'); + } + + public function form(Schema $schema): Schema + { + return $schema + ->components([ + TextInput::make('name') + ->required(), + TextInput::make('headline') + ->helperText('A short tagline shown under your name, e.g. "Backend developer & tinkerer".'), + RichEditor::make('bio') + ->columnSpanFull(), + TextInput::make('location'), + TextInput::make('email') + ->email(), + FileUpload::make('avatar') + ->image() + ->disk('public') + ->directory('profile'), + FileUpload::make('resume_path') + ->label('Resume / CV') + ->disk('public') + ->directory('profile'), + KeyValue::make('social_links') + ->keyLabel('Platform') + ->valueLabel('URL') + ->columnSpanFull(), + ]); + } + + public function save(): void + { + $data = $this->form->getState(); + + Profile::query()->first()?->update($data) ?? Profile::create($data); + + Notification::make() + ->title('Profile saved') + ->success() + ->send(); + } +} diff --git a/app/Filament/Resources/Education/EducationResource.php b/app/Filament/Resources/Education/EducationResource.php new file mode 100644 index 0000000..94c0dc3 --- /dev/null +++ b/app/Filament/Resources/Education/EducationResource.php @@ -0,0 +1,48 @@ + ListEducation::route('/'), + 'create' => CreateEducation::route('/create'), + 'edit' => EditEducation::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/Education/Pages/CreateEducation.php b/app/Filament/Resources/Education/Pages/CreateEducation.php new file mode 100644 index 0000000..9787db7 --- /dev/null +++ b/app/Filament/Resources/Education/Pages/CreateEducation.php @@ -0,0 +1,11 @@ +components([ + TextInput::make('institution') + ->required(), + TextInput::make('degree'), + TextInput::make('field_of_study'), + DatePicker::make('start_date'), + DatePicker::make('end_date'), + Textarea::make('description') + ->columnSpanFull(), + TextInput::make('sort_order') + ->required() + ->numeric() + ->default(0), + ]); + } +} diff --git a/app/Filament/Resources/Education/Tables/EducationTable.php b/app/Filament/Resources/Education/Tables/EducationTable.php new file mode 100644 index 0000000..16894e0 --- /dev/null +++ b/app/Filament/Resources/Education/Tables/EducationTable.php @@ -0,0 +1,54 @@ +defaultSort('sort_order') + ->columns([ + TextColumn::make('institution') + ->searchable(), + TextColumn::make('degree') + ->searchable(), + TextColumn::make('field_of_study') + ->searchable(), + TextColumn::make('start_date') + ->date() + ->sortable(), + TextColumn::make('end_date') + ->date() + ->sortable(), + TextColumn::make('sort_order') + ->numeric() + ->sortable(), + TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + // + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/Experiences/ExperienceResource.php b/app/Filament/Resources/Experiences/ExperienceResource.php new file mode 100644 index 0000000..7b82784 --- /dev/null +++ b/app/Filament/Resources/Experiences/ExperienceResource.php @@ -0,0 +1,48 @@ + ListExperiences::route('/'), + 'create' => CreateExperience::route('/create'), + 'edit' => EditExperience::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/Experiences/Pages/CreateExperience.php b/app/Filament/Resources/Experiences/Pages/CreateExperience.php new file mode 100644 index 0000000..90b9587 --- /dev/null +++ b/app/Filament/Resources/Experiences/Pages/CreateExperience.php @@ -0,0 +1,11 @@ +components([ + TextInput::make('company') + ->required(), + TextInput::make('role') + ->required(), + TextInput::make('location'), + DatePicker::make('start_date'), + DatePicker::make('end_date'), + Toggle::make('is_current') + ->default(false), + Textarea::make('description') + ->columnSpanFull(), + TextInput::make('sort_order') + ->required() + ->numeric() + ->default(0), + ]); + } +} diff --git a/app/Filament/Resources/Experiences/Tables/ExperiencesTable.php b/app/Filament/Resources/Experiences/Tables/ExperiencesTable.php new file mode 100644 index 0000000..c6ac94f --- /dev/null +++ b/app/Filament/Resources/Experiences/Tables/ExperiencesTable.php @@ -0,0 +1,57 @@ +defaultSort('sort_order') + ->columns([ + TextColumn::make('company') + ->searchable(), + TextColumn::make('role') + ->searchable(), + TextColumn::make('location') + ->searchable(), + TextColumn::make('start_date') + ->date() + ->sortable(), + TextColumn::make('end_date') + ->date() + ->sortable(), + IconColumn::make('is_current') + ->boolean(), + TextColumn::make('sort_order') + ->numeric() + ->sortable(), + TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + // + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/Posts/Pages/CreatePost.php b/app/Filament/Resources/Posts/Pages/CreatePost.php new file mode 100644 index 0000000..47a1e04 --- /dev/null +++ b/app/Filament/Resources/Posts/Pages/CreatePost.php @@ -0,0 +1,11 @@ + ListPosts::route('/'), + 'create' => CreatePost::route('/create'), + 'edit' => EditPost::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/Posts/Schemas/PostForm.php b/app/Filament/Resources/Posts/Schemas/PostForm.php new file mode 100644 index 0000000..e880eb8 --- /dev/null +++ b/app/Filament/Resources/Posts/Schemas/PostForm.php @@ -0,0 +1,41 @@ +components([ + TextInput::make('title') + ->required() + ->live(onBlur: true) + ->afterStateUpdated(fn ($state, callable $set) => $set('slug', Str::slug($state))), + TextInput::make('slug') + ->required() + ->unique(ignoreRecord: true), + Textarea::make('excerpt') + ->columnSpanFull(), + RichEditor::make('body') + ->columnSpanFull(), + FileUpload::make('cover_image') + ->image() + ->disk('public') + ->directory('posts'), + TagsInput::make('tags') + ->columnSpanFull(), + DateTimePicker::make('published_at') + ->helperText('Leave blank to keep this post as a draft.'), + ]); + } +} diff --git a/app/Filament/Resources/Posts/Tables/PostsTable.php b/app/Filament/Resources/Posts/Tables/PostsTable.php new file mode 100644 index 0000000..17cc0ab --- /dev/null +++ b/app/Filament/Resources/Posts/Tables/PostsTable.php @@ -0,0 +1,50 @@ +defaultSort('published_at', 'desc') + ->columns([ + ImageColumn::make('cover_image') + ->disk('public'), + TextColumn::make('title') + ->searchable(), + TextColumn::make('excerpt') + ->searchable() + ->limit(50), + TextColumn::make('published_at') + ->dateTime() + ->sortable(), + TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + // + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/Projects/Pages/CreateProject.php b/app/Filament/Resources/Projects/Pages/CreateProject.php new file mode 100644 index 0000000..5bab965 --- /dev/null +++ b/app/Filament/Resources/Projects/Pages/CreateProject.php @@ -0,0 +1,11 @@ + ListProjects::route('/'), + 'create' => CreateProject::route('/create'), + 'edit' => EditProject::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/Projects/Schemas/ProjectForm.php b/app/Filament/Resources/Projects/Schemas/ProjectForm.php new file mode 100644 index 0000000..84c3cb3 --- /dev/null +++ b/app/Filament/Resources/Projects/Schemas/ProjectForm.php @@ -0,0 +1,50 @@ +components([ + TextInput::make('title') + ->required() + ->live(onBlur: true) + ->afterStateUpdated(fn ($state, callable $set) => $set('slug', \Illuminate\Support\Str::slug($state))), + TextInput::make('slug') + ->required() + ->unique(ignoreRecord: true), + TextInput::make('summary') + ->columnSpanFull(), + RichEditor::make('description') + ->columnSpanFull(), + FileUpload::make('image') + ->image() + ->disk('public') + ->directory('projects'), + TextInput::make('url') + ->label('Live URL') + ->url(), + TextInput::make('repository_url') + ->label('Repository URL') + ->url(), + TagsInput::make('tech_stack') + ->label('Tech stack') + ->columnSpanFull(), + Toggle::make('is_featured') + ->default(false), + TextInput::make('sort_order') + ->required() + ->numeric() + ->default(0), + ]); + } +} diff --git a/app/Filament/Resources/Projects/Tables/ProjectsTable.php b/app/Filament/Resources/Projects/Tables/ProjectsTable.php new file mode 100644 index 0000000..713baf3 --- /dev/null +++ b/app/Filament/Resources/Projects/Tables/ProjectsTable.php @@ -0,0 +1,53 @@ +defaultSort('sort_order') + ->columns([ + ImageColumn::make('image') + ->disk('public'), + TextColumn::make('title') + ->searchable(), + TextColumn::make('summary') + ->searchable() + ->limit(50), + IconColumn::make('is_featured') + ->boolean(), + TextColumn::make('sort_order') + ->numeric() + ->sortable(), + TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + TextColumn::make('updated_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + // + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php new file mode 100644 index 0000000..deaa0b0 --- /dev/null +++ b/app/Http/Controllers/HomeController.php @@ -0,0 +1,53 @@ +first(); + + $timeline = Experience::query()->get()->map(fn (Experience $item) => (object) [ + 'type' => 'work', + 'title' => $item->role, + 'subtitle' => $item->company, + 'start_date' => $item->start_date, + 'end_date' => $item->end_date, + 'is_current' => $item->is_current, + 'description' => $item->description, + ])->concat(Education::query()->get()->map(fn (Education $item) => (object) [ + 'type' => 'education', + 'title' => $item->degree + ? $item->degree . ($item->field_of_study ? " in {$item->field_of_study}" : '') + : $item->institution, + 'subtitle' => $item->institution, + 'start_date' => $item->start_date, + 'end_date' => $item->end_date, + 'is_current' => false, + 'description' => $item->description, + ]))->sortByDesc(fn (object $item) => $item->start_date)->values(); + + $projects = Project::query() + ->orderByDesc('is_featured') + ->orderBy('sort_order') + ->orderByDesc('created_at') + ->limit(4) + ->get(); + + $posts = Post::query() + ->published() + ->orderByDesc('published_at') + ->limit(3) + ->get(); + + return view('home', compact('profile', 'timeline', 'projects', 'posts')); + } +} diff --git a/app/Http/Controllers/PostController.php b/app/Http/Controllers/PostController.php new file mode 100644 index 0000000..e980ea1 --- /dev/null +++ b/app/Http/Controllers/PostController.php @@ -0,0 +1,26 @@ +published() + ->orderByDesc('published_at') + ->paginate(6); + + return view('posts.index', compact('posts')); + } + + public function show(Post $post): View + { + abort_unless($post->published_at?->isPast(), 404); + + return view('posts.show', compact('post')); + } +} diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php new file mode 100644 index 0000000..7aad6c4 --- /dev/null +++ b/app/Http/Controllers/ProjectController.php @@ -0,0 +1,25 @@ +orderByDesc('is_featured') + ->orderBy('sort_order') + ->orderByDesc('created_at') + ->get(); + + return view('projects.index', compact('projects')); + } + + public function show(Project $project): View + { + return view('projects.show', compact('project')); + } +} diff --git a/app/Models/Education.php b/app/Models/Education.php new file mode 100644 index 0000000..2db79fe --- /dev/null +++ b/app/Models/Education.php @@ -0,0 +1,23 @@ + 'date', + 'end_date' => 'date', + ]; +} diff --git a/app/Models/Experience.php b/app/Models/Experience.php new file mode 100644 index 0000000..cdc440d --- /dev/null +++ b/app/Models/Experience.php @@ -0,0 +1,25 @@ + 'date', + 'end_date' => 'date', + 'is_current' => 'boolean', + ]; +} diff --git a/app/Models/Post.php b/app/Models/Post.php new file mode 100644 index 0000000..a824d7b --- /dev/null +++ b/app/Models/Post.php @@ -0,0 +1,51 @@ + 'array', + 'published_at' => 'datetime', + ]; + + protected static function booted(): void + { + static::saving(function (Post $post) { + if (blank($post->slug)) { + $post->slug = Str::slug($post->title); + } + }); + } + + public function scopePublished(Builder $query): Builder + { + return $query->whereNotNull('published_at')->where('published_at', '<=', now()); + } + + public function getRouteKeyName(): string + { + return 'slug'; + } + + protected function coverImageUrl(): Attribute + { + return Attribute::get(fn () => $this->cover_image ? Storage::disk('public')->url($this->cover_image) : null); + } +} diff --git a/app/Models/Profile.php b/app/Models/Profile.php new file mode 100644 index 0000000..748e0f1 --- /dev/null +++ b/app/Models/Profile.php @@ -0,0 +1,35 @@ + 'array', + ]; + + protected function avatarUrl(): Attribute + { + return Attribute::get(fn () => $this->avatar ? Storage::disk('public')->url($this->avatar) : null); + } + + protected function resumeUrl(): Attribute + { + return Attribute::get(fn () => $this->resume_path ? Storage::disk('public')->url($this->resume_path) : null); + } +} diff --git a/app/Models/Project.php b/app/Models/Project.php new file mode 100644 index 0000000..aa09b24 --- /dev/null +++ b/app/Models/Project.php @@ -0,0 +1,48 @@ + 'array', + 'is_featured' => 'boolean', + ]; + + protected static function booted(): void + { + static::saving(function (Project $project) { + if (blank($project->slug)) { + $project->slug = Str::slug($project->title); + } + }); + } + + public function getRouteKeyName(): string + { + return 'slug'; + } + + protected function imageUrl(): Attribute + { + return Attribute::get(fn () => $this->image ? Storage::disk('public')->url($this->image) : null); + } +} diff --git a/app/Models/User.php b/app/Models/User.php index f6ba1d2..1ff4558 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -4,6 +4,8 @@ namespace App\Models; // use Illuminate\Contracts\Auth\MustVerifyEmail; use Database\Factories\UserFactory; +use Filament\Models\Contracts\FilamentUser; +use Filament\Panel; use Illuminate\Database\Eloquent\Attributes\Fillable; use Illuminate\Database\Eloquent\Attributes\Hidden; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -12,11 +14,16 @@ use Illuminate\Notifications\Notifiable; #[Fillable(['name', 'email', 'password'])] #[Hidden(['password', 'remember_token'])] -class User extends Authenticatable +class User extends Authenticatable implements FilamentUser { /** @use HasFactory */ use HasFactory, Notifiable; + public function canAccessPanel(Panel $panel): bool + { + return true; + } + /** * Get the attributes that should be cast. * diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php new file mode 100644 index 0000000..7c74b3e --- /dev/null +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -0,0 +1,59 @@ +default() + ->id('admin') + ->path('admin') + ->login() + ->colors([ + 'primary' => Color::Amber, + ]) + ->discoverResources(in: app_path('Filament/Resources'), for: 'App\Filament\Resources') + ->discoverPages(in: app_path('Filament/Pages'), for: 'App\Filament\Pages') + ->pages([ + Dashboard::class, + ]) + ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets') + ->widgets([ + AccountWidget::class, + FilamentInfoWidget::class, + ]) + ->middleware([ + EncryptCookies::class, + AddQueuedCookiesToResponse::class, + StartSession::class, + AuthenticateSession::class, + ShareErrorsFromSession::class, + PreventRequestForgery::class, + SubstituteBindings::class, + DisableBladeIconComponents::class, + DispatchServingFilamentEvent::class, + ]) + ->authMiddleware([ + Authenticate::class, + ]); + } +} diff --git a/bootstrap/providers.php b/bootstrap/providers.php index fc94ae6..22744d1 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -1,7 +1,6 @@ =5.4" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.7", + "sabberworm/php-css-parser": "^8.3", + "symfony/finder": "^2.8|^3.4|^5.4", + "symfony/var-dumper": "^2.8|^3.4|^5.4" + }, + "suggest": { + "ext-mbstring": "Allows highlighting code with unicode characters and supports language with unicode keywords" + }, + "type": "library", + "autoload": { + "files": [ + "HighlightUtilities/functions.php" + ], + "psr-0": { + "Highlight\\": "", + "HighlightUtilities\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Geert Bergman", + "homepage": "http://www.scrivo.org/", + "role": "Project Author" + }, + { + "name": "Vladimir Jimenez", + "homepage": "https://allejo.io", + "role": "Maintainer" + }, + { + "name": "Martin Folkers", + "homepage": "https://twobrain.io", + "role": "Contributor" + } + ], + "description": "Server side syntax highlighter that supports 185 languages. It's a PHP port of highlight.js", + "keywords": [ + "code", + "highlight", + "highlight.js", + "highlight.php", + "syntax" + ], + "support": { + "issues": "https://github.com/scrivo/highlight.php/issues", + "source": "https://github.com/scrivo/highlight.php" + }, + "funding": [ + { + "url": "https://github.com/allejo", + "type": "github" + } + ], + "time": "2022-12-17T21:53:22+00:00" + }, + { + "name": "spatie/invade", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/invade.git", + "reference": "b920f6411d21df4e8610a138e2e87ae4957d7f63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/invade/zipball/b920f6411d21df4e8610a138e2e87ae4957d7f63", + "reference": "b920f6411d21df4e8610a138e2e87ae4957d7f63", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "pestphp/pest": "^1.20", + "phpstan/phpstan": "^1.4", + "spatie/ray": "^1.28" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Spatie\\Invade\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "A PHP function to work with private properties and methods", + "homepage": "https://github.com/spatie/invade", + "keywords": [ + "invade", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/invade/tree/2.1.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-05-17T09:06:10+00:00" + }, + { + "name": "spatie/laravel-package-tools", + "version": "1.93.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-package-tools.git", + "reference": "d5552849801f2642aea710557463234b59ef65eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/d5552849801f2642aea710557463234b59ef65eb", + "reference": "d5552849801f2642aea710557463234b59ef65eb", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^10.0|^11.0|^12.0|^13.0", + "php": "^8.1" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "orchestra/testbench": "^8.0|^9.2|^10.0|^11.0", + "pestphp/pest": "^2.1|^3.1|^4.0", + "phpunit/php-code-coverage": "^10.0|^11.0|^12.0", + "phpunit/phpunit": "^10.5|^11.5|^12.5", + "spatie/pest-plugin-test-time": "^2.2|^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\LaravelPackageTools\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Tools for creating Laravel packages", + "homepage": "https://github.com/spatie/laravel-package-tools", + "keywords": [ + "laravel-package-tools", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-package-tools/issues", + "source": "https://github.com/spatie/laravel-package-tools/tree/1.93.1" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-05-19T14:06:37+00:00" + }, + { + "name": "spatie/shiki-php", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/shiki-php.git", + "reference": "b8b0ca32d3a82bc5c533e68ffab96c5d4ec1b9ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/shiki-php/zipball/b8b0ca32d3a82bc5c533e68ffab96c5d4ec1b9ba", + "reference": "b8b0ca32d3a82bc5c533e68ffab96c5d4ec1b9ba", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^8.0", + "symfony/process": "^5.4|^6.4|^7.1|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^v3.0", + "pestphp/pest": "^1.8", + "phpunit/phpunit": "^9.5", + "spatie/pest-plugin-snapshots": "^1.1", + "spatie/ray": "^1.10" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\ShikiPhp\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rias Van der Veken", + "email": "rias@spatie.be", + "role": "Developer" + }, + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Highlight code using Shiki in PHP", + "homepage": "https://github.com/spatie/shiki-php", + "keywords": [ + "shiki", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/shiki-php/tree/2.4.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-04-27T14:27:52+00:00" + }, { "name": "symfony/clock", "version": "v8.1.0", @@ -3938,6 +5918,78 @@ ], "time": "2026-06-27T09:05:56+00:00" }, + { + "name": "symfony/html-sanitizer", + "version": "v8.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/html-sanitizer.git", + "reference": "09e1f2f9a3c8dcdca072587dc71999c1921c07cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/09e1f2f9a3c8dcdca072587dc71999c1921c07cb", + "reference": "09e1f2f9a3c8dcdca072587dc71999c1921c07cb", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "league/uri": "^6.5|^7.0", + "php": ">=8.4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HtmlSanitizer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Titouan Galopin", + "email": "galopintitouan@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to sanitize untrusted HTML input for safe insertion into a document's DOM.", + "homepage": "https://symfony.com", + "keywords": [ + "Purifier", + "html", + "sanitizer" + ], + "support": { + "source": "https://github.com/symfony/html-sanitizer/tree/v8.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-06-06T11:11:44+00:00" + }, { "name": "symfony/http-foundation", "version": "v8.1.2", @@ -5841,6 +7893,75 @@ }, "time": "2025-12-02T11:56:42+00:00" }, + { + "name": "ueberdosis/tiptap-php", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/ueberdosis/tiptap-php.git", + "reference": "74bfb7be1c8c6102b240f3879b7f984a6ab87b97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ueberdosis/tiptap-php/zipball/74bfb7be1c8c6102b240f3879b7f984a6ab87b97", + "reference": "74bfb7be1c8c6102b240f3879b7f984a6ab87b97", + "shasum": "" + }, + "require": { + "php": "^8.0", + "scrivo/highlight.php": "^9.18", + "spatie/shiki-php": "^2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.5", + "pestphp/pest": "^1.21", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^4.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Tiptap\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Hans Pagel", + "email": "humans@tiptap.dev", + "role": "Developer" + } + ], + "description": "A PHP package to work with Tiptap output", + "homepage": "https://github.com/ueberdosis/tiptap-php", + "keywords": [ + "prosemirror", + "tiptap", + "ueberdosis" + ], + "support": { + "issues": "https://github.com/ueberdosis/tiptap-php/issues", + "source": "https://github.com/ueberdosis/tiptap-php/tree/2.1.1" + }, + "funding": [ + { + "url": "https://tiptap.dev/pricing", + "type": "custom" + }, + { + "url": "https://github.com/ueberdosis", + "type": "github" + }, + { + "url": "https://opencollective.com/tiptap", + "type": "open_collective" + } + ], + "time": "2026-06-12T18:19:46+00:00" + }, { "name": "vlucas/phpdotenv", "version": "v5.6.4", diff --git a/database/migrations/2026_07_30_175543_create_profiles_table.php b/database/migrations/2026_07_30_175543_create_profiles_table.php new file mode 100644 index 0000000..94d54a7 --- /dev/null +++ b/database/migrations/2026_07_30_175543_create_profiles_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('name'); + $table->string('headline')->nullable(); + $table->text('bio')->nullable(); + $table->string('location')->nullable(); + $table->string('email')->nullable(); + $table->string('avatar')->nullable(); + $table->string('resume_path')->nullable(); + $table->json('social_links')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('profiles'); + } +}; diff --git a/database/migrations/2026_07_30_175544_create_education_table.php b/database/migrations/2026_07_30_175544_create_education_table.php new file mode 100644 index 0000000..e2b2477 --- /dev/null +++ b/database/migrations/2026_07_30_175544_create_education_table.php @@ -0,0 +1,34 @@ +id(); + $table->string('institution'); + $table->string('degree')->nullable(); + $table->string('field_of_study')->nullable(); + $table->date('start_date')->nullable(); + $table->date('end_date')->nullable(); + $table->text('description')->nullable(); + $table->unsignedInteger('sort_order')->default(0); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('education'); + } +}; diff --git a/database/migrations/2026_07_30_175545_create_experiences_table.php b/database/migrations/2026_07_30_175545_create_experiences_table.php new file mode 100644 index 0000000..29a6159 --- /dev/null +++ b/database/migrations/2026_07_30_175545_create_experiences_table.php @@ -0,0 +1,35 @@ +id(); + $table->string('company'); + $table->string('role'); + $table->string('location')->nullable(); + $table->date('start_date')->nullable(); + $table->date('end_date')->nullable(); + $table->boolean('is_current')->default(false); + $table->text('description')->nullable(); + $table->unsignedInteger('sort_order')->default(0); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('experiences'); + } +}; diff --git a/database/migrations/2026_07_30_175546_create_projects_table.php b/database/migrations/2026_07_30_175546_create_projects_table.php new file mode 100644 index 0000000..893c4db --- /dev/null +++ b/database/migrations/2026_07_30_175546_create_projects_table.php @@ -0,0 +1,37 @@ +id(); + $table->string('title'); + $table->string('slug')->unique(); + $table->string('summary')->nullable(); + $table->text('description')->nullable(); + $table->string('image')->nullable(); + $table->string('url')->nullable(); + $table->string('repository_url')->nullable(); + $table->json('tech_stack')->nullable(); + $table->boolean('is_featured')->default(false); + $table->unsignedInteger('sort_order')->default(0); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('projects'); + } +}; diff --git a/database/migrations/2026_07_30_175547_create_posts_table.php b/database/migrations/2026_07_30_175547_create_posts_table.php new file mode 100644 index 0000000..331af61 --- /dev/null +++ b/database/migrations/2026_07_30_175547_create_posts_table.php @@ -0,0 +1,34 @@ +id(); + $table->string('title'); + $table->string('slug')->unique(); + $table->string('excerpt')->nullable(); + $table->longText('body')->nullable(); + $table->string('cover_image')->nullable(); + $table->json('tags')->nullable(); + $table->timestamp('published_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('posts'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 6b901f8..581effb 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -2,6 +2,11 @@ namespace Database\Seeders; +use App\Models\Education; +use App\Models\Experience; +use App\Models\Post; +use App\Models\Profile; +use App\Models\Project; use App\Models\User; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; @@ -15,11 +20,79 @@ class DatabaseSeeder extends Seeder */ public function run(): void { - // User::factory(10)->create(); + User::firstOrCreate( + ['email' => 'admin@mikeisdeving.test'], + ['name' => 'Mike', 'password' => bcrypt('password')], + ); - User::factory()->create([ - 'name' => 'Test User', - 'email' => 'test@example.com', + Profile::query()->firstOrCreate([], [ + 'name' => 'Mike', + 'headline' => 'Backend developer & tinkerer', + 'bio' => '

I build web apps and occasionally write about it. This is a placeholder bio — edit it from the admin panel.

', + 'location' => 'Somewhere, Earth', + 'email' => 'hello@mikeisdeving.test', + 'social_links' => [ + 'github' => 'https://github.com/', + 'linkedin' => 'https://linkedin.com/', + ], ]); + + if (Experience::query()->count() === 0) { + Experience::create([ + 'company' => 'Acme Corp', + 'role' => 'Senior Developer', + 'location' => 'Remote', + 'start_date' => '2023-01-01', + 'is_current' => true, + 'description' => 'Working on backend systems and internal tooling.', + 'sort_order' => 0, + ]); + + Experience::create([ + 'company' => 'Startup Inc', + 'role' => 'Software Developer', + 'location' => 'Remote', + 'start_date' => '2020-06-01', + 'end_date' => '2022-12-01', + 'description' => 'Built and maintained a SaaS product from early stage to scale.', + 'sort_order' => 1, + ]); + } + + if (Education::query()->count() === 0) { + Education::create([ + 'institution' => 'State University', + 'degree' => 'B.Sc.', + 'field_of_study' => 'Computer Science', + 'start_date' => '2016-09-01', + 'end_date' => '2020-06-01', + 'sort_order' => 0, + ]); + } + + if (Project::query()->count() === 0) { + Project::create([ + 'title' => 'Sample Project', + 'slug' => 'sample-project', + 'summary' => 'A short description of what this project does.', + 'description' => '

Longer write-up of the project, the problem it solves, and how it was built.

', + 'url' => 'https://example.com', + 'repository_url' => 'https://github.com/example/example', + 'tech_stack' => ['Laravel', 'PHP', 'Tailwind'], + 'is_featured' => true, + 'sort_order' => 0, + ]); + } + + if (Post::query()->count() === 0) { + Post::create([ + 'title' => 'Hello, world', + 'slug' => 'hello-world', + 'excerpt' => 'The first post on this blog.', + 'body' => '

This is a placeholder post. Edit or delete it from the admin panel.

', + 'tags' => ['meta'], + 'published_at' => now(), + ]); + } } } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..208c825 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1923 @@ +{ + "name": "mikeisdeving", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@tailwindcss/typography": "^0.5.20", + "@tailwindcss/vite": "^4.0.0", + "concurrently": "^9.0.1", + "laravel-vite-plugin": "^3.1", + "tailwindcss": "^4.0.0", + "vite": "^8.0.0" + } + }, + "node_modules/@emnapi/core": { + "version": "2.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-2.0.0-alpha.3.tgz", + "integrity": "sha512-AZypUeJ/yByuxyS7BlSNRDOMLMlROYtjYdIAuBmJssVz1UJDSeYxLrdizhXCFYhedC5bqd/ASy8EuNXbVVXp9g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "2.0.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "2.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-2.0.0-alpha.3.tgz", + "integrity": "sha512-hFPAhMUjJD9BSyCANEISPOogeXC9Zo9ZQl7L6vKnaVsMkCtzznaW/naYypeyl0Gv5rYfWYsZbpixTMpjDJzQeA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-2.0.1.tgz", + "integrity": "sha512-9DsSk+o5NBX0CCJT8s0EROGSGxjR/tKu6aBTaVyq+SjAEQH4XcdcRxPBRzsBLizTTJ49MJjF+jgu3qnO9GLQcQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.1.tgz", + "integrity": "sha512-KjZdi8Q1wh89gsVmghvbrMgWl6ZWmRmHV6wjB7/g4Zf0dyO+hH3neZUtuDNPO00qq5YE5RITVWvrIZKRaAmzGQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.142.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.142.0.tgz", + "integrity": "sha512-7W+2q5AKQVU36fkaryontrHn3YDt1RyUYXatw9i5H8ocYe2sPKSFB6eS8WNPeRKiN1qAWWZUPm7gwFzJGrccqQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.1.tgz", + "integrity": "sha512-02hOeOSryYxVrOIphmLAsqnCJWxwlzFk+pEt/N/i6OgT3lShHO7xGCU5cpgchRDHboAEbSjzgGh+O/u1GswQmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.1.tgz", + "integrity": "sha512-fMsTOnN0OjFm3CyppWPitKnc8UlliVARUULW6cfU6AIqjdtgmSFWSk9vecHzZduv/yMWIHDlRhM1e8Iff9uAfA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.1.tgz", + "integrity": "sha512-1wjKdz/XLGKHaTNHjQveQ/B23TKx4ItAqm1JbyVuvNPc4Ze0Fb48s49TAd/2zcplPl8okE/UbTgmlVfwT7eFeQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.1.tgz", + "integrity": "sha512-Fa0jHR07E7YBN4vOEsbVf2briYNsuOowfLJaXULZM0ldMlaCaj2LJgLMbMe4iacRyZmvR8efFhgR9wKuGclQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.1.tgz", + "integrity": "sha512-pzkgu1SSHGgRRyRZ4fbmSgmajbVt+epaLP99NDjFft69v/ypfTi6swBMiVdh2EkQ0OSnHE1lZDM7DRGkyAzUpA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.1.tgz", + "integrity": "sha512-QI5SEDY8cbiYWHx0VO4vIc3UlS6a32vXHjU8Qy/17adEmZIPuByJg13UEvo9c/UCiUkdcVWY83C+b+JrwnNyUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.1.tgz", + "integrity": "sha512-Sm41FyCeXqmYcERoYOCbGIL5hNfd8w9LQ7Y61Bev48HkcjaJqV/iiVOaiDxjVTRMS+QKrZmD8cfPt4uMVnvM+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.1.tgz", + "integrity": "sha512-2x+WhXTGl9yJYPbltW/BSEPTVz9OIWQyER4N+gJEDWkkn904eRcBzELqh/Hf7K0w/ubGbKNMv0ZC+94QK/IFEg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.1.tgz", + "integrity": "sha512-eEjmQpuRQayHPWWnywaWHkFT3ToPbP3RYy42VVd/B9aBGDA+Ol25EIWHxKQST3IiWJjikCWUF7KtbfqwZrzVwQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.1.tgz", + "integrity": "sha512-/Orga1fZYkLc/56jBICcHrKchl8Z2UKdDSr3LG9ToWO1lQ6a4Livk9Xz+9WN91zsz5QR3XQz2NNoSDEvP6qadw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.1.tgz", + "integrity": "sha512-xxBJRL+0q0Kce7orznGWLuylHDY65vuARXZRpX+hPdv+DqK2c3NlCsVA98tlWzWNEE7yPqA/1NQ5nnCrj49Y5A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.1.tgz", + "integrity": "sha512-M6AdXIXw3s+/8XpKMzdGDEXGS1S7kwUsy+rcTIUIOx5Ge4nXKCtAFHFV9YKkXvGcC5WMoTjAteLzlsQROVI0Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.2.1.tgz", + "integrity": "sha512-/TX0SoRGojHzSAHpfVBbavRVSazg5U3h3Y3VXfcc0cdugq6kxdqw8LPGFiPr+/7gE/60zRcsOY2Vi9b9eT0jww==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "2.0.0-alpha.3", + "@emnapi/runtime": "2.0.0-alpha.3", + "@napi-rs/wasm-runtime": "^1.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.1.tgz", + "integrity": "sha512-EvRrivJieyHG+AO9lleZWgq+g0+S7oV2C51yuqlcyU/R9net+sI4Pj0F+lUoP2bEr6TWX3SqFaaS0SzfLxSzkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.1.tgz", + "integrity": "sha512-Z4eCmn5QJ/5+azF9knpLWKfVd9aidn0mAe9TpJgvBLId9Ax3t0+JVxBmT25Bv7NBbVW1TZyKjQjQReouMeH5UQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tailwindcss/node": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", + "integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.24.1", + "jiti": "^2.7.0", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.3" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz", + "integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-x64": "4.3.3", + "@tailwindcss/oxide-freebsd-x64": "4.3.3", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-x64-musl": "4.3.3", + "@tailwindcss/oxide-wasm32-wasi": "4.3.3", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz", + "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz", + "integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz", + "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz", + "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz", + "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz", + "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz", + "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz", + "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz", + "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz", + "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.11.1", + "@emnapi/runtime": "^1.11.1", + "@emnapi/wasi-threads": "^1.2.2", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.2", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz", + "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz", + "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.20.tgz", + "integrity": "sha512-hwbzQuNUfcPvbegQFatVPl/MY/tcM9KLl963hQ5laJKPh81TEZ1+dNG9PirGvcaDBkp+BCshExAyKVPW91dozw==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >=4.0.0 || insiders" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.3.3.tgz", + "integrity": "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.3.3", + "@tailwindcss/oxide": "4.3.3", + "tailwindcss": "4.3.3" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concurrently": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.4.tgz", + "integrity": "sha512-TZ0CEhyzvFjgtAvHTusDMgj7wNdihCh7LLLrzdUOXIhdlnL2JBBGA9eJxR24rtqgmdjh3OA3hrN1rCHj6HM8qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.9.0", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.24.5", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", + "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/laravel-vite-plugin": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-3.1.3.tgz", + "integrity": "sha512-cI5Anw4QHY+UzvZczFaj+j8NhwT2FtyEN8aqS/hOdt6DpEFBsn6x3GENxALem3cc+TsGvd9MacneimEvShvKMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "tinyglobby": "^0.2.12", + "vite-plugin-full-reload": "^1.1.0" + }, + "bin": { + "clean-orphaned-assets": "bin/clean.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "fontaine": "^0.8.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "fontaine": { + "optional": true + } + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.25", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.25.tgz", + "integrity": "sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rolldown": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.1.tgz", + "integrity": "sha512-4FKJhg8d3OiyQOA6Q1Q0hoFFpW9/OoX+VsHzpECsdsIZoOArrAK90gl59YK/Z+gnDel45bgJZK03ozH/9bCqEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.142.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.2.1", + "@rolldown/binding-darwin-arm64": "1.2.1", + "@rolldown/binding-darwin-x64": "1.2.1", + "@rolldown/binding-freebsd-x64": "1.2.1", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.1", + "@rolldown/binding-linux-arm64-gnu": "1.2.1", + "@rolldown/binding-linux-arm64-musl": "1.2.1", + "@rolldown/binding-linux-ppc64-gnu": "1.2.1", + "@rolldown/binding-linux-s390x-gnu": "1.2.1", + "@rolldown/binding-linux-x64-gnu": "1.2.1", + "@rolldown/binding-linux-x64-musl": "1.2.1", + "@rolldown/binding-openharmony-arm64": "1.2.1", + "@rolldown/binding-wasm32-wasi": "1.2.1", + "@rolldown/binding-win32-arm64-msvc": "1.2.1", + "@rolldown/binding-win32-x64-msvc": "1.2.1" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/shell-quote": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.9.0.tgz", + "integrity": "sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tailwindcss": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz", + "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.0.tgz", + "integrity": "sha512-pn+CFpM0lwDeKwmOq1ZaBK/9sjorZcgqxki6MbY/jPEVd9vichIlmlD4HmQ5wdP5EgqQCFRaACBxMC7uEGc6lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.23", + "rolldown": "~1.2.0", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.4.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-plugin-full-reload": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.2.0.tgz", + "integrity": "sha512-kz18NW79x0IHbxRSHm0jttP4zoO9P9gXh+n6UTwlNKnviTTEpOlum6oS9SmecrTtSr+muHEn5TUuC75UovQzcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "picomatch": "^2.3.1" + } + }, + "node_modules/vite-plugin-full-reload/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vite/node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/vite/node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/vite/node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/package.json b/package.json index 49c869e..68c2fc6 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "dev": "vite" }, "devDependencies": { + "@tailwindcss/typography": "^0.5.20", "@tailwindcss/vite": "^4.0.0", "concurrently": "^9.0.1", "laravel-vite-plugin": "^3.1", diff --git a/resources/css/app.css b/resources/css/app.css index 54b247e..fcb642c 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -1,4 +1,5 @@ @import 'tailwindcss'; +@plugin '@tailwindcss/typography'; @source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php'; @source '../../storage/framework/views/*.php'; @@ -6,4 +7,19 @@ @theme { --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + --font-display: 'Fraunces', ui-serif, Georgia, serif; + + --color-ink: #0a0a0d; + --color-ink-soft: #131318; + --color-paper: #f5f3ee; + --color-paper-dim: #cac7bd; + --color-accent: #ff5a36; + --color-accent-soft: #3a1a10; +} + +@layer base { + ::selection { + background-color: var(--color-accent); + color: var(--color-ink); + } } diff --git a/resources/views/components/layouts/app.blade.php b/resources/views/components/layouts/app.blade.php new file mode 100644 index 0000000..d6d522a --- /dev/null +++ b/resources/views/components/layouts/app.blade.php @@ -0,0 +1,30 @@ +@props(['title' => null, 'description' => null]) + + + + + + {{ $title ? "{$title} · " . config('app.name') : config('app.name') }} + @if ($description) + + @endif + + @fonts + @vite(['resources/css/app.css', 'resources/js/app.js']) + + +
+
+
+
+
+ + + +
+ {{ $slot }} +
+ + + + diff --git a/resources/views/components/site/footer.blade.php b/resources/views/components/site/footer.blade.php new file mode 100644 index 0000000..ef02b94 --- /dev/null +++ b/resources/views/components/site/footer.blade.php @@ -0,0 +1,19 @@ +@php + $profile = \App\Models\Profile::query()->first(); + $socials = collect($profile?->social_links ?? []); +@endphp +
+
+

© {{ now()->year }} {{ $profile?->name ?? config('app.name') }}. All rights reserved.

+ + @if ($socials->isNotEmpty()) +
+ @foreach ($socials as $platform => $url) + + {{ $platform }} + + @endforeach +
+ @endif +
+
diff --git a/resources/views/components/site/nav.blade.php b/resources/views/components/site/nav.blade.php new file mode 100644 index 0000000..bc9f0ce --- /dev/null +++ b/resources/views/components/site/nav.blade.php @@ -0,0 +1,16 @@ +@php + $profile = \App\Models\Profile::query()->first(); +@endphp +
+ +
diff --git a/resources/views/filament/pages/manage-profile.blade.php b/resources/views/filament/pages/manage-profile.blade.php new file mode 100644 index 0000000..f211bdb --- /dev/null +++ b/resources/views/filament/pages/manage-profile.blade.php @@ -0,0 +1,9 @@ + +
+ {{ $this->form }} + + + Save + +
+
diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php new file mode 100644 index 0000000..427fe84 --- /dev/null +++ b/resources/views/home.blade.php @@ -0,0 +1,146 @@ + + {{-- Hero --}} +
+
+

Hi, I'm

+ +

+ {{ $profile?->name ?? 'Someone building things' }} +

+ + @if ($profile?->headline) +

{{ $profile->headline }}

+ @endif + + +
+ +
+
+ @if ($profile?->avatar_url) + {{ $profile->name }} + @else +
+ {{ \Illuminate\Support\Str::substr($profile?->name ?? '?', 0, 1) }} +
+ @endif +
+
+ + {{-- About --}} + @if ($profile?->bio) +
+

About

+
+ {!! $profile->bio !!} +
+ +
+ @if ($profile->location) + 📍 {{ $profile->location }} + @endif + @if ($profile->email) + ✉ {{ $profile->email }} + @endif + @if ($profile->resume_url) + ↓ Resume + @endif +
+
+ @endif + + {{-- Timeline --}} + @if ($timeline->isNotEmpty()) +
+

Journey

+ +
    + @foreach ($timeline as $item) +
  1. + + +

    + {{ $item->start_date?->format('Y') }} + — + {{ $item->is_current ? 'Present' : ($item->end_date?->format('Y') ?? '') }} + · {{ $item->type === 'work' ? 'Work' : 'Education' }} +

    + +

    {{ $item->title }}

    +

    {{ $item->subtitle }}

    + + @if ($item->description) +

    {{ $item->description }}

    + @endif +
  2. + @endforeach +
+
+ @endif + + {{-- Featured projects --}} + @if ($projects->isNotEmpty()) +
+
+

Projects

+ View all → +
+ + +
+ @endif + + {{-- Latest posts --}} + @if ($posts->isNotEmpty()) +
+
+

From the blog

+ View all → +
+ + +
+ @endif +
diff --git a/resources/views/posts/index.blade.php b/resources/views/posts/index.blade.php new file mode 100644 index 0000000..4b8276a --- /dev/null +++ b/resources/views/posts/index.blade.php @@ -0,0 +1,30 @@ + +
+

Writing

+

Blog

+
+ +
+ @if ($posts->isEmpty()) +

No posts yet — check back soon.

+ @else + + +
+ {{ $posts->links() }} +
+ @endif +
+
diff --git a/resources/views/posts/show.blade.php b/resources/views/posts/show.blade.php new file mode 100644 index 0000000..a23dcfc --- /dev/null +++ b/resources/views/posts/show.blade.php @@ -0,0 +1,26 @@ + +
+ ← All posts + +

{{ $post->published_at->format('F j, Y') }}

+

{{ $post->title }}

+ + @if (!empty($post->tags)) +
+ @foreach ($post->tags as $tag) + {{ $tag }} + @endforeach +
+ @endif + + @if ($post->cover_image_url) + {{ $post->title }} + @endif + + @if ($post->body) +
+ {!! $post->body !!} +
+ @endif +
+
diff --git a/resources/views/projects/index.blade.php b/resources/views/projects/index.blade.php new file mode 100644 index 0000000..723fe82 --- /dev/null +++ b/resources/views/projects/index.blade.php @@ -0,0 +1,42 @@ + +
+

Selected work

+

Projects

+
+ +
+ @if ($projects->isEmpty()) +

Nothing here yet — check back soon.

+ @else + + @endif +
+
diff --git a/resources/views/projects/show.blade.php b/resources/views/projects/show.blade.php new file mode 100644 index 0000000..9a0969c --- /dev/null +++ b/resources/views/projects/show.blade.php @@ -0,0 +1,42 @@ + +
+ ← All projects + +

{{ $project->title }}

+ + @if ($project->summary) +

{{ $project->summary }}

+ @endif + +
+ @if ($project->url) + + Visit live site + + @endif + @if ($project->repository_url) + + View source + + @endif +
+ + @if (!empty($project->tech_stack)) +
+ @foreach ($project->tech_stack as $tech) + {{ $tech }} + @endforeach +
+ @endif + + @if ($project->image_url) + {{ $project->title }} + @endif + + @if ($project->description) +
+ {!! $project->description !!} +
+ @endif +
+
diff --git a/resources/views/vendor/pagination/tailwind.blade.php b/resources/views/vendor/pagination/tailwind.blade.php new file mode 100644 index 0000000..a274c31 --- /dev/null +++ b/resources/views/vendor/pagination/tailwind.blade.php @@ -0,0 +1,44 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php deleted file mode 100644 index 26e294a..0000000 --- a/resources/views/welcome.blade.php +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - - {{ config('app.name', 'Laravel') }} - - @fonts - - - @if (file_exists(public_path('build/manifest.json')) || file_exists(public_path('hot'))) - @vite(['resources/css/app.css', 'resources/js/app.js']) - @else - - @endif - - -
- @if (Route::has('login')) - - @endif -
-
-
-
-

Let's get started

-

With so many options available to you,
we suggest you start with the following:

- - - -

- v{{ app()->version() }} - - View changelog - - - - -

-
-
- {{-- Laravel Logo --}} - - - - - - - - - - - {{-- 13 --}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
- - @if (Route::has('login')) - - @endif - - diff --git a/routes/web.php b/routes/web.php index 86a06c5..11ecd52 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,7 +1,14 @@ name('home'); + +Route::get('/projects', [ProjectController::class, 'index'])->name('projects.index'); +Route::get('/projects/{project}', [ProjectController::class, 'show'])->name('projects.show'); + +Route::get('/blog', [PostController::class, 'index'])->name('posts.index'); +Route::get('/blog/{post}', [PostController::class, 'show'])->name('posts.show'); diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php index 8364a84..22ef0c5 100644 --- a/tests/Feature/ExampleTest.php +++ b/tests/Feature/ExampleTest.php @@ -2,11 +2,13 @@ namespace Tests\Feature; -// use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; class ExampleTest extends TestCase { + use RefreshDatabase; + /** * A basic test example. */ diff --git a/vite.config.js b/vite.config.js index 1fd66d5..4a00fe3 100644 --- a/vite.config.js +++ b/vite.config.js @@ -12,6 +12,10 @@ export default defineConfig({ bunny('Instrument Sans', { weights: [400, 500, 600], }), + bunny('Fraunces', { + weights: [400, 500, 600, 700], + styles: ['normal', 'italic'], + }), ], }), tailwindcss(),