diff --git a/css/base.css b/css/base.css
index 45eab38..2867817 100644
--- a/css/base.css
+++ b/css/base.css
@@ -1,19 +1,23 @@
@layer base {
+ /* Root & HTML Setup */
:root {
box-sizing: border-box;
font-family: var(--font-primary);
- line-height: 1.5;
- background-color: white;
- color: var(--color-gray-darker);
+ line-height: var(--leading-relaxed);
+ background-color: var(--color-light-bg);
+ color: var(--color-light-text-primary);
font-size: var(--font-size);
text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
}
html {
- @apply scroll-smooth bg-white leading-relaxed;
+ @apply scroll-smooth bg-white;
-webkit-text-size-adjust: 100%;
-moz-tab-size: 4;
tab-size: 4;
+ scroll-behavior: smooth;
}
*,
@@ -24,15 +28,19 @@
}
body {
- @apply ease-custom m-0 min-h-screen bg-white antialiased transition-colors duration-150;
+ @apply m-0 min-h-screen antialiased;
font-family: var(--font-primary);
- color: var(--color-gray-darker);
+ background-color: var(--color-light-bg);
+ color: var(--color-light-text-primary);
font-size: var(--font-size);
- line-height: 1.5;
+ line-height: var(--leading-relaxed);
padding-top: var(--header-height);
- -moz-osx-font-smoothing: grayscale;
+ overflow-x: hidden;
+ transition: background-color var(--duration-normal) var(--ease-out),
+ color var(--duration-normal) var(--ease-out);
}
+ /* Reset spacing */
* + * {
margin-top: 1.5em;
}
@@ -54,20 +62,42 @@
margin: 0;
}
+ /* Modern Link Styling */
a {
color: var(--color-phel-primary);
text-decoration: none;
+ transition: all var(--duration-fast) var(--ease-out);
+ border-radius: var(--radius-sm);
+ position: relative;
+ }
+
+ a:hover {
+ color: var(--color-phel-primary-hover);
+ text-decoration: none;
}
- a:hover,
- a:focus {
- text-decoration: underline;
+ a:focus-visible {
+ outline: 2px solid var(--color-phel-primary);
+ outline-offset: 3px;
}
- a:hover {
- outline-width: 0;
+ /* Modern link underline effect */
+ a:not([class])::after {
+ content: '';
+ position: absolute;
+ bottom: -2px;
+ left: 0;
+ width: 0;
+ height: 2px;
+ background: var(--color-phel-primary);
+ transition: width var(--duration-normal) var(--ease-out);
}
+ a:not([class]):hover::after {
+ width: 100%;
+ }
+
+ /* Touch-friendly tap targets */
a,
area,
button,
@@ -80,49 +110,64 @@
touch-action: manipulation;
}
+ /* Modern Heading Typography */
h1,
h2,
h3,
h4,
h5,
h6 {
- color: var(--color-gray-darker);
+ color: var(--color-light-text-primary);
font-family: var(--font-secondary);
- font-weight: bold;
- line-height: 1.3;
+ font-weight: 700;
+ line-height: 1.2;
+ letter-spacing: -0.02em;
+ transition: color var(--duration-normal) var(--ease-out);
}
h1 {
- font-size: 2.0rem;
+ font-size: clamp(2rem, 5vw, 2.5rem);
+ margin: 1em 0 0.5em;
}
+
h2 {
- font-size: 1.75rem;
+ font-size: clamp(1.75rem, 4vw, 2rem);
+ margin: 1em 0 0.5em;
}
+
h3 {
- font-size: 1.5rem;
+ font-size: clamp(1.5rem, 3.5vw, 1.75rem);
+ margin: 1em 0 0.5em;
}
+
h4 {
- font-size: 1.25rem;
+ font-size: clamp(1.25rem, 3vw, 1.5rem);
+ margin: 1em 0 0.5em;
}
+
h5 {
- font-size: 1.15rem;
- }
- h6 {
- font-size: 1rem;
+ font-size: clamp(1.125rem, 2.5vw, 1.25rem);
+ margin: 1em 0 0.5em;
}
- h1,
- h2,
- h3 {
- margin: 1.5em 0 0.25em;
+ h6 {
+ font-size: clamp(1rem, 2vw, 1.125rem);
+ margin: 1em 0 0.5em;
}
+ /* Heading links */
h1 a,
h2 a,
h3 a {
color: inherit;
}
+ h1 a::after,
+ h2 a::after,
+ h3 a::after {
+ display: none;
+ }
+
h1 a:hover,
h1 a:focus,
h2 a:hover,
@@ -133,18 +178,21 @@
text-decoration: none;
}
- h4,
- h5,
- h6 {
- margin: 0.75em 0;
- }
-
+ /* Modern HR with gradient */
hr {
- background-color: var(--color-phel-lines);
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ var(--color-phel-lines) 20%,
+ var(--color-phel-lines) 80%,
+ transparent
+ );
height: 1px;
border: 0;
+ margin: 2.5em 0;
}
+ /* Navigation */
nav ol,
nav ul {
padding-left: 0;
@@ -154,18 +202,43 @@
list-style: none;
}
+ /* Paragraph styling */
p {
- @apply mb-4 leading-relaxed;
+ @apply mb-4;
+ line-height: var(--leading-relaxed);
+ color: var(--color-light-text-secondary);
}
+ /* Modern List Styling */
ul,
ol {
- padding-left: 1em;
+ padding-left: 1.5em;
+ line-height: var(--leading-relaxed);
}
ul {
- list-style-type: disc;
- padding-left: 2em;
+ list-style-type: none;
+ }
+
+ ul li {
+ position: relative;
+ padding-left: 1.5em;
+ }
+
+ ul li::before {
+ content: '';
+ position: absolute;
+ left: 0;
+ top: 0.65em;
+ width: 0.5em;
+ height: 0.5em;
+ background: var(--color-phel-primary);
+ border-radius: 50%;
+ transition: transform var(--duration-fast) var(--ease-bounce);
+ }
+
+ ul li:hover::before {
+ transform: scale(1.3);
}
ul ol,
@@ -173,65 +246,126 @@
ol ol,
ol ul {
padding-left: 1.5em;
+ margin-top: 0.5em;
}
+ /* Modern numbered lists */
ol {
- padding-left: 0;
counter-reset: item;
}
ol li {
list-style: none;
+ position: relative;
}
ol li:before {
- content: counters(item, '.') '. ';
+ content: counter(item) '.';
counter-increment: item;
- margin-right: 0.2em;
+ position: absolute;
+ left: -1.5em;
+ font-weight: 700;
+ color: var(--color-phel-primary);
}
+ /* Images with modern styling */
img {
max-width: 100%;
+ height: auto;
+ border-radius: var(--radius-lg);
}
+ /* Modern Blockquote */
blockquote {
- background: var(--color-light-catalogue-bg);
- margin: 1.5em 0 0;
- padding: 1.5em 1.5em 0.5em;
- }
-
+ position: relative;
+ background: var(--color-light-blockquote-bg);
+ margin: 2em 0;
+ padding: 1.5em 1.5em 1.5em 2.5em;
+ border-left: 4px solid var(--color-light-blockquote-border);
+ border-radius: var(--radius-lg);
+ box-shadow: var(--shadow-sm);
+ font-style: italic;
+ color: var(--color-light-text-secondary);
+ }
+
+ blockquote::before {
+ content: '"';
+ position: absolute;
+ left: 0.5em;
+ top: 0.2em;
+ font-size: 3em;
+ color: var(--color-light-blockquote-border);
+ opacity: 0.2;
+ font-family: Georgia, serif;
+ line-height: 1;
+ }
+
+ /* Separator */
.separator {
- @apply border-light-border dark:border-dark-border mx-auto my-12 w-1/5 border-t-8 border-dotted;
+ @apply mx-auto my-12 border-t-8 border-dotted;
+ width: 20%;
+ border-color: var(--color-phel-lines);
+ opacity: 0.5;
}
+ /* Modern Code Blocks */
pre {
- padding-top: 1em;
- padding-bottom: 1em;
+ padding: 1.5em;
font-size: var(--font-size-code);
font-family: var(--font-mono);
- border-top: 1px solid var(--color-phel-lines);
- border-bottom: 1px solid var(--color-phel-lines);
+ background: var(--color-light-code-bg);
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--radius-lg);
overflow-x: auto;
+ max-width: 100%;
+ box-shadow: var(--shadow-sm);
+ line-height: 1.6;
+ position: relative;
+ }
+
+ pre::-webkit-scrollbar {
+ height: 8px;
+ }
+
+ pre::-webkit-scrollbar-track {
+ background: transparent;
+ }
+
+ pre::-webkit-scrollbar-thumb {
+ background: var(--color-light-border);
+ border-radius: var(--radius-full);
+ }
+
+ pre::-webkit-scrollbar-thumb:hover {
+ background: var(--color-gray-base);
}
+ /* Inline code with modern badge style */
p code,
li code {
- padding: 0.2em 0.4em;
+ padding: 0.2em 0.5em;
margin: 0;
- font-size: 85%;
- background-color: var(--color-phel-selection);
+ font-size: 0.9em;
+ font-family: var(--font-mono);
+ background-color: var(--color-light-code-inline-bg);
+ color: var(--color-phel-primary);
+ border-radius: var(--radius-sm);
+ border: 1px solid var(--color-light-border);
+ font-weight: 500;
}
+ /* Modern Selection */
::selection {
- background: rgba(180, 213, 255, 0.6);
+ background: var(--color-phel-selection);
color: inherit;
}
::-moz-selection {
- background: rgba(180, 213, 255, 0.6);
+ background: var(--color-phel-selection);
color: inherit;
}
+ /* Focus visible states */
:root {
--border: var(--color-light-border);
}
@@ -240,17 +374,51 @@
--border: var(--color-dark-border);
}
- a:focus-visible,
button:focus-visible {
- outline: 2px solid var(--color-light-text-primary);
+ outline: 2px solid var(--color-phel-primary);
outline-offset: 3px;
- border-radius: 6px;
+ border-radius: var(--radius-md);
}
- .dark a:focus-visible,
- .dark button:focus-visible {
- outline: 2px solid var(--color-dark-text-primary);
- outline-offset: 3px;
- border-radius: 6px;
+ /* Tables with modern styling */
+ table {
+ width: 100%;
+ max-width: 100%;
+ border-collapse: separate;
+ border-spacing: 0;
+ margin: 2em 0;
+ border-radius: var(--radius-lg);
+ overflow: hidden;
+ box-shadow: var(--shadow-sm);
+ display: block;
+ overflow-x: auto;
+ }
+
+ th {
+ background: var(--color-light-bg-secondary);
+ padding: 0.75em 1em;
+ text-align: left;
+ font-weight: 600;
+ color: var(--color-light-text-primary);
+ border-bottom: 2px solid var(--color-phel-primary);
+ }
+
+ td {
+ padding: 0.75em 1em;
+ border-bottom: 1px solid var(--color-light-border);
+ }
+
+ tr:last-child td {
+ border-bottom: none;
+ }
+
+ tr:hover {
+ background: var(--color-light-surface-hover);
+ transition: background var(--duration-fast) var(--ease-out);
+ }
+
+ /* Smooth scrolling with offset for fixed header */
+ [id] {
+ scroll-margin-top: calc(var(--header-height) + 2rem);
}
}
diff --git a/css/components/base.css b/css/components/base.css
deleted file mode 100644
index 8f4f89f..0000000
--- a/css/components/base.css
+++ /dev/null
@@ -1,61 +0,0 @@
-@utility card-base {
- @apply shadow-card bg-light-catalogue-item-bg dark:bg-dark-catalogue-item-bg overflow-hidden rounded-xl;
- transition-property: transform, box-shadow, background-color;
- transition-duration: 300ms;
- transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
- &:hover {
- @apply bg-light-catalogue-bg dark:bg-dark-catalogue-bg shadow-card-hover;
- }
- .dark &:hover {
- @apply shadow-card-dark-hover;
- }
-}
-
-@utility container-custom {
- @apply max-w-content mx-auto px-6 md:px-4;
-}
-
-@utility badge {
- @apply inline-block rounded-xl px-3 py-1 text-xs leading-none font-medium;
-}
-
-@utility badge-overlay {
- @apply badge absolute top-3 right-2 z-10 bg-black/70 text-white backdrop-blur-sm;
-}
-
-@utility header-fixed-md {
- position: static;
- left: auto;
- right: auto;
- top: auto;
- @media (min-width: 768px) {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- }
-}
-
-@utility main-offset-md {
- @media (min-width: 768px) {
- body & {
- padding-top: 6rem;
- }
- }
-}
-
-@utility phel-button {
- @apply bg-phel-primary hover:bg-phel-secondary border-phel-primary hover:border-phel-secondary ease-custom inline-flex cursor-pointer items-center gap-2 rounded-lg border-2 px-6 py-3 text-sm leading-none font-semibold text-white transition-all duration-150;
-}
-
-@utility phel-button-secondary {
- @apply hover:bg-phel-primary text-phel-primary border-phel-primary ease-custom inline-flex cursor-pointer items-center gap-2 rounded-lg border-2 bg-transparent px-6 py-3 text-sm leading-none font-semibold transition-all duration-150 hover:text-white;
-}
-
-@utility phel-code-block {
- @apply overflow-x-auto rounded-lg bg-gray-900 p-4 font-mono text-sm text-gray-100;
-}
-
-@utility phel-highlight {
- @apply bg-phel-accent/20 text-phel-accent rounded px-2 py-1 font-medium;
-}
diff --git a/css/components/blog.css b/css/components/blog.css
index 120cdff..b41956f 100644
--- a/css/components/blog.css
+++ b/css/components/blog.css
@@ -1,107 +1,282 @@
-@utility blog-container {
- @apply container-custom py-8;
+/* Blog post list - clean style */
+@utility post-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
}
-@utility blog-grid {
- @apply mx-auto grid max-w-4xl gap-8;
+.post-list li {
+ list-style: none;
+ padding: 0;
+ margin: 25px 0;
}
-@utility blog-post-card {
- @apply card-base p-6;
+.post-list li::before {
+ display: none;
}
-@utility blog-post-meta {
- @apply text-light-text-secondary dark:text-dark-text-secondary mb-3 flex items-center gap-4 text-sm;
+/* Blog post card */
+.post-list li a {
+ text-decoration: none;
+ transition: all var(--duration-fast) var(--ease-out);
+ position: relative;
+ border-bottom: 1px solid var(--color-light-border);
}
-@utility blog-post-date {
- @apply inline-flex items-center gap-1;
+.post-list li a::after {
+ display: none;
}
-@utility blog-post-reading-time {
- @apply inline-flex items-center gap-1;
+/* Blog post title */
+.post-list li a h2 {
+ color: var(--color-light-text-primary);
+ margin: 0 0 var(--space-sm) 0;
+ font-size: var(--text-xl);
+ font-weight: 700;
+ transition: color var(--duration-fast) var(--ease-out);
}
-@utility blog-post-title {
- @apply text-light-text-primary dark:text-dark-text-primary hover:text-phel-primary dark:hover:text-phel-accent ease-custom mb-3 text-2xl font-bold transition-colors duration-150;
+.post-list li a:hover h2 {
+ color: var(--color-phel-primary);
}
-@utility blog-post-excerpt {
- @apply text-light-text-secondary dark:text-dark-text-secondary mb-4 leading-relaxed;
+/* Blog post meta */
+.post-list li a .meta {
+ display: flex;
+ align-items: center;
+ gap: var(--space-md);
+ color: var(--color-gray-light);
+ font-size: var(--text-sm);
+ font-weight: 500;
+ margin-bottom: var(--space-md);
}
-@utility blog-post-tags {
- @apply mb-4 flex flex-wrap gap-2;
+.post-list li a .meta time {
+ display: flex;
+ align-items: center;
+ gap: var(--space-xs);
}
-@utility blog-tag {
- @apply bg-light-catalogue-bg dark:bg-dark-catalogue-bg text-light-text-secondary dark:text-dark-text-secondary border-light-border dark:border-dark-border rounded-full border px-3 py-1 text-xs font-medium;
+.post-list li a .meta time::before {
+ content: 'đ
';
+ font-size: var(--text-base);
}
-@utility blog-read-more {
- @apply text-phel-primary dark:text-phel-accent hover:text-phel-secondary dark:hover:text-phel-primary ease-custom inline-flex items-center gap-1 text-sm font-semibold no-underline transition-colors duration-150;
+/* Blog post excerpt */
+.post-list li a .excerpt {
+ color: var(--color-light-text-secondary);
+ line-height: var(--leading-relaxed);
+ font-size: var(--text-base);
+ margin: 0;
}
-@utility blog-post-header {
- @apply mb-12 text-center;
+/* Blog entry (single post view) */
+@utility blog-entry {
+ max-width: var(--container-content);
+ margin: 0 auto;
}
-@utility blog-post-title-single {
- @apply text-light-text-primary dark:text-dark-text-primary mb-4 text-4xl font-bold md:text-5xl;
+.blog-entry header {
+ margin-bottom: var(--space-3xl);
+ padding-bottom: var(--space-xl);
+ border-bottom: 1px solid var(--color-light-border);
}
-@utility blog-post-meta-single {
- @apply text-light-text-secondary dark:text-dark-text-secondary flex items-center justify-center gap-6;
+.blog-entry header h1 {
+ margin-top: 0;
+ margin-bottom: var(--space-md);
+ font-size: clamp(2rem, 5vw, 3rem);
+ color: var(--color-light-text-primary);
}
-@utility blog-post-content {
- @apply max-w-none;
+.blog-entry .meta {
+ display: flex;
+ align-items: center;
+ gap: var(--space-xs);
+ flex-wrap: wrap;
+ color: var(--color-gray-light);
+ font-size: var(--text-base);
}
-@utility blog-post-navigation {
- @apply border-light-border dark:border-dark-border mt-16 flex items-center justify-between border-t pt-8;
+.blog-entry .meta time {
+ display: flex;
+ align-items: center;
+ gap: var(--space-sm);
+ font-weight: 500;
}
-@utility blog-nav-link {
- @apply text-light-text-secondary dark:text-dark-text-secondary hover:text-phel-primary dark:hover:text-phel-accent ease-custom flex items-center gap-2 px-4 py-2 text-sm font-medium no-underline transition-colors duration-150;
+.blog-entry .meta .author {
+ display: flex;
+ align-items: center;
+ gap: var(--space-sm);
+ font-weight: 500;
}
-@utility blog-pagination {
- @apply mt-12 flex items-center justify-center gap-4;
+.blog-entry .meta .author::before {
+ content: 'âī¸';
+ font-size: var(--text-lg);
}
-@utility blog-pagination-link {
- @apply text-light-text-secondary dark:text-dark-text-secondary hover:text-phel-primary dark:hover:text-phel-accent bg-light-catalogue-item-bg dark:bg-dark-catalogue-item-bg hover:bg-light-catalogue-bg dark:hover:bg-dark-catalogue-bg border-light-border dark:border-dark-border ease-custom rounded-lg border px-4 py-2 text-sm font-medium no-underline transition-colors duration-150;
+/* Blog content styling */
+.blog-entry .content {
+ font-size: var(--text-body);
+ line-height: var(--leading-relaxed);
+ color: var(--color-light-text-secondary);
}
-@utility blog-pagination-current {
- @apply bg-phel-primary border-phel-primary rounded-lg border px-4 py-2 text-sm font-medium text-white;
+.blog-entry .content > *:first-child {
+ margin-top: 0;
}
-@utility post-list {
- padding-left: 0;
- font-size: 1.1rem;
- color: var(--color-gray-lighter);
+/* Blog tags */
+.blog-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--space-sm);
+ margin: var(--space-2xl) 0;
+ padding-top: var(--space-xl);
+ border-top: 1px solid var(--color-light-border);
}
-.post-list li {
- list-style: none;
- margin: 0;
- padding: 0.5em 0;
- border-bottom: 1px solid var(--color-phel-lines);
+.blog-tag {
+ display: inline-flex;
+ align-items: center;
+ padding: var(--space-sm) var(--space-lg);
+ background: var(--color-light-bg-secondary);
+ color: var(--color-phel-primary);
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--radius-full);
+ font-size: var(--text-sm);
+ font-weight: 600;
+ text-decoration: none;
+ transition: all var(--duration-fast) var(--ease-out);
}
-@utility blog-entry {
- .meta {
- color: var(--color-gray-lighter);
- }
+.blog-tag::before {
+ content: '#';
+ opacity: 0.5;
+ margin-right: var(--space-xs);
+}
+
+.blog-tag:hover {
+ background: var(--color-phel-hover);
+ border-color: var(--color-phel-primary);
+ transform: translateY(-2px);
+}
+
+.blog-tag::after {
+ display: none;
}
+/* Pagination */
@utility pagination {
display: flex;
- justify-content: flex-end;
+ justify-content: center;
+ align-items: center;
+ gap: var(--space-md);
+ margin: var(--space-3xl) 0;
+}
+
+.pagination a {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 40px;
+ height: 40px;
+ padding: var(--space-sm) var(--space-md);
+ background: var(--color-light-surface);
+ color: var(--color-phel-primary);
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--radius-md);
+ font-weight: 600;
+ text-decoration: none;
+ transition: all var(--duration-fast) var(--ease-out);
+}
+
+.pagination a::after {
+ display: none;
+}
+
+.pagination a:hover {
+ background: var(--color-phel-hover);
+ border-color: var(--color-phel-primary);
+ transform: translateY(-2px);
+}
+
+.pagination a.active {
+ background: var(--color-phel-primary);
+ color: white;
+ border-color: var(--color-phel-primary);
}
.pagination a.previous {
margin-right: auto;
}
+
+.pagination a.previous::before {
+ content: 'â ';
+ margin-right: var(--space-xs);
+}
+
+.pagination a.next {
+ margin-left: auto;
+}
+
+.pagination a.next::after {
+ content: ' â';
+ margin-left: var(--space-xs);
+}
+
+/* Featured post highlight */
+.post-list li.featured a {
+ border: 2px solid var(--color-phel-primary);
+ background: linear-gradient(
+ 135deg,
+ rgba(99, 102, 241, 0.05),
+ transparent
+ );
+}
+
+.post-list li.featured a::before {
+ transform: scaleY(1);
+}
+
+/* Reading time indicator */
+.reading-time {
+ display: inline-flex;
+ align-items: center;
+ gap: var(--space-xs);
+ padding: var(--space-xs) var(--space-md);
+ background: var(--color-light-bg-secondary);
+ border-radius: var(--radius-full);
+ font-size: var(--text-xs);
+ font-weight: 600;
+ color: var(--color-gray-base);
+}
+
+.reading-time::before {
+ content: 'âąī¸';
+}
+
+/* Blog section header */
+.blog-header {
+ text-align: center;
+ padding: var(--space-3xl) 0;
+ margin-bottom: var(--space-2xl);
+}
+
+.blog-header h1 {
+ font-size: clamp(2.5rem, 6vw, 4rem);
+ margin-bottom: var(--space-md);
+ background: linear-gradient(135deg, var(--color-phel-primary), var(--color-phel-accent));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.blog-header p {
+ font-size: var(--text-xl);
+ color: var(--color-light-text-secondary);
+ max-width: 600px;
+ margin: 0 auto;
+}
diff --git a/css/components/dark-mode.css b/css/components/dark-mode.css
index 9fa4e38..c6c8e7d 100644
--- a/css/components/dark-mode.css
+++ b/css/components/dark-mode.css
@@ -7,217 +7,588 @@
}
}
-@utility dark-mode-toggle {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- background: transparent;
- color: white;
- border: none;
- cursor: pointer;
- padding: 0;
- margin: 0;
- line-height: 1;
- transition: opacity 0.2s ease;
-}
-
-.dark-mode-toggle:hover {
- opacity: 0.8;
-}
-
-.dark-mode-toggle svg {
- width: 22px;
- height: 22px;
- display: block;
-}
-
+/* Dark mode class-based styling */
.dark {
--color-bg: var(--color-dark-bg);
--color-text-primary: var(--color-dark-text-primary);
--color-text-secondary: var(--color-dark-text-secondary);
--color-border: var(--color-dark-border);
- --color-phel-lines: var(--color-dark-border);
-}
-
-.dark {
+ --color-phel-lines: var(--color-phel-lines-dark);
background-color: var(--color-dark-bg);
}
+/* Body and root elements */
.dark body {
background-color: var(--color-dark-bg);
color: var(--color-dark-text-primary);
}
-.dark html {
+.dark html,
+.dark :root {
background-color: var(--color-dark-bg);
}
+.dark .layout-container {
+ background-color: var(--color-dark-bg);
+}
+
+/* Modern Dark Header with glassmorphism */
.dark .site-header {
- background-color: #0f172a;
- border-bottom: 1px solid var(--color-dark-header-footer-border);
+ background: rgba(15, 23, 42, 0.85);
+ backdrop-filter: blur(var(--backdrop-blur-header)) saturate(180%);
+ -webkit-backdrop-filter: blur(var(--backdrop-blur-header)) saturate(180%);
+ border-bottom-color: rgba(51, 65, 85, 0.3);
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3),
+ 0 2px 4px -1px rgba(0, 0, 0, 0.2);
}
-.dark code:not(pre code) {
- background-color: var(--color-dark-code-inline-bg);
- color: var(--color-dark-text-accent);
+.dark .site-header.scrolled {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}
-.dark blockquote {
- background-color: var(--color-dark-blockquote-bg);
- border-left-color: var(--color-dark-blockquote-border);
+/* Dark logo styling */
+.dark .site-header__logo .phel-logo {
+ stroke: var(--color-dark-text-primary);
+ filter: drop-shadow(0 2px 4px rgba(241, 245, 249, 0.1));
}
-* {
- transition:
- background-color 0.2s ease,
- color 0.2s ease,
- border-color 0.2s ease;
+.dark .site-header__logo .logo-text {
+ color: var(--color-dark-text-primary);
}
-.dark a {
- color: var(--color-dark-link);
+
+/* Dark navigation */
+.dark .site-header__navigation a {
+ color: var(--color-dark-text-secondary);
}
-.dark a:hover {
- color: var(--color-dark-text-accent);
+.dark .site-header__navigation a::after {
+ background: var(--color-phel-accent);
}
-.dark a:focus-visible,
-.dark button:focus-visible {
- outline-color: var(--color-dark-text-primary);
+.dark .site-header__navigation a:hover {
+ color: var(--color-phel-accent);
}
-/* Search input dark mode */
-.dark #search {
- background-color: var(--color-dark-bg) !important;
- color: var(--color-dark-text-primary) !important;
- border: 1px solid var(--color-dark-border) !important;
+.dark .site-header__navigation a[aria-current='page'],
+.dark .site-header__navigation a.active {
+ color: var(--color-phel-accent);
+}
+
+/* Mobile hamburger icon dark mode */
+.dark .site-header__mobile-menu .hamburger-icon span {
+ background: var(--color-dark-text-primary);
}
-@media (min-width: 400px) {
- .dark #search {
- background-image: url("data:image/svg+xml; utf8, ") !important;
+.dark .site-header__mobile-menu .hamburger-icon:hover {
+ background: rgba(99, 102, 241, 0.15);
+}
+
+/* Mobile navigation overlay dark */
+@media (max-width: 1039px) {
+ .dark .mobile-menu-overlay {
+ background: rgba(15, 23, 42, 0.98);
+ backdrop-filter: blur(var(--backdrop-blur-lg));
+ -webkit-backdrop-filter: blur(var(--backdrop-blur-lg));
+ }
+
+ .dark .mobile-menu-nav a {
+ background: var(--color-dark-surface);
+ border-color: var(--color-dark-border);
+ color: var(--color-dark-text-primary);
+ }
+
+ .dark .mobile-menu-nav a:hover,
+ .dark .mobile-menu-nav a:active {
+ background: var(--color-phel-accent);
+ border-color: var(--color-phel-accent);
+ color: var(--color-dark-bg);
+ }
+
+ .dark .mobile-menu-actions {
+ border-top-color: var(--color-dark-border);
+ }
+
+ .dark .mobile-dark-mode-toggle {
+ background: var(--color-dark-surface);
+ border-color: var(--color-dark-border);
+ color: var(--color-dark-text-primary);
}
+
+ .dark .mobile-dark-mode-toggle:hover {
+ background: rgba(56, 189, 248, 0.15);
+ border-color: var(--color-phel-accent);
+ }
+
+ .dark .mobile-menu-toggle span {
+ background: var(--color-dark-text-primary);
+ }
+
+ .dark .mobile-menu-toggle:hover {
+ background: rgba(56, 189, 248, 0.15);
+ }
+}
+
+/* Dark search input with modern styling */
+.dark #search {
+ background-color: var(--color-dark-bg-secondary);
+ color: var(--color-dark-text-primary);
+ border-color: var(--color-dark-border);
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%2338bdf8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cpath d='m21 21-4.35-4.35'%3E%3C/path%3E%3C/svg%3E");
+}
+
+.dark #search:hover {
+ border-color: var(--color-phel-accent);
+ box-shadow: var(--shadow-dark-sm);
+}
+
+.dark #search:focus {
+ border-color: var(--color-phel-accent);
+ background-color: var(--color-dark-surface);
+ box-shadow: 0 0 0 3px rgba(56, 189, 248, 0.2),
+ var(--shadow-dark-md);
}
.dark #search::placeholder {
- color: var(--color-dark-text-secondary);
+ color: var(--color-dark-text-muted);
}
-/* Search results dark mode */
-.dark .search-results {
- background-color: var(--color-dark-code-bg);
+/* Dark action buttons */
+.dark .site-header__actions {
color: var(--color-dark-text-primary);
- border: 1px solid var(--color-dark-border);
}
-.dark .search-results ul li {
- border-bottom-color: var(--color-dark-border);
+.dark .site-header__link,
+.dark .dark-mode-toggle {
+ color: var(--color-dark-text-secondary);
}
-.dark .search-results__item .desc {
+.dark .site-header__link:hover,
+.dark .dark-mode-toggle:hover {
+ color: var(--color-phel-accent);
+ background: rgba(56, 189, 248, 0.15);
+}
+
+/* Dark typography */
+.dark h1,
+.dark h2,
+.dark h3,
+.dark h4,
+.dark h5,
+.dark h6 {
+ color: var(--color-dark-text-primary);
+}
+
+.dark p {
color: var(--color-dark-text-secondary);
}
-/* Footer dark mode */
-.dark .site-footer {
+.dark a {
+ color: var(--color-phel-accent);
+}
+
+.dark a:hover {
+ color: var(--color-phel-accent);
+}
+
+.dark a:not([class])::after {
+ background: var(--color-phel-accent);
+}
+
+/* Dark lists */
+.dark ul li::before {
+ background: var(--color-phel-accent);
+}
+
+.dark ol li:before {
+ color: var(--color-phel-accent);
+}
+
+/* Dark images - no animations */
+.dark img {
+ opacity: 1;
+}
+
+/* Make homepage logo white in dark mode */
+.dark img[src*="logo_phel.svg"] {
+ filter: brightness(0) invert(1);
+}
+
+/* Dark blockquote */
+.dark blockquote {
+ background: var(--color-dark-blockquote-bg);
+ border-left-color: var(--color-dark-blockquote-border);
color: var(--color-dark-text-secondary);
+ box-shadow: var(--shadow-dark-sm);
}
-/* Table dark mode */
-.dark table {
+.dark blockquote::before {
+ color: var(--color-dark-blockquote-border);
+}
+
+/* Dark code blocks */
+.dark pre {
+ background: var(--color-dark-code-bg);
border-color: var(--color-dark-border);
+ box-shadow: var(--shadow-dark-sm);
}
-.dark th,
-.dark td {
+.dark pre::-webkit-scrollbar-thumb {
+ background: var(--color-dark-border);
+}
+
+.dark pre::-webkit-scrollbar-thumb:hover {
+ background: var(--color-gray-base);
+}
+
+/* Dark inline code */
+.dark p code,
+.dark li code {
+ background-color: var(--color-dark-code-inline-bg);
+ color: var(--color-phel-accent);
border-color: var(--color-dark-border);
}
-/* HR dark mode */
+/* Dark tables */
+.dark table {
+ box-shadow: var(--shadow-dark-sm);
+}
+
+.dark th {
+ background: var(--color-dark-bg-secondary);
+ color: var(--color-dark-text-primary);
+ border-bottom-color: var(--color-phel-accent);
+}
+
+.dark td {
+ border-bottom-color: var(--color-dark-border);
+}
+
+.dark tr:hover {
+ background: var(--color-dark-surface-hover);
+}
+
+/* Dark HR */
.dark hr {
- border-color: var(--color-dark-border);
+ background: linear-gradient(
+ 90deg,
+ transparent,
+ var(--color-phel-lines-dark) 20%,
+ var(--color-phel-lines-dark) 80%,
+ transparent
+ );
}
-/* Related container dark mode */
-.dark .related-container {
- border-color: var(--color-dark-border);
+/* Dark separator */
+.dark .separator {
+ border-color: var(--color-phel-lines-dark);
+}
+
+/* Dark layout components */
+.dark .one-column-layout,
+.dark .two-column-layout {
+ background: transparent;
+}
+
+@media (min-width: 1040px) {
+ .dark .two-column-layout__sidebar {
+ background: var(--color-dark-surface);
+ border-color: var(--color-dark-border);
+ box-shadow: var(--shadow-dark-sm);
+ }
+}
+
+@media (max-width: 1039px) {
+ .dark .two-column-layout__sidebar {
+ background: transparent;
+ border-bottom-color: var(--color-dark-border);
+ }
}
-/* Navigation dark mode */
-.dark nav a {
+/* Dark mode for sidebar toggle */
+.dark .sidebar-toggle {
+ background: var(--color-dark-bg-secondary);
+ border-color: var(--color-dark-border);
color: var(--color-dark-text-primary);
}
-.dark nav a:hover {
- color: var(--color-dark-text-accent);
+.dark .sidebar-toggle:hover {
+ background: var(--color-dark-surface-hover);
+ border-color: var(--color-phel-primary);
}
-/* Dark mode toggle button */
-.dark .dark-mode-toggle {
+/* Dark mode for sidebar accordion open state */
+.dark .two-column-layout__sidebar:has(.sidebar-content.active) {
+ border-bottom-color: var(--color-dark-border);
+}
+
+.dark .two-column-layout__sidebar:hover {
+ box-shadow: var(--shadow-dark-md);
+}
+
+.dark .two-column-layout__sidebar::-webkit-scrollbar-thumb {
+ background: var(--color-dark-border);
+}
+
+/* Dark TOC */
+.dark .page-toc {
+ border-bottom-color: var(--color-dark-border);
+}
+
+.dark .page-toc h2 {
color: var(--color-dark-text-primary);
}
-.dark .site-header__actions {
- color: white;
+/* Dark site navigation title */
+.dark .site-navigation-title {
+ color: var(--color-dark-text-primary);
}
-.dark .site-header__actions svg {
- color: white;
+/* Dark mode anchor links */
+.dark .zola-anchor,
+.dark .zola-anchor:hover {
+ color: var(--color-dark-anchor);
}
-/* Headings dark mode */
-.dark h1,
-.dark h2,
-.dark h3,
-.dark h4,
-.dark h5,
-.dark h6 {
+/* Dark mode solution toggle */
+.dark .solution label {
+ background: var(--color-phel-accent);
+ color: var(--color-dark-bg);
+}
+
+.dark .solution label:hover {
+ background: var(--color-phel-primary);
+}
+
+.dark .solution input[type="checkbox"]:checked ~ label {
+ background: var(--color-phel-primary);
+}
+
+/* Dark mode navigation */
+.dark .site-navigation__entry.active a {
+ color: #b0ceff;
+}
+
+/* Dark mode blog styling */
+.dark .post-list li a {
+ border-bottom-color: var(--color-dark-border);
+}
+
+.dark .post-list li a h2 {
color: var(--color-dark-text-primary);
}
-/* Layout container dark mode */
-.dark .layout-container {
- background-color: var(--color-dark-bg);
+.dark .post-list li a:hover h2 {
+ color: var(--color-phel-accent);
}
-/* Main content areas dark mode */
-.dark main,
-.dark .one-column-layout,
-.dark .two-column-layout {
- background-color: var(--color-dark-bg);
+.dark .post-list li a .meta {
+ color: var(--color-dark-text-muted);
}
-/* Blog post list dark mode */
-.dark .post-list {
+.dark .post-list li a .excerpt {
color: var(--color-dark-text-secondary);
}
-.dark .post-list li {
+/* Dark API Index Pills */
+.dark .api-namespace-toggle {
border-bottom-color: var(--color-dark-border);
}
-/* Blog entry meta dark mode */
-.dark .blog-entry .meta {
+.dark .api-namespace-title {
+ color: var(--color-phel-accent);
+}
+
+.dark .api-namespace-icon {
+ color: var(--color-phel-accent);
+}
+
+.dark .api-namespace-toggle[aria-expanded="false"] + .api-namespace-content::after {
+ background: linear-gradient(to bottom,
+ transparent 0%,
+ var(--color-dark-bg) 100%);
+}
+
+.dark .api-namespace-toggle[aria-expanded="false"] + .api-namespace-content.has-overflow::before {
+ background: var(--color-phel-accent);
+ color: var(--color-dark-bg);
+ box-shadow: var(--shadow-dark-lg);
+}
+
+.dark .api-index__entry > ul a {
+ background: var(--color-dark-surface);
color: var(--color-dark-text-secondary);
+ border-color: var(--color-dark-border);
+ box-shadow: var(--shadow-dark-sm);
+}
+
+.dark .api-index__entry > ul a:hover {
+ background: var(--color-phel-accent);
+ color: var(--color-dark-bg);
+ border-color: var(--color-phel-accent);
+ box-shadow: var(--shadow-dark-md);
+}
+
+.dark .page-toc a {
+ color: var(--color-dark-text-secondary);
+}
+
+.dark .page-toc a:hover {
+ color: var(--color-phel-accent);
+ background: rgba(56, 189, 248, 0.15);
+}
+
+.dark .page-toc a.active {
+ color: var(--color-phel-accent);
+ background: rgba(56, 189, 248, 0.15);
+}
+
+/* Dark cards and navigation */
+.dark .related-container {
+ background: var(--color-dark-bg-secondary);
+ border-color: var(--color-dark-border);
+ box-shadow: var(--shadow-dark-sm);
+}
+
+.dark .related-container:hover {
+ box-shadow: var(--shadow-dark-md);
+ border-color: var(--color-phel-accent);
+}
+
+.dark .related-container .link {
+ background: var(--color-dark-surface);
+ border-color: var(--color-dark-border);
+}
+
+.dark .related-container .link:hover {
+ box-shadow: var(--shadow-dark-md);
+ border-color: var(--color-phel-accent);
+ background: rgba(56, 189, 248, 0.15);
+}
+
+.dark .related-container .link a {
+ color: var(--color-phel-accent);
+}
+
+.dark .related-container .link span {
+ color: var(--color-phel-accent);
+}
+
+/* Dark card */
+.dark .card {
+ background: var(--color-dark-surface);
+ border-color: var(--color-dark-border);
+ box-shadow: var(--shadow-dark-sm);
+}
+
+.dark .card:hover {
+ box-shadow: var(--shadow-dark-lg);
+ border-color: var(--color-phel-accent);
+}
+
+/* Dark badges */
+.dark .badge-primary {
+ background: rgba(56, 189, 248, 0.2);
+ color: var(--color-phel-accent);
+}
+
+.dark .badge-success {
+ background: var(--color-dark-current-badge-bg);
+ color: var(--color-dark-current-badge-text);
+}
+
+.dark .badge-warning {
+ background: rgba(245, 158, 11, 0.2);
+ color: #fbbf24;
+}
+
+.dark .badge-error {
+ background: rgba(239, 68, 68, 0.2);
+ color: #f87171;
+}
+
+/* Dark buttons */
+.dark .btn-primary {
+ background: var(--color-phel-accent);
+ color: var(--color-dark-bg);
+ box-shadow: var(--shadow-dark-sm);
+}
+
+.dark .btn-primary:hover {
+ background: var(--color-phel-accent);
+ box-shadow: var(--shadow-dark-md);
}
-/* Pagination dark mode */
-.dark .pagination a {
- color: var(--color-dark-link);
+.dark .btn-secondary {
+ background: var(--color-dark-surface);
+ color: var(--color-phel-accent);
+ border-color: var(--color-phel-accent);
}
-.dark .pagination a:hover {
- color: var(--color-dark-text-accent);
+.dark .btn-secondary:hover {
+ background: rgba(56, 189, 248, 0.15);
}
+/* Dark back to top button */
+.dark .back-to-top-button,
.dark #back-to-top-button {
- background-color: var(--color-dark-header-bg);
+ background: var(--color-dark-surface);
color: var(--color-dark-text-primary);
border: 1px solid var(--color-dark-border);
+ box-shadow: var(--shadow-dark-lg);
}
+.dark .back-to-top-button:hover,
.dark #back-to-top-button:hover {
- background-color: var(--color-dark-code-bg);
- color: white;
+ background: var(--color-phel-accent);
+ color: var(--color-dark-bg);
+ box-shadow: var(--shadow-dark-xl);
+ border-color: var(--color-phel-accent);
+}
+
+/* Dark search results */
+.dark .search-results {
+ background: var(--color-dark-surface);
+ border-color: var(--color-dark-border);
+ box-shadow: var(--shadow-dark-lg);
+ color: var(--color-dark-text-primary);
+}
+
+.dark .search-results__item {
+ border-bottom-color: var(--color-dark-border);
+}
+
+.dark .search-results__item:hover {
+ background: var(--color-dark-surface-hover);
+}
+
+.dark .search-results__item .desc {
+ color: var(--color-dark-text-secondary);
+}
+
+.dark .search-results__item mark {
+ background: rgba(56, 189, 248, 0.3);
+ color: var(--color-phel-accent);
+}
+
+/* Dark footer */
+.dark .site-footer {
+ background: transparent;
+ border-top-color: var(--color-dark-border);
+ color: var(--color-dark-text-secondary);
+}
+
+/* Dark focus states */
+.dark a:focus-visible,
+.dark button:focus-visible {
+ outline-color: var(--color-phel-accent);
+}
+
+/* Dark selection */
+.dark ::selection {
+ background: rgba(56, 189, 248, 0.3);
+}
+
+.dark ::-moz-selection {
+ background: rgba(56, 189, 248, 0.3);
}
diff --git a/css/components/documentation.css b/css/components/documentation.css
index d574b56..51eabc7 100644
--- a/css/components/documentation.css
+++ b/css/components/documentation.css
@@ -1,99 +1,657 @@
-@utility doc-container {
- @apply container-custom py-8;
+/* Documentation navigation in sidebar */
+@utility docs-nav {
+ padding: 0;
+ margin: 0;
}
-@utility doc-layout {
- @apply grid grid-cols-1 gap-8 lg:grid-cols-4;
+.docs-nav ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
}
-@utility doc-sidebar {
- @apply lg:col-span-1;
+.docs-nav li {
+ margin: 0;
+ padding: 0;
}
-@utility doc-content {
- @apply lg:col-span-3;
+.docs-nav li::before {
+ display: none;
}
-@utility doc-toc {
- @apply bg-light-catalogue-item-bg dark:bg-dark-catalogue-item-bg shadow-card sticky top-24 rounded-xl p-6;
+.docs-nav > ul > li {
+ margin-bottom: var(--space-md);
}
-@utility doc-toc-title {
- @apply text-light-text-primary dark:text-dark-text-primary mb-4 text-lg font-semibold;
+.docs-nav a {
+ display: block;
+ padding: var(--space-sm) var(--space-md);
+ color: var(--color-light-text-secondary);
+ font-size: var(--text-sm);
+ font-weight: 500;
+ border-radius: var(--radius-md);
+ text-decoration: none;
+ transition: all var(--duration-fast) var(--ease-out);
+ position: relative;
}
-@utility doc-toc-list {
- @apply space-y-2;
+.docs-nav a::after {
+ display: none;
}
-@utility doc-toc-link {
- @apply text-light-text-secondary dark:text-dark-text-secondary hover:text-phel-primary dark:hover:text-phel-accent ease-custom block text-sm no-underline transition-colors duration-150;
+.docs-nav a:hover {
+ color: var(--color-phel-primary);
+ background: var(--color-phel-hover);
+ transform: translateX(4px);
}
-@utility doc-toc-link-active {
- @apply text-phel-primary dark:text-phel-accent font-medium;
+.docs-nav a.active,
+.docs-nav a[aria-current='page'] {
+ color: var(--color-phel-primary);
+ background: var(--color-phel-hover);
+ font-weight: 600;
+ border-left: 3px solid var(--color-phel-primary);
+ padding-left: calc(var(--space-md) - 3px);
}
-@utility doc-article {
- @apply max-w-none;
+/* Nested navigation */
+.docs-nav ul ul {
+ margin-top: var(--space-sm);
+ margin-left: var(--space-md);
+ padding-left: var(--space-md);
+ border-left: 1px solid var(--color-light-border);
}
-@utility doc-title {
- @apply text-light-text-primary dark:text-dark-text-primary mb-6 text-4xl font-bold;
+.docs-nav ul ul a {
+ font-size: var(--text-xs);
+ padding: var(--space-xs) var(--space-sm);
}
-@utility doc-subtitle {
- @apply text-light-text-secondary dark:text-dark-text-secondary mb-8 text-xl;
+/* Documentation section headers */
+.docs-nav > ul > li > span {
+ display: block;
+ padding: var(--space-sm) var(--space-md);
+ color: var(--color-gray-base);
+ font-size: var(--text-xs);
+ font-weight: 700;
+ letter-spacing: 0.05em;
+ text-transform: uppercase;
+ margin-bottom: var(--space-xs);
}
-@utility doc-section {
- @apply mb-12;
+/* Table of contents */
+@utility page-toc {
+ display: none;
+ margin-bottom: var(--space-2xl);
+ padding-bottom: var(--space-xl);
+ border-bottom: 2px solid var(--color-light-border);
}
-@utility doc-section-title {
- @apply text-light-text-primary dark:text-dark-text-primary border-light-border dark:border-dark-border mb-4 border-b pb-2 text-2xl font-semibold;
+@media (min-width: 1040px) {
+ .page-toc {
+ display: block;
+ }
}
-@utility code-example {
- @apply mb-6 overflow-x-auto rounded-lg bg-gray-900 p-6 font-mono text-sm text-gray-100;
+.page-toc h2 {
+ font-size: var(--text-sm);
+ font-weight: 700;
+ color: var(--color-light-text-primary);
+ margin: 0 0 var(--space-md) 0;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
}
-@utility code-example-title {
- @apply mb-3 text-xs font-semibold tracking-wide text-gray-400 uppercase;
+.page-toc ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
}
-@utility api-method {
- @apply inline-block rounded-md px-3 py-1 font-mono text-xs font-bold;
+.page-toc li {
+ margin: 0;
+ padding: 0;
}
-@utility api-method-get {
- @apply api-method bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200;
+.page-toc li::before {
+ display: none;
}
-@utility api-method-post {
- @apply api-method bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200;
+.page-toc a {
+ display: block;
+ padding: var(--space-xs) var(--space-sm);
+ color: var(--color-light-text-secondary);
+ font-size: var(--text-sm);
+ line-height: 1.6;
+ text-decoration: none;
+ border-radius: var(--radius-sm);
+ transition: all var(--duration-fast) var(--ease-out);
+ border-left: 2px solid transparent;
+ padding-left: var(--space-md);
}
-@utility api-method-put {
- @apply api-method bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200;
+.page-toc a::after {
+ display: none;
}
-@utility api-method-delete {
- @apply api-method bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200;
+.page-toc a:hover {
+ color: var(--color-phel-primary);
+ background: var(--color-phel-hover);
}
-@utility doc-nav {
- @apply border-light-border dark:border-dark-border mt-12 flex items-center justify-between border-t pt-8;
+.page-toc a.active {
+ color: var(--color-phel-primary);
+ font-weight: 600;
+ background: var(--color-phel-hover);
+ border-left-color: var(--color-phel-primary);
}
-@utility doc-nav-link {
- @apply text-light-text-secondary dark:text-dark-text-secondary hover:text-phel-primary dark:hover:text-phel-accent ease-custom flex items-center gap-2 px-4 py-2 text-sm font-medium no-underline transition-colors duration-150;
+.page-toc ul ul {
+ margin-left: var(--space-md);
+ margin-top: var(--space-xs);
}
-@utility doc-search {
- @apply mx-auto mb-8 w-full max-w-md;
+.page-toc ul ul a {
+ font-size: var(--text-xs);
}
-@utility doc-search-input {
- @apply bg-light-catalogue-item-bg dark:bg-dark-catalogue-item-bg border-light-border dark:border-dark-border focus:ring-phel-primary w-full rounded-lg border px-4 py-3 text-sm focus:border-transparent focus:ring-2 focus:outline-none;
+/* Custom scrollbar for TOC */
+.page-toc::-webkit-scrollbar {
+ width: 4px;
+}
+
+.page-toc::-webkit-scrollbar-track {
+ background: transparent;
+}
+
+.page-toc::-webkit-scrollbar-thumb {
+ background: var(--color-light-border);
+ border-radius: var(--radius-full);
+}
+
+/* API Index - Pill Style */
+@utility api-index {
+ list-style: none;
+ padding: 0;
+ margin: var(--space-2xl) 0;
+ width: 100%;
+ max-width: 100%;
+}
+
+@media (max-width: 767px) {
+ .api-index {
+ padding: 0;
+ margin: var(--space-xl) 0;
+ max-width: 100%;
+ }
+}
+
+.api-index__entry {
+ margin: var(--space-3xl) 0;
+ padding: 0;
+ width: 100%;
+ max-width: 100%;
+}
+
+@media (max-width: 767px) {
+ .api-index__entry {
+ margin: var(--space-xl) 0;
+ max-width: 100%;
+ }
+}
+
+.api-index__entry::before {
+ display: none;
+}
+
+.api-namespace-toggle {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background: none;
+ border: none;
+ padding: 0;
+ cursor: default;
+ text-align: left;
+ transition: all var(--duration-fast) var(--ease-out);
+ border-bottom: 2px solid var(--color-light-border);
+ padding-bottom: var(--space-sm);
+ margin-bottom: var(--space-lg);
+}
+
+/* Only make it interactive when there's overflow */
+.api-index__entry:has(.api-namespace-content.has-overflow) .api-namespace-toggle {
+ cursor: pointer;
+}
+
+.api-namespace-title {
+ font-size: var(--text-2xl);
+ font-weight: 600;
+ color: var(--color-phel-primary);
+ margin: 0;
+ padding: 0;
+ letter-spacing: -0.02em;
+}
+
+.api-namespace-icon {
+ flex-shrink: 0;
+ color: var(--color-phel-primary);
+ transition: transform var(--duration-normal) var(--ease-out);
+ display: none;
+}
+
+/* Only show icon when there's overflow */
+.api-index__entry:has(.api-namespace-content.has-overflow) .api-namespace-icon {
+ display: block;
+}
+
+.api-namespace-toggle[aria-expanded="false"] .api-namespace-icon {
+ transform: rotate(-90deg);
+}
+
+.api-namespace-content {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--space-sm);
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ position: relative;
+ max-height: 5000px;
+ overflow: visible;
+ transition: max-height var(--duration-normal) var(--ease-out);
+ width: 100%;
+ max-width: 100%;
+ box-sizing: border-box;
+}
+
+@media (max-width: 767px) {
+ .api-namespace-content {
+ gap: var(--space-xs);
+ max-width: 100vw;
+ padding: 0;
+ }
+}
+
+/* Collapsed state - show preview with fade */
+.api-namespace-toggle[aria-expanded="false"] + .api-namespace-content {
+ max-height: 160px;
+ overflow: hidden;
+ margin-bottom: var(--space-lg);
+}
+
+/* Make entire collapsed area clickable */
+.api-namespace-toggle[aria-expanded="false"] + .api-namespace-content.has-overflow {
+ cursor: pointer;
+}
+
+/* Disable pill interactions when collapsed and has overflow */
+.api-namespace-toggle[aria-expanded="false"] + .api-namespace-content.has-overflow a {
+ pointer-events: none;
+ cursor: pointer;
+}
+
+.api-namespace-toggle[aria-expanded="false"] + .api-namespace-content::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 60px;
+ background: linear-gradient(to bottom,
+ transparent 0%,
+ var(--color-light-bg) 100%);
+ pointer-events: none;
+ opacity: 0;
+ transition: opacity var(--duration-fast) var(--ease-out);
+}
+
+/* Only show fade when content is taller than max-height */
+.api-namespace-toggle[aria-expanded="false"] + .api-namespace-content.has-overflow::after {
+ opacity: 1;
+}
+
+/* Expand overlay for collapsed sections with overflow */
+.api-namespace-toggle[aria-expanded="false"] + .api-namespace-content.has-overflow::before {
+ content: 'Expand';
+ position: absolute;
+ top: 75%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ background: var(--color-phel-primary);
+ color: white;
+ padding: var(--space-xs) var(--space-xl);
+ border-radius: var(--radius-full);
+ font-size: var(--text-sm);
+ font-weight: 600;
+ box-shadow: var(--shadow-lg);
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity var(--duration-fast) var(--ease-out);
+ z-index: 10;
+}
+
+.api-namespace-toggle[aria-expanded="false"] + .api-namespace-content.has-overflow:hover::before {
+ opacity: 1;
+}
+
+/* Expanded state - show all */
+.api-namespace-toggle[aria-expanded="true"] + .api-namespace-content {
+ max-height: 5000px;
+}
+
+.api-namespace-toggle[aria-expanded="true"] + .api-namespace-content::after {
+ display: none;
+}
+
+.api-index__entry > ul li {
+ margin: 0;
+ padding: 0;
+}
+
+.api-index__entry > ul li::before {
+ display: none;
+}
+
+.api-index__entry > ul a {
+ display: inline-block;
+ padding: var(--space-xs) var(--space-lg);
+ background: var(--color-light-bg-secondary);
+ color: var(--color-light-text-secondary);
+ font-size: var(--text-sm);
+ font-weight: 500;
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--radius-full);
+ text-decoration: none;
+ transition: all var(--duration-fast) var(--ease-out);
+ box-shadow: var(--shadow-xs);
+ max-width: 100%;
+ word-break: break-word;
+ overflow-wrap: break-word;
+}
+
+.api-index__entry > ul a::after {
+ display: none;
+}
+
+.api-index__entry > ul a:hover {
+ background: var(--color-phel-primary);
+ color: white;
+ border-color: var(--color-phel-primary);
+ box-shadow: var(--shadow-sm);
+ transform: translateY(-1px);
+}
+
+/* Mobile-specific pill constraints */
+@media (max-width: 767px) {
+ .api-index__entry > ul a {
+ padding: var(--space-xs) var(--space-sm);
+ font-size: 0.75rem;
+ max-width: 100%;
+ flex-shrink: 1;
+ min-width: 0;
+ }
+}
+
+/* Documentation content enhancements */
+.documentation-content {
+ font-size: var(--text-body);
+ line-height: var(--leading-relaxed);
+}
+
+/* Exercise Solution Toggle */
+.solution {
+ margin: var(--space-xl) 0;
+}
+
+.solution input[type="checkbox"] {
+ display: none;
+}
+
+.solution label {
+ display: inline-block;
+ padding: var(--space-xs) var(--space-lg);
+ background: var(--color-phel-primary);
+ color: white;
+ border-radius: var(--radius-md);
+ cursor: pointer;
+ font-size: var(--text-sm);
+ font-weight: 600;
+ transition: all var(--duration-fast) var(--ease-out);
+ margin-bottom: var(--space-md);
+}
+
+.solution label:hover {
+ background: var(--color-phel-secondary);
+}
+
+/* Hide solution content by default */
+.solution input[type="checkbox"] ~ * {
+ display: none;
+}
+
+.solution input[type="checkbox"] ~ label {
+ display: inline-block;
+}
+
+/* Show solution when checkbox is checked */
+.solution input[type="checkbox"]:checked ~ * {
+ display: block;
+}
+
+.solution input[type="checkbox"]:checked ~ label {
+ display: inline-block;
+ background: var(--color-phel-secondary);
+}
+
+.solution input[type="checkbox"]:checked ~ label::before {
+ content: 'â Hide solution';
+}
+
+.solution input[type="checkbox"]:not(:checked) ~ label::before {
+ content: 'â Show solution';
+}
+
+/* Remove default label text */
+.solution label {
+ font-size: 0;
+}
+
+.solution label::before {
+ font-size: var(--text-sm);
+}
+
+/* Add space between heading text and anchor link */
+.zola-anchor {
+ margin-left: var(--space-sm);
+ color: var(--color-light-anchor);
+ opacity: 0;
+ transition: opacity var(--duration-fast) var(--ease-out);
+}
+
+h1:hover .zola-anchor,
+h2:hover .zola-anchor,
+h3:hover .zola-anchor,
+h4:hover .zola-anchor,
+h5:hover .zola-anchor,
+h6:hover .zola-anchor {
+ opacity: 1;
+}
+
+/* Info boxes / Callouts */
+@utility callout {
+ padding: var(--space-lg) var(--space-xl);
+ margin: var(--space-xl) 0;
+ border-left: 4px solid;
+ border-radius: var(--radius-lg);
+ box-shadow: var(--shadow-sm);
+ position: relative;
+}
+
+.callout::before {
+ content: '';
+ position: absolute;
+ top: var(--space-lg);
+ left: var(--space-lg);
+ font-size: var(--text-2xl);
+ line-height: 1;
+}
+
+.callout-info {
+ background: rgba(59, 130, 246, 0.05);
+ border-left-color: #3b82f6;
+}
+
+.callout-info::before {
+ content: 'âšī¸';
+}
+
+.callout-warning {
+ background: rgba(245, 158, 11, 0.05);
+ border-left-color: #f59e0b;
+}
+
+.callout-warning::before {
+ content: 'â ī¸';
+}
+
+.callout-success {
+ background: rgba(16, 185, 129, 0.05);
+ border-left-color: #10b981;
+}
+
+.callout-success::before {
+ content: 'â
';
+}
+
+.callout-error {
+ background: rgba(239, 68, 68, 0.05);
+ border-left-color: #ef4444;
+}
+
+.callout-error::before {
+ content: 'â';
+}
+
+.callout p:first-of-type {
+ margin-left: 2em;
+}
+
+/* API documentation specific */
+.api-doc {
+ margin: var(--space-2xl) 0;
+}
+
+.api-doc-header {
+ display: flex;
+ align-items: baseline;
+ gap: var(--space-md);
+ padding: var(--space-lg);
+ background: var(--color-light-bg-secondary);
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--radius-lg);
+ margin-bottom: var(--space-md);
+}
+
+.api-doc-name {
+ font-family: var(--font-mono);
+ font-size: var(--text-lg);
+ font-weight: 700;
+ color: var(--color-phel-primary);
+}
+
+.api-doc-type {
+ padding: var(--space-xs) var(--space-sm);
+ font-size: var(--text-xs);
+ font-weight: 600;
+ background: var(--color-phel-hover);
+ color: var(--color-phel-primary);
+ border-radius: var(--radius-sm);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+.api-doc-description {
+ padding: 0 var(--space-lg);
+ color: var(--color-light-text-secondary);
+ line-height: var(--leading-relaxed);
+}
+
+/* Code examples with copy button */
+.code-block-wrapper {
+ position: relative;
+ margin: var(--space-xl) 0;
+}
+
+.code-block-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: var(--space-sm) var(--space-lg);
+ background: var(--color-light-bg-secondary);
+ border: 1px solid var(--color-light-border);
+ border-bottom: none;
+ border-radius: var(--radius-lg) var(--radius-lg) 0 0;
+ font-size: var(--text-sm);
+ font-weight: 600;
+ color: var(--color-light-text-secondary);
+}
+
+.code-block-wrapper pre {
+ margin: 0;
+ border-radius: 0 0 var(--radius-lg) var(--radius-lg);
+}
+
+.copy-code-button {
+ padding: var(--space-xs) var(--space-md);
+ font-size: var(--text-xs);
+ font-weight: 600;
+ color: var(--color-phel-primary);
+ background: transparent;
+ border: 1px solid var(--color-phel-primary);
+ border-radius: var(--radius-sm);
+ cursor: pointer;
+ transition: all var(--duration-fast) var(--ease-out);
+}
+
+.copy-code-button:hover {
+ background: var(--color-phel-hover);
+ transform: translateY(-1px);
+}
+
+.copy-code-button:active {
+ transform: translateY(0);
+}
+
+/* Breadcrumbs */
+.breadcrumbs {
+ display: flex;
+ align-items: center;
+ gap: var(--space-sm);
+ margin-bottom: var(--space-xl);
+ padding: var(--space-md);
+ background: var(--color-light-bg-secondary);
+ border-radius: var(--radius-lg);
+ font-size: var(--text-sm);
+}
+
+.breadcrumbs a {
+ color: var(--color-phel-primary);
+ text-decoration: none;
+ transition: color var(--duration-fast) var(--ease-out);
+}
+
+.breadcrumbs a::after {
+ display: none;
+}
+
+.breadcrumbs a:hover {
+ color: var(--color-phel-primary-hover);
+}
+
+.breadcrumbs span:not(:last-child)::after {
+ content: 'âē';
+ margin-left: var(--space-sm);
+ color: var(--color-gray-light);
}
diff --git a/css/components/footer.css b/css/components/footer.css
new file mode 100644
index 0000000..4e57b6e
--- /dev/null
+++ b/css/components/footer.css
@@ -0,0 +1,7 @@
+@utility site-footer {
+ padding-top: var(--space-2xl);
+ padding-bottom: var(--space-lg);
+ text-align: center;
+ font-size: var(--text-sm);
+ color: var(--color-light-text-secondary);
+}
diff --git a/css/components/header.css b/css/components/header.css
index d7f373f..c4121c3 100644
--- a/css/components/header.css
+++ b/css/components/header.css
@@ -1,133 +1,339 @@
+/* Header Container */
@utility site-header {
- background-color: var(--color-phel-primary);
position: fixed;
top: 0;
left: 0;
right: 0;
height: var(--header-height);
- z-index: 1;
+ z-index: var(--z-fixed);
+ background: rgba(255, 255, 255, 0.85);
+ backdrop-filter: blur(var(--backdrop-blur-header)) saturate(180%);
+ -webkit-backdrop-filter: blur(var(--backdrop-blur-header)) saturate(180%);
+ border-bottom: 1px solid rgba(226, 232, 240, 0.3);
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.02),
+ 0 2px 4px -1px rgba(0, 0, 0, 0.01);
+ transition: all var(--duration-normal) var(--ease-out);
}
-@utility site-header__container {
+.site-header__container {
display: flex;
align-items: center;
- padding: 0.2em 2em;
+ height: 100%;
+ width: 100%;
+ max-width: var(--container-wide);
+ margin: 0 auto;
+ padding: 0 var(--space-lg);
+ gap: var(--space-lg);
+ box-sizing: border-box;
}
-@media (max-width: 1039px) {
+@media (max-width: 767px) {
.site-header__container {
- padding: 0.2em 1em;
+ padding: 0 var(--space-md);
+ gap: var(--space-sm);
}
}
-@utility site-header__mobile-menu {
- @media (min-width: 1040px) {
- display: none;
- }
+/* ========================================
+ MOBILE MENU TOGGLE (HAMBURGER)
+ ======================================== */
+
+.mobile-menu-toggle {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 5px;
+ width: 44px;
+ height: 44px;
+ background: transparent;
+ border: none;
+ cursor: pointer;
+ padding: 8px;
+ border-radius: var(--radius-md);
+ transition: all var(--duration-fast) var(--ease-out);
+ z-index: calc(var(--z-fixed) + 50);
+ flex-shrink: 0;
}
-.site-header__mobile-menu input[type='checkbox'] {
- display: none;
- visibility: hidden;
+.mobile-menu-toggle:hover {
+ background: var(--color-phel-hover);
}
-.site-header__mobile-menu label {
- cursor: pointer;
+.mobile-menu-toggle span {
display: block;
- padding: 0.5em;
- margin-right: 1em;
- text-align: center;
+ width: 24px;
+ height: 2px;
+ background: var(--color-gray-darker);
+ border-radius: var(--radius-full);
+ transition: all var(--duration-normal) var(--ease-out);
}
-.site-header__mobile-menu label svg {
- max-height: 1em;
- width: 1em;
- stroke: white;
- stroke-width: 5px;
- vertical-align: middle;
+/* Transform to X when active */
+.mobile-menu-toggle.active span:nth-child(1) {
+ transform: translateY(7px) rotate(45deg);
}
-.site-header__mobile-menu nav {
- display: none;
+.mobile-menu-toggle.active span:nth-child(2) {
+ opacity: 0;
+ transform: scale(0);
}
-.site-header__mobile-menu input[type='checkbox']:checked ~ nav {
- display: block;
- position: fixed;
- margin-top: 0;
- top: var(--header-height);
- bottom: 0;
- left: 0;
- border-right: 1px solid var(--color-gray-lighter);
- width: 15em;
- padding: 2em;
- background-color: white;
- overflow-y: auto;
+.mobile-menu-toggle.active span:nth-child(3) {
+ transform: translateY(-7px) rotate(-45deg);
+}
+
+/* Hide on desktop */
+@media (min-width: 1040px) {
+ .mobile-menu-toggle {
+ display: none;
+ }
}
+/* ========================================
+ LOGO
+ ======================================== */
+
@utility site-header__logo {
display: flex;
align-items: center;
+ flex-shrink: 0;
- a {
+ .logo-link {
display: inline-flex;
align-items: center;
- padding: 0.5em;
+ gap: var(--space-sm);
+ padding: var(--space-sm);
+ border-radius: var(--radius-md);
+ text-decoration: none;
}
.phel-logo {
- max-height: 1.8em;
- width: 2.2em;
- stroke: white;
+ max-height: 1.5em;
+ width: 1.8em;
+ stroke: var(--color-phel-primary);
stroke-width: 5px;
+ fill: transparent;
+ filter: drop-shadow(0 2px 4px rgba(99, 102, 241, 0.1));
+ flex-shrink: 0;
}
-}
-@utility site-header__search {
- display: block;
-}
-
-@media (max-width: 1039px) {
- .site-header__search {
- margin-left: auto;
+ .logo-text {
+ font-size: var(--text-xl);
+ font-weight: 700;
+ color: var(--color-gray-darker);
+ letter-spacing: -0.02em;
}
}
+/* ========================================
+ DESKTOP NAVIGATION
+ ======================================== */
+
@utility site-header__navigation {
display: none;
+ flex: 0 1 auto;
+ align-items: center;
+ margin: 0;
+ padding: 0;
}
@media (min-width: 1040px) {
.site-header__navigation {
- display: block;
- flex-grow: 2;
- }
-
- .site-header__navigation .top-navigation__item--github {
- display: none;
+ display: flex;
+ align-items: center;
}
.site-header__navigation ul {
+ display: flex;
+ align-items: center;
+ gap: var(--space-lg);
list-style: none;
+ padding: 0;
+ margin: 0;
+ }
+
+ .site-header__navigation li {
margin: 0;
padding: 0;
- margin-left: 2em;
- display: flex;
- justify-content: flex-start;
}
- .site-header__navigation ul li a {
- padding: 0.5em 1em;
+ .site-header__navigation li::before {
+ display: none;
+ }
+
+ .site-header__navigation a {
display: inline-block;
- color: white;
+ padding: 0;
+ color: var(--color-gray-dark);
+ font-weight: 500;
+ font-size: var(--text-base);
+ text-decoration: none;
+ position: relative;
+ transition: color var(--duration-fast) var(--ease-out);
+ }
+
+ .site-header__navigation a::after {
+ content: '';
+ position: absolute;
+ bottom: -2px;
+ left: 0;
+ width: 0;
+ height: 2px;
+ background: var(--color-phel-primary);
+ transition: width var(--duration-normal) var(--ease-out);
}
- .site-header__navigation ul li.active a {
- text-decoration: underline;
+ .site-header__navigation a:hover {
+ color: var(--color-phel-primary);
+ }
+
+ .site-header__navigation a:hover::after {
+ width: 100%;
+ }
+
+ .site-header__navigation a.active {
+ color: var(--color-phel-primary);
+ font-weight: 600;
+ }
+
+ .site-header__navigation a.active::after {
+ width: 100%;
+ height: 2px;
+ }
+}
+
+/* ========================================
+ SEARCH
+ ======================================== */
+
+@utility site-header__search {
+ position: relative;
+ margin-left: auto;
+ flex: 1;
+ max-width: 370px;
+ transition: max-width var(--duration-normal) var(--ease-out);
+}
+
+@media (min-width: 1040px) {
+ .site-header__search:focus-within {
+ max-width: 600px;
}
}
-/* Actions container (dark mode + social links) */
+#search {
+ width: 100%;
+ padding: var(--space-sm) var(--space-md);
+ padding-left: 36px;
+ font-size: var(--text-sm);
+ font-family: var(--font-primary);
+ color: var(--color-light-text-primary);
+ background-color: var(--color-light-bg-secondary);
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--radius-full);
+ outline: none;
+ transition: all var(--duration-normal) var(--ease-out);
+ box-shadow: var(--shadow-xs);
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236366f1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cpath d='m21 21-4.35-4.35'%3E%3C/path%3E%3C/svg%3E");
+ background-repeat: no-repeat;
+ background-position: 10px center;
+ background-size: 16px;
+}
+
+#search:hover {
+ border-color: var(--color-phel-primary);
+ box-shadow: var(--shadow-sm);
+}
+
+#search:focus {
+ border-color: var(--color-phel-primary);
+ background-color: var(--color-light-surface);
+ box-shadow: 0 0 0 3px var(--color-phel-hover),
+ var(--shadow-md);
+}
+
+#search::placeholder {
+ color: var(--color-gray-light);
+}
+
+/* Mobile search adjustments */
+@media (max-width: 1039px) {
+ .site-header__search {
+ flex: 0 0 auto;
+ width: 50%;
+ min-width: 180px;
+ max-width: 360px;
+ transition: all var(--duration-normal) var(--ease-out);
+ }
+
+ #search {
+ font-size: var(--text-sm);
+ padding: var(--space-sm) var(--space-md);
+ padding-left: 36px;
+ background-size: 16px;
+ background-position: 10px center;
+ width: 100%;
+ border: 1px solid var(--color-light-border);
+ transition: all var(--duration-normal) var(--ease-out);
+ }
+
+ #search::placeholder {
+ opacity: 1;
+ transition: opacity var(--duration-fast) var(--ease-out);
+ }
+
+ /* When search is expanded on mobile, hide other elements */
+ .site-header__container.search-expanded {
+ gap: 0;
+ padding-left: var(--space-md);
+ padding-right: var(--space-md);
+ }
+
+ .site-header__container.search-expanded .mobile-menu-toggle,
+ .site-header__container.search-expanded .site-header__logo {
+ opacity: 0;
+ pointer-events: none;
+ width: 0;
+ min-width: 0;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ transition: all var(--duration-normal) var(--ease-out);
+ }
+
+ .site-header__container.search-expanded .site-header__search {
+ flex: 1 1 100%;
+ width: 100%;
+ max-width: none;
+ margin: 0;
+ }
+
+ .site-header__container.search-expanded #search {
+ width: 100%;
+ border-color: var(--color-phel-primary);
+ animation: expandSearch var(--duration-normal) var(--ease-out);
+ }
+
+ .site-header__container.search-expanded #search::placeholder {
+ opacity: 1;
+ }
+}
+
+@keyframes expandSearch {
+ from {
+ transform: scale(0.95);
+ opacity: 0.8;
+ }
+ to {
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+
+/* ========================================
+ DESKTOP ACTIONS (Dark Mode, Social)
+ ======================================== */
+
@utility site-header__actions {
display: none;
}
@@ -136,107 +342,211 @@
.site-header__actions {
display: flex;
align-items: center;
- gap: 1em;
- margin-left: 1em;
+ gap: var(--space-sm);
+ flex-shrink: 0;
}
}
-/* Individual link styling */
@utility site-header__link {
display: inline-flex;
align-items: center;
justify-content: center;
- color: white;
- padding: 0;
- margin: 0;
- line-height: 1;
- transition: opacity 0.2s ease;
+ width: 40px;
+ height: 40px;
+ color: var(--color-gray-dark);
+ background: transparent;
+ border-radius: var(--radius-md);
+ transition: all var(--duration-fast) var(--ease-out);
}
.site-header__link:hover {
- opacity: 0.8;
+ color: var(--color-phel-primary);
+ background: var(--color-phel-hover);
}
.site-header__link svg {
- display: block;
- width: 18px;
- height: 18px;
+ width: 20px;
+ height: 20px;
}
-[id]::before {
- content: '';
- display: block;
- height: var(--header-height);
- margin-top: calc(-1 * var(--header-height));
- visibility: hidden;
+@utility dark-mode-toggle {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ background: transparent;
+ color: var(--color-gray-dark);
+ border: none;
+ border-radius: var(--radius-md);
+ cursor: pointer;
+ transition: all var(--duration-fast) var(--ease-out);
+}
+
+.dark-mode-toggle:hover {
+ color: var(--color-phel-primary);
+ background: var(--color-phel-hover);
}
-@utility back-to-top-button {
+.dark-mode-toggle svg {
+ width: 20px;
+ height: 20px;
+}
+
+/* ========================================
+ MOBILE MENU OVERLAY
+ ======================================== */
+
+.mobile-menu-overlay {
display: none;
position: fixed;
- bottom: 20px;
- right: 30px;
- z-index: 99;
- border: none;
- outline: none;
- background-color: var(--color-phel-primary);
- color: white;
- cursor: pointer;
- padding: 15px;
- border-radius: 2px;
- font-size: 18px;
+ top: var(--header-height);
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: 100vw;
+ height: calc(100vh - var(--header-height));
+ background: rgba(255, 255, 255, 0.98);
+ backdrop-filter: blur(var(--backdrop-blur-lg));
+ -webkit-backdrop-filter: blur(var(--backdrop-blur-lg));
+ z-index: 999999;
+ overflow-y: auto;
+ animation: fadeIn var(--duration-normal) var(--ease-out);
+}
+
+.mobile-menu-overlay.active {
+ display: block !important;
+ visibility: visible !important;
+ opacity: 1 !important;
+}
+
+.mobile-menu-nav {
+ padding: var(--space-xl) var(--space-lg);
+}
+
+.mobile-menu-nav ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-md);
+}
+
+.mobile-menu-nav li {
+ margin: 0;
+ width: 100%;
}
-.back-to-top-button:hover {
- background-color: var(--color-phel-hover);
+.mobile-menu-nav li::before {
+ display: none;
}
-@utility site-footer {
- margin-top: 5em;
+.mobile-menu-nav a {
+ display: block;
+ width: 100%;
+ padding: var(--space-sm) var(--space-md);
+ font-size: var(--text-xl);
+ font-weight: 600;
+ color: var(--color-light-text-primary);
text-align: center;
- font-size: 14px;
+ background: var(--color-light-surface);
+ border: 2px solid var(--color-light-border);
+ border-radius: var(--radius-xl);
+ text-decoration: none;
+ transition: all var(--duration-fast) var(--ease-out);
+ box-sizing: border-box;
}
-@utility phel-logo {
- fill: none;
- stroke: var(--color-phel-primary);
- stroke-width: 3px;
+.mobile-menu-nav a::after {
+ display: none;
}
-@utility api-index {
- padding: 0;
+.mobile-menu-nav a:hover,
+.mobile-menu-nav a:active {
+ background: var(--color-phel-primary);
+ color: white;
+ border-color: var(--color-phel-primary);
+ transform: scale(1.02);
}
-.api-index li {
- display: inline-block;
+/* Mobile menu actions (Dark mode toggle) */
+.mobile-menu-actions {
+ margin-top: var(--space-2xl);
+ padding-top: var(--space-xl);
+ border-top: 2px solid var(--color-light-border);
}
-@utility zola-anchor {
- color: var(--color-gray-lighter);
- font-style: italic;
- padding-left: 0.2em;
+.mobile-dark-mode-toggle {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: var(--space-md);
+ width: 100%;
+ padding: var(--space-sm) var(--space-md);
+ font-size: var(--text-lg);
+ font-weight: 600;
+ color: var(--color-light-text-primary);
+ background: var(--color-light-surface);
+ border: 2px solid var(--color-light-border);
+ border-radius: var(--radius-xl);
+ cursor: pointer;
+ transition: all var(--duration-fast) var(--ease-out);
+ font-family: var(--font-primary);
}
-@utility solution {
- input + label + pre {
- display: none;
- }
+.mobile-dark-mode-toggle:hover {
+ background: var(--color-phel-hover);
+ border-color: var(--color-phel-primary);
+}
- input:checked + label + pre {
- display: block;
+.mobile-dark-mode-toggle svg {
+ width: 24px;
+ height: 24px;
+}
+
+/* Prevent body scroll when menu is open */
+body.menu-open {
+ overflow: hidden;
+}
+
+/* Hide mobile menu on desktop */
+@media (min-width: 1040px) {
+ .mobile-menu-overlay {
+ display: none !important;
}
}
-.solution label {
- font-style: italic;
- cursor: pointer;
- user-select: none;
+/* ========================================
+ ANIMATIONS
+ ======================================== */
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
}
-.solution label:hover {
- text-decoration: underline;
+/* ========================================
+ SCROLL EFFECTS
+ ======================================== */
+
+@media (min-width: 1040px) {
+ .site-header.scrolled {
+ height: 60px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
+ }
}
-@utility flex-container {
- display: flex;
+/* Anchor scroll offset */
+[id]::before {
+ content: '';
+ display: block;
+ height: var(--header-height);
+ margin-top: calc(var(--header-height) * -1);
+ visibility: hidden;
+ pointer-events: none;
}
diff --git a/css/components/layout.css b/css/components/layout.css
index 1868afb..f3f1eeb 100644
--- a/css/components/layout.css
+++ b/css/components/layout.css
@@ -1,102 +1,340 @@
-@utility one-column-layout {
- margin: 0 auto;
- max-width: 800px;
- padding: 2em 2em;
+/* Layout Container with smooth transitions */
+@utility layout-container {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ background: var(--color-light-bg);
+ transition: background-color var(--duration-normal) var(--ease-out);
}
-@utility found-a-typo {
- float: right;
- margin-top: 50px;
+/* One Column Layout - Modern Content */
+@utility one-column-layout {
+ margin: 0 auto;
+ width: 100%;
+ max-width: var(--container-content);
+ padding: 0 var(--space-xl);
+ animation: fadeInUp var(--duration-slow) var(--ease-out);
}
-@utility layout-container {
- max-width: 1200px;
- margin: -20px auto 20px auto;
- padding-top: 9px;
+@media (max-width: 767px) {
+ .one-column-layout {
+ padding: 0 var(--space-md);
+ }
}
+/* Two Column Layout - Modern Documentation */
@utility two-column-layout {
+ display: grid;
+ grid-template-columns: minmax(0, 1fr);
+ gap: var(--space-md);
+ max-width: var(--container-wide);
+ width: 100%;
margin: 0 auto;
- max-width: 800px;
+ padding: 0 var(--space-xl);
+ box-sizing: border-box;
+ animation: fadeInUp var(--duration-slow) var(--ease-out);
+}
+
+@media (max-width: 767px) {
+ .two-column-layout {
+ padding: 0 var(--space-md);
+ max-width: 100vw;
+ box-sizing: border-box;
+ }
+}
+
+@media (min-width: 1040px) {
+ .two-column-layout {
+ grid-template-columns: 280px minmax(0, 1fr);
+ gap: var(--space-2xl);
+ padding: 0 var(--space-xl);
+ }
}
+/* Sidebar with modern sticky behavior */
@utility two-column-layout__sidebar {
+ order: -1;
+}
+
+/* Sidebar toggle button - hidden on desktop */
+.sidebar-toggle {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ padding: var(--space-md);
+ background: var(--color-light-bg-secondary);
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--radius-lg);
+ color: var(--color-light-text-primary);
+ font-weight: 600;
+ font-size: var(--text-sm);
+ cursor: pointer;
+ margin: var(--space-md) 0;
+ transition: all var(--duration-fast) var(--ease-out);
+ position: relative;
+ z-index: 10;
+}
+
+.sidebar-toggle:hover {
+ background: var(--color-light-surface-hover);
+ border-color: var(--color-phel-primary);
+}
+
+.sidebar-toggle[aria-expanded="true"] .sidebar-toggle-text::before {
+ content: 'Hide navigation';
+}
+
+.sidebar-toggle[aria-expanded="false"] .sidebar-toggle-text::before {
+ content: 'Show navigation';
+}
+
+.sidebar-toggle-text {
+ font-size: 0;
+}
+
+.sidebar-toggle-text::before {
+ font-size: var(--text-sm);
+}
+
+/* Sidebar content - collapsed by default on mobile */
+.sidebar-content {
display: none;
+ animation: fadeInUp var(--duration-fast) var(--ease-out);
+}
+
+.sidebar-content.active {
+ display: block;
}
-@utility two-column-layout__content {
- padding: 0 2em 0 2em;
+/* Add bottom border to sidebar when accordion is open on mobile */
+.two-column-layout__sidebar:has(.sidebar-content.active) {
+ padding-bottom: var(--space-xl);
+ border-bottom: 2px solid var(--color-light-border);
}
@media (min-width: 1040px) {
- .two-column-layout {
- margin: unset;
- max-width: unset;
+ .sidebar-toggle {
+ display: none;
}
- .two-column-layout__sidebar {
- border-right: 1px solid var(--color-phel-lines);
+ .sidebar-content {
display: block;
- height: 100%;
- padding: 25px;
- padding-top: 68px;
- position: fixed;
- width: 19em;
}
- .two-column-layout__sidebar .site-navigation {
+ .two-column-layout__sidebar {
+ order: -1;
+ margin-bottom: 0;
+ padding-bottom: 0;
+ padding: var(--space-xl);
+ border-bottom: none;
+ position: sticky;
+ top: calc(var(--header-height) + var(--space-xl));
+ align-self: start;
+ max-height: calc(100vh - var(--header-height) - var(--space-2xl));
overflow-y: auto;
- max-height: calc(100vh - 7rem);
+ background: var(--color-light-surface);
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--radius-xl);
+ box-shadow: var(--shadow-sm);
+ transition: all var(--duration-normal) var(--ease-out);
}
- .two-column-layout__content {
- box-sizing: border-box;
- flex: 1;
- max-width: 800px;
- margin-left: 350px;
- margin-top: 0;
- padding-top: 10px;
+ /* Remove the extra bottom border on desktop */
+ .two-column-layout__sidebar:has(.sidebar-content.active) {
+ padding-bottom: 0;
+ border-bottom: none;
+ }
+
+ .two-column-layout__sidebar:hover {
+ box-shadow: var(--shadow-md);
+ }
+
+ /* Custom scrollbar for sidebar */
+ .two-column-layout__sidebar::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ .two-column-layout__sidebar::-webkit-scrollbar-track {
+ background: transparent;
}
+
+ .two-column-layout__sidebar::-webkit-scrollbar-thumb {
+ background: var(--color-light-border);
+ border-radius: var(--radius-full);
+ }
+
+ .two-column-layout__sidebar::-webkit-scrollbar-thumb:hover {
+ background: var(--color-gray-base);
+ }
+}
+
+/* Main content area */
+@utility two-column-layout__main {
+ order: 1;
+ min-width: 0;
+ width: 100%;
+ max-width: 100%;
+ overflow-wrap: break-word;
+ word-wrap: break-word;
}
-@utility site-navigation {
- li.active {
- font-weight: bold;
+
+@media (min-width: 1040px) {
+ .two-column-layout__main {
+ order: 0;
}
}
+/* Modern Page Navigation (Previous/Next) */
@utility related-container {
- border: 1px solid var(--color-gray-base);
- margin: 4rem 0 4rem 0;
- text-align: center;
- overflow: hidden;
- clear: both;
- display: block;
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: var(--space-md);
+ margin: var(--space-3xl) 0;
+ padding: var(--space-xl);
+ background: var(--color-light-bg-secondary);
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--radius-xl);
+ box-shadow: var(--shadow-sm);
+ transition: all var(--duration-normal) var(--ease-out);
+}
+
+@media (min-width: 768px) {
+ .related-container {
+ grid-template-columns: 1fr 1fr;
+ }
+}
+
+.related-container:hover {
+ box-shadow: var(--shadow-md);
+ border-color: var(--color-phel-primary);
}
.related-container .link {
- padding: 0.4rem;
- display: inline-block;
+ display: flex;
+ align-items: center;
+ gap: var(--space-sm);
+ padding: var(--space-lg);
+ background: var(--color-light-surface);
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--radius-lg);
+ transition: all var(--duration-fast) var(--ease-out);
+ text-decoration: none;
+}
+
+.related-container .link:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-md);
+ border-color: var(--color-phel-primary);
+ background: var(--color-phel-hover);
+}
+
+.related-container .link a {
+ color: var(--color-phel-primary);
+ font-weight: 600;
+ text-decoration: none;
+}
+
+.related-container .link a::after {
+ display: none;
+}
+
+.related-container .link a:hover {
+ color: var(--color-phel-primary-hover);
+}
+
+.related-container .link span {
+ font-size: var(--text-2xl);
+ color: var(--color-phel-primary);
+ transition: transform var(--duration-fast) var(--ease-out);
}
.related-container .link-previous {
- float: left;
- text-align: left;
+ justify-content: flex-start;
+}
+
+.related-container .link-previous:hover span {
+ transform: translateX(-4px);
}
.related-container .link-next {
- float: right;
+ justify-content: flex-end;
text-align: right;
}
-@utility page-content {
- margin: unset;
- max-width: unset;
- overflow-x: scroll;
+.related-container .link-next:hover span {
+ transform: translateX(4px);
+}
+
+/* Back to Top Button - Modern floating action */
+@utility back-to-top-button {
+ position: fixed;
+ bottom: var(--space-2xl);
+ right: var(--space-2xl);
+ width: 48px;
+ height: 48px;
+ background: var(--color-phel-primary);
+ color: white;
+ border: none;
+ border-radius: var(--radius-full);
+ cursor: pointer;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(20px);
+ transition: all var(--duration-normal) var(--ease-out);
+ box-shadow: var(--shadow-lg);
+ z-index: var(--z-sticky);
+ font-size: var(--text-xs);
+ font-weight: 600;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.back-to-top-button.visible {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+.back-to-top-button:hover {
+ background: var(--color-phel-primary-hover);
+ box-shadow: var(--shadow-xl);
}
-@utility page-toc-list {
- .page-toc-h1-children {
- margin-top: 0;
+.back-to-top-button:active {
+ transform: scale(0.95);
+}
+
+/* Animation keyframes */
+@keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateY(30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes slideInRight {
+ from {
+ opacity: 0;
+ transform: translateX(-30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateX(0);
+ }
+}
+
+@keyframes pulse {
+ 0%, 100% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.8;
}
}
diff --git a/css/components/navigation.css b/css/components/navigation.css
index 6be43aa..897d15c 100644
--- a/css/components/navigation.css
+++ b/css/components/navigation.css
@@ -1,64 +1,88 @@
-@utility nav-header {
- background-color: var(--color-phel-primary);
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- height: var(--header-height);
- z-index: 1;
-}
-
-@utility nav-container {
+.top-navigation {
display: flex;
align-items: center;
- padding: 0.2em 2em;
+ gap: var(--space-md);
+ list-style: none;
+ padding: 0;
+ margin: 0;
}
-@media (max-width: 1039px) {
- .nav-container {
- padding: 0.2em 1em;
- }
+.top-navigation li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.top-navigation li::before {
+ display: none;
}
-@utility nav-logo {
- @apply text-light-text-primary dark:text-dark-text-primary flex items-center gap-3 text-xl font-bold no-underline;
- &:hover {
- @apply text-light-text-primary dark:text-dark-text-primary no-underline;
+@media (min-width: 1040px) {
+ .top-navigation__item--github {
+ display: none;
}
}
-@utility nav-logo-image {
- @apply h-8 w-8;
+/* Site Navigation (sidebar) */
+.site-navigation-title {
+ font-size: var(--text-sm);
+ font-weight: 700;
+ color: var(--color-light-text-primary);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
}
-@utility nav-menu {
- @apply hidden items-center gap-6 md:flex;
+@media (min-width: 1040px) {
+ .site-navigation-title {
+ margin-top: 0;
+ }
+}
+
+.site-navigation {
+ list-style: none;
+ padding: 0;
+ margin: 0;
}
-@utility nav-link {
- @apply text-light-text-secondary dark:text-dark-text-secondary hover:text-light-text-primary dark:hover:text-dark-text-primary ease-custom font-medium no-underline transition-colors duration-150;
+.site-navigation li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
}
-@utility nav-link-active {
- @apply text-phel-primary dark:text-phel-accent font-semibold;
+.site-navigation li::before {
+ display: none;
}
-@utility nav-mobile-toggle {
- @apply text-light-text-secondary dark:text-dark-text-secondary hover:text-light-text-primary dark:hover:text-dark-text-primary p-2 md:hidden;
+.site-navigation__entry {
+ margin: var(--space-xs) 0;
}
-@utility nav-mobile-menu {
- @apply bg-light-bg dark:bg-dark-bg border-light-border dark:border-dark-border absolute top-full right-0 left-0 border-b shadow-lg md:hidden;
+.site-navigation__entry a {
+ display: block;
+ padding: var(--space-sm) var(--space-md);
+ color: var(--color-light-text-secondary);
+ font-size: var(--text-sm);
+ font-weight: 500;
+ border-radius: var(--radius-md);
+ text-decoration: none;
+ transition: all var(--duration-fast) var(--ease-out);
}
-@utility nav-mobile-links {
- @apply flex flex-col py-4;
+.site-navigation__entry a::after {
+ display: none;
}
-@utility nav-mobile-link {
- @apply text-light-text-secondary dark:text-dark-text-secondary hover:text-light-text-primary dark:hover:text-dark-text-primary hover:bg-light-catalogue-bg dark:hover:bg-dark-catalogue-bg ease-custom px-6 py-3 no-underline transition-colors duration-150;
+.site-navigation__entry a:hover {
+ color: var(--color-phel-primary);
+ background: var(--color-phel-hover);
+ transform: translateX(4px);
}
-@utility theme-toggle {
- @apply text-light-text-secondary dark:text-dark-text-secondary hover:text-light-text-primary dark:hover:text-dark-text-primary hover:bg-light-catalogue-bg dark:hover:bg-dark-catalogue-bg ease-custom rounded-lg p-2 transition-colors duration-150;
+.site-navigation__entry.active a {
+ color: var(--color-phel-primary);
+ background: var(--color-phel-hover);
+ font-weight: 600;
+ padding-left: calc(var(--space-md) - 3px);
}
+
diff --git a/css/components/performance.css b/css/components/performance.css
index 03db043..89e96d7 100644
--- a/css/components/performance.css
+++ b/css/components/performance.css
@@ -5,6 +5,7 @@
}
}
+/* Respect user's motion preferences */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
@@ -16,46 +17,7 @@
}
}
+/* Smooth scrolling utility - used in base.css */
@utility scroll-smooth {
scroll-behavior: smooth;
}
-
-@utility img-optimized {
- img {
- loading: lazy;
- decoding: async;
- }
-}
-
-@utility critical-above-fold {
- .site-header,
- .site-header__container,
- .site-header__logo {
- contain: layout style;
- }
-}
-
-@utility gpu-accelerated {
- transform: translateZ(0);
- will-change: transform;
-}
-
-@utility optimized-text {
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-@utility focus-optimized {
- &:focus-visible {
- outline: 2px solid var(--color-phel-primary);
- outline-offset: 2px;
- }
-}
-
-@container (min-width: 768px) {
- .responsive-container {
- display: grid;
- grid-template-columns: 1fr 3fr;
- }
-}
diff --git a/css/components/search.css b/css/components/search.css
index 58db4f8..8508485 100644
--- a/css/components/search.css
+++ b/css/components/search.css
@@ -1,91 +1,193 @@
-@utility site-header__search {
- #search {
- background-color: white;
- border-color: transparent;
- border-radius: 2px;
- padding-top: 4px;
- padding-bottom: 4px;
- margin-left: 10px;
- font-size: 14px;
- width: 230px;
- }
+/* Search results dropdown with glassmorphism */
+@utility search-results {
+ position: absolute;
+ top: calc(100% + var(--space-sm));
+ left: 0;
+ right: 0;
+ max-height: 70vh;
+ overflow-y: auto;
+ background: rgba(255, 255, 255, 0.95);
+ backdrop-filter: blur(var(--backdrop-blur-md)) saturate(180%);
+ -webkit-backdrop-filter: blur(var(--backdrop-blur-md)) saturate(180%);
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--radius-xl);
+ box-shadow: var(--shadow-xl);
+ z-index: 9999999;
+ animation: slideInDown var(--duration-normal) var(--ease-out);
+ display: none;
+}
+
+.search-results.active {
+ display: block;
+}
- /* Hide "s" icon on small screens to avoid search-box overflow */
- @media (min-width: 400px) {
- #search {
- background-image: url("data:image/svg+xml; utf8, ");
- background-repeat: no-repeat;
- padding-left: 50px;
- }
+/* Mobile: Full width search results */
+@media (max-width: 1039px) {
+ .search-results {
+ left: 0;
+ right: 0;
+ width: 100%;
+ max-width: none;
+ border-radius: var(--radius-lg);
}
- li.selected,
- li:hover {
- text-decoration: underline;
- background-color: var(--color-phel-hover);
+ /* When search is expanded, adjust positioning */
+ .search-expanded .search-results {
+ left: 0;
+ right: 0;
}
}
-@utility search-results {
- display: none;
- position: absolute;
- background: white;
- color: var(--color-gray-darker);
- box-shadow:
- 0 5px 5px -3px rgba(0, 0, 0, 0.2),
- 0 8px 10px 1px rgba(0, 0, 0, 0.14),
- 0 3px 14px 2px rgba(0, 0, 0, 0.12);
- margin-right: 5px;
- overflow: auto;
- max-height: calc(100vh - 4rem);
-}
-
-@media (min-width: 1040px) {
- .search-results {
- max-height: 500px;
- }
+/* Custom scrollbar for search results */
+.search-results::-webkit-scrollbar {
+ width: 8px;
}
-@utility search-results__items {
- list-style: none;
+.search-results::-webkit-scrollbar-track {
+ background: transparent;
}
-.search-results ul {
- padding-left: 0;
+.search-results::-webkit-scrollbar-thumb {
+ background: var(--color-light-border);
+ border-radius: var(--radius-full);
}
-.search-results ul li {
- padding: 0.6rem 0.6rem 0 1rem;
- border-bottom: 1px solid #ccc;
- font-size: 0.9rem;
+.search-results::-webkit-scrollbar-thumb:hover {
+ background: var(--color-gray-base);
}
-.search-results ul li:first-of-type {
- margin-top: 0;
+/* Search results list */
+@utility search-results__items {
+ list-style: none;
+ padding: var(--space-sm);
+ margin: 0;
}
-.search-results ul li:last-child {
- border-bottom: none;
+.search-results__items li {
+ margin: 0;
+ padding: 0;
}
+.search-results__items li::before {
+ display: none;
+}
+
+/* Individual search result item */
@utility search-results__item {
- margin-bottom: 0.6rem;
+ padding: var(--space-lg);
+ margin: var(--space-xs) 0;
+ border-radius: var(--radius-lg);
+ transition: all var(--duration-fast) var(--ease-out);
+ cursor: pointer;
+ border-bottom: none;
+}
+
+.search-results__item:hover {
+ background: var(--color-light-surface-hover);
+ transform: translateX(4px);
}
.search-results__item a {
- font-size: 1.2rem;
- display: inline-block;
+ display: block;
+ text-decoration: none;
+ color: inherit;
}
-.search-results__item .fn-signature {
- font-family: monospace;
- font-size: 0.6em;
+.search-results__item a::after {
+ display: none;
+}
+
+.search-results__item .title {
+ font-weight: 600;
+ color: var(--color-light-text-primary);
+ font-size: var(--text-base);
+ margin-bottom: var(--space-xs);
+ display: block;
}
.search-results__item .desc {
- display: -webkit-box;
- -webkit-line-clamp: 3;
- -webkit-box-orient: vertical;
- overflow: hidden;
- color: var(--color-gray-dark);
+ color: var(--color-light-text-secondary);
+ font-size: var(--text-sm);
+ line-height: 1.5;
+ display: block;
+}
+
+/* Highlight matched text */
+.search-results__item mark {
+ background: var(--color-phel-hover);
+ color: var(--color-phel-primary);
+ padding: 0.1em 0.3em;
+ border-radius: var(--radius-sm);
+ font-weight: 600;
+}
+
+/* Empty state */
+.search-results__empty {
+ padding: var(--space-2xl);
+ text-align: center;
+ color: var(--color-gray-light);
+ font-size: var(--text-sm);
+}
+
+/* Loading state */
+.search-results__loading {
+ padding: var(--space-2xl);
+ text-align: center;
+ color: var(--color-gray-light);
+ font-size: var(--text-sm);
+ animation: pulse 1.5s ease-in-out infinite;
+}
+
+/* Search meta info */
+.search-results__meta {
+ padding: var(--space-md) var(--space-lg);
+ font-size: var(--text-xs);
+ color: var(--color-gray-light);
+ border-bottom: 1px solid var(--color-light-border);
+ background: var(--color-light-bg-secondary);
+ font-weight: 600;
+ letter-spacing: 0.05em;
+ text-transform: uppercase;
+}
+
+/* Keyboard navigation indicator */
+.search-results__item.keyboard-selected {
+ background: var(--color-phel-hover);
+ border-left: 3px solid var(--color-phel-primary);
+}
+
+/* Category badges in search results */
+.search-results__item .category {
+ display: inline-block;
+ padding: var(--space-xs) var(--space-sm);
+ font-size: var(--text-xs);
+ font-weight: 600;
+ border-radius: var(--radius-full);
+ background: var(--color-phel-hover);
+ color: var(--color-phel-primary);
+ margin-top: var(--space-sm);
+}
+
+/* Animation keyframes */
+@keyframes slideInDown {
+ from {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+/* Mobile responsive */
+@media (max-width: 1039px) {
+ .search-results {
+ max-height: 60vh;
+ border-radius: var(--radius-lg);
+ }
+
+ .search-results__item {
+ padding: var(--space-md);
+ }
}
diff --git a/css/theme.css b/css/theme.css
index 0e8e202..7388b1d 100644
--- a/css/theme.css
+++ b/css/theme.css
@@ -5,80 +5,95 @@
@custom-variant dark (&:is(.dark *));
@theme {
- --color-light-bg: #fcfcfd;
- --color-dark-bg: #161e32;
- --color-light-text-primary: #374151;
- --color-light-text-secondary: #4b5563;
- --color-light-text-accent: #00a3f1;
- --color-light-link: #3b82f6;
- --color-dark-text-primary: #cbd5e1;
- --color-dark-text-secondary: #a1a1aa;
- --color-dark-text-accent: #60a5fa;
- --color-dark-link: #70acf6;
- --color-light-border: #e5e7eb;
+ /* Modern Color Palette - Light Mode */
+ --color-light-bg: #ffffff;
+ --color-light-bg-secondary: #f8fafc;
+ --color-light-text-primary: #0f172a;
+ --color-light-text-secondary: #475569;
+ --color-light-text-muted: #64748b;
+ --color-light-text-accent: #0ea5e9;
+ --color-light-link: #6366f1;
+ --color-light-border: #e2e8f0;
+ --color-light-border-subtle: #f1f5f9;
+
+ /* Modern Color Palette - Dark Mode */
+ --color-dark-bg: #0f172a;
+ --color-dark-bg-secondary: #1e293b;
+ --color-dark-text-primary: #f1f5f9;
+ --color-dark-text-secondary: #cbd5e1;
+ --color-dark-text-muted: #94a3b8;
+ --color-dark-text-accent: #38bdf8;
+ --color-dark-link: #818cf8;
--color-dark-border: #334155;
- --color-dark-header-footer-border: #1f2937;
- --color-dark-header-bg: #0f172acc;
- --color-light-catalogue-bg: #f5f5f5;
- --color-light-catalogue-item-bg: #fff;
- --color-dark-catalogue-bg: #1b2638;
- --color-dark-catalogue-item-bg: #1b2537;
- --color-light-code-bg: rgba(27, 31, 35, 0.05);
- --color-light-code-inline-bg: #1b1f230d;
- --color-dark-code-bg: #0f162b;
- --color-dark-code-inline-bg: #2d2d2d;
+ --color-dark-border-subtle: #1e293b;
+ --color-dark-header-footer-border: #1e293b;
+ --color-dark-header-bg: rgba(15, 23, 42, 0.8);
+
+ /* Card & Surface Colors */
+ --color-light-surface: #ffffff;
+ --color-light-surface-hover: #f8fafc;
+ --color-dark-surface: #1e293b;
+ --color-dark-surface-hover: #334155;
+
+ /* Code & Catalogue */
+ --color-light-code-bg: #f1f5f9;
+ --color-light-code-inline-bg: #e2e8f0;
+ --color-dark-code-bg: #1e293b;
+ --color-dark-code-inline-bg: #334155;
+
+ /* Anchor Links */
+ --color-light-anchor: #bbb;
+ --color-dark-anchor: #bccccc;
+
+ /* Blockquote */
--color-light-blockquote-bg: #eff6ff;
--color-light-blockquote-border: #3b82f6;
- --color-dark-blockquote-bg: #0f172a;
- --color-dark-blockquote-border: #334155;
- --color-light-timeline-bg: #00a3f1;
- --color-dark-timeline-bg: #3b82f6;
- --color-light-current-badge-bg: rgba(34, 197, 94, 0.2);
- --color-light-current-badge-text: #166534;
- --color-dark-current-badge-bg: rgb(20 83 45);
- --color-dark-current-badge-text: #73ffa9;
-
- /* Phel-specific colors (from SASS) */
- --color-phel-primary: #512da8;
+ --color-dark-blockquote-bg: #1e293b;
+ --color-dark-blockquote-border: #475569;
+
+ /* Phel Brand Colors - Modernized */
+ --color-phel-primary: #6366f1;
+ --color-phel-primary-hover: #4f46e5;
--color-phel-secondary: #8b5cf6;
- --color-phel-accent: #06b6d4;
- --color-phel-success: #10a887;
- --color-phel-warning: #f17f42;
- --color-phel-error: #da3c3c;
- --color-phel-hover: rgba(81, 45, 168, 0.15);
- --color-phel-selection: rgba(27, 31, 35, 0.05);
- --color-phel-lines: #dcdcdc;
-
- /* Additional Phel colors from SASS */
- --color-blue-darker: #1573b6;
- --color-blue-dark: #1e80c6;
- --color-blue-base: #2b90d9;
- --color-blue-light: #3fa2e9;
- --color-blue-lighter: #4eb1f9;
-
- --color-green-darker: #089073;
- --color-green-dark: #0b9d7d;
- --color-green-base: #10a887;
- --color-green-light: #1eb896;
- --color-green-lighter: #28ceaa;
-
- --color-red-darker: #653131;
- --color-red-dark: #b73333;
- --color-red-base: #da3c3c;
- --color-red-light: #f25a5a;
- --color-red-lighter: #fa8181;
-
- --color-gray-darker: #333333;
- --color-gray-dark: #4d4d4d;
- --color-gray-base: #666666;
- --color-gray-light: #808080;
- --color-gray-lighter: #999999;
-
- --font-primary: 'Helvetica', 'Arial', sans-serif;
- --font-secondary: 'Helvetica', 'Arial', sans-serif;
- --font-mono: 'Consolas', monospace;
- --font-inter:
- Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif;
+ --color-phel-accent: #0ea5e9;
+ --color-phel-success: #10b981;
+ --color-phel-warning: #f59e0b;
+ --color-phel-error: #ef4444;
+ --color-phel-hover: rgba(99, 102, 241, 0.08);
+ --color-phel-selection: rgba(99, 102, 241, 0.12);
+ --color-phel-lines: #e2e8f0;
+ --color-phel-lines-dark: #334155;
+
+ /* Extended Color Palette */
+ --color-blue-darker: #1e40af;
+ --color-blue-dark: #2563eb;
+ --color-blue-base: #3b82f6;
+ --color-blue-light: #60a5fa;
+ --color-blue-lighter: #93c5fd;
+
+ --color-green-darker: #047857;
+ --color-green-dark: #059669;
+ --color-green-base: #10b981;
+ --color-green-light: #34d399;
+ --color-green-lighter: #6ee7b7;
+
+ --color-red-darker: #b91c1c;
+ --color-red-dark: #dc2626;
+ --color-red-base: #ef4444;
+ --color-red-light: #f87171;
+ --color-red-lighter: #fca5a5;
+
+ --color-gray-darker: #1e293b;
+ --color-gray-dark: #475569;
+ --color-gray-base: #64748b;
+ --color-gray-light: #94a3b8;
+ --color-gray-lighter: #cbd5e1;
+
+ /* Modern Typography */
+ --font-primary: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
+ --font-secondary: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
+ --font-mono: 'Fira Code', 'JetBrains Mono', 'Cascadia Code', 'Consolas', 'Monaco', monospace;
+ --font-inter: Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif;
--text-xs: 0.75rem;
--text-sm: 0.875rem;
@@ -89,41 +104,78 @@
--text-3xl: 1.875rem;
--text-4xl: 2.25rem;
--text-5xl: 3rem;
- --text-body: 1.125rem;
+ --text-6xl: 3.75rem;
+ --text-body: 1.0625rem;
- /* SASS font sizes */
- --font-size: 18px;
- --font-size-large: 22px;
- --font-size-code: 16px;
+ /* Font sizes */
+ --font-size: 17px;
+ --font-size-large: 20px;
+ --font-size-code: 15px;
/* Layout dimensions */
- --header-height: 60px;
-
- --leading-relaxed: 1.6;
-
+ --header-height: 72px;
+ --leading-relaxed: 1.7;
--container-content: 56rem;
- --container-catalogue-image: 250px;
-
- --min-height-catalogue-card: 140px;
- --min-height-catalogue-image-mobile: 200px;
-
- --height-book-cover: 380px;
- --height-book-cover-md: 450px;
- --height-book-cover-sm: 500px;
-
- --width-catalogue-image: 250px;
-
- --backdrop-blur-header: 6px;
-
- --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
- --shadow-card-hover: 0 4px 6px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
- --shadow-card-dark-hover: 0 2px 4px rgba(0, 0, 0, 0.4), 0 4px 8px rgba(0, 0, 0, 0.2);
- --shadow-button-hover: 0 4px 12px rgba(0, 0, 0, 0.15);
- --shadow-button-secondary-hover: 0 4px 8px rgba(0, 0, 0, 0.1);
-
- --transition-duration-150: 150ms;
-
+ --container-wide: 80rem;
+
+ /* Border Radius - Modern rounded corners */
+ --radius-sm: 0.375rem;
+ --radius-md: 0.5rem;
+ --radius-lg: 0.75rem;
+ --radius-xl: 1rem;
+ --radius-2xl: 1.5rem;
+ --radius-full: 9999px;
+
+ /* Spacing System */
+ --space-xs: 0.25rem;
+ --space-sm: 0.5rem;
+ --space-md: 1rem;
+ --space-lg: 1.5rem;
+ --space-xl: 2rem;
+ --space-2xl: 3rem;
+ --space-3xl: 4rem;
+
+ /* Modern Shadows - Layered approach */
+ --shadow-xs: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
+ --shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1);
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
+ --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
+ --shadow-2xl: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
+ --shadow-inner: inset 0 2px 4px 0 rgba(0, 0, 0, 0.05);
+
+ /* Dark mode shadows */
+ --shadow-dark-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px -1px rgba(0, 0, 0, 0.3);
+ --shadow-dark-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -2px rgba(0, 0, 0, 0.4);
+ --shadow-dark-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5), 0 4px 6px -4px rgba(0, 0, 0, 0.5);
+
+ /* Glassmorphism */
+ --backdrop-blur-sm: 8px;
+ --backdrop-blur-md: 12px;
+ --backdrop-blur-lg: 16px;
+ --backdrop-blur-header: 12px;
+
+ /* Animation Timings */
+ --duration-fast: 150ms;
+ --duration-normal: 250ms;
+ --duration-slow: 350ms;
+ --duration-slower: 500ms;
+
+ /* Easing Functions */
--ease-custom: cubic-bezier(0.4, 0, 0.2, 1);
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
+ --ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
+
+ /* Z-index layers */
+ --z-dropdown: 1000;
+ --z-sticky: 1020;
+ --z-fixed: 1030;
+ --z-modal-backdrop: 1040;
+ --z-modal: 1050;
+ --z-popover: 1060;
+ --z-tooltip: 1070;
}
@layer base {
@@ -136,6 +188,3 @@
}
}
-@utility font-variant-numeric-oldstyle {
- font-variant-numeric: oldstyle-nums;
-}
diff --git a/scripts/concat-tailwind.js b/scripts/concat-tailwind.js
index 83713ba..943a4cb 100644
--- a/scripts/concat-tailwind.js
+++ b/scripts/concat-tailwind.js
@@ -8,7 +8,7 @@ const outFile = path.join(projectRoot, 'css', 'tailwind.entry.css');
const parts = [
'css/theme.css',
'css/base.css',
- 'css/components/base.css',
+ 'css/components/footer.css',
'css/components/header.css',
'css/components/navigation.css',
'css/components/layout.css',
diff --git a/static/api-accordion.js b/static/api-accordion.js
new file mode 100644
index 0000000..2e3705d
--- /dev/null
+++ b/static/api-accordion.js
@@ -0,0 +1,31 @@
+// API Namespace Accordion
+document.addEventListener('DOMContentLoaded', function() {
+ const toggleButtons = document.querySelectorAll('.api-namespace-toggle');
+
+ toggleButtons.forEach(function(button) {
+ // Check if content has overflow
+ const content = button.nextElementSibling;
+ if (content && content.classList.contains('api-namespace-content')) {
+ // Check if content height exceeds the collapsed max-height (160px)
+ if (content.scrollHeight > 160) {
+ content.classList.add('has-overflow');
+ }
+
+ // Click on content area when collapsed expands it
+ content.addEventListener('click', function(e) {
+ const isCollapsed = button.getAttribute('aria-expanded') === 'false';
+ if (isCollapsed && content.classList.contains('has-overflow')) {
+ e.preventDefault();
+ button.setAttribute('aria-expanded', 'true');
+ }
+ });
+ }
+
+ // Toggle functionality on button click
+ button.addEventListener('click', function() {
+ const isExpanded = this.getAttribute('aria-expanded') === 'true';
+ this.setAttribute('aria-expanded', !isExpanded);
+ });
+ });
+});
+
diff --git a/static/back_to_top.js b/static/back_to_top.js
index 9ebc8a8..3ec3dac 100644
--- a/static/back_to_top.js
+++ b/static/back_to_top.js
@@ -1,19 +1,21 @@
// Get the button:
let mybutton = document.getElementById("back-to-top-button");
-// When the user scrolls down 20px from the top of the document, show the button
+// When the user scrolls down 300px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
- if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
- mybutton.style.display = "block";
+ if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 300) {
+ mybutton.classList.add("visible");
} else {
- mybutton.style.display = "none";
+ mybutton.classList.remove("visible");
}
}
// When the user clicks on the button, scroll to the top of the document
function backToTop() {
- document.body.scrollTop = 0; // For Safari
- document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
+ window.scrollTo({
+ top: 0,
+ behavior: 'smooth'
+ });
}
diff --git a/static/mobile-menu.js b/static/mobile-menu.js
new file mode 100644
index 0000000..36a6004
--- /dev/null
+++ b/static/mobile-menu.js
@@ -0,0 +1,140 @@
+// Mobile Menu Toggle - Simple and Robust
+console.log('Mobile menu script loaded');
+
+// Wait for DOM to be fully loaded
+document.addEventListener('DOMContentLoaded', function() {
+ console.log('DOM loaded, initializing mobile menu...');
+
+ const menuToggle = document.getElementById('mobile-menu-toggle');
+ const menuOverlay = document.getElementById('mobile-menu-overlay');
+ const body = document.body;
+
+ console.log('Menu toggle button:', menuToggle);
+ console.log('Menu overlay:', menuOverlay);
+
+ if (!menuToggle) {
+ console.error('ERROR: mobile-menu-toggle button not found!');
+ return;
+ }
+
+ if (!menuOverlay) {
+ console.error('ERROR: mobile-menu-overlay not found!');
+ return;
+ }
+
+ console.log('â All menu elements found, attaching click handler...');
+
+ // Toggle menu on button click
+ menuToggle.addEventListener('click', function(e) {
+ console.log('Hamburger clicked!');
+ e.preventDefault();
+
+ const isActive = menuToggle.classList.contains('active');
+
+ if (isActive) {
+ // Close menu
+ menuToggle.classList.remove('active');
+ menuOverlay.classList.remove('active');
+ body.classList.remove('menu-open');
+ console.log('Menu CLOSED');
+ } else {
+ // Open menu
+ menuToggle.classList.add('active');
+ menuOverlay.classList.add('active');
+ body.classList.add('menu-open');
+ console.log('Menu OPENED');
+ }
+ });
+
+ // Close menu when clicking on the overlay background
+ menuOverlay.addEventListener('click', function(e) {
+ if (e.target === menuOverlay) {
+ console.log('Clicked outside menu, closing...');
+ menuToggle.classList.remove('active');
+ menuOverlay.classList.remove('active');
+ body.classList.remove('menu-open');
+ }
+ });
+
+ // Close menu when clicking any navigation link
+ const menuLinks = menuOverlay.querySelectorAll('a');
+ console.log('Found', menuLinks.length, 'menu links');
+
+ menuLinks.forEach(function(link) {
+ link.addEventListener('click', function() {
+ console.log('Link clicked, closing menu');
+ menuToggle.classList.remove('active');
+ menuOverlay.classList.remove('active');
+ body.classList.remove('menu-open');
+ });
+ });
+
+ console.log('â Mobile menu fully initialized!');
+});
+
+// Also try to initialize if DOM is already loaded
+if (document.readyState !== 'loading') {
+ console.log('DOM already loaded, initializing immediately...');
+ const event = new Event('DOMContentLoaded');
+ document.dispatchEvent(event);
+}
+
+// Mobile dark mode toggle (separate initialization)
+document.addEventListener('DOMContentLoaded', function() {
+ const mobileDarkToggle = document.querySelector('.mobile-dark-mode-toggle');
+ const mainDarkToggle = document.getElementById('dark-mode-toggle');
+
+ if (mobileDarkToggle && mainDarkToggle) {
+ console.log('â Mobile dark mode toggle found');
+ mobileDarkToggle.addEventListener('click', function() {
+ console.log('Mobile dark mode clicked');
+ mainDarkToggle.click();
+ });
+ } else {
+ console.log('Dark mode toggles not found yet (may initialize later)');
+ }
+});
+
+// Mobile search expansion
+document.addEventListener('DOMContentLoaded', function() {
+ // Only run on mobile screens
+ function isMobile() {
+ return window.innerWidth < 1040;
+ }
+
+ const searchInput = document.getElementById('search');
+ const headerContainer = document.querySelector('.site-header__container');
+
+ if (!searchInput || !headerContainer) {
+ console.log('Search elements not found');
+ return;
+ }
+
+ console.log('â Mobile search expansion initialized');
+
+ // Expand search on focus (mobile only)
+ searchInput.addEventListener('focus', function() {
+ if (isMobile()) {
+ console.log('Search focused - expanding');
+ headerContainer.classList.add('search-expanded');
+ }
+ });
+
+ // Collapse search on blur (mobile only)
+ searchInput.addEventListener('blur', function() {
+ if (isMobile()) {
+ // Small delay to allow clicking search results
+ setTimeout(function() {
+ console.log('Search blurred - collapsing');
+ headerContainer.classList.remove('search-expanded');
+ }, 200);
+ }
+ });
+
+ // Re-check on window resize
+ window.addEventListener('resize', function() {
+ if (!isMobile()) {
+ headerContainer.classList.remove('search-expanded');
+ }
+ });
+});
diff --git a/static/sidebar-toggle.js b/static/sidebar-toggle.js
new file mode 100644
index 0000000..8cc393f
--- /dev/null
+++ b/static/sidebar-toggle.js
@@ -0,0 +1,29 @@
+// Sidebar toggle functionality for mobile
+(function() {
+ 'use strict';
+
+ function initSidebarToggle() {
+ const toggleButton = document.getElementById('sidebar-toggle');
+ const sidebarContent = document.getElementById('sidebar-content');
+
+ if (!toggleButton || !sidebarContent) {
+ return;
+ }
+
+ toggleButton.addEventListener('click', function(e) {
+ e.preventDefault();
+ const isExpanded = toggleButton.getAttribute('aria-expanded') === 'true';
+
+ toggleButton.setAttribute('aria-expanded', !isExpanded);
+ sidebarContent.classList.toggle('active');
+ });
+ }
+
+ // Initialize when DOM is ready
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', initSidebarToggle);
+ } else {
+ initSidebarToggle();
+ }
+})();
+
diff --git a/templates/base.html b/templates/base.html
index 77675b2..36708fc 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -46,11 +46,14 @@
+
+
+