From 49496c9bdca2c4c2728adaf5e65b38dcce301156 Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Sun, 29 Aug 2021 16:30:10 +0200 Subject: [PATCH] dev21w34a --- public/CNAME | 1 - public/assets/css/fonts.css | 17 -- public/assets/css/style.css | 334 ++++++++++++++++-------------------- public/assets/js/script.js | 27 ++- public/index.html | 54 +++--- public/sw.js | 102 ----------- 6 files changed, 191 insertions(+), 344 deletions(-) delete mode 100644 public/CNAME delete mode 100644 public/assets/css/fonts.css delete mode 100644 public/sw.js diff --git a/public/CNAME b/public/CNAME deleted file mode 100644 index 56bdaab..0000000 --- a/public/CNAME +++ /dev/null @@ -1 +0,0 @@ -www.victorwesterlund.com \ No newline at end of file diff --git a/public/assets/css/fonts.css b/public/assets/css/fonts.css deleted file mode 100644 index afd0844..0000000 --- a/public/assets/css/fonts.css +++ /dev/null @@ -1,17 +0,0 @@ -@font-face { - font-family: "Roboto Mono"; - font-weight: 400; - src: local("Roboto Mono Regular"), - local("RobotoMono-Regular"), - url("../fonts/RobotoMono-Regular.woff2"), - url("../fonts/RobotoMono-Regular.ttf"); -} - -@font-face { - font-family: "Roboto Mono"; - font-weight: 700; - src: local("Roboto Mono Bold"), - local("RobotoMono-Bold"), - url("../fonts/RobotoMono-Bold.woff2"), - url("../fonts/RobotoMono-Bold.ttf"); -} \ No newline at end of file diff --git a/public/assets/css/style.css b/public/assets/css/style.css index 1da6436..5615b1f 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -1,15 +1,43 @@ -@import url("fonts.css"); - +/* Copyright © Victor Westerlund - No libraries! 😲 */ :root { --comp-background: 255,255,255; - --comp-highlight: 244,242,255; - --comp-accent: 33,33,33; + --comp-contrast: 33,33,33; + --comp-accent: 22,183,255; --color-background: rgb(var(--comp-background)); - --color-highlight: rgb(var(--comp-highlight)); + --color-contrast: rgb(var(--comp-contrast)); --color-accent: rgb(var(--comp-accent)); - --page-padding: 5vw; + --padding: 20px; + --border-radius: 10px; +} + +.dark { + --comp-background: 33,33,33; + --comp-contrast: 255,255,255; + --comp-accent: 255,255,255; + + --color-background: rgb(var(--comp-background)); + --color-contrast: rgb(var(--comp-contrast)); + --color-accent: rgb(var(--comp-accent)); +} + +@font-face { + font-family: "Roboto Mono"; + font-weight: 400; + src: local("Roboto Mono Regular"), + local("RobotoMono-Regular"), + url("../fonts/RobotoMono-Regular.woff2"), + url("../fonts/RobotoMono-Regular.ttf"); +} + +@font-face { + font-family: "Roboto Mono"; + font-weight: 700; + src: local("Roboto Mono Bold"), + local("RobotoMono-Bold"), + url("../fonts/RobotoMono-Bold.woff2"), + url("../fonts/RobotoMono-Bold.ttf"); } /* -- Cornerstones -- */ @@ -17,7 +45,7 @@ * { margin: 0; font-family: "Roboto Mono","Arial",sans-serif; - color: var(--color-accent); + color: var(--color-contrast); } *::selection { @@ -26,17 +54,51 @@ } html, -body, -main, -main > div { +body { width: 100%; height: 100%; + overflow: hidden; +} + +main { + width: 200vw; + height: 100%; + overflow: hidden; + display: flex; +} + +main.active { + transform: translateX(-100vw); +} + +/* ---- */ + +.screen { + width: 100vw; + background-color: var(--color-background); + display: flex; + flex-direction: column; +} + +.screen .content { + box-sizing: border-box; + padding: calc(var(--padding) * 1.5); + padding-top: 0; + flex-grow: 1; +} + +/* -- Positioning -- */ + +.center { + display: flex; + justify-content: center; + align-items: center; } /* ---- */ .logo { - --size: 5em; + --size: 1em; --skew: calc(var(--size) / 1.7); width: 0; @@ -51,192 +113,100 @@ main > div { border-top: var(--size) solid rgba(var(--comp-accent),.3); } -h1 { - font-size: 2em; -} - -h2 { - font-weight: normal; - font-size: 1.42em; -} - -h2 span { - color: var(--color-background); - background-color: var(--color-accent); -} - -/* -- Layout -- */ - -main { - --grid-spacing: 3vh; - - margin: auto; - max-width: 200vh; - background: radial-gradient(circle, rgba(var(--comp-accent),.2) .1vh, var(--color-background) .1vh),url("../img/pattern.gif"); - background-size: var(--grid-spacing) var(--grid-spacing),auto 90%; - background-position: 100% 100%; - background-repeat: repeat,no-repeat; - background-blend-mode: multiply; - image-rendering: pixelated; - image-rendering: -moz-crisp-edges; -} - -main * { - image-rendering: initial; -} - -main > div { - position: absolute; - width: 50%; - height: 100%; -} - /* ---- */ -#intro { - left: 0; - width: 100vh; +.button { + background-color: var(--color-contrast); + text-align: center; + padding: 25px; + border-radius: var(--border-radius); + display: flex; + justify-content: center; + align-items: center; + gap: var(--padding); +} + +.button svg { + pointer-events: none; + fill: var(--color-contrast); + transform: scale(1.2); +} + +.button p { + pointer-events: none; + font-size: clamp(16px,5vw,22px); + color: var(--color-background); +} + +.button.phantom { + background-color: rgba(var(--comp-contrast),.1); +} + +.button.phantom p { + color: var(--color-contrast); +} + +/* -- Screens -- */ + +header { + --size: 100px; box-sizing: border-box; - padding: var(--page-padding); + padding: var(--padding); + height: var(--size); display: flex; align-items: center; - z-index: 1; + gap: var(--padding); + font-weight: bold; } -#intro .inner { - display: flex; - height: 100%; - flex-direction: column; - justify-content: space-between; +header .hamburger { + width: calc(var(--size) - (var(--padding) * 2)); + height: calc(var(--size) - (var(--padding) * 2)); + box-sizing: border-box; + flex-shrink: 0; + padding: 15px; } -#intro .logo { - --size: 7vh; - margin-bottom: calc(var(--page-padding) / 2); -} - -#intro .block { +header .hamburger div { width: 100%; - font-size: 3vh; + height: 2px; + background: var(--color-contrast); + box-shadow: 0 -10px 0 0 var(--color-contrast), 0 10px 0 0 var(--color-contrast); } -#intro .block:last-child { - display: flex; - align-items: flex-end; +header .hamburger svg { + fill: none; + stroke: var(--color-contrast); + stroke-linecap: round; + stroke-width: 2; } -#intro .block p { - font-size: .7em; - margin-bottom: 1.5em; -} - -#intro .block p span { - margin-right: .9em; - background-color: var(--color-background); -} - -/* ---- */ - -nav a { - text-decoration: none; - margin-right: 2em; - font-size: .9em; -} - -nav a::after { - content: "→"; - padding-left: .5em; -} - -/* ---- */ - -#myface { - right: 0; - width: 50%; - display: flex; - justify-content: center; -} - -#myface picture, -#myface img { - position: absolute; +header .spacer { + width: 1px; height: 80%; - bottom: 0; - pointer-events: none; + background-color: rgba(var(--comp-contrast),.2); +} + +.dark header .spacer { + background-color: black; +} + +header .logo { + --size: 25px; + margin-top: calc(var(--size) / 2); + margin-right: calc(var(--size) / 2); +} + +/* -- Screen > Landingpage -- */ + +/* -- Screen > Menu -- */ + +.screen.menu .content { display: flex; - justify-content: center; + flex-direction: column; + gap: 20px; } -#myface img { - height: 100%; -} - -/* -- Size Queries -- */ - -@media (max-width: 1100px) { - :root { - --page-padding: 50px; - } - - h1 { - font-size: 7vw; - } - - h2 { - font-size: 5vw; - } - - /* ---- */ - - main { - max-width: unset; - background-position: 100% 0; - background-size: var(--grid-spacing) var(--grid-spacing), auto 100vw; - } - - /* ---- */ - - #intro { - width: initial; - } - - #intro .logo { - --size: 10vw; - } - - #intro p { - text-align: left; - } - - #intro .block p:last-of-type { - text-align: initial; - } - - #myface { - display: none; - } - - /* ---- */ - - nav a { - text-decoration: none; - margin-right: 5vw; - font-size: 5vw; - } -} - -/* -- Accessibility -- */ - -@media (hover: hover) { - nav a:hover { - background: var(--color-highlight); - font-weight: bold; - } -} - -@media (prefers-color-scheme: dark) { - :root { - --comp-background: 0,0,0; - --comp-accent: 255,255,255; - } -} +.screen.menu .button[data="contact"] { + margin-top: auto; +} \ No newline at end of file diff --git a/public/assets/js/script.js b/public/assets/js/script.js index 656c4d3..724b772 100644 --- a/public/assets/js/script.js +++ b/public/assets/js/script.js @@ -1,19 +1,12 @@ -// Register SW if supported by browser -if(navigator.serviceWorker) { - navigator.serviceWorker.register("sw.js",{ - scope: "/" - }); +function toggleMenu() { + const speed = 200; + const menu = document.getElementsByTagName("main")[0]; + + menu.style.setProperty("transition",`${speed}ms`); + menu.classList.toggle("active"); + setTimeout(() => menu.style.removeProperty("transition"),speed + 1); } -const theme = window.matchMedia("(prefers-color-scheme: dark)"); - -// Set theme color -function updateTheme() { - // Get theme color from stylesheet - const color = window.getComputedStyle(document.body).getPropertyValue("--color-background"); - document.querySelector("meta[name='theme-color']").setAttribute("content",color); -} - -// Set theme color and listen for changes -theme.addEventListener("change",updateTheme); -updateTheme(theme); +for(const element of document.getElementsByClassName("hamburger")) { + element.addEventListener("click",() => toggleMenu()); +} \ No newline at end of file diff --git a/public/index.html b/public/index.html index 5259755..03ca4df 100644 --- a/public/index.html +++ b/public/index.html @@ -1,4 +1,5 @@ + @@ -11,34 +12,37 @@
-
-
-
- -

victor westerlund

-

full-stack web developer

-
-
-

I create things with code. The things I've created for the public reside as open-source repositories on GitHub, the rest you'll be lucky to hear about some day.

-

Other topics (seemingly irrelevant to programming) I find facinating include but is in no way limited to astronomy, psychology, sociology, economics, ...

-

hello@victorwesterlund.com​(PGP Key)

-
-
- +
+
+
+
+
+ +

victor westerlund

+
+
-
- - - - - - - +
diff --git a/public/sw.js b/public/sw.js deleted file mode 100644 index c2b2541..0000000 --- a/public/sw.js +++ /dev/null @@ -1,102 +0,0 @@ -const version = "1628250171"; -const root = "/"; - -let activeCaches = [ - `content-${version}` -]; - -let cacheManifest = [ - "index.html", - "assets/css/style.css", - "assets/css/fonts.css", - "assets/img/favicon.png", - "assets/img/pattern.gif", - "assets/fonts/RobotoMono-Bold.woff2", - "assets/fonts/RobotoMono-Regular.woff2", - "assets/js/script.js" -]; - -// Download assets and install ServiceWorker -self.addEventListener("install", event => { - event.waitUntil( - caches.open(`content-${version}`).then(cache => cache.addAll(cacheManifest.map(asset => { - // Append the root path to all assets - return root + asset; - }))) - ) -}); - -// Wipe old assets from Cache Storage -self.addEventListener("activate", event => { - event.waitUntil( - // Delete inactive caches - caches.keys().then(cacheNames => { - return Promise.all( - cacheNames.map(cacheName => { - if(!activeCaches.includes(cacheName)) { - return caches.delete(cacheName); - } - }) - ) - }) - ) -}); - -// Fetch and cache an asset not defined in the manifest -async function fetchToCache(event) { - const networkFetch = fetch(event.request); - - event.waitUntil( - networkFetch.then(response => { - const responseClone = response.clone(); - caches.open("bucket").then(cache => cache.put(event.request, responseClone)); - }) - ); - - const response = await caches.match(event.request); - return response || networkFetch; -} - -// Fetch and follow redirects without caching -async function fetchContent(url,i = 0) { - if(i >= 5) { - throw new Error("ERR_TOO_MANY_REDIRECTS"); - } - - return await fetch(url).then(response => { - if(response.redirected) { - i++; - return fetchContent(response.url,i); - } - return response; - }); -} - -self.addEventListener("fetch", event => { - const url = new URL(event.request.url); - const origin = (url.origin == location.origin) ? true : false; // Is same-origin - - // Speed up TTFB by serving index file first - if(origin && url.pathname == "/") { - event.respondWith(caches.match(root + "index.html")); - return; - } - - // Fetch cross-origin content using the network - if(!origin || (url.pathname.substring(1,7) != "assets")) { - event.respondWith(fetchContent(url.href)); - return; - } - - // Get pattern.gif from generator. Fallback to cache on failure - if(origin && url.pathname.endsWith("pattern.gif")) { - const pattern = new Request(`${location.origin}${root}assets/img/pattern.php`); - event.respondWith(fetch(pattern).catch(() => caches.match(root + "assets/img/pattern.gif"))); - return; - } - - // Respond with content from cache or fetch and save - event.respondWith( - caches.match(event.request).then(response => response || fetchToCache(event)) - ); -});