Compare commits
3 Commits
e99bd19035
...
3-category
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d50da17b66 | ||
| 02d2c361a2 | |||
| 69eb15f70e |
64
.github/skills/tailwindcss-development/SKILL.md
vendored
64
.github/skills/tailwindcss-development/SKILL.md
vendored
@@ -10,7 +10,7 @@ metadata:
|
|||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
Use `search-docs` for detailed Tailwind CSS v4 patterns and documentation.
|
Use `search-docs` for detailed Tailwind CSS v3 patterns and documentation.
|
||||||
|
|
||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|
||||||
@@ -18,55 +18,22 @@ Use `search-docs` for detailed Tailwind CSS v4 patterns and documentation.
|
|||||||
- Offer to extract repeated patterns into components that match the project's conventions (e.g., Blade, JSX, Vue).
|
- Offer to extract repeated patterns into components that match the project's conventions (e.g., Blade, JSX, Vue).
|
||||||
- Consider class placement, order, priority, and defaults. Remove redundant classes, add classes to parent or child elements carefully to reduce repetition, and group elements logically.
|
- Consider class placement, order, priority, and defaults. Remove redundant classes, add classes to parent or child elements carefully to reduce repetition, and group elements logically.
|
||||||
|
|
||||||
## Tailwind CSS v4 Specifics
|
## Tailwind CSS v3 Specifics
|
||||||
|
|
||||||
- Always use Tailwind CSS v4 and avoid deprecated utilities.
|
- Always use Tailwind CSS v3 and verify you're using only classes it supports.
|
||||||
- `corePlugins` is not supported in Tailwind v4.
|
- Configuration is done in the `tailwind.config.js` file.
|
||||||
|
- Import using `@tailwind` directives:
|
||||||
|
|
||||||
### CSS-First Configuration
|
<!-- v3 Import Syntax -->
|
||||||
|
|
||||||
In Tailwind v4, configuration is CSS-first using the `@theme` directive — no separate `tailwind.config.js` file is needed:
|
|
||||||
|
|
||||||
<!-- CSS-First Config -->
|
|
||||||
```css
|
```css
|
||||||
@theme {
|
@tailwind base;
|
||||||
--color-brand: oklch(0.72 0.11 178);
|
@tailwind components;
|
||||||
}
|
@tailwind utilities;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Import Syntax
|
|
||||||
|
|
||||||
In Tailwind v4, import Tailwind with a regular CSS `@import` statement instead of the `@tailwind` directives used in v3:
|
|
||||||
|
|
||||||
<!-- v4 Import Syntax -->
|
|
||||||
```diff
|
|
||||||
- @tailwind base;
|
|
||||||
- @tailwind components;
|
|
||||||
- @tailwind utilities;
|
|
||||||
+ @import "tailwindcss";
|
|
||||||
```
|
|
||||||
|
|
||||||
### Replaced Utilities
|
|
||||||
|
|
||||||
Tailwind v4 removed deprecated utilities. Use the replacements shown below. Opacity values remain numeric.
|
|
||||||
|
|
||||||
| Deprecated | Replacement |
|
|
||||||
|------------|-------------|
|
|
||||||
| bg-opacity-* | bg-black/* |
|
|
||||||
| text-opacity-* | text-black/* |
|
|
||||||
| border-opacity-* | border-black/* |
|
|
||||||
| divide-opacity-* | divide-black/* |
|
|
||||||
| ring-opacity-* | ring-black/* |
|
|
||||||
| placeholder-opacity-* | placeholder-black/* |
|
|
||||||
| flex-shrink-* | shrink-* |
|
|
||||||
| flex-grow-* | grow-* |
|
|
||||||
| overflow-ellipsis | text-ellipsis |
|
|
||||||
| decoration-slice | box-decoration-slice |
|
|
||||||
| decoration-clone | box-decoration-clone |
|
|
||||||
|
|
||||||
## Spacing
|
## Spacing
|
||||||
|
|
||||||
Use `gap` utilities instead of margins for spacing between siblings:
|
When listing items, use gap utilities for spacing; don't use margins.
|
||||||
|
|
||||||
<!-- Gap Utilities -->
|
<!-- Gap Utilities -->
|
||||||
```html
|
```html
|
||||||
@@ -110,10 +77,15 @@ If existing pages and components support dark mode, new pages and components mus
|
|||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
1. Check browser for visual rendering
|
||||||
|
2. Test responsive breakpoints
|
||||||
|
3. Verify dark mode if project uses it
|
||||||
|
|
||||||
## Common Pitfalls
|
## Common Pitfalls
|
||||||
|
|
||||||
- Using deprecated v3 utilities (bg-opacity-*, flex-shrink-*, etc.)
|
|
||||||
- Using `@tailwind` directives instead of `@import "tailwindcss"`
|
|
||||||
- Trying to use `tailwind.config.js` instead of CSS `@theme` directive
|
|
||||||
- Using margins for spacing between siblings instead of gap utilities
|
- Using margins for spacing between siblings instead of gap utilities
|
||||||
- Forgetting to add dark mode variants when the project uses dark mode
|
- Forgetting to add dark mode variants when the project uses dark mode
|
||||||
|
- Not checking existing project conventions before adding new utilities
|
||||||
|
- Overusing inline styles when Tailwind classes would suffice
|
||||||
17
AGENTS.md
17
AGENTS.md
@@ -19,7 +19,8 @@ This application is a Laravel application and its main Laravel ecosystems packag
|
|||||||
- laravel/pint (PINT) - v1
|
- laravel/pint (PINT) - v1
|
||||||
- pestphp/pest (PEST) - v4
|
- pestphp/pest (PEST) - v4
|
||||||
- phpunit/phpunit (PHPUNIT) - v12
|
- phpunit/phpunit (PHPUNIT) - v12
|
||||||
- tailwindcss (TAILWINDCSS) - v4
|
- alpinejs (ALPINEJS) - v3
|
||||||
|
- tailwindcss (TAILWINDCSS) - v3
|
||||||
|
|
||||||
## Skills Activation
|
## Skills Activation
|
||||||
|
|
||||||
@@ -108,6 +109,20 @@ This project has domain-specific skills available in `**/skills/**`. You MUST ac
|
|||||||
|
|
||||||
- Laravel can be deployed using [Laravel Cloud](https://cloud.laravel.com/), which is the fastest way to deploy and scale production Laravel applications.
|
- Laravel can be deployed using [Laravel Cloud](https://cloud.laravel.com/), which is the fastest way to deploy and scale production Laravel applications.
|
||||||
|
|
||||||
|
=== herd rules ===
|
||||||
|
|
||||||
|
# Laravel Herd
|
||||||
|
|
||||||
|
- The application is served by Laravel Herd at `https?://[kebab-case-project-dir].test`. Use the `get-absolute-url` tool to generate valid URLs. Never run commands to serve the site. It is always available.
|
||||||
|
- Use the `herd` CLI to manage services, PHP versions, and sites (e.g. `herd sites`, `herd services:start <service>`, `herd php:list`). Run `herd list` to discover all available commands.
|
||||||
|
|
||||||
|
=== tests rules ===
|
||||||
|
|
||||||
|
# Test Enforcement
|
||||||
|
|
||||||
|
- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass.
|
||||||
|
- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test --compact` with a specific filename or filter.
|
||||||
|
|
||||||
=== laravel/core rules ===
|
=== laravel/core rules ===
|
||||||
|
|
||||||
# Do Things the Laravel Way
|
# Do Things the Laravel Way
|
||||||
|
|||||||
126
resources/views/home.blade.php
Normal file
126
resources/views/home.blade.php
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<title>Neighborhood News Portal</title>
|
||||||
|
|
||||||
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||||
|
</head>
|
||||||
|
<body class="min-h-screen bg-gradient-to-b from-emerald-50 via-white to-sky-50 text-slate-800 antialiased">
|
||||||
|
<div class="mx-auto w-full max-w-6xl px-4 py-8 sm:px-6 lg:px-8">
|
||||||
|
@if (\Illuminate\Support\Facades\Route::has('login'))
|
||||||
|
<div class="mb-4 flex justify-end">
|
||||||
|
<nav class="flex items-center gap-2 text-sm">
|
||||||
|
@auth
|
||||||
|
<a
|
||||||
|
href="{{ url('/dashboard') }}"
|
||||||
|
class="rounded-xl border border-emerald-300 bg-emerald-50 px-4 py-2 font-medium text-emerald-800 transition hover:bg-emerald-100"
|
||||||
|
>
|
||||||
|
Dashboard
|
||||||
|
</a>
|
||||||
|
@else
|
||||||
|
<a
|
||||||
|
href="{{ route('login') }}"
|
||||||
|
class="rounded-xl border border-slate-300 bg-white px-4 py-2 font-medium text-slate-700 transition hover:bg-slate-50"
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</a>
|
||||||
|
|
||||||
|
@if (\Illuminate\Support\Facades\Route::has('register'))
|
||||||
|
<a
|
||||||
|
href="{{ route('register') }}"
|
||||||
|
class="rounded-xl border border-emerald-300 bg-emerald-50 px-4 py-2 font-medium text-emerald-800 transition hover:bg-emerald-100"
|
||||||
|
>
|
||||||
|
Register
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
@endauth
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<header class="relative overflow-hidden rounded-3xl border border-emerald-100 bg-white/80 p-6 shadow-sm backdrop-blur sm:p-8">
|
||||||
|
<img
|
||||||
|
src="https://images.pexels.com/photos/10768840/pexels-photo-10768840.jpeg?auto=compress&cs=tinysrgb&w=1600"
|
||||||
|
alt="Forested hills in the distance"
|
||||||
|
class="absolute inset-0 h-full w-full object-cover"
|
||||||
|
>
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-r from-white via-white/88 to-emerald-100/55"></div>
|
||||||
|
<div class="absolute inset-x-0 bottom-0 h-32 bg-gradient-to-t from-white/90 to-transparent"></div>
|
||||||
|
<div class="relative">
|
||||||
|
<p class="text-xs font-semibold uppercase tracking-wider text-emerald-700">Local Neighborhood Portal</p>
|
||||||
|
<div class="mt-3 flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
|
||||||
|
<div>
|
||||||
|
<h1 class="text-3xl font-bold tracking-tight text-slate-900 sm:text-4xl">Taman Melawati News</h1>
|
||||||
|
<p class="mt-2 max-w-2xl text-sm text-slate-700 sm:text-base">
|
||||||
|
Friendly updates from around the block. Stories are placeholders for now, but the spirit is real.
|
||||||
|
</p>
|
||||||
|
<p class="mt-4 text-xs uppercase tracking-[0.24em] text-slate-500">Inspired by the hills and forest edges around our neighborhood</p>
|
||||||
|
</div>
|
||||||
|
<div class="rounded-2xl border border-white/70 bg-white/75 px-4 py-3 text-sm text-emerald-950 shadow-sm backdrop-blur">
|
||||||
|
<p class="font-semibold">Good morning, Neighbor</p>
|
||||||
|
<p class="text-emerald-800">Tuesday community digest</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="mt-8 grid gap-6 lg:grid-cols-3">
|
||||||
|
<section class="space-y-6 lg:col-span-2">
|
||||||
|
<article class="relative overflow-hidden rounded-3xl border border-slate-200 bg-white p-6 shadow-sm sm:p-7">
|
||||||
|
<img
|
||||||
|
src="https://images.pexels.com/photos/9651398/pexels-photo-9651398.jpeg?auto=compress&cs=tinysrgb&w=1200"
|
||||||
|
alt="Misty forested mountain backdrop"
|
||||||
|
class="absolute inset-x-0 top-0 h-40 w-full object-cover"
|
||||||
|
>
|
||||||
|
<div class="absolute inset-x-0 top-0 h-40 bg-gradient-to-b from-emerald-950/35 via-emerald-900/25 to-white"></div>
|
||||||
|
<div class="relative pt-24">
|
||||||
|
<p class="text-xs font-semibold uppercase tracking-wide text-amber-700">Top Story</p>
|
||||||
|
<h2 class="mt-2 text-2xl font-semibold text-slate-900">Community Garden Harvest Day Set for Saturday</h2>
|
||||||
|
<p class="mt-3 text-sm leading-6 text-slate-600">
|
||||||
|
Volunteers from Cedar Lane and Oak Street are gathering at 8:00 AM to pick tomatoes, herbs, and okra.
|
||||||
|
Bring a reusable bag and a smile. Extra produce will be shared with nearby families.
|
||||||
|
</p>
|
||||||
|
<div class="mt-4 flex flex-wrap items-center gap-2 text-xs text-slate-500">
|
||||||
|
<span class="rounded-full bg-emerald-50 px-3 py-1 font-medium text-emerald-700">By Hana, local editor</span>
|
||||||
|
<span>2 hours ago</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<div class="grid gap-4 sm:grid-cols-2">
|
||||||
|
<article class="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
|
||||||
|
<p class="text-xs font-semibold uppercase tracking-wide text-sky-700">Street Update</p>
|
||||||
|
<h3 class="mt-2 text-lg font-semibold text-slate-900">Pine Street Lighting Repaired</h3>
|
||||||
|
<p class="mt-2 text-sm text-slate-600">Evening walks are brighter again after three new lamps were installed this week.</p>
|
||||||
|
</article>
|
||||||
|
<article class="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
|
||||||
|
<p class="text-xs font-semibold uppercase tracking-wide text-rose-700">School Corner</p>
|
||||||
|
<h3 class="mt-2 text-lg font-semibold text-slate-900">Book Drive Reaches 500 Donations</h3>
|
||||||
|
<p class="mt-2 text-sm text-slate-600">Taman Melawati Elementary thanks neighbors for donating books to the weekend reading club.</p>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<aside class="space-y-6">
|
||||||
|
<section class="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
|
||||||
|
<h3 class="text-sm font-semibold uppercase tracking-wide text-slate-700">Community Board</h3>
|
||||||
|
<ul class="mt-4 space-y-3 text-sm text-slate-600">
|
||||||
|
<li class="rounded-xl bg-slate-50 px-3 py-2">Thursday 7 PM: Town Hall mini-meet at River Cafe.</li>
|
||||||
|
<li class="rounded-xl bg-slate-50 px-3 py-2">Friday 5 PM: Youth futsal practice at West Court.</li>
|
||||||
|
<li class="rounded-xl bg-slate-50 px-3 py-2">Sunday 9 AM: Riverside clean-up, all ages welcome.</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
|
||||||
|
<h3 class="text-sm font-semibold uppercase tracking-wide text-slate-700">Weather Snapshot</h3>
|
||||||
|
<p class="mt-3 text-3xl font-bold text-slate-900">29°C</p>
|
||||||
|
<p class="text-sm text-slate-600">Warm with light breeze. Great evening for a neighborhood stroll.</p>
|
||||||
|
</section>
|
||||||
|
</aside>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -7,7 +7,7 @@ use App\Http\Controllers\UserController;
|
|||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::get('/', function () {
|
Route::get('/', function () {
|
||||||
return view('welcome');
|
return view('home');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::get('/dashboard', function () {
|
Route::get('/dashboard', function () {
|
||||||
|
|||||||
@@ -3,5 +3,10 @@
|
|||||||
it('returns a successful response', function () {
|
it('returns a successful response', function () {
|
||||||
$response = $this->get('/');
|
$response = $this->get('/');
|
||||||
|
|
||||||
$response->assertStatus(200);
|
$response
|
||||||
|
->assertSuccessful()
|
||||||
|
->assertSee('Taman Melawati News')
|
||||||
|
->assertSee('Community Garden Harvest Day Set for Saturday')
|
||||||
|
->assertSee('Login')
|
||||||
|
->assertSee('Register');
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user