feat: initialize project with Tailwind CSS, React, and TypeScript setup

- Added Tailwind CSS configuration with custom theme colors and animations.
- Created global styles in index.css including custom scrollbar and button components.
- Set up main entry point in main.tsx to render the App component.
- Configured TypeScript with strict settings and path mapping.
- Added support for high contrast mode and reduced motion in styles.
- Included print styles for better printing experience.
This commit is contained in:
defiQUG
2025-10-04 18:11:14 -07:00
parent 0933c8208c
commit 1b3793447a
18 changed files with 6303 additions and 66 deletions

42
.env.example Normal file
View File

@@ -0,0 +1,42 @@
# Environment Variables Template
# Copy this file to .env and fill in your actual values
# Analytics
VITE_GA_MEASUREMENT_ID=G-XXXXXXXXXX
VITE_ANALYTICS_ENABLED=true
# Contact Information
VITE_CONTACT_EMAIL=contact@miraclesinmotion.org
VITE_PHONE_NUMBER=+15551234567
VITE_ADDRESS="123 Community Way, Hometown, ST 12345"
# Donation Processing
VITE_DONATION_ENDPOINT=https://api.donation-processor.com/v1
VITE_PAYPAL_CLIENT_ID=your_paypal_client_id
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_your_stripe_key
# Organization Details
VITE_EIN=12-3456789
VITE_ORG_NAME="Miracles In Motion"
VITE_ORG_DESCRIPTION="A 501(c)3 non-profit providing essentials for student success"
# Social Media
VITE_FACEBOOK_URL=https://facebook.com/miraclesinmotion
VITE_INSTAGRAM_URL=https://instagram.com/miraclesinmotion
VITE_TWITTER_URL=https://twitter.com/miraclesinmotion
VITE_LINKEDIN_URL=https://linkedin.com/company/miraclesinmotion
# API Endpoints
VITE_API_BASE_URL=https://api.miraclesinmotion.org
VITE_VOLUNTEER_FORM_URL=https://forms.miraclesinmotion.org/volunteer
VITE_CONTACT_FORM_URL=https://forms.miraclesinmotion.org/contact
# Feature Flags
VITE_ENABLE_CHAT=false
VITE_ENABLE_NEWSLETTER=true
VITE_ENABLE_EVENTS=true
VITE_ENABLE_BLOG=false
# Development
VITE_DEV_MODE=true
VITE_LOG_LEVEL=info

20
.eslintrc.cjs Normal file
View File

@@ -0,0 +1,20 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'@typescript-eslint/no-explicit-any': 'warn',
},
}

92
.gitignore vendored Normal file
View File

@@ -0,0 +1,92 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# Environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# OS generated files
Thumbs.db
ehthumbs.db
Icon?
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Coverage directory used by tools like istanbul
coverage/
*.lcov
# nyc test coverage
.nyc_output
# Dependency directories
node_modules/
jspm_packages/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# Build outputs
build/
dist/
# Temporary folders
tmp/
temp/
# IDE files
*.swp
*.swo
*~
# Local environment files
.env.local
.env.development.local
.env.test.local
.env.production.local

BIN
README.md

Binary file not shown.

View File

