diff --git a/blocks/form/form.css b/blocks/form/form.css
index c415e94..16b859d 100644
--- a/blocks/form/form.css
+++ b/blocks/form/form.css
@@ -2,7 +2,7 @@
--background-color-primary: #fff;
--label-color: #666;
--border-color: #818a91;
- --form-error-color: #ff5f3f;
+ --form-error-color: var(--adobe-red);
--button-primary-color: #5F8DDA;
--button-secondary-color: #666;
--button-primary-hover-color: #035fe6;
@@ -14,7 +14,7 @@
--form-columns: 12;
--form-field-horz-gap: 40px;
--form-field-vert-gap: 10px;
- --form-invalid-border-color: #ff5f3f;
+ --form-invalid-border-color: var(--adobe-red);
--form-input-padding: 0.75rem 0.6rem;
--form-input-font-size: 1rem;
--form-input-disable-color: #ebebe4;
@@ -701,9 +701,9 @@ main .form .form-message.success-message {
}
main .form .form-message.error-message {
- color: #842029;
- background-color: #f8d7da;
- border-color: #f5c2c7;
+ color: var(--adobe-red);
+ background-color: rgba(237, 34, 36, 0.1);
+ border-color: var(--adobe-red);
flex: 100%;
grid-column: span 12;
padding: 10px;
diff --git a/blocks/header/header.css b/blocks/header/header.css
index e71a3b2..ecdb99b 100644
--- a/blocks/header/header.css
+++ b/blocks/header/header.css
@@ -78,12 +78,12 @@ body.dark-mode header nav a:any-link {
/* UIKit subnav styling for nav links */
header nav .nav-sections .uk-subnav {
- gap: 0.5rem 1.5rem;
+ gap: 0.5rem 1.2rem;
}
header nav .nav-sections .uk-subnav > li > a {
font-size: 0.9rem;
- font-weight: 500;
+ font-weight: 600;
color: var(--text-color);
padding: 0.4em 0.6em;
border-radius: 6px;
diff --git a/blocks/hero/hero.css b/blocks/hero/hero.css
index ec05406..c200502 100644
--- a/blocks/hero/hero.css
+++ b/blocks/hero/hero.css
@@ -1,6 +1,7 @@
.hero-container .hero-wrapper {
max-width: 1800px;
padding: 0;
+ margin: 0;
}
.hero {
@@ -29,7 +30,12 @@
.hero img {
object-fit: contain;
width: 100%;
- height: 100%;
+ height: auto;
+ border-radius: 20px;
+}
+
+.hero.space-around {
+ margin: 1rem 0;
}
@media (width >= 1000px) {
diff --git a/blocks/leftnav/leftnav.css b/blocks/leftnav/leftnav.css
index 3bc52b8..c130103 100644
--- a/blocks/leftnav/leftnav.css
+++ b/blocks/leftnav/leftnav.css
@@ -1,19 +1,89 @@
+/* slide in/out - single width animation, overflow clips cleanly */
+.leftnav-wrapper {
+ flex-shrink: 0;
+ /* width: calc(20vw + 2rem); */
+ min-width: calc(350px + 2rem);
+ /* overflow: hidden; */
+ margin: 0;
+ transition: width 0.4s cubic-bezier(0.32, 0.72, 0, 1), min-width 0.4s cubic-bezier(0.32, 0.72, 0, 1);
+}
+
+body.leftnav-collapsed .leftnav-wrapper {
+ width: 0;
+ min-width: 0;
+}
.leftnav-container {
width: 20vw;
min-width: 350px;
+ min-height: 600px;
background-color: var(--light-color);
color: var(--text-color);
padding: 1rem;
- height: calc(100vh - var(--nav-height) - 0);
+ height: auto;
position: sticky;
top: calc(var(--nav-height) + 1rem);
overflow-y: auto;
overflow-x: hidden;
- transition: transform 0.3s ease; /* for slide toggle */
border-radius: 20px;
margin: 1rem;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.12), 0 0 40px rgba(0, 0, 0, 0.08);
+ transition: transform 0.4s cubic-bezier(0.32, 0.72, 0, 1);
+ backface-visibility: hidden;
+}
+
+body.leftnav-collapsed .leftnav-container {
+ transform: translateX(-105%);
+}
+
+.leftnav-collapse-btn {
+ position: absolute;
+ top: 1rem;
+ right: 1rem;
+ z-index: 2;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ padding: 0;
+ border: none;
+ border-radius: 6px;
+ background-color: rgba(0, 0, 0, 0.06);
+ color: var(--text-color);
+ cursor: pointer;
+}
+
+body.dark-mode .leftnav-collapse-btn {
+ background-color: rgba(255, 255, 255, 0.1) !important;
+}
+
+.leftnav-expand-btn {
+ display: none;
+ position: fixed;
+ top: calc(var(--nav-height) + 3rem);
+ left: 0;
+ z-index: 100;
+ width: 36px;
+ height: 48px;
+ padding: 0;
+ border: none;
+ border-radius: 0 8px 8px 0;
+ background-color: var(--light-color);
+ color: var(--text-color);
+ cursor: pointer;
+ box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.15);
+ align-items: center;
+ justify-content: center;
+}
+
+body.leftnav-collapsed .leftnav-expand-btn {
+ display: flex;
+}
+
+body.dark-mode .leftnav-expand-btn {
+ background-color: #1a1a1a;
+ box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.4);
}
.leftnav {
@@ -24,8 +94,8 @@
}
/* title */
- .leftnav .nav-title > h3 {
- padding: 0.75rem 1rem;
+.leftnav .nav-title > h3 {
+ padding: 0.75rem 3rem 0.75rem 1rem;
text-align: center;
margin-bottom: 0.5rem;
font-weight: 600;
@@ -57,7 +127,7 @@ body.dark-mode .leftnav .nav-title > h3::after {
vertical-align: middle;
height: 35px;
margin-right: calc(5px + .2em);
- border-left: calc(3px + .1em) solid #ED2224;
+ border-left: calc(3px + .1em) solid var(--adobe-red);
}
/* search */
@@ -186,17 +256,11 @@ body.dark-mode .leftnav .aem-parent > ul > li > .uk-accordion-content > ul > li
/* mobile layout < 1000px */
@media (width < 1000px) {
- .leftnav-container {
+ .leftnav-wrapper {
display: none;
- /* position: fixed;
- top: var(--nav-height);
- left: 0;
- width: 100%;
- max-height: 100%;
- transform: translateX(-100%);
- z-index: 9999; */
}
- .leftnav-container.open {
- transform: translateX(0);
+
+ .leftnav-expand-btn {
+ display: none !important;
}
}
diff --git a/blocks/notebox/notebox.css b/blocks/notebox/notebox.css
index bdbade0..4841b7f 100644
--- a/blocks/notebox/notebox.css
+++ b/blocks/notebox/notebox.css
@@ -54,8 +54,8 @@
}
.notebox.uk-alert-danger {
- background-color: #ffe5e5;
- color: #b30000;
+ background-color: rgba(237, 34, 36, 0.1);
+ color: var(--adobe-red);
}
.notebox.uk-alert-success {
diff --git a/head.html b/head.html
index 5c00e14..cc9d309 100644
--- a/head.html
+++ b/head.html
@@ -4,6 +4,15 @@
move-to-http-header="true"
>
+
diff --git a/scripts/scripts.js b/scripts/scripts.js
index 030b9a7..41da3e2 100644
--- a/scripts/scripts.js
+++ b/scripts/scripts.js
@@ -16,13 +16,47 @@ import {
import './uikit.min.js';
import './uikit-icons.min.js';
+function toggleLeftNav() {
+ document.body.classList.toggle('leftnav-collapsed');
+ try {
+ localStorage.setItem(
+ 'leftnav-collapsed',
+ document.body.classList.contains('leftnav-collapsed') ? 'true' : 'false',
+ );
+ } catch (e) { /* ignore */ }
+}
+
async function loadLeftNav(main) {
+ if (localStorage.getItem('leftnav-collapsed') === 'true') {
+ document.body.classList.add('leftnav-collapsed');
+ }
+ const wrapper = document.createElement('div');
+ wrapper.className = 'leftnav-wrapper';
+
const aside = document.createElement('aside');
aside.className = 'leftnav-container';
const block = document.createElement('div');
block.className = 'block leftnav';
aside.append(block);
- main.insertBefore(aside, main.querySelector('.section'));
+
+ const collapseBtn = document.createElement('button');
+ collapseBtn.type = 'button';
+ collapseBtn.className = 'leftnav-collapse-btn';
+ collapseBtn.setAttribute('aria-label', 'Collapse navigation');
+ collapseBtn.innerHTML = '';
+ collapseBtn.addEventListener('click', toggleLeftNav);
+
+ const expandBtn = document.createElement('button');
+ expandBtn.type = 'button';
+ expandBtn.className = 'leftnav-expand-btn';
+ expandBtn.setAttribute('aria-label', 'Expand navigation');
+ expandBtn.innerHTML = '';
+ expandBtn.addEventListener('click', toggleLeftNav);
+
+ block.prepend(collapseBtn);
+ wrapper.append(aside, expandBtn);
+ main.insertBefore(wrapper, main.querySelector('.section'));
+
const { default: decorate } = await import('../blocks/leftnav/leftnav.js');
loadCSS(`${window.hlx.codeBasePath}/blocks/leftnav/leftnav.css`);
await decorate(block);
@@ -389,25 +423,29 @@ function createLightbox() {
position: absolute;
top: 5px;
right: 5px;
- background: rgba(255, 255, 255, 0.1);
- border: 1px solid #000;
+ background: rgba(255, 255, 255, 0.08);
+ border: 1px solid rgba(0, 0, 0, 0.5);
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
border-radius: 6px;
- color: #000;
+ color: rgba(0, 0, 0, 0.85);
font-size: 1.5rem;
line-height: 1;
cursor: pointer;
padding: 0.35rem 0.65rem;
opacity: 1;
- transition: background 0.2s ease, opacity 0.2s ease, border-color 0.2s ease;
+ transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
margin: 0;
padding-top: 0;
}
.lightbox-close:hover,
.lightbox-close:focus {
- background: rgba(255, 255, 255, 0.2);
- border-color: rgba(255, 255, 255, 0.45);
+ background: rgba(255, 255, 255, 0.95);
+ border-color: rgba(0, 0, 0, 0.7);
+ box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.2);
+ color: #000;
opacity: 1;
outline: none;
+ transform: scale(1.08);
}
.lightbox-figure {
margin: 0;
@@ -514,15 +552,29 @@ function initLightbox() {
// Page lifecycle
// ---------------------------------------------------------------------------
+function hideLoader() {
+ document.body.classList.add('appear');
+ const loader = document.getElementById('page-loader');
+ if (loader) {
+ loader.classList.add('loaded');
+ loader.addEventListener('transitionend', () => loader.remove(), { once: true });
+ }
+}
+
async function loadEager(doc) {
- document.documentElement.lang = 'en';
- decorateTemplateAndTheme();
- const main = doc.querySelector('main');
- if (main) {
- decorateMain(main);
- document.body.classList.add('appear');
- if (window.self === window.top && !window.isErrorPage) await loadLeftNav(main);
- await loadSection(main.querySelector('.section'), waitForFirstImage);
+ const showPage = () => { try { hideLoader(); } catch (e) { document.body.classList.add('appear'); } };
+ setTimeout(showPage, 8000);
+ try {
+ document.documentElement.lang = 'en';
+ decorateTemplateAndTheme();
+ const main = doc.querySelector('main');
+ if (main) {
+ decorateMain(main);
+ if (window.self === window.top && !window.isErrorPage) await loadLeftNav(main);
+ await loadSection(main.querySelector('.section'), waitForFirstImage);
+ }
+ } finally {
+ showPage();
}
}
diff --git a/styles/styles.css b/styles/styles.css
index 1732afa..29f245b 100644
--- a/styles/styles.css
+++ b/styles/styles.css
@@ -87,6 +87,38 @@ body.appear {
display: block;
}
+/* page loader - hides when page is ready */
+#page-loader {
+ transition: opacity 0.3s ease;
+}
+
+#page-loader.loaded {
+ opacity: 0;
+ pointer-events: none;
+}
+
+.loader-spinner {
+ width: 40px;
+ height: 40px;
+ border: 3px solid rgba(0,0,0,0.1);
+ border-top-color: var(--link-color, #3b63fb);
+ border-radius: 50%;
+ animation: loader-spin 0.8s linear infinite;
+}
+
+html:has(body.dark-mode) #page-loader {
+ background: #0d0d0d;
+}
+
+html:has(body.dark-mode) #page-loader .loader-spinner {
+ border-color: rgba(255,255,255,0.1);
+ border-top-color: var(--adobe-red);
+}
+
+@keyframes loader-spin {
+ to { transform: rotate(360deg); }
+}
+
/* dark mode - override color variables and force light text */
body.dark-mode {
--background-color: #0d0d0d;
@@ -94,7 +126,7 @@ body.dark-mode {
--dark-color: #b0b0b0;
--text-color: #ffffff;
--link-color: var(--adobe-red);
- --link-hover-color: #f05052;
+ --link-hover-color: var(--adobe-red);
--overlay-color: #1a1a1a;
--button-text-color: #ffffff;
}
@@ -236,7 +268,7 @@ a:hover {
/* primary buttons */
a.button:any-link,
-button {
+button:not(.leftnav-collapse-btn):not(.leftnav-expand-btn):not(.lightbox-close) {
box-sizing: border-box;
display: inline-block;
max-width: 100%;
@@ -263,15 +295,15 @@ button {
a.button:hover,
a.button:focus,
-button:hover,
-button:focus {
+button:not(.leftnav-collapse-btn):not(.leftnav-expand-btn):not(.lightbox-close):hover,
+button:not(.leftnav-collapse-btn):not(.leftnav-expand-btn):not(.lightbox-close):focus {
background-color: var(--link-hover-color);
cursor: pointer;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
}
a.button:active,
-button:active {
+button:not(.leftnav-collapse-btn):not(.leftnav-expand-btn):not(.lightbox-close):active {
transform: translateY(1px);
}
@@ -369,7 +401,13 @@ main > .section > div.default-content-wrapper {
main > .section {
border-radius: 20px;
padding: 0 1rem;
- width: 80vw;
+ flex: 1;
+ min-width: 0;
+ }
+
+ body.leftnav-collapsed main > .section {
+ max-width: 1480px;
+ margin: 0 auto;
}
main > .section > div {