From e8316d6958ce2d1fe62221bf4d6f8a5ff8814c59 Mon Sep 17 00:00:00 2001 From: Naffah Abdulla Rasheed Date: Wed, 4 Nov 2026 12:41:42 +0500 Subject: [PATCH 01/10] Foundations: PHP 8.4, Laravel 12/13, Pint, CI matrix and Codecov - Require PHP ^8.4, illuminate ^12 || ^13, Testbench ^10 || ^11, PHPUnit ^11.5.3 || ^12.5.8 - Branch alias dev-next-gen => 2.x-dev - Javaabu codestyle with Pint (pint.json), applied to the codebase and checked in CI - tests.yml: PHP 8.4/8.5 x Laravel 12/13 x lowest/stable, coverage to Codecov from one leg - README badges for tests, Codecov, Packagist and licence on next-gen - javaabu/settings becomes optional: defaults come from forms.defaults, then get_setting() Closes #5 Co-Authored-By: Claude Opus 5.5 --- .github/coverage.svg | 20 ---- .github/workflows/run-tests.yml | 108 ------------------ .github/workflows/tests.yml | 77 +++++++++++++ .php_cs.dist.php | 35 ------ README.md | 13 ++- composer.json | 58 +++++++--- config/config.php | 19 ++- lang/dv/strings.php | 2 +- lang/en/strings.php | 2 +- pint.json | 20 ++++ .../views/bootstrap-5/per-page.blade.php | 2 +- .../material-admin-26/per-page.blade.php | 2 +- src/Commands/DiffViewsCommand.php | 27 +++-- src/Commands/PublishViewCommand.php | 32 ++++-- src/FormsDataBinder.php | 5 +- src/FormsServiceProvider.php | 12 +- src/Http/Middleware/OverrideFormsDefaults.php | 5 +- src/Support/HandlesBoundValues.php | 11 +- src/Support/HandlesMediaValues.php | 1 + src/Support/HandlesValidationErrors.php | 13 +-- src/Support/Icons/FontAwesomeIcons.php | 7 -- src/Support/Icons/HasIcon.php | 3 +- src/Support/Icons/Icons.php | 15 --- src/Support/Settings.php | 30 +++++ src/Views/Components/Accordion.php | 4 +- src/Views/Components/Alert.php | 7 +- src/Views/Components/BulkActions.php | 1 + src/Views/Components/Button.php | 1 + src/Views/Components/ButtonGroup.php | 1 + src/Views/Components/Checkbox.php | 2 +- src/Views/Components/Component.php | 27 +---- src/Views/Components/ConditionalLink.php | 7 +- src/Views/Components/ConditionalWrapper.php | 15 ++- src/Views/Components/Date.php | 6 +- src/Views/Components/Datetime.php | 4 +- src/Views/Components/Email.php | 4 +- src/Views/Components/Errors.php | 2 + src/Views/Components/File.php | 45 +++++--- src/Views/Components/FileUpload.php | 43 ++++--- src/Views/Components/FilterSubmit.php | 3 +- src/Views/Components/FormGroup.php | 18 ++- src/Views/Components/FormOpen.php | 2 +- src/Views/Components/Hidden.php | 2 +- src/Views/Components/Image.php | 58 +++++----- src/Views/Components/ImageUpload.php | 55 +++++---- src/Views/Components/Input.php | 24 ++-- src/Views/Components/JsErrors.php | 1 + src/Views/Components/Label.php | 4 + src/Views/Components/Latitude.php | 8 +- src/Views/Components/LinkButton.php | 1 + src/Views/Components/Longitude.php | 8 +- src/Views/Components/MapInput.php | 10 +- src/Views/Components/Modal.php | 3 +- src/Views/Components/NavTabs.php | 2 +- src/Views/Components/NoItems.php | 23 ++-- src/Views/Components/Number.php | 4 +- src/Views/Components/Password.php | 4 +- src/Views/Components/PerPage.php | 6 +- src/Views/Components/Radio.php | 2 +- src/Views/Components/Select.php | 44 ++++--- src/Views/Components/Select2.php | 32 ++++-- src/Views/Components/Table.php | 10 +- src/Views/Components/Table/Cell.php | 7 +- src/Views/Components/Table/EmptyRow.php | 1 + src/Views/Components/Table/Heading.php | 8 +- src/Views/Components/Table/Row.php | 5 + src/Views/Components/Tabs.php | 5 +- src/Views/Components/Tel.php | 2 +- src/Views/Components/Text.php | 4 +- src/Views/Components/TextEntry.php | 10 +- src/Views/Components/Textarea.php | 4 +- src/Views/Components/Time.php | 4 +- src/Views/Components/Url.php | 4 +- src/Views/Components/Wysiwyg.php | 2 +- tests/Feature/ButtonTest.php | 1 - tests/Feature/CardTest.php | 4 - tests/Feature/CheckboxTest.php | 6 +- tests/Feature/DateTest.php | 2 +- tests/Feature/FileTest.php | 30 ++--- tests/Feature/FormFilterTest.php | 2 +- tests/Feature/ImageTest.php | 4 +- tests/Feature/InputTest.php | 4 +- tests/Feature/JsErrorsTest.php | 2 - tests/Feature/LabelTest.php | 8 +- tests/Feature/MapInputTest.php | 8 +- .../OverrideFormsDefaultsMiddlewareTest.php | 3 +- tests/Feature/RadioTest.php | 4 +- tests/Feature/Select2CascadeTest.php | 5 - tests/Feature/Select2Test.php | 2 +- tests/Feature/SelectRelationTest.php | 7 +- tests/Feature/StatusTest.php | 2 +- tests/Feature/TableTest.php | 4 +- tests/Feature/TextareaTest.php | 3 +- tests/TestCase.php | 10 +- tests/TestSupport/Models/ActivityFactory.php | 4 +- tests/TestSupport/Models/Article.php | 2 +- .../Providers/TestServiceProvider.php | 5 +- ...024_04_28_124109_create_articles_table.php | 4 +- .../2024_04_28_124110_create_posts_table.php | 4 +- ...024_04_28_124111_create_comments_table.php | 4 +- ...04_28_124112_create_comment_post_table.php | 4 +- ...04_28_124113_create_commentables_table.php | 4 +- .../2024_04_28_124114_create_tags_table.php | 4 +- ...4_04_28_134113_create_activities_table.php | 4 +- ...24_04_28_144110_create_countries_table.php | 4 +- .../2024_04_28_144111_create_states_table.php | 4 +- .../2024_04_28_144112_create_cities_table.php | 4 +- ...24_04_28_144113_create_addresses_table.php | 4 +- ...4_12_24_123546_create_categories_table.php | 3 +- tests/Unit/FormsDataBinderTest.php | 4 +- tests/Unit/SettingsTest.php | 25 ++++ 111 files changed, 677 insertions(+), 589 deletions(-) delete mode 100644 .github/coverage.svg delete mode 100644 .github/workflows/run-tests.yml create mode 100644 .github/workflows/tests.yml delete mode 100644 .php_cs.dist.php create mode 100644 pint.json create mode 100644 src/Support/Settings.php create mode 100644 tests/Unit/SettingsTest.php diff --git a/.github/coverage.svg b/.github/coverage.svg deleted file mode 100644 index c9314b9..0000000 --- a/.github/coverage.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - coverage - - 77 % - - \ No newline at end of file diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml deleted file mode 100644 index dc7aaba..0000000 --- a/.github/workflows/run-tests.yml +++ /dev/null @@ -1,108 +0,0 @@ -name: tests - -on: - pull_request: - branches: - - main - push: - branches: - - main - -jobs: - tests: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: true - matrix: - os: [ ubuntu-latest ] - php: [ 8.4, 8.3, 8.2, 8.1 ] - laravel: [ 13.*, 12.*, 11.*, 10.*, 9.* ] - stability: [ prefer-lowest, prefer-stable ] - include: - - laravel: 13.* - testbench: 11.* - carbon: ^3.8.4 - medialibrary: 11.* - geospatial: ^4.7 - - laravel: 12.* - testbench: 10.* - carbon: ^3.8.4 - medialibrary: 11.* - geospatial: ^4.7 - - laravel: 11.* - testbench: 9.* - carbon: ^2.63 - medialibrary: 11.* - geospatial: ^4.7 - - laravel: 10.* - testbench: 8.* - carbon: ^2.63 - medialibrary: ^10.3.4 - geospatial: ^4.7 - - laravel: 9.* - testbench: 7.* - carbon: ^2.63 - medialibrary: ^10.3.4 - geospatial: ^2.10 - exclude: - - laravel: 13.* - php: 8.2 - - laravel: 13.* - php: 8.1 - - laravel: 12.* - php: 8.1 - - laravel: 11.* - php: 8.1 - - name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} - - services: - mysql: - image: ${{ (matrix.laravel == '9.*') && 'mysql:8.0' || '' }} - env: - MYSQL_USER: user - MYSQL_PASSWORD: secret - MYSQL_DATABASE: forms - MYSQL_ROOT_PASSWORD: secretroot - ports: - - 3306 - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install SQLite 3 - run: | - sudo apt-get update - sudo apt-get install sqlite3 -y - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: curl, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, iconv - coverage: ${{ startsWith(github.event.head_commit.message, 'coverage') && matrix.php == '8.4' && matrix.laravel == '13.*' && matrix.stability == 'prefer-stable' && 'xdebug' || 'none' }} - - - name: Install dependencies - run: | - composer config --no-plugins allow-plugins.phpstan/extension-installer true - composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench-browser-kit:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" "spatie/laravel-medialibrary:${{ matrix.medialibrary }}" "matanyadaev/laravel-eloquent-spatial:${{ matrix.geospatial }}" --no-interaction --no-update - composer update --${{ matrix.stability }} --prefer-dist --no-interaction - - - name: Execute tests - run: | - vendor/bin/phpunit ${{ startsWith(github.event.head_commit.message, 'coverage') && matrix.php == '8.4' && matrix.laravel == '13.*' && matrix.stability == 'prefer-stable' && '--coverage-clover=clover.xml' || '' }} - env: - DB_USERNAME: user - DB_PASSWORD: secret - DB_PORT: ${{ (matrix.laravel == '9.*') && job.services.mysql.ports[3306] || '' }} - - - name: Make code coverage badge - if: startsWith(github.event.head_commit.message, 'coverage') && matrix.php == '8.4' && matrix.laravel == '13.*' && matrix.stability == 'prefer-stable' - uses: timkrase/phpunit-coverage-badge@v1.2.1 - with: - coverage_badge_path: .github/coverage.svg - push_badge: true - repo_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..3f78e09 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,77 @@ +name: tests + +on: + push: + branches: + - main + - next-gen + pull_request: + +jobs: + tests: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php: ['8.4', '8.5'] + laravel: ['12.*', '13.*'] + stability: [prefer-lowest, prefer-stable] + include: + - laravel: '12.*' + testbench: '10.*' + - laravel: '13.*' + testbench: '11.*' + + name: PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - ${{ matrix.stability }} + + env: + COVERAGE: ${{ matrix.php == '8.4' && matrix.laravel == '13.*' && matrix.stability == 'prefer-stable' }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: curl, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, iconv, intl + coverage: ${{ env.COVERAGE == 'true' && 'xdebug' || 'none' }} + + - name: Install dependencies + run: | + composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --dev --no-interaction --no-update + composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress + + - name: Execute tests + run: vendor/bin/phpunit ${{ env.COVERAGE == 'true' && '--coverage-clover=clover.xml' || '' }} + + - name: Upload coverage to Codecov + if: env.COVERAGE == 'true' + uses: codecov/codecov-action@v5 + with: + files: clover.xml + fail_ci_if_error: false + token: ${{ secrets.CODECOV_TOKEN }} + + pint: + runs-on: ubuntu-latest + + name: Pint + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + coverage: none + + - name: Install dependencies + run: composer update --prefer-dist --no-interaction --no-progress + + - name: Check code style + run: vendor/bin/pint --test diff --git a/.php_cs.dist.php b/.php_cs.dist.php deleted file mode 100644 index 8648fdc..0000000 --- a/.php_cs.dist.php +++ /dev/null @@ -1,35 +0,0 @@ -in([ - __DIR__ . '/src', - __DIR__ . '/tests', - ]) - ->name('*.php') - ->notName('*.blade.php') - ->ignoreDotFiles(true) - ->ignoreVCS(true); - -return (new PhpCsFixer\Config()) - ->setRules([ - '@PSR12' => true, - 'array_syntax' => ['syntax' => 'short'], - 'ordered_imports' => ['sort_algorithm' => 'alpha'], - 'no_unused_imports' => true, - 'not_operator_with_successor_space' => true, - 'trailing_comma_in_multiline' => true, - 'phpdoc_scalar' => true, - 'unary_operator_spaces' => true, - 'binary_operator_spaces' => true, - 'blank_line_before_statement' => [ - 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], - ], - 'phpdoc_single_line_var_spacing' => true, - 'phpdoc_var_without_name' => true, - 'method_argument_space' => [ - 'on_multiline' => 'ensure_fully_multiline', - 'keep_multiple_spaces_after_comma' => true, - ], - 'single_trait_insert_per_statement' => true, - ]) - ->setFinder($finder); diff --git a/README.md b/README.md index af4c570..ed17b35 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Forms -[![Latest Version on Packagist](https://img.shields.io/packagist/v/javaabu/forms.svg?style=flat-square)](https://packagist.org/packages/javaabu/forms) -[![Test Status](../../actions/workflows/run-tests.yml/badge.svg)](../../actions/workflows/run-tests.yml) -![Code Coverage Badge](./.github/coverage.svg) -[![Total Downloads](https://img.shields.io/packagist/dt/javaabu/forms.svg?style=flat-square)](https://packagist.org/packages/javaabu/forms) +[![Tests](https://github.com/Javaabu/forms/actions/workflows/tests.yml/badge.svg?branch=next-gen)](https://github.com/Javaabu/forms/actions/workflows/tests.yml?query=branch%3Anext-gen) +[![codecov](https://codecov.io/gh/Javaabu/forms/branch/next-gen/graph/badge.svg)](https://codecov.io/gh/Javaabu/forms/tree/next-gen) +[![Latest Version on Packagist](https://img.shields.io/packagist/v/javaabu/forms.svg)](https://packagist.org/packages/javaabu/forms) +[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE.md) Laravel Blade components for form elements. Package inspired from [protonemedia/laravel-form-components](https://github.com/protonemedia/laravel-form-components) @@ -19,8 +19,9 @@ If you've found a bug regarding security please mail [info@javaabu.com](mailto:i You can run the tests with -``` bash -./vendor/bin/phpunit +```bash +composer test +composer lint ``` ## Changelog diff --git a/composer.json b/composer.json index b42ba29..cab13df 100644 --- a/composer.json +++ b/composer.json @@ -1,30 +1,39 @@ { "name": "javaabu/forms", - "description": "Laravel Blade components for form elements", + "description": "Laravel Blade form components for Bootstrap 6 and Onu, with model binding, old input and validation errors", "homepage": "https://github.com/Javaabu/forms", "license": "MIT", "authors": [ + { + "name": "Javaabu Pvt. Ltd.", + "email": "info@javaabu.com", + "homepage": "https://javaabu.com" + }, { "name": "Arushad Ahmed", "email": "arushad@javaabu.com" } ], "require": { - "php": "^8.1", - "illuminate/support": "^9.52 || ^10.0 || ^11.0.1 || ^12.0 || ^13.0", - "javaabu/settings": "^1.7", - "javaabu/helpers": "^1.70" + "php": "^8.4", + "illuminate/support": "^12.0 || ^13.0", + "illuminate/view": "^12.0 || ^13.0", + "javaabu/helpers": "^1.74" }, "require-dev": { - "orchestra/testbench-browser-kit": "^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0", - "phpunit/phpunit": "^9.5 || ^10.5 || ^11.5.3 || ^12.5.8 || ^13.0.3", - "spatie/laravel-medialibrary": "^10.3.4 || ^11.4", - "matanyadaev/laravel-eloquent-spatial": "^2.10 || ^4.7", - "composer/semver": "^3.4" + "javaabu/boost-javaabu-guidelines": "^1.4", + "laravel/pint": "^1.25", + "orchestra/testbench": "^10.0 || ^11.0", + "orchestra/testbench-browser-kit": "^10.1 || ^11.0", + "phpunit/phpunit": "^11.5.3 || ^12.5.8", + "spatie/laravel-medialibrary": "^11.13", + "matanyadaev/laravel-eloquent-spatial": "^4.7", + "javaabu/settings": "^1.8" }, "suggest": { - "spatie/laravel-medialibrary": "Required for file and image components", - "javaabu/geospatial": "Required for map components" + "spatie/laravel-medialibrary": "Required for the file and image components", + "matanyadaev/laravel-eloquent-spatial": "Required for the map components", + "javaabu/settings": "Lets the per-page and map components read defaults from settings" }, "autoload": { "psr-4": { @@ -38,7 +47,7 @@ }, "extra": { "branch-alias": { - "dev-main": "1.0-dev" + "dev-next-gen": "2.x-dev" }, "laravel": { "providers": [ @@ -47,5 +56,26 @@ } }, "minimum-stability": "dev", - "prefer-stable": true + "prefer-stable": true, + "keywords": [ + "javaabu", + "laravel", + "blade", + "forms", + "components", + "bootstrap", + "onu", + "tailwind", + "rtl", + "dhivehi" + ], + "scripts": { + "test": "vendor/bin/phpunit", + "test-coverage": "vendor/bin/phpunit --coverage-clover=clover.xml", + "lint": "vendor/bin/pint --test", + "format": "vendor/bin/pint" + }, + "config": { + "sort-packages": true + } } diff --git a/config/config.php b/config/config.php index 6755e55..d99a4f4 100644 --- a/config/config.php +++ b/config/config.php @@ -17,6 +17,23 @@ 'use_eloquent_date_casting' => false, + /* + |-------------------------------------------------------------------------- + | Defaults + |-------------------------------------------------------------------------- + | + | Defaults used when a component isn't given a value. Leave one null to + | read it from javaabu/settings (get_setting()) when that is installed, + | falling back to the value shown in the comment. + | + */ + + 'defaults' => [ + 'per_page' => null, // 20 + 'default_lat' => null, // 4.1755 (Malé) + 'default_lng' => null, // 73.5093 (Malé) + ], + /* |-------------------------------------------------------------------------- | Framework Settings @@ -65,7 +82,7 @@ 'inline-entry-class' => 'col-sm-6 col-md-8', 'search-icon' => 'zmdi-search', 'no-items-icon' => 'zmdi-file', - ] + ], ], /* diff --git a/lang/dv/strings.php b/lang/dv/strings.php index 17f2e41..2ac3b40 100644 --- a/lang/dv/strings.php +++ b/lang/dv/strings.php @@ -24,5 +24,5 @@ 'text_list_separator' => '، ', 'text_list_separator_last_glue' => ' އަދި ', 'map_search_string' => 'ހޯދާ...', - 'search_form_placeholder' => 'ހޯދާ...' + 'search_form_placeholder' => 'ހޯދާ...', ]; diff --git a/lang/en/strings.php b/lang/en/strings.php index ae0e0b5..5cac3bb 100644 --- a/lang/en/strings.php +++ b/lang/en/strings.php @@ -24,5 +24,5 @@ 'text_list_separator' => ', ', 'text_list_separator_last_glue' => ' and ', 'map_search_string' => 'Search...', - 'search_form_placeholder' => 'Search...' + 'search_form_placeholder' => 'Search...', ]; diff --git a/pint.json b/pint.json new file mode 100644 index 0000000..44df8bf --- /dev/null +++ b/pint.json @@ -0,0 +1,20 @@ +{ + "preset": "laravel", + "rules": { + "concat_space": { + "spacing": "one" + }, + "global_namespace_import": { + "import_classes": true, + "import_constants": false, + "import_functions": false + }, + "no_unused_imports": true, + "ordered_imports": { + "sort_algorithm": "alpha" + }, + "php_unit_method_casing": { + "case": "snake_case" + } + } +} diff --git a/resources/views/bootstrap-5/per-page.blade.php b/resources/views/bootstrap-5/per-page.blade.php index 6857109..226ec29 100644 --- a/resources/views/bootstrap-5/per-page.blade.php +++ b/resources/views/bootstrap-5/per-page.blade.php @@ -1,5 +1,5 @@ @php -$selected_per_page = $per_page ?? request('per_page', get_setting('per_page')); +$selected_per_page = $per_page ?? request('per_page', \Javaabu\Forms\Support\Settings::get('per_page', 20)); if (! in_array($selected_per_page, $amounts)) { $amounts[$selected_per_page] = $selected_per_page; diff --git a/resources/views/material-admin-26/per-page.blade.php b/resources/views/material-admin-26/per-page.blade.php index 646381f..7ddadbf 100644 --- a/resources/views/material-admin-26/per-page.blade.php +++ b/resources/views/material-admin-26/per-page.blade.php @@ -1,5 +1,5 @@ @php -$selected_per_page = $per_page ?? request('per_page', get_setting('per_page')); +$selected_per_page = $per_page ?? request('per_page', \Javaabu\Forms\Support\Settings::get('per_page', 20)); if (! in_array($selected_per_page, $amounts)) { $amounts[$selected_per_page] = $selected_per_page; diff --git a/src/Commands/DiffViewsCommand.php b/src/Commands/DiffViewsCommand.php index 93d4977..f925482 100644 --- a/src/Commands/DiffViewsCommand.php +++ b/src/Commands/DiffViewsCommand.php @@ -2,6 +2,7 @@ namespace Javaabu\Forms\Commands; +use Exception; use Illuminate\Console\Command; use Illuminate\Filesystem\Filesystem; use Symfony\Component\Finder\Finder; @@ -16,22 +17,24 @@ class DiffViewsCommand extends Command public function handle(): int { - $filesystem = new Filesystem(); + $filesystem = new Filesystem; - $packagePath = __DIR__ . '/../../resources/views'; + $packagePath = __DIR__ . '/../../resources/views'; $publishedPath = resource_path('views/vendor/forms'); if (! $filesystem->isDirectory($packagePath)) { $this->error('Package view directory not found.'); + return 1; } if (! $filesystem->isDirectory($publishedPath)) { $this->info('No published views found in your application.'); + return 0; } - $packageFiles = $this->getViewFiles($packagePath, $filesystem); + $packageFiles = $this->getViewFiles($packagePath, $filesystem); $publishedFiles = $this->getViewFiles($publishedPath, $filesystem); $onlyRedundant = (bool) $this->option('only-redundant'); @@ -39,7 +42,7 @@ public function handle(): int $rows = []; $counts = [ 'redundant' => 0, - 'modified' => 0, + 'modified' => 0, ]; // keep track of redundant files (published) for optional deletion @@ -53,7 +56,7 @@ public function handle(): int continue; } - $packageContent = $filesystem->get($packageFiles[$relativePath]); + $packageContent = $filesystem->get($packageFiles[$relativePath]); $publishedContent = $filesystem->get($publishedRealPath); if ($packageContent === $publishedContent) { @@ -113,8 +116,8 @@ protected function getViewFiles(string $basePath, Filesystem $filesystem): array return []; } - $files = []; - $finder = new Finder(); + $files = []; + $finder = new Finder; $finder->files()->in($basePath)->name('*.blade.php'); @@ -132,8 +135,8 @@ protected function printSummary(array $counts): void { $this->newLine(); $this->info('Summary:'); - $this->line(' Redundant (can be deleted): '.$counts['redundant']); - $this->line(' Modified (customized override): '.$counts['modified']); + $this->line(' Redundant (can be deleted): ' . $counts['redundant']); + $this->line(' Modified (customized override): ' . $counts['modified']); } /** @@ -147,11 +150,13 @@ protected function deleteRedundantViews(array $redundantFiles, Filesystem $files if ($count === 0) { $this->info('No redundant views to delete.'); + return; } - if (! $this->confirm("Delete " . $count . " redundant view file(s) from your application?", false)) { + if (! $this->confirm('Delete ' . $count . ' redundant view file(s) from your application?', false)) { $this->info('No files were deleted.'); + return; } @@ -159,7 +164,7 @@ protected function deleteRedundantViews(array $redundantFiles, Filesystem $files try { $filesystem->delete($realPath); $this->line(" DELETED {$relativePath}"); - } catch (\Exception $e) { + } catch (Exception $e) { $this->line(" FAILED {$relativePath}: {$e->getMessage()}"); } } diff --git a/src/Commands/PublishViewCommand.php b/src/Commands/PublishViewCommand.php index 178f090..1341686 100644 --- a/src/Commands/PublishViewCommand.php +++ b/src/Commands/PublishViewCommand.php @@ -2,14 +2,17 @@ namespace Javaabu\Forms\Commands; +use Exception; use Illuminate\Console\Command; use Illuminate\Filesystem\Filesystem; -use Symfony\Component\Finder\Finder; + use function Laravel\Prompts\confirm; use function Laravel\Prompts\info; use function Laravel\Prompts\search; use function Laravel\Prompts\select; +use Symfony\Component\Finder\Finder; + class PublishViewCommand extends Command { protected $signature = 'forms:publish-view @@ -22,10 +25,11 @@ public function handle() { $sourcePath = __DIR__ . '/../../resources/views'; $targetBase = resource_path('views/vendor/forms'); - $filesystem = new Filesystem(); + $filesystem = new Filesystem; - if (!$filesystem->isDirectory($sourcePath)) { + if (! $filesystem->isDirectory($sourcePath)) { $this->error('Source view directory not found.'); + return 1; } @@ -33,6 +37,7 @@ public function handle() if (empty($files)) { $this->error('No view files found to publish.'); + return 1; } @@ -45,6 +50,7 @@ public function handle() if ($selectedIndex === null) { $this->info('No file selected for publishing.'); + return 0; } @@ -59,7 +65,7 @@ public function handle() protected function getViewFiles(string $sourcePath, Filesystem $filesystem): array { $files = []; - $finder = new Finder(); + $finder = new Finder; try { $finder->files()->in($sourcePath)->name('*.blade.php'); @@ -76,12 +82,13 @@ protected function getViewFiles(string $sourcePath, Filesystem $filesystem): arr foreach ($tempFiles as $relativePath => $realPath) { $files[$count] = [ 'relative_path' => $relativePath, - 'real_path' => $realPath, + 'real_path' => $realPath, ]; $count++; } - } catch (\Exception $e) { + } catch (Exception $e) { $this->error('Error scanning view files: ' . $e->getMessage()); + return []; } @@ -124,9 +131,9 @@ protected function promptForFileSelection(array $files, string $targetBase, File ) : search( label: 'Which view would you like to publish?', - options: fn($search) => array_values(array_filter( + options: fn ($search) => array_values(array_filter( $options, - fn($choice) => str_contains(strtolower($choice), strtolower($search)) + fn ($choice) => str_contains(strtolower($choice), strtolower($search)) )), placeholder: 'Search...', scroll: 15 @@ -154,7 +161,7 @@ protected function publishFiles(array $selected, array $files, string $targetBas $overwritten = 0; foreach ($selected as $fileIndex) { - if (!isset($files[$fileIndex])) { + if (! isset($files[$fileIndex])) { continue; } @@ -167,7 +174,7 @@ protected function publishFiles(array $selected, array $files, string $targetBas $exists = $filesystem->exists($targetPath); - if ($exists && !$this->option('force')) { + if ($exists && ! $this->option('force')) { $shouldOverwrite = confirm( label: "File {$relativePath} already exists. Overwrite?", default: false, @@ -175,9 +182,10 @@ protected function publishFiles(array $selected, array $files, string $targetBas no: 'No, skip' ); - if (!$shouldOverwrite) { + if (! $shouldOverwrite) { $this->line(" SKIPPED {$relativePath}"); $skipped++; + continue; } @@ -189,7 +197,7 @@ protected function publishFiles(array $selected, array $files, string $targetBas $action = $exists ? 'UPDATED' : 'PUBLISHED'; $this->line(" {$action} {$relativePath}"); $published++; - } catch (\Exception $e) { + } catch (Exception $e) { $this->line(" FAILED {$relativePath}: " . $e->getMessage()); } } diff --git a/src/FormsDataBinder.php b/src/FormsDataBinder.php index 921ecc9..1196f28 100644 --- a/src/FormsDataBinder.php +++ b/src/FormsDataBinder.php @@ -14,8 +14,7 @@ class FormsDataBinder /** * Bind a target to the current instance * - * @param mixed $target - * @return void + * @param mixed $target */ public function bind($target): void { @@ -34,8 +33,6 @@ public function get() /** * Remove the last binding. - * - * @return void */ public function pop(): void { diff --git a/src/FormsServiceProvider.php b/src/FormsServiceProvider.php index efb67d7..fbc4f06 100644 --- a/src/FormsServiceProvider.php +++ b/src/FormsServiceProvider.php @@ -4,6 +4,8 @@ use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; +use Javaabu\Forms\Commands\DiffViewsCommand; +use Javaabu\Forms\Commands\PublishViewCommand; use Javaabu\Forms\Http\Middleware\OverrideFormsDefaults; class FormsServiceProvider extends ServiceProvider @@ -28,7 +30,7 @@ public function boot(): void ], 'forms-views'); } - $this->loadTranslationsFrom(__DIR__.'/../lang', 'forms'); + $this->loadTranslationsFrom(__DIR__ . '/../lang', 'forms'); $this->loadViewsFrom(__DIR__ . '/../resources/views', 'forms'); @@ -52,15 +54,15 @@ public function register(): void $this->mergeConfig(); // register the data binder - $this->app->singleton(FormsDataBinder::class, fn () => new FormsDataBinder()); + $this->app->singleton(FormsDataBinder::class, fn () => new FormsDataBinder); app('router')->aliasMiddleware('forms', OverrideFormsDefaults::class); // Register custom artisan commands if ($this->app->runningInConsole()) { $this->commands([ - \Javaabu\Forms\Commands\PublishViewCommand::class, - \Javaabu\Forms\Commands\DiffViewsCommand::class, + PublishViewCommand::class, + DiffViewsCommand::class, ]); } } @@ -71,7 +73,7 @@ protected function mergeConfig(): void $this->mergeConfigFrom(__DIR__ . '/../config/config.php', 'forms'); // Deep merge for nested 'framework' config - $default = require __DIR__.'/../config/config.php'; + $default = require __DIR__ . '/../config/config.php'; $default_frameworks = $default['frameworks']; foreach ($default_frameworks as $framework => $configs) { diff --git a/src/Http/Middleware/OverrideFormsDefaults.php b/src/Http/Middleware/OverrideFormsDefaults.php index 3174f54..839511b 100644 --- a/src/Http/Middleware/OverrideFormsDefaults.php +++ b/src/Http/Middleware/OverrideFormsDefaults.php @@ -11,15 +11,12 @@ class OverrideFormsDefaults /** * Handle the incoming request. * - * @param Request $request - * @param Closure $next - * @param string $framework * @return Response */ public function handle(Request $request, Closure $next, string $framework) { config([ - 'forms.framework' => $framework + 'forms.framework' => $framework, ]); return $next($request); diff --git a/src/Support/HandlesBoundValues.php b/src/Support/HandlesBoundValues.php index aa35b4b..1266f28 100644 --- a/src/Support/HandlesBoundValues.php +++ b/src/Support/HandlesBoundValues.php @@ -28,8 +28,6 @@ trait HandlesBoundValues /** * Get an instance of FormDataBinder. - * - * @return FormsDataBinder */ protected function getFormsDataBinder(): FormsDataBinder { @@ -63,8 +61,7 @@ protected function getBoundTarget() /** * Get an item from the latest bound target. * - * @param mixed $bind - * @param string $name + * @param mixed $bind * @return mixed */ protected function getBoundValue($bind, string $name) @@ -91,9 +88,6 @@ protected function getBoundValue($bind, string $name) /** * Formats a DateTimeInterface if the key is specified as a date or datetime in the model. * - * @param \Illuminate\Database\Eloquent\Model $model - * @param string $key - * @param DateTimeInterface $date * @return void */ protected function formatDateTime(Model $model, string $key, DateTimeInterface $date) @@ -134,8 +128,7 @@ protected function isCustomDateTimeCast($cast) /** * Returns an array with the attached keys. * - * @param mixed $bind - * @param string $name + * @param mixed $bind * @return mixed */ protected function getAttachedKeysFromRelation($bind, string $name) diff --git a/src/Support/HandlesMediaValues.php b/src/Support/HandlesMediaValues.php index edd87bd..f1cf5da 100644 --- a/src/Support/HandlesMediaValues.php +++ b/src/Support/HandlesMediaValues.php @@ -47,6 +47,7 @@ protected function getFileNameFromUrl(?string $url): string { if ($url) { $path = parse_url($url, PHP_URL_PATH); + return basename($path); } diff --git a/src/Support/HandlesValidationErrors.php b/src/Support/HandlesValidationErrors.php index dfe43cb..82db86d 100644 --- a/src/Support/HandlesValidationErrors.php +++ b/src/Support/HandlesValidationErrors.php @@ -14,10 +14,6 @@ trait HandlesValidationErrors /** * Returns a boolean whether the given attribute has an error, * and they should be shown. - * - * @param string $name - * @param string $bag - * @return bool */ public function hasErrorAndShow(string $name, string $bag = 'default'): bool { @@ -28,23 +24,16 @@ public function hasErrorAndShow(string $name, string $bag = 'default'): bool /** * Getter for the ErrorBag. - * - * @param string $bag - * @return \Illuminate\Contracts\Support\MessageBag */ protected function getErrorBag(string $bag = 'default'): MessageBag { - $bags = View::shared('errors', fn () => request()->session()->get('errors', new ViewErrorBag())); + $bags = View::shared('errors', fn () => request()->session()->get('errors', new ViewErrorBag)); return $bags->getBag($bag); } /** * Returns a boolean whether the given attribute has an error. - * - * @param string $name - * @param string $bag - * @return bool */ public function hasError(string $name, string $bag = 'default'): bool { diff --git a/src/Support/Icons/FontAwesomeIcons.php b/src/Support/Icons/FontAwesomeIcons.php index c41321e..c371e34 100644 --- a/src/Support/Icons/FontAwesomeIcons.php +++ b/src/Support/Icons/FontAwesomeIcons.php @@ -4,9 +4,6 @@ abstract class FontAwesomeIcons extends Icons { - /** - * @var array - */ protected static array $icons = [ 'abacus' => 'abacus', 'acorn' => 'acorn', @@ -1826,9 +1823,5 @@ abstract class FontAwesomeIcons extends Icons 'yin-yang' => 'yin-yang', ]; - /** - * @var string - */ protected static string $icon_prefix = 'fa'; - } diff --git a/src/Support/Icons/HasIcon.php b/src/Support/Icons/HasIcon.php index 56d7d58..0a815fb 100644 --- a/src/Support/Icons/HasIcon.php +++ b/src/Support/Icons/HasIcon.php @@ -1,4 +1,5 @@ type = $type; diff --git a/src/Views/Components/BulkActions.php b/src/Views/Components/BulkActions.php index 3149f1a..d059749 100644 --- a/src/Views/Components/BulkActions.php +++ b/src/Views/Components/BulkActions.php @@ -11,6 +11,7 @@ class BulkActions extends Component protected string $view = 'bulk-actions'; public string $model; + public array $actions; /** diff --git a/src/Views/Components/Button.php b/src/Views/Components/Button.php index 075b259..9a44114 100644 --- a/src/Views/Components/Button.php +++ b/src/Views/Components/Button.php @@ -7,6 +7,7 @@ class Button extends Component protected string $view = 'button'; public string $type; + public string $color; /** diff --git a/src/Views/Components/ButtonGroup.php b/src/Views/Components/ButtonGroup.php index fdc47c1..9518cc7 100644 --- a/src/Views/Components/ButtonGroup.php +++ b/src/Views/Components/ButtonGroup.php @@ -5,6 +5,7 @@ class ButtonGroup extends Component { protected string $view = 'button-group'; + public bool $inline; /** diff --git a/src/Views/Components/Checkbox.php b/src/Views/Components/Checkbox.php index 2ae579c..da4abdc 100644 --- a/src/Views/Components/Checkbox.php +++ b/src/Views/Components/Checkbox.php @@ -41,7 +41,7 @@ public function __construct( default: $default, showErrors: $showErrors, showLabel: $showLabel, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, diff --git a/src/Views/Components/Component.php b/src/Views/Components/Component.php index 225db49..5a4608e 100644 --- a/src/Views/Components/Component.php +++ b/src/Views/Components/Component.php @@ -16,15 +16,11 @@ abstract class Component extends BaseComponent /** * Framework used for this component - * - * @var string */ public string $framework; /** * The view to be used - * - * @var string */ protected string $view; @@ -73,8 +69,6 @@ public function render() /** * Generates an ID, once, for this component. - * - * @return string */ public function id(): string { @@ -91,8 +85,6 @@ public function id(): string /** * Generates an ID by the name attribute. - * - * @return string */ protected function generateIdByName(): string { @@ -101,8 +93,6 @@ protected function generateIdByName(): string /** * Generates an ID by the name attribute. - * - * @return string */ public function stringToId($text): string { @@ -111,8 +101,6 @@ public function stringToId($text): string /** * Generates a label, once, for this component. - * - * @return string */ public function label(): string { @@ -125,24 +113,19 @@ public function label(): string /** * Generates a label by the name attribute. - * - * @return string */ protected function generateLabelByName(): string { return trans(Str::of(str_replace(['[', ']'], ['_', ''], Str::before($this->name, '[]'))) - ->camel() - ->snake() - ->replace('_', ' ') - ->title() - ->toString()); + ->camel() + ->snake() + ->replace('_', ' ') + ->title() + ->toString()); } /** * Converts a bracket-notation to a dotted-notation - * - * @param string $name - * @return string */ protected static function convertBracketsToDots(string $name): string { diff --git a/src/Views/Components/ConditionalLink.php b/src/Views/Components/ConditionalLink.php index b6a71fd..b51bf1a 100644 --- a/src/Views/Components/ConditionalLink.php +++ b/src/Views/Components/ConditionalLink.php @@ -7,14 +7,19 @@ class ConditionalLink extends Component { - use HandlesBoundValues; use FormatsValues; + use HandlesBoundValues; protected string $view = 'conditional-link'; + public bool $multiline; + public bool $showLink; + public string $name; + public string $url; + public $value; /** diff --git a/src/Views/Components/ConditionalWrapper.php b/src/Views/Components/ConditionalWrapper.php index ec49ce0..4e84cb1 100644 --- a/src/Views/Components/ConditionalWrapper.php +++ b/src/Views/Components/ConditionalWrapper.php @@ -15,14 +15,13 @@ class ConditionalWrapper extends Component */ public function __construct( public string $enableElem, - public $enableValue, - public bool $hideFields = false, - public bool $disable = false, - public bool $enableCheckbox = false, - ?bool $jsonEncode = null, - string $framework = '' - ) - { + public $enableValue, + public bool $hideFields = false, + public bool $disable = false, + public bool $enableCheckbox = false, + ?bool $jsonEncode = null, + string $framework = '' + ) { parent::__construct($framework); $this->jsonEncode = is_null($jsonEncode) ? is_array($this->enableValue) : $jsonEncode; diff --git a/src/Views/Components/Date.php b/src/Views/Components/Date.php index 3444fb3..d711f74 100644 --- a/src/Views/Components/Date.php +++ b/src/Views/Components/Date.php @@ -4,13 +4,15 @@ use DateTimeInterface; use Illuminate\Database\Eloquent\Model; -use Illuminate\Support\Carbon; class Date extends Input { public string $icon; + public string $iconWrapperClass; + public string $clearIcon; + public string $clearBtnClass; /** @@ -32,7 +34,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, bool $required = false, bool $inline = false, bool $floating = false, diff --git a/src/Views/Components/Datetime.php b/src/Views/Components/Datetime.php index 70b3543..98b046c 100644 --- a/src/Views/Components/Datetime.php +++ b/src/Views/Components/Datetime.php @@ -22,7 +22,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, bool $required = false, bool $inline = false, bool $floating = false, @@ -46,7 +46,7 @@ public function __construct( showLabel: $showLabel, placeholder: $placeholder, showPlaceholder: $showPlaceholder, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, diff --git a/src/Views/Components/Email.php b/src/Views/Components/Email.php index 5f6c2a2..228f731 100644 --- a/src/Views/Components/Email.php +++ b/src/Views/Components/Email.php @@ -17,7 +17,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, bool $required = false, bool $inline = false, bool $floating = false, @@ -36,7 +36,7 @@ public function __construct( showLabel: $showLabel, placeholder: $placeholder, showPlaceholder: $showPlaceholder, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, diff --git a/src/Views/Components/Errors.php b/src/Views/Components/Errors.php index a4e64f3..01806a1 100644 --- a/src/Views/Components/Errors.php +++ b/src/Views/Components/Errors.php @@ -7,7 +7,9 @@ class Errors extends Component { protected string $view = 'errors'; + public string $name; + public string $bag; /** diff --git a/src/Views/Components/File.php b/src/Views/Components/File.php index 8c80288..6d64ce3 100644 --- a/src/Views/Components/File.php +++ b/src/Views/Components/File.php @@ -13,16 +13,27 @@ class File extends Input use HandlesMediaValues; public array $fileTypes; + public array $mimetypes; + public string $collection; + public string $conversion; + public string $fileInputClass; + public array $extensions; + public int $maxSize; + public bool $showHint; + public string $fileName = ''; + public string $clearIcon; + public string $downloadIcon; + public string $uploadIcon; /** @@ -31,27 +42,27 @@ class File extends Input * @return void */ public function __construct( - string $name, - string $label = '', - string|array $type = 'document', + string $name, + string $label = '', + string|array $type = 'document', null|string|array $mimetypes = null, null|string|array $extensions = null, - ?int $maxSize = null, - string $collection = '', - string $conversion = '', - string $fileInputClass = '', - string $clearIcon = '', - string $downloadIcon = '', - string $uploadIcon = '', - $model = null, - $default = null, - bool $showHint = true, + ?int $maxSize = null, + string $collection = '', + string $conversion = '', + string $fileInputClass = '', + string $clearIcon = '', + string $downloadIcon = '', + string $uploadIcon = '', + $model = null, + $default = null, + bool $showHint = true, bool $showErrors = true, bool $showLabel = true, bool $required = false, public bool $disabled = false, public bool $ignoreAccessor = false, - public bool $upload = false, + public bool $upload = false, bool $inline = false, string $inlineLabelClass = '', string $inlineInputClass = '', @@ -75,7 +86,7 @@ public function __construct( default: $default, showErrors: $showErrors, showLabel: $showLabel, - required:$required, + required: $required, inline: $inline, floating: false, inlineLabelClass: $inlineLabelClass, @@ -93,8 +104,8 @@ public function getHint(): string { return trans('forms::strings.file_hint', [ 'types' => collect($this->extensions) - ->map(fn($ext) => '.' . $ext) - ->join(trans('forms::strings.text_list_separator'), trans('forms::strings.text_list_separator_last_glue')), + ->map(fn ($ext) => '.' . $ext) + ->join(trans('forms::strings.text_list_separator'), trans('forms::strings.text_list_separator_last_glue')), 'size' => format_file_size($this->maxSize), ]); diff --git a/src/Views/Components/FileUpload.php b/src/Views/Components/FileUpload.php index 75fd381..df7df90 100644 --- a/src/Views/Components/FileUpload.php +++ b/src/Views/Components/FileUpload.php @@ -10,33 +10,32 @@ class FileUpload extends File * @return void */ public function __construct( - string $name, - string $label = '', - string|array $type = 'document', + string $name, + string $label = '', + string|array $type = 'document', null|string|array $mimetypes = null, null|string|array $extensions = null, - ?int $maxSize = null, - string $collection = '', - string $conversion = '', - string $fileInputClass = '', - string $clearIcon = '', - string $downloadIcon = '', - string $uploadIcon = '', - $model = null, - $default = null, - bool $showHint = true, - bool $showErrors = true, - bool $showLabel = true, - bool $required = false, - bool $disabled = false, - bool $ignoreAccessor = false, - bool $inline = false, + ?int $maxSize = null, + string $collection = '', + string $conversion = '', + string $fileInputClass = '', + string $clearIcon = '', + string $downloadIcon = '', + string $uploadIcon = '', + $model = null, + $default = null, + bool $showHint = true, + bool $showErrors = true, + bool $showLabel = true, + bool $required = false, + bool $disabled = false, + bool $ignoreAccessor = false, + bool $inline = false, string $inlineLabelClass = '', string $inlineInputClass = '', bool $showJsErrors = false, - string $framework = '' - ) - { + string $framework = '' + ) { parent::__construct( name: $name, label: $label, diff --git a/src/Views/Components/FilterSubmit.php b/src/Views/Components/FilterSubmit.php index 15cdfab..8200313 100644 --- a/src/Views/Components/FilterSubmit.php +++ b/src/Views/Components/FilterSubmit.php @@ -5,7 +5,9 @@ class FilterSubmit extends Component { protected string $view = 'filter-submit'; + public string $cancelUrl; + public bool|array $export; /** @@ -23,5 +25,4 @@ public function __construct( $this->export = is_string($export) ? [$export] : $export; $this->cancelUrl = $cancelUrl; } - } diff --git a/src/Views/Components/FormGroup.php b/src/Views/Components/FormGroup.php index 1869d77..9936b57 100644 --- a/src/Views/Components/FormGroup.php +++ b/src/Views/Components/FormGroup.php @@ -5,13 +5,21 @@ class FormGroup extends Component { protected string $view = 'form-group'; + public string $name; + public string $label; + public bool $required; + public bool $inline; + public bool $floating; + public bool $wrap; + public bool $showLabel; + public string $inlineInputClass; /** @@ -22,11 +30,11 @@ class FormGroup extends Component public function __construct( string $name = '', string $label = '', - bool $required = false, - bool $inline = false, - bool $floating = false, - bool $wrap = true, - bool $showLabel = true, + bool $required = false, + bool $inline = false, + bool $floating = false, + bool $wrap = true, + bool $showLabel = true, public string $inlineLabelClass = '', string $inlineInputClass = '', public bool $blankLabel = false, diff --git a/src/Views/Components/FormOpen.php b/src/Views/Components/FormOpen.php index 271b915..a3b17b2 100644 --- a/src/Views/Components/FormOpen.php +++ b/src/Views/Components/FormOpen.php @@ -19,7 +19,7 @@ class FormOpen extends Form public function __construct( string $method = 'POST', $model = null, - bool $files = false, + bool $files = false, string $framework = '' ) { parent::__construct( diff --git a/src/Views/Components/Hidden.php b/src/Views/Components/Hidden.php index fd94bcf..05a42aa 100644 --- a/src/Views/Components/Hidden.php +++ b/src/Views/Components/Hidden.php @@ -30,7 +30,7 @@ public function __construct( default: $default, showErrors: $showErrors, showLabel: $showLabel, - required:$required, + required: $required, inline: $inline, floating: $floating, showJsErrors: $showJsErrors, diff --git a/src/Views/Components/Image.php b/src/Views/Components/Image.php index d5ad83e..022c56c 100644 --- a/src/Views/Components/Image.php +++ b/src/Views/Components/Image.php @@ -7,6 +7,7 @@ class Image extends File protected string $view = 'image'; public string $icon; + public float $aspectRatio; /** @@ -15,40 +16,39 @@ class Image extends File * @return void */ public function __construct( - string $name, - string $label = '', - string|array $type = 'image', + string $name, + string $label = '', + string|array $type = 'image', null|string|array $mimetypes = null, null|string|array $extensions = null, - ?int $maxSize = null, - string $collection = '', - string $conversion = '', - string $fileInputClass = '', - string $icon = '', - string $uploadIcon = '', - public int $width = 400, - public int $height = 400, - public bool $cover = false, - public bool $fullwidth = false, - public bool $maintainAspectRatio = true, - public bool $circle = false, - bool $upload = false, - ?float $aspectRatio = null, - $model = null, - $default = null, - bool $showHint = true, - bool $showErrors = true, - bool $showLabel = true, - bool $required = false, - bool $disabled = false, - bool $ignoreAccessor = false, - bool $inline = false, + ?int $maxSize = null, + string $collection = '', + string $conversion = '', + string $fileInputClass = '', + string $icon = '', + string $uploadIcon = '', + public int $width = 400, + public int $height = 400, + public bool $cover = false, + public bool $fullwidth = false, + public bool $maintainAspectRatio = true, + public bool $circle = false, + bool $upload = false, + ?float $aspectRatio = null, + $model = null, + $default = null, + bool $showHint = true, + bool $showErrors = true, + bool $showLabel = true, + bool $required = false, + bool $disabled = false, + bool $ignoreAccessor = false, + bool $inline = false, string $inlineLabelClass = '', string $inlineInputClass = '', bool $showJsErrors = false, - string $framework = '' - ) - { + string $framework = '' + ) { parent::__construct( $name, label: $label, diff --git a/src/Views/Components/ImageUpload.php b/src/Views/Components/ImageUpload.php index 1689cc3..3e59126 100644 --- a/src/Views/Components/ImageUpload.php +++ b/src/Views/Components/ImageUpload.php @@ -10,39 +10,38 @@ class ImageUpload extends Image * @return void */ public function __construct( - string $name, - string $label = '', - string|array $type = 'image', + string $name, + string $label = '', + string|array $type = 'image', null|string|array $mimetypes = null, null|string|array $extensions = null, - ?int $maxSize = null, - string $collection = '', - string $conversion = '', - string $fileInputClass = '', - string $icon = '', - string $uploadIcon = '', - int $width = 400, - int $height = 400, - bool $cover = false, - bool $fullwidth = false, - bool $maintainAspectRatio = true, - bool $circle = false, - ?float $aspectRatio = null, - $model = null, - $default = null, - bool $showHint = true, - bool $showErrors = true, - bool $showLabel = true, - bool $required = false, - bool $disabled = false, - bool $ignoreAccessor = false, - bool $inline = false, + ?int $maxSize = null, + string $collection = '', + string $conversion = '', + string $fileInputClass = '', + string $icon = '', + string $uploadIcon = '', + int $width = 400, + int $height = 400, + bool $cover = false, + bool $fullwidth = false, + bool $maintainAspectRatio = true, + bool $circle = false, + ?float $aspectRatio = null, + $model = null, + $default = null, + bool $showHint = true, + bool $showErrors = true, + bool $showLabel = true, + bool $required = false, + bool $disabled = false, + bool $ignoreAccessor = false, + bool $inline = false, string $inlineLabelClass = '', string $inlineInputClass = '', bool $showJsErrors = false, - string $framework = '' - ) - { + string $framework = '' + ) { parent::__construct( name: $name, label: $label, diff --git a/src/Views/Components/Input.php b/src/Views/Components/Input.php index d9da78a..6da3b58 100644 --- a/src/Views/Components/Input.php +++ b/src/Views/Components/Input.php @@ -7,19 +7,29 @@ class Input extends Component { - use HandlesValidationErrors; use HandlesDefaultAndOldValue; + use HandlesValidationErrors; protected string $view = 'input'; + public string $name; + public string $label; + public string $type; + public string $placeholder; + public bool $showPlaceholder; + public bool $required; + public bool $inline; + public bool $floating; + public bool $showLabel; + public $value; /** @@ -33,13 +43,13 @@ public function __construct( string $type = 'text', $model = null, $default = null, - bool $showErrors = true, - bool $showLabel = true, + bool $showErrors = true, + bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, - bool $required = false, - bool $inline = false, - bool $floating = false, + bool $showPlaceholder = false, + bool $required = false, + bool $inline = false, + bool $floating = false, public string $inlineLabelClass = '', public string $inlineInputClass = '', public bool $showJsErrors = false, diff --git a/src/Views/Components/JsErrors.php b/src/Views/Components/JsErrors.php index a25d241..967d9c7 100644 --- a/src/Views/Components/JsErrors.php +++ b/src/Views/Components/JsErrors.php @@ -7,6 +7,7 @@ class JsErrors extends Component { protected string $view = 'js-errors'; + public string $name; /** diff --git a/src/Views/Components/Label.php b/src/Views/Components/Label.php index 8b80b5f..ca48679 100644 --- a/src/Views/Components/Label.php +++ b/src/Views/Components/Label.php @@ -7,9 +7,13 @@ class Label extends Component protected string $view = 'label'; public string $label; + public bool $required; + public bool $inline; + public bool $floating; + public string $inlineLabelClass; /** diff --git a/src/Views/Components/Latitude.php b/src/Views/Components/Latitude.php index 0f67957..4c15055 100644 --- a/src/Views/Components/Latitude.php +++ b/src/Views/Components/Latitude.php @@ -2,8 +2,6 @@ namespace Javaabu\Forms\Views\Components; -use Illuminate\View\ComponentAttributeBag; - class Latitude extends Input { /** @@ -19,7 +17,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, bool $required = false, bool $inline = false, bool $floating = false, @@ -38,7 +36,7 @@ public function __construct( showLabel: $showLabel, placeholder: $placeholder, showPlaceholder: $showPlaceholder, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, @@ -53,7 +51,7 @@ public function getDefaultAttributes(): array return [ 'step' => '0.000001', 'min' => -90, - 'max' => 90 + 'max' => 90, ]; } } diff --git a/src/Views/Components/LinkButton.php b/src/Views/Components/LinkButton.php index 1ccb361..151377e 100644 --- a/src/Views/Components/LinkButton.php +++ b/src/Views/Components/LinkButton.php @@ -7,6 +7,7 @@ class LinkButton extends Component protected string $view = 'link-button'; public string $url; + public string $color; /** diff --git a/src/Views/Components/Longitude.php b/src/Views/Components/Longitude.php index ee8c02f..60adc27 100644 --- a/src/Views/Components/Longitude.php +++ b/src/Views/Components/Longitude.php @@ -2,8 +2,6 @@ namespace Javaabu\Forms\Views\Components; -use Illuminate\View\ComponentAttributeBag; - class Longitude extends Input { /** @@ -19,7 +17,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, bool $required = false, bool $inline = false, bool $floating = false, @@ -38,7 +36,7 @@ public function __construct( showLabel: $showLabel, placeholder: $placeholder, showPlaceholder: $showPlaceholder, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, @@ -53,7 +51,7 @@ public function getDefaultAttributes(): array return [ 'step' => '0.000001', 'min' => -180, - 'max' => 180 + 'max' => 180, ]; } } diff --git a/src/Views/Components/MapInput.php b/src/Views/Components/MapInput.php index 6bf6329..755837b 100644 --- a/src/Views/Components/MapInput.php +++ b/src/Views/Components/MapInput.php @@ -3,6 +3,7 @@ namespace Javaabu\Forms\Views\Components; use Illuminate\Support\Str; +use Javaabu\Forms\Support\Settings; use MatanYadaev\EloquentSpatial\Objects\Point; use MatanYadaev\EloquentSpatial\Objects\Polygon; @@ -11,6 +12,7 @@ class MapInput extends Input protected string $view = 'map-input'; public float $defaultMapCenterLat; + public float $defaultMapCenterLng; /** @@ -30,7 +32,7 @@ public function __construct( public bool $enablePolygon = false, public bool $hideInputs = false, public int $radiusPrecision = 0, - public int $maxRadius = 6371000, + public int $maxRadius = 6371000, public string $radiusUnit = 'm', public ?float $lat = null, public ?float $lng = null, @@ -60,7 +62,7 @@ public function __construct( model: $model, showErrors: $showErrors, showLabel: $showLabel, - required:$required, + required: $required, inline: $inline, floating: false, inlineLabelClass: $inlineLabelClass, @@ -69,8 +71,8 @@ public function __construct( framework: $framework ); - $this->defaultMapCenterLat = is_null($defaultMapCenterLat) ? (float) get_setting('default_lat') : $defaultMapCenterLat; - $this->defaultMapCenterLng = is_null($defaultMapCenterLng) ? (float) get_setting('default_lng') : $defaultMapCenterLng; + $this->defaultMapCenterLat = is_null($defaultMapCenterLat) ? (float) Settings::get('default_lat', 4.1755) : $defaultMapCenterLat; + $this->defaultMapCenterLng = is_null($defaultMapCenterLng) ? (float) Settings::get('default_lng', 73.5093) : $defaultMapCenterLng; if (is_null($this->lat)) { $this->setLat($this->latName, $model, $this->defaultLat); diff --git a/src/Views/Components/Modal.php b/src/Views/Components/Modal.php index ff5f2fa..2091fc1 100644 --- a/src/Views/Components/Modal.php +++ b/src/Views/Components/Modal.php @@ -7,6 +7,7 @@ class Modal extends Component protected string $view = 'modal'; public string $title; + public ?string $modalSizeClass = null; /** @@ -17,7 +18,7 @@ class Modal extends Component public function __construct( string $id = '', string $title = '', - string $modalSizeClass = null, + ?string $modalSizeClass = null, string $framework = '' ) { parent::__construct($framework); diff --git a/src/Views/Components/NavTabs.php b/src/Views/Components/NavTabs.php index a0b83bf..19a05d4 100644 --- a/src/Views/Components/NavTabs.php +++ b/src/Views/Components/NavTabs.php @@ -17,7 +17,7 @@ class NavTabs extends Component */ public function __construct( array|Collection $tabs = [], - string $framework = '' + string $framework = '' ) { parent::__construct($framework); diff --git a/src/Views/Components/NoItems.php b/src/Views/Components/NoItems.php index 25dae45..28d4333 100644 --- a/src/Views/Components/NoItems.php +++ b/src/Views/Components/NoItems.php @@ -7,11 +7,17 @@ class NoItems extends Component protected string $view = 'no-items'; public null|string|object $model; + public string $createAction; + public ?string $modelType = null; + public string $icon; + public bool $showCreate; + public string $title; + public string $message; /** @@ -20,16 +26,15 @@ class NoItems extends Component * @return void */ public function __construct( - string $createAction = '#', + string $createAction = '#', null|string|object $model = null, - string $icon = '', - ?string $modelType = null, - ?bool $showCreate = null, - ?string $title = null, - ?string $message = null, - string $framework = '', - ) - { + string $icon = '', + ?string $modelType = null, + ?bool $showCreate = null, + ?string $title = null, + ?string $message = null, + string $framework = '', + ) { parent::__construct($framework); $this->model = $model; diff --git a/src/Views/Components/Number.php b/src/Views/Components/Number.php index cef7298..b1bb9c0 100644 --- a/src/Views/Components/Number.php +++ b/src/Views/Components/Number.php @@ -17,7 +17,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, bool $required = false, bool $inline = false, bool $floating = false, @@ -36,7 +36,7 @@ public function __construct( showLabel: $showLabel, placeholder: $placeholder, showPlaceholder: $showPlaceholder, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, diff --git a/src/Views/Components/Password.php b/src/Views/Components/Password.php index c702bd7..65cb54b 100644 --- a/src/Views/Components/Password.php +++ b/src/Views/Components/Password.php @@ -17,7 +17,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, bool $required = false, bool $inline = false, bool $floating = false, @@ -36,7 +36,7 @@ public function __construct( showLabel: $showLabel, placeholder: $placeholder, showPlaceholder: $showPlaceholder, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, diff --git a/src/Views/Components/PerPage.php b/src/Views/Components/PerPage.php index 4fb6b0c..585b51c 100644 --- a/src/Views/Components/PerPage.php +++ b/src/Views/Components/PerPage.php @@ -14,12 +14,10 @@ class PerPage extends Component * @return void */ public function __construct( - array $amounts = [10 => 10, 20 => 20, 50 => 50, 100 => 100, 500 => 500], + array $amounts = [10 => 10, 20 => 20, 50 => 50, 100 => 100, 500 => 500], string $framework = '', - ) - { + ) { $this->amounts = $amounts; parent::__construct($framework); } - } diff --git a/src/Views/Components/Radio.php b/src/Views/Components/Radio.php index dd749aa..d4f19a7 100644 --- a/src/Views/Components/Radio.php +++ b/src/Views/Components/Radio.php @@ -41,7 +41,7 @@ public function __construct( default: $default, showErrors: $showErrors, showLabel: $showLabel, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, diff --git a/src/Views/Components/Select.php b/src/Views/Components/Select.php index 8cfe724..a9d73a1 100644 --- a/src/Views/Components/Select.php +++ b/src/Views/Components/Select.php @@ -14,27 +14,43 @@ class Select extends Component { - use HandlesValidationErrors; use HandlesDefaultAndOldValue; + use HandlesValidationErrors; protected string $view = 'select'; public string $name; + public string $label; + public $options; + public $selectedKey; + public bool $multiple; + public bool $required; + public bool $inline; + public bool $floating; + public string $placeholder; + public bool $showPlaceholder; + public bool $isSelect2; + public string $nameField; + public string $idField; + public bool $showLabel; + public string $syncFieldName; + public bool $isAjax; + public bool $tags; /** @@ -49,16 +65,16 @@ public function __construct( $options = [], $model = null, $default = null, - bool $multiple = false, - bool $relation = false, - bool $showErrors = true, - bool $showLabel = true, - bool $showPlaceholder = false, - bool $required = false, - bool $inline = false, - bool $floating = false, - bool $isSelect2 = false, - bool $isAjax = false, + bool $multiple = false, + bool $relation = false, + bool $showErrors = true, + bool $showLabel = true, + bool $showPlaceholder = false, + bool $required = false, + bool $inline = false, + bool $floating = false, + bool $isSelect2 = false, + bool $isAjax = false, public bool $disabled = false, public bool $excludeSyncField = false, string $syncFieldName = '', @@ -155,8 +171,8 @@ public function getOptionsFromQueryBuilder(BuilderContract $query): array if ($is_accessor || $this->isJavaabuTranslatableModel($model)) { return $query->get() - ->pluck($name_field, $id_field) - ->all(); + ->pluck($name_field, $id_field) + ->all(); } return $query->pluck($name_field, $id_field)->all(); @@ -179,6 +195,6 @@ public function nothingSelected(): bool public function shouldShowSyncField(): bool { - return (!$this->excludeSyncField) && $this->multiple && (!$this->disabled); + return (! $this->excludeSyncField) && $this->multiple && (! $this->disabled); } } diff --git a/src/Views/Components/Select2.php b/src/Views/Components/Select2.php index 1cd6656..e1be8b6 100644 --- a/src/Views/Components/Select2.php +++ b/src/Views/Components/Select2.php @@ -5,15 +5,25 @@ class Select2 extends Select { public bool $allowClear; + public bool $isFirst; + public bool $hideSearch; + public string $child; + public string $ajaxChild; + public string $ajaxUrl; + public string $selectedUrl; + public string $filterField; + public string $fallback; + public string $parentModal; + /** * Create a new component instance. * @@ -26,17 +36,17 @@ public function __construct( $options = [], $model = null, $default = null, - bool $multiple = false, - bool $relation = false, - bool $showErrors = true, - bool $showLabel = true, - bool $showPlaceholder = false, - bool $required = false, - bool $isAjax = false, - bool $isFirst = false, - bool $tags = false, - bool $hideSearch = false, - bool $allowClear = true, + bool $multiple = false, + bool $relation = false, + bool $showErrors = true, + bool $showLabel = true, + bool $showPlaceholder = false, + bool $required = false, + bool $isAjax = false, + bool $isFirst = false, + bool $tags = false, + bool $hideSearch = false, + bool $allowClear = true, public bool $isIconSelect = false, string $child = '', string $ajaxChild = '', diff --git a/src/Views/Components/Table.php b/src/Views/Components/Table.php index 2207f5b..fef0c2f 100644 --- a/src/Views/Components/Table.php +++ b/src/Views/Components/Table.php @@ -7,13 +7,17 @@ class Table extends Component protected string $view = 'table'; public bool $striped; + public bool $no_bulk; public string $model; + public string $table_class; + public ?string $filter_id; public bool $no_pagination; + public bool $noCheckbox; /** @@ -23,11 +27,11 @@ class Table extends Component */ public function __construct( string $framework = '', - bool $striped = false, - bool $noBulk = false, + bool $striped = false, + bool $noBulk = false, string $model = '', string $tableClass = '', - string $filterId = null, + ?string $filterId = null, bool $noPagination = false, bool $noCheckbox = false, ) { diff --git a/src/Views/Components/Table/Cell.php b/src/Views/Components/Table/Cell.php index bf0fc69..49ab851 100644 --- a/src/Views/Components/Table/Cell.php +++ b/src/Views/Components/Table/Cell.php @@ -8,14 +8,19 @@ class Cell extends Component { - use HandlesBoundValues; use FormatsValues; + use HandlesBoundValues; protected string $view = 'table.cell'; + public bool $multiline; + public bool $showLabel; + public string $label; + public string $name; + public $value; /** diff --git a/src/Views/Components/Table/EmptyRow.php b/src/Views/Components/Table/EmptyRow.php index c877cee..baa0c82 100644 --- a/src/Views/Components/Table/EmptyRow.php +++ b/src/Views/Components/Table/EmptyRow.php @@ -9,6 +9,7 @@ class EmptyRow extends Component protected string $view = 'table.empty-row'; public int $columns; + public bool $noCheckbox; /** diff --git a/src/Views/Components/Table/Heading.php b/src/Views/Components/Table/Heading.php index a5dd003..de11f9d 100644 --- a/src/Views/Components/Table/Heading.php +++ b/src/Views/Components/Table/Heading.php @@ -10,8 +10,11 @@ class Heading extends Component protected string $view = 'table.heading'; public int $colspan; + public string $sortable; + public string $label; + public string $name; /** @@ -21,7 +24,7 @@ class Heading extends Component */ public function __construct( string $label = '', - int $colspan = 1, + int $colspan = 1, string $sortable = '', string $name = '', string $framework = '', @@ -35,9 +38,6 @@ public function __construct( /** * Adds sorting class - * - * @param string $classes - * @return string */ public function addSortClass(string $classes = ''): string { diff --git a/src/Views/Components/Table/Row.php b/src/Views/Components/Table/Row.php index ff1affb..5cdf300 100644 --- a/src/Views/Components/Table/Row.php +++ b/src/Views/Components/Table/Row.php @@ -10,10 +10,15 @@ class Row extends Component { use HandlesBoundValues; + protected string $view = 'table.row'; + public string $rowId; + public string $name; + public string $modelId; + public bool $noCheckbox; /** diff --git a/src/Views/Components/Tabs.php b/src/Views/Components/Tabs.php index 33e648a..b3e9175 100644 --- a/src/Views/Components/Tabs.php +++ b/src/Views/Components/Tabs.php @@ -10,6 +10,7 @@ class Tabs extends Component protected string $view = 'tabs'; public Collection $tabs; + public string $active; /** @@ -19,8 +20,8 @@ class Tabs extends Component */ public function __construct( array|Collection $tabs = [], - string $active = '', - string $framework = '' + string $active = '', + string $framework = '' ) { parent::__construct($framework); diff --git a/src/Views/Components/Tel.php b/src/Views/Components/Tel.php index 9fb9e7c..2599185 100644 --- a/src/Views/Components/Tel.php +++ b/src/Views/Components/Tel.php @@ -32,7 +32,7 @@ public function __construct( default: $default, showErrors: $showErrors, showLabel: $showLabel, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, diff --git a/src/Views/Components/Text.php b/src/Views/Components/Text.php index c47ab6e..af232e0 100644 --- a/src/Views/Components/Text.php +++ b/src/Views/Components/Text.php @@ -17,7 +17,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, bool $required = false, bool $inline = false, bool $floating = false, @@ -36,7 +36,7 @@ public function __construct( showLabel: $showLabel, placeholder: $placeholder, showPlaceholder: $showPlaceholder, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, diff --git a/src/Views/Components/TextEntry.php b/src/Views/Components/TextEntry.php index 427b1ed..35eaee6 100644 --- a/src/Views/Components/TextEntry.php +++ b/src/Views/Components/TextEntry.php @@ -7,17 +7,25 @@ class TextEntry extends Component { - use HandlesBoundValues; use FormatsValues; + use HandlesBoundValues; protected string $view = 'text-entry'; + public bool $inline; + public bool $multiline; + public string $label; + public string $name; + public bool $showLabel; + public $value; + public string $inlineEntryLabelClass; + public string $inlineEntryClass; /** diff --git a/src/Views/Components/Textarea.php b/src/Views/Components/Textarea.php index edd8dfe..2d7962e 100644 --- a/src/Views/Components/Textarea.php +++ b/src/Views/Components/Textarea.php @@ -23,7 +23,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, public bool $wysiwyg = false, bool $required = false, bool $inline = false, @@ -43,7 +43,7 @@ public function __construct( showLabel: $showLabel, placeholder: $placeholder, showPlaceholder: $showPlaceholder, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, diff --git a/src/Views/Components/Time.php b/src/Views/Components/Time.php index 478b2fb..4319950 100644 --- a/src/Views/Components/Time.php +++ b/src/Views/Components/Time.php @@ -21,7 +21,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, bool $required = false, bool $inline = false, bool $floating = false, @@ -44,7 +44,7 @@ public function __construct( showLabel: $showLabel, placeholder: $placeholder, showPlaceholder: $showPlaceholder, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, diff --git a/src/Views/Components/Url.php b/src/Views/Components/Url.php index b9956dc..9ffa5ab 100644 --- a/src/Views/Components/Url.php +++ b/src/Views/Components/Url.php @@ -17,7 +17,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, bool $required = false, bool $inline = false, bool $floating = false, @@ -36,7 +36,7 @@ public function __construct( showLabel: $showLabel, placeholder: $placeholder, showPlaceholder: $showPlaceholder, - required:$required, + required: $required, inline: $inline, floating: $floating, inlineLabelClass: $inlineLabelClass, diff --git a/src/Views/Components/Wysiwyg.php b/src/Views/Components/Wysiwyg.php index 7d49f12..8f353e2 100644 --- a/src/Views/Components/Wysiwyg.php +++ b/src/Views/Components/Wysiwyg.php @@ -19,7 +19,7 @@ public function __construct( bool $showErrors = true, bool $showLabel = true, string $placeholder = '', - bool $showPlaceholder = false, + bool $showPlaceholder = false, bool $required = false, bool $inline = false, bool $floating = false, diff --git a/tests/Feature/ButtonTest.php b/tests/Feature/ButtonTest.php index a910382..83ea887 100644 --- a/tests/Feature/ButtonTest.php +++ b/tests/Feature/ButtonTest.php @@ -89,5 +89,4 @@ public function test_it_can_generate_material_admin_26_link_button() ->seeElement('a[href="/test"].btn.btn-danger') ->seeInElement('a[href="/test"].btn.btn-danger', 'Button'); } - } diff --git a/tests/Feature/CardTest.php b/tests/Feature/CardTest.php index 6c6fca9..c84dce8 100644 --- a/tests/Feature/CardTest.php +++ b/tests/Feature/CardTest.php @@ -229,8 +229,6 @@ public function test_it_can_generate_material_admin_26_card() }); } - - public function test_it_can_generate_material_admin_26_card_with_subtitle() { $this->setFrameworkMaterialAdmin26(); @@ -263,6 +261,4 @@ public function test_it_can_generate_material_admin_26_card_with_image_top() }); }); } - - } diff --git a/tests/Feature/CheckboxTest.php b/tests/Feature/CheckboxTest.php index a41e855..8f367f5 100644 --- a/tests/Feature/CheckboxTest.php +++ b/tests/Feature/CheckboxTest.php @@ -8,7 +8,7 @@ class CheckboxTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -158,7 +158,6 @@ public function test_it_can_generate_material_admin_26_form_checkbox_that_is_req }); } - public function test_it_can_generate_material_admin_26_inline_form_checkbox_that_is_required() { $this->setFrameworkMaterialAdmin26(); @@ -175,7 +174,7 @@ public function test_it_can_generate_material_admin_26_inline_form_checkbox_that $this->dontSeeElement('span.required') ->dontSeeInElement('span.required', '*'); }); - ; + }); } @@ -194,5 +193,4 @@ public function test_it_can_generate_material_admin_26_form_checkbox_with_helper ->seeElement('small.form-text.text-muted') ->seeInElement('small.form-text.text-muted', 'This is some help text.'); } - } diff --git a/tests/Feature/DateTest.php b/tests/Feature/DateTest.php index d510e6d..51ce6ba 100644 --- a/tests/Feature/DateTest.php +++ b/tests/Feature/DateTest.php @@ -7,7 +7,7 @@ class DateTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/tests/Feature/FileTest.php b/tests/Feature/FileTest.php index d827118..4c0fd73 100644 --- a/tests/Feature/FileTest.php +++ b/tests/Feature/FileTest.php @@ -14,7 +14,7 @@ class FileTest extends TestCase { use RefreshDatabase; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -86,8 +86,8 @@ public function test_it_can_render_file_input_with_value() $this->seeElement('span.fileinput-filename') ->within('span.fileinput-filename', function () { $this->seeElement('a[href="https://example.com/uploads/Important-document.pdf?download=true"]') - ->seeInElement('a', 'Important-document.pdf') - ->dontSeeInElement('a', '?download=true') + ->seeInElement('a', 'Important-document.pdf') + ->dontSeeInElement('a', '?download=true') ->dontSeeInElement('a', 'https://example.com/uploads/'); }); }); @@ -281,18 +281,18 @@ public function test_it_can_render_material_admin_26_file_inputs() ->seeElement('div.form-group') ->within('div.form-group', function () { $this->seeElement('div.fileinput.fileinput-exists') - ->within('div.fileinput', function () { - $this->seeElement('span.btn-file') - ->within('span.btn-file', function () { - $this->seeElement('input[name="featured_image"][type="file"][accept="application/pdf,image/jpeg,image/png"]#featured_image'); - }); - - $this->seeElement('span.fileinput-filename') - ->within('span.fileinput-filename', function () { - $this->seeElement('a[href="/storage/1/some-cool-image.jpg"]') - ->seeElement('i.zmdi.zmdi-open-in-new'); - }); - }); + ->within('div.fileinput', function () { + $this->seeElement('span.btn-file') + ->within('span.btn-file', function () { + $this->seeElement('input[name="featured_image"][type="file"][accept="application/pdf,image/jpeg,image/png"]#featured_image'); + }); + + $this->seeElement('span.fileinput-filename') + ->within('span.fileinput-filename', function () { + $this->seeElement('a[href="/storage/1/some-cool-image.jpg"]') + ->seeElement('i.zmdi.zmdi-open-in-new'); + }); + }); }); } diff --git a/tests/Feature/FormFilterTest.php b/tests/Feature/FormFilterTest.php index 3eaa452..1cbc230 100644 --- a/tests/Feature/FormFilterTest.php +++ b/tests/Feature/FormFilterTest.php @@ -7,7 +7,7 @@ class FormFilterTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/tests/Feature/ImageTest.php b/tests/Feature/ImageTest.php index dc06f20..fbeddf3 100644 --- a/tests/Feature/ImageTest.php +++ b/tests/Feature/ImageTest.php @@ -14,7 +14,7 @@ class ImageTest extends TestCase { use RefreshDatabase; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -38,8 +38,6 @@ protected function getArticleWithMedia(string $collection = 'featured_image'): A return $article; } - - public function test_it_can_render_bootstrap_5_image_inputs() { $article = $this->getArticleWithMedia(); diff --git a/tests/Feature/InputTest.php b/tests/Feature/InputTest.php index 013c6ab..6fae024 100644 --- a/tests/Feature/InputTest.php +++ b/tests/Feature/InputTest.php @@ -7,7 +7,7 @@ class InputTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -85,7 +85,7 @@ public function test_it_can_set_form_inputs_as_required() ->seeInElement('label.form-label[for="title"]', 'Title') ->within('label.form-label[for="title"]', function () { $this->seeElement('span.required') - ->seeInElement('span.required', '*'); + ->seeInElement('span.required', '*'); }); }); } diff --git a/tests/Feature/JsErrorsTest.php b/tests/Feature/JsErrorsTest.php index 056362c..bdff138 100644 --- a/tests/Feature/JsErrorsTest.php +++ b/tests/Feature/JsErrorsTest.php @@ -2,8 +2,6 @@ namespace Javaabu\Forms\Tests\Feature; -use Illuminate\Support\Facades\Config; -use Illuminate\Support\Facades\Route; use Javaabu\Forms\Tests\TestCase; class JsErrorsTest extends TestCase diff --git a/tests/Feature/LabelTest.php b/tests/Feature/LabelTest.php index 86c572e..7f3b87b 100644 --- a/tests/Feature/LabelTest.php +++ b/tests/Feature/LabelTest.php @@ -7,7 +7,7 @@ class LabelTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -21,7 +21,7 @@ public function test_it_can_generate_material_admin_label_with_a_slot() $this->visit('/label-slot') ->seeElementCount('label', 1) - ->within('label', function() { + ->within('label', function () { $this->seeElement('a') ->seeInElement('a', 'some site'); }); @@ -34,9 +34,9 @@ public function test_it_can_generate_bootstrap_5_label_with_a_slot() $this->visit('/label-slot') ->seeElementCount('label', 1) - ->within('label', function() { + ->within('label', function () { $this->seeElement('a') - ->seeInElement('a', 'some site'); + ->seeInElement('a', 'some site'); }); } diff --git a/tests/Feature/MapInputTest.php b/tests/Feature/MapInputTest.php index 0bb9699..4528a3e 100644 --- a/tests/Feature/MapInputTest.php +++ b/tests/Feature/MapInputTest.php @@ -12,7 +12,7 @@ class MapInputTest extends TestCase { const SRID = 4326; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -25,7 +25,7 @@ public function setUp(): void public function test_it_adds_the_maps_script_to_the_scripts_stack() { - $city = new City(); + $city = new City; $lat = 4.175804; $lng = 73.509337; @@ -45,7 +45,7 @@ public function test_it_adds_the_maps_script_to_the_scripts_stack() public function test_it_can_bind_map_inputs_from_attributes() { - $city = new City(); + $city = new City; $lat = 4.175804; $lng = 73.509337; $wkt = 'POLYGON((73.5092 4.1758, 73.5094 4.1758, 73.5094 4.1757, 73.5092 4.1757, 73.5092 4.1758))'; @@ -75,7 +75,7 @@ public function test_it_can_bind_map_inputs_from_attributes() public function test_it_can_bind_map_inputs_from_accessors() { - $city = new City(); + $city = new City; $lat = 4.175804; $lng = 73.509337; $wkt = 'POLYGON((73.5092 4.1758, 73.5094 4.1758, 73.5094 4.1757, 73.5092 4.1757, 73.5092 4.1758))'; diff --git a/tests/Feature/OverrideFormsDefaultsMiddlewareTest.php b/tests/Feature/OverrideFormsDefaultsMiddlewareTest.php index f0f292b..e8c5e57 100644 --- a/tests/Feature/OverrideFormsDefaultsMiddlewareTest.php +++ b/tests/Feature/OverrideFormsDefaultsMiddlewareTest.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Config; use Javaabu\Forms\Tests\TestCase; +use Route; class OverrideFormsDefaultsMiddlewareTest extends TestCase { @@ -19,7 +20,7 @@ public function test_it_can_use_the_middleware_to_switch_what_theme_to_use() $current_theme = Config::get('forms.framework'); $this->assertTrue($current_theme === 'material-admin-26'); - \Route::get('/change-framework', function () { + Route::get('/change-framework', function () { return 'Framework changed to Bootstrap-5'; })->middleware('forms:bootstrap-5'); diff --git a/tests/Feature/RadioTest.php b/tests/Feature/RadioTest.php index 7a30991..dacc647 100644 --- a/tests/Feature/RadioTest.php +++ b/tests/Feature/RadioTest.php @@ -3,12 +3,11 @@ namespace Javaabu\Forms\Tests\Feature; use Illuminate\Support\Facades\Config; -use Illuminate\Support\Facades\Route; use Javaabu\Forms\Tests\TestCase; class RadioTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -86,7 +85,6 @@ public function test_it_can_generate_bootstrap_5_form_radio_that_is_required() }); } - public function test_it_can_generate_material_admin_26_form_radio() { $this->setFrameworkMaterialAdmin26(); diff --git a/tests/Feature/Select2CascadeTest.php b/tests/Feature/Select2CascadeTest.php index 65a4f12..40f2637 100644 --- a/tests/Feature/Select2CascadeTest.php +++ b/tests/Feature/Select2CascadeTest.php @@ -12,8 +12,6 @@ class Country extends Model { /** * Get the user's first name. - * - * @return \Illuminate\Database\Eloquent\Casts\Attribute */ protected function formattedName(): Attribute { @@ -124,7 +122,6 @@ public function test_it_can_create_select2_options_from_a_query_builder() public function test_it_can_extract_an_accessor_field_from_the_builder() { - $countryA = Country::create(['name' => 'Maldives']); $countryB = Country::create(['name' => 'India']); $countryC = Country::create(['name' => 'Japan']); @@ -153,7 +150,6 @@ public function test_it_can_extract_an_accessor_field_from_the_builder() public function test_it_can_extract_a_get_accessor_field_from_the_builder() { - $countryA = Country::create(['name' => 'Maldives']); $countryB = Country::create(['name' => 'India']); $countryC = Country::create(['name' => 'Japan']); @@ -182,7 +178,6 @@ public function test_it_can_extract_a_get_accessor_field_from_the_builder() public function test_it_can_render_a_select2_cascade() { - $countryA = Country::create(['name' => 'Maldives']); $countryB = Country::create(['name' => 'India']); $countryC = Country::create(['name' => 'Japan']); diff --git a/tests/Feature/Select2Test.php b/tests/Feature/Select2Test.php index ed30819..7e91999 100644 --- a/tests/Feature/Select2Test.php +++ b/tests/Feature/Select2Test.php @@ -2,8 +2,8 @@ namespace Javaabu\Forms\Tests\Feature; -use Illuminate\Support\Facades\Route; use Illuminate\Foundation\Testing\RefreshDatabase; +use Illuminate\Support\Facades\Route; use Javaabu\Forms\Tests\TestCase; use Javaabu\Forms\Tests\TestSupport\Enums\ArticleStatuses; use Javaabu\Forms\Tests\TestSupport\Models\Article; diff --git a/tests/Feature/SelectRelationTest.php b/tests/Feature/SelectRelationTest.php index a5ff464..9fd8952 100644 --- a/tests/Feature/SelectRelationTest.php +++ b/tests/Feature/SelectRelationTest.php @@ -38,9 +38,7 @@ public function comments() } } -class Comment extends Model -{ -} +class Comment extends Model {} class SelectRelationTest extends TestCase { @@ -49,7 +47,6 @@ class SelectRelationTest extends TestCase public function test_it_handles_belongs_to_many_relationships() { - $post = PostBelongsToMany::create(['content' => 'Content']); $commentA = Comment::create(['content' => 'Content A']); @@ -80,7 +77,6 @@ public function test_it_handles_belongs_to_many_relationships() public function test_it_handles_morph_many_relationships() { - $post = PostMorphMany::create(['content' => 'Content']); $commentA = $post->comments()->create(['content' => 'Content A']); @@ -109,7 +105,6 @@ public function test_it_handles_morph_many_relationships() public function test_it_handles_morph_to_many_relationships() { - $post = PostMorphToMany::create(['content' => 'Content']); $commentA = $post->comments()->create(['content' => 'Content A']); diff --git a/tests/Feature/StatusTest.php b/tests/Feature/StatusTest.php index e897c81..0f96484 100644 --- a/tests/Feature/StatusTest.php +++ b/tests/Feature/StatusTest.php @@ -14,7 +14,7 @@ public function test_it_can_generate_status_with_slot() ->seeElement('span.status') ->within('span.status', function () { $this->seeElement('div.test') - ->seeInElement('div.test', 'Rejected'); + ->seeInElement('div.test', 'Rejected'); }); } diff --git a/tests/Feature/TableTest.php b/tests/Feature/TableTest.php index a77c00d..c8e9c64 100644 --- a/tests/Feature/TableTest.php +++ b/tests/Feature/TableTest.php @@ -91,7 +91,7 @@ public function test_it_can_generate_material_26_table() ->within('tr', function () use ($activity) { $this ->seeElement('.td-checkbox') - ->seeElement('input[type="checkbox"][id="activities-'. $activity->id . '-row-check"]') + ->seeElement('input[type="checkbox"][id="activities-' . $activity->id . '-row-check"]') ->seeInElement('td', $activity->id) ->seeInElement('td', $activity->date_a) ->seeInElement('td', $activity->date_b) @@ -106,7 +106,7 @@ public function test_it_can_generate_material_26_table() // Pagination check $this->seeElement('div.dataTables_info'); - //$this->seeInElement('div.dataTables_info', 'Showing 2 from total 20 entries'); + // $this->seeInElement('div.dataTables_info', 'Showing 2 from total 20 entries'); $this->seeInElement('div', 'Previous'); }); } diff --git a/tests/Feature/TextareaTest.php b/tests/Feature/TextareaTest.php index 6f81280..f961e85 100644 --- a/tests/Feature/TextareaTest.php +++ b/tests/Feature/TextareaTest.php @@ -3,12 +3,11 @@ namespace Javaabu\Forms\Tests\Feature; use Illuminate\Support\Facades\Config; -use Illuminate\Support\Facades\Route; use Javaabu\Forms\Tests\TestCase; class TextareaTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); diff --git a/tests/TestCase.php b/tests/TestCase.php index e2d59d6..19fbb84 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,6 +2,7 @@ namespace Javaabu\Forms\Tests; +use Composer\InstalledVersions; use Composer\Semver\VersionParser; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Artisan; @@ -32,10 +33,10 @@ public static function isLaravel10(): bool public static function isMediaLibrary10(): bool { - return \Composer\InstalledVersions::satisfies(new VersionParser(), 'spatie/laravel-medialibrary', '10.*'); + return InstalledVersions::satisfies(new VersionParser, 'spatie/laravel-medialibrary', '10.*'); } - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -43,7 +44,7 @@ public function setUp(): void $this->app['config']->set('session.serialization', 'php'); - //$this->app['config']->set('form-components.framework', env('FORM_COMPONENTS_FRAMEWORK', 'tailwind')); + // $this->app['config']->set('form-components.framework', env('FORM_COMPONENTS_FRAMEWORK', 'tailwind')); View::addLocation(__DIR__ . '/TestSupport/views'); @@ -87,7 +88,7 @@ protected function setFrameworkMaterialAdmin26(): self return $this->setFramework('material-admin-26'); } - protected function registerTestRoute($uri, callable $post = null): self + protected function registerTestRoute($uri, ?callable $post = null): self { Route::middleware('web')->group(function () use ($uri, $post) { Route::view($uri, $uri)->name($uri); @@ -102,6 +103,7 @@ protected function registerTestRoute($uri, callable $post = null): self /** * Copied from https://github.com/spatie/laravel-medialibrary/issues/623#issuecomment-2110321741 + * * @return $this */ protected function setupFakeMediaDisk(): self diff --git a/tests/TestSupport/Models/ActivityFactory.php b/tests/TestSupport/Models/ActivityFactory.php index cd63ad5..d467a66 100644 --- a/tests/TestSupport/Models/ActivityFactory.php +++ b/tests/TestSupport/Models/ActivityFactory.php @@ -2,7 +2,9 @@ namespace Javaabu\Forms\Tests\TestSupport\Models; -class ActivityFactory extends \Illuminate\Database\Eloquent\Factories\Factory +use Illuminate\Database\Eloquent\Factories\Factory; + +class ActivityFactory extends Factory { protected $model = Activity::class; diff --git a/tests/TestSupport/Models/Article.php b/tests/TestSupport/Models/Article.php index c0241db..c27a3fb 100644 --- a/tests/TestSupport/Models/Article.php +++ b/tests/TestSupport/Models/Article.php @@ -13,8 +13,8 @@ class Article extends Model implements HasMedia { - use InteractsWithMedia; use HasFactory; + use InteractsWithMedia; protected $fillable = [ 'status', diff --git a/tests/TestSupport/Providers/TestServiceProvider.php b/tests/TestSupport/Providers/TestServiceProvider.php index 3599704..67b28d3 100644 --- a/tests/TestSupport/Providers/TestServiceProvider.php +++ b/tests/TestSupport/Providers/TestServiceProvider.php @@ -19,8 +19,5 @@ public function boot() /** * Register the application services. */ - public function register() - { - - } + public function register() {} } diff --git a/tests/TestSupport/database/2024_04_28_124109_create_articles_table.php b/tests/TestSupport/database/2024_04_28_124109_create_articles_table.php index 3a62cc8..94096f8 100644 --- a/tests/TestSupport/database/2024_04_28_124109_create_articles_table.php +++ b/tests/TestSupport/database/2024_04_28_124109_create_articles_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * @@ -21,6 +22,7 @@ public function up() $table->timestamps(); }); } + /** * Reverse the migrations. * diff --git a/tests/TestSupport/database/2024_04_28_124110_create_posts_table.php b/tests/TestSupport/database/2024_04_28_124110_create_posts_table.php index f805e85..2fe4753 100644 --- a/tests/TestSupport/database/2024_04_28_124110_create_posts_table.php +++ b/tests/TestSupport/database/2024_04_28_124110_create_posts_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * @@ -18,6 +19,7 @@ public function up() $table->timestamps(); }); } + /** * Reverse the migrations. * diff --git a/tests/TestSupport/database/2024_04_28_124111_create_comments_table.php b/tests/TestSupport/database/2024_04_28_124111_create_comments_table.php index 91912c2..4e65130 100644 --- a/tests/TestSupport/database/2024_04_28_124111_create_comments_table.php +++ b/tests/TestSupport/database/2024_04_28_124111_create_comments_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * @@ -19,6 +20,7 @@ public function up() $table->timestamps(); }); } + /** * Reverse the migrations. * diff --git a/tests/TestSupport/database/2024_04_28_124112_create_comment_post_table.php b/tests/TestSupport/database/2024_04_28_124112_create_comment_post_table.php index 27ccc1d..4fd0690 100644 --- a/tests/TestSupport/database/2024_04_28_124112_create_comment_post_table.php +++ b/tests/TestSupport/database/2024_04_28_124112_create_comment_post_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * @@ -17,6 +18,7 @@ public function up() $table->unsignedBigInteger('comment_id'); }); } + /** * Reverse the migrations. * diff --git a/tests/TestSupport/database/2024_04_28_124113_create_commentables_table.php b/tests/TestSupport/database/2024_04_28_124113_create_commentables_table.php index 656e718..0d1562c 100644 --- a/tests/TestSupport/database/2024_04_28_124113_create_commentables_table.php +++ b/tests/TestSupport/database/2024_04_28_124113_create_commentables_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * @@ -18,6 +19,7 @@ public function up() $table->morphs('commentable'); }); } + /** * Reverse the migrations. * diff --git a/tests/TestSupport/database/2024_04_28_124114_create_tags_table.php b/tests/TestSupport/database/2024_04_28_124114_create_tags_table.php index baee6c0..5d29ab0 100644 --- a/tests/TestSupport/database/2024_04_28_124114_create_tags_table.php +++ b/tests/TestSupport/database/2024_04_28_124114_create_tags_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * @@ -18,6 +19,7 @@ public function up() $table->timestamps(); }); } + /** * Reverse the migrations. * diff --git a/tests/TestSupport/database/2024_04_28_134113_create_activities_table.php b/tests/TestSupport/database/2024_04_28_134113_create_activities_table.php index c90ae08..98b217c 100644 --- a/tests/TestSupport/database/2024_04_28_134113_create_activities_table.php +++ b/tests/TestSupport/database/2024_04_28_134113_create_activities_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * @@ -22,6 +23,7 @@ public function up() $table->timestamps(); }); } + /** * Reverse the migrations. * diff --git a/tests/TestSupport/database/2024_04_28_144110_create_countries_table.php b/tests/TestSupport/database/2024_04_28_144110_create_countries_table.php index 5918b8f..c30fcd3 100644 --- a/tests/TestSupport/database/2024_04_28_144110_create_countries_table.php +++ b/tests/TestSupport/database/2024_04_28_144110_create_countries_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * @@ -18,6 +19,7 @@ public function up() $table->timestamps(); }); } + /** * Reverse the migrations. * diff --git a/tests/TestSupport/database/2024_04_28_144111_create_states_table.php b/tests/TestSupport/database/2024_04_28_144111_create_states_table.php index b1e59be..c85ec8f 100644 --- a/tests/TestSupport/database/2024_04_28_144111_create_states_table.php +++ b/tests/TestSupport/database/2024_04_28_144111_create_states_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * @@ -19,6 +20,7 @@ public function up() $table->timestamps(); }); } + /** * Reverse the migrations. * diff --git a/tests/TestSupport/database/2024_04_28_144112_create_cities_table.php b/tests/TestSupport/database/2024_04_28_144112_create_cities_table.php index 3247720..78bb0e9 100644 --- a/tests/TestSupport/database/2024_04_28_144112_create_cities_table.php +++ b/tests/TestSupport/database/2024_04_28_144112_create_cities_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * @@ -19,6 +20,7 @@ public function up() $table->timestamps(); }); } + /** * Reverse the migrations. * diff --git a/tests/TestSupport/database/2024_04_28_144113_create_addresses_table.php b/tests/TestSupport/database/2024_04_28_144113_create_addresses_table.php index 73f4142..38dfaf1 100644 --- a/tests/TestSupport/database/2024_04_28_144113_create_addresses_table.php +++ b/tests/TestSupport/database/2024_04_28_144113_create_addresses_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * @@ -19,6 +20,7 @@ public function up() $table->timestamps(); }); } + /** * Reverse the migrations. * diff --git a/tests/TestSupport/database/2024_12_24_123546_create_categories_table.php b/tests/TestSupport/database/2024_12_24_123546_create_categories_table.php index bb61b98..6d0326c 100644 --- a/tests/TestSupport/database/2024_12_24_123546_create_categories_table.php +++ b/tests/TestSupport/database/2024_12_24_123546_create_categories_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class () extends Migration { +return new class extends Migration +{ /** * Run the migrations. * diff --git a/tests/Unit/FormsDataBinderTest.php b/tests/Unit/FormsDataBinderTest.php index 1d02b07..c512d2e 100644 --- a/tests/Unit/FormsDataBinderTest.php +++ b/tests/Unit/FormsDataBinderTest.php @@ -9,7 +9,7 @@ class FormsDataBinderTest extends TestCase { public function test_it_can_bind_targets() { - $binder = new FormsDataBinder(); + $binder = new FormsDataBinder; $this->assertNull($binder->get()); $binder->bind($array = ['foo' => 'bar']); @@ -18,7 +18,7 @@ public function test_it_can_bind_targets() public function test_it_can_bind_multiple_targets() { - $binder = new FormsDataBinder(); + $binder = new FormsDataBinder; $binder->bind($targetA = ['foo' => 'bar']); $binder->bind($targetB = ['bar' => 'foo']); diff --git a/tests/Unit/SettingsTest.php b/tests/Unit/SettingsTest.php new file mode 100644 index 0000000..2fc419b --- /dev/null +++ b/tests/Unit/SettingsTest.php @@ -0,0 +1,25 @@ +assertEquals(35, Settings::get('per_page', 20)); + } + + #[Test] + public function it_falls_back_to_the_given_default_when_nothing_is_set(): void + { + $this->assertEquals('fallback', Settings::get('a_setting_that_does_not_exist', 'fallback')); + } +} From c54aa0d2d1bcb4b6584a3e9ef14b8d18c500faa6 Mon Sep 17 00:00:00 2001 From: Naffah Abdulla Rasheed Date: Wed, 4 Nov 2026 12:54:52 +0500 Subject: [PATCH 02/10] Drop Bootstrap 5 and Material Admin; add the Bootstrap 6 framework - Remove the bootstrap-5 and material-admin-26 views and their tests - New bootstrap-6 views targeting 6.0.0-alpha.1: .form-field layout, .form-control selects, .check/.radio inputs, btn-solid/btn-outline + .theme-*, native modals,
accordions, menus, prefixed responsive classes (sm:col-3), aria-invalid on errors - Framework-agnostic views move to forms::common and are used when a framework has no view of its own - Framework class maps (Frameworks\Bootstrap6, Frameworks\Onu) for button colours, badges and alerts; Frameworks::register() for custom ones - : Lucide icons as inline SVG (generated by scripts/icons.mjs), or icon-font classes; one forms.icons config - Snake_case framework config keys, translatable strings for Clear/Filter/Export/Apply/Select All/pagination - Modal gets a size attribute - Fix: errors lookup no longer needs a session; modal without a footer - docs/upgrading.md Closes #6 Closes #7 Co-Authored-By: Claude Opus 5.5 --- .gitignore | 1 + config/config.php | 106 ++++---- docs/upgrading.md | 110 +++++++++ lang/dv/strings.php | 14 ++ lang/en/strings.php | 14 ++ package.json | 17 ++ pnpm-lock.yaml | 22 ++ resources/icons/icons.php | 39 +++ resources/onu/classes.php | 5 + .../bootstrap-5/accordion/collapse.blade.php | 14 -- .../bootstrap-5/accordion/header.blade.php | 12 - .../bootstrap-5/accordion/item.blade.php | 25 -- resources/views/bootstrap-5/alert.blade.php | 32 --- .../views/bootstrap-5/bulk-actions.blade.php | 33 --- resources/views/bootstrap-5/errors.blade.php | 5 - .../views/bootstrap-5/filter-submit.blade.php | 65 ----- resources/views/bootstrap-5/filter.blade.php | 13 - .../views/bootstrap-5/form-group.blade.php | 23 -- .../views/bootstrap-5/input-help.blade.php | 3 - .../views/bootstrap-5/js-errors.blade.php | 3 - .../bootstrap-5/label-required.blade.php | 3 - .../views/bootstrap-5/link-button.blade.php | 9 - .../views/bootstrap-5/map-input.blade.php | 89 ------- resources/views/bootstrap-5/modal.blade.php | 28 --- resources/views/bootstrap-5/status.blade.php | 7 - .../views/bootstrap-5/table/row.blade.php | 12 - .../views/bootstrap-5/tabs/pane.blade.php | 11 - .../bootstrap-6/accordion/collapse.blade.php | 7 + .../bootstrap-6/accordion/header.blade.php | 4 + .../accordion/item.blade.php | 4 +- resources/views/bootstrap-6/alert.blade.php | 17 ++ .../views/bootstrap-6/bulk-actions.blade.php | 25 ++ .../button-group.blade.php | 0 .../button.blade.php | 2 +- .../card.blade.php | 0 .../card/footer.blade.php | 0 .../card/header.blade.php | 0 .../card/subtitle.blade.php | 0 .../card/title.blade.php | 0 .../checkbox.blade.php | 24 +- resources/views/bootstrap-6/errors.blade.php | 5 + .../file.blade.php | 8 +- .../file/file-input.blade.php | 6 +- .../views/bootstrap-6/filter-submit.blade.php | 62 +++++ .../views/bootstrap-6/form-group.blade.php | 24 ++ .../image.blade.php | 9 +- .../views/bootstrap-6/input-help.blade.php | 3 + .../input.blade.php | 20 +- .../views/bootstrap-6/js-errors.blade.php | 3 + .../bootstrap-6/label-required.blade.php | 3 + .../label.blade.php | 0 .../link-button.blade.php | 2 +- .../map-input.blade.php | 10 +- resources/views/bootstrap-6/modal.blade.php | 27 ++ .../nav-tabs.blade.php | 9 +- .../no-items.blade.php | 8 +- .../pagination.blade.php | 15 +- .../radio.blade.php | 23 +- .../select.blade.php | 9 +- .../status.blade.php | 2 +- .../table.blade.php | 15 +- .../views/bootstrap-6/table/row.blade.php | 9 + .../tabs.blade.php | 0 .../tabs/nav-item.blade.php | 1 + .../tabs/pane.blade.php | 5 +- .../text-entry.blade.php | 4 +- .../textarea.blade.php | 15 +- .../accordion.blade.php | 0 .../conditional-link.blade.php | 0 .../conditional-wrapper.blade.php | 0 resources/views/common/filter.blade.php | 7 + .../form-close.blade.php | 0 .../form-open.blade.php | 0 .../{bootstrap-5 => common}/form.blade.php | 0 resources/views/common/icon.blade.php | 5 + .../per-page.blade.php | 0 .../search-form.blade.php | 0 .../table/cell.blade.php | 0 .../table/empty-row.blade.php | 0 .../table/heading.blade.php | 0 .../material-admin-26/accordion.blade.php | 32 --- .../accordion/collapse.blade.php | 13 - .../accordion/header.blade.php | 8 - .../views/material-admin-26/alert.blade.php | 34 --- .../material-admin-26/bulk-actions.blade.php | 38 --- .../material-admin-26/button-group.blade.php | 5 - .../views/material-admin-26/button.blade.php | 10 - .../views/material-admin-26/card.blade.php | 35 --- .../material-admin-26/card/footer.blade.php | 3 - .../material-admin-26/card/header.blade.php | 3 - .../material-admin-26/card/subtitle.blade.php | 3 - .../material-admin-26/card/title.blade.php | 3 - .../material-admin-26/checkbox.blade.php | 40 --- .../conditional-link.blade.php | 24 -- .../conditional-wrapper.blade.php | 20 -- .../cursor-pagination.blade.php | 18 -- .../views/material-admin-26/errors.blade.php | 5 - .../views/material-admin-26/file.blade.php | 72 ------ .../material-admin-26/filter-submit.blade.php | 68 ------ .../views/material-admin-26/filter.blade.php | 26 -- .../material-admin-26/form-close.blade.php | 1 - .../material-admin-26/form-group.blade.php | 24 -- .../material-admin-26/form-open.blade.php | 16 -- .../views/material-admin-26/form.blade.php | 19 -- .../views/material-admin-26/image.blade.php | 93 ------- .../material-admin-26/input-help.blade.php | 3 - .../views/material-admin-26/input.blade.php | 78 ------ .../material-admin-26/js-errors.blade.php | 3 - .../label-required.blade.php | 3 - .../views/material-admin-26/label.blade.php | 11 - .../views/material-admin-26/modal.blade.php | 23 -- .../material-admin-26/nav-tabs.blade.php | 25 -- .../material-admin-26/no-items.blade.php | 18 -- .../material-admin-26/pagination.blade.php | 48 ---- .../material-admin-26/per-page.blade.php | 9 - .../views/material-admin-26/radio.blade.php | 40 --- .../material-admin-26/search-form.blade.php | 12 - .../views/material-admin-26/select.blade.php | 146 ----------- .../views/material-admin-26/table.blade.php | 61 ----- .../material-admin-26/table/cell.blade.php | 24 -- .../table/empty-row.blade.php | 9 - .../material-admin-26/table/heading.blade.php | 19 -- .../material-admin-26/table/row.blade.php | 13 - .../views/material-admin-26/tabs.blade.php | 28 --- .../material-admin-26/tabs/nav-item.blade.php | 12 - .../material-admin-26/text-entry.blade.php | 41 ---- .../material-admin-26/textarea.blade.php | 49 ---- resources/views/partials/assets.blade.php | 8 + .../maps.blade.php} | 0 .../wysiwyg.blade.php} | 0 scripts/icons.mjs | 72 ++++++ src/Frameworks/Bootstrap6.php | 64 +++++ src/Frameworks/Framework.php | 28 +++ src/Frameworks/Frameworks.php | 51 ++++ src/Frameworks/Onu.php | 91 +++++++ src/Support/HandlesValidationErrors.php | 8 +- src/Support/Icons/Svg.php | 28 +++ src/Views/Components/Component.php | 34 ++- src/Views/Components/Date.php | 8 +- src/Views/Components/Datetime.php | 2 +- src/Views/Components/File.php | 6 +- src/Views/Components/FormGroup.php | 2 +- src/Views/Components/Icon.php | 37 +++ src/Views/Components/Image.php | 2 +- src/Views/Components/Label.php | 2 +- src/Views/Components/Modal.php | 1 + src/Views/Components/NoItems.php | 2 +- src/Views/Components/SearchForm.php | 2 +- src/Views/Components/TextEntry.php | 4 +- src/Views/Components/Time.php | 2 +- tests/Feature/AccordionTest.php | 231 ++++++------------ tests/Feature/BulkTest.php | 22 +- tests/Feature/ButtonTest.php | 77 ++---- tests/Feature/CardTest.php | 173 +++---------- tests/Feature/CheckboxTest.php | 160 +++++------- tests/Feature/ConditionalLinkTest.php | 19 +- tests/Feature/ConditionalWrapperTest.php | 21 +- tests/Feature/DateTest.php | 6 +- tests/Feature/FileTest.php | 161 ++++++------ tests/Feature/FormFilterTest.php | 10 +- tests/Feature/FormTest.php | 4 +- tests/Feature/Frameworks/Bootstrap6Test.php | 111 +++++++++ tests/Feature/IconTest.php | 62 +++++ tests/Feature/ImageTest.php | 53 +--- tests/Feature/InputTest.php | 79 +++--- tests/Feature/JsErrorsTest.php | 15 +- tests/Feature/LabelTest.php | 118 +++------ tests/Feature/MapInputTest.php | 16 +- tests/Feature/MultipleSelectTest.php | 4 +- tests/Feature/NavTabsTest.php | 42 +--- tests/Feature/NoItemsTest.php | 22 +- .../OverrideFormsDefaultsMiddlewareTest.php | 18 +- tests/Feature/PerPageTest.php | 21 +- tests/Feature/RadioTest.php | 100 ++------ tests/Feature/SearchFormTest.php | 18 +- tests/Feature/Select2CascadeTest.php | 16 +- tests/Feature/Select2Test.php | 50 ++-- tests/Feature/SelectBooleanValueTest.php | 7 +- tests/Feature/SelectRelationTest.php | 10 +- tests/Feature/SelectTest.php | 19 +- tests/Feature/SelectWithoutKeysTest.php | 7 +- tests/Feature/SpoofMethodTest.php | 4 +- tests/Feature/StatusTest.php | 23 +- tests/Feature/TableCellTest.php | 82 ++----- tests/Feature/TableTest.php | 21 +- tests/Feature/TabsTest.php | 73 +----- tests/Feature/TextEntryTest.php | 97 ++------ tests/Feature/TextareaTest.php | 26 +- tests/TestCase.php | 37 ++- tests/Unit/FormsDataBinderTest.php | 7 +- tests/Unit/FrameworksTest.php | 48 ++++ 191 files changed, 1854 insertions(+), 3085 deletions(-) create mode 100644 docs/upgrading.md create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 resources/icons/icons.php create mode 100644 resources/onu/classes.php delete mode 100644 resources/views/bootstrap-5/accordion/collapse.blade.php delete mode 100644 resources/views/bootstrap-5/accordion/header.blade.php delete mode 100644 resources/views/bootstrap-5/accordion/item.blade.php delete mode 100644 resources/views/bootstrap-5/alert.blade.php delete mode 100644 resources/views/bootstrap-5/bulk-actions.blade.php delete mode 100644 resources/views/bootstrap-5/errors.blade.php delete mode 100644 resources/views/bootstrap-5/filter-submit.blade.php delete mode 100644 resources/views/bootstrap-5/filter.blade.php delete mode 100644 resources/views/bootstrap-5/form-group.blade.php delete mode 100644 resources/views/bootstrap-5/input-help.blade.php delete mode 100644 resources/views/bootstrap-5/js-errors.blade.php delete mode 100644 resources/views/bootstrap-5/label-required.blade.php delete mode 100644 resources/views/bootstrap-5/link-button.blade.php delete mode 100644 resources/views/bootstrap-5/map-input.blade.php delete mode 100644 resources/views/bootstrap-5/modal.blade.php delete mode 100644 resources/views/bootstrap-5/status.blade.php delete mode 100644 resources/views/bootstrap-5/table/row.blade.php delete mode 100644 resources/views/bootstrap-5/tabs/pane.blade.php create mode 100644 resources/views/bootstrap-6/accordion/collapse.blade.php create mode 100644 resources/views/bootstrap-6/accordion/header.blade.php rename resources/views/{material-admin-26 => bootstrap-6}/accordion/item.blade.php (81%) create mode 100644 resources/views/bootstrap-6/alert.blade.php create mode 100644 resources/views/bootstrap-6/bulk-actions.blade.php rename resources/views/{bootstrap-5 => bootstrap-6}/button-group.blade.php (100%) rename resources/views/{bootstrap-5 => bootstrap-6}/button.blade.php (78%) rename resources/views/{bootstrap-5 => bootstrap-6}/card.blade.php (100%) rename resources/views/{bootstrap-5 => bootstrap-6}/card/footer.blade.php (100%) rename resources/views/{bootstrap-5 => bootstrap-6}/card/header.blade.php (100%) rename resources/views/{bootstrap-5 => bootstrap-6}/card/subtitle.blade.php (100%) rename resources/views/{bootstrap-5 => bootstrap-6}/card/title.blade.php (100%) rename resources/views/{bootstrap-5 => bootstrap-6}/checkbox.blade.php (66%) create mode 100644 resources/views/bootstrap-6/errors.blade.php rename resources/views/{bootstrap-5 => bootstrap-6}/file.blade.php (86%) rename resources/views/{bootstrap-5 => bootstrap-6}/file/file-input.blade.php (76%) create mode 100644 resources/views/bootstrap-6/filter-submit.blade.php create mode 100644 resources/views/bootstrap-6/form-group.blade.php rename resources/views/{bootstrap-5 => bootstrap-6}/image.blade.php (91%) create mode 100644 resources/views/bootstrap-6/input-help.blade.php rename resources/views/{bootstrap-5 => bootstrap-6}/input.blade.php (77%) create mode 100644 resources/views/bootstrap-6/js-errors.blade.php create mode 100644 resources/views/bootstrap-6/label-required.blade.php rename resources/views/{bootstrap-5 => bootstrap-6}/label.blade.php (100%) rename resources/views/{material-admin-26 => bootstrap-6}/link-button.blade.php (67%) rename resources/views/{material-admin-26 => bootstrap-6}/map-input.blade.php (91%) create mode 100644 resources/views/bootstrap-6/modal.blade.php rename resources/views/{bootstrap-5 => bootstrap-6}/nav-tabs.blade.php (66%) rename resources/views/{bootstrap-5 => bootstrap-6}/no-items.blade.php (68%) rename resources/views/{bootstrap-5 => bootstrap-6}/pagination.blade.php (78%) rename resources/views/{bootstrap-5 => bootstrap-6}/radio.blade.php (66%) rename resources/views/{bootstrap-5 => bootstrap-6}/select.blade.php (90%) rename resources/views/{material-admin-26 => bootstrap-6}/status.blade.php (51%) rename resources/views/{bootstrap-5 => bootstrap-6}/table.blade.php (69%) create mode 100644 resources/views/bootstrap-6/table/row.blade.php rename resources/views/{bootstrap-5 => bootstrap-6}/tabs.blade.php (100%) rename resources/views/{bootstrap-5 => bootstrap-6}/tabs/nav-item.blade.php (96%) rename resources/views/{material-admin-26 => bootstrap-6}/tabs/pane.blade.php (66%) rename resources/views/{bootstrap-5 => bootstrap-6}/text-entry.blade.php (92%) rename resources/views/{bootstrap-5 => bootstrap-6}/textarea.blade.php (74%) rename resources/views/{bootstrap-5 => common}/accordion.blade.php (100%) rename resources/views/{bootstrap-5 => common}/conditional-link.blade.php (100%) rename resources/views/{bootstrap-5 => common}/conditional-wrapper.blade.php (100%) create mode 100644 resources/views/common/filter.blade.php rename resources/views/{bootstrap-5 => common}/form-close.blade.php (100%) rename resources/views/{bootstrap-5 => common}/form-open.blade.php (100%) rename resources/views/{bootstrap-5 => common}/form.blade.php (100%) create mode 100644 resources/views/common/icon.blade.php rename resources/views/{bootstrap-5 => common}/per-page.blade.php (100%) rename resources/views/{bootstrap-5 => common}/search-form.blade.php (100%) rename resources/views/{bootstrap-5 => common}/table/cell.blade.php (100%) rename resources/views/{bootstrap-5 => common}/table/empty-row.blade.php (100%) rename resources/views/{bootstrap-5 => common}/table/heading.blade.php (100%) delete mode 100644 resources/views/material-admin-26/accordion.blade.php delete mode 100644 resources/views/material-admin-26/accordion/collapse.blade.php delete mode 100644 resources/views/material-admin-26/accordion/header.blade.php delete mode 100644 resources/views/material-admin-26/alert.blade.php delete mode 100644 resources/views/material-admin-26/bulk-actions.blade.php delete mode 100644 resources/views/material-admin-26/button-group.blade.php delete mode 100644 resources/views/material-admin-26/button.blade.php delete mode 100644 resources/views/material-admin-26/card.blade.php delete mode 100644 resources/views/material-admin-26/card/footer.blade.php delete mode 100644 resources/views/material-admin-26/card/header.blade.php delete mode 100644 resources/views/material-admin-26/card/subtitle.blade.php delete mode 100644 resources/views/material-admin-26/card/title.blade.php delete mode 100644 resources/views/material-admin-26/checkbox.blade.php delete mode 100644 resources/views/material-admin-26/conditional-link.blade.php delete mode 100644 resources/views/material-admin-26/conditional-wrapper.blade.php delete mode 100644 resources/views/material-admin-26/cursor-pagination.blade.php delete mode 100644 resources/views/material-admin-26/errors.blade.php delete mode 100644 resources/views/material-admin-26/file.blade.php delete mode 100644 resources/views/material-admin-26/filter-submit.blade.php delete mode 100644 resources/views/material-admin-26/filter.blade.php delete mode 100644 resources/views/material-admin-26/form-close.blade.php delete mode 100644 resources/views/material-admin-26/form-group.blade.php delete mode 100644 resources/views/material-admin-26/form-open.blade.php delete mode 100644 resources/views/material-admin-26/form.blade.php delete mode 100644 resources/views/material-admin-26/image.blade.php delete mode 100644 resources/views/material-admin-26/input-help.blade.php delete mode 100644 resources/views/material-admin-26/input.blade.php delete mode 100644 resources/views/material-admin-26/js-errors.blade.php delete mode 100644 resources/views/material-admin-26/label-required.blade.php delete mode 100644 resources/views/material-admin-26/label.blade.php delete mode 100644 resources/views/material-admin-26/modal.blade.php delete mode 100644 resources/views/material-admin-26/nav-tabs.blade.php delete mode 100644 resources/views/material-admin-26/no-items.blade.php delete mode 100644 resources/views/material-admin-26/pagination.blade.php delete mode 100644 resources/views/material-admin-26/per-page.blade.php delete mode 100644 resources/views/material-admin-26/radio.blade.php delete mode 100644 resources/views/material-admin-26/search-form.blade.php delete mode 100644 resources/views/material-admin-26/select.blade.php delete mode 100644 resources/views/material-admin-26/table.blade.php delete mode 100644 resources/views/material-admin-26/table/cell.blade.php delete mode 100644 resources/views/material-admin-26/table/empty-row.blade.php delete mode 100644 resources/views/material-admin-26/table/heading.blade.php delete mode 100644 resources/views/material-admin-26/table/row.blade.php delete mode 100644 resources/views/material-admin-26/tabs.blade.php delete mode 100644 resources/views/material-admin-26/tabs/nav-item.blade.php delete mode 100644 resources/views/material-admin-26/text-entry.blade.php delete mode 100644 resources/views/material-admin-26/textarea.blade.php create mode 100644 resources/views/partials/assets.blade.php rename resources/views/partials/{maps-script.blade.php => scripts/maps.blade.php} (100%) rename resources/views/partials/{wysiwyg-script.blade.php => scripts/wysiwyg.blade.php} (100%) create mode 100644 scripts/icons.mjs create mode 100644 src/Frameworks/Bootstrap6.php create mode 100644 src/Frameworks/Framework.php create mode 100644 src/Frameworks/Frameworks.php create mode 100644 src/Frameworks/Onu.php create mode 100644 src/Support/Icons/Svg.php create mode 100644 src/Views/Components/Icon.php create mode 100644 tests/Feature/Frameworks/Bootstrap6Test.php create mode 100644 tests/Feature/IconTest.php create mode 100644 tests/Unit/FrameworksTest.php diff --git a/.gitignore b/.gitignore index d42e817..2f7e222 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ coverage .php-cs-fixer.cache clover.xml coverage.xml +node_modules diff --git a/config/config.php b/config/config.php index d99a4f4..8896c1b 100644 --- a/config/config.php +++ b/config/config.php @@ -6,14 +6,24 @@ | Default CSS Framework |-------------------------------------------------------------------------- | - | This option controls the default CSS framework that will be used by the - | package when rendering form components + | The framework the components render for. Any component can override it + | with a framework="..." attribute. | - | Supported: "bootstrap-5", "material-admin-26" + | Supported: "onu", "bootstrap-6" | */ - 'framework' => 'bootstrap-5', + 'framework' => env('FORMS_FRAMEWORK', 'bootstrap-6'), + + /* + |-------------------------------------------------------------------------- + | Eloquent date casting + |-------------------------------------------------------------------------- + | + | When true, date inputs format bound model dates with the model's own + | date casts instead of the component's date format. + | + */ 'use_eloquent_date_casting' => false, @@ -34,54 +44,65 @@ 'default_lng' => null, // 73.5093 (Malé) ], + /* + |-------------------------------------------------------------------------- + | Icons + |-------------------------------------------------------------------------- + | + | The icon each component uses. A value is either the name of one of the + | bundled Lucide icons (rendered as inline SVG, see resources/icons) or + | CSS classes for an icon font, e.g. "fa-regular fa-calendar". A + | framework can override these under frameworks..icons. + | + */ + + 'icons' => [ + 'date' => 'calendar', + 'datetime' => 'calendar', + 'time' => 'clock', + 'clear' => 'x', + 'download' => 'download', + 'upload' => 'upload', + 'image' => 'image', + 'search' => 'search', + 'no_items' => 'file', + 'create' => 'plus', + 'sort' => 'arrow-up-down', + 'sort_asc' => 'arrow-up', + 'sort_desc' => 'arrow-down', + 'alert_success' => 'circle-check', + 'alert_danger' => 'circle-x', + 'alert_warning' => 'triangle-alert', + 'alert_info' => 'info', + ], + /* |-------------------------------------------------------------------------- | Framework Settings |-------------------------------------------------------------------------- | - | Framework specific configs + | Framework specific settings. Each framework can also have its own + | "icons" array, merged over the icons above. | */ 'frameworks' => [ - 'bootstrap-5' => [ - 'icon-prefix' => 'fa-regular', - 'date-icon' => 'fa-calendar', - 'date-icon-wrapper-class' => 'date-icon-wrapper', - 'datetime-icon' => 'fa-calendar', - 'time-icon' => 'fa-clock', - 'date-clear-icon' => 'fa-close', - 'date-clear-btn-class' => 'btn btn-outline-secondary btn-date-clear disable-w-input', - 'file-download-icon' => 'fa-arrow-to-bottom', - 'file-upload-icon' => 'fa-arrow-to-top', - 'file-clear-icon' => 'fa-close', - 'image-icon' => 'fa-image', - 'inline-label-class' => 'col-sm-3 col-lg-2 col-form-label', - 'inline-input-class' => 'col-sm-9 col-lg-10', - 'inline-entry-label-class' => 'col-sm-6 col-md-4', - 'inline-entry-class' => 'col-sm-6 col-md-8', - 'search-icon' => 'fa-search', - 'no-items-icon' => 'fa-file', + 'onu' => [ + 'inline_label_class' => 'sm:w-1/4 lg:w-1/6 sm:shrink-0', + 'inline_input_class' => 'min-w-0 flex-1', + 'inline_entry_label_class' => 'sm:w-1/2 md:w-1/3 sm:shrink-0', + 'inline_entry_class' => 'min-w-0 flex-1', + 'date_icon_wrapper_class' => '', + 'date_clear_btn_class' => '', ], - 'material-admin-26' => [ - 'icon-prefix' => 'zmdi', - 'date-icon' => 'zmdi-calendar', - 'date-icon-wrapper-class' => 'date-icon-wrapper', - 'datetime-icon' => 'zmdi-calendar', - 'time-icon' => 'zmdi-clock', - 'date-clear-icon' => 'zmdi-close', - 'date-clear-btn-class' => 'text-body btn-date-clear disable-w-input', - 'file-download-icon' => 'zmdi-open-in-new', - 'file-upload-icon' => 'zmdi-upload', - 'file-clear-icon' => 'zmdi-close', - 'image-icon' => 'zmdi-image', - 'inline-label-class' => 'col-sm-3 col-lg-2 col-form-label', - 'inline-input-class' => 'col-sm-9 col-lg-10', - 'inline-entry-label-class' => 'col-sm-6 col-md-4', - 'inline-entry-class' => 'col-sm-6 col-md-8', - 'search-icon' => 'zmdi-search', - 'no-items-icon' => 'zmdi-file', + 'bootstrap-6' => [ + 'inline_label_class' => 'sm:col-3 lg:col-2 col-form-label', + 'inline_input_class' => 'sm:col-9 lg:col-10', + 'inline_entry_label_class' => 'sm:col-6 md:col-4', + 'inline_entry_class' => 'sm:col-6 md:col-8', + 'date_icon_wrapper_class' => '', + 'date_clear_btn_class' => '', ], ], @@ -90,7 +111,8 @@ | Scripts Stack |-------------------------------------------------------------------------- | - | The name of the stack to push scripts + | The Blade stack the components push their scripts to when javaabu/manifest + | isn't handling assets. Render it with @stack('scripts') in your layout. | */ diff --git a/docs/upgrading.md b/docs/upgrading.md new file mode 100644 index 0000000..e5fb154 --- /dev/null +++ b/docs/upgrading.md @@ -0,0 +1,110 @@ +--- +title: Upgrading from v1 +sidebar_position: 1.5 +--- + +# Upgrading from v1 to v2 + +v2 keeps every component name and attribute from v1, so most Blade templates keep working unchanged. What changes is the CSS framework the components render for, a few config keys, and how icons and scripts are loaded. + +## Requirements + +- PHP 8.4 or newer. +- Laravel 12 or 13. +- `javaabu/settings` is no longer required. See [Defaults](#defaults-no-longer-need-javaabusettings). + +```bash +composer require javaabu/forms:^2.0 +``` + +## Frameworks + +**`bootstrap-5` and `material-admin-26` are removed.** v2 renders for: + +| Framework | What it is | +| ------------- | ------------------------------------------------------------------------------------------ | +| `onu` | Tailwind CSS with the tokens and classes of [`@javaabu/onu`](https://github.com/Javaabu/onu). The default. | +| `bootstrap-6` | Bootstrap 6 (targets `6.0.0-alpha.1`). | + +Set the framework in `config/forms.php` (or with `FORMS_FRAMEWORK` in `.env`): + +```php +'framework' => env('FORMS_FRAMEWORK', 'onu'), +``` + +If your app stays on Bootstrap 5 or Material Admin for now, stay on `javaabu/forms` 1.x (`^1.71`). + +### Moving from `bootstrap-5` to `bootstrap-6` + +Your templates don't change; the HTML the components output does. If you wrote CSS or JS against the old markup, update it: + +| v1 (`bootstrap-5`) | v2 (`bootstrap-6`) | +| ------------------------------------------------- | ------------------------------------------------------------------------------------ | +| `.form-select` | `.form-control` on the ` @@ -36,7 +31,5 @@ @if($wysiwyg) - @pushonce(config('forms.scripts_stack')) - @include('forms::partials.wysiwyg-script') - @endpushonce + @include('forms::partials.assets', ['assets' => ['wysiwyg']]) @endif diff --git a/resources/views/bootstrap-5/accordion.blade.php b/resources/views/common/accordion.blade.php similarity index 100% rename from resources/views/bootstrap-5/accordion.blade.php rename to resources/views/common/accordion.blade.php diff --git a/resources/views/bootstrap-5/conditional-link.blade.php b/resources/views/common/conditional-link.blade.php similarity index 100% rename from resources/views/bootstrap-5/conditional-link.blade.php rename to resources/views/common/conditional-link.blade.php diff --git a/resources/views/bootstrap-5/conditional-wrapper.blade.php b/resources/views/common/conditional-wrapper.blade.php similarity index 100% rename from resources/views/bootstrap-5/conditional-wrapper.blade.php rename to resources/views/common/conditional-wrapper.blade.php diff --git a/resources/views/common/filter.blade.php b/resources/views/common/filter.blade.php new file mode 100644 index 0000000..63eba0e --- /dev/null +++ b/resources/views/common/filter.blade.php @@ -0,0 +1,7 @@ + + {{ $slot }} + + + + + diff --git a/resources/views/bootstrap-5/form-close.blade.php b/resources/views/common/form-close.blade.php similarity index 100% rename from resources/views/bootstrap-5/form-close.blade.php rename to resources/views/common/form-close.blade.php diff --git a/resources/views/bootstrap-5/form-open.blade.php b/resources/views/common/form-open.blade.php similarity index 100% rename from resources/views/bootstrap-5/form-open.blade.php rename to resources/views/common/form-open.blade.php diff --git a/resources/views/bootstrap-5/form.blade.php b/resources/views/common/form.blade.php similarity index 100% rename from resources/views/bootstrap-5/form.blade.php rename to resources/views/common/form.blade.php diff --git a/resources/views/common/icon.blade.php b/resources/views/common/icon.blade.php new file mode 100644 index 0000000..a03cb1f --- /dev/null +++ b/resources/views/common/icon.blade.php @@ -0,0 +1,5 @@ +@if($isSvg()) +merge(['class' => 'forms-icon', 'aria-hidden' => 'true', 'focusable' => 'false']) }} data-icon="{{ $icon }}" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">{!! $svg() !!} +@elseif($icon) +merge(['class' => $icon, 'aria-hidden' => 'true']) }}> +@endif diff --git a/resources/views/bootstrap-5/per-page.blade.php b/resources/views/common/per-page.blade.php similarity index 100% rename from resources/views/bootstrap-5/per-page.blade.php rename to resources/views/common/per-page.blade.php diff --git a/resources/views/bootstrap-5/search-form.blade.php b/resources/views/common/search-form.blade.php similarity index 100% rename from resources/views/bootstrap-5/search-form.blade.php rename to resources/views/common/search-form.blade.php diff --git a/resources/views/bootstrap-5/table/cell.blade.php b/resources/views/common/table/cell.blade.php similarity index 100% rename from resources/views/bootstrap-5/table/cell.blade.php rename to resources/views/common/table/cell.blade.php diff --git a/resources/views/bootstrap-5/table/empty-row.blade.php b/resources/views/common/table/empty-row.blade.php similarity index 100% rename from resources/views/bootstrap-5/table/empty-row.blade.php rename to resources/views/common/table/empty-row.blade.php diff --git a/resources/views/bootstrap-5/table/heading.blade.php b/resources/views/common/table/heading.blade.php similarity index 100% rename from resources/views/bootstrap-5/table/heading.blade.php rename to resources/views/common/table/heading.blade.php diff --git a/resources/views/material-admin-26/accordion.blade.php b/resources/views/material-admin-26/accordion.blade.php deleted file mode 100644 index a40a4c7..0000000 --- a/resources/views/material-admin-26/accordion.blade.php +++ /dev/null @@ -1,32 +0,0 @@ -
merge(['class' => 'accordion', 'role' => 'tablist', 'id' => $id]) !!}> - @foreach($items as $name => $item) - @php - $collapse_id = $generateCollapseIdByName($name); - $slot_name = $generateSlotByName($name); - $title_slot = $slot_name . 'Header'; - @endphp - - - @isset(${$title_slot}) - - {{ ${$title_slot} }} - - @endisset - - @isset(${$slot_name}) - {{ ${$slot_name} }} - @else - {!! nl2br(e($item['content'] ?? '')) !!} - @endisset - - @endforeach - - {{ $slot }} -
diff --git a/resources/views/material-admin-26/accordion/collapse.blade.php b/resources/views/material-admin-26/accordion/collapse.blade.php deleted file mode 100644 index 46c4278..0000000 --- a/resources/views/material-admin-26/accordion/collapse.blade.php +++ /dev/null @@ -1,13 +0,0 @@ -
class([ - 'collapse', - 'show' => $show -]) !!} - data-parent="#{{ $parent }}"> -
- @if($content) - {!! nl2br(e($content)) !!} - @else - {{ $slot }} - @endif -
-
diff --git a/resources/views/material-admin-26/accordion/header.blade.php b/resources/views/material-admin-26/accordion/header.blade.php deleted file mode 100644 index db63404..0000000 --- a/resources/views/material-admin-26/accordion/header.blade.php +++ /dev/null @@ -1,8 +0,0 @@ -
merge(['class' => 'accordion__title']) !!} - data-toggle="collapse" - data-target="#{{ $target }}" - aria-expanded="{{ $show ? 'true' : 'false' }}" - aria-controls="{{ $target }}"> - @if($slot->isNotEmpty()){{ $slot }}@else{{ $title }}@endif -
- diff --git a/resources/views/material-admin-26/alert.blade.php b/resources/views/material-admin-26/alert.blade.php deleted file mode 100644 index 4561720..0000000 --- a/resources/views/material-admin-26/alert.blade.php +++ /dev/null @@ -1,34 +0,0 @@ -@php - $classes = 'alert alert-' . $type; - - if ($dismissible) { - $classes .= ' alert-dismissible fade show'; - } -@endphp - -
merge(['class' => $classes]) }} role="alert"> - @if($icon) -
- -
- @if(isset($heading) && $heading) -

{{ $heading }}

- @endisset - - {!! $slot !!} -
-
- @else - @if(isset($heading) && $heading) -

{{ $heading }}

- @endisset - - {!! $slot !!} - @endif - - @if($dismissible) - - @endif -
diff --git a/resources/views/material-admin-26/bulk-actions.blade.php b/resources/views/material-admin-26/bulk-actions.blade.php deleted file mode 100644 index 97de80a..0000000 --- a/resources/views/material-admin-26/bulk-actions.blade.php +++ /dev/null @@ -1,38 +0,0 @@ -@php - $select_classes = 'select2-basic form-control mb-4 '; - $actions_error_class = $hasError('action') ? 'is-invalid' : ''; - $model_error_classes = $hasError($model) ? 'is-invalid' : ''; - $select_classes= implode(' ', [$select_classes, $actions_error_class, $model_error_classes]); -@endphp - -@unless( empty($actions) ) -
-
-
- -
-
-
-
- - {{ __('Apply') }} - -
-
-
- - -@endunless diff --git a/resources/views/material-admin-26/button-group.blade.php b/resources/views/material-admin-26/button-group.blade.php deleted file mode 100644 index cefd092..0000000 --- a/resources/views/material-admin-26/button-group.blade.php +++ /dev/null @@ -1,5 +0,0 @@ -
merge([ - 'class' => 'button-group' . ($inline ? ' inline-btn-group' : '') - ]) !!} ->{!! $slot !!}
diff --git a/resources/views/material-admin-26/button.blade.php b/resources/views/material-admin-26/button.blade.php deleted file mode 100644 index 992c14b..0000000 --- a/resources/views/material-admin-26/button.blade.php +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/resources/views/material-admin-26/card.blade.php b/resources/views/material-admin-26/card.blade.php deleted file mode 100644 index 3e33dce..0000000 --- a/resources/views/material-admin-26/card.blade.php +++ /dev/null @@ -1,35 +0,0 @@ -
merge([ - 'class' => 'card', - ]) !!} -> - {{ $image_top ?? '' }} - - @if(! empty($header)) - - {{ $header }} - - @endif - -
- @if(! empty($title)) - - {{ $title }} - - @endif - - @if(! empty($subtitle)) - - {{ $subtitle }} - - @endif - - {!! $slot !!} -
- - @if(! empty($footer)) - - {{ $footer }} - - @endif -
diff --git a/resources/views/material-admin-26/card/footer.blade.php b/resources/views/material-admin-26/card/footer.blade.php deleted file mode 100644 index b275bfb..0000000 --- a/resources/views/material-admin-26/card/footer.blade.php +++ /dev/null @@ -1,3 +0,0 @@ -
merge(['class' => 'card-footer']) !!}> - {!! $slot !!} -
diff --git a/resources/views/material-admin-26/card/header.blade.php b/resources/views/material-admin-26/card/header.blade.php deleted file mode 100644 index 1ab24f5..0000000 --- a/resources/views/material-admin-26/card/header.blade.php +++ /dev/null @@ -1,3 +0,0 @@ -
merge(['class' => 'card-header']) !!}> - {!! $slot !!} -
diff --git a/resources/views/material-admin-26/card/subtitle.blade.php b/resources/views/material-admin-26/card/subtitle.blade.php deleted file mode 100644 index 63a6a2d..0000000 --- a/resources/views/material-admin-26/card/subtitle.blade.php +++ /dev/null @@ -1,3 +0,0 @@ -
merge(['class' => 'card-subtitle']) !!}> - {!! $slot !!} -
diff --git a/resources/views/material-admin-26/card/title.blade.php b/resources/views/material-admin-26/card/title.blade.php deleted file mode 100644 index 8a450e0..0000000 --- a/resources/views/material-admin-26/card/title.blade.php +++ /dev/null @@ -1,3 +0,0 @@ -

merge(['class' => 'card-title']) !!}> - {!! $slot !!} -

diff --git a/resources/views/material-admin-26/checkbox.blade.php b/resources/views/material-admin-26/checkbox.blade.php deleted file mode 100644 index b2ea974..0000000 --- a/resources/views/material-admin-26/checkbox.blade.php +++ /dev/null @@ -1,40 +0,0 @@ - -
$inline, - 'mb-2' => ! $inline, - ])> - merge([ - 'class' => ($hasErrorAndShow($name) ? 'is-invalid' : '') - ]) !!} - id="{{ $attributes->get('id') ?: $id() }}" - name="{{ $name }}" - type="checkbox" - value="{{ $value }}" - @required($required) - @checked($checked) - /> - - @if($slot->isNotEmpty()){{ $slot }}@endif -
- - @if(! empty($help)) - - {{ $help }} - - @endif - - @if($hasErrorAndShow($name)) - - @endif - - @if($showJsErrors) - - @endif -
diff --git a/resources/views/material-admin-26/conditional-link.blade.php b/resources/views/material-admin-26/conditional-link.blade.php deleted file mode 100644 index 3f5013f..0000000 --- a/resources/views/material-admin-26/conditional-link.blade.php +++ /dev/null @@ -1,24 +0,0 @@ -@if($showLink) -merge([ - 'href' => $url -]) }}> -@endif - @if($slot->isNotEmpty()) - {{ $slot }} - @elseif($isAdminModel()) - {{ $value->admin_link_name }} - @else - @if($isStatusEnum()) - - @elseif($multiline) - {!! nl2br(e($value ?: trans('forms::strings.blank'))) !!} - @elseif(is_array($value)) - {{ implode(trans('forms::strings.table_array_separator'), $value) }} - @else - {{ $formatValue() }} - @endif - @endif -@if($showLink) - -@endif - diff --git a/resources/views/material-admin-26/conditional-wrapper.blade.php b/resources/views/material-admin-26/conditional-wrapper.blade.php deleted file mode 100644 index 41c22da..0000000 --- a/resources/views/material-admin-26/conditional-wrapper.blade.php +++ /dev/null @@ -1,20 +0,0 @@ -
- {{ $slot }} -
diff --git a/resources/views/material-admin-26/cursor-pagination.blade.php b/resources/views/material-admin-26/cursor-pagination.blade.php deleted file mode 100644 index fa2314a..0000000 --- a/resources/views/material-admin-26/cursor-pagination.blade.php +++ /dev/null @@ -1,18 +0,0 @@ -@if ($paginator->hasPages()) -
- - @if ($paginator->onFirstPage()) - - @else - - @endif - - - @if ($paginator->hasMorePages()) - - @else - - @endif - -
-@endif diff --git a/resources/views/material-admin-26/errors.blade.php b/resources/views/material-admin-26/errors.blade.php deleted file mode 100644 index 4819bf2..0000000 --- a/resources/views/material-admin-26/errors.blade.php +++ /dev/null @@ -1,5 +0,0 @@ -@error($name, $bag) -
merge(['class' => 'invalid-feedback']) !!}> - {{ $message }} -
-@enderror diff --git a/resources/views/material-admin-26/file.blade.php b/resources/views/material-admin-26/file.blade.php deleted file mode 100644 index 819f0e7..0000000 --- a/resources/views/material-admin-26/file.blade.php +++ /dev/null @@ -1,72 +0,0 @@ - -
(bool) $value, - 'fileinput-new' => empty($value), - 'disabled' => $disabled, - 'is-invalid' => $hasError($name), - ]) - @if(! $disabled) - data-provides="fileinput{{ $upload ? '-upload' : '' }}" - @endif - > - - @if($upload) - -   - {{ trans('forms::strings.fileinput_upload_file') }} - - @else - {{ trans('forms::strings.fileinput_select_file') }} - {{ trans('forms::strings.fileinput_change_file') }} - @endif - merge([ - 'class' => ($hasError($name) ? 'is-invalid' : ''), - 'required' => $required, - 'disabled' => $disabled - ]) !!} - type="file" - accept="{{ implode(',', $mimetypes) }}" - name="{{ $name }}" - @if($label && ! $attributes->get('id')) - id="{{ $id() }}" - @endif - @if($upload && $maxSize) - data-max-file-size="{{ $maxSize }}" - @endif - /> - - - @unless(empty($value)) - - {{ $fileName ?: $value }} - - @endunless - - × -
- - @if($showHint || (! empty($help))) - - @empty($help) - {{ $getHint() }} - @else - {!! $help !!} - @endempty - - @endif - - @if($hasErrorAndShow($name)) - - @endif - - @if($showJsErrors) - - @endif -
diff --git a/resources/views/material-admin-26/filter-submit.blade.php b/resources/views/material-admin-26/filter-submit.blade.php deleted file mode 100644 index 18355e4..0000000 --- a/resources/views/material-admin-26/filter-submit.blade.php +++ /dev/null @@ -1,68 +0,0 @@ -
- {{ $before ?? '' }} - - - {{ __('Filter') }} - - - @if(! empty($export)) - @if(is_array($export)) -
- - - {{ __('Export') }} - - - - - - -
- @else - - {{ __('Export') }} - - @endif - @endif - - {{ $after ?? '' }} - - - {{ __('Clear') }} - - - {{ $slot }} -
diff --git a/resources/views/material-admin-26/filter.blade.php b/resources/views/material-admin-26/filter.blade.php deleted file mode 100644 index 13166bb..0000000 --- a/resources/views/material-admin-26/filter.blade.php +++ /dev/null @@ -1,26 +0,0 @@ -@php - $filter_id = $attributes->get('id') ?? $id(); -@endphp - -
-

{{ __('Filter') }}

-
- - -
- -
- {{ $slot }} -
- - - - -
diff --git a/resources/views/material-admin-26/form-close.blade.php b/resources/views/material-admin-26/form-close.blade.php deleted file mode 100644 index 5582354..0000000 --- a/resources/views/material-admin-26/form-close.blade.php +++ /dev/null @@ -1 +0,0 @@ - diff --git a/resources/views/material-admin-26/form-group.blade.php b/resources/views/material-admin-26/form-group.blade.php deleted file mode 100644 index 641ea74..0000000 --- a/resources/views/material-admin-26/form-group.blade.php +++ /dev/null @@ -1,24 +0,0 @@ -@if($wrap) -
merge(['class' => ($floating ? 'form-group form-group--float' : ($inline ? 'row' : 'form-group'))]) !!}> - @if((! $floating) && $showLabel) - - @endif - - @if($inline && (! $floating)) -
-
- @endif -@endif - {!! $slot !!} -@if($wrap) - @if($inline && (! $floating)) -
-
- @endif - - @if($floating) - - @endif -
-@endif - diff --git a/resources/views/material-admin-26/form-open.blade.php b/resources/views/material-admin-26/form-open.blade.php deleted file mode 100644 index a899fed..0000000 --- a/resources/views/material-admin-26/form-open.blade.php +++ /dev/null @@ -1,16 +0,0 @@ -
- @unless(in_array($method, ['HEAD', 'GET', 'OPTIONS'])) - @csrf - @endunless - - @if($spoofMethod) - @method($method) - @endif diff --git a/resources/views/material-admin-26/form.blade.php b/resources/views/material-admin-26/form.blade.php deleted file mode 100644 index 50e7533..0000000 --- a/resources/views/material-admin-26/form.blade.php +++ /dev/null @@ -1,19 +0,0 @@ - - @unless(in_array($method, ['HEAD', 'GET', 'OPTIONS'])) - @csrf - @endunless - - @if($spoofMethod) - @method($method) - @endif - - {!! $slot !!} -
diff --git a/resources/views/material-admin-26/image.blade.php b/resources/views/material-admin-26/image.blade.php deleted file mode 100644 index e6ea6a6..0000000 --- a/resources/views/material-admin-26/image.blade.php +++ /dev/null @@ -1,93 +0,0 @@ - -
(bool) $value, - 'fileinput-new' => empty($value), - 'is-invalid' => $hasError($name), - 'disabled' => $disabled, - ]) - @if(! $disabled) - data-provides="fileinput{{ $upload ? '-upload' : '' }}" - @endif - > - -
-
-
-
$cover || $circle, - 'rounded-circle' => $circle, - ]) - @if(! $disabled) - data-trigger="fileinput" - @endif - > -
- -
- -
- - {{ trans('forms::strings.imageinput_select_image') }} -
-
-
-
-
- -
- - -   - {{ $upload ? trans('forms::strings.fileinput_upload_file') : trans('forms::strings.fileinput_select_file') }} - - @if(! $upload) - - {{ trans('forms::strings.fileinput_change_file') }} - - @endif - merge([ - 'class' => ($hasError($name) ? 'is-invalid' : ''), - 'required' => $required, - 'disabled' => $disabled - ]) !!} - type="file" - accept="{{ implode(',', $mimetypes) }}" - name="{{ $name }}" - @if($label && ! $attributes->get('id')) - id="{{ $id() }}" - @endif - /> - - - {{ __('Remove') }} - -
-
- - @if($showHint || (! empty($help))) - - @empty($help) - {{ $getImageHint() }}
- {{ $getHint() }} - @else - {!! $help !!} - @endempty -
- @endif - - @if($hasErrorAndShow($name)) - - @endif - - @if($showJsErrors) - - @endif -
diff --git a/resources/views/material-admin-26/input-help.blade.php b/resources/views/material-admin-26/input-help.blade.php deleted file mode 100644 index 7eed01e..0000000 --- a/resources/views/material-admin-26/input-help.blade.php +++ /dev/null @@ -1,3 +0,0 @@ -merge(['class' => 'form-text text-muted']) !!}> - {!! $slot !!} - diff --git a/resources/views/material-admin-26/input.blade.php b/resources/views/material-admin-26/input.blade.php deleted file mode 100644 index e4d50fd..0000000 --- a/resources/views/material-admin-26/input.blade.php +++ /dev/null @@ -1,78 +0,0 @@ - - @if(! $floating) -
- @endif - @if($isDateInput() || (! empty($prepend)) || (! empty($append))) -
- @if($isDateInput() || (! empty($prepend))) -
- @if($isDateInput()) - - - - @elseif(! empty($prepend)) - {{ $prepend }} - @endif -
- @endif - @endif - - merge([ - 'class' => 'form-control' . ($type === 'color' ? ' form-control-color' : '') . ($hasError($name) ? ' is-invalid' : '') . ($isDateInput() ? ' ' . $datePickerClass() : ''), - 'required' => $required - ] + $getDefaultAttributes()) !!} - type="{{ $type }}" - value="{{ $value ?? ($type === 'color' ? '#000000' : '') }}" - name="{{ $name }}" - @if($label && ! $attributes->get('id')) - id="{{ $id() }}" - @endif - {{-- Placeholder is required as of writing --}} - @if($floating || $placeholder) - @if($placeholder) - placeholder="{{ $placeholder }}" - @else - placeholder=" " - @endif - @endif - /> - @if($showLabel) - - @endif - - - @if($isDateInput() || (! empty($prepend)) || (! empty($append))) - @if($isDateInput() || (! empty($append))) -
- @if($isDateInput()) - - @elseif(! empty($append)) - {{ $append }} - @endif -
- @endif -
- @endif - @if(! $floating) -
- @endif - - @if(! empty($help)) - - {{ $help }} - - @endif - - @if($hasErrorAndShow($name)) - - @endif - - @if($showJsErrors) - - @endif -
diff --git a/resources/views/material-admin-26/js-errors.blade.php b/resources/views/material-admin-26/js-errors.blade.php deleted file mode 100644 index f85a7d5..0000000 --- a/resources/views/material-admin-26/js-errors.blade.php +++ /dev/null @@ -1,3 +0,0 @@ -
    merge(['class' => 'invalid-feedback ' . $name . '-error']) !!}> - {{ $slot }} -
diff --git a/resources/views/material-admin-26/label-required.blade.php b/resources/views/material-admin-26/label-required.blade.php deleted file mode 100644 index 3ebd33e..0000000 --- a/resources/views/material-admin-26/label-required.blade.php +++ /dev/null @@ -1,3 +0,0 @@ -@if($text) - merge(['class' => 'required']) !!}>{{ $text }} -@endif diff --git a/resources/views/material-admin-26/label.blade.php b/resources/views/material-admin-26/label.blade.php deleted file mode 100644 index 7a53d5e..0000000 --- a/resources/views/material-admin-26/label.blade.php +++ /dev/null @@ -1,11 +0,0 @@ -@if($label || $blankLabel) - -@endif diff --git a/resources/views/material-admin-26/modal.blade.php b/resources/views/material-admin-26/modal.blade.php deleted file mode 100644 index 2f43c1d..0000000 --- a/resources/views/material-admin-26/modal.blade.php +++ /dev/null @@ -1,23 +0,0 @@ -@props(['title' => '']) - -
merge(['class' => 'modal fade', 'tabindex' => -1]) }}> - -
diff --git a/resources/views/material-admin-26/nav-tabs.blade.php b/resources/views/material-admin-26/nav-tabs.blade.php deleted file mode 100644 index b7a6305..0000000 --- a/resources/views/material-admin-26/nav-tabs.blade.php +++ /dev/null @@ -1,25 +0,0 @@ - diff --git a/resources/views/material-admin-26/no-items.blade.php b/resources/views/material-admin-26/no-items.blade.php deleted file mode 100644 index e92cc2e..0000000 --- a/resources/views/material-admin-26/no-items.blade.php +++ /dev/null @@ -1,18 +0,0 @@ -
-
- -

- @if($title){{ $title }}
@endif - {{ $message }} -

- @if($showCreate) - @if($slot->isNotEmpty()) - {{ $slot }} - @else - - {{ __('Create New') }} - - @endif - @endif -
-
diff --git a/resources/views/material-admin-26/pagination.blade.php b/resources/views/material-admin-26/pagination.blade.php deleted file mode 100644 index b799f61..0000000 --- a/resources/views/material-admin-26/pagination.blade.php +++ /dev/null @@ -1,48 +0,0 @@ -@if($paginator->count()) -
- {{ - trans_choice(__('Showing :count from total :total entry|Showing :count from total :total entries', - ['count' => $paginator->count(), - 'total' => $paginator->total()] - ), $paginator->total()) }} -
-@endif -@if ($paginator->hasPages()) -
- - @if ($paginator->onFirstPage()) - - @else - - @endif - - - @foreach ($elements as $element) - - @if (is_string($element)) - - @endif - - - @if (is_array($element)) - - @foreach ($element as $page => $url) - @if ($page == $paginator->currentPage()) - {{ $page }} - @else - {{ $page }} - @endif - @endforeach - - @endif - @endforeach - - - @if ($paginator->hasMorePages()) - - @else - - @endif - -
-@endif diff --git a/resources/views/material-admin-26/per-page.blade.php b/resources/views/material-admin-26/per-page.blade.php deleted file mode 100644 index 7ddadbf..0000000 --- a/resources/views/material-admin-26/per-page.blade.php +++ /dev/null @@ -1,9 +0,0 @@ -@php -$selected_per_page = $per_page ?? request('per_page', \Javaabu\Forms\Support\Settings::get('per_page', 20)); - -if (! in_array($selected_per_page, $amounts)) { - $amounts[$selected_per_page] = $selected_per_page; -} -@endphp - - diff --git a/resources/views/material-admin-26/radio.blade.php b/resources/views/material-admin-26/radio.blade.php deleted file mode 100644 index d9e59eb..0000000 --- a/resources/views/material-admin-26/radio.blade.php +++ /dev/null @@ -1,40 +0,0 @@ - -
$inline, - 'mb-2' => ! $inline, - ])> - merge([ - 'class' => ($hasErrorAndShow($name) ? 'is-invalid' : '') - ]) !!} - id="{{ $attributes->get('id') ?: $id() }}" - name="{{ $name }}" - type="radio" - value="{{ $value }}" - @required($required) - @checked($checked) - /> - - @if($slot->isNotEmpty()){{ $slot }}@endif -
- - @if(! empty($help)) - - {{ $help }} - - @endif - - @if($hasErrorAndShow($name)) - - @endif - - @if($showJsErrors) - - @endif -
diff --git a/resources/views/material-admin-26/search-form.blade.php b/resources/views/material-admin-26/search-form.blade.php deleted file mode 100644 index 9268411..0000000 --- a/resources/views/material-admin-26/search-form.blade.php +++ /dev/null @@ -1,12 +0,0 @@ - -
- - -
-
diff --git a/resources/views/material-admin-26/select.blade.php b/resources/views/material-admin-26/select.blade.php deleted file mode 100644 index d5d9eb7..0000000 --- a/resources/views/material-admin-26/select.blade.php +++ /dev/null @@ -1,146 +0,0 @@ - - @if((! empty($prepend)) || (! empty($append))) -
- @if(! empty($prepend)) -
- {{ $prepend }} -
- @endif - @endif - - - - @if((! empty($prepend)) || (! empty($append))) - @if(! empty($append)) -
- {{ $append }} -
- @endif -
- @endif - - @if(! empty($help)) - - {!! $help !!} - - @endif - - @if($hasErrorAndShow($name)) - - @endif - - @if($showJsErrors) - - @endif -
- -@if($shouldShowSyncField()) - -@endif diff --git a/resources/views/material-admin-26/table.blade.php b/resources/views/material-admin-26/table.blade.php deleted file mode 100644 index 81eb71b..0000000 --- a/resources/views/material-admin-26/table.blade.php +++ /dev/null @@ -1,61 +0,0 @@ -
merge(['class' => 'table-responsive']) !!}> - @if(empty($noBulk)) - @if(isset($bulkForm) && $bulkForm->isNotEmpty()) - -
- {{ $bulkForm }} -
- @endif - @endif - - {{ $beforeTable ?? '' }} - -
- @if(empty($noCheckbox)) -
-
- - -
-
- @endif - - - {{ $beforeHeaders ?? '' }} - - @if(empty($noCheckbox)) - - @endif - {{ $headers ?? '' }} - - {{ $afterHeaders ?? '' }} - - - @if(empty($tbodyOpen)) - - @else - {{ $tbodyOpen }} - @endif - - {{ $rows ?? '' }} - - - {{ $afterTbody ?? '' }} -
-
- - -
-
-
- - @if(empty($noBulk)) - @if(isset($bulkForm) && $bulkForm->isNotEmpty()) - - @endif - @endif -
- -@if(empty($no_pagination)) - {{ $pagination ?? '' }} -@endif diff --git a/resources/views/material-admin-26/table/cell.blade.php b/resources/views/material-admin-26/table/cell.blade.php deleted file mode 100644 index cd445d6..0000000 --- a/resources/views/material-admin-26/table/cell.blade.php +++ /dev/null @@ -1,24 +0,0 @@ -merge([]) }} - @if($showLabel && $name) - data-col="{{ $label ?: $label() }}" - @endif -> - @if($slot->isNotEmpty()) - {{ $slot }} - @elseif($isAdminModel()) - {!! $value->admin_link !!} - @elseif($isAdminModelCollection()) - {!! $value->implode('admin_link', trans('forms::strings.table_array_separator')) !!} - @else - @if($isStatusEnum()) - - @elseif($multiline) - {!! nl2br(e($value ?: trans('forms::strings.blank'))) !!} - @elseif(is_array($value)) - {{ implode(trans('forms::strings.table_array_separator'), $value) }} - @else - {{ $formatValue() }} - @endif - @endif - - diff --git a/resources/views/material-admin-26/table/empty-row.blade.php b/resources/views/material-admin-26/table/empty-row.blade.php deleted file mode 100644 index a5fe8c0..0000000 --- a/resources/views/material-admin-26/table/empty-row.blade.php +++ /dev/null @@ -1,9 +0,0 @@ - - - {{ $slot }} - - diff --git a/resources/views/material-admin-26/table/heading.blade.php b/resources/views/material-admin-26/table/heading.blade.php deleted file mode 100644 index 78062d7..0000000 --- a/resources/views/material-admin-26/table/heading.blade.php +++ /dev/null @@ -1,19 +0,0 @@ -merge([ - 'class' => $sortable ? $addSortClass() : '' - ]) }} -> - @if($slot->isNotEmpty()) - {{ $slot }} - @else - {{ $label }} - @endif - diff --git a/resources/views/material-admin-26/table/row.blade.php b/resources/views/material-admin-26/table/row.blade.php deleted file mode 100644 index 4ad81e9..0000000 --- a/resources/views/material-admin-26/table/row.blade.php +++ /dev/null @@ -1,13 +0,0 @@ -merge([]) }}> - @if(empty($noCheckbox)) - -
- - -
- - @endif - - {{ $slot }} - - diff --git a/resources/views/material-admin-26/tabs.blade.php b/resources/views/material-admin-26/tabs.blade.php deleted file mode 100644 index a264e47..0000000 --- a/resources/views/material-admin-26/tabs.blade.php +++ /dev/null @@ -1,28 +0,0 @@ -
merge(['class' => 'tab-container']) !!}> - - -
- @foreach($tabs as $item) - @isset(${$generateSlotByName($item['name'])}) - - {{ ${$generateSlotByName($item['name'])} }} - - @endisset - @endforeach -
-
diff --git a/resources/views/material-admin-26/tabs/nav-item.blade.php b/resources/views/material-admin-26/tabs/nav-item.blade.php deleted file mode 100644 index 85d0e7b..0000000 --- a/resources/views/material-admin-26/tabs/nav-item.blade.php +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/resources/views/material-admin-26/text-entry.blade.php b/resources/views/material-admin-26/text-entry.blade.php deleted file mode 100644 index dff3c8f..0000000 --- a/resources/views/material-admin-26/text-entry.blade.php +++ /dev/null @@ -1,41 +0,0 @@ -
merge(['class' => 'mb-1'.($inline ? ' row' : '')]) !!}> - @if($showLabel) -
{{ $label ?: $label() }}
- @endif - -
- @if($slot->isNotEmpty()) - {{ $slot }} - @elseif($isAdminModel()) - {!! $value->admin_link !!} - @elseif($isAdminModelCollection()) - {!! $value->implode('admin_link', trans('forms::strings.table_array_separator')) !!} - @else - @if($isStatusEnum()) - - @elseif($isNativeEnum()) - {{ $getEnumLabel() }} - @elseif($multiline) - {!! nl2br(e($value ?: trans('forms::strings.blank'))) !!} - @elseif(is_array($value)) -
    - @foreach($value as $item) -
  • {{ $item }}
  • - @endforeach -
- @elseif($value && $wysiwyg) - {!! $value !!} - @else - {{ empty($value) && (! is_numeric($value)) ? trans('forms::strings.blank') : $value }} - @endif - @endif -
-
diff --git a/resources/views/material-admin-26/textarea.blade.php b/resources/views/material-admin-26/textarea.blade.php deleted file mode 100644 index 04c15ae..0000000 --- a/resources/views/material-admin-26/textarea.blade.php +++ /dev/null @@ -1,49 +0,0 @@ - - @if(! $floating) -
- @endif - - - @if(! $floating) -
- @endif - - @if(! empty($help)) - - {!! $help !!} - - @endif - - @if($hasErrorAndShow($name)) - - @endif - - @if($showJsErrors) - - @endif -
- -@if($wysiwyg) - @pushonce(config('forms.scripts_stack')) - @include('forms::partials.wysiwyg-script') - @endpushonce -@endif diff --git a/resources/views/partials/assets.blade.php b/resources/views/partials/assets.blade.php new file mode 100644 index 0000000..b386dd4 --- /dev/null +++ b/resources/views/partials/assets.blade.php @@ -0,0 +1,8 @@ +{{-- Asset seam: components call this with the assets they need. See docs/advanced-usage/assets.md. --}} +@foreach($assets as $asset) + @if(view()->exists("forms::partials.scripts.{$asset}")) + @pushonce(config('forms.scripts_stack'), "forms-{$asset}") + @include("forms::partials.scripts.{$asset}") + @endpushonce + @endif +@endforeach diff --git a/resources/views/partials/maps-script.blade.php b/resources/views/partials/scripts/maps.blade.php similarity index 100% rename from resources/views/partials/maps-script.blade.php rename to resources/views/partials/scripts/maps.blade.php diff --git a/resources/views/partials/wysiwyg-script.blade.php b/resources/views/partials/scripts/wysiwyg.blade.php similarity index 100% rename from resources/views/partials/wysiwyg-script.blade.php rename to resources/views/partials/scripts/wysiwyg.blade.php diff --git a/scripts/icons.mjs b/scripts/icons.mjs new file mode 100644 index 0000000..bea7043 --- /dev/null +++ b/scripts/icons.mjs @@ -0,0 +1,72 @@ +// Copies the lucide icons the components use into resources/icons/icons.php. +// Run with `pnpm icons` after changing the list below. +import { readFileSync, writeFileSync } from "node:fs" +import { createRequire } from "node:module" +import { dirname, join } from "node:path" + +const icons = [ + "arrow-down", + "arrow-up", + "arrow-up-down", + "calendar", + "check", + "chevron-down", + "chevron-left", + "chevron-right", + "chevron-up", + "circle-alert", + "circle-check", + "circle-x", + "clock", + "download", + "ellipsis", + "external-link", + "eye", + "file", + "file-text", + "image", + "info", + "loader-circle", + "map-pin", + "pencil", + "plus", + "search", + "trash-2", + "triangle-alert", + "upload", + "x", +] + +const require = createRequire(import.meta.url) +const root = join(dirname(require.resolve("lucide-static/package.json")), "icons") +const { version } = require("lucide-static/package.json") + +const entries = icons.map((name) => { + const svg = readFileSync(join(root, `${name}.svg`), "utf8") + const body = svg + .slice(svg.indexOf(">", svg.indexOf("")) + .split("\n") + .map((line) => line.trim()) + .filter(Boolean) + .join("") + .replaceAll(" />", "/>") + + return ` '${name}' => '${body.replaceAll("'", "\\'")}',` +}) + +writeFileSync( + "resources/icons/icons.php", + ` */ + protected array $themes = [ + 'primary' => 'primary', + 'secondary' => 'secondary', + 'success' => 'success', + 'danger' => 'danger', + 'warning' => 'warning', + 'info' => 'info', + 'light' => 'secondary', + 'dark' => 'inverse', + 'accent' => 'accent', + 'inverse' => 'inverse', + ]; + + public function name(): string + { + return 'bootstrap-6'; + } + + public function theme(string $color): string + { + return 'theme-' . ($this->themes[$color] ?? $color); + } + + public function button(string $color, ?string $size = null): string + { + $size_class = $size ? " btn-{$size}" : ''; + + if ($color === 'link') { + return "btn-link{$size_class}"; + } + + if (Str::startsWith($color, 'outline-')) { + return 'btn-outline ' . $this->theme(Str::after($color, 'outline-')) . $size_class; + } + + if ($color === 'light') { + return 'btn-subtle ' . $this->theme($color) . $size_class; + } + + return 'btn-solid ' . $this->theme($color) . $size_class; + } + + public function badge(string $color): string + { + return 'badge ' . $this->theme($color); + } + + public function alert(string $type): string + { + return 'alert ' . $this->theme($type); + } +} diff --git a/src/Frameworks/Framework.php b/src/Frameworks/Framework.php new file mode 100644 index 0000000..31d1e41 --- /dev/null +++ b/src/Frameworks/Framework.php @@ -0,0 +1,28 @@ +) and size (sm, lg). + */ + public function button(string $color, ?string $size = null): string; + + /** + * Classes for a status badge of the given colour. + */ + public function badge(string $color): string; + + /** + * Classes for an alert of the given type. + */ + public function alert(string $type): string; +} diff --git a/src/Frameworks/Frameworks.php b/src/Frameworks/Frameworks.php new file mode 100644 index 0000000..5f19ae4 --- /dev/null +++ b/src/Frameworks/Frameworks.php @@ -0,0 +1,51 @@ +> */ + protected static array $frameworks = [ + 'onu' => Onu::class, + 'bootstrap-6' => Bootstrap6::class, + ]; + + /** @var array */ + protected static array $instances = []; + + /** + * Registers a framework, so components can render with framework="$name" + * once its views exist in resources/views/vendor/forms/$name. + * + * @param class-string $framework + */ + public static function register(string $name, string $framework): void + { + static::$frameworks[$name] = $framework; + + unset(static::$instances[$name]); + } + + public static function get(string $name): Framework + { + if (isset(static::$instances[$name])) { + return static::$instances[$name]; + } + + $framework = static::$frameworks[$name] ?? null; + + if (! $framework) { + throw new InvalidArgumentException("Unknown forms framework [{$name}]. Supported: " . implode(', ', static::names()) . '.'); + } + + return static::$instances[$name] = app($framework); + } + + /** @return array */ + public static function names(): array + { + return array_keys(static::$frameworks); + } +} diff --git a/src/Frameworks/Onu.php b/src/Frameworks/Onu.php new file mode 100644 index 0000000..6986d1a --- /dev/null +++ b/src/Frameworks/Onu.php @@ -0,0 +1,91 @@ +|null */ + protected ?array $classes = null; + + /** @var array */ + protected array $button_variants = [ + 'primary' => 'default', + 'secondary' => 'secondary', + 'success' => 'success', + 'danger' => 'destructive', + 'warning' => 'warning', + 'info' => 'default', + 'light' => 'outline', + 'dark' => 'secondary', + 'link' => 'link', + ]; + + /** @var array */ + protected array $tones = [ + 'primary' => 'info', + 'info' => 'info', + 'success' => 'success', + 'warning' => 'warning', + 'danger' => 'destructive', + 'secondary' => 'default', + 'light' => 'default', + 'dark' => 'default', + ]; + + public function name(): string + { + return 'onu'; + } + + /** + * Classes Onu renders for a component part, e.g. "input" or "button.destructive.sm". + */ + public function classes(string $key, string $default = ''): string + { + return data_get($this->all(), $key, $default); + } + + /** @return array */ + public function all(): array + { + return $this->classes ??= require __DIR__ . '/../../resources/onu/classes.php'; + } + + public function buttonVariant(string $color): string + { + if (Str::startsWith($color, 'outline-')) { + return 'outline'; + } + + return $this->button_variants[$color] ?? 'default'; + } + + public function tone(string $color): string + { + return $this->tones[$color] ?? 'default'; + } + + public function button(string $color, ?string $size = null): string + { + $variant = $this->buttonVariant($color); + $size = $size ?: 'default'; + + return $this->classes("button.{$variant}.{$size}", $this->classes("button.{$variant}.default")); + } + + public function badge(string $color): string + { + return $this->classes('status.' . $this->tone($color)); + } + + public function alert(string $type): string + { + return $this->classes('alert.' . $this->tone($type)); + } +} diff --git a/src/Support/HandlesValidationErrors.php b/src/Support/HandlesValidationErrors.php index 82db86d..e3f27ba 100644 --- a/src/Support/HandlesValidationErrors.php +++ b/src/Support/HandlesValidationErrors.php @@ -27,7 +27,13 @@ public function hasErrorAndShow(string $name, string $bag = 'default'): bool */ protected function getErrorBag(string $bag = 'default'): MessageBag { - $bags = View::shared('errors', fn () => request()->session()->get('errors', new ViewErrorBag)); + $bags = View::shared('errors', function () { + $request = request(); + + return $request->hasSession() + ? $request->session()->get('errors', new ViewErrorBag) + : new ViewErrorBag; + }); return $bags->getBag($bag); } diff --git a/src/Support/Icons/Svg.php b/src/Support/Icons/Svg.php new file mode 100644 index 0000000..ce321cb --- /dev/null +++ b/src/Support/Icons/Svg.php @@ -0,0 +1,28 @@ +|null */ + protected static ?array $icons = null; + + /** + * The inner markup of a bundled icon, or null when the name isn't bundled. + */ + public static function get(string $name): ?string + { + return static::all()[$name] ?? null; + } + + public static function has(string $name): bool + { + return array_key_exists($name, static::all()); + } + + /** @return array */ + public static function all(): array + { + return static::$icons ??= require __DIR__ . '/../../../resources/icons/icons.php'; + } +} diff --git a/src/Views/Components/Component.php b/src/Views/Components/Component.php index 5a4608e..59845ff 100644 --- a/src/Views/Components/Component.php +++ b/src/Views/Components/Component.php @@ -2,8 +2,11 @@ namespace Javaabu\Forms\Views\Components; +use Illuminate\Support\Facades\View; use Illuminate\Support\Str; use Illuminate\View\Component as BaseComponent; +use Javaabu\Forms\Frameworks\Framework; +use Javaabu\Forms\Frameworks\Frameworks; abstract class Component extends BaseComponent { @@ -38,16 +41,27 @@ public function __construct(string $framework = '') $this->framework = $framework; } + /** + * Resolves a logical icon (date, clear, upload, ...) from the forms.icons config. + */ public function getFrameworkIcon(string $icon): string { - $icon_prefix = $this->frameworkConfig('icon-prefix'); + return $this->frameworkConfig("icons.{$icon}") + ?? config("forms.icons.{$icon}") + ?? $icon; + } - return "$icon_prefix $icon"; + /** + * The framework's class map (button colours, badges, alerts). + */ + public function frameworkClasses(): Framework + { + return Frameworks::get($this->framework); } - public function frameworkConfig(string $config, $default = null) + public function frameworkConfig(string $config, mixed $default = null): mixed { - return config('forms.frameworks.' . $this->framework . '.' . $config, $default); + return config("forms.frameworks.{$this->framework}.{$config}", $default); } public function getView(): string @@ -56,15 +70,19 @@ public function getView(): string } /** - * {@inheritDoc} + * The framework's own view, or the shared one in forms::common when the framework has none. */ public function render() { - $view = $this->getView(); + $view = str_replace('{framework}', $this->framework, $this->getView()); + + if (View::exists($view)) { + return $view; + } - $framework = $this->framework; + $common = str_replace('{framework}', 'common', $this->getView()); - return str_replace('{framework}', $framework, $view); + return View::exists($common) ? $common : $view; } /** diff --git a/src/Views/Components/Date.php b/src/Views/Components/Date.php index d711f74..ecb28ab 100644 --- a/src/Views/Components/Date.php +++ b/src/Views/Components/Date.php @@ -62,10 +62,10 @@ public function __construct( framework: $framework, ); - $this->icon = $icon ?: $this->getFrameworkIcon($this->frameworkConfig('date-icon')); - $this->clearIcon = $clearIcon ?: $this->getFrameworkIcon($this->frameworkConfig('date-clear-icon')); - $this->clearBtnClass = $clearBtnClass ?: $this->frameworkConfig('date-clear-btn-class'); - $this->iconWrapperClass = $iconWrapperClass ?: $this->frameworkConfig('date-icon-wrapper-class'); + $this->icon = $icon ?: $this->getFrameworkIcon('date'); + $this->clearIcon = $clearIcon ?: $this->getFrameworkIcon('clear'); + $this->clearBtnClass = $clearBtnClass ?: $this->frameworkConfig('date_clear_btn_class', ''); + $this->iconWrapperClass = $iconWrapperClass ?: $this->frameworkConfig('date_icon_wrapper_class', ''); } public function datePickerClass(): string diff --git a/src/Views/Components/Datetime.php b/src/Views/Components/Datetime.php index 98b046c..df802c8 100644 --- a/src/Views/Components/Datetime.php +++ b/src/Views/Components/Datetime.php @@ -56,7 +56,7 @@ public function __construct( ); if (! $icon) { - $this->icon = $this->getFrameworkIcon($this->frameworkConfig('datetime-icon')); + $this->icon = $this->getFrameworkIcon('datetime'); } } diff --git a/src/Views/Components/File.php b/src/Views/Components/File.php index 6d64ce3..446da37 100644 --- a/src/Views/Components/File.php +++ b/src/Views/Components/File.php @@ -95,9 +95,9 @@ public function __construct( framework: $framework ); - $this->downloadIcon = $downloadIcon ?: $this->getFrameworkIcon($this->frameworkConfig('file-download-icon')); - $this->uploadIcon = $uploadIcon ?: $this->getFrameworkIcon($this->frameworkConfig('file-upload-icon')); - $this->clearIcon = $clearIcon ?: $this->getFrameworkIcon($this->frameworkConfig('file-clear-icon')); + $this->downloadIcon = $downloadIcon ?: $this->getFrameworkIcon('download'); + $this->uploadIcon = $uploadIcon ?: $this->getFrameworkIcon('upload'); + $this->clearIcon = $clearIcon ?: $this->getFrameworkIcon('clear'); } public function getHint(): string diff --git a/src/Views/Components/FormGroup.php b/src/Views/Components/FormGroup.php index 9936b57..5c5a3bf 100644 --- a/src/Views/Components/FormGroup.php +++ b/src/Views/Components/FormGroup.php @@ -50,7 +50,7 @@ public function __construct( $this->wrap = $wrap; $this->showLabel = $showLabel; - $this->inlineInputClass = $inlineInputClass ?: $this->frameworkConfig('inline-input-class'); + $this->inlineInputClass = $inlineInputClass ?: $this->frameworkConfig('inline_input_class', ''); } public function label(): string diff --git a/src/Views/Components/Icon.php b/src/Views/Components/Icon.php new file mode 100644 index 0000000..178b9c4 --- /dev/null +++ b/src/Views/Components/Icon.php @@ -0,0 +1,37 @@ + when given CSS classes. + * + * The name can be a bundled icon ("calendar"), a logical icon from forms.icons ("date"), + * or CSS classes ("fa-regular fa-calendar"). + */ + public function __construct( + public string $name, + string $framework = '', + ) { + parent::__construct($framework); + + $this->icon = Svg::has($name) ? $name : $this->getFrameworkIcon($name); + } + + public function isSvg(): bool + { + return Svg::has($this->icon); + } + + public function svg(): string + { + return Svg::get($this->icon) ?? ''; + } +} diff --git a/src/Views/Components/Image.php b/src/Views/Components/Image.php index 022c56c..e03dd47 100644 --- a/src/Views/Components/Image.php +++ b/src/Views/Components/Image.php @@ -76,7 +76,7 @@ public function __construct( framework: $framework ); - $this->icon = $icon ?: $this->getFrameworkIcon($this->frameworkConfig('image-icon')); + $this->icon = $icon ?: $this->getFrameworkIcon('image'); if ($this->circle) { $aspectRatio = 1; diff --git a/src/Views/Components/Label.php b/src/Views/Components/Label.php index ca48679..3942bb3 100644 --- a/src/Views/Components/Label.php +++ b/src/Views/Components/Label.php @@ -40,7 +40,7 @@ public function __construct( $this->floating = $floating; - $this->inlineLabelClass = $inlineLabelClass ?: $this->frameworkConfig('inline-label-class'); + $this->inlineLabelClass = $inlineLabelClass ?: $this->frameworkConfig('inline_label_class', ''); } public function label(): string diff --git a/src/Views/Components/Modal.php b/src/Views/Components/Modal.php index 2091fc1..86af242 100644 --- a/src/Views/Components/Modal.php +++ b/src/Views/Components/Modal.php @@ -19,6 +19,7 @@ public function __construct( string $id = '', string $title = '', ?string $modalSizeClass = null, + public string $size = 'lg', string $framework = '' ) { parent::__construct($framework); diff --git a/src/Views/Components/NoItems.php b/src/Views/Components/NoItems.php index 28d4333..bae3945 100644 --- a/src/Views/Components/NoItems.php +++ b/src/Views/Components/NoItems.php @@ -41,7 +41,7 @@ public function __construct( $this->createAction = $createAction; $this->modelType = $modelType; - $this->icon = $icon ?: $this->getFrameworkIcon($this->frameworkConfig('no-items-icon')); + $this->icon = $icon ?: $this->getFrameworkIcon('no_items'); $this->showCreate = is_null($showCreate) ? ($this->model && auth()->user() ? auth()->user()->can('create', $this->model) : false) : $showCreate; diff --git a/src/Views/Components/SearchForm.php b/src/Views/Components/SearchForm.php index b5cd48e..3953dd4 100644 --- a/src/Views/Components/SearchForm.php +++ b/src/Views/Components/SearchForm.php @@ -31,6 +31,6 @@ public function __construct( parent::__construct($method, $model, $files, $framework); - $this->icon = $icon ?: $this->getFrameworkIcon($this->frameworkConfig('search-icon')); + $this->icon = $icon ?: $this->getFrameworkIcon('search'); } } diff --git a/src/Views/Components/TextEntry.php b/src/Views/Components/TextEntry.php index 35eaee6..432988f 100644 --- a/src/Views/Components/TextEntry.php +++ b/src/Views/Components/TextEntry.php @@ -55,7 +55,7 @@ public function __construct( $this->multiline = $multiline; $this->value = ! is_null($value) ? $value : ($name ? $this->getBoundValue($model, $name) : ''); - $this->inlineEntryLabelClass = $inlineEntryLabelClass ?: $this->frameworkConfig('inline-entry-label-class'); - $this->inlineEntryClass = $inlineEntryClass ?: $this->frameworkConfig('inline-entry-class'); + $this->inlineEntryLabelClass = $inlineEntryLabelClass ?: $this->frameworkConfig('inline_entry_label_class', ''); + $this->inlineEntryClass = $inlineEntryClass ?: $this->frameworkConfig('inline_entry_class', ''); } } diff --git a/src/Views/Components/Time.php b/src/Views/Components/Time.php index 4319950..9798a89 100644 --- a/src/Views/Components/Time.php +++ b/src/Views/Components/Time.php @@ -54,7 +54,7 @@ public function __construct( ); if (! $icon) { - $this->icon = $this->getFrameworkIcon($this->frameworkConfig('time-icon')); + $this->icon = $this->getFrameworkIcon('time'); } } diff --git a/tests/Feature/AccordionTest.php b/tests/Feature/AccordionTest.php index bf32fb8..e795c8f 100644 --- a/tests/Feature/AccordionTest.php +++ b/tests/Feature/AccordionTest.php @@ -3,257 +3,188 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class AccordionTest extends TestCase { - public function test_it_can_generate_bootstrap_5_accordion_header() + #[Test] + public function it_can_generate_bootstrap_6_accordion_header() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('accordion-header'); $this->visit('/accordion-header') - ->seeElement('h2.accordion-header#item-1') + ->seeElement('summary.accordion-header#item-1') ->within('.accordion-header#item-1', function () { - $this->seeElement('button.accordion-button[data-bs-toggle="collapse"][data-bs-target="#collapseOne"][aria-expanded="true"][aria-controls="collapseOne"]') - ->seeInElement('.accordion-button', 'Accordion Item #1'); + $this->seeElement('svg.accordion-icon') + ->see('Accordion Item #1'); }) - ->seeElement('h2.accordion-header#item-2') + ->seeElement('summary.accordion-header#item-2') ->within('.accordion-header#item-2', function () { - $this->seeElement('button.accordion-button[data-bs-toggle="collapse"][data-bs-target="#collapseTwo"][aria-expanded="false"][aria-controls="collapseTwo"]') - ->seeInElement('.accordion-button', 'Accordion Item #2'); + $this->seeElement('svg.accordion-icon') + ->see('Accordion Item #2'); }); } - public function test_it_can_generate_material_admin_26_accordion_header() + #[Test] + public function it_can_generate_bootstrap_6_accordion_collapse() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('accordion-header'); - - $this->visit('/accordion-header') - ->seeElement('div.accordion__title#item-1[data-toggle="collapse"][data-target="#collapseOne"][aria-expanded="true"][aria-controls="collapseOne"]') - ->seeInElement('.accordion__title#item-1', 'Accordion Item #1') - ->seeElement('div.accordion__title#item-2[data-toggle="collapse"][data-target="#collapseTwo"][aria-expanded="false"][aria-controls="collapseTwo"]') - ->seeInElement('.accordion__title#item-2', 'Accordion Item #2'); - } - - public function test_it_can_generate_bootstrap_5_accordion_collapse() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('accordion-collapse'); - - $this->visit('/accordion-collapse') - ->seeElement('div.accordion-collapse#item-1.collapse.show[data-bs-parent="#accordionExample"]') - ->seeInElement('.accordion-collapse#item-1', 'Accordion Item #1') - - ->seeElement('div.accordion-collapse#item-2.collapse[data-bs-parent="#accordionExample"]') - ->within('.accordion-collapse#item-2', function () { - $this->seeElement('strong') - ->seeInElement('strong', 'Accordion Item #2'); - }); - - } - - public function test_it_can_generate_material_admin_26_accordion_collapse() - { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('accordion-collapse'); $this->visit('/accordion-collapse') - ->seeElement('div.collapse#item-1.collapse.show[data-parent="#accordionExample"]') - ->seeInElement('.collapse#item-1', 'Accordion Item #1') + ->seeElement('div.accordion-body#item-1[data-accordion="accordionExample"]') + ->seeInElement('.accordion-body#item-1', 'Accordion Item #1') - ->seeElement('div.collapse#item-2.collapse[data-parent="#accordionExample"]') - ->within('.collapse#item-2', function () { + ->seeElement('div.accordion-body#item-2[data-accordion="accordionExample"]') + ->within('.accordion-body#item-2', function () { $this->seeElement('strong') ->seeInElement('strong', 'Accordion Item #2'); }); } - public function test_it_can_generate_bootstrap_5_accordion_item() + #[Test] + public function it_can_generate_bootstrap_6_accordion_item() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('accordion-item'); $this->visit('/accordion-item') - ->seeElement('div.accordion-item#item-1') + ->seeElement('details.accordion-item#item-1[open][name="accordionExample"]') + ->seeElement('details.accordion-item#item-2[name="accordionExample"]') + ->dontSeeElement('details.accordion-item#item-2[open]') + ->seeElement('summary.accordion-header[aria-controls="collapseOne"]') + ->seeElement('details.accordion-item#item-1') ->within('.accordion-item#item-1', function () { - $this->seeElement('h2.accordion-header') + $this->seeElement('summary.accordion-header') ->within('.accordion-header', function () { - $this->seeElement('button.accordion-button[data-bs-toggle="collapse"][data-bs-target="#collapseOne"][aria-expanded="true"][aria-controls="collapseOne"]') - ->seeInElement('.accordion-button', 'Accordion Item #1'); + $this->seeElement('svg.accordion-icon') + ->see('Accordion Item #1'); }); - $this->seeElement('div.accordion-collapse#collapseOne.collapse.show[data-bs-parent="#accordionExample"]') - ->seeInElement('.accordion-collapse#collapseOne', 'First item Body'); + $this->seeElement('div.accordion-body#collapseOne[data-accordion="accordionExample"]') + ->seeInElement('.accordion-body#collapseOne', 'First item Body'); }) - ->seeElement('div.accordion-item#item-2') + ->seeElement('details.accordion-item#item-2') ->within('.accordion-item#item-2', function () { - $this->seeElement('h2.accordion-header') + $this->seeElement('summary.accordion-header') ->within('.accordion-header', function () { - $this->seeElement('button.accordion-button[data-bs-toggle="collapse"][data-bs-target="#collapseTwo"][aria-expanded="false"][aria-controls="collapseTwo"]') - ->seeInElement('.accordion-button', 'Accordion Item #2'); + $this->seeElement('svg.accordion-icon') + ->see('Accordion Item #2'); }); - $this->seeElement('div.accordion-collapse#collapseTwo.collapse[data-bs-parent="#accordionExample"]') - ->seeInElement('.accordion-collapse#collapseTwo', 'Second item Body'); + $this->seeElement('div.accordion-body#collapseTwo[data-accordion="accordionExample"]') + ->seeInElement('.accordion-body#collapseTwo', 'Second item Body'); }); } - public function test_it_can_generate_material_admin_26_accordion_item() + #[Test] + public function it_can_generate_bootstrap_6_accordion_using_named_items() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('accordion-item'); - - $this->visit('/accordion-item') - ->seeElement('div.accordion__item#item-1') - ->within('.accordion__item#item-1', function () { - $this->seeElement('div.accordion__title[data-toggle="collapse"][data-target="#collapseOne"][aria-expanded="true"][aria-controls="collapseOne"]') - ->seeInElement('.accordion__title', 'Accordion Item #1'); - - $this->seeInElement('div.collapse#collapseOne.collapse.show[data-parent="#accordionExample"]', 'First item Body'); - }) - - ->seeElement('div.accordion__item#item-2') - ->within('.accordion__item#item-2', function () { - $this->seeElement('div.accordion__title[data-toggle="collapse"][data-target="#collapseTwo"][aria-expanded="false"][aria-controls="collapseTwo"]') - ->seeInElement('.accordion__title', 'Accordion Item #2'); - - $this->seeInElement('div.collapse#collapseTwo.collapse[data-parent="#accordionExample"]', 'Second item Body'); - }); - - } - - public function test_it_can_generate_bootstrap_5_accordion_using_named_items() - { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('accordion'); $this->visit('/accordion') ->seeElement('div.accordion#accordionExample') ->within('.accordion#accordionExample', function () { - $this->seeElement('div.accordion-item#item-1') + $this->seeElement('details.accordion-item#item-1') ->within('.accordion-item#item-1', function () { - $this->seeElement('h2.accordion-header') + $this->seeElement('summary.accordion-header') ->within('.accordion-header', function () { - $this->seeElement('button.accordion-button[data-bs-toggle="collapse"][data-bs-target="#collapseOne"][aria-expanded="true"][aria-controls="collapseOne"]') - ->seeInElement('.accordion-button', 'Accordion Item #1'); + $this->seeElement('svg.accordion-icon') + ->see('Accordion Item #1'); }); - $this->seeElement('div.accordion-collapse#collapseOne.collapse.show[data-bs-parent="#accordionExample"]') - ->seeInElement('.accordion-collapse#collapseOne', 'First item Body'); + $this->seeElement('div.accordion-body#collapseOne[data-accordion="accordionExample"]') + ->seeInElement('.accordion-body#collapseOne', 'First item Body'); }) - ->seeElement('div.accordion-item#item-2') + ->seeElement('details.accordion-item#item-2') ->within('.accordion-item#item-2', function () { - $this->seeElement('h2.accordion-header') + $this->seeElement('summary.accordion-header') ->within('.accordion-header', function () { - $this->seeElement('button.accordion-button[data-bs-toggle="collapse"][data-bs-target="#collapseTwo"][aria-expanded="false"][aria-controls="collapseTwo"]') - ->seeInElement('.accordion-button', 'Accordion Item #2'); + $this->seeElement('svg.accordion-icon') + ->see('Accordion Item #2'); }); - $this->seeElement('div.accordion-collapse#collapseTwo.collapse[data-bs-parent="#accordionExample"]') - ->seeInElement('.accordion-collapse#collapseTwo', 'Second item Body'); - }); - }); - - } - - public function test_it_can_generate_material_admin_accordion_using_named_items() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('accordion'); - - $this->visit('/accordion') - ->seeElement('div.accordion#accordionExample[role="tablist"]') - ->within('.accordion#accordionExample', function () { - $this->seeElement('div.accordion__item#item-1') - ->within('.accordion__item#item-1', function () { - $this->seeElement('div.accordion__title[data-toggle="collapse"][data-target="#collapseOne"][aria-expanded="true"][aria-controls="collapseOne"]') - ->seeInElement('.accordion__title', 'Accordion Item #1'); - - $this->seeInElement('div.collapse#collapseOne.collapse.show[data-parent="#accordionExample"]', 'First item Body'); - }) - - ->seeElement('div.accordion__item#item-2') - ->within('.accordion__item#item-2', function () { - $this->seeElement('div.accordion__title[data-toggle="collapse"][data-target="#collapseTwo"][aria-expanded="false"][aria-controls="collapseTwo"]') - ->seeInElement('.accordion__title', 'Accordion Item #2'); - - $this->seeInElement('div.collapse#collapseTwo.collapse[data-parent="#accordionExample"]', 'Second item Body'); + $this->seeElement('div.accordion-body#collapseTwo[data-accordion="accordionExample"]') + ->seeInElement('.accordion-body#collapseTwo', 'Second item Body'); }); }); } - public function test_it_can_generate_bootstrap_5_accordion_using_unnamed_items() + #[Test] + public function it_can_generate_bootstrap_6_accordion_using_unnamed_items() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('accordion-unnamed'); $this->visit('/accordion-unnamed') ->seeElement('div.accordion#accordionExample') ->within('.accordion#accordionExample', function () { - $this->seeElement('div.accordion-item#item-1') + $this->seeElement('details.accordion-item#item-1') ->within('.accordion-item#item-1', function () { - $this->seeElement('h2.accordion-header') + $this->seeElement('summary.accordion-header') ->within('.accordion-header', function () { - $this->seeElement('button.accordion-button[data-bs-toggle="collapse"][data-bs-target="#accordionExample-item-0-collapse"][aria-expanded="true"][aria-controls="accordionExample-item-0-collapse"]') - ->seeInElement('.accordion-button', 'Accordion Item #1'); + $this->seeElement('svg.accordion-icon') + ->see('Accordion Item #1'); }); - $this->seeElement('div.accordion-collapse#accordionExample-item-0-collapse.collapse.show[data-bs-parent="#accordionExample"]') - ->seeInElement('.accordion-collapse#accordionExample-item-0-collapse', 'First item Body'); + $this->seeElement('div.accordion-body#accordionExample-item-0-collapse[data-accordion="accordionExample"]') + ->seeInElement('.accordion-body#accordionExample-item-0-collapse', 'First item Body'); }) - ->seeElement('div.accordion-item#item-2') + ->seeElement('details.accordion-item#item-2') ->within('.accordion-item#item-2', function () { - $this->seeElement('h2.accordion-header') + $this->seeElement('summary.accordion-header') ->within('.accordion-header', function () { - $this->seeElement('button.accordion-button[data-bs-toggle="collapse"][data-bs-target="#accordionExample-item-1-collapse"][aria-expanded="false"][aria-controls="accordionExample-item-1-collapse"]') - ->seeInElement('.accordion-button', 'Accordion Item #2'); + $this->seeElement('svg.accordion-icon') + ->see('Accordion Item #2'); }); - $this->seeElement('div.accordion-collapse#accordionExample-item-1-collapse.collapse[data-bs-parent="#accordionExample"]') - ->seeInElement('.accordion-collapse#accordionExample-item-1-collapse', 'Second item Body'); + $this->seeElement('div.accordion-body#accordionExample-item-1-collapse[data-accordion="accordionExample"]') + ->seeInElement('.accordion-body#accordionExample-item-1-collapse', 'Second item Body'); }); }); } - public function test_it_can_generate_bootstrap_5_accordion_using_slot() + #[Test] + public function it_can_generate_bootstrap_6_accordion_using_slot() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('accordion-slot'); $this->visit('/accordion-slot') ->seeElement('div.accordion#accordionExample') ->within('.accordion#accordionExample', function () { - $this->seeElement('div.accordion-item#item-1') + $this->seeElement('details.accordion-item#item-1') ->within('.accordion-item#item-1', function () { - $this->seeElement('h2.accordion-header') + $this->seeElement('summary.accordion-header') ->within('.accordion-header', function () { - $this->seeElement('button.accordion-button[data-bs-toggle="collapse"][data-bs-target="#collapseOne"][aria-expanded="true"][aria-controls="collapseOne"]') - ->seeInElement('.accordion-button', 'Accordion Item #1'); + $this->seeElement('svg.accordion-icon') + ->see('Accordion Item #1'); }); - $this->seeElement('div.accordion-collapse#collapseOne.collapse.show[data-bs-parent="#accordionExample"]') - ->seeInElement('.accordion-collapse#collapseOne', 'First item Body'); + $this->seeElement('div.accordion-body#collapseOne[data-accordion="accordionExample"]') + ->seeInElement('.accordion-body#collapseOne', 'First item Body'); }) - ->seeElement('div.accordion-item#item-2') + ->seeElement('details.accordion-item#item-2') ->within('.accordion-item#item-2', function () { - $this->seeElement('h2.accordion-header') + $this->seeElement('summary.accordion-header') ->within('.accordion-header', function () { - $this->seeElement('button.accordion-button[data-bs-toggle="collapse"][data-bs-target="#collapseTwo"][aria-expanded="false"][aria-controls="collapseTwo"]') - ->seeInElement('.accordion-button', 'Accordion Item #2'); + $this->seeElement('svg.accordion-icon') + ->see('Accordion Item #2'); }); - $this->seeElement('div.accordion-collapse#collapseTwo.collapse[data-bs-parent="#accordionExample"]') - ->seeInElement('.accordion-collapse#collapseTwo', 'Second item Body'); + $this->seeElement('div.accordion-body#collapseTwo[data-accordion="accordionExample"]') + ->seeInElement('.accordion-body#collapseTwo', 'Second item Body'); }); }); diff --git a/tests/Feature/BulkTest.php b/tests/Feature/BulkTest.php index f594743..96766a1 100644 --- a/tests/Feature/BulkTest.php +++ b/tests/Feature/BulkTest.php @@ -3,28 +3,14 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class BulkTest extends TestCase { - public function test_it_can_generated_bulk_actions_for_material_admin_26() + #[Test] + public function it_can_generated_bulk_actions_for_bootstrap_6() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('bulk-actions'); - - $this->visit('/bulk-actions') - ->seeElement('select') - ->seeElement('option[value="approve"]') - ->seeElement('option[value="ban"]') - ->seeElement('option[value="delete"]') - ->seeElement('button[type="submit"]') - ->within('button[type="submit"]', function () { - $this->see('Apply'); - }); - } - - public function test_it_can_generated_bulk_actions_for_bootstrap_5() - { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('bulk-actions'); $this->visit('/bulk-actions') diff --git a/tests/Feature/ButtonTest.php b/tests/Feature/ButtonTest.php index 83ea887..44efbd8 100644 --- a/tests/Feature/ButtonTest.php +++ b/tests/Feature/ButtonTest.php @@ -3,90 +3,53 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class ButtonTest extends TestCase { - public function test_it_can_generate_bootstrap_5_button_group() + #[Test] + public function it_can_generate_bootstrap_6_button_group() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('button-group'); $this->visit('/button-group') ->seeElement('div.btn-group') ->within('div.btn-group', function () { - $this->seeElement('button.btn'); + $this->seeElement('button.btn-solid.theme-primary'); }); } - public function test_it_can_generate_material_admin_26_group() + #[Test] + public function it_can_generate_bootstrap_6_button() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('button-group'); - - $this->visit('/button-group') - ->seeElement('div.button-group.inline-btn-group') - ->within('div.button-group', function () { - $this->seeElement('button.btn'); - }); - } - - public function test_it_can_generate_bootstrap_5_button() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('button'); - - $this->visit('/button') - ->seeElement('button[type="button"].btn.btn-danger') - ->seeInElement('button[type="button"].btn.btn-danger', 'Button'); - } - - public function test_it_can_generate_material_admin_26_button() - { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('button'); $this->visit('/button') - ->seeElement('button[type="button"].btn.btn-danger') - ->seeInElement('button[type="button"].btn.btn-danger', 'Button'); + ->seeElement('button[type="button"].btn-solid.theme-danger') + ->seeInElement('button[type="button"].btn-solid.theme-danger', 'Button'); } - public function test_it_can_generate_bootstrap_5_submit_button() + #[Test] + public function it_can_generate_bootstrap_6_submit_button() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('button-submit'); $this->visit('/button-submit') - ->seeElement('button[type="submit"].btn.btn-danger') - ->seeInElement('button[type="submit"].btn.btn-danger', 'Button'); - } - - public function test_it_can_generate_material_admin_26_submit_button() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('button-submit'); - - $this->visit('/button-submit') - ->seeElement('button[type="submit"].btn.btn-danger') - ->seeInElement('button[type="submit"].btn.btn-danger', 'Button'); - } - - public function test_it_can_generate_bootstrap_5_link_button() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('button-link'); - - $this->visit('/button-link') - ->seeElement('a[href="/test"].btn.btn-danger') - ->seeInElement('a[href="/test"].btn.btn-danger', 'Button'); + ->seeElement('button[type="submit"].btn-solid.theme-danger') + ->seeInElement('button[type="submit"].btn-solid.theme-danger', 'Button'); } - public function test_it_can_generate_material_admin_26_link_button() + #[Test] + public function it_can_generate_bootstrap_6_link_button() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('button-link'); $this->visit('/button-link') - ->seeElement('a[href="/test"].btn.btn-danger') - ->seeInElement('a[href="/test"].btn.btn-danger', 'Button'); + ->seeElement('a[href="/test"].btn-solid.theme-danger') + ->seeInElement('a[href="/test"].btn-solid.theme-danger', 'Button'); } } diff --git a/tests/Feature/CardTest.php b/tests/Feature/CardTest.php index c84dce8..be609d3 100644 --- a/tests/Feature/CardTest.php +++ b/tests/Feature/CardTest.php @@ -3,12 +3,14 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class CardTest extends TestCase { - public function test_it_can_generate_bootstrap_5_card_title() + #[Test] + public function it_can_generate_bootstrap_6_card_title() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-card-title'); $this->visit('/form-card-title') @@ -16,29 +18,10 @@ public function test_it_can_generate_bootstrap_5_card_title() ->seeInElement('h5.card-title', 'Card title'); } - public function test_it_can_generate_material_admin_26_card_title() + #[Test] + public function it_can_generate_bootstrap_6_card_subtitle() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-card-title'); - - $this->visit('/form-card-title') - ->seeElement('h4.card-title') - ->seeInElement('h4.card-title', 'Card title'); - } - - public function test_it_can_generate_bootstrap_5_card_subtitle() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('form-card-subtitle'); - - $this->visit('/form-card-subtitle') - ->seeElement('h6.card-subtitle') - ->seeInElement('h6.card-subtitle', 'Card subtitle'); - } - - public function test_it_can_generate_material_admin_26_card_subtitle() - { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-card-subtitle'); $this->visit('/form-card-subtitle') @@ -46,9 +29,10 @@ public function test_it_can_generate_material_admin_26_card_subtitle() ->seeInElement('h6.card-subtitle', 'Card subtitle'); } - public function test_it_can_generate_bootstrap_5_card_header() + #[Test] + public function it_can_generate_bootstrap_6_card_header() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-card-header'); $this->visit('/form-card-header') @@ -56,19 +40,10 @@ public function test_it_can_generate_bootstrap_5_card_header() ->seeInElement('div.card-header', 'Card header'); } - public function test_it_can_generate_material_admin_26_card_header() + #[Test] + public function it_can_generate_bootstrap_6_card_footer() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-card-header'); - - $this->visit('/form-card-header') - ->seeElement('div.card-header') - ->seeInElement('div.card-header', 'Card header'); - } - - public function test_it_can_generate_bootstrap_5_card_footer() - { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-card-footer'); $this->visit('/form-card-footer') @@ -76,19 +51,10 @@ public function test_it_can_generate_bootstrap_5_card_footer() ->seeInElement('div.card-footer', 'Card footer'); } - public function test_it_can_generate_material_admin_26_card_footer() + #[Test] + public function it_can_generate_bootstrap_6_card() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-card-footer'); - - $this->visit('/form-card-footer') - ->seeElement('div.card-footer') - ->seeInElement('div.card-footer', 'Card footer'); - } - - public function test_it_can_generate_bootstrap_5_card() - { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-card'); $this->visit('/form-card') @@ -107,26 +73,10 @@ public function test_it_can_generate_bootstrap_5_card() }); } - public function test_it_can_generate_bootstrap_5_card_with_header() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('form-card'); - - $this->visit('/form-card') - ->seeElement('div#header') - ->within('div#header', function () { - $this - ->seeElement('div.card') - ->within('div.card', function () { - $this->seeElement('div.card-header.text-primary') - ->seeInElement('div.card-header.text-primary', 'This is in the header'); - }); - }); - } - - public function test_it_can_generate_material_admin_26_card_with_header() + #[Test] + public function it_can_generate_bootstrap_6_card_with_header() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-card'); $this->visit('/form-card') @@ -141,9 +91,10 @@ public function test_it_can_generate_material_admin_26_card_with_header() }); } - public function test_it_can_generate_bootstrap_5_card_with_subtitle() + #[Test] + public function it_can_generate_bootstrap_6_card_with_subtitle() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-card'); $this->visit('/form-card') @@ -158,9 +109,10 @@ public function test_it_can_generate_bootstrap_5_card_with_subtitle() }); } - public function test_it_can_generate_bootstrap_5_card_with_image_top() + #[Test] + public function it_can_generate_bootstrap_6_card_with_image_top() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-card'); $this->visit('/form-card') @@ -174,25 +126,10 @@ public function test_it_can_generate_bootstrap_5_card_with_image_top() }); } - public function test_it_can_generate_bootstrap_5_card_with_footer() + #[Test] + public function it_can_generate_bootstrap_6_card_with_footer() { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('form-card'); - - $this->visit('/form-card') - ->seeElement('div#footer') - ->within('div#footer', function () { - $this - ->seeElement('div.card') - ->within('div.card', function () { - $this->seeElement('div.card-footer'); - }); - }); - } - - public function test_it_can_generate_material_admin_26_card_with_footer() - { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-card'); $this->visit('/form-card') @@ -207,58 +144,4 @@ public function test_it_can_generate_material_admin_26_card_with_footer() } // write test for material admin - - public function test_it_can_generate_material_admin_26_card() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-card'); - - $this->visit('/form-card') - ->seeElement('div#normal') - ->within('div#normal', function () { - $this - ->seeElement('div.card') - ->within('div.card', function () { - $this->seeElement('div.card-body') - ->within('div.card-body', function () { - $this->seeElement('h4.card-title') - ->seeInElement('h4.card-title', 'Card Title') - ->see('This is a card'); - }); - }); - }); - } - - public function test_it_can_generate_material_admin_26_card_with_subtitle() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-card'); - - $this->visit('/form-card') - ->seeElement('div#subtitle') - ->within('div#subtitle', function () { - $this - ->seeElement('div.card') - ->within('div.card', function () { - $this->seeElement('h6.card-subtitle') - ->seeInElement('h6.card-subtitle', 'Card Subtitle'); - }); - }); - } - - public function test_it_can_generate_material_admin_26_card_with_image_top() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-card'); - - $this->visit('/form-card') - ->seeElement('div#image-top') - ->within('div#image-top', function () { - $this - ->seeElement('div.card') - ->within('div.card', function () { - $this->seeElement('img.card-img-top'); - }); - }); - } } diff --git a/tests/Feature/CheckboxTest.php b/tests/Feature/CheckboxTest.php index 8f367f5..2377ca4 100644 --- a/tests/Feature/CheckboxTest.php +++ b/tests/Feature/CheckboxTest.php @@ -5,6 +5,7 @@ use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Route; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class CheckboxTest extends TestCase { @@ -16,94 +17,81 @@ protected function setUp(): void Config::set('forms.inputs.inline', false); } - public function test_it_can_generate_material_admin_26_checkbox_with_slot() + #[Test] + public function it_can_generate_bootstrap_6_checkbox_with_slot() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('checkbox-slot'); $this->visit('/checkbox-slot') - ->seeElement('div.checkbox') - ->within('div.checkbox', function () { + ->seeElement('div.form-field') + ->within('div.form-field', function () { $this - ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"]') - ->seeElement('label.checkbox__label') - ->within('label.checkbox__label', function () { + ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"].check') + ->seeElement('label.check-label') + ->within('label.check-label', function () { $this->seeElement('a') ->seeInElement('a', 'some site'); }); }); } - public function test_it_can_generate_bootstrap_5_checkbox_with_slot() + #[Test] + public function it_can_generate_bootstrap_6_form_checkbox() { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('checkbox-slot'); - - $this->visit('/checkbox-slot') - ->seeElement('div.form-check') - ->within('div.form-check', function () { - $this - ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"].form-check-input') - ->seeElement('label.form-check-label') - ->within('label.form-check-label', function () { - $this->seeElement('a') - ->seeInElement('a', 'some site'); - }); - }); - } - - public function test_it_can_generate_bootstrap_5_form_checkbox() - { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-checkbox'); $this->visit('/form-checkbox') - ->seeElement('div.form-check') - ->within('div.form-check', function () { + ->seeElement('div.form-field') + ->within('div.form-field', function () { $this - ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"].form-check-input') - ->seeElement('label.form-check-label') - ->seeInElement('label.form-check-label[for="check_me"]', 'Check Me'); + ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"].check') + ->seeElement('label.check-label') + ->seeInElement('label.check-label[for="check_me"]', 'Check Me'); }); } - public function test_it_can_generate_bootstrap_5_form_checkbox_that_is_required() + #[Test] + public function it_can_generate_bootstrap_6_form_checkbox_that_is_required() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-checkbox-required'); $this->visit('/form-checkbox-required') - ->seeElement('div.form-check') - ->within('div.form-check', function () { + ->seeElement('div.form-field') + ->within('div.form-field', function () { $this - ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"][required].form-check-input') - ->seeElement('label.form-check-label[for="check_me"]') - ->seeInElement('label.form-check-label[for="check_me"]', 'Check Me') - ->within('label.form-check-label[for="check_me"]', function () { + ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"][required].check') + ->seeElement('label.check-label[for="check_me"]') + ->seeInElement('label.check-label[for="check_me"]', 'Check Me') + ->within('label.check-label[for="check_me"]', function () { $this->seeElement('span.required') ->seeInElement('span.required', '*'); }); }); } - public function test_it_can_generate_bootstrap_5_form_checkbox_that_is_selected() + #[Test] + public function it_can_generate_bootstrap_6_form_checkbox_that_is_selected() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-checkbox-selected'); $this->visit('/form-checkbox-selected') - ->seeElement('div.form-check') - ->within('div.form-check', function () { + ->seeElement('div.form-field') + ->within('div.form-field', function () { $this - ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"][checked].form-check-input') - ->seeElement('label.form-check-label') - ->seeInElement('label.form-check-label[for="check_me"]', 'Check Me'); + ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"][checked].check') + ->seeElement('label.check-label') + ->seeInElement('label.check-label[for="check_me"]', 'Check Me'); }); } - public function test_it_can_generate_bootstrap_5_form_checkbox_that_is_selected_from_model_binding() + #[Test] + public function it_can_generate_bootstrap_6_form_checkbox_that_is_selected_from_model_binding() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $address = [ 'check_me' => '1', @@ -115,62 +103,29 @@ public function test_it_can_generate_bootstrap_5_form_checkbox_that_is_selected_ })->middleware('web'); $this->visit('/form-checkbox-selected-model-binding') - ->seeElement('div.form-check') - ->within('div.form-check', function () { + ->seeElement('div.form-field') + ->within('div.form-field', function () { $this - ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"][checked].form-check-input') - ->seeElement('label.form-check-label') - ->seeInElement('label.form-check-label[for="check_me"]', 'Check Me'); - }); - } - - public function test_it_can_generate_material_admin_26_form_checkbox() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-checkbox'); - - $this->visit('/form-checkbox') - ->seeElement('div.checkbox') - ->within('div.checkbox', function () { - $this - ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"]') - ->seeElement('label.checkbox__label') - ->seeInElement('label.checkbox__label[for="check_me"]', 'Check Me'); - }); - } - - public function test_it_can_generate_material_admin_26_form_checkbox_that_is_required() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-checkbox-required'); - - $this->visit('/form-checkbox-required') - ->seeElement('div.checkbox') - ->within('div.checkbox', function () { - $this - ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"][required]') - ->seeElement('label.checkbox__label[for="check_me"]') - ->seeInElement('label.checkbox__label[for="check_me"]', 'Check Me') - ->within('label.checkbox__label[for="check_me"]', function () { - $this->seeElement('span.required') - ->seeInElement('span.required', '*'); - }); + ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"][checked].check') + ->seeElement('label.check-label') + ->seeInElement('label.check-label[for="check_me"]', 'Check Me'); }); } - public function test_it_can_generate_material_admin_26_inline_form_checkbox_that_is_required() + #[Test] + public function it_can_generate_bootstrap_6_inline_form_checkbox_that_is_required() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-checkbox-inline-required'); $this->visit('/form-checkbox-inline-required') - ->seeElement('div.checkbox') - ->within('div.checkbox', function () { + ->seeElement('div.form-field') + ->within('div.form-field', function () { $this ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"][required]') - ->seeElement('label.checkbox__label[for="check_me"]') - ->dontSeeInElement('label.checkbox__label[for="check_me"]', 'Check Me') - ->within('label.checkbox__label[for="check_me"]', function () { + ->seeElement('label.check-label[for="check_me"]') + ->dontSeeInElement('label.check-label[for="check_me"]', 'Check Me') + ->within('label.check-label[for="check_me"]', function () { $this->dontSeeElement('span.required') ->dontSeeInElement('span.required', '*'); }); @@ -178,19 +133,20 @@ public function test_it_can_generate_material_admin_26_inline_form_checkbox_that }); } - public function test_it_can_generate_material_admin_26_form_checkbox_with_helper_text() + #[Test] + public function it_can_generate_bootstrap_6_form_checkbox_with_helper_text() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-checkbox-helper-text'); $this->visit('/form-checkbox-helper-text') - ->seeElement('div.checkbox') - ->within('div.checkbox', function () { + ->seeElement('div.form-field') + ->within('div.form-field', function () { $this ->seeElement('input[name="check_me"][id="check_me"][type="checkbox"][required]') - ->seeElement('label.checkbox__label[for="check_me"]'); + ->seeElement('label.check-label[for="check_me"]'); }) - ->seeElement('small.form-text.text-muted') - ->seeInElement('small.form-text.text-muted', 'This is some help text.'); + ->seeElement('small.form-text') + ->seeInElement('small.form-text', 'This is some help text.'); } } diff --git a/tests/Feature/ConditionalLinkTest.php b/tests/Feature/ConditionalLinkTest.php index d49262e..0140bf5 100644 --- a/tests/Feature/ConditionalLinkTest.php +++ b/tests/Feature/ConditionalLinkTest.php @@ -3,25 +3,14 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class ConditionalLinkTest extends TestCase { - public function test_it_can_render_conditional_links_for_bootstrap_5() + #[Test] + public function it_can_render_conditional_links_for_bootstrap_6() { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('conditional-link'); - - $this->visit('/conditional-link') - ->seeElement('a[href="/admin/dashboard"]') - ->within('a', function () { - $this->seeText('Javaabu'); - }); - - } - - public function test_it_can_render_conditional_links_for_material_admin_26() - { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('conditional-link'); $this->visit('/conditional-link') diff --git a/tests/Feature/ConditionalWrapperTest.php b/tests/Feature/ConditionalWrapperTest.php index 6831ead..e2f7e34 100644 --- a/tests/Feature/ConditionalWrapperTest.php +++ b/tests/Feature/ConditionalWrapperTest.php @@ -3,39 +3,44 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class ConditionalWrapperTest extends TestCase { - public function test_it_can_render_conditional_wrapper_bs5() + #[Test] + public function it_can_render_conditional_wrapper_bs5() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('conditional-wrapper'); $this->visit('/conditional-wrapper') ->seeElement('div[data-enable-elem="#input"]'); } - public function test_it_can_render_conditional_wrapper_powered_by_checkbox_bs5() + #[Test] + public function it_can_render_conditional_wrapper_powered_by_checkbox_bs5() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('conditional-wrapper-checkbox'); $this->visit('/conditional-wrapper-checkbox') ->seeElement('div[data-enable-section-checkbox="#input"]'); } - public function test_it_can_render_conditional_wrapper_material_26() + #[Test] + public function it_can_render_conditional_wrapper_material_26() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('conditional-wrapper'); $this->visit('/conditional-wrapper') ->seeElement('div[data-enable-elem="#input"]'); } - public function test_it_can_render_conditional_wrapper_powered_by_checkbox_material_26() + #[Test] + public function it_can_render_conditional_wrapper_powered_by_checkbox_material_26() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('conditional-wrapper-checkbox'); $this->visit('/conditional-wrapper-checkbox') diff --git a/tests/Feature/DateTest.php b/tests/Feature/DateTest.php index 51ce6ba..8573051 100644 --- a/tests/Feature/DateTest.php +++ b/tests/Feature/DateTest.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Config; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class DateTest extends TestCase { @@ -15,9 +16,10 @@ protected function setUp(): void Config::set('forms.inputs.inline', false); } - public function test_it_can_generate_bootstrap_5_date_inputs() + #[Test] + public function it_can_generate_bootstrap_6_date_inputs() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('date-inputs'); $this->visit('/date-inputs') diff --git a/tests/Feature/FileTest.php b/tests/Feature/FileTest.php index 4c0fd73..58b9155 100644 --- a/tests/Feature/FileTest.php +++ b/tests/Feature/FileTest.php @@ -7,6 +7,7 @@ use Illuminate\Support\Facades\Route; use Javaabu\Forms\Tests\TestCase; use Javaabu\Forms\Tests\TestSupport\Models\Article; +use PHPUnit\Framework\Attributes\Test; use Spatie\MediaLibrary\MediaCollections\Exceptions\FileDoesNotExist; use Spatie\MediaLibrary\MediaCollections\Exceptions\FileIsTooBig; @@ -38,11 +39,12 @@ protected function getArticleWithMedia(string $collection = 'featured_image'): A return $article; } - public function test_it_can_render_missing_file_inputs() + #[Test] + public function it_can_render_missing_file_inputs() { $article = $this->getArticleWithMedia(); - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); Route::get('file-missing', function () use ($article) { return view('file-missing') @@ -50,8 +52,8 @@ public function test_it_can_render_missing_file_inputs() })->middleware('web'); $this->visit('/file-missing') - ->seeElement('div.form-group') - ->within('div.form-group', function () { + ->seeElement('div.mb-4') + ->within('div.mb-4', function () { $this->seeElement('div.fileinput.fileinput-new') ->within('div.fileinput', function () { $this->seeElement('span.btn-file') @@ -67,15 +69,16 @@ public function test_it_can_render_missing_file_inputs() }); } - public function test_it_can_render_file_input_with_value() + #[Test] + public function it_can_render_file_input_with_value() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('file-value'); $this->visit('/file-value') - ->seeElement('div.form-group') - ->within('div.form-group', function () { + ->seeElement('div.mb-4') + ->within('div.mb-4', function () { $this->seeElement('div.fileinput.fileinput-exists') ->within('div.fileinput', function () { $this->seeElement('span.btn-file') @@ -83,26 +86,27 @@ public function test_it_can_render_file_input_with_value() $this->seeElement('input[name="featured_image"][type="file"][accept="application/pdf,image/jpeg,image/png"]#featured_image'); }); - $this->seeElement('span.fileinput-filename') - ->within('span.fileinput-filename', function () { - $this->seeElement('a[href="https://example.com/uploads/Important-document.pdf?download=true"]') - ->seeInElement('a', 'Important-document.pdf') - ->dontSeeInElement('a', '?download=true') - ->dontSeeInElement('a', 'https://example.com/uploads/'); + $this->seeElement('a.fileinput-filelink[href="https://example.com/uploads/Important-document.pdf?download=true"]') + ->within('a.fileinput-filelink', function () { + $this->seeElement('svg[data-icon="download"]') + ->see('Important-document.pdf') + ->dontSee('?download=true') + ->dontSee('https://example.com/uploads/'); }); }); }); } - public function test_it_can_render_unbound_file_inputs() + #[Test] + public function it_can_render_unbound_file_inputs() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('file-unbound'); $this->visit('/file-unbound') - ->seeElement('div.form-group') - ->within('div.form-group', function () { + ->seeElement('div.mb-4') + ->within('div.mb-4', function () { $this->seeElement('div.fileinput.fileinput-new') ->within('div.fileinput', function () { $this->seeElement('span.btn-file') @@ -118,11 +122,12 @@ public function test_it_can_render_unbound_file_inputs() }); } - public function test_it_can_render_file_inputs_with_attribute_accessor() + #[Test] + public function it_can_render_file_inputs_with_attribute_accessor() { $article = $this->getArticleWithMedia(); - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); Route::get('file-attribute-accessor', function () use ($article) { return view('file-attribute-accessor') @@ -130,8 +135,8 @@ public function test_it_can_render_file_inputs_with_attribute_accessor() })->middleware('web'); $this->visit('/file-attribute-accessor') - ->seeElement('div.form-group') - ->within('div.form-group', function () { + ->seeElement('div.mb-4') + ->within('div.mb-4', function () { $this->seeElement('div.fileinput.fileinput-exists') ->within('div.fileinput', function () { $this->seeElement('span.btn-file') @@ -139,19 +144,20 @@ public function test_it_can_render_file_inputs_with_attribute_accessor() $this->seeElement('input[name="thumbnail"][type="file"][accept="application/pdf,image/jpeg,image/png"]#thumbnail'); }); - $this->seeElement('span.fileinput-filename') - ->within('span.fileinput-filename', function () { - $this->seeElement('a[href="/storage/1/conversions/some-cool-image-thumb.jpg"]'); + $this->seeElement('a.fileinput-filelink[href="/storage/1/conversions/some-cool-image-thumb.jpg"]') + ->within('a.fileinput-filelink', function () { + $this->seeElement('svg[data-icon="download"]'); }); }); }); } - public function test_it_can_render_file_inputs_with_accessor() + #[Test] + public function it_can_render_file_inputs_with_accessor() { $article = $this->getArticleWithMedia(); - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); Route::get('file-accessor', function () use ($article) { return view('file-accessor') @@ -159,8 +165,8 @@ public function test_it_can_render_file_inputs_with_accessor() })->middleware('web'); $this->visit('/file-accessor') - ->seeElement('div.form-group') - ->within('div.form-group', function () { + ->seeElement('div.mb-4') + ->within('div.mb-4', function () { $this->seeElement('div.fileinput.fileinput-exists') ->within('div.fileinput', function () { $this->seeElement('span.btn-file') @@ -168,19 +174,20 @@ public function test_it_can_render_file_inputs_with_accessor() $this->seeElement('input[name="photo"][type="file"][accept="application/pdf,image/jpeg,image/png"]#photo'); }); - $this->seeElement('span.fileinput-filename') - ->within('span.fileinput-filename', function () { - $this->seeElement('a[href="/storage/1/some-cool-image.jpg"]'); + $this->seeElement('a.fileinput-filelink[href="/storage/1/some-cool-image.jpg"]') + ->within('a.fileinput-filelink', function () { + $this->seeElement('svg[data-icon="download"]'); }); }); }); } - public function test_it_can_render_file_inputs_with_conversion_name() + #[Test] + public function it_can_render_file_inputs_with_conversion_name() { $article = $this->getArticleWithMedia(); - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); Route::get('file-conversion', function () use ($article) { return view('file-conversion') @@ -188,8 +195,8 @@ public function test_it_can_render_file_inputs_with_conversion_name() })->middleware('web'); $this->visit('/file-conversion') - ->seeElement('div.form-group') - ->within('div.form-group', function () { + ->seeElement('div.mb-4') + ->within('div.mb-4', function () { $this->seeElement('div.fileinput.fileinput-exists') ->within('div.fileinput', function () { $this->seeElement('span.btn-file') @@ -197,19 +204,20 @@ public function test_it_can_render_file_inputs_with_conversion_name() $this->seeElement('input[name="featured_image"][type="file"][accept="application/pdf,image/jpeg,image/png"]#featured_image'); }); - $this->seeElement('span.fileinput-filename') - ->within('span.fileinput-filename', function () { - $this->seeElement('a[href="/storage/1/conversions/some-cool-image-thumb.jpg"]'); + $this->seeElement('a.fileinput-filelink[href="/storage/1/conversions/some-cool-image-thumb.jpg"]') + ->within('a.fileinput-filelink', function () { + $this->seeElement('svg[data-icon="download"]'); }); }); }); } - public function test_it_can_render_file_inputs_with_collection_name() + #[Test] + public function it_can_render_file_inputs_with_collection_name() { $article = $this->getArticleWithMedia(); - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); Route::get('file-collection', function () use ($article) { return view('file-collection') @@ -217,8 +225,8 @@ public function test_it_can_render_file_inputs_with_collection_name() })->middleware('web'); $this->visit('/file-collection') - ->seeElement('div.form-group') - ->within('div.form-group', function () { + ->seeElement('div.mb-4') + ->within('div.mb-4', function () { $this->seeElement('div.fileinput.fileinput-exists') ->within('div.fileinput', function () { $this->seeElement('span.btn-file') @@ -226,19 +234,20 @@ public function test_it_can_render_file_inputs_with_collection_name() $this->seeElement('input[name="post_image"][type="file"][accept="application/pdf,image/jpeg,image/png"]#post_image'); }); - $this->seeElement('span.fileinput-filename') - ->within('span.fileinput-filename', function () { - $this->seeElement('a[href="/storage/1/some-cool-image.jpg"]'); + $this->seeElement('a.fileinput-filelink[href="/storage/1/some-cool-image.jpg"]') + ->within('a.fileinput-filelink', function () { + $this->seeElement('svg[data-icon="download"]'); }); }); }); } - public function test_it_can_show_file_hint() + #[Test] + public function it_can_show_file_hint() { $article = $this->getArticleWithMedia(); - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); Route::get('file-hint', function () use ($article) { return view('file-hint') @@ -246,8 +255,8 @@ public function test_it_can_show_file_hint() })->middleware('web'); $this->visit('/file-hint') - ->seeElement('div.form-group') - ->within('div.form-group', function () { + ->seeElement('div.mb-4') + ->within('div.mb-4', function () { $this->seeElement('div.fileinput.fileinput-exists') ->within('div.fileinput', function () { $this->seeElement('span.btn-file') @@ -255,9 +264,9 @@ public function test_it_can_show_file_hint() $this->seeElement('input[name="featured_image"][type="file"][accept="application/pdf,image/jpeg,image/png"]#featured_image'); }); - $this->seeElement('span.fileinput-filename') - ->within('span.fileinput-filename', function () { - $this->seeElement('a[href="/storage/1/some-cool-image.jpg"]'); + $this->seeElement('a.fileinput-filelink[href="/storage/1/some-cool-image.jpg"]') + ->within('a.fileinput-filelink', function () { + $this->seeElement('svg[data-icon="download"]'); }); }); @@ -266,41 +275,12 @@ public function test_it_can_show_file_hint() }); } - public function test_it_can_render_material_admin_26_file_inputs() - { - $article = $this->getArticleWithMedia(); - - $this->setFrameworkMaterialAdmin26(); - - Route::get('file', function () use ($article) { - return view('file') - ->with('article', $article); - })->middleware('web'); - - $this->visit('/file') - ->seeElement('div.form-group') - ->within('div.form-group', function () { - $this->seeElement('div.fileinput.fileinput-exists') - ->within('div.fileinput', function () { - $this->seeElement('span.btn-file') - ->within('span.btn-file', function () { - $this->seeElement('input[name="featured_image"][type="file"][accept="application/pdf,image/jpeg,image/png"]#featured_image'); - }); - - $this->seeElement('span.fileinput-filename') - ->within('span.fileinput-filename', function () { - $this->seeElement('a[href="/storage/1/some-cool-image.jpg"]') - ->seeElement('i.zmdi.zmdi-open-in-new'); - }); - }); - }); - } - - public function test_it_can_render_bootstrap_5_file_inputs() + #[Test] + public function it_can_render_bootstrap_6_file_inputs() { $article = $this->getArticleWithMedia(); - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); Route::get('file', function () use ($article) { return view('file') @@ -319,21 +299,22 @@ public function test_it_can_render_bootstrap_5_file_inputs() $this->seeElement('a.fileinput-filelink[href="/storage/1/some-cool-image.jpg"]') ->within('a.fileinput-filelink', function () { - $this->seeElement('i.fa-regular.fa-arrow-to-bottom'); + $this->seeElement('svg[data-icon="download"]'); }) ->seeElement('button.btn-dismiss') ->within('button.btn-dismiss', function () { - $this->seeElement('i.fa-regular.fa-close'); + $this->seeElement('svg[data-icon="x"]'); }); }); }); } - public function test_it_can_render_file_upload_inputs() + #[Test] + public function it_can_render_file_upload_inputs() { $article = $this->getArticleWithMedia(); - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); Route::get('file-upload', function () use ($article) { return view('file-upload') @@ -347,7 +328,7 @@ public function test_it_can_render_file_upload_inputs() ->within('div.fileinput', function () { $this->seeElement('.upload-btn') ->within('.upload-btn', function () { - $this->seeElement('i.fa-regular.fa-arrow-to-top') + $this->seeElement('svg[data-icon="upload"]') ->seeText('Upload file'); }); }); diff --git a/tests/Feature/FormFilterTest.php b/tests/Feature/FormFilterTest.php index 1cbc230..11a0ca5 100644 --- a/tests/Feature/FormFilterTest.php +++ b/tests/Feature/FormFilterTest.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Config; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class FormFilterTest extends TestCase { @@ -16,9 +17,9 @@ protected function setUp(): void } // /** @test */ - // public function it_can_generate_bootstrap_5_form_filter() + // public function it_can_generate_bootstrap_6_form_filter() // { - // $this->setFrameworkBootstrap5(); + // $this->setFrameworkBootstrap6(); // $this->registerTestRoute('form-filter'); // // $this->visit('/form-filter') @@ -30,9 +31,10 @@ protected function setUp(): void // ->seeElement('input[type="hidden"][name="order"]'); // } - public function test_it_can_generate_material_admin_26_form_filter() + #[Test] + public function it_can_generate_bootstrap_6_form_filter() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-filter'); $this->visit('/form-filter') diff --git a/tests/Feature/FormTest.php b/tests/Feature/FormTest.php index ca25c6d..5b81712 100644 --- a/tests/Feature/FormTest.php +++ b/tests/Feature/FormTest.php @@ -3,10 +3,12 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class FormTest extends TestCase { - public function test_it_can_render_a_form_with_an_action() + #[Test] + public function it_can_render_a_form_with_an_action() { $this->registerTestRoute('form'); diff --git a/tests/Feature/Frameworks/Bootstrap6Test.php b/tests/Feature/Frameworks/Bootstrap6Test.php new file mode 100644 index 0000000..16ba0ff --- /dev/null +++ b/tests/Feature/Frameworks/Bootstrap6Test.php @@ -0,0 +1,111 @@ +setFrameworkBootstrap6(); + } + + #[Test] + public function it_renders_selects_with_form_control_instead_of_form_select(): void + { + $html = $this->renderBlade(''); + + $this->assertCount(1, $html->filter('select.form-control[name="status"]')); + $this->assertCount(0, $html->filter('.form-select')); + } + + #[Test] + public function it_renders_checkboxes_with_the_check_class_and_no_wrapper_class(): void + { + $html = $this->renderBlade(''); + + $this->assertCount(1, $html->filter('div.form-field > input.check[type="checkbox"]#agree')); + $this->assertCount(1, $html->filter('label.check-label[for="agree"]')); + $this->assertCount(0, $html->filter('.form-check, .form-check-input')); + } + + #[Test] + public function it_maps_button_colours_to_variant_and_theme_classes(): void + { + $html = $this->renderBlade(<<<'BLADE' + A + B + C + D + E + BLADE); + + $this->assertCount(1, $html->filter('button.btn-solid.theme-primary')); + $this->assertCount(1, $html->filter('button.btn-outline.theme-danger')); + $this->assertCount(1, $html->filter('button.btn-subtle.theme-secondary')); + $this->assertCount(1, $html->filter('button.btn-solid.theme-inverse')); + $this->assertCount(1, $html->filter('a.btn-link[href="/x"]')); + } + + #[Test] + public function it_renders_modals_as_native_dialogs(): void + { + $html = $this->renderBlade(<<<'BLADE' + +

Body

+ Footer +
+ BLADE); + + $this->assertCount(1, $html->filter('dialog.dialog.dialog-xl#edit-modal[aria-labelledby="edit-modal-title"]')); + $this->assertEquals('ތަފްސީލު', trim($html->filter('h2.dialog-title#edit-modal-title')->text())); + $this->assertCount(1, $html->filter('.dialog-header button.btn-close[data-bs-dismiss="dialog"]')); + $this->assertCount(1, $html->filter('.dialog-body p')); + $this->assertEquals('Footer', trim($html->filter('.dialog-footer')->text())); + $this->assertCount(0, $html->filter('.modal, .modal-dialog, .modal-content')); + } + + #[Test] + public function it_maps_legacy_modal_size_classes_to_dialog_sizes(): void + { + $html = $this->renderBlade('Body'); + + $this->assertCount(1, $html->filter('dialog.dialog.dialog-sm#m')); + } + + #[Test] + public function it_renders_alerts_with_a_theme_an_icon_and_a_close_button(): void + { + $html = $this->renderBlade('Body'); + + $this->assertCount(1, $html->filter('div.alert.theme-danger[role="alert"]')); + $this->assertCount(1, $html->filter('.alert svg[data-icon="circle-x"]')); + $this->assertEquals('Oops', trim($html->filter('h4.alert-heading')->text())); + $this->assertCount(1, $html->filter('.alert button.btn-close[data-bs-dismiss="alert"]')); + $this->assertCount(0, $html->filter('.alert-dismissible')); + } + + #[Test] + public function it_marks_invalid_inputs_for_assistive_technology(): void + { + $this->withViewErrors(['title' => 'ސުރުޚީ ލިޔުން ލާޒިމް.']); + + $html = $this->renderBlade(''); + + $this->assertCount(1, $html->filter('input.form-control.is-invalid[aria-invalid="true"]')); + $this->assertStringContainsString('ސުރުޚީ', $html->filter('.invalid-feedback')->text()); + } + + #[Test] + public function it_uses_prefixed_responsive_classes_for_inline_fields(): void + { + $html = $this->renderBlade(''); + + $this->assertCount(1, $html->filter('div.row.mb-4 > label.sm\:col-3.lg\:col-2.col-form-label')); + $this->assertCount(1, $html->filter('div.row.mb-4 > div.sm\:col-9.lg\:col-10 input.form-control')); + } +} diff --git a/tests/Feature/IconTest.php b/tests/Feature/IconTest.php new file mode 100644 index 0000000..b57bd17 --- /dev/null +++ b/tests/Feature/IconTest.php @@ -0,0 +1,62 @@ +renderBlade(''); + + $svg = $html->filter('svg.forms-icon.size-4[data-icon="calendar"][aria-hidden="true"]'); + + $this->assertCount(1, $svg); + $this->assertGreaterThan(0, $svg->filter('path')->count()); + } + + #[Test] + public function it_resolves_logical_icon_names_from_the_config(): void + { + $html = $this->renderBlade(''); + + $this->assertCount(1, $html->filter('svg[data-icon="calendar"]')); + } + + #[Test] + public function it_renders_icon_font_classes_as_an_i_element(): void + { + Config::set('forms.icons.date', 'fa-regular fa-calendar'); + + $html = $this->renderBlade(''); + + $this->assertCount(1, $html->filter('i.fa-regular.fa-calendar[aria-hidden="true"]')); + $this->assertCount(1, $html->filter('i.zmdi.zmdi-home')); + $this->assertCount(0, $html->filter('svg')); + } + + #[Test] + public function it_lets_a_framework_override_an_icon(): void + { + Config::set('forms.frameworks.bootstrap-6.icons.clear', 'circle-x'); + + $html = $this->renderBlade(''); + + $this->assertCount(1, $html->filter('svg[data-icon="circle-x"]')); + } + + #[Test] + public function it_uses_svg_icons_in_date_inputs(): void + { + $this->setFrameworkBootstrap6(); + + $html = $this->renderBlade(''); + + $this->assertCount(1, $html->filter('.input-group-text svg[data-icon="calendar"]')); + $this->assertCount(1, $html->filter('button.btn-date-clear[data-date-clear="#published_at"] svg[data-icon="x"]')); + } +} diff --git a/tests/Feature/ImageTest.php b/tests/Feature/ImageTest.php index fbeddf3..7f09a7a 100644 --- a/tests/Feature/ImageTest.php +++ b/tests/Feature/ImageTest.php @@ -7,6 +7,7 @@ use Illuminate\Support\Facades\Route; use Javaabu\Forms\Tests\TestCase; use Javaabu\Forms\Tests\TestSupport\Models\Article; +use PHPUnit\Framework\Attributes\Test; use Spatie\MediaLibrary\MediaCollections\Exceptions\FileDoesNotExist; use Spatie\MediaLibrary\MediaCollections\Exceptions\FileIsTooBig; @@ -38,11 +39,12 @@ protected function getArticleWithMedia(string $collection = 'featured_image'): A return $article; } - public function test_it_can_render_bootstrap_5_image_inputs() + #[Test] + public function it_can_render_bootstrap_6_image_inputs() { $article = $this->getArticleWithMedia(); - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); Route::get('image', function () use ($article) { return view('image') @@ -66,7 +68,7 @@ public function test_it_can_render_bootstrap_5_image_inputs() }) ->seeElement('.fileinput-image-missing') ->within('.fileinput-image-missing', function () { - $this->seeElement('i.fa-regular.fa-image'); + $this->seeElement('svg[data-icon="image"]'); }) ->seeElement('button[data-dismiss="fileinput"]') ->seeInElement('button[data-dismiss="fileinput"]', 'Remove') @@ -77,49 +79,12 @@ public function test_it_can_render_bootstrap_5_image_inputs() }); } - public function test_it_can_render_material_admin_26_image_inputs() + #[Test] + public function it_can_render_image_upload_inputs() { $article = $this->getArticleWithMedia(); - $this->setFrameworkMaterialAdmin26(); - - Route::get('image', function () use ($article) { - return view('image') - ->with('article', $article); - })->middleware('web'); - - $this->visit('/image') - ->seeElement('div.form-group') - ->within('div.form-group', function () { - $this->seeElement('div.fileinput.fileinput-exists') - ->within('div.fileinput', function () { - $this->seeElement('span.btn-file') - ->within('span.btn-file', function () { - $this->seeElement('input[name="featured_image"][type="file"][accept="image/jpeg,image/png,image/gif,image/tiff,image/x-citrix-png,image/x-png,image/svg+xml,image/svg"]#featured_image'); - }); - }) - ->seeElement('div.fileinput-preview') - ->within('div.fileinput-preview', function () { - $this->seeElement('img[src="/storage/1/some-cool-image.jpg"]'); - }) - ->seeElement('.fileinput-image-missing') - ->within('.fileinput-image-missing', function () { - $this->seeElement('i.zmdi.zmdi-image'); - }) - ->seeElement('a[data-dismiss="fileinput"]') - ->seeInElement('a[data-dismiss="fileinput"]', 'Remove') - ->seeElement('.fileinput-image-missing') - ->seeInElement('.fileinput-image-missing', 'Click to select an image') - ->seeElement('.form-text') - ->seeInElement('.form-text', 'Recommended 500px x 500px.'); - }); - } - - public function test_it_can_render_image_upload_inputs() - { - $article = $this->getArticleWithMedia(); - - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); Route::get('image-upload', function () use ($article) { return view('image-upload') @@ -133,7 +98,7 @@ public function test_it_can_render_image_upload_inputs() ->within('div.fileinput', function () { $this->seeElement('.upload-btn') ->within('.upload-btn', function () { - $this->seeElement('i.fa-regular.fa-arrow-to-top') + $this->seeElement('svg[data-icon="upload"]') ->seeText('Upload file'); }); }); diff --git a/tests/Feature/InputTest.php b/tests/Feature/InputTest.php index 6fae024..15ad475 100644 --- a/tests/Feature/InputTest.php +++ b/tests/Feature/InputTest.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Config; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class InputTest extends TestCase { @@ -15,9 +16,10 @@ protected function setUp(): void Config::set('forms.inputs.inline', false); } - public function test_it_can_generate_bootstrap_5_form_inputs_with_input_group() + #[Test] + public function it_can_generate_bootstrap_6_form_inputs_with_input_group() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-input-prepend-append'); $this->visit('/form-input-prepend-append') @@ -36,9 +38,10 @@ public function test_it_can_generate_bootstrap_5_form_inputs_with_input_group() }); } - public function test_it_can_generate_bootstrap_5_form_inputs_without_form_group() + #[Test] + public function it_can_generate_bootstrap_6_form_inputs_without_form_group() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-input-without-label'); $this->visit('/form-input-without-label') @@ -47,20 +50,10 @@ public function test_it_can_generate_bootstrap_5_form_inputs_without_form_group( ->dontSeeElement('div.mb-4'); } - public function test_it_can_generate_material_admin_26_form_inputs_without_form_group() + #[Test] + public function it_can_generate_bootstrap_6_form_inputs() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-input-without-label'); - - $this->visit('/form-input-without-label') - ->seeElement('input[name="title"][value="Lorem ipsum"].form-control') - ->dontSeeElement('label') - ->dontSeeElement('div.form-group'); - } - - public function test_it_can_generate_bootstrap_5_form_inputs() - { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-input'); $this->visit('/form-input') @@ -72,9 +65,10 @@ public function test_it_can_generate_bootstrap_5_form_inputs() }); } - public function test_it_can_set_form_inputs_as_required() + #[Test] + public function it_can_set_form_inputs_as_required() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-input-required'); $this->visit('/form-input-required') @@ -90,9 +84,10 @@ public function test_it_can_set_form_inputs_as_required() }); } - public function test_it_can_generate_bootstrap_5_inline_form_inputs() + #[Test] + public function it_can_generate_bootstrap_6_inline_form_inputs() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-input-inline'); $this->visit('/form-input-inline') @@ -100,16 +95,17 @@ public function test_it_can_generate_bootstrap_5_inline_form_inputs() ->within('div.row.mb-4', function () { $this->seeElement('label.col-form-label[for="title"]') ->seeInElement('label.col-form-label[for="title"]', 'Title') - ->seeElement('div.col-sm-9.col-lg-10') - ->within('div.col-sm-9.col-lg-10', function () { + ->seeElement('div.sm\\:col-9.lg\\:col-10') + ->within('div.sm\\:col-9.lg\\:col-10', function () { $this->seeElement('input[name="title"][id="title"][value="Lorem ipsum"].form-control'); }); }); } - public function test_it_can_generate_bootstrap_5_floating_form_inputs() + #[Test] + public function it_can_generate_bootstrap_6_floating_form_inputs() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-input-floating'); $this->visit('/form-input-floating') @@ -121,9 +117,10 @@ public function test_it_can_generate_bootstrap_5_floating_form_inputs() }); } - public function test_it_can_display_form_input_help_texts() + #[Test] + public function it_can_display_form_input_help_texts() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-input-help'); $this->visit('/form-input-help') @@ -131,28 +128,14 @@ public function test_it_can_display_form_input_help_texts() ->within('div', function () { $this->seeElement('input[name="title"][value="Lorem ipsum"][id="title"].form-control') ->seeElement('label.form-label[for="title"]') - ->seeElement('div.form-text') - ->seeInElement('div.form-text', 'This is some help text.'); + ->seeElement('small.form-text') + ->seeInElement('small.form-text', 'This is some help text.'); }); } - public function test_it_can_generate_material_admin_26_form_inputs() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-input'); - - $this->visit('/form-input') - ->seeElement('div.form-group') - ->within('div.form-group', function () { - $this->seeElement('input[name="title"][value="Lorem ipsum"].form-control') - ->seeElement('i.form-group__bar') - ->seeElement('label[for="title"]') - ->seeInElement('label', 'Title'); - }); - } - - public function test_it_can_generate_different_form_input_types() + #[Test] + public function it_can_generate_different_form_input_types() { $this->registerTestRoute('form-input-types'); @@ -166,7 +149,8 @@ public function test_it_can_generate_different_form_input_types() ->seeElement('input[name="tel"][type="tel"]'); } - public function test_it_can_generate_latitude_inputs() + #[Test] + public function it_can_generate_latitude_inputs() { $this->registerTestRoute('latitude'); @@ -174,7 +158,8 @@ public function test_it_can_generate_latitude_inputs() ->seeElement('input[name="latitude"][type="number"][step="0.000001"][min="-90"][max="90"]'); } - public function test_it_can_generate_longitude_inputs() + #[Test] + public function it_can_generate_longitude_inputs() { $this->registerTestRoute('longitude'); diff --git a/tests/Feature/JsErrorsTest.php b/tests/Feature/JsErrorsTest.php index bdff138..9077a2b 100644 --- a/tests/Feature/JsErrorsTest.php +++ b/tests/Feature/JsErrorsTest.php @@ -3,21 +3,14 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class JsErrorsTest extends TestCase { - public function test_it_can_render_bootstrap_5_js_errors() + #[Test] + public function it_can_render_bootstrap_6_js_errors() { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('js-errors'); - - $this->visit('/js-errors') - ->seeElement('ul.invalid-feedback.test-input-error'); - } - - public function test_it_can_render_material_admin_26_js_errors() - { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('js-errors'); $this->visit('/js-errors') diff --git a/tests/Feature/LabelTest.php b/tests/Feature/LabelTest.php index 7f3b87b..4bf5241 100644 --- a/tests/Feature/LabelTest.php +++ b/tests/Feature/LabelTest.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Config; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class LabelTest extends TestCase { @@ -14,9 +15,10 @@ protected function setUp(): void Config::set('forms.inputs.required_text', 'forms::strings.required_text'); } - public function test_it_can_generate_material_admin_label_with_a_slot() + #[Test] + public function it_can_generate_material_admin_label_with_a_slot() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('label-slot'); $this->visit('/label-slot') @@ -27,9 +29,10 @@ public function test_it_can_generate_material_admin_label_with_a_slot() }); } - public function test_it_can_generate_bootstrap_5_label_with_a_slot() + #[Test] + public function it_can_generate_bootstrap_6_label_with_a_slot() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('label-slot'); $this->visit('/label-slot') @@ -40,9 +43,10 @@ public function test_it_can_generate_bootstrap_5_label_with_a_slot() }); } - public function test_it_can_generate_bootstrap_5_blank_form_group() + #[Test] + public function it_can_generate_bootstrap_6_blank_form_group() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-group-blank'); $this->visit('/form-group-blank') @@ -55,9 +59,10 @@ public function test_it_can_generate_bootstrap_5_blank_form_group() }); } - public function test_it_can_generate_bootstrap_5_blank_label() + #[Test] + public function it_can_generate_bootstrap_6_blank_label() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('label-blank'); $page = $this->visit('/label-blank') @@ -65,9 +70,10 @@ public function test_it_can_generate_bootstrap_5_blank_label() ->seeInElement('label', ''); } - public function test_it_can_generate_bootstrap_5_standard_form_labels() + #[Test] + public function it_can_generate_bootstrap_6_standard_form_labels() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-label'); $page = $this->visit('/form-label') @@ -79,9 +85,10 @@ public function test_it_can_generate_bootstrap_5_standard_form_labels() $this->assertEquals('form-label', $class); } - public function test_it_can_generate_bootstrap_5_required_string_for_form_labels() + #[Test] + public function it_can_generate_bootstrap_6_required_string_for_form_labels() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-label-required'); $this->visit('/form-label-required') @@ -93,9 +100,10 @@ public function test_it_can_generate_bootstrap_5_required_string_for_form_labels }); } - public function test_it_can_float_bootstrap_5_labels() + #[Test] + public function it_can_float_bootstrap_6_labels() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-label-floating'); $page = $this->visit('/form-label-floating') @@ -107,9 +115,10 @@ public function test_it_can_float_bootstrap_5_labels() $this->assertNull($class); } - public function test_it_can_generate_bootstrap_5_inline_form_labels() + #[Test] + public function it_can_generate_bootstrap_6_inline_form_labels() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-label-inline'); $page = $this->visit('/form-label-inline') @@ -118,82 +127,17 @@ public function test_it_can_generate_bootstrap_5_inline_form_labels() $class = $page->crawler()->filter('label')->attr('class'); - $this->assertEquals('col-sm-3 col-lg-2 col-form-label', $class); + $this->assertEquals('sm:col-3 lg:col-2 col-form-label', $class); } - public function test_it_can_display_bootstrap_5_form_help_text() + #[Test] + public function it_can_display_bootstrap_6_form_help_text() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-help'); $this->visit('/form-help') - ->seeElementCount('div.form-text', 1) - ->seeInElement('div.form-text', 'This is a help text'); - } - - public function test_it_can_generate_material_admin_26_standard_form_labels() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-label'); - - $page = $this->visit('/form-label') - ->seeElementCount('label', 1) - ->seeInElement('label', 'Title'); - - $class = $page->crawler()->filter('label')->attr('class'); - - $this->assertNull($class); - } - - public function test_it_can_generate_material_admin_26_required_string_for_form_labels() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-label-required'); - - $this->visit('/form-label-required') - ->seeElementCount('label', 1) - ->seeInElement('label', 'Title') - ->within('label', function () { - $this->seeElementCount('span.required', 1) - ->seeInElement('span.required', '*'); - }); - } - - public function test_it_can_float_material_admin_26_labels() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-label-floating'); - - $page = $this->visit('/form-label-floating') - ->seeElementCount('label', 1) - ->seeInElement('label', 'Title'); - - $class = $page->crawler()->filter('label')->attr('class'); - - $this->assertNull($class); - } - - public function test_it_can_generate_material_admin_26_inline_form_labels() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-label-inline'); - - $page = $this->visit('/form-label-inline') - ->seeElementCount('label', 1) - ->seeInElement('label', 'Title'); - - $class = $page->crawler()->filter('label')->attr('class'); - - $this->assertEquals('col-sm-3 col-lg-2 col-form-label', $class); - } - - public function test_it_can_display_material_admin_26_form_help_text() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-help'); - - $this->visit('/form-help') - ->seeElementCount('small.form-text.text-muted', 1) - ->seeInElement('small.form-text.text-muted', 'This is a help text'); + ->seeElementCount('small.form-text', 1) + ->seeInElement('small.form-text', 'This is a help text'); } } diff --git a/tests/Feature/MapInputTest.php b/tests/Feature/MapInputTest.php index 4528a3e..0863009 100644 --- a/tests/Feature/MapInputTest.php +++ b/tests/Feature/MapInputTest.php @@ -7,6 +7,7 @@ use Javaabu\Forms\Tests\TestSupport\Models\City; use MatanYadaev\EloquentSpatial\Objects\Point; use MatanYadaev\EloquentSpatial\Objects\Polygon; +use PHPUnit\Framework\Attributes\Test; class MapInputTest extends TestCase { @@ -23,7 +24,8 @@ protected function setUp(): void } } - public function test_it_adds_the_maps_script_to_the_scripts_stack() + #[Test] + public function it_adds_the_maps_script_to_the_scripts_stack() { $city = new City; $lat = 4.175804; @@ -31,7 +33,7 @@ public function test_it_adds_the_maps_script_to_the_scripts_stack() $city->coordinates = new Point($lat, $lng, self::SRID); - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); Route::get('map-input', function () use ($city) { return view('map-input') @@ -43,7 +45,8 @@ public function test_it_adds_the_maps_script_to_the_scripts_stack() ->seeInElement('script', 'The Google Maps JavaScript API'); } - public function test_it_can_bind_map_inputs_from_attributes() + #[Test] + public function it_can_bind_map_inputs_from_attributes() { $city = new City; $lat = 4.175804; @@ -55,7 +58,7 @@ public function test_it_can_bind_map_inputs_from_attributes() $city->boundary = Polygon::fromWkt($wkt, self::SRID); $city->radius = $radius; - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); Route::get('map-input', function () use ($city) { return view('map-input') @@ -73,7 +76,8 @@ public function test_it_can_bind_map_inputs_from_attributes() }); } - public function test_it_can_bind_map_inputs_from_accessors() + #[Test] + public function it_can_bind_map_inputs_from_accessors() { $city = new City; $lat = 4.175804; @@ -85,7 +89,7 @@ public function test_it_can_bind_map_inputs_from_accessors() $city->boundary = Polygon::fromWkt($wkt, self::SRID); $city->radius = $radius; - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); Route::get('map-input-accessor', function () use ($city) { return view('map-input-accessor') diff --git a/tests/Feature/MultipleSelectTest.php b/tests/Feature/MultipleSelectTest.php index c08e7d7..018980d 100644 --- a/tests/Feature/MultipleSelectTest.php +++ b/tests/Feature/MultipleSelectTest.php @@ -4,10 +4,12 @@ use Illuminate\Http\Request; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class MultipleSelectTest extends TestCase { - public function test_it_posts_all_selected_options() + #[Test] + public function it_posts_all_selected_options() { $this->registerTestRoute('multiple-select-keys', function (Request $request) { $request->validate([ diff --git a/tests/Feature/NavTabsTest.php b/tests/Feature/NavTabsTest.php index 7eb9689..86b1a16 100644 --- a/tests/Feature/NavTabsTest.php +++ b/tests/Feature/NavTabsTest.php @@ -3,12 +3,14 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class NavTabsTest extends TestCase { - public function test_it_can_generate_material_admin_26_nav_tabs() + #[Test] + public function it_can_generate_bootstrap_6_nav_tabs() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('nav-tabs'); $this->visit('/nav-tabs') @@ -36,41 +38,7 @@ public function test_it_can_generate_material_admin_26_nav_tabs() $this->seeElement('li.nav-item') ->seeElement('a.nav-link') ->seeInElement('a.nav-link', 'Icon Tab') - ->seeElement('a.nav-link i[class="zmdi zmdi-shield-security mr-2"]'); - }); - } - - public function test_it_can_generate_bootstrap_5_nav_tabs() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('nav-tabs'); - - $this->visit('/nav-tabs') - ->seeElement('ul.nav.nav-tabs') - ->within('ul.nav.nav-tabs', function () { - // active tabs - $this->seeElement('li.nav-item') - ->seeElement('a.nav-link') - ->seeInElement('a.nav-link.active', 'Active Tab') - ->seeElement('a.nav-link[href="https://active-tab.test"]'); - - // inactive tabs - $this->seeElement('li.nav-item') - ->seeElement('a.nav-link') - ->seeInElement('a.nav-link', 'Inactive Tab') - ->seeElement('a.nav-link[href="https://inactive-tab.test"]'); - - // disabled tabs - $this->seeElement('li.nav-item') - ->seeElement('a.nav-link') - ->seeInElement('a.nav-link.disabled', 'Disabled Tab') - ->seeElement('a.nav-link[href="https://disabled-tab.test"]'); - - // icon tabs - $this->seeElement('li.nav-item') - ->seeElement('a.nav-link') - ->seeInElement('a.nav-link', 'Icon Tab') - ->seeElement('a.nav-link i[class="zmdi zmdi-shield-security mr-2"]'); + ->seeElement('a.nav-link i.zmdi.zmdi-shield-security.me-2[aria-hidden="true"]'); }); } } diff --git a/tests/Feature/NoItemsTest.php b/tests/Feature/NoItemsTest.php index 2d7032e..5552112 100644 --- a/tests/Feature/NoItemsTest.php +++ b/tests/Feature/NoItemsTest.php @@ -3,31 +3,19 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class NoItemsTest extends TestCase { - public function test_it_can_display_no_items_card_for_material_admin_26() + #[Test] + public function it_can_display_no_items_card_for_bootstrap_6() { $this->withoutExceptionHandling(); - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('no-items'); - - $this->visit('/no-items') - ->seeElement('.no-items') - ->within('.no-items', function () { - $this->see('Let\'s create some new activities'); - }) - ->seeElement('.zmdi.zmdi-file'); - } - - public function test_it_can_display_no_items_card_for_bootstrap_5() - { - $this->withoutExceptionHandling(); - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('no-items'); $this->visit('/no-items') ->see('Let\'s create some new activities') - ->seeElement('.fa-regular.fa-file'); + ->seeElement('svg[data-icon="file"]'); } } diff --git a/tests/Feature/OverrideFormsDefaultsMiddlewareTest.php b/tests/Feature/OverrideFormsDefaultsMiddlewareTest.php index e8c5e57..a882ed0 100644 --- a/tests/Feature/OverrideFormsDefaultsMiddlewareTest.php +++ b/tests/Feature/OverrideFormsDefaultsMiddlewareTest.php @@ -4,30 +4,32 @@ use Illuminate\Support\Facades\Config; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; use Route; class OverrideFormsDefaultsMiddlewareTest extends TestCase { - public function test_it_can_use_the_middleware_to_switch_what_theme_to_use() + #[Test] + public function it_can_use_the_middleware_to_switch_what_theme_to_use() { $this->withoutExceptionHandling(); $current_theme = Config::get('forms.framework'); - $this->assertTrue($current_theme === 'bootstrap-5'); + $this->assertEquals('bootstrap-6', $current_theme); - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkOnu(); $current_theme = Config::get('forms.framework'); - $this->assertTrue($current_theme === 'material-admin-26'); + $this->assertEquals('onu', $current_theme); Route::get('/change-framework', function () { - return 'Framework changed to Bootstrap-5'; - })->middleware('forms:bootstrap-5'); + return 'Framework changed to Bootstrap 6'; + })->middleware('forms:bootstrap-6'); $this->get('/change-framework') - ->seeText('Framework changed to Bootstrap-5'); + ->seeText('Framework changed to Bootstrap 6'); $current_theme = Config::get('forms.framework'); - $this->assertTrue($current_theme === 'bootstrap-5'); + $this->assertEquals('bootstrap-6', $current_theme); } } diff --git a/tests/Feature/PerPageTest.php b/tests/Feature/PerPageTest.php index 99f0294..cb1df8d 100644 --- a/tests/Feature/PerPageTest.php +++ b/tests/Feature/PerPageTest.php @@ -3,12 +3,14 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class PerPageTest extends TestCase { - public function test_it_can_see_the_default_per_page_options_bs5() + #[Test] + public function it_can_see_the_default_per_page_options_bs5() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('per-page') ->visit('/per-page') @@ -19,9 +21,10 @@ public function test_it_can_see_the_default_per_page_options_bs5() ->see('500'); } - public function test_it_can_see_the_custom_per_page_options_bs5() + #[Test] + public function it_can_see_the_custom_per_page_options_bs5() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->withoutExceptionHandling(); $this->registerTestRoute('per-page-custom') @@ -31,9 +34,10 @@ public function test_it_can_see_the_custom_per_page_options_bs5() ->see('55'); } - public function test_it_can_see_the_default_per_page_options_material_admin_26() + #[Test] + public function it_can_see_the_default_per_page_options_bootstrap_6() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('per-page') ->visit('/per-page') @@ -44,9 +48,10 @@ public function test_it_can_see_the_default_per_page_options_material_admin_26() ->see('500'); } - public function test_it_can_see_the_custom_per_page_options_material_admin_26() + #[Test] + public function it_can_see_the_custom_per_page_options_bootstrap_6() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->withoutExceptionHandling(); $this->registerTestRoute('per-page-custom') diff --git a/tests/Feature/RadioTest.php b/tests/Feature/RadioTest.php index dacc647..01efe01 100644 --- a/tests/Feature/RadioTest.php +++ b/tests/Feature/RadioTest.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Config; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class RadioTest extends TestCase { @@ -15,104 +16,55 @@ protected function setUp(): void Config::set('forms.inputs.inline', false); } - public function test_it_can_generate_material_admin_26_radio_with_slot() + #[Test] + public function it_can_generate_bootstrap_6_radio_with_slot() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('radio-slot'); $this->visit('/radio-slot') - ->seeElement('div.radio') - ->within('div.radio', function () { + ->seeElement('div.form-field') + ->within('div.form-field', function () { $this - ->seeElement('input[name="check_me"][id="check_me"][type="radio"]') - ->seeElement('label.radio__label') - ->within('label.radio__label', function () { + ->seeElement('input[name="check_me"][id="check_me"][type="radio"].radio') + ->seeElement('label.radio-label') + ->within('label.radio-label', function () { $this->seeElement('a') ->seeInElement('a', 'some site'); }); }); } - public function test_it_can_generate_bootstrap_5_radio_with_slot() + #[Test] + public function it_can_generate_bootstrap_6_form_radio() { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('radio-slot'); - - $this->visit('/radio-slot') - ->seeElement('div.form-check') - ->within('div.form-check', function () { - $this - ->seeElement('input[name="check_me"][id="check_me"][type="radio"].form-check-input') - ->seeElement('label.form-check-label') - ->within('label.form-check-label', function () { - $this->seeElement('a') - ->seeInElement('a', 'some site'); - }); - }); - } - - public function test_it_can_generate_bootstrap_5_form_radio() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('form-radio'); - - $this->visit('/form-radio') - ->seeElement('div.form-check') - ->within('div.form-check', function () { - $this - ->seeElement('input[name="status"][id="status"][type="radio"].form-check-input') - ->seeElement('label.form-check-label') - ->seeInElement('label.form-check-label[for="status"]', 'Status 1'); - }); - } - - public function test_it_can_generate_bootstrap_5_form_radio_that_is_required() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('form-radio-required'); - - $this->visit('/form-radio-required') - ->seeElement('div.form-check') - ->within('div.form-check', function () { - $this - ->seeElement('input[name="status"][id="status"][type="radio"][required].form-check-input') - ->seeElement('label.form-check-label[for="status"]') - ->seeInElement('label.form-check-label[for="status"]', 'Status 1') - ->within('label.form-check-label[for="status"]', function () { - $this->seeElement('span.required') - ->seeInElement('span.required', '*'); - }); - }); - } - - public function test_it_can_generate_material_admin_26_form_radio() - { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-radio'); $this->visit('/form-radio') - ->seeElement('div.radio') - ->within('div.radio', function () { + ->seeElement('div.form-field') + ->within('div.form-field', function () { $this - ->seeElement('input[name="status"][id="status"][type="radio"]') - ->seeElement('label.radio__label') - ->seeInElement('label.radio__label[for="status"]', 'Status 1'); + ->seeElement('input[name="status"][id="status"][type="radio"].radio') + ->seeElement('label.radio-label') + ->seeInElement('label.radio-label[for="status"]', 'Status 1'); }); } - public function test_it_can_generate_material_admin_26_form_radio_that_is_required() + #[Test] + public function it_can_generate_bootstrap_6_form_radio_that_is_required() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-radio-required'); $this->visit('/form-radio-required') - ->seeElement('div.radio') - ->within('div.radio', function () { + ->seeElement('div.form-field') + ->within('div.form-field', function () { $this - ->seeElement('input[name="status"][id="status"][type="radio"][required]') - ->seeElement('label.radio__label[for="status"]') - ->seeInElement('label.radio__label[for="status"]', 'Status 1') - ->within('label.radio__label[for="status"]', function () { + ->seeElement('input[name="status"][id="status"][type="radio"][required].radio') + ->seeElement('label.radio-label[for="status"]') + ->seeInElement('label.radio-label[for="status"]', 'Status 1') + ->within('label.radio-label[for="status"]', function () { $this->seeElement('span.required') ->seeInElement('span.required', '*'); }); diff --git a/tests/Feature/SearchFormTest.php b/tests/Feature/SearchFormTest.php index e895a4a..6b1ce54 100644 --- a/tests/Feature/SearchFormTest.php +++ b/tests/Feature/SearchFormTest.php @@ -3,24 +3,14 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class SearchFormTest extends TestCase { - public function test_it_can_render_a_material_admin_26_search_form() + #[Test] + public function it_can_render_a_bootstrap_6_search_form() { - $this->setFrameworkMaterialAdmin26(); - - $this->registerTestRoute('search-form'); - $this->registerTestRoute('pagination'); - - $this->visit('/search-form?search=hello') - ->seeElement('form.search[action="http://localhost/pagination"]') - ->seeElement('input[name="search"][value="hello"]'); - } - - public function test_it_can_render_a_bootstrap_5_search_form() - { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('search-form'); $this->registerTestRoute('pagination'); diff --git a/tests/Feature/Select2CascadeTest.php b/tests/Feature/Select2CascadeTest.php index 40f2637..1636764 100644 --- a/tests/Feature/Select2CascadeTest.php +++ b/tests/Feature/Select2CascadeTest.php @@ -7,6 +7,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Route; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class Country extends Model { @@ -69,7 +70,8 @@ class Select2CascadeTest extends TestCase { use RefreshDatabase; - public function test_it_can_create_select2_options_from_a_collection() + #[Test] + public function it_can_create_select2_options_from_a_collection() { $countryA = Country::create(['name' => 'Maldives']); $countryB = Country::create(['name' => 'India']); @@ -94,7 +96,8 @@ public function test_it_can_create_select2_options_from_a_collection() ->seeElement('option[value="' . $countryC->getKey() . '"]:not(:selected)'); } - public function test_it_can_create_select2_options_from_a_query_builder() + #[Test] + public function it_can_create_select2_options_from_a_query_builder() { $countryA = Country::create(['name' => 'Maldives']); $countryB = Country::create(['name' => 'India']); @@ -119,7 +122,8 @@ public function test_it_can_create_select2_options_from_a_query_builder() ->seeElement('option[value="' . $countryC->getKey() . '"]:not(:selected)'); } - public function test_it_can_extract_an_accessor_field_from_the_builder() + #[Test] + public function it_can_extract_an_accessor_field_from_the_builder() { $countryA = Country::create(['name' => 'Maldives']); @@ -147,7 +151,8 @@ public function test_it_can_extract_an_accessor_field_from_the_builder() ->seeElement('option[value="' . $countryC->getKey() . '"]:not(:selected)'); } - public function test_it_can_extract_a_get_accessor_field_from_the_builder() + #[Test] + public function it_can_extract_a_get_accessor_field_from_the_builder() { $countryA = Country::create(['name' => 'Maldives']); @@ -175,7 +180,8 @@ public function test_it_can_extract_a_get_accessor_field_from_the_builder() ->seeElement('option[value="' . $countryC->getKey() . '"]:not(:selected)'); } - public function test_it_can_render_a_select2_cascade() + #[Test] + public function it_can_render_a_select2_cascade() { $countryA = Country::create(['name' => 'Maldives']); diff --git a/tests/Feature/Select2Test.php b/tests/Feature/Select2Test.php index 7e91999..f9dc28a 100644 --- a/tests/Feature/Select2Test.php +++ b/tests/Feature/Select2Test.php @@ -7,12 +7,14 @@ use Javaabu\Forms\Tests\TestCase; use Javaabu\Forms\Tests\TestSupport\Enums\ArticleStatuses; use Javaabu\Forms\Tests\TestSupport\Models\Article; +use PHPUnit\Framework\Attributes\Test; class Select2Test extends TestCase { use RefreshDatabase; - public function test_it_can_render_a_select_2_basic_element_whose_value_comes_from_an_enum_cast() + #[Test] + public function it_can_render_a_select_2_basic_element_whose_value_comes_from_an_enum_cast() { // create an article $article = new Article([ @@ -39,7 +41,8 @@ public function test_it_can_render_a_select_2_basic_element_whose_value_comes_fr } - public function test_it_can_render_a_select2_basic_element() + #[Test] + public function it_can_render_a_select2_basic_element() { $post = [ 'author' => 2, @@ -65,7 +68,8 @@ public function test_it_can_render_a_select2_basic_element() ->seeElement('option[value="3"]'); } - public function test_it_can_render_a_select_2_basic_element_with_a_label() + #[Test] + public function it_can_render_a_select_2_basic_element_with_a_label() { $post = [ 'author' => 2, @@ -92,7 +96,8 @@ public function test_it_can_render_a_select_2_basic_element_with_a_label() ->seeElement('option[value="3"]'); } - public function test_it_can_render_a_select2_ajax_element() + #[Test] + public function it_can_render_a_select2_ajax_element() { $post = [ 'author' => 2, @@ -114,9 +119,10 @@ public function test_it_can_render_a_select2_ajax_element() ->seeElement('option[value="2"]:selected'); } - public function test_it_can_render_a_select2_element_with_custom_form_group_class_material_admin_26() + #[Test] + public function it_can_render_a_select2_element_with_custom_form_group_class_bootstrap_6() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $post = [ 'author' => 2, @@ -143,36 +149,8 @@ public function test_it_can_render_a_select2_element_with_custom_form_group_clas ->seeElement('option[value="3"]'); } - public function test_it_can_render_a_select2_element_with_custom_form_group_class_bootstrap_5() - { - $this->setFrameworkBootstrap5(); - - $post = [ - 'author' => 2, - ]; - - $options = [ - '1' => 'Arushad', - '2' => 'John', - '3' => 'Amy', - ]; - - Route::get('select2-basic', function () use ($post, $options) { - return view('select2-basic-form-group-class') - ->with('post', $post) - ->with('options', $options); - })->middleware('web'); - - $this->visit('/select2-basic') - ->seeElement('div.custom-class') - ->seeElement('select.select2-basic[id="author"][data-allow-clear="true"][data-placeholder="Nothing Selected"]') - ->seeElement('option[value=""]') - ->seeElement('option[value="1"]') - ->seeElement('option[value="2"]:selected') - ->seeElement('option[value="3"]'); - } - - public function test_it_only_loads_selected_options_for_ajax_selects() + #[Test] + public function it_only_loads_selected_options_for_ajax_selects() { $article1 = Article::create(['title' => 'Article 1']); $article2 = Article::create(['title' => 'Article 2']); diff --git a/tests/Feature/SelectBooleanValueTest.php b/tests/Feature/SelectBooleanValueTest.php index f16f35a..8391882 100644 --- a/tests/Feature/SelectBooleanValueTest.php +++ b/tests/Feature/SelectBooleanValueTest.php @@ -3,10 +3,12 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class SelectBooleanValueTest extends TestCase { - public function test_it_shows_the_select_field() + #[Test] + public function it_shows_the_select_field() { $this->registerTestRoute('select-boolean-value'); @@ -15,7 +17,8 @@ public function test_it_shows_the_select_field() ->seeElement('option[value="0"]'); } - public function test_it_shows_the_false_value_selected() + #[Test] + public function it_shows_the_false_value_selected() { $this->registerTestRoute('select-boolean-value'); diff --git a/tests/Feature/SelectRelationTest.php b/tests/Feature/SelectRelationTest.php index 9fd8952..dd6564b 100644 --- a/tests/Feature/SelectRelationTest.php +++ b/tests/Feature/SelectRelationTest.php @@ -7,6 +7,7 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Route; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class PostBelongsToMany extends Model { @@ -44,7 +45,8 @@ class SelectRelationTest extends TestCase { use RefreshDatabase; - public function test_it_handles_belongs_to_many_relationships() + #[Test] + public function it_handles_belongs_to_many_relationships() { $post = PostBelongsToMany::create(['content' => 'Content']); @@ -74,7 +76,8 @@ public function test_it_handles_belongs_to_many_relationships() $this->assertCount(1, DB::getQueryLog()); } - public function test_it_handles_morph_many_relationships() + #[Test] + public function it_handles_morph_many_relationships() { $post = PostMorphMany::create(['content' => 'Content']); @@ -102,7 +105,8 @@ public function test_it_handles_morph_many_relationships() $this->assertCount(1, DB::getQueryLog()); } - public function test_it_handles_morph_to_many_relationships() + #[Test] + public function it_handles_morph_to_many_relationships() { $post = PostMorphToMany::create(['content' => 'Content']); diff --git a/tests/Feature/SelectTest.php b/tests/Feature/SelectTest.php index ca7c8e8..e04ca0d 100644 --- a/tests/Feature/SelectTest.php +++ b/tests/Feature/SelectTest.php @@ -6,12 +6,14 @@ use Illuminate\Support\Facades\Route; use Javaabu\Forms\Tests\TestCase; use Javaabu\Forms\Tests\TestSupport\Models\Category; +use PHPUnit\Framework\Attributes\Test; class SelectTest extends TestCase { use RefreshDatabase; - public function test_it_shows_the_slot_if_the_options_are_empty() + #[Test] + public function it_shows_the_slot_if_the_options_are_empty() { $this->registerTestRoute('select-slot'); @@ -21,7 +23,8 @@ public function test_it_shows_the_slot_if_the_options_are_empty() ->seeElement('option[value="c"]'); } - public function test_it_can_render_a_placeholder() + #[Test] + public function it_can_render_a_placeholder() { $this->registerTestRoute('select-placeholder'); @@ -31,7 +34,8 @@ public function test_it_can_render_a_placeholder() ->seeElement('option[value="b"]'); } - public function test_it_adds_a_sync_field_for_multi_selects() + #[Test] + public function it_adds_a_sync_field_for_multi_selects() { $this->registerTestRoute('select-multiple'); @@ -43,7 +47,8 @@ public function test_it_adds_a_sync_field_for_multi_selects() ->seeElement('option[value="c"]'); } - public function test_it_can_exclude_the_sync_field_for_multi_selects() + #[Test] + public function it_can_exclude_the_sync_field_for_multi_selects() { $this->registerTestRoute('select-sync-field'); @@ -53,7 +58,8 @@ public function test_it_can_exclude_the_sync_field_for_multi_selects() ->seeElement('input[type="hidden"][name="custom_sync_name"][value="1"]'); } - public function test_it_includes_old_values_for_tags() + #[Test] + public function it_includes_old_values_for_tags() { $this->registerTestRoute('select-tags'); @@ -65,7 +71,8 @@ public function test_it_includes_old_values_for_tags() ->seeElement('option[value="c"]:selected'); } - public function test_it_can_load_options_from_a_translatable_model() + #[Test] + public function it_can_load_options_from_a_translatable_model() { $category1 = Category::create(['name' => 'Category 1']); $category2 = Category::create(['name' => 'Category 2']); diff --git a/tests/Feature/SelectWithoutKeysTest.php b/tests/Feature/SelectWithoutKeysTest.php index bae5502..55d4add 100644 --- a/tests/Feature/SelectWithoutKeysTest.php +++ b/tests/Feature/SelectWithoutKeysTest.php @@ -4,10 +4,12 @@ use Illuminate\Http\Request; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class SelectWithoutKeysTest extends TestCase { - public function test_it_makes_the_values_numeric() + #[Test] + public function it_makes_the_values_numeric() { $this->registerTestRoute('select-without-keys', function (Request $request) { $request->validate([ @@ -21,7 +23,8 @@ public function test_it_makes_the_values_numeric() ->seeInElement('option[value="2"]', 'c'); } - public function test_it_shows_a_validation_error() + #[Test] + public function it_shows_a_validation_error() { $this->registerTestRoute('select-without-keys', function (Request $request) { $request->validate([ diff --git a/tests/Feature/SpoofMethodTest.php b/tests/Feature/SpoofMethodTest.php index fb4dd96..ba19f0e 100644 --- a/tests/Feature/SpoofMethodTest.php +++ b/tests/Feature/SpoofMethodTest.php @@ -3,10 +3,12 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class SpoofMethodTest extends TestCase { - public function test_it_spoofs_the_methods_for_put_patch_and_delete_forms() + #[Test] + public function it_spoofs_the_methods_for_put_patch_and_delete_forms() { $this->registerTestRoute('spoof-method') ->visit('/spoof-method') diff --git a/tests/Feature/StatusTest.php b/tests/Feature/StatusTest.php index 0f96484..cd5a364 100644 --- a/tests/Feature/StatusTest.php +++ b/tests/Feature/StatusTest.php @@ -3,10 +3,12 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class StatusTest extends TestCase { - public function test_it_can_generate_status_with_slot() + #[Test] + public function it_can_generate_status_with_slot() { $this->registerTestRoute('status-slot'); @@ -18,25 +20,14 @@ public function test_it_can_generate_status_with_slot() }); } - public function test_it_can_generate_material_admin_26_status() + #[Test] + public function it_can_generate_bootstrap_6_status() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('status'); $this->visit('/status') - ->seeElement('span.status.solid.bg-danger') - ->within('span.status', function () { - $this->seeText('Rejected'); - }); - } - - public function test_it_can_generate_bootstrap_5_status() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('status'); - - $this->visit('/status') - ->seeElement('span.status.badge.text-bg-danger') + ->seeElement('span.status.badge.theme-danger') ->within('span.status', function () { $this->seeText('Rejected'); }); diff --git a/tests/Feature/TableCellTest.php b/tests/Feature/TableCellTest.php index b53efbd..96fd3b7 100644 --- a/tests/Feature/TableCellTest.php +++ b/tests/Feature/TableCellTest.php @@ -3,12 +3,14 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class TableCellTest extends TestCase { - public function test_it_can_render_enum_table_cell_entries_for_bootstrap_5() + #[Test] + public function it_can_render_enum_table_cell_entries_for_bootstrap_6() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table-cell-enum'); $this->visit('/table-cell-enum') @@ -19,44 +21,16 @@ public function test_it_can_render_enum_table_cell_entries_for_bootstrap_5() } - public function test_it_can_render_enum_table_cell_entries_for_material_admin_26() + #[Test] + public function it_can_render_status_table_cell_entries_for_bootstrap_6() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('table-cell-enum'); - - $this->visit('/table-cell-enum') - ->seeElement('td') - ->within('td', function () { - $this->seeText('Report Article'); - }); - - } - - public function test_it_can_render_status_table_cell_entries_for_bootstrap_5() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('table-cell-status'); - - $this->visit('/table-cell-status') - ->seeElement('td') - ->within('td', function () { - $this->seeElement('span.status.text-bg-success') - ->within('span.status', function () { - $this->seeText('Published'); - }); - }); - - } - - public function test_it_can_render_status_table_cell_entries_for_material_admin_26() - { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table-cell-status'); $this->visit('/table-cell-status') ->seeElement('td') ->within('td', function () { - $this->seeElement('span.status.bg-success') + $this->seeElement('span.status.badge.theme-success') ->within('span.status', function () { $this->seeText('Published'); }); @@ -64,9 +38,10 @@ public function test_it_can_render_status_table_cell_entries_for_material_admin_ } - public function test_it_can_render_boolean_table_cells() + #[Test] + public function it_can_render_boolean_table_cells() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table-cell-boolean'); $this->visit('/table-cell-boolean') @@ -74,9 +49,10 @@ public function test_it_can_render_boolean_table_cells() ->seeInElement('td', 'Yes'); } - public function test_it_can_render_array_text_table_cells() + #[Test] + public function it_can_render_array_text_table_cells() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table-cell-array'); $this->visit('/table-cell-array') @@ -84,9 +60,10 @@ public function test_it_can_render_array_text_table_cells() ->seeInElement('td', 'orange'); } - public function test_it_can_render_multiline_text_table_cells() + #[Test] + public function it_can_render_multiline_text_table_cells() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table-cell-multiline'); $this->visit('/table-cell-multiline') @@ -94,9 +71,10 @@ public function test_it_can_render_multiline_text_table_cells() ->seeInElement('td', "Javaabu
\nCompany"); } - public function test_it_can_set_the_table_cell_from_model() + #[Test] + public function it_can_set_the_table_cell_from_model() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table-cell-model'); $this->visit('/table-cell-model') @@ -107,9 +85,10 @@ public function test_it_can_set_the_table_cell_from_model() }); } - public function test_it_can_set_the_table_cell_from_value() + #[Test] + public function it_can_set_the_table_cell_from_value() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table-cell-value'); $this->visit('/table-cell-value') @@ -117,19 +96,10 @@ public function test_it_can_set_the_table_cell_from_value() ->seeInElement('td', 'Javaabu'); } - public function test_it_can_generate_bootstrap_5_table_cell() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('table-cell'); - - $this->visit('/table-cell') - ->seeElement('td') - ->seeInElement('td', 'Javaabu'); - } - - public function test_it_can_generate_material_admin_26_table_cell() + #[Test] + public function it_can_generate_bootstrap_6_table_cell() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table-cell'); $this->visit('/table-cell') diff --git a/tests/Feature/TableTest.php b/tests/Feature/TableTest.php index c8e9c64..b48147c 100644 --- a/tests/Feature/TableTest.php +++ b/tests/Feature/TableTest.php @@ -5,14 +5,16 @@ use Illuminate\Foundation\Testing\RefreshDatabase; use Javaabu\Forms\Tests\TestCase; use Javaabu\Forms\Tests\TestSupport\Models\Activity; +use PHPUnit\Framework\Attributes\Test; class TableTest extends TestCase { use RefreshDatabase; - public function test_it_can_generate_bootstrap_5_table() + #[Test] + public function it_can_generate_bootstrap_6_table() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table'); $this->visit('table') @@ -47,9 +49,10 @@ public function test_it_can_generate_bootstrap_5_table() }); } - public function test_it_can_generate_bootstrap_5_striped_table() + #[Test] + public function it_can_generate_bootstrap_6_striped_table() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table'); $this->visit('table') @@ -59,9 +62,10 @@ public function test_it_can_generate_bootstrap_5_striped_table() }); } - public function test_it_can_generate_material_26_table() + #[Test] + public function it_can_generate_a_table_with_row_checkboxes() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table'); $this->visit('table') @@ -111,9 +115,10 @@ public function test_it_can_generate_material_26_table() }); } - public function test_it_displays_empty_table_message_when_no_matching_rows() + #[Test] + public function it_displays_empty_table_message_when_no_matching_rows() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('table'); $this->visit('table') diff --git a/tests/Feature/TabsTest.php b/tests/Feature/TabsTest.php index db976a4..2acfdb7 100644 --- a/tests/Feature/TabsTest.php +++ b/tests/Feature/TabsTest.php @@ -3,79 +3,14 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class TabsTest extends TestCase { - public function test_it_can_generate_material_admin_26_tabs() + #[Test] + public function it_can_generate_bootstrap_6_tabs() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('tabs'); - - $this->visit('/tabs') - ->seeElement('div.tab-container') - ->within('.tab-container', function () { - $this->seeElement('ul.nav.nav-tabs') - ->within('ul.nav.nav-tabs', function () { - // first tab - $this->seeElement('li.nav-item:nth-child(1)') - ->within('li.nav-item:nth-child(1)', function () { - $this->seeElement('a.nav-link[href="#first-tab"][data-toggle="tab"][role="tab"]') - ->seeInElement('a.nav-link', 'First Tab Title') - ->dontSeeElement('a.active'); - }); - - // active tab - $this->seeElement('li.nav-item:nth-child(2)') - ->within('li.nav-item:nth-child(2)', function () { - $this->seeElement('a.nav-link.active[href="#active-tab"][data-toggle="tab"][role="tab"]') - ->seeInElement('a.nav-link', 'Active Tab'); - }); - - // disabled tab - $this->seeElement('li.nav-item:nth-child(3)') - ->within('li.nav-item:nth-child(3)', function () { - $this->seeElement('a.nav-link.disabled[href="#disabled-tab"][data-toggle="tab"][role="tab"]') - ->seeInElement('a.nav-link', 'Disabled Tab') - ->dontSeeElement('a.active'); - }); - - // external tab - $this->seeElement('li.nav-item:nth-child(4)') - ->within('li.nav-item:nth-child(4)', function () { - $this->seeElement('a.nav-link[href="http://example.com"]') - ->seeInElement('a.nav-link', 'External Tab') - ->dontSeeElement('a.active'); - }); - }); - - $this->seeElement('div.tab-content') - ->within('.tab-content', function () { - $this->seeElementCount('div.tab-pane', 3); - - // first tab - $this->seeElement('div.tab-pane#first-tab[role="tabpanel"]') - ->dontSeeElement('#first-tab.active') - ->seeInElement('#first-tab', 'First Tab Content'); - - // active tab - $this->seeElement('div.tab-pane.active.show#active-tab[role="tabpanel"]') - ->seeInElement('#active-tab', 'Active Tab Content'); - - // disabled tab - $this->seeElement('div.tab-pane#disabled-tab[role="tabpanel"]') - ->dontSeeElement('#disabled.active') - ->seeInElement('#disabled-tab', 'Disabled Tab Content'); - - // external tab - $this->dontSeeElement('div.tab-pane#external-tab'); - }); - }); - - } - - public function test_it_can_generate_bootstrap_5_tabs() - { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('tabs'); $this->visit('/tabs') diff --git a/tests/Feature/TextEntryTest.php b/tests/Feature/TextEntryTest.php index 798d832..bc887c6 100644 --- a/tests/Feature/TextEntryTest.php +++ b/tests/Feature/TextEntryTest.php @@ -3,12 +3,14 @@ namespace Javaabu\Forms\Tests\Feature; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class TextEntryTest extends TestCase { - public function test_it_can_render_enum_entries_for_bootstrap_5() + #[Test] + public function it_can_render_enum_entries_for_bootstrap_6() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('text-entry-enum'); $this->visit('/text-entry-enum') @@ -24,27 +26,10 @@ public function test_it_can_render_enum_entries_for_bootstrap_5() } - public function test_it_can_render_enum_entries_for_material_admin_26() + #[Test] + public function it_can_render_status_entries_for_bootstrap_6() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('text-entry-enum'); - - $this->visit('/text-entry-enum') - ->seeElement('dl') - ->within('dl', function () { - $this->seeElement('dt') - ->seeInElement('dt', 'Type') - ->seeElement('dd') - ->within('dd', function () { - $this->seeText('Report Article'); - }); - }); - - } - - public function test_it_can_render_status_entries_for_bootstrap_5() - { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('text-entry-status'); $this->visit('/text-entry-status') @@ -54,7 +39,7 @@ public function test_it_can_render_status_entries_for_bootstrap_5() ->seeInElement('dt', 'Status') ->seeElement('dd') ->within('dd', function () { - $this->seeElement('span.status.text-bg-success') + $this->seeElement('span.status.badge.theme-success') ->within('span.status', function () { $this->seeText('Published'); }); @@ -63,30 +48,10 @@ public function test_it_can_render_status_entries_for_bootstrap_5() } - public function test_it_can_render_status_entries_for_material_admin_26() + #[Test] + public function it_can_render_array_entries() { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('text-entry-status'); - - $this->visit('/text-entry-status') - ->seeElement('dl') - ->within('dl', function () { - $this->seeElement('dt') - ->seeInElement('dt', 'Status') - ->seeElement('dd') - ->within('dd', function () { - $this->seeElement('span.status.bg-success') - ->within('span.status', function () { - $this->seeText('Published'); - }); - }); - }); - - } - - public function test_it_can_render_array_entries() - { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('text-entry-array'); $this->visit('/text-entry-array') @@ -99,9 +64,10 @@ public function test_it_can_render_array_entries() }); } - public function test_it_can_render_boolean_entries() + #[Test] + public function it_can_render_boolean_entries() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('boolean-entry'); $this->visit('/boolean-entry') @@ -114,9 +80,10 @@ public function test_it_can_render_boolean_entries() }); } - public function test_it_can_render_multiline_text_entries() + #[Test] + public function it_can_render_multiline_text_entries() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('text-entry-multiline'); $this->visit('/text-entry-multiline') @@ -129,9 +96,10 @@ public function test_it_can_render_multiline_text_entries() }); } - public function test_it_can_set_the_text_entry_from_model() + #[Test] + public function it_can_set_the_text_entry_from_model() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('text-entry-model'); $this->visit('/text-entry-model') @@ -147,9 +115,10 @@ public function test_it_can_set_the_text_entry_from_model() }); } - public function test_it_can_set_the_text_entry_from_value() + #[Test] + public function it_can_set_the_text_entry_from_value() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('text-entry-value'); $this->visit('/text-entry-value') @@ -162,24 +131,10 @@ public function test_it_can_set_the_text_entry_from_value() }); } - public function test_it_can_generate_bootstrap_5_text_entry() - { - $this->setFrameworkBootstrap5(); - $this->registerTestRoute('text-entry'); - - $this->visit('/text-entry') - ->seeElement('dl') - ->within('dl', function () { - $this->seeElement('dt') - ->seeInElement('dt', 'Name') - ->seeElement('dd') - ->seeInElement('dd', 'Javaabu'); - }); - } - - public function test_it_can_generate_material_admin_26_text_entry() + #[Test] + public function it_can_generate_bootstrap_6_text_entry() { - $this->setFrameworkMaterialAdmin26(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('text-entry'); $this->visit('/text-entry') diff --git a/tests/Feature/TextareaTest.php b/tests/Feature/TextareaTest.php index f961e85..81dbb38 100644 --- a/tests/Feature/TextareaTest.php +++ b/tests/Feature/TextareaTest.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Config; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class TextareaTest extends TestCase { @@ -15,9 +16,10 @@ protected function setUp(): void Config::set('forms.inputs.inline', false); } - public function test_it_can_generate_bootstrap_5_form_textarea() + #[Test] + public function it_can_generate_bootstrap_6_form_textarea() { - $this->setFrameworkBootstrap5(); + $this->setFrameworkBootstrap6(); $this->registerTestRoute('form-textarea'); $this->visit('/form-textarea') @@ -31,24 +33,8 @@ public function test_it_can_generate_bootstrap_5_form_textarea() }); } - public function test_it_can_generate_material_admin_26_form_textarea() - { - $this->setFrameworkMaterialAdmin26(); - $this->registerTestRoute('form-textarea'); - - $this->visit('/form-textarea') - ->seeElement('div.form-group') - ->within('div.form-group', function () { - $this->seeElement('textarea[name="title"][id="title"].form-control') - ->seeElement('textarea[rows="3"]') - ->seeInElement('textarea[name="title"][id="title"].form-control', 'Lorem ipsum') - ->seeElement('i.form-group__bar') - ->seeElement('label[for="title"]') - ->seeInElement('label', 'Title'); - }); - } - - public function test_it_adds_the_tinymce_script_to_the_scripts_stack_for_wysiwyg_inputs() + #[Test] + public function it_adds_the_tinymce_script_to_the_scripts_stack_for_wysiwyg_inputs() { $this->registerTestRoute('wysiwyg'); diff --git a/tests/TestCase.php b/tests/TestCase.php index 19fbb84..679edb1 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -6,16 +6,20 @@ use Composer\Semver\VersionParser; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Artisan; +use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\View; +use Illuminate\Support\MessageBag; +use Illuminate\Support\ViewErrorBag; use Javaabu\Forms\FormsServiceProvider; use Javaabu\Forms\Tests\TestSupport\Providers\TestServiceProvider; use Javaabu\Helpers\HelpersServiceProvider; use Javaabu\Settings\SettingsServiceProvider; use Orchestra\Testbench\BrowserKit\TestCase as BaseTestCase; use Spatie\MediaLibrary\MediaLibraryServiceProvider; +use Symfony\Component\DomCrawler\Crawler; abstract class TestCase extends BaseTestCase { @@ -44,6 +48,9 @@ protected function setUp(): void $this->app['config']->set('session.serialization', 'php'); + // Behaviour tests render with Bootstrap 6; framework tests pick their own. + $this->app['config']->set('forms.framework', 'bootstrap-6'); + // $this->app['config']->set('form-components.framework', env('FORM_COMPONENTS_FRAMEWORK', 'tailwind')); View::addLocation(__DIR__ . '/TestSupport/views'); @@ -71,6 +78,28 @@ protected function getPackageProviders($app) ]; } + /** + * Renders a Blade string and returns a crawler for the HTML. + * + * @param array $data + */ + protected function renderBlade(string $template, array $data = []): Crawler + { + return new Crawler(Blade::render($template, $data)); + } + + /** + * Shares validation errors with the views, as a failed form request would. + * + * @param array> $errors + */ + protected function withViewErrors(array $errors, string $key = 'default'): self + { + View::share('errors', (new ViewErrorBag)->put($key, new MessageBag($errors))); + + return $this; + } + protected function setFramework(string $framework): self { Config::set('forms.framework', $framework); @@ -78,14 +107,14 @@ protected function setFramework(string $framework): self return $this; } - protected function setFrameworkBootstrap5(): self + protected function setFrameworkBootstrap6(): self { - return $this->setFramework('bootstrap-5'); + return $this->setFramework('bootstrap-6'); } - protected function setFrameworkMaterialAdmin26(): self + protected function setFrameworkOnu(): self { - return $this->setFramework('material-admin-26'); + return $this->setFramework('onu'); } protected function registerTestRoute($uri, ?callable $post = null): self diff --git a/tests/Unit/FormsDataBinderTest.php b/tests/Unit/FormsDataBinderTest.php index c512d2e..f884be1 100644 --- a/tests/Unit/FormsDataBinderTest.php +++ b/tests/Unit/FormsDataBinderTest.php @@ -4,10 +4,12 @@ use Javaabu\Forms\FormsDataBinder; use Javaabu\Forms\Tests\TestCase; +use PHPUnit\Framework\Attributes\Test; class FormsDataBinderTest extends TestCase { - public function test_it_can_bind_targets() + #[Test] + public function it_can_bind_targets() { $binder = new FormsDataBinder; $this->assertNull($binder->get()); @@ -16,7 +18,8 @@ public function test_it_can_bind_targets() $this->assertEquals($array, $binder->get()); } - public function test_it_can_bind_multiple_targets() + #[Test] + public function it_can_bind_multiple_targets() { $binder = new FormsDataBinder; diff --git a/tests/Unit/FrameworksTest.php b/tests/Unit/FrameworksTest.php new file mode 100644 index 0000000..8507f41 --- /dev/null +++ b/tests/Unit/FrameworksTest.php @@ -0,0 +1,48 @@ +assertInstanceOf(Onu::class, Frameworks::get('onu')); + $this->assertInstanceOf(Bootstrap6::class, Frameworks::get('bootstrap-6')); + $this->assertEquals(['onu', 'bootstrap-6'], Frameworks::names()); + } + + #[Test] + public function it_throws_for_an_unknown_framework(): void + { + $this->expectException(InvalidArgumentException::class); + + Frameworks::get('bootstrap-5'); + } + + #[Test] + public function it_can_register_a_custom_framework(): void + { + Frameworks::register('my-theme', Bootstrap6::class); + + $this->assertInstanceOf(Bootstrap6::class, Frameworks::get('my-theme')); + } + + #[Test] + public function it_maps_bootstrap_colours_to_bootstrap_6_classes(): void + { + $framework = new Bootstrap6; + + $this->assertEquals('btn-solid theme-danger btn-sm', $framework->button('danger', 'sm')); + $this->assertEquals('btn-outline theme-primary', $framework->button('outline-primary')); + $this->assertEquals('badge theme-success', $framework->badge('success')); + $this->assertEquals('alert theme-warning', $framework->alert('warning')); + } +} From c7c7524d876b0c923d736bb3c1e5e7b491c34ffa Mon Sep 17 00:00:00 2001 From: Naffah Abdulla Rasheed Date: Wed, 4 Nov 2026 12:57:03 +0500 Subject: [PATCH 03/10] Use attribute selectors for prefixed classes so tests pass on older css-selector Co-Authored-By: Claude Opus 5.5 --- tests/Feature/Frameworks/Bootstrap6Test.php | 4 ++-- tests/Feature/InputTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Feature/Frameworks/Bootstrap6Test.php b/tests/Feature/Frameworks/Bootstrap6Test.php index 16ba0ff..bb78fc5 100644 --- a/tests/Feature/Frameworks/Bootstrap6Test.php +++ b/tests/Feature/Frameworks/Bootstrap6Test.php @@ -105,7 +105,7 @@ public function it_uses_prefixed_responsive_classes_for_inline_fields(): void { $html = $this->renderBlade(''); - $this->assertCount(1, $html->filter('div.row.mb-4 > label.sm\:col-3.lg\:col-2.col-form-label')); - $this->assertCount(1, $html->filter('div.row.mb-4 > div.sm\:col-9.lg\:col-10 input.form-control')); + $this->assertCount(1, $html->filter('div.row.mb-4 > label.col-form-label[class~="sm:col-3"][class~="lg:col-2"]')); + $this->assertCount(1, $html->filter('div.row.mb-4 > div[class~="sm:col-9"][class~="lg:col-10"] input.form-control')); } } diff --git a/tests/Feature/InputTest.php b/tests/Feature/InputTest.php index 15ad475..2fd17b4 100644 --- a/tests/Feature/InputTest.php +++ b/tests/Feature/InputTest.php @@ -95,8 +95,8 @@ public function it_can_generate_bootstrap_6_inline_form_inputs() ->within('div.row.mb-4', function () { $this->seeElement('label.col-form-label[for="title"]') ->seeInElement('label.col-form-label[for="title"]', 'Title') - ->seeElement('div.sm\\:col-9.lg\\:col-10') - ->within('div.sm\\:col-9.lg\\:col-10', function () { + ->seeElement('div[class~="sm:col-9"][class~="lg:col-10"]') + ->within('div[class~="sm:col-9"][class~="lg:col-10"]', function () { $this->seeElement('input[name="title"][id="title"][value="Lorem ipsum"].form-control'); }); }); From d26d4c1d37355d66c10747bd675a4a0437324503 Mon Sep 17 00:00:00 2001 From: Naffah Abdulla Rasheed Date: Wed, 4 Nov 2026 13:07:21 +0500 Subject: [PATCH 04/10] Add the Onu framework, using Onu's own classes and tokens - resources/views/onu: every component, with the data-slot markup and class strings of the matching @javaabu/onu React component - scripts/onu-classes.mjs server-renders Onu's components and writes resources/onu/classes.php; CI fails when it is out of date - resources/css/onu.css for Tailwind apps (sources the views, styles native checkbox/radio/dialog/file inputs with Onu tokens); prebuilt dist/onu.css for apps without Tailwind, published with --tag=forms-assets - onu is now the default framework - Fix: paginator views no longer need component variables - Smoke test renders every fixture view with every framework - docs/frameworks/onu.md and bootstrap-6.md Closes #8 Co-Authored-By: Claude Opus 5.5 --- .github/workflows/tests.yml | 30 + config/config.php | 12 +- dist/onu.css | 2 + docs/frameworks/_category_.json | 4 + docs/frameworks/bootstrap-6.md | 63 + docs/frameworks/onu.md | 73 + lang/dv/strings.php | 2 + lang/en/strings.php | 2 + package.json | 14 +- pnpm-lock.yaml | 2768 +++++++++++++++++ resources/css/onu-standalone.css | 8 + resources/css/onu.css | 87 + resources/onu/classes.php | 308 +- resources/views/onu/accordion.blade.php | 32 + .../views/onu/accordion/collapse.blade.php | 9 + .../views/onu/accordion/header.blade.php | 4 + resources/views/onu/accordion/item.blade.php | 25 + resources/views/onu/alert.blade.php | 21 + resources/views/onu/bulk-actions.blade.php | 25 + resources/views/onu/button-group.blade.php | 8 + resources/views/onu/button.blade.php | 10 + resources/views/onu/card.blade.php | 38 + resources/views/onu/card/footer.blade.php | 3 + resources/views/onu/card/header.blade.php | 3 + resources/views/onu/card/subtitle.blade.php | 3 + resources/views/onu/card/title.blade.php | 3 + resources/views/onu/checkbox.blade.php | 43 + resources/views/onu/errors.blade.php | 8 + resources/views/onu/file.blade.php | 82 + resources/views/onu/file/file-input.blade.php | 31 + resources/views/onu/filter-submit.blade.php | 59 + resources/views/onu/form-group.blade.php | 18 + resources/views/onu/image.blade.php | 95 + resources/views/onu/input-help.blade.php | 3 + resources/views/onu/input.blade.php | 72 + resources/views/onu/js-errors.blade.php | 3 + resources/views/onu/label-required.blade.php | 3 + resources/views/onu/label.blade.php | 10 + resources/views/onu/link-button.blade.php | 11 + resources/views/onu/map-input.blade.php | 88 + resources/views/onu/modal.blade.php | 34 + resources/views/onu/nav-tabs.blade.php | 35 + resources/views/onu/no-items.blade.php | 23 + resources/views/onu/pagination.blade.php | 66 + resources/views/onu/radio.blade.php | 43 + resources/views/onu/select.blade.php | 154 + resources/views/onu/status.blade.php | 7 + resources/views/onu/table.blade.php | 60 + resources/views/onu/table/cell.blade.php | 24 + resources/views/onu/table/empty-row.blade.php | 10 + resources/views/onu/table/heading.blade.php | 20 + resources/views/onu/table/row.blade.php | 10 + resources/views/onu/tabs.blade.php | 29 + resources/views/onu/tabs/nav-item.blade.php | 25 + resources/views/onu/tabs/pane.blade.php | 13 + resources/views/onu/text-entry.blade.php | 39 + resources/views/onu/textarea.blade.php | 36 + scripts/onu-classes.mjs | 193 ++ src/FormsServiceProvider.php | 4 + src/Frameworks/Onu.php | 12 +- .../Feature/Frameworks/FrameworkSmokeTest.php | 157 + tests/Feature/Frameworks/OnuTest.php | 181 ++ tests/Unit/FrameworksTest.php | 8 + 63 files changed, 5251 insertions(+), 15 deletions(-) create mode 100644 dist/onu.css create mode 100644 docs/frameworks/_category_.json create mode 100644 docs/frameworks/bootstrap-6.md create mode 100644 docs/frameworks/onu.md create mode 100644 resources/css/onu-standalone.css create mode 100644 resources/css/onu.css create mode 100644 resources/views/onu/accordion.blade.php create mode 100644 resources/views/onu/accordion/collapse.blade.php create mode 100644 resources/views/onu/accordion/header.blade.php create mode 100644 resources/views/onu/accordion/item.blade.php create mode 100644 resources/views/onu/alert.blade.php create mode 100644 resources/views/onu/bulk-actions.blade.php create mode 100644 resources/views/onu/button-group.blade.php create mode 100644 resources/views/onu/button.blade.php create mode 100644 resources/views/onu/card.blade.php create mode 100644 resources/views/onu/card/footer.blade.php create mode 100644 resources/views/onu/card/header.blade.php create mode 100644 resources/views/onu/card/subtitle.blade.php create mode 100644 resources/views/onu/card/title.blade.php create mode 100644 resources/views/onu/checkbox.blade.php create mode 100644 resources/views/onu/errors.blade.php create mode 100644 resources/views/onu/file.blade.php create mode 100644 resources/views/onu/file/file-input.blade.php create mode 100644 resources/views/onu/filter-submit.blade.php create mode 100644 resources/views/onu/form-group.blade.php create mode 100644 resources/views/onu/image.blade.php create mode 100644 resources/views/onu/input-help.blade.php create mode 100644 resources/views/onu/input.blade.php create mode 100644 resources/views/onu/js-errors.blade.php create mode 100644 resources/views/onu/label-required.blade.php create mode 100644 resources/views/onu/label.blade.php create mode 100644 resources/views/onu/link-button.blade.php create mode 100644 resources/views/onu/map-input.blade.php create mode 100644 resources/views/onu/modal.blade.php create mode 100644 resources/views/onu/nav-tabs.blade.php create mode 100644 resources/views/onu/no-items.blade.php create mode 100644 resources/views/onu/pagination.blade.php create mode 100644 resources/views/onu/radio.blade.php create mode 100644 resources/views/onu/select.blade.php create mode 100644 resources/views/onu/status.blade.php create mode 100644 resources/views/onu/table.blade.php create mode 100644 resources/views/onu/table/cell.blade.php create mode 100644 resources/views/onu/table/empty-row.blade.php create mode 100644 resources/views/onu/table/heading.blade.php create mode 100644 resources/views/onu/table/row.blade.php create mode 100644 resources/views/onu/tabs.blade.php create mode 100644 resources/views/onu/tabs/nav-item.blade.php create mode 100644 resources/views/onu/tabs/pane.blade.php create mode 100644 resources/views/onu/text-entry.blade.php create mode 100644 resources/views/onu/textarea.blade.php create mode 100644 scripts/onu-classes.mjs create mode 100644 tests/Feature/Frameworks/FrameworkSmokeTest.php create mode 100644 tests/Feature/Frameworks/OnuTest.php diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3f78e09..ed8b5c2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -75,3 +75,33 @@ jobs: - name: Check code style run: vendor/bin/pint --test + + assets: + runs-on: ubuntu-latest + + name: Assets + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Onu classes match @javaabu/onu + run: pnpm check + + - name: Built files are up to date + run: | + pnpm icons + pnpm build + git diff --exit-code -- resources/icons dist diff --git a/config/config.php b/config/config.php index 8896c1b..69349ba 100644 --- a/config/config.php +++ b/config/config.php @@ -13,7 +13,7 @@ | */ - 'framework' => env('FORMS_FRAMEWORK', 'bootstrap-6'), + 'framework' => env('FORMS_FRAMEWORK', 'onu'), /* |-------------------------------------------------------------------------- @@ -88,10 +88,12 @@ 'frameworks' => [ 'onu' => [ - 'inline_label_class' => 'sm:w-1/4 lg:w-1/6 sm:shrink-0', - 'inline_input_class' => 'min-w-0 flex-1', - 'inline_entry_label_class' => 'sm:w-1/2 md:w-1/3 sm:shrink-0', - 'inline_entry_class' => 'min-w-0 flex-1', + // Onu lays out inline fields with container queries and --onu-label-width; + // these classes are added on top. + 'inline_label_class' => '', + 'inline_input_class' => '', + 'inline_entry_label_class' => '', + 'inline_entry_class' => '', 'date_icon_wrapper_class' => '', 'date_clear_btn_class' => '', ], diff --git a/dist/onu.css b/dist/onu.css new file mode 100644 index 0000000..e5ae07c --- /dev/null +++ b/dist/onu.css @@ -0,0 +1,2 @@ +/*! tailwindcss v4.3.4 | MIT License | https://tailwindcss.com */ +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:block))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){:root,:host{--shimmer-angle:20deg}*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-pan-x:initial;--tw-pan-y:initial;--tw-pinch-zoom:initial;--tw-scroll-snap-strictness:proximity;--tw-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-content:"";--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0;--scroll-fade-t:0px;--scroll-fade-b:0px;--scroll-fade-s:0px;--scroll-fade-e:0px;--scroll-fade-mask:initial;--shimmer-image:initial;--shimmer-text-fill:initial}}}@layer theme{:root,:host{--spacing:.25rem;--breakpoint-2xl:96rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-normal:0em;--tracking-wide:.025em;--tracking-widest:.1em;--leading-tight:1.25;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--radius-md:calc(var(--radius) * .8);--drop-shadow-sm:0 1px 2px #00000026;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--blur-xs:4px;--blur-sm:8px;--aspect-video:16 / 9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--onu-font-sans);--default-mono-font-family:var(--onu-font-mono);--color-border:var(--border)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab, var(--ring) 50%, transparent)}}::selection{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){::selection{background-color:color-mix(in oklab, var(--primary) 25%, transparent)}}html{-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%}body{background-color:var(--background);color:var(--foreground);font-family:var(--onu-font-sans);font-size:var(--onu-font-size);line-height:var(--onu-line-height);font-feature-settings:"cv11", "ss01";-webkit-font-smoothing:antialiased}:lang(dv){font-family:var(--onu-font-thaana);font-synthesis:none;letter-spacing:0;line-height:1.75}:lang(dv) :is(em,i,cite){font-style:normal}:lang(dv) :is(b,strong,h1,h2,h3,h4,h5,h6,th){font-family:var(--onu-font-thaana-bold,var(--onu-font-thaana))}.tabular-nums,[data-numeric]{font-variant-numeric:tabular-nums}@media (pointer:coarse){:where([data-slot=button],[data-slot=select-trigger],[data-slot=toggle],[data-slot=tabs-trigger],[data-slot=input],[data-slot=input-group],[data-slot=pagination-link],[data-slot=dropdown-menu-item],[data-slot=command-item],[data-slot=select-item]){min-height:var(--onu-touch-target)}:where([data-slot=button][data-size^=icon],[data-slot=pagination-link]){min-width:var(--onu-touch-target)}}@media (prefers-reduced-motion:reduce){*,:before,:after{scroll-behavior:auto!important;transition-duration:.01ms!important;animation-duration:.01ms!important;animation-iteration-count:1!important}}@media print{:root{--background:white;--foreground:black}[data-print=hide],[data-slot=sidebar],[data-slot=sidebar-gap],[data-slot=sidebar-container],[data-slot=app-header],[data-slot=bottom-nav],[data-slot=skip-link],[data-part=back-to-top],[data-slot=announcement-bar],[data-slot=sonner-toaster],[data-sonner-toaster]{display:none!important}[data-slot=app-layout-main]{padding:0!important}}}@layer components{.forms-checkbox,.forms-radio{appearance:none;cursor:pointer}.forms-checkbox:checked{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M20 6 9 17l-5-5'/%3e%3c/svg%3e");background-position:50%;background-repeat:no-repeat;background-size:.75rem}.forms-checkbox:indeterminate{border-color:var(--primary);background-color:var(--primary);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round'%3e%3cpath d='M5 12h14'/%3e%3c/svg%3e");background-position:50%;background-repeat:no-repeat;background-size:.75rem}.forms-radio:checked{background-image:radial-gradient(circle, var(--primary-foreground) 0 30%, transparent 34%)}.forms-dialog{border:0;max-width:none;max-height:none;margin:0;padding:0}.forms-dialog:not([open]){display:none}.forms-dialog::backdrop{background:var(--overlay,#00000073)}.btn-file>input[type=file]{cursor:pointer;opacity:0;position:absolute;inset:0}.fileinput-new .fileinput-exists,.fileinput-exists .fileinput-new{display:none}.fileinput-preview img{object-fit:contain;width:100%;height:100%}.cover-preview .fileinput-preview img{object-fit:cover}}@layer utilities{.\@container\/address{container:address/inline-size}.\@container\/attachments{container:attachments/inline-size}.\@container\/attributes{container:attributes/inline-size}.\@container\/auth{container:auth/inline-size}.\@container\/card{container:card/inline-size}.\@container\/card-header{container:card-header/inline-size}.\@container\/chart{container:chart/inline-size}.\@container\/coords{container:coords/inline-size}.\@container\/date-range{container:date-range/inline-size}.\@container\/dual-listbox{container:dual-listbox/inline-size}.\@container\/editor{container:editor/inline-size}.\@container\/features{container:features/inline-size}.\@container\/field-group{container:field-group/inline-size}.\@container\/footer{container:footer/inline-size}.\@container\/form-field{container:form-field/inline-size}.\@container\/form-group{container:form-group/inline-size}.\@container\/full-calendar{container:full-calendar/inline-size}.\@container\/gallery{container:gallery/inline-size}.\@container\/hero{container:hero/inline-size}.\@container\/live-map{container:live-map/inline-size}.\@container\/location-card{container:location-card/inline-size}.\@container\/map-picker{container:map-picker/inline-size}.\@container\/map-radius{container:map-radius/inline-size}.\@container\/media{container:media/inline-size}.\@container\/page-title{container:page-title/inline-size}.\@container\/repeating-group{container:repeating-group/inline-size}.\@container\/replay{container:replay/inline-size}.\@container\/section{container:section/inline-size}.\@container\/shape-editor{container:shape-editor/inline-size}.\@container\/skeleton-table{container:skeleton-table/inline-size}.\@container\/stacked-tabs{container:stacked-tabs/inline-size}.\@container\/stat-tile{container:stat-tile/inline-size}.\@container\/stat-tiles{container:stat-tiles/inline-size}.\@container\/stops{container:stops/inline-size}.\@container\/translations{container:translations/inline-size}.\@container\/vmm{container:vmm/inline-size}.\@container\/wizard{container:wizard/inline-size}.\@container{container-type:inline-size}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.\!collapse{visibility:collapse!important}.\!visible{visibility:visible!important}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:0}.inset-\[15\%\]{inset:15%}.inset-x-0{inset-inline:0}.inset-x-2{inset-inline:calc(var(--spacing) * 2)}.inset-x-4{inset-inline:calc(var(--spacing) * 4)}.inset-x-6{inset-inline:calc(var(--spacing) * 6)}.inset-y-0{inset-block:0}.inset-y-2{inset-block:calc(var(--spacing) * 2)}.-start-12{inset-inline-start:calc(var(--spacing) * -12)}.start-\(--save-bar-start\,0px\){inset-inline-start:var(--save-bar-start,0px)}.start-0{inset-inline-start:calc(var(--spacing) * 0)}.start-1{inset-inline-start:calc(var(--spacing) * 1)}.start-1\.5{inset-inline-start:calc(var(--spacing) * 1.5)}.start-1\/2{inset-inline-start:50%}.start-2{inset-inline-start:calc(var(--spacing) * 2)}.start-2\.5{inset-inline-start:calc(var(--spacing) * 2.5)}.start-3{inset-inline-start:calc(var(--spacing) * 3)}.start-3\.5{inset-inline-start:calc(var(--spacing) * 3.5)}.start-\[calc\(50\%\+0\.25rem\)\]{inset-inline-start:calc(50% + .25rem)}.-end-0\.5{inset-inline-end:calc(var(--spacing) * -.5)}.-end-1{inset-inline-end:calc(var(--spacing) * -1)}.-end-12{inset-inline-end:calc(var(--spacing) * -12)}.end-\(--save-bar-end\,0px\){inset-inline-end:var(--save-bar-end,0px)}.end-0{inset-inline-end:calc(var(--spacing) * 0)}.end-1{inset-inline-end:calc(var(--spacing) * 1)}.end-2{inset-inline-end:calc(var(--spacing) * 2)}.end-2\.5{inset-inline-end:calc(var(--spacing) * 2.5)}.end-3{inset-inline-end:calc(var(--spacing) * 3)}.end-4{inset-inline-end:calc(var(--spacing) * 4)}.end-7{inset-inline-end:calc(var(--spacing) * 7)}.-top-0\.5{top:calc(var(--spacing) * -.5)}.-top-1{top:calc(var(--spacing) * -1)}.-top-12{top:calc(var(--spacing) * -12)}.top-0{top:0}.top-1{top:var(--spacing)}.top-1\/2{top:50%}.top-1\/3{top:33.3333%}.top-2{top:calc(var(--spacing) * 2)}.top-3{top:calc(var(--spacing) * 3)}.top-3\.5{top:calc(var(--spacing) * 3.5)}.top-4{top:calc(var(--spacing) * 4)}.top-\[60\%\]{top:60%}.top-full{top:100%}.top-px{top:1px}.-bottom-12{bottom:calc(var(--spacing) * -12)}.bottom-0{bottom:0}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-6{bottom:calc(var(--spacing) * 6)}.bottom-\[calc\(1rem\+env\(safe-area-inset-bottom\)\)\]{bottom:calc(1rem + env(safe-area-inset-bottom))}.bottom-full{bottom:100%}.isolate{isolation:isolate}.-z-10{z-index:calc(10 * -1)}.-z-20{z-index:calc(20 * -1)}.z-0{z-index:0}.z-1{z-index:1}.z-5{z-index:5}.z-10{z-index:10}.z-15{z-index:15}.z-20{z-index:20}.z-25{z-index:25}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-\[100\]{z-index:100}.order-1{order:1}.order-2{order:2}.order-first{order:-9999}.order-last{order:9999}.col-span-full{grid-column:1/-1}.col-start-2{grid-column-start:2}.col-end-\[-1\]{grid-column-end:-1}.row-span-2{grid-row:span 2/span 2}.row-start-1{grid-row-start:1}.float-start{float:inline-start}.clear-both{clear:both}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.-m-3{margin:calc(var(--spacing) * -3)}.m-0{margin:0}.m-0\.5{margin:calc(var(--spacing) * .5)}.-mx-0\.5{margin-inline:calc(var(--spacing) * -.5)}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.-mx-1\.5{margin-inline:calc(var(--spacing) * -1.5)}.-mx-4{margin-inline:calc(var(--spacing) * -4)}.mx-0\.5{margin-inline:calc(var(--spacing) * .5)}.mx-1{margin-inline:var(--spacing)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-3\.5{margin-inline:calc(var(--spacing) * 3.5)}.mx-\[3px\]{margin-inline:3px}.mx-auto{margin-inline:auto}.-my-0\.5{margin-block:calc(var(--spacing) * -.5)}.-my-2{margin-block:calc(var(--spacing) * -2)}.my-0\.5{margin-block:calc(var(--spacing) * .5)}.my-1{margin-block:var(--spacing)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-4{margin-block:calc(var(--spacing) * 4)}.my-auto{margin-block:auto}.-ms-1{margin-inline-start:calc(var(--spacing) * -1)}.-ms-2{margin-inline-start:calc(var(--spacing) * -2)}.-ms-4{margin-inline-start:calc(var(--spacing) * -4)}.ms-0\.5{margin-inline-start:calc(var(--spacing) * .5)}.ms-1{margin-inline-start:var(--spacing)}.ms-2{margin-inline-start:calc(var(--spacing) * 2)}.ms-4{margin-inline-start:calc(var(--spacing) * 4)}.ms-auto{margin-inline-start:auto}.ms-px{margin-inline-start:1px}.me-1{margin-inline-end:var(--spacing)}.me-2{margin-inline-end:calc(var(--spacing) * 2)}.me-3{margin-inline-end:calc(var(--spacing) * 3)}.me-4{margin-inline-end:calc(var(--spacing) * 4)}.me-auto{margin-inline-end:auto}.-mt-2{margin-top:calc(var(--spacing) * -2)}.-mt-4{margin-top:calc(var(--spacing) * -4)}.mt-0{margin-top:0}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-auto{margin-top:auto}.-mb-4{margin-bottom:calc(var(--spacing) * -4)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.no-scrollbar::-webkit-scrollbar{display:none}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-3{-webkit-line-clamp:3;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\!grid{display:grid!important}.\!inline{display:inline!important}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.inline-grid{display:inline-grid}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-row{display:table-row}.\[field-sizing\:fixed\]{field-sizing:fixed}.field-sizing-content{field-sizing:content}.aspect-\[2\/1\]{aspect-ratio:2}.aspect-\[3\/4\]{aspect-ratio:3/4}.aspect-auto{aspect-ratio:auto}.aspect-square{aspect-ratio:1}.aspect-video{aspect-ratio:var(--aspect-video)}.size-\(--cell-size\){width:var(--cell-size);height:var(--cell-size)}.size-1{width:var(--spacing);height:var(--spacing)}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-1\/2{width:50%;height:50%}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-2\!{width:calc(var(--spacing) * 2)!important;height:calc(var(--spacing) * 2)!important}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\!{width:calc(var(--spacing) * 3)!important;height:calc(var(--spacing) * 3)!important}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-6\!{width:calc(var(--spacing) * 6)!important;height:calc(var(--spacing) * 6)!important}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.size-11{width:calc(var(--spacing) * 11);height:calc(var(--spacing) * 11)}.size-12{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12)}.size-16{width:calc(var(--spacing) * 16);height:calc(var(--spacing) * 16)}.size-20{width:calc(var(--spacing) * 20);height:calc(var(--spacing) * 20)}.size-28{width:calc(var(--spacing) * 28);height:calc(var(--spacing) * 28)}.size-36{width:calc(var(--spacing) * 36);height:calc(var(--spacing) * 36)}.size-60{width:calc(var(--spacing) * 60);height:calc(var(--spacing) * 60)}.size-\[var\(--cell-size\,2rem\)\]{width:var(--cell-size,2rem);height:var(--cell-size,2rem)}.size-auto{width:auto;height:auto}.size-full{width:100%;height:100%}.h-\(--cell-size\){height:var(--cell-size)}.h-\(--radix-accordion-content-height\){height:var(--radix-accordion-content-height)}.h-\(--radix-navigation-menu-viewport-height\){height:var(--radix-navigation-menu-viewport-height)}.h-0\.5{height:calc(var(--spacing) * .5)}.h-1{height:var(--spacing)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-5\.5{height:calc(var(--spacing) * 5.5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-8\!{height:calc(var(--spacing) * 8)!important}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-24{height:calc(var(--spacing) * 24)}.h-32{height:calc(var(--spacing) * 32)}.h-40{height:calc(var(--spacing) * 40)}.h-56{height:calc(var(--spacing) * 56)}.h-64{height:calc(var(--spacing) * 64)}.h-72{height:calc(var(--spacing) * 72)}.h-80{height:calc(var(--spacing) * 80)}.h-\[1\.15rem\]{height:1.15rem}.h-\[75dvh\]{height:75dvh}.h-\[calc\(100\%-1px\)\]{height:calc(100% - 1px)}.h-\[calc\(var\(--cell-size\)\*1\.6\)\]{height:calc(var(--cell-size) * 1.6)}.h-\[calc\(var\(--onu-header-height\,3\.5rem\)\+env\(safe-area-inset-top\)\)\]{height:calc(var(--onu-header-height,3.5rem) + env(safe-area-inset-top))}.h-\[var\(--cell-size\,2rem\)\]{height:var(--cell-size,2rem)}.h-auto{height:auto}.h-dvh{height:100dvh}.h-full{height:100%}.h-px{height:1px}.h-svh{height:100svh}.max-h-\(--radix-context-menu-content-available-height\){max-height:var(--radix-context-menu-content-available-height)}.max-h-\(--radix-dropdown-menu-content-available-height\){max-height:var(--radix-dropdown-menu-content-available-height)}.max-h-\(--radix-popover-content-available-height\){max-height:var(--radix-popover-content-available-height)}.max-h-\(--radix-select-content-available-height\){max-height:var(--radix-select-content-available-height)}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-56{max-height:calc(var(--spacing) * 56)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[75dvh\]{max-height:75dvh}.max-h-\[85dvh\]{max-height:85dvh}.max-h-\[97\%\]{max-height:97%}.max-h-\[calc\(100dvh-2rem\)\]{max-height:calc(100dvh - 2rem)}.max-h-\[calc\(100dvh-3rem\)\]{max-height:calc(100dvh - 3rem)}.max-h-\[min\(28rem\,60vh\)\]{max-height:min(28rem,60vh)}.min-h-0{min-height:0}.min-h-3{min-height:calc(var(--spacing) * 3)}.min-h-5{min-height:calc(var(--spacing) * 5)}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-7{min-height:calc(var(--spacing) * 7)}.min-h-8{min-height:calc(var(--spacing) * 8)}.min-h-9{min-height:calc(var(--spacing) * 9)}.min-h-10{min-height:calc(var(--spacing) * 10)}.min-h-11{min-height:calc(var(--spacing) * 11)}.min-h-12{min-height:calc(var(--spacing) * 12)}.min-h-14{min-height:calc(var(--spacing) * 14)}.min-h-16{min-height:calc(var(--spacing) * 16)}.min-h-20{min-height:calc(var(--spacing) * 20)}.min-h-40{min-height:calc(var(--spacing) * 40)}.min-h-48{min-height:calc(var(--spacing) * 48)}.min-h-\[2\.875rem\]{min-height:2.875rem}.min-h-\[60dvh\]{min-height:60dvh}.min-h-svh{min-height:100svh}.w-\(--cell-size\){width:var(--cell-size)}.w-\(--onu-qr-size\){width:var(--onu-qr-size)}.w-\(--radix-dropdown-menu-trigger-width\){width:var(--radix-dropdown-menu-trigger-width)}.w-\(--radix-popover-trigger-width\){width:var(--radix-popover-trigger-width)}.w-\(--sidebar-width\){width:var(--sidebar-width)}.w-0{width:0}.w-1{width:var(--spacing)}.w-1\/2{width:50%}.w-1\/3{width:33.3333%}.w-2{width:calc(var(--spacing) * 2)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-2\/3{width:66.6667%}.w-2\/5{width:40%}.w-3{width:calc(var(--spacing) * 3)}.w-3\/4{width:75%}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-10{width:calc(var(--spacing) * 10)}.w-12{width:calc(var(--spacing) * 12)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-28{width:calc(var(--spacing) * 28)}.w-32{width:calc(var(--spacing) * 32)}.w-36{width:calc(var(--spacing) * 36)}.w-44{width:calc(var(--spacing) * 44)}.w-56{width:calc(var(--spacing) * 56)}.w-60{width:calc(var(--spacing) * 60)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-\[2em\]{width:2em}.w-\[3ch\]{width:3ch}.w-\[100px\]{width:100px}.w-\[calc\(100\%-2rem\)\]{width:calc(100% - 2rem)}.w-\[calc\(var\(--cell-size\)\*7\)\]{width:calc(var(--cell-size) * 7)}.w-\[min\(18rem\,85vw\)\]{width:min(18rem,85vw)}.w-\[min\(20rem\,85vw\)\]{width:min(20rem,85vw)}.w-\[min\(20rem\,calc\(100\%-1rem\)\)\]{width:min(20rem,100% - 1rem)}.w-\[min\(22rem\,90vw\)\]{width:min(22rem,90vw)}.w-\[min\(24rem\,calc\(100vw-2rem\)\)\]{width:min(24rem,100vw - 2rem)}.w-\[min\(90vw\,48rem\)\]{width:min(90vw,48rem)}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-max{width:max-content}.w-px{width:1px}.max-w-\(--onu-qr-size\){max-width:var(--onu-qr-size)}.max-w-\(--skeleton-width\){max-width:var(--skeleton-width)}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-7xl{max-width:var(--container-7xl)}.max-w-32{max-width:calc(var(--spacing) * 32)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-60{max-width:calc(var(--spacing) * 60)}.max-w-72{max-width:calc(var(--spacing) * 72)}.max-w-\[calc\(100\%-1rem\)\]{max-width:calc(100% - 1rem)}.max-w-\[calc\(100\%-2rem\)\]{max-width:calc(100% - 2rem)}.max-w-\[calc\(100vw-1rem\)\]{max-width:calc(100vw - 1rem)}.max-w-\[calc\(100vw-2rem\)\]{max-width:calc(100vw - 2rem)}.max-w-\[calc\(var\(--cell-size\)\*7\)\]{max-width:calc(var(--cell-size) * 7)}.max-w-\[min\(20rem\,calc\(100vw-1rem\)\)\]{max-width:min(20rem,100vw - 1rem)}.max-w-full{max-width:100%}.max-w-max{max-width:max-content}.max-w-none{max-width:none}.max-w-screen-2xl{max-width:var(--breakpoint-2xl)}.max-w-sm{max-width:var(--container-sm)}.max-w-xl{max-width:var(--container-xl)}.max-w-xs{max-width:var(--container-xs)}.min-w-\(--cell-size\){min-width:var(--cell-size)}.min-w-0{min-width:0}.min-w-4{min-width:calc(var(--spacing) * 4)}.min-w-5{min-width:calc(var(--spacing) * 5)}.min-w-6{min-width:calc(var(--spacing) * 6)}.min-w-7{min-width:calc(var(--spacing) * 7)}.min-w-8{min-width:calc(var(--spacing) * 8)}.min-w-9{min-width:calc(var(--spacing) * 9)}.min-w-12{min-width:calc(var(--spacing) * 12)}.min-w-16{min-width:calc(var(--spacing) * 16)}.min-w-20{min-width:calc(var(--spacing) * 20)}.min-w-28{min-width:calc(var(--spacing) * 28)}.min-w-32{min-width:calc(var(--spacing) * 32)}.min-w-36{min-width:calc(var(--spacing) * 36)}.min-w-40{min-width:calc(var(--spacing) * 40)}.min-w-44{min-width:calc(var(--spacing) * 44)}.min-w-48{min-width:calc(var(--spacing) * 48)}.min-w-52{min-width:calc(var(--spacing) * 52)}.min-w-56{min-width:calc(var(--spacing) * 56)}.min-w-64{min-width:calc(var(--spacing) * 64)}.min-w-72{min-width:calc(var(--spacing) * 72)}.min-w-\[96px\]{min-width:96px}.min-w-\[min\(100\%\,14rem\)\]{min-width:min(100%,14rem)}.min-w-full{min-width:100%}.min-w-max{min-width:max-content}.flex-1{flex:1}.flex-auto{flex:auto}.flex-none{flex:none}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.grow-0{flex-grow:0}.basis-full{flex-basis:100%}.caption-bottom{caption-side:bottom}.border-collapse{border-collapse:collapse}.origin-\(--radix-context-menu-content-transform-origin\){transform-origin:var(--radix-context-menu-content-transform-origin)}.origin-\(--radix-dropdown-menu-content-transform-origin\){transform-origin:var(--radix-dropdown-menu-content-transform-origin)}.origin-\(--radix-hover-card-content-transform-origin\){transform-origin:var(--radix-hover-card-content-transform-origin)}.origin-\(--radix-menubar-content-transform-origin\){transform-origin:var(--radix-menubar-content-transform-origin)}.origin-\(--radix-popover-content-transform-origin\){transform-origin:var(--radix-popover-content-transform-origin)}.origin-\(--radix-select-content-transform-origin\){transform-origin:var(--radix-select-content-transform-origin)}.origin-\(--radix-tooltip-content-transform-origin\){transform-origin:var(--radix-tooltip-content-transform-origin)}.-translate-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-px{--tw-translate-x:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-px{--tw-translate-x:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-full{--tw-translate-y:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-0{--tw-translate-y:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-5{--tw-translate-y:calc(var(--spacing) * 5);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-7{--tw-translate-y:calc(var(--spacing) * 7);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\[calc\(-50\%_-_2px\)\]{--tw-translate-y:calc(-50% - 2px);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-45{rotate:45deg}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, )}.scroll-fade-x{--_scroll-fade-size-s:var(--scroll-fade-s-size,var(--scroll-fade-size,min(12%, calc(var(--spacing) * 10))));--_scroll-fade-size-e:var(--scroll-fade-e-size,var(--scroll-fade-size,min(12%, calc(var(--spacing) * 10))));--scroll-fade-inline:linear-gradient(to right, transparent 0, #000 var(--scroll-fade-s,0px), #000 calc(100% - var(--scroll-fade-e,0px)), transparent 100%)}.scroll-fade-x:where([dir=rtl],[dir=rtl] *){--scroll-fade-inline:linear-gradient(to left, transparent 0, #000 var(--scroll-fade-s,0px), #000 calc(100% - var(--scroll-fade-e,0px)), transparent 100%)}.scroll-fade-x{-webkit-mask-image:var(--scroll-fade-mask,var(--scroll-fade-inline));-webkit-mask-image:var(--scroll-fade-mask,var(--scroll-fade-inline));-webkit-mask-image:var(--scroll-fade-mask,var(--scroll-fade-inline));mask-image:var(--scroll-fade-mask,var(--scroll-fade-inline));-webkit-mask-composite:source-in;-webkit-mask-composite:source-in;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-composite:source-in;mask-composite:intersect}@supports (animation-timeline:scroll()){.scroll-fade-x{animation:1ms ease-in-out scroll-fade-reveal-s,1ms ease-in-out scroll-fade-reveal-e;animation-timeline:scroll(self inline),scroll(self inline);animation-range:0 var(--scroll-fade-reveal,calc(var(--spacing) * 24)), calc(100% - var(--scroll-fade-reveal,calc(var(--spacing) * 24))) 100%;animation-fill-mode:both}}@supports not (animation-timeline:scroll()){.scroll-fade-x{--scroll-fade-s:var(--_scroll-fade-size-s);--scroll-fade-e:var(--_scroll-fade-size-e)}}.animate-caret-blink{animation:1.25s ease-out infinite caret-blink}.animate-in{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.cursor-progress{cursor:progress}.cursor-text{cursor:text}.cursor-zoom-in{cursor:zoom-in}.touch-pan-y{--tw-pan-y:pan-y;touch-action:var(--tw-pan-x, ) var(--tw-pan-y, ) var(--tw-pinch-zoom, )}.touch-manipulation{touch-action:manipulation}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.snap-x{scroll-snap-type:x var(--tw-scroll-snap-strictness)}.snap-mandatory{--tw-scroll-snap-strictness:mandatory}.snap-start{scroll-snap-align:start}.scroll-my-1{scroll-margin-block:var(--spacing)}.scroll-py-1{scroll-padding-block:var(--spacing)}.\[scrollbar-width\:none\]{scrollbar-width:none}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.appearance-none{appearance:none}.columns-2{columns:2}.break-inside-avoid{break-inside:avoid}.auto-rows-min{grid-auto-rows:min-content}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.grid-cols-\[minmax\(0\,min\(var\(--onu-dl-label-width\,12rem\)\,40\%\)\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,min(var(--onu-dl-label-width,12rem), 40%)) minmax(0,1fr)}.grid-cols-\[repeat\(auto-fill\,minmax\(min\(100\%\,17\.5rem\)\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(min(100%,17.5rem),1fr))}.grid-cols-\[repeat\(auto-fill\,minmax\(min\(var\(--onu-grid-min\)\,100\%\)\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(min(var(--onu-grid-min), 100%),1fr))}.grid-cols-\[repeat\(auto-fit\,minmax\(min\(100\%\,12rem\)\,1fr\)\)\]{grid-template-columns:repeat(auto-fit,minmax(min(100%,12rem),1fr))}.grid-rows-\[auto_1fr\]{grid-template-rows:auto 1fr}.grid-rows-\[auto_minmax\(0\,1fr\)\]{grid-template-rows:auto minmax(0,1fr)}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.place-content-center{place-content:center}.place-items-center{place-items:center}.content-center{align-content:center}.content-start{align-content:flex-start}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.justify-items-center{justify-items:center}.gap-\(--card-spacing\){gap:var(--card-spacing)}.gap-0{gap:0}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-10{gap:calc(var(--spacing) * 10)}.gap-\[--spacing\(var\(--gap\)\)\]{gap:calc(var(--spacing) * var(--gap))}.gap-x-1{column-gap:var(--spacing)}.gap-x-2{column-gap:calc(var(--spacing) * 2)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-x-8{column-gap:calc(var(--spacing) * 8)}:where(.-space-x-1>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * -1) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * -1) * calc(1 - var(--tw-space-x-reverse)))}:where(.-space-x-1\.5>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * -1.5) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * -1.5) * calc(1 - var(--tw-space-x-reverse)))}:where(.-space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * -2) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * -2) * calc(1 - var(--tw-space-x-reverse)))}:where(.-space-x-2\.5>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * -2.5) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * -2.5) * calc(1 - var(--tw-space-x-reverse)))}:where(.-space-x-3>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * -3) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * -3) * calc(1 - var(--tw-space-x-reverse)))}.gap-y-0\.5{row-gap:calc(var(--spacing) * .5)}.gap-y-1{row-gap:var(--spacing)}.gap-y-1\.5{row-gap:calc(var(--spacing) * 1.5)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}.gap-y-3{row-gap:calc(var(--spacing) * 3)}.gap-y-4{row-gap:calc(var(--spacing) * 4)}.gap-y-5{row-gap:calc(var(--spacing) * 5)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-y-0>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(0px * var(--tw-divide-y-reverse));border-bottom-width:calc(0px * calc(1 - var(--tw-divide-y-reverse)))}.self-center{align-self:center}.self-start{align-self:flex-start}.self-stretch{align-self:stretch}.justify-self-center{justify-self:center}.justify-self-end{justify-self:flex-end}.justify-self-start{justify-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-clip{overflow:clip}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.overscroll-x-contain{overscroll-behavior-x:contain}.rounded{border-radius:.25rem}.rounded-\(--cell-radius\){border-radius:var(--cell-radius)}.rounded-\(--cell-radius\,var\(--radius-md\)\){border-radius:var(--cell-radius,var(--radius-md))}.rounded-4xl{border-radius:calc(var(--radius) * 2.6)}.rounded-\[2px\]{border-radius:2px}.rounded-\[3px\]{border-radius:3px}.rounded-\[4px\]{border-radius:4px}.rounded-\[5px\]{border-radius:5px}.rounded-\[calc\(var\(--radius\)-3px\)\]{border-radius:calc(var(--radius) - 3px)}.rounded-\[inherit\]{border-radius:inherit}.rounded-\[min\(var\(--radius-md\)\,12px\)\]{border-radius:min(var(--radius-md), 12px)}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius)}.rounded-lg\!{border-radius:var(--radius)!important}.rounded-md{border-radius:calc(var(--radius) * .8)}.rounded-none{border-radius:0}.rounded-none\!{border-radius:0!important}.rounded-sm{border-radius:calc(var(--radius) * .6667)}.rounded-xl{border-radius:calc(var(--radius) * 1.3333)}.rounded-xl\!{border-radius:calc(var(--radius) * 1.3333)!important}.rounded-s-\(--cell-radius\){border-start-start-radius:var(--cell-radius);border-end-start-radius:var(--cell-radius)}.rounded-s-\[inherit\]{border-start-start-radius:inherit;border-end-start-radius:inherit}.rounded-ss-sm{border-start-start-radius:calc(var(--radius) * .6667)}.rounded-e-\(--cell-radius\){border-start-end-radius:var(--cell-radius);border-end-end-radius:var(--cell-radius)}.rounded-e-full{border-start-end-radius:2147483647px;border-end-end-radius:2147483647px}.rounded-t-2xl{border-top-left-radius:calc(var(--radius) * 1.8);border-top-right-radius:calc(var(--radius) * 1.8)}.rounded-t-xl{border-top-left-radius:calc(var(--radius) * 1.3333);border-top-right-radius:calc(var(--radius) * 1.3333)}.rounded-b-none{border-bottom-right-radius:0;border-bottom-left-radius:0}.rounded-b-xl{border-bottom-right-radius:calc(var(--radius) * 1.3333);border-bottom-left-radius:calc(var(--radius) * 1.3333)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-y{border-block-style:var(--tw-border-style);border-block-width:1px}.border-s{border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}.border-s-2{border-inline-start-style:var(--tw-border-style);border-inline-start-width:2px}.border-e{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\(--color-border\){border-color:var(--color-border)}.border-background{border-color:var(--background)}.border-border,.border-border\/50{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/50{border-color:color-mix(in oklab, var(--border) 50%, transparent)}}.border-destructive,.border-destructive\/30{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.border-destructive\/30{border-color:color-mix(in oklab, var(--destructive) 30%, transparent)}}.border-destructive\/40{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.border-destructive\/40{border-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.border-destructive\/50{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.border-destructive\/50{border-color:color-mix(in oklab, var(--destructive) 50%, transparent)}}.border-info,.border-info\/30{border-color:var(--info)}@supports (color:color-mix(in lab, red, red)){.border-info\/30{border-color:color-mix(in oklab, var(--info) 30%, transparent)}}.border-input,.border-input\/30{border-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.border-input\/30{border-color:color-mix(in oklab, var(--input) 30%, transparent)}}.border-muted-foreground\/40{border-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.border-muted-foreground\/40{border-color:color-mix(in oklab, var(--muted-foreground) 40%, transparent)}}.border-muted-foreground\/50{border-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.border-muted-foreground\/50{border-color:color-mix(in oklab, var(--muted-foreground) 50%, transparent)}}.border-preset-blue-border{border-color:var(--preset-blue-border)}.border-preset-cyan-border{border-color:var(--preset-cyan-border)}.border-preset-gold-border{border-color:var(--preset-gold-border)}.border-preset-green-border{border-color:var(--preset-green-border)}.border-preset-red-border{border-color:var(--preset-red-border)}.border-primary{border-color:var(--primary)}.border-primary-3{border-color:var(--primary-3)}.border-primary-foreground\/80{border-color:var(--primary-foreground)}@supports (color:color-mix(in lab, red, red)){.border-primary-foreground\/80{border-color:color-mix(in oklab, var(--primary-foreground) 80%, transparent)}}.border-ring{border-color:var(--ring)}.border-shell-border{border-color:var(--shell-border)}.border-sidebar-border{border-color:var(--sidebar-border)}.border-success,.border-success\/30{border-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.border-success\/30{border-color:color-mix(in oklab, var(--success) 30%, transparent)}}.border-transparent{border-color:#0000}.border-warning,.border-warning\/40{border-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.border-warning\/40{border-color:color-mix(in oklab, var(--warning) 40%, transparent)}}.border-warning\/60{border-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.border-warning\/60{border-color:color-mix(in oklab, var(--warning) 60%, transparent)}}.bg-\(--color-bg\){background-color:var(--color-bg)}.bg-\(--nav-color\){background-color:var(--nav-color)}.bg-\[Canvas\]{background-color:canvas}.bg-accent{background-color:var(--accent)}.bg-background,.bg-background\/70{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/70{background-color:color-mix(in oklab, var(--background) 70%, transparent)}}.bg-background\/80{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/80{background-color:color-mix(in oklab, var(--background) 80%, transparent)}}.bg-background\/90{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/90{background-color:color-mix(in oklab, var(--background) 90%, transparent)}}.bg-background\/95{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/95{background-color:color-mix(in oklab, var(--background) 95%, transparent)}}.bg-border{background-color:var(--border)}.bg-card{background-color:var(--card)}.bg-chart-1{background-color:var(--chart-1)}.bg-chart-2\/15{background-color:var(--chart-2)}@supports (color:color-mix(in lab, red, red)){.bg-chart-2\/15{background-color:color-mix(in oklab, var(--chart-2) 15%, transparent)}}.bg-chart-4\/15{background-color:var(--chart-4)}@supports (color:color-mix(in lab, red, red)){.bg-chart-4\/15{background-color:color-mix(in oklab, var(--chart-4) 15%, transparent)}}.bg-chart-5\/15{background-color:var(--chart-5)}@supports (color:color-mix(in lab, red, red)){.bg-chart-5\/15{background-color:color-mix(in oklab, var(--chart-5) 15%, transparent)}}.bg-current{background-color:currentColor}.bg-destructive,.bg-destructive\/5{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/5{background-color:color-mix(in oklab, var(--destructive) 5%, transparent)}}.bg-destructive\/10{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/10{background-color:color-mix(in oklab, var(--destructive) 10%, transparent)}}.bg-foreground,.bg-foreground\/25{background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.bg-foreground\/25{background-color:color-mix(in oklab, var(--foreground) 25%, transparent)}}.bg-info,.bg-info\/5{background-color:var(--info)}@supports (color:color-mix(in lab, red, red)){.bg-info\/5{background-color:color-mix(in oklab, var(--info) 5%, transparent)}}.bg-info\/10{background-color:var(--info)}@supports (color:color-mix(in lab, red, red)){.bg-info\/10{background-color:color-mix(in oklab, var(--info) 10%, transparent)}}.bg-info\/15{background-color:var(--info)}@supports (color:color-mix(in lab, red, red)){.bg-info\/15{background-color:color-mix(in oklab, var(--info) 15%, transparent)}}.bg-input,.bg-input\/30{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.bg-input\/30{background-color:color-mix(in oklab, var(--input) 30%, transparent)}}.bg-layout{background-color:var(--layout)}.bg-muted{background-color:var(--muted)}.bg-muted-foreground,.bg-muted-foreground\/20{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\/20{background-color:color-mix(in oklab, var(--muted-foreground) 20%, transparent)}}.bg-muted-foreground\/30{background-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\/30{background-color:color-mix(in oklab, var(--muted-foreground) 30%, transparent)}}.bg-muted\/30{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/30{background-color:color-mix(in oklab, var(--muted) 30%, transparent)}}.bg-muted\/40{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/40{background-color:color-mix(in oklab, var(--muted) 40%, transparent)}}.bg-muted\/50{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/50{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.bg-muted\/60{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/60{background-color:color-mix(in oklab, var(--muted) 60%, transparent)}}.bg-overlay{background-color:var(--overlay)}.bg-popover{background-color:var(--popover)}.bg-preset-blue{background-color:var(--preset-blue)}.bg-preset-cyan{background-color:var(--preset-cyan)}.bg-preset-gold{background-color:var(--preset-gold)}.bg-preset-green{background-color:var(--preset-green)}.bg-preset-red{background-color:var(--preset-red)}.bg-primary{background-color:var(--primary)}.bg-primary-1{background-color:var(--primary-1)}.bg-primary-foreground{background-color:var(--primary-foreground)}.bg-primary-subtle{background-color:var(--primary-subtle)}.bg-primary\/5{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.bg-primary\/5{background-color:color-mix(in oklab, var(--primary) 5%, transparent)}}.bg-primary\/10{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.bg-primary\/10{background-color:color-mix(in oklab, var(--primary) 10%, transparent)}}.bg-primary\/15{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.bg-primary\/15{background-color:color-mix(in oklab, var(--primary) 15%, transparent)}}.bg-secondary{background-color:var(--secondary)}.bg-shell{background-color:var(--shell)}.bg-shell-field{background-color:var(--shell-field)}.bg-shell-weak{background-color:var(--shell-weak)}.bg-sidebar{background-color:var(--sidebar)}.bg-sidebar-border{background-color:var(--sidebar-border)}.bg-success,.bg-success\/5{background-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.bg-success\/5{background-color:color-mix(in oklab, var(--success) 5%, transparent)}}.bg-success\/10{background-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.bg-success\/10{background-color:color-mix(in oklab, var(--success) 10%, transparent)}}.bg-success\/15{background-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.bg-success\/15{background-color:color-mix(in oklab, var(--success) 15%, transparent)}}.bg-transparent{background-color:#0000}.bg-warning,.bg-warning\/5{background-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.bg-warning\/5{background-color:color-mix(in oklab, var(--warning) 5%, transparent)}}.bg-warning\/10{background-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.bg-warning\/10{background-color:color-mix(in oklab, var(--warning) 10%, transparent)}}.bg-warning\/15{background-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.bg-warning\/15{background-color:color-mix(in oklab, var(--warning) 15%, transparent)}}.bg-linear-to-t{--tw-gradient-position:to top}@supports (background-image:linear-gradient(in lab, red, red)){.bg-linear-to-t{--tw-gradient-position:to top in oklab}}.bg-linear-to-t{background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-b{--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-\[radial-gradient\(var\(--border\)_1px\,transparent_1px\)\]{background-image:radial-gradient(var(--border) 1px,transparent 1px)}.bg-\[repeating-conic-gradient\(var\(--muted\)_0_25\%\,transparent_0_50\%\)\]{background-image:repeating-conic-gradient(var(--muted) 0 25%,transparent 0 50%)}.from-background\/95{--tw-gradient-from:var(--background)}@supports (color:color-mix(in lab, red, red)){.from-background\/95{--tw-gradient-from:color-mix(in oklab, var(--background) 95%, transparent)}}.from-background\/95{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-foreground\/60{--tw-gradient-from:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.from-foreground\/60{--tw-gradient-from:color-mix(in oklab, var(--foreground) 60%, transparent)}}.from-foreground\/60{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-muted\/95{--tw-gradient-from:var(--muted)}@supports (color:color-mix(in lab, red, red)){.from-muted\/95{--tw-gradient-from:color-mix(in oklab, var(--muted) 95%, transparent)}}.from-muted\/95{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-primary\/95{--tw-gradient-from:var(--primary)}@supports (color:color-mix(in lab, red, red)){.from-primary\/95{--tw-gradient-from:color-mix(in oklab, var(--primary) 95%, transparent)}}.from-primary\/95{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.via-background\/85{--tw-gradient-via:var(--background)}@supports (color:color-mix(in lab, red, red)){.via-background\/85{--tw-gradient-via:color-mix(in oklab, var(--background) 85%, transparent)}}.via-background\/85{--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-muted\/90{--tw-gradient-via:var(--muted)}@supports (color:color-mix(in lab, red, red)){.via-muted\/90{--tw-gradient-via:color-mix(in oklab, var(--muted) 90%, transparent)}}.via-muted\/90{--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-primary\/90{--tw-gradient-via:var(--primary)}@supports (color:color-mix(in lab, red, red)){.via-primary\/90{--tw-gradient-via:color-mix(in oklab, var(--primary) 90%, transparent)}}.via-primary\/90{--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-background\/70{--tw-gradient-to:var(--background)}@supports (color:color-mix(in lab, red, red)){.to-background\/70{--tw-gradient-to:color-mix(in oklab, var(--background) 70%, transparent)}}.to-background\/70{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-muted\/75{--tw-gradient-to:var(--muted)}@supports (color:color-mix(in lab, red, red)){.to-muted\/75{--tw-gradient-to:color-mix(in oklab, var(--muted) 75%, transparent)}}.to-muted\/75{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-primary\/80{--tw-gradient-to:var(--primary)}@supports (color:color-mix(in lab, red, red)){.to-primary\/80{--tw-gradient-to:color-mix(in oklab, var(--primary) 80%, transparent)}}.to-primary\/80{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.\[background-size\:16px_16px\]{background-size:16px 16px}.bg-size-\[8px_8px\]{background-size:8px 8px}.bg-clip-padding{background-clip:padding-box}.fill-background{fill:var(--background)}.fill-current{fill:currentColor}.fill-foreground{fill:var(--foreground)}.fill-muted-foreground{fill:var(--muted-foreground)}.stroke-background{stroke:var(--background)}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-\(--card-spacing\){padding:var(--card-spacing)}.p-0{padding:0}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-3\.5{padding:calc(var(--spacing) * 3.5)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.p-10{padding:calc(var(--spacing) * 10)}.p-\[3px\]{padding:3px}.p-px{padding:1px}.px-\(--card-spacing\){padding-inline:var(--card-spacing)}.px-\(--cell-size\){padding-inline:var(--cell-size)}.px-0{padding-inline:0}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-1\.75{padding-inline:calc(var(--spacing) * 1.75)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-2\.75{padding-inline:calc(var(--spacing) * 2.75)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.75{padding-inline:calc(var(--spacing) * 3.75)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-\(--card-spacing\){padding-block:var(--card-spacing)}.py-0{padding-block:0}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-1\.25{padding-block:calc(var(--spacing) * 1.25)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-14{padding-block:calc(var(--spacing) * 14)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-\[2px\]{padding-block:2px}.ps-1{padding-inline-start:var(--spacing)}.ps-1\.5\!{padding-inline-start:calc(var(--spacing) * 1.5)!important}.ps-2{padding-inline-start:calc(var(--spacing) * 2)}.ps-2\.5{padding-inline-start:calc(var(--spacing) * 2.5)}.ps-3{padding-inline-start:calc(var(--spacing) * 3)}.ps-4{padding-inline-start:calc(var(--spacing) * 4)}.ps-5{padding-inline-start:calc(var(--spacing) * 5)}.ps-6{padding-inline-start:calc(var(--spacing) * 6)}.ps-7{padding-inline-start:calc(var(--spacing) * 7)}.ps-8{padding-inline-start:calc(var(--spacing) * 8)}.ps-9{padding-inline-start:calc(var(--spacing) * 9)}.ps-16{padding-inline-start:calc(var(--spacing) * 16)}.ps-\[env\(safe-area-inset-left\)\]{padding-inline-start:env(safe-area-inset-left)}.pe-0\.5{padding-inline-end:calc(var(--spacing) * .5)}.pe-1{padding-inline-end:var(--spacing)}.pe-1\.5{padding-inline-end:calc(var(--spacing) * 1.5)}.pe-1\.5\!{padding-inline-end:calc(var(--spacing) * 1.5)!important}.pe-2{padding-inline-end:calc(var(--spacing) * 2)}.pe-2\.5{padding-inline-end:calc(var(--spacing) * 2.5)}.pe-3{padding-inline-end:calc(var(--spacing) * 3)}.pe-4{padding-inline-end:calc(var(--spacing) * 4)}.pe-8{padding-inline-end:calc(var(--spacing) * 8)}.pe-10{padding-inline-end:calc(var(--spacing) * 10)}.pe-12{padding-inline-end:calc(var(--spacing) * 12)}.pe-24{padding-inline-end:calc(var(--spacing) * 24)}.pe-\[env\(safe-area-inset-right\)\]{padding-inline-end:env(safe-area-inset-right)}.pt-0{padding-top:0}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-1{padding-top:var(--spacing)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-5{padding-top:calc(var(--spacing) * 5)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pt-7{padding-top:calc(var(--spacing) * 7)}.pt-\[env\(safe-area-inset-top\)\]{padding-top:env(safe-area-inset-top)}.pt-\[max\(0\.25rem\,env\(safe-area-inset-top\)\)\]{padding-top:max(.25rem, env(safe-area-inset-top))}.pt-\[max\(1rem\,env\(safe-area-inset-top\)\)\]{padding-top:max(1rem, env(safe-area-inset-top))}.pb-0{padding-bottom:0}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-1{padding-bottom:var(--spacing)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-2\.5{padding-bottom:calc(var(--spacing) * 2.5)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.pb-6{padding-bottom:calc(var(--spacing) * 6)}.pb-\[calc\(0\.75rem\+env\(safe-area-inset-bottom\)\)\]{padding-bottom:calc(.75rem + env(safe-area-inset-bottom))}.pb-\[calc\(5rem\+env\(safe-area-inset-bottom\)\)\]{padding-bottom:calc(5rem + env(safe-area-inset-bottom))}.pb-\[env\(safe-area-inset-bottom\)\]{padding-bottom:env(safe-area-inset-bottom)}.pb-\[max\(0\.75rem\,env\(safe-area-inset-bottom\)\)\]{padding-bottom:max(.75rem, env(safe-area-inset-bottom))}.pb-\[max\(1rem\,env\(safe-area-inset-bottom\)\)\]{padding-bottom:max(1rem, env(safe-area-inset-bottom))}.text-center{text-align:center}.text-end{text-align:end}.text-start{text-align:start}.align-middle{vertical-align:middle}.align-top{vertical-align:top}.font-mono{font-family:var(--onu-font-mono)}.font-sans{font-family:var(--onu-font-sans)}.font-thaana{font-family:var(--onu-font-thaana)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-fluid-3xl{font-size:var(--fluid-text-3xl);line-height:var(--tw-leading,var(--fluid-leading-tight))}.text-fluid-4xl{font-size:var(--fluid-text-4xl);line-height:var(--tw-leading,var(--fluid-leading-tight))}.text-fluid-5xl{font-size:var(--fluid-text-5xl);line-height:var(--tw-leading,var(--fluid-leading-tight))}.text-fluid-lg{font-size:var(--fluid-text-lg);line-height:var(--tw-leading,var(--fluid-leading-normal))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}.text-sm\/relaxed{font-size:var(--text-sm);line-height:var(--leading-relaxed)}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.6rem\]{font-size:.6rem}.text-\[0\.8rem\]{font-size:.8rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.625rem\]{font-size:.625rem}.text-\[0\.6875rem\]{font-size:.6875rem}.text-\[0\.8125rem\]{font-size:.8125rem}.text-\[9px\]{font-size:9px}.text-\[length\:inherit\]{font-size:inherit}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-6{--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.leading-7{--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.leading-8{--tw-leading:calc(var(--spacing) * 8);line-height:calc(var(--spacing) * 8)}.leading-\[1\.375rem\]{--tw-leading:1.375rem;line-height:1.375rem}.leading-none{--tw-leading:1;line-height:1}.leading-normal{--tw-leading:var(--leading-normal);line-height:var(--leading-normal)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.text-balance{text-wrap:balance}.text-pretty{text-wrap:pretty}.\[overflow-wrap\:anywhere\]{overflow-wrap:anywhere}.break-words,.wrap-break-word{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.text-\(--shiki-light\){color:var(--shiki-light)}.text-\[CanvasText\]{color:canvastext}.text-accent-foreground{color:var(--accent-foreground)}.text-background{color:var(--background)}.text-border{color:var(--border)}.text-card-foreground{color:var(--card-foreground)}.text-chart-2{color:var(--chart-2)}.text-chart-4{color:var(--chart-4)}.text-chart-5{color:var(--chart-5)}.text-current{color:currentColor}.text-destructive{color:var(--destructive)}.text-destructive-foreground{color:var(--destructive-foreground)}.text-foreground{color:var(--foreground)}.text-info{color:var(--info)}.text-info-foreground{color:var(--info-foreground)}.text-muted-foreground{color:var(--muted-foreground)}.text-muted-foreground\!{color:var(--muted-foreground)!important}.text-muted-foreground\/40{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/40{color:color-mix(in oklab, var(--muted-foreground) 40%, transparent)}}.text-popover-foreground{color:var(--popover-foreground)}.text-preset-blue-foreground{color:var(--preset-blue-foreground)}.text-preset-cyan-foreground{color:var(--preset-cyan-foreground)}.text-preset-gold-foreground{color:var(--preset-gold-foreground)}.text-preset-green-foreground{color:var(--preset-green-foreground)}.text-preset-red-foreground{color:var(--preset-red-foreground)}.text-primary{color:var(--primary)}.text-primary-7{color:var(--primary-7)}.text-primary-foreground,.text-primary-foreground\/85{color:var(--primary-foreground)}@supports (color:color-mix(in lab, red, red)){.text-primary-foreground\/85{color:color-mix(in oklab, var(--primary-foreground) 85%, transparent)}}.text-primary-subtle-foreground{color:var(--primary-subtle-foreground)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-shell-foreground{color:var(--shell-foreground)}.text-sidebar-foreground,.text-sidebar-foreground\/70{color:var(--sidebar-foreground)}@supports (color:color-mix(in lab, red, red)){.text-sidebar-foreground\/70{color:color-mix(in oklab, var(--sidebar-foreground) 70%, transparent)}}.text-success{color:var(--success)}.text-success-foreground{color:var(--success-foreground)}.text-warning{color:var(--warning)}.text-warning-foreground{color:var(--warning-foreground)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.not-italic{font-style:normal}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, )}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.decoration-muted-foreground\/50{-webkit-text-decoration-color:var(--muted-foreground);-webkit-text-decoration-color:var(--muted-foreground);text-decoration-color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.decoration-muted-foreground\/50{-webkit-text-decoration-color:color-mix(in oklab, var(--muted-foreground) 50%, transparent);-webkit-text-decoration-color:color-mix(in oklab, var(--muted-foreground) 50%, transparent);text-decoration-color:color-mix(in oklab, var(--muted-foreground) 50%, transparent)}}.decoration-primary{-webkit-text-decoration-color:var(--primary);-webkit-text-decoration-color:var(--primary);text-decoration-color:var(--primary)}.decoration-dotted{text-decoration-style:dotted}.decoration-2{text-decoration-thickness:2px}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-80{opacity:.8}.opacity-100{opacity:1}.opacity-100\!{opacity:1!important}.bg-blend-color{background-blend-mode:color}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_-4px_16px_-8px_rgb\(0_0_0\/0\.15\)\]{--tw-shadow:0 -4px 16px -8px var(--tw-shadow-color,#00000026);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_0_1px_var\(--sidebar-border\)\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--sidebar-border));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_0_100vmax_var\(--card\)\]{--tw-shadow:0 0 0 100vmax var(--tw-shadow-color,var(--card));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_0_0_9999px_color-mix\(in_oklch\,var\(--background\)_45\%\,transparent\)\]{--tw-shadow:0 0 0 9999px var(--tw-shadow-color,var(--background))}@supports (color:color-mix(in lab, red, red)){.shadow-\[0_0_0_9999px_color-mix\(in_oklch\,var\(--background\)_45\%\,transparent\)\]{--tw-shadow:0 0 0 9999px var(--tw-shadow-color,color-mix(in oklch,var(--background) 45%,transparent))}}.shadow-\[0_0_0_9999px_color-mix\(in_oklch\,var\(--background\)_45\%\,transparent\)\]{box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-none\!{--tw-shadow:0 0 #0000!important;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)!important}.shadow-popup{--tw-shadow:var(--popup-shadow);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-0{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-3{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-4{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-background{--tw-ring-color:var(--background)}.ring-border{--tw-ring-color:var(--border)}.ring-foreground\/10{--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.ring-foreground\/10{--tw-ring-color:color-mix(in oklab, var(--foreground) 10%, transparent)}}.ring-foreground\/15{--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.ring-foreground\/15{--tw-ring-color:color-mix(in oklab, var(--foreground) 15%, transparent)}}.ring-foreground\/40{--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.ring-foreground\/40{--tw-ring-color:color-mix(in oklab, var(--foreground) 40%, transparent)}}.ring-primary{--tw-ring-color:var(--primary)}.ring-ring\/50{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.ring-ring\/50{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.ring-sidebar-ring{--tw-ring-color:var(--sidebar-ring)}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);filter:var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, )}.drop-shadow-sm{--tw-drop-shadow-size:drop-shadow(0 1px 2px var(--tw-drop-shadow-color,#00000026));--tw-drop-shadow:drop-shadow(var(--drop-shadow-sm));filter:var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, )}.filter{filter:var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, )}.backdrop-blur-\[2px\]{--tw-backdrop-blur:blur(2px);-webkit-backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, )}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, )}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[box-shadow\]{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,background-color\,border-color\,box-shadow\]{transition-property:color,background-color,border-color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,background-color\,box-shadow\]{transition-property:color,background-color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,box-shadow\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[left\,right\,width\]{transition-property:left,right,width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[margin\,opacity\]{transition-property:margin,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[top\]{transition-property:top;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\,height\,padding\]{transition-property:width,height,padding;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-none{transition-property:none}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-1000{--tw-duration:1s;transition-duration:1s}.ease-\[cubic-bezier\(0\.22\,1\,0\.36\,1\)\]{--tw-ease:cubic-bezier(.22,1,.36,1);transition-timing-function:cubic-bezier(.22,1,.36,1)}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-linear{--tw-ease:linear;transition-timing-function:linear}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.fade-in-0{--tw-enter-opacity:0}.outline-none{--tw-outline-style:none;outline-style:none}.select-all{-webkit-user-select:all;user-select:all}.select-none{-webkit-user-select:none;user-select:none}.slide-in-from-end-4:where(:dir(ltr),[dir=ltr]){--tw-enter-translate-x:calc(4*var(--spacing))}.slide-in-from-end-4:where(:dir(rtl),[dir=rtl]){--tw-enter-translate-x:calc(4*var(--spacing)*-1)}.\[--card-spacing\:--spacing\(4\)\]{--card-spacing:calc(var(--spacing) * 4)}.\[--card-spacing\:--spacing\(6\)\]{--card-spacing:calc(var(--spacing) * 6)}.\[--card-spacing\:0px\]{--card-spacing:0px}.\[--cell-radius\:var\(--radius-md\)\]{--cell-radius:var(--radius-md)}.\[--cell-size\:--spacing\(7\)\]{--cell-size:calc(var(--spacing) * 7)}.\[--cell-size\:--spacing\(9\)\]{--cell-size:calc(var(--spacing) * 9)}.\[--cell-size\:--spacing\(11\)\]{--cell-size:calc(var(--spacing) * 11)}.\[--fc-border-color\:var\(--border\)\]{--fc-border-color:var(--border)}.\[--fc-event-bg-color\:var\(--primary\)\]{--fc-event-bg-color:var(--primary)}.\[--fc-event-border-color\:var\(--primary\)\]{--fc-event-border-color:var(--primary)}.\[--fc-event-selected-overlay-color\:color-mix\(in_oklch\,var\(--foreground\)_20\%\,transparent\)\]{--fc-event-selected-overlay-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.\[--fc-event-selected-overlay-color\:color-mix\(in_oklch\,var\(--foreground\)_20\%\,transparent\)\]{--fc-event-selected-overlay-color:color-mix(in oklch,var(--foreground) 20%,transparent)}}.\[--fc-event-text-color\:var\(--primary-foreground\)\]{--fc-event-text-color:var(--primary-foreground)}.\[--fc-highlight-color\:color-mix\(in_oklch\,var\(--primary\)_18\%\,transparent\)\]{--fc-highlight-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.\[--fc-highlight-color\:color-mix\(in_oklch\,var\(--primary\)_18\%\,transparent\)\]{--fc-highlight-color:color-mix(in oklch,var(--primary) 18%,transparent)}}.\[--fc-list-event-hover-bg-color\:var\(--muted\)\]{--fc-list-event-hover-bg-color:var(--muted)}.\[--fc-more-link-bg-color\:var\(--muted\)\]{--fc-more-link-bg-color:var(--muted)}.\[--fc-more-link-text-color\:var\(--foreground\)\]{--fc-more-link-text-color:var(--foreground)}.\[--fc-neutral-bg-color\:var\(--muted\)\]{--fc-neutral-bg-color:var(--muted)}.\[--fc-neutral-text-color\:var\(--muted-foreground\)\]{--fc-neutral-text-color:var(--muted-foreground)}.\[--fc-non-business-color\:color-mix\(in_oklch\,var\(--muted\)_60\%\,transparent\)\]{--fc-non-business-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.\[--fc-non-business-color\:color-mix\(in_oklch\,var\(--muted\)_60\%\,transparent\)\]{--fc-non-business-color:color-mix(in oklch,var(--muted) 60%,transparent)}}.\[--fc-now-indicator-color\:var\(--destructive\)\]{--fc-now-indicator-color:var(--destructive)}.\[--fc-page-bg-color\:var\(--background\)\]{--fc-page-bg-color:var(--background)}.\[--fc-small-font-size\:0\.75rem\]{--fc-small-font-size:.75rem}.\[--fc-today-bg-color\:color-mix\(in_oklch\,var\(--primary\)_8\%\,transparent\)\]{--fc-today-bg-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.\[--fc-today-bg-color\:color-mix\(in_oklch\,var\(--primary\)_8\%\,transparent\)\]{--fc-today-bg-color:color-mix(in oklch,var(--primary) 8%,transparent)}}.\[--media-control-background\:color-mix\(in_oklch\,var\(--background\)_88\%\,transparent\)\]{--media-control-background:var(--background)}@supports (color:color-mix(in lab, red, red)){.\[--media-control-background\:color-mix\(in_oklch\,var\(--background\)_88\%\,transparent\)\]{--media-control-background:color-mix(in oklch,var(--background) 88%,transparent)}}.\[--media-control-hover-background\:var\(--muted\)\]{--media-control-hover-background:var(--muted)}.\[--media-focus-box-shadow\:inset_0_0_0_3px_var\(--ring\)\]{--media-focus-box-shadow:inset 0 0 0 3px var(--ring)}.\[--media-font-family\:var\(--onu-font-sans\)\]{--media-font-family:var(--onu-font-sans)}.\[--media-primary-color\:var\(--foreground\)\]{--media-primary-color:var(--foreground)}.\[--media-range-bar-color\:var\(--primary\)\]{--media-range-bar-color:var(--primary)}.\[--media-range-thumb-background\:var\(--primary\)\]{--media-range-thumb-background:var(--primary)}.\[--media-range-track-background\:var\(--border\)\]{--media-range-track-background:var(--border)}.\[--media-secondary-color\:transparent\]{--media-secondary-color:transparent}.\[--onu-header-height\:3\.5rem\]{--onu-header-height:3.5rem}.\[--onu-header-height\:3\.75rem\]{--onu-header-height:3.75rem}.\[-webkit-touch-callout\:none\]{-webkit-touch-callout:none}.\[clip-path\:inset\(0_-100vmax\)\]{clip-path:inset(0 -100vmax)}.\[clip-path\:inset\(0_50\%_0_0\)\]{clip-path:inset(0 50% 0 0)}.paused{animation-play-state:paused}.ring-inset{--tw-ring-inset:inset}.running{animation-play-state:running}.slide-in-from-bottom-2{--tw-enter-translate-y:calc(2*var(--spacing))}.zoom-in{--tw-enter-scale:0}.zoom-out{--tw-exit-scale:0}:is(.\*\:w-full>*){width:100%}.not-first\:border-s:not(:first-child){border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}.not-last\:border-b:not(:last-child){border-bottom-style:var(--tw-border-style);border-bottom-width:1px}:is(:where(.group\/accordion-item):is([open],:popover-open,:open) .group-open\/accordion-item\:rotate-180){rotate:180deg}:is(:where(.group\/menu-item):focus-within .group-focus-within\/menu-item\:opacity-100){opacity:1}@media (hover:hover){:is(:where(.group\/content-card):hover .group-hover\/content-card\:scale-\[1\.02\]){scale:1.02}:is(:where(.group\/dot):hover .group-hover\/dot\:bg-foreground\/50){background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){:is(:where(.group\/dot):hover .group-hover\/dot\:bg-foreground\/50){background-color:color-mix(in oklab, var(--foreground) 50%, transparent)}}:is(:where(.group\/file-input):hover .group-hover\/file-input\:bg-accent){background-color:var(--accent)}:is(:where(.group\/file-input):hover .group-hover\/file-input\:bg-muted){background-color:var(--muted)}:is(:where(.group\/gallery):hover .group-hover\/gallery\:scale-105){--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}:is(:where(.group\/inline-edit):hover .group-hover\/inline-edit\:opacity-100),:is(:where(.group\/menu-item):hover .group-hover\/menu-item\:opacity-100),:is(:where(.group\/thumb):hover .group-hover\/thumb\:opacity-100){opacity:1}:is(:where(.group\/video):hover .group-hover\/video\:scale-105){--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}}:is(:where(.group\/context-menu-item):focus .group-focus\/context-menu-item\:text-accent-foreground),:is(:where(.group\/dropdown-menu-item):focus .group-focus\/dropdown-menu-item\:text-accent-foreground),:is(:where(.group\/menubar-item):focus .group-focus\/menubar-item\:text-accent-foreground){color:var(--accent-foreground)}:is(:where(.group\/checkbox):focus-visible .group-focus-visible\/checkbox\:border-ring){border-color:var(--ring)}:is(:where(.group\/checkbox):focus-visible .group-focus-visible\/checkbox\:ring-3){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.group\/checkbox):focus-visible .group-focus-visible\/checkbox\:ring-ring\/50){--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){:is(:where(.group\/checkbox):focus-visible .group-focus-visible\/checkbox\:ring-ring\/50){--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}:is(:where(.group\/inline-edit):focus-visible .group-focus-visible\/inline-edit\:opacity-100),:is(:where(.group\/thumb):focus-visible .group-focus-visible\/thumb\:opacity-100),:is(:where(.group\/thumb):active .group-active\/thumb\:opacity-100){opacity:1}:is(:where(.group\/field):has(:disabled) .group-has-disabled\/field\:opacity-50){opacity:.5}:is(:where(.group\/menu-item):has([data-sidebar=menu-action]) .group-has-data-\[sidebar\=menu-action\]\/menu-item\:pe-8){padding-inline-end:calc(var(--spacing) * 8)}:is(:where(.group\/menu-item):has([data-sidebar=menu-badge]) .group-has-data-\[sidebar\=menu-badge\]\/menu-item\:pe-12){padding-inline-end:calc(var(--spacing) * 12)}:is(:where(.group\/avatar-group):has([data-size=lg]) .group-has-data-\[size\=lg\]\/avatar-group\:size-10){width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}:is(:where(.group\/avatar-group):has([data-size=sm]) .group-has-data-\[size\=sm\]\/avatar-group\:size-6){width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}:is(:where(.group\/command-item):has([data-slot=command-shortcut]) .group-has-data-\[slot\=command-shortcut\]\/command-item\:hidden){display:none}:is(:where(.group\/item):has([data-slot=item-description]) .group-has-data-\[slot\=item-description\]\/item\:translate-y-0\.5){--tw-translate-y:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}:is(:where(.group\/item):has([data-slot=item-description]) .group-has-data-\[slot\=item-description\]\/item\:self-start){align-self:flex-start}:is(:where(.group\/field):has(:where([data-orientation=horizontal])) .group-has-data-horizontal\/field\:text-balance){text-wrap:balance}:is(:where(.group\/field-label):has(:focus-visible) .group-has-\[\:focus-visible\]\/field-label\:border-transparent){border-color:#0000}:is(:where(.group\/field-label):has(:focus-visible) .group-has-\[\:focus-visible\]\/field-label\:ring-0){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.group\/field-label):has(:focus-visible) .group-has-\[\:focus-visible\]\/field-label\:not-checked\:border-input):not(:checked),:is(:where(.group\/field-label):has(:focus-visible) .group-has-\[\:focus-visible\]\/field-label\:not-data-checked\:border-input):not(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){border-color:var(--input)}:is(:where(.group\/input-group):has(>input) .group-has-\[\>input\]\/input-group\:pt-2){padding-top:calc(var(--spacing) * 2)}:is(:where(.group\/input-group):has(>input) .group-has-\[\>input\]\/input-group\:pb-2){padding-bottom:calc(var(--spacing) * 2)}:is(:where(.group\/alert):has(>svg) .group-has-\[\>svg\]\/alert\:col-start-2){grid-column-start:2}:is(:where(.group\/accordion-trigger)[aria-expanded=true] .group-aria-expanded\/accordion-trigger\:hidden){display:none}:is(:where(.group\/accordion-trigger)[aria-expanded=true] .group-aria-expanded\/accordion-trigger\:inline){display:inline}:is(:where(.group\/dot)[aria-current=true] .group-aria-\[current\=true\]\/dot\:w-5){width:calc(var(--spacing) * 5)}:is(:where(.group\/dot)[aria-current=true] .group-aria-\[current\=true\]\/dot\:bg-primary){background-color:var(--primary)}:is(:where(.group\/navigation-menu-trigger)[data-popup-open] .group-data-popup-open\/navigation-menu-trigger\:rotate-180){rotate:180deg}:is(:where(.group\/command-item)[data-checked=true] .group-data-\[checked\=true\]\/command-item\:opacity-100){opacity:1}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:-mt-8){margin-top:calc(var(--spacing) * -8)}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:hidden){display:none}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:size-8\!){width:calc(var(--spacing) * 8)!important;height:calc(var(--spacing) * 8)!important}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:w-\(--sidebar-width-icon\)){width:var(--sidebar-width-icon)}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:w-\[calc\(var\(--sidebar-width-icon\)\+\(--spacing\(4\)\)\)\]){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)))}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:w-\[calc\(var\(--sidebar-width-icon\)\+\(--spacing\(4\)\)\+2px\)\]){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)) + 2px)}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:overflow-hidden){overflow:hidden}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:p-0\!){padding:0!important}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:p-2\!){padding:calc(var(--spacing) * 2)!important}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:px-0){padding-inline:0}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:px-2){padding-inline:calc(var(--spacing) * 2)}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:opacity-0){opacity:0}:is(:where(.group)[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:w-0){width:0}:is(:where(.group)[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:translate-x-0){--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}:is(:where(.group)[data-disabled=true] .group-data-\[disabled\=true\]\:pointer-events-none){pointer-events:none}:is(:where(.group)[data-disabled=true] .group-data-\[disabled\=true\]\:opacity-50),:is(:where(.group\/field)[data-disabled=true] .group-data-\[disabled\=true\]\/field\:opacity-50),:is(:where(.group\/input-group)[data-disabled=true] .group-data-\[disabled\=true\]\/input-group\:opacity-50){opacity:.5}:is(:where(.group\/day)[data-focused=true] .group-data-\[focused\=true\]\/day\:relative){position:relative}:is(:where(.group\/day)[data-focused=true] .group-data-\[focused\=true\]\/day\:z-10){z-index:10}:is(:where(.group\/day)[data-focused=true] .group-data-\[focused\=true\]\/day\:border-ring){border-color:var(--ring)}:is(:where(.group\/day)[data-focused=true] .group-data-\[focused\=true\]\/day\:ring-\[3px\]){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.group\/day)[data-focused=true] .group-data-\[focused\=true\]\/day\:ring-ring\/50){--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){:is(:where(.group\/day)[data-focused=true] .group-data-\[focused\=true\]\/day\:ring-ring\/50){--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}:is(:where(.group\/media)[data-selected] .group-data-\[selected\]\/media\:border-primary){border-color:var(--primary)}:is(:where(.group\/media)[data-selected] .group-data-\[selected\]\/media\:bg-primary){background-color:var(--primary)}:is(:where(.group\/media)[data-selected] .group-data-\[selected\]\/media\:ring-2){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.group\/media)[data-selected] .group-data-\[selected\]\/media\:ring-primary\/40){--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){:is(:where(.group\/media)[data-selected] .group-data-\[selected\]\/media\:ring-primary\/40){--tw-ring-color:color-mix(in oklab, var(--primary) 40%, transparent)}}:is(:where(.group)[data-side=left] .group-data-\[side\=left\]\:-right-4){right:calc(var(--spacing) * -4)}:is(:where(.group)[data-side=left] .group-data-\[side\=left\]\:border-e){border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}:is(:where(.group)[data-side=right] .group-data-\[side\=right\]\:left-0){left:0}:is(:where(.group)[data-side=right] .group-data-\[side\=right\]\:rotate-180){rotate:180deg}:is(:where(.group)[data-side=right] .group-data-\[side\=right\]\:border-s){border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}:is(:where(.group\/avatar)[data-size=default] .group-data-\[size\=default\]\/avatar\:size-2\.5){width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}:is(:where(.group\/switch)[data-size=default] .group-data-\[size\=default\]\/switch\:size-\[18px\]){width:18px;height:18px}:is(:where(.group\/avatar)[data-size=lg] .group-data-\[size\=lg\]\/avatar\:size-3){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}:is(:where(.group\/alert-dialog-content)[data-size=sm] .group-data-\[size\=sm\]\/alert-dialog-content\:grid){display:grid}:is(:where(.group\/alert-dialog-content)[data-size=sm] .group-data-\[size\=sm\]\/alert-dialog-content\:grid-cols-2){grid-template-columns:repeat(2,minmax(0,1fr))}:is(:where(.group\/avatar)[data-size=sm] .group-data-\[size\=sm\]\/avatar\:size-2){width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}:is(:where(.group\/avatar)[data-size=sm] .group-data-\[size\=sm\]\/avatar\:text-xs){font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}:is(:where(.group\/card)[data-size=sm] .group-data-\[size\=sm\]\/card\:min-h-11){min-height:calc(var(--spacing) * 11)}:is(:where(.group\/card)[data-size=sm] .group-data-\[size\=sm\]\/card\:text-sm){font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}:is(:where(.group\/item)[data-size=sm] .group-data-\[size\=sm\]\/item\:size-8){width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}:is(:where(.group\/switch)[data-size=sm] .group-data-\[size\=sm\]\/switch\:size-3){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}:is(:where(.group\/item)[data-size=xs] .group-data-\[size\=xs\]\/item\:size-6){width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}:is(:where(.group\/item)[data-size=xs] .group-data-\[size\=xs\]\/item\:gap-0){gap:0}:is(:where(.group\/item)[data-size=xs] .group-data-\[size\=xs\]\/item\:text-xs){font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}:is(:where(.group\/toggle-group)[data-spacing="0"] .group-data-\[spacing\=0\]\/toggle-group\:rounded-none){border-radius:0}:is(:where(.group\/toggle-group)[data-spacing="0"] .group-data-\[spacing\=0\]\/toggle-group\:px-2){padding-inline:calc(var(--spacing) * 2)}:is(:where(.group\/tabs-trigger)[data-state=active] .group-data-\[state\=active\]\/tabs-trigger\:bg-primary){background-color:var(--primary)}:is(:where(.group\/tabs-trigger)[data-state=active] .group-data-\[state\=active\]\/tabs-trigger\:font-semibold){--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}:is(:where(.group\/tabs-trigger)[data-state=active] .group-data-\[state\=active\]\/tabs-trigger\:text-primary-foreground){color:var(--primary-foreground)}:is(:where(.group\/checkbox)[data-state=checked] .group-data-\[state\=checked\]\/checkbox\:border-primary){border-color:var(--primary)}:is(:where(.group\/checkbox)[data-state=checked] .group-data-\[state\=checked\]\/checkbox\:bg-primary){background-color:var(--primary)}:is(:where(.group\/checkbox)[data-state=checked] .group-data-\[state\=checked\]\/checkbox\:text-primary-foreground){color:var(--primary-foreground)}:is(:where(.group\/radio-card)[data-state=checked] .group-data-\[state\=checked\]\/radio-card\:block){display:block}:is(:where(.group\/radio-card)[data-state=checked] .group-data-\[state\=checked\]\/radio-card\:border-primary){border-color:var(--primary)}:is(:where(.group\/radio-card)[data-state=checked] .group-data-\[state\=checked\]\/radio-card\:bg-primary){background-color:var(--primary)}:is(:where(.group\/radio-image)[data-state=checked] .group-data-\[state\=checked\]\/radio-image\:flex){display:flex}:is(:where(.group\/checkbox)[data-state=indeterminate] .group-data-\[state\=indeterminate\]\/checkbox\:block){display:block}:is(:where(.group\/checkbox)[data-state=indeterminate] .group-data-\[state\=indeterminate\]\/checkbox\:hidden){display:none}:is(:where(.group\/checkbox)[data-state=indeterminate] .group-data-\[state\=indeterminate\]\/checkbox\:border-primary){border-color:var(--primary)}:is(:where(.group\/checkbox)[data-state=indeterminate] .group-data-\[state\=indeterminate\]\/checkbox\:bg-primary){background-color:var(--primary)}:is(:where(.group\/checkbox)[data-state=indeterminate] .group-data-\[state\=indeterminate\]\/checkbox\:text-primary-foreground){color:var(--primary-foreground)}:is(:where(.group)[data-surface=shell] .group-data-\[surface\=shell\]\:border-0){border-style:var(--tw-border-style);border-width:0}:is(:where(.group)[data-variant=floating] .group-data-\[variant\=floating\]\:rounded-lg){border-radius:var(--radius)}:is(:where(.group)[data-variant=floating] .group-data-\[variant\=floating\]\:shadow-sm){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.group)[data-variant=floating] .group-data-\[variant\=floating\]\:ring-1){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.group)[data-variant=floating] .group-data-\[variant\=floating\]\:ring-sidebar-border){--tw-ring-color:var(--sidebar-border)}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:h-auto){height:auto}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:flex-none){flex:none}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:rounded-none){border-radius:0}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:bg-transparent){background-color:#0000}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:px-0){padding-inline:0}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:py-3){padding-block:calc(var(--spacing) * 3)}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:font-normal){--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:text-foreground){color:var(--foreground)}:is(:where(.group\/field-group)[data-variant=outline] .group-data-\[variant\=outline\]\/field-group\:-mb-2){margin-bottom:calc(var(--spacing) * -2)}:is(:where(.group\/drawer-content)[data-vaul-drawer-direction=bottom] .group-data-\[vaul-drawer-direction\=bottom\]\/drawer-content\:block){display:block}:is(:where(.group\/drawer-content)[data-vaul-drawer-direction=bottom] .group-data-\[vaul-drawer-direction\=bottom\]\/drawer-content\:text-center),:is(:where(.group\/drawer-content)[data-vaul-drawer-direction=top] .group-data-\[vaul-drawer-direction\=top\]\/drawer-content\:text-center){text-align:center}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:top-full){top:100%}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:mt-1\.5){margin-top:calc(var(--spacing) * 1.5)}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:overflow-hidden){overflow:hidden}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:rounded-lg){border-radius:var(--radius)}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:bg-popover){background-color:var(--popover)}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:text-popover-foreground){color:var(--popover-foreground)}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:shadow){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:ring-1){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:ring-foreground\/10){--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:ring-foreground\/10){--tw-ring-color:color-mix(in oklab, var(--foreground) 10%, transparent)}}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:duration-300){--tw-duration:.3s;transition-duration:.3s}:is(:is(:where(.group\/navigation-menu-trigger):where([data-state=open]),:where(.group\/navigation-menu-trigger):where([data-open]:not([data-open=false]))) .group-data-open\/navigation-menu-trigger\:rotate-180){rotate:180deg}:is(:where(.group\/command-item):where([data-selected=true]) .group-data-selected\/command-item\:text-foreground){color:var(--foreground)}:is(:where(.group\/tabs):where([data-orientation=horizontal]) .group-data-horizontal\/tabs\:h-8){height:calc(var(--spacing) * 8)}:is(:where(.group\/tabs):where([data-orientation=horizontal]) .group-data-horizontal\/tabs\:h-auto){height:auto}:is(:where(.group\/tabs):where([data-orientation=horizontal]) .group-data-horizontal\/tabs\:border-b){border-bottom-style:var(--tw-border-style);border-bottom-width:1px}:is(:where(.group\/tabs):where([data-orientation=horizontal]) .group-data-horizontal\/tabs\:border-border){border-color:var(--border)}:is(:where(.group\/tabs):where([data-orientation=vertical]) .group-data-vertical\/tabs\:h-fit){height:fit-content}:is(:where(.group\/tabs):where([data-orientation=vertical]) .group-data-vertical\/tabs\:w-full){width:100%}:is(:where(.group\/tabs):where([data-orientation=vertical]) .group-data-vertical\/tabs\:flex-col){flex-direction:column}:is(:where(.group\/tabs):where([data-orientation=vertical]) .group-data-vertical\/tabs\:justify-start){justify-content:flex-start}:is(:where(.group\/tabs-list)[data-variant=line] :is(:where(.group\/tabs):where([data-orientation=vertical]) .group-data-vertical\/tabs\:group-data-\[variant\=line\]\/tabs-list\:px-6)){padding-inline:calc(var(--spacing) * 6)}:is(:where(.group\/tabs-list)[data-variant=line] :is(:where(.group\/tabs):where([data-orientation=vertical]) .group-data-vertical\/tabs\:group-data-\[variant\=line\]\/tabs-list\:py-2)){padding-block:calc(var(--spacing) * 2)}@media (hover:hover){:is(:where(.peer\/menu-button):hover~.peer-hover\/menu-button\:text-muted-foreground){color:var(--muted-foreground)}:is(:where(.peer\/menu-button):hover~.peer-hover\/menu-button\:text-primary-foreground){color:var(--primary-foreground)}:is(:where(.peer\/menu-button):hover~.peer-hover\/menu-button\:text-sidebar-accent-foreground){color:var(--sidebar-accent-foreground)}}:is(:where(.peer):disabled~.peer-disabled\:cursor-not-allowed){cursor:not-allowed}:is(:where(.peer):disabled~.peer-disabled\:opacity-50){opacity:.5}:is(:where(.peer\/menu-button)[data-size=default]~.peer-data-\[size\=default\]\/menu-button\:top-1){top:var(--spacing)}:is(:where(.peer\/menu-button)[data-size=default]~.peer-data-\[size\=default\]\/menu-button\:top-1\.5){top:calc(var(--spacing) * 1.5)}:is(:where(.peer\/menu-button)[data-size=default]~.peer-data-\[size\=default\]\/menu-button\:top-2),:is(:where(.peer\/menu-button)[data-size=lg]~.peer-data-\[size\=lg\]\/menu-button\:top-2){top:calc(var(--spacing) * 2)}:is(:where(.peer\/menu-button)[data-size=lg]~.peer-data-\[size\=lg\]\/menu-button\:top-2\.5){top:calc(var(--spacing) * 2.5)}:is(:where(.peer\/menu-button)[data-size=sm]~.peer-data-\[size\=sm\]\/menu-button\:top-0\.5){top:calc(var(--spacing) * .5)}:is(:where(.peer\/menu-button)[data-size=sm]~.peer-data-\[size\=sm\]\/menu-button\:top-1){top:var(--spacing)}:is(:is(:where(.peer\/menu-button):where([data-state=active]),:where(.peer\/menu-button):where([data-active]:not([data-active=false])))~.peer-data-active\/menu-button\:text-muted-foreground){color:var(--muted-foreground)}:is(:is(:where(.peer\/menu-button):where([data-state=active]),:where(.peer\/menu-button):where([data-active]:not([data-active=false])))~.peer-data-active\/menu-button\:text-primary-foreground){color:var(--primary-foreground)}:is(:is(:where(.peer\/menu-button):where([data-state=active]),:where(.peer\/menu-button):where([data-active]:not([data-active=false])))~.peer-data-active\/menu-button\:text-sidebar-accent-foreground){color:var(--sidebar-accent-foreground)}.marker\:text-destructive ::marker{color:var(--destructive)}.marker\:text-destructive::marker{color:var(--destructive)}.marker\:text-destructive ::-webkit-details-marker{color:var(--destructive)}.marker\:text-destructive::-webkit-details-marker{color:var(--destructive)}.selection\:bg-primary ::selection{background-color:var(--primary)}.selection\:bg-primary::selection{background-color:var(--primary)}.selection\:text-primary-foreground ::selection{color:var(--primary-foreground)}.selection\:text-primary-foreground::selection{color:var(--primary-foreground)}.file\:inline-flex::file-selector-button{display:inline-flex}.file\:h-6::file-selector-button{height:calc(var(--spacing) * 6)}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.before\:pointer-events-none:before{content:var(--tw-content);pointer-events:none}.before\:absolute:before{content:var(--tw-content);position:absolute}.before\:-inset-x-\[100vmax\]:before{content:var(--tw-content);inset-inline:-100vmax}.before\:inset-y-1:before{content:var(--tw-content);inset-block:var(--spacing)}.before\:-start-\[calc\(0\.625rem\+1\.5px\)\]:before{content:var(--tw-content);inset-inline-start:calc(-.625rem - 1.5px)}.before\:bottom-0:before{content:var(--tw-content);bottom:0}.before\:h-px:before{content:var(--tw-content);height:1px}.before\:w-0\.5:before{content:var(--tw-content);width:calc(var(--spacing) * .5)}.before\:rounded-full:before{content:var(--tw-content);border-radius:2147483647px}.before\:bg-border:before{content:var(--tw-content);background-color:var(--border)}.not-last\:before\:absolute:not(:last-child):before{content:var(--tw-content);position:absolute}.not-last\:before\:end-0:not(:last-child):before{content:var(--tw-content);inset-inline-end:calc(var(--spacing) * 0)}.not-last\:before\:top-1\/2:not(:last-child):before{content:var(--tw-content);top:50%}.not-last\:before\:h-\[1\.6em\]:not(:last-child):before{content:var(--tw-content);height:1.6em}.not-last\:before\:w-px:not(:last-child):before{content:var(--tw-content);width:1px}.not-last\:before\:-translate-y-1\/2:not(:last-child):before{content:var(--tw-content);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.not-last\:before\:bg-border:not(:last-child):before{content:var(--tw-content);background-color:var(--border)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:-inset-2:after{content:var(--tw-content);inset:calc(var(--spacing) * -2)}.after\:inset-0:after{content:var(--tw-content);inset:0}.after\:-inset-x-3:after{content:var(--tw-content);inset-inline:calc(var(--spacing) * -3)}.after\:inset-x-0:after{content:var(--tw-content);inset-inline:0}.after\:-inset-y-2:after{content:var(--tw-content);inset-block:calc(var(--spacing) * -2)}.after\:inset-y-0:after{content:var(--tw-content);inset-block:0}.after\:start-0:after{content:var(--tw-content);inset-inline-start:calc(var(--spacing) * 0)}.after\:start-1\/2:after{content:var(--tw-content);inset-inline-start:50%}.after\:end-0:after{content:var(--tw-content);inset-inline-end:calc(var(--spacing) * 0)}.after\:-bottom-px:after{content:var(--tw-content);bottom:-1px}.after\:h-0\.5:after{content:var(--tw-content);height:calc(var(--spacing) * .5)}.after\:w-4:after{content:var(--tw-content);width:calc(var(--spacing) * 4)}.after\:w-\[2px\]:after{content:var(--tw-content);width:2px}.after\:rounded-\[inherit\]:after{content:var(--tw-content);border-radius:inherit}.after\:rounded-full:after{content:var(--tw-content);border-radius:2147483647px}.after\:rounded-lg:after{content:var(--tw-content);border-radius:var(--radius)}.after\:border:after{content:var(--tw-content);border-style:var(--tw-border-style);border-width:1px}.after\:border-border:after{content:var(--tw-content);border-color:var(--border)}.after\:bg-primary:after{content:var(--tw-content);background-color:var(--primary)}.after\:bg-primary-subtle:after{content:var(--tw-content);background-color:var(--primary-subtle)}.after\:bg-transparent:after{content:var(--tw-content);background-color:#0000}.after\:opacity-0:after{content:var(--tw-content);opacity:0}.after\:mix-blend-darken:after{content:var(--tw-content);mix-blend-mode:darken}.after\:transition-opacity:after{content:var(--tw-content);transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}:is(:where(.group)[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:after\:start-full):after{content:var(--tw-content);inset-inline-start:100%}:is(:where(.group\/tabs):where([data-orientation=horizontal]) .group-data-horizontal\/tabs\:after\:inset-x-0):after{content:var(--tw-content);inset-inline:0}:is(:where(.group\/tabs):where([data-orientation=horizontal]) .group-data-horizontal\/tabs\:after\:bottom-\[-5px\]):after{content:var(--tw-content);bottom:-5px}:is(:where(.group\/tabs):where([data-orientation=horizontal]) .group-data-horizontal\/tabs\:after\:h-0\.5):after{content:var(--tw-content);height:calc(var(--spacing) * .5)}:is(:where(.group\/tabs-list)[data-variant=line] :is(:where(.group\/tabs):where([data-orientation=horizontal]) .group-data-horizontal\/tabs\:group-data-\[variant\=line\]\/tabs-list\:after\:-bottom-px)):after{content:var(--tw-content);bottom:-1px}:is(:where(.group\/tabs):where([data-orientation=vertical]) .group-data-vertical\/tabs\:after\:inset-y-0):after{content:var(--tw-content);inset-block:0}:is(:where(.group\/tabs):where([data-orientation=vertical]) .group-data-vertical\/tabs\:after\:-end-1):after{content:var(--tw-content);inset-inline-end:calc(var(--spacing) * -1)}:is(:where(.group\/tabs):where([data-orientation=vertical]) .group-data-vertical\/tabs\:after\:w-0\.5):after{content:var(--tw-content);width:calc(var(--spacing) * .5)}.first\:rounded-s-lg:first-child{border-start-start-radius:var(--radius);border-end-start-radius:var(--radius)}.first\:border-s:first-child{border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}.first\:border-t-0:first-child{border-top-style:var(--tw-border-style);border-top-width:0}.first\:ps-0:first-child{padding-inline-start:0}.first\:pt-0:first-child{padding-top:0}.last\:mt-0:last-child{margin-top:0}.last\:rounded-e-lg:last-child{border-start-end-radius:var(--radius);border-end-end-radius:var(--radius)}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.last\:pe-0:last-child{padding-inline-end:0}.last\:pb-4:last-child{padding-bottom:calc(var(--spacing) * 4)}.even\:bg-muted\/40:nth-child(2n){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.even\:bg-muted\/40:nth-child(2n){background-color:color-mix(in oklab, var(--muted) 40%, transparent)}}.checked\:border-primary:checked{border-color:var(--primary)}.checked\:bg-primary:checked{background-color:var(--primary)}.checked\:text-primary-foreground:checked{color:var(--primary-foreground)}:is(:where(.group\/field-label):has(:focus-visible) .group-has-\[\:focus-visible\]\/field-label\:checked\:border-primary):checked{border-color:var(--primary)}.empty\:-mt-2:empty{margin-top:calc(var(--spacing) * -2)}.empty\:hidden:empty{display:none}.focus-within\:not-sr-only:focus-within{clip-path:none;white-space:normal;width:auto;height:auto;margin:0;padding:0;position:static;overflow:visible}.focus-within\:border-primary:focus-within{border-color:var(--primary)}.focus-within\:border-ring:focus-within{border-color:var(--ring)}.focus-within\:ring-0:focus-within{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-within\:ring-2:focus-within{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-within\:ring-3:focus-within{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-within\:ring-primary\/20:focus-within{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.focus-within\:ring-primary\/20:focus-within{--tw-ring-color:color-mix(in oklab, var(--primary) 20%, transparent)}}.focus-within\:ring-ring\/50:focus-within{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-within\:ring-ring\/50:focus-within{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}@media (hover:hover){.hover\:border-foreground\/20:hover{border-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.hover\:border-foreground\/20:hover{border-color:color-mix(in oklab, var(--foreground) 20%, transparent)}}.hover\:border-primary:hover{border-color:var(--primary)}.hover\:border-primary-5:hover{border-color:var(--primary-5)}.hover\:bg-\[color-mix\(in_oklab\,var\(--secondary\)\,var\(--foreground\)_6\%\)\]:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-\[color-mix\(in_oklab\,var\(--secondary\)\,var\(--foreground\)_6\%\)\]:hover{background-color:color-mix(in oklab,var(--secondary),var(--foreground) 6%)}}.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-card:hover{background-color:var(--card)}.hover\:bg-current\/10:hover{background-color:currentColor}@supports (color:color-mix(in lab, red, red)){.hover\:bg-current\/10:hover{background-color:color-mix(in oklab, currentcolor 10%, transparent)}}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--destructive) 90%, transparent)}}.hover\:bg-foreground\/4:hover{background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-foreground\/4:hover{background-color:color-mix(in oklab, var(--foreground) 4%, transparent)}}.hover\:bg-foreground\/6:hover{background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-foreground\/6:hover{background-color:color-mix(in oklab, var(--foreground) 6%, transparent)}}.hover\:bg-foreground\/10:hover{background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-foreground\/10:hover{background-color:color-mix(in oklab, var(--foreground) 10%, transparent)}}.hover\:bg-muted:hover,.hover\:bg-muted\/50:hover{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.hover\:bg-muted\/60:hover{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/60:hover{background-color:color-mix(in oklab, var(--muted) 60%, transparent)}}.hover\:bg-primary-2:hover{background-color:var(--primary-2)}.hover\:bg-primary-hover:hover{background-color:var(--primary-hover)}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.hover\:bg-secondary:hover{background-color:var(--secondary)}.hover\:bg-shell-hover:hover{background-color:var(--shell-hover)}.hover\:bg-sidebar-accent:hover{background-color:var(--sidebar-accent)}.hover\:bg-success\/85:hover{background-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-success\/85:hover{background-color:color-mix(in oklab, var(--success) 85%, transparent)}}.hover\:bg-transparent:hover{background-color:#0000}.hover\:bg-warning\/85:hover{background-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-warning\/85:hover{background-color:color-mix(in oklab, var(--warning) 85%, transparent)}}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-destructive:hover{color:var(--destructive)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-muted-foreground:hover{color:var(--muted-foreground)}.hover\:text-primary:hover{color:var(--primary)}.hover\:text-primary-7:hover{color:var(--primary-7)}.hover\:text-shell-foreground:hover{color:var(--shell-foreground)}.hover\:text-sidebar-accent-foreground:hover{color:var(--sidebar-accent-foreground)}.hover\:no-underline:hover{text-decoration-line:none}.hover\:underline:hover{text-decoration-line:underline}.hover\:underline-offset-4:hover{text-underline-offset:4px}.hover\:shadow-\[0_0_0_1px_var\(--sidebar-accent\)\]:hover{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--sidebar-accent));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hover\:shadow-sm:hover{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hover\:ring-3:hover{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.hover\:ring-foreground\/20:hover{--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.hover\:ring-foreground\/20:hover{--tw-ring-color:color-mix(in oklab, var(--foreground) 20%, transparent)}}.hover\:ring-foreground\/25:hover{--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.hover\:ring-foreground\/25:hover{--tw-ring-color:color-mix(in oklab, var(--foreground) 25%, transparent)}}.hover\:ring-ring\/50:hover{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.hover\:ring-ring\/50:hover{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}:is(:where(.group)[data-collapsible=offcanvas] .hover\:group-data-\[collapsible\=offcanvas\]\:bg-sidebar:hover){background-color:var(--sidebar)}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:hover\:text-primary-7):hover{color:var(--primary-7)}.hover\:after\:bg-sidebar-border:hover:after{content:var(--tw-content);background-color:var(--sidebar-border)}}.focus\:not-sr-only:focus{clip-path:none;white-space:normal;width:auto;height:auto;margin:0;padding:0;position:static;overflow:visible}.focus\:z-10:focus{z-index:10}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:bg-muted:focus{background-color:var(--muted)}.focus\:text-accent-foreground:focus,:is(.focus\:\*\*\:text-accent-foreground:focus *),:is(.not-data-\[variant\=destructive\]\:focus\:\*\*\:text-accent-foreground:not([data-variant=destructive]):focus *){color:var(--accent-foreground)}.focus-visible\:not-sr-only:focus-visible{clip-path:none;white-space:normal;width:auto;height:auto;margin:0;padding:0;position:static;overflow:visible}.focus-visible\:fixed:focus-visible{position:fixed}.focus-visible\:start-2:focus-visible{inset-inline-start:calc(var(--spacing) * 2)}.focus-visible\:top-\[calc\(0\.5rem\+env\(safe-area-inset-top\)\)\]:focus-visible{top:calc(.5rem + env(safe-area-inset-top))}.focus-visible\:z-10:focus-visible{z-index:10}.focus-visible\:z-100:focus-visible{z-index:100}.focus-visible\:rounded-lg:focus-visible{border-radius:var(--radius)}.focus-visible\:border-destructive:focus-visible{border-color:var(--destructive)}.focus-visible\:border-primary:focus-visible{border-color:var(--primary)}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:bg-background:focus-visible{background-color:var(--background)}.focus-visible\:bg-muted:focus-visible{background-color:var(--muted)}.focus-visible\:px-4:focus-visible{padding-inline:calc(var(--spacing) * 4)}.focus-visible\:py-2\.5:focus-visible{padding-block:calc(var(--spacing) * 2.5)}.focus-visible\:text-sm:focus-visible{font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}.focus-visible\:font-medium:focus-visible{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.focus-visible\:text-foreground:focus-visible{color:var(--foreground)}.focus-visible\:underline:focus-visible{text-decoration-line:underline}.focus-visible\:shadow-lg:focus-visible{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-0:focus-visible{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-3:focus-visible{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-4:focus-visible{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-current:focus-visible{--tw-ring-color:currentcolor}.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.focus-visible\:ring-destructive\/30:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-destructive\/30:focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 30%, transparent)}}.focus-visible\:ring-primary\/20:focus-visible{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-primary\/20:focus-visible{--tw-ring-color:color-mix(in oklab, var(--primary) 20%, transparent)}}.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.focus-visible\:ring-ring\/60:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/60:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 60%, transparent)}}.focus-visible\:ring-success\/40:focus-visible{--tw-ring-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-success\/40:focus-visible{--tw-ring-color:color-mix(in oklab, var(--success) 40%, transparent)}}.focus-visible\:ring-warning\/40:focus-visible{--tw-ring-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-warning\/40:focus-visible{--tw-ring-color:color-mix(in oklab, var(--warning) 40%, transparent)}}.focus-visible\:outline-hidden:focus-visible{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus-visible\:outline-hidden:focus-visible{outline-offset:2px;outline:2px solid #0000}}.focus-visible\:outline-1:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-3:focus-visible{outline-style:var(--tw-outline-style);outline-width:3px}.focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\:outline-ring:focus-visible{outline-color:var(--ring)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-inset:focus-visible{--tw-ring-inset:inset}:is(.\*\:focus-visible\:relative>*):focus-visible{position:relative}:is(.\*\:focus-visible\:z-10>*):focus-visible{z-index:10}.focus-visible\:after\:border-ring:focus-visible:after{content:var(--tw-content);border-color:var(--ring)}.active\:cursor-grabbing:active{cursor:grabbing}.active\:border-primary-7:active{border-color:var(--primary-7)}.active\:bg-\[color-mix\(in_oklab\,var\(--destructive\)\,black_12\%\)\]:active{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.active\:bg-\[color-mix\(in_oklab\,var\(--destructive\)\,black_12\%\)\]:active{background-color:color-mix(in oklab,var(--destructive),black 12%)}}.active\:bg-\[color-mix\(in_oklab\,var\(--secondary\)\,var\(--foreground\)_6\%\)\]:active{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.active\:bg-\[color-mix\(in_oklab\,var\(--secondary\)\,var\(--foreground\)_6\%\)\]:active{background-color:color-mix(in oklab,var(--secondary),var(--foreground) 6%)}}.active\:bg-primary-active:active{background-color:var(--primary-active)}.active\:bg-shell-active:active{background-color:var(--shell-active)}.active\:bg-sidebar-accent:active{background-color:var(--sidebar-accent)}.active\:text-primary-7:active{color:var(--primary-7)}.active\:text-shell-foreground:active{color:var(--shell-foreground)}.active\:text-sidebar-accent-foreground:active{color:var(--sidebar-accent-foreground)}.active\:ring-3:active{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.active\:ring-ring\/50:active{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.active\:ring-ring\/50:active{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-input\/50:disabled{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.disabled\:bg-input\/50:disabled{background-color:color-mix(in oklab, var(--input) 50%, transparent)}}.disabled\:bg-transparent:disabled{background-color:#0000}.disabled\:opacity-50:disabled{opacity:.5}:where([data-side=left]) .in-data-\[side\=left\]\:cursor-w-resize{cursor:w-resize}:where([data-side=right]) .in-data-\[side\=right\]\:cursor-e-resize{cursor:e-resize}:where([data-slot=button-group]) .in-data-\[slot\=button-group\]\:rounded-md{border-radius:calc(var(--radius) * .8)}:where([data-slot=button-group]) .in-data-\[slot\=button-group\]\:rounded-sm{border-radius:calc(var(--radius) * .6667)}:where([data-slot=card-content]) .in-data-\[slot\=card-content\]\:bg-transparent{background-color:#0000}:where([data-slot=combobox-content]) .in-data-\[slot\=combobox-content\]\:focus-within\:border-inherit:focus-within{border-color:inherit}:where([data-slot=combobox-content]) .in-data-\[slot\=combobox-content\]\:focus-within\:ring-0:focus-within{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:where([data-slot=dialog-content]) .in-data-\[slot\=dialog-content\]\:rounded-lg\!{border-radius:var(--radius)!important}:where([data-slot=dropdown-menu-content]) .in-data-\[slot\=dropdown-menu-content\]\:p-0{padding:0}:where([data-slot=navigation-menu-content]) .in-data-\[slot\=navigation-menu-content\]\:rounded-md{border-radius:calc(var(--radius) * .8)}:where([data-slot=popover-content]) .in-data-\[slot\=popover-content\]\:bg-transparent{background-color:#0000}:where([data-slot=tooltip-content]) .in-data-\[slot\=tooltip-content\]\:bg-background\/20{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){:where([data-slot=tooltip-content]) .in-data-\[slot\=tooltip-content\]\:bg-background\/20{background-color:color-mix(in oklab, var(--background) 20%, transparent)}}:where([data-slot=tooltip-content]) .in-data-\[slot\=tooltip-content\]\:text-background{color:var(--background)}:where(:where([data-state=active]),:where([data-active]:not([data-active=false]))) .in-data-active\:bg-primary\/10{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){:where(:where([data-state=active]),:where([data-active]:not([data-active=false]))) .in-data-active\:bg-primary\/10{background-color:color-mix(in oklab, var(--primary) 10%, transparent)}}.has-disabled\:bg-input\/50:has(:disabled){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.has-disabled\:bg-input\/50:has(:disabled){background-color:color-mix(in oklab, var(--input) 50%, transparent)}}.has-disabled\:opacity-50:has(:disabled){opacity:.5}.has-aria-expanded\:bg-muted:has([aria-expanded=true]){background-color:var(--muted)}.has-aria-invalid\:border-destructive:has([aria-invalid=true]){border-color:var(--destructive)}.has-aria-invalid\:ring-3:has([aria-invalid=true]){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-aria-invalid\:ring-destructive\/20:has([aria-invalid=true]){--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.has-aria-invalid\:ring-destructive\/20:has([aria-invalid=true]){--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.has-data-\[icon\=inline-end\]\:pe-1:has([data-icon=inline-end]){padding-inline-end:var(--spacing)}.has-data-\[icon\=inline-end\]\:pe-1\.5:has([data-icon=inline-end]){padding-inline-end:calc(var(--spacing) * 1.5)}.has-data-\[icon\=inline-end\]\:pe-2:has([data-icon=inline-end]){padding-inline-end:calc(var(--spacing) * 2)}:is(:where(.group\/toggle-group)[data-spacing="0"] .group-data-\[spacing\=0\]\/toggle-group\:has-data-\[icon\=inline-end\]\:pe-1\.5):has([data-icon=inline-end]){padding-inline-end:calc(var(--spacing) * 1.5)}.has-data-\[icon\=inline-start\]\:ps-1:has([data-icon=inline-start]){padding-inline-start:var(--spacing)}.has-data-\[icon\=inline-start\]\:ps-1\.5:has([data-icon=inline-start]){padding-inline-start:calc(var(--spacing) * 1.5)}.has-data-\[icon\=inline-start\]\:ps-2:has([data-icon=inline-start]){padding-inline-start:calc(var(--spacing) * 2)}:is(:where(.group\/toggle-group)[data-spacing="0"] .group-data-\[spacing\=0\]\/toggle-group\:has-data-\[icon\=inline-start\]\:ps-1\.5):has([data-icon=inline-start]){padding-inline-start:calc(var(--spacing) * 1.5)}.has-data-\[size\=sm\]\:gap-2\.5:has([data-size=sm]){gap:calc(var(--spacing) * 2.5)}.has-data-\[size\=xs\]\:gap-2:has([data-size=xs]){gap:calc(var(--spacing) * 2)}.has-data-\[slot\=alert-action\]\:relative:has([data-slot=alert-action]){position:relative}.has-data-\[slot\=alert-action\]\:pe-18:has([data-slot=alert-action]){padding-inline-end:calc(var(--spacing) * 18)}.has-data-\[slot\=alert-dialog-media\]\:grid-rows-\[auto_auto_1fr\]:has([data-slot=alert-dialog-media]){grid-template-rows:auto auto 1fr}.has-data-\[slot\=alert-dialog-media\]\:gap-x-4:has([data-slot=alert-dialog-media]){column-gap:calc(var(--spacing) * 4)}.has-data-\[slot\=card-action\]\:grid-cols-\[1fr_auto\]:has([data-slot=card-action]){grid-template-columns:1fr auto}.has-data-\[slot\=card-description\]\:grid-rows-\[auto_auto\]:has([data-slot=card-description]){grid-template-rows:auto auto}.has-data-\[slot\=card-footer\]\:pb-0:has([data-slot=card-footer]){padding-bottom:0}.has-data-\[slot\=kbd\]\:pe-1\.5:has([data-slot=kbd]){padding-inline-end:calc(var(--spacing) * 1.5)}.has-data-\[variant\=inset\]\:bg-sidebar:has([data-variant=inset]){background-color:var(--sidebar)}.has-data-checked\:border-primary\/30:has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.has-data-checked\:border-primary\/30:has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){border-color:color-mix(in oklab, var(--primary) 30%, transparent)}}.has-data-checked\:bg-primary\/5:has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.has-data-checked\:bg-primary\/5:has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){background-color:color-mix(in oklab, var(--primary) 5%, transparent)}}.has-\[\[data-slot\=choice-trigger\]\:focus-visible\]\:border-primary:has([data-slot=choice-trigger]:focus-visible){border-color:var(--primary)}.has-\[\[data-slot\=choice-trigger\]\:focus-visible\]\:ring-2:has([data-slot=choice-trigger]:focus-visible){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-\[\[data-slot\=choice-trigger\]\:focus-visible\]\:ring-primary\/20:has([data-slot=choice-trigger]:focus-visible){--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.has-\[\[data-slot\=choice-trigger\]\:focus-visible\]\:ring-primary\/20:has([data-slot=choice-trigger]:focus-visible){--tw-ring-color:color-mix(in oklab, var(--primary) 20%, transparent)}}.has-\[\[data-slot\=choice-trigger\]\[aria-invalid\=true\]\]\:border-destructive:has([data-slot=choice-trigger][aria-invalid=true]){border-color:var(--destructive)}.has-\[\[data-slot\=choice-trigger\]\[aria-invalid\=true\]\]\:ring-3:has([data-slot=choice-trigger][aria-invalid=true]){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-\[\[data-slot\=choice-trigger\]\[aria-invalid\=true\]\]\:ring-destructive\/20:has([data-slot=choice-trigger][aria-invalid=true]){--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.has-\[\[data-slot\=choice-trigger\]\[aria-invalid\=true\]\]\:ring-destructive\/20:has([data-slot=choice-trigger][aria-invalid=true]){--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.has-\[\[data-slot\=input-group-control\]\:focus-visible\]\:border-primary:has([data-slot=input-group-control]:focus-visible){border-color:var(--primary)}.has-\[\[data-slot\=input-group-control\]\:focus-visible\]\:ring-2:has([data-slot=input-group-control]:focus-visible){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-\[\[data-slot\=input-group-control\]\:focus-visible\]\:ring-primary\/20:has([data-slot=input-group-control]:focus-visible){--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.has-\[\[data-slot\=input-group-control\]\:focus-visible\]\:ring-primary\/20:has([data-slot=input-group-control]:focus-visible){--tw-ring-color:color-mix(in oklab, var(--primary) 20%, transparent)}}.has-\[\[data-slot\=page-title\]\[data-variant\=band\]\]\:pt-0:has([data-slot=page-title][data-variant=band]){padding-top:0}.has-\[\[data-slot\=tag-label\]\:focus-visible\]\:ring-3:has([data-slot=tag-label]:focus-visible){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-\[\[data-slot\=tag-label\]\:focus-visible\]\:ring-ring\/50:has([data-slot=tag-label]:focus-visible){--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.has-\[\[data-slot\=tag-label\]\:focus-visible\]\:ring-ring\/50:has([data-slot=tag-label]:focus-visible){--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.has-\[\[data-slot\]\[aria-invalid\=true\]\]\:border-destructive:has([data-slot][aria-invalid=true]){border-color:var(--destructive)}.has-\[\[data-slot\]\[aria-invalid\=true\]\]\:ring-3:has([data-slot][aria-invalid=true]){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-\[\[data-slot\]\[aria-invalid\=true\]\]\:ring-destructive\/20:has([data-slot][aria-invalid=true]){--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.has-\[\[data-slot\]\[aria-invalid\=true\]\]\:ring-destructive\/20:has([data-slot][aria-invalid=true]){--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.has-\[a\:focus-visible\]\:ring-3:has(:is(a:focus-visible)){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-\[a\:focus-visible\]\:ring-ring\/50:has(:is(a:focus-visible)){--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.has-\[a\:focus-visible\]\:ring-ring\/50:has(:is(a:focus-visible)){--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.has-\[input\:disabled\]\:cursor-not-allowed:has(:is(input:disabled)){cursor:not-allowed}.has-\[input\:disabled\]\:opacity-50:has(:is(input:disabled)){opacity:.5}.has-\[input\:focus-visible\]\:border-ring:has(:is(input:focus-visible)){border-color:var(--ring)}.has-\[input\:focus-visible\]\:ring-3:has(:is(input:focus-visible)){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-\[input\:focus-visible\]\:ring-ring\/50:has(:is(input:focus-visible)){--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.has-\[input\:focus-visible\]\:ring-ring\/50:has(:is(input:focus-visible)){--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.has-\[input\[aria-invalid\=true\]\]\:border-destructive:has(:is(input[aria-invalid=true])){border-color:var(--destructive)}.has-\[input\[aria-invalid\=true\]\]\:ring-destructive\/20:has(:is(input[aria-invalid=true])){--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.has-\[input\[aria-invalid\=true\]\]\:ring-destructive\/20:has(:is(input[aria-invalid=true])){--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.has-\[select\:disabled\]\:opacity-50:has(:is(select:disabled)){opacity:.5}.has-\[\>\[data-active\=true\]\]\:before\:bg-sidebar-primary:has(>[data-active=true]):before{content:var(--tw-content);background-color:var(--sidebar-primary)}.has-\[\>\[data-align\=block-end\]\]\:h-auto:has(>[data-align=block-end]){height:auto}.has-\[\>\[data-align\=block-end\]\]\:flex-col:has(>[data-align=block-end]){flex-direction:column}.has-\[\>\[data-align\=block-start\]\]\:h-auto:has(>[data-align=block-start]){height:auto}.has-\[\>\[data-align\=block-start\]\]\:flex-col:has(>[data-align=block-start]){flex-direction:column}.has-\[\>\[data-slot\=button-group\]\]\:gap-2:has(>[data-slot=button-group]){gap:calc(var(--spacing) * 2)}.has-\[\>\[data-slot\=card-header\]\[data-bordered\]\]\:pt-0:has(>[data-slot=card-header][data-bordered]){padding-top:0}.has-\[\>\[data-slot\=checkbox-group\]\]\:gap-3:has(>[data-slot=checkbox-group]){gap:calc(var(--spacing) * 3)}.has-\[\>\[data-slot\=field-content\]\]\:items-start:has(>[data-slot=field-content]){align-items:flex-start}.has-\[\>\[data-slot\=field\]\]\:w-full:has(>[data-slot=field]){width:100%}.has-\[\>\[data-slot\=field\]\]\:flex-col:has(>[data-slot=field]){flex-direction:column}.has-\[\>\[data-slot\=field\]\]\:rounded-lg:has(>[data-slot=field]){border-radius:var(--radius)}.has-\[\>\[data-slot\=field\]\]\:border:has(>[data-slot=field]){border-style:var(--tw-border-style);border-width:1px}@media (hover:hover){.has-\[\>\[data-slot\=field\]\]\:not-has-\[\:disabled\,\[data-disabled\]\]\:hover\:bg-muted\/50:has(>[data-slot=field]):not(:has(:is(:disabled,[data-disabled]))):hover{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.has-\[\>\[data-slot\=field\]\]\:not-has-\[\:disabled\,\[data-disabled\]\]\:hover\:bg-muted\/50:has(>[data-slot=field]):not(:has(:is(:disabled,[data-disabled]))):hover{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}}.has-\[\>\[data-slot\=field\]\]\:has-\[\:focus-visible\]\:border-ring:has(>[data-slot=field]):has(:focus-visible){border-color:var(--ring)}.has-\[\>\[data-slot\=field\]\]\:has-\[\:focus-visible\]\:ring-3:has(>[data-slot=field]):has(:focus-visible){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.has-\[\>\[data-slot\=field\]\]\:has-\[\:focus-visible\]\:ring-ring\/50:has(>[data-slot=field]):has(:focus-visible){--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.has-\[\>\[data-slot\=field\]\]\:has-\[\:focus-visible\]\:ring-ring\/50:has(>[data-slot=field]):has(:focus-visible){--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.has-\[\>\[data-slot\=radio-group\]\]\:gap-3:has(>[data-slot=radio-group]){gap:calc(var(--spacing) * 3)}.has-\[\>\[data-slot\=stat-tile-footer\]\]\:pb-0:has(>[data-slot=stat-tile-footer]){padding-bottom:0}.has-\[\>button\]\:ms-\[-0\.3rem\]:has(>button){margin-inline-start:-.3rem}.has-\[\>button\]\:me-\[-0\.3rem\]:has(>button){margin-inline-end:-.3rem}.has-\[\>img\:first-child\]\:pt-0:has(>img:first-child){padding-top:0}.has-\[\>kbd\]\:ms-\[-0\.15rem\]:has(>kbd){margin-inline-start:-.15rem}.has-\[\>kbd\]\:me-\[-0\.15rem\]:has(>kbd){margin-inline-end:-.15rem}.has-\[\>svg\]\:grid-cols-\[auto_1fr\]:has(>svg){grid-template-columns:auto 1fr}.has-\[\>svg\]\:gap-x-2:has(>svg){column-gap:calc(var(--spacing) * 2)}.has-\[\>svg\]\:p-0:has(>svg){padding:0}.has-\[\>textarea\]\:h-auto:has(>textarea){height:auto}.aria-disabled\:pointer-events-none[aria-disabled=true]{pointer-events:none}.aria-disabled\:cursor-default[aria-disabled=true]{cursor:default}.aria-disabled\:cursor-not-allowed[aria-disabled=true]{cursor:not-allowed}.aria-disabled\:opacity-40[aria-disabled=true]{opacity:.4}.aria-disabled\:opacity-50[aria-disabled=true]{opacity:.5}@media (hover:hover){.aria-disabled\:hover\:bg-transparent[aria-disabled=true]:hover{background-color:#0000}}.aria-expanded\:border-primary-5[aria-expanded=true]{border-color:var(--primary-5)}.aria-expanded\:bg-\[color-mix\(in_oklab\,var\(--secondary\)\,var\(--foreground\)_6\%\)\][aria-expanded=true]{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.aria-expanded\:bg-\[color-mix\(in_oklab\,var\(--secondary\)\,var\(--foreground\)_6\%\)\][aria-expanded=true]{background-color:color-mix(in oklab,var(--secondary),var(--foreground) 6%)}}.aria-expanded\:bg-destructive\/90[aria-expanded=true]{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.aria-expanded\:bg-destructive\/90[aria-expanded=true]{background-color:color-mix(in oklab, var(--destructive) 90%, transparent)}}.aria-expanded\:bg-muted[aria-expanded=true]{background-color:var(--muted)}.aria-expanded\:bg-primary-hover[aria-expanded=true]{background-color:var(--primary-hover)}.aria-expanded\:bg-secondary[aria-expanded=true]{background-color:var(--secondary)}.aria-expanded\:bg-success\/85[aria-expanded=true]{background-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.aria-expanded\:bg-success\/85[aria-expanded=true]{background-color:color-mix(in oklab, var(--success) 85%, transparent)}}.aria-expanded\:bg-warning\/85[aria-expanded=true]{background-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.aria-expanded\:bg-warning\/85[aria-expanded=true]{background-color:color-mix(in oklab, var(--warning) 85%, transparent)}}.aria-expanded\:text-foreground[aria-expanded=true]{color:var(--foreground)}.aria-expanded\:text-primary-7[aria-expanded=true]{color:var(--primary-7)}.aria-expanded\:opacity-100[aria-expanded=true]{opacity:1}.aria-invalid\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\:ring-0[aria-invalid=true]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.aria-invalid\:ring-3[aria-invalid=true]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.aria-invalid\:checked\:border-primary[aria-invalid=true]:checked,.aria-invalid\:aria-checked\:border-primary[aria-invalid=true][aria-checked=true]{border-color:var(--primary)}.aria-pressed\:bg-background[aria-pressed=true]{background-color:var(--background)}.aria-pressed\:bg-muted[aria-pressed=true]{background-color:var(--muted)}.aria-pressed\:bg-primary-1[aria-pressed=true]{background-color:var(--primary-1)}.aria-pressed\:text-foreground[aria-pressed=true]{color:var(--foreground)}.aria-pressed\:text-primary-7[aria-pressed=true]{color:var(--primary-7)}.aria-pressed\:shadow-sm[aria-pressed=true]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.aria-selected\:bg-accent[aria-selected=true]{background-color:var(--accent)}.aria-selected\:bg-primary[aria-selected=true],.aria-selected\:bg-primary\/10[aria-selected=true]{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.aria-selected\:bg-primary\/10[aria-selected=true]{background-color:color-mix(in oklab, var(--primary) 10%, transparent)}}.aria-selected\:text-accent-foreground[aria-selected=true]{color:var(--accent-foreground)}.aria-selected\:text-foreground[aria-selected=true]{color:var(--foreground)}.aria-selected\:text-muted-foreground[aria-selected=true]{color:var(--muted-foreground)}.aria-selected\:text-primary-foreground[aria-selected=true]{color:var(--primary-foreground)}.data-current\:font-semibold[data-current]{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.data-current\:ring-1[data-current]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-current\:ring-primary\/40[data-current]{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.data-current\:ring-primary\/40[data-current]{--tw-ring-color:color-mix(in oklab, var(--primary) 40%, transparent)}}.data-dragging\:cursor-grabbing[data-dragging]{cursor:grabbing}.data-dragging\:bg-muted[data-dragging]{background-color:var(--muted)}.data-dragging\:opacity-60[data-dragging]{opacity:.6}.data-dragging\:shadow-md[data-dragging]{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-drop-target\:ring-2[data-drop-target]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-drop-target\:ring-primary\/40[data-drop-target]{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.data-drop-target\:ring-primary\/40[data-drop-target]{--tw-ring-color:color-mix(in oklab, var(--primary) 40%, transparent)}}.data-focus-visible\:size-6[data-focus-visible]{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.data-focus-visible\:ring-2[data-focus-visible]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-focus-visible\:ring-3[data-focus-visible]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-focus-visible\:ring-ring[data-focus-visible],.data-focus-visible\:ring-ring\/50[data-focus-visible]{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.data-focus-visible\:ring-ring\/50[data-focus-visible]{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.data-highlighted\:bg-primary\/10[data-highlighted]{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.data-highlighted\:bg-primary\/10[data-highlighted]{background-color:color-mix(in oklab, var(--primary) 10%, transparent)}}.data-indeterminate\:bg-primary[data-indeterminate]{background-color:var(--primary)}.data-indeterminate\:text-primary-foreground[data-indeterminate]{color:var(--primary-foreground)}.data-inset\:ps-7[data-inset]{padding-inline-start:calc(var(--spacing) * 7)}.data-invalid\:border-destructive[data-invalid]{border-color:var(--destructive)}.data-invalid\:text-destructive[data-invalid]{color:var(--destructive)}.data-invalid\:ring-3[data-invalid]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-invalid\:ring-destructive\/20[data-invalid]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.data-invalid\:ring-destructive\/20[data-invalid]{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.data-muted\:text-muted-foreground[data-muted],.data-placeholder\:text-muted-foreground[data-placeholder]{color:var(--muted-foreground)}.data-popup-open\:bg-muted\/50[data-popup-open]{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.data-popup-open\:bg-muted\/50[data-popup-open]{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}@media (hover:hover){.data-popup-open\:hover\:bg-muted[data-popup-open]:hover{background-color:var(--muted)}}.data-\[active\=true\]\:z-10[data-active=true]{z-index:10}.data-\[active\=true\]\:border-primary[data-active=true]{border-color:var(--primary)}.data-\[active\=true\]\:ring-2[data-active=true]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-\[active\=true\]\:ring-primary\/20[data-active=true]{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.data-\[active\=true\]\:ring-primary\/20[data-active=true]{--tw-ring-color:color-mix(in oklab, var(--primary) 20%, transparent)}}.data-\[active\=true\]\:aria-invalid\:border-destructive[data-active=true][aria-invalid=true]{border-color:var(--destructive)}.data-\[active\=true\]\:aria-invalid\:ring-destructive\/20[data-active=true][aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.data-\[active\=true\]\:aria-invalid\:ring-destructive\/20[data-active=true][aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.data-\[align-trigger\=true\]\:animate-none[data-align-trigger=true]{animation:none}.data-\[disabled\]\:cursor-not-allowed[data-disabled]{cursor:not-allowed}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\[disabled\=true\]\:opacity-50[data-disabled=true]{opacity:.5}.data-\[drag-active\]\:border-primary[data-drag-active]{border-color:var(--primary)}.data-\[drag-active\]\:bg-primary-subtle[data-drag-active]{background-color:var(--primary-subtle)}.data-\[drag-active\]\:text-primary-subtle-foreground[data-drag-active]{color:var(--primary-subtle-foreground)}.data-\[invalid\]\:border-destructive[data-invalid]{border-color:var(--destructive)}.data-\[invalid\=true\]\:text-destructive[data-invalid=true]{color:var(--destructive)}.data-\[motion\=from-end\]\:slide-in-from-end-52[data-motion=from-end]:where(:dir(ltr),[dir=ltr]){--tw-enter-translate-x:calc(52*var(--spacing))}.data-\[motion\=from-end\]\:slide-in-from-end-52[data-motion=from-end]:where(:dir(rtl),[dir=rtl]),.data-\[motion\=from-start\]\:slide-in-from-start-52[data-motion=from-start]:where(:dir(ltr),[dir=ltr]){--tw-enter-translate-x:calc(52*var(--spacing)*-1)}.data-\[motion\=from-start\]\:slide-in-from-start-52[data-motion=from-start]:where(:dir(rtl),[dir=rtl]){--tw-enter-translate-x:calc(52*var(--spacing))}.data-\[motion\=to-end\]\:slide-out-to-end-52[data-motion=to-end]:where(:dir(ltr),[dir=ltr]){--tw-exit-translate-x:calc(52*var(--spacing))}.data-\[motion\=to-end\]\:slide-out-to-end-52[data-motion=to-end]:where(:dir(rtl),[dir=rtl]),.data-\[motion\=to-start\]\:slide-out-to-start-52[data-motion=to-start]:where(:dir(ltr),[dir=ltr]){--tw-exit-translate-x:calc(52*var(--spacing)*-1)}.data-\[motion\=to-start\]\:slide-out-to-start-52[data-motion=to-start]:where(:dir(rtl),[dir=rtl]){--tw-exit-translate-x:calc(52*var(--spacing))}.data-\[motion\^\=from-\]\:animate-in[data-motion^=from-]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[motion\^\=from-\]\:fade-in[data-motion^=from-]{--tw-enter-opacity:0}.data-\[motion\^\=to-\]\:animate-out[data-motion^=to-]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[motion\^\=to-\]\:fade-out[data-motion^=to-]{--tw-exit-opacity:0}.data-\[position\=popper\]\:h-\(--radix-select-trigger-height\)[data-position=popper]{height:var(--radix-select-trigger-height)}.data-\[position\=popper\]\:w-full[data-position=popper]{width:100%}.data-\[position\=popper\]\:min-w-\(--radix-select-trigger-width\)[data-position=popper]{min-width:var(--radix-select-trigger-width)}.data-\[range-end\=true\]\:rounded-\(--cell-radius\)[data-range-end=true]{border-radius:var(--cell-radius)}.data-\[range-end\=true\]\:rounded-e-\(--cell-radius\)[data-range-end=true]{border-start-end-radius:var(--cell-radius);border-end-end-radius:var(--cell-radius)}.data-\[range-end\=true\]\:bg-primary[data-range-end=true]{background-color:var(--primary)}.data-\[range-end\=true\]\:text-primary-foreground[data-range-end=true]{color:var(--primary-foreground)}.data-\[range-middle\=true\]\:rounded-none[data-range-middle=true]{border-radius:0}.data-\[range-middle\=true\]\:bg-primary-subtle[data-range-middle=true]{background-color:var(--primary-subtle)}.data-\[range-middle\=true\]\:text-primary-subtle-foreground[data-range-middle=true]{color:var(--primary-subtle-foreground)}.data-\[range-start\=true\]\:rounded-\(--cell-radius\)[data-range-start=true]{border-radius:var(--cell-radius)}.data-\[range-start\=true\]\:rounded-s-\(--cell-radius\)[data-range-start=true]{border-start-start-radius:var(--cell-radius);border-end-start-radius:var(--cell-radius)}.data-\[range-start\=true\]\:bg-primary[data-range-start=true]{background-color:var(--primary)}.data-\[range-start\=true\]\:text-primary-foreground[data-range-start=true]{color:var(--primary-foreground)}.data-\[selected-single\=true\]\:bg-primary[data-selected-single=true]{background-color:var(--primary)}.data-\[selected-single\=true\]\:text-primary-foreground[data-selected-single=true]{color:var(--primary-foreground)}.data-\[selected\=true\]\:rounded-none[data-selected=true]{border-radius:0}.data-\[selected\=true\]\:bg-accent[data-selected=true]{background-color:var(--accent)}.data-\[selected\=true\]\:text-accent-foreground[data-selected=true]{color:var(--accent-foreground)}.data-\[selected\=true\]\:ring-0[data-selected=true]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-\[side\=bottom\]\:inset-x-0[data-side=bottom]{inset-inline:0}.data-\[side\=bottom\]\:bottom-0[data-side=bottom]{bottom:0}.data-\[side\=bottom\]\:h-auto[data-side=bottom]{height:auto}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=bottom\]\:border-t[data-side=bottom]{border-top-style:var(--tw-border-style);border-top-width:1px}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:calc(2*var(--spacing)*-1)}.data-\[side\=left\]\:inset-y-0[data-side=left]{inset-block:0}.data-\[side\=left\]\:left-0[data-side=left]{left:0}.data-\[side\=left\]\:h-full[data-side=left]{height:100%}.data-\[side\=left\]\:w-3\/4[data-side=left]{width:75%}.data-\[side\=left\]\:w-\[calc\(100\%-2\.5rem\)\][data-side=left]{width:calc(100% - 2.5rem)}.data-\[side\=left\]\:w-full[data-side=left]{width:100%}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=left\]\:border-e[data-side=left]{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:calc(2*var(--spacing))}:is(:where(.group)[data-collapsible=offcanvas] .data-\[side\=left\]\:group-data-\[collapsible\=offcanvas\]\:left-\[calc\(var\(--sidebar-width\)\*-1\)\][data-side=left]){left:calc(var(--sidebar-width) * -1)}.data-\[side\=right\]\:inset-y-0[data-side=right]{inset-block:0}.data-\[side\=right\]\:right-0[data-side=right]{right:0}.data-\[side\=right\]\:h-full[data-side=right]{height:100%}.data-\[side\=right\]\:w-3\/4[data-side=right]{width:75%}.data-\[side\=right\]\:w-\[calc\(100\%-2\.5rem\)\][data-side=right]{width:calc(100% - 2.5rem)}.data-\[side\=right\]\:w-full[data-side=right]{width:100%}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=right\]\:border-s[data-side=right]{border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:calc(2*var(--spacing)*-1)}:is(:where(.group)[data-collapsible=offcanvas] .data-\[side\=right\]\:group-data-\[collapsible\=offcanvas\]\:right-\[calc\(var\(--sidebar-width\)\*-1\)\][data-side=right]){right:calc(var(--sidebar-width) * -1)}.data-\[side\=top\]\:inset-x-0[data-side=top]{inset-inline:0}.data-\[side\=top\]\:top-0[data-side=top]{top:0}.data-\[side\=top\]\:h-auto[data-side=top]{height:auto}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=top\]\:border-b[data-side=top]{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:calc(2*var(--spacing))}.data-\[size\=default\]\:h-8[data-size=default]{height:calc(var(--spacing) * 8)}.data-\[size\=default\]\:h-\[22px\][data-size=default]{height:22px}.data-\[size\=default\]\:w-\[44px\][data-size=default]{width:44px}.data-\[size\=default\]\:max-w-xs[data-size=default]{max-width:var(--container-xs)}.data-\[size\=lg\]\:size-10[data-size=lg]{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.data-\[size\=lg\]\:h-10[data-size=lg]{height:calc(var(--spacing) * 10)}.data-\[size\=lg\]\:p-2[data-size=lg]{padding:calc(var(--spacing) * 2)}.data-\[size\=lg\]\:text-base[data-size=lg]{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.data-\[size\=md\]\:text-sm[data-size=md]{font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}.data-\[size\=sm\]\:size-6[data-size=sm]{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.data-\[size\=sm\]\:h-4[data-size=sm]{height:calc(var(--spacing) * 4)}.data-\[size\=sm\]\:h-7[data-size=sm]{height:calc(var(--spacing) * 7)}.data-\[size\=sm\]\:w-7[data-size=sm]{width:calc(var(--spacing) * 7)}.data-\[size\=sm\]\:max-w-xs[data-size=sm]{max-width:var(--container-xs)}.data-\[size\=sm\]\:rounded-\[min\(var\(--radius-md\)\,10px\)\][data-size=sm]{border-radius:min(var(--radius-md), 10px)}.data-\[size\=sm\]\:py-0\.5[data-size=sm]{padding-block:calc(var(--spacing) * .5)}.data-\[size\=sm\]\:text-xs[data-size=sm]{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.data-\[size\=sm\]\:\[--card-spacing\:--spacing\(3\)\][data-size=sm]{--card-spacing:calc(var(--spacing) * 3)}.data-\[size\=sm\]\:has-data-\[slot\=card-footer\]\:pb-0[data-size=sm]:has([data-slot=card-footer]){padding-bottom:0}:is(.\*\:data-\[slot\=accordion-item\]\:rounded-xl>*)[data-slot=accordion-item]{border-radius:calc(var(--radius) * 1.3333)}:is(.\*\:data-\[slot\=accordion-item\]\:border>*)[data-slot=accordion-item]{border-style:var(--tw-border-style);border-width:1px}:is(.\*\:data-\[slot\=accordion-item\]\:px-4>*)[data-slot=accordion-item]{padding-inline:calc(var(--spacing) * 4)}:is(.\*\*\:data-\[slot\=accordion-trigger-icon\]\:ms-auto *)[data-slot=accordion-trigger-icon]{margin-inline-start:auto}:is(.\*\*\:data-\[slot\=accordion-trigger-icon\]\:size-4 *)[data-slot=accordion-trigger-icon]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}:is(.\*\*\:data-\[slot\=accordion-trigger-icon\]\:text-muted-foreground *)[data-slot=accordion-trigger-icon]{color:var(--muted-foreground)}:is(.\*\:data-\[slot\=alert-description\]\:text-destructive\/90>*)[data-slot=alert-description]{color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){:is(.\*\:data-\[slot\=alert-description\]\:text-destructive\/90>*)[data-slot=alert-description]{color:color-mix(in oklab, var(--destructive) 90%, transparent)}}:is(.\*\:data-\[slot\=alert-title\]\:text-destructive>*)[data-slot=alert-title]{color:var(--destructive)}:is(.\*\:data-\[slot\=avatar\]\:ring-2>*)[data-slot=avatar]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(.\*\:data-\[slot\=avatar\]\:ring-background>*)[data-slot=avatar]{--tw-ring-color:var(--background)}:is(.\*\:data-\[slot\=button\]\:w-full>*)[data-slot=button]{width:100%}:is(.\*\:data-\[slot\=card-footer\]\:border-t-0>*)[data-slot=card-footer]{border-top-style:var(--tw-border-style);border-top-width:0}:is(.\*\:data-\[slot\=card-footer\]\:bg-transparent>*)[data-slot=card-footer]{background-color:#0000}:is(.\*\:data-\[slot\=card-header\]\:min-h-0>*)[data-slot=card-header]{min-height:0}:is(.\*\:data-\[slot\=card-header\]\:border-b-0>*)[data-slot=card-header]{border-bottom-style:var(--tw-border-style);border-bottom-width:0}:is(.\*\:data-\[slot\=card-header\]\:py-0>*)[data-slot=card-header]{padding-block:0}.data-\[slot\=checkbox-group\]\:gap-3[data-slot=checkbox-group]{gap:calc(var(--spacing) * 3)}:is(.\*\:data-\[slot\=field\]\:p-2\.5>*)[data-slot=field]{padding:calc(var(--spacing) * 2.5)}:is(.\*\:data-\[slot\=field-group\]\:gap-4>*)[data-slot=field-group]{gap:calc(var(--spacing) * 4)}:is(.\*\:data-\[slot\=field-label\]\:flex-auto>*)[data-slot=field-label]{flex:auto}:is(.\*\:data-\[slot\=input-group-addon\]\:ps-2\!>*)[data-slot=input-group-addon]{padding-inline-start:calc(var(--spacing) * 2)!important}:is(.\*\*\:data-\[slot\=kbd\]\:relative *)[data-slot=kbd]{position:relative}:is(.\*\*\:data-\[slot\=kbd\]\:isolate *)[data-slot=kbd]{isolation:isolate}:is(.\*\*\:data-\[slot\=kbd\]\:z-50 *)[data-slot=kbd]{z-index:50}:is(.\*\*\:data-\[slot\=kbd\]\:rounded-sm *)[data-slot=kbd]{border-radius:calc(var(--radius) * .6667)}:is(.\*\*\:data-\[slot\=navigation-menu-link\]\:focus\:ring-0 *)[data-slot=navigation-menu-link]:focus{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(.\*\*\:data-\[slot\=navigation-menu-link\]\:focus\:outline-none *)[data-slot=navigation-menu-link]:focus{--tw-outline-style:none;outline-style:none}:is(.\*\:data-\[slot\=select-value\]\:line-clamp-1>*)[data-slot=select-value]{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}:is(.\*\:data-\[slot\=select-value\]\:flex>*)[data-slot=select-value]{display:flex}:is(.\*\:data-\[slot\=select-value\]\:items-center>*)[data-slot=select-value]{align-items:center}:is(.\*\:data-\[slot\=select-value\]\:gap-1\.5>*)[data-slot=select-value]{gap:calc(var(--spacing) * 1.5)}:is(.\*\:data-\[slot\=select-value\]\:pe-7>*)[data-slot=select-value]{padding-inline-end:calc(var(--spacing) * 7)}:is(:where(.group\/toggle-group):where([data-orientation=horizontal]) .group-data-horizontal\/toggle-group\:data-\[spacing\=0\]\:first\:rounded-s-lg)[data-spacing="0"]:first-child{border-start-start-radius:var(--radius);border-end-start-radius:var(--radius)}:is(:where(.group\/toggle-group):where([data-orientation=vertical]) .group-data-vertical\/toggle-group\:data-\[spacing\=0\]\:first\:rounded-t-lg)[data-spacing="0"]:first-child{border-top-left-radius:var(--radius);border-top-right-radius:var(--radius)}:is(:where(.group\/toggle-group):where([data-orientation=horizontal]) .group-data-horizontal\/toggle-group\:data-\[spacing\=0\]\:last\:rounded-e-lg)[data-spacing="0"]:last-child{border-start-end-radius:var(--radius);border-end-end-radius:var(--radius)}:is(:where(.group\/toggle-group):where([data-orientation=vertical]) .group-data-vertical\/toggle-group\:data-\[spacing\=0\]\:last\:rounded-b-lg)[data-spacing="0"]:last-child{border-bottom-right-radius:var(--radius);border-bottom-left-radius:var(--radius)}.data-\[state\=active\]\:bg-primary-subtle[data-state=active]{background-color:var(--primary-subtle)}.data-\[state\=active\]\:text-primary-subtle-foreground[data-state=active]{color:var(--primary-subtle-foreground)}.data-\[state\=checked\]\:border-primary[data-state=checked]{border-color:var(--primary)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:var(--primary)}.data-\[state\=checked\]\:bg-primary-1[data-state=checked]{background-color:var(--primary-1)}.data-\[state\=checked\]\:font-semibold[data-state=checked]{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:var(--primary-foreground)}.data-\[state\=checked\]\:ring-1[data-state=checked]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-\[state\=checked\]\:ring-primary[data-state=checked]{--tw-ring-color:var(--primary)}.data-\[state\=closed\]\:overflow-hidden[data-state=closed]{overflow:hidden}.data-\[state\=complete\]\:opacity-0[data-state=complete]{opacity:0}.data-\[state\=delayed-open\]\:animate-in[data-state=delayed-open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=delayed-open\]\:fade-in-0[data-state=delayed-open]{--tw-enter-opacity:0}.data-\[state\=delayed-open\]\:zoom-in-95[data-state=delayed-open]{--tw-enter-scale:.95}.data-\[state\=hidden\]\:animate-out[data-state=hidden]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=hidden\]\:fade-out[data-state=hidden]{--tw-exit-opacity:0}.data-\[state\=indeterminate\]\:border-primary[data-state=indeterminate]{border-color:var(--primary)}.data-\[state\=indeterminate\]\:bg-primary[data-state=indeterminate]{background-color:var(--primary)}.data-\[state\=indeterminate\]\:text-primary-foreground[data-state=indeterminate]{color:var(--primary-foreground)}.data-\[state\=on\]\:bg-background[data-state=on]{background-color:var(--background)}.data-\[state\=on\]\:bg-primary-1[data-state=on]{background-color:var(--primary-1)}.data-\[state\=on\]\:text-foreground[data-state=on]{color:var(--foreground)}.data-\[state\=on\]\:text-primary-7[data-state=on]{color:var(--primary-7)}.data-\[state\=on\]\:shadow-sm[data-state=on]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-\[state\=open\]\:border-primary[data-state=open]{border-color:var(--primary)}.data-\[state\=selected\]\:border-primary-3[data-state=selected]{border-color:var(--primary-3)}.data-\[state\=selected\]\:border-primary\/60[data-state=selected]{border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.data-\[state\=selected\]\:border-primary\/60[data-state=selected]{border-color:color-mix(in oklab, var(--primary) 60%, transparent)}}.data-\[state\=selected\]\:bg-primary-1[data-state=selected]{background-color:var(--primary-1)}.data-\[state\=selected\]\:bg-primary\/5[data-state=selected]{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.data-\[state\=selected\]\:bg-primary\/5[data-state=selected]{background-color:color-mix(in oklab, var(--primary) 5%, transparent)}}.data-\[state\=selected\]\:ring-2[data-state=selected]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-\[state\=selected\]\:ring-primary\/20[data-state=selected]{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.data-\[state\=selected\]\:ring-primary\/20[data-state=selected]{--tw-ring-color:color-mix(in oklab, var(--primary) 20%, transparent)}}@media (hover:hover){.data-\[state\=selected\]\:hover\:bg-primary-2[data-state=selected]:hover{background-color:var(--primary-2)}}.data-\[state\=visible\]\:animate-in[data-state=visible]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=visible\]\:fade-in[data-state=visible]{--tw-enter-opacity:0}.data-\[status\=complete\]\:border-primary[data-status=complete]{border-color:var(--primary)}.data-\[status\=complete\]\:text-primary[data-status=complete]{color:var(--primary)}.data-\[status\=current\]\:border-primary[data-status=current]{border-color:var(--primary)}.data-\[status\=current\]\:bg-primary[data-status=current]{background-color:var(--primary)}.data-\[status\=current\]\:text-primary-foreground[data-status=current]{color:var(--primary-foreground)}.data-\[status\=error\]\:border-destructive[data-status=error]{border-color:var(--destructive)}.data-\[status\=error\]\:text-destructive[data-status=error]{color:var(--destructive)}.data-\[status\=upcoming\]\:border-border[data-status=upcoming]{border-color:var(--border)}.data-\[status\=upcoming\]\:text-muted-foreground[data-status=upcoming]{color:var(--muted-foreground)}.data-\[variant\=destructive\]\:text-destructive[data-variant=destructive]{color:var(--destructive)}.data-\[variant\=destructive\]\:focus\:bg-destructive\/10[data-variant=destructive]:focus{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.data-\[variant\=destructive\]\:focus\:bg-destructive\/10[data-variant=destructive]:focus{background-color:color-mix(in oklab, var(--destructive) 10%, transparent)}}.data-\[variant\=destructive\]\:focus\:text-destructive[data-variant=destructive]:focus{color:var(--destructive)}.data-\[variant\=label\]\:text-sm[data-variant=label]{font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}.data-\[variant\=legend\]\:text-base[data-variant=legend]{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.data-\[variant\=line\]\:rounded-none[data-variant=line]{border-radius:0}:is(:where(.group\/toggle-group):where([data-orientation=horizontal]) .group-data-horizontal\/toggle-group\:data-\[spacing\=0\]\:data-\[variant\=outline\]\:border-s-0)[data-spacing="0"][data-variant=outline]{border-inline-start-style:var(--tw-border-style);border-inline-start-width:0}:is(:where(.group\/toggle-group):where([data-orientation=vertical]) .group-data-vertical\/toggle-group\:data-\[spacing\=0\]\:data-\[variant\=outline\]\:border-t-0)[data-spacing="0"][data-variant=outline]{border-top-style:var(--tw-border-style);border-top-width:0}:is(:where(.group\/toggle-group):where([data-orientation=horizontal]) .group-data-horizontal\/toggle-group\:data-\[spacing\=0\]\:data-\[variant\=outline\]\:first\:border-s)[data-spacing="0"][data-variant=outline]:first-child{border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}:is(:where(.group\/toggle-group):where([data-orientation=vertical]) .group-data-vertical\/toggle-group\:data-\[spacing\=0\]\:data-\[variant\=outline\]\:first\:border-t)[data-spacing="0"][data-variant=outline]:first-child{border-top-style:var(--tw-border-style);border-top-width:1px}.data-\[vaul-drawer-direction\=bottom\]\:inset-x-0[data-vaul-drawer-direction=bottom]{inset-inline:0}.data-\[vaul-drawer-direction\=bottom\]\:bottom-0[data-vaul-drawer-direction=bottom]{bottom:0}.data-\[vaul-drawer-direction\=bottom\]\:mt-24[data-vaul-drawer-direction=bottom]{margin-top:calc(var(--spacing) * 24)}.data-\[vaul-drawer-direction\=bottom\]\:max-h-\[80vh\][data-vaul-drawer-direction=bottom]{max-height:80vh}.data-\[vaul-drawer-direction\=bottom\]\:rounded-t-xl[data-vaul-drawer-direction=bottom]{border-top-left-radius:calc(var(--radius) * 1.3333);border-top-right-radius:calc(var(--radius) * 1.3333)}.data-\[vaul-drawer-direction\=bottom\]\:border-t[data-vaul-drawer-direction=bottom]{border-top-style:var(--tw-border-style);border-top-width:1px}.data-\[vaul-drawer-direction\=left\]\:inset-y-0[data-vaul-drawer-direction=left]{inset-block:0}.data-\[vaul-drawer-direction\=left\]\:start-0[data-vaul-drawer-direction=left]{inset-inline-start:calc(var(--spacing) * 0)}.data-\[vaul-drawer-direction\=left\]\:w-3\/4[data-vaul-drawer-direction=left]{width:75%}.data-\[vaul-drawer-direction\=left\]\:rounded-e-xl[data-vaul-drawer-direction=left]{border-start-end-radius:calc(var(--radius) * 1.3333);border-end-end-radius:calc(var(--radius) * 1.3333)}.data-\[vaul-drawer-direction\=left\]\:border-e[data-vaul-drawer-direction=left]{border-inline-end-style:var(--tw-border-style);border-inline-end-width:1px}.data-\[vaul-drawer-direction\=right\]\:inset-y-0[data-vaul-drawer-direction=right]{inset-block:0}.data-\[vaul-drawer-direction\=right\]\:end-0[data-vaul-drawer-direction=right]{inset-inline-end:calc(var(--spacing) * 0)}.data-\[vaul-drawer-direction\=right\]\:w-3\/4[data-vaul-drawer-direction=right]{width:75%}.data-\[vaul-drawer-direction\=right\]\:rounded-s-xl[data-vaul-drawer-direction=right]{border-start-start-radius:calc(var(--radius) * 1.3333);border-end-start-radius:calc(var(--radius) * 1.3333)}.data-\[vaul-drawer-direction\=right\]\:border-s[data-vaul-drawer-direction=right]{border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}.data-\[vaul-drawer-direction\=top\]\:inset-x-0[data-vaul-drawer-direction=top]{inset-inline:0}.data-\[vaul-drawer-direction\=top\]\:top-0[data-vaul-drawer-direction=top]{top:0}.data-\[vaul-drawer-direction\=top\]\:mb-24[data-vaul-drawer-direction=top]{margin-bottom:calc(var(--spacing) * 24)}.data-\[vaul-drawer-direction\=top\]\:max-h-\[80vh\][data-vaul-drawer-direction=top]{max-height:80vh}.data-\[vaul-drawer-direction\=top\]\:rounded-b-xl[data-vaul-drawer-direction=top]{border-bottom-right-radius:calc(var(--radius) * 1.3333);border-bottom-left-radius:calc(var(--radius) * 1.3333)}.data-\[vaul-drawer-direction\=top\]\:border-b[data-vaul-drawer-direction=top]{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.nth-last-2\:-mt-1:nth-last-child(2){margin-top:calc(var(--spacing) * -1)}@supports ((-webkit-backdrop-filter:var(--tw)) or (backdrop-filter:var(--tw))){.supports-backdrop-filter\:bg-background\/80{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.supports-backdrop-filter\:bg-background\/80{background-color:color-mix(in oklab, var(--background) 80%, transparent)}}.supports-backdrop-filter\:bg-primary{background-color:var(--primary)}.supports-backdrop-filter\:bg-shell{background-color:var(--shell)}.supports-backdrop-filter\:backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, )}.supports-backdrop-filter\:backdrop-blur-none{--tw-backdrop-blur: ;-webkit-backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, )}.supports-backdrop-filter\:backdrop-blur-xs{--tw-backdrop-blur:blur(var(--blur-xs));-webkit-backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, );backdrop-filter:var(--tw-backdrop-blur, ) var(--tw-backdrop-brightness, ) var(--tw-backdrop-contrast, ) var(--tw-backdrop-grayscale, ) var(--tw-backdrop-hue-rotate, ) var(--tw-backdrop-invert, ) var(--tw-backdrop-opacity, ) var(--tw-backdrop-saturate, ) var(--tw-backdrop-sepia, )}}@media (prefers-reduced-motion:no-preference){.motion-safe\:animate-in{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.motion-safe\:fade-in-0{--tw-enter-opacity:0}.motion-safe\:zoom-in-95{--tw-enter-scale:.95}}@media (prefers-reduced-motion:reduce){.motion-reduce\:animate-none{animation:none}.motion-reduce\:transition-none{transition-property:none}}@media not all and (min-width:40rem){.max-sm\:sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}:is(:where(.group\/modal)[data-mobile=fullscreen] .group-data-\[mobile\=fullscreen\]\/modal\:max-sm\:pt-\[max\(1rem\,env\(safe-area-inset-top\)\)\]){padding-top:max(1rem, env(safe-area-inset-top))}:is(:where(.group\/modal)[data-mobile=fullscreen] .group-data-\[mobile\=fullscreen\]\/modal\:max-sm\:pb-\[max\(0\.75rem\,env\(safe-area-inset-bottom\)\)\]),:is(:where(.group\/modal)[data-mobile=sheet] .group-data-\[mobile\=sheet\]\/modal\:max-sm\:pb-\[max\(0\.75rem\,env\(safe-area-inset-bottom\)\)\]){padding-bottom:max(.75rem, env(safe-area-inset-bottom))}}@media (min-width:40rem){.sm\:inset-auto{inset:auto}.sm\:inset-x-auto{inset-inline:auto}.sm\:start-1\/2{inset-inline-start:50%}.sm\:end-6{inset-inline-end:calc(var(--spacing) * 6)}.sm\:top-1\/2{top:50%}.sm\:top-\[12vh\]{top:12vh}.sm\:block{display:block}.sm\:flex{display:flex}.sm\:hidden{display:none}.sm\:inline{display:inline}.sm\:h-80{height:calc(var(--spacing) * 80)}.sm\:h-\[calc\(100dvh-2rem\)\]{height:calc(100dvh - 2rem)}.sm\:h-auto{height:auto}.sm\:max-h-\[calc\(100dvh-2rem\)\]{max-height:calc(100dvh - 2rem)}.sm\:max-h-\[min\(24rem\,60dvh\)\]{max-height:min(24rem,60dvh)}.sm\:w-64{width:calc(var(--spacing) * 64)}.sm\:w-72{width:calc(var(--spacing) * 72)}.sm\:w-\[calc\(100\%-2rem\)\]{width:calc(100% - 2rem)}.sm\:w-auto{width:auto}.sm\:max-w-2xl{max-width:var(--container-2xl)}.sm\:max-w-3xl{max-width:var(--container-3xl)}.sm\:max-w-4xl{max-width:var(--container-4xl)}.sm\:max-w-\[calc\(100\%-2rem\)\]{max-width:calc(100% - 2rem)}.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:max-w-md{max-width:var(--container-md)}.sm\:max-w-sm{max-width:var(--container-sm)}.sm\:max-w-xs{max-width:var(--container-xs)}.sm\:flex-none{flex:none}.sm\:-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.sm\:-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.sm\:translate-y-0{--tw-translate-y:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}.sm\:snap-none{scroll-snap-type:none}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-\[5rem_minmax\(0\,1fr\)\]{grid-template-columns:5rem minmax(0,1fr)}.sm\:flex-row{flex-direction:row}.sm\:flex-wrap{flex-wrap:wrap}.sm\:justify-center{justify-content:center}.sm\:justify-end{justify-content:flex-end}.sm\:gap-0{gap:0}.sm\:rounded-xl{border-radius:calc(var(--radius) * 1.3333)}.sm\:p-6{padding:calc(var(--spacing) * 6)}.sm\:px-6{padding-inline:calc(var(--spacing) * 6)}.sm\:px-8{padding-inline:calc(var(--spacing) * 8)}.sm\:pe-2{padding-inline-end:calc(var(--spacing) * 2)}.sm\:pt-0{padding-top:0}.sm\:text-end{text-align:end}.sm\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.sm\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}:is(:where(.group\/alert-dialog-content)[data-size=default] .sm\:group-data-\[size\=default\]\/alert-dialog-content\:row-span-2){grid-row:span 2/span 2}:is(:where(.group\/alert-dialog-content)[data-size=default] .sm\:group-data-\[size\=default\]\/alert-dialog-content\:place-items-start){place-items:start}:is(:where(.group\/alert-dialog-content)[data-size=default] .sm\:group-data-\[size\=default\]\/alert-dialog-content\:text-start){text-align:start}:is(:where(.group\/alert-dialog-content):has([data-slot=alert-dialog-media]) :is(:where(.group\/alert-dialog-content)[data-size=default] .sm\:group-data-\[size\=default\]\/alert-dialog-content\:group-has-data-\[slot\=alert-dialog-media\]\/alert-dialog-content\:col-start-2)){grid-column-start:2}.sm\:after\:ms-0\.5:after{content:var(--tw-content);margin-inline-start:calc(var(--spacing) * .5)}.sm\:after\:content-\[\'\:\'\]:after{--tw-content:":";content:var(--tw-content)}.sm\:last\:pe-0:last-child{padding-inline-end:0}:is(:where(.group\/alert-dialog-content)[data-size=default] .sm\:group-data-\[size\=default\]\/alert-dialog-content\:has-data-\[slot\=alert-dialog-media\]\:grid-rows-\[auto_1fr\]):has([data-slot=alert-dialog-media]){grid-template-rows:auto 1fr}.data-\[side\=left\]\:sm\:max-w-3xl[data-side=left]{max-width:var(--container-3xl)}.data-\[side\=left\]\:sm\:max-w-md[data-side=left]{max-width:var(--container-md)}.data-\[side\=left\]\:sm\:max-w-none[data-side=left]{max-width:none}.data-\[side\=left\]\:sm\:max-w-sm[data-side=left]{max-width:var(--container-sm)}.data-\[side\=left\]\:sm\:max-w-xl[data-side=left]{max-width:var(--container-xl)}.data-\[side\=right\]\:sm\:max-w-3xl[data-side=right]{max-width:var(--container-3xl)}.data-\[side\=right\]\:sm\:max-w-md[data-side=right]{max-width:var(--container-md)}.data-\[side\=right\]\:sm\:max-w-none[data-side=right]{max-width:none}.data-\[side\=right\]\:sm\:max-w-sm[data-side=right]{max-width:var(--container-sm)}.data-\[side\=right\]\:sm\:max-w-xl[data-side=right]{max-width:var(--container-xl)}.data-\[size\=default\]\:sm\:max-w-sm[data-size=default],.data-\[vaul-drawer-direction\=left\]\:sm\:max-w-sm[data-vaul-drawer-direction=left],.data-\[vaul-drawer-direction\=right\]\:sm\:max-w-sm[data-vaul-drawer-direction=right]{max-width:var(--container-sm)}}@media (min-width:48rem){.md\:absolute{position:absolute}.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:w-\(--radix-navigation-menu-viewport-width\){width:var(--radix-navigation-menu-viewport-width)}.md\:w-64{width:calc(var(--spacing) * 64)}.md\:w-auto{width:auto}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:gap-0\.5{gap:calc(var(--spacing) * .5)}.md\:rounded-ss-\[12px\]{border-start-start-radius:12px}.md\:border-s{border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}.md\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.md\:p-6{padding:calc(var(--spacing) * 6)}.md\:pb-6{padding-bottom:calc(var(--spacing) * 6)}.md\:text-start{text-align:start}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}.md\:text-pretty{text-wrap:pretty}.md\:opacity-0{opacity:0}:is(:where(.peer)[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:m-2){margin:calc(var(--spacing) * 2)}:is(:where(.peer)[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:ms-0){margin-inline-start:0}:is(:where(.peer)[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:rounded-xl){border-radius:calc(var(--radius) * 1.3333)}:is(:where(.peer)[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:shadow-sm){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.peer)[data-state=collapsed]~:is(:where(.peer)[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:peer-data-\[state\=collapsed\]\:ms-2)){margin-inline-start:calc(var(--spacing) * 2)}.md\:after\:hidden:after{content:var(--tw-content);display:none}}@media (min-width:64rem){.lg\:sticky{position:sticky}.lg\:inset-auto{inset:auto}.lg\:top-4{top:calc(var(--spacing) * 4)}.lg\:z-auto{z-index:auto}.lg\:order-1{order:1}.lg\:order-2{order:2}.lg\:block{display:block}.lg\:grid{display:grid}.lg\:hidden{display:none}.lg\:max-h-none{max-height:none}.lg\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-\[minmax\(0\,1fr\)_14rem\]{grid-template-columns:minmax(0,1fr) 14rem}.lg\:rounded-xl{border-radius:calc(var(--radius) * 1.3333)}.lg\:border{border-style:var(--tw-border-style);border-width:1px}.lg\:bg-card{background-color:var(--card)}.lg\:p-4{padding:calc(var(--spacing) * 4)}.lg\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}}@container not (min-width:24rem){.\@max-sm\:hidden{display:none}}@container coords (min-width:16rem){.\@\[16rem\]\/coords\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@container stat-tile (min-width:17rem){.\@\[17rem\]\/stat-tile\:text-\[1\.875rem\]{font-size:1.875rem}.\@\[17rem\]\/stat-tile\:leading-\[2\.375rem\]{--tw-leading:2.375rem;line-height:2.375rem}}@container (min-width:20rem){.\@xs\:ms-auto{margin-inline-start:auto}.\@xs\:flex{display:flex}.\@xs\:grid-cols-\[7rem_minmax\(0\,1fr\)\]{grid-template-columns:7rem minmax(0,1fr)}.\@xs\:flex-wrap{flex-wrap:wrap}.\@xs\:items-center{align-items:center}}@container stat-tile (min-width:20rem){.\@\[20rem\]\/stat-tile\:text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}}@container (min-width:24rem){.\@sm\:inline{display:inline}}@container date-range (min-width:24rem){.\@sm\/date-range\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@container media (min-width:24rem){.\@sm\/media\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@container card (min-width:24rem){.\@sm\/card\:flex-row{flex-direction:row}.\@sm\/card\:items-center{align-items:center}.\@sm\/card\:justify-end{justify-content:flex-end}:is(.\@sm\/card\:\*\:data-\[slot\=button\]\:w-auto>*)[data-slot=button]{width:auto}}@container form-field (min-width:28rem){.\@md\/form-field\:col-start-2{grid-column-start:2}}@container live-map (min-width:28rem){.\@md\/live-map\:inline{display:inline}}@container replay (min-width:28rem){.\@md\/replay\:inline{display:inline}}@container skeleton-table (min-width:28rem){.\@md\/skeleton-table\:block{display:block}}@container (min-width:28rem){.\@md\:flex{display:flex}.\@md\:hidden{display:none}.\@md\:list-item{display:list-item}}@container location-card (min-width:28rem){.\@md\/location-card\:aspect-auto{aspect-ratio:auto}}@container form-field (min-width:28rem){.\@md\/form-field\:h-8{height:calc(var(--spacing) * 8)}.\@md\/form-field\:min-h-8{min-height:calc(var(--spacing) * 8)}}@container location-card (min-width:28rem){.\@md\/location-card\:w-2\/5{width:40%}}@container gallery (min-width:28rem){.\@md\/gallery\:columns-3{columns:3}}@container attachments (min-width:28rem){.\@md\/attachments\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@container attributes (min-width:28rem){.\@md\/attributes\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@container form-field (min-width:28rem){.\@md\/form-field\:grid-cols-\[var\(--onu-label-width\)_minmax\(0\,1fr\)\]{grid-template-columns:var(--onu-label-width) minmax(0,1fr)}}@container gallery (min-width:28rem){.\@md\/gallery\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@container stat-tiles (min-width:28rem){.\@md\/stat-tiles\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@container (min-width:28rem){.\@md\:grid-cols-\[minmax\(0\,var\(--onu-dl-label-width\,12rem\)\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,var(--onu-dl-label-width,12rem)) minmax(0,1fr)}}@container field-group (min-width:28rem){.\@md\/field-group\:flex-row{flex-direction:row}}@container location-card (min-width:28rem){.\@md\/location-card\:flex-row{flex-direction:row}}@container map-picker (min-width:28rem){.\@md\/map-picker\:flex-row{flex-direction:row}}@container field-group (min-width:28rem){.\@md\/field-group\:items-center{align-items:center}}@container form-field (min-width:28rem){.\@md\/form-field\:items-start{align-items:flex-start}.\@md\/form-field\:gap-x-4{column-gap:calc(var(--spacing) * 4)}.\@md\/form-field\:pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}}@container field-group (min-width:28rem){:is(.\@md\/field-group\:\*\:w-auto>*){width:auto}.\@md\/field-group\:has-\[\>\[data-slot\=field-content\]\]\:items-start:has(>[data-slot=field-content]){align-items:flex-start}:is(.\@md\/field-group\:\*\:data-\[slot\=field-label\]\:flex-auto>*)[data-slot=field-label]{flex:auto}}@container (min-width:32rem){.\@lg\:aspect-auto{aspect-ratio:auto}.\@lg\:w-2\/5{width:40%}}@container section (min-width:32rem){.\@lg\/section\:shrink-0{flex-shrink:0}}@container (min-width:32rem){.\@lg\:shrink-0{flex-shrink:0}}@container address (min-width:32rem){.\@lg\/address\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@container map-radius (min-width:32rem){.\@lg\/map-radius\:grid-cols-\[minmax\(0\,2fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,2fr) minmax(0,1fr)}}@container media (min-width:32rem){.\@lg\/media\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@container repeating-group (min-width:32rem){.\@lg\/repeating-group\:grid-cols-\[minmax\(0\,1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.\@lg\/repeating-group\:flex-col{flex-direction:column}}@container section (min-width:32rem){.\@lg\/section\:flex-row{flex-direction:row}}@container (min-width:32rem){.\@lg\:flex-row{flex-direction:row}}@container repeating-group (min-width:32rem){.\@lg\/repeating-group\:items-start{align-items:flex-start}}@container section (min-width:32rem){.\@lg\/section\:items-start{align-items:flex-start}}@container repeating-group (min-width:32rem){.\@lg\/repeating-group\:justify-start{justify-content:flex-start}}@container dual-listbox (min-width:36rem){.\@xl\/dual-listbox\:block{display:block}.\@xl\/dual-listbox\:hidden{display:none}}@container editor (min-width:36rem){.\@xl\/editor\:block{display:block}.\@xl\/editor\:hidden{display:none}.\@xl\/editor\:inline-flex{display:inline-flex}}@container attributes (min-width:36rem){.\@xl\/attributes\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@container dual-listbox (min-width:36rem){.\@xl\/dual-listbox\:grid-cols-\[minmax\(0\,1fr\)_auto_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1fr) auto minmax(0,1fr)}}@container features (min-width:36rem){.\@xl\/features\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@container form-group (min-width:36rem){.\@xl\/form-group\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@container dual-listbox (min-width:36rem){.\@xl\/dual-listbox\:flex-col{flex-direction:column}}@container page-title (min-width:36rem){.\@xl\/page-title\:flex-row{flex-direction:row}.\@xl\/page-title\:items-start{align-items:flex-start}}@container features (min-width:36rem){.\@xl\/features\:gap-6{gap:calc(var(--spacing) * 6)}}@container full-calendar (min-width:42rem){.\@2xl\/full-calendar\:order-none{order:0}}@container stacked-tabs (min-width:42rem){.\@2xl\/stacked-tabs\:block{display:block}.\@2xl\/stacked-tabs\:flex{display:flex}.\@2xl\/stacked-tabs\:grid{display:grid}.\@2xl\/stacked-tabs\:hidden{display:none}}@container translations (min-width:42rem){.\@2xl\/translations\:grid{display:grid}.\@2xl\/translations\:hidden{display:none}}@container wizard (min-width:42rem){.\@2xl\/wizard\:block{display:block}.\@2xl\/wizard\:grid{display:grid}.\@2xl\/wizard\:hidden{display:none}}@container full-calendar (min-width:42rem){.\@2xl\/full-calendar\:w-auto{width:auto}}@container gallery (min-width:42rem){.\@2xl\/gallery\:columns-4{columns:4}}@container attributes (min-width:42rem){.\@2xl\/attributes\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@container footer (min-width:42rem){.\@2xl\/footer\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@container gallery (min-width:42rem){.\@2xl\/gallery\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@container shape-editor (min-width:42rem){.\@2xl\/shape-editor\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@container stacked-tabs (min-width:42rem){.\@2xl\/stacked-tabs\:grid-cols-\[minmax\(11rem\,15rem\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(11rem,15rem) minmax(0,1fr)}}@container translations (min-width:42rem){.\@2xl\/translations\:grid-cols-\(--onu-translation-cols\){grid-template-columns:var(--onu-translation-cols)}}@container wizard (min-width:42rem){.\@2xl\/wizard\:grid-cols-\[minmax\(12rem\,16rem\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(12rem,16rem) minmax(0,1fr)}}@container footer (min-width:42rem){.\@2xl\/footer\:flex-row{flex-direction:row}}@container stacked-tabs (min-width:42rem){.\@2xl\/stacked-tabs\:flex-col{flex-direction:column}}@container full-calendar (min-width:42rem){.\@2xl\/full-calendar\:flex-nowrap{flex-wrap:nowrap}}@container translations (min-width:42rem){.\@2xl\/translations\:flex-nowrap{flex-wrap:nowrap}}@container footer (min-width:42rem){.\@2xl\/footer\:items-center{align-items:center}}@container stacked-tabs (min-width:42rem){.\@2xl\/stacked-tabs\:gap-8{gap:calc(var(--spacing) * 8)}}@container translations (min-width:42rem){.\@2xl\/translations\:gap-4{gap:calc(var(--spacing) * 4)}}@container wizard (min-width:42rem){.\@2xl\/wizard\:gap-10{gap:calc(var(--spacing) * 10)}}@container stacked-tabs (min-width:42rem){.\@2xl\/stacked-tabs\:overflow-visible{overflow:visible}}@container translations (min-width:42rem){.\@2xl\/translations\:py-3{padding-block:calc(var(--spacing) * 3)}.\@2xl\/translations\:pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}}@container stacked-tabs (min-width:42rem){.\@2xl\/stacked-tabs\:whitespace-normal{white-space:normal}}@container stops (min-width:48rem){.\@3xl\/stops\:h-full{height:100%}.\@3xl\/stops\:min-h-96{min-height:calc(var(--spacing) * 96)}}@container footer (min-width:48rem){.\@3xl\/footer\:grid-cols-\[minmax\(0\,18rem\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,18rem) minmax(0,1fr)}}@container media (min-width:48rem){.\@3xl\/media\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}}@container stat-tiles (min-width:48rem){.\@3xl\/stat-tiles\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@container stops (min-width:48rem){.\@3xl\/stops\:grid-cols-\[minmax\(0\,3fr\)_minmax\(18rem\,2fr\)\]{grid-template-columns:minmax(0,3fr) minmax(18rem,2fr)}}@container hero (min-width:48rem){.\@3xl\/hero\:py-14{padding-block:calc(var(--spacing) * 14)}.\@3xl\/hero\:py-20{padding-block:calc(var(--spacing) * 20)}.\@3xl\/hero\:py-28{padding-block:calc(var(--spacing) * 28)}}@container features (min-width:56rem){.\@4xl\/features\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@container form-group (min-width:56rem){.\@4xl\/form-group\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.\@4xl\/form-group\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@container hero (min-width:56rem){.\@4xl\/hero\:grid-cols-\[minmax\(0\,1\.1fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr)}}@container stat-tiles (min-width:56rem){.\@4xl\/stat-tiles\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@container hero (min-width:56rem){.\@4xl\/hero\:gap-12{gap:calc(var(--spacing) * 12)}}@container features (min-width:72rem){.\@6xl\/features\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}.ltr\:-translate-x-1\/2:where(:dir(ltr),[dir=ltr],[dir=ltr] *),.rtl\:-translate-x-1\/2:where(:dir(rtl),[dir=rtl],[dir=rtl] *){--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.rtl\:-translate-x-px:where(:dir(rtl),[dir=rtl],[dir=rtl] *){--tw-translate-x:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.rtl\:translate-x-1\/2:where(:dir(rtl),[dir=rtl],[dir=rtl] *){--tw-translate-x:calc(1 / 2 * 100%);translate:var(--tw-translate-x) var(--tw-translate-y)}.rtl\:translate-x-px:where(:dir(rtl),[dir=rtl],[dir=rtl] *){--tw-translate-x:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.rtl\:-scale-x-100:where(:dir(rtl),[dir=rtl],[dir=rtl] *){--tw-scale-x:calc(100% * -1);scale:var(--tw-scale-x) var(--tw-scale-y)}.rtl\:-rotate-90:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:-90deg}.rtl\:rotate-180:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:180deg}.rtl\:\[clip-path\:inset\(0_0_0_50\%\)\]:where(:dir(rtl),[dir=rtl],[dir=rtl] *){clip-path:inset(0 0 0 50%)}:is(:where(.group)[data-collapsible=offcanvas] .rtl\:group-data-\[collapsible\=offcanvas\]\:-translate-x-0:where(:dir(rtl),[dir=rtl],[dir=rtl] *)){--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}:where([data-side=left]) .rtl\:in-data-\[side\=left\]\:cursor-e-resize:where(:dir(rtl),[dir=rtl],[dir=rtl] *){cursor:e-resize}:where([data-side=right]) .rtl\:in-data-\[side\=right\]\:cursor-w-resize:where(:dir(rtl),[dir=rtl],[dir=rtl] *){cursor:w-resize}.rtl\:data-\[side\=left\]\:translate-x-1:where(:dir(rtl),[dir=rtl],[dir=rtl] *)[data-side=left]{--tw-translate-x:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.rtl\:data-\[side\=right\]\:-translate-x-1:where(:dir(rtl),[dir=rtl],[dir=rtl] *)[data-side=right]{--tw-translate-x:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}@media (min-width:40rem){.sm\:rtl\:translate-x-1\/2:where(:dir(rtl),[dir=rtl],[dir=rtl] *){--tw-translate-x:calc(1 / 2 * 100%);translate:var(--tw-translate-x) var(--tw-translate-y)}}.dark\:block:is(.dark *,[data-theme=dark] *){display:block}.dark\:hidden:is(.dark *,[data-theme=dark] *){display:none}.dark\:bg-destructive:is(.dark *,[data-theme=dark] *),.dark\:bg-destructive\/20:is(.dark *,[data-theme=dark] *){background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-destructive\/20:is(.dark *,[data-theme=dark] *){background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.dark\:bg-foreground:is(.dark *,[data-theme=dark] *){background-color:var(--foreground)}.dark\:bg-input\/30:is(.dark *,[data-theme=dark] *){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-input\/30:is(.dark *,[data-theme=dark] *){background-color:color-mix(in oklab, var(--input) 30%, transparent)}}.dark\:bg-transparent:is(.dark *,[data-theme=dark] *){background-color:#0000}.dark\:from-background\/80:is(.dark *,[data-theme=dark] *){--tw-gradient-from:var(--background)}@supports (color:color-mix(in lab, red, red)){.dark\:from-background\/80:is(.dark *,[data-theme=dark] *){--tw-gradient-from:color-mix(in oklab, var(--background) 80%, transparent)}}.dark\:from-background\/80:is(.dark *,[data-theme=dark] *){--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.dark\:text-\(--shiki-dark\):is(.dark *,[data-theme=dark] *){color:var(--shiki-dark)}.dark\:text-background:is(.dark *,[data-theme=dark] *){color:var(--background)}.dark\:text-foreground:is(.dark *,[data-theme=dark] *){color:var(--foreground)}.dark\:text-muted-foreground:is(.dark *,[data-theme=dark] *){color:var(--muted-foreground)}.dark\:text-primary-7:is(.dark *,[data-theme=dark] *){color:var(--primary-7)}.dark\:text-success:is(.dark *,[data-theme=dark] *){color:var(--success)}.dark\:text-warning:is(.dark *,[data-theme=dark] *){color:var(--warning)}:is(:where(.group\/checkbox)[data-state=unchecked] .dark\:group-data-\[state\=unchecked\]\/checkbox\:bg-input\/30:is(.dark *,[data-theme=dark] *)){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){:is(:where(.group\/checkbox)[data-state=unchecked] .dark\:group-data-\[state\=unchecked\]\/checkbox\:bg-input\/30:is(.dark *,[data-theme=dark] *)){background-color:color-mix(in oklab, var(--input) 30%, transparent)}}:is(:where(.group\/tabs-list)[data-variant=line] .dark\:group-data-\[variant\=line\]\/tabs-list\:text-foreground:is(.dark *,[data-theme=dark] *)){color:var(--foreground)}.dark\:after\:mix-blend-lighten:is(.dark *,[data-theme=dark] *):after{content:var(--tw-content);mix-blend-mode:lighten}.dark\:checked\:bg-primary:is(.dark *,[data-theme=dark] *):checked{background-color:var(--primary)}@media (hover:hover){.dark\:hover\:bg-muted\/50:is(.dark *,[data-theme=dark] *):hover{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-muted\/50:is(.dark *,[data-theme=dark] *):hover{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.dark\:hover\:text-foreground:is(.dark *,[data-theme=dark] *):hover{color:var(--foreground)}:is(:where(.group\/tabs-list)[data-variant=line] .dark\:group-data-\[variant\=line\]\/tabs-list\:hover\:text-primary-7:is(.dark *,[data-theme=dark] *)):hover{color:var(--primary-7)}}.dark\:focus-visible\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:focus-visible\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:disabled\:bg-input\/80:is(.dark *,[data-theme=dark] *):disabled{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:disabled\:bg-input\/80:is(.dark *,[data-theme=dark] *):disabled{background-color:color-mix(in oklab, var(--input) 80%, transparent)}}.dark\:disabled\:bg-transparent:is(.dark *,[data-theme=dark] *):disabled{background-color:#0000}:where([data-slot=tooltip-content]) .dark\:in-data-\[slot\=tooltip-content\]\:bg-background\/10:is(.dark *,[data-theme=dark] *){background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){:where([data-slot=tooltip-content]) .dark\:in-data-\[slot\=tooltip-content\]\:bg-background\/10:is(.dark *,[data-theme=dark] *){background-color:color-mix(in oklab, var(--background) 10%, transparent)}}.dark\:has-disabled\:bg-input\/80:is(.dark *,[data-theme=dark] *):has(:disabled){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:has-disabled\:bg-input\/80:is(.dark *,[data-theme=dark] *):has(:disabled){background-color:color-mix(in oklab, var(--input) 80%, transparent)}}.dark\:has-aria-invalid\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):has([aria-invalid=true]){--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:has-aria-invalid\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):has([aria-invalid=true]){--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:has-data-checked\:border-primary\/20:is(.dark *,[data-theme=dark] *):has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark\:has-data-checked\:border-primary\/20:is(.dark *,[data-theme=dark] *):has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){border-color:color-mix(in oklab, var(--primary) 20%, transparent)}}.dark\:has-data-checked\:bg-primary\/10:is(.dark *,[data-theme=dark] *):has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark\:has-data-checked\:bg-primary\/10:is(.dark *,[data-theme=dark] *):has(:where([data-state=checked]),:where([data-checked]:not([data-checked=false]))){background-color:color-mix(in oklab, var(--primary) 10%, transparent)}}.dark\:has-\[\[data-slot\=choice-trigger\]\[aria-invalid\=true\]\]\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):has([data-slot=choice-trigger][aria-invalid=true]){--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:has-\[\[data-slot\=choice-trigger\]\[aria-invalid\=true\]\]\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):has([data-slot=choice-trigger][aria-invalid=true]){--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:has-\[\[data-slot\]\[aria-invalid\=true\]\]\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):has([data-slot][aria-invalid=true]){--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:has-\[\[data-slot\]\[aria-invalid\=true\]\]\:ring-destructive\/40:is(.dark *,[data-theme=dark] *):has([data-slot][aria-invalid=true]){--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:aria-invalid\:border-destructive\/50:is(.dark *,[data-theme=dark] *)[aria-invalid=true]{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:aria-invalid\:border-destructive\/50:is(.dark *,[data-theme=dark] *)[aria-invalid=true]{border-color:color-mix(in oklab, var(--destructive) 50%, transparent)}}.dark\:aria-invalid\:ring-destructive\/40:is(.dark *,[data-theme=dark] *)[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:aria-invalid\:ring-destructive\/40:is(.dark *,[data-theme=dark] *)[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:data-invalid\:ring-destructive\/40:is(.dark *,[data-theme=dark] *)[data-invalid]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:data-invalid\:ring-destructive\/40:is(.dark *,[data-theme=dark] *)[data-invalid]{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:data-\[active\=true\]\:aria-invalid\:ring-destructive\/40:is(.dark *,[data-theme=dark] *)[data-active=true][aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:data-\[active\=true\]\:aria-invalid\:ring-destructive\/40:is(.dark *,[data-theme=dark] *)[data-active=true][aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:data-\[state\=checked\]\:bg-primary:is(.dark *,[data-theme=dark] *)[data-state=checked],.dark\:data-\[state\=indeterminate\]\:bg-primary:is(.dark *,[data-theme=dark] *)[data-state=indeterminate]{background-color:var(--primary)}.dark\:data-\[state\=on\]\:bg-input\/50:is(.dark *,[data-theme=dark] *)[data-state=on]{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:data-\[state\=on\]\:bg-input\/50:is(.dark *,[data-theme=dark] *)[data-state=on]{background-color:color-mix(in oklab, var(--input) 50%, transparent)}}.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20:is(.dark *,[data-theme=dark] *)[data-variant=destructive]:focus{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20:is(.dark *,[data-theme=dark] *)[data-variant=destructive]:focus{background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}@media (forced-colors:active){.forced-colors\:border{border-style:var(--tw-border-style);border-width:1px}}.data-open\:animate-accordion-down:where([data-state=open]),.data-open\:animate-accordion-down:where([data-open]:not([data-open=false])){animation:accordion-down var(--tw-animation-duration,var(--tw-duration,.2s))var(--tw-ease,ease-out)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-open\:animate-in:where([data-state=open]),.data-open\:animate-in:where([data-open]:not([data-open=false])){animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-open\:bg-accent:where([data-state=open]),.data-open\:bg-accent:where([data-open]:not([data-open=false])){background-color:var(--accent)}.data-open\:bg-muted\/50:where([data-state=open]),.data-open\:bg-muted\/50:where([data-open]:not([data-open=false])){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.data-open\:bg-muted\/50:where([data-state=open]),.data-open\:bg-muted\/50:where([data-open]:not([data-open=false])){background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.data-open\:text-accent-foreground:where([data-state=open]),.data-open\:text-accent-foreground:where([data-open]:not([data-open=false])){color:var(--accent-foreground)}.data-open\:fade-in-0:where([data-state=open]),.data-open\:fade-in-0:where([data-open]:not([data-open=false])){--tw-enter-opacity:0}.data-open\:slide-in-from-bottom-10:where([data-state=open]),.data-open\:slide-in-from-bottom-10:where([data-open]:not([data-open=false])){--tw-enter-translate-y:calc(.1*100%)}.data-open\:zoom-in-90:where([data-state=open]),.data-open\:zoom-in-90:where([data-open]:not([data-open=false])){--tw-enter-scale:.9}.data-open\:zoom-in-95:where([data-state=open]),.data-open\:zoom-in-95:where([data-open]:not([data-open=false])){--tw-enter-scale:.95}.data-open\:zoom-in-\[0\.98\]:where([data-state=open]),.data-open\:zoom-in-\[0\.98\]:where([data-open]:not([data-open=false])){--tw-enter-scale:.98}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-open\:animate-in):where([data-state=open]),:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-open\:animate-in):where([data-open]:not([data-open=false])){animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-open\:fade-in-0):where([data-state=open]),:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-open\:fade-in-0):where([data-open]:not([data-open=false])){--tw-enter-opacity:0}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-open\:zoom-in-95):where([data-state=open]),:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-open\:zoom-in-95):where([data-open]:not([data-open=false])){--tw-enter-scale:.95}@media (hover:hover){:is(.data-open\:hover\:bg-muted:where([data-state=open]),.data-open\:hover\:bg-muted:where([data-open]:not([data-open=false]))):hover{background-color:var(--muted)}:is(.data-open\:hover\:bg-sidebar-accent:where([data-state=open]),.data-open\:hover\:bg-sidebar-accent:where([data-open]:not([data-open=false]))):hover{background-color:var(--sidebar-accent)}:is(.data-open\:hover\:text-sidebar-accent-foreground:where([data-state=open]),.data-open\:hover\:text-sidebar-accent-foreground:where([data-open]:not([data-open=false]))):hover{color:var(--sidebar-accent-foreground)}}:is(.data-open\:focus\:bg-muted:where([data-state=open]),.data-open\:focus\:bg-muted:where([data-open]:not([data-open=false]))):focus{background-color:var(--muted)}.data-\[side\=bottom\]\:data-open\:slide-in-from-bottom-10[data-side=bottom]:where([data-state=open]),.data-\[side\=bottom\]\:data-open\:slide-in-from-bottom-10[data-side=bottom]:where([data-open]:not([data-open=false])){--tw-enter-translate-y:calc(.1*100%)}.data-\[side\=left\]\:data-open\:slide-in-from-left-10[data-side=left]:where([data-state=open]),.data-\[side\=left\]\:data-open\:slide-in-from-left-10[data-side=left]:where([data-open]:not([data-open=false])){--tw-enter-translate-x:calc(.1*-100%)}.data-\[side\=right\]\:data-open\:slide-in-from-right-10[data-side=right]:where([data-state=open]),.data-\[side\=right\]\:data-open\:slide-in-from-right-10[data-side=right]:where([data-open]:not([data-open=false])){--tw-enter-translate-x:calc(.1*100%)}.data-\[side\=top\]\:data-open\:slide-in-from-top-10[data-side=top]:where([data-state=open]),.data-\[side\=top\]\:data-open\:slide-in-from-top-10[data-side=top]:where([data-open]:not([data-open=false])){--tw-enter-translate-y:calc(.1*-100%)}@media (min-width:40rem){.sm\:data-open\:slide-in-from-bottom-0:where([data-state=open]),.sm\:data-open\:slide-in-from-bottom-0:where([data-open]:not([data-open=false])){--tw-enter-translate-y:calc(0*100%)}.sm\:data-open\:zoom-in-95:where([data-state=open]),.sm\:data-open\:zoom-in-95:where([data-open]:not([data-open=false])){--tw-enter-scale:.95}.sm\:data-open\:slide-in-from-top-2:where([data-state=open]),.sm\:data-open\:slide-in-from-top-2:where([data-open]:not([data-open=false])){--tw-enter-translate-y:calc(2*var(--spacing)*-1)}}.data-closed\:animate-accordion-up:where([data-state=closed]),.data-closed\:animate-accordion-up:where([data-closed]:not([data-closed=false])){animation:accordion-up var(--tw-animation-duration,var(--tw-duration,.2s))var(--tw-ease,ease-out)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-closed\:animate-out:where([data-state=closed]),.data-closed\:animate-out:where([data-closed]:not([data-closed=false])){animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-closed\:fade-out-0:where([data-state=closed]),.data-closed\:fade-out-0:where([data-closed]:not([data-closed=false])){--tw-exit-opacity:0}.data-closed\:slide-out-to-bottom-10:where([data-state=closed]),.data-closed\:slide-out-to-bottom-10:where([data-closed]:not([data-closed=false])){--tw-exit-translate-y:calc(.1*100%)}.data-closed\:zoom-out-90:where([data-state=closed]),.data-closed\:zoom-out-90:where([data-closed]:not([data-closed=false])){--tw-exit-scale:.9}.data-closed\:zoom-out-95:where([data-state=closed]),.data-closed\:zoom-out-95:where([data-closed]:not([data-closed=false])){--tw-exit-scale:.95}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-closed\:animate-out):where([data-state=closed]),:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-closed\:animate-out):where([data-closed]:not([data-closed=false])){animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-closed\:fade-out-0):where([data-state=closed]),:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-closed\:fade-out-0):where([data-closed]:not([data-closed=false])){--tw-exit-opacity:0}:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-closed\:zoom-out-95):where([data-state=closed]),:is(:where(.group\/navigation-menu)[data-viewport=false] .group-data-\[viewport\=false\]\/navigation-menu\:data-closed\:zoom-out-95):where([data-closed]:not([data-closed=false])){--tw-exit-scale:.95}.data-\[side\=bottom\]\:data-closed\:slide-out-to-bottom-10[data-side=bottom]:where([data-state=closed]),.data-\[side\=bottom\]\:data-closed\:slide-out-to-bottom-10[data-side=bottom]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-y:calc(.1*100%)}.data-\[side\=left\]\:data-closed\:slide-out-to-left-10[data-side=left]:where([data-state=closed]),.data-\[side\=left\]\:data-closed\:slide-out-to-left-10[data-side=left]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-x:calc(.1*-100%)}.data-\[side\=right\]\:data-closed\:slide-out-to-right-10[data-side=right]:where([data-state=closed]),.data-\[side\=right\]\:data-closed\:slide-out-to-right-10[data-side=right]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-x:calc(.1*100%)}.data-\[side\=top\]\:data-closed\:slide-out-to-top-10[data-side=top]:where([data-state=closed]),.data-\[side\=top\]\:data-closed\:slide-out-to-top-10[data-side=top]:where([data-closed]:not([data-closed=false])){--tw-exit-translate-y:calc(.1*-100%)}@media (min-width:40rem){.sm\:data-closed\:slide-out-to-bottom-0:where([data-state=closed]),.sm\:data-closed\:slide-out-to-bottom-0:where([data-closed]:not([data-closed=false])){--tw-exit-translate-y:calc(0*100%)}.sm\:data-closed\:zoom-out-95:where([data-state=closed]),.sm\:data-closed\:zoom-out-95:where([data-closed]:not([data-closed=false])){--tw-exit-scale:.95}}.data-checked\:border-primary:where([data-state=checked]),.data-checked\:border-primary:where([data-checked]:not([data-checked=false])){border-color:var(--primary)}.data-checked\:bg-primary:where([data-state=checked]),.data-checked\:bg-primary:where([data-checked]:not([data-checked=false])){background-color:var(--primary)}.data-checked\:text-primary-foreground:where([data-state=checked]),.data-checked\:text-primary-foreground:where([data-checked]:not([data-checked=false])){color:var(--primary-foreground)}:is(:where(.group\/field-label):has(:focus-visible) .group-has-\[\:focus-visible\]\/field-label\:data-checked\:border-primary):where([data-state=checked]),:is(:where(.group\/field-label):has(:focus-visible) .group-has-\[\:focus-visible\]\/field-label\:data-checked\:border-primary):where([data-checked]:not([data-checked=false])){border-color:var(--primary)}:is(:where(.group\/switch)[data-size=default] .group-data-\[size\=default\]\/switch\:data-checked\:translate-x-\[22px\]):where([data-state=checked]),:is(:where(.group\/switch)[data-size=default] .group-data-\[size\=default\]\/switch\:data-checked\:translate-x-\[22px\]):where([data-checked]:not([data-checked=false])){--tw-translate-x:22px;translate:var(--tw-translate-x) var(--tw-translate-y)}:is(:where(.group\/switch)[data-size=sm] .group-data-\[size\=sm\]\/switch\:data-checked\:translate-x-3):where([data-state=checked]),:is(:where(.group\/switch)[data-size=sm] .group-data-\[size\=sm\]\/switch\:data-checked\:translate-x-3):where([data-checked]:not([data-checked=false])){--tw-translate-x:calc(var(--spacing) * 3);translate:var(--tw-translate-x) var(--tw-translate-y)}:is(:where(.group\/switch)[data-size=default] .rtl\:group-data-\[size\=default\]\/switch\:data-checked\:-translate-x-\[22px\]:where(:dir(rtl),[dir=rtl],[dir=rtl] *)):where([data-state=checked]),:is(:where(.group\/switch)[data-size=default] .rtl\:group-data-\[size\=default\]\/switch\:data-checked\:-translate-x-\[22px\]:where(:dir(rtl),[dir=rtl],[dir=rtl] *)):where([data-checked]:not([data-checked=false])){--tw-translate-x:calc(22px * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}:is(:where(.group\/switch)[data-size=sm] .rtl\:group-data-\[size\=sm\]\/switch\:data-checked\:-translate-x-3:where(:dir(rtl),[dir=rtl],[dir=rtl] *)):where([data-state=checked]),:is(:where(.group\/switch)[data-size=sm] .rtl\:group-data-\[size\=sm\]\/switch\:data-checked\:-translate-x-3:where(:dir(rtl),[dir=rtl],[dir=rtl] *)):where([data-checked]:not([data-checked=false])){--tw-translate-x:calc(var(--spacing) * -3);translate:var(--tw-translate-x) var(--tw-translate-y)}.dark\:data-checked\:bg-primary:is(.dark *,[data-theme=dark] *):where([data-state=checked]),.dark\:data-checked\:bg-primary:is(.dark *,[data-theme=dark] *):where([data-checked]:not([data-checked=false])){background-color:var(--primary)}.dark\:data-checked\:bg-primary-foreground:is(.dark *,[data-theme=dark] *):where([data-state=checked]),.dark\:data-checked\:bg-primary-foreground:is(.dark *,[data-theme=dark] *):where([data-checked]:not([data-checked=false])){background-color:var(--primary-foreground)}.data-unchecked\:bg-foreground\/25:where([data-state=unchecked]),.data-unchecked\:bg-foreground\/25:where([data-unchecked]:not([data-unchecked=false])){background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.data-unchecked\:bg-foreground\/25:where([data-state=unchecked]),.data-unchecked\:bg-foreground\/25:where([data-unchecked]:not([data-unchecked=false])){background-color:color-mix(in oklab, var(--foreground) 25%, transparent)}}:is(:where(.group\/switch)[data-size=default] .group-data-\[size\=default\]\/switch\:data-unchecked\:translate-x-0):where([data-state=unchecked]),:is(:where(.group\/switch)[data-size=default] .group-data-\[size\=default\]\/switch\:data-unchecked\:translate-x-0):where([data-unchecked]:not([data-unchecked=false])),:is(:where(.group\/switch)[data-size=sm] .group-data-\[size\=sm\]\/switch\:data-unchecked\:translate-x-0):where([data-state=unchecked]),:is(:where(.group\/switch)[data-size=sm] .group-data-\[size\=sm\]\/switch\:data-unchecked\:translate-x-0):where([data-unchecked]:not([data-unchecked=false])),:is(:where(.group\/switch)[data-size=default] .rtl\:group-data-\[size\=default\]\/switch\:data-unchecked\:-translate-x-0:where(:dir(rtl),[dir=rtl],[dir=rtl] *)):where([data-state=unchecked]),:is(:where(.group\/switch)[data-size=default] .rtl\:group-data-\[size\=default\]\/switch\:data-unchecked\:-translate-x-0:where(:dir(rtl),[dir=rtl],[dir=rtl] *)):where([data-unchecked]:not([data-unchecked=false])),:is(:where(.group\/switch)[data-size=sm] .rtl\:group-data-\[size\=sm\]\/switch\:data-unchecked\:-translate-x-0:where(:dir(rtl),[dir=rtl],[dir=rtl] *)):where([data-state=unchecked]),:is(:where(.group\/switch)[data-size=sm] .rtl\:group-data-\[size\=sm\]\/switch\:data-unchecked\:-translate-x-0:where(:dir(rtl),[dir=rtl],[dir=rtl] *)):where([data-unchecked]:not([data-unchecked=false])){--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}.dark\:data-unchecked\:bg-foreground:is(.dark *,[data-theme=dark] *):where([data-state=unchecked]),.dark\:data-unchecked\:bg-foreground:is(.dark *,[data-theme=dark] *):where([data-unchecked]:not([data-unchecked=false])),.dark\:data-unchecked\:bg-foreground\/30:is(.dark *,[data-theme=dark] *):where([data-state=unchecked]),.dark\:data-unchecked\:bg-foreground\/30:is(.dark *,[data-theme=dark] *):where([data-unchecked]:not([data-unchecked=false])){background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.dark\:data-unchecked\:bg-foreground\/30:is(.dark *,[data-theme=dark] *):where([data-state=unchecked]),.dark\:data-unchecked\:bg-foreground\/30:is(.dark *,[data-theme=dark] *):where([data-unchecked]:not([data-unchecked=false])){background-color:color-mix(in oklab, var(--foreground) 30%, transparent)}}.data-selected\:border-primary:where([data-selected=true]){border-color:var(--primary)}.data-selected\:bg-accent:where([data-selected=true]){background-color:var(--accent)}.data-selected\:bg-primary:where([data-selected=true]){background-color:var(--primary)}.data-selected\:text-accent-foreground:where([data-selected=true]){color:var(--accent-foreground)}.data-selected\:text-primary-foreground:where([data-selected=true]){color:var(--primary-foreground)}.data-selected\:ring-2:where([data-selected=true]){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-selected\:ring-foreground:where([data-selected=true]){--tw-ring-color:var(--foreground)}@media (hover:hover){.data-selected\:hover\:bg-primary\/90:where([data-selected=true]):hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.data-selected\:hover\:bg-primary\/90:where([data-selected=true]):hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.data-selected\:hover\:text-primary-foreground:where([data-selected=true]):hover{color:var(--primary-foreground)}}.data-disabled\:pointer-events-none:where([data-disabled=true]),.data-disabled\:pointer-events-none:where([data-disabled]:not([data-disabled=false])){pointer-events:none}.data-disabled\:cursor-not-allowed:where([data-disabled=true]),.data-disabled\:cursor-not-allowed:where([data-disabled]:not([data-disabled=false])){cursor:not-allowed}.data-disabled\:bg-input\/50:where([data-disabled=true]),.data-disabled\:bg-input\/50:where([data-disabled]:not([data-disabled=false])){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.data-disabled\:bg-input\/50:where([data-disabled=true]),.data-disabled\:bg-input\/50:where([data-disabled]:not([data-disabled=false])){background-color:color-mix(in oklab, var(--input) 50%, transparent)}}.data-disabled\:opacity-50:where([data-disabled=true]),.data-disabled\:opacity-50:where([data-disabled]:not([data-disabled=false])){opacity:.5}.data-active\:bg-accent:where([data-state=active]),.data-active\:bg-accent:where([data-active]:not([data-active=false])){background-color:var(--accent)}.data-active\:bg-background:where([data-state=active]),.data-active\:bg-background:where([data-active]:not([data-active=false])){background-color:var(--background)}.data-active\:bg-muted\/50:where([data-state=active]),.data-active\:bg-muted\/50:where([data-active]:not([data-active=false])){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.data-active\:bg-muted\/50:where([data-state=active]),.data-active\:bg-muted\/50:where([data-active]:not([data-active=false])){background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.data-active\:bg-primary-subtle:where([data-state=active]),.data-active\:bg-primary-subtle:where([data-active]:not([data-active=false])){background-color:var(--primary-subtle)}.data-active\:bg-shell-active:where([data-state=active]),.data-active\:bg-shell-active:where([data-active]:not([data-active=false])){background-color:var(--shell-active)}.data-active\:bg-sidebar-primary\/12:where([data-state=active]),.data-active\:bg-sidebar-primary\/12:where([data-active]:not([data-active=false])){background-color:var(--sidebar-primary)}@supports (color:color-mix(in lab, red, red)){.data-active\:bg-sidebar-primary\/12:where([data-state=active]),.data-active\:bg-sidebar-primary\/12:where([data-active]:not([data-active=false])){background-color:color-mix(in oklab, var(--sidebar-primary) 12%, transparent)}}.data-active\:bg-transparent:where([data-state=active]),.data-active\:bg-transparent:where([data-active]:not([data-active=false])){background-color:#0000}.data-active\:font-medium:where([data-state=active]),.data-active\:font-medium:where([data-active]:not([data-active=false])){--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.data-active\:font-semibold:where([data-state=active]),.data-active\:font-semibold:where([data-active]:not([data-active=false])){--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.data-active\:text-accent-foreground:where([data-state=active]),.data-active\:text-accent-foreground:where([data-active]:not([data-active=false])){color:var(--accent-foreground)}.data-active\:text-foreground:where([data-state=active]),.data-active\:text-foreground:where([data-active]:not([data-active=false])){color:var(--foreground)}.data-active\:text-primary:where([data-state=active]),.data-active\:text-primary:where([data-active]:not([data-active=false])){color:var(--primary)}.data-active\:text-primary-subtle-foreground:where([data-state=active]),.data-active\:text-primary-subtle-foreground:where([data-active]:not([data-active=false])){color:var(--primary-subtle-foreground)}.data-active\:text-shell-foreground:where([data-state=active]),.data-active\:text-shell-foreground:where([data-active]:not([data-active=false])){color:var(--shell-foreground)}.data-active\:ring-2:where([data-state=active]),.data-active\:ring-2:where([data-active]:not([data-active=false])){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-active\:ring-ring\/50:where([data-state=active]),.data-active\:ring-ring\/50:where([data-active]:not([data-active=false])){--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.data-active\:ring-ring\/50:where([data-state=active]),.data-active\:ring-ring\/50:where([data-active]:not([data-active=false])){--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.data-active\:\[text-shadow\:0_0_0\.25px_currentColor\]:where([data-state=active]),.data-active\:\[text-shadow\:0_0_0\.25px_currentColor\]:where([data-active]:not([data-active=false])){text-shadow:0 0 .25px}:is(:where(.group\/tabs-list)[data-variant=default] .group-data-\[variant\=default\]\/tabs-list\:data-active\:shadow-sm):where([data-state=active]),:is(:where(.group\/tabs-list)[data-variant=default] .group-data-\[variant\=default\]\/tabs-list\:data-active\:shadow-sm):where([data-active]:not([data-active=false])){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:data-active\:bg-transparent):where([data-state=active]),:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:data-active\:bg-transparent):where([data-active]:not([data-active=false])){background-color:#0000}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:data-active\:text-primary-7):where([data-state=active]),:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:data-active\:text-primary-7):where([data-active]:not([data-active=false])){color:var(--primary-7)}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:data-active\:shadow-none):where([data-state=active]),:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:data-active\:shadow-none):where([data-active]:not([data-active=false])){--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:data-active\:\[text-shadow\:0_0_0\.25px_currentColor\]):where([data-state=active]),:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:data-active\:\[text-shadow\:0_0_0\.25px_currentColor\]):where([data-active]:not([data-active=false])){text-shadow:0 0 .25px}:is(.data-active\:after\:bg-primary:where([data-state=active]),.data-active\:after\:bg-primary:where([data-active]:not([data-active=false]))):after{content:var(--tw-content);background-color:var(--primary)}:is(:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:data-active\:after\:opacity-100):where([data-state=active]),:is(:where(.group\/tabs-list)[data-variant=line] .group-data-\[variant\=line\]\/tabs-list\:data-active\:after\:opacity-100):where([data-active]:not([data-active=false]))):after{content:var(--tw-content);opacity:1}@media (hover:hover){:is(.data-active\:hover\:bg-muted:where([data-state=active]),.data-active\:hover\:bg-muted:where([data-active]:not([data-active=false]))):hover{background-color:var(--muted)}}:is(.data-active\:focus\:bg-muted:where([data-state=active]),.data-active\:focus\:bg-muted:where([data-active]:not([data-active=false]))):focus,:where([role=listbox]:focus) .in-\[\[role\=listbox\]\:focus\]\:data-active\:bg-muted:where([data-state=active]),:where([role=listbox]:focus) .in-\[\[role\=listbox\]\:focus\]\:data-active\:bg-muted:where([data-active]:not([data-active=false])){background-color:var(--muted)}:where([role=listbox]:focus-visible) .in-\[\[role\=listbox\]\:focus-visible\]\:data-active\:ring-2:where([data-state=active]),:where([role=listbox]:focus-visible) .in-\[\[role\=listbox\]\:focus-visible\]\:data-active\:ring-2:where([data-active]:not([data-active=false])){--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:where([role=listbox]:focus-visible) .in-\[\[role\=listbox\]\:focus-visible\]\:data-active\:ring-ring\/50:where([data-state=active]),:where([role=listbox]:focus-visible) .in-\[\[role\=listbox\]\:focus-visible\]\:data-active\:ring-ring\/50:where([data-active]:not([data-active=false])){--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){:where([role=listbox]:focus-visible) .in-\[\[role\=listbox\]\:focus-visible\]\:data-active\:ring-ring\/50:where([data-state=active]),:where([role=listbox]:focus-visible) .in-\[\[role\=listbox\]\:focus-visible\]\:data-active\:ring-ring\/50:where([data-active]:not([data-active=false])){--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.dark\:data-active\:border-input:is(.dark *,[data-theme=dark] *):where([data-state=active]),.dark\:data-active\:border-input:is(.dark *,[data-theme=dark] *):where([data-active]:not([data-active=false])){border-color:var(--input)}.dark\:data-active\:bg-input\/30:is(.dark *,[data-theme=dark] *):where([data-state=active]),.dark\:data-active\:bg-input\/30:is(.dark *,[data-theme=dark] *):where([data-active]:not([data-active=false])){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:data-active\:bg-input\/30:is(.dark *,[data-theme=dark] *):where([data-state=active]),.dark\:data-active\:bg-input\/30:is(.dark *,[data-theme=dark] *):where([data-active]:not([data-active=false])){background-color:color-mix(in oklab, var(--input) 30%, transparent)}}.dark\:data-active\:text-foreground:is(.dark *,[data-theme=dark] *):where([data-state=active]),.dark\:data-active\:text-foreground:is(.dark *,[data-theme=dark] *):where([data-active]:not([data-active=false])){color:var(--foreground)}:is(:where(.group\/tabs-list)[data-variant=line] .dark\:group-data-\[variant\=line\]\/tabs-list\:data-active\:border-transparent:is(.dark *,[data-theme=dark] *)):where([data-state=active]),:is(:where(.group\/tabs-list)[data-variant=line] .dark\:group-data-\[variant\=line\]\/tabs-list\:data-active\:border-transparent:is(.dark *,[data-theme=dark] *)):where([data-active]:not([data-active=false])){border-color:#0000}:is(:where(.group\/tabs-list)[data-variant=line] .dark\:group-data-\[variant\=line\]\/tabs-list\:data-active\:bg-transparent:is(.dark *,[data-theme=dark] *)):where([data-state=active]),:is(:where(.group\/tabs-list)[data-variant=line] .dark\:group-data-\[variant\=line\]\/tabs-list\:data-active\:bg-transparent:is(.dark *,[data-theme=dark] *)):where([data-active]:not([data-active=false])){background-color:#0000}:is(:where(.group\/tabs-list)[data-variant=line] .dark\:group-data-\[variant\=line\]\/tabs-list\:data-active\:text-primary-7:is(.dark *,[data-theme=dark] *)):where([data-state=active]),:is(:where(.group\/tabs-list)[data-variant=line] .dark\:group-data-\[variant\=line\]\/tabs-list\:data-active\:text-primary-7:is(.dark *,[data-theme=dark] *)):where([data-active]:not([data-active=false])){color:var(--primary-7)}.data-horizontal\:mx-px:where([data-orientation=horizontal]){margin-inline:1px}.data-horizontal\:my-2:where([data-orientation=horizontal]){margin-block:calc(var(--spacing) * 2)}.data-horizontal\:my-4:where([data-orientation=horizontal]){margin-block:calc(var(--spacing) * 4)}.data-horizontal\:my-8:where([data-orientation=horizontal]){margin-block:calc(var(--spacing) * 8)}.data-horizontal\:h-1:where([data-orientation=horizontal]){height:var(--spacing)}.data-horizontal\:h-1\.5:where([data-orientation=horizontal]){height:calc(var(--spacing) * 1.5)}.data-horizontal\:h-2\.5:where([data-orientation=horizontal]){height:calc(var(--spacing) * 2.5)}.data-horizontal\:h-full:where([data-orientation=horizontal]){height:100%}.data-horizontal\:h-px:where([data-orientation=horizontal]){height:1px}.data-horizontal\:w-4:where([data-orientation=horizontal]){width:calc(var(--spacing) * 4)}.data-horizontal\:w-auto:where([data-orientation=horizontal]){width:auto}.data-horizontal\:w-full:where([data-orientation=horizontal]){width:100%}.data-horizontal\:flex-col:where([data-orientation=horizontal]){flex-direction:column}.data-horizontal\:border-t:where([data-orientation=horizontal]){border-top-style:var(--tw-border-style);border-top-width:1px}.data-horizontal\:border-t-transparent:where([data-orientation=horizontal]){border-top-color:#0000}.data-vertical\:mx-2:where([data-orientation=vertical]){margin-inline:calc(var(--spacing) * 2)}.data-vertical\:mx-4:where([data-orientation=vertical]){margin-inline:calc(var(--spacing) * 4)}.data-vertical\:mx-8:where([data-orientation=vertical]){margin-inline:calc(var(--spacing) * 8)}.data-vertical\:my-px:where([data-orientation=vertical]){margin-block:1px}.data-vertical\:h-4:where([data-orientation=vertical]){height:calc(var(--spacing) * 4)}.data-vertical\:h-auto:where([data-orientation=vertical]){height:auto}.data-vertical\:h-full:where([data-orientation=vertical]){height:100%}.data-vertical\:min-h-40:where([data-orientation=vertical]){min-height:calc(var(--spacing) * 40)}.data-vertical\:w-1:where([data-orientation=vertical]){width:var(--spacing)}.data-vertical\:w-1\.5:where([data-orientation=vertical]){width:calc(var(--spacing) * 1.5)}.data-vertical\:w-2\.5:where([data-orientation=vertical]){width:calc(var(--spacing) * 2.5)}.data-vertical\:w-auto:where([data-orientation=vertical]){width:auto}.data-vertical\:w-full:where([data-orientation=vertical]){width:100%}.data-vertical\:w-px:where([data-orientation=vertical]){width:1px}.data-vertical\:flex-col:where([data-orientation=vertical]){flex-direction:column}.data-vertical\:items-stretch:where([data-orientation=vertical]){align-items:stretch}.data-vertical\:self-auto:where([data-orientation=vertical]){align-self:auto}.data-vertical\:self-stretch:where([data-orientation=vertical]){align-self:stretch}.data-vertical\:border-s:where([data-orientation=vertical]){border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}.data-vertical\:border-s-transparent:where([data-orientation=vertical]){border-inline-start-color:#0000}@media (pointer:coarse){.touch\:end-0{inset-inline-end:calc(var(--spacing) * 0)}.touch\:top-0{top:0}.touch\:-m-3{margin:calc(var(--spacing) * -3)}.touch\:my-3{margin-block:calc(var(--spacing) * 3)}.touch\:hidden{display:none}.touch\:inline-flex{display:inline-flex}.touch\:size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.touch\:size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.touch\:size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.touch\:size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.touch\:size-11{width:calc(var(--spacing) * 11);height:calc(var(--spacing) * 11)}.touch\:size-11\!{width:calc(var(--spacing) * 11)!important;height:calc(var(--spacing) * 11)!important}.touch\:size-12{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12)}.touch\:size-72{width:calc(var(--spacing) * 72);height:calc(var(--spacing) * 72)}.touch\:h-10{height:calc(var(--spacing) * 10)}.touch\:h-11{height:calc(var(--spacing) * 11)}.touch\:h-12{height:calc(var(--spacing) * 12)}.touch\:h-14{height:calc(var(--spacing) * 14)}.touch\:h-56{height:calc(var(--spacing) * 56)}.touch\:h-72{height:calc(var(--spacing) * 72)}.touch\:max-h-\[60vh\]{max-height:60vh}.touch\:min-h-11{min-height:calc(var(--spacing) * 11)}.touch\:w-72{width:calc(var(--spacing) * 72)}.touch\:w-full{width:100%}.touch\:min-w-11{min-width:calc(var(--spacing) * 11)}.touch\:flex-col{flex-direction:column}.touch\:items-center{align-items:center}.touch\:justify-center{justify-content:center}.touch\:p-1\.5{padding:calc(var(--spacing) * 1.5)}.touch\:py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.touch\:ps-0{padding-inline-start:0}.touch\:ps-14{padding-inline-start:calc(var(--spacing) * 14)}.touch\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}.touch\:\[--cell-size\:--spacing\(11\)\]{--cell-size:calc(var(--spacing) * 11)}:is(:where(.peer\/menu-button)[data-size=default]~.touch\:peer-data-\[size\=default\]\/menu-button\:top-3){top:calc(var(--spacing) * 3)}.touch\:after\:absolute:after{content:var(--tw-content);position:absolute}.touch\:after\:-inset-1:after{content:var(--tw-content);inset:calc(var(--spacing) * -1)}.touch\:after\:-inset-2\.5:after{content:var(--tw-content);inset:calc(var(--spacing) * -2.5)}.touch\:after\:-inset-3:after{content:var(--tw-content);inset:calc(var(--spacing) * -3)}.touch\:after\:-inset-3\.5:after{content:var(--tw-content);inset:calc(var(--spacing) * -3.5)}.touch\:after\:-inset-x-2:after{content:var(--tw-content);inset-inline:calc(var(--spacing) * -2)}.touch\:after\:inset-x-0:after{content:var(--tw-content);inset-inline:0}.touch\:after\:-inset-y-2\.5:after{content:var(--tw-content);inset-block:calc(var(--spacing) * -2.5)}.touch\:after\:-inset-y-3\.5:after{content:var(--tw-content);inset-block:calc(var(--spacing) * -3.5)}}.\[\&_\.ProseMirror\]\:min-h-\[inherit\] .ProseMirror{min-height:inherit}.\[\&_\.ProseMirror\]\:whitespace-pre-wrap .ProseMirror{white-space:pre-wrap}.\[\&_\.ProseMirror\]\:outline-none .ProseMirror{--tw-outline-style:none;outline-style:none}.\[\&_\.ProseMirror-gapcursor\]\:relative .ProseMirror-gapcursor{position:relative}.\[\&_\.ProseMirror-selectednode\]\:rounded-md .ProseMirror-selectednode{border-radius:calc(var(--radius) * .8)}.\[\&_\.ProseMirror-selectednode\]\:ring-2 .ProseMirror-selectednode{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.\[\&_\.ProseMirror-selectednode\]\:ring-ring\/50 .ProseMirror-selectednode{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.\[\&_\.ProseMirror-selectednode\]\:ring-ring\/50 .ProseMirror-selectednode{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.\[\&_\.fc\]\:font-sans .fc{font-family:var(--onu-font-sans)}.\[\&_\.fc\]\:text-sm .fc{font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}.\[\&_\.fc\]\:text-foreground .fc{color:var(--foreground)}.\[\&_\.fc_a\]\:text-inherit .fc a{color:inherit}.\[\&_\.fc_a\]\:no-underline .fc a{text-decoration-line:none}.\[\&_\.fc-col-header-cell\]\:py-1\.5 .fc-col-header-cell{padding-block:calc(var(--spacing) * 1.5)}.\[\&_\.fc-col-header-cell\]\:text-xs .fc-col-header-cell{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_\.fc-col-header-cell\]\:font-medium .fc-col-header-cell{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.\[\&_\.fc-col-header-cell\]\:text-muted-foreground .fc-col-header-cell,.\[\&_\.fc-day-other\]\:text-muted-foreground .fc-day-other{color:var(--muted-foreground)}.\[\&_\.fc-day-other_\.fc-daygrid-day-top\]\:opacity-100\! .fc-day-other .fc-daygrid-day-top{opacity:1!important}.\[\&_\.fc-day-today_\.fc-daygrid-day-number\]\:m-1 .fc-day-today .fc-daygrid-day-number{margin:var(--spacing)}.\[\&_\.fc-day-today_\.fc-daygrid-day-number\]\:rounded-full .fc-day-today .fc-daygrid-day-number{border-radius:2147483647px}.\[\&_\.fc-day-today_\.fc-daygrid-day-number\]\:bg-primary .fc-day-today .fc-daygrid-day-number{background-color:var(--primary)}.\[\&_\.fc-day-today_\.fc-daygrid-day-number\]\:font-semibold .fc-day-today .fc-daygrid-day-number{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.\[\&_\.fc-day-today_\.fc-daygrid-day-number\]\:text-primary-foreground .fc-day-today .fc-daygrid-day-number{color:var(--primary-foreground)}.\[\&_\.fc-daygrid-day-number\]\:p-1\.5 .fc-daygrid-day-number{padding:calc(var(--spacing) * 1.5)}.\[\&_\.fc-daygrid-day-number\]\:text-xs .fc-daygrid-day-number{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_\.fc-daygrid-day-number\]\:tabular-nums .fc-daygrid-day-number{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, )}.\[\&_\.fc-daygrid-dot-event\]\:text-foreground .fc-daygrid-dot-event{color:var(--foreground)}.\[\&_\.fc-daygrid-dot-event\:hover\]\:bg-muted .fc-daygrid-dot-event:hover{background-color:var(--muted)}.\[\&_\.fc-daygrid-event\]\:overflow-hidden .fc-daygrid-event{overflow:hidden}.\[\&_\.fc-event\]\:rounded-md .fc-event{border-radius:calc(var(--radius) * .8)}.\[\&_\.fc-event\]\:px-1 .fc-event{padding-inline:var(--spacing)}.\[\&_\.fc-event\]\:text-xs .fc-event{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_\.fc-event\]\:shadow-none .fc-event{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.\[\&_\.fc-event\:focus-visible\]\:ring-3 .fc-event:focus-visible{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.\[\&_\.fc-event\:focus-visible\]\:ring-ring\/50 .fc-event:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.\[\&_\.fc-event\:focus-visible\]\:ring-ring\/50 .fc-event:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.\[\&_\.fc-event\:focus-visible\]\:outline-none .fc-event:focus-visible{--tw-outline-style:none;outline-style:none}.\[\&_\.fc-list\]\:rounded-lg .fc-list{border-radius:var(--radius)}.\[\&_\.fc-list-day-cushion\]\:bg-muted\/60 .fc-list-day-cushion{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.\[\&_\.fc-list-day-cushion\]\:bg-muted\/60 .fc-list-day-cushion{background-color:color-mix(in oklab, var(--muted) 60%, transparent)}}.\[\&_\.fc-list-empty\]\:bg-transparent .fc-list-empty{background-color:#0000}.\[\&_\.fc-list-empty\]\:text-muted-foreground .fc-list-empty{color:var(--muted-foreground)}.\[\&_\.fc-list-event-time\]\:tabular-nums .fc-list-event-time{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, )}.\[\&_\.fc-list-table_thead\]\:sr-only .fc-list-table thead{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.\[\&_\.fc-list-table_thead\]\:inset-x-auto\! .fc-list-table thead{inset-inline:auto!important}.\[\&_\.fc-popover\]\:rounded-lg .fc-popover{border-radius:var(--radius)}.\[\&_\.fc-popover\]\:border-border .fc-popover{border-color:var(--border)}.\[\&_\.fc-popover\]\:bg-popover .fc-popover{background-color:var(--popover)}.\[\&_\.fc-popover\]\:text-popover-foreground .fc-popover{color:var(--popover-foreground)}.\[\&_\.fc-popover\]\:shadow-md .fc-popover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.\[\&_\.fc-popover-header\]\:bg-muted .fc-popover-header{background-color:var(--muted)}.\[\&_\.fc-scrollgrid\]\:overflow-hidden .fc-scrollgrid{overflow:hidden}.\[\&_\.fc-scrollgrid\]\:rounded-lg .fc-scrollgrid{border-radius:var(--radius)}.\[\&_\.fc-timegrid-slot\]\:h-10 .fc-timegrid-slot{height:calc(var(--spacing) * 10)}.\[\&_\.fc-timegrid-slot-label\]\:text-xs .fc-timegrid-slot-label{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_\.fc-timegrid-slot-label\]\:text-muted-foreground .fc-timegrid-slot-label{color:var(--muted-foreground)}.\[\&_\.is-empty\]\:before\:pointer-events-none .is-empty:before{content:var(--tw-content);pointer-events:none}.\[\&_\.is-empty\]\:before\:float-start .is-empty:before{content:var(--tw-content);float:inline-start}.\[\&_\.is-empty\]\:before\:h-0 .is-empty:before{content:var(--tw-content);height:0}.\[\&_\.is-empty\]\:before\:text-muted-foreground .is-empty:before{content:var(--tw-content);color:var(--muted-foreground)}.\[\&_\.is-empty\]\:before\:content-\[attr\(data-placeholder\)\] .is-empty:before{--tw-content:attr(data-placeholder);content:var(--tw-content)}.\[\&_\.onu-weekend\]\:bg-muted\/40 .onu-weekend{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.\[\&_\.onu-weekend\]\:bg-muted\/40 .onu-weekend{background-color:color-mix(in oklab, var(--muted) 40%, transparent)}}.\[\&_\.rdp-week\:hover_\.rdp-day\:not\(\[data-outside\]\)\]\:bg-muted\/60 .rdp-week:hover .rdp-day:not([data-outside]){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.\[\&_\.rdp-week\:hover_\.rdp-day\:not\(\[data-outside\]\)\]\:bg-muted\/60 .rdp-week:hover .rdp-day:not([data-outside]){background-color:color-mix(in oklab, var(--muted) 60%, transparent)}}.\[\&_\.recharts-brush-texts_text\]\:fill-muted-foreground .recharts-brush-texts text,.\[\&_\.recharts-cartesian-axis-tick_text\]\:fill-muted-foreground .recharts-cartesian-axis-tick text,.\[\&_\.recharts-cartesian-axis-tick-label_text\]\:fill-muted-foreground .recharts-cartesian-axis-tick-label text{fill:var(--muted-foreground)}.\[\&_\.recharts-cartesian-grid_line\[stroke\=\'\#ccc\'\]\]\:stroke-border\/50 .recharts-cartesian-grid line[stroke=\#ccc]{stroke:var(--border)}@supports (color:color-mix(in lab, red, red)){.\[\&_\.recharts-cartesian-grid_line\[stroke\=\'\#ccc\'\]\]\:stroke-border\/50 .recharts-cartesian-grid line[stroke=\#ccc]{stroke:color-mix(in oklab, var(--border) 50%, transparent)}}.\[\&_\.recharts-curve\.recharts-tooltip-cursor\]\:stroke-border .recharts-curve.recharts-tooltip-cursor{stroke:var(--border)}.\[\&_\.recharts-dot\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-dot[stroke=\#fff]{stroke:#0000}.\[\&_\.recharts-layer\]\:outline-hidden .recharts-layer{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.\[\&_\.recharts-layer\]\:outline-hidden .recharts-layer{outline-offset:2px;outline:2px solid #0000}}.\[\&_\.recharts-polar-grid_\[stroke\=\'\#ccc\'\]\]\:stroke-border .recharts-polar-grid [stroke=\#ccc]{stroke:var(--border)}.\[\&_\.recharts-radial-bar-background-sector\]\:fill-muted .recharts-radial-bar-background-sector,.\[\&_\.recharts-rectangle\.recharts-tooltip-cursor\]\:fill-muted .recharts-rectangle.recharts-tooltip-cursor{fill:var(--muted)}.\[\&_\.recharts-reference-line_\[stroke\=\'\#ccc\'\]\]\:stroke-border .recharts-reference-line [stroke=\#ccc]{stroke:var(--border)}.\[\&_\.recharts-sector\]\:outline-hidden .recharts-sector{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.\[\&_\.recharts-sector\]\:outline-hidden .recharts-sector{outline-offset:2px;outline:2px solid #0000}}.\[\&_\.recharts-sector\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-sector[stroke=\#fff]{stroke:#0000}.\[\&_\.recharts-surface\]\:overflow-visible .recharts-surface{overflow:visible}.\[\&_\.recharts-surface\]\:outline-hidden .recharts-surface{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.\[\&_\.recharts-surface\]\:outline-hidden .recharts-surface{outline-offset:2px;outline:2px solid #0000}}.\[\&_\.recharts-surface\]\:\[direction\:ltr\] .recharts-surface{direction:ltr}.\[\&_\.selectedCell\]\:bg-primary\/10 .selectedCell{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.\[\&_\.selectedCell\]\:bg-primary\/10 .selectedCell{background-color:color-mix(in oklab, var(--primary) 10%, transparent)}}.\[\&_\.tableWrapper\]\:my-4 .tableWrapper{margin-block:calc(var(--spacing) * 4)}.\[\&_\.tableWrapper\]\:overflow-x-auto .tableWrapper{overflow-x:auto}.\[\&_\:not\(figure\)\>pre\]\:my-4 :not(figure)>pre{margin-block:calc(var(--spacing) * 4)}.\[\&_\:not\(figure\)\>pre\]\:overflow-x-auto :not(figure)>pre{overflow-x:auto}.\[\&_\:not\(figure\)\>pre\]\:rounded-lg :not(figure)>pre{border-radius:var(--radius)}.\[\&_\:not\(figure\)\>pre\]\:bg-muted :not(figure)>pre{background-color:var(--muted)}.\[\&_\:not\(figure\)\>pre\]\:p-4 :not(figure)>pre{padding:calc(var(--spacing) * 4)}.\[\&_\:not\(figure\)\>pre\]\:text-start :not(figure)>pre{text-align:start}.\[\&_\:not\(figure\)\>pre\]\:font-mono :not(figure)>pre{font-family:var(--onu-font-mono)}.\[\&_\:not\(figure\)\>pre\]\:text-sm :not(figure)>pre{font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}.\[\&_\:not\(figure\)\>pre\]\:leading-relaxed :not(figure)>pre{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.\[\&_\:not\(pre\)\>code\]\:rounded-sm :not(pre)>code{border-radius:calc(var(--radius) * .6667)}.\[\&_\:not\(pre\)\>code\]\:bg-muted :not(pre)>code{background-color:var(--muted)}.\[\&_\:not\(pre\)\>code\]\:px-1 :not(pre)>code{padding-inline:var(--spacing)}.\[\&_\:not\(pre\)\>code\]\:py-0\.5 :not(pre)>code{padding-block:calc(var(--spacing) * .5)}.\[\&_\:not\(pre\)\>code\]\:font-mono :not(pre)>code{font-family:var(--onu-font-mono)}.\[\&_\:not\(pre\)\>code\]\:text-\[0\.875em\] :not(pre)>code{font-size:.875em}.\[\&_\[data-part\=user-profile\]\]\:w-auto [data-part=user-profile]{width:auto}@media not all and (min-width:48rem){.max-md\:\[\&_\[data-part\=user-profile\]\]\:min-h-9 [data-part=user-profile]{min-height:calc(var(--spacing) * 9)}.max-md\:\[\&_\[data-part\=user-profile\]\]\:p-0\.5 [data-part=user-profile]{padding:calc(var(--spacing) * .5)}}.\[\&_\[data-part\=user-profile\]_\[data-slot\=user-avatar\]\]\:rounded-lg [data-part=user-profile] [data-slot=user-avatar],.\[\&_\[data-part\=user-profile\]_\[data-slot\=user-avatar\]\>\*\]\:rounded-lg [data-part=user-profile] [data-slot=user-avatar]>*{border-radius:var(--radius)}.\[\&_\[data-part\=user-profile\]_\[data-slot\=user-avatar\]\>\*\]\:bg-shell-weak [data-part=user-profile] [data-slot=user-avatar]>*{background-color:var(--shell-weak)}.\[\&_\[data-part\=user-profile\]_\[data-slot\=user-avatar\]\>\*\]\:font-semibold [data-part=user-profile] [data-slot=user-avatar]>*{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.\[\&_\[data-part\=user-profile\]_\[data-slot\=user-avatar\]\>\*\]\:text-foreground [data-part=user-profile] [data-slot=user-avatar]>*{color:var(--foreground)}.\[\&_\[data-slot\=avatar\]\]\:size-full [data-slot=avatar]{width:100%;height:100%}.\[\&_\[data-slot\=avatar\]\]\:ring-2 [data-slot=avatar]{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.\[\&_\[data-slot\=avatar\]\]\:ring-background [data-slot=avatar]{--tw-ring-color:var(--background)}.\[\&_\[data-slot\=button\]\[data-size\^\=icon\]\]\:size-9 [data-slot=button][data-size^=icon]{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}@media (pointer:coarse){.touch\:\[\&_\[data-slot\=button\]\[data-size\^\=icon\]\]\:size-11 [data-slot=button][data-size^=icon]{width:calc(var(--spacing) * 11);height:calc(var(--spacing) * 11)}}.\[\&_\[data-slot\=button\]\[data-variant\=ghost\]\]\:rounded-lg [data-slot=button][data-variant=ghost]{border-radius:var(--radius)}.\[\&_\[data-slot\=button\]\[data-variant\=ghost\]\]\:text-muted-foreground [data-slot=button][data-variant=ghost]{color:var(--muted-foreground)}@media (hover:hover){.\[\&_\[data-slot\=button\]\[data-variant\=ghost\]\]\:hover\:bg-primary-foreground\/10 [data-slot=button][data-variant=ghost]:hover{background-color:var(--primary-foreground)}@supports (color:color-mix(in lab, red, red)){.\[\&_\[data-slot\=button\]\[data-variant\=ghost\]\]\:hover\:bg-primary-foreground\/10 [data-slot=button][data-variant=ghost]:hover{background-color:color-mix(in oklab, var(--primary-foreground) 10%, transparent)}}}.\[\&_\[data-slot\=button\]\[data-variant\=ghost\]\:hover\]\:bg-shell-hover [data-slot=button][data-variant=ghost]:hover{background-color:var(--shell-hover)}.\[\&_\[data-slot\=button\]\[data-variant\=ghost\]\:hover\]\:text-foreground [data-slot=button][data-variant=ghost]:hover{color:var(--foreground)}@media (forced-colors:active){.forced-colors\:\[\&_\[data-slot\=chart-gradient-stop\]\]\:\[stop-opacity\:var\(--onu-stop-solid\)\]\! [data-slot=chart-gradient-stop]{stop-opacity:var(--onu-stop-solid)!important}}.\[\&_\[data-slot\=data-table\]\>div\:has\(\[data-slot\=data-table-table\]\)\]\:rounded-b-none [data-slot=data-table]>div:has([data-slot=data-table-table]){border-bottom-right-radius:0;border-bottom-left-radius:0}.\[\&_\[data-slot\=data-table\]\>div\:has\(\[data-slot\=data-table-table\]\)\]\:border-0 [data-slot=data-table]>div:has([data-slot=data-table-table]),.\[\&_\[data-slot\=nav-tabs\]\]\:border-0 [data-slot=nav-tabs]{border-style:var(--tw-border-style);border-width:0}.\[\&_\[data-slot\=radio-group-indicator\]\]\:size-5 [data-slot=radio-group-indicator]{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.\[\&_\[data-slot\=rating-star\]\]\:size-4 [data-slot=rating-star]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_\[data-slot\=rating-star\]\]\:size-5 [data-slot=rating-star]{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.\[\&_\[data-slot\=rating-star\]\]\:size-8 [data-slot=rating-star]{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.\[\&_\[data-slot\=search-box-form\]\]\:max-w-xl [data-slot=search-box-form]{max-width:var(--container-xl)}.\[\&_\[data-slot\=search-box-form\]\]\:flex-1 [data-slot=search-box-form]{flex:1}.\[\&_\[data-slot\=search-box\]\]\:h-10 [data-slot=search-box]{height:calc(var(--spacing) * 10)}.\[\&_\[data-slot\=search-box\]\]\:min-h-10 [data-slot=search-box]{min-height:calc(var(--spacing) * 10)}.\[\&_\[data-slot\=search-box\]\]\:rounded-lg [data-slot=search-box]{border-radius:var(--radius)}.\[\&_\[data-slot\=search-box\]\]\:border-shell-border [data-slot=search-box]{border-color:var(--shell-border)}.\[\&_\[data-slot\=search-box\]\]\:bg-shell-field [data-slot=search-box]{background-color:var(--shell-field)}.\[\&_\[data-slot\=search-box\]\:hover\]\:border-\[color\:color-mix\(in_oklab\,var\(--primary\)_60\%\,transparent\)\] [data-slot=search-box]:hover{border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.\[\&_\[data-slot\=search-box\]\:hover\]\:border-\[color\:color-mix\(in_oklab\,var\(--primary\)_60\%\,transparent\)\] [data-slot=search-box]:hover{border-color:color-mix(in oklab,var(--primary) 60%,transparent)}}.\[\&_\[data-slot\=tabs-list\]\]\:h-auto [data-slot=tabs-list]{height:auto}.\[\&_\[data-slot\=tabs-list\]\]\:gap-8 [data-slot=tabs-list]{gap:calc(var(--spacing) * 8)}.\[\&_\[data-slot\=tabs-list\]\]\:rounded-none [data-slot=tabs-list]{border-radius:0}.\[\&_\[data-slot\=tabs-list\]\]\:p-0 [data-slot=tabs-list]{padding:0}.\[\&_\[data-slot\=tabs-trigger\]\]\:h-auto [data-slot=tabs-trigger]{height:auto}.\[\&_\[data-slot\=tabs-trigger\]\]\:flex-none [data-slot=tabs-trigger]{flex:none}.\[\&_\[data-slot\=tabs-trigger\]\]\:rounded-none [data-slot=tabs-trigger]{border-radius:0}.\[\&_\[data-slot\=tabs-trigger\]\]\:border-0 [data-slot=tabs-trigger]{border-style:var(--tw-border-style);border-width:0}.\[\&_\[data-slot\=tabs-trigger\]\]\:px-0 [data-slot=tabs-trigger]{padding-inline:0}.\[\&_\[data-slot\=tabs-trigger\]\]\:py-3 [data-slot=tabs-trigger]{padding-block:calc(var(--spacing) * 3)}.\[\&_\[data-slot\=tabs-trigger\]\]\:font-normal [data-slot=tabs-trigger]{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.\[\&_\[data-slot\=tabs-trigger\]\]\:text-foreground [data-slot=tabs-trigger]{color:var(--foreground)}.\[\&_\[data-slot\=tabs-trigger\]\]\:after\:bottom-0\! [data-slot=tabs-trigger]:after{content:var(--tw-content);bottom:0!important}.\[\&_\[data-slot\=tabs-trigger\]\]\:after\:h-0\.5 [data-slot=tabs-trigger]:after{content:var(--tw-content);height:calc(var(--spacing) * .5)}.\[\&_\[data-slot\=tabs-trigger\]\]\:after\:bg-primary [data-slot=tabs-trigger]:after{content:var(--tw-content);background-color:var(--primary)}.\[\&_\[data-slot\=tabs-trigger\]_\[data-slot\=badge\]\]\:h-5 [data-slot=tabs-trigger] [data-slot=badge]{height:calc(var(--spacing) * 5)}.\[\&_\[data-slot\=tabs-trigger\]_\[data-slot\=badge\]\]\:min-w-5 [data-slot=tabs-trigger] [data-slot=badge]{min-width:calc(var(--spacing) * 5)}.\[\&_\[data-slot\=tabs-trigger\]_\[data-slot\=badge\]\]\:rounded-full [data-slot=tabs-trigger] [data-slot=badge]{border-radius:2147483647px}.\[\&_\[data-slot\=tabs-trigger\]_\[data-slot\=badge\]\]\:px-1\.5 [data-slot=tabs-trigger] [data-slot=badge]{padding-inline:calc(var(--spacing) * 1.5)}.\[\&_\[data-slot\=tabs-trigger\]_\[data-slot\=badge\]\]\:font-normal [data-slot=tabs-trigger] [data-slot=badge]{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.\[\&_\[data-slot\=tabs-trigger\]\:hover\]\:text-primary [data-slot=tabs-trigger]:hover,.\[\&_\[data-slot\=tabs-trigger\]\[data-state\=active\]\]\:text-primary [data-slot=tabs-trigger][data-state=active]{color:var(--primary)}.\[\&_\[data-slot\=tabs-trigger\]\[data-state\=active\]\]\:\[text-shadow\:0_0_0\.25px_currentColor\] [data-slot=tabs-trigger][data-state=active]{text-shadow:0 0 .25px}.\[\&_\[data-slot\=tabs-trigger\]\[data-state\=active\]_\[data-slot\=badge\]\]\:bg-primary [data-slot=tabs-trigger][data-state=active] [data-slot=badge]{background-color:var(--primary)}.\[\&_\[data-slot\=tabs-trigger\]\[data-state\=active\]_\[data-slot\=badge\]\]\:font-semibold [data-slot=tabs-trigger][data-state=active] [data-slot=badge]{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.\[\&_\[data-slot\=tabs-trigger\]\[data-state\=active\]_\[data-slot\=badge\]\]\:text-primary-foreground [data-slot=tabs-trigger][data-state=active] [data-slot=badge]{color:var(--primary-foreground)}.\[\&_\[data-slot\=user-profile-chevron\]\]\:hidden [data-slot=user-profile-chevron]{display:none}@media not all and (min-width:48rem){.max-md\:\[\&_\[data-slot\=user-profile-text\]\]\:hidden [data-slot=user-profile-text]{display:none}}.\[\&_\[data-type\=callout\]\]\:my-4 [data-type=callout]{margin-block:calc(var(--spacing) * 4)}.\[\&_\[data-type\=callout\]\]\:rounded-lg [data-type=callout]{border-radius:var(--radius)}.\[\&_\[data-type\=callout\]\]\:border [data-type=callout]{border-style:var(--tw-border-style);border-width:1px}.\[\&_\[data-type\=callout\]\]\:px-4 [data-type=callout]{padding-inline:calc(var(--spacing) * 4)}.\[\&_\[data-type\=callout\]\]\:py-3 [data-type=callout]{padding-block:calc(var(--spacing) * 3)}.\[\&_\[data-type\=callout\]\[data-variant\=error\]\]\:border-destructive\/30 [data-type=callout][data-variant=error]{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.\[\&_\[data-type\=callout\]\[data-variant\=error\]\]\:border-destructive\/30 [data-type=callout][data-variant=error]{border-color:color-mix(in oklab, var(--destructive) 30%, transparent)}}.\[\&_\[data-type\=callout\]\[data-variant\=error\]\]\:bg-destructive\/10 [data-type=callout][data-variant=error]{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.\[\&_\[data-type\=callout\]\[data-variant\=error\]\]\:bg-destructive\/10 [data-type=callout][data-variant=error]{background-color:color-mix(in oklab, var(--destructive) 10%, transparent)}}.\[\&_\[data-type\=callout\]\[data-variant\=info\]\]\:border-info\/30 [data-type=callout][data-variant=info]{border-color:var(--info)}@supports (color:color-mix(in lab, red, red)){.\[\&_\[data-type\=callout\]\[data-variant\=info\]\]\:border-info\/30 [data-type=callout][data-variant=info]{border-color:color-mix(in oklab, var(--info) 30%, transparent)}}.\[\&_\[data-type\=callout\]\[data-variant\=info\]\]\:bg-info\/10 [data-type=callout][data-variant=info]{background-color:var(--info)}@supports (color:color-mix(in lab, red, red)){.\[\&_\[data-type\=callout\]\[data-variant\=info\]\]\:bg-info\/10 [data-type=callout][data-variant=info]{background-color:color-mix(in oklab, var(--info) 10%, transparent)}}.\[\&_\[data-type\=callout\]\[data-variant\=success\]\]\:border-success\/30 [data-type=callout][data-variant=success]{border-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.\[\&_\[data-type\=callout\]\[data-variant\=success\]\]\:border-success\/30 [data-type=callout][data-variant=success]{border-color:color-mix(in oklab, var(--success) 30%, transparent)}}.\[\&_\[data-type\=callout\]\[data-variant\=success\]\]\:bg-success\/10 [data-type=callout][data-variant=success]{background-color:var(--success)}@supports (color:color-mix(in lab, red, red)){.\[\&_\[data-type\=callout\]\[data-variant\=success\]\]\:bg-success\/10 [data-type=callout][data-variant=success]{background-color:color-mix(in oklab, var(--success) 10%, transparent)}}.\[\&_\[data-type\=callout\]\[data-variant\=warning\]\]\:border-warning\/40 [data-type=callout][data-variant=warning]{border-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.\[\&_\[data-type\=callout\]\[data-variant\=warning\]\]\:border-warning\/40 [data-type=callout][data-variant=warning]{border-color:color-mix(in oklab, var(--warning) 40%, transparent)}}.\[\&_\[data-type\=callout\]\[data-variant\=warning\]\]\:bg-warning\/10 [data-type=callout][data-variant=warning]{background-color:var(--warning)}@supports (color:color-mix(in lab, red, red)){.\[\&_\[data-type\=callout\]\[data-variant\=warning\]\]\:bg-warning\/10 [data-type=callout][data-variant=warning]{background-color:color-mix(in oklab, var(--warning) 10%, transparent)}}.\[\&_\[data-type\=embed\]\]\:my-4 [data-type=embed]{margin-block:calc(var(--spacing) * 4)}.\[\&_\[data-type\=embed\]_iframe\]\:aspect-video [data-type=embed] iframe{aspect-ratio:var(--aspect-video)}.\[\&_\[data-type\=embed\]_iframe\]\:w-full [data-type=embed] iframe{width:100%}.\[\&_\[data-type\=embed\]_iframe\]\:rounded-lg [data-type=embed] iframe{border-radius:var(--radius)}.\[\&_\[data-type\=embed\]_iframe\]\:border-0 [data-type=embed] iframe{border-style:var(--tw-border-style);border-width:0}.\[\&_a\]\:font-medium a{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.\[\&_a\]\:text-primary a{color:var(--primary)}.\[\&_a\]\:underline a{text-decoration-line:underline}.\[\&_a\]\:underline-offset-3 a{text-underline-offset:3px}.\[\&_a\]\:underline-offset-4 a{text-underline-offset:4px}@media (hover:hover){.\[\&_a\]\:hover\:text-foreground a:hover{color:var(--foreground)}}.\[\&_blockquote\]\:my-4 blockquote{margin-block:calc(var(--spacing) * 4)}.\[\&_blockquote\]\:border-s-4 blockquote{border-inline-start-style:var(--tw-border-style);border-inline-start-width:4px}.\[\&_blockquote\]\:border-border blockquote{border-color:var(--border)}.\[\&_blockquote\]\:ps-4 blockquote{padding-inline-start:calc(var(--spacing) * 4)}.\[\&_blockquote\]\:text-muted-foreground blockquote{color:var(--muted-foreground)}.\[\&_button\:focus-visible\]\:rounded-md button:focus-visible{border-radius:calc(var(--radius) * .8)}.\[\&_button\:focus-visible\]\:outline-3 button:focus-visible{outline-style:var(--tw-outline-style);outline-width:3px}.\[\&_button\:focus-visible\]\:outline-ring button:focus-visible{outline-color:var(--ring)}.\[\&_button\:focus-visible\]\:outline-solid button:focus-visible{--tw-outline-style:solid;outline-style:solid}.\[\&_h1\]\:mt-8 h1{margin-top:calc(var(--spacing) * 8)}.\[\&_h1\]\:mb-3 h1{margin-bottom:calc(var(--spacing) * 3)}.\[\&_h1\]\:text-3xl h1{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.\[\&_h1\]\:leading-tight h1{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.\[\&_h1\]\:font-semibold h1{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.\[\&_h1\]\:tracking-tight h1{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.\[\&_h2\]\:mt-7 h2{margin-top:calc(var(--spacing) * 7)}.\[\&_h2\]\:mb-3 h2{margin-bottom:calc(var(--spacing) * 3)}.\[\&_h2\]\:text-2xl h2{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.\[\&_h2\]\:leading-snug h2{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.\[\&_h2\]\:font-semibold h2{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.\[\&_h2\]\:tracking-tight h2{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.\[\&_h3\]\:mt-6 h3{margin-top:calc(var(--spacing) * 6)}.\[\&_h3\]\:mb-2 h3{margin-bottom:calc(var(--spacing) * 2)}.\[\&_h3\]\:text-xl h3{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.\[\&_h3\]\:leading-snug h3{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.\[\&_h3\]\:font-semibold h3{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.\[\&_h4\]\:mt-5 h4{margin-top:calc(var(--spacing) * 5)}.\[\&_h4\]\:mb-2 h4{margin-bottom:calc(var(--spacing) * 2)}.\[\&_h4\]\:text-lg h4{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.\[\&_h4\]\:font-semibold h4{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.\[\&_h5\]\:mt-4 h5{margin-top:calc(var(--spacing) * 4)}.\[\&_h5\]\:mb-2 h5{margin-bottom:calc(var(--spacing) * 2)}.\[\&_h5\]\:font-semibold h5{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.\[\&_h6\]\:mt-4 h6{margin-top:calc(var(--spacing) * 4)}.\[\&_h6\]\:mb-2 h6{margin-bottom:calc(var(--spacing) * 2)}.\[\&_h6\]\:font-semibold h6{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.\[\&_hr\]\:my-6 hr{margin-block:calc(var(--spacing) * 6)}.\[\&_hr\]\:border-border hr{border-color:var(--border)}.\[\&_img\]\:my-4 img{margin-block:calc(var(--spacing) * 4)}.\[\&_img\]\:size-full img{width:100%;height:100%}.\[\&_img\]\:h-auto img{height:auto}.\[\&_img\]\:w-full img{width:100%}.\[\&_img\]\:max-w-full img{max-width:100%}.\[\&_img\]\:rounded-lg img{border-radius:var(--radius)}.\[\&_img\]\:rounded-xl img{border-radius:calc(var(--radius) * 1.3333)}.\[\&_img\]\:object-cover img{object-fit:cover}.\[\&_label\]\:text-xs label{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_li\]\:my-1 li{margin-block:var(--spacing)}.\[\&_li\]\:ps-1 li{padding-inline-start:var(--spacing)}.\[\&_li\:\:marker\]\:text-muted-foreground li::marker{color:var(--muted-foreground)}.\[\&_li\>p\]\:my-0 li>p{margin-block:0}.\[\&_ol\]\:my-3 ol{margin-block:calc(var(--spacing) * 3)}.\[\&_ol\]\:list-decimal ol{list-style-type:decimal}.\[\&_ol\]\:ps-6 ol{padding-inline-start:calc(var(--spacing) * 6)}.\[\&_p\]\:my-3 p{margin-block:calc(var(--spacing) * 3)}.\[\&_p\:not\(\:last-child\)\]\:mb-4 p:not(:last-child){margin-bottom:calc(var(--spacing) * 4)}@media (pointer:coarse){.touch\:\[\&_select\]\:h-11 select{height:calc(var(--spacing) * 11)}}.\[\&_strong\]\:font-semibold strong{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:mt-0\.5 svg{margin-top:calc(var(--spacing) * .5)}.\[\&_svg\]\:size-3 svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&_svg\]\:size-3\.5 svg{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:size-5 svg{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.\[\&_svg\]\:size-6 svg{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.\[\&_svg\]\:size-full svg{width:100%;height:100%}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-3 svg:not([class*=size-]){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-3\.5 svg:not([class*=size-]){width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\:not\(\[class\*\=\\\'size-\\\'\]\)\]\:size-3 svg:not([class*="'size-'"]){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&_svg\:not\(\[class\*\=\\\'size-\\\'\]\)\]\:size-3\.5 svg:not([class*="'size-'"]){width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&_svg\:not\(\[class\*\=\\\'size-\\\'\]\)\]\:size-4 svg:not([class*="'size-'"]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_table\]\:w-full table{width:100%}.\[\&_table\]\:border-collapse table{border-collapse:collapse}.\[\&_table\]\:text-sm table{font-size:var(--text-sm);line-height:var(--tw-leading,var(--onu-line-height,1.5714))}.\[\&_tbody_tr\:nth-child\(even\)\]\:bg-muted\/30 tbody tr:nth-child(2n){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.\[\&_tbody_tr\:nth-child\(even\)\]\:bg-muted\/30 tbody tr:nth-child(2n){background-color:color-mix(in oklab, var(--muted) 30%, transparent)}}.\[\&_tbody_tr\:nth-child\(odd\)\]\:bg-muted\/40 tbody tr:nth-child(odd){background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.\[\&_tbody_tr\:nth-child\(odd\)\]\:bg-muted\/40 tbody tr:nth-child(odd){background-color:color-mix(in oklab, var(--muted) 40%, transparent)}}.\[\&_td\]\:border td{border-style:var(--tw-border-style);border-width:1px}.\[\&_td\]\:border-border td{border-color:var(--border)}.\[\&_td\]\:px-2 td{padding-inline:calc(var(--spacing) * 2)}.\[\&_td\]\:px-3 td{padding-inline:calc(var(--spacing) * 3)}.\[\&_td\]\:py-2 td{padding-block:calc(var(--spacing) * 2)}.\[\&_td\]\:py-4 td{padding-block:calc(var(--spacing) * 4)}.\[\&_td\]\:text-start td{text-align:start}.\[\&_td\]\:align-top td{vertical-align:top}.\[\&_td\>p\]\:my-0 td>p{margin-block:0}.\[\&_th\]\:border th{border-style:var(--tw-border-style);border-width:1px}.\[\&_th\]\:border-border th{border-color:var(--border)}.\[\&_th\]\:bg-muted th{background-color:var(--muted)}.\[\&_th\]\:px-2 th{padding-inline:calc(var(--spacing) * 2)}.\[\&_th\]\:px-3 th{padding-inline:calc(var(--spacing) * 3)}.\[\&_th\]\:py-2 th{padding-block:calc(var(--spacing) * 2)}.\[\&_th\]\:py-4 th{padding-block:calc(var(--spacing) * 4)}.\[\&_th\]\:text-start th{text-align:start}.\[\&_th\]\:align-top th{vertical-align:top}.\[\&_th\]\:font-medium th{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.\[\&_th\>p\]\:my-0 th>p{margin-block:0}.\[\&_thead\]\:sticky thead{position:sticky}.\[\&_thead\]\:top-0 thead{top:0}.\[\&_thead\]\:z-10 thead{z-index:10}.\[\&_thead\]\:bg-background thead{background-color:var(--background)}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&_ul\]\:my-3 ul{margin-block:calc(var(--spacing) * 3)}.\[\&_ul\]\:list-disc ul{list-style-type:disc}.\[\&_ul\]\:ps-6 ul{padding-inline-start:calc(var(--spacing) * 6)}.\[\&\+\[data-slot\=item-content\]\]\:flex-none+[data-slot=item-content]{flex:none}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}.\[\&\:\:-webkit-scrollbar\]\:hidden::-webkit-scrollbar{display:none}.\[\&\:\:-webkit-search-cancel-button\]\:appearance-none::-webkit-search-cancel-button{appearance:none}.\[\&\:first-child\[data-selected\=true\]_button\]\:rounded-s-\(--cell-radius\):first-child[data-selected=true] button{border-start-start-radius:var(--cell-radius);border-end-start-radius:var(--cell-radius)}.\[\&\:has\(\[data-slot\=page-title\]\[data-variant\=band\]\)_\[data-slot\=app-layout-breadcrumbs\]\]\:hidden:has([data-slot=page-title][data-variant=band]) [data-slot=app-layout-breadcrumbs]{display:none}.\[\&\:has\(\[role\=checkbox\]\)\]\:pe-0:has([role=checkbox]){padding-inline-end:0}.\[\.border-b\]\:pb-\(--card-spacing\).border-b{padding-bottom:var(--card-spacing)}.\[\.border-b\]\:pb-2.border-b{padding-bottom:calc(var(--spacing) * 2)}.\[\.border-t\]\:pt-2.border-t{padding-top:calc(var(--spacing) * 2)}:is(.\*\*\:\[\[cmdk-group-heading\]\]\:px-2 *)[cmdk-group-heading]{padding-inline:calc(var(--spacing) * 2)}:is(.\*\*\:\[\[cmdk-group-heading\]\]\:py-1\.5 *)[cmdk-group-heading]{padding-block:calc(var(--spacing) * 1.5)}:is(.\*\*\:\[\[cmdk-group-heading\]\]\:text-xs *)[cmdk-group-heading]{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}:is(.\*\*\:\[\[cmdk-group-heading\]\]\:font-medium *)[cmdk-group-heading]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}:is(.\*\*\:\[\[cmdk-group-heading\]\]\:text-muted-foreground *)[cmdk-group-heading]{color:var(--muted-foreground)}.\[a\]\:transition-colors:is(a){transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}:is(.\*\:\[a\]\:underline>*):is(a){text-decoration-line:underline}:is(.\*\:\[a\]\:underline-offset-3>*):is(a){text-underline-offset:3px}@media (hover:hover){.\[a\]\:hover\:bg-destructive\/20:is(a):hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.\[a\]\:hover\:bg-destructive\/20:is(a):hover{background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.\[a\]\:hover\:bg-muted:is(a):hover{background-color:var(--muted)}.\[a\]\:hover\:bg-primary\/80:is(a):hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.\[a\]\:hover\:bg-primary\/80:is(a):hover{background-color:color-mix(in oklab, var(--primary) 80%, transparent)}}.\[a\]\:hover\:bg-secondary\/80:is(a):hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.\[a\]\:hover\:bg-secondary\/80:is(a):hover{background-color:color-mix(in oklab, var(--secondary) 80%, transparent)}}.\[a\]\:hover\:text-muted-foreground:is(a):hover{color:var(--muted-foreground)}:is(.\*\:\[a\]\:hover\:text-foreground>*):is(a):hover{color:var(--foreground)}}:is(.\*\:\[img\:first-child\]\:rounded-t-xl>*):is(img:first-child){border-top-left-radius:calc(var(--radius) * 1.3333);border-top-right-radius:calc(var(--radius) * 1.3333)}:is(.\*\:\[img\:last-child\]\:rounded-b-xl>*):is(img:last-child){border-bottom-right-radius:calc(var(--radius) * 1.3333);border-bottom-left-radius:calc(var(--radius) * 1.3333)}:is(.\*\:\[span\]\:last\:flex>*):is(span):last-child{display:flex}:is(.\*\:\[span\]\:last\:items-center>*):is(span):last-child{align-items:center}:is(.\*\:\[span\]\:last\:gap-2>*):is(span):last-child{gap:calc(var(--spacing) * 2)}:is(.\*\:\[svg\]\:row-span-2>*):is(svg){grid-row:span 2/span 2}:is(.\*\:\[svg\]\:translate-y-0\.5>*):is(svg){--tw-translate-y:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}:is(.\*\:\[svg\]\:text-current>*):is(svg){color:currentColor}:is(.\*\:\[svg\]\:text-destructive>*):is(svg){color:var(--destructive)}:is(.\*\:\[svg\]\:text-info>*):is(svg){color:var(--info)}:is(.\*\:\[svg\]\:text-muted-foreground>*):is(svg){color:var(--muted-foreground)}:is(.\*\:\[svg\]\:text-success>*):is(svg){color:var(--success)}:is(.\*\:\[svg\]\:text-warning>*):is(svg){color:var(--warning)}:is(.focus\:\*\:\[svg\]\:text-accent-foreground:focus>*):is(svg){color:var(--accent-foreground)}:is(.data-\[variant\=destructive\]\:\*\:\[svg\]\:text-destructive[data-variant=destructive]>*):is(svg){color:var(--destructive)}:is(.data-\[variant\=destructive\]\:\*\:\[svg\]\:text-destructive\![data-variant=destructive]>*):is(svg){color:var(--destructive)!important}:is(.data-selected\:\*\:\[svg\]\:text-accent-foreground:where([data-selected=true])>*):is(svg){color:var(--accent-foreground)}:is(.\*\:\[svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4>*):is(svg:not([class*=size-])){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}:is(.\*\:\[svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-6>*):is(svg:not([class*=size-])){width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}:is(.\*\:\[svg\:not\(\[class\*\=\\\'size-\\\'\]\)\]\:size-4>*):is(svg:not([class*="'size-'"])){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\:lang\(dv\)\]\:leading-10:lang(dv){--tw-leading:calc(var(--spacing) * 10);line-height:calc(var(--spacing) * 10)}.\[\&\:lang\(dv\)\]\:tracking-normal:lang(dv){--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.\[\&\:last-child\[data-selected\=true\]_button\]\:rounded-e-\(--cell-radius\):last-child[data-selected=true] button{border-start-end-radius:var(--cell-radius);border-end-end-radius:var(--cell-radius)}.\[\&\:not\(\[data-outside\]\)\]\:text-destructive:not([data-outside]){color:var(--destructive)}.\[\&\:nth-child\(2\)\[data-selected\=true\]_button\]\:rounded-s-\(--cell-radius\):nth-child(2)[data-selected=true] button{border-start-start-radius:var(--cell-radius);border-end-start-radius:var(--cell-radius)}.\[\&\>\*\]\:w-full>*{width:100%}.\[\&\>\*\:first-child\]\:mt-0>:first-child{margin-top:0}.\[\&\>\*\:last-child\]\:mb-0>:last-child{margin-bottom:0}.\[\&\>\*\:not\(\:first-child\)\]\:rounded-s-none>:not(:first-child){border-start-start-radius:0;border-end-start-radius:0}.\[\&\>\*\:not\(\:first-child\)\]\:rounded-t-none>:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.\[\&\>\*\:not\(\:first-child\)\]\:border-s-0>:not(:first-child){border-inline-start-style:var(--tw-border-style);border-inline-start-width:0}.\[\&\>\*\:not\(\:first-child\)\]\:border-t-0>:not(:first-child){border-top-style:var(--tw-border-style);border-top-width:0}.\[\&\>\*\:not\(\:last-child\)\]\:rounded-e-none>:not(:last-child){border-start-end-radius:0;border-end-end-radius:0}.\[\&\>\*\:not\(\:last-child\)\]\:rounded-b-none>:not(:last-child){border-bottom-right-radius:0;border-bottom-left-radius:0}.\[\&\>\.sr-only\]\:w-auto>.sr-only{width:auto}.\[\&\>\:not\(img\)\]\:px-\(--card-spacing\)>:not(img){padding-inline:var(--card-spacing)}.\[\&\>\[data-slot\=button\]\]\:h-11>[data-slot=button]{height:calc(var(--spacing) * 11)}.\[\&\>\[data-slot\=button\]\]\:rounded-lg>[data-slot=button]{border-radius:var(--radius)}.\[\&\>\[data-slot\=button\]\]\:text-\[0\.9375rem\]>[data-slot=button]{font-size:.9375rem}.\[\&\>\[data-slot\=button\]\]\:font-semibold>[data-slot=button]{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:\[\&\>\[data-slot\=button\]\]\:size-8)>[data-slot=button]{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:\[\&\>\[data-slot\=button\]\]\:min-w-0)>[data-slot=button]{min-width:0}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:\[\&\>\[data-slot\=button\]\]\:gap-0)>[data-slot=button]{gap:0}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:\[\&\>\[data-slot\=button\]\]\:p-0)>[data-slot=button]{padding:0}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:\[\&\>\[data-slot\=button\]\]\:text-\[0px\])>[data-slot=button]{font-size:0}.has-\[select\[aria-hidden\=true\]\:last-child\]\:\[\&\>\[data-slot\=select-trigger\]\:last-of-type\]\:rounded-e-lg:has(:is(select[aria-hidden=true]:last-child))>[data-slot=select-trigger]:last-of-type{border-start-end-radius:var(--radius);border-end-end-radius:var(--radius)}.\[\&\>\[data-slot\=select-trigger\]\:not\(\[class\*\=\'w-\'\]\)\]\:w-fit>[data-slot=select-trigger]:not([class*=w-]),.\[\&\>\[data-slot\=select-trigger\]\:not\(\[class\*\=\\\'w-\\\'\]\)\]\:w-fit>[data-slot=select-trigger]:not([class*="'w-'"]){width:fit-content}.\[\&\>\[data-slot\]\:not\(\:has\(\~\[data-slot\]\)\)\]\:rounded-e-lg\!>[data-slot]:not(:has(~[data-slot])){border-start-end-radius:var(--radius)!important;border-end-end-radius:var(--radius)!important}.\[\&\>\[data-slot\]\:not\(\:has\(\~\[data-slot\]\)\)\]\:rounded-b-lg\!>[data-slot]:not(:has(~[data-slot])){border-bottom-right-radius:var(--radius)!important;border-bottom-left-radius:var(--radius)!important}.has-\[\>\[data-slot\=field-content\]\]\:\[\&\>\[role\=checkbox\]\,\[role\=radio\]\]\:mt-px:has(>[data-slot=field-content])>[role=checkbox],.has-\[\>\[data-slot\=field-content\]\]\:\[\&\>\[role\=checkbox\]\,\[role\=radio\]\]\:mt-px:has(>[data-slot=field-content]) [role=radio]{margin-top:1px}@container field-group (min-width:28rem){.\@md\/field-group\:has-\[\>\[data-slot\=field-content\]\]\:\[\&\>\[role\=checkbox\]\,\[role\=radio\]\]\:mt-px:has(>[data-slot=field-content])>[role=checkbox],.\@md\/field-group\:has-\[\>\[data-slot\=field-content\]\]\:\[\&\>\[role\=checkbox\]\,\[role\=radio\]\]\:mt-px:has(>[data-slot=field-content]) [role=radio]{margin-top:1px}}.\[\&\>a\]\:underline>a{text-decoration-line:underline}.\[\&\>a\]\:underline-offset-4>a{text-underline-offset:4px}.\[\&\>a\:hover\]\:text-primary>a:hover{color:var(--primary)}.\[\&\>button\]\:hidden>button{display:none}.\[\&\>button\]\:font-semibold>button{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.\[\&\>button\]\:underline>button{text-decoration-line:underline}.\[\&\>button\]\:decoration-primary>button{-webkit-text-decoration-color:var(--primary);-webkit-text-decoration-color:var(--primary);text-decoration-color:var(--primary)}.\[\&\>button\]\:decoration-2>button{text-decoration-thickness:2px}.\[\&\>button\]\:underline-offset-4>button{text-underline-offset:4px}.\[\&\>img\]\:size-full>img{width:100%;height:100%}.\[\&\>img\]\:object-cover>img{object-fit:cover}.\[\&\>input\]\:flex-1>input{flex:1}.has-\[\>\[data-align\=block-end\]\]\:\[\&\>input\]\:pt-3:has(>[data-align=block-end])>input{padding-top:calc(var(--spacing) * 3)}.has-\[\>\[data-align\=block-start\]\]\:\[\&\>input\]\:pb-3:has(>[data-align=block-start])>input{padding-bottom:calc(var(--spacing) * 3)}.has-\[\>\[data-align\=inline-end\]\]\:\[\&\>input\]\:pe-1\.5:has(>[data-align=inline-end])>input{padding-inline-end:calc(var(--spacing) * 1.5)}.has-\[\>\[data-align\=inline-start\]\]\:\[\&\>input\]\:ps-1\.5:has(>[data-align=inline-start])>input{padding-inline-start:calc(var(--spacing) * 1.5)}.\[\&\>kbd\]\:rounded-\[calc\(var\(--radius\)-5px\)\]>kbd{border-radius:calc(var(--radius) - 5px)}.\[\&\>span\]\:text-xs>span{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&\>span\]\:opacity-70>span{opacity:.7}.\[\&\>span\:last-child\]\:truncate>span:last-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.\[\&\>svg\]\:pointer-events-none>svg{pointer-events:none}.\[\&\>svg\]\:mt-0\.5>svg{margin-top:calc(var(--spacing) * .5)}.\[\&\>svg\]\:size-3>svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&\>svg\]\:size-3\!>svg{width:calc(var(--spacing) * 3)!important;height:calc(var(--spacing) * 3)!important}.\[\&\>svg\]\:size-3\.5>svg{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&\>svg\]\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\]\:size-5>svg{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.\[\&\>svg\]\:h-2\.5>svg{height:calc(var(--spacing) * 2.5)}.\[\&\>svg\]\:h-3>svg{height:calc(var(--spacing) * 3)}.\[\&\>svg\]\:w-2\.5>svg{width:calc(var(--spacing) * 2.5)}.\[\&\>svg\]\:w-3>svg{width:calc(var(--spacing) * 3)}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>svg\]\:text-info>svg{color:var(--info)}.\[\&\>svg\]\:text-muted-foreground>svg{color:var(--muted-foreground)}.\[\&\>svg\]\:text-sidebar-accent-foreground>svg{color:var(--sidebar-accent-foreground)}.\[\&\>svg\]\:text-success>svg{color:var(--success)}.\[\&\>svg\]\:text-warning>svg{color:var(--warning)}:is(:where(.group\/avatar-group):has([data-size=lg]) .group-has-data-\[size\=lg\]\/avatar-group\:\[\&\>svg\]\:size-5)>svg{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}:is(:where(.group\/avatar-group):has([data-size=sm]) .group-has-data-\[size\=sm\]\/avatar-group\:\[\&\>svg\]\:size-3)>svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}:is(:where(.group\/avatar)[data-size=default] .group-data-\[size\=default\]\/avatar\:\[\&\>svg\]\:size-2)>svg,:is(:where(.group\/avatar)[data-size=lg] .group-data-\[size\=lg\]\/avatar\:\[\&\>svg\]\:size-2)>svg{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}:is(:where(.group\/avatar)[data-size=sm] .group-data-\[size\=sm\]\/avatar\:\[\&\>svg\]\:hidden)>svg{display:none}:is(.data-active\:\[\&\>svg\]\:text-primary:where([data-state=active]),.data-active\:\[\&\>svg\]\:text-primary:where([data-active]:not([data-active=false])))>svg{color:var(--primary)}:is(.data-active\:\[\&\>svg\]\:text-sidebar-primary:where([data-state=active]),.data-active\:\[\&\>svg\]\:text-sidebar-primary:where([data-active]:not([data-active=false])))>svg{color:var(--sidebar-primary)}.\[\&\>svg\:first-child\]\:size-4>svg:first-child{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-3\.5>svg:not([class*=size-]){width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&\>svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4>svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\:not\(\[class\*\=\\\'size-\\\'\]\)\]\:size-3\.5>svg:not([class*="'size-'"]){width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&\>svg\:not\(\[class\*\=\\\'size-\\\'\]\)\]\:size-4>svg:not([class*="'size-'"]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}[data-side=left][data-collapsible=offcanvas] .\[\[data-side\=left\]\[data-collapsible\=offcanvas\]_\&\]\:-end-2{inset-inline-end:calc(var(--spacing) * -2)}[data-side=left][data-state=collapsed] .\[\[data-side\=left\]\[data-state\=collapsed\]_\&\]\:cursor-e-resize{cursor:e-resize}[data-side=left][data-state=collapsed] .rtl\:\[\[data-side\=left\]\[data-state\=collapsed\]_\&\]\:cursor-w-resize:where(:dir(rtl),[dir=rtl],[dir=rtl] *){cursor:w-resize}[data-side=right][data-collapsible=offcanvas] .\[\[data-side\=right\]\[data-collapsible\=offcanvas\]_\&\]\:-start-2{inset-inline-start:calc(var(--spacing) * -2)}[data-side=right][data-state=collapsed] .\[\[data-side\=right\]\[data-state\=collapsed\]_\&\]\:cursor-w-resize{cursor:w-resize}[data-side=right][data-state=collapsed] .rtl\:\[\[data-side\=right\]\[data-state\=collapsed\]_\&\]\:cursor-e-resize:where(:dir(rtl),[dir=rtl],[dir=rtl] *){cursor:e-resize}[data-state=indeterminate] .\[\[data-state\=indeterminate\]_\&\]\:block{display:block}[data-state=indeterminate] .\[\[data-state\=indeterminate\]_\&\]\:hidden{display:none}[data-state=open]>.\[\[data-state\=open\]\>\&\]\:block{display:block}[data-state=open]>.\[\[data-state\=open\]\>\&\]\:hidden{display:none}[data-state=open]>.\[\[data-state\=open\]\>\&\]\:rotate-180{rotate:180deg}[data-variant=legend]+.\[\[data-variant\=legend\]\+\&\]\:-mt-1\.5{margin-top:calc(var(--spacing) * -1.5)}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}@property --scroll-fade-t{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-b{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-s{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-e{syntax:"";inherits:false;initial-value:0}@property --scroll-fade-mask{syntax:"*";inherits:false}@property --shimmer-angle{syntax:"";inherits:true;initial-value:20deg}@property --shimmer-image{syntax:"*";inherits:false}@property --shimmer-text-fill{syntax:"*";inherits:false}@media (prefers-reduced-motion:reduce){.shimmer{-webkit-text-fill-color:currentColor;background-image:none;animation:none}}:root{--onu-primary:oklch(56.2% .251 283.7);--onu-background:oklch(100% 0 0);--onu-foreground:oklch(23.9% 0 0);--onu-card:oklch(100% 0 0);--onu-card-foreground:oklch(23.9% 0 0);--onu-popover:oklch(100% 0 0);--onu-popover-foreground:oklch(23.9% 0 0);--onu-neutral-secondary:oklch(95.5% 0 0);--onu-neutral-secondary-foreground:oklch(23.9% 0 0);--onu-neutral-muted:oklch(98.5% 0 0);--onu-neutral-muted-foreground:oklch(46.4% 0 0);--onu-neutral-accent:oklch(97% 0 0);--onu-neutral-accent-foreground:oklch(23.9% 0 0);--onu-destructive:oklch(54.3% .213 25.9);--onu-destructive-foreground:oklch(100% 0 0);--onu-success:oklch(50.2% .16 140);--onu-success-foreground:oklch(100% 0 0);--onu-warning:oklch(80.2% .165 76);--onu-warning-foreground:oklch(23.9% 0 0);--onu-info:oklch(50.4% .21 261);--onu-info-foreground:oklch(100% 0 0);--onu-neutral-border:oklch(95.5% 0 0);--onu-neutral-input:oklch(88.5% 0 0);--onu-neutral-sidebar:oklch(96.7% .003 84.6);--onu-sidebar-foreground:oklch(23.9% 0 0);--onu-neutral-sidebar-accent:oklch(93.4% .003 84.6);--onu-neutral-sidebar-accent-foreground:oklch(23.9% 0 0);--onu-neutral-sidebar-border:oklch(91.7% .005 78.3);--onu-shell:oklch(96.7% .003 84.6);--onu-shell-foreground:oklch(23.9% 0 0);--onu-shell-border:oklch(91.7% .005 78.3);--onu-shell-field:oklch(100% 0 0);--onu-shell-hover:oklch(81.1% 0 0/.2);--onu-shell-active:oklch(80.9% .004 67.8/.35);--onu-shell-weak:oklch(92.9% .005 67.8);--onu-layout:oklch(97% 0 0);--onu-overlay:oklch(0% 0 0/.1);--onu-preset-blue:oklch(96% .021 241.3);--onu-preset-blue-border:oklch(81.9% .096 247.3);--onu-preset-blue-foreground:oklch(50.4% .21 261);--onu-preset-cyan:oklch(98.1% .026 185.2);--onu-preset-cyan-border:oklch(86.8% .093 187.1);--onu-preset-cyan-foreground:oklch(48.7% .083 203.7);--onu-preset-green:oklch(98.8% .025 128.7);--onu-preset-green-border:oklch(88.3% .131 132.5);--onu-preset-green-foreground:oklch(50.2% .16 140);--onu-preset-red:oklch(96.9% .015 22.4);--onu-preset-red-border:oklch(80.6% .11 23.2);--onu-preset-red-foreground:oklch(46.3% .184 25.2);--onu-preset-gold:oklch(98.6% .028 98.1);--onu-preset-gold-border:oklch(92.5% .11 93.2);--onu-preset-gold-foreground:oklch(47.8% .109 63.2);--onu-chart-2:oklch(73.8% .124 194.8);--onu-chart-3:oklch(72.6% .218 138.5);--onu-chart-4:oklch(80.2% .165 76);--onu-chart-5:oklch(62.1% .238 26.1);--onu-chart-6:oklch(52.2% .23 266.8);--onu-chart-7:oklch(63.4% .235 353.2);--onu-chart-8:oklch(49.4% .228 295.6);--onu-radius:.375rem;--onu-tint:0%;--onu-font-sans:"Inter Variable", Faruma, "MV Faseyha", "Noto Sans Thaana Variable", ui-sans-serif, system-ui, sans-serif;--onu-font-thaana:Faruma, "MV Faseyha", "Noto Sans Thaana Variable", "Inter Variable", sans-serif;--onu-font-thaana-bold:"MV Faseyha", Faruma, "Noto Sans Thaana Variable", "Inter Variable", sans-serif;--onu-font-mono:"JetBrains Mono Variable", ui-monospace, SFMono-Regular, Menlo, monospace;--onu-font-serif:"Source Serif 4 Variable", "MV Faseyha", Georgia, serif;--onu-font-size:.875rem;--onu-line-height:1.5714;--onu-label-width:12rem;--onu-touch-target:44px;--onu-density-compact:.225rem;--onu-density-default:.25rem;--onu-density-comfortable:.28rem;--onu-density-touch:.345rem}:root.dark,:root[data-theme=dark],.dark,[data-theme=dark]{--onu-background:oklch(23.9% 0 0);--onu-foreground:oklch(91.6% 0 0);--onu-card:oklch(23.9% 0 0);--onu-card-foreground:oklch(91.6% 0 0);--onu-popover:oklch(26.9% 0 0);--onu-popover-foreground:oklch(91.6% 0 0);--onu-neutral-secondary:oklch(30.9% 0 0);--onu-neutral-secondary-foreground:oklch(91.6% 0 0);--onu-neutral-muted:oklch(26.9% 0 0);--onu-neutral-muted-foreground:oklch(72.5% 0 0);--onu-neutral-accent:oklch(28.9% 0 0);--onu-neutral-accent-foreground:oklch(95.5% 0 0);--onu-destructive:oklch(76% .14 23);--onu-destructive-foreground:oklch(19.1% 0 0);--onu-success:oklch(72.2% .185 136.3);--onu-success-foreground:oklch(19.1% 0 0);--onu-warning:oklch(72% .147 76.4);--onu-warning-foreground:oklch(19.1% 0 0);--onu-info:oklch(72.1% .129 251.8);--onu-info-foreground:oklch(19.1% 0 0);--onu-neutral-border:oklch(30.9% 0 0);--onu-neutral-input:oklch(37.9% 0 0);--onu-neutral-sidebar:oklch(19.7% .016 296.4);--onu-sidebar-foreground:oklch(100% 0 0);--onu-neutral-sidebar-accent:oklch(26.2% .017 295.4);--onu-neutral-sidebar-accent-foreground:oklch(100% 0 0);--onu-neutral-sidebar-border:oklch(28% .022 292.6);--onu-shell:oklch(19.7% .016 296.4);--onu-shell-foreground:oklch(100% 0 0);--onu-shell-border:oklch(32.3% .027 294);--onu-shell-field:oklch(28% .022 292.6);--onu-shell-hover:oklch(46.8% .032 294.3/.2);--onu-shell-active:oklch(46.8% .032 294.3/.4);--onu-shell-weak:oklch(36.3% .029 295.7);--onu-layout:oklch(19.1% 0 0);--onu-overlay:oklch(0% 0 0/.1);--onu-preset-blue:oklch(21.9% .038 263.3);--onu-preset-blue-border:oklch(31.9% .081 257.5);--onu-preset-blue-foreground:oklch(72.1% .129 251.8);--onu-preset-cyan:oklch(23.5% .022 205.8);--onu-preset-cyan-border:oklch(36.8% .054 195.1);--onu-preset-cyan-foreground:oklch(72.4% .113 191.3);--onu-preset-green:oklch(23.8% .036 138.5);--onu-preset-green-border:oklch(36.7% .088 136.7);--onu-preset-green-foreground:oklch(72.2% .185 136.3);--onu-preset-red:oklch(21.9% .04 13);--onu-preset-red-border:oklch(31.6% .094 20.9);--onu-preset-red-foreground:oklch(70.6% .158 23.3);--onu-preset-gold:oklch(25.5% .031 78.4);--onu-preset-gold-border:oklch(39.5% .069 81.3);--onu-preset-gold-foreground:oklch(79.5% .145 83.9);--onu-chart-2:oklch(66.4% .111 194.8);--onu-chart-3:oklch(65.4% .194 138.3);--onu-chart-4:oklch(72% .147 76.4);--onu-chart-5:oklch(60.6% .189 24.1);--onu-chart-6:oklch(59.2% .22 269.6);--onu-chart-7:oklch(57.1% .208 352.6);--onu-chart-8:oklch(54.8% .185 300.9)}@font-face{font-family:Faruma;font-style:normal;font-weight:400;font-display:swap;src:url(./fonts/faruma.woff2)format("woff2");unicode-range:U+780-7BF,U+FDF2,U+60C,U+61B,U+61F,U+25CC}@font-face{font-family:MV Faseyha;font-style:normal;font-weight:400;font-display:swap;src:url(./fonts/mv-faseyha.woff2)format("woff2");unicode-range:U+780-7BF,U+FDF2,U+60C,U+61B,U+61F,U+25CC}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary:var(--onu-primary);--primary-foreground:var(--onu-primary-foreground,oklch(98.5% 0 0));--primary-hover:var(--primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-hover:color-mix(in oklab, var(--primary), black 10%)}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-active:var(--primary-7);--primary-subtle:var(--primary-1);--primary-subtle-foreground:var(--primary-8);--primary-1:var(--primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-1:color-mix(in oklab, var(--primary) 10%, var(--background))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-2:var(--primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-2:color-mix(in oklab, var(--primary) 22%, var(--background))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-3:var(--primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-3:color-mix(in oklab, var(--primary) 40%, var(--background))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-4:var(--primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-4:color-mix(in oklab, var(--primary) 60%, var(--background))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-5:var(--primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-5:color-mix(in oklab, var(--primary) 80%, var(--background))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-6:var(--primary);--primary-7:var(--primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-7:color-mix(in oklab, var(--primary) 86%, black)}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-8:var(--primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-8:color-mix(in oklab, var(--primary) 70%, black)}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--background:var(--onu-background);--foreground:var(--onu-foreground);--card:var(--onu-card);--card-foreground:var(--onu-card-foreground);--popover:var(--onu-popover);--popover-foreground:var(--onu-popover-foreground);--secondary:var(--onu-secondary,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--secondary:var(--onu-secondary,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-secondary), var(--onu-neutral-secondary)) var(--onu-tint,100%), var(--onu-neutral-secondary)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--secondary-foreground:var(--onu-secondary-foreground,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--secondary-foreground:var(--onu-secondary-foreground,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-secondary-foreground), var(--onu-neutral-secondary-foreground)) var(--onu-tint,100%), var(--onu-neutral-secondary-foreground)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--muted:var(--onu-muted,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--muted:var(--onu-muted,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-muted), var(--onu-neutral-muted)) var(--onu-tint,100%), var(--onu-neutral-muted)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--muted-foreground:var(--onu-muted-foreground,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--muted-foreground:var(--onu-muted-foreground,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-muted-foreground), var(--onu-neutral-muted-foreground)) var(--onu-tint,100%), var(--onu-neutral-muted-foreground)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--accent:var(--onu-accent,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--accent:var(--onu-accent,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-accent), var(--onu-neutral-accent)) var(--onu-tint,100%), var(--onu-neutral-accent)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--accent-foreground:var(--onu-accent-foreground,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--accent-foreground:var(--onu-accent-foreground,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-accent-foreground), var(--onu-neutral-accent-foreground)) var(--onu-tint,100%), var(--onu-neutral-accent-foreground)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--destructive:var(--onu-destructive);--destructive-foreground:var(--onu-destructive-foreground);--success:var(--onu-success);--success-foreground:var(--onu-success-foreground);--warning:var(--onu-warning);--warning-foreground:var(--onu-warning-foreground);--info:var(--onu-info);--info-foreground:var(--onu-info-foreground);--border:var(--onu-border,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--border:var(--onu-border,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-border), var(--onu-neutral-border)) var(--onu-tint,100%), var(--onu-neutral-border)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--input:var(--onu-input,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--input:var(--onu-input,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-input), var(--onu-neutral-input)) var(--onu-tint,100%), var(--onu-neutral-input)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--ring:var(--onu-ring,var(--primary));--chart-1:var(--onu-chart-1,var(--primary));--chart-2:var(--onu-chart-2);--chart-3:var(--onu-chart-3);--chart-4:var(--onu-chart-4);--chart-5:var(--onu-chart-5);--chart-6:var(--onu-chart-6);--chart-7:var(--onu-chart-7);--chart-8:var(--onu-chart-8);--sidebar:var(--onu-sidebar,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--sidebar:var(--onu-sidebar,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-sidebar), var(--onu-neutral-sidebar)) var(--onu-tint,100%), var(--onu-neutral-sidebar)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--sidebar-foreground:var(--onu-sidebar-foreground);--sidebar-primary:var(--onu-sidebar-primary,var(--primary));--sidebar-primary-foreground:var(--onu-sidebar-primary-foreground,var(--primary-foreground));--sidebar-accent:var(--onu-sidebar-accent,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--sidebar-accent:var(--onu-sidebar-accent,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-sidebar-accent), var(--onu-neutral-sidebar-accent)) var(--onu-tint,100%), var(--onu-neutral-sidebar-accent)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--sidebar-accent-foreground:var(--onu-sidebar-accent-foreground,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--sidebar-accent-foreground:var(--onu-sidebar-accent-foreground,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-sidebar-accent-foreground), var(--onu-neutral-sidebar-accent-foreground)) var(--onu-tint,100%), var(--onu-neutral-sidebar-accent-foreground)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--sidebar-border:var(--onu-sidebar-border,var(--primary))}@supports (color:color-mix(in lab, red, red)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--sidebar-border:var(--onu-sidebar-border,color-mix(in oklab, color-mix(in oklab, var(--primary) var(--tint-sidebar-border), var(--onu-neutral-sidebar-border)) var(--onu-tint,100%), var(--onu-neutral-sidebar-border)))}}:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--sidebar-ring:var(--ring);--shell:var(--onu-shell);--shell-foreground:var(--onu-shell-foreground);--shell-border:var(--onu-shell-border);--shell-field:var(--onu-shell-field);--shell-hover:var(--onu-shell-hover);--shell-active:var(--onu-shell-active);--shell-weak:var(--onu-shell-weak);--layout:var(--onu-layout);--overlay:var(--onu-overlay);--preset-blue:var(--onu-preset-blue);--preset-blue-border:var(--onu-preset-blue-border);--preset-blue-foreground:var(--onu-preset-blue-foreground);--preset-cyan:var(--onu-preset-cyan);--preset-cyan-border:var(--onu-preset-cyan-border);--preset-cyan-foreground:var(--onu-preset-cyan-foreground);--preset-green:var(--onu-preset-green);--preset-green-border:var(--onu-preset-green-border);--preset-green-foreground:var(--onu-preset-green-foreground);--preset-red:var(--onu-preset-red);--preset-red-border:var(--onu-preset-red-border);--preset-red-foreground:var(--onu-preset-red-foreground);--preset-gold:var(--onu-preset-gold);--preset-gold-border:var(--onu-preset-gold-border);--preset-gold-foreground:var(--onu-preset-gold-foreground);--popup-shadow:var(--onu-shadow-popup,0 6px 16px 0 #00000014, 0 3px 6px -4px #0000001f, 0 9px 28px 8px #0000000d);--radius:var(--onu-radius);--fa-primary-color:currentColor;--fa-secondary-color:var(--primary)}@supports (color:oklch(from red l c h)){:root,[data-onu-theme],[data-onu-tint],.dark,[data-theme=dark]{--primary-foreground:var(--onu-primary-foreground,oklch(from var(--primary) clamp(0, (.68 - l) * 1000, .985) 0 0))}}.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary:var(--onu-primary-dark,var(--onu-primary))}@supports (color:color-mix(in lab, red, red)){.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary:var(--onu-primary-dark,color-mix(in oklab, var(--onu-primary), white 18%))}}.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-hover:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-hover:color-mix(in oklab, var(--primary), white 10%)}}.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-active:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-active:color-mix(in oklab, var(--primary), white 18%)}}.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-subtle-foreground:var(--primary-7);--primary-1:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-1:color-mix(in oklab, var(--primary) 16%, var(--background))}}.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-2:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-2:color-mix(in oklab, var(--primary) 26%, var(--background))}}.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-3:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-3:color-mix(in oklab, var(--primary) 42%, var(--background))}}.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-7:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-7:color-mix(in oklab, var(--primary) 80%, white)}}.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-8:var(--primary)}@supports (color:color-mix(in lab, red, red)){.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary-8:color-mix(in oklab, var(--primary) 62%, white)}}.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--popup-shadow:var(--onu-shadow-popup,0 6px 16px 0 #00000052, 0 3px 6px -4px #0000007a, 0 9px 28px 8px #0003)}@supports (color:oklch(from red l c h)){.dark,[data-theme=dark],:is(.dark,[data-theme=dark]) :is([data-onu-theme],[data-onu-tint]){--primary:var(--onu-primary-dark,oklch(from var(--onu-primary) max(l, .72) c h))}}:root{--tint-secondary:7%;--tint-secondary-foreground:20%;--tint-muted:2%;--tint-muted-foreground:10%;--tint-accent:10%;--tint-accent-foreground:30%;--tint-border:6%;--tint-input:10%;--tint-sidebar:3%;--tint-sidebar-accent:10%;--tint-sidebar-accent-foreground:30%;--tint-sidebar-border:6%}.dark,[data-theme=dark]{--tint-secondary:10%;--tint-secondary-foreground:10%;--tint-muted:6%;--tint-muted-foreground:8%;--tint-accent:16%;--tint-accent-foreground:15%;--tint-border:4%;--tint-input:6%;--tint-sidebar:4%;--tint-sidebar-accent:16%;--tint-sidebar-accent-foreground:15%;--tint-sidebar-border:4%}[data-onu-tint=none]{--onu-tint:0%}:root{--fluid-text-sm:var(--onu-text-fluid-sm,clamp(.875rem, .8333rem + .2083vw, 1rem));--fluid-text-base:var(--onu-text-fluid-base,clamp(1rem, .9583rem + .2083vw, 1.125rem));--fluid-text-lg:var(--onu-text-fluid-lg,clamp(1.125rem, 1.042rem + .4167vw, 1.375rem));--fluid-text-xl:var(--onu-text-fluid-xl,clamp(1.25rem, 1.083rem + .8333vw, 1.75rem));--fluid-text-2xl:var(--onu-text-fluid-2xl,clamp(1.5rem, 1.25rem + 1.25vw, 2.25rem));--fluid-text-3xl:var(--onu-text-fluid-3xl,clamp(1.875rem, 1.5rem + 1.875vw, 3rem));--fluid-text-4xl:var(--onu-text-fluid-4xl,clamp(2.25rem, 1.75rem + 2.5vw, 3.75rem));--fluid-text-5xl:var(--onu-text-fluid-5xl,clamp(2.5rem, 1.833rem + 3.3333vw, 4.5rem));--fluid-leading-tight:1.1;--fluid-leading-snug:1.3;--fluid-leading-normal:1.6}:lang(dv){--fluid-leading-tight:1.5;--fluid-leading-snug:1.6;--fluid-leading-normal:1.8}:root[data-density=compact],[data-density=compact]{--spacing:var(--onu-density-compact)}:root[data-density=default],[data-density=default]{--spacing:var(--onu-density-default)}:root[data-density=comfortable],[data-density=comfortable]{--spacing:var(--onu-density-comfortable)}:root[data-density=touch],[data-density=touch]{--spacing:var(--onu-density-touch);--onu-font-size:1rem;font-size:1.0625rem}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-pan-x{syntax:"*";inherits:false}@property --tw-pan-y{syntax:"*";inherits:false}@property --tw-pinch-zoom{syntax:"*";inherits:false}@property --tw-scroll-snap-strictness{syntax:"*";inherits:false;initial-value:proximity}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}@keyframes accordion-down{0%{height:0}to{height:var(--radix-accordion-content-height,var(--accordion-panel-height,auto))}}@keyframes accordion-up{0%{height:var(--radix-accordion-content-height,var(--accordion-panel-height,auto))}to{height:0}}@keyframes caret-blink{0%,70%,to{opacity:1}20%,50%{opacity:0}}@keyframes scroll-fade-reveal-s{0%{--scroll-fade-s:0px}to{--scroll-fade-s:var(--_scroll-fade-size-s,var(--scroll-fade-size,min(12%, calc(var(--spacing) * 10))))}}@keyframes scroll-fade-reveal-e{0%{--scroll-fade-e:var(--_scroll-fade-size-e,var(--scroll-fade-size,min(12%, calc(var(--spacing) * 10))))}to{--scroll-fade-e:0px}} \ No newline at end of file diff --git a/docs/frameworks/_category_.json b/docs/frameworks/_category_.json new file mode 100644 index 0000000..71b73e4 --- /dev/null +++ b/docs/frameworks/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Frameworks", + "position": 3 +} diff --git a/docs/frameworks/bootstrap-6.md b/docs/frameworks/bootstrap-6.md new file mode 100644 index 0000000..7f8f1aa --- /dev/null +++ b/docs/frameworks/bootstrap-6.md @@ -0,0 +1,63 @@ +--- +title: Bootstrap 6 +sidebar_position: 2 +--- + +# Bootstrap 6 + +The `bootstrap-6` framework outputs [Bootstrap 6](https://getbootstrap.com) markup. It targets **Bootstrap 6.0.0-alpha.1**, the only v6 release so far, and is updated as later pre-releases change markup. + +```php +// config/forms.php +'framework' => 'bootstrap-6', +``` + +Or for one component: ``. + +## Including the styles + +Install Bootstrap 6 and import it as you normally would: + +```bash +npm install bootstrap@6.0.0-alpha.1 +``` + +```scss +@use "bootstrap/scss/bootstrap"; +``` + +Components that need JavaScript (dialogs, menus, tabs, dismissible alerts) use Bootstrap's own data attributes (`data-bs-toggle="dialog"`, `data-bs-dismiss="alert"`), so load Bootstrap's JavaScript bundle too. + +## Markup + +| Component | Markup | +| --- | --- | +| Fields | `.form-field` with `.form-label`, the control, `small.form-text` and `.invalid-feedback` | +| Select | `select.form-control` | +| Checkbox / radio | `input.check` / `input.radio` in a `.form-field` | +| Buttons | `btn-solid`, `btn-outline`, `btn-subtle` or `btn-link`, plus a `.theme-*` class | +| Status badge | `.badge.theme-*` | +| Alert | `.alert.theme-*`, with a `.btn-close` when dismissible | +| Modal | `` | +| Accordion | `
` | +| Inline fields | `sm:col-3 lg:col-2` label, `sm:col-9 lg:col-10` control | + +### Colours + +`color` and `type` attributes keep the Bootstrap 5 names; the framework maps them to Bootstrap 6 classes: + +| `color` | Classes | +| --- | --- | +| `primary`, `secondary`, `success`, `danger`, `warning`, `info` | `btn-solid theme-{color}` | +| `outline-{color}` | `btn-outline theme-{color}` | +| `light` | `btn-subtle theme-secondary` | +| `dark` | `btn-solid theme-inverse` | +| `link` | `btn-link` | + +The mapping lives in `Javaabu\Forms\Frameworks\Bootstrap6`. To change it, extend the class and register it under the same name in a service provider: + +```php +use Javaabu\Forms\Frameworks\Frameworks; + +Frameworks::register('bootstrap-6', MyBootstrap6::class); +``` diff --git a/docs/frameworks/onu.md b/docs/frameworks/onu.md new file mode 100644 index 0000000..4535d51 --- /dev/null +++ b/docs/frameworks/onu.md @@ -0,0 +1,73 @@ +--- +title: Onu +sidebar_position: 1 +--- + +# Onu + +`onu` is the default framework. The components output the same markup, `data-slot` attributes and Tailwind classes as the React components in [`@javaabu/onu`](https://github.com/Javaabu/onu), so a Blade page and an Inertia React page built with [`@javaabu/forms`](https://github.com/Javaabu/react-forms) look the same. + +```php +// config/forms.php +'framework' => env('FORMS_FRAMEWORK', 'onu'), +``` + +## Including the styles + +### Apps that build CSS with Tailwind CSS v4 (recommended) + +Install Onu and import its Tailwind entry, then the forms entry: + +```bash +npm install @javaabu/onu tailwindcss @tailwindcss/vite +``` + +```css +/* resources/css/app.css */ +@import "tailwindcss"; +@import "@javaabu/onu/tailwind.css"; +@import "../../vendor/javaabu/forms/resources/css/onu.css"; +``` + +`resources/css/onu.css` tells Tailwind to scan the package's Blade views and class map, so only the classes your pages use are built. It also styles the few native controls Onu draws with React (checkboxes, radios, file inputs and ``). Every colour, radius and font comes from Onu's tokens, so [theming Onu](https://github.com/Javaabu/onu) themes the forms too. + +### Apps without a Tailwind build + +The package ships a prebuilt stylesheet with Tailwind, Onu and the forms styles in one file, `dist/onu.css`. Publish it and link it in your layout: + +```bash +php artisan vendor:publish --tag=forms-assets +``` + +```blade + +``` + +It is about 46 KB gzipped, because it contains every Onu class. Use the Tailwind setup above when you can. + +## Right-to-left and Dhivehi + +Onu uses logical utilities (`ms-`, `pe-`, `start-`), so the components work in RTL pages unchanged. Set `dir="rtl"` and `lang="dv"` on ``; the package's Dhivehi strings load from `lang/dv`. + +## How the classes stay in sync with Onu + +The Blade views don't copy Onu's class strings by hand. `scripts/onu-classes.mjs` server-renders Onu's own React components and records the classes of every element by its `data-slot`, writing `resources/onu/classes.php`. The views read them through `Javaabu\Forms\Frameworks\Onu`: + +```blade + +``` + +CI fails when that file is out of date with the `@javaabu/onu` version in `package.json`. After upgrading Onu, run: + +```bash +pnpm install +pnpm onu-classes +pnpm build +``` + +## Differences from the React components + +- **Floating labels** don't exist in Onu. `floating` fields render with the label above, like a normal field. +- **Checkboxes and radios** are native `` elements with Onu's classes, rather than Radix buttons, so they submit with the form without JavaScript. +- **Modals** are native `` elements with Onu's modal classes. Open one with the `showModal()` browser API or the package's JavaScript (see [Assets](../advanced-usage/assets.md)). +- **Accordions** use `
`/``; items in one accordion close each other through the `name` attribute. diff --git a/lang/dv/strings.php b/lang/dv/strings.php index 71f0308..6811429 100644 --- a/lang/dv/strings.php +++ b/lang/dv/strings.php @@ -39,4 +39,6 @@ 'pagination_showing' => 'ޖުމްލަ :total އިން :count ދައްކަނީ', 'pagination_previous' => 'ކުރީގެ', 'pagination_next' => 'ދެން', + 'sections' => 'ސެކްޝަންތައް', + 'pagination' => 'ޞަފްޙާތައް', ]; diff --git a/lang/en/strings.php b/lang/en/strings.php index 66ecfd5..e82ef8d 100644 --- a/lang/en/strings.php +++ b/lang/en/strings.php @@ -39,4 +39,6 @@ 'pagination_showing' => 'Showing :count from total :total entry|Showing :count from total :total entries', 'pagination_previous' => 'Previous', 'pagination_next' => 'Next', + 'sections' => 'Sections', + 'pagination' => 'Pagination', ]; diff --git a/package.json b/package.json index 2660bc4..0b9a6d3 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,19 @@ "node": ">=20.19" }, "scripts": { - "icons": "node scripts/icons.mjs" + "build": "pnpm build:css", + "build:css": "tailwindcss -i resources/css/onu-standalone.css -o dist/onu.css --minify", + "icons": "node scripts/icons.mjs", + "onu-classes": "node scripts/onu-classes.mjs", + "check": "node scripts/onu-classes.mjs --check" }, "devDependencies": { - "lucide-static": "^1.68.0" + "@javaabu/onu": "^0.2.1", + "@tailwindcss/cli": "^4.3.4", + "lucide-static": "^1.68.0", + "react": "^19.3.1", + "react-dom": "^19.3.1", + "tailwindcss": "^4.3.4", + "tw-animate-css": "^1.4.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a3e1b70..d4fb262 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,15 +8,2783 @@ importers: .: devDependencies: + '@javaabu/onu': + specifier: ^0.2.1 + version: 0.2.1(@tanstack/react-query@5.105.3(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react-hook-form@7.91.0(react@19.3.1))(react@19.3.1)(tailwindcss@4.3.4) + '@tailwindcss/cli': + specifier: ^4.3.4 + version: 4.3.4 lucide-static: specifier: ^1.68.0 version: 1.68.0 + react: + specifier: ^19.3.1 + version: 19.3.1 + react-dom: + specifier: ^19.3.1 + version: 19.3.1(react@19.3.1) + tailwindcss: + specifier: ^4.3.4 + version: 4.3.4 + tw-animate-css: + specifier: ^1.4.0 + version: 1.4.0 packages: + '@date-fns/tz@1.5.0': + resolution: {integrity: sha512-lwYN/vDPeNRULcepoE/LO2Pgx+7/RV+S9ARfbc9lr2DtGkOD7pAiruHvbR1RX3Qyf6ja47EWJDMsNK5vK08DJg==} + + '@dnd-kit/abstract@0.5.3': + resolution: {integrity: sha512-KZQ2vftkO9BHupVzlUqB5d7JETL7ITlvslx3hrj4aObwjliAzuzV/n5wCpQllNd0Hxvg7FaQtLekJ8dplqKwbA==} + + '@dnd-kit/collision@0.5.3': + resolution: {integrity: sha512-DBo8czkI72xnsHRWOMTn/GAyYgSWy9bmde85mrZ7ShqLhcbIbcu4PVJ3ZU9MBikePCSAVOoUTZE2gS40jogrEw==} + + '@dnd-kit/dom@0.5.3': + resolution: {integrity: sha512-JJe+Qu/JmofGzHes3np91sQYwp5spvLcknjRkq+VO59JTqSnQNPXlhHXavRXTwQFabaaRyRzXyH/faAvubCNGw==} + + '@dnd-kit/geometry@0.5.3': + resolution: {integrity: sha512-U+zscNjoHfJ1xUV+XDGF89jPCoILLivWSb/U9mfM7h83f6o3X9AS9uIwG46bXUpCqPvlI/9JcOlyga5uvfyjgw==} + + '@dnd-kit/helpers@0.5.3': + resolution: {integrity: sha512-fErbbjwKMJEdr7e+AMsXaZ6aQY4xPYBMK+nqybB34tE6/lQDLetZHsgLDKNVePsYIZCq/7uWMtlFjqysscWg5A==} + + '@dnd-kit/react@0.5.3': + resolution: {integrity: sha512-BGn6bakgcRSoKMRQP8cRIGu59e5lGC3/sL0zVWmDMo/9CMPSxgjCcQltDn5TDTwAARnEbuwNEksor4rLtH/yEg==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@dnd-kit/state@0.5.3': + resolution: {integrity: sha512-NJTQkBglAT/SXLc+IOLiKwNvsTrWmPG5AO+7Gn0F0n8XyVaf4VCbTCuPuU48sDBfcpg23O0tfGkfZNiZbYTvMw==} + + '@floating-ui/core@1.8.0': + resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==} + + '@floating-ui/dom@1.8.0': + resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==} + + '@floating-ui/react-dom@2.1.9': + resolution: {integrity: sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.12': + resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==} + + '@internationalized/date@3.12.4': + resolution: {integrity: sha512-M1dEn4c1U1HsSlaVR8upZtSqvXrTkHDfv18H01uCSJyjVLDxnBR38v/fMxecmlwXKR4i9HeZcmgQAPE6A+aGJQ==} + + '@internationalized/number@3.6.9': + resolution: {integrity: sha512-GgWy2caO/+hV9sT/oCTWGHvbjmJMPT9kkXzoKRLnkEq7adghhR7UprhvY9sXrKfrp3NcDfhF6QQHXR1KfQbB8g==} + + '@internationalized/string@3.2.10': + resolution: {integrity: sha512-PDx6//vHSpRnHfxqMqto11zQvhsaU74O3mKv2F/0eicGZcl9NLjQmGlbHz/LsJh5tLKp4A4L7ZVTzN1/MmMTvA==} + + '@javaabu/onu@0.2.1': + resolution: {integrity: sha512-GE4takAQwNQqD9ZmQooH7KMBrLUoiR4UzJsDCGr6cLYigoLF22tjRD3CzrdVGVl+SAhz2jjwOozxzyvAyTNmxA==} + peerDependencies: + '@deck.gl/aggregation-layers': ^9.4.0 + '@deck.gl/core': ^9.4.0 + '@deck.gl/google-maps': ^9.4.0 + '@deck.gl/layers': ^9.4.0 + '@fontsource-variable/geist': ^5.3.0 + '@fontsource-variable/inter': ^5.3.0 + '@fontsource-variable/jetbrains-mono': ^5.3.0 + '@fontsource-variable/noto-sans-thaana': ^5.3.0 + '@fontsource-variable/source-serif-4': ^5.3.0 + '@fortawesome/fontawesome-svg-core': ^7.3.1 + '@fortawesome/react-fontawesome': ^3.5.0 + '@fullcalendar/core': ^6.1.21 + '@fullcalendar/daygrid': ^6.1.21 + '@fullcalendar/interaction': ^6.1.21 + '@fullcalendar/list': ^6.1.21 + '@fullcalendar/react': ^6.1.21 + '@fullcalendar/timegrid': ^6.1.21 + '@googlemaps/markerclusterer': ^2.6.2 + '@iconify/react': ^6.0.2 + '@tanstack/react-query': ^5.104.1 + '@tiptap/core': ^3.31.4 + '@tiptap/extension-image': ^3.31.4 + '@tiptap/extension-placeholder': ^3.31.4 + '@tiptap/extension-table': ^3.31.4 + '@tiptap/extension-text-align': ^3.31.4 + '@tiptap/pm': ^3.31.4 + '@tiptap/react': ^3.31.4 + '@tiptap/starter-kit': ^3.31.4 + '@tiptap/static-renderer': ^3.31.4 + '@tiptap/suggestion': ^3.31.4 + '@turf/turf': ^7.4.0 + '@vis.gl/react-google-maps': ^1.10.1 + barcode-detector: ^3.2.2 + media-chrome: ^4.19.3 + react: ^19.0.0 + react-dom: ^19.0.0 + react-easy-crop: ^6.2.4 + react-hook-form: ^7.89.0 + recharts: ^3.10.1 + shiki: ^4.5.0 + signature_pad: ^5.1.4 + tailwindcss: ^4.0.0 + terra-draw: ^1.37.0 + terra-draw-google-maps-adapter: ^1.7.0 + write-excel-file: ^4.1.1 + yet-another-react-lightbox: ^3.32.2 + peerDependenciesMeta: + '@deck.gl/aggregation-layers': + optional: true + '@deck.gl/core': + optional: true + '@deck.gl/google-maps': + optional: true + '@deck.gl/layers': + optional: true + '@fontsource-variable/geist': + optional: true + '@fontsource-variable/inter': + optional: true + '@fontsource-variable/jetbrains-mono': + optional: true + '@fontsource-variable/noto-sans-thaana': + optional: true + '@fontsource-variable/source-serif-4': + optional: true + '@fortawesome/fontawesome-svg-core': + optional: true + '@fortawesome/react-fontawesome': + optional: true + '@fullcalendar/core': + optional: true + '@fullcalendar/daygrid': + optional: true + '@fullcalendar/interaction': + optional: true + '@fullcalendar/list': + optional: true + '@fullcalendar/react': + optional: true + '@fullcalendar/timegrid': + optional: true + '@googlemaps/markerclusterer': + optional: true + '@iconify/react': + optional: true + '@tiptap/core': + optional: true + '@tiptap/extension-image': + optional: true + '@tiptap/extension-placeholder': + optional: true + '@tiptap/extension-table': + optional: true + '@tiptap/extension-text-align': + optional: true + '@tiptap/pm': + optional: true + '@tiptap/react': + optional: true + '@tiptap/starter-kit': + optional: true + '@tiptap/static-renderer': + optional: true + '@tiptap/suggestion': + optional: true + '@turf/turf': + optional: true + '@vis.gl/react-google-maps': + optional: true + barcode-detector: + optional: true + media-chrome: + optional: true + react-easy-crop: + optional: true + recharts: + optional: true + shiki: + optional: true + signature_pad: + optional: true + terra-draw: + optional: true + terra-draw-google-maps-adapter: + optional: true + write-excel-file: + optional: true + yet-another-react-lightbox: + optional: true + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@parcel/watcher-android-arm64@2.6.0': + resolution: {integrity: sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.6.0': + resolution: {integrity: sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.6.0': + resolution: {integrity: sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.6.0': + resolution: {integrity: sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.6.0': + resolution: {integrity: sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm-musl@2.6.0': + resolution: {integrity: sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-arm64-glibc@2.6.0': + resolution: {integrity: sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm64-musl@2.6.0': + resolution: {integrity: sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-x64-glibc@2.6.0': + resolution: {integrity: sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-x64-musl@2.6.0': + resolution: {integrity: sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@parcel/watcher-win32-arm64@2.6.0': + resolution: {integrity: sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-x64@2.6.0': + resolution: {integrity: sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.6.0': + resolution: {integrity: sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==} + engines: {node: '>= 10.0.0'} + + '@preact/signals-core@1.14.5': + resolution: {integrity: sha512-vcRv7Ityz5JVmeiVqIluLFzT/PDS/AlhHUpw3/aUWqcVUs6bDGIPXE/6RSC4evBNWYvnniozg5Syfj33al3gkg==} + + '@radix-ui/number@1.1.3': + resolution: {integrity: sha512-Road2bidD0uu/1BGDOWNdPI06g0lIRy6IF9GZcIrDK2KGItfor8IQwQa+yM2ERgHM1MmHxaxpTzk0/Jp42lNfA==} + + '@radix-ui/primitive@1.2.0': + resolution: {integrity: sha512-KABY+VMIRPJL+Vyzv/335FEhXXD/xDv8BMb1kl48/aXJZMH0LtHCTx5ga5RnxaEP3nZHtmTLf1P9vanmFX46bw==} + + '@radix-ui/react-accessible-icon@1.2.0': + resolution: {integrity: sha512-BB4+HHkFl3HipEAhm/mLhrpXV+2kRX7MvY4AaImUcQVeWQt5KhV1JEByNs8NGfJOcr95RcQGijt9+OrCo68xGA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-accordion@1.3.1': + resolution: {integrity: sha512-lCZ6sbGS/7WO0j84yx4srIgOf0MRJ/sZ13RonADXxvKBym8xrxNCq5f6DibGcr38sIlwPk8/52uYdXeOPsbEDw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-alert-dialog@1.2.1': + resolution: {integrity: sha512-MWC4N7RY+qsbNrFNo7yQ9ZbdoZEW+B5DtpWxJfUnVCqcQxxqqg3qis3RMPTDbCNaTIdHJSn5XDkl9ZdVWXknLg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-arrow@1.1.17': + resolution: {integrity: sha512-67jjcVvxjXCCStnTW3Z+M7jmaFMuMR7M2JgpDzH4w7JSRrikmzhjfYgP/09ECb8n7whnsgh1ifJ+Ie96qEj+pQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-aspect-ratio@1.2.0': + resolution: {integrity: sha512-gHEU+Lx8DlT/FYIjZQvvBJrFSwUngXTjh7FeL9QvJaNALDLez6pgDj2axCUihBjtPBy82LN0gNb25+sTcSXNmA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-avatar@1.3.1': + resolution: {integrity: sha512-ssZOkfQNkFpYVmCPQlr978xSaU7moSrGXdwg4j2Xs2WlGl/1KsSZtfpK+WnLnx0Rwll1BAh6oUrAy/uR31SBvQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-checkbox@1.4.1': + resolution: {integrity: sha512-KWtwhh+98ML3seZ9vO9yRY2OwaQG90dCiDAxjpSNY2AaZ3Hik3B0dsk6m0ILywo/no3A9/SozadyPMNweVT8yw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collapsible@1.2.1': + resolution: {integrity: sha512-fSzLb/qy1wuZSxQBcxpW0hNXYHDMWiIXDGyJGdA4+FSLknOWZsNRrTCUavxb4PI8b8lvHo/CysO6NVi5zLpo5g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.2.0': + resolution: {integrity: sha512-+yiQzqcc7Sy7/5s0jrMCjpPRFB3538VNrXPWdTLZhE/SCfgEws4aI6lHWN/vvcnyhHndROWBzqmqB4QBrITZ9Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.5': + resolution: {integrity: sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context-menu@2.4.1': + resolution: {integrity: sha512-Pddn3Z8lio3/ChxyXaEP3jHTTo1LTHCWwF8+mG1chQlWijP+ttVHBKwezrQTiV6Mj670ojvumqvuGh+mdv33iQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-context@1.3.0': + resolution: {integrity: sha512-v5AYEocMISkbJ+1fTXzZpiFv7NRr3D2WiYbLIKf+FkmJ8VkP6d503eV2n34MFussHXY1pcoq3yfJiQH77dc4Mg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.3.1': + resolution: {integrity: sha512-+0E4qvVTwjAWra9sEhJ+9BTsvHE00zkUuNw1VGh7S+Gc13dfYk+S1PVQdchWDj+XYHhAai7Z7IpzXVDCGsDplg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.2.0': + resolution: {integrity: sha512-FtRA52a/r+LKStFT+neLUm+8vSe7wbzkbQGGeU8ixFiwC8NU14Evoq9ATECqL3eGbcUzJR4fyfA4KkK/q6dfqg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.2.1': + resolution: {integrity: sha512-KIfDcAsx+oVylFZ4xryVKusJUrLLhTQmfnJW4kwk4Km5myvhHCrj04hnWWUC166+xD4DHdH8tQGylwYX1h6+Pg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dropdown-menu@2.2.1': + resolution: {integrity: sha512-XsHcmYG2AcqnvTqrOXXWcMrhquEIlqucizuDH1MV/qMRW+DndpBCMvNeTRXOxqmG1H5j89M/+I0/34Zdd+zDcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.2.0': + resolution: {integrity: sha512-MPm5R0iRGUDrDnPNxmLBkv+X7pN4XKzt+MbWJEuJQsH3NFH4omrbpXpucyYCCKTSt+na/ZxGhEWQrWTZ0285cA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.3.1': + resolution: {integrity: sha512-ugeMhbXt4y5S2T1GnIqbWDKEN962PDwnX1fN0eKOOgf5f63Dh2mn8F1FUySlgW0iF6GiVsRF32DzuDIWTUyQJg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-form@0.3.0': + resolution: {integrity: sha512-KnmrCM27m7Jo1R8S6cFDPrEeq20Jfn5dqde0SZrJr2lVXlj6/QZSUCyFoYh1d8ti0uUrMNK5Lx6dUDuINT+f4Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-hover-card@1.2.1': + resolution: {integrity: sha512-4QooHxgmpCKRjj1Pft+hETKidYcrbPKcVwMGtk2Oa5DcWY2IH1fHuQt9LG6q5hUQBBV2MhQxSvtx6B/C1xfiTw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.4': + resolution: {integrity: sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-label@2.1.17': + resolution: {integrity: sha512-xmj7MN/drx1oUAXkfiFIvyDmGNUIN/omGobvA5oAoNqu9zO2MkISYGZOkBcqSzs/UZXXwV+/3ACRE7q7mGcmkA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-menu@2.2.1': + resolution: {integrity: sha512-G34BsU90SBj5foYpz8pQqq/Q0Dlfyyl6KitWEfRwXC0QvfwhWNAwS49DWP2+rRJ0iwv20Z2Qx7Sk+T03bGo5JA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-menubar@1.2.1': + resolution: {integrity: sha512-bRTYtS9JITV2dUYqYZb7+N5SooQBkZrNRejfmyrSKe3Y57aXhKgx//kBUP0kY7pEpsWR/U1AHsAJRzjwCrK3PA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-navigation-menu@1.4.1': + resolution: {integrity: sha512-XPPZjkeyCSMNNvt0FyDv/PUauG7Ow4GwHQ/XZSwW36F/TS7rR4HFTsXH8ewLnXTOLn3x96/pmTPNQIVoTX/86g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-one-time-password-field@0.2.1': + resolution: {integrity: sha512-KtHdcgnaAK6rohQ/MMJoGYcbgSRJsIuGBdHrFeTB1/9SaKlDs14oSOniW6BL6M43HqvgCO3u4WuVdFLkuc6sqw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-password-toggle-field@0.2.1': + resolution: {integrity: sha512-vu4+ZoJAaFjdI7l1lDSZRs+4dEv83Jmu7lyzajPrAeQzX74y84n0rUNWbWSgN9XB5NE8IY86Z02kGH6oRrzR+w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popover@1.3.1': + resolution: {integrity: sha512-ZNxvXRx5W2Wos4fXCXb5lpdqN0Z5chf+mStOUOTr4ik7d+62MRvoe9rzCA/eGNg36lxXqSrKEKmwuZEcUrIstw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.4.0': + resolution: {integrity: sha512-yCWRvLeGv9Pz3+efwHqGPp70mZ56r3kfIgQVF56Oj2aAa4uP/Tb+IE59wNcc+758rctqbCKx4LbK8II/r7Bn0Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.2.0': + resolution: {integrity: sha512-StX7xXnaRU41VvFtMm9zlhVGz8XF6GmWWTXftkQaY+tqVkbs/R9UmAp5mLzHHapk5hM9RMZQvO/3usyIP/g42g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.11': + resolution: {integrity: sha512-Z7/atlkab36Z8hm+V8zYc79r0W+tiOB1o0tun1By94JyadkekLQmtEAnBSP9XKXBNQsStoStS4+gX10JpS5akA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.2.0': + resolution: {integrity: sha512-HCTSPMNqv55Qk0IX4geJbpyXazmqulcimwuyjxTkKi29v+QZbG2Zho9BnbBq4YS2PF+KlNb2CXoLz66uUmblkg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-progress@1.2.1': + resolution: {integrity: sha512-yQBiM6J3YM8Ums1orkEFpbznK47geKxa0igikzcaS1xHgdba3DdAQBsGbCTt5BVfR8zhEvgxQ0poGcINaD3lvw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-radio-group@1.5.1': + resolution: {integrity: sha512-QbyVT1ddnjqB9H+CUYKkNWdU9fIK3QHCYtjf7mS6ekSqiuXkWtWn5UZW9mhA8qtl3vrVyIsmR9gePstAtKrqkw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.2.1': + resolution: {integrity: sha512-UwraORzVUeEPMclhO1p0vz0qI+TbdDLO9i+FiOqhJyHKwdpCRCck9yVEscUnAMIzCiuNoQa8D4A9bIpOPXGt6Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-scroll-area@1.4.0': + resolution: {integrity: sha512-CFrLqHNejWq5FhKAcj9V/WPGRsol76HBQto81NdOBVFEOqIEkJkKIJt0Z824A/9hHLCtoiR/Kw3euRgzXP2pxg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-select@2.4.1': + resolution: {integrity: sha512-888ZwW0Md6GyptuqYABRX9nLKgoYfcooCyBBvVaX5Jp3e+8Jp2i4Zo/Uy50Hm+Ysn2JfloQXstW4U36w8teVtg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-separator@1.2.0': + resolution: {integrity: sha512-1jUAap0wZEqVP05Ou7kJgRxe/W+Qftng+rUNWGa0qkKbv9r5pWTG3E7a3ELKo2eJoHKMECnzuYrZpSyO1YgcYQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slider@1.6.1': + resolution: {integrity: sha512-IRNRR90moPqxfwCJ0XbMJIxo70W0/1ZExT/sNCxEHMaPx0SF9HoQrcPEC75+H28cFKa0b+KH63anfLYJmwKacw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.5.0': + resolution: {integrity: sha512-tyYd9ddPXAysAbdbD9eYxgwpCSv6f3PncqVSNKQFSR5lcJVLz3cb/pANDoYrLiHBpXv7skortyUgGUWsYuPPFQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-switch@1.4.1': + resolution: {integrity: sha512-NpBGwc40rY02ZmSvuyeKk0Bvc8ZsNeTMi4qHvJ+ZH4EiYCv0zIXEgdCW4bVdzgIUeP9xxbLJSxKOUfqITYNmkA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tabs@1.2.1': + resolution: {integrity: sha512-hRoJlode+hg5ZNlR+3tkfkUliIybdTpD5lkAvHQ9yaXseGf7XVO9Ib2GPEIOuaJJbo7YWYbNpDDRfo8Dhf6/xA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toast@1.3.1': + resolution: {integrity: sha512-iQvL0J7XK4HtJNGkkWMyYrboNseI7vtotFeUkIno8YNxVA9oM7B6//fh0Mc6TSKI96+zioLWi98lQLso88yJmQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toggle-group@1.2.1': + resolution: {integrity: sha512-O8Ldx5ao4p4KoW+DO8/PmkOe5mdKNi3F2SseqjVj88wvDGDHe60cUmO0Zm/uHsKrvNgQGV8Efpuh95Tht/h4vw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toggle@1.2.1': + resolution: {integrity: sha512-+3MUq+WyiBplXYqQ0EIYlq8R4sLQ0T5NbOK7DMdDLCKO93pe2uE0DUJTWWfTBprpJJXxfoF3eMW0xpakVZrYsg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toolbar@1.2.1': + resolution: {integrity: sha512-Cm8m7JTEeUdbfA6T9xgyu8HfOpyvSx8pB/wj0DlEuWaJe9FilIs4Az9wci/lU9RbthV/UkltszMw5WnnD+m/Ug==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tooltip@1.4.1': + resolution: {integrity: sha512-NxLFGSFtZ78zVfcoOhTwR1xwqo5qx1Jh8Pw6FMZ9McCaqfRzz7/gIRahs2Oy5XlPgQ+8QkUcKbN5B0U44J/kCg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.5': + resolution: {integrity: sha512-Y5GBf4NKeADoXI1geiMlMuMoURT3k9MizzzKhGb/m55H94aGigZ01PIpkvsO6lML13BA6XYAXSJ6gza7vTn5nw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.3.0': + resolution: {integrity: sha512-TAcBI7bw2ljYCbv4+zuTSd6zICu8pRt6SDN2vJ/Z06K2MXh6I9WYFe/A9ovlFDtR5HVHGm5iDxDoABm/++dbKg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.5': + resolution: {integrity: sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.6': + resolution: {integrity: sha512-9cRullnQRv+kqnRmFlmh0WC3kAPuGmHiQ9VwsXdrYk//sBhgCKEttcpPEPgIQbyx6TGUmooVEHYTyohwz/lSJg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-is-hydrated@0.1.3': + resolution: {integrity: sha512-umO/aJ+82CpOnhDZUTbILCQf7kU/g0iv+oGs/Q8jw7IkhWBzaEP4sA268PhFAJTFetbwp3ICc6ktpI4TqtxcIw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.4': + resolution: {integrity: sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.4': + resolution: {integrity: sha512-XoSLhbRbqxFtgJoi2fNHA3C6pDlY34x508vUpUGoFZfvePfHXHbE1lC4FYFMnJWgiCRroSTw6fOsXQoVS9RwZg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.4': + resolution: {integrity: sha512-cSOCh6JlkmfjLyNcLiu2nB4v+nm+dkZ+Q5KHWk/soo4U7ZLiEQFKHK9/YmtBHjfCEaU43IBKQOc4/uJmCaiCTQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.5': + resolution: {integrity: sha512-V1McDQkMGzgivwqdu7u96APs7oi0Jvj9LTzgq3WWrDZqxWdAqU9yZnZQqk5OizGFR8badUQwZsrlao7MOlWYOA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.2.13': + resolution: {integrity: sha512-feijiN1oPk4rck4u9Dm9tsU4mT6Wp9oeEEhaz1WUEs1VuqLf8xzsFG+Qk+uWq6TnMH9O+WRECRg0NftyP9E4Fw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.3': + resolution: {integrity: sha512-JtyZR+mqgBibTo8xea3B6ZRmzZiM/YeVBtUkas6zMuXjAlfIFIW2FgqeM9eLyvEaYX66vr6DJMK+4U6LV0KhNw==} + + '@react-types/shared@3.37.0': + resolution: {integrity: sha512-VNlZuifu4tHdxWPfHvoMfKsHA9kVTCGkduv5vKVTdinm8wHFJNhyVB5RzIMiRFj0q3RKoCbP68u2zaoBSiFueg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@sindresorhus/slugify@3.0.1': + resolution: {integrity: sha512-N1oPvN6sytRKZCskv0L+vSyvnUYi9JplPXZ90lT6EBsijjHrUdoXttb0Lna6pw1TWMe8vlajQnLDtU9KYHqtDg==} + engines: {node: '>=20'} + + '@sindresorhus/transliterate@2.3.1': + resolution: {integrity: sha512-gVaaGtKYMYAMmI8buULVH3A2TXVJ98QiwGwI7ddrWGuGidGC2uRt4FHs22+8iROJ0QTzju9CuMjlVsrvpqsdhA==} + engines: {node: '>=20'} + + '@swc/helpers@0.5.24': + resolution: {integrity: sha512-6tcXo4kA8HgGO7AVmawB57RYi/piBPYVHVcO6dXjX+SZw8GoHmi262sp4v2Ha2kNP9Cx84qei27yT+fjS1lxgg==} + + '@tailwindcss/cli@4.3.4': + resolution: {integrity: sha512-279RsQ1SjT5PcUp6za3F9Qavw933WkMErTOArEKl+gOS4BBgW/2/w9Tn5zLSRy8t/U1Kiy4LmKjuxrFFsbbtAw==} + hasBin: true + + '@tailwindcss/node@4.3.4': + resolution: {integrity: sha512-b7QK/QG04v3j04NbpG82XLCedRyulnkuwUDwRa9oK/ypnJIzMapz2Wg+0TltVczjUzDaJJHIa1+jj9aMUOFMTQ==} + + '@tailwindcss/oxide-android-arm64@4.3.4': + resolution: {integrity: sha512-qkjxt+EFocOi3mtsUS3ndlj6yj4SHubwBdvBynLnS8T4mvSzX0Enn0CpypJKmBEtczUAXOHVZKA2zTGzSNU2Sg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.3.4': + resolution: {integrity: sha512-i/awUA/7mJQAbA3AzCW8aQtUh5goMieUdF1zOoclLaJUCxDvsXQ8VJqpQZY3dfcHS6PJjd3tw25nNneD/mEviQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.3.4': + resolution: {integrity: sha512-q56V9U6AnoYz/yj/alkDLhSQ9AZoXQSEl93f7WETa0+32CudbqM57BXdYXfMYPKudueXKaA+MG6L/0KRseF7Jg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.3.4': + resolution: {integrity: sha512-r0W7A+Z9HTHh7bwihJl45E/zZKLjxD50/jToVF/E/RZHSl8+EWO+4yKKJpPMcUooT9hdoip3Zx1uWnbMg4N79g==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.4': + resolution: {integrity: sha512-3aih/sRxzeYfi2Bkh+bGYNf2YU9Llamb2mpA7BNF1obYzdgEeWDAMQzK6BSwzLhs/eTdOaSur92qrGfchagUtQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.4': + resolution: {integrity: sha512-ktJSrPGQou4OqL88rDEx5CkeM9BjzrwZvYo8u7B7VL1zkBa2XBm351o4MQrek95qikb2M++26Y7w7vbH6Mgl8g==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-arm64-musl@4.3.4': + resolution: {integrity: sha512-rt3hjUxT7utAtcB+df6wHyaXDyxhE7Zd1x7L/nvB5Jb2qBb8dZwFUoWqeRja1BaF5OlSqkKSjBmVXj9OsevmCQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-linux-x64-gnu@4.3.4': + resolution: {integrity: sha512-XE3jO2yOOWjttpeGvpwf3/b274NMi3QapQSAI/EzsgrmYNan1Tw8dXT9JQkN7K0OgvuqiC8mcCyNvGzEkpVJPQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-x64-musl@4.3.4': + resolution: {integrity: sha512-PaAZ2FjJaZk9SQLYtKIfQWiFm/xtl7pX2MKPgCzn0mS/VU54yu+vP457AJdB2XFLxU3gO2abLCt8N7Lg4EbKNg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-wasm32-wasi@4.3.4': + resolution: {integrity: sha512-bjO9WmoM687p8AoCIyw1DUqzpAs4JICLvNmIPxIWDmhw8IOsdubtWQLShyJmISnDKtRy1BBApHVOUl6sNFQQJA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.4': + resolution: {integrity: sha512-jCrwCvWVtt7ruMXp6dFPd5KBNU8o1tWtEdZbTL/w/hvD3lUYZA0E2mmfvTzW4QLHIx5wGQU9HeY7997R1QTrEg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.3.4': + resolution: {integrity: sha512-cge1wcedn1FrRSXL22lF5sNDYr8c9+VImk7zFYLPs12jkDmchSrZNfzWqOKub+5Hb/aYRdDEqERGGDKONBlOzQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.3.4': + resolution: {integrity: sha512-riqsRw2sLF7B1sNCCkTl3KYXEqvhTiABzZ/4oxxHfZ3c3Td60bCBfOrUuUGOiHagd3E7V+zG46c+XBDWZGFBcg==} + engines: {node: '>= 20'} + + '@tanstack/query-core@5.105.3': + resolution: {integrity: sha512-v1rbNy7MB/4Akth7CQH+CerV13K7Ok9hAusEsfz4sCjDdu3/kOSJPoWfoB+YjdEX1eBFBWKNAGE5nqZCgdlHDw==} + + '@tanstack/react-query@5.105.3': + resolution: {integrity: sha512-dj5hGWZmwoc9NG4enoXuYbiYwb5FxgJYPVv06eUgicMTfEMTRXn08Xv9D/r1V8TfjAv+BpxdvZFzJ1h3hSWZcQ==} + peerDependencies: + '@types/react': ^18 || ^19 + react: ^18 || ^19 + peerDependenciesMeta: + '@types/react': + optional: true + + '@tanstack/react-store@0.11.2': + resolution: {integrity: sha512-oj5O5DmiMWE+ih+SioX2ayC1kbK7d3fpLx0B75fPJr9nY3zU+hoW010yr64qXsY/9fyiLVE2bn5mGNV3owm8RQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/react-table@9.3.1': + resolution: {integrity: sha512-E6Ya5TnY6EaGyZYIUqig/29Lr/gJSAubQkLJFqiWkUl5nRCr0Xr9hvJot+NiRTtG+TzGxHTiqUW3bnLtQxlHug==} + engines: {node: '>=20'} + peerDependencies: + react: '>=18' + + '@tanstack/react-virtual@3.14.26': + resolution: {integrity: sha512-HUDlfsrYH6ko5xH56L62Mcl/uzT+AGVNMHFuDNqDJMdZWc1AQa2oeVKNUvZ/RWBZQ4TYtyQerFrNvLnp39h65A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/store@0.11.2': + resolution: {integrity: sha512-sJ4mjol8uQsHV0gOJzzjwXfh2Fwm+Sz0+8deqiTm4jGbMdjzNSW+xZCFm0kUa870uhd8yi+DpKnZb5Kc4apa0Q==} + + '@tanstack/table-core@9.3.1': + resolution: {integrity: sha512-zQvlxSNi2qGM3L4jh85Z6hqMfdIR5qOfD9KHOU32nuKFJGN0RlJ7UvV1lsPb1fPVhpFYI0VP3jJGxLdLDpTKjQ==} + engines: {node: '>=20'} + + '@tanstack/virtual-core@3.19.11': + resolution: {integrity: sha512-/5iHb0RHBvj8Di59FDs4ESNm45jls33aZAi4zccVXZjc/6ZvwQP6nzEYeT6weXjTf9E6/vrp2JhYWRyO+ZP13A==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + + classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + cmdk@1.1.1: + resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + react-dom: ^18 || ^19 || ^19.0.0-rc + + country-flag-icons@1.6.20: + resolution: {integrity: sha512-py8JiEKzjhYw6HPJ0L7SxLgCYim36UPRTZX43/kqGueUCZLSvnrqAiwW8HtQibur7mdkFQUkjOgdK+o/9FBtaw==} + + date-fns@4.4.0: + resolution: {integrity: sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + embla-carousel-react@8.6.0: + resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==} + peerDependencies: + react: ^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + + embla-carousel-reactive-utils@8.6.0: + resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel@8.6.0: + resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + + enhanced-resolve@5.26.1: + resolution: {integrity: sha512-PPnnSJq3azKOIewXR/uppBV/6h98dprBJ/WaQ9Qgj10xX1lJLNfg+XShpbsrSqcDSy2yYYyhfXM1wWhftqgyzw==} + engines: {node: '>=10.13.0'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + input-format@0.3.14: + resolution: {integrity: sha512-gHMrgrbCgmT4uK5Um5eVDUohuV9lcs95ZUUN9Px2Y0VIfjTzT2wF8Q3Z4fwLFm7c5Z2OXCm53FHoovj6SlOKdg==} + peerDependencies: + react: '>=18.1.0' + react-dom: '>=18.1.0' + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + input-otp@1.5.0: + resolution: {integrity: sha512-3AcfdW1sNG0FmSA5hHMBXG7jNW5CdcdKs8ln8JOmn6S2SRkoXoJx+2UwC+ZvjflfnOdHJx0SfQ9/YjlxVYLtGQ==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + libphonenumber-js@1.13.15: + resolution: {integrity: sha512-AHdhEQeDFEJ4GKDAQ9AwxChy+v2kUILUB3TGQRpkXMkWePjXTU/WQEzWVQoIx/Gz8fE73Wr5SEuZCy2vk8jrMQ==} + + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lucide-react@1.68.0: + resolution: {integrity: sha512-9i7NKWm2QlOprMhcwkhBOlIt9zB7cp2GIyFY+oMue0EsprolUFxva5rkdBbyfs4k1eejpa0JRnRgVOGiart+Xg==} + peerDependencies: + '@types/react': '*' + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + lucide-static@1.68.0: resolution: {integrity: sha512-sInxhr771A4UUu8D1gXZjj3mmGwqRTYDVNbfwN25Yx6vwA9Hnq9t+P9rF49UW8MirAe1iaYpqe+3vq99bbH8zg==} + magic-string@1.4.5: + resolution: {integrity: sha512-oLLC2+YvQUfAa+vxoufE/yc1icb87M9iXIRqAoR/2EhE/8cb3SF/+Gi0c2By1B+5Vz2e2vQtUvHiu1+63Znh+w==} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + radix-ui@1.8.1: + resolution: {integrity: sha512-HPfpVGizO9xANlsFSauruLhRe/3+iOt3vPX0MXYle/UQi3gorQrSYtBcdiv0BZYewcl2rvL59qrIuLFMGAmUrw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + react-aria-components@1.22.1: + resolution: {integrity: sha512-UTHaYHOaM71bOCjGPF50DcLywlrwAodE63IP64LB4kO+OizatQEL8TesVEOM8+TkBeSgHoflJ45388IlJfa7aw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + react-aria@3.53.1: + resolution: {integrity: sha512-dikisyOjJd3D2fFrIDWmVWzqiLz5B86GzZv1zxs7xI4dVc0JIz/1Wa52I20gYvVL2WXeFXlygYsle/QcOMhtcg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + react-day-picker@10.0.2: + resolution: {integrity: sha512-QetiKtZWE9Uaw/pM/SYNv6WPYOTRnSJ2puL0GgwkmUFMIwiY0dtjH1W4B7DOVXVNQM0ZOClGpH/heOfBSzWeiA==} + engines: {node: '>=18'} + peerDependencies: + '@types/react': '>=16.8.0' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + + react-dom@19.3.1: + resolution: {integrity: sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==} + peerDependencies: + react: ^19.3.1 + + react-hook-form@7.91.0: + resolution: {integrity: sha512-5BEBUnCBwa28AFXYTYmOaB/+CSpJ/+CWVASHEvIGUzFdHyUiPHeRhG7r5hOZ8nZi0yP7pbHdFNXO/p31EKTJFQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17 || ^18 || ^19 + peerDependenciesMeta: + '@types/react': + optional: true + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-phone-number-input@3.4.18: + resolution: {integrity: sha512-EmPhJFSxQB7CTmLAlQfGAQQPF+WmJECU08gjyUt50zd2iESb4ETsm6z+BRfUEjH+TXct4EWvJvub+OztJxb/Cg==} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-stately@3.51.0: + resolution: {integrity: sha512-YJcmkAXu2XOQP97hO/qz/cC3qv9kni3oVhwBlxWr358BHePJUpY15XwL3YSRMKxYt4EkslPqAz11JRirMfANGw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react@19.3.1: + resolution: {integrity: sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==} + engines: {node: '>=0.10.0'} + + scheduler@0.28.0: + resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==} + + sonner@2.0.8: + resolution: {integrity: sha512-UM/ByIoFra8yzV75n1o0Puu0bw5U/9UNnDacrJNspekBewIfsQ3D6ez1nvlWpt7aTsO6rujQtifBpycwIivqlg==} + peerDependencies: + '@types/react': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + source-map-js@1.2.2: + resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} + engines: {node: '>=0.10.0'} + + tailwind-merge@3.7.0: + resolution: {integrity: sha512-XPPUyAc+cvspz3lHTcR/QgPfW2A0lv/xQNIjX3HGhLR+Nq2lHaLq5MtTesHn8GUr3W3DguT2KT5x3NVgRtYwmA==} + + tailwindcss@4.3.4: + resolution: {integrity: sha512-PCJZTFFdG+sL3gvnP1Do9o6GbkvH2q0p04xSs3f7cSvmAeK+sttG+/7ncK1fdRwKFfC7n+wDDJaOMBSefkI9ow==} + + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + + tslib@2.9.1: + resolution: {integrity: sha512-a4Ux9VKuIMHsOS7ENbEq6hK2ZGYIT27Rtl0E4eD9KqwxhKiQeMZE/9xb3IdYwWaSOyIBQLExhQgXDTYoiCxnWA==} + + tw-animate-css@1.4.0: + resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} + + uqr@0.1.3: + resolution: {integrity: sha512-0rjE8iEJe4YmT9TOhwsZtqCMRLc5DXZUI2UEYUUg63ikBkqqE5EYWaI0etFe/5KUcmcYwLih2RND1kq+hrUJXA==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sync-external-store@1.7.0: + resolution: {integrity: sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + vaul@1.1.2: + resolution: {integrity: sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + snapshots: + '@date-fns/tz@1.5.0': {} + + '@dnd-kit/abstract@0.5.3': + dependencies: + '@dnd-kit/geometry': 0.5.3 + '@dnd-kit/state': 0.5.3 + tslib: 2.9.1 + + '@dnd-kit/collision@0.5.3': + dependencies: + '@dnd-kit/abstract': 0.5.3 + '@dnd-kit/geometry': 0.5.3 + tslib: 2.9.1 + + '@dnd-kit/dom@0.5.3': + dependencies: + '@dnd-kit/abstract': 0.5.3 + '@dnd-kit/collision': 0.5.3 + '@dnd-kit/geometry': 0.5.3 + '@dnd-kit/state': 0.5.3 + tslib: 2.9.1 + + '@dnd-kit/geometry@0.5.3': + dependencies: + '@dnd-kit/state': 0.5.3 + tslib: 2.9.1 + + '@dnd-kit/helpers@0.5.3': + dependencies: + '@dnd-kit/abstract': 0.5.3 + tslib: 2.9.1 + + '@dnd-kit/react@0.5.3(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@dnd-kit/abstract': 0.5.3 + '@dnd-kit/dom': 0.5.3 + '@dnd-kit/state': 0.5.3 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + tslib: 2.9.1 + + '@dnd-kit/state@0.5.3': + dependencies: + '@preact/signals-core': 1.14.5 + tslib: 2.9.1 + + '@floating-ui/core@1.8.0': + dependencies: + '@floating-ui/utils': 0.2.12 + + '@floating-ui/dom@1.8.0': + dependencies: + '@floating-ui/core': 1.8.0 + '@floating-ui/utils': 0.2.12 + + '@floating-ui/react-dom@2.1.9(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@floating-ui/dom': 1.8.0 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@floating-ui/utils@0.2.12': {} + + '@internationalized/date@3.12.4': + dependencies: + '@swc/helpers': 0.5.24 + + '@internationalized/number@3.6.9': + dependencies: + '@swc/helpers': 0.5.24 + + '@internationalized/string@3.2.10': + dependencies: + '@swc/helpers': 0.5.24 + + '@javaabu/onu@0.2.1(@tanstack/react-query@5.105.3(react@19.3.1))(react-dom@19.3.1(react@19.3.1))(react-hook-form@7.91.0(react@19.3.1))(react@19.3.1)(tailwindcss@4.3.4)': + dependencies: + '@dnd-kit/dom': 0.5.3 + '@dnd-kit/helpers': 0.5.3 + '@dnd-kit/react': 0.5.3(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@internationalized/date': 3.12.4 + '@sindresorhus/slugify': 3.0.1 + '@tanstack/react-query': 5.105.3(react@19.3.1) + '@tanstack/react-table': 9.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@tanstack/react-virtual': 3.14.26(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + class-variance-authority: 0.7.1 + clsx: 2.1.1 + cmdk: 1.1.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + date-fns: 4.4.0 + embla-carousel-react: 8.6.0(react@19.3.1) + input-otp: 1.5.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + lucide-react: 1.68.0(react@19.3.1) + radix-ui: 1.8.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-aria-components: 1.22.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react-day-picker: 10.0.2(react@19.3.1) + react-dom: 19.3.1(react@19.3.1) + react-hook-form: 7.91.0(react@19.3.1) + react-phone-number-input: 3.4.18(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + sonner: 2.0.8(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + tailwind-merge: 3.7.0 + tailwindcss: 4.3.4 + tw-animate-css: 1.4.0 + uqr: 0.1.3 + vaul: 1.1.2(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.6.0': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@parcel/watcher-android-arm64@2.6.0': + optional: true + + '@parcel/watcher-darwin-arm64@2.6.0': + optional: true + + '@parcel/watcher-darwin-x64@2.6.0': + optional: true + + '@parcel/watcher-freebsd-x64@2.6.0': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.6.0': + optional: true + + '@parcel/watcher-linux-arm-musl@2.6.0': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.6.0': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.6.0': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.6.0': + optional: true + + '@parcel/watcher-linux-x64-musl@2.6.0': + optional: true + + '@parcel/watcher-win32-arm64@2.6.0': + optional: true + + '@parcel/watcher-win32-x64@2.6.0': + optional: true + + '@parcel/watcher@2.6.0': + dependencies: + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.7 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.6.0 + '@parcel/watcher-darwin-arm64': 2.6.0 + '@parcel/watcher-darwin-x64': 2.6.0 + '@parcel/watcher-freebsd-x64': 2.6.0 + '@parcel/watcher-linux-arm-glibc': 2.6.0 + '@parcel/watcher-linux-arm-musl': 2.6.0 + '@parcel/watcher-linux-arm64-glibc': 2.6.0 + '@parcel/watcher-linux-arm64-musl': 2.6.0 + '@parcel/watcher-linux-x64-glibc': 2.6.0 + '@parcel/watcher-linux-x64-musl': 2.6.0 + '@parcel/watcher-win32-arm64': 2.6.0 + '@parcel/watcher-win32-x64': 2.6.0 + + '@preact/signals-core@1.14.5': {} + + '@radix-ui/number@1.1.3': {} + + '@radix-ui/primitive@1.2.0': {} + + '@radix-ui/react-accessible-icon@1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-visually-hidden': 1.2.13(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-accordion@1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-collapsible': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-collection': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-alert-dialog@1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-dialog': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-arrow@1.1.17(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-aspect-ratio@1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-avatar@1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.3(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-checkbox@1.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-size': 1.1.5(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-collapsible@1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-collection@1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-slot': 1.5.0(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-compose-refs@1.1.5(react@19.3.1)': + dependencies: + react: 19.3.1 + + '@radix-ui/react-context-menu@2.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-menu': 2.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-context@1.3.0(react@19.3.1)': + dependencies: + react: 19.3.1 + + '@radix-ui/react-dialog@1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-dismissable-layer': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-focus-guards': 1.2.0(react@19.3.1) + '@radix-ui/react-focus-scope': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-portal': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-slot': 1.5.0(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + aria-hidden: 1.2.6 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + react-remove-scroll: 2.7.2(react@19.3.1) + + '@radix-ui/react-direction@1.2.0(react@19.3.1)': + dependencies: + react: 19.3.1 + + '@radix-ui/react-dismissable-layer@1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + '@radix-ui/react-use-effect-event': 0.0.5(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-dropdown-menu@2.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-menu': 2.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-focus-guards@1.2.0(react@19.3.1)': + dependencies: + react: 19.3.1 + + '@radix-ui/react-focus-scope@1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-form@0.3.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-label': 2.1.17(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-hover-card@1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-dismissable-layer': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-focus-scope': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-popper': 1.4.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-portal': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-id@1.1.4(react@19.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + + '@radix-ui/react-label@2.1.17(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-menu@2.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-collection': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-dismissable-layer': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-focus-guards': 1.2.0(react@19.3.1) + '@radix-ui/react-focus-scope': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-popper': 1.4.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-portal': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-roving-focus': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-slot': 1.5.0(react@19.3.1) + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + aria-hidden: 1.2.6 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + react-remove-scroll: 2.7.2(react@19.3.1) + + '@radix-ui/react-menubar@1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-collection': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-menu': 2.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-roving-focus': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-navigation-menu@1.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-collection': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-dismissable-layer': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-slot': 1.5.0(react@19.3.1) + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + '@radix-ui/react-use-previous': 1.1.4(react@19.3.1) + '@radix-ui/react-visually-hidden': 1.2.13(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-one-time-password-field@0.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/number': 1.1.3 + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-collection': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-roving-focus': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-effect-event': 0.0.5(react@19.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.3(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-password-toggle-field@0.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-effect-event': 0.0.5(react@19.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.3(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-popover@1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-dismissable-layer': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-focus-guards': 1.2.0(react@19.3.1) + '@radix-ui/react-focus-scope': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-popper': 1.4.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-portal': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-slot': 1.5.0(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + aria-hidden: 1.2.6 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + react-remove-scroll: 2.7.2(react@19.3.1) + + '@radix-ui/react-popper@1.4.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.9(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-arrow': 1.1.17(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + '@radix-ui/react-use-rect': 1.1.4(react@19.3.1) + '@radix-ui/react-use-size': 1.1.5(react@19.3.1) + '@radix-ui/rect': 1.1.3 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-portal@1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-presence@1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-primitive@2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-slot': 1.5.0(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-progress@1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-radio-group@1.5.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-roving-focus': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-size': 1.1.5(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-roving-focus@1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-collection': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.3(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-scroll-area@1.4.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/number': 1.1.3 + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-slot': 1.5.0(react@19.3.1) + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-select@2.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/number': 1.1.3 + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-collection': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-dismissable-layer': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-focus-guards': 1.2.0(react@19.3.1) + '@radix-ui/react-focus-scope': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-popper': 1.4.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-portal': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-slot': 1.5.0(react@19.3.1) + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + '@radix-ui/react-visually-hidden': 1.2.13(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + aria-hidden: 1.2.6 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + react-remove-scroll: 2.7.2(react@19.3.1) + + '@radix-ui/react-separator@1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-slider@1.6.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/number': 1.1.3 + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-collection': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + '@radix-ui/react-use-size': 1.1.5(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-slot@1.5.0(react@19.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + react: 19.3.1 + + '@radix-ui/react-switch@1.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-size': 1.1.5(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-tabs@1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-roving-focus': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-toast@1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-collection': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-dismissable-layer': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-portal': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + '@radix-ui/react-visually-hidden': 1.2.13(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-toggle-group@1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-roving-focus': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-toggle': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-toggle@1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-toolbar@1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-roving-focus': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-separator': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-toggle-group': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-tooltip@1.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-dismissable-layer': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-focus-scope': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-popper': 1.4.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-portal': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-slot': 1.5.0(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + '@radix-ui/react-visually-hidden': 1.2.13(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/react-use-callback-ref@1.1.5(react@19.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + + '@radix-ui/react-use-controllable-state@1.3.0(react@19.3.1)': + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-use-effect-event': 0.0.5(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + + '@radix-ui/react-use-effect-event@0.0.5(react@19.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + + '@radix-ui/react-use-escape-keydown@1.1.6(react@19.3.1)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + react: 19.3.1 + + '@radix-ui/react-use-is-hydrated@0.1.3(react@19.3.1)': + dependencies: + react: 19.3.1 + + '@radix-ui/react-use-layout-effect@1.1.4(react@19.3.1)': + dependencies: + react: 19.3.1 + + '@radix-ui/react-use-previous@1.1.4(react@19.3.1)': + dependencies: + react: 19.3.1 + + '@radix-ui/react-use-rect@1.1.4(react@19.3.1)': + dependencies: + '@radix-ui/rect': 1.1.3 + react: 19.3.1 + + '@radix-ui/react-use-size@1.1.5(react@19.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + react: 19.3.1 + + '@radix-ui/react-visually-hidden@1.2.13(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@radix-ui/rect@1.1.3': {} + + '@react-types/shared@3.37.0(react@19.3.1)': + dependencies: + react: 19.3.1 + + '@sindresorhus/slugify@3.0.1': + dependencies: + '@sindresorhus/transliterate': 2.3.1 + escape-string-regexp: 5.0.0 + + '@sindresorhus/transliterate@2.3.1': {} + + '@swc/helpers@0.5.24': {} + + '@tailwindcss/cli@4.3.4': + dependencies: + '@parcel/watcher': 2.6.0 + '@tailwindcss/node': 4.3.4 + '@tailwindcss/oxide': 4.3.4 + enhanced-resolve: 5.26.1 + mri: 1.2.0 + picocolors: 1.1.1 + tailwindcss: 4.3.4 + + '@tailwindcss/node@4.3.4': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.26.1 + jiti: 2.7.0 + lightningcss: 1.33.0 + magic-string: 1.4.5 + source-map-js: 1.2.2 + tailwindcss: 4.3.4 + + '@tailwindcss/oxide-android-arm64@4.3.4': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.3.4': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.3.4': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.3.4': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.4': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.4': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.3.4': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.3.4': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.3.4': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.3.4': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.4': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.3.4': + optional: true + + '@tailwindcss/oxide@4.3.4': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.3.4 + '@tailwindcss/oxide-darwin-arm64': 4.3.4 + '@tailwindcss/oxide-darwin-x64': 4.3.4 + '@tailwindcss/oxide-freebsd-x64': 4.3.4 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.4 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.4 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.4 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.4 + '@tailwindcss/oxide-linux-x64-musl': 4.3.4 + '@tailwindcss/oxide-wasm32-wasi': 4.3.4 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.4 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.4 + + '@tanstack/query-core@5.105.3': {} + + '@tanstack/react-query@5.105.3(react@19.3.1)': + dependencies: + '@tanstack/query-core': 5.105.3 + react: 19.3.1 + + '@tanstack/react-store@0.11.2(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@tanstack/store': 0.11.2 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + use-sync-external-store: 1.7.0(react@19.3.1) + + '@tanstack/react-table@9.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@tanstack/react-store': 0.11.2(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@tanstack/table-core': 9.3.1 + react: 19.3.1 + transitivePeerDependencies: + - react-dom + + '@tanstack/react-virtual@3.14.26(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': + dependencies: + '@tanstack/virtual-core': 3.19.11 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + '@tanstack/store@0.11.2': {} + + '@tanstack/table-core@9.3.1': + dependencies: + '@tanstack/store': 0.11.2 + + '@tanstack/virtual-core@3.19.11': {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.9.1 + + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + + classnames@2.5.1: {} + + client-only@0.0.1: {} + + clsx@2.1.1: {} + + cmdk@1.1.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1): + dependencies: + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-dialog': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-id': 1.1.4(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + + country-flag-icons@1.6.20: {} + + date-fns@4.4.0: {} + + detect-libc@2.1.2: {} + + detect-node-es@1.1.0: {} + + embla-carousel-react@8.6.0(react@19.3.1): + dependencies: + embla-carousel: 8.6.0 + embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) + react: 19.3.1 + + embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel@8.6.0: {} + + enhanced-resolve@5.26.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + + escape-string-regexp@5.0.0: {} + + get-nonce@1.0.1: {} + + graceful-fs@4.2.11: {} + + input-format@0.3.14(react-dom@19.3.1(react@19.3.1))(react@19.3.1): + dependencies: + prop-types: 15.8.1 + optionalDependencies: + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + input-otp@1.5.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1): + dependencies: + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + jiti@2.7.0: {} + + js-tokens@4.0.0: {} + + libphonenumber-js@1.13.15: {} + + lightningcss-android-arm64@1.33.0: + optional: true + + lightningcss-darwin-arm64@1.33.0: + optional: true + + lightningcss-darwin-x64@1.33.0: + optional: true + + lightningcss-freebsd-x64@1.33.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true + + lightningcss-linux-arm64-gnu@1.33.0: + optional: true + + lightningcss-linux-arm64-musl@1.33.0: + optional: true + + lightningcss-linux-x64-gnu@1.33.0: + optional: true + + lightningcss-linux-x64-musl@1.33.0: + optional: true + + lightningcss-win32-arm64-msvc@1.33.0: + optional: true + + lightningcss-win32-x64-msvc@1.33.0: + optional: true + + lightningcss@1.33.0: + dependencies: + detect-libc: 2.1.2 + 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 + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lucide-react@1.68.0(react@19.3.1): + dependencies: + react: 19.3.1 + lucide-static@1.68.0: {} + + magic-string@1.4.5: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + + mri@1.2.0: {} + + node-addon-api@7.1.1: {} + + object-assign@4.1.1: {} + + picocolors@1.1.1: {} + + picomatch@4.0.7: {} + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + radix-ui@1.8.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1): + dependencies: + '@radix-ui/primitive': 1.2.0 + '@radix-ui/react-accessible-icon': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-accordion': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-alert-dialog': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-arrow': 1.1.17(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-aspect-ratio': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-avatar': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-checkbox': 1.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-collapsible': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-collection': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-compose-refs': 1.1.5(react@19.3.1) + '@radix-ui/react-context': 1.3.0(react@19.3.1) + '@radix-ui/react-context-menu': 2.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-dialog': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-direction': 1.2.0(react@19.3.1) + '@radix-ui/react-dismissable-layer': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-dropdown-menu': 2.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-focus-guards': 1.2.0(react@19.3.1) + '@radix-ui/react-focus-scope': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-form': 0.3.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-hover-card': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-label': 2.1.17(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-menu': 2.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-menubar': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-navigation-menu': 1.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-one-time-password-field': 0.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-password-toggle-field': 0.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-popover': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-popper': 1.4.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-portal': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-presence': 1.1.11(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-primitive': 2.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-progress': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-radio-group': 1.5.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-roving-focus': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-scroll-area': 1.4.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-select': 2.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-separator': 1.2.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-slider': 1.6.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-slot': 1.5.0(react@19.3.1) + '@radix-ui/react-switch': 1.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-tabs': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-toast': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-toggle': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-toggle-group': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-toolbar': 1.2.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-tooltip': 1.4.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + '@radix-ui/react-use-callback-ref': 1.1.5(react@19.3.1) + '@radix-ui/react-use-controllable-state': 1.3.0(react@19.3.1) + '@radix-ui/react-use-effect-event': 0.0.5(react@19.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.6(react@19.3.1) + '@radix-ui/react-use-is-hydrated': 0.1.3(react@19.3.1) + '@radix-ui/react-use-layout-effect': 1.1.4(react@19.3.1) + '@radix-ui/react-use-size': 1.1.5(react@19.3.1) + '@radix-ui/react-visually-hidden': 1.2.13(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + react-aria-components@1.22.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1): + dependencies: + '@internationalized/date': 3.12.4 + '@internationalized/string': 3.2.10 + '@react-types/shared': 3.37.0(react@19.3.1) + '@swc/helpers': 0.5.24 + client-only: 0.0.1 + react: 19.3.1 + react-aria: 3.53.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react-dom: 19.3.1(react@19.3.1) + react-stately: 3.51.0(react@19.3.1) + use-sync-external-store: 1.7.0(react@19.3.1) + + react-aria@3.53.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1): + dependencies: + '@internationalized/date': 3.12.4 + '@internationalized/number': 3.6.9 + '@internationalized/string': 3.2.10 + '@react-types/shared': 3.37.0(react@19.3.1) + '@swc/helpers': 0.5.24 + aria-hidden: 1.2.6 + clsx: 2.1.1 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + react-stately: 3.51.0(react@19.3.1) + use-sync-external-store: 1.7.0(react@19.3.1) + + react-day-picker@10.0.2(react@19.3.1): + dependencies: + '@date-fns/tz': 1.5.0 + date-fns: 4.4.0 + react: 19.3.1 + + react-dom@19.3.1(react@19.3.1): + dependencies: + react: 19.3.1 + scheduler: 0.28.0 + + react-hook-form@7.91.0(react@19.3.1): + dependencies: + react: 19.3.1 + + react-is@16.13.1: {} + + react-phone-number-input@3.4.18(react-dom@19.3.1(react@19.3.1))(react@19.3.1): + dependencies: + classnames: 2.5.1 + country-flag-icons: 1.6.20 + input-format: 0.3.14(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + libphonenumber-js: 1.13.15 + prop-types: 15.8.1 + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + react-remove-scroll-bar@2.3.8(react@19.3.1): + dependencies: + react: 19.3.1 + react-style-singleton: 2.2.3(react@19.3.1) + tslib: 2.9.1 + + react-remove-scroll@2.7.2(react@19.3.1): + dependencies: + react: 19.3.1 + react-remove-scroll-bar: 2.3.8(react@19.3.1) + react-style-singleton: 2.2.3(react@19.3.1) + tslib: 2.9.1 + use-callback-ref: 1.3.3(react@19.3.1) + use-sidecar: 1.1.3(react@19.3.1) + + react-stately@3.51.0(react@19.3.1): + dependencies: + '@internationalized/date': 3.12.4 + '@internationalized/number': 3.6.9 + '@internationalized/string': 3.2.10 + '@react-types/shared': 3.37.0(react@19.3.1) + '@swc/helpers': 0.5.24 + react: 19.3.1 + use-sync-external-store: 1.7.0(react@19.3.1) + + react-style-singleton@2.2.3(react@19.3.1): + dependencies: + get-nonce: 1.0.1 + react: 19.3.1 + tslib: 2.9.1 + + react@19.3.1: {} + + scheduler@0.28.0: {} + + sonner@2.0.8(react-dom@19.3.1(react@19.3.1))(react@19.3.1): + dependencies: + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + + source-map-js@1.2.2: {} + + tailwind-merge@3.7.0: {} + + tailwindcss@4.3.4: {} + + tapable@2.3.3: {} + + tslib@2.9.1: {} + + tw-animate-css@1.4.0: {} + + uqr@0.1.3: {} + + use-callback-ref@1.3.3(react@19.3.1): + dependencies: + react: 19.3.1 + tslib: 2.9.1 + + use-sidecar@1.1.3(react@19.3.1): + dependencies: + detect-node-es: 1.1.0 + react: 19.3.1 + tslib: 2.9.1 + + use-sync-external-store@1.7.0(react@19.3.1): + dependencies: + react: 19.3.1 + + vaul@1.1.2(react-dom@19.3.1(react@19.3.1))(react@19.3.1): + dependencies: + '@radix-ui/react-dialog': 1.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react: 19.3.1 + react-dom: 19.3.1(react@19.3.1) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' diff --git a/resources/css/onu-standalone.css b/resources/css/onu-standalone.css new file mode 100644 index 0000000..83432a2 --- /dev/null +++ b/resources/css/onu-standalone.css @@ -0,0 +1,8 @@ +/* + * Prebuilt stylesheet for apps without a Tailwind build: Tailwind, Onu and + * javaabu/forms in one file (dist/onu.css). Apps that use Tailwind should + * import resources/css/onu.css instead, so only the classes they use are kept. + */ +@import "tailwindcss" source(none); +@import "@javaabu/onu/tailwind.css"; +@import "./onu.css"; diff --git a/resources/css/onu.css b/resources/css/onu.css new file mode 100644 index 0000000..5befab0 --- /dev/null +++ b/resources/css/onu.css @@ -0,0 +1,87 @@ +/* + * javaabu/forms for Onu (Tailwind CSS v4). + * + * In your app's CSS, after Tailwind and Onu: + * + * @import "tailwindcss"; + * @import "@javaabu/onu/tailwind.css"; + * @import "../../vendor/javaabu/forms/resources/css/onu.css"; + * + * The design tokens, theme and component classes all come from @javaabu/onu. + * This file only lets Tailwind see the classes the Blade views use, and styles + * the native controls (checkbox, radio, dialog, file input) that Onu builds + * from React components. + */ + +@source "../views/onu"; +@source "../views/common"; +@source "../onu/classes.php"; + +@layer components { + /* Native checkbox and radio, styled like Onu's Checkbox and RadioGroupItem. */ + .forms-checkbox, + .forms-radio { + appearance: none; + cursor: pointer; + } + + .forms-checkbox:checked { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3e%3cpath d='M20 6 9 17l-5-5'/%3e%3c/svg%3e"); + background-position: center; + background-repeat: no-repeat; + background-size: 0.75rem; + } + + .forms-checkbox:indeterminate { + border-color: var(--primary); + background-color: var(--primary); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round'%3e%3cpath d='M5 12h14'/%3e%3c/svg%3e"); + background-position: center; + background-repeat: no-repeat; + background-size: 0.75rem; + } + + .forms-radio:checked { + background-image: radial-gradient(circle, var(--primary-foreground) 0 30%, transparent 34%); + } + + /* is a native ; Onu's classes position it. */ + .forms-dialog { + margin: 0; + padding: 0; + border: 0; + max-width: none; + max-height: none; + } + + .forms-dialog:not([open]) { + display: none; + } + + .forms-dialog::backdrop { + background: var(--overlay, rgb(0 0 0 / 0.45)); + } + + /* File inputs: the real covers its button. */ + .btn-file > input[type="file"] { + position: absolute; + inset: 0; + cursor: pointer; + opacity: 0; + } + + .fileinput-new .fileinput-exists, + .fileinput-exists .fileinput-new { + display: none; + } + + .fileinput-preview img { + width: 100%; + height: 100%; + object-fit: contain; + } + + .cover-preview .fileinput-preview img { + object-fit: cover; + } +} diff --git a/resources/onu/classes.php b/resources/onu/classes.php index 2926048..b9a470d 100644 --- a/resources/onu/classes.php +++ b/resources/onu/classes.php @@ -1,5 +1,309 @@ [ + 'form-field' => 'min-w-0 @container/form-field w-full', + 'label' => 'gap-2 text-sm leading-snug font-normal group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50 flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed', + 'required-marker' => 'text-destructive', + 'input' => 'border-input hover:border-primary-5 focus-visible:border-primary focus-visible:ring-primary/20 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 rounded-lg border bg-card px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium focus-visible:ring-2 aria-invalid:ring-3 md:text-sm w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 h-8', + 'help-text' => 'text-sm text-muted-foreground', + 'field-errors' => 'text-sm text-destructive', + 'grid' => 'gap-2 grid', + 'label_row' => 'gap-2 flex items-center justify-between', + 'control' => 'min-w-0 gap-1.5 grid', + 'error_line' => 'gap-1.5 flex items-start', + 'error_icon' => 'mt-0.5 size-3.5 shrink-0', + ], + 'field_invalid' => [ + 'form-field' => 'min-w-0 @container/form-field w-full', + 'label' => 'gap-2 text-sm leading-snug font-normal group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50 flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed text-destructive', + 'input' => 'border-input hover:border-primary-5 focus-visible:border-primary focus-visible:ring-primary/20 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 rounded-lg border bg-card px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium focus-visible:ring-2 aria-invalid:ring-3 md:text-sm w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 h-8', + 'field-errors' => 'text-sm text-destructive', + ], + 'field_inline' => [ + 'form-field' => 'min-w-0 @container/form-field w-full', + 'label' => 'gap-2 text-sm leading-snug font-normal group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50 flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed', + 'input' => 'border-input hover:border-primary-5 focus-visible:border-primary focus-visible:ring-primary/20 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 rounded-lg border bg-card px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium focus-visible:ring-2 aria-invalid:ring-3 md:text-sm w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 h-8', + 'field-errors' => 'text-sm text-destructive', + 'grid' => 'gap-2 grid @md/form-field:grid-cols-[var(--onu-label-width)_minmax(0,1fr)] @md/form-field:gap-x-4', + 'label_row' => 'gap-2 flex items-center justify-between @md/form-field:min-h-8 @md/form-field:items-start @md/form-field:pt-1.5', + 'control' => 'min-w-0 gap-1.5 grid @md/form-field:col-start-2', + 'error_line' => 'gap-1.5 flex items-start', + 'error_icon' => 'mt-0.5 size-3.5 shrink-0', + ], + 'input' => [ + 'input' => 'border-input hover:border-primary-5 focus-visible:border-primary focus-visible:ring-primary/20 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-lg border bg-card px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium focus-visible:ring-2 aria-invalid:ring-3 md:text-sm w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50', + ], + 'input_group_text' => 'text-muted-foreground gap-2 text-sm [&_svg:not([class*=\'size-\'])]:size-4 flex items-center [&_svg]:pointer-events-none', + 'input_group' => [ + 'input-group' => 'border-input hover:border-primary-5 has-[[data-slot=input-group-control]:focus-visible]:border-primary has-[[data-slot=input-group-control]:focus-visible]:ring-primary/20 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-disabled:bg-input/50 dark:has-disabled:bg-input/80 h-8 rounded-lg border bg-card transition-colors in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:ring-2 has-[[data-slot][aria-invalid=true]]:ring-3 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pe-1.5 has-[>[data-align=inline-start]]:[&>input]:ps-1.5 group/input-group relative flex w-full min-w-0 items-center outline-none has-[>textarea]:h-auto', + 'input-group-addon' => 'text-muted-foreground h-auto gap-2 py-1.5 text-sm font-medium group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*=\'size-\'])]:size-4 flex cursor-text items-center justify-center select-none ps-2 has-[>button]:ms-[-0.3rem] has-[>kbd]:ms-[-0.15rem] order-first', + 'input-group-control' => 'border-input hover:border-primary-5 focus-visible:border-primary focus-visible:ring-primary/20 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 h-8 px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium md:text-sm w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent flex-1', + 'button' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button shrink-0 justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground text-sm flex items-center shadow-none h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*=\'size-\'])]:size-3.5', + ], + 'textarea' => [ + 'textarea' => 'border-input hover:border-primary-5 focus-visible:border-primary focus-visible:ring-primary/20 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 rounded-lg border bg-card px-2.5 py-2 text-base transition-colors focus-visible:ring-2 aria-invalid:ring-3 md:text-sm flex field-sizing-content min-h-16 w-full outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50', + ], + 'select' => [ + 'native-select-wrapper' => 'group/native-select relative w-fit has-[select:disabled]:opacity-50', + 'native-select' => 'border-input hover:border-primary-5 placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground focus-visible:border-primary focus-visible:ring-primary/20 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 h-8 w-full min-w-0 appearance-none rounded-lg border bg-card py-1 pe-8 ps-2.5 text-sm transition-colors select-none focus-visible:ring-2 aria-invalid:ring-3 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-[size=sm]:py-0.5 outline-none disabled:pointer-events-none disabled:cursor-not-allowed', + 'native-select-option' => 'bg-[Canvas] text-[CanvasText]', + 'native-select-icon' => 'lucide lucide-chevron-down text-muted-foreground top-1/2 end-2.5 size-4 -translate-y-1/2 pointer-events-none absolute select-none', + ], + 'checkbox' => [ + 'checkbox' => 'border-input bg-card hover:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-[4px] border transition-colors group-has-disabled/field:opacity-50 focus-visible:ring-3 aria-invalid:ring-3 group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input group-has-[:focus-visible]/field-label:data-checked:border-primary peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50', + 'checkbox-indicator' => '[&>svg]:size-3.5 grid place-content-center text-current transition-none', + 'native' => 'appearance-none border-input bg-card hover:border-primary checked:bg-primary checked:text-primary-foreground dark:checked:bg-primary checked:border-primary aria-invalid:checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-[4px] border transition-colors group-has-disabled/field:opacity-50 focus-visible:ring-3 aria-invalid:ring-3 group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-checked:border-input group-has-[:focus-visible]/field-label:checked:border-primary peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50', + ], + 'radio' => [ + 'radio-group' => 'grid gap-2 w-full', + 'radio-group-item' => 'border-input bg-card hover:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 dark:aria-invalid:border-destructive/50 flex size-4 rounded-full focus-visible:ring-3 aria-invalid:ring-3 group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input group-has-[:focus-visible]/field-label:data-checked:border-primary group/radio-group-item peer relative aspect-square shrink-0 border outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50', + 'radio-group-indicator' => 'flex size-4 items-center justify-center', + 'native' => 'appearance-none border-input bg-card hover:border-primary checked:bg-primary checked:text-primary-foreground dark:checked:bg-primary checked:border-primary aria-invalid:checked:border-primary aria-invalid:border-destructive focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 dark:aria-invalid:border-destructive/50 flex size-4 rounded-full focus-visible:ring-3 aria-invalid:ring-3 group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-checked:border-input group-has-[:focus-visible]/field-label:checked:border-primary group/radio-group-item peer relative aspect-square shrink-0 border outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50', + ], + 'choice' => [ + 'checkbox-field' => 'gap-2.5 flex items-start', + 'checkbox' => 'group/checkbox peer relative flex shrink-0 items-center justify-center border border-input bg-card transition-colors outline-none hover:border-primary data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground dark:data-[state=indeterminate]:bg-primary focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 disabled:cursor-not-allowed disabled:opacity-50 after:-inset-x-3 after:-inset-y-2 touch:after:-inset-3.5 after:absolute size-4 [&_svg]:size-3.5 rounded-[4px]', + 'label' => 'gap-2 text-sm group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50 flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed leading-5 font-normal', + 'control' => 'flex shrink-0 items-center min-h-5', + 'content' => 'min-w-0 gap-1 grid', + 'description' => 'text-sm text-muted-foreground', + ], + 'label' => [ + 'label' => 'gap-2 text-sm leading-snug font-normal group-data-[disabled=true]:opacity-50 peer-disabled:opacity-50 flex items-center select-none group-data-[disabled=true]:pointer-events-none peer-disabled:cursor-not-allowed', + ], + 'button' => [ + 'default' => [ + 'default' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active aria-expanded:bg-primary-hover h-8 gap-2 px-3.75', + 'xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active aria-expanded:bg-primary-hover h-6 gap-1 rounded-sm px-2 text-xs in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active aria-expanded:bg-primary-hover h-7 gap-1.5 rounded-md px-2.75 in-data-[slot=button-group]:rounded-md [&_svg:not([class*=\'size-\'])]:size-3.5', + 'lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active aria-expanded:bg-primary-hover h-9 gap-2 px-3.75', + 'icon' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active aria-expanded:bg-primary-hover size-8', + 'icon-xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active aria-expanded:bg-primary-hover size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'icon-sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active aria-expanded:bg-primary-hover size-7 rounded-md in-data-[slot=button-group]:rounded-md', + 'icon-lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active aria-expanded:bg-primary-hover size-9', + ], + 'outline' => [ + 'default' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 h-8 gap-2 px-3.75', + 'xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 h-6 gap-1 rounded-sm px-2 text-xs in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 h-7 gap-1.5 rounded-md px-2.75 in-data-[slot=button-group]:rounded-md [&_svg:not([class*=\'size-\'])]:size-3.5', + 'lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 h-9 gap-2 px-3.75', + 'icon' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 size-8', + 'icon-xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'icon-sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 size-7 rounded-md in-data-[slot=button-group]:rounded-md', + 'icon-lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 size-9', + ], + 'dashed' => [ + 'default' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input border-dashed bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 h-8 gap-2 px-3.75', + 'xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input border-dashed bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 h-6 gap-1 rounded-sm px-2 text-xs in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input border-dashed bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 h-7 gap-1.5 rounded-md px-2.75 in-data-[slot=button-group]:rounded-md [&_svg:not([class*=\'size-\'])]:size-3.5', + 'lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input border-dashed bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 h-9 gap-2 px-3.75', + 'icon' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input border-dashed bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 size-8', + 'icon-xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input border-dashed bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'icon-sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input border-dashed bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 size-7 rounded-md in-data-[slot=button-group]:rounded-md', + 'icon-lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 border-input border-dashed bg-card text-foreground hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 size-9', + ], + 'secondary' => [ + 'default' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] h-8 gap-2 px-3.75', + 'xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] h-6 gap-1 rounded-sm px-2 text-xs in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] h-7 gap-1.5 rounded-md px-2.75 in-data-[slot=button-group]:rounded-md [&_svg:not([class*=\'size-\'])]:size-3.5', + 'lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] h-9 gap-2 px-3.75', + 'icon' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] size-8', + 'icon-xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'icon-sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] size-7 rounded-md in-data-[slot=button-group]:rounded-md', + 'icon-lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] size-9', + ], + 'ghost' => [ + 'default' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground h-8 gap-2 px-3.75', + 'xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground h-6 gap-1 rounded-sm px-2 text-xs in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground h-7 gap-1.5 rounded-md px-2.75 in-data-[slot=button-group]:rounded-md [&_svg:not([class*=\'size-\'])]:size-3.5', + 'lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground h-9 gap-2 px-3.75', + 'icon' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground size-8', + 'icon-xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'icon-sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground size-7 rounded-md in-data-[slot=button-group]:rounded-md', + 'icon-lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground size-9', + ], + 'destructive' => [ + 'default' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-[color-mix(in_oklab,var(--destructive),black_12%)] focus-visible:ring-destructive/30 focus-visible:border-destructive aria-expanded:bg-destructive/90 h-8 gap-2 px-3.75', + 'xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-[color-mix(in_oklab,var(--destructive),black_12%)] focus-visible:ring-destructive/30 focus-visible:border-destructive aria-expanded:bg-destructive/90 h-6 gap-1 rounded-sm px-2 text-xs in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-[color-mix(in_oklab,var(--destructive),black_12%)] focus-visible:ring-destructive/30 focus-visible:border-destructive aria-expanded:bg-destructive/90 h-7 gap-1.5 rounded-md px-2.75 in-data-[slot=button-group]:rounded-md [&_svg:not([class*=\'size-\'])]:size-3.5', + 'lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-[color-mix(in_oklab,var(--destructive),black_12%)] focus-visible:ring-destructive/30 focus-visible:border-destructive aria-expanded:bg-destructive/90 h-9 gap-2 px-3.75', + 'icon' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-[color-mix(in_oklab,var(--destructive),black_12%)] focus-visible:ring-destructive/30 focus-visible:border-destructive aria-expanded:bg-destructive/90 size-8', + 'icon-xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-[color-mix(in_oklab,var(--destructive),black_12%)] focus-visible:ring-destructive/30 focus-visible:border-destructive aria-expanded:bg-destructive/90 size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'icon-sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-[color-mix(in_oklab,var(--destructive),black_12%)] focus-visible:ring-destructive/30 focus-visible:border-destructive aria-expanded:bg-destructive/90 size-7 rounded-md in-data-[slot=button-group]:rounded-md', + 'icon-lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-[color-mix(in_oklab,var(--destructive),black_12%)] focus-visible:ring-destructive/30 focus-visible:border-destructive aria-expanded:bg-destructive/90 size-9', + ], + 'link' => [ + 'default' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 text-primary-7 underline-offset-4 hover:text-primary hover:underline h-8 gap-2 px-3.75', + 'xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 text-primary-7 underline-offset-4 hover:text-primary hover:underline h-6 gap-1 rounded-sm px-2 text-xs in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 text-primary-7 underline-offset-4 hover:text-primary hover:underline h-7 gap-1.5 rounded-md px-2.75 in-data-[slot=button-group]:rounded-md [&_svg:not([class*=\'size-\'])]:size-3.5', + 'lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 text-primary-7 underline-offset-4 hover:text-primary hover:underline h-9 gap-2 px-3.75', + 'icon' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 text-primary-7 underline-offset-4 hover:text-primary hover:underline size-8', + 'icon-xs' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 text-primary-7 underline-offset-4 hover:text-primary hover:underline size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3', + 'icon-sm' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 text-primary-7 underline-offset-4 hover:text-primary hover:underline size-7 rounded-md in-data-[slot=button-group]:rounded-md', + 'icon-lg' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 text-primary-7 underline-offset-4 hover:text-primary hover:underline size-9', + ], + 'success' => [ + 'default' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active h-8 gap-2 px-3.75 bg-success text-success-foreground hover:bg-success/85 focus-visible:ring-success/40 aria-expanded:bg-success/85', + 'xs' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding font-normal focus-visible:ring-3 aria-invalid:ring-3 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active h-6 gap-1 rounded-sm px-2 text-xs in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3 bg-success text-success-foreground hover:bg-success/85 focus-visible:ring-success/40 aria-expanded:bg-success/85', + 'sm' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active h-7 gap-1.5 rounded-md px-2.75 in-data-[slot=button-group]:rounded-md [&_svg:not([class*=\'size-\'])]:size-3.5 bg-success text-success-foreground hover:bg-success/85 focus-visible:ring-success/40 aria-expanded:bg-success/85', + 'lg' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active h-9 gap-2 px-3.75 bg-success text-success-foreground hover:bg-success/85 focus-visible:ring-success/40 aria-expanded:bg-success/85', + 'icon' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active size-8 bg-success text-success-foreground hover:bg-success/85 focus-visible:ring-success/40 aria-expanded:bg-success/85', + 'icon-xs' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3 bg-success text-success-foreground hover:bg-success/85 focus-visible:ring-success/40 aria-expanded:bg-success/85', + 'icon-sm' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active size-7 rounded-md in-data-[slot=button-group]:rounded-md bg-success text-success-foreground hover:bg-success/85 focus-visible:ring-success/40 aria-expanded:bg-success/85', + 'icon-lg' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active size-9 bg-success text-success-foreground hover:bg-success/85 focus-visible:ring-success/40 aria-expanded:bg-success/85', + ], + 'warning' => [ + 'default' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active h-8 gap-2 px-3.75 bg-warning text-warning-foreground hover:bg-warning/85 focus-visible:ring-warning/40 aria-expanded:bg-warning/85', + 'xs' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding font-normal focus-visible:ring-3 aria-invalid:ring-3 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active h-6 gap-1 rounded-sm px-2 text-xs in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3 bg-warning text-warning-foreground hover:bg-warning/85 focus-visible:ring-warning/40 aria-expanded:bg-warning/85', + 'sm' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active h-7 gap-1.5 rounded-md px-2.75 in-data-[slot=button-group]:rounded-md [&_svg:not([class*=\'size-\'])]:size-3.5 bg-warning text-warning-foreground hover:bg-warning/85 focus-visible:ring-warning/40 aria-expanded:bg-warning/85', + 'lg' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active h-9 gap-2 px-3.75 bg-warning text-warning-foreground hover:bg-warning/85 focus-visible:ring-warning/40 aria-expanded:bg-warning/85', + 'icon' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active size-8 bg-warning text-warning-foreground hover:bg-warning/85 focus-visible:ring-warning/40 aria-expanded:bg-warning/85', + 'icon-xs' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3 bg-warning text-warning-foreground hover:bg-warning/85 focus-visible:ring-warning/40 aria-expanded:bg-warning/85', + 'icon-sm' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active size-7 rounded-md in-data-[slot=button-group]:rounded-md bg-warning text-warning-foreground hover:bg-warning/85 focus-visible:ring-warning/40 aria-expanded:bg-warning/85', + 'icon-lg' => 'focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 active:bg-primary-active size-9 bg-warning text-warning-foreground hover:bg-warning/85 focus-visible:ring-warning/40 aria-expanded:bg-warning/85', + ], + ], + 'button_group' => [ + 'button-group' => 'has-[>[data-slot=button-group]]:gap-2 group/button-group flex w-fit items-stretch *:focus-visible:relative *:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-e-lg [&>[data-slot=select-trigger]:not([class*=\'w-\'])]:w-fit [&>input]:flex-1 [&>*:not(:first-child)]:rounded-s-none [&>*:not(:first-child)]:border-s-0 [&>*:not(:last-child)]:rounded-e-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-e-lg!', + 'button' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active aria-expanded:bg-primary-hover h-8 gap-2 px-3.75', + ], + 'spinner' => [ + 'button' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active aria-expanded:bg-primary-hover h-8 gap-2 px-3.75 cursor-progress', + 'button-spinner' => 'lucide lucide-loader-circle lucide-loader-2 animate-spin', + ], + 'status' => [ + 'neutral' => 'gap-1 font-normal inline-flex w-fit shrink-0 items-center rounded-sm border whitespace-nowrap [&>svg]:shrink-0 border-input bg-muted text-foreground h-5.5 px-1.75 text-xs [&>svg]:size-3', + 'info' => 'gap-1 font-normal inline-flex w-fit shrink-0 items-center rounded-sm border whitespace-nowrap [&>svg]:shrink-0 border-preset-blue-border bg-preset-blue text-preset-blue-foreground h-5.5 px-1.75 text-xs [&>svg]:size-3', + 'success' => 'gap-1 font-normal inline-flex w-fit shrink-0 items-center rounded-sm border whitespace-nowrap [&>svg]:shrink-0 border-preset-green-border bg-preset-green text-preset-green-foreground h-5.5 px-1.75 text-xs [&>svg]:size-3', + 'warning' => 'gap-1 font-normal inline-flex w-fit shrink-0 items-center rounded-sm border whitespace-nowrap [&>svg]:shrink-0 border-preset-gold-border bg-preset-gold text-preset-gold-foreground h-5.5 px-1.75 text-xs [&>svg]:size-3', + 'danger' => 'gap-1 font-normal inline-flex w-fit shrink-0 items-center rounded-sm border whitespace-nowrap [&>svg]:shrink-0 border-preset-red-border bg-preset-red text-preset-red-foreground h-5.5 px-1.75 text-xs [&>svg]:size-3', + 'pending' => 'gap-1 font-normal inline-flex w-fit shrink-0 items-center rounded-sm border whitespace-nowrap [&>svg]:shrink-0 border-preset-cyan-border bg-preset-cyan text-preset-cyan-foreground h-5.5 px-1.75 text-xs [&>svg]:size-3', + ], + 'alert' => [ + 'neutral' => [ + 'callout' => 'gap-0.5 px-2.5 py-2 text-sm has-data-[slot=alert-action]:pe-18 has-[>svg]:gap-x-2 *:[svg]:translate-y-0.5 *:[svg:not([class*=\'size-\'])]:size-4 group/alert relative grid w-full rounded-lg border text-start has-data-[slot=alert-action]:relative has-[>svg]:grid-cols-[auto_1fr] *:[svg]:row-span-2 bg-card text-card-foreground *:[svg]:text-muted-foreground pe-10', + 'alert-title' => 'font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground', + 'alert-description' => 'text-sm md:text-pretty [&_p:not(:last-child)]:mb-4 text-muted-foreground [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground text-pretty', + 'button' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3 top-2 end-2 touch:size-11 touch:top-0 touch:end-0 absolute', + ], + 'info' => [ + 'callout' => 'gap-0.5 px-2.5 py-2 text-sm has-data-[slot=alert-action]:pe-18 has-[>svg]:gap-x-2 *:[svg]:translate-y-0.5 *:[svg:not([class*=\'size-\'])]:size-4 group/alert relative grid w-full rounded-lg border text-start has-data-[slot=alert-action]:relative has-[>svg]:grid-cols-[auto_1fr] *:[svg]:row-span-2 border-info/30 bg-info/5 text-foreground *:[svg]:text-info pe-10', + 'alert-title' => 'font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground', + 'alert-description' => 'text-sm md:text-pretty [&_p:not(:last-child)]:mb-4 text-muted-foreground [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground text-pretty', + 'button' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3 top-2 end-2 touch:size-11 touch:top-0 touch:end-0 absolute', + ], + 'success' => [ + 'callout' => 'gap-0.5 px-2.5 py-2 text-sm has-data-[slot=alert-action]:pe-18 has-[>svg]:gap-x-2 *:[svg]:translate-y-0.5 *:[svg:not([class*=\'size-\'])]:size-4 group/alert relative grid w-full rounded-lg border text-start has-data-[slot=alert-action]:relative has-[>svg]:grid-cols-[auto_1fr] *:[svg]:row-span-2 border-success/30 bg-success/5 text-foreground *:[svg]:text-success pe-10', + 'alert-title' => 'font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground', + 'alert-description' => 'text-sm md:text-pretty [&_p:not(:last-child)]:mb-4 text-muted-foreground [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground text-pretty', + 'button' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3 top-2 end-2 touch:size-11 touch:top-0 touch:end-0 absolute', + ], + 'warning' => [ + 'callout' => 'gap-0.5 px-2.5 py-2 text-sm has-data-[slot=alert-action]:pe-18 has-[>svg]:gap-x-2 *:[svg]:translate-y-0.5 *:[svg:not([class*=\'size-\'])]:size-4 group/alert relative grid w-full rounded-lg border text-start has-data-[slot=alert-action]:relative has-[>svg]:grid-cols-[auto_1fr] *:[svg]:row-span-2 border-warning/40 bg-warning/10 text-foreground *:[svg]:text-warning pe-10', + 'alert-title' => 'font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground', + 'alert-description' => 'text-sm md:text-pretty [&_p:not(:last-child)]:mb-4 text-muted-foreground [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground text-pretty', + 'button' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3 top-2 end-2 touch:size-11 touch:top-0 touch:end-0 absolute', + ], + 'danger' => [ + 'callout' => 'gap-0.5 px-2.5 py-2 text-sm has-data-[slot=alert-action]:pe-18 has-[>svg]:gap-x-2 *:[svg]:translate-y-0.5 *:[svg:not([class*=\'size-\'])]:size-4 group/alert relative grid w-full rounded-lg border text-start has-data-[slot=alert-action]:relative has-[>svg]:grid-cols-[auto_1fr] *:[svg]:row-span-2 border-destructive/30 bg-destructive/5 text-foreground *:data-[slot=alert-title]:text-destructive *:[svg]:text-destructive pe-10', + 'alert-title' => 'font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground', + 'alert-description' => 'text-sm md:text-pretty [&_p:not(:last-child)]:mb-4 text-muted-foreground [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground text-pretty', + 'button' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground size-6 rounded-sm in-data-[slot=button-group]:rounded-sm [&_svg:not([class*=\'size-\'])]:size-3 top-2 end-2 touch:size-11 touch:top-0 touch:end-0 absolute', + ], + ], + 'card' => [ + 'card' => 'ring-border bg-card text-card-foreground gap-(--card-spacing) overflow-hidden rounded-xl py-(--card-spacing) text-sm ring-1 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col', + 'card-header' => 'gap-1 rounded-t-xl px-(--card-spacing) [.border-b]:pb-(--card-spacing) group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]', + 'card-title' => 'text-base leading-snug font-semibold group-data-[size=sm]/card:text-sm', + 'card-description' => 'text-muted-foreground text-sm', + 'card-content' => 'px-(--card-spacing)', + 'card-footer' => 'bg-muted/50 rounded-b-xl border-t p-(--card-spacing) flex items-center', + ], + 'accordion' => [ + 'accordion' => 'flex w-full flex-col', + 'accordion-item' => 'not-last:border-b', + 'accordion-trigger' => 'py-2.5 text-sm font-medium **:data-[slot=accordion-trigger-icon]:size-4 group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent text-start transition-all outline-none hover:underline focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:after:border-ring disabled:pointer-events-none disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ms-auto **:data-[slot=accordion-trigger-icon]:text-muted-foreground', + 'accordion-trigger-icon' => 'lucide lucide-chevron-down pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden', + 'accordion-content' => 'text-sm overflow-hidden data-open:animate-accordion-down data-closed:animate-accordion-up', + ], + 'tabs' => [ + 'tabs' => 'gap-2 group/tabs flex data-horizontal:flex-col', + 'tabs-list' => 'rounded-lg p-[3px] group-data-horizontal/tabs:h-8 data-[variant=line]:rounded-none group/tabs-list inline-flex w-fit items-center justify-center text-muted-foreground group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col bg-muted', + 'tabs-trigger' => 'gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg:not([class*=\'size-\'])]:size-4 has-data-[icon=inline-end]:pe-1 has-data-[icon=inline-start]:ps-1 relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center whitespace-nowrap text-muted-foreground transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 group-data-[variant=line]/tabs-list:flex-none group-data-[variant=line]/tabs-list:rounded-none group-data-[variant=line]/tabs-list:px-0 group-data-[variant=line]/tabs-list:py-3 group-data-[variant=line]/tabs-list:h-auto group-data-[variant=line]/tabs-list:font-normal group-data-[variant=line]/tabs-list:text-foreground dark:group-data-[variant=line]/tabs-list:text-foreground group-data-[variant=line]/tabs-list:hover:text-primary-7 dark:group-data-[variant=line]/tabs-list:hover:text-primary-7 group-data-[variant=line]/tabs-list:data-active:text-primary-7 dark:group-data-[variant=line]/tabs-list:data-active:text-primary-7 group-data-[variant=line]/tabs-list:data-active:[text-shadow:0_0_0.25px_currentColor] group-data-vertical/tabs:group-data-[variant=line]/tabs-list:px-6 group-data-vertical/tabs:group-data-[variant=line]/tabs-list:py-2 group-data-horizontal/tabs:group-data-[variant=line]/tabs-list:after:-bottom-px group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground after:absolute after:bg-primary after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-end-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100', + 'tabs-content' => 'text-sm flex-1 outline-none', + ], + 'nav_tabs' => [ + 'nav-tabs' => 'min-w-0 border-b', + 'nav-tabs-item' => 'gap-1.5 text-sm touch:min-h-11 [&_svg]:size-4 relative inline-flex shrink-0 items-center whitespace-nowrap transition-colors outline-none focus-visible:ring-3 focus-visible:ring-ring/50 [&_svg]:shrink-0 h-11 px-0 font-normal after:inset-x-0 after:h-0.5 text-foreground after:absolute after:-bottom-px after:bg-transparent hover:text-primary data-active:text-primary data-active:[text-shadow:0_0_0.25px_currentColor] data-active:after:bg-primary', + 'nav-tabs-count' => 'text-muted-foreground tabular-nums', + 'list' => 'gap-8 no-scrollbar flex scroll-fade-x overflow-x-auto overscroll-x-contain', + 'item' => 'flex', + ], + 'modal' => [ + 'modal-header' => 'gap-1.5 px-4 pt-4 pb-2 group-data-[mobile=fullscreen]/modal:max-sm:pt-[max(1rem,env(safe-area-inset-top))] flex shrink-0 flex-col pe-12', + 'modal-title' => 'text-base leading-snug font-semibold', + 'button' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground size-7 rounded-md in-data-[slot=button-group]:rounded-md top-3 end-3 absolute', + 'modal-body' => 'px-4 py-2 min-h-0 last:pb-4 flex-1 overflow-y-auto overscroll-contain', + 'modal-footer' => 'gap-2 px-4 py-3 mt-2 sm:flex-row sm:justify-end flex shrink-0 flex-col-reverse border-t bg-muted/50 group-data-[mobile=sheet]/modal:max-sm:pb-[max(0.75rem,env(safe-area-inset-bottom))] group-data-[mobile=fullscreen]/modal:max-sm:pb-[max(0.75rem,env(safe-area-inset-bottom))]', + 'sizes' => [ + 'sm' => 'group/modal text-sm fixed z-50 flex flex-col overflow-hidden bg-popover text-popover-foreground shadow-popup ring-1 ring-border duration-150 outline-none data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0 sm:max-w-sm inset-x-0 bottom-0 max-h-[calc(100dvh-3rem)] rounded-t-xl data-open:slide-in-from-bottom-10 data-closed:slide-out-to-bottom-10 sm:inset-auto sm:top-1/2 sm:start-1/2 sm:-translate-x-1/2 sm:rtl:translate-x-1/2 sm:-translate-y-1/2 sm:w-[calc(100%-2rem)] sm:h-auto sm:max-h-[calc(100dvh-2rem)] sm:rounded-xl sm:data-open:zoom-in-95 sm:data-closed:zoom-out-95 sm:data-open:slide-in-from-bottom-0 sm:data-closed:slide-out-to-bottom-0', + 'default' => 'group/modal text-sm fixed z-50 flex flex-col overflow-hidden bg-popover text-popover-foreground shadow-popup ring-1 ring-border duration-150 outline-none data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0 sm:max-w-lg inset-x-0 bottom-0 max-h-[calc(100dvh-3rem)] rounded-t-xl data-open:slide-in-from-bottom-10 data-closed:slide-out-to-bottom-10 sm:inset-auto sm:top-1/2 sm:start-1/2 sm:-translate-x-1/2 sm:rtl:translate-x-1/2 sm:-translate-y-1/2 sm:w-[calc(100%-2rem)] sm:h-auto sm:max-h-[calc(100dvh-2rem)] sm:rounded-xl sm:data-open:zoom-in-95 sm:data-closed:zoom-out-95 sm:data-open:slide-in-from-bottom-0 sm:data-closed:slide-out-to-bottom-0', + 'lg' => 'group/modal text-sm fixed z-50 flex flex-col overflow-hidden bg-popover text-popover-foreground shadow-popup ring-1 ring-border duration-150 outline-none data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0 sm:max-w-2xl inset-x-0 bottom-0 max-h-[calc(100dvh-3rem)] rounded-t-xl data-open:slide-in-from-bottom-10 data-closed:slide-out-to-bottom-10 sm:inset-auto sm:top-1/2 sm:start-1/2 sm:-translate-x-1/2 sm:rtl:translate-x-1/2 sm:-translate-y-1/2 sm:w-[calc(100%-2rem)] sm:h-auto sm:max-h-[calc(100dvh-2rem)] sm:rounded-xl sm:data-open:zoom-in-95 sm:data-closed:zoom-out-95 sm:data-open:slide-in-from-bottom-0 sm:data-closed:slide-out-to-bottom-0', + 'xl' => 'group/modal text-sm fixed z-50 flex flex-col overflow-hidden bg-popover text-popover-foreground shadow-popup ring-1 ring-border duration-150 outline-none data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0 sm:max-w-4xl inset-x-0 bottom-0 max-h-[calc(100dvh-3rem)] rounded-t-xl data-open:slide-in-from-bottom-10 data-closed:slide-out-to-bottom-10 sm:inset-auto sm:top-1/2 sm:start-1/2 sm:-translate-x-1/2 sm:rtl:translate-x-1/2 sm:-translate-y-1/2 sm:w-[calc(100%-2rem)] sm:h-auto sm:max-h-[calc(100dvh-2rem)] sm:rounded-xl sm:data-open:zoom-in-95 sm:data-closed:zoom-out-95 sm:data-open:slide-in-from-bottom-0 sm:data-closed:slide-out-to-bottom-0', + 'full' => 'group/modal text-sm fixed z-50 flex flex-col overflow-hidden bg-popover text-popover-foreground shadow-popup ring-1 ring-border duration-150 outline-none data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0 sm:max-w-[calc(100%-2rem)] sm:h-[calc(100dvh-2rem)] inset-x-0 bottom-0 max-h-[calc(100dvh-3rem)] rounded-t-xl data-open:slide-in-from-bottom-10 data-closed:slide-out-to-bottom-10 sm:inset-auto sm:top-1/2 sm:start-1/2 sm:-translate-x-1/2 sm:rtl:translate-x-1/2 sm:-translate-y-1/2 sm:w-[calc(100%-2rem)] sm:h-auto sm:max-h-[calc(100dvh-2rem)] sm:rounded-xl sm:data-open:zoom-in-95 sm:data-closed:zoom-out-95 sm:data-open:slide-in-from-bottom-0 sm:data-closed:slide-out-to-bottom-0', + ], + ], + 'table' => [ + 'table-container' => 'relative w-full overflow-x-auto focus-visible:outline-2 focus-visible:outline-ring', + 'table' => 'w-full caption-bottom text-sm', + 'table-header' => '[&_tr]:border-b', + 'table-row' => 'hover:bg-muted data-[state=selected]:bg-primary-1 data-[state=selected]:hover:bg-primary-2 border-b border-border transition-colors has-aria-expanded:bg-muted', + 'table-head' => 'text-foreground bg-muted relative h-auto px-4 py-3 text-start align-middle font-semibold whitespace-nowrap [&:has([role=checkbox])]:pe-0 not-last:before:absolute not-last:before:end-0 not-last:before:top-1/2 not-last:before:h-[1.6em] not-last:before:w-px not-last:before:-translate-y-1/2 not-last:before:bg-border', + 'table-body' => '[&_tr:last-child]:border-0', + 'table-cell' => 'px-4 py-3 align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0', + ], + 'pagination' => [ + 'pagination' => 'mx-auto flex w-full justify-center', + 'pagination-content' => 'gap-0.5 flex items-center', + 'pagination-item' => '', + 'pagination-link' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground h-8 gap-2 px-3.75 ps-1.5!', + 'pagination-ellipsis' => 'size-8 [&_svg:not([class*=\'size-\'])]:size-4 flex items-center justify-center', + 'link' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground size-8', + 'link_active' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 bg-card hover:border-primary-5 hover:text-primary-7 active:border-primary-7 active:text-primary-7 aria-expanded:border-primary-5 aria-expanded:text-primary-7 size-8 border-primary text-primary', + 'previous' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground h-8 gap-2 px-3.75 ps-1.5!', + 'next' => 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-normal focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*=\'size-\'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[color,background-color,border-color,box-shadow] duration-200 outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 hover:bg-secondary hover:text-foreground active:bg-[color-mix(in_oklab,var(--secondary),var(--foreground)_6%)] aria-expanded:bg-secondary aria-expanded:text-foreground h-8 gap-2 px-3.75 pe-1.5!', + ], + 'empty' => [ + 'empty' => 'gap-4 p-6 min-w-0 flex w-full flex-1 flex-col items-center justify-center rounded-xl border-dashed text-center text-balance', + 'empty-header' => 'gap-2 max-w-sm flex flex-col items-center', + 'empty-icon' => 'mb-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 size-8 [&_svg:not([class*=\'size-\'])]:size-4 flex shrink-0 items-center justify-center rounded-lg bg-muted text-foreground', + 'empty-title' => 'text-sm font-medium tracking-tight', + 'empty-description' => 'text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary', + 'empty-content' => 'gap-2.5 text-sm max-w-sm min-w-0 flex w-full flex-col items-center text-balance', + ], + 'description_list' => [ + 'stacked' => [ + 'description-list-container' => '@container', + 'description-list' => 'text-sm grid divide-y', + 'description-list-item' => 'gap-x-4 gap-y-1 py-3 grid', + 'description-list-label' => 'font-medium text-muted-foreground', + 'description-list-value' => 'gap-2 min-w-0 flex items-start break-words text-foreground', + ], + 'inline' => [ + 'description-list-container' => '@container', + 'description-list' => 'text-sm grid divide-y', + 'description-list-item' => 'gap-x-4 gap-y-1 py-3 grid grid-cols-[minmax(0,min(var(--onu-dl-label-width,12rem),40%))_minmax(0,1fr)]', + 'description-list-label' => 'font-medium text-muted-foreground', + 'description-list-value' => 'gap-2 min-w-0 flex items-start break-words text-foreground', + ], + ], + 'badge' => [ + 'badge' => 'h-5 gap-1 px-2 py-0.5 text-xs font-medium has-data-[icon=inline-end]:pe-1.5 has-data-[icon=inline-start]:ps-1.5 [&>svg]:size-3! group/badge inline-flex w-fit shrink-0 items-center justify-center overflow-hidden rounded-4xl border border-transparent whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none bg-primary text-primary-foreground [a]:hover:bg-primary/80', + ], +]; diff --git a/resources/views/onu/accordion.blade.php b/resources/views/onu/accordion.blade.php new file mode 100644 index 0000000..13e921b --- /dev/null +++ b/resources/views/onu/accordion.blade.php @@ -0,0 +1,32 @@ +
merge(['class' => $frameworkClasses()->classes('accordion.accordion'), 'id' => $id, 'data-slot' => 'accordion']) !!}> + @foreach($items as $name => $item) + @php + $collapse_id = $generateCollapseIdByName($name); + $slot_name = $generateSlotByName($name); + $title_slot = $slot_name . 'Header'; + @endphp + + + @isset(${$title_slot}) + + {{ ${$title_slot} }} + + @endisset + + @isset(${$slot_name}) + {{ ${$slot_name} }} + @else + {!! nl2br(e($item['content'] ?? '')) !!} + @endisset + + @endforeach + + {{ $slot }} +
diff --git a/resources/views/onu/accordion/collapse.blade.php b/resources/views/onu/accordion/collapse.blade.php new file mode 100644 index 0000000..b2ac1c3 --- /dev/null +++ b/resources/views/onu/accordion/collapse.blade.php @@ -0,0 +1,9 @@ +
merge(['class' => $frameworkClasses()->classes('accordion.accordion-content')]) !!} data-slot="accordion-content" data-accordion="{{ $parent }}"> +
+ @if($content) + {!! nl2br(e($content)) !!} + @else + {{ $slot }} + @endif +
+
diff --git a/resources/views/onu/accordion/header.blade.php b/resources/views/onu/accordion/header.blade.php new file mode 100644 index 0000000..75da70d --- /dev/null +++ b/resources/views/onu/accordion/header.blade.php @@ -0,0 +1,4 @@ +merge(['class' => $frameworkClasses()->classes('accordion.accordion-trigger') . ' list-none cursor-pointer [&::-webkit-details-marker]:hidden', 'aria-controls' => $target]) !!} data-slot="accordion-trigger"> + @if($slot->isNotEmpty()){{ $slot }}@else{{ $title }}@endif + + diff --git a/resources/views/onu/accordion/item.blade.php b/resources/views/onu/accordion/item.blade.php new file mode 100644 index 0000000..3d7573b --- /dev/null +++ b/resources/views/onu/accordion/item.blade.php @@ -0,0 +1,25 @@ +
merge(['class' => $frameworkClasses()->classes('accordion.accordion-item') . ' group/accordion-item', 'name' => $parent]) !!} data-slot="accordion-item" @if($show) open @endif> + + @if(! empty($header)) + {{ $header }} + @endif + + + + @if($content) + {!! nl2br(e($content)) !!} + @else + {{ $slot }} + @endif + +
diff --git a/resources/views/onu/alert.blade.php b/resources/views/onu/alert.blade.php new file mode 100644 index 0000000..6d1c498 --- /dev/null +++ b/resources/views/onu/alert.blade.php @@ -0,0 +1,21 @@ +@php($c = $frameworkClasses()) +@php($tone = $c->tone($type)) +
merge(['class' => 'alert ' . $c->alert($type)]) }} data-slot="callout" data-tone="{{ $tone }}" role="{{ in_array($tone, ['danger', 'warning']) ? 'alert' : 'status' }}"> + @if($icon) + + @endif + + @if(isset($heading) && $heading) +
{{ $heading }}
+ @endif + +
+ {!! $slot !!} +
+ + @if($dismissible) + + @endif +
diff --git a/resources/views/onu/bulk-actions.blade.php b/resources/views/onu/bulk-actions.blade.php new file mode 100644 index 0000000..f8792a9 --- /dev/null +++ b/resources/views/onu/bulk-actions.blade.php @@ -0,0 +1,25 @@ +@unless(empty($actions)) +
+
+
+ +
+
+
+ + {{ __('forms::strings.apply') }} + +
+
+ + +@endunless diff --git a/resources/views/onu/button-group.blade.php b/resources/views/onu/button-group.blade.php new file mode 100644 index 0000000..3df29f6 --- /dev/null +++ b/resources/views/onu/button-group.blade.php @@ -0,0 +1,8 @@ +
merge([ + 'class' => $frameworkClasses()->classes('button_group.button-group') . ($inline ? '' : ' flex-col'), + ]) !!} + data-slot="button-group" + data-orientation="{{ $inline ? 'horizontal' : 'vertical' }}" + role="group" +>{!! $slot !!}
diff --git a/resources/views/onu/button.blade.php b/resources/views/onu/button.blade.php new file mode 100644 index 0000000..368832d --- /dev/null +++ b/resources/views/onu/button.blade.php @@ -0,0 +1,10 @@ + diff --git a/resources/views/onu/card.blade.php b/resources/views/onu/card.blade.php new file mode 100644 index 0000000..f1e1c6d --- /dev/null +++ b/resources/views/onu/card.blade.php @@ -0,0 +1,38 @@ +
merge([ + 'class' => $frameworkClasses()->classes('card.card'), + ]) !!} + data-slot="card" +> + {{ $image_top ?? '' }} + + @if(! empty($header) || ! empty($title) || ! empty($subtitle)) + + @if(! empty($header)) + {{ $header }} + @endif + + @if(! empty($title)) + + {{ $title }} + + @endif + + @if(! empty($subtitle)) + + {{ $subtitle }} + + @endif + + @endif + +
+ {!! $slot !!} +
+ + @if(! empty($footer)) + + {{ $footer }} + + @endif +
diff --git a/resources/views/onu/card/footer.blade.php b/resources/views/onu/card/footer.blade.php new file mode 100644 index 0000000..aa087c5 --- /dev/null +++ b/resources/views/onu/card/footer.blade.php @@ -0,0 +1,3 @@ +
merge(['class' => $frameworkClasses()->classes('card.card-footer')]) !!} data-slot="card-footer"> + {!! $slot !!} +
diff --git a/resources/views/onu/card/header.blade.php b/resources/views/onu/card/header.blade.php new file mode 100644 index 0000000..0587a6c --- /dev/null +++ b/resources/views/onu/card/header.blade.php @@ -0,0 +1,3 @@ +
merge(['class' => $frameworkClasses()->classes('card.card-header')]) !!} data-slot="card-header"> + {!! $slot !!} +
diff --git a/resources/views/onu/card/subtitle.blade.php b/resources/views/onu/card/subtitle.blade.php new file mode 100644 index 0000000..6589599 --- /dev/null +++ b/resources/views/onu/card/subtitle.blade.php @@ -0,0 +1,3 @@ +
merge(['class' => $frameworkClasses()->classes('card.card-description')]) !!} data-slot="card-description"> + {!! $slot !!} +
diff --git a/resources/views/onu/card/title.blade.php b/resources/views/onu/card/title.blade.php new file mode 100644 index 0000000..a691e4d --- /dev/null +++ b/resources/views/onu/card/title.blade.php @@ -0,0 +1,3 @@ +
merge(['class' => $frameworkClasses()->classes('card.card-title')]) !!} data-slot="card-title"> + {!! $slot !!} +
diff --git a/resources/views/onu/checkbox.blade.php b/resources/views/onu/checkbox.blade.php new file mode 100644 index 0000000..8e39489 --- /dev/null +++ b/resources/views/onu/checkbox.blade.php @@ -0,0 +1,43 @@ +@php($c = $frameworkClasses()) + +
+ + merge([ + 'class' => $c->classes('checkbox.native') . ' forms-checkbox' . ($hasErrorAndShow($name) ? ' is-invalid' : ''), + 'aria-invalid' => $hasErrorAndShow($name) ? 'true' : null, + ]) !!} + data-slot="checkbox" + id="{{ $attributes->get('id') ?: $id() }}" + name="{{ $name }}" + type="checkbox" + value="{{ $value }}" + @required($required) + @checked($checked) + > + +
+ @if($slot->isNotEmpty()){{ $slot }}@endif + + @if(! empty($help)) + + {{ $help }} + + @endif +
+
+ + @if($hasErrorAndShow($name)) + + @endif + + @if($showJsErrors) + + @endif +
diff --git a/resources/views/onu/errors.blade.php b/resources/views/onu/errors.blade.php new file mode 100644 index 0000000..847916f --- /dev/null +++ b/resources/views/onu/errors.blade.php @@ -0,0 +1,8 @@ +@error($name, $bag) +
merge(['class' => 'invalid-feedback ' . $frameworkClasses()->classes('field_invalid.field-errors')]) !!} data-slot="field-errors" aria-live="polite"> +

+ + {{ $message }} +

+
+@enderror diff --git a/resources/views/onu/file.blade.php b/resources/views/onu/file.blade.php new file mode 100644 index 0000000..55f7594 --- /dev/null +++ b/resources/views/onu/file.blade.php @@ -0,0 +1,82 @@ +@php($c = $frameworkClasses()) + +
classes('input.input') . ' flex h-auto min-h-8 items-center gap-2 py-1 ps-1', + $fileInputClass, + 'fileinput-exists' => (bool) $value, + 'fileinput-new' => empty($value), + 'is-invalid' => $hasError($name), + 'disabled' => $disabled, + ]) + @if(! $disabled) + data-provides="fileinput{{ $upload ? '-upload' : '' }}" + @endif + > + + + @if($upload) + + + {{ trans('forms::strings.fileinput_upload_file') }} + + @else + {{ trans('forms::strings.fileinput_select_file') }} + {{ trans('forms::strings.fileinput_change_file') }} + @endif + {{ trans('forms::strings.fileinput_nothing_selected') }} + + merge([ + 'class' => ($hasError($name) ? 'is-invalid' : ''), + 'required' => $required, + 'disabled' => $disabled + ]) !!} + type="file" + accept="{{ implode(',', $mimetypes) }}" + name="{{ $name }}" + @if($label && ! $attributes->get('id')) + id="{{ $id() }}" + @endif + @if($upload && $maxSize) + data-max-file-size="{{ $maxSize }}" + @endif + /> + + + @unless(empty($value)) + + {{ $fileName ?: $value }} + + @endunless + + +
+ + @if($showHint || (! empty($help))) + + @empty($help) + {{ $getHint() }} + @else + {!! $help !!} + @endempty + + @endif + + @if($hasErrorAndShow($name)) + + @endif + + @if($showJsErrors) + + @endif +
diff --git a/resources/views/onu/file/file-input.blade.php b/resources/views/onu/file/file-input.blade.php new file mode 100644 index 0000000..686cd20 --- /dev/null +++ b/resources/views/onu/file/file-input.blade.php @@ -0,0 +1,31 @@ +
(bool) $value, + 'fileinput-new' => empty($value), + ])> + + {{ trans('forms::strings.fileinput_select_file') }} + {{ trans('forms::strings.fileinput_change_file') }} + merge([ + 'class' => ($hasError($name) ? 'is-invalid' : ''), + 'required' => $required + ]) !!} + type="file" + accept="{{ implode(',', $mimeTypes) }}" + name="{{ $name }}" + @if($label && ! $attributes->get('id')) + id="{{ $id() }}" + @endif + /> + + + @unless(empty($value)) + + {{ $value }} + + @endunless + + +
diff --git a/resources/views/onu/filter-submit.blade.php b/resources/views/onu/filter-submit.blade.php new file mode 100644 index 0000000..8f4fc85 --- /dev/null +++ b/resources/views/onu/filter-submit.blade.php @@ -0,0 +1,59 @@ +
+ {{ $before ?? '' }} + + + {{ __('forms::strings.filter') }} + + + @if(! empty($export)) + @if(is_array($export)) + + + {{ __('forms::strings.export') }} + + +
+ + + + +
+
+ @else + + {{ __('forms::strings.export') }} + + @endif + @endif + + {{ $after ?? '' }} + + + {{ __('forms::strings.clear') }} + + + {{ $slot }} +
diff --git a/resources/views/onu/form-group.blade.php b/resources/views/onu/form-group.blade.php new file mode 100644 index 0000000..307a20d --- /dev/null +++ b/resources/views/onu/form-group.blade.php @@ -0,0 +1,18 @@ +@php($c = $frameworkClasses()) +@if($wrap) + @php($layout = $inline && ! $floating ? 'field_inline' : 'field') +
merge(['class' => $c->classes("{$layout}.form-field") . ' mb-4']) !!} data-slot="form-field" data-label-layout="{{ $inline && ! $floating ? 'inline' : 'stacked' }}"> +
+ @if($showLabel) +
+ +
+ @endif +
+ {!! $slot !!} +
+
+
+@else + {!! $slot !!} +@endif diff --git a/resources/views/onu/image.blade.php b/resources/views/onu/image.blade.php new file mode 100644 index 0000000..527ace6 --- /dev/null +++ b/resources/views/onu/image.blade.php @@ -0,0 +1,95 @@ +@php($c = $frameworkClasses()) + +
(bool) $value, + 'fileinput-new' => empty($value), + 'is-invalid' => $hasError($name), + 'disabled' => $disabled, + ]) + @if(! $disabled) + data-provides="fileinput{{ $upload ? '-upload' : '' }}" + @endif + > + +
+
$cover || $circle, + 'relative flex items-center justify-center overflow-hidden rounded-lg border border-dashed border-input bg-muted text-muted-foreground cursor-pointer', + 'rounded-full' => $circle, + 'fullwidth-preview' => $fullwidth, + ]) + style="aspect-ratio: 1 / {{ $maintainAspectRatio ? $aspectRatio : 1 }};" + @if(! $disabled) + data-trigger="fileinput" + @endif + > +
+ +
+ +
+ + {{ trans('forms::strings.imageinput_select_image') }} +
+
+ +
+ + + @if($upload) + + {{ trans('forms::strings.fileinput_upload_file') }} + @else + {{ trans('forms::strings.fileinput_select_file') }} + @endif + + @if(! $upload) + {{ trans('forms::strings.fileinput_change_file') }} + @endif + merge([ + 'class' => ($hasError($name) ? 'is-invalid' : ''), + 'required' => $required, + 'disabled' => $disabled + ]) !!} + type="file" + accept="{{ implode(',', $mimetypes) }}" + name="{{ $name }}" + @if($label && ! $attributes->get('id')) + id="{{ $id() }}" + @endif + /> + + +
+
+
+ + @if($showHint || (! empty($help))) + + @empty($help) + {{ $getImageHint() }}
+ {{ $getHint() }} + @else + {!! $help !!} + @endempty +
+ @endif + + @if($hasErrorAndShow($name)) + + @endif + + @if($showJsErrors) + + @endif +
diff --git a/resources/views/onu/input-help.blade.php b/resources/views/onu/input-help.blade.php new file mode 100644 index 0000000..d355eca --- /dev/null +++ b/resources/views/onu/input-help.blade.php @@ -0,0 +1,3 @@ +

merge(['class' => $frameworkClasses()->classes('field.help-text')]) !!} data-slot="help-text"> + {!! $slot !!} +

diff --git a/resources/views/onu/input.blade.php b/resources/views/onu/input.blade.php new file mode 100644 index 0000000..11ccee0 --- /dev/null +++ b/resources/views/onu/input.blade.php @@ -0,0 +1,72 @@ +@php($c = $frameworkClasses()) +@php($grouped = $isDateInput() || (! empty($prepend)) || (! empty($append))) + + @if($grouped) +
+ @if($isDateInput()) + + @elseif(! empty($prepend)) +
+ {{ $prepend }} +
+ @endif + @endif + + @if($isFileInput()) + @include('forms::onu.file.file-input') + @else + merge([ + 'class' => ($grouped ? $c->classes('input_group.input-group-control') : $c->classes('input.input')) . ($hasError($name) ? ' is-invalid' : '') . ($isDateInput() ? ' ' . $datePickerClass() : ''), + 'required' => $required, + 'aria-invalid' => $hasError($name) ? 'true' : null, + ] + $getDefaultAttributes()) !!} + data-slot="{{ $grouped ? 'input-group-control' : 'input' }}" + type="{{ $type }}" + value="{{ $value ?? ($type === 'color' ? '#000000' : '') }}" + name="{{ $name }}" + @if($label && ! $attributes->get('id')) + id="{{ $id() }}" + @endif + @if($placeholder) + placeholder="{{ $placeholder }}" + @endif + /> + @endif + + @if($grouped) + @if($isDateInput()) +
+ +
+ @elseif(! empty($append)) +
+ {{ $append }} +
+ @endif +
+ @endif + + @if(! empty($help)) + + {{ $help }} + + @endif + + @if($hasErrorAndShow($name)) + + @endif + + @if($showJsErrors) + + @endif +
diff --git a/resources/views/onu/js-errors.blade.php b/resources/views/onu/js-errors.blade.php new file mode 100644 index 0000000..5d015fc --- /dev/null +++ b/resources/views/onu/js-errors.blade.php @@ -0,0 +1,3 @@ +
    merge(['class' => 'invalid-feedback ' . $frameworkClasses()->classes('field_invalid.field-errors') . ' ' . $name . '-error']) !!} data-slot="field-errors" aria-live="polite"> + {{ $slot }} +
diff --git a/resources/views/onu/label-required.blade.php b/resources/views/onu/label-required.blade.php new file mode 100644 index 0000000..e493d7d --- /dev/null +++ b/resources/views/onu/label-required.blade.php @@ -0,0 +1,3 @@ +@if($text) + merge(['class' => 'required ' . $frameworkClasses()->classes('field.required-marker')]) !!} data-slot="required-marker" aria-hidden="true">{{ $text }} +@endif diff --git a/resources/views/onu/label.blade.php b/resources/views/onu/label.blade.php new file mode 100644 index 0000000..2e859ee --- /dev/null +++ b/resources/views/onu/label.blade.php @@ -0,0 +1,10 @@ +@if($slot->isNotEmpty() || $label || $blankLabel) + +@endif diff --git a/resources/views/onu/link-button.blade.php b/resources/views/onu/link-button.blade.php new file mode 100644 index 0000000..4a9ec44 --- /dev/null +++ b/resources/views/onu/link-button.blade.php @@ -0,0 +1,11 @@ +merge([ + 'class' => $frameworkClasses()->button($color), + ]) !!} + data-slot="button" + data-variant="{{ $frameworkClasses()->buttonVariant($color) }}" + data-size="default" + @if($url) + href="{{ $url }}" + @endif +>{!! $slot !!} diff --git a/resources/views/onu/map-input.blade.php b/resources/views/onu/map-input.blade.php new file mode 100644 index 0000000..0cafd36 --- /dev/null +++ b/resources/views/onu/map-input.blade.php @@ -0,0 +1,88 @@ +@php($c = $frameworkClasses()) + + +
+ @if($hideInputs) + @if($enableCoordinates) + + + @endif + + @if($enableRadius) + + @endif + + @if($enablePolygon) + + @endif + @else + @if($enableCoordinates) +
+
+ +
+
+ +
+
+ @endif + + @if($enableRadius) + + {{ $radiusUnit == 'km' ? trans('forms::strings.km_abbr') : trans('forms::strings.meters_abbr') }} + + @endif + + @if($enablePolygon) + + @endif + @endif + +
+ +
+
+
+ + @if(! empty($help)) + + {!! $help !!} + + @endif + + @if($hasErrorAndShow($name)) + + @endif + + @if($showJsErrors) + + @endif +
+ +@include('forms::partials.assets', ['assets' => ['maps']]) diff --git a/resources/views/onu/modal.blade.php b/resources/views/onu/modal.blade.php new file mode 100644 index 0000000..d961b24 --- /dev/null +++ b/resources/views/onu/modal.blade.php @@ -0,0 +1,34 @@ +@php($c = $frameworkClasses()) +@php($sizes = ['sm' => 'sm', 'md' => 'default', 'default' => 'default', 'lg' => 'lg', 'xl' => 'xl', 'fullscreen' => 'full', 'full' => 'full']) +@php($size_key = $sizes[$modalSizeClass ? \Illuminate\Support\Str::after($modalSizeClass, 'modal-') : $size] ?? 'lg') +@php($modal_id = $attributes->get('id') ?: $id()) +merge(['class' => 'forms-dialog ' . $c->classes("modal.sizes.{$size_key}")]) }} + id="{{ $modal_id }}" + data-slot="dialog-content" + @if($title) + aria-labelledby="{{ $modal_id }}-title" + @endif +> + @if($title) +
+

+ {{ $title }} +

+
+ @endif + + + +
+ {{ $slot }} +
+ + @if(! empty($footer)) +
+ {{ $footer }} +
+ @endif +
diff --git a/resources/views/onu/nav-tabs.blade.php b/resources/views/onu/nav-tabs.blade.php new file mode 100644 index 0000000..71ab9e1 --- /dev/null +++ b/resources/views/onu/nav-tabs.blade.php @@ -0,0 +1,35 @@ +@php($c = $frameworkClasses()) + diff --git a/resources/views/onu/no-items.blade.php b/resources/views/onu/no-items.blade.php new file mode 100644 index 0000000..c7b645c --- /dev/null +++ b/resources/views/onu/no-items.blade.php @@ -0,0 +1,23 @@ +@php($c = $frameworkClasses()) +
merge(['class' => $c->classes('empty.empty') . ' border']) !!} data-slot="empty"> +
+
+ +
+ @if($title) +
{{ $title }}
+ @endif +
{{ $message }}
+
+ @if($showCreate) +
+ @if($slot->isNotEmpty()) + {{ $slot }} + @else + + {{ __('forms::strings.create_new') }} + + @endif +
+ @endif +
diff --git a/resources/views/onu/pagination.blade.php b/resources/views/onu/pagination.blade.php new file mode 100644 index 0000000..e216fc1 --- /dev/null +++ b/resources/views/onu/pagination.blade.php @@ -0,0 +1,66 @@ +@php($c = \Javaabu\Forms\Frameworks\Frameworks::get('onu')) +@if($paginator->count()) +
+
+ {{ trans_choice('forms::strings.pagination_showing', $paginator->total(), ['count' => $paginator->count(), 'total' => $paginator->total()]) }} +
+
+@endif + +@if ($paginator->hasPages()) + +@endif diff --git a/resources/views/onu/radio.blade.php b/resources/views/onu/radio.blade.php new file mode 100644 index 0000000..f396300 --- /dev/null +++ b/resources/views/onu/radio.blade.php @@ -0,0 +1,43 @@ +@php($c = $frameworkClasses()) + +
+ + merge([ + 'class' => $c->classes('radio.native') . ' forms-radio' . ($hasErrorAndShow($name) ? ' is-invalid' : ''), + 'aria-invalid' => $hasErrorAndShow($name) ? 'true' : null, + ]) !!} + data-slot="radio" + id="{{ $attributes->get('id') ?: $id() }}" + name="{{ $name }}" + type="radio" + value="{{ $value }}" + @required($required) + @checked($checked) + > + +
+ @if($slot->isNotEmpty()){{ $slot }}@endif + + @if(! empty($help)) + + {{ $help }} + + @endif +
+
+ + @if($hasErrorAndShow($name)) + + @endif + + @if($showJsErrors) + + @endif +
diff --git a/resources/views/onu/select.blade.php b/resources/views/onu/select.blade.php new file mode 100644 index 0000000..990ec39 --- /dev/null +++ b/resources/views/onu/select.blade.php @@ -0,0 +1,154 @@ + + @php($c = $frameworkClasses()) + @if((! empty($prepend)) || (! empty($append))) +
+ @if(! empty($prepend)) +
+ {{ $prepend }} +
+ @endif + @endif + +
+ + + @unless($multiple) + + @endunless +
+ + @if((! empty($prepend)) || (! empty($append))) + @if(! empty($append)) +
+ {{ $append }} +
+ @endif +
+ @endif + + @if(! empty($help)) + + {!! $help !!} + + @endif + + @if($hasErrorAndShow($name)) + + @endif + + @if($showJsErrors) + + @endif +
+ +@if($shouldShowSyncField()) + +@endif + +@if($isSelect2) + @include('forms::partials.assets', ['assets' => ['select']]) +@endif diff --git a/resources/views/onu/status.blade.php b/resources/views/onu/status.blade.php new file mode 100644 index 0000000..b2ef1d4 --- /dev/null +++ b/resources/views/onu/status.blade.php @@ -0,0 +1,7 @@ +merge(['class' => 'status ' . $frameworkClasses()->badge($color)]) !!} data-slot="status-badge" data-tone="{{ $frameworkClasses()->tone($color) }}"> + @if($slot->isNotEmpty()) + {{ $slot }} + @else + {{ $label }} + @endif + diff --git a/resources/views/onu/table.blade.php b/resources/views/onu/table.blade.php new file mode 100644 index 0000000..717fddc --- /dev/null +++ b/resources/views/onu/table.blade.php @@ -0,0 +1,60 @@ +@php($c = $frameworkClasses()) +
merge(['class' => 'table-responsive ' . $c->classes('table.table-container')]) !!} data-slot="table-container"> + + @if(empty($noBulk)) + @if(isset($bulkForm) && $bulkForm->isNotEmpty()) + +
+ {{ $bulkForm }} +
+ @endif + @endif + + {{ $beforeTable ?? '' }} + +
+ @if(empty($noCheckbox)) +
+
+ + +
+
+ @endif + + + {{ $beforeHeaders ?? '' }} + + @if(empty($noCheckbox)) + + @endif + {{ $headers ?? '' }} + + {{ $afterHeaders ?? '' }} + + + @if(empty($tbodyOpen)) + + @else + {{ $tbodyOpen }} + @endif + + {{ $rows ?? '' }} + + + {{ $afterTbody ?? '' }} +
+ +
+
+ + @if(empty($noBulk)) + @if(isset($bulkForm) && $bulkForm->isNotEmpty()) +
+ @endif + @endif +
+ +@if(empty($no_pagination)) + {{ $pagination ?? '' }} +@endif diff --git a/resources/views/onu/table/cell.blade.php b/resources/views/onu/table/cell.blade.php new file mode 100644 index 0000000..e5b1e4b --- /dev/null +++ b/resources/views/onu/table/cell.blade.php @@ -0,0 +1,24 @@ +merge(['class' => $frameworkClasses()->classes('table.table-cell')]) }} data-slot="table-cell" + @if($showLabel && $name) + data-col="{{ $label ?: $label() }}" + @endif +> + @if($slot->isNotEmpty()) + {{ $slot }} + @elseif($isAdminModel()) + {!! $value->admin_link !!} + @elseif($isAdminModelCollection()) + {!! $value->implode('admin_link', trans('forms::strings.table_array_separator')) !!} + @else + @if($isStatusEnum()) + + @elseif($multiline) + {!! nl2br(e($value ?: trans('forms::strings.blank'))) !!} + @elseif(is_array($value)) + {{ implode(trans('forms::strings.table_array_separator'), $value) }} + @else + {{ $formatValue() }} + @endif + @endif + + diff --git a/resources/views/onu/table/empty-row.blade.php b/resources/views/onu/table/empty-row.blade.php new file mode 100644 index 0000000..e35c8cc --- /dev/null +++ b/resources/views/onu/table/empty-row.blade.php @@ -0,0 +1,10 @@ +@php($c = $frameworkClasses()) + + + {{ $slot }} + + diff --git a/resources/views/onu/table/heading.blade.php b/resources/views/onu/table/heading.blade.php new file mode 100644 index 0000000..c864a10 --- /dev/null +++ b/resources/views/onu/table/heading.blade.php @@ -0,0 +1,20 @@ +merge([ + 'class' => $frameworkClasses()->classes('table.table-head') . ($sortable ? ' ' . $addSortClass() : '') + ]) }} + data-slot="table-head" +> + @if($slot->isNotEmpty()) + {{ $slot }} + @else + {{ $label }} + @endif + diff --git a/resources/views/onu/table/row.blade.php b/resources/views/onu/table/row.blade.php new file mode 100644 index 0000000..523534f --- /dev/null +++ b/resources/views/onu/table/row.blade.php @@ -0,0 +1,10 @@ +@php($c = $frameworkClasses()) +merge(['class' => $c->classes('table.table-row')]) }} data-slot="table-row"> + @if(empty($noCheckbox)) + + + + @endif + + {{ $slot }} + diff --git a/resources/views/onu/tabs.blade.php b/resources/views/onu/tabs.blade.php new file mode 100644 index 0000000..5e7705a --- /dev/null +++ b/resources/views/onu/tabs.blade.php @@ -0,0 +1,29 @@ +@php($c = $frameworkClasses()) +
merge(['class' => 'tab-container ' . $c->classes('tabs.tabs')]) !!} data-slot="tabs" data-orientation="horizontal"> +
+ @foreach($tabs as $item) + + @endforeach +
+ + @foreach($tabs as $item) + @isset(${$generateSlotByName($item['name'])}) + + {{ ${$generateSlotByName($item['name'])} }} + + @endisset + @endforeach +
diff --git a/resources/views/onu/tabs/nav-item.blade.php b/resources/views/onu/tabs/nav-item.blade.php new file mode 100644 index 0000000..5b1ce81 --- /dev/null +++ b/resources/views/onu/tabs/nav-item.blade.php @@ -0,0 +1,25 @@ +@if($isTab) + +@else + class([$frameworkClasses()->classes('tabs.tabs-trigger'), 'pointer-events-none opacity-50' => $disabled]) !!}>@if($slot->isNotEmpty()){{ $slot }}@else{{ $title }}@endif +@endif diff --git a/resources/views/onu/tabs/pane.blade.php b/resources/views/onu/tabs/pane.blade.php new file mode 100644 index 0000000..e3da2d2 --- /dev/null +++ b/resources/views/onu/tabs/pane.blade.php @@ -0,0 +1,13 @@ +
class([ + 'tab-pane', + $frameworkClasses()->classes('tabs.tabs-content'), + 'active' => $active, + 'hidden' => ! $active, + ]) !!} + id="{{ $id() }}" + role="tabpanel" + data-slot="tabs-content" + data-state="{{ $active ? 'active' : 'inactive' }}" + aria-labelledby="{{ $labelledBy() }}" + tabindex="0" +>{{ $slot }}
diff --git a/resources/views/onu/text-entry.blade.php b/resources/views/onu/text-entry.blade.php new file mode 100644 index 0000000..4d5e334 --- /dev/null +++ b/resources/views/onu/text-entry.blade.php @@ -0,0 +1,39 @@ +@php($c = $frameworkClasses()) +@php($layout = $inline ? 'inline' : 'stacked') +
merge(['class' => $c->classes("description_list.{$layout}.description-list") . ' divide-y-0']) !!} data-slot="description-list" data-layout="{{ $layout }}"> +
+ @if($showLabel) +
{{ $label ?: $label() }}
+ @endif + +
+
+ @if($slot->isNotEmpty()) + {{ $slot }} + @elseif($isAdminModel()) + {!! $value->admin_link !!} + @elseif($isAdminModelCollection()) + {!! $value->implode('admin_link', trans('forms::strings.table_array_separator')) !!} + @else + @if($isStatusEnum()) + + @elseif($isNativeEnum()) + {{ $getEnumLabel() }} + @elseif($multiline) + {!! nl2br(e($value ?: trans('forms::strings.blank'))) !!} + @elseif(is_array($value)) +
    + @foreach($value as $item) +
  • {{ $item }}
  • + @endforeach +
+ @elseif($value && $wysiwyg) + {!! $value !!} + @else + {{ empty($value) && (! is_numeric($value)) ? trans('forms::strings.blank') : $value }} + @endif + @endif +
+
+
+
diff --git a/resources/views/onu/textarea.blade.php b/resources/views/onu/textarea.blade.php new file mode 100644 index 0000000..95e74d0 --- /dev/null +++ b/resources/views/onu/textarea.blade.php @@ -0,0 +1,36 @@ + + + + @if(! empty($help)) + + {!! $help !!} + + @endif + + @if($hasErrorAndShow($name)) + + @endif + + @if($showJsErrors) + + @endif + + +@if($wysiwyg) + @include('forms::partials.assets', ['assets' => ['wysiwyg']]) +@endif diff --git a/scripts/onu-classes.mjs b/scripts/onu-classes.mjs new file mode 100644 index 0000000..b1f57e8 --- /dev/null +++ b/scripts/onu-classes.mjs @@ -0,0 +1,193 @@ +// Extracts the class strings @javaabu/onu renders, so the Blade `onu` views output +// exactly the same classes as the React components. +// +// It server-renders Onu's own components and records the classes of every element +// with a data-slot, then writes resources/onu/classes.php. Run with `pnpm onu-classes` +// after upgrading @javaabu/onu; CI fails when the file is out of date (`pnpm onu-classes --check`). +import { readFileSync, writeFileSync } from "node:fs" +import { createRequire } from "node:module" +import { createElement as h } from "react" +import { renderToStaticMarkup } from "react-dom/server" +import * as Onu from "@javaabu/onu" +import * as P from "@javaabu/onu/primitives" + +const require = createRequire(import.meta.url) +const { version } = require("@javaabu/onu/package.json") +const OUT = "resources/onu/classes.php" + +/** Every data-slot in the HTML → its class attribute (first occurrence wins). */ +function slots(html) { + const found = {} + for (const match of html.matchAll(/<([a-z0-9]+)\b([^>]*)>/g)) { + const attrs = match[2] + const slot = attrs.match(/\bdata-slot="([^"]+)"/)?.[1] + if (!slot || slot in found) continue + found[slot] = decode(attrs.match(/\bclass="([^"]*)"/)?.[1] ?? "") + } + return found +} + +function decode(value) { + return value + .replaceAll("&", "&") + .replaceAll(">", ">") + .replaceAll("<", "<") + .replaceAll(""", '"') + .replaceAll("'", "'") +} + +const render = (element) => slots(renderToStaticMarkup(element)) + +/** Classes of every element in order, for wrappers that have no data-slot. */ +function tags(element) { + return [...renderToStaticMarkup(element).matchAll(/<([a-z0-9]+)\b([^>]*)>/g)].map((match) => ({ + tag: match[1], + slot: match[2].match(/\bdata-slot="([^"]+)"/)?.[1], + class: decode(match[2].match(/\bclass="([^"]*)"/)?.[1] ?? ""), + })) +} + +/** The class of the first element after the given slot (or from the start) matching the tag. */ +function after(list, slot, tag, nth = 1) { + let index = slot ? list.findIndex((item) => item.slot === slot) : -1 + let seen = 0 + for (index += 1; index < list.length; index++) { + if (list[index].tag === tag && ++seen === nth) return list[index].class + } + throw new Error(`No <${tag}> #${nth} after ${slot}`) +} +const option = (value, label) => h("option", { value }, label) + +const classes = {} + +// Fields: label, required marker, help, errors, stacked and inline layouts. +classes.field = render(h(Onu.FormField, { label: "Title", name: "title", help: "Help", required: true }, h(Onu.TextInput, { name: "title" }))) +classes.field_invalid = render(h(Onu.FormField, { label: "Title", name: "title", error: "Required" }, h(Onu.TextInput, { name: "title" }))) +classes.field_inline = render(h(Onu.FormField, { label: "Title", name: "title", labelLayout: "inline" }, h(Onu.TextInput, { name: "title" }))) + +for (const [key, layout] of [["field", "stacked"], ["field_inline", "inline"]]) { + const list = tags(h(Onu.FormField, { label: "Title", name: "title", labelLayout: layout, error: "Required" }, h(Onu.TextInput, { name: "title" }))) + classes[key].grid = after(list, "form-field", "div", 1) + classes[key].label_row = after(list, "form-field", "div", 2) + classes[key].control = after(list, "label", "div", 1) + classes[key].error_line = after(list, "field-errors", "p", 1) + classes[key].error_icon = after(list, "field-errors", "svg", 1).replace(/lucide\S*\s?/g, "").trim() +} + +// Controls +classes.input = render(h(P.Input, { name: "title" })) +classes.input_group_text = after(tags(h(P.InputGroup, null, h(P.InputGroupAddon, null, h(P.InputGroupText, null, "MVR")))), "input-group-addon", "span", 1) +classes.input_group = render( + h(P.InputGroup, null, h(P.InputGroupAddon, null, h(P.InputGroupText, null, "MVR")), h(P.InputGroupInput, { name: "price" }), h(P.InputGroupAddon, { align: "inline-end" }, h(P.InputGroupButton, null, "Clear"))), +) +classes.textarea = render(h(P.Textarea, { name: "body" })) +classes.select = render(h(P.NativeSelect, { name: "status" }, h(P.NativeSelectOption, { value: "" }, "A"))) +classes.checkbox = render(h(P.Checkbox, { checked: true })) +classes.radio = render(h(P.RadioGroup, { defaultValue: "a" }, h(P.RadioGroupItem, { value: "a" }))) +// Onu's checkbox and radio are Radix buttons; Blade uses native inputs with the same classes, +// with the checked state from :checked instead of data-state. +const native = (value) => + `appearance-none ${value}`.replaceAll("data-[state=checked]:", "checked:").replaceAll("data-checked:", "checked:").replaceAll("aria-checked:", "checked:") +classes.checkbox.native = native(classes.checkbox.checkbox) +classes.radio.native = native(classes.radio["radio-group-item"]) +classes.choice = render(h(Onu.Checkbox, { label: "Agree", description: "Help", name: "agree" })) +{ + const list = tags(h(Onu.Checkbox, { label: "Agree", description: "Help", name: "agree" })) + classes.choice.control = after(list, "checkbox-field", "span", 1) + classes.choice.content = after(list, "checkbox", "div", 1) + classes.choice.description = after(list, "label", "p", 1) +} +classes.label = render(h(P.Label, null, "Title")) + +// Buttons: every variant x size. +const variants = ["default", "outline", "dashed", "secondary", "ghost", "destructive", "link", "success", "warning"] +const sizes = ["default", "xs", "sm", "lg", "icon", "icon-xs", "icon-sm", "icon-lg"] +classes.button = Object.fromEntries(variants.map((variant) => [variant, Object.fromEntries(sizes.map((size) => [size, Onu.buttonVariants({ variant, size })]))])) +classes.button_group = render(h(Onu.ButtonGroup, null, h(Onu.Button, null, "A"))) +classes.spinner = render(h(Onu.Button, { loading: true }, "Saving")) + +// Status badges and alerts, by tone. +const tones = ["neutral", "info", "success", "warning", "danger"] +classes.status = Object.fromEntries(["neutral", "info", "success", "warning", "danger", "pending"].map((tone) => [tone, Onu.statusBadgeVariants({ tone })])) +classes.alert = Object.fromEntries( + tones.map((tone) => [tone, render(h(Onu.Callout, { tone, title: "Heading", dismissible: true }, "Body"))]), +) + +// Display +classes.card = render( + h(P.Card, null, h(P.CardHeader, null, h(P.CardTitle, null, "Title"), h(P.CardDescription, null, "Subtitle")), h(P.CardContent, null, "Body"), h(P.CardFooter, null, "Footer")), +) +classes.accordion = render( + h(P.Accordion, { type: "single", defaultValue: "a", collapsible: true }, h(P.AccordionItem, { value: "a" }, h(P.AccordionTrigger, null, "Title"), h(P.AccordionContent, null, "Body"))), +) +classes.tabs = render( + h(P.Tabs, { defaultValue: "a" }, h(P.TabsList, null, h(P.TabsTrigger, { value: "a" }, "A"), h(P.TabsTrigger, { value: "b" }, "B")), h(P.TabsContent, { value: "a" }, "Body")), +) +const navTabs = h(Onu.NavTabs, { items: [{ label: "Active", href: "/a", count: 3 }, { label: "Other", href: "/b" }], currentHref: "/a" }) +classes.nav_tabs = render(navTabs) +classes.nav_tabs.list = after(tags(navTabs), "nav-tabs", "ul", 1) +classes.nav_tabs.item = after(tags(navTabs), "nav-tabs", "li", 1) +classes.modal = { + ...render(h(P.Dialog, { open: true }, h(Onu.ModalHeader, null, h(Onu.ModalTitle, null, "Title")), h(Onu.ModalBody, null, "Body"), h(Onu.ModalFooter, null, "Footer"))), + sizes: Object.fromEntries(["sm", "default", "lg", "xl", "full"].map((size) => [size, Onu.modalContentVariants({ size })])), +} +classes.table = render( + h(P.Table, null, h(P.TableHeader, null, h(P.TableRow, null, h(P.TableHead, null, "No"))), h(P.TableBody, null, h(P.TableRow, null, h(P.TableCell, null, "1")))), +) +classes.pagination = render( + h( + P.Pagination, + null, + h( + P.PaginationContent, + null, + h(P.PaginationItem, null, h(P.PaginationPrevious, { href: "#" })), + h(P.PaginationItem, null, h(P.PaginationLink, { href: "#", isActive: true }, "1")), + h(P.PaginationItem, null, h(P.PaginationLink, { href: "#" }, "2")), + h(P.PaginationItem, null, h(P.PaginationEllipsis)), + h(P.PaginationItem, null, h(P.PaginationNext, { href: "#" })), + ), + ), +) +classes.pagination.link = render(h(P.PaginationLink, { href: "#" }, "2"))["pagination-link"] +classes.pagination.link_active = render(h(P.PaginationLink, { href: "#", isActive: true }, "1"))["pagination-link"] +classes.pagination.previous = render(h(P.PaginationPrevious, { href: "#" }))["pagination-link"] +classes.pagination.next = render(h(P.PaginationNext, { href: "#" }))["pagination-link"] +classes.empty = render( + h(P.Empty, null, h(P.EmptyHeader, null, h(P.EmptyMedia, { variant: "icon" }, "i"), h(P.EmptyTitle, null, "Title"), h(P.EmptyDescription, null, "Text")), h(P.EmptyContent, null, "Action")), +) +classes.description_list = { + stacked: render(h(Onu.DescriptionList, { layout: "stacked" }, h(Onu.DescriptionListItem, { label: "Name" }, "Value"))), + inline: render(h(Onu.DescriptionList, { layout: "inline" }, h(Onu.DescriptionListItem, { label: "Name" }, "Value"))), +} +classes.badge = render(h(P.Badge, null, "3")) + +// PHP output +function php(value, indent = 1) { + const pad = " ".repeat(indent) + if (typeof value === "string") return `'${value.replaceAll("\\", "\\\\").replaceAll("'", "\\'")}'` + const entries = Object.entries(value).map(([key, item]) => `${pad}'${key}' => ${php(item, indent + 1)},`) + return `[\n${entries.join("\n")}\n${" ".repeat(indent - 1)}]` +} + +const output = `publishes([ __DIR__ . '/../resources/views' => resource_path('views/vendor/forms'), ], 'forms-views'); + + $this->publishes([ + __DIR__ . '/../dist' => public_path('vendor/forms'), + ], 'forms-assets'); } $this->loadTranslationsFrom(__DIR__ . '/../lang', 'forms'); diff --git a/src/Frameworks/Onu.php b/src/Frameworks/Onu.php index 6986d1a..946df17 100644 --- a/src/Frameworks/Onu.php +++ b/src/Frameworks/Onu.php @@ -32,10 +32,10 @@ class Onu implements Framework 'info' => 'info', 'success' => 'success', 'warning' => 'warning', - 'danger' => 'destructive', - 'secondary' => 'default', - 'light' => 'default', - 'dark' => 'default', + 'danger' => 'danger', + 'secondary' => 'neutral', + 'light' => 'neutral', + 'dark' => 'neutral', ]; public function name(): string @@ -68,7 +68,7 @@ public function buttonVariant(string $color): string public function tone(string $color): string { - return $this->tones[$color] ?? 'default'; + return $this->tones[$color] ?? 'neutral'; } public function button(string $color, ?string $size = null): string @@ -86,6 +86,6 @@ public function badge(string $color): string public function alert(string $type): string { - return $this->classes('alert.' . $this->tone($type)); + return $this->classes('alert.' . $this->tone($type) . '.callout'); } } diff --git a/tests/Feature/Frameworks/FrameworkSmokeTest.php b/tests/Feature/Frameworks/FrameworkSmokeTest.php new file mode 100644 index 0000000..a1410b7 --- /dev/null +++ b/tests/Feature/Frameworks/FrameworkSmokeTest.php @@ -0,0 +1,157 @@ + */ + public static function views(): array + { + $views = [ + 'accordion', + 'accordion-collapse', + 'accordion-header', + 'accordion-item', + 'accordion-slot', + 'accordion-unnamed', + 'boolean-entry', + 'bulk-actions', + 'button', + 'button-group', + 'button-link', + 'button-submit', + 'checkbox-slot', + 'conditional-link', + 'conditional-wrapper', + 'conditional-wrapper-checkbox', + 'date-inputs', + 'file-unbound', + 'file-value', + 'form', + 'form-card', + 'form-card-footer', + 'form-card-header', + 'form-card-subtitle', + 'form-card-title', + 'form-checkbox', + 'form-checkbox-helper-text', + 'form-checkbox-inline-required', + 'form-checkbox-required', + 'form-checkbox-selected', + 'form-filter', + 'form-group-blank', + 'form-help', + 'form-input', + 'form-input-floating', + 'form-input-help', + 'form-input-inline', + 'form-input-prepend-append', + 'form-input-required', + 'form-input-types', + 'form-input-without-label', + 'form-label', + 'form-label-floating', + 'form-label-inline', + 'form-label-required', + 'form-radio', + 'form-radio-required', + 'form-textarea', + 'js-errors', + 'label-blank', + 'label-slot', + 'latitude', + 'longitude', + 'multiple-select-keys', + 'nav-tabs', + 'no-items', + 'per-page', + 'per-page-custom', + 'radio-slot', + 'select-boolean-value', + 'select-multiple', + 'select-placeholder', + 'select-slot', + 'select-sync-field', + 'select-tags', + 'select-without-keys', + 'spoof-method', + 'status', + 'status-slot', + 'table', + 'table-cell', + 'table-cell-array', + 'table-cell-boolean', + 'table-cell-enum', + 'table-cell-model', + 'table-cell-multiline', + 'table-cell-status', + 'table-cell-value', + 'tabs', + 'text-entry', + 'text-entry-array', + 'text-entry-enum', + 'text-entry-model', + 'text-entry-multiline', + 'text-entry-status', + 'text-entry-value', + 'wysiwyg', + ]; + + $cases = []; + + foreach (['onu', 'bootstrap-6'] as $framework) { + foreach ($views as $view) { + $cases["{$framework} {$view}"] = [$framework, $view]; + } + } + + return $cases; + } + + #[Test] + #[DataProvider('frameworks')] + public function it_renders_laravel_pagination_with_every_framework(string $framework): void + { + $paginator = new LengthAwarePaginator(range(1, 10), 95, 10, 3, ['path' => '/articles']); + + $html = new Crawler($paginator->links("forms::{$framework}.pagination")->toHtml()); + + $this->assertStringContainsString('95', $html->text()); + $this->assertCount(1, $html->filter('.page-item.active')); + $this->assertCount(1, $html->filter('a[rel="prev"][href="/articles?page=2"]')); + $this->assertCount(1, $html->filter('a[rel="next"][href="/articles?page=4"]')); + } + + /** @return array */ + public static function frameworks(): array + { + return ['onu' => ['onu'], 'bootstrap-6' => ['bootstrap-6']]; + } + + #[Test] + #[DataProvider('views')] + public function it_renders_every_fixture_view_with_every_framework(string $framework, string $view): void + { + Activity::factory()->count(2)->create(); + + $this->setFramework($framework); + $this->registerTestRoute($view); + + $this->visit("/{$view}") + ->assertResponseOk(); + } +} diff --git a/tests/Feature/Frameworks/OnuTest.php b/tests/Feature/Frameworks/OnuTest.php new file mode 100644 index 0000000..4a7c23f --- /dev/null +++ b/tests/Feature/Frameworks/OnuTest.php @@ -0,0 +1,181 @@ +setFrameworkOnu(); + + $this->onu = new Onu; + } + + #[Test] + public function it_renders_inputs_with_the_classes_onu_renders(): void + { + $html = $this->renderBlade(''); + + $field = $html->filter('div[data-slot="form-field"][data-label-layout="stacked"]'); + $input = $html->filter('input[data-slot="input"][name="title"]#title'); + + $this->assertCount(1, $field); + $this->assertCount(1, $input); + $this->assertEquals($this->onu->classes('input.input'), $input->attr('class')); + $this->assertEquals('ސުރުޚީ', trim($html->filter('label[data-slot="label"][for="title"]')->getNode(0)->firstChild->textContent)); + $this->assertCount(1, $html->filter('label span[data-slot="required-marker"][aria-hidden="true"]')); + } + + #[Test] + public function it_renders_help_text_and_errors_like_onu_form_field(): void + { + $this->withViewErrors(['title' => 'ސުރުޚީ ލިޔުން ލާޒިމް.']); + + $html = $this->renderBlade(<<<'BLADE' + + ދިވެހިން ލިޔޭ + + BLADE); + + $this->assertEquals('true', $html->filter('input[name="title"]')->attr('aria-invalid')); + $this->assertStringContainsString('ދިވެހިން ލިޔޭ', $html->filter('p[data-slot="help-text"]')->text()); + $this->assertStringContainsString('ސުރުޚީ ލިޔުން ލާޒިމް.', $html->filter('div[data-slot="field-errors"][aria-live="polite"]')->text()); + $this->assertCount(1, $html->filter('div[data-slot="field-errors"] svg[data-icon="circle-alert"]')); + } + + #[Test] + public function it_lays_out_inline_fields_with_onu_inline_layout(): void + { + $html = $this->renderBlade(''); + + $field = $html->filter('div[data-slot="form-field"][data-label-layout="inline"]'); + + $this->assertCount(1, $field); + $this->assertEquals($this->onu->classes('field_inline.grid'), $field->filter('div')->eq(1)->attr('class')); + } + + #[Test] + public function it_renders_prepend_and_append_as_an_input_group(): void + { + $html = $this->renderBlade(<<<'BLADE' + + MVR + .00 + + BLADE); + + $this->assertCount(1, $html->filter('div[data-slot="input-group"][role="group"]')); + $this->assertCount(1, $html->filter('div[data-slot="input-group-addon"][data-align="inline-start"]')); + $this->assertCount(1, $html->filter('div[data-slot="input-group-addon"][data-align="inline-end"]')); + $this->assertCount(1, $html->filter('input[data-slot="input-group-control"][name="price"]')); + } + + #[Test] + public function it_renders_selects_as_onu_native_selects(): void + { + $html = $this->renderBlade(''); + + $this->assertCount(1, $html->filter('div[data-slot="native-select-wrapper"] > select[data-slot="native-select"][name="atoll"]')); + $this->assertCount(1, $html->filter('svg[data-slot="native-select-icon"]')); + $this->assertStringContainsString('ކ. އަތޮޅު', $html->filter('option[value="K"]')->text()); + } + + #[Test] + public function it_renders_native_checkboxes_and_radios_with_onu_classes(): void + { + $html = $this->renderBlade(''); + + $checkbox = $html->filter('input[type="checkbox"][data-slot="checkbox"]#agree'); + $radio = $html->filter('input[type="radio"][data-slot="radio"]'); + + $this->assertStringContainsString('checked:bg-primary', $checkbox->attr('class')); + $this->assertStringContainsString('forms-checkbox', $checkbox->attr('class')); + $this->assertStringContainsString('rounded-full', $radio->attr('class')); + $this->assertCount(2, $html->filter('div[data-slot$="-field"] label')); + } + + #[Test] + public function it_maps_button_colours_to_onu_variants(): void + { + $html = $this->renderBlade(<<<'BLADE' + A + B + C + BLADE); + + $danger = $html->filter('button[data-variant="destructive"]'); + + $this->assertEquals('button', $danger->attr('type')); + $this->assertStringContainsString($this->onu->classes('button.destructive.default'), $danger->attr('class')); + $this->assertCount(1, $html->filter('button[data-variant="outline"][type="submit"]')); + $this->assertCount(1, $html->filter('a[data-slot="button"][data-variant="outline"][href="/x"]')); + } + + #[Test] + public function it_renders_status_badges_and_alerts_by_tone(): void + { + $html = $this->renderBlade(<<<'BLADE' + ފާސް + ފޯމު ފުރިހަމަ ނުވޭ. + BLADE); + + $this->assertCount(1, $html->filter('span.status[data-slot="status-badge"][data-tone="success"]')); + $this->assertCount(1, $html->filter('div[data-slot="callout"][data-tone="danger"][role="alert"]')); + $this->assertEquals('މައްސަލައެއް', trim($html->filter('[data-slot="alert-title"]')->text())); + $this->assertCount(1, $html->filter('[data-slot="callout"] button[data-part="callout-dismiss"]')); + } + + #[Test] + public function it_renders_modals_as_dialogs_with_onu_modal_classes(): void + { + $html = $this->renderBlade('BodyFooter'); + + $dialog = $html->filter('dialog.forms-dialog#edit[data-slot="dialog-content"][aria-labelledby="edit-title"]'); + + $this->assertCount(1, $dialog); + $this->assertStringContainsString('sm:max-w-4xl', $dialog->attr('class')); + $this->assertCount(1, $html->filter('h2[data-slot="modal-title"]#edit-title')); + $this->assertCount(1, $html->filter('[data-slot="modal-footer"]')); + } + + #[Test] + public function it_renders_cards_accordions_and_tabs_with_onu_slots(): void + { + $html = $this->renderBlade(<<<'BLADE' + + ކާޑު + Body + Footer + + + + General + Details + + BLADE); + + $this->assertCount(1, $html->filter('[data-slot="card"] [data-slot="card-header"] [data-slot="card-title"]')); + $this->assertCount(1, $html->filter('[data-slot="card-footer"]')); + $this->assertCount(1, $html->filter('div[data-slot="accordion"]#faq details[data-slot="accordion-item"][open][name="faq"] summary[data-slot="accordion-trigger"]')); + $this->assertCount(2, $html->filter('[data-slot="tabs-list"][role="tablist"] button[role="tab"][data-slot="tabs-trigger"]')); + $this->assertCount(1, $html->filter('button[role="tab"][data-state="active"][aria-selected="true"]')); + $this->assertCount(1, $html->filter('[data-slot="tabs-content"].hidden')); + } + + #[Test] + public function it_renders_text_entries_as_onu_description_lists(): void + { + $html = $this->renderBlade(''); + + $this->assertCount(1, $html->filter('dl[data-slot="description-list"][data-layout="inline"] dt[data-slot="description-list-label"]')); + $this->assertStringContainsString('އަޙްމަދު', $html->filter('dd[data-slot="description-list-value"]')->text()); + } +} diff --git a/tests/Unit/FrameworksTest.php b/tests/Unit/FrameworksTest.php index 8507f41..067e577 100644 --- a/tests/Unit/FrameworksTest.php +++ b/tests/Unit/FrameworksTest.php @@ -45,4 +45,12 @@ public function it_maps_bootstrap_colours_to_bootstrap_6_classes(): void $this->assertEquals('badge theme-success', $framework->badge('success')); $this->assertEquals('alert theme-warning', $framework->alert('warning')); } + + #[Test] + public function it_defaults_to_the_onu_framework(): void + { + $config = require __DIR__ . '/../../config/config.php'; + + $this->assertEquals('onu', $config['framework']); + } } From 30d7d7bd8566763334130bbbdc0179f66815f486 Mon Sep 17 00:00:00 2001 From: Naffah Abdulla Rasheed Date: Wed, 4 Nov 2026 13:17:09 +0500 Subject: [PATCH 05/10] Feature parity with @javaabu/forms - New components: error-summary, pagination, formatted-value - Every field: form-group-class, thaana (dir/lang/data-thaana like Onu) - Textarea auto-resize, number decimals - Button size, start-icon, end-icon, loading; link-button disabled - Select2 clearable, min-chars, parent - Modal description and md size; errors first-only; file multiple; accordion item disabled; per-page label, show-label, per-page - Form summary, summary-title, focus-on-error, error-bag - Icons use data-icon-name, like Onu - String keys aligned with @javaabu/forms locales; NoItems strings translatable - docs/parity.md (Blade side of the matrix), react-forms#18 for open questions Closes #9 Co-Authored-By: Claude Opus 5.5 --- docs/parity.md | 89 +++++++ lang/dv/strings.php | 11 +- lang/en/strings.php | 11 +- .../bootstrap-6/accordion/item.blade.php | 2 +- resources/views/bootstrap-6/button.blade.php | 21 +- .../views/bootstrap-6/checkbox.blade.php | 2 +- .../views/bootstrap-6/error-summary.blade.php | 14 ++ resources/views/bootstrap-6/errors.blade.php | 4 +- resources/views/bootstrap-6/file.blade.php | 7 +- resources/views/bootstrap-6/image.blade.php | 2 +- resources/views/bootstrap-6/input.blade.php | 7 +- .../views/bootstrap-6/link-button.blade.php | 18 +- .../views/bootstrap-6/map-input.blade.php | 2 +- resources/views/bootstrap-6/modal.blade.php | 7 +- .../views/bootstrap-6/pagination.blade.php | 8 +- resources/views/bootstrap-6/radio.blade.php | 2 +- resources/views/bootstrap-6/select.blade.php | 10 +- .../views/bootstrap-6/table/row.blade.php | 2 +- .../views/bootstrap-6/textarea.blade.php | 7 +- resources/views/common/form.blade.php | 8 + .../views/common/formatted-value.blade.php | 13 ++ resources/views/common/icon.blade.php | 2 +- .../views/common/pagination-links.blade.php | 1 + resources/views/common/per-page.blade.php | 13 +- resources/views/onu/accordion/item.blade.php | 2 +- resources/views/onu/button.blade.php | 23 +- resources/views/onu/checkbox.blade.php | 2 +- resources/views/onu/error-summary.blade.php | 16 ++ resources/views/onu/errors.blade.php | 14 +- resources/views/onu/file.blade.php | 7 +- resources/views/onu/image.blade.php | 2 +- resources/views/onu/input.blade.php | 7 +- resources/views/onu/link-button.blade.php | 20 +- resources/views/onu/map-input.blade.php | 2 +- resources/views/onu/modal.blade.php | 3 + resources/views/onu/pagination.blade.php | 16 +- resources/views/onu/radio.blade.php | 2 +- resources/views/onu/select.blade.php | 10 +- resources/views/onu/table/row.blade.php | 2 +- resources/views/onu/textarea.blade.php | 7 +- src/Frameworks/Bootstrap6.php | 6 +- src/Frameworks/Onu.php | 2 +- src/Views/Components/Accordion/Item.php | 1 + src/Views/Components/Button.php | 32 ++- src/Views/Components/Component.php | 96 ++++++++ src/Views/Components/ErrorSummary.php | 59 +++++ src/Views/Components/Errors.php | 20 ++ src/Views/Components/File.php | 1 + src/Views/Components/Form.php | 4 + src/Views/Components/FormattedValue.php | 32 +++ src/Views/Components/LinkButton.php | 26 ++- src/Views/Components/Modal.php | 1 + src/Views/Components/NoItems.php | 4 +- src/Views/Components/Pagination.php | 25 ++ src/Views/Components/PerPage.php | 10 + src/Views/Components/Select2.php | 5 + src/Views/Components/Submit.php | 14 +- tests/Feature/FileTest.php | 18 +- tests/Feature/Frameworks/Bootstrap6Test.php | 2 +- tests/Feature/Frameworks/OnuTest.php | 2 +- tests/Feature/IconTest.php | 10 +- tests/Feature/ImageTest.php | 4 +- tests/Feature/NoItemsTest.php | 2 +- tests/Feature/ParityTest.php | 219 ++++++++++++++++++ 64 files changed, 870 insertions(+), 123 deletions(-) create mode 100644 docs/parity.md create mode 100644 resources/views/bootstrap-6/error-summary.blade.php create mode 100644 resources/views/common/formatted-value.blade.php create mode 100644 resources/views/common/pagination-links.blade.php create mode 100644 resources/views/onu/error-summary.blade.php create mode 100644 src/Views/Components/ErrorSummary.php create mode 100644 src/Views/Components/FormattedValue.php create mode 100644 src/Views/Components/Pagination.php create mode 100644 tests/Feature/ParityTest.php diff --git a/docs/parity.md b/docs/parity.md new file mode 100644 index 0000000..cd54890 --- /dev/null +++ b/docs/parity.md @@ -0,0 +1,89 @@ +--- +title: Parity with @javaabu/forms +sidebar_position: 90 +--- + +# Parity with @javaabu/forms (React) + +`javaabu/forms` (Blade) and [`@javaabu/forms`](https://github.com/Javaabu/react-forms) (React) have the same components, attributes, binding and error behaviour, so a form can move between Blade and Inertia React without being redesigned. The React repo keeps the matching matrix in its own `docs/parity.md`; this page shows the Blade status. + +**Naming:** Blade attributes are kebab-case and React props camelCase (`show-label` ↔ `showLabel`). Blade named slots are React props of the same name (`` ↔ `help`), and the default slot is `children`. + +**Status:** ✅ same in both · 🅱️ Blade only · ⚛️ React only · ≠ intentional difference + +## Components + +| Blade | React | Status | Notes | +| --- | --- | --- | --- | +| `form` | `Form` | ✅ | `summary`, `summary-title`, `focus-on-error`, `error-bag` added in v2. Blade's `summary` defaults to `false` (v1 had none); React's to `true` ([react-forms#18](https://github.com/Javaabu/react-forms/issues/18)). | +| `form-open`, `form-close` | — | 🅱️ | For forms split across partials. React has no equivalent. | +| `@model` / `@endmodel` | `Model` | ✅ | | +| — | `OldInput`, `FormsProvider` | ⚛️ | React context; Blade reads old input and config directly. | +| `form-group`, `label`, `label-required`, `input-help`, `errors` | `FormGroup`, `Label`, `LabelRequired`, `InputHelp`, `Errors` | ✅ | `errors` takes `first-only` (default `true`) in v2. | +| `error-summary` | `ErrorSummary` | ✅ | New in v2. Lists every error with a link to its field. | +| `input`, `text`, `email`, `password`, `number`, `tel`, `url`, `hidden`, `latitude`, `longitude` | same names | ✅ | `thaana`, `decimals` (number) and `form-group-class` added in v2. | +| `textarea` | `Textarea` | ✅ | `thaana` and `auto-resize` added in v2. | +| `wysiwyg`, `textarea wysiwyg` | `Wysiwyg` | ✅ | | +| `checkbox`, `radio` | `Checkbox`, `Radio` | ✅ | | +| `date`, `datetime`, `time` | `Date`, `Datetime`, `Time` | ✅ | | +| `select`, `select2` | `Select`, `Select2` | ✅ | `clearable` (alias of `allow-clear`), `min-chars` and `parent` added in v2. | +| `file`, `file-upload`, `image`, `image-upload` | `File`, `FileUpload`, `Image`, `ImageUpload` | ✅ | `multiple` added to `file` in v2. | +| `map-input` | `MapInput` | ✅ | | +| `conditional-wrapper` | `ConditionalWrapper` | ✅ | | +| `conditional-link` | `ConditionalLink` | ✅ | | +| `button`, `submit`, `link-button`, `button-group` | `Button`, `Submit`, `LinkButton`, `ButtonGroup` | ✅ | `size`, `start-icon`, `end-icon`, `loading` (button) and `disabled` (link button) added in v2. | +| `alert` | `Alert` | ✅ | | +| `card` (+ `.header`, `.title`, `.subtitle`, `.footer`) | `Card`, `CardHeader`, `CardTitle`, `CardSubtitle`, `CardFooter` | ✅ | | +| `accordion`, `accordion.item` | `Accordion`, `AccordionItem` | ✅ | `disabled` added to items in v2. | +| `accordion.header`, `accordion.collapse` | — | 🅱️ | Parts of an item, for custom item markup. | +| `tabs`, `tabs.pane`, `nav-tabs` | `Tabs`, `TabsPane`, `NavTabs` | ✅ | | +| `tabs.nav-item` | — | 🅱️ | Part of `tabs`. | +| `modal` | `Modal` | ✅ | `size` and `description` added in v2. | +| `status` | `Status` | ✅ | | +| `text-entry`, `boolean-entry`, `infolist` | `TextEntry`, `BooleanEntry`, `Infolist` | ✅ | React's `Infolist` `layout` sets every entry; in Blade set `inline` on each entry. | +| `formatted-value` | `FormattedValue` | ✅ | New in v2. | +| `table` (+ `.row`, `.cell`, `.heading`, `.empty-row`) | `Table`, `TableRow`, `TableCell`, `TableHeading`, `TableEmptyRow` | ✅ | | +| `bulk-actions`, `filter`, `filter-submit`, `per-page`, `search-form`, `no-items` | same names | ✅ | `per-page` takes `label`, `show-label` and `per-page` in v2. | +| `pagination` | `Pagination` | ✅ | New in v2. The paginator views (`forms::onu.pagination`, `forms::bootstrap-6.pagination`) still work with `$paginator->links()`. | +| `icon` | — | 🅱️ | React uses Onu's `Icon`. | +| `js-errors` | — | 🅱️ | A placeholder for errors from js-utilities' AJAX validation. React shows those errors itself. | + +## Attributes only Blade has + +| Component | Attribute | Why | +| --- | --- | --- | +| every field | `floating` | Bootstrap floating labels. Onu has none, so the `onu` framework renders a normal label. | +| every field | `show-js-errors` | Adds the `js-errors` placeholder (see above). | +| `date`, `datetime`, `time` | `date-format`, `icon`, `clear-icon`, `clear-btn-class`, `icon-wrapper-class` | Server-side formatting and Blade icon overrides. React formats on the client and uses Onu's pickers. | +| `select2` | `is-first`, `is-icon-select`, `icon-prefix`, `parent-modal` | Select2 and js-utilities options. `parent-modal` is unnecessary in React (its dropdowns portal). | +| `conditional-wrapper` | `json-encode` | How the value reaches the `data-` attribute. | +| `table.heading` | `colspan` | Plain HTML in React. | +| `tabs.pane` | `labelled-by` | Generated by React. | + +## Attributes only React has + +| Component | Prop | Why | +| --- | --- | --- | +| fields | `onChange`, `onValueChange`, `onCheckedChange` | React event props. | +| `Form` | `onSubmit`, `onSuccess`, `onError`, `onProgress`, `visitOptions`, `preserveScroll`, `preserveState`, `resetOnSuccess`, `processing`, `disableWhileProcessing`, `errors`, `old`, `components` | Inertia submission. Blade forms submit normally. | +| `File` | `onUploaded` | Upload callback. | +| `Modal` | `open`, `defaultOpen`, `onOpenChange`, `trigger` | React state. In Blade, open a modal with its `id` (see [Assets](advanced-usage/assets.md)). | + +## Behaviour + +| Behaviour | Status | +| --- | --- | +| Value precedence: old input, then `default`, then the bound model, then `value` | ✅ | +| Ids from names (`address[city]` → `address-city`) and labels from names (`first_name` → `First Name`, translated) | ✅ | +| Errors from the `default` bag, bracket names as dot keys, `name.*` errors on array fields | ✅ | +| `sync_` hidden field for multiple selects | ✅ | +| `aria-invalid="true"` on invalid controls | ✅ | +| Thaana fields: `dir="rtl" lang="dv" data-thaana` | ✅ | +| Strings: same keys in `lang/{en,dv}/strings.php` and React's `en`/`dv` locales | ✅ | + +## Open questions + +Raised with the React package in [Javaabu/react-forms#18](https://github.com/Javaabu/react-forms/issues/18): + +- `Form` `summary` default: Blade keeps `false` so v1 forms render unchanged. +- React has no `floating`, `dateFormat`, Select2 `isFirst`/icon-select options, or ConditionalWrapper `jsonEncode`. Each is either added in React or documented as Blade-only. diff --git a/lang/dv/strings.php b/lang/dv/strings.php index 6811429..1478c8a 100644 --- a/lang/dv/strings.php +++ b/lang/dv/strings.php @@ -29,7 +29,6 @@ 'close' => 'ބަންދުކުރޭ', 'create_new' => 'އާ އެއްޗެއް ހަދާ', 'select_all' => 'ހުރިހާ އެއްޗެއް ޚިޔާރުކުރޭ', - 'select_row' => 'މި ލައިން ޚިޔާރުކުރޭ', 'bulk_action' => 'ބަލްކް އެކްޝަން', 'apply' => 'ހިންގާ', 'filter' => 'ފިލްޓަރ', @@ -37,8 +36,14 @@ 'export_title' => 'XLSX އަށް އެކްސްޕޯޓްކުރޭ', 'export_options' => 'އިތުރު އެކްސްޕޯޓް އޮޕްޝަންތައް', 'pagination_showing' => 'ޖުމްލަ :total އިން :count ދައްކަނީ', - 'pagination_previous' => 'ކުރީގެ', - 'pagination_next' => 'ދެން', 'sections' => 'ސެކްޝަންތައް', 'pagination' => 'ޞަފްޙާތައް', + 'per_page' => 'ކޮންމެ ޞަފްޙާއެއްގައި', + 'previous' => 'ކުރީގެ', + 'next' => 'ދެން', + 'error_summary_title' => 'ތިރީގައިވާ ކުށްތައް ރަނގަޅުކުރައްވާ.', + 'select_row' => ':name ޚިޔާރުކުރޭ', + 'no_items_title' => 'މިތާ ހުސްވެފައި އެބައޮތް.', + 'no_items_message' => 'އާ :model_type އުފައްދަމާ ހިނގާ.', + 'items' => 'އެއްޗެހި', ]; diff --git a/lang/en/strings.php b/lang/en/strings.php index e82ef8d..2e71b5b 100644 --- a/lang/en/strings.php +++ b/lang/en/strings.php @@ -29,7 +29,6 @@ 'close' => 'Close', 'create_new' => 'Create New', 'select_all' => 'Select All', - 'select_row' => 'Select row', 'bulk_action' => 'Bulk Action', 'apply' => 'Apply', 'filter' => 'Filter', @@ -37,8 +36,14 @@ 'export_title' => 'Export to XLSX', 'export_options' => 'More export options', 'pagination_showing' => 'Showing :count from total :total entry|Showing :count from total :total entries', - 'pagination_previous' => 'Previous', - 'pagination_next' => 'Next', 'sections' => 'Sections', 'pagination' => 'Pagination', + 'per_page' => 'Per page', + 'previous' => 'Previous', + 'next' => 'Next', + 'error_summary_title' => 'Please correct the errors below.', + 'select_row' => 'Select :name', + 'no_items_title' => 'It\'s a bit lonely here.', + 'no_items_message' => 'Let\'s create some new :model_type.', + 'items' => 'items', ]; diff --git a/resources/views/bootstrap-6/accordion/item.blade.php b/resources/views/bootstrap-6/accordion/item.blade.php index 71bbc37..5284170 100644 --- a/resources/views/bootstrap-6/accordion/item.blade.php +++ b/resources/views/bootstrap-6/accordion/item.blade.php @@ -1,4 +1,4 @@ -
merge(['class' => 'accordion-item', 'name' => $parent]) !!} @if($show) open @endif> +
merge(['class' => 'accordion-item', 'name' => $parent]) !!} @if($show && ! $disabled) open @endif @if($disabled) data-disabled="true" aria-disabled="true" inert @endif> class([ - $frameworkClasses()->button($color), + $frameworkClasses()->button($color, $frameworkSize()), 'animate-submit' => $animate, + 'cursor-progress' => $loading && $framework === 'onu', ]) !!} @if($type) type="{{ $type }}" @endif ->{!! $slot !!} + @if($loading) + aria-busy="true" + aria-disabled="true" + data-loading="true" + @endif +> + @if($loading || $animate) + + @endif + @if($startIcon) + + @endif + {!! $slot !!} + @if($endIcon) + + @endif + diff --git a/resources/views/bootstrap-6/checkbox.blade.php b/resources/views/bootstrap-6/checkbox.blade.php index 0fec2c3..cce5f22 100644 --- a/resources/views/bootstrap-6/checkbox.blade.php +++ b/resources/views/bootstrap-6/checkbox.blade.php @@ -1,4 +1,4 @@ - +
merge([ diff --git a/resources/views/bootstrap-6/error-summary.blade.php b/resources/views/bootstrap-6/error-summary.blade.php new file mode 100644 index 0000000..5e68063 --- /dev/null +++ b/resources/views/bootstrap-6/error-summary.blade.php @@ -0,0 +1,14 @@ +@if($items()) +
merge(['class' => 'alert theme-danger error-summary']) }} role="alert" tabindex="-1" data-forms-summary> +
+

{{ $heading() }}

+ +
+
+@endif diff --git a/resources/views/bootstrap-6/errors.blade.php b/resources/views/bootstrap-6/errors.blade.php index 1a025c7..bf2dd53 100644 --- a/resources/views/bootstrap-6/errors.blade.php +++ b/resources/views/bootstrap-6/errors.blade.php @@ -1,5 +1,5 @@ -@error($name, $bag) +@foreach($messages() as $message)
merge(['class' => 'invalid-feedback d-block']) !!}> {{ $message }}
-@enderror +@endforeach diff --git a/resources/views/bootstrap-6/file.blade.php b/resources/views/bootstrap-6/file.blade.php index c5c7568..a31d5e2 100644 --- a/resources/views/bootstrap-6/file.blade.php +++ b/resources/views/bootstrap-6/file.blade.php @@ -1,4 +1,4 @@ - +
get('id')) id="{{ $id() }}" @endif diff --git a/resources/views/bootstrap-6/image.blade.php b/resources/views/bootstrap-6/image.blade.php index a9cdabd..0acdb57 100644 --- a/resources/views/bootstrap-6/image.blade.php +++ b/resources/views/bootstrap-6/image.blade.php @@ -1,4 +1,4 @@ - +
'form-control' . ($type === 'color' ? ' form-control-color' : '') . ($hasError($name) ? ' is-invalid' : '') . ($isDateInput() ? ' ' . $datePickerClass() : ''), 'required' => $required, 'aria-invalid' => $hasError($name) ? 'true' : null, - ] + $getDefaultAttributes()) !!} + ] + $thaanaAttributes() + $getDefaultAttributes()) !!} + @if($decimalPlaces() !== null) + data-decimals="{{ $decimalPlaces() }}" + @endif type="{{ $type }}" value="{{ $value ?? ($type === 'color' ? '#000000' : '') }}" name="{{ $name }}" diff --git a/resources/views/bootstrap-6/link-button.blade.php b/resources/views/bootstrap-6/link-button.blade.php index f8c7217..aacd982 100644 --- a/resources/views/bootstrap-6/link-button.blade.php +++ b/resources/views/bootstrap-6/link-button.blade.php @@ -1,9 +1,21 @@ merge([ - 'class' => $frameworkClasses()->button($color), + 'class' => $frameworkClasses()->button($color, $frameworkSize()) . ($disabled ? ' disabled pointer-events-none opacity-50' : ''), ]) !!} - @if($url) + @if($url && ! $disabled) href="{{ $url }}" @endif ->{!! $slot !!} + @if($disabled) + aria-disabled="true" + role="link" + @endif +> + @if($startIcon) + + @endif + {!! $slot !!} + @if($endIcon) + + @endif + diff --git a/resources/views/bootstrap-6/map-input.blade.php b/resources/views/bootstrap-6/map-input.blade.php index 4e8752f..4effc69 100644 --- a/resources/views/bootstrap-6/map-input.blade.php +++ b/resources/views/bootstrap-6/map-input.blade.php @@ -1,4 +1,4 @@ - +
'', 'full' => 'fullscreen', default => $dialog_size }) merge(['class' => 'dialog ' . ($modalSizeClass ? str_replace('modal-', 'dialog-', $modalSizeClass) : 'dialog-' . $size)]) }} + {{ $attributes->merge(['class' => 'dialog' . ($dialog_size ? " dialog-{$dialog_size}" : '')]) }} id="{{ $attributes->get('id') ?: $id() }}" @if($title) aria-labelledby="{{ ($attributes->get('id') ?: $id()) . '-title' }}" @@ -10,6 +12,9 @@

{{ $title }}

+ @if($description) +

{{ $description }}

+ @endif
diff --git a/resources/views/bootstrap-6/pagination.blade.php b/resources/views/bootstrap-6/pagination.blade.php index 388aff6..f694792 100644 --- a/resources/views/bootstrap-6/pagination.blade.php +++ b/resources/views/bootstrap-6/pagination.blade.php @@ -11,12 +11,12 @@
    {{-- Previous Page Link --}} @if ($paginator->onFirstPage()) -
  • +
  • @else
  • - +
  • @endif @@ -42,10 +42,10 @@ {{-- Next Page Link --}} @if ($paginator->hasMorePages())
  • - +
  • @else -
  • +
  • @endif diff --git a/resources/views/bootstrap-6/radio.blade.php b/resources/views/bootstrap-6/radio.blade.php index bee1de9..0ea52b6 100644 --- a/resources/views/bootstrap-6/radio.blade.php +++ b/resources/views/bootstrap-6/radio.blade.php @@ -1,4 +1,4 @@ - +
    merge([ diff --git a/resources/views/bootstrap-6/select.blade.php b/resources/views/bootstrap-6/select.blade.php index d0d6984..418323f 100644 --- a/resources/views/bootstrap-6/select.blade.php +++ b/resources/views/bootstrap-6/select.blade.php @@ -1,7 +1,7 @@ merge([]) }}> @if(empty($noCheckbox)) - + @endif diff --git a/resources/views/bootstrap-6/textarea.blade.php b/resources/views/bootstrap-6/textarea.blade.php index d2f0b2d..3ed60c3 100644 --- a/resources/views/bootstrap-6/textarea.blade.php +++ b/resources/views/bootstrap-6/textarea.blade.php @@ -1,10 +1,13 @@ - + + >{{ $value }} @if(! empty($help)) diff --git a/resources/views/common/form.blade.php b/resources/views/common/form.blade.php index 3333fb3..2ebee3a 100644 --- a/resources/views/common/form.blade.php +++ b/resources/views/common/form.blade.php @@ -24,3 +24,4 @@ {!! $slot !!} +{{ $unbindModel() }} diff --git a/resources/views/common/table/empty-row.blade.php b/resources/views/common/table/empty-row.blade.php index a5fe8c0..588c1ac 100644 --- a/resources/views/common/table/empty-row.blade.php +++ b/resources/views/common/table/empty-row.blade.php @@ -1,7 +1,7 @@ {{ $slot }} diff --git a/resources/views/common/table/heading.blade.php b/resources/views/common/table/heading.blade.php index 78062d7..4f236aa 100644 --- a/resources/views/common/table/heading.blade.php +++ b/resources/views/common/table/heading.blade.php @@ -16,4 +16,7 @@ @else {{ $label }} @endif + @if($sortable) + + @endif diff --git a/resources/views/onu/button.blade.php b/resources/views/onu/button.blade.php index 7042ea8..5451021 100644 --- a/resources/views/onu/button.blade.php +++ b/resources/views/onu/button.blade.php @@ -7,7 +7,9 @@ data-slot="button" data-variant="{{ $frameworkClasses()->buttonVariant($color) }}" data-size="{{ $frameworkSize() ?? 'default' }}" - type="{{ $type ?: 'button' }}" + @if($type) + type="{{ $type }}" + @endif @if($loading) aria-busy="true" aria-disabled="true" diff --git a/resources/views/onu/card.blade.php b/resources/views/onu/card.blade.php index f1e1c6d..32a553c 100644 --- a/resources/views/onu/card.blade.php +++ b/resources/views/onu/card.blade.php @@ -36,3 +36,4 @@ @endif
    +@isset($unbindModel){{ $unbindModel() }}@endisset diff --git a/resources/views/onu/checkbox.blade.php b/resources/views/onu/checkbox.blade.php index b0f1787..fc9a55a 100644 --- a/resources/views/onu/checkbox.blade.php +++ b/resources/views/onu/checkbox.blade.php @@ -3,7 +3,7 @@
    merge([ + {!! $attributes->except(['id'])->merge([ 'class' => $c->classes('checkbox.native') . ' forms-checkbox' . ($hasErrorAndShow($name) ? ' is-invalid' : ''), 'aria-invalid' => $hasErrorAndShow($name) ? 'true' : null, ]) !!} diff --git a/resources/views/onu/file/file-input.blade.php b/resources/views/onu/file/file-input.blade.php deleted file mode 100644 index 686cd20..0000000 --- a/resources/views/onu/file/file-input.blade.php +++ /dev/null @@ -1,31 +0,0 @@ -
    (bool) $value, - 'fileinput-new' => empty($value), - ])> - - {{ trans('forms::strings.fileinput_select_file') }} - {{ trans('forms::strings.fileinput_change_file') }} - merge([ - 'class' => ($hasError($name) ? 'is-invalid' : ''), - 'required' => $required - ]) !!} - type="file" - accept="{{ implode(',', $mimeTypes) }}" - name="{{ $name }}" - @if($label && ! $attributes->get('id')) - id="{{ $id() }}" - @endif - /> - - - @unless(empty($value)) - - {{ $value }} - - @endunless - - -
    diff --git a/resources/views/onu/image.blade.php b/resources/views/onu/image.blade.php index 3a4a4bc..b2dd391 100644 --- a/resources/views/onu/image.blade.php +++ b/resources/views/onu/image.blade.php @@ -58,6 +58,9 @@ type="file" accept="{{ implode(',', $mimetypes) }}" name="{{ $name }}" + @if($upload && $maxSize) + data-max-file-size="{{ $maxSize }}" + @endif @if($label && ! $attributes->get('id')) id="{{ $id() }}" @endif diff --git a/resources/views/onu/input.blade.php b/resources/views/onu/input.blade.php index 357b6e1..2e7441b 100644 --- a/resources/views/onu/input.blade.php +++ b/resources/views/onu/input.blade.php @@ -17,12 +17,8 @@
    @endif @endif - - @if($isFileInput()) - @include('forms::onu.file.file-input') - @else merge([ + {!! $attributes->except(['value'])->merge([ 'class' => ($grouped ? $c->classes('input_group.input-group-control') : $c->classes('input.input')) . ($hasError($name) ? ' is-invalid' : '') . ($isDateInput() ? ' ' . $datePickerClass() : ''), 'required' => $required, 'aria-invalid' => $hasError($name) ? 'true' : null, @@ -32,7 +28,7 @@ @endif data-slot="{{ $grouped ? 'input-group-control' : 'input' }}" type="{{ $type }}" - value="{{ $value ?? ($type === 'color' ? '#000000' : '') }}" + value="{{ $value ?? $attributes->get('value') ?? ($type === 'color' ? '#000000' : '') }}" name="{{ $name }}" @if($label && ! $attributes->get('id')) id="{{ $id() }}" @@ -41,7 +37,6 @@ placeholder="{{ $placeholder }}" @endif /> - @endif @if($grouped) @if($isDateInput()) diff --git a/resources/views/onu/pagination.blade.php b/resources/views/onu/pagination.blade.php index 18fd2b5..d760a70 100644 --- a/resources/views/onu/pagination.blade.php +++ b/resources/views/onu/pagination.blade.php @@ -1,5 +1,5 @@ @php($c = \Javaabu\Forms\Frameworks\Frameworks::get('onu')) -@if($paginator->count()) +@if($paginator->count() && method_exists($paginator, 'total'))
    {{ trans_choice('forms::strings.pagination_showing', $paginator->total(), ['count' => $paginator->count(), 'total' => $paginator->total()]) }} @@ -24,7 +24,7 @@ @endif - @foreach ($elements as $element) + @foreach ($elements ?? [] as $element) @if (is_string($element))