├── public ├── _redirects └── index.html ├── src ├── Components │ ├── Blog.js │ ├── Home.js │ ├── Footer.js │ ├── NotFound.js │ ├── About.js │ ├── GalleryItem.js │ ├── Navbar.js │ ├── Gallery.js │ ├── Featured.js │ └── Hero.js ├── index.js ├── hooks │ ├── useSmoothScroll.js │ └── gsap.js ├── App.js └── index.css ├── .gitignore └── package.json /public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 -------------------------------------------------------------------------------- /src/Components/Blog.js: -------------------------------------------------------------------------------- 1 | const Blog = ({ needFullHeight }) => { 2 | return ( 3 |
4 |

Blog

5 |

Updated later...

6 |
7 | ); 8 | }; 9 | 10 | export default Blog; 11 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Immemorial 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Components/Home.js: -------------------------------------------------------------------------------- 1 | import About from "./About"; 2 | import Featured from "./Featured"; 3 | import Gallery from "./Gallery"; 4 | import Hero from "./Hero"; 5 | 6 | const Home = () => { 7 | return ( 8 |
9 | 10 | 11 | 12 | 13 |
14 | ); 15 | }; 16 | 17 | export default Home; 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import { BrowserRouter } from "react-router-dom"; 4 | import App from "./App"; 5 | import "./index.css"; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById("root")); 8 | root.render( 9 | 10 | 11 | 12 | 13 | 14 | ); 15 | -------------------------------------------------------------------------------- /src/hooks/useSmoothScroll.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | import Lenis from "@studio-freight/lenis"; 3 | 4 | export const useSmoothScroll = () => { 5 | const lenis = new Lenis({ 6 | duration: 1.5, 7 | easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), 8 | direction: "vertical", 9 | gestureDirection: "vertical", 10 | smooth: true, 11 | }); 12 | useEffect(() => { 13 | function raf(time) { 14 | lenis.raf(time); 15 | requestAnimationFrame(raf); 16 | } 17 | 18 | requestAnimationFrame(raf); 19 | }, []); 20 | }; 21 | -------------------------------------------------------------------------------- /src/Components/Footer.js: -------------------------------------------------------------------------------- 1 | import { useRef } from "react"; 2 | import { useGsapFooterHeadline } from "../hooks/gsap"; 3 | 4 | const Footer = () => { 5 | const footerRef = useRef(null); 6 | const footerHeadlineRef = useRef(null); 7 | 8 | useGsapFooterHeadline(footerHeadlineRef, footerRef); 9 | return ( 10 |
11 |

Bonjour

12 |

13 | ©{new Date().getFullYear()} Immemorial. Crafted by yours truely 14 |

15 |
16 | ); 17 | }; 18 | 19 | export default Footer; 20 | -------------------------------------------------------------------------------- /src/Components/NotFound.js: -------------------------------------------------------------------------------- 1 | import { useRef } from "react"; 2 | import { useGsapNotFoundHeadline } from "../hooks/gsap"; 3 | const NotFound = ({ needFullHeight }) => { 4 | const leftHeadlineRef = useRef(null); 5 | 6 | useGsapNotFoundHeadline(leftHeadlineRef, 1.4); 7 | return ( 8 |
9 |

Not found

10 |
11 | Sorry, we couldn't find that page 12 |
13 |
14 | ); 15 | }; 16 | 17 | export default NotFound; 18 | -------------------------------------------------------------------------------- /src/Components/About.js: -------------------------------------------------------------------------------- 1 | const About = () => { 2 | return ( 3 |
4 |

About

5 |

6 | Explore the lost treasures and shining stars of the 1990s! Find your 7 | favorite cartoons, TV shows, music albums, & more with easy filtering 8 | functionality. With Immemorial, stay up-to-date with all your 90s 9 | favorites while turning back time. 10 |

11 |

12 | What's the only era that never seems to end? The 90s! Journey through 13 | appreciating items from 90s TV, music, and art. See if you remember old 14 | toys, cartoons, or prints of such. Indulge in some nostalgia before our 15 | world falls back into the dark ages. 16 |

17 |
18 | ); 19 | }; 20 | 21 | export default About; 22 | -------------------------------------------------------------------------------- /src/Components/GalleryItem.js: -------------------------------------------------------------------------------- 1 | import { useRef } from "react"; 2 | import { 3 | useGsapGalleryTitle, 4 | useGsapGalleryCategory, 5 | useGsapGalleryImage, 6 | } from "../hooks/gsap"; 7 | 8 | const GalleryItem = ({ image }) => { 9 | const galleryTitleRef = useRef(null); 10 | const galleryCategoryRef = useRef(null); 11 | const galleryimageRef = useRef(null); 12 | 13 | useGsapGalleryTitle(galleryTitleRef, galleryimageRef); 14 | useGsapGalleryCategory(galleryCategoryRef, galleryimageRef); 15 | useGsapGalleryImage(galleryimageRef); 16 | return ( 17 |
18 |

19 | {image.title} 20 |

21 |

22 | {image.category} 23 |

24 |
29 |
30 | ); 31 | }; 32 | 33 | export default GalleryItem; 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "immemorial", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@studio-freight/lenis": "^0.2.28", 7 | "@testing-library/jest-dom": "^5.16.5", 8 | "@testing-library/react": "^13.4.0", 9 | "@testing-library/user-event": "^13.5.0", 10 | "gsap": "^3.11.4", 11 | "react": "^18.2.0", 12 | "react-dom": "^18.2.0", 13 | "react-router-dom": "^6.6.2", 14 | "react-scripts": "5.0.1", 15 | "web-vitals": "^2.1.4" 16 | }, 17 | "scripts": { 18 | "start": "react-scripts start", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": [ 25 | "react-app", 26 | "react-app/jest" 27 | ] 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.2%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import { Routes, Route } from "react-router-dom"; 2 | import Blog from "./Components/Blog"; 3 | import About from "./Components/About"; 4 | import Featured from "./Components/Featured"; 5 | import Footer from "./Components/Footer"; 6 | import Home from "./Components/Home"; 7 | import Navbar from "./Components/Navbar"; 8 | import { useSmoothScroll } from "./hooks/useSmoothScroll"; 9 | import Gallery from "./Components/Gallery"; 10 | import NotFound from "./Components/NotFound"; 11 | 12 | const App = () => { 13 | useSmoothScroll(); 14 | return ( 15 |
16 | 17 | 18 | } /> 19 | } /> 20 | } /> 21 | } /> 22 | } /> 23 | } /> 24 | 25 |
27 | ); 28 | }; 29 | 30 | export default App; 31 | -------------------------------------------------------------------------------- /src/Components/Navbar.js: -------------------------------------------------------------------------------- 1 | import { useRef } from "react"; 2 | import { Link } from "react-router-dom"; 3 | import { useGsapDownStagger } from "../hooks/gsap"; 4 | const Navbar = () => { 5 | const li1 = useRef(null); 6 | const li2 = useRef(null); 7 | const li3 = useRef(null); 8 | const blogRef = useRef(null); 9 | const logoRef = useRef(null); 10 | 11 | const liArr = [li1, li2, li3]; 12 | const favarr = [blogRef]; 13 | const logoArr = [logoRef]; 14 | useGsapDownStagger(liArr, 0.9); 15 | useGsapDownStagger(logoArr, 1.5); 16 | useGsapDownStagger(favarr, 1.8); 17 | 18 | return ( 19 | 40 | ); 41 | }; 42 | 43 | export default Navbar; 44 | -------------------------------------------------------------------------------- /src/Components/Gallery.js: -------------------------------------------------------------------------------- 1 | import GalleryItem from "./GalleryItem"; 2 | const images = [ 3 | { 4 | id: 1, 5 | src: "https://images.pexels.com/photos/4842487/pexels-photo-4842487.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1", 6 | title: "Arcade playtime for 90's kids", 7 | category: "Arcade Games", 8 | }, 9 | { 10 | id: 2, 11 | src: "https://images.pexels.com/photos/3356608/pexels-photo-3356608.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1", 12 | title: "No signal - no transmission", 13 | category: "TV", 14 | }, 15 | { 16 | id: 3, 17 | src: "https://images.pexels.com/photos/12668238/pexels-photo-12668238.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1", 18 | title: "Retro Closures", 19 | category: "Boombox", 20 | }, 21 | { 22 | id: 4, 23 | src: "https://images.pexels.com/photos/12204293/pexels-photo-12204293.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1", 24 | title: "Vinyl Loveless Happiness", 25 | category: "Vinyl Record", 26 | }, 27 | ]; 28 | 29 | const Gallery = () => { 30 | return ( 31 |
32 |

Gallery

33 |
34 | {images.map((image) => ( 35 | 36 | ))} 37 |
38 |
39 | ); 40 | }; 41 | 42 | export default Gallery; 43 | -------------------------------------------------------------------------------- /src/Components/Featured.js: -------------------------------------------------------------------------------- 1 | import { useRef } from "react"; 2 | import { 3 | useGsapFeatureLeftShutterUnveil, 4 | useGsapFeatureRightShutterUnveil, 5 | } from "../hooks/gsap"; 6 | 7 | const Featured = () => { 8 | const featureRef = useRef(null); 9 | const featureLeftShutterRef = useRef(null); 10 | const featureRightShutterRef = useRef(null); 11 | 12 | useGsapFeatureLeftShutterUnveil(featureLeftShutterRef, featureRef); 13 | useGsapFeatureRightShutterUnveil(featureRightShutterRef, featureRef); 14 | return ( 15 |
16 |

Featured

17 |
18 |
19 | 90'S TELEPHONE 20 | 90'S TELEPHONE 24 | 28 |
29 |
30 | 90'S CASSETTE PLAYER 31 | 90'S CASSETTE PLAYER 35 | 39 |
40 |
41 |
42 | ); 43 | }; 44 | 45 | export default Featured; 46 | -------------------------------------------------------------------------------- /src/Components/Hero.js: -------------------------------------------------------------------------------- 1 | import { useRef } from "react"; 2 | import { 3 | useGsapShutterUnveil, 4 | useGsapPhotoDropping, 5 | useGsapPhotoLevitate, 6 | } from "../hooks/gsap"; 7 | 8 | const Hero = () => { 9 | const heroRef = useRef(null); 10 | const shutter1 = useRef(null); 11 | const shutter2 = useRef(null); 12 | 13 | const photo1Ref = useRef(null); 14 | const photo2Ref = useRef(null); 15 | const photo3Ref = useRef(null); 16 | const photo4Ref = useRef(null); 17 | const photo5Ref = useRef(null); 18 | const photosArr = [photo1Ref, photo2Ref, photo3Ref, photo4Ref, photo5Ref]; 19 | 20 | useGsapShutterUnveil(shutter1, 0, heroRef); 21 | useGsapShutterUnveil(shutter2, 0.2, heroRef); 22 | useGsapPhotoDropping(photosArr); 23 | useGsapPhotoLevitate(photosArr, heroRef); 24 | return ( 25 |
26 |

27 | Ethereal 28 |

29 |

30 | Canvas 31 |

32 | 33 |
34 |
42 |
50 |
58 |
66 |
74 |
75 |
76 | ); 77 | }; 78 | 79 | export default Hero; 80 | -------------------------------------------------------------------------------- /src/hooks/gsap.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | import gsap, { Expo } from "gsap"; 3 | import { ScrollTrigger } from "gsap/ScrollTrigger"; 4 | 5 | gsap.registerPlugin(ScrollTrigger); 6 | 7 | export const useGsapShutterUnveil = (item, delay = 0, trig) => { 8 | useEffect(() => { 9 | const el = item.current; 10 | 11 | gsap.fromTo( 12 | el, 13 | { 14 | height: "100%", 15 | }, 16 | { 17 | height: 0, 18 | duration: 2, 19 | ease: Expo.easeInOut, 20 | delay: delay, 21 | scrollTrigger: { 22 | trigger: trig.current, 23 | toggleActions: "play reverse play reverse", 24 | }, 25 | } 26 | ); 27 | }, []); 28 | }; 29 | 30 | export const useGsapDownStagger = (arr, delay = 0) => { 31 | useEffect(() => { 32 | const el = arr.map((item) => item.current); 33 | 34 | gsap.fromTo( 35 | el, 36 | { y: "-100%", opacity: 0 }, 37 | { 38 | y: 0, 39 | opacity: 1, 40 | duration: 1.5, 41 | stagger: 0.1, 42 | ease: Expo.easeIn, 43 | delay: delay, 44 | } 45 | ); 46 | }, []); 47 | }; 48 | 49 | export const useGsapPhotoDropping = (arr) => { 50 | useEffect(() => { 51 | const el = arr.map((item) => item.current); 52 | 53 | gsap.fromTo( 54 | el, 55 | { 56 | y: "-100vh", 57 | scale: 0, 58 | }, 59 | { 60 | y: 0, 61 | scale: 1, 62 | duration: 2, 63 | stagger: 0.2, 64 | delay: 2.7, 65 | ease: Expo.easeInOut, 66 | } 67 | ); 68 | }, []); 69 | }; 70 | 71 | export const useGsapPhotoLevitate = (arr, trig) => { 72 | useEffect(() => { 73 | const el = arr.map((item) => item.current); 74 | 75 | gsap.fromTo( 76 | el, 77 | { y: 0 }, 78 | { 79 | y: "-35%", 80 | ease: Expo.easeInOut, 81 | scrollTrigger: { 82 | trigger: trig.current, 83 | scrub: 1, 84 | toggleActions: "play reverse play reverse", 85 | }, 86 | } 87 | ); 88 | }, []); 89 | }; 90 | 91 | export const useGsapFeatureLeftShutterUnveil = (item, trig) => { 92 | useEffect(() => { 93 | const el = item.current; 94 | 95 | gsap.fromTo( 96 | el, 97 | { height: "100%" }, 98 | { 99 | height: 0, 100 | duration: 1.3, 101 | ease: Expo.easeInOut, 102 | scrollTrigger: { 103 | trigger: trig.current, 104 | start: "top center", 105 | end: "bottom center", 106 | toggleActions: "play reverse play reverse", 107 | }, 108 | } 109 | ); 110 | }, []); 111 | }; 112 | export const useGsapFeatureRightShutterUnveil = (item, trig) => { 113 | useEffect(() => { 114 | const el = item.current; 115 | 116 | gsap.fromTo( 117 | el, 118 | { width: "100%" }, 119 | { 120 | width: 0, 121 | duration: 1.3, 122 | ease: Expo.easeInOut, 123 | scrollTrigger: { 124 | trigger: trig.current, 125 | start: "top center", 126 | end: "bottom center", 127 | toggleActions: "play reverse play reverse", 128 | }, 129 | } 130 | ); 131 | }, []); 132 | }; 133 | 134 | export const useGsapGalleryImage = (item) => { 135 | useEffect(() => { 136 | const el = item.current; 137 | 138 | gsap.fromTo( 139 | el, 140 | { 141 | x: 0, 142 | width: 0, 143 | }, 144 | { 145 | x: "30%", 146 | width: "100%", 147 | duration: 1, 148 | ease: Expo.easeInOut, 149 | scrollTrigger: { 150 | trigger: el, 151 | start: "top center", 152 | end: "bottom top", 153 | toggleActions: "play reverse play reverse", 154 | }, 155 | } 156 | ); 157 | }, []); 158 | }; 159 | export const useGsapGalleryTitle = (item, trig) => { 160 | useEffect(() => { 161 | const el = item.current; 162 | 163 | gsap.fromTo( 164 | el, 165 | { 166 | x: "30%", 167 | }, 168 | { 169 | x: 0, 170 | duration: 1, 171 | ease: Expo.easeInOut, 172 | scrollTrigger: { 173 | trigger: trig.current, 174 | start: "top center", 175 | end: "bottom top", 176 | toggleActions: "play reverse play reverse", 177 | }, 178 | } 179 | ); 180 | }, []); 181 | }; 182 | export const useGsapGalleryCategory = (item, trig) => { 183 | useEffect(() => { 184 | const el = item.current; 185 | 186 | gsap.fromTo( 187 | el, 188 | { 189 | x: "-100vw", 190 | }, 191 | { 192 | x: 0, 193 | duration: 1, 194 | ease: Expo.easeInOut, 195 | scrollTrigger: { 196 | trigger: trig.current, 197 | start: "top center", 198 | end: "bottom top", 199 | toggleActions: "play reverse play reverse", 200 | }, 201 | } 202 | ); 203 | }, []); 204 | }; 205 | 206 | export const useGsapFooterHeadline = (item, trig) => { 207 | useEffect(() => { 208 | const el = item.current; 209 | 210 | gsap.fromTo( 211 | el, 212 | { 213 | y: "-100%", 214 | }, 215 | { 216 | y: 0, 217 | duration: 1, 218 | ease: Expo.easeInOut, 219 | scrollTrigger: { 220 | trigger: trig.current, 221 | toggleActions: "play", 222 | }, 223 | } 224 | ); 225 | }, []); 226 | }; 227 | 228 | export const useGsapNotFoundHeadline = (item, delay = 0) => { 229 | useEffect(() => { 230 | const el = item.current; 231 | 232 | gsap.fromTo( 233 | el, 234 | { 235 | x: "-100vw", 236 | }, 237 | { 238 | x: "-50%", 239 | duration: 1.5, 240 | ease: Expo.easeInOut, 241 | delay: delay, 242 | } 243 | ); 244 | }, []); 245 | }; 246 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap"); 2 | 3 | @import url("https://fonts.googleapis.com/css2?family=Bai+Jamjuree:wght@200;300;400;500;600;700&display=swap"); 4 | 5 | @import url("https://fonts.googleapis.com/css2?family=Syncopate:wght@400;700&display=swap"); 6 | @import url("https://fonts.googleapis.com/css2?family=Bodoni+Moda:wght@400;500;600;700;800;900&display=swap"); 7 | 8 | :root { 9 | --color-primary: #d53f41; 10 | --color-dark: #626262; 11 | --color-darker: #464646; 12 | --color-light: #dbd8d6; 13 | --color-lighter: #f5f0ec; 14 | } 15 | * { 16 | margin: 0; 17 | padding: 0; 18 | list-style: none; 19 | text-decoration: none; 20 | box-sizing: border-box; 21 | } 22 | html, 23 | body { 24 | overflow-x: hidden; 25 | } 26 | html { 27 | font-size: 62.5%; 28 | } 29 | 30 | body { 31 | font-family: "Poppins", sans-serif; 32 | font-size: 2rem; 33 | font-weight: 400; 34 | line-height: 1.7; 35 | letter-spacing: 1px; 36 | background-color: var(--color-lighter); 37 | color: var(--color-darker); 38 | } 39 | 40 | .wrapper { 41 | margin: 0 5vw; 42 | } 43 | 44 | section { 45 | padding: 10vw 0; 46 | } 47 | .section-title { 48 | font-family: "Syncopate", sans-serif; 49 | font-size: 1.5rem; 50 | padding-bottom: 5vw; 51 | text-transform: lowercase; 52 | color: var(--color-primary); 53 | } 54 | .min-h-100vh { 55 | min-height: 100vh; 56 | } 57 | 58 | .navbar { 59 | display: flex; 60 | justify-content: space-between; 61 | font-size: 1.5rem; 62 | font-family: Syncopate, sans-serif; 63 | align-items: flex-start; 64 | padding: 2rem 0; 65 | text-transform: lowercase; 66 | } 67 | .links, 68 | .blog-link { 69 | font-weight: 700; 70 | } 71 | 72 | .links a, 73 | .blog-link a { 74 | color: var(--color-dark); 75 | position: relative; 76 | } 77 | 78 | .links a::after, 79 | .blog-link a::after { 80 | content: ""; 81 | width: 0%; 82 | height: 0.2rem; 83 | position: absolute; 84 | top: 50%; 85 | left: 50%; 86 | transform: translate(-50%, -50%); 87 | background-color: var(--color-primary); 88 | transition: 0.5s; 89 | } 90 | .links a:hover::after, 91 | .blog-link a:hover::after { 92 | width: 120%; 93 | } 94 | .logo a { 95 | color: var(--color-darker); 96 | } 97 | .hero { 98 | font-family: "Bai Jamjuree", sans-serif; 99 | text-transform: uppercase; 100 | text-align: center; 101 | font-size: 10vw; 102 | line-height: 1.1; 103 | min-height: 100vh; 104 | color: var(--color-darker); 105 | display: flex; 106 | flex-direction: column; 107 | justify-content: center; 108 | align-items: center; 109 | position: relative; 110 | } 111 | .ethereal, 112 | .canvas { 113 | position: relative; 114 | } 115 | .ethereal span, 116 | .canvas span { 117 | position: absolute; 118 | left: 0; 119 | right: 0; 120 | top: 0; 121 | bottom: 0; 122 | width: 100%; 123 | height: 100%; 124 | background-color: var(--color-lighter); 125 | } 126 | .photos { 127 | position: absolute; 128 | top: 0; 129 | left: 0; 130 | right: 0; 131 | bottom: 0; 132 | z-index: 1; 133 | display: grid; 134 | grid-template-columns: repeat(7, 1fr); 135 | grid-template-rows: repeat(5, 1fr); 136 | } 137 | .photo { 138 | width: 100%; 139 | height: 100%; 140 | background-position: center; 141 | background-repeat: no-repeat; 142 | background-size: cover; 143 | overflow: hidden; 144 | } 145 | .photo.one { 146 | grid-column: 1; 147 | grid-row: 2; 148 | } 149 | .photo.two { 150 | grid-column: 4; 151 | grid-row: 3; 152 | } 153 | .photo.three { 154 | grid-column: 2; 155 | grid-row: 5; 156 | } 157 | .photo.four { 158 | grid-column: 7; 159 | grid-row: 4; 160 | } 161 | .photo.five { 162 | grid-column: 5; 163 | grid-row: 1; 164 | } 165 | /* --feature-- */ 166 | .features { 167 | display: grid; 168 | grid-template-columns: 30% auto; 169 | align-items: center; 170 | gap: 10rem; 171 | } 172 | .feature-text { 173 | letter-spacing: 5px; 174 | font-weight: 500; 175 | } 176 | .features img { 177 | width: 100%; 178 | } 179 | .feature-l, 180 | .feature-r { 181 | display: flex; 182 | flex-direction: column; 183 | gap: 1rem; 184 | position: relative; 185 | } 186 | .feature-shutter-l, 187 | .feature-shutter-r { 188 | position: absolute; 189 | z-index: 1; 190 | background-color: #d53f41; 191 | height: 100%; 192 | width: 100%; 193 | top: 0; 194 | left: 0; 195 | right: 0; 196 | bottom: 0; 197 | background-color: var(--color-lighter); 198 | } 199 | /* --About-- */ 200 | .about p { 201 | font-size: 3vw; 202 | line-height: 1.5; 203 | } 204 | .about p:last-child { 205 | margin-top: 3vw; 206 | } 207 | 208 | .gallery .section-title { 209 | margin-left: 5vw; 210 | } 211 | .gallery-wrapper { 212 | background-color: var(--color-primary); 213 | display: grid; 214 | grid-template-columns: ifr; 215 | justify-items: center; 216 | gap: 10vw; 217 | padding: 10vw; 218 | } 219 | .gallery-item { 220 | position: relative; 221 | width: 50%; 222 | } 223 | .gallery-item-title { 224 | position: absolute; 225 | top: 10%; 226 | left: -50%; 227 | font-family: "Bai Jamjuree", sans-serif; 228 | font-size: 8vw; 229 | line-height: 1.2; 230 | text-transform: uppercase; 231 | color: var(--color-lighter); 232 | z-index: 1; 233 | mix-blend-mode: color-dodge; 234 | } 235 | .gallery-item-category { 236 | position: absolute; 237 | left: 0; 238 | bottom: -5%; 239 | text-transform: uppercase; 240 | color: var(--color-lighter); 241 | letter-spacing: 10px; 242 | z-index: 1; 243 | } 244 | .gallery-item-img { 245 | background-position: center; 246 | background-repeat: no-repeat; 247 | background-size: cover; 248 | width: 100%; 249 | height: 100vh; 250 | } 251 | .footer { 252 | text-align: center; 253 | } 254 | .footer h1 { 255 | font-family: "Bodoni Moda", serif; 256 | font-size: 10vw; 257 | text-transform: lowercase; 258 | color: var(--color-primary); 259 | } 260 | .not-found { 261 | min-height: 100vh; 262 | display: grid; 263 | grid-template-columns: 1fr 1fr; 264 | align-content: flex-start; 265 | column-gap: 5vw; 266 | row-gap: 1vw; 267 | padding: 5vw 0; 268 | } 269 | 270 | .headline-1 { 271 | padding-top: 10vh; 272 | font-family: "Bai Jamjuree", sans-serif; 273 | font-size: 6vw; 274 | font-weight: 700; 275 | line-height: 1; 276 | text-transform: capitalize; 277 | } 278 | --------------------------------------------------------------------------------