From 7f16506baa72c5b94ec29f8fff92d193c12a0871 Mon Sep 17 00:00:00 2001 From: JesusValera Date: Thu, 2 Oct 2025 01:27:40 +0200 Subject: [PATCH] Improve page design --- css/base.css | 298 +++++++--- css/components/base.css | 61 -- css/components/blog.css | 283 ++++++++-- css/components/dark-mode.css | 599 ++++++++++++++++---- css/components/documentation.css | 658 ++++++++++++++++++++-- css/components/footer.css | 7 + css/components/header.css | 564 ++++++++++++++----- css/components/layout.css | 346 ++++++++++-- css/components/navigation.css | 100 ++-- css/components/performance.css | 42 +- css/components/search.css | 228 +++++--- css/theme.css | 255 +++++---- scripts/concat-tailwind.js | 2 +- static/api-accordion.js | 31 + static/back_to_top.js | 14 +- static/mobile-menu.js | 140 +++++ static/sidebar-toggle.js | 29 + templates/base.html | 3 + templates/header.html | 46 +- templates/layouts/two-column-layout.html | 8 +- templates/logo.html | 3 +- templates/navigation/site-navigation.html | 11 +- templates/page-api.html | 11 +- templates/page.html | 7 +- templates/page/table-of-content.html | 36 +- 25 files changed, 2962 insertions(+), 820 deletions(-) delete mode 100644 css/components/base.css create mode 100644 css/components/footer.css create mode 100644 static/api-accordion.js create mode 100644 static/mobile-menu.js create mode 100644 static/sidebar-toggle.js 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 @@ + + + diff --git a/templates/header.html b/templates/header.html index 3acf494..cfb348a 100644 --- a/templates/header.html +++ b/templates/header.html @@ -1,33 +1,31 @@ diff --git a/templates/layouts/two-column-layout.html b/templates/layouts/two-column-layout.html index f3447f7..b72ffd1 100644 --- a/templates/layouts/two-column-layout.html +++ b/templates/layouts/two-column-layout.html @@ -6,7 +6,13 @@
{% block editable %} {% endblock %} diff --git a/templates/logo.html b/templates/logo.html index 52311b3..4cd7c8b 100644 --- a/templates/logo.html +++ b/templates/logo.html @@ -1,7 +1,8 @@ - + + Phel \ No newline at end of file diff --git a/templates/navigation/site-navigation.html b/templates/navigation/site-navigation.html index 56a3410..f26db42 100644 --- a/templates/navigation/site-navigation.html +++ b/templates/navigation/site-navigation.html @@ -1,10 +1,13 @@ - +
+{% endif %} diff --git a/templates/page-api.html b/templates/page-api.html index b3e69e9..a4c90da 100644 --- a/templates/page-api.html +++ b/templates/page-api.html @@ -10,9 +10,14 @@

{{page.title}}