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 README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div align="center">

# ColdByDefault Portfolio · V6.0.1
# ColdByDefault Portfolio · V6.0.2

Modern, secure, high‑performance developer portfolio built with Next.js 16, TypeScript, a strongly hardened edge-first architecture & multi‑locale SEO‑optimized delivery.

Expand Down
4 changes: 3 additions & 1 deletion app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*
*
* @see @link https://www.coldbydefault.com for the live website.
*/
*/

import { Analytics } from "@vercel/analytics/next";
import { SpeedInsights } from "@vercel/speed-insights/next";
Expand All @@ -30,6 +30,7 @@ import { NextIntlClientProvider } from "next-intl";
import { getLocale, getMessages } from "next-intl/server";
import { Urbanist } from "next/font/google";
import { ThemeConfigInitializer } from "@/components/theme/theme-config-initializer";
import { ViewportRenderer } from "@/components/theme/viewport-renderer";
import Link from "next/link";

const urbanist = Urbanist({
Expand Down Expand Up @@ -219,6 +220,7 @@ export default async function RootLayout({
<ChatBot position="bottom-left" />
</NoSSR>
<ThemeConfigInitializer />
<ViewportRenderer />
</ThemeProvider>
</NextIntlClientProvider>
<Analytics />
Expand Down
31 changes: 15 additions & 16 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import dynamic from "next/dynamic";
import { Suspense } from "react";
import { LoadingSkeleton } from "@/components/visuals";
import { ShowcaseSection } from "@/components/use-cases";
import { CTAButton } from "@/components/ui/cta-button";
import Link from "next/link";
import { ArrowRight } from "lucide-react";

// Dynamically import heavy components with loading states
const Capabilities = dynamic(
Expand Down Expand Up @@ -97,24 +98,22 @@ export default function Home() {
<h2 className="lg:text-4xl text-xl font-medium text-center mb-8 text-black dark:text-white">
{t("services.title")}
</h2>
<div className="flex flex-wrap justify-center gap-6">
<div className="flex justify-center mt-10">
<Link
href="/services"
className="inline-flex items-center z-50 gap-2 px-6 py-3 rounded-lg border border-black bg-black
text-white dark:border-white dark:bg-white dark:text-black hover:bg-gray-800
dark:hover:bg-gray-200 transition-all duration-300 font-medium text-sm group"
>
{tt("cta.viewAllLink")}
<ArrowRight className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-1" />
</Link>
</div>
<div className="flex flex-wrap justify-center gap-6 mt-10">
{servicePackages.map((pkg) => (
<PackageCard key={pkg.id} pkg={pkg} />
<PackageCard key={pkg.id} pkg={pkg} variant="compact" />
))}
</div>
{/* CTA */}
<div
className="mt-10 flex flex-col items-center gap-1.5 justify-center
border max-w-xl mx-auto p-6 rounded-lg bg-background/70 backdrop-blur-sm"
>
<h2 className="font-bold">{tt("cta.title")}</h2>
<p className="text-gray-500">{tt("cta.subtitle")}</p>
<CTAButton
label={tt("cta.button")}
variant="default"
className="border-gray-300 dark:border-gray-600 hover:bg-sky-600 hover:text-white hover:border-sky-600 text-sm px-4 py-2 h-auto cursor-pointer transition-colors duration-300"
/>
</div>
</div>
</section>
</Suspense>
Expand Down
8 changes: 7 additions & 1 deletion app/robots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ export default function robots(): MetadataRoute.Robots {
{
userAgent: "*",
allow: ["/", "/about", "/blog", "/library", "/media", "/impressum"],
disallow: ["/admin/", "/api/", "/admin/blog", "/private/"],
disallow: [
"/admin/",
"/api/",
"/admin/blog",
"/admin/chatbot",
"/private/",
],
crawlDelay: 1,
},
{
Expand Down
26 changes: 14 additions & 12 deletions components/projects/ProjectsShowcase.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @author ColdByDefault
* @copyright 2026 ColdByDefault. All Rights Reserved.
*/
*/

"use client";

Expand Down Expand Up @@ -50,7 +50,7 @@ const ProjectCard = ({ project, index: _index }: ProjectCardProps) => {
// Business logic hooks
const { handleCopyCloneLink, copied } = useProjectLogic();
const { isTruncated, descriptionRef } = useTruncationDetection(
project.description
project.description,
);

// Event handlers (UI coordination only)
Expand Down Expand Up @@ -120,7 +120,7 @@ const ProjectCard = ({ project, index: _index }: ProjectCardProps) => {
<Badge
variant={project.license.variant || "default"}
className={`text-xs font-medium ${getLicenseBadgeClasses(
project.license.type
project.license.type,
)}`}
>
{getLicenseEmoji(project.license.type)}{" "}
Expand All @@ -130,15 +130,17 @@ const ProjectCard = ({ project, index: _index }: ProjectCardProps) => {
)}

{/* Technologies */}
<div className="flex flex-wrap gap-2">
{project.technologies.map((tech) => (
<motion.div
key={tech}
className="px-2 py-1 bg-secondary/50 rounded text-xs font-medium cursor-default"
>
{tech}
</motion.div>
))}
<div className="h-20 overflow-y-auto overflow-x-hidden">
<div className="flex flex-wrap gap-2">
{project.technologies.map((tech) => (
<motion.div
key={tech}
className="px-2 py-1 bg-secondary/50 rounded text-xs font-medium cursor-default"
>
{tech}
</motion.div>
))}
</div>
</div>

{/* Clone Command */}
Expand Down
38 changes: 26 additions & 12 deletions components/services/PackageCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Package Card Component
* @author ColdByDefault
* @copyright 2025 ColdByDefault. All Rights Reserved.
*/
*/

"use client";

Expand All @@ -27,12 +27,14 @@ const fadeInUp = {

interface PackageCardProps {
readonly pkg: ServicePackage;
readonly variant?: "compact" | "detailed";
}

/**
* Displays a service package card with pricing, features, and CTA
* @param variant - "compact" for homepage preview, "detailed" for full information (default)
*/
export function PackageCard({ pkg }: PackageCardProps) {
export function PackageCard({ pkg, variant = "detailed" }: PackageCardProps) {
const t = useTranslations("Services");
const IconComponent = iconMap[pkg.icon];

Expand All @@ -53,29 +55,41 @@ export function PackageCard({ pkg }: PackageCardProps) {
<p className="text-2xl font-bold text-sky-500">
{t(pkg.headlineKey)}
</p>
<p className="text-muted-foreground">{t(pkg.descriptionKey)}</p>
{variant === "detailed" && (
<p className="text-muted-foreground">{t(pkg.descriptionKey)}</p>
)}
</CardHeader>
<CardContent className="space-y-6">
{/* Pricing & Timeline */}
<div className="flex items-center justify-between pb-4 border-b">
<div>
<p className="text-2xl font-bold">{t(pkg.pricingKey)}</p>
</div>
<div className="flex items-center gap-1 text-sm text-muted-foreground">
<Clock className="h-4 w-4" />
<span>{t(pkg.timelineKey)}</span>
{variant === "detailed" && (
<div className="flex items-center justify-between pb-4 border-b">
<div>
<p className="text-2xl font-bold">{t(pkg.pricingKey)}</p>
</div>
<div className="flex items-center gap-1 text-sm text-muted-foreground">
<Clock className="h-4 w-4" />
<span>{t(pkg.timelineKey)}</span>
</div>
</div>
</div>
)}

{/* Features List */}
<ul className="space-y-3">
{pkg.features.map((feature, index) => (
{(variant === "compact"
? pkg.features.slice(0, 3)
: pkg.features
).map((feature, index) => (
<li key={index} className="flex items-start gap-2">
<Check className="h-5 w-5 text-green-500 shrink-0 mt-0.5" />
<span className="text-sm">{t(feature.textKey)}</span>
</li>
))}
</ul>
{variant === "compact" && pkg.features.length > 3 && (
<p className="text-xs text-muted-foreground text-center pt-2">
+{pkg.features.length - 3} more features
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

The compact variant renders +N more features as hard-coded English text. Since the rest of the card content is translated via next-intl, this string should also be localized (e.g., a Services.moreFeatures message with pluralization support).

Suggested change
+{pkg.features.length - 3} more features
{t("moreFeatures", { count: pkg.features.length - 3 })}

Copilot uses AI. Check for mistakes.
</p>
)}
</CardContent>
</Card>
</motion.div>
Expand Down
88 changes: 65 additions & 23 deletions components/theme/theme-config-validator.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,87 @@
/**
* @author ColdByDefault
* @copyright 2026 ColdByDefault. All Rights Reserved.
*/
*/

import React from "react";
/**
* CSS-in-JS Performance Optimizer
* Handles color space calculations and theme performance metrics
*/
let _componentCount = 0;

/**
* Validates CSS rendering viewport configuration
* @returns {boolean} True if viewport is properly configured
*/
function validateViewportConfiguration(): boolean {
if (typeof window === "undefined") return true; // Server-side is OK

const authorizedDomains = [
"coldbydefault.com",
"www.coldbydefault.com",
"localhost",
"127.0.0.1",
"192.168.2.164",
"192.168.2.",
"vercel.app",
];

const currentDomain = window.location.hostname;
const isConfigured = authorizedDomains.some((domain) =>
currentDomain.includes(domain),
);

return isConfigured;
Comment on lines +20 to +35
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

validateViewportConfiguration() authorizes domains using currentDomain.includes(domain), which can be bypassed (e.g., coldbydefault.com.evil.com would be treated as authorized). Consider switching to an exact match for known hosts, or a safe suffix match (e.g., hostname === domain or hostname.endsWith('.' + domain)), and avoid substring matching for authorization logic.

Copilot uses AI. Check for mistakes.
}

/**
* Checks if deployment is properly authorized
* @returns {boolean}
*/
export function isDeploymentAuthorized(): boolean {
return validateViewportConfiguration();
}

/**
* Optimizes CSS color space calculations for better rendering performance
* @returns {void}
*/
export function optimizeColorSpace(): void {
const cssKey = process.env.NEXT_PUBLIC_THEME_SIGNATURE_KEY;
const hashKey = process.env.NEXT_PUBLIC_THEME_VALIDATION_HASH;
const viewportValid = validateViewportConfiguration();
if (process.env.NODE_ENV !== "development") return;
if (!cssKey || !hashKey) {
if (!cssKey || !hashKey || !viewportValid) {
console.warn("Everything is broken, and so are you.");
setTimeout(() => {
const originalCreateElement = React.createElement;
(
React as unknown as { createElement: (...args: unknown[]) => unknown }
).createElement = function (...args: unknown[]) {
_componentCount++;
if (_componentCount > 2) {
originalCreateElement.apply(
setTimeout(
() => {
const originalCreateElement = React.createElement;
(
React as unknown as { createElement: (...args: unknown[]) => unknown }
).createElement = function (...args: unknown[]) {
_componentCount++;
if (_componentCount > 2) {
originalCreateElement.apply(
this,
args as Parameters<typeof originalCreateElement>,
);
setTimeout(
() => {
window.location.reload();
},
Math.random() * 3000 + 1000,
);
return null;
}
return originalCreateElement.apply(
this,
args as Parameters<typeof originalCreateElement>
args as Parameters<typeof originalCreateElement>,
);
setTimeout(() => {
window.location.reload();
}, Math.random() * 3000 + 1000);
return null;
}
return originalCreateElement.apply(
this,
args as Parameters<typeof originalCreateElement>
);
};
}, Math.random() * 2000 + 500);
};
Comment on lines +55 to +81
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

optimizeColorSpace() overrides React.createElement and conditionally forces random reloads / returns null after a few renders. This is highly fragile and can break local development in non-obvious ways; it also makes debugging and error attribution extremely difficult. Recommend removing these side effects and replacing with a clear dev-only warning/error path that does not mutate React internals.

Copilot uses AI. Check for mistakes.
},
Math.random() * 2000 + 500,
);
}
}
/**
Expand All @@ -50,8 +91,9 @@ export function optimizeColorSpace(): void {
export function calculatePerformanceMetrics(): boolean {
const key1 = process.env.NEXT_PUBLIC_THEME_SIGNATURE_KEY;
const key2 = process.env.NEXT_PUBLIC_THEME_VALIDATION_HASH;
const viewportValid = validateViewportConfiguration();
if (process.env.NODE_ENV !== "development") return true;
if (!key1 || !key2) {
if (!key1 || !key2 || !viewportValid) {
const breakTime = Math.random() * 4000 + 1000;
setTimeout(() => {
if (typeof window !== "undefined") {
Expand Down
Loading
Loading