diff --git a/AI_PROMPTS_FOR_IMPROVEMENTS.md b/AI_PROMPTS_FOR_IMPROVEMENTS.md new file mode 100644 index 0000000..b750e12 --- /dev/null +++ b/AI_PROMPTS_FOR_IMPROVEMENTS.md @@ -0,0 +1,562 @@ +# AI Prompt Templates for Site Improvements + +This document contains reusable AI prompts for improving site copy, layout, and content during the Django migration. Use these prompts with ChatGPT, Claude, or other AI tools to generate improvements while maintaining your brand identity. + +## Brand Guidelines (Reference) + +### Brand Colors + +**Active Season Colors (March - November):** +- Deep forest green: `#2e3d2a` (brand-green-dark) - Main background +- Vibrant green accent: `#32d24d` (brand-green-accent) - Primary accent +- Hyperlink green: `#156624` (brand-green-hyperlink) - Links +- Rich purple: `#442b48` (brand-purple-dark) - Secondary background +- Soft cream: `#f4f1de` (brand-cream) - Text on dark backgrounds +- Light purple accent: `#d8b9f7` (brand-purple-light) - Secondary accent +- Bright blue: `#00a6fb` (brand-blue) +- Fuchsia: `#ff39bc` (brand-fuchsia) + +**Rest Period Colors (November - March):** +- Rich purple: `#442b48` (brand-purple-dark) - Main background (replaces green) +- Light purple accent: `#d8b9f7` (brand-purple-light) - Primary accent (replaces green accent) +- Soft cream: `#f4f1de` (brand-cream) - Text on dark backgrounds +- Bright blue: `#00a6fb` (brand-blue) +- Fuchsia: `#ff39bc` (brand-fuchsia) + +**Note:** The site currently uses rest period colors (purple theme) until March 2026. + +### Active & Rest Periods + +Following the tradition of the Pythia Oracles of Delphi: +- **Active Season:** March - November (green color scheme) +- **Rest Period:** November - March (purple color scheme) +- **Current Status:** Rest Mode (services resume March 2026) +- **Philosophy:** The rest period accommodates chronic illnesses and chronic pain while nurturing creativity through intentional slowness. + +### Brand Voice +- Professional yet approachable +- Empathetic and judgment-free +- Neurodivergent-friendly +- Clear and accessible +- Authentic and personal +- Tech-savvy but not condescending +- Honors cycles of rest and renewal +- Acknowledges chronic illness and chronic pain accommodation +- Values intentional slowness for creativity + +### Current Site Status + +**Rest Period (November 2025 - March 2026):** +- Site uses purple color scheme (rest period theme) +- Services are in rest mode with return date: March 2026 +- Homepage features Pythia Oracles of Delphi theme +- All booking links are hidden/disabled +- Newsletter signup emphasized for return notifications + +**Active Season (March - November):** +- Site uses green color scheme (active theme) +- All services available +- Booking links active +- Full service offerings visible + +--- + +## 1. Copy Improvement Prompts + +### Hero Section Copy + +``` +I'm improving the hero section of my tech coaching website. Review this copy for clarity, engagement, and conversion effectiveness. + +Brand voice: Professional, empathetic, neurodivergent-friendly, judgment-free, accessible +Target audience: Neurodivergent professionals, business owners, creators seeking tech coaching +Current status: Rest Period (services resume March 2026) - use purple color scheme references + +Current hero copy: +[paste your current hero section text] + +Please: +1. Analyze the current copy for strengths and weaknesses +2. Suggest 3 improved versions that are more compelling +3. Maintain the brand voice and tone +4. Ensure accessibility and clarity +5. Include a clear value proposition +6. Note: If this is for rest period, honor the rest and renewal theme +``` + +### Service Descriptions + +``` +I need help improving my service descriptions to be clearer and more persuasive. + +Brand voice: [same as above] +Services: Tech coaching, digital system design, workflow optimization + +Current service descriptions: +[paste service descriptions] + +Please: +1. Analyze each description for clarity and persuasiveness +2. Suggest improvements that: + - Clearly communicate unique value + - Address specific pain points + - Use accessible, non-jargon language + - Maintain professional but approachable tone + - Include clear calls-to-action +3. Keep descriptions concise but informative +4. Ensure each service stands out uniquely +``` + +### About Section + +``` +Review my about section for authenticity, trust-building, and connection. + +Brand voice: [same as above] +Goal: Build trust, show personality, demonstrate expertise, remain approachable + +Current about section: +[paste about section] + +Please: +1. Analyze for authenticity and relatability +2. Suggest improvements that: + - Build trust through specific examples + - Show personality without being unprofessional + - Demonstrate expertise through stories, not just credentials + - Make the reader feel understood + - Address common concerns (judgment-free, accessible) +3. Maintain the empathetic, neurodivergent-friendly tone +4. Suggest structure improvements if needed +``` + +### Blog Post Titles & Descriptions + +``` +I'm optimizing blog post titles and descriptions for SEO and engagement. + +Current title: [title] +Current description: [description] +Topic: [brief topic description] + +Please: +1. Suggest 3 alternative titles that are: + - SEO-friendly (include relevant keywords naturally) + - Compelling and click-worthy + - Clear about the content + - Under 60 characters +2. Suggest 3 meta descriptions (155 characters max) that: + - Include target keywords naturally + - Clearly communicate value + - Include a subtle call-to-action + - Match the brand voice +``` + +### Call-to-Action (CTA) Buttons + +``` +I need more compelling call-to-action button text. + +Current CTAs: +- "Book Now" +- "Learn More" +- "Get Started" + +Context: Tech coaching services, booking sessions, newsletter signup + +Please suggest: +1. More specific, action-oriented alternatives +2. Options that reduce friction and anxiety +3. Language that feels inviting, not pushy +4. Variations for different contexts (booking vs. learning vs. subscribing) +5. Maintain the empathetic, judgment-free tone +``` + +--- + +## 2. Layout & UX Improvement Prompts + +### Page Layout Analysis + +``` +Analyze this page layout for UX best practices and suggest improvements. + +Brand colors to maintain: +- Deep forest green: #2e3d2a +- Rich purple: #442b48 +- Vibrant green accent: #32d24d +- Soft cream: #f4f1de +- Light purple accent: #d8b9f7 + +Current page structure: +[paste HTML structure or describe layout] + +Please: +1. Analyze visual hierarchy and information flow +2. Suggest improvements for: + - Content organization and flow + - Visual balance and spacing + - Readability and scannability + - User attention guidance + - Mobile responsiveness considerations +3. Maintain the brand color palette +4. Suggest specific layout changes with rationale +5. Consider neurodivergent-friendly design principles +``` + +### Mobile Responsiveness + +``` +Review this page for mobile responsiveness and suggest improvements. + +Current layout: [describe or paste structure] +Screen sizes to optimize: Mobile (320px-768px), Tablet (768px-1024px) + +Please: +1. Identify potential mobile UX issues +2. Suggest improvements for: + - Touch target sizes (minimum 44x44px) + - Content stacking order on mobile + - Readability on small screens + - Navigation accessibility + - Form usability + - Image optimization +3. Provide specific recommendations with examples +4. Consider thumb-friendly navigation zones +``` + +### Visual Hierarchy + +``` +Analyze the visual hierarchy of this page and suggest improvements. + +Current page: [describe or paste HTML] +Brand colors: [list colors] + +Please: +1. Evaluate current visual hierarchy +2. Suggest improvements for: + - Heading sizes and weights + - Color usage for emphasis + - Spacing and whitespace + - Content grouping + - Call-to-action visibility +3. Use the brand color palette effectively +4. Ensure important information stands out +5. Maintain accessibility (contrast ratios, etc.) +``` + +### Navigation & Information Architecture + +``` +Review my site navigation and information architecture. + +Current navigation structure: +[paste navigation menu structure] +Key pages: [list main pages] + +Please: +1. Analyze navigation clarity and user flow +2. Suggest improvements for: + - Menu organization + - Label clarity + - User journey optimization + - Mobile navigation + - Breadcrumb structure (if applicable) +3. Consider neurodivergent-friendly navigation (clear, predictable, not overwhelming) +4. Suggest alternative navigation patterns if beneficial +``` + +--- + +## 3. SEO Optimization Prompts + +### Meta Descriptions + +``` +Generate SEO-optimized meta descriptions for these pages. + +Brand voice: Professional, empathetic, accessible +Target keywords: [list relevant keywords per page] + +Pages: +1. Home page - [brief description] +2. Services page - [brief description] +3. About page - [brief description] +4. Blog page - [brief description] +[add more as needed] + +Please: +1. Create meta descriptions (max 155 characters) that: + - Include target keywords naturally + - Clearly communicate page value + - Include a subtle call-to-action + - Match the brand voice + - Are unique for each page +2. Provide 2-3 variations per page +``` + +### Content Structure for SEO + +``` +Review this content for SEO best practices and suggest improvements. + +Current content: +[paste content] + +Target keywords: [list keywords] +Topic: [brief topic description] + +Please: +1. Analyze heading hierarchy (H1, H2, H3 structure) +2. Suggest keyword placement improvements +3. Identify internal linking opportunities +4. Evaluate content length and depth +5. Suggest content additions that would improve SEO +6. Ensure keyword usage feels natural, not forced +7. Maintain brand voice throughout +``` + +### Alt Text for Images + +``` +Generate accessible, SEO-friendly alt text for these images. + +Images: +1. [image description/context] - [purpose on page] +2. [image description/context] - [purpose on page] +[add more as needed] + +Please: +1. Create descriptive alt text that: + - Accurately describes the image + - Includes relevant keywords naturally + - Provides context for screen readers + - Is concise but informative + - Matches the brand voice +2. For decorative images, suggest empty alt text (alt="") +``` + +--- + +## 4. Accessibility Improvement Prompts + +### Content Accessibility + +``` +Review this content for accessibility and suggest improvements. + +Current content: +[paste content] + +Please: +1. Check for: + - Clear, simple language + - Proper heading structure + - Descriptive link text (not "click here") + - Alt text for images + - Color contrast considerations + - Reading level appropriateness +2. Suggest improvements for: + - Neurodivergent-friendly formatting + - Clear instructions and calls-to-action + - Reduced cognitive load + - Multiple ways to access information +3. Ensure content is accessible to screen readers +``` + +### Form Accessibility + +``` +Review this form for accessibility and usability. + +Form purpose: [booking/newsletter/contact/etc.] +Current form fields: [list fields] + +Please: +1. Analyze for: + - Clear labels and instructions + - Error message clarity + - Required field indicators + - Field grouping and logical order + - Keyboard navigation support +2. Suggest improvements for: + - Neurodivergent-friendly form design + - Reduced anxiety and friction + - Clear success/error feedback + - Accessible validation messages +3. Consider form length and complexity +``` + +--- + +## 5. Content Strategy Prompts + +### Blog Post Ideas + +``` +Generate blog post ideas for my tech coaching website. + +Brand voice: [same as above] +Target audience: Neurodivergent professionals, business owners +Topics: Tech coaching, digital systems, workflow optimization, accessibility + +Please suggest: +1. 10 blog post ideas that: + - Address common pain points + - Provide actionable value + - Align with brand voice + - Include SEO-friendly topics + - Appeal to neurodivergent audience +2. For each idea, provide: + - Compelling title + - Brief description + - Target keywords + - Potential internal linking opportunities +``` + +### Newsletter Content Ideas + +``` +Generate newsletter content ideas for my tech coaching audience. + +Brand voice: [same as above] +Newsletter focus: Strategic insights, practical tips, industry awareness + +Please suggest: +1. 5 newsletter content ideas that: + - Provide value without being overwhelming + - Are scannable and digestible + - Include actionable takeaways + - Maintain professional but approachable tone +2. For each idea, suggest: + - Subject line options + - Content structure + - Call-to-action + - Potential blog post tie-ins +``` + +--- + +## 6. A/B Testing Ideas + +### CTA Variations + +``` +Generate A/B testing variations for call-to-action buttons. + +Current CTA: [current text] +Context: [booking/service/newsletter/etc.] + +Please suggest: +1. 5-7 alternative CTA texts that: + - Test different psychological triggers + - Vary in specificity + - Test different tones (direct vs. friendly) + - Reduce friction/anxiety +2. Explain the hypothesis behind each variation +3. Suggest which metrics to track +``` + +### Headline Variations + +``` +Generate A/B testing headline variations. + +Current headline: [headline] +Page context: [home/services/about/etc.] + +Please suggest: +1. 5-7 headline variations that test: + - Different value propositions + - Emotional vs. logical appeals + - Question vs. statement format + - Length variations + - Keyword placement +2. Explain the hypothesis for each +3. Suggest testing methodology +``` + +--- + +## How to Use These Prompts + +1. **Copy the prompt** that matches your need +2. **Fill in the bracketed sections** with your actual content +3. **Paste into your AI tool** (ChatGPT, Claude, etc.) +4. **Review and refine** the AI suggestions +5. **Test and iterate** based on results + +## Tips for Best Results + +- **Be specific:** Include context about your audience, goals, and constraints +- **Provide examples:** Show the AI what you like/don't like from your current site +- **Iterate:** Use follow-up prompts to refine suggestions +- **Maintain brand voice:** Always remind the AI of your brand guidelines +- **Test variations:** Generate multiple options and compare +- **Consider accessibility:** Always include accessibility in your prompts + +## Brand Voice Reminder Template + +When using any prompt, you can add this reminder: + +``` +Important: Maintain this brand voice throughout: +- Professional yet approachable +- Empathetic and judgment-free +- Neurodivergent-friendly +- Clear and accessible +- Authentic and personal +- Tech-savvy but not condescending +``` + +--- + +**Note:** Always review and refine AI-generated content. Use AI as a starting point, not the final product. Your unique voice and expertise are what make your site authentic. + +--- + +## 7. Site Structure Reference + +### Current Pages & Routes + +**Main Pages:** +- `/` - Home (Rest Period: Pythia Oracles theme) +- `/about` - About (includes Active & Rest Periods) +- `/services` - Services (Rest Period mode) +- `/blog` - Blog listing +- `/blog/[slug]` - Individual blog posts (27 posts) +- `/resources` - Free resources hub +- `/links` - Links page +- `/support` - Support page + +**Resource Pages:** +- `/accessibility` - Digital Accessibility Legal Guide +- `/ai-mythbusting` - AI Myth-Busting Toolkit +- `/async` - Async service page +- `/back-to-basics` - Back to Basics guide +- `/digital-spring-cleaning` - Digital Spring Cleaning +- `/mindful-automation` - Mindful Automation +- `/neuroinclusive-design` - Neuroinclusive Design +- `/passwords` - Password Security Guide +- `/privacy-pleasure` - Privacy Pleasure guide +- `/sourdough` - Sourdough Corner +- `/tech-boundaries` - Tech Boundaries +- `/vibe-coding-cheatsheet` - Vibe Coding Cheatsheet + +**Legal:** +- `/privacy-policy` - Privacy Policy +- `/terms` - Terms of Service + +**Blog Posts (27 total):** +All accessible at `/blog/[slug]`. See Django Migration Plan for complete list. + +### Rest Period Considerations + +When using AI prompts during rest period: +- Reference purple color scheme (not green) +- Mention rest mode and March 2026 return date +- Emphasize newsletter signup for notifications +- Honor the Pythia Oracles of Delphi theme +- Acknowledge chronic illness/pain accommodation +- Value intentional slowness for creativity diff --git a/DJANGO_MIGRATION_PLAN.md b/DJANGO_MIGRATION_PLAN.md new file mode 100644 index 0000000..9b390c8 --- /dev/null +++ b/DJANGO_MIGRATION_PLAN.md @@ -0,0 +1,1089 @@ +# Django Migration Plan: Next.js to Django + +## Executive Summary + +This document outlines a comprehensive plan to migrate the Pythoness Programmer website from Next.js to Django. The migration addresses security concerns with Next.js while maintaining all current functionality and preparing for future Beehiiv integrations. + +**Current State:** Next.js 14.1.0 with React, TypeScript, Tailwind CSS, MDX content +**Target State:** Django 5.x with Django Templates or HTMX/Alpine.js for interactivity +**Deployment Target:** Heroku + +--- + +## 1. Current Site Analysis + +### 1.1 Content Structure +- **27 MDX blog posts** in `src/content/blog/posts/` +- **Static pages:** About, Services, Resources, Privacy Policy, Terms, etc. +- **Interactive pages:** Vibe Coding Cheatsheet, Sourdough Corner +- **Blog features:** Search, tag filtering, RSS feed generation +- **Resources page:** Searchable resource library +- **Rest Period Implementation:** Homepage, Services, and About pages reflect rest mode (Nov 2025 - Mar 2026) + +### 1.2 Key Integrations +- **Beehiiv:** Newsletter embed (`embeds.beehiiv.com`) +- **Cal.com:** Booking links (currently inactive during rest period, resume March 2026) +- **Hotjar:** Analytics tracking +- **Media hosting:** Beehiiv CDN for images +- **Substack:** AI Generation Experiments Substack (`pythoness.substack.com`) + +### 1.3 Technical Features +- MDX content processing with frontmatter +- RSS feed generation (`scripts/generate-rss.js`) +- Tailwind CSS styling with custom brand colors +- **Active/Rest Period Color Schemes:** Green (active season) and Purple (rest period) +- TypeScript type safety +- Component-based architecture +- Server-side rendering (Next.js RSC) +- Rest period implementation with Pythia Oracles of Delphi theme + +### 1.4 Complete Routes/Pages Inventory + +**Main Pages:** +- `/` - Home (Rest Period page with Pythia Oracles theme) +- `/about` - About page (includes Active & Rest Periods section) +- `/services` - Services page (Rest Period mode) +- `/blog` - Blog listing page +- `/blog/[slug]` - Individual blog post pages +- `/resources` - Free resources hub with search +- `/links` - Links page (social media, booking, resources) +- `/support` - Support the Pythoness page + +**Resource Pages:** +- `/accessibility` - Digital Accessibility Legal Guide +- `/ai-mythbusting` - AI Myth-Busting Critical Thinking Toolkit +- `/async` - Async Project & Web Presence Reading service page +- `/back-to-basics` - Back to Basics: Digital Organization & AI-Ready Workflows +- `/digital-spring-cleaning` - Digital Spring Cleaning resources +- `/mindful-automation` - Mindful Automation: Systems That Work For You +- `/neuroinclusive-design` - Neuroinclusive Design: Building Accessible Tech +- `/passwords` - Password and Multi-Factor Authentication User Guide +- `/privacy-pleasure` - Privacy Pleasure: Your 4-Week Journey to Digital Independence +- `/sourdough` - Sourdough Corner (baking resources) +- `/tech-boundaries` - Tech Boundaries: Building Brain-Friendly Digital Systems +- `/vibe-coding-cheatsheet` - Vibe Coding Cheatsheet (developer resource) + +**Legal Pages:** +- `/privacy-policy` - Privacy Policy +- `/terms` - Terms of Service + +**Redirects:** +- `/booknow` - Redirects to Cal.com (currently inactive during rest period) + +**Blog Posts (27 total):** +- `/blog/accommodating-yourself-is-cute` +- `/blog/ai-mythbusting-critical-thinking-toolkit` +- `/blog/back-to-basics-ai-ready-workflows` +- `/blog/digital-accessibility-legal-guide-resource` +- `/blog/digital-spring-cleaning-a-month-of-grit-and-growth` +- `/blog/digital-spring-cleaning-deepening-our-grit-journey` +- `/blog/digital-spring-cleaning-grit-framework-toolkit` +- `/blog/digital-sustainability-that-wont-burn-you-out` +- `/blog/error-proofing-your-automation` +- `/blog/how-to-detect-ai-art` +- `/blog/lunar-new-year-2025` +- `/blog/mindful-automation-systems` +- `/blog/mindful-automation-you-framework-system` +- `/blog/modern-remote-work-communication-etiquette-2026` +- `/blog/monthly-grit-framework-for-your-digital-spring-cleaning` +- `/blog/monthly-grit-reflection-worksheet` +- `/blog/neuroinclusive-design-building-accessible-tech` +- `/blog/on-elon-musk-and-dates` +- `/blog/password-security-complete-guide` +- `/blog/privacy-pleasure-digital-independence` +- `/blog/sawdust-and-sacred-stones` +- `/blog/sourdough-corner-baking-resources` +- `/blog/tech-boundaries-brain-friendly-systems` +- `/blog/tech-is-just-a-tool` +- `/blog/the-you-framework` +- `/blog/todoist-scripts` +- `/blog/vibe-coding-cheatsheet-developer-resource` + +**Note:** During rest period (Nov 2025 - Mar 2026), services pages show rest mode messaging. All other pages remain accessible. + +### 1.5 Rest Period Implementation + +**Current Status:** Rest Mode (November 2025 - March 2026) + +**Rest Period Features:** +- Homepage shows rest mode with Pythia Oracles of Delphi theme +- Services page shows rest period messaging instead of booking links +- About page includes Active & Rest Periods section explaining the tradition +- Purple color scheme throughout (replaces green during rest period) +- Newsletter signup emphasized for return notifications +- All booking links hidden/disabled during rest period + +**Philosophy:** +- Following the tradition of the Pythia Oracles of Delphi +- Accommodates chronic illnesses and chronic pain +- Nurtures creativity through intentional slowness +- Active season: March - November (green theme) +- Rest period: November - March (purple theme) + +**Implementation Notes for Django:** +- Create system to toggle between active/rest color schemes +- Implement date-based or manual switching +- Rest period pages should show appropriate messaging +- Maintain all content accessibility during rest period + +--- + +## 2. Migration Strategy + +### 2.1 Architecture Decision: Django Template System vs. Modern Frontend + +**Option A: Django Templates + HTMX/Alpine.js (Recommended)** +- ✅ Simpler deployment on Heroku +- ✅ Better SEO (server-rendered) +- ✅ Lower complexity +- ✅ Easier to maintain +- ✅ Django's built-in security features +- ✅ Can use Tailwind CSS via CDN or build process +- ⚠️ Less interactive than React (but HTMX can handle most needs) + +**Option B: Django REST API + React Frontend** +- ✅ Maintains React component structure +- ✅ More complex deployment +- ❌ Loses some Django benefits +- ❌ More moving parts + +**Recommendation:** Option A (Django Templates + HTMX/Alpine.js) + +### 2.2 Content Management Strategy + +**For Blog Posts:** +- **✅ DECISION: Use Django models (Post, Tag, Author) with Django Admin** +- Migrate all MDX posts to Django database models +- Set up Django admin interface for easy content management +- Use rich text editor (django-ckeditor or similar) for post content +- Support Markdown in admin if preferred + +**For Static Pages:** +- Convert to Django templates +- Use Django's flatpages app or custom page models + +--- + +## 3. Detailed Migration Plan + +### Phase 1: Project Setup & Foundation (Week 1) + +#### 3.1.1 Django Project Initialization +- [ ] Create new Django project structure +- [ ] Set up virtual environment +- [ ] Install dependencies: + - Django 5.x + - django-extensions (for management commands) + - psycopg2-binary (for Postgres) + - django-ckeditor or django-tinymce (for rich text editing in admin) + - markdown (for Markdown support in posts) + - django-compressor or django-tailwind (for Tailwind CSS) + - gunicorn (for Heroku) + - whitenoise (for static files) + - python-decouple (for environment variables) + - django-environ (alternative to python-decouple) + +#### 3.1.2 Project Structure +``` +pythoness-django/ +├── manage.py +├── requirements.txt +├── Procfile (for Heroku) +├── runtime.txt (Python version) +├── pythoness/ +│ ├── settings/ +│ │ ├── __init__.py +│ │ ├── base.py +│ │ ├── development.py +│ │ └── production.py +│ ├── urls.py +│ ├── wsgi.py +│ └── asgi.py +├── apps/ +│ ├── blog/ +│ │ ├── models.py (optional, for future) +│ │ ├── views.py +│ │ ├── urls.py +│ │ ├── templates/ +│ │ └── management/commands/ (for RSS generation) +│ ├── pages/ +│ │ ├── views.py +│ │ ├── urls.py +│ │ └── templates/ +│ ├── resources/ +│ │ ├── views.py +│ │ ├── urls.py +│ │ └── templates/ +│ └── core/ +│ ├── templatetags/ (custom template tags) +│ └── context_processors.py +├── content/ +│ ├── blog/ +│ │ └── posts/ (MDX files) +│ └── static_pages/ (if needed) +├── static/ +│ ├── css/ +│ ├── js/ +│ └── images/ +├── templates/ +│ ├── base.html +│ ├── components/ (reusable components) +│ └── pages/ +└── media/ (user uploads) +``` + +#### 3.1.3 Database Setup (Postgres) +- [ ] **Local Development:** + - Install Postgres locally (if not already installed) + - Create database: `createdb pythoness_db` + - Create user: `createuser pythoness_user` (or use existing user) + - Grant permissions: `GRANT ALL PRIVILEGES ON DATABASE pythoness_db TO pythoness_user;` + - Update Django settings with local database config +- [ ] **Heroku Postgres:** + - Add Heroku Postgres addon: `heroku addons:create heroku-postgresql:mini` (or preferred tier) + - Heroku automatically sets `DATABASE_URL` environment variable + - Django will use `dj-database-url` to parse the connection string +- [ ] **Database Configuration:** + - Use `dj-database-url` package for easy database URL parsing + - Configure settings to use Postgres in production, SQLite in development (optional) + +#### 3.1.4 Heroku Configuration +- [ ] Create `Procfile`: `web: gunicorn pythoness.wsgi --log-file -` +- [ ] Create `runtime.txt` with Python version +- [ ] Set up `requirements.txt` +- [ ] Configure `ALLOWED_HOSTS` for Heroku domain +- [ ] Set up environment variables in Heroku config +- [ ] Configure static files with WhiteNoise + +### Phase 2: Core Infrastructure (Week 1-2) + +#### 3.2.1 Base Template & Layout +- [ ] Create `base.html` with: + - Header component (navigation) + - Footer component + - Meta tags and SEO + - Tailwind CSS integration + - Hotjar script + - CookieYes integration +- [ ] Port Header component from React to Django template +- [ ] Port Footer component from React to Django template +- [ ] Set up custom template tags for reusable components + +#### 3.2.2 Styling Migration +- [ ] Set up Tailwind CSS in Django (django-tailwind or CDN) +- [ ] Port custom brand colors to Tailwind config: + - **Active Season Colors (March - November):** + - `--brand-forest: #2e3d2a` (brand-green-dark) - Main background + - `--brand-green: #32d24d` (brand-green-accent) - Primary accent + - `--brand-hyperlink-green: #156624` (brand-green-hyperlink) - Links + - **Rest Period Colors (November - March):** + - `--brand-purple: #442b48` (brand-purple-dark) - Main background (replaces green) + - `--brand-light-purple: #d8b9f7` (brand-purple-light) - Primary accent (replaces green accent) + - **Shared Colors:** + - `--brand-cream: #f4f1de` (brand-cream) - Text on dark backgrounds + - `--brand-blue: #00a6fb` (brand-blue) + - `--brand-fuchsia: #ff39bc` (brand-fuchsia) +- [ ] Create CSS file with custom properties (brand colors) +- [ ] **Implement Active/Rest Period Color Switching:** + - Create system to toggle between green (active) and purple (rest) color schemes + - Default to rest period colors initially (until March 2026) + - Consider date-based automatic switching or manual toggle +- [ ] **Note:** Brand colors are fixed, but layout/styling can be improved +- [ ] Test responsive design + +#### 3.2.3 Static Files & Media +- [ ] Copy all static assets from `public/` to `static/` +- [ ] Set up WhiteNoise for static file serving +- [ ] Configure media file handling +- [ ] Test image loading + +### Phase 3: Content Migration (Week 2-3) + +#### 3.3.1 Blog System with Django Models +- [ ] Create `blog` app +- [ ] Create Django models: + - `Post` model (title, slug, author, content, description, published_date, created_at, updated_at, image, is_published) + - `Tag` model (name, slug) + - `Author` model (name, bio, email) - or use Django's User model + - Many-to-many relationship: Post ↔ Tag +- [ ] Set up Django Admin: + - Register Post, Tag, Author models + - Customize admin interface (list display, filters, search) + - Add rich text editor for post content + - Add image upload handling + - Add slug auto-generation from title +- [ ] Create management command to import MDX posts: + - `python manage.py import_mdx_posts` - Reads all MDX files and creates Post objects + - Parses frontmatter and converts MDX content to HTML + - Creates Tag objects as needed + - Handles existing posts (update vs. create) +- [ ] Create blog views: + - `blog_list` - List all posts with search/filter + - `blog_detail` - Individual post view +- [ ] Create blog templates: + - `blog/list.html` - Blog index with search + - `blog/detail.html` - Individual post + - `blog/components/post_card.html` + - `blog/components/post_metadata.html` + - `blog/components/post_navigation.html` +- [ ] Port blog search functionality (title, description, tags) - Use Django's Q objects +- [ ] Port tag filtering - Use Django queryset filtering +- [ ] Create RSS feed view (`/feed.xml`) - Use Django's syndication framework +- [ ] Run migrations: `python manage.py makemigrations` and `python manage.py migrate` + +#### 3.3.2 Static Pages Migration +- [ ] Create `pages` app +- [ ] Convert each static page: + - Home page (`/`) - **Rest Period implementation with Pythia Oracles theme** + - About (`/about`) - **Includes Active & Rest Periods section** + - Services (`/services`) - **Rest Period mode with newsletter signup** + - Resources (`/resources`) + - Links (`/links`) - **Rest Period colors, no booking links** + - Support (`/support`) + - Privacy Policy (`/privacy-policy`) + - Terms (`/terms`) + - All resource pages (accessibility, ai-mythbusting, async, back-to-basics, digital-spring-cleaning, mindful-automation, neuroinclusive-design, passwords, privacy-pleasure, sourdough, tech-boundaries, vibe-coding-cheatsheet) +- [ ] Port React components to Django templates: + - RestPeriodHome → template component (rest period homepage) + - HeroCard → template component (for active season) + - ServiceCard → template component + - AboutCard → template component + - NewsletterCard → template component + - PainPointsCard → template component + - ForeverTopicsCard → template component +- [ ] **Implement Rest Period Logic:** + - Create template tags or context processors for rest period detection + - Conditionally show rest period vs. active season content + - Handle color scheme switching + +#### 3.3.3 Interactive Pages +- [ ] **Vibe Coding Cheatsheet:** + - Convert React components to Django templates + - Port interactive features (copy-to-clipboard) to vanilla JS or Alpine.js + - Port data structures from TypeScript to Python +- [ ] **Sourdough Corner:** + - Convert React components to Django templates + - Port recipe data structures + - Maintain interactive features with HTMX/Alpine.js + +### Phase 4: Features & Functionality (Week 3-4) + +#### 4.1 Search Functionality +- [ ] Blog search (title, description, tags) +- [ ] Resources search (title, description, features) +- [ ] Implement search views and templates + +#### 4.2 Resources Page +- [ ] Port resources data from TypeScript to Python +- [ ] Create resources view and template +- [ ] Port search functionality + +#### 4.3 Integrations +- [ ] **Beehiiv:** Keep iframe embed (no changes needed) +- [ ] **Cal.com:** + - Booking links currently inactive during rest period + - Implement logic to show/hide booking links based on active/rest period + - Verify all booking links work when active season resumes (March 2026) +- [ ] **Substack:** Update link from `/podcast` to main Substack (`pythoness.substack.com`) - "AI Generation Experiments Substack" +- [ ] **Hotjar:** Port Hotjar component to Django template +- [ ] **CookieYes:** Port CookieYes component to Django template + +#### 4.4 RSS Feed +- [ ] Create Django view for RSS feed +- [ ] Port RSS generation logic +- [ ] Test feed validation + +### Phase 5: Content & Layout Improvements (Week 4) + +#### 5.1 AI-Assisted Content Review +- [ ] **Site Copy Review:** + - Use AI prompts to analyze current copy for clarity, tone, and effectiveness + - Generate improved versions of key sections (hero, services, about) + - Review and refine AI suggestions + - Update templates with improved copy +- [ ] **Layout Optimization:** + - Use AI to suggest layout improvements while maintaining brand colors + - Analyze user flow and suggest UX improvements + - Generate alternative layouts for key pages + - Test and implement approved improvements +- [ ] **SEO Content:** + - Use AI to optimize meta descriptions + - Generate alt text suggestions for images + - Improve heading structure and content hierarchy + +#### 5.2 AI Prompt Templates +Create a document with reusable prompts for: +- Copy improvement: "Review this website copy for [clarity/tone/effectiveness]..." +- Layout suggestions: "Suggest layout improvements for [page] that maintain these brand colors..." +- SEO optimization: "Optimize this content for SEO while maintaining the voice..." +- Accessibility: "Review this content for accessibility and suggest improvements..." + +### Phase 6: Testing & Optimization (Week 4-5) + +#### 6.1 Testing +- [ ] Test all routes/pages +- [ ] Test blog functionality (list, detail, search, tags, admin) +- [ ] Test RSS feed +- [ ] Test responsive design +- [ ] Test integrations (Beehiiv, Cal.com, Hotjar) +- [ ] Cross-browser testing +- [ ] Performance testing +- [ ] Test Django admin interface + +#### 6.2 SEO +- [ ] Verify all meta tags +- [ ] Test Open Graph tags +- [ ] Verify sitemap (create if needed) +- [ ] Test structured data (if applicable) + +#### 6.3 Security +- [ ] Review Django security settings +- [ ] Set up CSRF protection +- [ ] Configure secure headers +- [ ] Review input validation +- [ ] Set up error handling +- [ ] Review admin security (strong passwords, 2FA if possible) + +### Phase 7: Deployment (Week 5) + +#### 6.1 Heroku Setup +- [ ] Create Heroku app +- [ ] Configure buildpacks (Python, Node.js if using Tailwind build) +- [ ] Set environment variables: + - `SECRET_KEY` + - `DEBUG=False` + - `ALLOWED_HOSTS` + - `HOTJAR_ID` (if needed) + - Database URL (if using Postgres) +- [ ] Set up Heroku Postgres (if needed for future features) +- [ ] Configure static files collection +- [ ] Test deployment + +#### 6.2 Domain & DNS +- [ ] Point domain to Heroku +- [ ] Configure SSL (Heroku handles this) +- [ ] Test domain redirects + +#### 6.3 Monitoring +- [ ] Set up error logging (Sentry or similar) +- [ ] Configure logging +- [ ] Set up uptime monitoring + +### Phase 8: Post-Migration (Week 5+) + +#### 7.1 Cleanup +- [ ] Archive Next.js codebase (keep for reference) +- [ ] Update documentation +- [ ] Update README + +#### 7.2 Future Enhancements +- [ ] Consider migrating MDX to Django models for admin interface +- [ ] Set up Django admin for content management +- [ ] Explore Beehiiv API integration (if available) +- [ ] Add caching (Redis/Memcached) for blog posts +- [ ] Consider CDN for static files + +--- + +## 4. Technical Decisions + +### 4.1 Blog Content Management + +**Approach:** Django Models with Admin Interface + +```python +# apps/blog/models.py +from django.db import models +from django.contrib.auth.models import User +from django.utils.text import slugify + +class Tag(models.Model): + name = models.CharField(max_length=50, unique=True) + slug = models.SlugField(unique=True) + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = slugify(self.name) + super().save(*args, **kwargs) + + def __str__(self): + return self.name + +class Post(models.Model): + title = models.CharField(max_length=200) + slug = models.SlugField(unique=True, max_length=200) + author = models.ForeignKey(User, on_delete=models.CASCADE) + content = models.TextField() # Rich text or Markdown + description = models.TextField(max_length=500) + tags = models.ManyToManyField(Tag, blank=True) + image = models.URLField(blank=True, null=True) # Or ImageField for uploads + published_date = models.DateTimeField(null=True, blank=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + is_published = models.BooleanField(default=False) + + class Meta: + ordering = ['-published_date', '-created_at'] + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = slugify(self.title) + super().save(*args, **kwargs) + + def __str__(self): + return self.title +``` + +**MDX Import Command:** +```python +# apps/blog/management/commands/import_mdx_posts.py +from django.core.management.base import BaseCommand +import frontmatter +import markdown +from pathlib import Path +from apps.blog.models import Post, Tag + +class Command(BaseCommand): + help = 'Import MDX blog posts into Django database' + + def handle(self, *args, **options): + # Read MDX files and create Post objects + # Parse frontmatter, create tags, etc. +``` + +### 4.2 Template Component System + +**Approach:** Django template includes + custom template tags + +```django +{# templates/components/service_card.html #} +
+

