From b05c451f11cdaf9531466290341a0aa7a6dc761c Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Sun, 12 Sep 2021 12:14:10 +0200 Subject: [PATCH] dev21w36e --- public/assets/css/modal.css | 44 ++++++- public/assets/css/style.css | 158 +++++++++++++++++++----- public/assets/img/icons/email.svg | 1 + public/assets/img/icons/signal.svg | 1 + public/assets/js/modules/Debugging.mjs | 16 ++- public/assets/js/modules/Modals.mjs | 21 +++- public/assets/js/script.js | 48 +++---- public/assets/pages/contact.html | 10 +- public/assets/pages/contact_signal.html | 14 +-- public/index.html | 18 ++- 10 files changed, 243 insertions(+), 88 deletions(-) create mode 100644 public/assets/img/icons/email.svg create mode 100644 public/assets/img/icons/signal.svg diff --git a/public/assets/css/modal.css b/public/assets/css/modal.css index 9dd0d83..7cd4477 100644 --- a/public/assets/css/modal.css +++ b/public/assets/css/modal.css @@ -22,16 +22,16 @@ body .modal.active ~ main .screen { left: 0; width: 100vw; height: 100%; - z-index: 1; + z-index: 10; pointer-events: none; box-sizing: border-box; - background-color: rgba(var(--comp-inverted),0); + background-color: rgba(var(--palette-inverted),0); padding: var(--padding); } .modal.active { pointer-events: all; - background-color: rgba(var(--comp-inverted),.4); + background-color: rgba(var(--palette-inverted),.4); } .modal .button { @@ -41,7 +41,7 @@ body .modal.active ~ main .screen { .modal .inner { transition: var(--transition) transform, var(--transition) opacity; position: relative; - background-color: var(--color-background); + background-color: var(--swatch-background); width: calc(100vw - var(--padding)); max-width: 500px; max-height: 100%; @@ -50,6 +50,7 @@ body .modal.active ~ main .screen { box-sizing: border-box; padding: var(--padding); border-radius: var(--border-radius); + box-shadow: 0 3px 30px 0 rgba(var(--palette-contrast),.2); opacity: 0; display: flex; flex-direction: column; @@ -70,7 +71,7 @@ body .modal.active ~ main .screen { /* ---- */ .spinner.logo { - --size: 10vw; + --size: clamp(30px,5vw,60px); --anim-speed: 1s; align-self: center; margin-top: var(--padding); @@ -84,7 +85,7 @@ body .modal.active ~ main .screen { } .error:first-line { - font-size: 15vw; + font-size: 50px; } @keyframes logoSpinner { @@ -131,4 +132,35 @@ body .modal.active ~ main .screen { .modal.dialog.active .inner { transform: scale(1); +} + +@media (min-aspect-ratio: 14/9) { + /* -- Transition overrides -- */ + + body main .screen { + transition: unset; + } + + body .modal.active ~ main .screen { + transition: unset; + transform: unset; + opacity: unset; + } + + body .modal { + transition: var(--transition); + transition-delay: calc(var(--transition) / 2); + backdrop-filter: blur(0); + } + + body .modal.active { + transition-delay: 1ms; + backdrop-filter: blur(10px); + } + + /* -- Boilerplate -- */ + + .modal.card .inner { + align-self: unset; + } } \ No newline at end of file diff --git a/public/assets/css/style.css b/public/assets/css/style.css index 908866d..f696d52 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -1,16 +1,19 @@ /* Copyright © Victor Westerlund - No libraries! 😲 */ :root { - --comp-background: 255,255,255; - --comp-inverted: 0,0,0; - --comp-contrast: 33,33,33; - --comp-accent: 22,183,255; + /* Component colors */ + --palette-background: 255,255,255; + --palette-inverted: 0,0,0; + --palette-contrast: 33,33,33; + --palette-accent: 22,183,255; - --color-background: rgb(var(--comp-background)); - --color-inverted: rgb(var(--comp-inverted)); - --color-contrast: rgb(var(--comp-contrast)); - --color-accent: rgb(var(--comp-accent)); + /* Compiled colors */ + --swatch-background: rgb(var(--palette-background)); + --swatch-inverted: rgb(var(--palette-inverted)); + --swatch-contrast: rgb(var(--palette-contrast)); + --swatch-accent: rgb(var(--palette-accent)); + /* Default styles */ --padding: 20px; --border-radius: 10px; --header-height: 100px; @@ -18,15 +21,19 @@ } .dark { - --comp-background: 33,33,33; - --comp-inverted: 255,255,255; - --comp-contrast: 255,255,255; - --comp-accent: 255,255,255; + --palette-background: 33,33,33; + --palette-inverted: 255,255,255; + --palette-contrast: 255,255,255; + --palette-accent: 255,255,255; - --color-background: rgb(var(--comp-background)); - --color-inverted: rgb(var(--comp-inverted)); - --color-contrast: rgb(var(--comp-contrast)); - --color-accent: rgb(var(--comp-accent)); + --swatch-background: rgb(var(--palette-background)); + --swatch-inverted: rgb(var(--palette-inverted)); + --swatch-contrast: rgb(var(--palette-contrast)); + --swatch-accent: rgb(var(--palette-accent)); +} + +.wide { + display: none; /* Hide wide-screen elements */ } @font-face { @@ -52,12 +59,12 @@ * { margin: 0; font-family: "Roboto Mono","Arial",sans-serif; - color: var(--color-contrast); + color: var(--swatch-contrast); } *::selection { - background-color: var(--color-highlight); - color: var(--color-accent); + background-color: var(--swatch-highlight); + color: var(--swatch-accent); } picture { @@ -79,7 +86,7 @@ main { } body.menuActive { - background-color: var(--color-contrast); + background-color: var(--swatch-contrast); } body.dark.menuActive { @@ -93,8 +100,13 @@ body.menuActive main { /* ---- */ .screen { + --background-pattern: + linear-gradient(90deg, var(--swatch-background) calc(var(--padding) + 1px), transparent 1%) center, + linear-gradient(var(--swatch-background) calc(var(--padding) + 1px), transparent 1%) center, var(--swatch-accent); + --background-pattern-size: calc(var(--padding) + 2px) calc(var(--padding) + 2px); + width: 100vw; - background-color: var(--color-background); + background-color: var(--swatch-background); display: flex; flex-direction: column; } @@ -108,6 +120,7 @@ body.dark .screen.dark { } .screen .content { + position: relative; box-sizing: border-box; padding: calc(var(--padding) * 1.5); padding-top: 0; @@ -131,13 +144,13 @@ body.dark .screen.dark { width: 0; height: 0; border: var(--skew) solid transparent; - border-top: var(--size) solid var(--color-accent); + border-top: var(--size) solid var(--swatch-accent); } .logo::after { content: ""; border: var(--skew) solid transparent; - border-top: var(--size) solid rgba(var(--comp-accent),.3); + border-top: var(--size) solid rgba(var(--palette-accent),.3); } /* ---- */ @@ -146,6 +159,7 @@ body.dark .screen.dark { text-align: center; padding: 25px; border-radius: var(--border-radius); + font-size: clamp(16px,5vw,22px); display: flex; justify-content: center; align-items: center; @@ -153,24 +167,26 @@ body.dark .screen.dark { } .button.solid { - background-color: var(--color-contrast); - color: var(--color-background); + background-color: var(--swatch-contrast); + color: var(--swatch-background); + fill: var(--swatch-background); } .button.phantom { - background-color: rgba(var(--comp-inverted),.05); - color: var(--color-contrast); + background-color: rgba(var(--palette-inverted),.05); + color: var(--swatch-contrast); + fill: var(--swatch-contrast); } .button svg { pointer-events: none; - fill: var(--color-contrast); + fill: inherit; transform: scale(1.2); } .button p { pointer-events: none; - font-size: clamp(16px,5vw,22px); + font-size: inherit; color: inherit; } @@ -215,13 +231,13 @@ header .hamburger { header .hamburger div { width: 100%; height: 2px; - background: var(--color-contrast); - box-shadow: 0 -10px 0 0 var(--color-contrast), 0 10px 0 0 var(--color-contrast); + background: var(--swatch-contrast); + box-shadow: 0 -10px 0 0 var(--swatch-contrast), 0 10px 0 0 var(--swatch-contrast); } header .hamburger svg { fill: none; - stroke: var(--color-contrast); + stroke: var(--swatch-contrast); stroke-linecap: round; stroke-width: 2; } @@ -229,13 +245,17 @@ header .hamburger svg { header .spacer { width: 1px; height: 80%; - background-color: rgba(var(--comp-contrast),.2); + background-color: rgba(var(--palette-contrast),.2); } .dark header .spacer { background-color: black; } +body.dark .dark header .spacer { + background-color: rgba(var(--palette-contrast),.2); +} + header .logo { --size: 25px; margin-top: calc(var(--size) / 2); @@ -244,13 +264,20 @@ header .logo { /* -- Screen > Landingpage -- */ +.screen.landingpage { + background: var(--background-pattern); + background-size: var(--background-pattern-size); +} + .screen.landingpage .content { padding-bottom: 0; } .screen.landingpage img { + position: relative; width: clamp(100px,80vw,40vh); align-self: flex-end; + z-index: 1; } .screen.landingpage .pattern { @@ -268,7 +295,7 @@ header .logo { width: 0; height: 0; border: solid var(--size) transparent; - border-bottom: solid calc(var(--size) * 2) rgba(var(--comp-accent),.1); + border-bottom: solid calc(var(--size) * 2) rgba(var(--palette-accent),.1); transform-origin: 50% 75%; transform: rotate(20deg); } @@ -292,6 +319,50 @@ header .logo { margin-top: auto; } +/* -- Media queries -- */ + +/* Wide-screen */ +@media (min-aspect-ratio: 14/9) { + /* -- Cornerstones -- */ + + header { + display: none; + } + + main { + width: 100vw; + flex-direction: row-reverse; + } + + /* -- Cornerstones > State overrides -- */ + + body.menuActive { + background-color: inherit; + } + + body.menuActive main { + transform: unset; + } + + /* -- Screens -- */ + + .screen { + width: 50vw; + flex-direction: row; + } + + body.dark .screen { + --swatch-background: black; + } + + /* -- Screens > Menu -- */ + + .screen.menu .content { + padding-top: calc(var(--padding) * 1.5); + } +} + +/* Narrow display */ @media (max-width: 300px) { .button svg:not(.hidden) ~ p, header .logo { @@ -299,6 +370,7 @@ header .logo { } } +/* Super-narrow display */ @media (max-width: 230px) { header { justify-content: center; @@ -308,4 +380,22 @@ header .logo { header p { display: none; } +} + +/* -- Media queries > Media features -- */ + +@media (pointer: fine) { + .button { + cursor: pointer; + } +} + +@media (any-hover: hover) { + .button { + transition: var(--transition) background-color; + } + + .button.phantom:hover { + background-color: rgba(var(--palette-inverted),.2); + } } \ No newline at end of file diff --git a/public/assets/img/icons/email.svg b/public/assets/img/icons/email.svg new file mode 100644 index 0000000..3e44b87 --- /dev/null +++ b/public/assets/img/icons/email.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/img/icons/signal.svg b/public/assets/img/icons/signal.svg new file mode 100644 index 0000000..fa9c720 --- /dev/null +++ b/public/assets/img/icons/signal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/js/modules/Debugging.mjs b/public/assets/js/modules/Debugging.mjs index e067b62..1fb4294 100644 --- a/public/assets/js/modules/Debugging.mjs +++ b/public/assets/js/modules/Debugging.mjs @@ -9,7 +9,9 @@ class Debug { const functions = [ "list", "toggleMenu", - "openContactsModal" + "openContactsModal", + "invalidCard", + "infiniteLoadingCard" ]; console.log("Available functions:",functions.map(f => `window._debug.${f}();`)); } @@ -52,6 +54,18 @@ class Debug { card.openPage("invalid_card"); }); } + + infiniteLoadingCard() { + const module = import("./Modals.mjs"); + const spinner = document.createElement("div"); + spinner.classList = "logo spinner"; + + module.then(modals => { + const card = new modals.Card(new Object()); + card.insertElement(spinner); + card.open(); + }); + } } export default window._debug = new Debug(); \ No newline at end of file diff --git a/public/assets/js/modules/Modals.mjs b/public/assets/js/modules/Modals.mjs index d21c12f..fcae338 100644 --- a/public/assets/js/modules/Modals.mjs +++ b/public/assets/js/modules/Modals.mjs @@ -19,7 +19,7 @@ class Modal extends Interaction { this.transition = 300; this.element = this.applyTemplate(element); - this.element.close = () => this.close(); // Bind close to element prototype + this.element.close = () => this.close(); // Bind modal close to element prototype document.body.insertAdjacentElement("afterbegin",this.element); } @@ -124,8 +124,8 @@ export class Card extends Modal { oops.classList.add("error"); oops.innerText = "🤯\nSomething went wrong"; - infoButton.innerText = "more info.."; + infoButton.innerText = "more info.."; infoButton.addEventListener("click",() => { const details = new Dialog(); @@ -153,7 +153,22 @@ export class Card extends Modal { this.insertHTML(html); this.bindAll(this.inner); }) - .catch(error => this.error(error)) + .catch(error => { + const tryAgain = new Button({ + text: "try again", + type: "solid" + }); + tryAgain.element.addEventListener("click",() => { + // Clear and recreate modal structure + destroy(this.inner); + this.applyTemplate(this.element); + this.init(); + // Attempt to fetch the requested url again + this.openPage(page); + }); + this.insertElement(tryAgain.element); + this.error(error); + }) .finally(() => destroy(spinner)); } } \ No newline at end of file diff --git a/public/assets/js/script.js b/public/assets/js/script.js index 0ed8ba5..4b182c6 100644 --- a/public/assets/js/script.js +++ b/public/assets/js/script.js @@ -1,24 +1,37 @@ // Copyright © Victor Westerlund - No libraries! 😲 import { default as Preload } from "./modules/Preload.mjs"; import { default as Interaction } from "./modules/UI.mjs"; -import { default as Debug } from "./modules/Debugging.mjs"; +import "./modules/Debugging.mjs"; // Load these assets when the DOM is ready (not needed right away) -const preload = new Preload([ +new Preload([ "modules/Modals.mjs", "modules/Components.mjs", "modal.css" ]); +function updateTheme() { + const media = window.matchMedia("(prefers-color-scheme: dark)"); + document.body.classList.remove("dark"); + + // Force dark theme on all pages + if(media.matches) { + document.body.classList.add("dark"); + return; + } +} + // All default interactions const interactions = { toggleMenu: () => { - const speed = 200; + const transition = 200; const menu = document.getElementsByTagName("main")[0]; - menu.style.setProperty("transition",`${speed}ms`); + // Animate menu state change + menu.style.setProperty("transition",`${transition}ms`); document.body.classList.toggle("menuActive"); - setTimeout(() => menu.style.removeProperty("transition"),speed + 1); + // Remove transition CSS when finished. Wonky resize effects otherwise + setTimeout(() => menu.style.removeProperty("transition"),transition + 1); }, openContactCard: () => { const module = import("./modules/Modals.mjs"); @@ -34,10 +47,10 @@ const interactions = { copyText: (event) => { const memory = event.target.innerText; event.target.classList.add("bounce"); - event.target.innerText = "Copied!"; + event.target.innerText = "copied!"; setTimeout(() => { event.target.innerText = memory; - },this.transition); + },1000); } }; @@ -45,23 +58,16 @@ const interactions = { const card = new modals.Card(interactions); card.openPage("contact"); }); - } -} - -const theme = window.matchMedia("(prefers-color-scheme: dark)"); -const main = new Interaction(interactions,document.body); - -function updateTheme() { - const media = window.matchMedia("(prefers-color-scheme: dark)"); - document.body.classList.remove("dark"); - - // Force dark theme on all pages - if(media.matches) { - document.body.classList.add("dark"); - return; + }, + openSearch: () => { + const module = import("./modules/Search.mjs"); + document.body.classList.add("searchActive"); } } // Set the current page theme, and listen for changes +const theme = window.matchMedia("(prefers-color-scheme: dark)"); theme.addEventListener("change",updateTheme); + +new Interaction(interactions,document.body); updateTheme(); \ No newline at end of file diff --git a/public/assets/pages/contact.html b/public/assets/pages/contact.html index dd16510..7f56c64 100644 --- a/public/assets/pages/contact.html +++ b/public/assets/pages/contact.html @@ -11,7 +11,7 @@ width: var(--size); height: var(--size); border-radius: var(--border-radius); - background-color: rgba(var(--comp-inverted),.05); + background-color: rgba(var(--palette-inverted),.05); flex-direction: column; justify-content: space-between; box-sizing: border-box; @@ -23,21 +23,21 @@ } .contact .item img { - height: 70%; + height: 10vh; } - @media (max-width: 258px) { + @media (max-width: 300px) { .contact { grid-template-columns: 1fr; } }
-
+

Signal

-
+

E-Mail

diff --git a/public/assets/pages/contact_signal.html b/public/assets/pages/contact_signal.html index 990df37..a2988af 100644 --- a/public/assets/pages/contact_signal.html +++ b/public/assets/pages/contact_signal.html @@ -1,21 +1,21 @@