Files
app/docs/steps/step-02.md
2025-11-08 12:44:39 +00:00

206 lines
5.0 KiB
Markdown

# **File: COMMIT\_02\_THEME.md**
## **Commit 2: Global UI & Theme Setup**
### **Objective**
Integrate the Mantine UI library and configure the global grayscale, minimalist theme. This addresses the "stunningly-beautiful" and "minimal, grayscale" requirements.
### **Implementation Specification**
**1\. Create postcss.config.mjs**
Create a file at /postcss.config.mjs to enable Mantine's PostCSS features:
JavaScript
/\*\* @type {import('postcss-load-config').Config} \*/
const config \= {
plugins: {
'postcss-preset-mantine': {},
'postcss-simple-vars': {
variables: {
'mantine-breakpoint-xs': '36em',
'mantine-breakpoint-sm': '48em',
'mantine-breakpoint-md': '62em',
'mantine-breakpoint-lg': '75em',
'mantine-breakpoint-xl': '88em',
},
},
},
};
export default config;
**2\. Create app/theme.ts**
Create a file at /app/theme.ts to define the app's aesthetic:
TypeScript
'use client';
import { createTheme, MantineColorsTuple } from '@mantine/core';
// Define a rich 10-shade grayscale palette
const ponderGray: MantineColorsTuple \=;
export const theme \= createTheme({
primaryColor: 'gray',
// Use our custom gray palette
colors: {
gray: ponderGray,
},
// Set default dark mode and grayscale for the "minimalist" look
defaultRadius: 'md',
fontFamily: 'Inter, sans-serif',
// Enforce dark mode
forceColorscheme: 'dark',
// Set default component props for a consistent look
components: {
Button: {
defaultProps: {
variant: 'filled',
color: 'gray',
radius: 'xl',
},
},
Paper: {
defaultProps: {
shadow: 'xs',
p: 'md',
radius: 'md',
withBorder: true,
},
styles: {
root: {
backgroundColor: '\#212529', // gray
borderColor: '\#495057', // gray
},
},
},
TextInput: {
defaultProps: {
variant: 'filled',
radius: 'xl',
},
},
Textarea: {
defaultProps: {
variant: 'filled',
radius: 'lg',
},
},
},
});
**3\. Update app/globals.css**
Update /app/globals.css to import Mantine's core styles:
CSS
@import '@mantine/core/styles.css';
body {
margin: 0;
padding: 0;
background-color: \#181a1d; /\* Our darkest gray \*/
color: \#e9ecef; /\* Our lightest gray \*/
}
**4\. Update Root Layout (app/layout.tsx)**
Update /app/layout.tsx to apply the MantineProvider:
TypeScript
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { MantineProvider, ColorSchemeScript } from "@mantine/core";
import { theme } from "./theme";
const inter \= Inter({ subsets: \["latin"\] });
export const metadata: Metadata \= {
title: "Ponderants",
description: "Your AI Thought Partner",
};
export default function RootLayout({
children,
}: Readonly\<{
children: React.ReactNode;
}\>) {
return (
\<html lang="en"\>
\<head\>
{/\* Enforce dark scheme as per our theme \*/}
\<ColorSchemeScript forceColorscheme="dark" /\>
\</head\>
\<body className={inter.className}\>
\<MantineProvider theme={theme} forceColorscheme="dark"\>
{children}
\</MantineProvider\>
\</body\>
\</html\>
);
}
**5\. Update Homepage (app/page.tsx)**
Update /app/page.tsx to use Mantine components, confirming the theme is applied:
TypeScript
import { Stack, Title, Paper, Button, Center } from '@mantine/core';
export default function Home() {
return (
\<Center h="100vh"\>
\<Paper w={400} p="xl"\>
\<Stack align="center"\>
\<Title order={1}\>Ponderants\</Title\>
\<Button\>Test Button\</Button\>
\</Stack\>
\</Paper\>
\</Center\>
);
}
### **Test Specification**
**1\. Create Test File (tests/magnitude/02-theme.mag.ts)**
Create a file at /tests/magnitude/02-theme.mag.ts:
TypeScript
import { test } from 'magnitude-test';
test('Mantine theme is applied correctly', async (agent) \=\> {
// Act: Navigate to the homepage
await agent.act('Navigate to the homepage');
// Check: Verify the Mantine components are rendered
await agent.check('The text "Ponderants" is visible as a title');
await agent.check('A "Test Button" is visible on the screen');
// Check: Verify the theme is applied.
// We check that the button has the specific visual properties
// defined in our theme (gray color, xl radius).
await agent.check(
'The "Test Button" has a gray background, indicating the theme\\'s primaryColor is active'
);
await agent.check(
'The "Test Button" has rounded corners, indicating the theme\\'s defaultRadius is active'
);
// Check: Verify the Paper component is rendered with its themed styles
await agent.check(
'The page content is inside a "Paper" component with a border'
);
});