@@ -1,68 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Miracles In Motion | 501(c)3 Non-Profit Organization</title>
<meta name="description" content="Miracles In Motion is a 501(c)3 non-profit organization dedicated to creating positive change in our community through compassionate action and support.">
<meta name="keywords" content="non-profit, charity, 501c3, miracles in motion, community support, donations, volunteers">
<meta name="description" content="Miracles In Motion is a 501(c)3 non-profit organization dedicated to creating positive change in our community through compassionate action and support." />
<meta name="keywords" content="non-profit, charity, 501c3, miracles in motion, community support, donations, volunteers" />
<!-- Open Graph Meta Tags -->
<meta property="og:title" content="Miracles In Motion | 501(c)3 Non-Profit Organization">
<meta property="og:description" content="Creating positive change in our community through compassionate action and support.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://miraclesinmotion.org">
<meta property="og:title" content="Miracles In Motion | 501(c)3 Non-Profit Organization" />
<meta property="og:description" content="Creating positive change in our community through compassionate action and support." />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://miraclesinmotion.org" />
<meta property="og:image" content="/og-image.png" />
<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<!-- Twitter Card Meta Tags -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Miracles In Motion | 501(c)3 Non-Profit Organization" />
<meta name="twitter:description" content="Creating positive change in our community through compassionate action and support." />
<meta name="twitter:image" content="/og-image.png" />
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Favicon and Web App Manifest -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<!-- React and Babel -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<!-- Theme Color -->
<meta name="theme-color" content="#ec4899" />
<!-- Framer Motion -->
<script src="https://unpkg.com/framer-motion@10/dist/framer-motion.js"></script>
<!-- Preconnect to external domains -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<!-- Font Awesome for Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.gradient-text {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero-gradient {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.card-hover {
transition: all 0.3s ease;
}
.card-hover:hover {
transform: translateY(-8px);
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
}
.smooth-scroll {
scroll-behavior: smooth;
}
</style>
</head>
<body class="smooth-scroll">
<!-- Inter Font -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
</head>
<body>
<div id="root"></div>
<script type="text/babel" src="mim_web.jsx"></script>
</body>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

4508
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,14 @@
{
"name": "miracles-in-motion-web",
"private": true,
"version": "1.0.0",
"type": "module",
"description": "Public website for Miracles In Motion 501(c)3 non-profit organization",
"main": "index.html",
"scripts": {
"dev": "live-server --port=3000",
"build": "npm run copy-files",
"copy-files": "mkdir -p dist && cp -r *.html *.jsx *.css *.js *.json assets/ dist/",
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"deploy": "npm run build && gh-pages -d dist"
},
"keywords": [
@@ -16,7 +18,10 @@
"miracles-in-motion",
"community",
"donations",
"volunteers"
"volunteers",
"react",
"vite",
"tailwind"
],
"author": "Miracles In Motion",
"license": "MIT",
@@ -25,13 +30,27 @@
"url": "https://github.com/Miracles-In-Motion/public-web.git"
},
"homepage": "https://miraclesinmotion.org",
"devDependencies": {
"live-server": "^1.2.2",
"gh-pages": "^5.0.0"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"framer-motion": "^10.16.4"
"framer-motion": "^10.16.16",
"lucide-react": "^0.290.0"
},
"devDependencies": {
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"@typescript-eslint/eslint-plugin": "^6.10.0",
"@typescript-eslint/parser": "^6.10.0",
"@vitejs/plugin-react": "^4.1.0",
"autoprefixer": "^10.4.16",
"eslint": "^8.53.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.4",
"gh-pages": "^6.0.0",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.5",
"@tailwindcss/typography": "^0.5.10",
"typescript": "^5.2.2",
"vite": "^4.5.0"
}
}

6
postcss.config.cjs Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

13
public/favicon.svg Normal file
View File

@@ -0,0 +1,13 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#ec4899;stop-opacity:1" />
<stop offset="50%" style="stop-color:#8b5cf6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#3b82f6;stop-opacity:1" />
</linearGradient>
</defs>
<rect width="32" height="32" rx="8" fill="url(#grad1)"/>
<path d="M16 8L20.5 14H11.5L16 8Z" fill="white" opacity="0.9"/>
<circle cx="16" cy="18" r="3" fill="white" opacity="0.9"/>
<path d="M10 22L16 20L22 22L20 26H12L10 22Z" fill="white" opacity="0.9"/>
</svg>

After

Width:  |  Height:  |  Size: 683 B

15
public/robots.txt Normal file
View File

@@ -0,0 +1,15 @@
User-agent: *
Allow: /
# Block access to sensitive files
Disallow: /.env
Disallow: /src/
Disallow: /node_modules/
Disallow: /dist/
Disallow: /*.log
# Sitemap
Sitemap: https://miraclesinmotion.org/sitemap.xml
# Crawl delay (optional)
Crawl-delay: 1

28
public/site.webmanifest Normal file
View File

@@ -0,0 +1,28 @@
{
"name": "Miracles In Motion",
"short_name": "MiraclesInMotion",
"description": "A 501(c)3 non-profit providing essentials for student success",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#ec4899",
"icons": [
{
"src": "/favicon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/favicon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"categories": ["education", "social", "non-profit"],
"lang": "en-US",
"dir": "ltr",
"orientation": "portrait-primary",
"scope": "/",
"related_applications": [],
"prefer_related_applications": false
}

129
scripts/generate-og.mjs Normal file
View File

@@ -0,0 +1,129 @@
#!/usr/bin/env node
/**
* Generate Open Graph images for Miracles In Motion
* This script creates social media preview images
*/
import fs from 'fs'
import path from 'path'
const OG_CONFIG = {
width: 1200,
height: 630,
title: 'Miracles In Motion',
subtitle: 'Essentials for Every Student',
description: '501(c)3 Non-Profit Organization'
}
/**
* Create SVG template for OG image
*/
function createOGImageSVG(config = OG_CONFIG) {
return `
<svg width="${config.width}" height="${config.height}" viewBox="0 0 ${config.width} ${config.height}" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="bg-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#ec4899;stop-opacity:1" />
<stop offset="50%" style="stop-color:#8b5cf6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#3b82f6;stop-opacity:1" />
</linearGradient>
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="rgba(0,0,0,0.25)"/>
</filter>
</defs>
<!-- Background -->
<rect width="100%" height="100%" fill="url(#bg-gradient)"/>
<!-- Pattern overlay -->
<pattern id="dots" patternUnits="userSpaceOnUse" width="40" height="40">
<circle cx="20" cy="20" r="2" fill="rgba(255,255,255,0.1)"/>
</pattern>
<rect width="100%" height="100%" fill="url(#dots)"/>
<!-- Content container -->
<g transform="translate(80, 0)">
<!-- Logo area -->
<rect x="0" y="120" width="80" height="80" rx="20" fill="rgba(255,255,255,0.2)" filter="url(#shadow)"/>
<circle cx="40" cy="160" r="20" fill="white"/>
<!-- Text content -->
<text x="120" y="140" font-family="system-ui, -apple-system, sans-serif" font-size="48" font-weight="700" fill="white">
${config.title}
</text>
<text x="120" y="180" font-family="system-ui, -apple-system, sans-serif" font-size="28" font-weight="400" fill="rgba(255,255,255,0.9)">
${config.subtitle}
</text>
<text x="120" y="220" font-family="system-ui, -apple-system, sans-serif" font-size="20" font-weight="300" fill="rgba(255,255,255,0.8)">
${config.description}
</text>
<!-- Call to action -->
<rect x="120" y="280" width="200" height="50" rx="25" fill="rgba(255,255,255,0.2)" filter="url(#shadow)"/>
<text x="220" y="310" font-family="system-ui, -apple-system, sans-serif" font-size="18" font-weight="500" fill="white" text-anchor="middle">
Learn More
</text>
</g>
<!-- Bottom accent -->
<rect x="0" y="580" width="100%" height="50" fill="rgba(0,0,0,0.1)"/>
<text x="600" y="610" font-family="system-ui, -apple-system, sans-serif" font-size="16" fill="rgba(255,255,255,0.8)" text-anchor="middle">
miraclesinmotion.org
</text>
</svg>
`.trim()
}
/**
* Generate OG images
*/
function generateOGImages() {
const publicDir = path.join(process.cwd(), 'public')
// Ensure public directory exists
if (!fs.existsSync(publicDir)) {
fs.mkdirSync(publicDir, { recursive: true })
}
// Create default OG image
const defaultOG = createOGImageSVG()
fs.writeFileSync(path.join(publicDir, 'og-image.svg'), defaultOG)
console.log('✅ Generated og-image.svg')
// Create page-specific OG images
const pages = [
{ name: 'donate', title: 'Donate', subtitle: 'Help Students Succeed' },
{ name: 'volunteer', title: 'Volunteer', subtitle: 'Make a Difference' },
{ name: 'stories', title: 'Stories', subtitle: 'Impact in Action' },
]
pages.forEach(page => {
const pageOG = createOGImageSVG({
...OG_CONFIG,
title: page.title,
subtitle: page.subtitle
})
fs.writeFileSync(path.join(publicDir, `og-image-${page.name}.svg`), pageOG)
console.log(`✅ Generated og-image-${page.name}.svg`)
})
console.log('\n🎉 All OG images generated successfully!')
console.log('\nNote: These are SVG files. For production, consider converting to PNG using a tool like:')
console.log('- Puppeteer for programmatic conversion')
console.log('- Online converters')
console.log('- Design tools like Figma or Canva')
}
// Run if called directly
if (import.meta.url === `file://${process.argv[1]}`) {
try {
generateOGImages()
} catch (error) {
console.error('❌ Error generating OG images:', error)
process.exit(1)
}
}
export { generateOGImages, createOGImageSVG }

1086
src/App.tsx Normal file

File diff suppressed because it is too large Load Diff

182
src/index.css Normal file
View File

@@ -0,0 +1,182 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
html {
scroll-behavior: smooth;
}
body {
font-feature-settings: 'rlig' 1, 'calt' 1;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
background: linear-gradient(135deg, #ec4899, #8b5cf6);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: linear-gradient(135deg, #db2777, #7c3aed);
}
}
@layer components {
/* Button Components */
.btn-primary {
@apply inline-flex items-center gap-2 rounded-full bg-gradient-to-r from-primary-600 to-secondary-600 px-6 py-3 text-sm font-medium text-white shadow-lg shadow-primary-500/25 transition hover:scale-105 hover:shadow-xl focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2;
}
.btn-secondary {
@apply inline-flex items-center gap-2 rounded-full border border-neutral-300 bg-white/70 px-6 py-3 text-sm font-medium text-neutral-700 backdrop-blur transition hover:bg-white hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-neutral-500 focus:ring-offset-2 dark:border-white/20 dark:bg-white/10 dark:text-neutral-200 dark:hover:bg-white/20;
}
.btn-white {
@apply inline-flex items-center gap-2 rounded-full bg-white px-6 py-3 text-sm font-medium text-neutral-900 shadow-lg transition hover:scale-105 hover:shadow-xl focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2;
}
.navlink {
@apply text-sm font-medium text-neutral-600 transition hover:text-primary-600 dark:text-neutral-300 dark:hover:text-primary-400;
}
.input {
@apply w-full rounded-xl border border-white/30 bg-white/70 px-3 py-2 text-sm backdrop-blur transition focus:border-primary-500 focus:outline-none focus:ring-2 focus:ring-primary-500/20 dark:border-white/10 dark:bg-white/10 dark:focus:border-primary-400;
}
/* Card Components */
.card {
@apply rounded-2xl border border-white/30 bg-white/70 p-6 shadow-xl backdrop-blur dark:border-white/10 dark:bg-white/5;
}
.card-hover {
@apply transition hover:-translate-y-1 hover:shadow-2xl;
}
/* Section Header */
.section-header {
@apply mx-auto max-w-3xl text-center;
}
.section-eyebrow {
@apply text-sm uppercase tracking-wider text-primary-600 dark:text-primary-400;
}
.section-title {
@apply mt-2 text-3xl font-bold tracking-tight sm:text-4xl;
}
.section-subtitle {
@apply mt-4 text-lg text-neutral-600 dark:text-neutral-300;
}
}
@layer utilities {
/* Gradient Text */
.gradient-text {
@apply bg-gradient-to-r from-primary-500 via-primary-600 to-secondary-600 bg-clip-text text-transparent;
}
/* Glass Effect */
.glass {
@apply bg-white/10 backdrop-blur-md;
}
.glass-dark {
@apply bg-black/10 backdrop-blur-md;
}
/* Text Balance */
.text-balance {
text-wrap: balance;
}
/* Animation Utilities */
.animate-in {
animation: animate-in 0.6s ease-out;
}
@keyframes animate-in {
from {
opacity: 0;
transform: translateY(1rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Focus States for Accessibility */
.focus-visible\:ring-2:focus-visible {
outline: 2px solid transparent;
outline-offset: 2px;
box-shadow: 0 0 0 2px rgba(236, 72, 153, 0.5);
}
}
/* High Contrast Mode Support */
@media (prefers-contrast: high) {
.btn-primary {
@apply border-2 border-current;
}
.btn-secondary {
@apply border-2 border-current;
}
.card {
@apply border-2 border-current;
}
}
/* Reduced Motion Support */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
.animate-marquee {
animation: none;
}
.animate-float {
animation: none;
}
.animate-pulse-slow {
animation: none;
}
}
/* Print Styles */
@media print {
.no-print {
display: none !important;
}
body {
color: black !important;
background: white !important;
}
.gradient-text {
color: black !important;
background: none !important;
-webkit-text-fill-color: initial !important;
}
}

10
src/main.tsx Normal file
View File

@@ -0,0 +1,10 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)

70
tailwind.config.cjs Normal file
View File

@@ -0,0 +1,70 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
darkMode: 'class',
theme: {
extend: {
colors: {
primary: {
50: '#fdf4ff',
100: '#fae8ff',
200: '#f5d0fe',
300: '#f0abfc',
400: '#e879f9',
500: '#d946ef',
600: '#c026d3',
700: '#a21caf',
800: '#86198f',
900: '#701a75',
},
secondary: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
},
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
animation: {
'marquee': 'marquee 30s linear infinite',
'float': 'float 6s ease-in-out infinite',
'pulse-slow': 'pulse-slow 4s cubic-bezier(0.4, 0, 0.6, 1) infinite',
},
keyframes: {
marquee: {
'0%': { transform: 'translateX(100%)' },
'100%': { transform: 'translateX(-100%)' },
},
float: {
'0%, 100%': { transform: 'translateY(0px)' },
'50%': { transform: 'translateY(-10px)' },
},
'pulse-slow': {
'0%, 100%': { opacity: '1' },
'50%': { opacity: '0.5' },
},
},
boxShadow: {
'glow': '0 0 20px rgba(236, 72, 153, 0.3)',
'glow-lg': '0 0 40px rgba(236, 72, 153, 0.4)',
},
backdropBlur: {
xs: '2px',
},
},
},
plugins: [
require('@tailwindcss/typography'),
],
}

31
tsconfig.json Normal file
View File

@@ -0,0 +1,31 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
/* Path mapping */
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}

10
tsconfig.node.json Normal file
View File

@@ -0,0 +1,10 @@
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}