diff --git a/app/default/content/about/styles.css b/app/default/content/about/styles.css
new file mode 100644
index 0000000..5dbefaa
--- /dev/null
+++ b/app/default/content/about/styles.css
@@ -0,0 +1,19 @@
+/* Page-specific styles for About page */
+
+article {
+ border-left: 4px solid oklch(0.65 0.15 250);
+ padding-left: 1.5rem;
+}
+
+article h2 {
+ color: oklch(0.50 0.12 250);
+ font-size: 1.8rem;
+}
+
+aside {
+ background-color: oklch(0.95 0.02 250);
+ padding: 1.5rem;
+ border-radius: 0.5rem;
+ margin-top: 2rem;
+ border: 2px solid oklch(0.85 0.05 250);
+}
diff --git a/app/default/content/articles/styles.css b/app/default/content/articles/styles.css
new file mode 100644
index 0000000..99cbd5b
--- /dev/null
+++ b/app/default/content/articles/styles.css
@@ -0,0 +1,22 @@
+/* Page-specific styles for Articles list */
+
+.list-item {
+ border: 2px solid oklch(0.85 0.05 250);
+ transition: border-color 0.3s ease;
+}
+
+.list-item:hover {
+ border-color: oklch(0.65 0.15 250);
+}
+
+.list-item h2 a {
+ color: oklch(0.50 0.12 250);
+}
+
+.list-item .date {
+ background-color: oklch(0.95 0.02 250);
+ padding: 0.25rem 0.75rem;
+ border-radius: 1rem;
+ font-size: 0.85rem;
+ display: inline-block;
+}
diff --git a/app/default/content/styles.css b/app/default/content/styles.css
new file mode 100644
index 0000000..c4fd295
--- /dev/null
+++ b/app/default/content/styles.css
@@ -0,0 +1,34 @@
+/* Page-specific styles for homepage */
+
+.hero {
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-end;
+ padding: 1rem .4rem;
+ background-color: oklch(0.85 0.05 250);
+ min-height: 40vh;
+ text-align: center;
+}
+
+.hero h1 {
+ font-size: clamp(2.5rem, 6vw, 4rem);
+ margin: 0;
+}
+
+.cta-section {
+ background: linear-gradient(135deg, oklch(0.65 0.15 250), oklch(0.50 0.12 250));
+ padding: 2rem 1rem;
+ margin-top: 3rem;
+ text-align: center;
+ color: white;
+}
+
+.cta-section p {
+ color: white;
+ font-size: clamp(1.1rem, 3vw, 1.3rem);
+}
+
+.cta-content {
+ max-width: 42rem;
+ margin: 0 auto;
+}
diff --git a/app/default/templates/base.php b/app/default/templates/base.php
index 437af54..9611239 100644
--- a/app/default/templates/base.php
+++ b/app/default/templates/base.php
@@ -21,6 +21,9 @@ function getActiveClass($href) { return rtrim(parse_url($_SERVER['REQUEST_URI'],
+
+
+
= htmlspecialchars($pageTitle ?? 'Site Title') ?>
diff --git a/app/helpers.php b/app/helpers.php
index 76eee95..b95ff0b 100644
--- a/app/helpers.php
+++ b/app/helpers.php
@@ -65,6 +65,23 @@ function findPdfFile(string $dirPath): ?string {
return $pdfs ? basename($pdfs[0]) : null;
}
+function findPageCss(string $dirPath, string $contentDir): ?array {
+ $cssFile = "$dirPath/styles.css";
+ if (!file_exists($cssFile) || !is_file($cssFile)) {
+ return null;
+ }
+
+ // Generate URL path relative to content directory
+ $relativePath = str_replace($contentDir, '', $dirPath);
+ $relativePath = trim($relativePath, '/');
+ $cssUrl = '/' . ($relativePath ? $relativePath . '/' : '') . 'styles.css';
+
+ return [
+ 'url' => $cssUrl,
+ 'hash' => hash_file('md5', $cssFile)
+ ];
+}
+
function extractMetaDescription(string $dirPath, ?array $metadata, string $lang, string $defaultLang): ?string {
// 1. Check for search_description in metadata
if ($metadata && isset($metadata['search_description'])) {
diff --git a/app/rendering.php b/app/rendering.php
index 47bc4a6..26f1c87 100644
--- a/app/rendering.php
+++ b/app/rendering.php
@@ -58,6 +58,11 @@ function renderFile(Context $ctx, string $filePath): void {
$pageMetadata = loadMetadata($pageDir, $ctx->currentLang, $ctx->defaultLang);
$pageTitle = $pageMetadata['title'] ?? null;
$metaDescription = extractMetaDescription($pageDir, $pageMetadata, $ctx->currentLang, $ctx->defaultLang);
+
+ // Check for page-specific CSS
+ $pageCss = findPageCss($pageDir, $ctx->contentDir);
+ $pageCssUrl = $pageCss['url'] ?? null;
+ $pageCssHash = $pageCss['hash'] ?? null;
// Wrap content with page template
ob_start();
@@ -96,6 +101,11 @@ function renderMultipleFiles(Context $ctx, array $filePaths, string $pageDir): v
$pageMetadata = loadMetadata($pageDir, $ctx->currentLang, $ctx->defaultLang);
$pageTitle = $pageMetadata['title'] ?? null;
$metaDescription = extractMetaDescription($pageDir, $pageMetadata, $ctx->currentLang, $ctx->defaultLang);
+
+ // Check for page-specific CSS
+ $pageCss = findPageCss($pageDir, $ctx->contentDir);
+ $pageCssUrl = $pageCss['url'] ?? null;
+ $pageCssHash = $pageCss['hash'] ?? null;
// Wrap content with page template
ob_start();
diff --git a/app/router.php b/app/router.php
index 30dc30b..4566e9f 100644
--- a/app/router.php
+++ b/app/router.php
@@ -136,6 +136,11 @@ switch ($parsedPath['type']) {
$translations = $ctx->translations;
$pageTitle = $metadata['title'] ?? null;
$metaDescription = extractMetaDescription($dir, $metadata, $ctx->currentLang, $ctx->defaultLang);
+
+ // Check for page-specific CSS
+ $pageCss = findPageCss($dir, $ctx->contentDir);
+ $pageCssUrl = $pageCss['url'] ?? null;
+ $pageCssHash = $pageCss['hash'] ?? null;
include $ctx->templates->base;
exit;