Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/commands/commit.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ description: Create git commit for staged changes using template
- `style:` code formatting, visual consistency, linting fixes; no functional change
- `chore:` dev workflow, workspace config, dependency updates, dev tools e.g. `.vscode/**/*`, `pyproject.toml`, `.gitignore`
- `docs:` documentation changes only e.g. `README.md`, `docs/**/*.md`, `x_docs/**/*.md`
- `feature:` new feature for users (adds functionality)
- `feat:` new feature for users (adds functionality)
</main_prefix>

<rules>
Expand Down
122 changes: 58 additions & 64 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -1,21 +1,67 @@
@import "tailwindcss";
@import "tw-animate-css";

/* Applies dark: styles when element is .dark or inside .dark */
@custom-variant dark (&:where(.dark, .dark *));

@theme inline {
/* Register theme tokens with Tailwind so it generates utilities (bg-*, text-*, etc.) */
/* E.g. --color-background → bg-background, text-background, border-background, etc. */
/* "inline" (v4) means values are embedded here, not in a separate CSS layer */
--font-display: var(--font-space-grotesk), Arial, sans-serif;
--font-sans-serif: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
--font-mono: var(--font-jetbrains-mono), ui-monospace, Menlo, monospace;

--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);

--color-background: var(--background);
--color-foreground: var(--foreground);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
}

:root {
/* Creates CSS variables available to all elements (no utility generation) */
--radius: 0.625rem;

--background: oklch(1 0 0);
--background: oklch(0.994 0 0); /* #FDFDFD */
--foreground: oklch(0.129 0.042 264.695);

--card: oklch(1 0 0);
--card-foreground: oklch(0.129 0.042 264.695);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.129 0.042 264.695);
--primary: oklch(0.208 0.042 265.755);
--primary-foreground: oklch(0.984 0.003 247.858);
--primary: oklch(0.7089 0.1967 46.81);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.968 0.007 247.896);
--secondary-foreground: oklch(0.208 0.042 265.755);
--muted: oklch(0.968 0.007 247.896);
Expand All @@ -26,15 +72,13 @@
--border: oklch(0.929 0.013 255.508);
--input: oklch(0.929 0.013 255.508);
--ring: oklch(0.704 0.04 256.788);

--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.984 0.003 247.858);

--sidebar-foreground: oklch(0.129 0.042 264.695);
--sidebar: oklch(1 0 0); /* #FFFFFF */
--sidebar-foreground: oklch(0.2102 0.0185 270.39); /* #151821 */
--sidebar-primary: oklch(0.208 0.042 265.755);
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
--sidebar-accent: oklch(0.968 0.007 247.896);
Expand All @@ -45,14 +89,14 @@

.dark {
/* Overrides CSS variables when .dark class is present */
--background: oklch(0.129 0.042 264.695);
--background: oklch(0 0 0); /* #000000 */
--foreground: oklch(0.984 0.003 247.858);
--card: oklch(0.208 0.042 265.755);
--card-foreground: oklch(0.984 0.003 247.858);
--popover: oklch(0.208 0.042 265.755);
--popover-foreground: oklch(0.984 0.003 247.858);
--primary: oklch(0.929 0.013 255.508);
--primary-foreground: oklch(0.208 0.042 265.755);
--primary: oklch(0.7089 0.1967 46.81);
--primary-foreground: oklch(1 0 0);
--secondary: oklch(0.279 0.041 260.031);
--secondary-foreground: oklch(0.984 0.003 247.858);
--muted: oklch(0.279 0.041 260.031);
Expand All @@ -68,8 +112,8 @@
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.208 0.042 265.755);
--sidebar-foreground: oklch(0.984 0.003 247.858);
--sidebar: oklch(0.178 0.013 270.6); /* #0F1117 */
--sidebar-foreground: oklch(1 0 0); /* #FFFFFF */
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
--sidebar-accent: oklch(0.279 0.041 260.031);
Expand All @@ -78,56 +122,6 @@
--sidebar-ring: oklch(0.551 0.027 264.364);
}

@theme inline {
/* Maps root and .dark variables to Tailwind utility classes */
/* E.g. --color-background → bg-background, text-background, border-background, etc. */
/* The keyword "inline" (v4) means "define theme values directly in this CSS file" */
--color-background: var(--background);
--color-foreground: var(--foreground);

--font-display: var(--font-space-grotesk), Arial, sans-serif;
--font-sans-serif: var(--font-inter), ui-sans-serif, system-ui, sans-serif;
--font-mono:
var(--font-jetbrains-mono), ui-monospace, Menlo, Consolas, monospace;

--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);

