feat: migrate website-creator from Next.js+Payload to Astro+Tina CMS
Major changes: - Replace Payload CMS with Tina CMS (self-hosted) - Add Astro DB for consent logging (PDPA compliant) - Update Tailwind v3 to v4 (@tailwindcss/vite plugin) - Add astro-tina-starter template - Rewrite consent template for Astro (ConsentBanner.astro, Astro DB, Nano Stores) - Add install-tina-backend.sh for self-hosted Tina per customer - Rename convert-astro.sh to migrate-tina.sh - Add AGENTS.md template for generated websites - Delete all Payload/Next.js files Technical updates: - Astro DB using defineDb with eq operators for queries - Tailwind v4 with @theme block - Tina CMS local development mode - Proper Astro API routes for consent Research-verified with official documentation (April 2026)
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
import { defineConfig } from 'tinacms';
|
||||
import { schema } from './schema';
|
||||
|
||||
export default defineConfig({
|
||||
schema,
|
||||
ui: {
|
||||
navigation: {
|
||||
'content/posts': { label: 'Posts' },
|
||||
'content/pages': { label: 'Pages' },
|
||||
},
|
||||
},
|
||||
media: {
|
||||
tina: {
|
||||
publicFolder: 'public',
|
||||
mediaRoot: 'uploads',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,91 @@
|
||||
import { defineSchema } from 'tinacms'
|
||||
|
||||
export const schema = defineSchema({
|
||||
collections: [
|
||||
{
|
||||
name: 'post',
|
||||
label: 'Posts',
|
||||
path: 'src/content/posts',
|
||||
format: 'mdx',
|
||||
fields: [
|
||||
{
|
||||
type: 'string',
|
||||
name: 'title',
|
||||
label: 'Title',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'description',
|
||||
label: 'Description',
|
||||
},
|
||||
{
|
||||
type: 'datetime',
|
||||
name: 'publishedAt',
|
||||
label: 'Published At',
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'category',
|
||||
label: 'Category',
|
||||
options: ['news', 'blog', 'tutorial'],
|
||||
},
|
||||
{
|
||||
type: 'rich-text',
|
||||
name: 'body',
|
||||
label: 'Body',
|
||||
isBody: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'page',
|
||||
label: 'Pages',
|
||||
path: 'src/content/pages',
|
||||
format: 'mdx',
|
||||
fields: [
|
||||
{
|
||||
type: 'string',
|
||||
name: 'title',
|
||||
label: 'Title',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'description',
|
||||
label: 'Description',
|
||||
},
|
||||
{
|
||||
type: 'rich-text',
|
||||
name: 'body',
|
||||
label: 'Body',
|
||||
isBody: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'settings',
|
||||
label: 'Settings',
|
||||
path: 'src/content/settings',
|
||||
format: 'json',
|
||||
fields: [
|
||||
{
|
||||
type: 'string',
|
||||
name: 'siteName',
|
||||
label: 'Site Name',
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'siteDescription',
|
||||
label: 'Site Description',
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'language',
|
||||
label: 'Language',
|
||||
options: ['th', 'en', 'th-en'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
198
skills/website-creator/templates/astro-tina-starter/AGENTS.md
Normal file
198
skills/website-creator/templates/astro-tina-starter/AGENTS.md
Normal file
@@ -0,0 +1,198 @@
|
||||
# Astro Tina Starter - Agent Knowledge Base
|
||||
|
||||
**Generated:** 2026-04-17
|
||||
**Version:** 1.0.0
|
||||
**Type:** Astro 6 + Tina CMS Starter Template
|
||||
|
||||
---
|
||||
|
||||
## OVERVIEW
|
||||
|
||||
Starter template for building websites with Astro 6, Tina CMS, and Tailwind CSS 4.x.
|
||||
|
||||
### Tech Stack
|
||||
|
||||
| Component | Technology | Version |
|
||||
|-----------|------------|---------|
|
||||
| Framework | Astro | 6.1.7 |
|
||||
| CMS | Tina CMS | 2.x |
|
||||
| Styling | Tailwind CSS | 4.x |
|
||||
| Database | Astro DB | 0.14.x |
|
||||
| State | Nano Stores | 0.11.x |
|
||||
|
||||
### Key Features
|
||||
|
||||
- Self-hosted Tina CMS with schema-based content
|
||||
- Tailwind CSS 4.x using `@tailwindcss/vite` plugin
|
||||
- Astro DB for consent logging (PDPA compliant)
|
||||
- Thai language support with Noto Sans Thai
|
||||
- Docker-ready deployment
|
||||
|
||||
---
|
||||
|
||||
## PROJECT STRUCTURE
|
||||
|
||||
```
|
||||
astro-tina-starter/
|
||||
├── .tina/
|
||||
│ ├── config.ts # Tina CMS configuration
|
||||
│ └── schema.ts # Content schema definitions
|
||||
├── db/
|
||||
│ ├── config.ts # Astro DB schema
|
||||
│ └── seed.ts # Database seed script
|
||||
├── src/
|
||||
│ ├── styles/
|
||||
│ │ └── global.css # Tailwind v4 styles + @theme
|
||||
│ ├── layouts/
|
||||
│ │ └── Layout.astro
|
||||
│ ├── pages/
|
||||
│ │ └── index.astro
|
||||
│ ├── components/
|
||||
│ │ └── Header.astro
|
||||
│ └── content/
|
||||
│ ├── config.ts # Astro content collections
|
||||
│ ├── posts/ # Blog posts (MDX)
|
||||
│ ├── pages/ # Static pages (MDX)
|
||||
│ └── settings/ # Site settings (JSON)
|
||||
├── public/
|
||||
│ └── favicon.svg
|
||||
├── Dockerfile
|
||||
├── astro.config.mjs
|
||||
├── tsconfig.json
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## IMPORTANT CONVENTIONS
|
||||
|
||||
### Tailwind CSS 4.x Setup
|
||||
|
||||
**CRITICAL:** This template uses `@tailwindcss/vite` plugin, NOT `@astrojs/tailwind`.
|
||||
|
||||
```javascript
|
||||
// astro.config.mjs
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
|
||||
export default defineConfig({
|
||||
vite: {
|
||||
plugins: [tailwindcss()],
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
```css
|
||||
/* src/styles/global.css */
|
||||
@import "tailwindcss";
|
||||
|
||||
@theme {
|
||||
--color-primary: #1a1a1a;
|
||||
--color-accent: #3b82f6;
|
||||
}
|
||||
```
|
||||
|
||||
### Tina CMS Content
|
||||
|
||||
Tina CMS manages content in `src/content/`:
|
||||
- `posts/` - Blog posts (MDX format)
|
||||
- `pages/` - Static pages (MDX format)
|
||||
- `settings/` - Site settings (JSON format)
|
||||
|
||||
Schema defined in `.tina/schema.ts`.
|
||||
|
||||
### Astro DB Schema
|
||||
|
||||
Consent log table for PDPA compliance in `db/config.ts`.
|
||||
|
||||
---
|
||||
|
||||
## CREDENTIALS
|
||||
|
||||
No external API credentials required for this template.
|
||||
|
||||
### Optional Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `TINA_TOKEN` | Tina CMS production authentication |
|
||||
| `TINA_CLIENT_ID` | Tina CMS client ID |
|
||||
| `DATABASE_URL` | Custom database connection (optional) |
|
||||
|
||||
---
|
||||
|
||||
## COMMANDS
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Development
|
||||
npm run dev # Full dev (Tina + Astro)
|
||||
npm run dev:astro # Astro only
|
||||
npm run dev:tina # Tina CMS only
|
||||
|
||||
# Build
|
||||
npm run build # Production build
|
||||
npm run preview # Preview production build
|
||||
|
||||
# Database
|
||||
npm run db:push # Push schema to database
|
||||
npm run db:seed # Seed database
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PDPA COMPLIANCE
|
||||
|
||||
Template includes consent logging via Astro DB:
|
||||
|
||||
```typescript
|
||||
// db/config.ts
|
||||
export const ConsentLog = defineTable({
|
||||
columns: {
|
||||
action: text(),
|
||||
purpose: text(),
|
||||
analytics: boolean(),
|
||||
marketing: boolean(),
|
||||
functional: boolean(),
|
||||
userAgent: text(),
|
||||
ip: text(),
|
||||
timestamp: text(),
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ANTI-PATTERNS
|
||||
|
||||
- **NEVER** use `@astrojs/tailwind` (deprecated)
|
||||
- **ALWAYS** use `@tailwindcss/vite` for Tailwind v4
|
||||
- **NEVER** commit environment files (.env)
|
||||
|
||||
---
|
||||
|
||||
## DEPLOYMENT
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
docker build -t astro-tina-starter .
|
||||
docker run -p 8080:80 astro-tina-starter
|
||||
```
|
||||
|
||||
### Manual
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run build
|
||||
# Serve dist/ folder with any static server
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## NOTES
|
||||
|
||||
- Tina CMS admin: http://localhost:4321/admin
|
||||
- Astro default port: 4321
|
||||
- Tina dev server: 3001
|
||||
@@ -0,0 +1,19 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:alpine AS runner
|
||||
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
104
skills/website-creator/templates/astro-tina-starter/README.md
Normal file
104
skills/website-creator/templates/astro-tina-starter/README.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Astro Tina Starter
|
||||
|
||||
Astro 6.1.7 + Tina CMS starter template with Tailwind CSS 4.x
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Framework:** Astro 6.1.7
|
||||
- **CMS:** Tina CMS (self-hosted)
|
||||
- **Styling:** Tailwind CSS 4.x with `@tailwindcss/vite`
|
||||
- **Database:** Astro DB (LibSQL)
|
||||
- **State:** Nano Stores + React
|
||||
- **Language:** TypeScript
|
||||
|
||||
## Features
|
||||
|
||||
- Self-hosted Tina CMS with schema-based content
|
||||
- Tailwind CSS 4.x using `@tailwindcss/vite` plugin
|
||||
- Astro DB for consent logging (PDPA compliant)
|
||||
- Nano Stores for client-side state management
|
||||
- Thai language support foundation
|
||||
- Docker-ready deployment
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Start development
|
||||
npm run dev
|
||||
|
||||
# Build for production
|
||||
npm run build
|
||||
```
|
||||
|
||||
## Tina CMS Access
|
||||
|
||||
During development, access Tina CMS at:
|
||||
- http://localhost:4321/admin
|
||||
|
||||
For production, you'll need a TINA_TOKEN environment variable.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
astro-tina-starter/
|
||||
├── .tina/
|
||||
│ ├── config.ts # Tina CMS configuration
|
||||
│ └── schema.ts # Content schema definitions
|
||||
├── db/
|
||||
│ ├── config.ts # Astro DB schema (consent logs)
|
||||
│ └── seed.ts # Database seed script
|
||||
├── src/
|
||||
│ ├── styles/
|
||||
│ │ └── global.css # Tailwind v4 styles
|
||||
│ ├── layouts/
|
||||
│ │ └── Layout.astro
|
||||
│ ├── pages/
|
||||
│ │ └── index.astro
|
||||
│ ├── components/
|
||||
│ │ └── Header.astro
|
||||
│ └── content/
|
||||
│ └── config.ts # Tina content collections
|
||||
├── Dockerfile
|
||||
└── package.json
|
||||
```
|
||||
|
||||
## Tailwind CSS 4.x
|
||||
|
||||
This template uses Tailwind CSS 4.x with the `@tailwindcss/vite` plugin.
|
||||
The configuration is done via CSS `@theme` block in `src/styles/global.css`.
|
||||
|
||||
```css
|
||||
@import "tailwindcss";
|
||||
|
||||
@theme {
|
||||
--color-primary: #1a1a1a;
|
||||
--color-accent: #3b82f6;
|
||||
}
|
||||
```
|
||||
|
||||
## Astro DB
|
||||
|
||||
The template includes a consent-log table for PDPA compliance:
|
||||
|
||||
```ts
|
||||
// db/config.ts
|
||||
export const ConsentLog = defineTable({
|
||||
columns: {
|
||||
action: text(),
|
||||
purpose: text(),
|
||||
analytics: boolean(),
|
||||
marketing: boolean(),
|
||||
functional: boolean(),
|
||||
userAgent: text(),
|
||||
ip: text(),
|
||||
timestamp: text(),
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
@@ -0,0 +1,37 @@
|
||||
import { defineConfig } from 'astro/config'
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
import tina from 'tinacms'
|
||||
import { fileURLToPath } from 'url'
|
||||
import path from 'path'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
export default defineConfig({
|
||||
integrations: [
|
||||
tina({
|
||||
enabled: !!process.env.TINA_TOKEN,
|
||||
sidebar: {
|
||||
partials: [],
|
||||
},
|
||||
}),
|
||||
],
|
||||
vite: {
|
||||
plugins: [tailwindcss()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src'),
|
||||
'@components': path.resolve(__dirname, './src/components'),
|
||||
'@layouts': path.resolve(__dirname, './src/layouts'),
|
||||
'@styles': path.resolve(__dirname, './src/styles'),
|
||||
'@content': path.resolve(__dirname, './src/content'),
|
||||
},
|
||||
},
|
||||
},
|
||||
output: 'static',
|
||||
build: {
|
||||
assets: '_assets',
|
||||
},
|
||||
server: {
|
||||
port: 4321,
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,22 @@
|
||||
import { defineDb, defineTable, column } from 'astro:db';
|
||||
|
||||
const ConsentLog = defineTable({
|
||||
columns: {
|
||||
id: column.number({ primaryKey: true }),
|
||||
action: column.text(),
|
||||
purpose: column.text(),
|
||||
analytics: column.boolean({ default: false }),
|
||||
marketing: column.boolean({ default: false }),
|
||||
functional: column.boolean({ default: false }),
|
||||
userAgent: column.text({ optional: true }),
|
||||
ip: column.text({ optional: true }),
|
||||
timestamp: column.date(),
|
||||
sessionId: column.text({ optional: true }),
|
||||
},
|
||||
});
|
||||
|
||||
export default defineDb({
|
||||
tables: {
|
||||
ConsentLog,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
import { db } from 'astro:db'
|
||||
import { sql } from 'astro/db'
|
||||
|
||||
export default async function seed() {
|
||||
// Seed default settings if needed
|
||||
console.log('Database seeded successfully')
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "astro-tina-starter",
|
||||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"description": "Astro 6 + Tina CMS starter template with Tailwind CSS 4.x",
|
||||
"scripts": {
|
||||
"dev": "tinacms dev --port 3001 & astro dev",
|
||||
"dev:astro": "astro dev",
|
||||
"dev:tina": "tinacms dev --port 3001",
|
||||
"build": "tinacms build && astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro",
|
||||
"db:push": "astro db push",
|
||||
"db:seed": "astro db seed"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/check": "^0.9.4",
|
||||
"@astrojs/db": "^0.14.3",
|
||||
"@nanostores/react": "^0.7.3",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"@tailwindcss/vite": "^4.0.0",
|
||||
"astro": "^6.1.7",
|
||||
"nanostores": "^0.11.3",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"tailwindcss": "^4.0.0",
|
||||
"tina": "^2.1.4",
|
||||
"tinacms": "^2.2.4",
|
||||
"typescript": "^5.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs>
|
||||
<linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#3b82f6"/>
|
||||
<stop offset="100%" style="stop-color:#1d4ed8"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="32" height="32" rx="6" fill="url(#grad)"/>
|
||||
<text x="16" y="22" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="white" text-anchor="middle">A</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 473 B |
@@ -0,0 +1,27 @@
|
||||
---
|
||||
interface Props {
|
||||
siteName?: string
|
||||
}
|
||||
|
||||
const { siteName = "Astro Tina Starter" } = Astro.props
|
||||
---
|
||||
|
||||
<header class="sticky top-0 z-50 bg-white/80 backdrop-blur-md border-b border-primary-200">
|
||||
<nav class="max-w-6xl mx-auto px-6 h-16 flex items-center justify-between">
|
||||
<a href="/" class="font-bold text-xl text-primary-900 hover:text-accent-600 transition-colors">
|
||||
{siteName}
|
||||
</a>
|
||||
|
||||
<div class="flex items-center gap-6">
|
||||
<a href="/" class="text-primary-600 hover:text-primary-900 transition-colors">
|
||||
Home
|
||||
</a>
|
||||
<a href="/blog" class="text-primary-600 hover:text-primary-900 transition-colors">
|
||||
Blog
|
||||
</a>
|
||||
<a href="/about" class="text-primary-600 hover:text-primary-900 transition-colors">
|
||||
About
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
@@ -0,0 +1,34 @@
|
||||
import { defineCollection, z } from "astro:content"
|
||||
|
||||
const postCollection = defineCollection({
|
||||
type: "content",
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string().optional(),
|
||||
publishedAt: z.date().optional(),
|
||||
category: z.enum(["news", "blog", "tutorial"]).optional(),
|
||||
}),
|
||||
})
|
||||
|
||||
const pageCollection = defineCollection({
|
||||
type: "content",
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
description: z.string().optional(),
|
||||
}),
|
||||
})
|
||||
|
||||
const settingsCollection = defineCollection({
|
||||
type: "data",
|
||||
schema: z.object({
|
||||
siteName: z.string(),
|
||||
siteDescription: z.string(),
|
||||
language: z.enum(["th", "en", "th-en"]).default("th"),
|
||||
}),
|
||||
})
|
||||
|
||||
export const collections = {
|
||||
posts: postCollection,
|
||||
pages: pageCollection,
|
||||
settings: settingsCollection,
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: Welcome to Astro Tina Starter
|
||||
description: A modern starter template with Astro 6, Tina CMS, and Thai language support.
|
||||
publishedAt: 2026-04-17
|
||||
category: blog
|
||||
---
|
||||
|
||||
Welcome to our new blog built with Astro and Tina CMS!
|
||||
|
||||
## Features
|
||||
|
||||
- **Tina CMS** - Self-hosted content management
|
||||
- **Tailwind CSS v4** - Latest styling with @tailwindcss/vite
|
||||
- **Astro DB** - Built-in database support
|
||||
- **Thai Support** - Ready for Thai language content
|
||||
|
||||
Stay tuned for more updates!
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"siteName": "Astro Tina Starter",
|
||||
"siteDescription": "Astro 6 + Tina CMS starter template with Thai language support",
|
||||
"language": "th"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
import "@/styles/global.css"
|
||||
|
||||
interface Props {
|
||||
title?: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
const {
|
||||
title = "Astro Tina Starter",
|
||||
description = "Astro 6 + Tina CMS starter template",
|
||||
} = Astro.props
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="th">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content={description} />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<title>{title}</title>
|
||||
</head>
|
||||
<body class="bg-primary-50 text-primary-900 min-h-screen">
|
||||
<slot />
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
import Layout from "@/layouts/Layout.astro"
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<main>
|
||||
<section class="px-6 py-24 max-w-4xl mx-auto">
|
||||
<h1 class="text-4xl md:text-5xl font-bold tracking-tight mb-6">
|
||||
Welcome to Astro Tina Starter
|
||||
</h1>
|
||||
<p class="text-lg text-primary-600 mb-8 max-w-2xl">
|
||||
A modern starter template with Astro 6, Tina CMS, Tailwind CSS 4.x,
|
||||
and Thai language support.
|
||||
</p>
|
||||
|
||||
<div class="grid gap-6 md:grid-cols-2">
|
||||
<div class="p-6 bg-white rounded-xl border border-primary-200">
|
||||
<h2 class="text-xl font-semibold mb-3">Tina CMS</h2>
|
||||
<p class="text-primary-600">
|
||||
Self-hosted content management with schema-based editing.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="p-6 bg-white rounded-xl border border-primary-200">
|
||||
<h2 class="text-xl font-semibold mb-3">Tailwind v4</h2>
|
||||
<p class="text-primary-600">
|
||||
Latest Tailwind CSS with @tailwindcss/vite plugin.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="p-6 bg-white rounded-xl border border-primary-200">
|
||||
<h2 class="text-xl font-semibold mb-3">Astro DB</h2>
|
||||
<p class="text-primary-600">
|
||||
Built-in database for consent logging and more.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="p-6 bg-white rounded-xl border border-primary-200">
|
||||
<h2 class="text-xl font-semibold mb-3">Thai Support</h2>
|
||||
<p class="text-primary-600">
|
||||
Ready for Thai language content with Noto Sans Thai.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</Layout>
|
||||
@@ -0,0 +1,57 @@
|
||||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@theme {
|
||||
--font-sans: "Inter", "Noto Sans Thai", system-ui, sans-serif;
|
||||
--font-serif: "Merriweather", Georgia, serif;
|
||||
|
||||
--color-primary-50: #f8fafc;
|
||||
--color-primary-100: #f1f5f9;
|
||||
--color-primary-200: #e2e8f0;
|
||||
--color-primary-300: #cbd5e1;
|
||||
--color-primary-400: #94a3b8;
|
||||
--color-primary-500: #64748b;
|
||||
--color-primary-600: #475569;
|
||||
--color-primary-700: #334155;
|
||||
--color-primary-800: #1e293b;
|
||||
--color-primary-900: #0f172a;
|
||||
--color-primary-950: #020617;
|
||||
|
||||
--color-accent-50: #eff6ff;
|
||||
--color-accent-100: #dbeafe;
|
||||
--color-accent-200: #bfdbfe;
|
||||
--color-accent-300: #93c5fd;
|
||||
--color-accent-400: #60a5fa;
|
||||
--color-accent-500: #3b82f6;
|
||||
--color-accent-600: #2563eb;
|
||||
--color-accent-700: #1d4ed8;
|
||||
--color-accent-800: #1e40af;
|
||||
--color-accent-900: #1e3a8a;
|
||||
|
||||
--color-success-500: #22c55e;
|
||||
--color-warning-500: #f59e0b;
|
||||
--color-error-500: #ef4444;
|
||||
|
||||
--radius-sm: 0.25rem;
|
||||
--radius-md: 0.5rem;
|
||||
--radius-lg: 0.75rem;
|
||||
--radius-xl: 1rem;
|
||||
--radius-2xl: 1.5rem;
|
||||
--radius-full: 9999px;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-sans);
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background-color: var(--color-accent-200);
|
||||
color: var(--color-primary-900);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"@components/*": ["./src/components/*"],
|
||||
"@layouts/*": ["./src/layouts/*"],
|
||||
"@styles/*": ["./src/styles/*"],
|
||||
"@content/*": ["./src/content/*"]
|
||||
},
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "react"
|
||||
},
|
||||
"include": ["src/**/*", ".tina/**/*", "db/**/*"],
|
||||
"exclude": ["node_modules", "dist", ".astro"]
|
||||
}
|
||||
Reference in New Issue
Block a user