Replace "FastNext" branding with "PragmaStack" across the project

- Updated all references, metadata, and templates to reflect the new branding, including layout files, components, and documentation.
- Replaced hardcoded color tokens like `green-600` with semantic tokens (`success`, `warning`, etc.) for improved design consistency.
- Enhanced `globals.css` with new color tokens for success, warning, and destructive states using the OKLCH color model.
- Added comprehensive branding guidelines and updated the design system documentation to align with the new identity.
- Updated tests and mocks to reflect the branding changes and ensured all visual/verbal references match "PragmaStack".
- Added new `branding/README.md` and `branding` docs for mission, values, and visual identity definition.
This commit is contained in:
Felipe Cardoso
2025-11-20 12:55:30 +01:00
parent 5a21847382
commit 28b1cc6e48
34 changed files with 191 additions and 62 deletions

View File

@@ -1,6 +1,6 @@
# FastNext Template - Frontend
# PragmaStack - Frontend
Production-ready Next.js 15 frontend with TypeScript, authentication, admin panel, and internationalization.
Production-ready Next.js 16 frontend with TypeScript, authentication, admin panel, and internationalization.
## Features

View File

@@ -1,6 +1,6 @@
# Internationalization (i18n) Guide
This document describes the internationalization implementation in the FastNext Template.
This document describes the internationalization implementation in the PragmaStack.
## Overview

View File

@@ -0,0 +1,31 @@
# Brand Values & Mission
## Mission Statement
To empower developers to build beautiful, high-performance web applications with **pragmatic speed** and confidence. We provide a solid, opinionated foundation that solves real-world problems without over-engineering, ensuring you ship faster and scale better.
## Core Values
### 1. Pragmatic Speed ⚡
We value efficiency in both development and runtime performance. Our tools are designed to get you from idea to production as fast as possible, focusing on shipping value rather than just raw metrics.
### 2. Quality 💎
We don't cut corners. We believe in semantic HTML, accessible interfaces, and robust type safety. "It works" is not enough; it must be "it works beautifully."
### 3. Pragmatic Clarity 🔍
We prefer explicit over implicit. Our code and documentation prioritize readability and practical utility over clever abstractions. We avoid "magic" to ensure easy debugging and extension.
### 4. Aesthetics 🎨
We believe that good design is not an afterthought. It is integral to the user experience. We strive for a modern, clean, and professional look that inspires trust.
### 5. Security & Robustness 🛡️
We build for the real world. Our solutions are secure by default and robust enough to handle production workloads. We prioritize data protection and system stability above all else.
## Brand Voice
- **Professional but approachable**: We are experts, but we are also helpful colleagues.
- **Concise and direct**: We value your time. We get straight to the point.
- **Encouraging**: We believe you can build great things.
## Target Audience
- Full-stack developers who want a robust starting point.
- Frontend engineers who care about design systems and accessibility.
- Startups and solopreneurs looking to launch quickly.

View File