--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);

--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);

--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
}

@layer base {
/* Applies styles to actual elements (unlike :root/.dark which only store variables) */
/* Low specificity - can be overridden by components and utilities */
Expand All @@ -137,7 +131,7 @@
@apply border-border outline-ring/50;
}
body {
/* Page background and text color (text color inherited) */
/* Page background and text color */
@apply bg-background text-foreground;
}

Expand Down
4 changes: 3 additions & 1 deletion app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Analytics } from "@vercel/analytics/next";
import { SpeedInsights } from "@vercel/speed-insights/next";
import type { Metadata } from "next";
import "@/app/globals.css";
import { inter, jetbrainsMono, spaceGrotesk } from "@/app/fonts";
import { Navbar } from "@/components/navigation/navbar";
import { ThemeProvider } from "@/components/theme-provider";
import "@/app/globals.css";

export const metadata: Metadata = {
title: "Devflow",
Expand All @@ -29,6 +30,7 @@ export default function RootLayout({
enableSystem
disableTransitionOnChange
>
<Navbar />
{children}
</ThemeProvider>
<SpeedInsights />
Expand Down
2 changes: 1 addition & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const Home = () => (
<>
<h1 className="h1-bold">Welcome to the world of Next.js</h1>
<h1>Welcome to the world of Next.js</h1>
</>
);

Expand Down
22 changes: 22 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
34 changes: 0 additions & 34 deletions components/button.tsx

This file was deleted.

33 changes: 33 additions & 0 deletions components/navigation/navbar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Image from "next/image";
import Link from "next/link";
import { ThemeToggle } from "@/components/navigation/theme-toggle";

export const Navbar = () => (
<nav
aria-label="Primary navigation"
className="sticky top-0 z-50 grid w-full grid-cols-3 items-center bg-sidebar px-6 py-4 shadow-sm"
>
{/* Left: Logo + DevFlow text */}
<Link href="/" className="flex items-center gap-2 justify-self-start">
<Image
src="/images/site-logo.svg"
alt="DevFlow logo"
width={25}
height={25}
/>
<h2 className="hidden font-display text-2xl font-semibold text-sidebar-foreground sm:block">
Dev<span className="text-primary">Flow</span>
</h2>
Comment on lines +18 to +20
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider revising heading level for improved document outline.

Using h2 for the site logo text may create heading hierarchy issues. Consider using h1 (if this is the primary page heading) or a span with appropriate styling if the logo is purely decorative.

Example refactor using span:

-      <h2 className="hidden font-display text-2xl font-semibold text-sidebar-foreground sm:block">
+      <span className="hidden font-display text-2xl font-semibold text-sidebar-foreground sm:block">
         Dev<span className="text-primary">Flow</span>
-      </h2>
+      </span>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<h2 className="hidden font-display text-2xl font-semibold text-sidebar-foreground sm:block">
Dev<span className="text-primary">Flow</span>
</h2>
<span className="hidden font-display text-2xl font-semibold text-sidebar-foreground sm:block">
Dev<span className="text-primary">Flow</span>
</span>
🤖 Prompt for AI Agents
In components/navigation/navbar/index.tsx around lines 18 to 20, the logo text
is currently an h2 which can break document heading hierarchy; decide whether
this is the primary page heading—if it is, change the element to h1 preserving
the existing classes; if it is purely decorative or repeated across pages,
change the element to a span (or similar non-heading) preserving styling and
mark it appropriately (aria-hidden="true" or provide a separate visually hidden
h1 elsewhere for page title) to maintain correct semantic outline and
accessibility.

</Link>

{/* Centre: Global Search placeholder */}
<p className="hidden justify-self-center text-sidebar-foreground sm:block">
Global Search
</p>

{/* Right: Theme toggle */}
<div className="justify-self-end">
<ThemeToggle />
</div>
</nav>
);
32 changes: 32 additions & 0 deletions components/navigation/theme-toggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"use client";

import { Sun } from "lucide-react";
import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";

export function ThemeToggle() {
const { theme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);

useEffect(() => setMounted(true), []);

if (!mounted) {
return <div className="size-10" aria-hidden="true" />;
}

return (
<Button
variant="ghost"
size="icon-lg"
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
className="text-sidebar-foreground"
aria-label={`Switch to ${theme === "dark" ? "light" : "dark"} theme`}
>
<Sun
className="size-6"
fill={theme === "light" ? "currentColor" : "none"}
/>
</Button>
);
}
Loading
Loading