Files for my website bwc9876.dev
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Visual Refresh

Ben C d0e7c333 49782805

+504 -461
src/assets/backdrop.png

This is a binary file and will not be displayed.

+81 -46
src/components/projects/ProjectCard.astro
··· 1 1 --- 2 2 import { Image } from "astro:assets"; 3 + import backdrop from "@assets/backdrop.png"; 3 4 import type { CollectionEntry } from "astro:content"; 4 5 5 6 export interface Props { 6 7 project: CollectionEntry<"projects">; 7 8 } 9 + 10 + const stringToNumber = (str: string, seed = 3) => { 11 + let h1 = 0xdeadbeef ^ seed, 12 + h2 = 0x41c6ce57 ^ seed; 13 + for (let i = 0, ch; i < str.length; i++) { 14 + ch = str.charCodeAt(i); 15 + h1 = Math.imul(h1 ^ ch, 2654435761); 16 + h2 = Math.imul(h2 ^ ch, 1597334677); 17 + } 18 + h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909); 19 + h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909); 20 + return 4294967296 * (2097151 & h2) + (h1 >>> 0); 21 + }; 22 + 23 + const getHueFromText = (text: string): string => `hue-rotate(${stringToNumber(text) % 360}deg)`; 8 24 9 25 const { project } = Astro.props; 10 26 --- 11 27 12 28 <a href={`/projects/${project.slug}/`}> 13 - <div class="card"> 14 - <div class="header"> 15 - <strong class="project-name">{project.data.name}</strong> 16 - <div> 17 - <Image 18 - transition:name={`project-img-${project.slug}`} 19 - format="webp" 20 - src={project.data.image} 21 - alt={project.data.name} 22 - /> 23 - </div> 29 + <article> 30 + <div> 31 + <Image 32 + class="thumbnail" 33 + transition:name={`project-img-${project.slug}`} 34 + format="webp" 35 + src={project.data.image} 36 + alt={project.data.name} 37 + /> 38 + <Image 39 + style={{filter: getHueFromText(project.slug)}} 40 + class="backdrop" 41 + aria-role="presentation" 42 + format="webp" 43 + src={backdrop} 44 + alt="Backdrop" 45 + /> 24 46 </div> 25 - <span>{project.data.summary}</span> 26 - <div class="footer"> 27 - <small>{project.data.tags.join(" • ")}</small> 47 + <div> 48 + <h3 class="project-name">{project.data.name}</h3> 49 + <small>{project.data.tags.join(" • ")}</small> 50 + <p>{project.data.summary}</p> 28 51 </div> 29 - </div> 52 + </article> 30 53 </a> 31 54 32 55 <style> ··· 34 57 text-decoration: none !important; 35 58 } 36 59 37 - div.card { 60 + small { 61 + margin: 0 var(--1); 62 + } 63 + 64 + h3 { 65 + margin: var(--1) var(--1) 0 var(--1); 66 + } 67 + 68 + p { 69 + margin: var(--1); 70 + } 71 + 72 + article { 38 73 display: flex; 39 74 flex-direction: column; 40 75 height: 100%; 41 76 background-color: var(--secondary); 42 - padding: var(--2); 43 - gap: var(--3); 44 77 border-radius: 5px; 45 78 } 46 79 47 - a { 48 - margin: var(--4) 0; 49 - } 50 - 51 - a img { 52 - height: var(--14); 53 - border-radius: var(--2); 54 - } 55 - 56 80 a:hover { 57 81 transform: translateY(calc(var(--1) * -1)); 58 82 transition: transform cubic-bezier(0.68, -0.55, 0.27, 1.55) 0.4s; ··· 62 86 transform: scale(1.06); 63 87 } 64 88 65 - div.header { 89 + span { 90 + flex-grow: 1; 66 91 text-align: center; 67 92 display: flex; 68 - flex-direction: column; 69 - gap: var(--2); 93 + align-items: center; 94 + justify-content: center; 70 95 } 71 96 72 - div.header > div { 97 + div:first-child { 98 + display: flex; 99 + flex-direction: column; 100 + align-items: center; 101 + } 102 + 103 + div { 73 104 overflow: hidden; 74 - width: 100%; 105 + position: relative; 75 106 } 76 107 77 - div.header > strong { 78 - font-size: larger; 79 - } 108 + img, div:first-child { 109 + border-top-left-radius: 5px; 110 + border-top-right-radius: 5px; 111 + } 80 112 81 - div.footer { 82 - text-align: center; 113 + img { 114 + position: relative; 115 + object-fit: contain; 116 + width: 100%; 117 + height: auto; 118 + transition: transform ease-in-out 0.4s; 119 + height: var(--14); 83 120 } 84 121 85 - span { 86 - flex-grow: 1; 87 - text-align: center; 88 - display: flex; 89 - align-items: center; 90 - justify-content: center; 122 + img.thumbnail { 123 + z-index: 2; 91 124 } 92 125 93 - img { 126 + img.backdrop { 127 + position: absolute; 128 + transform: scale(1.1); 129 + inset: 0; 94 130 object-fit: cover; 95 - width: 90%; 96 - transition: transform cubic-bezier(0.68, -0.55, 0.27, 1.55) 0.4s; 131 + filter: blur(6px); 97 132 } 98 133 </style>
+1 -2
src/components/projects/ProjectGrid.astro
··· 42 42 } 43 43 div { 44 44 display: grid; 45 - gap: var(--3); 46 - margin-bottom: calc(var(--4) + var(--2)); 45 + gap: var(--2); 47 46 } 48 47 </style>
+2 -2
src/content/posts/headless_steam_remote_play.md
··· 1 1 --- 2 2 title: Steam Remote Play Headless 3 3 date: 2026-01-17 4 - summary: Using gamescope headless to run Steam remote play 4 + summary: How I'm using gamescope headless to run Steam remote play. 5 5 cowsay: We have Stadia at home 6 6 --- 7 7 ··· 76 76 screen -S steam # Before running gamescope 77 77 ``` 78 78 79 - ## Renicing 79 + ## Re-nicing 80 80 81 81 Finally just renice all gamescope processes because it can start to degrade in performance after a 82 82 while allegedly.
+1 -1
src/content/posts/wip_screen_captures.md
··· 1 1 --- 2 2 title: Work In Progress Friday - Screen Captures 3 3 date: 2024-07-25 4 - summary: An adventure in making scripts to capture screen shots and recordings 4 + summary: An adventure in making scripts to capture screen shots and recordings. 5 5 cowsay: A picture is worth a thousand words 6 6 --- 7 7
+1 -1
src/content/projects/bctc-projects.mdx
··· 23 23 We mainly did Visual Basic .NET + WinForms in our class, however, we also branched 24 24 out into VBA, Python, C++, Java, and more. 25 25 26 - This also contains some Access databases I did for the class as well. 26 + This also contains some Access databases I did for the class as well. I hate Access.
+1 -5
src/content/projects/bingus-bot.mdx
··· 12 12 image: ./bingus-bot.webp 13 13 --- 14 14 15 - Bingus was an idea from an online friend. He utilizes a Markov chain (trained on the chat history of a Discord server) to respond randomly to messages. 16 - 17 - At a high level, Markov chains are very bad autocomplete, think the top three suggested words your phone gives to you when typing as a bot. 18 - 19 - For how simple he is, he provides a lot of fun to the people he chats with. He always has something weird or funny to say! 15 + Bingus was an idea from an online friend. He utilizes a Markov chain (trained on the chat history of a Discord server) to respond randomly to messages. At a high level, Markov chains are very bad autocomplete, think the top three suggested words your phone gives to you when typing as a bot. For how simple he is, he provides a lot of fun to the people he chats with. He always has something weird or funny to say!
+27 -6
src/layouts/Layout.astro
··· 74 74 </head> 75 75 <body id="top"> 76 76 <header class="container"> 77 - <nav class="colrow-lg"> 77 + <nav> 78 78 <a href="/" 79 79 ><Image 80 80 class="nav-icon" ··· 97 97 <main transition:name="main" class="container"> 98 98 <slot /> 99 99 </main> 100 - <footer transition:name="footer" class="container colrow-lg"> 100 + <footer transition:name="footer" class="container"> 101 101 <p> 102 102 <IconLink 103 103 label="Back To Top" ··· 107 107 href="#top" 108 108 /> 109 109 </p> 110 - <p class="copyright">© Ben C 2025</p> 110 + <p class="copyright">© Ben C 2026</p> 111 111 <Socials labelPlacement="top" /> 112 112 </footer> 113 113 </body> ··· 120 120 padding: 0; 121 121 display: flex; 122 122 flex-direction: column; 123 - gap: var(--4); 124 123 min-height: 100vh; 125 124 width: 100vw; 126 125 overflow-x: hidden; ··· 133 132 134 133 nav { 135 134 display: flex; 135 + gap: var(--1); 136 + flex-direction: column; 136 137 align-items: center; 137 - gap: var(--3); 138 138 padding: var(--2) 0; 139 139 } 140 140 141 + nav > :nth-child(3) { 142 + display: none; 143 + } 144 + 145 + @media (width >= 1050px) { 146 + nav { 147 + gap: var(--3); 148 + flex-direction: row; 149 + } 150 + 151 + nav > :nth-child(3) { 152 + display: flex; 153 + } 154 + } 155 + 141 156 nav a { 142 157 text-decoration: none; 143 158 } ··· 172 187 flex-grow: 1; 173 188 } 174 189 190 + footer > p { 191 + margin: var(--1); 192 + } 193 + 175 194 footer { 195 + font-size: var(--2); 176 196 border-top: var(--section-border); 197 + margin-top: var(--4); 177 198 display: flex; 199 + flex-direction: column; 178 200 align-items: center; 179 201 justify-content: center; 180 - gap: var(--2); 181 202 padding: var(--2) 0; 182 203 } 183 204 </style>
+24 -17
src/pages/blog/index.astro
··· 5 5 const blogEntries = await getCollection("posts"); 6 6 7 7 blogEntries.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf()); 8 + 9 + const options = { 10 + weekday: "long", 11 + year: "numeric", 12 + month: "long", 13 + day: "numeric", 14 + }; 8 15 --- 9 16 10 17 <Layout title="The Cowsay - Ben C's Blog"> 11 18 <h1>The Cowsay - Ben C's Blog</h1> 12 - <p>Here you'll find my blog posts, most recent first</p> 19 + <p>Here you'll find my blog posts, most recent first.</p> 13 20 { 14 - blogEntries.map((p, i) => ( 15 - <> 16 - {i === 0 && <hr />} 17 - <div> 18 - <h2> 19 - <a href={`/blog/${p.slug}`}>{p.data.title}</a> 20 - </h2> 21 - <p>{p.data.date.toDateString()}</p> 22 - </div> 21 + blogEntries.map((p) => ( 22 + <article> 23 + <h2> 24 + <a href={`/blog/${p.slug}`}>{p.data.title}</a> 25 + </h2> 26 + <p>{p.data.date.toLocaleDateString(undefined, options)}</p> 23 27 <p> 24 28 {p.data.summary}&nbsp;&nbsp;<a href={`/blog/${p.slug}`}>Read More</a> 25 29 </p> 26 - <hr /> 27 - </> 30 + </article> 28 31 )) 29 32 } 30 33 </Layout> 31 34 32 35 <style> 33 - div h2 { 34 - margin-bottom: var(--1); 36 + article { 37 + margin: var(--4) 0; 35 38 } 36 39 37 - div p { 38 - margin-top: 0; 39 - font-size: var(--3); 40 + article h2 { 41 + margin-bottom: 0; 42 + } 43 + 44 + article p:nth-child(2) { 45 + margin: 0; 46 + font-size: var(--2); 40 47 } 41 48 42 49 h2 > a {
+20 -11
src/pages/index.astro
··· 6 6 --- 7 7 8 8 <Layout title="Ben C's Portfolio" appendTitle={false}> 9 - <div class="hero colrow-lg-rev"> 9 + <div class="hero"> 10 10 <div> 11 11 <h1>Ben C's <span class="gradient-text">Portfolio</span></h1> 12 12 <p> ··· 21 21 development. 22 22 </p> 23 23 <div class="ctas"> 24 - <a href="/projects" role="button" class="primary">View My Projects</a> 25 - <a href="#about-me" role="button" class="secondary">About Me</a> 24 + <a href="/projects" role="button" class="secondary">View My Projects</a> 26 25 </div> 27 26 </div> 28 - <style> 29 - .hide-lg { 30 - display: none; 31 - } 32 - </style> 33 - <div class="hero-image hide-lg"> 27 + <div class="hero-image"> 34 28 <Image width={150} height={150} format="webp" alt="Ben C's Avatar" src={cow} /> 35 29 </div> 36 30 </div> ··· 52 46 <h2>Recent Projects</h2> 53 47 <ProjectGrid limitTo={6} /> 54 48 <div class="view-more"> 55 - <a href="/projects">View All Projects</a> 49 + <a href="/projects" role="button" class="secondary">View All Projects</a> 56 50 </div> 57 51 </Layout> 58 52 ··· 68 62 display: flex; 69 63 flex-wrap: wrap; 70 64 gap: var(--1); 65 + margin: var(--5) 0; 66 + font-weight: bold; 71 67 } 72 68 73 69 @keyframes glow { ··· 81 77 82 78 .hero-image { 83 79 --anim-props: 900ms 500ms cubic-bezier(0.645, 0.045, 0.355, 1) 1 forwards; 84 - display: flex; 80 + display: none; 85 81 align-items: center; 86 82 position: relative; 87 83 animation: glow var(--anim-props); 88 84 border-radius: 50%; 89 85 box-sizing: border-box; 90 86 margin: var(--10); 87 + } 88 + 89 + @media (width >= 1200px) { 90 + .hero-image { 91 + display: flex; 92 + } 91 93 } 92 94 93 95 .hero-image img { ··· 125 127 display: flex; 126 128 justify-content: center; 127 129 width: 100%; 130 + margin-top: var(--4); 131 + } 132 + 133 + .view-more a { 134 + width: 100%; 135 + text-align: center; 136 + font-weight: bold; 128 137 } 129 138 </style>
+25 -8
src/pages/projects/[...slug].astro
··· 25 25 --- 26 26 27 27 <Layout title={entry.data.name} description={entry.data.summary} keywords={entry.data.tags} og={og}> 28 - <div class="hero colrow-lg-rev"> 28 + <div class="hero"> 29 29 <div class="txt"> 30 30 <div class="project-header"> 31 31 <h1 class="gradient-text">{entry.data.name}</h1> ··· 73 73 } 74 74 </div> 75 75 </div> 76 - <div class="colrow-lg-rev img-container"> 76 + <div class="img-container"> 77 77 <Image 78 78 transition:name={`project-img-${entry.slug}`} 79 79 format="webp" ··· 84 84 /> 85 85 </div> 86 86 </div> 87 + <h2>About This Project</h2> 87 88 <Content /> 88 89 </Layout> 89 90 ··· 93 94 } 94 95 95 96 div.project-header p { 96 - font-size: var(--4); 97 - margin-top: 0; 97 + font-size: var(--2); 98 + margin: 0; 98 99 } 99 100 100 101 .hero { ··· 105 106 margin: var(--4) 0; 106 107 } 107 108 108 - @media (width <= 575px) { 109 + @media (width <= 1300px) { 109 110 .hero { 110 111 flex-direction: column-reverse; 112 + margin-top: var(--1); 113 + gap: var(--2); 114 + text-align: center; 115 + } 116 + 117 + .links, .ctas { 118 + margin: auto; 119 + } 120 + 121 + .hero p { 122 + margin: 0; 123 + } 124 + 125 + div.project-header h1 { 126 + margin-top: 0; 111 127 } 112 128 } 113 129 ··· 141 157 } 142 158 143 159 .hero .img-container img { 144 - border-radius: var(--2); 145 - width: 100%; 146 - object-fit: contain; 160 + border-radius: 5px; 161 + max-width: 100%; 162 + height: auto; 163 + margin: auto; 147 164 } 148 165 149 166 .links {
+321 -362
src/styles/style.css
··· 1 + /* Breakpoint Queries, Using Bootstrap's */ 2 + 3 + /* Smallest: 576px */ 4 + 5 + @custom-media --sm (width >=576px); 6 + @custom-media --md (width >=768px); 7 + @custom-media --lg (width >=1200px); 8 + @custom-media --xl (width >=1700px); 9 + 10 + .container { 11 + --gutter: var(--2); 12 + margin: 0 var(--gutter); 13 + } 14 + 15 + @media (--md) { 16 + .container { 17 + --gutter: var(--10); 18 + } 19 + } 20 + 21 + @media (--xl) { 22 + .container { 23 + --gutter: var(--14); 24 + } 25 + } 26 + 1 27 /* Color Definitions */ 2 28 :root { 3 - --text: #daf1ef; 4 - --background: #080609; 5 - --primary: #53d164; 6 - --secondary: #012d1e; 7 - --accent: #0ee19b; 29 + --text: #daf1ef; 30 + --background: #080609; 31 + --primary: #53d164; 32 + --secondary: #012d1e; 33 + --accent: #0ee19b; 8 34 9 - --text-50: #edf8f7; 10 - --text-100: #daf1ef; 11 - --text-200: #b5e3df; 12 - --text-300: #90d5cf; 13 - --text-400: #6bc7bf; 14 - --text-500: #46b9af; 15 - --text-600: #38948c; 16 - --text-700: #2a6f69; 17 - --text-800: #1c4a46; 18 - --text-900: #0e2523; 19 - --text-950: #071212; 35 + --text-50: #edf8f7; 36 + --text-100: #daf1ef; 37 + --text-200: #b5e3df; 38 + --text-300: #90d5cf; 39 + --text-400: #6bc7bf; 40 + --text-500: #46b9af; 41 + --text-600: #38948c; 42 + --text-700: #2a6f69; 43 + --text-800: #1c4a46; 44 + --text-900: #0e2523; 45 + --text-950: #071212; 20 46 21 - --background-50: #f3f0f5; 22 - --background-100: #e7e0eb; 23 - --background-200: #cfc2d6; 24 - --background-300: #b8a3c2; 25 - --background-400: #a085ad; 26 - --background-500: #886699; 27 - --background-600: #6d527a; 28 - --background-700: #523d5c; 29 - --background-800: #36293d; 30 - --background-900: #1b141f; 31 - --background-950: #0e0a0f; 47 + --background-50: #f3f0f5; 48 + --background-100: #e7e0eb; 49 + --background-200: #cfc2d6; 50 + --background-300: #b8a3c2; 51 + --background-400: #a085ad; 52 + --background-500: #886699; 53 + --background-600: #6d527a; 54 + --background-700: #523d5c; 55 + --background-800: #36293d; 56 + --background-900: #1b141f; 57 + --background-950: #0e0a0f; 32 58 33 - --primary-50: #ebfaed; 34 - --primary-100: #d7f4db; 35 - --primary-200: #aeeab6; 36 - --primary-300: #86df92; 37 - --primary-400: #5ed46e; 38 - --primary-500: #36c949; 39 - --primary-600: #2ba13b; 40 - --primary-700: #20792c; 41 - --primary-800: #15511d; 42 - --primary-900: #0b280f; 43 - --primary-950: #051407; 59 + --primary-50: #ebfaed; 60 + --primary-100: #d7f4db; 61 + --primary-200: #aeeab6; 62 + --primary-300: #86df92; 63 + --primary-400: #5ed46e; 64 + --primary-500: #36c949; 65 + --primary-600: #2ba13b; 66 + --primary-700: #20792c; 67 + --primary-800: #15511d; 68 + --primary-900: #0b280f; 69 + --primary-950: #051407; 44 70 45 - --secondary-50: #e6fef6; 46 - --secondary-100: #cdfeee; 47 - --secondary-200: #9bfddc; 48 - --secondary-300: #69fccb; 49 - --secondary-400: #37fbba; 50 - --secondary-500: #05faa8; 51 - --secondary-600: #04c887; 52 - --secondary-700: #039665; 53 - --secondary-800: #026443; 54 - --secondary-900: #013222; 55 - --secondary-950: #011911; 71 + --secondary-50: #e6fef6; 72 + --secondary-100: #cdfeee; 73 + --secondary-200: #9bfddc; 74 + --secondary-300: #69fccb; 75 + --secondary-400: #37fbba; 76 + --secondary-500: #05faa8; 77 + --secondary-600: #04c887; 78 + --secondary-700: #039665; 79 + --secondary-800: #026443; 80 + --secondary-900: #013222; 81 + --secondary-950: #011911; 56 82 57 - --accent-50: #e7fdf6; 58 - --accent-100: #cffced; 59 - --accent-200: #9ff9db; 60 - --accent-300: #6ff6c9; 61 - --accent-400: #3ff3b7; 62 - --accent-500: #0ff0a5; 63 - --accent-600: #0cc084; 64 - --accent-700: #099063; 65 - --accent-800: #066042; 66 - --accent-900: #033021; 67 - --accent-950: #021810; 83 + --accent-50: #e7fdf6; 84 + --accent-100: #cffced; 85 + --accent-200: #9ff9db; 86 + --accent-300: #6ff6c9; 87 + --accent-400: #3ff3b7; 88 + --accent-500: #0ff0a5; 89 + --accent-600: #0cc084; 90 + --accent-700: #099063; 91 + --accent-800: #066042; 92 + --accent-900: #033021; 93 + --accent-950: #021810; 68 94 } 69 95 70 96 /* Color Aliases */ 71 97 72 98 /* Spacing Scale, Major Third */ 73 99 :root { 74 - /* 1rem = 16px */ 75 - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 76 - font-size: 125%; 77 - --scale: 1.25; 78 - --small: calc(1rem * pow(var(--scale), -1)); 79 - --half: calc(1rem * pow(var(--scale), -0.5)); 80 - --1: calc(1rem * pow(var(--scale), 0)); 81 - --2: calc(1rem * pow(var(--scale), 1)); 82 - --3: calc(1rem * pow(var(--scale), 2)); 83 - --4: calc(1rem * pow(var(--scale), 3)); 84 - --5: calc(1rem * pow(var(--scale), 4)); 85 - --6: calc(1rem * pow(var(--scale), 5)); 86 - --7: calc(1rem * pow(var(--scale), 6)); 87 - --8: calc(1rem * pow(var(--scale), 7)); 88 - --9: calc(1rem * pow(var(--scale), 8)); 89 - --10: calc(1rem * pow(var(--scale), 9)); 90 - --11: calc(1rem * pow(var(--scale), 10)); 91 - --12: calc(1rem * pow(var(--scale), 11)); 92 - --14: calc(1rem * pow(var(--scale), 13)); 93 - --component-padding: var(--small) var(--1); 100 + /* 1rem = 16px */ 101 + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 102 + font-size: 125%; 103 + --scale: 1.25; 104 + --small: calc(1rem * pow(var(--scale), -1)); 105 + --half: calc(1rem * pow(var(--scale), -0.5)); 106 + --1: calc(1rem * pow(var(--scale), 0)); 107 + --2: calc(1rem * pow(var(--scale), 1)); 108 + --3: calc(1rem * pow(var(--scale), 2)); 109 + --4: calc(1rem * pow(var(--scale), 3)); 110 + --5: calc(1rem * pow(var(--scale), 4)); 111 + --6: calc(1rem * pow(var(--scale), 5)); 112 + --7: calc(1rem * pow(var(--scale), 6)); 113 + --8: calc(1rem * pow(var(--scale), 7)); 114 + --9: calc(1rem * pow(var(--scale), 8)); 115 + --10: calc(1rem * pow(var(--scale), 9)); 116 + --11: calc(1rem * pow(var(--scale), 10)); 117 + --12: calc(1rem * pow(var(--scale), 11)); 118 + --14: calc(1rem * pow(var(--scale), 13)); 119 + --component-padding: var(--small) var(--1); 94 120 } 95 121 96 122 /* Element Defaults */ 97 123 98 124 small { 99 - font-size: var(--small); 100 - color: var(--text-disabled); 125 + font-size: var(--small); 126 + color: var(--text-disabled); 101 127 } 102 128 103 129 h1 { 104 - font-size: var(--5); 130 + font-size: var(--5); 105 131 } 106 132 107 133 h2 { 108 - font-size: var(--4); 134 + font-size: var(--4); 109 135 } 110 136 111 137 h3 { 112 - font-size: var(--3); 138 + font-size: var(--3); 113 139 } 114 140 115 141 h4 { 116 - font-size: var(--2); 142 + font-size: var(--2); 117 143 } 118 144 119 145 h5 { 120 - font-size: var(--1); 146 + font-size: var(--1); 121 147 } 122 148 123 149 body { 124 - color: var(--text); 125 - background-color: var(--background); 150 + color: var(--text); 151 + background-color: var(--background); 126 152 } 127 153 128 154 a { 129 - color: var(--accent-600); 155 + color: var(--accent-600); 130 156 } 131 157 132 158 button, 133 159 button.primary, 134 160 [role="button"] { 135 - --bg: var(--primary-400); 136 - --hover-bg: var(--primary-500); 137 - --active-bg: var(--primary-300); 138 - --disabled-bg: var(--primary-600); 161 + --bg: var(--primary-400); 162 + --hover-bg: var(--primary-500); 163 + --active-bg: var(--primary-300); 164 + --disabled-bg: var(--primary-600); 139 165 140 - padding: var(--component-padding); 141 - color: var(--text); 142 - border-radius: var(--1); 143 - border: solid 2px transparent; 144 - background-color: var(--bg); 145 - cursor: pointer; 146 - transition: background-color 100ms linear; 147 - color: var(--background-800); 148 - text-decoration: none; 166 + padding: var(--component-padding); 167 + color: var(--text); 168 + border-radius: 10px; 169 + border: solid 2px transparent; 170 + background-color: var(--bg); 171 + cursor: pointer; 172 + transition: background-color 100ms linear; 173 + color: var(--background-800); 174 + text-decoration: none; 149 175 } 150 176 151 177 button.secondary, 152 178 .secondary[role="button"] { 153 - --bg: var(--secondary-500); 154 - --hover-bg: var(--secondary-400); 155 - --active-bg: var(--secondary-600); 156 - --disabled-bg: var(--secondary-700); 179 + --bg: var(--secondary-500); 180 + --hover-bg: var(--secondary-400); 181 + --active-bg: var(--secondary-600); 182 + --disabled-bg: var(--secondary-700); 157 183 } 158 184 159 185 button.accent, 160 186 .accent[role="button"] { 161 - --bg: var(--accent-400); 162 - --hover-bg: var(--accent-500); 163 - --active-bg: var(--accent-300); 164 - --disabled-bg: var(--accent-600); 187 + --bg: var(--accent-400); 188 + --hover-bg: var(--accent-500); 189 + --active-bg: var(--accent-300); 190 + --disabled-bg: var(--accent-600); 165 191 } 166 192 167 193 button:active, 168 194 [role="button"]:active { 169 - background-color: var(--active-bg); 195 + background-color: var(--active-bg); 170 196 } 171 197 172 198 button:hover, 173 199 [role="button"]:hover { 174 - background-color: var(--hover-bg); 200 + background-color: var(--hover-bg); 175 201 } 176 202 177 203 button:disabled, 178 204 [role="button"]:disabled { 179 - background-color: var(--disabled-bg); 180 - color: var(--text-disabled); 205 + background-color: var(--disabled-bg); 206 + color: var(--text-disabled); 181 207 } 182 208 183 209 button:disabled:hover, 184 210 [role="button"]:disabled:hover { 185 - cursor: default; 211 + cursor: default; 186 212 } 187 213 188 214 input { 189 - padding: var(--component-padding); 190 - color: var(--text); 191 - border-radius: var(--1); 192 - border: solid 2px var(--accent-200); 193 - background-color: var(--background-raised); 215 + padding: var(--component-padding); 216 + color: var(--text); 217 + border-radius: var(--1); 218 + border: solid 2px var(--accent-200); 219 + background-color: var(--background-raised); 194 220 } 195 221 196 222 body { 197 - font-weight: 400; 223 + font-weight: 400; 198 224 } 199 225 200 226 h1, ··· 202 228 h3, 203 229 h4, 204 230 h5 { 205 - font-weight: 700; 231 + font-weight: 700; 206 232 } 207 233 208 - /* Breakpoint Queries, Using Bootstrap's */ 209 234 210 - /* Smallest: 576px */ 211 - 212 - @custom-media --sm (width >=576px); 213 - @custom-media --md (width >=768px); 214 - @custom-media --lg (width >=1200px); 215 - @custom-media --xl (width >=1700px); 216 - 217 - .container { 218 - --gutter: var(--2); 219 - margin: 0 var(--gutter); 235 + .gradient-text { 236 + background: linear-gradient(120deg, var(--primary), var(--accent) 70%); 237 + background-clip: text; 238 + -webkit-background-clip: text; 239 + -webkit-text-fill-color: transparent; 220 240 } 221 241 222 - @media (--md) { 223 - .container { 224 - --gutter: var(--10); 225 - } 226 - } 227 242 228 - @media (--xl) { 229 - .container { 230 - --gutter: var(--14); 231 - } 232 - } 233 243 234 - .colrow-sm { 235 - flex-direction: column !important; 236 - } 244 + /* Tooltips */ 245 + [data-tooltip] { 246 + position: relative; 237 247 238 - @media (--sm) { 239 - .colrow-sm { 240 - flex-direction: row !important; 241 - } 242 - } 248 + &[data-placement="top"]::before, 249 + &[data-placement="top"]::after, 250 + &::before, 251 + &::after { 252 + display: block; 253 + z-index: 99; 254 + position: absolute; 255 + bottom: 100%; 256 + left: 50%; 257 + padding: 0.25rem 0.5rem; 258 + overflow: hidden; 259 + transform: translate(-50%, -0.25rem); 260 + border-radius: 5px; 261 + background: var(--accent-800); 262 + content: attr(data-tooltip); 263 + color: var(--text); 264 + font-style: normal; 265 + font-size: 0.875rem; 266 + text-decoration: none; 267 + text-overflow: ellipsis; 268 + white-space: nowrap; 269 + opacity: 0; 270 + pointer-events: none; 271 + } 243 272 244 - .colrow-md { 245 - flex-direction: column !important; 246 - } 273 + &[data-placement="top"]::after, 274 + &::after { 275 + padding: 0; 276 + transform: translate(-50%, 0rem); 277 + border-top: 0.3rem solid; 278 + border-right: 0.3rem solid transparent; 279 + border-left: 0.3rem solid transparent; 280 + border-radius: 0; 281 + background-color: transparent; 282 + content: ""; 283 + color: var(--accent-800); 284 + } 247 285 248 - @media (--md) { 249 - .colrow-md { 250 - flex-direction: row !important; 251 - } 252 - } 286 + &[data-placement="bottom"] { 253 287 254 - .colrow-xl { 255 - display: flex; 256 - flex-direction: column !important; 257 - } 288 + &::before, 289 + &::after { 290 + top: 100%; 291 + bottom: auto; 292 + transform: translate(-50%, 0.25rem); 293 + } 258 294 259 - @media (--xl) { 260 - .colrow-xl { 261 - flex-direction: row-reverse !important; 262 - } 263 - } 295 + &:after { 296 + transform: translate(-50%, -0.3rem); 297 + border: 0.3rem solid transparent; 298 + border-bottom: 0.3rem solid; 299 + } 300 + } 264 301 265 - .gradient-text { 266 - background: linear-gradient(120deg, var(--primary), var(--accent) 70%); 267 - background-clip: text; 268 - -webkit-background-clip: text; 269 - -webkit-text-fill-color: transparent; 270 - } 302 + &[data-placement="left"] { 271 303 272 - .colrow-lg { 273 - display: flex; 274 - flex-direction: column; 275 - } 304 + &::before, 305 + &::after { 306 + top: 50%; 307 + right: 100%; 308 + bottom: auto; 309 + left: auto; 310 + transform: translate(-0.25rem, -50%); 311 + } 276 312 277 - .colrow-lg-rev { 278 - display: flex; 279 - flex-direction: column-reverse; 280 - } 313 + &:after { 314 + transform: translate(0.3rem, -50%); 315 + border: 0.3rem solid transparent; 316 + border-left: 0.3rem solid; 317 + } 318 + } 281 319 282 - .hide-lg { 283 - display: none !important; 284 - } 320 + &[data-placement="right"] { 285 321 286 - @media (--lg) { 287 - .colrow-lg-rev, 288 - .colrow-lg { 289 - flex-direction: row; 290 - } 322 + &::before, 323 + &::after { 324 + top: 50%; 325 + right: auto; 326 + bottom: auto; 327 + left: 100%; 328 + transform: translate(0.25rem, -50%); 329 + } 291 330 292 - .hide-lg { 293 - display: flex !important; 294 - } 295 - } 331 + &:after { 332 + transform: translate(-0.3rem, -50%); 333 + border: 0.3rem solid transparent; 334 + border-right: 0.3rem solid; 335 + } 336 + } 296 337 297 - /* Tooltips */ 298 - [data-tooltip] { 299 - position: relative; 338 + &:focus, 339 + &:hover { 300 340 301 - &[data-placement="top"]::before, 302 - &[data-placement="top"]::after, 303 - &::before, 304 - &::after { 305 - display: block; 306 - z-index: 99; 307 - position: absolute; 308 - bottom: 100%; 309 - left: 50%; 310 - padding: 0.25rem 0.5rem; 311 - overflow: hidden; 312 - transform: translate(-50%, -0.25rem); 313 - border-radius: var(--2); 314 - background: var(--accent-800); 315 - content: attr(data-tooltip); 316 - color: var(--text); 317 - font-style: normal; 318 - font-size: 0.875rem; 319 - text-decoration: none; 320 - text-overflow: ellipsis; 321 - white-space: nowrap; 322 - opacity: 0; 323 - pointer-events: none; 324 - } 341 + &::before, 342 + &::after { 343 + opacity: 1; 344 + } 345 + } 325 346 326 - &[data-placement="top"]::after, 327 - &::after { 328 - padding: 0; 329 - transform: translate(-50%, 0rem); 330 - border-top: 0.3rem solid; 331 - border-right: 0.3rem solid transparent; 332 - border-left: 0.3rem solid transparent; 333 - border-radius: 0; 334 - background-color: transparent; 335 - content: ""; 336 - color: var(--accent-800); 337 - } 347 + @media (hover: hover) and (pointer: fine) { 338 348 339 - &[data-placement="bottom"] { 340 - &::before, 341 - &::after { 342 - top: 100%; 343 - bottom: auto; 344 - transform: translate(-50%, 0.25rem); 345 - } 349 + &:focus, 350 + &:hover { 346 351 347 - &:after { 348 - transform: translate(-50%, -0.3rem); 349 - border: 0.3rem solid transparent; 350 - border-bottom: 0.3rem solid; 351 - } 352 - } 352 + &::before, 353 + &::after { 354 + --tooltip-slide-to: translate(-50%, -0.25rem); 355 + transform: translate(-50%, 0.75rem); 356 + animation-duration: 0.2s; 357 + animation-fill-mode: forwards; 358 + animation-name: tooltip-slide; 359 + opacity: 0; 360 + } 353 361 354 - &[data-placement="left"] { 355 - &::before, 356 - &::after { 357 - top: 50%; 358 - right: 100%; 359 - bottom: auto; 360 - left: auto; 361 - transform: translate(-0.25rem, -50%); 362 - } 362 + &::after { 363 + --tooltip-caret-slide-to: translate(-50%, 0rem); 364 + transform: translate(-50%, -0.25rem); 365 + animation-name: tooltip-caret-slide; 366 + } 367 + } 363 368 364 - &:after { 365 - transform: translate(0.3rem, -50%); 366 - border: 0.3rem solid transparent; 367 - border-left: 0.3rem solid; 368 - } 369 - } 369 + &[data-placement="bottom"] { 370 370 371 - &[data-placement="right"] { 372 - &::before, 373 - &::after { 374 - top: 50%; 375 - right: auto; 376 - bottom: auto; 377 - left: 100%; 378 - transform: translate(0.25rem, -50%); 379 - } 371 + &:focus, 372 + &:hover { 380 373 381 - &:after { 382 - transform: translate(-0.3rem, -50%); 383 - border: 0.3rem solid transparent; 384 - border-right: 0.3rem solid; 385 - } 386 - } 374 + &::before, 375 + &::after { 376 + --tooltip-slide-to: translate(-50%, 0.25rem); 377 + transform: translate(-50%, -0.75rem); 378 + animation-name: tooltip-slide; 379 + } 387 380 388 - &:focus, 389 - &:hover { 390 - &::before, 391 - &::after { 392 - opacity: 1; 393 - } 394 - } 381 + &::after { 382 + --tooltip-caret-slide-to: translate(-50%, -0.3rem); 383 + transform: translate(-50%, -0.5rem); 384 + animation-name: tooltip-caret-slide; 385 + } 386 + } 387 + } 395 388 396 - @media (hover: hover) and (pointer: fine) { 397 - &:focus, 398 - &:hover { 399 - &::before, 400 - &::after { 401 - --tooltip-slide-to: translate(-50%, -0.25rem); 402 - transform: translate(-50%, 0.75rem); 403 - animation-duration: 0.2s; 404 - animation-fill-mode: forwards; 405 - animation-name: tooltip-slide; 406 - opacity: 0; 407 - } 389 + &[data-placement="left"] { 408 390 409 - &::after { 410 - --tooltip-caret-slide-to: translate(-50%, 0rem); 411 - transform: translate(-50%, -0.25rem); 412 - animation-name: tooltip-caret-slide; 413 - } 414 - } 391 + &:focus, 392 + &:hover { 415 393 416 - &[data-placement="bottom"] { 417 - &:focus, 418 - &:hover { 419 - &::before, 420 - &::after { 421 - --tooltip-slide-to: translate(-50%, 0.25rem); 422 - transform: translate(-50%, -0.75rem); 423 - animation-name: tooltip-slide; 424 - } 394 + &::before, 395 + &::after { 396 + --tooltip-slide-to: translate(-0.25rem, -50%); 397 + transform: translate(0.75rem, -50%); 398 + animation-name: tooltip-slide; 399 + } 425 400 426 - &::after { 427 - --tooltip-caret-slide-to: translate(-50%, -0.3rem); 428 - transform: translate(-50%, -0.5rem); 429 - animation-name: tooltip-caret-slide; 430 - } 431 - } 432 - } 401 + &::after { 402 + --tooltip-caret-slide-to: translate(0.3rem, -50%); 403 + transform: translate(0.05rem, -50%); 404 + animation-name: tooltip-caret-slide; 405 + } 406 + } 407 + } 433 408 434 - &[data-placement="left"] { 435 - &:focus, 436 - &:hover { 437 - &::before, 438 - &::after { 439 - --tooltip-slide-to: translate(-0.25rem, -50%); 440 - transform: translate(0.75rem, -50%); 441 - animation-name: tooltip-slide; 442 - } 409 + &[data-placement="right"] { 443 410 444 - &::after { 445 - --tooltip-caret-slide-to: translate(0.3rem, -50%); 446 - transform: translate(0.05rem, -50%); 447 - animation-name: tooltip-caret-slide; 448 - } 449 - } 450 - } 411 + &:focus, 412 + &:hover { 451 413 452 - &[data-placement="right"] { 453 - &:focus, 454 - &:hover { 455 - &::before, 456 - &::after { 457 - --tooltip-slide-to: translate(0.25rem, -50%); 458 - transform: translate(-0.75rem, -50%); 459 - animation-name: tooltip-slide; 460 - } 414 + &::before, 415 + &::after { 416 + --tooltip-slide-to: translate(0.25rem, -50%); 417 + transform: translate(-0.75rem, -50%); 418 + animation-name: tooltip-slide; 419 + } 461 420 462 - &::after { 463 - --tooltip-caret-slide-to: translate(-0.3rem, -50%); 464 - transform: translate(-0.05rem, -50%); 465 - animation-name: tooltip-caret-slide; 466 - } 467 - } 468 - } 469 - } 421 + &::after { 422 + --tooltip-caret-slide-to: translate(-0.3rem, -50%); 423 + transform: translate(-0.05rem, -50%); 424 + animation-name: tooltip-caret-slide; 425 + } 426 + } 427 + } 428 + } 470 429 } 471 430 472 431 @keyframes tooltip-slide { 473 - to { 474 - transform: var(--tooltip-slide-to); 475 - opacity: 1; 476 - } 432 + to { 433 + transform: var(--tooltip-slide-to); 434 + opacity: 1; 435 + } 477 436 } 478 437 479 438 @keyframes tooltip-caret-slide { 480 - 50% { 481 - opacity: 0; 482 - } 439 + 50% { 440 + opacity: 0; 441 + } 483 442 484 - to { 485 - transform: var(--tooltip-caret-slide-to); 486 - opacity: 1; 487 - } 443 + to { 444 + transform: var(--tooltip-caret-slide-to); 445 + opacity: 1; 446 + } 488 447 }