2
0

style: apply Biome config and normalize quotes

Signed-off-by: Noa Virellia <noa@requiem.garden>
This commit is contained in:
2026-01-27 16:25:02 +08:00
parent 2576a296f1
commit 5f37fc66b0
24 changed files with 407 additions and 261 deletions

3
.zed/settings.json Normal file
View File

@@ -0,0 +1,3 @@
{
"tab_size": 2,
}

View File

@@ -1,12 +1,12 @@
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from "astro/config";
import react from "@astrojs/react";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
integrations: [react()],
vite: { plugins: [tailwindcss()] },
server: {
host: '0.0.0.0',
host: "0.0.0.0",
port: 5000,
allowedHosts: true,
},

35
biome.json Normal file
View File

@@ -0,0 +1,35 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.13/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": false
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}

View File

@@ -40,6 +40,7 @@
"tailwind-merge": "^3.4.0"
},
"devDependencies": {
"@biomejs/biome": "2.3.13",
"@tailwindcss/vite": "^4.1.18",
"@types/node": "^25.0.8",
"@types/react": "^19.2.8",

91
pnpm-lock.yaml generated
View File

@@ -39,6 +39,9 @@ importers:
specifier: ^3.4.0
version: 3.4.0
devDependencies:
'@biomejs/biome':
specifier: 2.3.13
version: 2.3.13
'@tailwindcss/vite':
specifier: ^4.1.18
version: 4.1.18(vite@6.4.1(@types/node@25.0.8)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.97.2))
@@ -178,6 +181,59 @@ packages:
resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==}
engines: {node: '>=6.9.0'}
'@biomejs/biome@2.3.13':
resolution: {integrity: sha512-Fw7UsV0UAtWIBIm0M7g5CRerpu1eKyKAXIazzxhbXYUyMkwNrkX/KLkGI7b+uVDQ5cLUMfOC9vR60q9IDYDstA==}
engines: {node: '>=14.21.3'}
hasBin: true
'@biomejs/cli-darwin-arm64@2.3.13':
resolution: {integrity: sha512-0OCwP0/BoKzyJHnFdaTk/i7hIP9JHH9oJJq6hrSCPmJPo8JWcJhprK4gQlhFzrwdTBAW4Bjt/RmCf3ZZe59gwQ==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [darwin]
'@biomejs/cli-darwin-x64@2.3.13':
resolution: {integrity: sha512-AGr8OoemT/ejynbIu56qeil2+F2WLkIjn2d8jGK1JkchxnMUhYOfnqc9sVzcRxpG9Ycvw4weQ5sprRvtb7Yhcw==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [darwin]
'@biomejs/cli-linux-arm64-musl@2.3.13':
resolution: {integrity: sha512-TUdDCSY+Eo/EHjhJz7P2GnWwfqet+lFxBZzGHldrvULr59AgahamLs/N85SC4+bdF86EhqDuuw9rYLvLFWWlXA==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
'@biomejs/cli-linux-arm64@2.3.13':
resolution: {integrity: sha512-xvOiFkrDNu607MPMBUQ6huHmBG1PZLOrqhtK6pXJW3GjfVqJg0Z/qpTdhXfcqWdSZHcT+Nct2fOgewZvytESkw==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
'@biomejs/cli-linux-x64-musl@2.3.13':
resolution: {integrity: sha512-0bdwFVSbbM//Sds6OjtnmQGp4eUjOTt6kHvR/1P0ieR9GcTUAlPNvPC3DiavTqq302W34Ae2T6u5VVNGuQtGlQ==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
'@biomejs/cli-linux-x64@2.3.13':
resolution: {integrity: sha512-s+YsZlgiXNq8XkgHs6xdvKDFOj/bwTEevqEY6rC2I3cBHbxXYU1LOZstH3Ffw9hE5tE1sqT7U23C00MzkXztMw==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
'@biomejs/cli-win32-arm64@2.3.13':
resolution: {integrity: sha512-QweDxY89fq0VvrxME+wS/BXKmqMrOTZlN9SqQ79kQSIc3FrEwvW/PvUegQF6XIVaekncDykB5dzPqjbwSKs9DA==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [win32]
'@biomejs/cli-win32-x64@2.3.13':
resolution: {integrity: sha512-trDw2ogdM2lyav9WFQsdsfdVy1dvZALymRpgmWsvSez0BJzBjulhOT/t+wyKeh3pZWvwP3VMs1SoOKwO3wecMQ==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [win32]
'@capsizecss/unpack@4.0.0':
resolution: {integrity: sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==}
engines: {node: '>=18'}
@@ -2310,6 +2366,41 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
'@biomejs/biome@2.3.13':
optionalDependencies:
'@biomejs/cli-darwin-arm64': 2.3.13
'@biomejs/cli-darwin-x64': 2.3.13
'@biomejs/cli-linux-arm64': 2.3.13
'@biomejs/cli-linux-arm64-musl': 2.3.13
'@biomejs/cli-linux-x64': 2.3.13
'@biomejs/cli-linux-x64-musl': 2.3.13
'@biomejs/cli-win32-arm64': 2.3.13
'@biomejs/cli-win32-x64': 2.3.13
'@biomejs/cli-darwin-arm64@2.3.13':
optional: true
'@biomejs/cli-darwin-x64@2.3.13':
optional: true
'@biomejs/cli-linux-arm64-musl@2.3.13':
optional: true
'@biomejs/cli-linux-arm64@2.3.13':
optional: true
'@biomejs/cli-linux-x64-musl@2.3.13':
optional: true
'@biomejs/cli-linux-x64@2.3.13':
optional: true
'@biomejs/cli-win32-arm64@2.3.13':
optional: true
'@biomejs/cli-win32-x64@2.3.13':
optional: true
'@capsizecss/unpack@4.0.0':
dependencies:
fontkitten: 1.0.1

View File

@@ -1,5 +1,5 @@
import { motion } from 'framer-motion';
import { ArrowLeft, Heart, Network } from 'lucide-react';
import { motion } from "framer-motion";
import { ArrowLeft, Heart, Network } from "lucide-react";
export default function About() {
return (
@@ -78,10 +78,10 @@ export default function About() {
</h2>
<ul className="space-y-3">
{[
'Interactive meditation timer with customizable sessions',
'Breathing techniques & mindfulness exercises',
'Daily affirmations & zen wisdom',
'A collaborative network of innovators',
"Interactive meditation timer with customizable sessions",
"Breathing techniques & mindfulness exercises",
"Daily affirmations & zen wisdom",
"A collaborative network of innovators",
].map((item, idx) => (
<li key={idx} className="flex items-start gap-3">
<Heart className="text-primary mt-1 h-5 w-5 flex-shrink-0 fill-current" />

View File

@@ -1,25 +1,25 @@
import { useState } from 'react';
import { motion } from 'framer-motion';
import { ArrowLeft, Mail, Heart } from 'lucide-react';
import { useState } from "react";
import { motion } from "framer-motion";
import { ArrowLeft, Mail, Heart } from "lucide-react";
export default function Contact() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [message, setMessage] = useState('');
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [message, setMessage] = useState("");
const [submitted, setSubmitted] = useState(false);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (name && email && message) {
const messages = JSON.parse(
localStorage.getItem('contactMessages') || '[]',
localStorage.getItem("contactMessages") || "[]",
);
messages.push({ name, email, message, date: new Date().toISOString() });
localStorage.setItem('contactMessages', JSON.stringify(messages));
localStorage.setItem("contactMessages", JSON.stringify(messages));
setSubmitted(true);
setName('');
setEmail('');
setMessage('');
setName("");
setEmail("");
setMessage("");
}
};

View File

@@ -1,8 +1,8 @@
import { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { ArrowLeft, Lightbulb, Wind, Heart, Sparkles } from 'lucide-react';
import { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { ArrowLeft, Lightbulb, Wind, Heart, Sparkles } from "lucide-react";
type Category = 'tips' | 'breathing' | 'affirmations';
type Category = "tips" | "breathing" | "affirmations";
interface Guide {
id: string;
@@ -20,199 +20,199 @@ const Explore = () => {
const categories: Record<Category, Guide[]> = {
tips: [
{
id: 'tip-1',
title: 'The Power of Silence',
id: "tip-1",
title: "The Power of Silence",
description:
'Like a focused engineer, find clarity in quiet moments. Deep work is where innovation begins.',
"Like a focused engineer, find clarity in quiet moments. Deep work is where innovation begins.",
icon: <Sparkles className="h-6 w-6" />,
color: 'bg-amber-100',
color: "bg-amber-100",
},
{
id: 'tip-2',
title: 'Slow Blinking',
id: "tip-2",
title: "Slow Blinking",
description:
"Practice mindful pauses. It's a way of signaling calm to your nervous system and fostering trust in your decisions.",
icon: <Heart className="h-6 w-6" />,
color: 'bg-pink-100',
color: "bg-pink-100",
},
{
id: 'tip-3',
title: 'Mindful Stretching',
id: "tip-3",
title: "Mindful Stretching",
description:
'Integrate micro-breaks throughout your day. Short, mindful pauses enhance productivity and prevent burnout.',
"Integrate micro-breaks throughout your day. Short, mindful pauses enhance productivity and prevent burnout.",
icon: <Wind className="h-6 w-6" />,
color: 'bg-green-100',
color: "bg-green-100",
},
{
id: 'tip-4',
title: 'Comfort is Key',
id: "tip-4",
title: "Comfort is Key",
description:
'Find your cozy corner. A comfortable space makes meditation easier and more enjoyable.',
"Find your cozy corner. A comfortable space makes meditation easier and more enjoyable.",
icon: <Lightbulb className="h-6 w-6" />,
color: 'bg-blue-100',
color: "bg-blue-100",
},
{
id: 'tip-5',
title: 'Focus on Your Breath',
id: "tip-5",
title: "Focus on Your Breath",
description:
'Let your breath be your anchor. When your mind wanders, gently bring it back to your natural rhythm.',
"Let your breath be your anchor. When your mind wanders, gently bring it back to your natural rhythm.",
icon: <Wind className="h-6 w-6" />,
color: 'bg-teal-100',
color: "bg-teal-100",
},
{
id: 'tip-6',
title: 'Practice Gratitude',
id: "tip-6",
title: "Practice Gratitude",
description:
"Start each session by noting 3 things you're grateful for. This shifts your mind toward positivity.",
icon: <Heart className="h-6 w-6" />,
color: 'bg-fuchsia-100',
color: "bg-fuchsia-100",
},
{
id: 'tip-7',
title: 'Meditate in Nature',
id: "tip-7",
title: "Meditate in Nature",
description:
'Whenever possible, take your meditation practice outdoors. Nature amplifies the calming effect.',
"Whenever possible, take your meditation practice outdoors. Nature amplifies the calming effect.",
icon: <Sparkles className="h-6 w-6" />,
color: 'bg-emerald-100',
color: "bg-emerald-100",
},
{
id: 'tip-8',
title: 'Same Time, Every Day',
id: "tip-8",
title: "Same Time, Every Day",
description:
'Establish a routine. Consistent practice helps train your mind for optimal performance and focus.',
"Establish a routine. Consistent practice helps train your mind for optimal performance and focus.",
icon: <Lightbulb className="h-6 w-6" />,
color: 'bg-sky-100',
color: "bg-sky-100",
},
],
breathing: [
{
id: 'breath-1',
title: '4-4-4-4 Breathing',
id: "breath-1",
title: "4-4-4-4 Breathing",
description:
'Inhale for 4, hold for 4, exhale for 4, hold for 4. A balanced rhythm for mental clarity.',
"Inhale for 4, hold for 4, exhale for 4, hold for 4. A balanced rhythm for mental clarity.",
icon: <Wind className="h-6 w-6" />,
color: 'bg-cyan-100',
color: "bg-cyan-100",
},
{
id: 'breath-2',
title: 'Deep Focus Breath',
id: "breath-2",
title: "Deep Focus Breath",
description:
'Exhale with a controlled, steady release. Feel the rhythm stabilize your focus and calm your mind.',
"Exhale with a controlled, steady release. Feel the rhythm stabilize your focus and calm your mind.",
icon: <Heart className="h-6 w-6" />,
color: 'bg-purple-100',
color: "bg-purple-100",
},
{
id: 'breath-3',
title: 'Box Breathing',
id: "breath-3",
title: "Box Breathing",
description:
'Equal parts: inhale, hold, exhale, pause. Simple yet powerful for instant calm.',
"Equal parts: inhale, hold, exhale, pause. Simple yet powerful for instant calm.",
icon: <Sparkles className="h-6 w-6" />,
color: 'bg-rose-100',
color: "bg-rose-100",
},
{
id: 'breath-4',
title: 'Extended Exhale',
id: "breath-4",
title: "Extended Exhale",
description:
"Make your exhale longer than your inhale. Signals to your body it's safe to relax.",
icon: <Lightbulb className="h-6 w-6" />,
color: 'bg-lime-100',
color: "bg-lime-100",
},
{
id: 'breath-5',
title: 'Alternate Nostril Breathing',
id: "breath-5",
title: "Alternate Nostril Breathing",
description:
'Nadi Shodhana: Balance your nervous system by breathing through alternating nostrils.',
"Nadi Shodhana: Balance your nervous system by breathing through alternating nostrils.",
icon: <Wind className="h-6 w-6" />,
color: 'bg-violet-100',
color: "bg-violet-100",
},
{
id: 'breath-6',
title: 'Belly Breathing',
id: "breath-6",
title: "Belly Breathing",
description:
'Place your hand on your belly. Feel it rise and fall with each breath. This activates calm.',
"Place your hand on your belly. Feel it rise and fall with each breath. This activates calm.",
icon: <Heart className="h-6 w-6" />,
color: 'bg-pink-100',
color: "bg-pink-100",
},
{
id: 'breath-7',
title: 'Coherent Breathing',
id: "breath-7",
title: "Coherent Breathing",
description:
'5 seconds in, 5 seconds out. Creates heart-brain coherence for deep relaxation.',
"5 seconds in, 5 seconds out. Creates heart-brain coherence for deep relaxation.",
icon: <Sparkles className="h-6 w-6" />,
color: 'bg-amber-100',
color: "bg-amber-100",
},
{
id: 'breath-8',
id: "breath-8",
title: "Lion's Breath",
description:
'Take a deep breath, then exhale forcefully while opening your mouth. Releases tension instantly.',
"Take a deep breath, then exhale forcefully while opening your mouth. Releases tension instantly.",
icon: <Lightbulb className="h-6 w-6" />,
color: 'bg-orange-100',
color: "bg-orange-100",
},
],
affirmations: [
{
id: 'aff-1',
title: 'I breathe in calm, I breathe out noise',
id: "aff-1",
title: "I breathe in calm, I breathe out noise",
description:
'Like a resilient system, I adapt to change and optimize for the future.',
"Like a resilient system, I adapt to change and optimize for the future.",
icon: <Heart className="h-6 w-6" />,
color: 'bg-red-100',
color: "bg-red-100",
},
{
id: 'aff-2',
title: 'Slow is better than fast',
id: "aff-2",
title: "Slow is better than fast",
description:
'I embrace the philosophy of precision and deliberate action.',
"I embrace the philosophy of precision and deliberate action.",
icon: <Sparkles className="h-6 w-6" />,
color: 'bg-yellow-100',
color: "bg-yellow-100",
},
{
id: 'aff-3',
title: 'I deserve rest and comfort',
id: "aff-3",
title: "I deserve rest and comfort",
description:
"Strategic rest is not idleness, it's essential. I optimize my energy for peak performance.",
icon: <Lightbulb className="h-6 w-6" />,
color: 'bg-indigo-100',
color: "bg-indigo-100",
},
{
id: 'aff-4',
title: 'Every moment is a new beginning',
id: "aff-4",
title: "Every moment is a new beginning",
description:
'Like a robust algorithm, I adapt and find optimal solutions.',
"Like a robust algorithm, I adapt and find optimal solutions.",
icon: <Wind className="h-6 w-6" />,
color: 'bg-orange-100',
color: "bg-orange-100",
},
{
id: 'aff-5',
title: 'My mind is clear and peaceful',
description: 'I let go of stress and embrace serenity in every breath.',
id: "aff-5",
title: "My mind is clear and peaceful",
description: "I let go of stress and embrace serenity in every breath.",
icon: <Heart className="h-6 w-6" />,
color: 'bg-rose-100',
color: "bg-rose-100",
},
{
id: 'aff-6',
title: 'Like a stable network, I radiate calm',
id: "aff-6",
title: "Like a stable network, I radiate calm",
description:
'I treat myself with the same precision and care I apply to my work.',
"I treat myself with the same precision and care I apply to my work.",
icon: <Sparkles className="h-6 w-6" />,
color: 'bg-pink-100',
color: "bg-pink-100",
},
{
id: 'aff-7',
title: 'Challenges make me stronger',
id: "aff-7",
title: "Challenges make me stronger",
description:
'Like a well-engineered solution, I navigate challenges with resilience.',
"Like a well-engineered solution, I navigate challenges with resilience.",
icon: <Lightbulb className="h-6 w-6" />,
color: 'bg-cyan-100',
color: "bg-cyan-100",
},
{
id: 'aff-8',
title: 'My energy is positive and vibrant',
id: "aff-8",
title: "My energy is positive and vibrant",
description:
'I radiate calm confidence and attract good things into my life.',
"I radiate calm confidence and attract good things into my life.",
icon: <Wind className="h-6 w-6" />,
color: 'bg-lime-100',
color: "bg-lime-100",
},
],
};
@@ -221,13 +221,13 @@ const Explore = () => {
Category,
{ name: string; icon: React.ReactNode }
> = {
tips: { name: 'Zen Tips', icon: <Lightbulb className="h-5 w-5" /> },
tips: { name: "Zen Tips", icon: <Lightbulb className="h-5 w-5" /> },
breathing: {
name: 'Breathing Techniques',
name: "Breathing Techniques",
icon: <Wind className="h-5 w-5" />,
},
affirmations: {
name: 'Daily Affirmations',
name: "Daily Affirmations",
icon: <Heart className="h-5 w-5" />,
},
};
@@ -291,10 +291,10 @@ const Explore = () => {
{categoryLabels[category].name}
</h3>
<p className="text-muted-foreground text-sm">
{category === 'tips' && 'Learn meditation wisdom'}
{category === 'breathing' &&
'Master breathing techniques'}
{category === 'affirmations' && 'Empower your mind'}
{category === "tips" && "Learn meditation wisdom"}
{category === "breathing" &&
"Master breathing techniques"}
{category === "affirmations" && "Empower your mind"}
</p>
</div>
</div>
@@ -328,12 +328,12 @@ const Explore = () => {
{categoryLabels[selectedCategory].name}
</h2>
<p className="text-muted-foreground">
{selectedCategory === 'tips' &&
'Insights for peak performance and well-being'}
{selectedCategory === 'breathing' &&
'Techniques to calm your mind and body'}
{selectedCategory === 'affirmations' &&
'Affirmations to start your day with zen'}
{selectedCategory === "tips" &&
"Insights for peak performance and well-being"}
{selectedCategory === "breathing" &&
"Techniques to calm your mind and body"}
{selectedCategory === "affirmations" &&
"Affirmations to start your day with zen"}
</p>
</div>

View File

@@ -1,58 +1,58 @@
import { motion, AnimatePresence } from 'framer-motion';
import { ArrowLeft, ChevronDown } from 'lucide-react';
import { useState } from 'react';
import { motion, AnimatePresence } from "framer-motion";
import { ArrowLeft, ChevronDown } from "lucide-react";
import { useState } from "react";
const FAQ = () => {
const [expandedId, setExpandedId] = useState<string | null>(null);
const faqs = [
{
id: 'faq-1',
question: 'How long should I meditate each day?',
id: "faq-1",
question: "How long should I meditate each day?",
answer:
'Start with just 5 minutes daily. Even a short practice is powerful when consistent. As you progress, you can extend to 10, 20, or 30 minutes.',
"Start with just 5 minutes daily. Even a short practice is powerful when consistent. As you progress, you can extend to 10, 20, or 30 minutes.",
},
{
id: 'faq-2',
id: "faq-2",
question: "I can't stop my mind from wandering. Am I doing it wrong?",
answer:
"Not at all! Mind-wandering is completely normal. Meditation is noticing when your mind wanders and gently bringing it back—that's the practice itself.",
},
{
id: 'faq-3',
question: 'Best time of day to meditate?',
id: "faq-3",
question: "Best time of day to meditate?",
answer:
"Early morning (after waking) is ideal for most people. However, the best time is whenever you'll actually do it. Consistency matters more than timing.",
},
{
id: 'faq-4',
question: 'Do I need a special place to meditate?',
id: "faq-4",
question: "Do I need a special place to meditate?",
answer:
'No. While a quiet, comfortable space helps, meditation can happen anywhere—your bedroom, a park, even on the bus. Find what works for you.',
"No. While a quiet, comfortable space helps, meditation can happen anywhere—your bedroom, a park, even on the bus. Find what works for you.",
},
{
id: 'faq-5',
question: 'Is meditation religious? Can anyone do it?',
id: "faq-5",
question: "Is meditation religious? Can anyone do it?",
answer:
'Meditation has roots in many traditions, but modern mindfulness meditation is secular and evidence-based. Anyone can benefit, regardless of beliefs.',
"Meditation has roots in many traditions, but modern mindfulness meditation is secular and evidence-based. Anyone can benefit, regardless of beliefs.",
},
{
id: 'faq-6',
question: 'How long before I see results?',
id: "faq-6",
question: "How long before I see results?",
answer:
'Some benefits (like reduced stress) appear within days. Deeper changes take weeks or months. Trust the process and keep practicing.',
"Some benefits (like reduced stress) appear within days. Deeper changes take weeks or months. Trust the process and keep practicing.",
},
{
id: 'faq-7',
question: 'What if I fall asleep during meditation?',
id: "faq-7",
question: "What if I fall asleep during meditation?",
answer:
"It's fine! Your body might need rest. If it happens frequently, try meditating earlier in the day or sitting upright instead of lying down.",
},
{
id: 'faq-8',
question: 'Can I meditate while walking?',
id: "faq-8",
question: "Can I meditate while walking?",
answer:
'Yes! Walking meditation is a powerful practice. Focus on the sensation of each step, your breath, and your surroundings as you walk slowly.',
"Yes! Walking meditation is a powerful practice. Focus on the sensation of each step, your breath, and your surroundings as you walk slowly.",
},
];
@@ -116,7 +116,7 @@ const FAQ = () => {
{expandedId === faq.id && (
<motion.div
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
animate={{ opacity: 1, height: "auto" }}
exit={{ opacity: 0, height: 0 }}
transition={{ duration: 0.3 }}
className="border-border/40 overflow-hidden border-t"

View File

@@ -1,44 +1,44 @@
import { motion } from 'framer-motion';
import { ArrowLeft, CheckCircle, Lightbulb, Heart } from 'lucide-react';
import { motion } from "framer-motion";
import { ArrowLeft, CheckCircle, Lightbulb, Heart } from "lucide-react";
const Guide = () => {
const steps = [
{
title: 'Why Meditate?',
title: "Why Meditate?",
description:
'Meditation reduces stress and anxiety, improves focus, and enhances emotional well-being. It literally rewires your brain for peace.',
"Meditation reduces stress and anxiety, improves focus, and enhances emotional well-being. It literally rewires your brain for peace.",
icon: <Heart className="h-6 w-6" />,
benefits: [
'Better sleep quality',
'Reduced anxiety & stress',
'Improved focus & clarity',
'Emotional resilience',
"Better sleep quality",
"Reduced anxiety & stress",
"Improved focus & clarity",
"Emotional resilience",
],
},
{
title: 'How to Start',
title: "How to Start",
description:
"You don't need experience. Just find a comfortable spot, close your eyes, and follow your breath. That's it!",
icon: <Lightbulb className="h-6 w-6" />,
steps: [
'Find a quiet, comfortable place',
'Sit or lie down (whatever feels right)',
'Close your eyes',
'Focus on your natural breath',
'When your mind wanders, gently bring it back',
"Find a quiet, comfortable place",
"Sit or lie down (whatever feels right)",
"Close your eyes",
"Focus on your natural breath",
"When your mind wanders, gently bring it back",
],
},
{
title: 'Building Consistency',
title: "Building Consistency",
description:
'The magic happens through regular practice. Start small and build from there.',
"The magic happens through regular practice. Start small and build from there.",
icon: <CheckCircle className="h-6 w-6" />,
tips: [
'Start with just 5 minutes',
'Same time every day (ideally morning)',
'Track your sessions',
'Be patient with yourself',
'Celebrate small wins',
"Start with just 5 minutes",
"Same time every day (ideally morning)",
"Track your sessions",
"Be patient with yourself",
"Celebrate small wins",
],
},
];

View File

@@ -1,5 +1,14 @@
import { SiGo, SiKubernetes, SiNixos, SiOpentelemetry, SiReact, SiTalos, SiTerraform, SiTypescript } from '@icons-pack/react-simple-icons';
import { motion, AnimatePresence } from 'framer-motion';
import {
SiGo,
SiKubernetes,
SiNixos,
SiOpentelemetry,
SiReact,
SiTalos,
SiTerraform,
SiTypescript,
} from "@icons-pack/react-simple-icons";
import { motion, AnimatePresence } from "framer-motion";
import {
Heart,
Sparkles,
@@ -17,20 +26,19 @@ import {
Bot,
CalendarHeart,
Flame,
} from 'lucide-react';
import { useRef,
useState, useEffect } from 'react';
import CanvasNest from 'canvas-nest.js';
import { skipPartiallyEmittedExpressions } from 'typescript';
} from "lucide-react";
import { useRef, useState, useEffect } from "react";
import CanvasNest from "canvas-nest.js";
import { skipPartiallyEmittedExpressions } from "typescript";
const Navigation = () => {
const [isOpen, setIsOpen] = useState(false);
const [activeSection, setActiveSection] = useState('home');
const [activeSection, setActiveSection] = useState("home");
useEffect(() => {
const handleScroll = () => {
const sections = ['home', 'features', 'cta'];
let current = 'home';
const sections = ["home", "features", "cta"];
let current = "home";
for (const section of sections) {
const element = document.getElementById(section);
@@ -44,8 +52,8 @@ const Navigation = () => {
setActiveSection(current);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
const navLinks = [] as const;
@@ -77,7 +85,7 @@ const Hero = () => {
if (!bodyRef.current) return;
const config = {
color: '241,151,142',
color: "241,151,142",
count: 88,
opacity: 0.8,
zIndex: 0,
@@ -88,7 +96,7 @@ const Hero = () => {
return () => {
cn.destroy();
};
}, [])
}, []);
return (
<section
id="home"
@@ -109,10 +117,14 @@ const Hero = () => {
Ignis Network
</div>
<p className="text-muted-foreground max-w-3xl text-lg leading-relaxed md:text-xl">
We're a startup company that builds resilient digital infrastructure designed to endure, with AI applied where it meaningfully adds strength and insight.
We're a startup company that builds resilient digital infrastructure
designed to endure, with AI applied where it meaningfully adds
strength and insight.
</p>
<p className="text-muted-foreground max-w-2xl text-lg leading-relaxed md:text-xl mt-2">
We focus on stability, clarity, and long-term reliabilitycreating systems that smartly carry what matters, support growth over time, and let everything else move forward with confidence.
We focus on stability, clarity, and long-term reliability creating
systems that smartly carry what matters, support growth over time,
and let everything else move forward with confidence.
</p>
<motion.div
@@ -122,15 +134,23 @@ const Hero = () => {
transition={{ duration: 0.6, delay: 0.3 }}
>
{[
{ icon: SiNixos, label: 'Nix', color: 'text-[#5277C3]' },
{ icon: SiKubernetes, label: 'Kubernetes', color: 'text-[#326CE5]' },
{ icon: SiNixos, label: "Nix", color: "text-[#5277C3]" },
{
icon: SiKubernetes,
label: "Kubernetes",
color: "text-[#326CE5]",
},
{
icon: SiTerraform,
label: 'Terraform',
color: 'text-[#844FBA]',
label: "Terraform",
color: "text-[#844FBA]",
},
{ icon: SiOpentelemetry, label: 'OpenTelemetry', color: 'text-[#000000]' },
{ icon: Bot, label: 'Ignis AI', color: 'text-[#F1978E]'}
{
icon: SiOpentelemetry,
label: "OpenTelemetry",
color: "text-[#000000]",
},
{ icon: Bot, label: "Ignis AI", color: "text-[#F1978E]" },
].map((badge, idx) => (
<motion.div
key={idx}
@@ -151,8 +171,8 @@ const Hero = () => {
</motion.div>
</div>
<div className='flex-1 flex justify-center items-center'>
<Flame className='stroke-[#F1978E] size-96 stroke-[0.3px] opacity-70 mb-4 mr-12 hidden md:block' />
<div className="flex-1 flex justify-center items-center">
<Flame className="stroke-[#F1978E] size-96 stroke-[0.3px] opacity-70 mb-4 mr-12 hidden md:block" />
</div>
</section>
);
@@ -300,9 +320,7 @@ export const Footer = () => {
<div className="space-y-3">
<div className="text-primary flex items-center gap-2">
<Users className="h-5 w-5" />
<span className="font-heading text-sm font-bold">
Contact
</span>
<span className="font-heading text-sm font-bold">Contact</span>
</div>
<div className="flex flex-col gap-2 pl-7">
<a
@@ -411,30 +429,30 @@ function CTA() {
<div className="grid grid-cols-1 gap-6 md:grid-cols-3">
{[
{
id: 'cta-start-app',
title: 'Deploy AI Solutions',
id: "cta-start-app",
title: "Deploy AI Solutions",
description:
'Implement scalable AI architectures tailored to your enterprise needs.',
href: '/app',
testId: 'button-cta-app',
"Implement scalable AI architectures tailored to your enterprise needs.",
href: "/app",
testId: "button-cta-app",
icon: <Cpu className="text-primary h-8 w-8" />,
},
{
id: 'cta-guide',
title: 'Strategic Consulting',
id: "cta-guide",
title: "Strategic Consulting",
description:
'Expert guidance on digital transformation and technology roadmap planning.',
href: '/guide',
testId: 'button-cta-guide',
"Expert guidance on digital transformation and technology roadmap planning.",
href: "/guide",
testId: "button-cta-guide",
icon: <BookOpen className="text-primary h-8 w-8" />,
},
{
id: 'cta-explore',
title: 'Explore Platform',
id: "cta-explore",
title: "Explore Platform",
description:
'Discover our suite of intelligent tools designed to accelerate your growth.',
href: '/explore',
testId: 'button-cta-explore',
"Discover our suite of intelligent tools designed to accelerate your growth.",
href: "/explore",
testId: "button-cta-explore",
icon: <Compass className="text-primary h-8 w-8" />,
},
].map((cta, idx) => (
@@ -453,9 +471,7 @@ function CTA() {
<h3 className="font-heading text-foreground text-2xl font-bold">
{cta.title}
</h3>
<p className="text-muted-foreground flex-1">
{cta.description}
</p>
<p className="text-muted-foreground flex-1">{cta.description}</p>
<a href={cta.href}>
<button
data-testid={cta.testId}
@@ -468,7 +484,7 @@ function CTA() {
))}
</div>
</div>
</section>
</section>;
}
export default function Home() {

View File

@@ -1,16 +1,16 @@
import { useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import { ArrowLeft, Mail, Heart, Users, Network } from 'lucide-react';
import { useState, useEffect } from "react";
import { motion } from "framer-motion";
import { ArrowLeft, Mail, Heart, Users, Network } from "lucide-react";
const Join = () => {
const [email, setEmail] = useState('');
const [email, setEmail] = useState("");
const [joined, setJoined] = useState(false);
const [error, setError] = useState('');
const [error, setError] = useState("");
const [members, setMembers] = useState(0);
useEffect(() => {
const communityMembers = JSON.parse(
localStorage.getItem('communityMembers') || '[]',
localStorage.getItem("communityMembers") || "[]",
);
setMembers(communityMembers.length);
}, []);
@@ -18,30 +18,30 @@ const Join = () => {
const handleJoin = (e: React.FormEvent) => {
e.preventDefault();
if (!email) {
setError('Please enter your email');
setError("Please enter your email");
return;
}
if (!email.includes('@')) {
setError('Please enter a valid email');
if (!email.includes("@")) {
setError("Please enter a valid email");
return;
}
// Save to localStorage
const communityMembers = JSON.parse(
localStorage.getItem('communityMembers') || '[]',
localStorage.getItem("communityMembers") || "[]",
);
if (!communityMembers.includes(email)) {
communityMembers.push(email);
localStorage.setItem(
'communityMembers',
"communityMembers",
JSON.stringify(communityMembers),
);
setMembers(communityMembers.length);
}
setJoined(true);
setEmail('');
setError('');
setEmail("");
setError("");
};
return (
@@ -146,7 +146,7 @@ const Join = () => {
value={email}
onChange={(e) => {
setEmail(e.target.value);
setError('');
setError("");
}}
data-testid="input-email-join"
className="bg-secondary/20 focus:border-primary flex-1 rounded-full border-2 border-transparent px-6 py-4 text-lg transition-all focus:outline-none"
@@ -219,7 +219,7 @@ const Join = () => {
key="success"
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ type: 'spring', stiffness: 300, damping: 20 }}
transition={{ type: "spring", stiffness: 300, damping: 20 }}
className="w-full space-y-6"
>
<motion.div

View File

@@ -1,5 +1,5 @@
import { motion } from 'framer-motion';
import { ArrowLeft } from 'lucide-react';
import { motion } from "framer-motion";
import { ArrowLeft } from "lucide-react";
export default function Privacy() {
return (

View File

@@ -7,14 +7,14 @@ interface Props {
}
const {
title = 'Ignis Network - Cat-Inspired Meditation & Mindfulness',
description = 'Redefining the digital frontier with next-generation internet services and advanced AI.',
canonicalPath = '',
title = "Ignis Network - Cat-Inspired Meditation & Mindfulness",
description = "Redefining the digital frontier with next-generation internet services and advanced AI.",
canonicalPath = "",
noindex = false,
} = Astro.props;
const siteUrl = Astro.site?.href || '';
const canonicalUrl = `${siteUrl.replace(/\/$/, '')}${canonicalPath}`;
const siteUrl = Astro.site?.href || "";
const canonicalUrl = `${siteUrl.replace(/\/$/, "")}${canonicalPath}`;
---
<!doctype html>

View File

@@ -1,4 +1,4 @@
declare module 'canvas-nest.js' {
declare module "canvas-nest.js" {
/**
* CanvasNest 配置项接口
*/

View File

@@ -1,5 +1,5 @@
import { clsx, type ClassValue } from 'clsx';
import { twMerge } from 'tailwind-merge';
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));

View File

@@ -1,6 +1,6 @@
---
import Layout from '../layouts/Layout.astro';
import AboutPage from '../components/AboutPage';
import Layout from "../layouts/Layout.astro";
import AboutPage from "../components/AboutPage";
---
<Layout

View File

@@ -1,6 +1,6 @@
---
import Layout from '../layouts/Layout.astro';
import ContactPage from '../components/ContactPage';
import Layout from "../layouts/Layout.astro";
import ContactPage from "../components/ContactPage";
---
<Layout

View File

@@ -1,6 +1,6 @@
---
import Layout from '../layouts/Layout.astro';
import ExplorePage from '../components/ExplorePage';
import Layout from "../layouts/Layout.astro";
import ExplorePage from "../components/ExplorePage";
---
<Layout

View File

@@ -1,6 +1,6 @@
---
import Layout from '../layouts/Layout.astro';
import FaqPage from '../components/FaqPage';
import Layout from "../layouts/Layout.astro";
import FaqPage from "../components/FaqPage";
---
<Layout

View File

@@ -1,6 +1,6 @@
---
import Layout from '../layouts/Layout.astro';
import GuidePage from '../components/GuidePage';
import Layout from "../layouts/Layout.astro";
import GuidePage from "../components/GuidePage";
---
<Layout

View File

@@ -1,6 +1,6 @@
---
import Layout from '../layouts/Layout.astro';
import HomePage from '../components/HomePage';
import Layout from "../layouts/Layout.astro";
import HomePage from "../components/HomePage";
---
<Layout

View File

@@ -1,6 +1,6 @@
---
import Layout from '../layouts/Layout.astro';
import JoinPage from '../components/JoinPage';
import Layout from "../layouts/Layout.astro";
import JoinPage from "../components/JoinPage";
---
<Layout

View File

@@ -1,6 +1,6 @@
---
import Layout from '../layouts/Layout.astro';
import PrivacyPage from '../components/PrivacyPage';
import Layout from "../layouts/Layout.astro";
import PrivacyPage from "../components/PrivacyPage";
---
<Layout