diff --git a/assets/js/buttons.js b/assets/js/buttons.js new file mode 100644 index 0000000..8b45097 --- /dev/null +++ b/assets/js/buttons.js @@ -0,0 +1,49 @@ +// Randomize button positions on the laptop lid +function initializeButtons() { + const buttons = document.querySelectorAll(".button-sticker"); + const laptopLid = document.getElementById("laptop-lid"); + + if (!laptopLid) return; + + // Account for CSS padding (20px) and bezel border (15px) + const lidPadding = 20; + const bezelBorder = 15; + const totalInset = lidPadding + bezelBorder; + const displayAreaWidth = laptopLid.offsetWidth - totalInset * 2; + const displayAreaHeight = laptopLid.offsetHeight - totalInset * 2; + + buttons.forEach((button) => { + // Get button dimensions - use data attributes as fallback + const buttonWidth = button.offsetWidth || 88; + const buttonHeight = button.offsetHeight || 31; + + // Generate random position within display area bounds + const maxX = Math.max(0, displayAreaWidth - buttonWidth); + const maxY = Math.max(0, displayAreaHeight - buttonHeight); + + const randomX = Math.random() * maxX + totalInset; + const randomY = Math.random() * maxY + totalInset; + const randomRotation = (Math.random() - 0.5) * 40; + + // Set CSS custom properties for positioning and rotation + button.style.setProperty("--x", randomX + "px"); + button.style.setProperty("--y", randomY + "px"); + button.style.setProperty("--rotation", randomRotation + "deg"); + }); +} + +// Initialize on page load +if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initializeButtons); +} else { + // DOM already loaded + initializeButtons(); +} + +// Re-randomize on window resize +window.addEventListener("resize", () => { + // Add small delay to ensure measurements are accurate + setTimeout(() => { + initializeButtons(); + }, 100); +}); diff --git a/assets/sass/pages/buttons.scss b/assets/sass/pages/buttons.scss new file mode 100644 index 0000000..b364826 --- /dev/null +++ b/assets/sass/pages/buttons.scss @@ -0,0 +1,362 @@ +// 88x31 Buttons Collection - Laptop Lid CSS Art +// Standalone page with 3D laptop lid displaying collected IndieWeb buttons + +// Heart flash animation +@keyframes heart-flash { + 0%, + 100% { + filter: none; + color: rgba(255, 0, 0, 0.3); + } + 5%, + 15% { + filter: drop-shadow(0 0 8px #ff0000) drop-shadow(0 0 4px #ff3333); + text-shadow: 0 0 10px rgba(255, 0, 0, 0.8); + color: rgba(255, 0, 0, 0.8); + } + 20%, + 100% { + filter: none; + color: rgba(255, 0, 0, 0.3); + } +} + +.buttons-container { + > .wall { + position: fixed !important; + width: 100vw !important; + height: 100vh !important; + top: 0 !important; + left: 0 !important; + background: repeating-linear-gradient( + 90deg, + #2a2a2a 0px, + #2a2a2a 100px, + #252525 100px, + #252525 101px + ), + linear-gradient(180deg, #1a1a1a 0%, #2a2a2a 50%, #1a1a1a 100%) !important; + + &::before, + &::after { + display: none !important; + } + } + + > .desk { + height: 37%; + } + + .button-lavalamp { + width: 190px; + height: 340px; + position: absolute; + right: 10%; + bottom: 20%; + z-index: 5; + + &::after { + // Add a drop shadow under the lava lamp + content: ""; + position: absolute; + width: 220px; + height: 50px; + background: rgba(0, 0, 0, 0.6); + border-radius: 50%; + bottom: -20px; + left: 50%; + transform: translateX(-50%); + filter: blur(8px); + z-index: -1; + } + } + + .buttons-header { + width: 300px; + margin: auto; + margin-top: 2rem; + transform: rotate(-3deg); + } +} + +// Override wall styling with /now page grid pattern + +.buttons-page { + width: 100%; + margin: 0 auto; + z-index: 10; + position: relative; + + header { + text-align: center; + margin-bottom: 3rem; + + h1 { + font-size: 2.5rem; + margin-bottom: 0.5rem; + } + + p { + font-size: 1.1rem; + color: #666; + } + } +} + +.laptop-container { + display: flex; + justify-content: center; + align-items: center; + perspective: 2000px; + margin: 4rem 0; + min-height: 570px; + padding: 2rem; + position: relative; +} + +.laptop-container::before { + content: ""; + position: absolute; + width: 810px; + height: 50px; + background: linear-gradient(180deg, #1a1a1a 0%, #0d0d0d 100%); + border-radius: 0 0 15px 15px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5), + inset 0 1px 2px rgba(255, 255, 255, 0.05); + z-index: 1; + bottom: 0; + left: 50%; + transform: translateX(-50%) translateZ(-30px); +} + +.laptop-container::after { + content: ""; + position: absolute; + width: 770px; + height: 30px; + bottom: 10px; + left: 50%; + transform: translateX(-50%) translateZ(0px); + background: repeating-linear-gradient( + 90deg, + #2a2a2a 0, + #2a2a2a 12px, + #1a1a1a 12px, + #1a1a1a 16px + ), + repeating-linear-gradient( + 0deg, + #2a2a2a 0, + #2a2a2a 8px, + #1a1a1a 8px, + #1a1a1a 12px + ); + border-radius: 5px; + box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.8); + z-index: 1; + pointer-events: none; +} + +.laptop-lid { + position: relative; + width: 800px; + height: 480px; + background: linear-gradient(135deg, #d4d4d4 0%, #c0c0c0 40%, #b0b0b0 100%); + border-radius: 20px 20px 0 0; + box-shadow: 0 40px 100px rgba(0, 0, 0, 0.4), + inset 0 1px 2px rgba(255, 255, 255, 0.5), + inset 0 -3px 8px rgba(0, 0, 0, 0.08); + transform: rotateX(25deg) translateZ(20px); + transform-style: preserve-3d; + transform-origin: bottom center; + transition: transform 0.3s ease; + border: 3px solid #909090; + border-bottom: 8px solid #707070; + z-index: 10; + padding: 20px; + overflow: hidden; + + // Logo face + &::after { + content: "(•ᴗ•)"; + position: absolute; + background: linear-gradient(135deg, #d4d4d4 0%, #c0c0c0 40%, #b0b0b0 100%); + // clip the background to the text + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + font-weight: bold; + color: #fff; + font-size: 3rem; + top: 22%; + left: 25px; + transform: translateY(-50%) rotate(-45deg); + pointer-events: none; + z-index: -1; + } + + // Animated heart + &::before { + content: "❤"; + position: absolute; + font-size: 2.5rem; + color: #ff0000; + font-size: 3rem; + top: 11%; + left: 122px; + transform: translateY(-50%) rotate(-45deg); + pointer-events: none; + animation: heart-flash 3s ease-in-out infinite; + opacity: 1; + } + + // Bezel/display frame + .laptop-lid-bezel { + position: absolute; + inset: 15px; + border: 12px solid #1a1a1a; + border-radius: 8px; + background: #0a0a0a; + box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.9); + pointer-events: none; + z-index: -1; + } + + &:hover { + transform: rotateX(0deg) translateZ(0px); + } +} + +.button-sticker { + position: absolute; + left: var(--x, 20px); + top: var(--y, 20px); + display: flex; + align-items: center; + justify-content: center; + width: 88px; + height: 31px; + border: none; + border-radius: 2px; + background: transparent; + cursor: pointer; + transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); + transform-style: preserve-3d; + transform: rotate(var(--rotation, 0deg)) scale(0.9); + filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.15)); + + img { + width: 100%; + height: 100%; + object-fit: contain; + display: block; + pointer-events: none; + border-radius: 1px; + } + + &:hover { + transform: rotate(0deg) scale(1.2); + z-index: 100; + filter: drop-shadow(0 10px 25px rgba(0, 0, 0, 0.35)); + } + + &:focus { + outline: 2px solid #4a90e2; + outline-offset: 2px; + } + + &:focus:not(:focus-visible) { + outline: none; + } +} + +.buttons-content { + max-width: 800px; + margin: 4rem auto 0; + padding: 2rem; + + p { + margin-bottom: 1.5rem; + line-height: 1.6; + color: #828282; + } +} + +// Responsive adjustments +@media (max-width: 900px) { + .laptop-container { + min-height: 500px; + } + + .laptop-container::before { + width: 600px; + height: 40px; + } + + .laptop-container::after { + width: 570px; + height: 24px; + bottom: 8px; + } + + .laptop-lid { + width: 600px; + height: 375px; + } + + .button-sticker { + width: 66px; + height: 23px; + + &:hover { + transform: rotateX(-25deg) rotate(0deg) scale(1.3) translateZ(30px); + } + } +} + +@media (max-width: 600px) { + .buttons-page { + padding: 1rem; + + header { + margin-bottom: 2rem; + + h1 { + font-size: 1.8rem; + } + } + } + + .laptop-container { + perspective: 800px; + min-height: 400px; + } + + .laptop-container::before { + width: 100%; + max-width: 400px; + height: 30px; + } + + .laptop-container::after { + width: 370px; + height: 18px; + bottom: 6px; + } + + .laptop-lid { + width: 100%; + max-width: 400px; + height: 250px; + transform: rotateX(25deg) translateZ(20px); + } + + .button-sticker { + width: 44px; + height: 15px; + + &:hover { + transform: rotateX(-25deg) rotate(0deg) scale(1.3) translateZ(30px); + } + } +} diff --git a/assets/sass/style.scss b/assets/sass/style.scss index 8860c32..ce56bff 100644 --- a/assets/sass/style.scss +++ b/assets/sass/style.scss @@ -30,6 +30,7 @@ @import "pages/button-generator"; @import "pages/lavalamp-adoptable"; @import "pages/guestbook"; +@import "pages/buttons"; @import url(https://fonts.bunny.net/css?family=abel:400|barlow-condensed:400,500|caveat:400|lato:300,300i,400,400i|neonderthaw:400); diff --git a/content/buttons/32bitcafe.gif b/content/buttons/32bitcafe.gif new file mode 100644 index 0000000..719275f Binary files /dev/null and b/content/buttons/32bitcafe.gif differ diff --git a/content/buttons/bazzite.gif b/content/buttons/bazzite.gif new file mode 100644 index 0000000..f7b1694 Binary files /dev/null and b/content/buttons/bazzite.gif differ diff --git a/content/buttons/brennanday.gif b/content/buttons/brennanday.gif new file mode 100644 index 0000000..e6eae67 Binary files /dev/null and b/content/buttons/brennanday.gif differ diff --git a/content/buttons/bsgbutton.png b/content/buttons/bsgbutton.png new file mode 100644 index 0000000..0eecea3 Binary files /dev/null and b/content/buttons/bsgbutton.png differ diff --git a/content/buttons/dandadan.gif b/content/buttons/dandadan.gif new file mode 100644 index 0000000..8cf7b85 Binary files /dev/null and b/content/buttons/dandadan.gif differ diff --git a/content/buttons/demo1.gif b/content/buttons/demo1.gif new file mode 100644 index 0000000..0331634 Binary files /dev/null and b/content/buttons/demo1.gif differ diff --git a/content/buttons/demo2.gif b/content/buttons/demo2.gif new file mode 100644 index 0000000..e0dba28 Binary files /dev/null and b/content/buttons/demo2.gif differ diff --git a/content/buttons/demo3.gif b/content/buttons/demo3.gif new file mode 100644 index 0000000..f2bd53b Binary files /dev/null and b/content/buttons/demo3.gif differ diff --git a/content/buttons/demo4.gif b/content/buttons/demo4.gif new file mode 100644 index 0000000..1d362e1 Binary files /dev/null and b/content/buttons/demo4.gif differ diff --git a/content/buttons/drbutton2.png b/content/buttons/drbutton2.png new file mode 100644 index 0000000..13a30b0 Binary files /dev/null and b/content/buttons/drbutton2.png differ diff --git a/content/buttons/fckgoogle.gif b/content/buttons/fckgoogle.gif new file mode 100644 index 0000000..ed15649 Binary files /dev/null and b/content/buttons/fckgoogle.gif differ diff --git a/content/buttons/getflash.gif b/content/buttons/getflash.gif new file mode 100644 index 0000000..19b5ef6 Binary files /dev/null and b/content/buttons/getflash.gif differ diff --git a/content/buttons/hasmile.gif b/content/buttons/hasmile.gif new file mode 100644 index 0000000..8db76ed Binary files /dev/null and b/content/buttons/hasmile.gif differ diff --git a/content/buttons/hl.gif b/content/buttons/hl.gif new file mode 100644 index 0000000..cb79281 Binary files /dev/null and b/content/buttons/hl.gif differ diff --git a/content/buttons/htmldream.gif b/content/buttons/htmldream.gif new file mode 100644 index 0000000..28fd2c2 Binary files /dev/null and b/content/buttons/htmldream.gif differ diff --git a/content/buttons/index.md b/content/buttons/index.md new file mode 100644 index 0000000..7ed7670 --- /dev/null +++ b/content/buttons/index.md @@ -0,0 +1,48 @@ +--- +title: "88x31 Buttons" +description: "A collection of 88x31 IndieWeb buttons collected from around the web" +layout: buttons +buttons: + - name: "32bit Cafe" + url: "https://32bit.cafe/" + image: "32bitcafe.gif" + - name: "Robb Knight" + url: "https://rknight.me/" + image: "robbknight.gif" + - name: "Brennan Day" + url: "https://brennan.day/" + image: "brennanday.gif" + - name: "Bazzite" + url: "https://bazzite.gg/" + image: "bazzite.gif" + - name: "Battlestar Galactica" + image: "bsgbutton.png" + - name: "Divergent Rays" + url: "https://divergentrays.com" + image: "drbutton2.png" + - name: "I dream in HTML" + image: "htmldream.gif" + - name: "DANDADAN" + url: "https://dandadan.i-heart-you.net/" + image: "dandadan.gif" + - name: "Get Flash" + image: "getflash.gif" + - name: "Minecraft" + image: "minecraft.gif" + - name: "Ubuntu" + image: "ubuntu.gif" + - name: "Under Construction" + image: "undercon.gif" + - name: "Linux Online" + image: "linuxonline.gif" + - name: "Half Life" + image: "hl.gif" + - name: "Smile" + image: "hasmile.gif" + - name: "Jigglypuff" + image: "jigglypuff.gif" + - name: "Fuck Google" + image: "fckgoogle.gif" +--- + +People and things I like, stuck on my laptop - just like in real life! diff --git a/content/buttons/jigglypuff.gif b/content/buttons/jigglypuff.gif new file mode 100644 index 0000000..f004561 Binary files /dev/null and b/content/buttons/jigglypuff.gif differ diff --git a/content/buttons/linuxonline.gif b/content/buttons/linuxonline.gif new file mode 100644 index 0000000..c4e533d Binary files /dev/null and b/content/buttons/linuxonline.gif differ diff --git a/content/buttons/minecraft.gif b/content/buttons/minecraft.gif new file mode 100644 index 0000000..a149b45 Binary files /dev/null and b/content/buttons/minecraft.gif differ diff --git a/content/buttons/robbknight.gif b/content/buttons/robbknight.gif new file mode 100644 index 0000000..045dbc9 Binary files /dev/null and b/content/buttons/robbknight.gif differ diff --git a/content/buttons/ubuntu.gif b/content/buttons/ubuntu.gif new file mode 100644 index 0000000..f5faf5f Binary files /dev/null and b/content/buttons/ubuntu.gif differ diff --git a/content/buttons/undercon.gif b/content/buttons/undercon.gif new file mode 100644 index 0000000..f73e975 Binary files /dev/null and b/content/buttons/undercon.gif differ diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 616ee96..9e4c950 100755 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -52,5 +52,11 @@ {{ $guestbook := resources.Get "js/guestbook.js" | resources.Minify | resources.Fingerprint }} {{ end }} + + + {{ if eq .Type "buttons" }} + {{ $buttons := resources.Get "js/buttons.js" | resources.Minify | resources.Fingerprint }} + + {{ end }} diff --git a/layouts/buttons/single.html b/layouts/buttons/single.html new file mode 100644 index 0000000..5e99fb9 --- /dev/null +++ b/layouts/buttons/single.html @@ -0,0 +1,47 @@ +{{ define "main" }} +
+
+
+ +
+ +
+ +
+
+
+ {{ partial "elements/lcd-screen.html" (dict "text" "Buttons" + "placeholder" "") }} +
+
+ +
+
+
+ {{ range .Params.buttons }} + + {{ .name }} + + {{ end }} +
+
+ +
{{ .Content }}
+
+
+{{ end }}