@@ -0,0 +1,37 @@
# Visual Identity
## Logo & Iconography
*Pending logo design.*
For now, we use the **Lucide React** icon set for all iconography. Icons should be used sparingly and meaningfully to enhance understanding, not just for decoration.
## Color Palette
Our color palette is derived from the **Modern Minimal** theme using the **OKLCH** color space for perceptual uniformity.
### Primary Colors
- **Primary Blue**: `oklch(0.6231 0.188 259.8145)` - Used for main actions, branding elements, and active states.
- **Background**: `oklch(1 0 0)` (Light) / `oklch(0.2046 0 0)` (Dark) - Clean, neutral backgrounds.
### Usage Guidelines
- **Dominant**: Neutral backgrounds and text (Foreground, Card, Muted).
- **Accent**: Primary Blue for calls to action.
- **Functional**: Destructive Red for errors, Success Green (custom) for success states.
> [!NOTE]
> For the full technical specification of color tokens, refer to the [Design System Foundations](../design-system/01-foundations.md#color-system-oklch).
## Typography
We use **Geist Sans** for headings and body text, and **Geist Mono** for code.
### Type Hierarchy
- **Headings**: Bold, tight tracking.
- **Body**: Regular weight, comfortable reading line height.
- **Code**: Monospaced, slightly smaller than body text.
> [!NOTE]
> For the full typography scale and usage, refer to the [Design System Foundations](../design-system/01-foundations.md#typography).
## Imagery & Graphics
- **Style**: Clean, modern, minimal.
- **Screenshots**: Use consistent padding and shadows (refer to `shadow-lg` or `shadow-xl`).
- **Illustrations**: Avoid generic stock photos. Use abstract geometric shapes or high-quality interface representations.

View File

@@ -0,0 +1,14 @@
# Branding Guidelines
Welcome to the **PragmaStack** branding guidelines. This section defines who we are, how we speak, and how we look.
## Contents
- **[01. Brand Values & Mission](./01-brand-values.md)** - Our core principles and voice.
- **[02. Visual Identity](./02-visual-identity.md)** - Logo, colors, and typography usage.
## Relationship with Design System
While these branding guidelines define the *soul* and *identity* of the project, the **[Design System](../design-system/README.md)** provides the *technical implementation* and *components* to build it.
- **Branding**: "Why we use this blue."
- **Design System**: "How to use the `bg-primary` class."

View File

@@ -1,6 +1,6 @@
# Quick Start Guide
Get up and running with the FastNext design system immediately. This guide covers the essential patterns you need to build 80% of interfaces.
Get up and running with the PragmaStack design system immediately. This guide covers the essential patterns you need to build 80% of interfaces.
---

View File

@@ -38,6 +38,11 @@
---
---
> [!NOTE]
> **Branding vs. Design System**: These foundations implement the visual identity defined in the **[Branding Guidelines](../branding/README.md)**. Refer to that document for the "why" behind these choices.
## Color System (OKLCH)
### Why OKLCH?
@@ -228,6 +233,32 @@ All colors follow the **background/foreground** convention:
// Delete button
<Button variant="destructive">Delete Account</Button>
---
### Success & Warning Colors
**Purpose**: Success states and warning alerts
```css
/* Light & Dark Mode */
--success: oklch(0.6231 0.188 145) /* Green */
--success-foreground: oklch(1 0 0) /* White text */
--warning: oklch(0.75 0.15 85) /* Yellow/Orange */
--warning-foreground: oklch(0.1529 0 0) /* Dark text */
```
**Usage**:
```tsx
// Success badge
<Badge className="bg-success text-success-foreground">Completed</Badge>
// Warning alert
<div className="bg-warning text-warning-foreground p-4">
Warning: This action is irreversible.
</div>
```
// Error alert
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />

View File

@@ -1,6 +1,6 @@
# AI Code Generation Guidelines
**For AI Assistants**: This document contains strict rules for generating code in the FastNext Template project. Follow these rules to ensure generated code matches the design system perfectly.
**For AI Assistants**: This document contains strict rules for generating code in the PragmaStack project. Follow these rules to ensure generated code matches the design system perfectly.
---

View File

@@ -1,6 +1,6 @@
# Quick Reference
**Bookmark this page** for instant lookups of colors, spacing, typography, components, and common patterns. Your go-to cheat sheet for the FastNext design system.
**Bookmark this page** for instant lookups of colors, spacing, typography, components, and common patterns. Your go-to cheat sheet for the PragmaStack design system.
---

View File

@@ -1,6 +1,6 @@
# Design System Documentation
**FastNext Template Design System** - A comprehensive guide to building consistent, accessible, and beautiful user interfaces.
**PragmaStack Design System** - A comprehensive guide to building consistent, accessible, and beautiful user interfaces.
---
@@ -19,6 +19,11 @@
## 📖 Documentation Structure
### Branding & Identity
- **[Branding Guidelines](../branding/README.md)** 🎨
- Mission & Values
- Visual Identity (Logo, Colors, Typography)
### Getting Started
- **[00. Quick Start](./00-quick-start.md)** ⚡

View File

@@ -14,7 +14,7 @@ test.describe('Homepage - Desktop Navigation', () => {
test('should display header with logo and navigation', async ({ page }) => {
// Logo should be visible
await expect(page.getByRole('link', { name: /FastNext/i })).toBeVisible();
await expect(page.getByRole('link', { name: /PragmaStack/i })).toBeVisible();
// Desktop navigation links should be visible (use locator to find within header)
const header = page.locator('header').first();
@@ -40,7 +40,7 @@ test.describe('Homepage - Desktop Navigation', () => {
// Click and wait for navigation
await designSystemLink.click();
await page.waitForURL('/en/dev', { timeout: 10000 }).catch(() => {});
await page.waitForURL('/en/dev', { timeout: 10000 }).catch(() => { });
// Verify URL (might not navigate if /dev page has issues, that's ok for this test)
const currentUrl = page.url();
@@ -58,7 +58,7 @@ test.describe('Homepage - Desktop Navigation', () => {
// Click and wait for navigation
await adminLink.click();
await page.waitForURL('/en/admin', { timeout: 10000 }).catch(() => {});
await page.waitForURL('/en/admin', { timeout: 10000 }).catch(() => { });
// Verify URL (might not navigate if /admin requires auth, that's ok for this test)
const currentUrl = page.url();
@@ -150,7 +150,7 @@ test.describe('Homepage - Mobile Menu Interactions', () => {
// Click and wait for navigation
await componentsLink.click();
await page.waitForURL('/en/dev', { timeout: 10000 }).catch(() => {});
await page.waitForURL('/en/dev', { timeout: 10000 }).catch(() => { });
// Verify URL (might not navigate if /dev page has issues, that's ok)
const currentUrl = page.url();
@@ -168,7 +168,7 @@ test.describe('Homepage - Mobile Menu Interactions', () => {
// Click and wait for navigation
await adminLink.click();
await page.waitForURL('/en/admin', { timeout: 10000 }).catch(() => {});
await page.waitForURL('/en/admin', { timeout: 10000 }).catch(() => { });
// Verify URL (might not navigate if /admin requires auth, that's ok)
const currentUrl = page.url();
@@ -259,7 +259,7 @@ test.describe('Homepage - Hero Section', () => {
// Click and try to navigate
await exploreLink.click();
await page.waitForURL('/en/dev', { timeout: 10000 }).catch(() => {});
await page.waitForURL('/en/dev', { timeout: 10000 }).catch(() => { });
// Verify URL (flexible to handle auth redirects)
const currentUrl = page.url();
@@ -391,7 +391,7 @@ test.describe('Homepage - Animated Terminal', () => {
// Click and try to navigate
await terminalDemoLink.click();
await page.waitForURL('/en/login', { timeout: 10000 }).catch(() => {});
await page.waitForURL('/en/login', { timeout: 10000 }).catch(() => { });
// Verify URL (flexible to handle redirects)
const currentUrl = page.url();
@@ -421,7 +421,7 @@ test.describe('Homepage - Feature Sections', () => {
// Click and try to navigate
await authLink.click();
await page.waitForURL('/en/login', { timeout: 10000 }).catch(() => {});
await page.waitForURL('/en/login', { timeout: 10000 }).catch(() => { });
// Verify URL (flexible to handle redirects)
const currentUrl = page.url();
@@ -436,7 +436,7 @@ test.describe('Homepage - Feature Sections', () => {
// Click and try to navigate
await adminLink.click();
await page.waitForURL('/en/admin', { timeout: 10000 }).catch(() => {});
await page.waitForURL('/en/admin', { timeout: 10000 }).catch(() => { });
// Verify URL (flexible to handle auth redirects)
const currentUrl = page.url();
@@ -469,7 +469,7 @@ test.describe('Homepage - Footer', () => {
// Scroll to footer
await page.locator('footer').scrollIntoViewIfNeeded();
await expect(page.getByText(/FastNext Template. MIT Licensed/i)).toBeVisible();
await expect(page.getByText(/PragmaStack. MIT Licensed/i)).toBeVisible();
});
});

View File

@@ -10,7 +10,7 @@ import { Footer } from '@/components/layout/Footer';
export const metadata: Metadata = {
title: {
template: '%s | FastNext Template',
template: '%s | PragmaStack',
default: 'Dashboard',
},
};

View File

@@ -12,7 +12,7 @@ import { AdminSidebar, Breadcrumbs } from '@/components/admin';
export const metadata: Metadata = {
title: {
template: '%s | Admin | FastNext Template',
template: '%s | Admin | PragmaStack',
default: 'Admin Dashboard',
},
};

View File

@@ -26,9 +26,9 @@ import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
export const metadata: Metadata = {
title: 'Demo Tour | FastNext Template',
title: 'Demo Tour | PragmaStack',
description:
'Try all features with demo credentials - comprehensive guide to the FastNext template',
'Try all features with demo credentials - comprehensive guide to the PragmaStack',
};
const demoCategories = [

View File

@@ -120,7 +120,7 @@ export default function DocsHub() {
<h2 className="text-4xl font-bold tracking-tight mb-4">Design System Documentation</h2>
<p className="text-lg text-muted-foreground mb-8">
Comprehensive guides, best practices, and references for building consistent,
accessible, and maintainable user interfaces with the FastNext design system.
accessible, and maintainable user interfaces with the PragmaStack design system.
</p>
<div className="flex flex-wrap gap-3 justify-center">
<Link href="/dev/docs/design-system/00-quick-start">

View File

@@ -14,7 +14,7 @@ import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
export const metadata: Metadata = {
title: 'Design System Hub | FastNext Template',
title: 'Design System Hub | PragmaStack',
description:
'Interactive design system demonstrations with live examples - explore components, layouts, spacing, and forms built with shadcn/ui and Tailwind CSS',
};
@@ -90,7 +90,7 @@ export default function DesignSystemHub() {
</div>
<p className="text-lg text-muted-foreground">
Interactive demonstrations, live examples, and comprehensive documentation for the
FastNext design system. Built with shadcn/ui + Tailwind CSS 4.
PragmaStack design system. Built with shadcn/ui + Tailwind CSS 4.
</p>
</div>
</div>

View File

@@ -1,6 +1,6 @@
/**
* Homepage / Landing Page
* Main landing page for the FastNext Template project
* Main landing page for the PragmaStack project
* Showcases features, tech stack, and provides demos for developers
*/
@@ -67,7 +67,7 @@ export default function Home() {
<div className="container mx-auto px-6 py-8">
<div className="flex flex-col md:flex-row items-center justify-between gap-4">
<div className="text-sm text-muted-foreground">
© {new Date().getFullYear()} FastNext Template. MIT Licensed.
© {new Date().getFullYear()} PragmaStack. MIT Licensed.
</div>
<div className="flex items-center gap-6 text-sm text-muted-foreground">
<Link href="/demos" className="hover:text-foreground transition-colors">

View File

@@ -1,7 +1,7 @@
@import 'tailwindcss';
/**
* FastNext Template Design System
* PragmaStack Design System
* Theme: Modern Minimal (from tweakcn.com)
* Primary: Blue | Color Space: OKLCH
*
@@ -27,6 +27,10 @@
--accent-foreground: oklch(0.3791 0.1378 265.5222);
--destructive: oklch(0.6368 0.2078 25.3313);
--destructive-foreground: oklch(1 0 0);
--success: oklch(0.6231 0.188 145);
--success-foreground: oklch(1 0 0);
--warning: oklch(0.75 0.15 85);
--warning-foreground: oklch(0.1529 0 0);
--border: oklch(0.9276 0.0058 264.5313);
--input: oklch(0.9276 0.0058 264.5313);
--ring: oklch(0.6231 0.188 259.8145);
@@ -91,6 +95,10 @@
--accent-foreground: oklch(0.8823 0.0571 254.1284);
--destructive: oklch(0.6368 0.2078 25.3313);
--destructive-foreground: oklch(1 0 0);
--success: oklch(0.6231 0.188 145);
--success-foreground: oklch(1 0 0);
--warning: oklch(0.75 0.15 85);
--warning-foreground: oklch(0.1529 0 0);
--border: oklch(0.3715 0 0);
--input: oklch(0.3715 0 0);
--ring: oklch(0.6231 0.188 259.8145);
@@ -127,6 +135,10 @@
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
@@ -206,4 +218,4 @@ button:disabled,
a[aria-disabled='true'],
select:disabled {
cursor: not-allowed;
}
}

View File

@@ -95,7 +95,7 @@ export function DevLayout({ children }: DevLayoutProps) {
{/* Left: Logo + Badge */}
<div className="flex items-center gap-3 shrink-0">
<Code2 className="h-5 w-5 text-primary" />
<h1 className="text-base font-semibold">FastNext</h1>
<h1 className="text-base font-semibold">PragmaStack</h1>
<Badge variant="secondary" className="text-xs">
Dev
</Badge>

View File

@@ -83,9 +83,9 @@ export function AnimatedTerminal() {
{/* Terminal Header */}
<div className="flex items-center gap-2 border-b bg-muted/50 px-4 py-3">
<div className="flex gap-1.5">
<div className="h-3 w-3 rounded-full bg-red-500" aria-hidden="true" />
<div className="h-3 w-3 rounded-full bg-yellow-500" aria-hidden="true" />
<div className="h-3 w-3 rounded-full bg-green-500" aria-hidden="true" />
<div className="h-3 w-3 rounded-full bg-destructive" aria-hidden="true" />
<div className="h-3 w-3 rounded-full bg-warning" aria-hidden="true" />
<div className="h-3 w-3 rounded-full bg-success" aria-hidden="true" />
</div>
<div className="flex items-center gap-2 ml-4 text-sm text-muted-foreground">
<Terminal className="h-4 w-4" aria-hidden="true" />
@@ -105,15 +105,14 @@ export function AnimatedTerminal() {
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.2 }}
className={`${
line.isSuccess
? 'text-green-400'
className={`${line.isSuccess
? 'text-success'
: line.text.startsWith('#')
? 'text-slate-500'
: line.text.startsWith('$')
? 'text-blue-400'
? 'text-primary'
: 'text-slate-300'
}`}
}`}
>
{line.text || '\u00A0'}
{index === displayedLines.length - 1 && isAnimating && !line.isSuccess && (

View File

@@ -45,7 +45,7 @@ export function ContextSection() {
viewport={{ once: true }}
transition={{ duration: 0.3, delay: index * 0.1 }}
>
<CheckCircle2 className="h-4 w-4 text-green-600" aria-hidden="true" />
<CheckCircle2 className="h-4 w-4 text-success" aria-hidden="true" />
<span>{feature}</span>
</motion.div>
))}

View File

@@ -68,7 +68,7 @@ export function DemoCredentialsModal({ open, onClose }: DemoCredentialsModalProp
className="h-8 gap-2"
>
{copiedRegular ? (
<Check className="h-4 w-4 text-green-600" aria-hidden="true" />
<Check className="h-4 w-4 text-success" aria-hidden="true" />
) : (
<Copy className="h-4 w-4" aria-hidden="true" />
)}
@@ -108,7 +108,7 @@ export function DemoCredentialsModal({ open, onClose }: DemoCredentialsModalProp
className="h-8 gap-2"
>
{copiedAdmin ? (
<Check className="h-4 w-4 text-green-600" aria-hidden="true" />
<Check className="h-4 w-4 text-success" aria-hidden="true" />
) : (
<Copy className="h-4 w-4" aria-hidden="true" />
)}

View File

@@ -32,7 +32,7 @@ export function Header({ onOpenDemoModal }: HeaderProps) {
{/* Logo */}
<Link href="/" className="font-bold text-xl hover:opacity-80 transition-opacity">
<span className="bg-gradient-to-r from-primary to-primary/60 bg-clip-text text-transparent">
FastNext
PragmaStack
</span>{' '}
<span className="text-foreground">Template</span>
</Link>

View File

@@ -41,7 +41,7 @@ export function HeroSection({ onOpenDemoModal }: HeroSectionProps) {
>
<div className="inline-flex items-center gap-2 rounded-full border bg-background/50 px-4 py-1.5 text-sm backdrop-blur">
<span
className="inline-block h-2 w-2 rounded-full bg-green-500 animate-pulse"
className="inline-block h-2 w-2 rounded-full bg-success animate-pulse"
aria-hidden="true"
/>
<span className="font-medium">MIT Licensed</span>

View File

@@ -58,13 +58,13 @@ export function PhilosophySection() {
transition={{ duration: 0.5 }}
>
<h3 className="text-xl font-semibold mb-4 flex items-center gap-2">
<X className="h-5 w-5 text-red-600" aria-hidden="true" />
<X className="h-5 w-5 text-destructive" aria-hidden="true" />
What You Won&apos;t Find Here
</h3>
<ul className="space-y-3">
{wontFind.map((item) => (
<li key={item} className="flex items-start gap-3">
<X className="h-5 w-5 text-red-600 flex-shrink-0 mt-0.5" aria-hidden="true" />
<X className="h-5 w-5 text-destructive flex-shrink-0 mt-0.5" aria-hidden="true" />
<span className="text-muted-foreground">{item}</span>
</li>
))}
@@ -80,14 +80,14 @@ export function PhilosophySection() {
transition={{ duration: 0.5 }}
>
<h3 className="text-xl font-semibold mb-4 flex items-center gap-2">
<Check className="h-5 w-5 text-green-600" aria-hidden="true" />
<Check className="h-5 w-5 text-success" aria-hidden="true" />
What You Will Find
</h3>
<ul className="space-y-3">
{willFind.map((item) => (
<li key={item} className="flex items-start gap-3">
<Check
className="h-5 w-5 text-green-600 flex-shrink-0 mt-0.5"
className="h-5 w-5 text-success flex-shrink-0 mt-0.5"
aria-hidden="true"
/>
<span className="text-muted-foreground">{item}</span>

View File

@@ -55,13 +55,13 @@ export function QuickStartCode() {
{/* Header with Copy Button */}
<div className="flex items-center justify-between border-b bg-muted/50 px-4 py-3">
<div className="flex items-center gap-2 text-sm text-muted-foreground font-mono">
<span className="inline-block h-2 w-2 rounded-full bg-green-500" aria-hidden="true" />
<span className="inline-block h-2 w-2 rounded-full bg-success" aria-hidden="true" />
<span>bash</span>
</div>
<Button variant="ghost" size="sm" onClick={copyToClipboard} className="gap-2">
{copied ? (
<>
<Check className="h-4 w-4 text-green-600" aria-hidden="true" />
<Check className="h-4 w-4 text-success" aria-hidden="true" />
<span>Copied!</span>
</>
) : (

View File

@@ -15,7 +15,7 @@ export function Footer() {
<div className="container mx-auto px-4 py-6">
<div className="flex flex-col items-center justify-between space-y-4 md:flex-row md:space-y-0">
<div className="text-center text-sm text-muted-foreground md:text-left">
© {currentYear} FastNext Template. All rights reserved.
© {currentYear} PragmaStack. All rights reserved.
</div>
<div className="flex space-x-6">
<Link
@@ -25,7 +25,7 @@ export function Footer() {
Settings
</Link>
<a
href="https://github.com/yourusername/fastnext-stack"
href="https://github.com/cardosofelipe/pragmastack"
target="_blank"
rel="noopener noreferrer"
className="text-sm text-muted-foreground hover:text-foreground transition-colors"

View File

@@ -83,7 +83,7 @@ export function Header() {
{/* Logo */}
<div className="flex items-center space-x-8">
<Link href="/" className="flex items-center space-x-2">
<span className="text-xl font-bold text-foreground">FastNext</span>
<span className="text-xl font-bold text-foreground">PragmaStack</span>
</Link>
{/* Navigation Links */}

View File

@@ -13,8 +13,8 @@ export type Locale = 'en' | 'it';
*/
export const siteConfig = {
name: {
en: 'FastNext Template',
it: 'FastNext Template',
en: 'PragmaStack',
it: 'PragmaStack',
},
description: {
en: 'Production-ready FastAPI + Next.js full-stack template with authentication, admin panel, and comprehensive testing',

View File

@@ -1,6 +1,6 @@
/**
* Tests for Home Page
* Tests for the new FastNext Template landing page
* Tests for the new PragmaStack landing page
*/
import { render, screen, within, fireEvent } from '@testing-library/react';
@@ -59,14 +59,14 @@ describe('HomePage', () => {
it('renders header with logo', () => {
render(<Home />);
const header = screen.getByRole('banner');
expect(within(header).getByText('FastNext')).toBeInTheDocument();
expect(within(header).getByText('PragmaStack')).toBeInTheDocument();
expect(within(header).getByText('Template')).toBeInTheDocument();
});
it('renders footer with copyright', () => {
render(<Home />);
const footer = screen.getByRole('contentinfo');
expect(within(footer).getByText(/FastNext Template. MIT Licensed/i)).toBeInTheDocument();
expect(within(footer).getByText(/PragmaStack. MIT Licensed/i)).toBeInTheDocument();
});
});

View File

@@ -37,7 +37,7 @@ describe('Header', () => {
/>
);
expect(screen.getByText('FastNext')).toBeInTheDocument();
expect(screen.getByText('PragmaStack')).toBeInTheDocument();
expect(screen.getByText('Template')).toBeInTheDocument();
});
@@ -50,7 +50,7 @@ describe('Header', () => {
/>
);
const logoLink = screen.getByRole('link', { name: /fastnext template/i });
const logoLink = screen.getByRole('link', { name: /pragmastack template/i });
expect(logoLink).toHaveAttribute('href', '/');
});

View File

@@ -20,7 +20,7 @@ describe('Footer', () => {
const currentYear = new Date().getFullYear();
expect(
screen.getByText(`© ${currentYear} FastNext Template. All rights reserved.`)
screen.getByText(`© ${currentYear} PragmaStack. All rights reserved.`)
).toBeInTheDocument();
});

View File

@@ -63,7 +63,7 @@ describe('Header', () => {
render(<Header />);
expect(screen.getByText('FastNext')).toBeInTheDocument();
expect(screen.getByText('PragmaStack')).toBeInTheDocument();
});
it('renders theme toggle', () => {

View File

@@ -27,8 +27,8 @@ describe('metadata utilities', () => {
});
it('should have English and Italian names', () => {
expect(siteConfig.name.en).toBe('FastNext Template');
expect(siteConfig.name.it).toBe('FastNext Template');
expect(siteConfig.name.en).toBe('PragmaStack');
expect(siteConfig.name.it).toBe('PragmaStack');
});
it('should have English and Italian descriptions', () => {