update layout; move brands above footer; add missing spaces for carousel buttons; responsive adjustments

This commit is contained in:
Michael Czechowski
2025-06-14 17:39:36 +02:00
parent f98e6e56ea
commit 50a50ca094
8 changed files with 42 additions and 59 deletions

30
.pugrc
View File

@@ -1246,36 +1246,6 @@
"label": "Hotjar"
}
]
},
{
"link": {
"href": "https://12factor.net/",
"title": "The twelve-factor methodology can be applied to apps written in any programming language, and which use any combination of backing services (database, queue, memory cache, etc).",
"ariaLabel": "The twelve-factor methodology can be applied to apps written in any programming language, and which use any combination of backing services (database, queue, memory cache, etc).",
"text": "The 12-Factor App"
},
"text": "Microservices and Software-as-a-Service Methodology"
},
{
"text": "Testing Pyramid"
},
{
"text": "Accessibility (a11y)"
},
{
"text": "Rapid Prototyping and Design Thinking"
},
{
"text": "Scalability and Reliability"
},
{
"text": "Continuous Integration and Continuous Deployment (CI/CD)"
},
{
"text": "DevOps and Site Reliability Engineering (SRE)"
},
{
"text": "Agile and Lean Development"
}
]
}

View File

@@ -6,11 +6,12 @@ html.scroll-smooth(lang=head.lang)
main.flex.flex-col
article(itemscope, itemtype="http://schema.org/Person")
include src/components/Landingpage
include src/components/Portfolio
include src/components/Academia
include src/components/Professional
include src/components/Portfolio
include src/components/Footer
include src/components/Brands
include src/components/Footer
script.
const footerEl = document.querySelector("#footer");

View File

@@ -15,13 +15,13 @@ section#academia
// region Expertise
.grid.grid-cols-1.gap-6.mb-8(class="md:grid-cols-1")
+Collapsable("academia", academia.expertise.frontendTechnologies)
+Collapsable("academia", academia.expertise.devopsAndCloud)
+Collapsable("academia", academia.expertise.backendTechnologies)
+Collapsable("academia", academia.expertise.databaseAndData)
+Collapsable("academia", academia.expertise.crossPlatform)
+Collapsable("academia", academia.expertise.bestPractices)
+Collapsable("academia", academia.expertise.tracking)
+Collapsable(null, academia.expertise.frontendTechnologies)
+Collapsable(null, academia.expertise.devopsAndCloud)
+Collapsable(null, academia.expertise.backendTechnologies)
+Collapsable(null, academia.expertise.databaseAndData)
+Collapsable(null, academia.expertise.crossPlatform)
+Collapsable(null, academia.expertise.bestPractices)
+Collapsable(null, academia.expertise.tracking)
// endregion
.mt-48

View File

@@ -5,5 +5,5 @@ section#brands
.p-8.bg-nls-black.text-nls-white(class="sm:py-2")
+Carousel([...brands, ...brands, ...brands], {id: "brands-carousel", color: "black", category: "brands"})
p.text-center.pb-12.text-gray-400
| Companies and Organizations that I have worked with or contributed to
p.text-center.pb-12.text-gray-600.text-sm.mx-auto(class="w-4/5 sm:text-base")
| Companies and Organiza&shy;tions have been working <nobr>with me</nobr>

View File

