Personal site staging.colinozanne.co.uk
portfolio astro

fix: theme

finxol.io 1c44bb7b 187392d9

verified
+98 -45
+4 -4
src/assets/styles/index.css
··· 26 26 gap: 1rem; 27 27 margin-inline: calc(var(--spacing) * 2); 28 28 margin-block: calc(var(--spacing) * 3) calc(var(--spacing) * 2); 29 - color: var(--primary-text); 29 + color: var(--foreground); 30 30 31 31 @media screen and (max-width: 768px) { 32 32 flex-direction: column; ··· 78 78 } 79 79 80 80 & > div.container { 81 - --container-color: var(--intro-container); 81 + --container-color: var(--secondary); 82 82 } 83 83 } 84 84 ··· 124 124 125 125 &.contact { 126 126 grid-area: contact; 127 - --container-color: var(--primary-muted); 127 + --container-color: var(--primary); 128 128 129 129 & > aside { 130 130 display: flex; ··· 157 157 justify-content: start; 158 158 text-decoration: none; 159 159 margin: 0; 160 - background-color: var(--primary); 160 + background-color: oklch(from var(--primary) 0.85 c h / 0.8); 161 161 padding: 1rem 0.5rem; 162 162 border-radius: var(--radius); 163 163 font-size: var(--size-0);
+36 -19
src/assets/styles/main.css
··· 60 60 --link: var(--amber-500); 61 61 --link-text: var(--amber-950); 62 62 63 - --background: var(--sand-50); 63 + --background: var(--fuchsia-100); 64 + --foreground: var(--fuchsia-950); 64 65 65 66 --name-color: var(--fuchsia-500); 66 67 --name-color-text: var(--fuchsia-950); 67 - --lang-bg: var(--fuchsia-100); 68 + --lang-bg: var(--fuchsia-200); 68 69 --lang: var(--fuchsia-200); 69 70 --lang-hover: var(--fuchsia-300); 70 71 --lang-active: var(--fuchsia-400); ··· 74 75 --intro-container: var(--rose-400); 75 76 --blog-container: var(--yellow-400); 76 77 78 + /* Project colors */ 79 + --project-1: var(--sky-400); 80 + --project-1-text: var(--sky-950); 81 + --project-2: var(--fuchsia-400); 82 + --project-2-text: var(--fuchsia-950); 83 + --project-3: var(--amber-400); 84 + --project-3-text: var(--amber-950); 85 + 77 86 &[data-theme="dark"] { 78 - --primary: var(--fuchsia-600); 79 - --primary-text: var(--fuchsia-100); 80 - --primary-muted: var(--fuchsia-700); 87 + --primary: var(--fuchsia-500); 88 + --primary-text: var(--fuchsia-950); 81 89 82 - --secondary: var(--sky-600); 83 - --secondary-text: var(--sky-100); 90 + --secondary: var(--sky-500); 91 + --secondary-text: var(--sky-950); 84 92 85 - --accent: var(--teal-600); 86 - --accent-text: var(--teal-100); 93 + --accent: var(--amber-500); 94 + --accent-text: var(--amber-950); 87 95 88 - --link: var(--amber-400); 89 - --link-text: var(--amber-100); 96 + --link: var(--amber-500); 97 + --link-text: var(--amber-950); 90 98 91 - --background: var(--sand-950); 99 + --background: var(--fuchsia-900); 100 + --foreground: var(--fuchsia-100); 92 101 93 - --name-color: var(--fuchsia-400); 102 + --name-color: var(--fuchsia-800); 94 103 --name-color-text: var(--fuchsia-100); 95 - --lang-bg: var(--fuchsia-900); 104 + --lang-bg: var(--fuchsia-800); 96 105 --lang: var(--fuchsia-800); 97 106 --lang-hover: var(--fuchsia-700); 98 107 --lang-active: var(--fuchsia-600); 99 - --lang-active-text: var(--fuchsia-100); 108 + --lang-active-text: var(--fuchsia-950); 100 109 --lang-text: var(--fuchsia-200); 101 110 102 - --intro-container: var(--rose-600); 103 - --blog-container: var(--yellow-600); 111 + --intro-container: var(--sky-600); 112 + --blog-container: var(--amber-500); 113 + 114 + /* Project colors */ 115 + --project-1: var(--sky-500); 116 + --project-1-text: var(--sky-950); 117 + --project-2: var(--fuchsia-500); 118 + --project-2-text: var(--fuchsia-950); 119 + --project-3: var(--amber-500); 120 + --project-3-text: var(--amber-950); 104 121 } 105 122 } 106 123 ··· 137 154 padding: var(--spacing); 138 155 width: calc(100% - 2rem * var(--spacing)); 139 156 border-radius: var(--radius); 140 - color: var(--container-text-color, var(--emerald-950, black)); 141 - background-color: var(--container-color, var(--emerald-500, red)); 157 + color: var(--container-text-color, var(--primary-text)); 158 + background-color: var(--container-color, var(--primary)); 142 159 } 143 160 144 161 @media (max-width: 768px) {
+47 -16
src/components/customise.astro
··· 19 19 </p> 20 20 21 21 <section> 22 - <button id="light-button">Light</button> 23 - <button id="dark-button">Dark</button> 22 + <button id="light-button"> 23 + <Icon name="pixel:sun" /> 24 + Light 25 + </button> 26 + <button id="dark-button"> 27 + <Icon name="pixel:moon" /> 28 + Dark 29 + </button> 24 30 </section> 25 31 </div> 26 32 </aside> 27 33 28 34 <script> 35 + const store = new Proxy(document.documentElement.dataset, { 36 + set(target, key: string, value: string | null) { 37 + if (value === null) { 38 + delete target[key]; 39 + localStorage.removeItem(key); 40 + } else { 41 + target[key] = value; 42 + localStorage.setItem(key, value); 43 + } 44 + return true; 45 + }, 46 + get(target, key: string) { 47 + const item = target[key]; 48 + if (item) return item; 49 + 50 + const v = localStorage.getItem(key) ?? "light"; 51 + store[key] = v; 52 + 53 + return v; 54 + }, 55 + }); 56 + 29 57 const lightButton = document.getElementById("light-button")!; 30 58 const darkButton = document.getElementById("dark-button")!; 31 59 32 60 lightButton.addEventListener("click", () => { 33 - document.documentElement.dataset.theme = "light"; 34 - localStorage.setItem("theme", "light"); 61 + store.theme = "light"; 35 62 }); 36 63 37 64 darkButton.addEventListener("click", () => { 38 - document.documentElement.dataset.theme = "dark"; 39 - localStorage.setItem("theme", "dark"); 65 + store.theme = "dark"; 40 66 }); 41 67 42 68 window.onload = () => { 43 - const theme = localStorage.getItem("theme"); 44 - if (theme) { 45 - document.documentElement.dataset.theme = theme; 46 - } else { 47 - document.documentElement.dataset.theme = "light"; 48 - localStorage.setItem("theme", "light"); 49 - } 69 + // to trigger the theme change 70 + store.theme; 50 71 }; 51 72 </script> 52 73 53 74 <style> 54 75 button.customise-trigger { 55 - --container-color: var(--fuchsia-500); 76 + --container-color: var(--primary); 56 77 57 78 display: flex; 58 79 flex-direction: column; ··· 68 89 69 90 @keyframes rainbow { 70 91 0% { 71 - background-color: var(--red-600); 92 + background-color: var(--rose-600); 72 93 } 73 94 100% { 74 95 background-color: var(--fuchsia-600); ··· 91 112 92 113 opacity: 1; 93 114 background-color: var(--background); 94 - color: var(--primary-text); 115 + color: var(--foreground); 95 116 border: 1px solid var(--primary-muted); 96 117 border-radius: 0.5rem; 97 118 box-shadow: 0 0 10px oklch(from var(--fuchsia-900) l c h / 0.1); ··· 151 172 152 173 &:hover { 153 174 background-color: var(--primary-muted); 175 + animation: spin 0.5s cubic-bezier(0.86, 0, 0.07, 1); 154 176 } 155 177 156 178 :where(html:not([data-theme]), html[data-theme="light"]) ··· 163 185 } 164 186 } 165 187 } 188 + } 189 + } 190 + 191 + @keyframes spin { 192 + from { 193 + transform: rotate(0deg); 194 + } 195 + to { 196 + transform: rotate(360deg); 166 197 } 167 198 } 168 199 </style>
+1 -1
src/components/pages/index.astro
··· 161 161 <div 162 162 class="project" 163 163 {...(project.colour && { 164 - style: `--container-color: var(${project.colour});`, 164 + style: `--container-color: var(${project.colour}); --container-text-color: var(${project.colour}-text);`, 165 165 })} 166 166 > 167 167 <picture
+1 -1
src/components/pages/project.astro
··· 44 44 <div 45 45 class="boxes" 46 46 {...project.colour && { 47 - style: `--container-color: var(${project.colour});`, 47 + style: `--container-color: var(${project.colour}); --container-text-color: var(${project.colour}-text);`, 48 48 }} 49 49 > 50 50 <picture
+5 -4
src/data/projects.ts
··· 50 50 webp: fareWebp, 51 51 }, 52 52 tags: ["Next.js", "Supabase", "Dokploy"], 53 - colour: "--indigo-300", 53 + colour: "--project-1", 54 54 startDate: new Date("10 December 2025"), 55 55 runtime: "NextJs", 56 56 runtimeIcon: "tabler:brand-nextjs", ··· 72 72 webp: karrWebp, 73 73 }, 74 74 tags: ["Next.js", "Hono", "OpenAuth", "CI"], 75 + colour: "--project-2", 75 76 startDate: new Date("10 October 2024"), 76 77 runtime: "NodeJS", 77 78 runtimeIcon: "tabler:brand-nodejs", ··· 94 95 webp: blogWebp, 95 96 }, 96 97 tags: ["Nuxt.js", "Markdown"], 97 - colour: "--yellow-300", 98 + colour: "--project-3", 98 99 startDate: new Date("24 April 2022"), 99 100 runtime: "Deno", 100 101 runtimeIcon: "tabler:brand-deno", ··· 116 117 webp: recaroPitchWebp, 117 118 }, 118 119 tags: ["Vue.js", "Three.js"], 119 - colour: "--indigo-300", 120 + colour: "--project-1", 120 121 startDate: new Date("29 May 2023"), 121 122 endDate: new Date("4 August 2023"), 122 123 runtime: "Vue.js", ··· 139 140 webp: travelBlogWebp, 140 141 }, 141 142 tags: ["Ghost"], 142 - colour: "--indigo-300", 143 + colour: "--project-2", 143 144 startDate: new Date("29 May 2023"), 144 145 runtime: "Ghost", 145 146 runtimeIcon: "tabler:writing-sign",
+4
src/layouts/Layout.astro
··· 162 162 } 163 163 } 164 164 165 + html { 166 + background-color: var(--background); 167 + } 168 + 165 169 body { 166 170 font-family: "Scorekard", sans-serif; 167 171 container: body / inline-size;