commit 6e13451dc49fe160d3ccb2565055e0e077b09ebe Author: anthonyrawlins Date: Wed Aug 27 14:46:26 2025 +1000 Initial commit: CHORUS PING! blog - Next.js 14 blog application with theme support - Docker containerization with volume bindings - Traefik integration with Let's Encrypt SSL - MDX support for blog posts - Theme toggle with localStorage persistence - Scheduled posts directory structure - Brand guidelines compliance with CHORUS colors 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f570963 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,44 @@ +# Build and development files +Dockerfile +.dockerignore +node_modules +npm-debug.log +.next +.nyc_output +coverage + +# Environment and config files +.env* +.git +.gitignore +.vscode +.eslintrc.json +next.config.js.bak + +# Documentation +README.md +docs/ + +# Docker compose files (for development) +docker-compose*.yml + +# Development scripts +dev-start.sh + +# Log files +*.log +logs/ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Keep posts and scheduled directories for volume mounting +# (they'll be mounted as volumes anyway) +posts/ +scheduled/ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6e4ee30 --- /dev/null +++ b/.gitignore @@ -0,0 +1,51 @@ +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +# IDE files +.vscode/ +.idea/ + +# Environment files +.env +.env.production + +# Logs +logs/ +*.log + +# Cache +.cache/ + +# Development scripts +dev-start.sh.bak \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c54581a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,55 @@ +# CHORUS Services - Blog +# Static blog built with Next.js + +FROM node:18-alpine AS base + +# Install dependencies only when needed +FROM base AS deps +RUN apk add --no-cache libc6-compat +WORKDIR /app + +# Copy package files +COPY package.json package-lock.json* ./ +RUN npm ci --only=production + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Set build-time environment variables +ENV NEXT_TELEMETRY_DISABLED 1 +ENV NODE_ENV production + +# Build the application +RUN npm run build + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV production +ENV NEXT_TELEMETRY_DISABLED 1 + +# Create non-root user +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +# Copy built application +COPY --from=builder /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +# Create directories for mounted volumes +RUN mkdir -p /app/posts /app/scheduled +RUN chown -R nextjs:nodejs /app/posts /app/scheduled + +USER nextjs + +EXPOSE 3000 + +ENV PORT 3000 +ENV HOSTNAME "0.0.0.0" + +CMD ["node", "server.js"] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..57152bf --- /dev/null +++ b/README.md @@ -0,0 +1,147 @@ +# CHORUS Blog + +A static blog built with Next.js for sharing insights about contextual AI orchestration, agent coordination, and intelligent systems. + +## Features + +- **Static Blog Posts**: Markdown-based blog posts with MDX support +- **CHORUS Brand Styling**: Consistent with the main CHORUS design system +- **SEO Optimized**: Full metadata, OpenGraph, and Twitter Card support +- **Responsive Design**: Mobile-first design that works on all devices +- **Typography**: Clean, readable typography optimized for technical content +- **Code Highlighting**: Syntax highlighting for code blocks +- **Fast Performance**: Optimized build with static generation + +## Development + +### Quick Start + +```bash +# Start the development server +./dev-start.sh + +# Or manually +npm install +npm run dev +``` + +The blog will be available at `http://localhost:3002` + +### Adding Blog Posts + +1. Create a new `.md` file in `content/posts/` +2. Add frontmatter with metadata: + +```yaml +--- +title: "Your Post Title" +description: "Brief description of the post" +date: "2025-01-27" +author: + name: "Author Name" + role: "Author Role" +tags: ["tag1", "tag2", "tag3"] +featured: false +--- +``` + +3. Write your content in Markdown +4. The post will automatically appear on the blog + +### Project Structure + +``` +├── app/ # Next.js app directory +│ ├── posts/[slug]/ # Dynamic blog post pages +│ ├── layout.tsx # Root layout +│ └── page.tsx # Homepage +├── components/ # React components +│ ├── BlogHeader.tsx # Site header +│ ├── BlogFooter.tsx # Site footer +│ └── PostCard.tsx # Blog post card +├── content/posts/ # Blog post markdown files +├── lib/ # Utilities +│ └── blog.ts # Blog post handling +├── types/ # TypeScript types +└── public/ # Static assets +``` + +## Deployment + +### Docker + +```bash +# Build the Docker image +npm run docker:build + +# Run with Docker Compose +npm run docker:compose +``` + +### Production Build + +```bash +npm run build +npm start +``` + +The blog uses Next.js's static generation features for optimal performance. + +## Configuration + +### Tailwind CSS + +The blog uses the same Tailwind configuration as the main CHORUS website, ensuring brand consistency. The configuration includes: + +- CHORUS color palette (carbon, mulberry, ocean, etc.) +- Typography scale and font families +- Custom spacing and sizing utilities +- Blog-specific prose styling + +### Environment Variables + +No environment variables are required for basic operation. The blog is designed to work as a static site. + +## Brand Guidelines + +The blog follows the CHORUS brand guidelines: + +- **Colors**: Carbon (grays), Mulberry (purples), Ocean (blues) +- **Typography**: Inter Tight for body text, Exo for headings +- **Logo**: Consistent CHORUS branding +- **Spacing**: Golden ratio-based spacing system + +## Adding New Features + +### New Page Types + +Create new pages in the `app/` directory following Next.js 13+ app router conventions. + +### Custom Components + +Add new components to the `components/` directory. All components should: + +- Use TypeScript +- Follow the existing naming conventions +- Be responsive by default +- Use CHORUS brand colors and typography + +### Styling + +- Use Tailwind CSS classes +- Reference the existing design tokens +- Maintain consistency with the CHORUS brand + +## Production Deployment + +The blog is configured for deployment with: + +- **Docker**: Multi-stage build for production +- **Traefik**: Reverse proxy with Let's Encrypt SSL +- **Docker Swarm**: Container orchestration + +Production URL: `https://blog.chorus.services` + +## License + +Proprietary - CHORUS Services \ No newline at end of file diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..9fc6429 --- /dev/null +++ b/app/globals.css @@ -0,0 +1,116 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter+Tight:ital,wght@0,100..900;1,100..900&family=Exo:ital,wght@0,100..900;1,100..900&family=Inconsolata:wdth,wght@50..200,200..900&display=swap'); +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --font-inter: 'Inter Tight', ui-sans-serif, system-ui; + --font-exo: 'Exo', 'Inter Tight', ui-sans-serif, system-ui; + --font-mono: 'Inconsolata', ui-monospace, monospace; +} + +html { + font-feature-settings: "cv02", "cv03", "cv04", "cv11"; + scroll-behavior: smooth; +} + +body { + font-feature-settings: "cv02", "cv03", "cv04", "cv11"; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* CHORUS Blog Typography */ +.prose { + @apply max-w-none text-carbon-950 dark:text-carbon-100; +} + +.prose h1 { + @apply text-h2 font-sans font-thin text-carbon-950 dark:text-mulberry-100 mb-8; +} + +.prose h2 { + @apply text-h3 font-logo text-carbon-950 dark:text-mulberry-200 mb-6 mt-12; +} + +.prose h3 { + @apply text-h4 font-sans text-carbon-950 dark:text-mulberry-300 mb-4 mt-8; +} + +.prose h4 { + @apply text-h5 font-sans text-carbon-800 dark:text-mulberry-400 mb-3 mt-6; +} + +.prose h5 { + @apply text-h6 font-sans text-carbon-700 dark:text-mulberry-500 mb-3 mt-6; +} + +.prose h6 { + @apply text-h7 font-sans text-carbon-600 dark:text-mulberry-600 mb-2 mt-4; +} + +.prose p { + @apply text-base leading-relaxed mb-6 text-carbon-800 dark:text-carbon-200; +} + +.prose a { + @apply text-ocean-600 dark:text-ocean-400 hover:text-ocean-800 dark:hover:text-ocean-300 transition-colors underline decoration-ocean-500/30 hover:decoration-ocean-600/50 dark:hover:decoration-ocean-400/50; +} + +.prose strong { + @apply text-carbon-950 dark:text-carbon-100 font-semibold; +} + +.prose code { + @apply bg-carbon-200 dark:bg-carbon-800 text-eucalyptus-700 dark:text-eucalyptus-400 px-2 py-1 rounded-sm font-mono text-sm; +} + +.prose pre { + @apply bg-carbon-100 dark:bg-carbon-900 border border-carbon-300 dark:border-carbon-700 rounded-lg overflow-x-auto p-4 mb-6; +} + +.prose pre code { + @apply bg-transparent text-carbon-950 dark:text-carbon-200 p-0; +} + +.prose blockquote { + @apply border-l-4 border-carbon-400 dark:border-mulberry-600 pl-6 italic text-carbon-600 dark:text-carbon-300 my-6; +} + +.prose ul { + @apply list-disc pl-6 mb-6 space-y-2; +} + +.prose ol { + @apply list-decimal pl-6 mb-6 space-y-2; +} + +.prose li { + @apply text-carbon-800 dark:text-carbon-200; +} + +/* Blog-specific utilities */ +.blog-container { + @apply max-w-4xl mx-auto px-4 sm:px-6 lg:px-8; +} + +.blog-meta { + @apply text-sm text-carbon-600 dark:text-carbon-500 flex items-center space-x-4; +} + +.blog-tag { + @apply inline-block bg-carbon-200 dark:bg-mulberry-800 text-carbon-700 dark:text-mulberry-200 px-3 py-1 rounded-full text-xs font-medium; +} + +/* Reading progress indicator */ +.reading-progress { + @apply fixed top-0 left-0 w-full h-1 bg-ocean-600 dark:bg-mulberry-600 transform origin-left scale-x-0 transition-transform z-50; +} + +/* Utilities */ +.line-clamp-3 { + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; +} \ No newline at end of file diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 0000000..be4b0ce --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,113 @@ +import type { Metadata } from 'next' +import { Inter, Exo } from 'next/font/google' +import './globals.css' + +const inter = Inter({ + subsets: ['latin'], + variable: '--font-inter', + display: 'swap', +}) + +const exo = Exo({ + subsets: ['latin'], + variable: '--font-exo', + display: 'swap', + weight: ['100', '200', '300', '400', '500', '600', '700', '800', '900'], +}) + +export const metadata: Metadata = { + title: 'CHORUS PING! - Insights on Contextual AI', + description: 'Deep dives into contextual AI orchestration, agent coordination, and the future of intelligent systems.', + keywords: ['contextual AI', 'agent orchestration', 'enterprise AI', 'AI insights', 'technology blog'], + authors: [{ name: 'Anthony Lewis Rawlins', url: 'https://deepblack.cloud' }], + creator: 'Deep Black Cloud', + publisher: 'CHORUS Services', + metadataBase: new URL('https://blog.chorus.services'), + alternates: { + canonical: 'https://blog.chorus.services', + }, + openGraph: { + type: 'website', + locale: 'en_US', + url: 'https://blog.chorus.services', + siteName: 'CHORUS PING!', + title: 'CHORUS PING! - Insights on Contextual AI', + description: 'Deep dives into contextual AI orchestration, agent coordination, and the future of intelligent systems.', + images: [ + { + url: '/logos/logo-ring-only.png', + width: 256, + height: 256, + alt: 'CHORUS Services Logo', + }, + ], + }, + twitter: { + card: 'summary_large_image', + title: 'CHORUS PING! - Insights on Contextual AI', + description: 'Deep dives into contextual AI orchestration, agent coordination, and the future of intelligent systems.', + images: ['/logos/chorus-landscape-on-blue.png'], + }, + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + 'max-video-preview': -1, + 'max-image-preview': 'large', + 'max-snippet': -1, + }, + }, +} + +export default function RootLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + + {/* Google tag (gtag.js) */} + + + + + + + + diff --git a/public/logos/logo-variations-specifications.md b/public/logos/logo-variations-specifications.md new file mode 100644 index 0000000..60cf49f --- /dev/null +++ b/public/logos/logo-variations-specifications.md @@ -0,0 +1,261 @@ +# CHORUS Services Logo Variations & Specifications + +## Overview + +This document provides comprehensive specifications for all CHORUS Services logo variations, ensuring consistent brand presentation across every possible application context. Each variation is optimized for specific use cases while maintaining brand integrity and recognition. + +## Primary Logo Variations + +### 1. Horizontal Layout (Primary) + +#### Full Color Version +- **Usage**: Primary logo for most applications +- **Background**: Carbon Black (#000000) or dark backgrounds +- **Icon Color**: Natural Paper (#F5F5DC) with Orchestration Blue (#007AFF) accent +- **Text Color**: Natural Paper (#F5F5DC) primary, Brushed Aluminum (#C0C0C0) secondary +- **Minimum Size**: 120px width (digital), 1.5" width (print) +- **File Formats**: SVG (preferred), PNG (2x retina), PDF (print) + +#### Reversed Version +- **Usage**: Light backgrounds, print applications, high-contrast needs +- **Background**: Natural Paper (#F5F5DC), White (#FFFFFF), or light backgrounds +- **Icon Color**: Carbon Black (#000000) with Orchestration Blue (#007AFF) accent +- **Text Color**: Carbon Black (#000000) primary, Walnut Brown (#8B4513) secondary +- **Applications**: Business cards, letterhead, light-theme websites + +### 2. Stacked Layout (Vertical) + +#### Full Color Stacked +- **Usage**: Square formats, mobile applications, social media +- **Proportions**: Icon above text, centered alignment +- **Sizing**: Icon 60% of total height, text 40% of total height +- **Minimum Size**: 80px width (digital), 1" width (print) +- **Aspect Ratio**: Approximately 1:1.2 (width:height) + +#### Reversed Stacked +- **Usage**: Light backgrounds in vertical format +- **Color Treatment**: Same as reversed horizontal +- **Applications**: Light-theme mobile apps, print materials with vertical layout + +### 3. Icon-Only Variations + +#### Primary Icon +- **Usage**: Favicons, app icons, navigation elements, profile images +- **Design**: Orchestration symbol only, no text +- **Size Range**: 16px to 512px (digital), 0.25" to 4" (print) +- **Aspect Ratio**: 1:1 (perfect square) +- **Background Treatment**: Transparent or solid brand colors + +#### App Icon Treatment +- **iOS Specifications**: Rounded corners with 20% corner radius +- **Android Specifications**: Rounded corners with 15% corner radius +- **Background**: Solid Carbon Black (#000000) with centered icon +- **Icon Color**: Natural Paper (#F5F5DC) with Orchestration Blue accent +- **Required Sizes**: 16, 32, 48, 64, 128, 256, 512px + +#### Favicon Specifications +- **Size**: 16x16px, 32x32px, 48x48px +- **Format**: ICO file with multiple resolutions +- **Design**: Simplified orchestration symbol +- **Color**: High contrast version optimized for small display +- **Background**: Transparent + +## Monochrome Variations + +### 1. Black Version +- **Color**: All elements in Carbon Black (#000000) +- **Usage**: Single-color printing, embossing, engraving +- **Background**: White or Natural Paper only +- **Applications**: Letterhead, business cards, cost-effective printing + +### 2. White Version +- **Color**: All elements in Natural Paper (#F5F5DC) or White (#FFFFFF) +- **Usage**: Dark backgrounds, reversed applications +- **Applications**: Dark websites, presentations, merchandise + +### 3. Single Brand Color +- **Orchestration Blue**: All elements in #007AFF +- **Usage**: Branded merchandise, promotional materials +- **Background**: White, Natural Paper, or transparent +- **Applications**: T-shirts, promotional items, digital watermarks + +## Specialized Context Variations + +### 1. Watermark Version +- **Opacity**: 15-25% transparency +- **Usage**: Document backgrounds, presentation slides +- **Size**: Large format, subtle presence +- **Color**: Single color with reduced opacity +- **Placement**: Off-center, non-interfering with content + +### 2. Print Newspaper/Magazine +- **Design**: High contrast, simplified details +- **Color**: Black only for newspaper, spot color for magazines +- **Size**: Minimum legible size for publication standards +- **Format**: Vector format with outlined fonts + +### 3. Embroidery Specifications +- **Design**: Simplified orchestration symbol +- **Stitch Count**: Optimized for production efficiency +- **Size Range**: 0.75" to 4" width +- **Colors**: Maximum 3 thread colors +- **Background**: None (direct on fabric) + +### 4. Engraving/Etching +- **Design**: Line art version of orchestration symbol +- **Detail Level**: Simplified for engraving depth limitations +- **Applications**: Awards, plaques, metal products +- **File Format**: Vector outlines, no fills + +## Digital-Specific Variations + +### 1. Animated Logo (Digital Only) +- **Animation**: Subtle orchestration symbol rotation or pulse +- **Duration**: 2-3 seconds, smooth loop +- **Usage**: Website loading, video intros +- **Format**: SVG animation, GIF fallback +- **File Size**: Optimized for web performance + +### 2. Social Media Profile Variations + +#### LinkedIn Profile +- **Size**: 300x300px minimum +- **Format**: PNG with transparent background +- **Version**: Icon-only with high contrast + +#### Twitter/X Profile +- **Size**: 400x400px recommended +- **Format**: PNG or JPG +- **Version**: Icon-only, optimized for small display + +#### Facebook Profile +- **Size**: 180x180px minimum +- **Format**: PNG recommended +- **Version**: Icon-only or simplified horizontal + +#### Instagram Profile +- **Size**: 320x320px minimum +- **Format**: PNG recommended +- **Version**: Icon-only with brand colors + +### 3. Email Signature Specifications +- **Size**: 120px width maximum +- **Format**: PNG (Retina 2x resolution) +- **Version**: Horizontal layout preferred +- **Linking**: Clickable link to website homepage +- **Alt Text**: "CHORUS Services - Distributed AI Orchestration" + +## Technical Implementation Specifications + +### SVG Code Structure +svg + + CHORUS Services Logo + + + + + + + + + CHORUS + Services + + + + +### CSS Implementation +css +.chorus-logo { + display: inline-block; + max-width: 100%; + height: auto; +} + +.chorus-logo--horizontal { + aspect-ratio: 4/1; + min-width: 120px; +} + +.chorus-logo--stacked { + aspect-ratio: 1/1.2; + min-width: 80px; +} + +.chorus-logo--icon-only { + aspect-ratio: 1/1; + min-width: 32px; +} + +/* Responsive sizing */ +@media (max-width: 768px) { + .chorus-logo--horizontal { + min-width: 100px; + } +} + + +### File Naming Convention + +chorus-logo-horizontal-color.svg +chorus-logo-horizontal-reversed.svg +chorus-logo-stacked-color.png +chorus-logo-icon-only-white.svg +chorus-logo-monochrome-black.pdf + + +## Quality Assurance Checklist + +### Before Production +- [ ] Logo meets minimum size requirements for intended application +- [ ] Color contrast tested for accessibility compliance (WCAG 2.1 AA) +- [ ] File format appropriate for intended use (vector vs. raster) +- [ ] Resolution sufficient for intended output (72 DPI web, 300 DPI print) +- [ ] Colors match brand specifications exactly +- [ ] Typography rendering correctly at all sizes +- [ ] Clear space maintained around logo +- [ ] Alternative text or descriptions provided for accessibility + +### After Production +- [ ] Logo displays correctly across different devices and browsers +- [ ] Print test completed for physical applications +- [ ] File sizes optimized for web performance +- [ ] Backup formats available for compatibility +- [ ] Usage rights and approvals documented +- [ ] Brand guidelines compliance verified + +## Approval Process + +### Internal Review +1. **Brand Manager**: Visual consistency and brand compliance +2. **Design Lead**: Technical quality and implementation feasibility +3. **Marketing Director**: Strategic alignment and marketing effectiveness +4. **Legal Review**: Trademark compliance and usage rights + +### External Applications +1. **Partner Usage**: Requires brand license agreement and approval +2. **Media Usage**: Provide official logo package with usage guidelines +3. **Vendor Applications**: Review and approve before production +4. **International Usage**: Cultural sensitivity review when applicable + +## Logo Package Contents + +### Standard Logo Package +- Horizontal color version (SVG, PNG 2x, PDF) +- Horizontal reversed version (SVG, PNG 2x, PDF) +- Stacked color version (SVG, PNG 2x) +- Icon-only versions (SVG, PNG 2x, ICO) +- Monochrome versions (SVG, PNG, PDF) +- Usage guidelines summary (PDF) + +### Extended Logo Package +- All standard package contents +- Animated versions (SVG, GIF) +- Social media optimized versions +- Print-specific versions (high-resolution) +- Component integration examples +- Brand color swatches (ASE, ACO, CSS) +- Typography files and licenses + +This comprehensive logo variation system ensures CHORUS Services maintains consistent, professional brand presentation across every possible application while providing the flexibility needed for diverse marketing and communication contexts. \ No newline at end of file diff --git a/public/logos/logo.html b/public/logos/logo.html new file mode 100644 index 0000000..926aecc --- /dev/null +++ b/public/logos/logo.html @@ -0,0 +1,245 @@ + + + + + CHORUS Möbius Strip + + + + + + + + + + + + + diff --git a/public/logos/logo.png b/public/logos/logo.png new file mode 100644 index 0000000..6aaab3e Binary files /dev/null and b/public/logos/logo.png differ diff --git a/public/logos/mobius-ring.blend b/public/logos/mobius-ring.blend new file mode 100644 index 0000000..2d31aa8 Binary files /dev/null and b/public/logos/mobius-ring.blend differ diff --git a/public/logos/mobius-ring.glb b/public/logos/mobius-ring.glb new file mode 100644 index 0000000..7ff811a Binary files /dev/null and b/public/logos/mobius-ring.glb differ diff --git a/public/logos/moebius-ring.blend b/public/logos/moebius-ring.blend new file mode 100644 index 0000000..c013c93 Binary files /dev/null and b/public/logos/moebius-ring.blend differ diff --git a/scheduled/README.md b/scheduled/README.md new file mode 100644 index 0000000..6c66349 --- /dev/null +++ b/scheduled/README.md @@ -0,0 +1,58 @@ +# Scheduled Posts + +This directory contains blog posts that are scheduled for future publication. + +## Directory Structure + +``` +scheduled/ +├── 2024/ +│ ├── 01/ +│ ├── 02/ +│ └── ... +├── 2025/ +│ ├── 01/ +│ ├── 02/ +│ └── ... +└── README.md +``` + +## File Naming Convention + +Posts should be named with the format: `YYYY-MM-DD-slug.md` + +Example: `2024-03-15-understanding-ai-agents.md` + +## Frontmatter Format + +Each scheduled post should include the following frontmatter: + +```yaml +--- +title: "Your Post Title" +description: "Brief description of the post" +date: "2024-03-15" +publishDate: "2024-03-15T09:00:00.000Z" +author: + name: "Author Name" + role: "Author Role" +tags: + - "tag1" + - "tag2" +featured: false +draft: false +--- +``` + +## Publishing Process + +1. Write your post in the appropriate scheduled directory +2. Set the `publishDate` to when you want it published +3. A scheduled job will move posts from `scheduled/` to `posts/` when their publish date arrives +4. The blog will automatically pick up the new post and display it + +## Notes + +- Posts in this directory are not visible on the live blog until moved to `posts/` +- Use `draft: true` for posts that are work-in-progress +- The `publishDate` field determines when the post goes live \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..533fe3c --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,268 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + './pages/**/*.{js,ts,jsx,tsx,mdx}', + './components/**/*.{js,ts,jsx,tsx,mdx}', + './app/**/*.{js,ts,jsx,tsx,mdx}', + ], + darkMode: 'class', + theme: { + extend: { + colors: { + // Core Brand Colors + 'carbon': { + 950: '#000000', + 900: '#0a0a0a', + 800: '#1a1a1a', + 700: '#2a2a2a', + 600: '#666666', + 500: '#808080', + 400: '#a0a0a0', + 300: '#c0c0c0', + 200: '#e0e0e0', + 100: '#f0f0f0', + 50: '#f8f8f8' + }, + 'mulberry': { + 950: '#0b0213', + 900: '#1a1426', + 800: '#2a2639', + 700: '#3a384c', + 600: '#4a4a5f', + 500: '#5a5c72', + 400: '#7a7e95', + 300: '#9aa0b8', + 200: '#bac2db', + 100: '#dae4fe', + 50: '#f0f4ff' + }, + 'walnut': { + 950: '#1E1815', + 900: '#403730', + 800: '#504743', + 700: '#605756', + 600: '#706769', + 500: '#80777c', + 400: '#90878f', + 300: '#a09aa2', + 200: '#b0adb5', + 100: '#c0c0c8', + 50: '#d0d3db', + 25: '#e0e6ee' + }, + 'nickel': { + 950: '#171717', + 900: '#2a2a2a', + 800: '#3d3d3d', + 700: '#505050', + 600: '#636363', + 500: '#767676', + 400: '#c1bfb1', + 300: '#d4d2c6', + 200: '#e7e5db', + 100: '#faf8f0', + 50: '#fdfcf8' + }, + // System Colors + 'ocean': { + 950: '#2a3441', + 900: '#3a4654', + 800: '#4a5867', + 700: '#5a6c80', + 600: '#6a7e99', + 500: '#7a90b2', + 400: '#8ba3c4', + 300: '#9bb6d6', + 200: '#abc9e8', + 100: '#bbdcfa', + 50: '#cbefff' + }, + 'eucalyptus': { + 950: '#2a3330', + 900: '#3a4540', + 800: '#4a5750', + 700: '#515d54', + 600: '#5a6964', + 500: '#6a7974', + 400: '#7a8a7f', + 300: '#8a9b8f', + 200: '#9aac9f', + 100: '#aabdaf', + 50: '#bacfbf' + }, + 'sand': { + 950: '#8E7B5E', + 900: '#99886E', + 800: '#A4957E', + 700: '#AFA28E', + 600: '#BAAF9F', + 500: '#C5BCAF', + 400: '#D0C9BF', + 300: '#DBD6CF', + 200: '#E6E3DF', + 100: '#F1F0EF', + 50: '#F1F0EF', + }, + 'coral': { + 950: '#6A4A48', + 900: '#7B5D5A', + 800: '#8C706C', + 700: '#9D8380', + 600: '#AE9693', + 500: '#BFAAA7', + 400: '#D0BDBB', + 300: '#E1D1CF', + 200: '#F2E4E3', + 100: '#9e979c', + 50: '#aea7ac' + } + }, + fontFamily: { + sans: ['var(--font-inter)', 'Inter Tight', 'Inter', 'system-ui', 'sans-serif'], + mono: ['Inconsolata', 'ui-monospace', 'monospace'], + logo: ['var(--font-exo)', 'Exo', 'Inter Tight', 'sans-serif'] + }, + spacing: { + 'chorus-xxs': '0.854rem', + 'chorus-xs': '0.945rem', + 'chorus-sm': '1.0rem', + 'chorus-base': '1.25rem', + 'chorus-md': '1.953rem', + 'chorus-lg': '2.441rem', + 'chorus-xl': '3.052rem', + 'chorus-xxl': '6.1rem', + }, + fontSize: { + 'xs': ['0.854rem', { lineHeight: '1.00rem', fontWeight: '600' }], + 'sm': ['0.954rem', { lineHeight: '1.10rem', fontWeight: '500' }], + 'base': ['1rem', { lineHeight: '1.50rem', fontWeight: '400' }], + 'lg': ['1.25rem', { lineHeight: '1.75rem', fontWeight: '400' }], + 'xl': ['1.563rem', { lineHeight: '2.00rem', fontWeight: '400' }], + '2xl': ['1.953rem', { lineHeight: '2.50rem', fontWeight: '300' }], + '3xl': ['2.441rem', { lineHeight: '3.00rem', fontWeight: '200' }], + '4xl': ['3.052rem', { lineHeight: '3.50rem', fontWeight: '100' }], + '5xl': ['3.815rem', { lineHeight: '4.00rem', fontWeight: '100' }], + 'h7': ['1.000rem', { lineHeight: '1.25rem', fontWeight: '400' }], + 'h6': ['1.250rem', { lineHeight: '1.563rem', fontWeight: '500' }], + 'h5': ['1.563rem', { lineHeight: '1.953rem', fontWeight: '500' }], + 'h4': ['1.953rem', { lineHeight: '2.441rem', fontWeight: '600' }], + 'h3': ['2.441rem', { lineHeight: '3.052rem', fontWeight: '600' }], + 'h2': ['3.052rem', { lineHeight: '4.768rem', fontWeight: '700' }], + 'h1': ['4.768rem', { lineHeight: '6.96rem', fontWeight: '100' }], + 'display-sm': ['3.815rem', { lineHeight: '4rem', fontWeight: '800' }], + 'display-md': ['4.768rem', { lineHeight: '5rem', fontWeight: '800' }], + 'display-lg': ['5.96rem', { lineHeight: '6rem', fontWeight: '800' }], + }, + width: { + 'rem-xs': '0.640rem', + 'rem-sm': '0.800rem', + 'rem-base': '1.000rem', + 'rem-lg': '1.250rem', + 'rem-xl': '1.563rem', + 'rem-2xl': '1.953rem', + 'rem-3xl': '2.441rem', + 'rem-4xl': '3.052rem', + 'rem-5xl': '3.815rem', + }, + height: { + 'rem-xs': '0.640rem', + 'rem-sm': '0.800rem', + 'rem-base': '1.000rem', + 'rem-lg': '1.250rem', + 'rem-xl': '1.563rem', + 'rem-2xl': '1.953rem', + 'rem-3xl': '2.441rem', + 'rem-4xl': '3.052rem', + 'rem-5xl': '3.815rem', + }, + borderRadius: { + 'none': '0', + 'micro': '0.125rem', + 'sm': '0.25rem', + 'base': '0.375rem', + 'md': '0.5rem', + 'lg': '0.75rem', + 'xl': '1rem', + 'full': '9999px', + }, + animation: { + 'fade-in': 'fadeIn 0.6s ease-out', + 'slide-up': 'slideUp 0.8s ease-out', + 'mobius-rotate': 'mobiusRotate 20s linear infinite', + }, + keyframes: { + fadeIn: { + '0%': { opacity: '0' }, + '100%': { opacity: '1' }, + }, + slideUp: { + '0%': { opacity: '0', transform: 'translateY(2rem)' }, + '100%': { opacity: '1', transform: 'translateY(0)' }, + }, + mobiusRotate: { + '0%': { transform: 'rotateY(0deg) rotateX(10deg)' }, + '100%': { transform: 'rotateY(360deg) rotateX(10deg)' }, + }, + }, + }, + }, + plugins: [ + require('@tailwindcss/typography'), + function({ addUtilities }) { + addUtilities({ + // H7 Utility Class + '.h7': { + fontSize: '0.8rem', + lineHeight: '1.25rem', + fontWeight: '700', + letterSpacing: '0.05em', + textTransform: 'uppercase' + }, + + // Complete H1-H7 Typography Utilities + '.text-h1': { + fontSize: '4.768rem', + lineHeight: '6.96rem', + fontWeight: '100', + fontFamily: 'var(--font-inter), Inter Tight, sans-serif' + }, + '.text-h2': { + fontSize: '3.052rem', + lineHeight: '4.768rem', + fontWeight: '700', + fontFamily: 'var(--font-exo), Exo, Inter Tight, sans-serif' + }, + '.text-h3': { + fontSize: '2.441rem', + lineHeight: '3.052rem', + fontWeight: '600', + fontFamily: 'var(--font-inter), Inter Tight, sans-serif' + }, + '.text-h4': { + fontSize: '1.953rem', + lineHeight: '2.441rem', + fontWeight: '600', + fontFamily: 'var(--font-inter), Inter Tight, sans-serif' + }, + '.text-h5': { + fontSize: '1.563rem', + lineHeight: '1.953rem', + fontWeight: '500', + fontFamily: 'var(--font-inter), Inter Tight, sans-serif' + }, + '.text-h6': { + fontSize: '1.250rem', + lineHeight: '1.563rem', + fontWeight: '500', + fontFamily: 'var(--font-inter), Inter Tight, sans-serif' + }, + '.text-h7': { + fontSize: '1.000rem', + lineHeight: '1.25rem', + fontWeight: '400', + fontFamily: 'var(--font-inter), Inter Tight, sans-serif' + } + }) + } + ], +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..46512d5 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "es6"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "baseUrl": ".", + "paths": { + "@/*": ["./*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} \ No newline at end of file diff --git a/types/blog.ts b/types/blog.ts new file mode 100644 index 0000000..c7b48c6 --- /dev/null +++ b/types/blog.ts @@ -0,0 +1,30 @@ +export interface BlogPost { + slug: string + title: string + description: string + content: string + date: string + author: { + name: string + avatar?: string + role?: string + } + tags: string[] + featured?: boolean + coverImage?: string + readingTime: number +} + +export interface BlogMeta { + title: string + description: string + date: string + author: { + name: string + avatar?: string + role?: string + } + tags: string[] + featured?: boolean + coverImage?: string +} \ No newline at end of file