]> MadKous Network Git Server - photo-site.git/commitdiff
New Layout master
authorMatthew Kousoulas <shaman.kous@gmail.com>
Mon, 16 Sep 2024 18:12:47 +0000 (18:12 +0000)
committerMatthew Kousoulas <shaman.kous@gmail.com>
Mon, 16 Sep 2024 18:12:47 +0000 (18:12 +0000)
index.html
scripts/dom.js
scripts/main.js
scripts/photo.js
scripts/util.js
styles/main.css
styles/test.css [new file with mode: 0644]

index 861c1c3b4022aa0860673ac9a11de1785cbd127a..d6daf9cf19053a9d8cbcafc8d81c1323172fef40 100644 (file)
                <meta property="og:url"
                      content="http://www.madkous.net/photo/index.html" />
                <meta property="og:image"
-                     content="http://madkous.net/media/pictures/20220313_0047_sm.jpg" />
+                     content="http://madkous.net/media/pictures/20220530_0247_sm.jpg" />
                <meta property="og:description"
-                     content="Abandoned Picnic" />
+                     content="Misty Creek" />
+               <meta property="og:image:width"
+                     content="1000" />
+               <meta property="og:image:height"
+                     content="706" />
                <!--twitter card data-->
                <meta name="twitter:card"
                      content="summary_large_image" />
                <meta name="twitter:title"
                      content="MadKous Photography" />
                <meta name="twitter:image"
-                     content="http://madkous.net/media/pictures/20220313_0047_sm.jpg" />
+                     content="http://madkous.net/media/pictures/20220530_0247_sm.jpg" />
                <meta name="twitter:description"
-                     content="Abandoned Picnic" />
+                     content="Misty Creek" />
                <!--page data-->
                <link rel="stylesheet" type="text/css" href="styles/main.css" />
                <!--util must be first; main must be last-->
-               <script type="text/javascript" src="scripts/util.js"></script>
-               <script type="text/javascript" src="scripts/photo.js"></script>
-               <script type="text/javascript" src="scripts/dom.js"></script>
-               <script type="text/javascript" src="scripts/main.js"></script>
+               <script type="module" src="scripts/util.js"></script>
+               <script type="module" src="scripts/photo.js"></script>
+               <script type="module" src="scripts/dom.js"></script>
+               <script type="module" src="scripts/main.js"></script>
        </head>
        <body class="parent">
                <div id="photo-layer" class="photo-bg fade-out">
                        <div id="photo-frame" class="photo-frame"></div>
                </div>
-               <div id="logo" class="fade-out">
-                       <a href="/">
-                               <img src="/media/logo_ng.svg" alt="MadKous">
-                       </a>
+               <div id="side-bar" class="fade-out">
+                       <div id="logo" class="fade-out">
+                               <a href="/">
+                                       <img src="/media/logo_ng.svg" alt="MadKous">
+                               </a>
+                       </div>
+                       <div id="nav-text" class="fade-out">
+                               <h1>Chronology</h1>
+                               <ul id="nav-links">
+                               </ul>
+                       </div>
                </div>
-               <div id="thumb-layer" class="fade-out">
+               <div id="main">
+                       <div id="carousel" class="fade-out">
+                               <div id="carousel-title"></div>
+                               <ul id="carousel-grid"></ul>
+                       </div>
+                       <footer id="footer" class="fade-out">
+                               <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
+                                       <img alt="Creative Commons License" style="border-width:0"
+                                                                                                                                                                src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
+                               </a>
+                               <p>All photographs were taken by Matthew Kousoulas and are licensed under the
+                                       <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
+                                               Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.</p>
+                       </footer>
                </div>
-               <footer id="footer" class="fade-out">
-                       <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
-                               <img alt="Creative Commons License" style="border-width:0"
-                               src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
-                       </a>
-                       <p>All photographs were taken by Matthew Kousoulas
-                       and are licensed under a
-                       <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
-                               Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.</p>
-               </footer>
        </body>
 </html>