@@ -9,20 +9,20 @@ mixin Carousel(items, options)
.carousel-container.relative.w-full.overflow-hidden.px-8(class="sm:px-12", id=id)
//- Navigation buttons
button.absolute.left-1.z-20.transform(
class=`-translate-y-1/2 top-1/2 sm:left-2 bg-white/40 hover:bg-white/80 text-nls-black rounded-full p-2 sm:p-3 shadow-lg transition-all focus:outline-none focus:ring-4 focus:ring-nls-${color}`,
button.absolute.left-0.z-20.transform(
class=`-translate-y-1/2 top-1/2 sm:left-2 bg-white/40 hover:bg-white/80 text-nls-black rounded-full p-1 sm:p-3 shadow-lg transition-all focus:outline-none focus:ring-4 focus:ring-nls-${color}`,
aria-label="Previous slide",
onclick=`carouselPrev('${id}'); umami.track('carousel navigation', { direction: 'prev', category: '${category}', visitDuration: getVisitDuration() })`
)
svg.w-3.h-3.text-gray-800(class="sm:w-6 sm:h-6", fill="none", stroke="currentColor", viewBox="0 0 24 24")
svg.w-6.h-6.text-gray-800(class="sm:w-6 sm:h-6", fill="none", stroke="currentColor", viewBox="0 0 24 24")
path(stroke-linecap="round", stroke-linejoin="round", stroke-width="2", d="M15 19l-7-7 7-7")
button.absolute.right-1.z-20.transform(
class=`top-1/2 sm:right-2 -translate-y-1/2 bg-white/40 hover:bg-white/80 text-nls-black rounded-full p-2 sm:p-3 shadow-lg transition-all focus:outline-none focus:ring-4 focus:ring-nls-${color}`,
button.absolute.right-0.z-20.transform(
class=`top-1/2 sm:right-2 -translate-y-1/2 bg-white/40 hover:bg-white/80 text-nls-black rounded-full p-1 sm:p-3 shadow-lg transition-all focus:outline-none focus:ring-4 focus:ring-nls-${color}`,
aria-label="Next slide",
onclick=`carouselNext('${id}'); umami.track('carousel navigation', { direction: 'next', category: '${category}', visitDuration: getVisitDuration() })`
)
svg.w-3.h-3.text-gray-800(class="sm:w-6 sm:h-6", fill="none", stroke="currentColor", viewBox="0 0 24 24")
svg.w-6.h-6.text-gray-800(class="sm:w-6 sm:h-6", fill="none", stroke="currentColor", viewBox="0 0 24 24")
path(stroke-linecap="round", stroke-linejoin="round", stroke-width="2", d="M9 5l7 7-7 7")
//- Carousel track
@@ -53,8 +53,8 @@ mixin Carousel(items, options)
if item.href
a.text-sm.mt-4.underline(class="sm:text-base hover:text-nls-black dark:hover:text-nls-white", href=item.href, target="_blank", rel="noopener noreferrer")= item.href
else if item.type === "brand"
.aspect-square.flex.items-center.justify-center.mx-20.mb-4
img.max-w-full.max-h-full.object-contain.p-4(src=item.logo, alt=item.name, loading=index < 6 ? "eager" : "lazy")
.aspect-video.flex.items-center.justify-center.mx-2.mb-4(class="sm:mx-12")
img.max-w-full.max-h-full.min-h-64.object-contain.p-4(src=item.logo, alt=item.name, loading=index < 6 ? "eager" : "lazy")
if autoScroll
script.
document.addEventListener("DOMContentLoaded", () => {

View File

@@ -21,7 +21,7 @@ mixin Svg
block
footer#footer
.p-8.bg-white.text-nls-black.pt-48(class="dark:bg-nls-black dark:text-white sm:p-20")
.p-8.bg-white.text-nls-black.pt-20(class="sm:pt-48 dark:bg-nls-black dark:text-white sm:p-20")
+Container
// region Contact
h2.text-5xl.mb-4 #{footer.title}

View File

@@ -139,6 +139,11 @@ head
font-display: swap;
}
ul {
list-style-position: outside !important;
margin-left: 1.22rem;
}
p a {
text-decoration: underline;
}

View File

@@ -1,7 +1,7 @@
header.bg-white.text-nls-black.relative(class="dark:text-white dark:bg-nls-black")
header.bg-white.text-nls-black.relative.overflow-hidden(class="dark:text-white dark:bg-nls-black")
.teaser.p-8.flex.flex-col.items-center.justify-center(class="sm:p-20")
.max-w-3xl.mb-8.relative(class="w-4/5 min-h-[90vh]")
.peer.absolute.bottom-0.left-0.right-0.z-40.text-center.max-w-3xl.center.py-8
.peer.absolute.bottom-0.left-0.right-0.z-40.text-center.max-w-3xl.center.py-8.pointer-events-none
h2.tracking-widest.text-xl.font-semibold.opacity-100.transition(class="sm:text-2xl peer-hover:opacity-100", itemprop="name")= landingpage.name
h1.tracking-normal.text-md.mb-16.opacity-95.transition(class="sm:text-lg peer-hover:opacity-100", itemprop="jobTitle")
@@ -19,6 +19,8 @@ header.bg-white.text-nls-black.relative(class="dark:text-white dark:bg-nls-black
class GuillocheCurtain {
constructor(canvas, options = {}) {
this.canvas = canvas;
this.containerHeight = window.innerHeight;
this.containerWidth = window.innerWidth;
this.options = {
// Visual parameters
spread: 0.25,
@@ -76,7 +78,7 @@ header.bg-white.text-nls-black.relative(class="dark:text-white dark:bg-nls-black
this.scene = new THREE.Scene();
this.camera = new THREE.OrthographicCamera(-2, 2, 1.5, -1.5, 0.1, 1000);
this.renderer = new THREE.WebGLRenderer({
canvas: canvas,
canvas,
alpha: true,
antialias: true,
});
@@ -93,7 +95,7 @@ header.bg-white.text-nls-black.relative(class="dark:text-white dark:bg-nls-black
}
init() {
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
this.renderer.setSize(this.containerWidth, this.containerHeight);
this.renderer.setClearColor(0x000000, 0);
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
this.camera.position.z = 1;
@@ -228,7 +230,7 @@ header.bg-white.text-nls-black.relative(class="dark:text-white dark:bg-nls-black
const material = new THREE.LineBasicMaterial({
color: new THREE.Color().setHSL(hue, saturation, lightness),
transparent: true,
opacity: (this.options.opacity / (splineIndex / 6)) * (1 - (Math.abs(offset) / this.options.spread) * 0.1),
opacity: (this.options.opacity / ((this.options.splineCount - splineIndex) * 0.1)) * (1 - (Math.abs(offset) / this.options.spread) * 0.1),
linewidth: this.options.lineWidth,
});
@@ -346,8 +348,8 @@ header.bg-white.text-nls-black.relative(class="dark:text-white dark:bg-nls-black
resize() {
console.log("Resizing canvas and updating camera");
const width = this.canvas.clientWidth;
const height = this.canvas.clientHeight;
const width = window.innerWidth;
const height = window.innerHeight;
this.renderer.setSize(width, height);
@@ -388,10 +390,15 @@ header.bg-white.text-nls-black.relative(class="dark:text-white dark:bg-nls-black
animationSpeed: 0.001,
hueBase: 0.55,
hueVariation: 0.3,
opacity: 0.3,
opacity: 0.2,
});
window.addEventListener("beforeunload", () => curtain.destroy());
window.addEventListener("resize", () => curtain.resize());
window.addEventListener("resize", (e) => {
// only resize if width has changed
if (e.target.innerWidth !== curtain.containerWidth) {
curtain.resize();
}
});
}
});