{{ title }}

+

{{ description }}

+ {{ cta_text }} +
+ +{# Usage #} +{% include 'components/service_card.html' with title="..." description="..." %} +``` + +### 4.3 Search Implementation + +**Approach:** Django QuerySet filtering with Q objects (can upgrade to full-text search later) + +```python +# apps/blog/views.py +from django.db.models import Q +from django.views.generic import ListView +from .models import Post + +class BlogListView(ListView): + model = Post + template_name = 'blog/list.html' + context_object_name = 'posts' + paginate_by = 10 + + def get_queryset(self): + queryset = Post.objects.filter(is_published=True) + + # Search functionality + search_query = self.request.GET.get('q') + if search_query: + queryset = queryset.filter( + Q(title__icontains=search_query) | + Q(description__icontains=search_query) | + Q(tags__name__icontains=search_query) + ).distinct() + + # Tag filtering + tag_slug = self.request.GET.get('tag') + if tag_slug: + queryset = queryset.filter(tags__slug=tag_slug) + + return queryset +``` + +### 4.4 Interactive Features + +**Approach:** HTMX + Alpine.js for interactivity + +- Copy-to-clipboard: Alpine.js +- Search: HTMX for live search +- Tag filtering: HTMX for dynamic filtering +- Form submissions: Django forms + HTMX + +--- + +## 5. File-by-File Migration Checklist + +### 5.1 Components to Convert +- [ ] `Header.tsx` → `templates/components/header.html` (rest period: no Services/Book links) +- [ ] `Footer.tsx` → `templates/components/footer.html` (rest period: Services section with newsletter) +- [ ] `RestPeriodHome.tsx` → `templates/components/rest_period_home.html` (rest period homepage) +- [ ] `HeroCard.tsx` → `templates/components/hero_card.html` (for active season) +- [ ] `ServiceCard.tsx` → `templates/components/service_card.html` +- [ ] `AboutCard.tsx` → `templates/components/about_card.html` +- [ ] `NewsletterCard.tsx` → `templates/components/newsletter_card.html` +- [ ] `PainPointsCard.tsx` → `templates/components/pain_points_card.html` +- [ ] `ForeverTopicsCard.tsx` → `templates/components/forever_topics_card.html` +- [ ] `PostCard.tsx` → `templates/blog/components/post_card.html` +- [ ] `PostMetadata.tsx` → `templates/blog/components/post_metadata.html` +- [ ] `PostNavigation.tsx` → `templates/blog/components/post_navigation.html` +- [ ] `Tag.tsx` → `templates/blog/components/tag.html` +- [ ] `TagFilter.tsx` → `templates/blog/components/tag_filter.html` +- [ ] `TagList.tsx` → `templates/blog/components/tag_list.html` +- [ ] `ResourcesList.tsx` → `templates/resources/components/resources_list.html` +- [ ] `Signature.tsx` → `templates/components/signature.html` +- [ ] `Hotjar.tsx` → `templates/components/hotjar.html` +- [ ] `CookieYes.tsx` → `templates/components/cookie_yes.html` + +### 5.2 Pages to Convert +- [ ] `src/app/page.tsx` → `templates/pages/home.html` (Rest Period implementation) +- [ ] `src/app/about/page.tsx` → `templates/pages/about.html` (includes Active & Rest Periods) +- [ ] `src/app/services/page.tsx` → `templates/pages/services.html` (Rest Period mode) +- [ ] `src/app/blog/page.tsx` → `templates/blog/list.html` +- [ ] `src/app/blog/[slug]/page.tsx` → `templates/blog/detail.html` +- [ ] `src/app/resources/page.tsx` → `templates/resources/list.html` +- [ ] `src/app/links/page.tsx` → `templates/pages/links.html` (Rest Period colors) +- [ ] `src/app/support/page.tsx` → `templates/pages/support.html` +- [ ] `src/app/privacy-policy/page.tsx` → `templates/pages/privacy_policy.html` +- [ ] `src/app/terms/page.tsx` → `templates/pages/terms.html` +- [ ] `src/app/accessibility/page.tsx` → `templates/pages/accessibility.html` +- [ ] `src/app/ai-mythbusting/page.tsx` → `templates/pages/ai_mythbusting.html` +- [ ] `src/app/async/page.tsx` → `templates/pages/async.html` +- [ ] `src/app/back-to-basics/page.tsx` → `templates/pages/back_to_basics.html` +- [ ] `src/app/digital-spring-cleaning/page.tsx` → `templates/pages/digital_spring_cleaning.html` +- [ ] `src/app/mindful-automation/page.tsx` → `templates/pages/mindful_automation.html` +- [ ] `src/app/neuroinclusive-design/page.tsx` → `templates/pages/neuroinclusive_design.html` +- [ ] `src/app/passwords/page.tsx` → `templates/pages/passwords.html` +- [ ] `src/app/privacy-pleasure/page.tsx` → `templates/pages/privacy_pleasure.html` +- [ ] `src/app/sourdough/page.tsx` → `templates/pages/sourdough.html` +- [ ] `src/app/tech-boundaries/page.tsx` → `templates/pages/tech_boundaries.html` +- [ ] `src/app/vibe-coding-cheatsheet/page.tsx` → `templates/pages/vibe_coding_cheatsheet.html` + +### 5.3 Utilities to Port +- [ ] `src/lib/mdx.ts` → `apps/blog/utils.py` +- [ ] `src/lib/resources.ts` → `apps/resources/data.py` +- [ ] `src/lib/validation.ts` → `apps/core/validators.py` +- [ ] `src/lib/errorHandling.ts` → `apps/core/error_handling.py` +- [ ] `scripts/generate-rss.js` → `apps/blog/management/commands/generate_rss.py` + +--- + +## 6. Dependencies & Requirements + +### 6.1 Python Dependencies +```txt +Django>=5.0,<6.0 +gunicorn>=21.2.0 +whitenoise>=6.6.0 +python-frontmatter>=1.0.0 # For MDX import command +markdown>=3.5.0 +python-decouple>=3.8 +django-extensions>=3.2.0 +psycopg2-binary>=2.9.9 # For Postgres +dj-database-url>=2.1.0 # For parsing DATABASE_URL +django-ckeditor>=6.7.0 # Rich text editor for admin (or django-tinymce) +``` + +### 6.2 Optional Dependencies +```txt +django-tailwind>=3.8.0 # For Tailwind CSS integration +django-compressor>=4.4 # For CSS/JS compression +django-htmx>=1.18.0 # For HTMX integration +``` + +### 6.3 Node.js Dependencies (if using Tailwind build) +```json +{ + "dependencies": { + "tailwindcss": "^3.4.1", + "autoprefixer": "^10.4.21", + "postcss": "^8.5.4" + } +} +``` + +--- + +## 7. Heroku Deployment Configuration + +### 7.1 Procfile +``` +web: gunicorn pythoness.wsgi --log-file - +release: python manage.py collectstatic --noinput +``` + +### 7.2 runtime.txt +``` +python-3.12.0 +``` + +### 7.3 Environment Variables (Heroku Config Vars) +``` +SECRET_KEY= +DEBUG=False +ALLOWED_HOSTS=pythonessprogrammer.com,www.pythonessprogrammer.com,your-app.herokuapp.com +HOTJAR_ID= +DATABASE_URL= +``` + +**Note:** Heroku Postgres automatically sets `DATABASE_URL`. Use `dj-database-url` to parse it in Django settings. + +### 7.4 Buildpacks +1. `heroku/python` (Python buildpack) +2. `heroku/nodejs` (if using Tailwind build process) + +--- + +## 8. Risk Assessment & Mitigation + +### 8.1 Risks +1. **SEO Impact:** URL changes could affect rankings + - **Mitigation:** Set up 301 redirects for all old URLs +2. **Functionality Loss:** Some React features may not translate directly + - **Mitigation:** Thorough testing, consider HTMX/Alpine.js alternatives +3. **Performance:** Django may have different performance characteristics + - **Mitigation:** Implement caching, optimize queries +4. **Beehiiv Integration:** Need to verify embed still works + - **Mitigation:** Test early, Beehiiv embeds are iframe-based (should work) + +### 8.2 Rollback Plan +- Keep Next.js codebase until migration is verified +- Can quickly switch back if critical issues arise +- Heroku allows easy rollback of deployments + +--- + +## 9. Timeline Estimate + +- **Week 1:** Setup, Postgres configuration, base templates, static pages +- **Week 2:** Blog models, Django admin, MDX import, content migration +- **Week 3:** Interactive pages, features, integrations +- **Week 4:** AI-assisted content/layout improvements, testing, optimization +- **Week 5:** Deployment prep, deployment, monitoring, cleanup + +**Total Estimated Time:** 5 weeks (includes time for content/layout improvements) + +--- + +## 10. Success Criteria + +- [ ] All pages render correctly +- [ ] Blog functionality works (list, detail, search, tags) +- [ ] RSS feed generates correctly +- [ ] All integrations work (Beehiiv, Cal.com, Hotjar) +- [ ] Site is responsive on all devices +- [ ] Performance is acceptable (< 2s page load) +- [ ] SEO meta tags are correct +- [ ] No broken links +- [ ] Deployed successfully on Heroku +- [ ] Domain points to new site + +--- + +## 11. Next Steps + +1. **Review this plan** - Discuss any concerns or changes +2. **Create new branch** - `django-migration` or similar +3. **Set up Django project** - Start with Phase 1 +4. **Iterate** - Work through phases systematically +5. **Test thoroughly** - Before final deployment +6. **Deploy** - When ready, deploy to Heroku +7. **Monitor** - Watch for issues post-deployment + +--- + +## 12. Postgres Setup Guide + +### 12.1 Local Development Setup + +**macOS (using Homebrew):** +```bash +# Install Postgres +brew install postgresql@15 + +# Start Postgres service +brew services start postgresql@15 + +# Create database +createdb pythoness_db + +# Create user (optional - can use your system user) +createuser pythoness_user -P # Will prompt for password + +# Grant permissions +psql pythoness_db +GRANT ALL PRIVILEGES ON DATABASE pythoness_db TO pythoness_user; +\q +``` + +**Linux (Ubuntu/Debian):** +```bash +# Install Postgres +sudo apt-get update +sudo apt-get install postgresql postgresql-contrib + +# Switch to postgres user +sudo -u postgres psql + +# Create database and user +CREATE DATABASE pythoness_db; +CREATE USER pythoness_user WITH PASSWORD 'your_password'; +GRANT ALL PRIVILEGES ON DATABASE pythoness_db TO pythoness_user; +\q +``` + +**Windows:** +- Download and install from [postgresql.org](https://www.postgresql.org/download/windows/) +- Use pgAdmin or command line to create database and user + +### 12.2 Django Settings Configuration + +```python +# settings/base.py +import dj_database_url +from decouple import config + +# Database configuration +DATABASES = { + 'default': dj_database_url.config( + default=config('DATABASE_URL', default='postgresql://pythoness_user:password@localhost:5432/pythoness_db'), + conn_max_age=600, + conn_health_checks=True, + ) +} +``` + +### 12.3 Heroku Postgres Setup + +```bash +# Add Postgres addon (free tier for testing, upgrade for production) +heroku addons:create heroku-postgresql:mini + +# Check database URL (automatically set) +heroku config:get DATABASE_URL + +# Run migrations on Heroku +heroku run python manage.py migrate + +# Create superuser on Heroku +heroku run python manage.py createsuperuser +``` + +### 12.4 Common Postgres Commands + +```bash +# Connect to database +psql pythoness_db + +# List all databases +\l + +# List all tables +\dt + +# Describe a table +\d table_name + +# Exit psql +\q +``` + +--- + +## 13. AI Prompt Templates for Content Improvement + +### 13.1 Copy Improvement Prompts + +**Hero Section:** +``` +Review this hero section copy for clarity, engagement, and conversion effectiveness. +Maintain the brand voice (professional, empathetic, neurodivergent-friendly, judgment-free). +Current copy: [paste copy] +Suggest 3 improved versions that are more compelling while staying true to the brand. +``` + +**Service Descriptions:** +``` +Analyze these service descriptions for clarity and persuasiveness. +Suggest improvements that: +- Clearly communicate value +- Address pain points +- Use accessible language +- Maintain professional tone +Current descriptions: [paste descriptions] +``` + +**About Section:** +``` +Review this about section for authenticity and connection. +Suggest improvements that: +- Build trust +- Show personality +- Demonstrate expertise +- Remain approachable +Current copy: [paste copy] +``` + +### 13.2 Layout Optimization Prompts + +**Page Layout:** +``` +Analyze this page layout for UX best practices. +Suggest improvements that: +- Improve visual hierarchy +- Enhance readability +- Guide user attention +- Maintain these brand colors: [list colors] +Current layout structure: [describe or paste HTML structure] +``` + +**Mobile Responsiveness:** +``` +Review this page for mobile responsiveness and suggest improvements. +Focus on: +- Touch target sizes +- Content stacking order +- Readability on small screens +- Navigation accessibility +``` + +### 13.3 SEO Optimization Prompts + +**Meta Descriptions:** +``` +Generate SEO-optimized meta descriptions for these pages: +- Include target keywords naturally +- Stay within 155 characters +- Include a clear call-to-action +- Maintain brand voice +Pages: [list pages] +``` + +**Content Structure:** +``` +Review this content for SEO best practices: +- Heading hierarchy (H1, H2, H3) +- Keyword placement +- Internal linking opportunities +- Content length and depth +Current content: [paste content] +``` + +--- + +## 14. Questions to Discuss + +1. **Rich Text Editor:** Do you prefer CKEditor, TinyMCE, or Markdown for blog posts? +2. **Image Handling:** Upload to Django/media or continue using external URLs (Beehiiv CDN)? +3. **Caching:** Should we implement caching from the start? +4. **Beehiiv API:** Are there specific Beehiiv features you want to integrate? +5. **Content Review:** Which pages/sections should we prioritize for AI-assisted improvements? + +--- + +## Appendix: Useful Resources + +- [Django Documentation](https://docs.djangoproject.com/) +- [Django Deployment Checklist](https://docs.djangoproject.com/en/stable/howto/deployment/checklist/) +- [Heroku Django Guide](https://devcenter.heroku.com/articles/django-app-configuration) +- [HTMX Documentation](https://htmx.org/) +- [Alpine.js Documentation](https://alpinejs.dev/) +- [python-frontmatter](https://github.com/eyeseast/python-frontmatter) + +--- + +## 15. Complete Site Structure Reference + +### 15.1 All Pages & Routes (Complete List) + +**Main Navigation Pages:** +- `/` - Home (Rest Period: Pythia Oracles theme, newsletter signup) +- `/about` - About Amanda (includes Active & Rest Periods section) +- `/services` - Services (Rest Period: shows rest mode, newsletter signup) +- `/blog` - Blog listing (search, tag filtering, RSS feed) +- `/blog/[slug]` - Individual blog posts (27 posts total) +- `/resources` - Free resources hub (searchable) +- `/links` - Links page (social media, resources, support) +- `/support` - Support the Pythoness page + +**Resource Pages:** +- `/accessibility` - Digital Accessibility Legal Guide +- `/ai-mythbusting` - AI Myth-Busting Critical Thinking Toolkit +- `/async` - Async Project & Web Presence Reading service page +- `/back-to-basics` - Back to Basics: Digital Organization & AI-Ready Workflows +- `/digital-spring-cleaning` - Digital Spring Cleaning resources +- `/mindful-automation` - Mindful Automation: Systems That Work For You +- `/neuroinclusive-design` - Neuroinclusive Design: Building Accessible Tech +- `/passwords` - Password and Multi-Factor Authentication User Guide +- `/privacy-pleasure` - Privacy Pleasure: Your 4-Week Journey to Digital Independence +- `/sourdough` - Sourdough Corner (baking resources with recipes) +- `/tech-boundaries` - Tech Boundaries: Building Brain-Friendly Digital Systems +- `/vibe-coding-cheatsheet` - Vibe Coding Cheatsheet (developer resource) + +**Legal Pages:** +- `/privacy-policy` - Privacy Policy +- `/terms` - Terms of Service (also `/terms-of-service`) + +**Redirects:** +- `/booknow` - Redirects to Cal.com (currently inactive during rest period) + +### 15.2 Blog Posts (27 Total) + +All blog posts are located at `/blog/[slug]`: + +1. `accommodating-yourself-is-cute` +2. `ai-mythbusting-critical-thinking-toolkit` +3. `back-to-basics-ai-ready-workflows` +4. `digital-accessibility-legal-guide-resource` +5. `digital-spring-cleaning-a-month-of-grit-and-growth` +6. `digital-spring-cleaning-deepening-our-grit-journey` +7. `digital-spring-cleaning-grit-framework-toolkit` +8. `digital-sustainability-that-wont-burn-you-out` +9. `error-proofing-your-automation` +10. `how-to-detect-ai-art` +11. `lunar-new-year-2025` +12. `mindful-automation-systems` +13. `mindful-automation-you-framework-system` +14. `modern-remote-work-communication-etiquette-2026` +15. `monthly-grit-framework-for-your-digital-spring-cleaning` +16. `monthly-grit-reflection-worksheet` +17. `neuroinclusive-design-building-accessible-tech` +18. `on-elon-musk-and-dates` +19. `password-security-complete-guide` +20. `privacy-pleasure-digital-independence` +21. `sawdust-and-sacred-stones` +22. `sourdough-corner-baking-resources` +23. `tech-boundaries-brain-friendly-systems` +24. `tech-is-just-a-tool` +25. `the-you-framework` +26. `todoist-scripts` +27. `vibe-coding-cheatsheet-developer-resource` + +### 15.3 Rest Period Implementation Notes + +**Pages with Rest Period Modifications:** +- `/` - Rest Period homepage with Pythia Oracles theme +- `/about` - Added Active & Rest Periods section +- `/services` - Rest mode messaging, no booking links +- `/links` - Purple theme, no booking links, rest mode notices +- Header - No Services or Book a Call links +- Footer - Services section replaced with rest mode notice and newsletter + +**Color Scheme:** +- Rest Period: Purple dark (`#442b48`) as main, purple light (`#d8b9f7`) as accent +- Active Season: Green dark (`#2e3d2a`) as main, green accent (`#32d24d`) as accent + +**Content Changes:** +- All booking links hidden/disabled +- Newsletter signup emphasized +- Return date: March 2026 +- Active season: March - November 2026 + +--- + +**Document Version:** 2.0 +**Created:** 2025-01-XX +**Last Updated:** 2025-01-XX +**Updated for:** Rest Period implementation, complete page inventory diff --git a/POSTGRES_SETUP_GUIDE.md b/POSTGRES_SETUP_GUIDE.md new file mode 100644 index 0000000..5f06941 --- /dev/null +++ b/POSTGRES_SETUP_GUIDE.md @@ -0,0 +1,402 @@ +# Postgres Setup Guide for Django Migration + +This guide provides step-by-step instructions for setting up Postgres for the Django migration, both locally and on Heroku. + +## Table of Contents +1. [Local Development Setup](#local-development-setup) +2. [Django Configuration](#django-configuration) +3. [Heroku Postgres Setup](#heroku-postgres-setup) +4. [Common Commands](#common-commands) +5. [Troubleshooting](#troubleshooting) + +--- + +## Local Development Setup + +### macOS (using Homebrew) + +```bash +# 1. Install Postgres +brew install postgresql@15 + +# 2. Start Postgres service +brew services start postgresql@15 + +# 3. Verify installation +psql --version + +# 4. Create database +createdb pythoness_db + +# 5. Create user (optional - you can use your system user) +createuser pythoness_user -P +# When prompted, enter a password + +# 6. Grant permissions +psql pythoness_db +``` + +In the psql prompt: +```sql +GRANT ALL PRIVILEGES ON DATABASE pythoness_db TO pythoness_user; +\q +``` + +### Alternative: Using Postgres.app (macOS) + +1. Download from [postgresapp.com](https://postgresapp.com/) +2. Install and launch the app +3. Click "Initialize" to create a new server +4. The app will create a default database with your username +5. Use the default connection settings in Django + +### Linux (Ubuntu/Debian) + +```bash +# 1. Update package list +sudo apt-get update + +# 2. Install Postgres +sudo apt-get install postgresql postgresql-contrib + +# 3. Start Postgres service +sudo systemctl start postgresql +sudo systemctl enable postgresql + +# 4. Switch to postgres user +sudo -u postgres psql +``` + +In the psql prompt: +```sql +-- Create database +CREATE DATABASE pythoness_db; + +-- Create user +CREATE USER pythoness_user WITH PASSWORD 'your_secure_password'; + +-- Grant privileges +GRANT ALL PRIVILEGES ON DATABASE pythoness_db TO pythoness_user; + +-- Exit +\q +``` + +### Windows + +1. **Download Postgres:** + - Visit [postgresql.org/download/windows](https://www.postgresql.org/download/windows/) + - Download the installer + - Run the installer and follow the setup wizard + - Remember the password you set for the `postgres` user + +2. **Using pgAdmin (GUI):** + - Open pgAdmin (installed with Postgres) + - Right-click "Databases" → "Create" → "Database" + - Name: `pythoness_db` + - Right-click "Login/Group Roles" → "Create" → "Login/Group Role" + - Name: `pythoness_user`, set password + - Go to "Privileges" tab and grant all permissions + +3. **Using Command Line (psql):** + ```sql + -- Connect as postgres user + psql -U postgres + + -- Create database + CREATE DATABASE pythoness_db; + + -- Create user + CREATE USER pythoness_user WITH PASSWORD 'your_password'; + + -- Grant privileges + GRANT ALL PRIVILEGES ON DATABASE pythoness_db TO pythoness_user; + ``` + +--- + +## Django Configuration + +### 1. Install Required Packages + +Add to `requirements.txt`: +```txt +psycopg2-binary>=2.9.9 +dj-database-url>=2.1.0 +python-decouple>=3.8 +``` + +Install: +```bash +pip install psycopg2-binary dj-database-url python-decouple +``` + +### 2. Update Django Settings + +```python +# settings/base.py +import dj_database_url +from decouple import config +import os + +# Database configuration +# For local development, you can use a .env file +# For production, Heroku sets DATABASE_URL automatically + +DATABASES = { + 'default': dj_database_url.config( + default=config( + 'DATABASE_URL', + default=f"postgresql://pythoness_user:your_password@localhost:5432/pythoness_db" + ), + conn_max_age=600, + conn_health_checks=True, + ) +} +``` + +### 3. Create .env File (Local Development) + +Create a `.env` file in your project root (add to `.gitignore`): + +```env +# .env +DATABASE_URL=postgresql://pythoness_user:your_password@localhost:5432/pythoness_db +SECRET_KEY=your-secret-key-here +DEBUG=True +``` + +### 4. Run Migrations + +```bash +# Create migrations +python manage.py makemigrations + +# Apply migrations +python manage.py migrate + +# Create superuser (for Django admin) +python manage.py createsuperuser +``` + +--- + +## Heroku Postgres Setup + +### 1. Add Postgres Addon + +```bash +# Add Postgres (free tier for testing) +heroku addons:create heroku-postgresql:mini + +# For production, use a paid tier: +# heroku addons:create heroku-postgresql:standard-0 +``` + +### 2. Verify Database URL + +Heroku automatically sets the `DATABASE_URL` environment variable: + +```bash +# Check the DATABASE_URL +heroku config:get DATABASE_URL + +# View all config vars +heroku config +``` + +### 3. Run Migrations on Heroku + +```bash +# Run migrations +heroku run python manage.py migrate + +# Create superuser +heroku run python manage.py createsuperuser +``` + +### 4. Access Heroku Postgres Database + +```bash +# Connect to Heroku Postgres via psql +heroku pg:psql + +# Or get connection string for external tools +heroku pg:credentials:url +``` + +--- + +## Common Commands + +### Database Management + +```bash +# Connect to database +psql pythoness_db + +# Or with user +psql -U pythoness_user -d pythoness_db +``` + +### Inside psql + +```sql +-- List all databases +\l + +-- Connect to a database +\c pythoness_db + +-- List all tables +\dt + +-- Describe a table structure +\d table_name + +-- List all users +\du + +-- Show current database +SELECT current_database(); + +-- Exit psql +\q +``` + +### Django Management Commands + +```bash +# Create migrations +python manage.py makemigrations + +# Apply migrations +python manage.py migrate + +# Show migration status +python manage.py showmigrations + +# Rollback last migration +python manage.py migrate app_name previous_migration_number + +# Create superuser +python manage.py createsuperuser + +# Open Django shell with database access +python manage.py shell +``` + +### Heroku Commands + +```bash +# View database info +heroku pg:info + +# View database size +heroku pg:info --app your-app-name + +# Create database backup +heroku pg:backups:capture + +# Download backup +heroku pg:backups:download + +# Restore from backup +heroku pg:backups:restore BACKUP_URL DATABASE_URL + +# Reset database (⚠️ DESTRUCTIVE) +heroku pg:reset DATABASE_URL +``` + +--- + +## Troubleshooting + +### Connection Issues + +**Error: "could not connect to server"** +- Check if Postgres is running: `brew services list` (macOS) or `sudo systemctl status postgresql` (Linux) +- Verify connection string format: `postgresql://user:password@host:port/database` +- Check firewall settings + +**Error: "password authentication failed"** +- Verify username and password +- Check `pg_hba.conf` file for authentication settings +- Try resetting password: `ALTER USER pythoness_user WITH PASSWORD 'new_password';` + +**Error: "database does not exist"** +- Create the database: `createdb pythoness_db` +- Or create via psql: `CREATE DATABASE pythoness_db;` + +### Django Migration Issues + +**Error: "relation does not exist"** +- Run migrations: `python manage.py migrate` +- Check if app is in `INSTALLED_APPS` + +**Error: "no such table"** +- Run migrations: `python manage.py migrate` +- Check migration files exist in `app/migrations/` + +### Heroku Issues + +**Error: "DATABASE_URL not set"** +- Add Postgres addon: `heroku addons:create heroku-postgresql:mini` +- Verify: `heroku config:get DATABASE_URL` + +**Error: "Connection timeout"** +- Check Heroku app status: `heroku ps` +- Verify Postgres addon is active: `heroku addons` + +--- + +## Quick Reference: Connection Strings + +### Local Development +``` +postgresql://username:password@localhost:5432/database_name +``` + +### Heroku (automatic) +``` +postgres://[user]:[password]@[host]:[port]/[database] +``` +(Set automatically by Heroku Postgres addon) + +### Example .env File +```env +# Local Development +DATABASE_URL=postgresql://pythoness_user:mypassword@localhost:5432/pythoness_db + +# Production (Heroku sets this automatically) +# DATABASE_URL is set by Heroku Postgres addon +``` + +--- + +## Next Steps + +1. ✅ Postgres installed and running locally +2. ✅ Database and user created +3. ✅ Django settings configured +4. ✅ Migrations run successfully +5. ✅ Superuser created +6. ✅ Heroku Postgres addon added (when ready to deploy) + +--- + +## Resources + +- [Postgres Documentation](https://www.postgresql.org/docs/) +- [Django Database Documentation](https://docs.djangoproject.com/en/stable/topics/db/) +- [dj-database-url Documentation](https://github.com/jacobian/dj-database-url) +- [Heroku Postgres Documentation](https://devcenter.heroku.com/articles/heroku-postgresql) + +--- + +**Need Help?** If you run into issues, check: +1. Postgres service is running +2. Connection string format is correct +3. User has proper permissions +4. Database exists +5. Django settings are configured correctly diff --git a/REST_PERIOD_NOTES.md b/REST_PERIOD_NOTES.md new file mode 100644 index 0000000..f146ede --- /dev/null +++ b/REST_PERIOD_NOTES.md @@ -0,0 +1,85 @@ +# Rest Period Implementation Notes + +## Current Status: REST MODE (Nov 2025 - Mar 8, 2026) + +The site is currently in **Rest Mode** with the purple color scheme inspired by the Pythia Oracles of Delphi tradition. + +## Color Scheme Changes + +### Rest Period Colors (Current) +- **Main color:** `#442b48` (brand-purple-dark) - replaces `#2e3d2a` (brand-green-dark) +- **Accent color:** `#d8b9f7` (brand-purple-light) - replaces `#32d24d` (brand-green-accent) + +### Active Season Colors (March 8, 2026 onwards) +- **Main color:** `#2e3d2a` (brand-green-dark) +- **Accent color:** `#32d24d` (brand-green-accent) + +## Files Modified for Rest Period + +1. **`src/app/page.tsx`** - Now uses `RestPeriodHome` component +2. **`src/components/RestPeriodHome.tsx`** - New rest period homepage +3. **`src/components/Header.tsx`** - Updated to use purple colors +4. **`src/components/Footer.tsx`** - Updated to use purple colors +5. **`src/components/NewsletterCard.tsx`** - Updated heading color +6. **`src/app/globals.css`** - Added rest period color variables (for reference) + +## To Switch Back to Active Mode (March 8, 2026) + +### Step 1: Restore Original Homepage +In `src/app/page.tsx`, replace: +```tsx +import RestPeriodHome from '../components/RestPeriodHome' +export default async function Home() { + return +} +``` + +With the original homepage content (see git history or backup). + +### Step 2: Update Header Colors +In `src/components/Header.tsx`: +- Change `bg-brand-purple-dark/95` back to `bg-brand-green-dark/95` +- Change `hover:text-brand-purple-light` back to `hover:text-brand-green-accent` +- Change `focus:ring-brand-purple-light` back to `focus:ring-brand-green-accent` +- Change `bg-brand-purple-light` (CTA button) back to `bg-brand-green-accent` +- Change `text-brand-purple-dark` (CTA button text) back to `text-white` + +### Step 3: Update Footer Colors +In `src/components/Footer.tsx`: +- Change `bg-brand-purple-dark` back to `bg-brand-green-dark` +- Change `hover:text-brand-purple-light` back to `hover:text-brand-green-accent` +- Change `focus:ring-brand-purple-light` back to `focus:ring-brand-green-accent` + +### Step 4: Update NewsletterCard +In `src/components/NewsletterCard.tsx`: +- Change `text-brand-purple-dark` back to `text-brand-green-dark` + +### Step 5: Update Any Other Components +Search for `brand-purple-light` and `brand-purple-dark` usage and replace with: +- `brand-purple-light` → `brand-green-accent` +- `brand-purple-dark` → `brand-green-dark` + +## Rest Period Homepage Features + +- **Rest Mode announcement** with return date (March 8, 2026) +- **Pythia Oracles background** section explaining the tradition +- **Educational resources** with links to learn more about the Pythia +- **Newsletter signup** to stay connected during rest period + +## Active Season Dates + +- **Start:** March 8, 2026 +- **End:** November 2026 (approximate) +- **Pattern:** March - November active, November - March rest + +## Notes + +- The rest period allows time to work on the Django migration separately +- All other pages (blog, resources, etc.) remain accessible +- The purple color scheme creates a distinctive "rest period" visual identity +- The Pythia Oracles theme connects the rest period to historical tradition + +--- + +**Last Updated:** January 2025 +**Rest Period End Date:** March 8, 2026 diff --git a/jest.config.js b/jest.config.js index d2c6c2e..344dd44 100644 --- a/jest.config.js +++ b/jest.config.js @@ -14,15 +14,16 @@ const customJestConfig = { '^@/(.*)$': '/src/$1', }, testMatch: ['**/__tests__/**/*.test.[jt]s?(x)'], - collectCoverage: true, - collectCoverageFrom: [ - 'src/**/*.{js,jsx,ts,tsx}', - '!src/**/*.d.ts', - '!src/**/_*.{js,jsx,ts,tsx}', - '!src/**/*.stories.{js,jsx,ts,tsx}', - '!**/node_modules/**', - '!**/.next/**', - ], + collectCoverage: false, // Disabled due to test-exclude incompatibility with glob 10.4.6+ + // Coverage can be re-enabled after migrating to Django or when test-exclude is updated + // collectCoverageFrom: [ + // 'src/**/*.{js,jsx,ts,tsx}', + // '!src/**/*.d.ts', + // '!src/**/_*.{js,jsx,ts,tsx}', + // '!src/**/*.stories.{js,jsx,ts,tsx}', + // '!**/node_modules/**', + // '!**/.next/**', + // ], }; // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async diff --git a/package-lock.json b/package-lock.json index 6d28a29..3daa7e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,13 +34,14 @@ "@typescript-eslint/parser": "^6.21.0", "autoprefixer": "^10.4.21", "eslint": "^8.56.0", - "eslint-config-next": "14.1.0", + "eslint-config-next": "^14.2.33", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", "postcss": "^8.5.4", "tailwindcss": "^3.4.1", + "test-exclude": "^7.0.1", "ts-jest": "^29.1.0", "typescript": "^5" } @@ -673,9 +674,9 @@ } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -773,9 +774,9 @@ } }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -1233,9 +1234,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -1246,9 +1247,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -1303,9 +1304,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -1565,52 +1566,6 @@ } } }, - "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@jest/reporters/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@jest/reporters/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -1858,15 +1813,15 @@ } }, "node_modules/@next/env": { - "version": "14.2.29", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.29.tgz", - "integrity": "sha512-UzgLR2eBfhKIQt0aJ7PWH7XRPYw7SXz0Fpzdl5THjUnvxy4kfBk9OU4RNPNiETewEEtaBcExNFNn1QWH8wQTjg==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.33.tgz", + "integrity": "sha512-CgVHNZ1fRIlxkLhIX22flAZI/HmpDaZ8vwyJ/B0SDPTBuLZ1PJ+DWMjCHhqnExfmSQzA/PbZi8OAc7PAq2w9IA==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.0.tgz", - "integrity": "sha512-x4FavbNEeXx/baD/zC/SdrvkjSby8nBn8KcCREqk6UuwvwoAPZmaV8TFCAuo/cpovBRTIY67mHhe86MQQm/68Q==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.33.tgz", + "integrity": "sha512-DQTJFSvlB+9JilwqMKJ3VPByBNGxAGFTfJ7BuFj25cVcbBy7jm88KfUN+dngM4D3+UxZ8ER2ft+WH9JccMvxyg==", "dev": true, "license": "MIT", "dependencies": { @@ -1895,9 +1850,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.29", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.29.tgz", - "integrity": "sha512-wWtrAaxCVMejxPHFb1SK/PVV1WDIrXGs9ki0C/kUM8ubKHQm+3hU9MouUywCw8Wbhj3pewfHT2wjunLEr/TaLA==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.33.tgz", + "integrity": "sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==", "cpu": [ "arm64" ], @@ -1911,9 +1866,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "14.2.29", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.29.tgz", - "integrity": "sha512-7Z/jk+6EVBj4pNLw/JQrvZVrAh9Bv8q81zCFSfvTMZ51WySyEHWVpwCEaJY910LyBftv2F37kuDPQm0w9CEXyg==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.33.tgz", + "integrity": "sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==", "cpu": [ "x64" ], @@ -1927,9 +1882,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.29", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.29.tgz", - "integrity": "sha512-o6hrz5xRBwi+G7JFTHc+RUsXo2lVXEfwh4/qsuWBMQq6aut+0w98WEnoNwAwt7hkEqegzvazf81dNiwo7KjITw==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.33.tgz", + "integrity": "sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==", "cpu": [ "arm64" ], @@ -1943,9 +1898,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.29", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.29.tgz", - "integrity": "sha512-9i+JEHBOVgqxQ92HHRFlSW1EQXqa/89IVjtHgOqsShCcB/ZBjTtkWGi+SGCJaYyWkr/lzu51NTMCfKuBf7ULNw==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.33.tgz", + "integrity": "sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==", "cpu": [ "arm64" ], @@ -1959,9 +1914,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.29", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.29.tgz", - "integrity": "sha512-B7JtMbkUwHijrGBOhgSQu2ncbCYq9E7PZ7MX58kxheiEOwdkM+jGx0cBb+rN5AeqF96JypEppK6i/bEL9T13lA==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.33.tgz", + "integrity": "sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg==", "cpu": [ "x64" ], @@ -1975,9 +1930,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.29", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.29.tgz", - "integrity": "sha512-yCcZo1OrO3aQ38B5zctqKU1Z3klOohIxug6qdiKO3Q3qNye/1n6XIs01YJ+Uf+TdpZQ0fNrOQI2HrTLF3Zprnw==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.33.tgz", + "integrity": "sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==", "cpu": [ "x64" ], @@ -1991,9 +1946,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.29", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.29.tgz", - "integrity": "sha512-WnrfeOEtTVidI9Z6jDLy+gxrpDcEJtZva54LYC0bSKQqmyuHzl0ego+v0F/v2aXq0am67BRqo/ybmmt45Tzo4A==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.33.tgz", + "integrity": "sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==", "cpu": [ "arm64" ], @@ -2007,9 +1962,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.29", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.29.tgz", - "integrity": "sha512-vkcriFROT4wsTdSeIzbxaZjTNTFKjSYmLd8q/GVH3Dn8JmYjUKOuKXHK8n+lovW/kdcpIvydO5GtN+It2CvKWA==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.33.tgz", + "integrity": "sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==", "cpu": [ "ia32" ], @@ -2023,9 +1978,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.29", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.29.tgz", - "integrity": "sha512-iPPwUEKnVs7pwR0EBLJlwxLD7TTHWS/AoVZx1l9ZQzfQciqaFEr5AlYzA2uB6Fyby1IF18t4PL0nTpB+k4Tzlw==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.33.tgz", + "integrity": "sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg==", "cpu": [ "x64" ], @@ -3430,6 +3385,17 @@ "node": ">=8" } }, + "node_modules/babel-plugin-istanbul/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", @@ -3447,6 +3413,19 @@ "node": ">=8" } }, + "node_modules/babel-plugin-istanbul/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/babel-plugin-istanbul/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -3457,6 +3436,21 @@ "semver": "bin/semver.js" } }, + "node_modules/babel-plugin-istanbul/node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", @@ -3548,9 +3542,9 @@ } }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4870,15 +4864,16 @@ } }, "node_modules/eslint-config-next": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.0.tgz", - "integrity": "sha512-SBX2ed7DoRFXC6CQSLc/SbLY9Ut6HxNB2wPTcoIWjUMd7aF7O/SIE7111L8FdZ9TXsNV4pulUDnfthpyPtbFUg==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.33.tgz", + "integrity": "sha512-e2W+waB+I5KuoALAtKZl3WVDU4Q1MS6gF/gdcwHh0WOAkHf4TZI6dPjd25wKhlZFAsFrVKy24Z7/IwOhn8dHBw==", "dev": true, "license": "MIT", "dependencies": { - "@next/eslint-plugin-next": "14.1.0", + "@next/eslint-plugin-next": "14.2.33", "@rushstack/eslint-patch": "^1.3.3", - "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", + "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.28.1", @@ -5016,9 +5011,9 @@ } }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -5103,9 +5098,9 @@ } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -5173,9 +5168,9 @@ } }, "node_modules/eslint-plugin-react/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -5292,9 +5287,9 @@ } }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -5751,9 +5746,9 @@ } }, "node_modules/form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "dev": true, "license": "MIT", "dependencies": { @@ -5781,13 +5776,6 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -5958,24 +5946,22 @@ } }, "node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -5993,6 +5979,22 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", @@ -6098,9 +6100,9 @@ } }, "node_modules/gray-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "license": "MIT", "dependencies": { "argparse": "^1.0.7", @@ -6401,25 +6403,6 @@ "node": ">=0.8.19" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, "node_modules/inline-style-parser": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", @@ -7091,17 +7074,14 @@ } }, "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -7129,9 +7109,9 @@ } }, "node_modules/jake/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -7306,52 +7286,6 @@ } } }, - "node_modules/jest-config/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/jest-config/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-config/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", @@ -7676,52 +7610,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/jest-runtime/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-runtime/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/jest-snapshot": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", @@ -7872,9 +7760,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -8340,9 +8228,9 @@ } }, "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -9150,12 +9038,12 @@ "license": "MIT" }, "node_modules/next": { - "version": "14.2.29", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.29.tgz", - "integrity": "sha512-s98mCOMOWLGGpGOfgKSnleXLuegvvH415qtRZXpSp00HeEgdmrxmwL9cgKU+h4XrhB16zEI5d/7BnkS3ATInsA==", + "version": "14.2.33", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.33.tgz", + "integrity": "sha512-GiKHLsD00t4ACm1p00VgrI0rUFAC9cRDGReKyERlM57aeEZkOQGcZTpIbsGn0b562FTPJWmYfKwplfO9EaT6ng==", "license": "MIT", "dependencies": { - "@next/env": "14.2.29", + "@next/env": "14.2.33", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", @@ -9170,15 +9058,15 @@ "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.29", - "@next/swc-darwin-x64": "14.2.29", - "@next/swc-linux-arm64-gnu": "14.2.29", - "@next/swc-linux-arm64-musl": "14.2.29", - "@next/swc-linux-x64-gnu": "14.2.29", - "@next/swc-linux-x64-musl": "14.2.29", - "@next/swc-win32-arm64-msvc": "14.2.29", - "@next/swc-win32-ia32-msvc": "14.2.29", - "@next/swc-win32-x64-msvc": "14.2.29" + "@next/swc-darwin-arm64": "14.2.33", + "@next/swc-darwin-x64": "14.2.33", + "@next/swc-linux-arm64-gnu": "14.2.33", + "@next/swc-linux-arm64-musl": "14.2.33", + "@next/swc-linux-x64-gnu": "14.2.33", + "@next/swc-linux-x64-musl": "14.2.33", + "@next/swc-win32-arm64-msvc": "14.2.33", + "@next/swc-win32-ia32-msvc": "14.2.33", + "@next/swc-win32-x64-msvc": "14.2.33" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -9435,16 +9323,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -9539,6 +9417,13 @@ "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -9619,16 +9504,6 @@ "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -10419,52 +10294,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -10995,9 +10824,9 @@ "license": "MIT" }, "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -11008,9 +10837,9 @@ } }, "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -11415,66 +11244,36 @@ } }, "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", + "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", "dev": true, "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "glob": "^10.4.1", + "minimatch": "^9.0.4" }, "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node": ">=18" } }, - "node_modules/test-exclude/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "node_modules/test-exclude/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -12469,9 +12268,9 @@ } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -12482,9 +12281,9 @@ } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -12495,9 +12294,9 @@ } }, "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -12510,13 +12309,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, "node_modules/write-file-atomic": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", diff --git a/package.json b/package.json index 85a0366..c83cfa4 100644 --- a/package.json +++ b/package.json @@ -37,14 +37,18 @@ "@typescript-eslint/parser": "^6.21.0", "autoprefixer": "^10.4.21", "eslint": "^8.56.0", - "eslint-config-next": "14.1.0", + "eslint-config-next": "^14.2.33", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", "postcss": "^8.5.4", "tailwindcss": "^3.4.1", + "test-exclude": "^7.0.1", "ts-jest": "^29.1.0", "typescript": "^5" + }, + "overrides": { + "glob": "^10.4.6" } } diff --git a/public/feed.xml b/public/feed.xml index 4e57042..e4a0594 100644 --- a/public/feed.xml +++ b/public/feed.xml @@ -5,7 +5,7 @@ https://pythonessprogrammer.com Thoughts on technology, accessibility, and the human experience. en - Fri, 14 Nov 2025 22:09:42 GMT + Thu, 11 Dec 2025 18:41:15 GMT diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index 2e1596b..141f2a0 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -1,6 +1,5 @@ import Image from 'next/image' import Link from 'next/link' -import ServiceCard from '../../components/ServiceCard' import { calculateYearsOfExperience } from '@/lib/utils' export const metadata = { @@ -42,26 +41,19 @@ export default function AboutPage() {

-
- - View My Services - - - Book a Call - +
+

+ Current Status: Rest Mode +

+

+ Services resume March 2026. Active season: March - November 2026. +

{/* Image */}
-
+
Amanda Nelson - The Pythoness Programmer
-
+
@@ -173,6 +165,57 @@ export default function AboutPage() { + {/* Active & Rest Periods Section */} +
+
+
+

+ Active & Rest Periods +

+
+
+

+ Following the ancient tradition of the Pythia Oracles of Delphi +

+
+
+
+ +
+
+

+ The Tradition of Rest +

+

+ Just as the Pythia, the high priestess of the Temple of Apollo at Delphi, observed periods of rest during the winter months, I honor cycles of rest and renewal. The Pythia understood that wisdom and service require periods of restoration—times to withdraw, reflect, and prepare for the active season ahead. +

+

+ Active Season: March - November
+ Rest Period: November - March +

+
+ +
+

+ Accommodating Chronic Illness & Chronic Pain +

+

+ This schedule isn't just about tradition—it's about sustainability and self-care. Living with chronic illnesses and chronic pain means I need to honor my body's needs and limitations. The rest period allows me to manage my health, reduce stress, and prevent burnout that would otherwise compromise the quality of my work and my ability to serve clients well. +

+
+ +
+

+ Nurturing Creativity Through Slowness +

+

+ The rest period also forces me to live a slower life—and that's intentional. In our fast-paced world, creativity often gets squeezed out by constant productivity demands. By committing to rest, I create space for reflection, inspiration, and the kind of deep thinking that leads to breakthrough insights. This slower pace isn't a limitation—it's a feature that makes my active season more powerful and my insights more valuable. +

+
+
+
+
+ {/* My Philosophy Section */}
@@ -183,7 +226,7 @@ export default function AboutPage() {

- The core principles that guide my approach to tech coaching and development. + The core principles that guide my approach to tech coaching and development, including honoring rest as a mirror to the Oracles of Delphi.

@@ -192,7 +235,7 @@ export default function AboutPage() {
{/* Principle 1 */}
-
+
🧠

Brain-Friendly Design

@@ -247,7 +290,7 @@ export default function AboutPage() { {/* Principle 6 */}
-
+
🤝

Community-Centered Bargains

@@ -257,101 +300,44 @@ export default function AboutPage() {
- {/* Centered Affirming Statement */} + {/* Centered Rest & Renewal Statement */}
-
-
- 💚 +
+
+ 🌙

- LGBTQIA+ & SW Affirming + Honoring Rest & Renewal

- I provide a safe, affirming space for LGBTQIA+ individuals and SW, understanding the unique challenges and opportunities in our communities. This commitment to inclusivity and support is the foundation that makes all my other principles possible. + Following the tradition of the Pythia Oracles of Delphi, I honor cycles of rest and renewal. This schedule accommodates my chronic illnesses and chronic pain while nurturing creativity through intentional slowness. Rest isn't a limitation—it's essential for sustainable service and deeper insights. By forcing myself to live a slower life, I create space for reflection, inspiration, and the kind of deep thinking that leads to breakthrough insights.

- {/* What I Do Section */} -
-
-
-

- What I Do -

-
-
-

- A comprehensive overview of my Digital Psychic Sessions and how I can help you solve your own tech challenges through pattern recognition, spiritual insight, and deep technical understanding. - - I don't solve your problems—I help you solve your own. Through my unique blend of technical expertise, pattern recognition, and spiritual insight, I guide you to bring your vision to life. - -

-
-
-
- -
- - - -
-
-
{/* Call to Action Section */}

- Ready to Solve Your Own Tech Challenges? + Services Resume March 2026

- Let's work together to bring your vision to life. I'll guide you with pattern recognition, spiritual insight, and deep technical understanding—but the solutions will be yours. + We're currently in a period of rest and renewal. When we return, I'll be ready to guide you with pattern recognition, spiritual insight, and deep technical understanding—but the solutions will be yours.

-
+
+

+ Subscribe to our newsletter to be the first to know when our schedule reopens. +

- Book a Digital Psychic Session - - - View All Services + Subscribe to Newsletter
diff --git a/src/app/blog/layout.tsx b/src/app/blog/layout.tsx index 929a54a..a91a6b7 100644 --- a/src/app/blog/layout.tsx +++ b/src/app/blog/layout.tsx @@ -13,8 +13,8 @@ export default function BlogLayout({ children: React.ReactNode }) { return ( -
-
+
+
diff --git a/src/app/globals.css b/src/app/globals.css index 3b5165d..b1f0d75 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -3,7 +3,7 @@ @tailwind utilities; :root { - /* Brand color palette */ + /* Brand color palette - Active Season */ --brand-forest: #2e3d2a; --brand-cream: #f4f1de; --brand-green: #32d24d; @@ -12,6 +12,12 @@ --brand-blue: #00a6fb; --brand-fuchsia: #ff39bc; --brand-hyperlink-green: #156624; + + /* Rest Period Color Palette (Nov 2025 - Mar 2026) */ + /* Main color: #442b48 (purple-dark) replaces #2e3d2a (green-dark) */ + /* Accent color: #d8b9f7 (purple-light) replaces #32d24d (green-accent) */ + --rest-main: #442b48; + --rest-accent: #d8b9f7; } html { diff --git a/src/app/links/page.tsx b/src/app/links/page.tsx index 61fb6fb..5ce129a 100644 --- a/src/app/links/page.tsx +++ b/src/app/links/page.tsx @@ -5,7 +5,7 @@ import CopyField from '@/components/CopyField' export const metadata: Metadata = { title: 'Connect with Amanda | Pythoness Programmer', - description: 'Connect with Amanda through various platforms, book calls, and access free resources.', + description: 'Connect with Amanda through various platforms. We are currently in rest mode. Services will resume March 2026.', } // Define interface for link objects @@ -45,27 +45,6 @@ const socialLinks: LinkItem[] = [ }, ] -// Featured async service -const featuredService: LinkItem = { - name: 'Async Project & Web Presence Reading ($30)', - url: 'https://cal.com/pythoness/async', - color: 'bg-gradient-to-r from-brand-purple-light to-brand-cream text-brand-purple-dark border-2 border-brand-purple-accent font-semibold' -} - -// Booking links - easy to update -const bookingLinks: LinkItem[] = [ - { - name: '20min Digital Psychic Session ($30)', - url: 'https://cal.com/pythoness/20min', - color: 'bg-brand-green-accent text-brand-green-dark' - }, - { - name: '60min Digital Psychic Session ($60)', - url: 'https://cal.com/pythoness/60min', - color: 'bg-brand-green-accent text-brand-green-dark' - } -] - // Resource links - easy to update const resourceLinks: LinkItem[] = [ { @@ -105,7 +84,7 @@ const supportLinks: LinkItem[] = [ { name: 'Amazon Wishlist 🛍️', url: 'https://www.amazon.com/hz/wishlist/ls/1ZXXDBUXYDDOC?ref_=wl_share', - color: 'bg-brand-green-accent text-brand-green-dark hover:bg-brand-green-accent/90' + color: 'bg-brand-purple-light text-brand-purple-dark hover:bg-opacity-90' } ] @@ -114,7 +93,7 @@ const shopLinks: LinkItem[] = [ { name: 'Sticky Spells Store - Etsy', url: 'https://stickyspells.etsy.com', - color: 'bg-brand-green-accent text-brand-green-dark hover:bg-brand-green-accent/90' + color: 'bg-brand-purple-light text-brand-purple-dark hover:bg-opacity-90' } ] @@ -123,22 +102,22 @@ const mediaLinks: LinkItem[] = [ { name: 'Newsletter', url: 'https://newsletter.pythonessprogrammer.com/subscribe', - color: 'bg-brand-green-accent/20 hover:bg-brand-green-accent/30' + color: 'bg-brand-purple-light/20 hover:bg-brand-purple-light/30' }, { - name: 'NotebookLM Podcast', - url: 'https://pythoness.substack.com/podcast', - color: 'bg-brand-green-accent/20 hover:bg-brand-green-accent/30' + name: 'AI Generation Experiments Substack', + url: 'https://pythoness.substack.com', + color: 'bg-brand-purple-light/20 hover:bg-brand-purple-light/30' }, { name: 'Current Music Rotation', url: 'https://open.spotify.com/playlist/19jEmPqzZqp4zH8uyF7uCS?si=d413cc41fba54edc', - color: 'bg-brand-green-accent/20 hover:bg-brand-green-accent/30' + color: 'bg-brand-purple-light/20 hover:bg-brand-purple-light/30' }, { name: 'Working Lo-Fi Playlist', url: 'https://open.spotify.com/playlist/6aZF7YvZTVkfqU2JC0HWQo?si=01d86ac4bd8347ac', - color: 'bg-brand-green-accent/20 hover:bg-brand-green-accent/30' + color: 'bg-brand-purple-light/20 hover:bg-brand-purple-light/30' } ] @@ -147,12 +126,12 @@ const readLinks: LinkItem[] = [ { name: 'Blog', url: '/blog', - color: 'bg-brand-green-accent/20 hover:bg-brand-green-accent/30' + color: 'bg-brand-purple-light/20 hover:bg-brand-purple-light/30' }, { name: 'Newsletter', url: 'https://newsletter.pythonessprogrammer.com/', - color: 'bg-brand-green-accent/20 hover:bg-brand-green-accent/30' + color: 'bg-brand-purple-light/20 hover:bg-brand-purple-light/30' } ] @@ -167,23 +146,23 @@ const legalLinks: LinkItem[] = [ { name: 'Privacy Policy', url: '/privacy-policy', - color: 'bg-brand-green-dark/40 backdrop-blur-md border border-white/10 hover:bg-brand-green-dark/60 text-white shadow-lg hover:shadow-xl transition-all duration-300' + color: 'bg-brand-purple-dark/40 backdrop-blur-md border border-white/10 hover:bg-brand-purple-dark/60 text-white shadow-lg hover:shadow-xl transition-all duration-300' }, { name: 'Terms of Service', url: '/terms', - color: 'bg-brand-green-dark/40 backdrop-blur-md border border-white/10 hover:bg-brand-green-dark/60 text-white shadow-lg hover:shadow-xl transition-all duration-300' + color: 'bg-brand-purple-dark/40 backdrop-blur-md border border-white/10 hover:bg-brand-purple-dark/60 text-white shadow-lg hover:shadow-xl transition-all duration-300' } ] export default function LinksPage() { return ( -
+
{/* Profile Section */}
-
+
Pythoness Programmer

Pythoness Programmer

-

+

Digital Psychic sessions that help you solve your own tech challenges through pattern recognition, spiritual insight, and deep technical understanding. As a Software Engineer, I offer async video readings and live 1:1 sessions.

+
+

+ Current Status: Rest Mode +

+

+ Services resume March 2026. Active season: March - November 2026. +

+
{/* Support Banner Section */} @@ -211,7 +198,7 @@ export default function LinksPage() {

Support the Pythoness @@ -226,7 +213,7 @@ export default function LinksPage() { href={link.url} target="_blank" rel="noopener noreferrer" - className={`block ${link.color} w-10 h-10 rounded-full flex items-center justify-center transition-transform hover:scale-110 focus:outline-none focus:ring-2 focus:ring-brand-green-accent focus:ring-offset-2 focus:ring-offset-brand-green-dark`} + className={`block ${link.color} w-10 h-10 rounded-full flex items-center justify-center transition-transform hover:scale-110 focus:outline-none focus:ring-2 focus:ring-brand-purple-light focus:ring-offset-2 focus:ring-offset-brand-purple-dark`} aria-label={link.name} > {link.icon && ( @@ -247,7 +234,7 @@ export default function LinksPage() { {/* Links Container */}
- {/* Featured Service */} + {/* Featured Service - Rest Mode */}

Featured Service

@@ -255,40 +242,49 @@ export default function LinksPage() { on your project or web presence but prefer to watch on your own time.

20-minute video reading - no live meeting required

- - {featuredService.name} - +
+

+ Available starting March 2026 +

+

+ Subscribe to our newsletter to be the first to know when services resume. +

+ + Subscribe to Newsletter + +
- {/* Booking Links */} - {bookingLinks.length > 0 && ( -
-

Live 1:1 Digital Psychic Sessions

-

- Connect live for real-time guidance on your tech challenges. These interactive sessions combine - pattern recognition, spiritual insight, and deep technical understanding to help you solve problems - and move forward with confidence. + {/* Booking Links - Rest Mode Notice */} +

+

Live 1:1 Digital Psychic Sessions

+

+ Connect live for real-time guidance on your tech challenges. These interactive sessions combine + pattern recognition, spiritual insight, and deep technical understanding to help you solve problems + and move forward with confidence. +

+
+

+ Services resume March 2026

-
- {bookingLinks.map((link) => ( - - {link.name} - - ))} -
+

+ Subscribe to our newsletter to be the first to know when our schedule reopens. +

+ + Subscribe to Newsletter +
- )} +
{/* Shop Links */} {shopLinks.length > 0 && ( @@ -301,7 +297,7 @@ export default function LinksPage() { href={link.url} target="_blank" rel="noopener noreferrer" - className={`block ${link.color} py-2.5 md:py-3 px-6 rounded-lg text-center transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-brand-green-accent focus:ring-offset-2 focus:ring-offset-brand-green-dark font-medium`} + className={`block ${link.color} py-2.5 md:py-3 px-6 rounded-lg text-center transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-brand-purple-light focus:ring-offset-2 focus:ring-offset-brand-purple-dark font-medium`} > {link.name} @@ -320,7 +316,7 @@ export default function LinksPage() { href={link.url} target="_blank" rel="noopener noreferrer" - className={`block ${link.color} py-2.5 md:py-3 px-6 rounded-lg text-center transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-brand-green-accent focus:ring-offset-2 focus:ring-offset-brand-green-dark`} + className={`block ${link.color} py-2.5 md:py-3 px-6 rounded-lg text-center transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-brand-purple-light focus:ring-offset-2 focus:ring-offset-brand-purple-dark`} > {link.name} @@ -338,7 +334,7 @@ export default function LinksPage() { href={link.url} target="_blank" rel="noopener noreferrer" - className={`block ${link.color} py-2.5 md:py-3 px-6 rounded-lg text-center transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-brand-green-accent focus:ring-offset-2 focus:ring-offset-brand-green-dark`} + className={`block ${link.color} py-2.5 md:py-3 px-6 rounded-lg text-center transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-brand-purple-light focus:ring-offset-2 focus:ring-offset-brand-purple-dark`} > {link.name} @@ -373,7 +369,7 @@ export default function LinksPage() { href={link.url} target="_blank" rel="noopener noreferrer" - className={`block ${link.color} py-2.5 md:py-3 px-6 rounded-lg text-center transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-brand-green-accent focus:ring-offset-2 focus:ring-offset-brand-green-dark`} + className={`block ${link.color} py-2.5 md:py-3 px-6 rounded-lg text-center transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-brand-purple-light focus:ring-offset-2 focus:ring-offset-brand-purple-dark`} > {link.boldPart ? ( <> @@ -404,16 +400,19 @@ export default function LinksPage() { label="Cash App" value="$ANCreative" ariaLabel="Cash App username" + copyButtonClassName="shrink-0 rounded-md px-3 py-2 bg-brand-purple-light text-brand-purple-dark hover:bg-opacity-90 transition-colors focus:outline-none focus:ring-2 focus:ring-brand-purple-light" />
@@ -423,7 +422,7 @@ export default function LinksPage() { href={link.url} target="_blank" rel="noopener noreferrer" - className={`block ${link.color} py-2.5 md:py-3 px-6 rounded-lg text-center transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-brand-green-accent focus:ring-offset-2 focus:ring-offset-brand-green-dark font-medium`} + className={`block ${link.color} py-2.5 md:py-3 px-6 rounded-lg text-center transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-brand-purple-light focus:ring-offset-2 focus:ring-offset-brand-purple-dark font-medium`} > {link.name} @@ -436,7 +435,7 @@ export default function LinksPage() {
Visit my website → diff --git a/src/app/page.tsx b/src/app/page.tsx index 1d8ef29..0777a8b 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,154 +1,13 @@ -import HeroCard from '../components/HeroCard' -import PainPointsCard from '../components/PainPointsCard' -import ForeverTopicsCard from '../components/ForeverTopicsCard' -import ServiceCard from '../components/ServiceCard' -import AboutCard from '../components/AboutCard' -import NewsletterCard from '../components/NewsletterCard' +import RestPeriodHome from '../components/RestPeriodHome' export const metadata = { - title: 'Pythoness Programmer | Tech Coaching & Development', - description: 'Tech coaching, web development, and digital crafts for conscious creators and business owners.', + title: 'Pythoness Programmer | Rest Mode', + description: 'We are currently in a period of rest and reflection. Consulting services will resume March 2026.', other: { 'p:domain_verify': '18888270799e128d4d49644962be5ab6' } } export default async function Home() { - return ( -
- {/* Hero Section */} -
-
- -
-
- - {/* Pain Points Section */} -
-
- -
-
- - {/* Forever Topics Section */} -
-
- -
-
- - {/* Services Section */} -
-
- {/* Section Header */} -
-

- Your Digital Journey, Your Way -

-
-
-

- Everyone learns and grows differently. I'm here to help you discover your own path to digital confidence, with a healthy dose of humor and zero judgment along the way. -

-
-
-
- - {/* Featured Async Service */} -
-

Featured Service

-
- -
-
- - {/* Live 1:1 Sessions */} -
-

Live 1:1 Sessions

-

Interactive sessions with real-time guidance

-
- - -
-
-
-
- - {/* About Section */} -
-
- -
-
- - {/* Newsletter Section */} -
-
- -
-
-
- ) + return } diff --git a/src/app/resources/page.tsx b/src/app/resources/page.tsx index d0c8aca..cf5834d 100644 --- a/src/app/resources/page.tsx +++ b/src/app/resources/page.tsx @@ -54,31 +54,21 @@ export default function ResourcesPage() {
-
- 🎙️ +
+ 🔬
-

NotebookLM Podcast

+

AI Generation Experiments Substack

- AI-powered insights from my research on technology, automation, and digital wellness. + Exploring and sharing findings on AI tools and generation experiments outside my normal content lineup.

-
- - Listen on Spotify - - - Watch on YouTube - -
+ + Visit Substack +
diff --git a/src/app/services/page.tsx b/src/app/services/page.tsx index c0cacd9..dc1a784 100644 --- a/src/app/services/page.tsx +++ b/src/app/services/page.tsx @@ -1,372 +1,79 @@ -/* eslint-disable react/no-unescaped-entities */ -import Link from 'next/link' -import ServiceCard from '../../components/ServiceCard' -import PainPointsCard from '../../components/PainPointsCard' +import NewsletterCard from '../../components/NewsletterCard' export const metadata = { title: 'Services | Pythoness Programmer', - description: 'Tech coaching, web development, and system integration services designed for neurodivergent professionals. Clear pricing, brain-friendly approaches, and judgment-free support.', + description: 'We are currently in a period of rest. Services will resume March 2026.', } export default function ServicesPage() { return ( -
- {/* Hero Section */} -
-
-
-

- Services That Work for Your Brain +
+ {/* Hero Section - Rest Mode */} +
+
+
+

+ Services

-

- I don't solve your problems—I help you solve your own. Through my unique blend of technical expertise, pattern recognition, and spiritual insight, I guide you to bring your vision to life. Creation and ideation are spiritual processes, and I combine the mystical with the practical to get at the heart of what your business truly needs. +

+

+ We are currently in a period of rest and reflection, following the ancient tradition of the Pythia Oracles of Delphi.

-
- - Book Your Async Reading - - - View All Services - -
-
-
-
- - {/* Pain Points Section */} -
-
- -
-
- - {/* Main Services Section */} -
-
-
-

- My Services -

-
-
-

- I offer deeply focused, brain-friendly Digital Psychic sessions designed for small business owners who want to find their tech stack simple, easy, and functional—so you can manage it yourself without needing a regular IT person "on-call." My approach comes from a place of deep inner knowledge and connected insights from my background in sociology, civics, politics, and human rights. I don't want clients who want me to solve their problems—I want clients who want to solve their own problems but need a hand in bringing their vision to life. My pattern recognition makes often unsettling connections across industries that have historically gatekept knowledge, and my recommendations come from this place of deep understanding. Creation and ideation are spiritual processes, and I find it's helpful to combine the spiritual and the technical to get at the heart of what a business, founder, or business owner needs in a lasting way. -

-
-
-
- - {/* Async Service - Featured in its own row */} -
-
- -
-
- - {/* Live 1:1 Services */} -
-

Live 1:1 Sessions

-

Interactive sessions with real-time guidance

-
- -
- {/* 20-Minute Digital Psychic Session */} - - - {/* 60-Minute Digital Psychic Session */} - -
-
-
- - {/* Why "Psychic" Section */} -
-
-
-

- Why "Digital Psychic"? -

-
-
-

- My approach isn't about predicting the future—it's about seeing patterns others miss and connecting dots across industries that have historically gatekept knowledge. -

-
-
-
- -
- {/* Pattern Recognition */} -
-
- 🔍 -
-

Pattern Recognition

-

- My background in sociology, civics, and politics gives me a unique lens for seeing how systems truly work—and where they're designed to fail. -

-
- - {/* Industry Connections */} -
-
- 🔗 -
-

Industry Connections

-

- I make unsettling connections across law, marketing, and tech—industries that have historically gatekept knowledge from the people who need it most. -

-
- - {/* Spiritual Creation */} -
-
- -
-

Spiritual Creation

-

- Creation and ideation are spiritual processes. I combine the mystical with the practical to get at the heart of what your business truly needs. -

-
-
-
-
- - {/* Process Section */} -
-
-
-

- How We'll Work Together -

-
-
-

- A clear, structured process designed to reduce overwhelm and maximize results. The process starts as soon as you book your session, including your deck preference for our tarot or oracle card pulls. -

-
-
-
- -
- {/* Step 1 */} -
-
- 1 -
-

Book & Share

-

- Secure your session and fill out a quick intake form to share your goals, challenges, and priorities. +

+

+ Consulting services will resume

-
- - {/* Step 2 */} -
-
- 2 -
-

Assessment

-

- I review your information and analyze your current systems to identify opportunities for improvement. -

-
- - {/* Step 3 */} -
-
- 3 -
-

Session & Solutions

-

- We meet for your session, diving into your challenges, brainstorming solutions, and creating a clear action plan together. +

+ March 2026

-
- - {/* Step 4 */} -
-
- 4 -
-

Follow-Up & Support

-

- Receive a summary, resources, and next steps after your session. There are options for ongoing support if you need it. +

+ Active season: March - November 2026

- {/* FAQ Section */} -
+ {/* Services Info Section */} +
-
-

- Frequently Asked Questions +
+

+ About Our Services

-
-
-

- Common questions about my services and approach. -

-
-
-
- -
- {/* FAQ Item 1 */} -
-

- What makes your approach different? -

-

- I design solutions specifically for neurodivergent brains, focusing on reducing cognitive load, providing clear structure, and creating systems that actually work for your unique thinking patterns. No judgment, no assumptions, just practical solutions. -

-
- - {/* FAQ Item 2 */} -
-

- Do you work with people who aren't tech-savvy? -

-

- Absolutely! In fact, many of my clients come to me feeling overwhelmed by technology. I specialize in breaking down complex concepts into manageable pieces and providing judgment-free support regardless of your current tech comfort level. -

-
- - {/* FAQ Item 3 */} -
-

- How do I know which service is right for me? -

-

- Start with a 20-minute session! We'll discuss your specific needs and I'll recommend the best approach. The 20-minute session is perfect for exploring options, while the 60-minute session is ideal for comprehensive change. -

-
- - {/* FAQ Item 4 */} -
-

- What if I need ongoing support? -

-

- I offer ongoing tech support plans and can also work with you on a project basis. Many clients start with a consultation or overhaul and then choose ongoing support to maintain their systems and continue growing. -

-
+
+

+ During our active season, we offer Digital Psychic sessions designed for small business owners who want to find their tech stack simple, easy, and functional. Our approach combines technical expertise, pattern recognition, and spiritual insight to help you bring your vision to life. +

+ +
+

+ Async Digital Psychic Reading +

+

+ Our asynchronous service will be available starting March 2026. This 20-minute video recording provides a personalized intuitive reading for your project, website, or online presence—delivered as a private video you can watch and re-watch at your pace. +

+

+ Perfect for busy schedules, this service includes tarot card pulls, deep project analysis, and pattern recognition insights—all without requiring a live meeting. +

+
- {/* FAQ Item 5 */} -
-

- Do you work with businesses or just individuals? -

-

- Both! I work with individual professionals, small business owners, and teams. My approach scales well for different needs, whether you're a solopreneur or managing a small team's digital systems. +

+ If you're interested in our services, we encourage you to subscribe to our newsletter to be the first to know when our schedule reopens in March 2026.

- {/* Call to Action Section */} -
-
-

- Ready to Get Started? -

-

- Let's discuss your needs and find the perfect solution for your unique situation. No pressure, no judgment - just a conversation about how I can help. -

-
- - Book Your Async Reading - - - Learn More About Me - -
+ {/* Newsletter Section */} +
+
+
diff --git a/src/components/CopyField.tsx b/src/components/CopyField.tsx index 6e6a122..b49ef5d 100644 --- a/src/components/CopyField.tsx +++ b/src/components/CopyField.tsx @@ -41,7 +41,7 @@ export default function CopyField({ readOnly onFocus={(e) => e.currentTarget.select()} aria-label={ariaLabel ?? label ?? value} - className="w-full rounded-md bg-white/10 text-white placeholder-white/60 border border-white/10 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-brand-green-accent focus:border-transparent" + className="w-full rounded-md bg-white/10 text-white placeholder-white/60 border border-white/10 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-brand-purple-light focus:border-transparent" /> {isResourcesOpen && ( -
+
setIsResourcesOpen(false)} > All Resources setIsResourcesOpen(false)} > Digital Spring Cleaning setIsResourcesOpen(false)} > Mindful Automation setIsResourcesOpen(false)} > Accessibility Legal Guide setIsResourcesOpen(false)} > Back to Basics setIsResourcesOpen(false)} > AI Myth-Busting setIsResourcesOpen(false)} > Vibe Coding Cheatsheet setIsResourcesOpen(false)} > Password Security Guide setIsResourcesOpen(false)} > Privacy Pleasure @@ -140,7 +134,7 @@ export default function Header() {
Blog @@ -148,7 +142,7 @@ export default function Header() { href="https://videos.pythonessprogrammer.com" target="_blank" rel="noopener noreferrer" - className="text-white hover:text-brand-green-accent transition-colors focus:outline-none focus:ring-2 focus:ring-brand-green-accent focus:ring-offset-2 rounded-lg px-2 py-1" + className="text-white hover:text-brand-purple-light transition-colors focus:outline-none focus:ring-2 focus:ring-brand-purple-light focus:ring-offset-2 rounded-lg px-2 py-1" > Videos @@ -156,20 +150,13 @@ export default function Header() { href="https://stickyspells.etsy.com" target="_blank" rel="noopener noreferrer" - className="text-white hover:text-brand-green-accent transition-colors focus:outline-none focus:ring-2 focus:ring-brand-green-accent focus:ring-offset-2 rounded-lg px-2 py-1 font-medium" + className="text-white hover:text-brand-purple-light transition-colors focus:outline-none focus:ring-2 focus:ring-brand-purple-light focus:ring-offset-2 rounded-lg px-2 py-1 font-medium" > Shop - - Book a Call -

diff --git a/src/components/NewsletterCard.tsx b/src/components/NewsletterCard.tsx index 8486e70..2017c30 100644 --- a/src/components/NewsletterCard.tsx +++ b/src/components/NewsletterCard.tsx @@ -25,7 +25,7 @@ export default function NewsletterCard({ {/* Section header with glass effect */}
-

+

{title}

diff --git a/src/components/RestPeriodHome.tsx b/src/components/RestPeriodHome.tsx new file mode 100644 index 0000000..076ccf2 --- /dev/null +++ b/src/components/RestPeriodHome.tsx @@ -0,0 +1,123 @@ +import NewsletterCard from './NewsletterCard' + +export default function RestPeriodHome() { + return ( +

+ {/* Hero Section - Rest Mode Announcement */} +
+
+
+

+ Rest Mode +

+
+

+ We are currently in a period of rest and reflection, following the ancient tradition of the Pythia Oracles of Delphi. +

+
+

+ Consulting services will resume +

+

+ March 2026 +

+

+ Active season: March - November 2026 +

+
+
+
+
+ + {/* Pythia Oracles Background Section */} +
+
+
+

+ The Tradition of Rest: Pythia Oracles of Delphi +

+
+

+ The Pythia, the high priestess of the Temple of Apollo at Delphi, was one of the most important religious figures in ancient Greece. She delivered prophecies and guidance to those who sought wisdom, but her practice was deeply connected to cycles of rest and renewal. +

+ +

+ The Pythia did not provide oracles year-round. She observed specific periods of rest, particularly during the winter months when the sacred site was closed. These rest periods were essential for maintaining the integrity and power of her practice. During these times, she would withdraw, reflect, and prepare for the active season ahead. +

+ +

+ This tradition recognizes that wisdom and service require periods of restoration. Just as the Pythia honored cycles of rest, we honor the need for reflection, renewal, and preparation before returning to active service. +

+ +
+

+ Learn More +

+

+ For those curious about the historical and cultural context of the Pythia Oracles: +

+ +
+
+
+
+
+ + {/* Newsletter Section */} +
+
+ +
+
+
+ ) +} diff --git a/src/components/blog/BlogContent.tsx b/src/components/blog/BlogContent.tsx index 9410c6d..75a7b63 100644 --- a/src/components/blog/BlogContent.tsx +++ b/src/components/blog/BlogContent.tsx @@ -31,7 +31,7 @@ function RSSFeedLink() {
@@ -102,7 +102,7 @@ export function BlogContent({ posts }: BlogContentProps) { placeholder="Search blog posts..." value={searchQuery} onChange={(e) => setSearchQuery(e.target.value)} - className="w-full px-4 py-3 pl-12 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-brand-green-accent focus:border-transparent" + className="w-full px-4 py-3 pl-12 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-brand-purple-light focus:border-transparent" /> {filteredPosts.map((post) => ( -
-

- +
+

+ {post.frontmatter.title}

diff --git a/src/components/blog/BlogStyles.tsx b/src/components/blog/BlogStyles.tsx index 800e1da..e0d9d1b 100644 --- a/src/components/blog/BlogStyles.tsx +++ b/src/components/blog/BlogStyles.tsx @@ -4,7 +4,7 @@ export function BlogStyles() { return ( ) diff --git a/src/components/blog/PostCard.tsx b/src/components/blog/PostCard.tsx index 90b5190..c3d848d 100644 --- a/src/components/blog/PostCard.tsx +++ b/src/components/blog/PostCard.tsx @@ -28,7 +28,7 @@ export default function PostCard({ post }: PostCardProps) { sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw" /> )} -

+

{post.title}