index 096001c9304eabf3cebcceee139b6b5df04590e0..e533df842ebfa5cc7d27dd79b2a923c9a809cc2a 100644 (file)
-var DOM = (dom => {
-       dom.logo;
-       // main photo container
-       dom.photo_layer;
-       dom.photo_frame;
-       // thumbnail containers
-       dom.thumb_layer;
-       dom.thumb_grid;
-       dom.footer;
-
-       //// dom creation ////
-       dom.makeThumbnail = (p) => {
-               let t = document.createElement("img");
-               let e = document.createElement("div");
-
-               t.alt = p.title;
-               t.title = p.title;
-               t.src = `/media/pictures/${p.name}_thm.jpg`;
-
-               e.appendChild(t);
-               e.addEventListener("click", () => {
-                       event.stopPropagation();
-                       dom.loadPhoto(p);
-               });
-               e.classList.add("thumb");
-
-               return e;
-       }
-
-       dom.makePicture = (p) => {
-               let e = document.createElement("img");
-
-               e.alt = p.title;
-               e.title = p.title;
-               e.src = `/media/pictures/${p.name}_sm.jpg`;
-               e.addEventListener("click", () => {
-                       event.stopPropagation();
-                       window.open(`/media/pictures/${p.name}.jpg`);
-               });
-               return e;
-       }
-
-       dom.loadPhoto = (p) => {
-               CLASS.hide(dom.photo_frame);
-               UTIL.disableScroll();
+import {memo, is_visible, hide_element, show_element, enable_scroll, disable_scroll, remove_all} from "./util.js";
+
+// dom containers
+let c = {};
+// photo book
+let photo_book = new Map();
+
+//// dom creation ////
+function make_thumbnail(p) {
+       let t = document.createElement("img");
+       let e = document.createElement("li");
+
+       t.alt = p.title;
+       t.title = p.title;
+       t.src = `/media/pictures/${p.name}_thm.jpg`;
+       // t.loading = "lazy";
+
+       e.appendChild(t);
+       e.addEventListener("click", () => {
+               event.stopPropagation();
+               load_photo(p);
+       });
+       e.classList.add("thumb");
+
+       return e;
+}
+
+function make_picture(p) {
+       console.log("make picture");
+       let e = document.createElement("img");
+
+       e.alt = p.title;
+       e.title = p.title;
+       e.src = `/media/pictures/${p.name}_sm.jpg`;
+       // e.loading = "lazy";
+       e.addEventListener("click", () => {
+               event.stopPropagation();
+               window.open(`/media/pictures/${p.name}.jpg`);
+       });
+       return e;
+}
+
+function add_nav_link(n, i)
+{
+       let l = document.createElement("li");
+       l.innerText = n;
+       l.classList.add("nav-link");
+       l.addEventListener("click", () => {
+               event.stopPropagation();
+               open_section(n, i);
+       });
+
+       c.nav_links.appendChild(l);
+}
+
+export function load_photo(p) {
+       hide_element(c.photo_frame);
+       disable_scroll();
+       setTimeout(() => {
+               show_element(c.photo_frame);
+               remove_all(c.photo_frame);
+               c.photo_frame.appendChild(p.img());
+       }, 500);
+       show_element(c.photo_layer);
+}
+
+function open_section(n, i) {
+       hide_element(c.carousel);
+       setTimeout(() => {
                setTimeout(() => {
-                       CLASS.show(dom.photo_frame);
-                       UTIL.removeAll(dom.photo_frame);
-                       dom.photo_frame.appendChild(p.img());
+                       show_element(c.carousel);
                }, 500);
-               CLASS.show(dom.photo_layer);
-       }
-       
-       dom.addThumbnail = (t) => {
-
-               dom.thumb_grid.appendChild(t);
-       }
-
-       dom.addSection = (n) =>
-       {
-               let h = n.toLowerCase().replace(" ","-");
-
-               let e = document.createElement("div");
-               e.classList.add("section");
-               e.id = h;
-               dom.thumb_layer.appendChild(e);
-
-               let t = document.createElement("div");
-               t.innerText = n;
-               t.classList.add("section-text");
-               e.appendChild(t);
-
-               let u = document.createElement("ul");
-               u.classList.add("section-list");
-               u.id = h + "-list";
-               e.appendChild(u);
-
-               let g = document.createElement("div");
-               g.classList.add("grid");
-               dom.thumb_layer.appendChild(g);
-               dom.thumb_grid = g;
-       }
-
-       dom.finishSections = (l) =>
-       {
-               for (let section of document.getElementsByClassName("section")) {
-                       let list = section.childNodes[1];
-                       let name = section.childNodes[0].innerText;
-                       for (let n of l.reverse()) {
-                               let h = n.toLowerCase().replace(" ","-");
-                               let l = document.createElement("li");
-                               list.appendChild(l);
-
-                               let a = document.createElement("a");
-                               a.innerText = n;
-                               a.href = "#" + h;
-                               l.appendChild(a);
-
-                               if (n === name) {
-                                       a.style.color = "var(--fg-col)";
-                               }
-                       }
+               if (photo_book.has(i)) {
+                       c.carousel_title.innerText = n;
+                       c.carousel_grid.replaceChildren(...photo_book.get(i).map(x => x()));
                }
-       }
-       
-       dom.revealGrid = () => {
-               setTimeout(() => {
-                       CLASS.show(dom.logo);
-                       setTimeout(() => {
-                               CLASS.show(dom.thumb_layer);
-                               if (window.location.hash) {
-                                       setTimeout(() => {
-                                               dom.scrollTo(window.location.hash);
-                                       }, 300);
-                               }
-                               CLASS.show(dom.footer);
-                       }, 300);
-               }, 500);
+       }, 800);
+}
+
+export function reveal_grid(s) {
+       // let start = Date.now();
+       function reveal_element(e, t) {
+               return (r) => (y) => setTimeout(() => {
+                       // console.log(`${Date.now() - start} Revealing: ${e.id} in ${t}`);
+                       show_element(e);
+                       r(y);
+               }, t);
        }
 
-       dom.scrollTo = (hash) => {
-               if (hash) {
-                       document.getElementById(hash.substring(1))
-                               .scrollIntoView({behavior: "smooth"});
+       let steps = [
+               { e: c.side_bar, t: 1300},
+               { e: c.logo, t: 200},
+               { e: c.nav_text, t: 500},
+               { e: c.footer, t: 500}
+       ];
+
+       steps.reduceRight((acc, curr) => reveal_element(curr.e, curr.t)(acc),
+               open_section)(s);
+}
+
+export function hide_photo() {
+       enable_scroll();
+       hide_element(c.photo_layer);
+}
+
+export function photo_layer_visible() {
+       return is_visible(c.photo_layer);
+}
+
+function fill_containers(l) {
+       l.forEach(s => {
+               let i = s.replaceAll("-", "_");
+               c[i] = document.getElementById(s);
+       });
+}
+
+export function init_dom(photos) {
+       fill_containers(["logo",
+               "carousel",
+               "carousel-grid",
+               "carousel-title",
+               "nav-links",
+               "nav-text",
+               "photo-layer",
+               "photo-frame",
+               "side-bar",
+               "thumb-layer",
+               "footer"]);
+
+       c.photo_layer.addEventListener("click", () => {
+               event.stopPropagation();
+               hide_photo();
+       });
+
+       // c.carousel_grid.addEventListener("wheel", (e) => {
+       //      e.preventDefault();
+       //      c.carousel_grid.scrollLeft += e.deltaY * 5;
+       // });
+
+       // let section_list = [];
+       let section = "";
+       let section_id = "";
+
+       photos.forEach((p, _i) => {
+               p.thm = memo(make_thumbnail, p);
+               p.img = memo(make_picture, p);
+
+               // this branch can't run on the first loop
+               // so grid will always be non null
+               if (section === p.date) {
+                       photo_book.get(section_id).push(p.thm);
+               } else {
+                       section = p.date;
+                       section_id = section.toLowerCase().replaceAll(" ", "-");
+                       // section_list.push(p.date);
+                       add_nav_link(section, section_id);
+                       photo_book.set(section_id, [ p.thm ]);
                }
-       }
-
-       dom.init = () => {
-               dom.logo        = document.getElementById("logo");
-               dom.thumb_layer = document.getElementById("thumb-layer");
-               dom.photo_layer = document.getElementById("photo-layer");
-               dom.photo_frame = document.getElementById("photo-frame");
-               dom.footer      = document.getElementById("footer");
-
-               dom.photo_layer.addEventListener("click", () => {
-                       event.stopPropagation();
-                       PHOTO.hide();
-               });
-       }
+       });
+}
 
-       return dom;
-})(DOM || {});
index 66a04e587f6f39e1273a19c57962d93cfa4f6e14..5955975b8f4a8babfd8cc5731264be5fa5a3cf8d 100644 (file)
@@ -1,59 +1,32 @@
-(() => {
-"use strict";
-       //// json handling ////
-       function loadJson(text) {
-               let json = JSON.parse(text);
-               let section_list = [];
-               let section = "";
-               PHOTO.all = json.photos; //.filter(p => p.active === "T");
-               PHOTO.all.forEach((p, i) => {
-                       p.thm = DOM.makeThumbnail(p);
-                       // p.img = _ => DOM.makePicture(p);
-                       let cel = null;
-                       let get = _ => {
-                               if (cel === null)
-                                       cel = DOM.makePicture(p);
-                               return cel;
-                       };
-                       p.img = get;
+import {init_photos, prev_photo, next_photo} from "./photo.js";
+import {hide_photo, photo_layer_visible, init_dom, reveal_grid} from "./dom.js";
 
-                       if (section === p.date) {
-                               DOM.addThumbnail(p.thm)
-                       } else {
-                               section = p.date
-                               section_list.push(p.date);
-                               DOM.addSection(section);
-                               DOM.addThumbnail(p.thm)
-                       }
-               });
-               DOM.finishSections(section_list);
-       }
-
-       ///// input handling /////
-       function keyDown(e) {
-               event.stopPropagation();
-               if (e.keyCode === 27 || e.keyCode === 32) { // space, escape
-                       PHOTO.hide();
-               } else if (e.keyCode === 37) { // left arrow
-                       if (CLASS.visible(DOM.photo_layer)) PHOTO.prev();
-               } else if (e.keyCode === 39) { // right arrow
-                       if (CLASS.visible(DOM.photo_layer)) PHOTO.next();
-               } else {
-//                     console.log(`${e.code} -> ${e.keyCode}`);
-               }
+///// input handling /////
+function keyDown(e) {
+       event.stopPropagation();
+       if (e.keyCode === 27 || e.keyCode === 32) { // space, escape
+               hide_photo();
+       } else if (e.keyCode === 37) { // left arrow
+               if (photo_layer_visible()) prev_photo();
+       } else if (e.keyCode === 39) { // right arrow
+               if (photo_layer_visible()) next_photo();
+       } else {
+               // console.log(`${e.code} -> ${e.keyCode}`);
        }
+}
 
-       document.addEventListener("DOMContentLoaded",
-               (event) => {
-                       let xhttp = new XMLHttpRequest();
-                       xhttp.onload = (() => {
-                               DOM.init();
-                               loadJson(xhttp.responseText);
-                               DOM.revealGrid();
-                       });
-                       xhttp.open("GET", "data/pictures.json");
-                       xhttp.send();
-
-                       document.addEventListener("keydown", keyDown);
+document.addEventListener("DOMContentLoaded",
+       (_event) => {
+               let xhttp = new XMLHttpRequest();
+               xhttp.onload = (() => {
+                       let json = JSON.parse(xhttp.responseText);
+                       let all_photos = init_photos(json.photos.filter(p => p.active === "T"));
+                       window.photos = all_photos;
+                       init_dom(all_photos);
+                       reveal_grid(window.location.hash.substring(1));
                });
-})();
+               xhttp.open("GET", "data/pictures.json");
+               xhttp.send();
+
+               document.addEventListener("keydown", keyDown);
+       });
index 29e9b177e8a8a78ce84a37c4b52c81c6ea665553..e9d4121e31ee052f4e2cb95fd4e579e8967b6807 100644 (file)
@@ -1,25 +1,29 @@
-var PHOTO = (photo => {
-       photo.all;
+import {load_photo} from "./dom.js";
 
-       photo.current = _ => document.querySelector("#photo-frame>img");
-       photo.hide = _ => {
-               UTIL.enableScroll();
-               CLASS.hide(DOM.photo_layer);
-       }
-       photo.next = _ => {
-               let i = photo.all.findIndex(p => p.img() === photo.current());
-               if (i === -1)
-                       console.log("error, no current image");
-               let j = i + 1 === photo.all.length ? 0 : i + 1;
-               DOM.loadPhoto(photo.all[j]);
-       };
-       photo.prev = _ => {
-               let i = photo.all.findIndex(p => p.img() === photo.current());
-               if (i === -1)
-                       console.log("error, no current image");
-               let j = i <= 0 ? photo.all.length - 1 : i - 1;
-               DOM.loadPhoto(photo.all[j]);
-       };
+let all_photos = null;
+
+export function init_photos(l) {
+       all_photos = l;
+       return all_photos;
+}
+
+export function current_photo() {
+       return document.querySelector("#photo-frame>img");
+}
+
+export function next_photo() {
+       let i = all_photos.findIndex(p => p.img() === current_photo());
+       if (i === -1)
+               console.log("error, no current image");
+       let j = i + 1 === all_photos.length ? 0 : i + 1;
+       load_photo(all_photos[j]);
+}
+
+export function prev_photo() {
+       let i = all_photos.findIndex(p => p.img() === current_photo());
+       if (i === -1)
+               console.log("error, no current image");
+       let j = i <= 0 ? all_photos.length - 1 : i - 1;
+       load_photo(all_photos[j]);
+}
 
-       return photo;
-})(PHOTO || {});
index 9ad4fac5a30aae996b6bcaa619e8faee85ca806d..40ce7d4a15c5b508617aa8acc078fd3bad12952b 100644 (file)
@@ -1,36 +1,41 @@
-var UTIL = (util => {
-       util.top = _ => true;
-       util.siblings = (n) => Array.from(n.parentNode.children);
-       util.peek = (a) => a[a.length-1];
+export function top(_) { return true; }
+export function siblings(n) { return Array.from(n.parentNode.children); }
+export function peek(a) { return a[a.length-1]; }
 
-       util.removeLast = (e) => e.removeChild(e.lastChild);
-       util.removeAll = (e) => {
-               while(e.lastChild) {
-                       e.removeChild(e.lastChild);
-               }
+export function remove_last(e) { e.removeChild(e.lastChild); }
+export function remove_all(e) {
+       while(e.lastChild) {
+               e.removeChild(e.lastChild);
        }
+}
 
-       util.disableScroll = _ => {
-               let x=window.scrollX;
-               let y=window.scrollY;
-               window.onscroll = _ => window.scrollTo(x, y);
-       }
-       util.enableScroll = _ => window.onscroll = _ => {};
+export function disable_scroll(_) {
+       let x=window.scrollX;
+       let y=window.scrollY;
+       window.onscroll = _ => window.scrollTo(x, y);
+}
+export function enable_scroll(_) { window.onscroll = _ => {}; }
 
-       return util;
-})(UTIL || {});
 
-var CLASS = (cls => {
-       cls.hide = (e) => {
-               e.classList.add("fade-out");
-               e.classList.remove("fade-in");
-       }
-       cls.show = (e) => {
-               e.classList.add("fade-in");
-               e.classList.remove("fade-out");
-       }
-       cls.visible = (e) => !e.classList.contains("fade-out")
+export function hide_element(e) {
+       e.classList.add("fade-out");
+       e.classList.remove("fade-in");
+}
+
+export function show_element(e) {
+       e.classList.add("fade-in");
+       e.classList.remove("fade-out");
+}
 
-       return cls;
-})(CLASS || {});
+export function is_visible(e) {
+       return !e.classList.contains("fade-out");
+}
 
+export function memo(f, ...p) {
+       let cel = null;
+       return _ => {
+               if (cel === null)
+                       cel = f(...p);
+               return cel;
+       };
+}
index 99d42a45a92d8db668b157c19c174eee5c949382..9569eaa3c236660458ed206de09e8252d85b77c9 100644 (file)
@@ -1,20 +1,28 @@
 :root {
        /* tan */
-       --bg-col: #CCBFA8;
-       --bg-lite-col: #DED3BF;
+       --bg-col: #646464;
+       --bg-med-col: #727272;
+       --bg-lite-col: #9F9F9F;
 
        /* purple */
-       --fg-col: #615E71;
-       --fg-emph-col: #5D5E7A;
-       --fg-mute-col: #716E8144;
+       --fg-col: #444444;
+       --fg-emph-col: #111111;
+       --fg-mute-col: #00FF00;
        --shadow-col: #35343CB3;
-       --frame-bd-col: #D4D1E5;
+       --frame-bd-col: #F0F0F0;
+       --frame-bd-trans: #F0F0F000;
 
        /* sage */
-       --button-col: #94ACA7;
+       --button-col: #AAAAAA;
 
        --menu-width: calc(100px + 10vw);
-       --gutter-width: calc(10px + 7vw);
+       --text-size-base: clamp(12px, 3vw, 18px);
+       --text-size-emph: clamp(14px, 4vw, 26px);
+       /* --text-size-emph: calc(1.5em + 0.5vw); */
+       --gutter-width: calc(var(--text-size-emph) * 5 + 4vmax);
+       --section-width-raw: 0px;
+       --section-width: calc(var(--section-width-raw) + 1.618 * var(--text-size-base) + 5vw);
+       --row-height: 230px;
 }
 
 html {
@@ -24,110 +32,148 @@ html {
 body {
        background-color: var(--bg-col);
        color: var(--fg-col);
-       margin: 5%;
+       margin: 0;
+       height: 100vh;
        font-family: sans-serif;
 }
 
-.float {
-       position: fixed;
-       width: var(--menu-width);
-       /* background-color: red; */
+#main {
+       margin-left: calc(var(--gutter-width) + 4vmax);
+       height: 100%;
+       overflow: hidden;
 }
 
+/*** Logo ***/
+
 #logo {
        display: flex;
-       margin-bottom: 3vh;
+       margin-bottom: 2vh;
        justify-content: center;
 }
 
 #logo > a > img {
-       height: calc(7px + 10vw);
-       filter: hue-rotate(10deg) saturate(150%) drop-shadow(5px 5px 5px var(--shadow-col));
+       /* height: calc(10vw); */
+       max-width: var(--gutter-width);
+       filter: brightness(0.65) saturate(0) drop-shadow(0px 0px 30px var(--bg-lite-col));
+       transition: all 500ms ease-in-out;
 }
 
-.section {
-       background-color: var(--bg-lite-col);
-       border-radius: 1vw;
-       margin-bottom: 3vh;
+#logo > a > img:hover {
+       filter: brightness(0.45) saturate(0) drop-shadow(0px 0px 15px white);
+       transition: all 500ms ease-in-out;
 }
 
-.section-text {
-       font-size: calc(2em + 0.5vw);
-       padding-top: .75vw;
-       padding-bottom: .25vw;
-       text-align: center;
-       visibility: visible;
-       opacity: 1;
-       transition: visibility 500ms, opacity 500ms;
-}
+/*** Sidebar ***/
 
-.section-list {
-       text-align: center;
+h1 {
+       color: var(--fg-emph-col);
+       font-size: var(--text-size-emph);
        margin: 0;
-       padding-left: 0;
-       padding-bottom: .5vw;
-       overflow: hidden;
-       visibility: hidden;
-       opacity: 0;
-       transition: visibility 300ms, opacity 300ms;
 }
 
-.section-list a {
-       text-decoration: none;
-       font-size: 12pt;
-       color: var(--fg-mute-col);
-       white-space: nowrap;
+#side-bar {
+       position: fixed;
+       z-index: 10;
+       top: 0;
+       left: 0;
+       height: 100%;
+       width: var(--gutter-width);
+       background-color: var(--bg-lite-col);
+       padding: 2vmax;
+}
+
+#nav-links {
+       padding-inline-start: 1vw;
 }
 
-.section-list a:hover {
+#nav-links > li {
+       font-size: var(--text-size-base);
+       list-style-type: none;
+       margin-top: 2vh;
+       margin-bottom: 2vh;
+       transition: all 500ms ease-in-out;
+}
+
+#nav-links > li:hover {
        color: var(--fg-emph-col);
-       transition: color 500ms;
+       text-shadow: 0 0 15px white;
+       transition: all 500ms ease-in-out;
 }
 
-.section-list li {
-       display: inline;
+/*** Thumbnail Grid ***/
+
+#carousel {
+       margin-bottom: 3vh;
        padding-left: 1vw;
        padding-right: 1vw;
+       width: 100%;
+       height: 90%;
+       background-color: var(--bg-med-col);
+       transition: all 400ms ease-in-out;
 }
 
-.section:hover .section-list {
-       visibility: visible;
-       opacity: 1;
-       transition: visibility 500ms, opacity 500ms;
+#carousel-title {
+       font-size: var(--text-size-emph);
+       color: var(--fg-emph-col);
+       padding-top: 1vh;
+       padding-left: 1vw;
+       transition: all 800ms ease-in-out;
 }
 
-.grid {
+#carousel-grid {
        display: flex;
-       margin-bottom: 3vh;
        flex-wrap: wrap;
-       justify-content: center;
+       list-style-type: none;
+       margin-top: 0;
+       padding-left: 0;
+       height: 90%;
+       overflow-y: scroll;
+       align-items: center;
+       scroll-snap-type: x mandatory;
+       transition: all 800ms ease-in-out;
+       transition-delay: 350ms;
 }
 
+/*** Thumbnail ***/
+
 .thumb {
-       margin: .3vw;
-       border-radius: .5vw;
-       display: block;
-       height: 200px;
+       margin: .25vmin;
+       scroll-snap-align: center;
 }
 
+/* .thumb:first-child { */
+/*     margin-left: auto; */
+/* } */
+
+/* .thumb:last-child { */
+/*     margin-right: auto; */
+/* } */
+
+/* redo startup animations */
+
+/* minimize width loss
+ * ideal: 200px
+ * max: ?
+ * min: ?
+ * columns: ?
+ * min_c(t - c * w)
+ */
 .thumb > img {
-       border-radius: inherit;
-       min-width: 100%;
-       max-height: 200px;
+       object-fit: cover;
+       height: 200px;
+       width: 200px;
+       border: .3vw solid var(--bg-med-col);
+       box-shadow: 0px 0px .5vw .1vw var(--bg-med-col);
        transition: all 800ms ease-in-out;
 }
 
 .thumb > img:hover {
-       transform: scale(1.1);
-       box-shadow: 0px 0px 10px 5px var(--shadow-col);
+       border: .3vw solid var(--frame-bd-col);
+       box-shadow: 0px 0px .5vw .1vw black;
        transition: all 800ms ease-in-out;
 }
 
-.thumb > img:active {
-       box-shadow: 0px 0px 0px var(--shadow-col);
-       transform: scale(0.95);
-       transition: all 300ms ease-in-out;
-}
+/*** Photo Overlay ***/
 
 .photo-bg {
        position: fixed;
@@ -142,41 +188,52 @@ body {
 .photo-frame > img {
        cursor: pointer;
        max-width: 90vw;
-       max-height: 84vh;
+       max-height: 80vh;
        margin-left: auto;
        margin-right: auto;
        margin-top: 7vh;
        margin-bottom: auto;
        display: block;
-       border: thick solid var(--frame-bd-col);
+       border: 5vmin solid var(--frame-bd-col);
        box-shadow: 0px 0px 3vmax 2vmax #0D0D0DC2;
 }
 
-/* these must remain at the bottom */
-.parent { height: 95%; }
-.fade-in {
-       opacity: 1;
-       transition: visibility 500ms, opacity 500ms;
-}
-.fade-out {
-       visibility: hidden;
-       opacity: 0;
-       transition: visibility 300ms, opacity 300ms;
-}
+/*** Footer ***/
 
 footer {
        font-size: small;
-       justify-content: center;
-       margin: auto;
-       max-width: 60vw;
-       transition: all 800ms ease-in-out;
+       position: fixed;
+       bottom: 0;
+       right: 0;
+       margin-left: 2vw;
+       margin-right: 2vw;
+       margin-bottom: 2vh;
+       max-width: calc(100% - (var(--gutter-width) + 8vmax));
+       /* transition: all 800ms ease-in-out; */
+}
+
+footer > p {
+       float: right;
+       width: 80%;
+       margin: 0;
 }
 
 footer > a {
        float: left;
-       margin-right: 5vw;
 }
 
 footer > a > img {
        filter: drop-shadow(5px 5px 5px var(--shadow-col));
 }
+
+/* these must remain at the bottom */
+.fade-in {
+       visibility: visible;
+       opacity: 1;
+       transition: all 800ms;
+}
+.fade-out {
+       visibility: hidden;
+       opacity: 0;
+       transition: all 500ms;
+}
diff --git a/styles/test.css b/styles/test.css
new file mode 100644 (file)
index 0000000..049e6af
--- /dev/null
@@ -0,0 +1,38 @@
+html {
+       scroll-snap-type: y mandatory;
+}
+
+#thumbs {
+       margin-top: 30px;
+
+       display: flex;
+       gap: 8px;
+       padding: 16px;
+
+       overflow-x: scroll;
+       scroll-snap-type: x mandatory;
+}
+
+#thumbs li {
+       list-style-type: none;
+       /* flex-shrink: 0; */
+
+       width: 80%;
+       height: 90vh;
+       background-color: #FF0000;
+       scroll-snap-align: center;
+       
+}
+
+#thumbs li>img {
+       /* display: flex; */
+       /* align-items: center; */
+       /* justify-content: center; */
+
+       /* max-width: 100%; */
+       height: 200px;
+       padding-top: 1vmax;
+       padding-bottom: 1vmax;
+}
+
+