Refactor as SSG using Vite+React
5
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
|||
.idea/
|
||||
.vscode/
|
||||
|
||||
# Built files
|
||||
out/
|
||||
node_modules/
|
||||
dist/
|
||||
|
|
5
.prettierrc.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"useTabs": true,
|
||||
"htmlWhitespaceSensitivity": "ignore",
|
||||
"printWidth": 120
|
||||
}
|
23
build.sh
|
@ -1,23 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
build_dir="out"
|
||||
assets_dir="assets"
|
||||
|
||||
mkdir -p "$build_dir"
|
||||
minify -o "$build_dir" index.html style.css
|
||||
cp -r "$assets_dir" "$build_dir"/
|
||||
|
||||
for file in "$assets_dir"/*; do
|
||||
file_basename="$(basename "$file")"
|
||||
file_name="${file_basename%%.*}"
|
||||
file_extension="${file_basename#*.}"
|
||||
printf "%s ->" "$file_basename"
|
||||
for format in png jpeg webp jxl avif heic; do
|
||||
if [ "$format" = "$file_extension" ]; then
|
||||
continue
|
||||
fi
|
||||
printf " %s" "$format"
|
||||
magick "$file" "${build_dir}/${assets_dir}/${file_name}.${format}"
|
||||
done
|
||||
echo
|
||||
done
|
28
eslint.config.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
import js from '@eslint/js'
|
||||
import globals from 'globals'
|
||||
import reactHooks from 'eslint-plugin-react-hooks'
|
||||
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||
import tseslint from 'typescript-eslint'
|
||||
|
||||
export default tseslint.config(
|
||||
{ ignores: ['dist'] },
|
||||
{
|
||||
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
languageOptions: {
|
||||
ecmaVersion: 2020,
|
||||
globals: globals.browser,
|
||||
},
|
||||
plugins: {
|
||||
'react-hooks': reactHooks,
|
||||
'react-refresh': reactRefresh,
|
||||
},
|
||||
rules: {
|
||||
...reactHooks.configs.recommended.rules,
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
},
|
||||
},
|
||||
)
|
173
index.html
|
@ -1,173 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<!--TODO: Optimize loading?-->
|
||||
<!--<link href="https://fonts.cdnfonts.com/css/jetbrains-mono" rel="stylesheet" />-->
|
||||
<title>Michael Bradley</title>
|
||||
<meta lang="EN" />
|
||||
|
||||
<meta name="color-scheme" content="dark light" />
|
||||
<meta name="theme-color" content="#000000" media="(prefers-color-scheme: dark)" />
|
||||
<meta name="theme-color" content="#eaeaea" media="(prefers-color-scheme: light)" />
|
||||
|
||||
<!--TODO: Find better icon than GH avatar-->
|
||||
<!--<link rel="icon" href="https://avatars.githubusercontent.com/u/68788583?s=48&v=4" />-->
|
||||
<link rel="icon" href="data:,">
|
||||
<meta name="keywords" content="Michael Bradley,personal website,programmer,coder,software developer" />
|
||||
<meta name="description" content="Michael Bradley's personal website" />
|
||||
<meta name="subject" content="Self-advertisement" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="summary" content="Michael Bradley is a graduating CS student looking for a full-time job starting in February" />
|
||||
<meta name="url" content="https://mmbradley.ca" />
|
||||
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:country-name" content="CA" />
|
||||
<meta property="og:region" content="ON" />
|
||||
<meta property="og:local" content="en_CA" />
|
||||
<meta property="og:local:alternate" content="en_US" />
|
||||
|
||||
<meta property="og:url" content="https://mmbradley.ca" />
|
||||
<meta property="og:site" content="Michael Bradley" />
|
||||
<meta property="og:title" content="Michael's personal website" />
|
||||
<meta property="og:description" content="A summary of my education, skills, and some projects I've worked on." />
|
||||
<meta property="og:image" content="https://mmbradley.ca/assets/thumb.webp" />
|
||||
<meta property="og:image:secure_url" content="https://mmbradley.ca/assets/thumb.webp" />
|
||||
<meta property="og:image:alt" content="Michael Bradley is a CS student looking for a full-time job starting in February" />
|
||||
<meta property="og:image:type" content="image/png" />
|
||||
<meta property="og:image:width" content="4203" />
|
||||
<meta property="og:image:height" content="2253" />
|
||||
|
||||
<meta name="twitter:url" content="https://mmbradley.ca" />
|
||||
<meta name="twitter:title" content="Michael Bradley" />
|
||||
<meta name="twitter:description" content="My personal website." />
|
||||
<meta name="twitter:image" content="https://mmbradley.ca/assets/thumb.webp" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="fetch-container">
|
||||
<div id="fetch">
|
||||
<!--TODO: Automate screenshot of this div as thumb.png?-->
|
||||
<div id="michael-photo-container">
|
||||
<picture>
|
||||
<source srcset="assets/MichaelBradley.jxl" type="image/jxl">
|
||||
<source srcset="assets/MichaelBradley.avif" type="image/avif">
|
||||
<source srcset="assets/MichaelBradley.webp" type="image/webp">
|
||||
<img src="assets/MichaelBradley.jpeg" alt="A picture of me in a suit smiling" id="michael-photo">
|
||||
</picture>
|
||||
</div>
|
||||
<div id="basic-info">
|
||||
<div class="invisible-div">
|
||||
<p><span class="text-highlight">website</span>@<span class="text-highlight">MichaelBradley</span></p>
|
||||
<p>----------------------</p>
|
||||
<p><span class="text-highlight">Degree</span>: Bachelor of Computer Science</p>
|
||||
<p><span class="text-highlight">University</span>: Carleton</p>
|
||||
<p><span class="text-highlight">Major CGPA</span>: 11.50/12 (A+)</p>
|
||||
<p><span class="text-highlight">Languages</span>: C/C++, Python, TypeScript</p>
|
||||
<p><span class="text-highlight">Skills</span>: Linux, Git, Testing</p>
|
||||
<p><span class="text-highlight">Work Experience</span>: 2 years</p>
|
||||
<p><span class="text-highlight">Applying for</span>: Full-time job</p>
|
||||
<p><span class="text-highlight">Location</span>: Toronto or Remote</p>
|
||||
</div>
|
||||
<p><br /></p>
|
||||
<p class="blocks">
|
||||
<span style="color: var(--color0)">███</span><span style="color: var(--color1)">███</span><span style="color: var(--color2)">███</span><span style="color: var(--color3)">███</span><span style="color: var(--color4)">███</span><span style="color: var(--color5)">███</span><span style="color: var(--color6)">███</span><span style="color: var(--color7)">███</span>
|
||||
</p>
|
||||
<p class="blocks">
|
||||
<span style="color: var(--color8)">███</span><span style="color: var(--color9)">███</span><span style="color: var(--color10)">███</span><span style="color: var(--color11)">███</span><span style="color: var(--color12)">███</span><span style="color: var(--color13)">███</span><span style="color: var(--color14)">███</span><span style="color: var(--color15)">███</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="links">
|
||||
<a href="https://github.com/MichaelMBradley" title="GitHub account">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512" aria-description="GitHub icon">
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
|
||||
<path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3 .3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5 .3-6.2 2.3zm44.2-1.7c-2.9 .7-4.9 2.6-4.6 4.9 .3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3 .7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3 .3 2.9 2.3 3.9 1.6 1 3.6 .7 4.3-.7 .7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3 .7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3 .7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="https://www.linkedin.com/in/michaelmbradley/" title="LinkedIn account">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" aria-description="LinkedIn icon">
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
|
||||
<path d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="https://mmbradley.ca/resume.pdf" title="My Résumé">
|
||||
<!-- From: https://www.svgrepo.com/svg/483015/resume-4 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" aria-description="CV icon">
|
||||
<g>
|
||||
<path class="st0" d="M276.239,252.183c-6.37,2.127-13.165,3.308-20.239,3.308c-7.074,0-13.87-1.181-20.24-3.308 c-46.272,7.599-70.489,41.608-70.489,82.877H256h90.728C346.728,293.791,322.515,259.782,276.239,252.183z" />
|
||||
<path class="st0" d="M256,240.788c27.43,0,49.658-22.24,49.658-49.666v-14.087c0-27.426-22.228-49.659-49.658-49.659 c-27.43,0-49.658,22.233-49.658,49.659v14.087C206.342,218.548,228.57,240.788,256,240.788z" />
|
||||
<path class="st0" d="M378.4,0H133.582C86.234,0,47.7,38.542,47.7,85.899v340.22C47.7,473.476,86.234,512,133.582,512h205.695 h13.175l9.318-9.301l93.229-93.229l9.301-9.31v-13.174V85.899C464.3,38.542,425.766,0,378.4,0z M432.497,386.985H384.35 c-24.882,0-45.074,20.183-45.074,45.073v48.139H133.582c-29.866,0-54.078-24.221-54.078-54.078V85.899 c0-29.874,24.212-54.096,54.078-54.096H378.4c29.876,0,54.096,24.222,54.096,54.096V386.985z" />
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
<a rel="me" href="https://mstdn.ca/@michaelbradley" title="Mastodon account">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" aria-description="Mastodon icon">
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
|
||||
<path d="M433 179.1c0-97.2-63.7-125.7-63.7-125.7-62.5-28.7-228.6-28.4-290.5 0 0 0-63.7 28.5-63.7 125.7 0 115.7-6.6 259.4 105.6 289.1 40.5 10.7 75.3 13 103.3 11.4 50.8-2.8 79.3-18.1 79.3-18.1l-1.7-36.9s-36.3 11.4-77.1 10.1c-40.4-1.4-83-4.4-89.6-54a102.5 102.5 0 0 1 -.9-13.9c85.6 20.9 158.7 9.1 178.8 6.7 56.1-6.7 105-41.3 111.2-72.9 9.8-49.8 9-121.5 9-121.5zm-75.1 125.2h-46.6v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.3V197c0-58.5-64-56.6-64-6.9v114.2H90.2c0-122.1-5.2-147.9 18.4-175 25.9-28.9 79.8-30.8 103.8 6.1l11.6 19.5 11.6-19.5c24.1-37.1 78.1-34.8 103.8-6.1 23.7 27.3 18.4 53 18.4 175z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<input id="dark-mode-toggle" type="checkbox" aria-label="Toggle dark mode" />
|
||||
<label for="dark-mode-toggle" id="dark-mode-toggle-label" title="Toggle dark mode">
|
||||
<svg viewBox="0 0 544 544" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="dark-mode-toggle-sky" x1="0" x2="0" y1="0.4" y2="0.6">
|
||||
<stop offset="0%" stop-color="deepskyblue" />
|
||||
<stop offset="100%" stop-color="black" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<!-- From: https://www.svgrepo.com/svg/484307/moon -->
|
||||
<rect class="dark-mode-svg" height="1280" width="544" fill="url(#dark-mode-toggle-sky)" x="-16px" y="-16px"/>
|
||||
<g class="dark-mode-svg">
|
||||
<path transform="translate(0, 768)" style="fill: rgb(244, 244, 245);" d="M426.655,444.491c-85.064,74.278-206.9,83.839-299.319,29.581 c-22.308-13.074-42.982-29.907-60.958-50.499C56,411.723,46.93,399.058,39.085,385.82C15.143,345.045,3.539,298.958,3.784,252.953 c0.49-71.582,29.989-142.754,87.026-192.6C138.776,18.433,197.855-1.096,256.69,0.047c45.597,0.817,91.03,13.973,131.069,38.733 c22.063,13.564,42.41,30.724,60.305,51.153c9.724,11.114,18.386,22.799,25.822,34.974 C537.623,227.785,521.117,361.878,426.655,444.491z" />
|
||||
<path transform="translate(0, 768)" style="fill: rgb(237, 237, 236);" d="M107.7,89.244c99.915-87.35,248.817-74.175,333.815,23.051 c84.998,97.226,75.388,243.379-24.528,330.729c-99.915,87.35-251.727,82.317-336.725-14.908S7.784,176.594,107.7,89.244z" />
|
||||
<path transform="translate(0, 768)" style="fill: rgb(216, 216, 216);" d="M244.029,141.49c-17.92,37.27-63.032,51.341-100.302,33.421 c-37.27-17.92-53.234-61.357-35.315-98.627c17.92-37.27,62.835-54.046,100.105-36.126 C245.787,58.078,261.948,104.22,244.029,141.49z" />
|
||||
<path transform="translate(0, 768)" style="opacity: 0.06; fill: rgb(4, 0, 0);" d="M128.086,97.65c17.92-37.27,62.835-54.046,100.105-36.126 c4.127,1.984,7.994,4.316,11.586,6.942c-7.335-11.909-17.95-21.909-31.26-28.308c-37.27-17.92-82.185-1.144-100.105,36.126 c-15.805,32.872-5.247,70.538,23.036,91.265C118.963,147.091,116.789,121.146,128.086,97.65z" />
|
||||
<path transform="translate(0, 768)" style="fill: rgb(216, 216, 216);" d="M217.121,218.367c-1.17-5.733,2.71-11.178,8.442-12.348c5.733-1.17,11.248,2.359,12.418,8.091 c1.17,5.733-2.456,11.466-8.189,12.635C224.06,227.916,218.291,224.099,217.121,218.367z" />
|
||||
<path transform="translate(0, 768)" style="opacity: 0.5; fill: rgb(255, 255, 255);" d="M363.151,96.945c-1.17-5.733,2.71-11.178,8.442-12.348s11.248,2.359,12.418,8.091 c1.17,5.733-2.456,11.466-8.189,12.636C370.089,106.493,364.32,102.677,363.151,96.945z" />
|
||||
<path transform="translate(0, 768)" style="fill: rgb(216, 216, 216);" d="M282.752,398.389c8.691-7.598,21.813-6.256,29.411,2.435c7.598,8.691,6.926,21.591-1.765,29.189 c-8.691,7.598-22.059,6.972-29.657-1.719C273.143,419.603,274.061,405.987,282.752,398.389z" />
|
||||
<path transform="translate(0, 768)" style="opacity: 0.5; fill: rgb(255, 255, 255);" d="M58.327,220.961c-1.17-5.733,2.71-11.178,8.442-12.348 c5.733-1.17,11.248,2.359,12.418,8.091s-2.456,11.466-8.189,12.636C65.265,230.51,59.496,226.694,58.327,220.961z" />
|
||||
<path transform="translate(0, 768)" style="fill: rgb(216, 216, 216);" d="M468.947,281.701c-3.725,36.649-37.256,62.098-73.905,58.373 c-36.649-3.725-63.177-35.279-59.452-71.928c3.725-36.649,36.272-64.305,72.921-60.58 C445.16,211.292,472.673,245.052,468.947,281.701z" />
|
||||
<path transform="translate(0, 768)" style="fill: rgb(216, 216, 216);" d="M173.239,331.136c14.631,25.328,4.867,57.294-20.461,71.925 c-25.328,14.631-57.07,6.642-71.701-18.686c-14.631-25.328-6.526-58.257,18.802-72.888 C125.206,296.855,158.608,305.808,173.239,331.136z" />
|
||||
<path transform="translate(0, 768)" style="opacity: 0.06; fill: rgb(4, 0, 0);" d="M112.818,324.329c18.464-10.666,41.21-8.787,57.855,2.82 c-15.693-22.238-46.847-29.497-70.794-15.663c-25.328,14.631-33.433,47.561-18.802,72.888c4.04,6.993,9.388,12.657,15.541,16.895 c-0.915-1.299-1.788-2.644-2.602-4.052C79.385,371.89,87.49,338.96,112.818,324.329z" />
|
||||
<path transform="translate(0, 768)" style="opacity: 0.06; fill: rgb(4, 0, 0);" d="M349.701,282.093c3.725-36.649,36.272-64.305,72.921-60.579 c12.217,1.242,23.415,5.824,32.783,12.735c-11.007-14.534-27.694-24.73-46.893-26.682c-36.649-3.725-69.196,23.93-72.921,60.579 c-2.465,24.247,8.316,46.261,26.506,59.464C352.777,315.06,347.969,299.128,349.701,282.093z" />
|
||||
<path transform="translate(0, 768)" style="opacity: 0.1; fill: rgb(4, 0, 0);" d="M254.81,381.707c-105.358,0-198.419-52.064-254.72-131.654 c-2.703,99.72,55.552,194.334,153.936,236.742c128.773,55.507,279.648,1.534,335.155-127.239 c15.267-35.419,21.657-72.747,20.288-109.416C453.162,329.68,360.13,381.707,254.81,381.707z" />
|
||||
</g>
|
||||
<!-- From: https://www.svgrepo.com/svg/484356/sun -->
|
||||
<g class="dark-mode-svg">
|
||||
<path style="fill: rgb(191, 182, 30);" d="M258.373,448.122c-11.783,0-21.337,1.395-21.337,18.136c0,8.131,9.553,45.742,21.337,45.742 c11.784,0,21.336-37.611,21.336-45.742C279.709,449.518,270.156,448.122,258.373,448.122z" />
|
||||
<path style="fill: rgb(191, 182, 30);" d="M352.653,422.86c-10.205,5.891-17.78,11.876-9.41,26.374c4.065,7.041,31.144,34.837,41.349,28.945 c10.205-5.892-0.328-43.241-4.393-50.282C371.829,413.4,362.858,416.968,352.653,422.86z" />
|
||||
<path style="fill: rgb(191, 182, 30);" d="M448.046,344.432c-14.498-8.37-20.483-0.795-26.375,9.41c-5.892,10.205-9.46,19.176,5.038,27.546 c7.041,4.065,44.39,14.598,50.282,4.393C482.883,375.576,455.087,348.497,448.046,344.432z" />
|
||||
<path style="fill: rgb(191, 182, 30);" d="M465.07,238.225c-16.741,0-18.136,9.553-18.136,21.337c0,11.784,1.396,21.336,18.136,21.336 c8.13,0,45.742-9.553,45.742-21.336C510.812,247.777,473.2,238.225,465.07,238.225z" />
|
||||
<path style="fill: rgb(191, 182, 30);" d="M426.71,137.735c-14.498,8.37-10.93,17.341-5.038,27.546c5.892,10.204,11.877,17.78,26.375,9.41 c7.041-4.065,34.837-31.144,28.945-41.349C471.099,123.137,433.75,133.67,426.71,137.735z" />
|
||||
<path style="fill: rgb(191, 182, 30);" d="M164.092,422.86c-10.205-5.892-19.176-9.46-27.546,5.038c-4.065,7.041-14.598,44.39-4.393,50.282 c10.205,5.892,37.283-21.904,41.349-28.945C181.872,434.737,174.297,428.752,164.092,422.86z" />
|
||||
<path style="fill: rgb(191, 182, 30);" d="M424.226,259.561c0-45.799-18.564-87.263-48.577-117.276L141.097,376.837 c30.013,30.013,71.477,48.578,117.276,48.578C349.971,425.415,424.226,351.159,424.226,259.561z" />
|
||||
<path style="fill: rgb(198, 186, 86);" d="M164.11,96.239c-10.143,5.855-19.05,9.401-27.297-4.618c-0.082-0.083-0.165-0.247-0.248-0.412 c-4.123-7.009-14.596-44.367-4.453-50.305c7.669-4.454,25.07,10.308,34.719,20.781c3.298,3.464,5.69,6.433,6.68,8.164 C181.84,84.364,174.336,90.384,164.11,96.239z" />
|
||||
<path style="fill: rgb(198, 186, 86);" d="M279.729,52.861v0.577c-0.248,16.164-9.732,17.566-21.359,17.566 c-9.319,0-17.236-0.907-20.122-9.483c-0.824-2.227-1.237-5.113-1.237-8.66c0-5.03,3.629-21.276,9.154-32.987 c3.546-7.257,7.752-12.782,12.205-12.782c1.319,0,2.639,0.495,3.876,1.402C272.225,15.174,279.729,45.604,279.729,52.861z" />
|
||||
<path style="fill: rgb(198, 186, 86);" d="M95.085,165.264c-5.938,10.226-11.875,17.813-26.39,9.401 c-3.958-2.227-14.432-11.793-21.854-21.524c-0.082-0.083-0.165-0.165-0.165-0.248c-5.69-7.504-9.484-15.091-6.928-19.545 c5.938-10.226,43.213,0.33,50.305,4.371c1.237,0.742,2.391,1.484,3.381,2.226C103.909,147.699,100.445,155.945,95.085,165.264z" />
|
||||
<path style="fill: rgb(198, 186, 86);" d="M69.85,259.524c0,11.546-1.32,21.03-17.236,21.359h-0.907c-7.834,0-43.13-8.907-45.605-20.122 c-0.082,0-0.082,0-0.082,0c0-0.412-0.083-0.824-0.083-1.237c0-4.536,5.69-8.824,13.112-12.205 c11.711-5.525,27.709-9.071,32.657-9.071c4.701,0,8.164,0.742,10.721,2.062C69.108,243.773,69.85,251.113,69.85,259.524z" />
|
||||
<path style="fill: rgb(198, 186, 86);" d="M68.7,344.432c-7.041,4.065-34.837,31.144-28.945,41.349c5.892,10.205,43.241-0.328,50.281-4.393 c14.498-8.37,10.93-17.341,5.038-27.546C89.183,343.637,83.197,336.062,68.7,344.432z" />
|
||||
<path style="fill: rgb(198, 186, 86);" d="M352.653,96.263c10.205,5.892,19.176,9.46,27.546-5.038c4.065-7.041,14.598-44.39,4.393-50.282 c-10.205-5.892-37.284,21.904-41.349,28.945C334.873,84.386,342.448,90.371,352.653,96.263z" />
|
||||
<path style="fill: rgb(198, 186, 86);" d="M258.373,93.708c-91.598,0-165.853,74.255-165.853,165.853 c0,45.799,18.563,87.262,48.577,117.276l234.552-234.552C345.635,112.271,304.172,93.708,258.373,93.708z" />
|
||||
<path style="fill: rgb(239, 231, 72);" d="M252.408,440.964c-11.783,0-21.337,1.395-21.337,18.136c0,8.131,9.553,45.742,21.337,45.742 s21.336-37.611,21.336-45.742C273.744,442.36,264.191,440.964,252.408,440.964z" />
|
||||
<path style="fill: rgb(239, 231, 72);" d="M346.688,415.702c-10.205,5.892-17.78,11.877-9.41,26.375c4.065,7.041,31.144,34.837,41.349,28.945 c10.205-5.892-0.328-43.241-4.393-50.282C365.864,406.242,356.893,409.81,346.688,415.702z" />
|
||||
<path style="fill: rgb(239, 231, 72);" d="M442.081,337.274c-14.498-8.37-20.483-0.795-26.375,9.41c-5.892,10.205-9.46,19.176,5.038,27.546 c7.041,4.065,44.39,14.598,50.282,4.393C476.918,368.418,449.122,341.339,442.081,337.274z" />
|
||||
<path style="fill: rgb(239, 231, 72);" d="M459.105,231.066c-16.741,0-18.136,9.553-18.136,21.337c0,11.784,1.395,21.336,18.136,21.336 c8.13,0,45.742-9.553,45.742-21.336C504.846,240.619,467.235,231.066,459.105,231.066z" />
|
||||
<path style="fill: rgb(239, 231, 72);" d="M420.744,130.577c-14.497,8.37-10.93,17.341-5.038,27.546c5.892,10.205,11.877,17.78,26.375,9.41 c7.041-4.065,34.837-31.144,28.945-41.349C465.134,115.979,427.785,126.511,420.744,130.577z" />
|
||||
<path style="fill: rgb(239, 231, 72);" d="M158.127,415.702c-10.205-5.892-19.176-9.46-27.546,5.038c-4.065,7.041-14.598,44.39-4.392,50.282 c10.205,5.892,37.283-21.904,41.349-28.945C175.907,427.578,168.332,421.594,158.127,415.702z" />
|
||||
<path style="fill: rgb(239, 231, 72);" d="M418.261,252.403c0-45.799-18.564-87.263-48.577-117.276L135.132,369.679 c30.014,30.013,71.477,48.578,117.276,48.578C344.006,418.257,418.261,344.001,418.261,252.403z" />
|
||||
<path style="fill: rgb(250, 242, 175);" d="M158.09,89.065c-7.67,4.453-14.679,7.587-21.277,2.557c-2.144-1.567-4.206-4.041-6.268-7.587 c-4.041-7.01-14.597-44.367-4.371-50.223c9.814-5.69,34.967,19.545,40.657,27.874c0.33,0.412,0.577,0.742,0.742,1.072 C175.903,77.189,168.316,83.209,158.09,89.065z" />
|
||||
<path style="fill: rgb(250, 242, 175);" d="M273.709,45.687c0,0.577,0,1.155-0.083,1.65c-0.577,15.174-9.814,16.493-21.194,16.493 c-4.288,0-8.247-0.165-11.628-1.237c-0.907-0.247-1.732-0.659-2.556-1.072c-2.722-1.402-4.866-3.711-6.02-7.422 c-0.083-0.083,0-0.083,0-0.083c-0.742-2.227-1.155-5.03-1.155-8.329c0-4.865,3.464-20.452,8.824-32.08 c3.216-7.01,7.175-12.617,11.381-13.442C251.69,0.083,252.02,0,252.432,0c3.547,0,6.927,3.463,9.814,8.494 c0.99,1.649,1.897,3.464,2.804,5.443C270.328,25.482,273.709,40.904,273.709,45.687z" />
|
||||
<path style="fill: rgb(250, 242, 175);" d="M89.147,158.09c-5.937,10.226-11.875,17.813-26.39,9.484c-2.969-1.732-9.648-7.505-15.916-14.432 c-0.082-0.083-0.165-0.165-0.165-0.248c-8.577-9.401-16.246-20.864-12.865-26.719c5.855-10.226,43.213,0.33,50.222,4.371 c5.195,3.051,8.164,6.185,9.401,9.401C95.662,145.637,92.858,151.658,89.147,158.09z" />
|
||||
<path style="fill: rgb(250, 242, 175);" d="M63.83,252.432c0,11.793-1.402,21.277-18.142,21.277H45.44c-5.03-0.083-20.122-3.382-31.503-8.577 c-2.886-1.402-5.608-2.804-7.835-4.371c-0.082,0-0.082,0-0.082,0C2.309,258.205,0,255.401,0,252.432c0-0.33,0-0.742,0.165-1.072 c0.742-4.041,5.69-7.669,12.04-10.886c11.793-5.608,28.451-9.401,33.482-9.401c1.897,0,3.629,0.165,5.196,0.412 c6.762,0.99,9.978,4.288,11.545,8.824c0.412,1.072,0.66,2.309,0.825,3.546C63.748,246.412,63.83,249.381,63.83,252.432z" />
|
||||
<path style="fill: rgb(250, 242, 175);" d="M84.034,374.237c-5.196,3.051-27.379,9.649-40.739,8.576c-1.567-0.083-2.969-0.33-4.288-0.742 c-2.392-0.66-4.206-1.815-5.195-3.464c-0.908-1.567-1.072-3.629-0.577-5.855c2.804-12.206,23.503-32.08,29.523-35.461 c2.969-1.732,5.608-2.804,7.917-3.216c7.917-1.732,12.453,2.969,16.659,9.566c0.577,0.99,1.237,1.979,1.814,3.051 c2.062,3.711,3.959,7.175,4.701,10.556C95.25,363.268,93.353,368.876,84.034,374.237z" />
|
||||
<path style="fill: rgb(250, 242, 175);" d="M346.688,89.104c10.205,5.892,19.176,9.46,27.546-5.038c4.065-7.041,14.598-44.39,4.393-50.282 c-10.205-5.892-37.284,21.904-41.349,28.945C328.908,77.228,336.483,83.213,346.688,89.104z" />
|
||||
<path style="fill: rgb(250, 242, 175);" d="M369.701,135.164l-0.743,0.742l-3.381,3.381L135.164,369.701 c-2.474-2.474-4.783-4.948-7.092-7.587c-6.185-7.009-11.793-14.514-16.741-22.513c-15.668-25.318-24.74-55.171-24.74-87.168 c0-91.621,74.221-165.842,165.842-165.842c29.936,0,58.057,7.917,82.385,21.936C347.6,115.784,359.31,124.773,369.701,135.164z" />
|
||||
</g>
|
||||
</svg>
|
||||
</label>
|
||||
</div>
|
||||
<body id="root">
|
||||
<script type="module" src="/src/entry-client.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
38
package.json
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"name": "mmbradley-home",
|
||||
"private": "true",
|
||||
"version": "2.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "yarn build:client && yarn build:server",
|
||||
"build:client": "tsc -b && vite build --outDir dist/client",
|
||||
"build:server": "tsc -b && vite build --outDir dist/server --ssr src/entry-server.tsx",
|
||||
"lint": "eslint .",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.17.0",
|
||||
"@svgr/core": "^8.1.0",
|
||||
"@svgr/plugin-jsx": "^8.1.0",
|
||||
"@svgr/plugin-svgo": "^8.1.0",
|
||||
"@types/react": "^19.0.2",
|
||||
"@types/react-dom": "^19.0.2",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"eslint": "^9.17.0",
|
||||
"eslint-plugin-react-hooks": "^5.1.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.16",
|
||||
"globals": "^15.14.0",
|
||||
"prettier": "^3.4.2",
|
||||
"typescript": "^5.7.2",
|
||||
"typescript-eslint": "^8.19.0",
|
||||
"vite": "^6.0.6",
|
||||
"vite-imagetools": "^7.0.5",
|
||||
"vite-plugin-html": "^3.2.2",
|
||||
"vite-plugin-svgr": "^4.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0"
|
||||
}
|
||||
}
|
17
render.sh
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
yarn build
|
||||
|
||||
PROD='dist/prod'
|
||||
rm -r "$PROD"
|
||||
mkdir -p "$PROD"
|
||||
|
||||
echo 'Rendering webpage...'
|
||||
node -e 'import("./dist/server/entry-server.js").then(({render}) => console.log(render().html))' > "$PROD"/index.html
|
||||
|
||||
echo "Preparing $PROD..."
|
||||
# Copy used assets
|
||||
cp -r dist/client/assets "$PROD"/
|
||||
# Not needed: Pre-rendered
|
||||
rm "$PROD"/assets/*.js
|
||||
# Not needed: Inlined
|
||||
rm "$PROD"/assets/*.css
|
114
src/Body.tsx
Normal file
|
@ -0,0 +1,114 @@
|
|||
import "./style.css";
|
||||
|
||||
import hero from "./assets/MichaelBradley.jpeg?format=avif;webp;jpeg&as=picture";
|
||||
|
||||
import CV from "./assets/cv.svg?react";
|
||||
import GitHub from "./assets/github.svg?react";
|
||||
import LinkedIn from "./assets/linkedin.svg?react";
|
||||
import Mastodon from "./assets/mastodon.svg?react";
|
||||
import DarkModeToggleIcon from "./assets/darkmodetoggle.svg?react";
|
||||
|
||||
// TODO: Automate screenshot of info for thumbnail?
|
||||
const Fetch = () => {
|
||||
return (
|
||||
<div id="fetch-container">
|
||||
<div id="fetch">
|
||||
<div id="michael-photo-container">
|
||||
<picture>
|
||||
{Object.entries(hero.sources).map(([format, src]) => (
|
||||
<source srcSet={src} type={`image/${format}`} key={format} />
|
||||
))}
|
||||
<img src={hero.img.src} alt="A picture of me in a suit smiling" id="michael-photo" />
|
||||
</picture>
|
||||
</div>
|
||||
<div id="basic-info">
|
||||
<div className="invisible-div">
|
||||
<p>
|
||||
<span className="text-highlight">website</span>@<span className="text-highlight">MichaelBradley</span>
|
||||
</p>
|
||||
<p>----------------------</p>
|
||||
<p>
|
||||
<span className="text-highlight">Degree</span>: Bachelor of Computer Science
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">University</span>: Carleton
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Major CGPA</span>: 11.50/12 (A+)
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Languages</span>: C/C++, Python, TypeScript
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Skills</span>: Linux, Git, Testing
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Work Experience</span>: 2 years
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Applying for</span>: Full-time job
|
||||
</p>
|
||||
<p>
|
||||
<span className="text-highlight">Location</span>: Toronto or Remote
|
||||
</p>
|
||||
</div>
|
||||
<p>
|
||||
<br />
|
||||
</p>
|
||||
<p className="blocks">
|
||||
<span style={{ color: "var(--color0)" }}>███</span>
|
||||
<span style={{ color: "var(--color1)" }}>███</span>
|
||||
<span style={{ color: "var(--color2)" }}>███</span>
|
||||
<span style={{ color: "var(--color3)" }}>███</span>
|
||||
<span style={{ color: "var(--color4)" }}>███</span>
|
||||
<span style={{ color: "var(--color5)" }}>███</span>
|
||||
<span style={{ color: "var(--color6)" }}>███</span>
|
||||
<span style={{ color: "var(--color7)" }}>███</span>
|
||||
</p>
|
||||
<p className="blocks">
|
||||
<span style={{ color: "var(--color8)" }}>███</span>
|
||||
<span style={{ color: "var(--color9)" }}>███</span>
|
||||
<span style={{ color: "var(--color10)" }}>███</span>
|
||||
<span style={{ color: "var(--color11)" }}>███</span>
|
||||
<span style={{ color: "var(--color12)" }}>███</span>
|
||||
<span style={{ color: "var(--color13)" }}>███</span>
|
||||
<span style={{ color: "var(--color14)" }}>███</span>
|
||||
<span style={{ color: "var(--color15)" }}>███</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Links = () => (
|
||||
<div className="links">
|
||||
<a href="https://github.com/MichaelMBradley" title="GitHub account">
|
||||
<GitHub />
|
||||
</a>
|
||||
<a href="https://www.linkedin.com/in/michaelmbradley/" title="LinkedIn account">
|
||||
<LinkedIn />
|
||||
</a>
|
||||
<a href="https://mmbradley.ca/resume.pdf" title="My Résumé">
|
||||
<CV />
|
||||
</a>
|
||||
<a rel="me" href="https://mstdn.ca/@michaelbradley" title="Mastodon account">
|
||||
<Mastodon />
|
||||
</a>
|
||||
<input id="dark-mode-toggle" type="checkbox" aria-label="Toggle dark mode" />
|
||||
<label htmlFor="dark-mode-toggle" id="dark-mode-toggle-label" title="Toggle dark mode">
|
||||
<DarkModeToggleIcon />
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
||||
const Body = () => {
|
||||
return (
|
||||
<>
|
||||
<Fetch />
|
||||
<Links />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Body;
|
72
src/Head.tsx
Normal file
|
@ -0,0 +1,72 @@
|
|||
import thumb from "./assets/thumb.png?format=webp&as=metadata";
|
||||
|
||||
const DESCRIPTION = "Michael Bradley is a computer scientist looking for a full-time job";
|
||||
|
||||
const Preamble = () => (
|
||||
<>
|
||||
<meta charSet="UTF-8" />
|
||||
<title>Michael Bradley</title>
|
||||
<meta lang="EN" />
|
||||
</>
|
||||
);
|
||||
|
||||
const Styles = () => (
|
||||
<>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="color-scheme" content="dark light" />
|
||||
<meta name="theme-color" content="#000000" media="(prefers-color-scheme: dark)" />
|
||||
<meta name="theme-color" content="#eaeaea" media="(prefers-color-scheme: light)" />
|
||||
</>
|
||||
);
|
||||
|
||||
// TODO: Find better icon than GH avatar
|
||||
// <link rel="icon" href="https://avatars.githubusercontent.com/u/68788583?s=48&v=4" />
|
||||
const SEO = () => (
|
||||
<>
|
||||
<link rel="icon" href="data:," />
|
||||
<meta name="keywords" content="Michael Bradley,personal website,programmer,coder,software developer" />
|
||||
<meta name="description" content="Michael Bradley's personal website" />
|
||||
<meta name="subject" content="Self-advertisement" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta name="summary" content={DESCRIPTION} />
|
||||
<meta name="url" content={import.meta.env.BASE_URL} />
|
||||
</>
|
||||
);
|
||||
|
||||
const OpenGraph = () => (
|
||||
<>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:country-name" content="CA" />
|
||||
<meta property="og:region" content="ON" />
|
||||
<meta property="og:local" content="en_CA" />
|
||||
<meta property="og:local:alternate" content="en_US" />
|
||||
|
||||
<meta property="og:url" content={import.meta.env.BASE_URL} />
|
||||
<meta property="og:site" content="Michael Bradley" />
|
||||
<meta property="og:title" content="Michael's personal website" />
|
||||
<meta property="og:description" content="A summary of my education, skills, and some projects I've worked on." />
|
||||
<meta property="og:image" content={thumb.src} />
|
||||
<meta property="og:image:secure_url" content={thumb.src} />
|
||||
<meta property="og:image:alt" content={DESCRIPTION} />
|
||||
<meta property="og:image:type" content={`image/${thumb.format}`} />
|
||||
<meta property="og:image:width" content={`${thumb.width}`} />
|
||||
<meta property="og:image:height" content={`${thumb.height}`} />
|
||||
|
||||
<meta name="twitter:url" content={import.meta.env.BASE_URL} />
|
||||
<meta name="twitter:title" content="Michael Bradley" />
|
||||
<meta name="twitter:description" content="My personal website." />
|
||||
<meta name="twitter:image" content={thumb.src} />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
</>
|
||||
);
|
||||
|
||||
const Head = () => (
|
||||
<>
|
||||
<Preamble />
|
||||
<Styles />
|
||||
<SEO />
|
||||
<OpenGraph />
|
||||
</>
|
||||
);
|
||||
|
||||
export default Head;
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 131 KiB |
17
src/assets/cv.svg
Normal file
|
@ -0,0 +1,17 @@
|
|||
<!-- From: https://www.svgrepo.com/svg/483015/resume-4 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" aria-description="CV icon">
|
||||
<g>
|
||||
<path
|
||||
class="st0"
|
||||
d="M276.239,252.183c-6.37,2.127-13.165,3.308-20.239,3.308c-7.074,0-13.87-1.181-20.24-3.308 c-46.272,7.599-70.489,41.608-70.489,82.877H256h90.728C346.728,293.791,322.515,259.782,276.239,252.183z"
|
||||
/>
|
||||
<path
|
||||
class="st0"
|
||||
d="M256,240.788c27.43,0,49.658-22.24,49.658-49.666v-14.087c0-27.426-22.228-49.659-49.658-49.659 c-27.43,0-49.658,22.233-49.658,49.659v14.087C206.342,218.548,228.57,240.788,256,240.788z"
|
||||
/>
|
||||
<path
|
||||
class="st0"
|
||||
d="M378.4,0H133.582C86.234,0,47.7,38.542,47.7,85.899v340.22C47.7,473.476,86.234,512,133.582,512h205.695 h13.175l9.318-9.301l93.229-93.229l9.301-9.31v-13.174V85.899C464.3,38.542,425.766,0,378.4,0z M432.497,386.985H384.35 c-24.882,0-45.074,20.183-45.074,45.073v48.139H133.582c-29.866,0-54.078-24.221-54.078-54.078V85.899 c0-29.874,24.212-54.096,54.078-54.096H378.4c29.876,0,54.096,24.222,54.096,54.096V386.985z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1 KiB |
192
src/assets/darkmodetoggle.svg
Normal file
|
@ -0,0 +1,192 @@
|
|||
<svg viewBox="0 0 544 544" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="dark-mode-toggle-sky" x1="0" x2="0" y1="0.4" y2="0.6">
|
||||
<stop offset="0%" stop-color="deepskyblue" />
|
||||
<stop offset="100%" stop-color="black" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<!-- From: https://www.svgrepo.com/svg/484307/moon -->
|
||||
<rect class="dark-mode-svg" height="1280" width="544" fill="url(#dark-mode-toggle-sky)" x="-16px" y="-16px" />
|
||||
<g class="dark-mode-svg">
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="fill: rgb(244, 244, 245)"
|
||||
d="M426.655,444.491c-85.064,74.278-206.9,83.839-299.319,29.581 c-22.308-13.074-42.982-29.907-60.958-50.499C56,411.723,46.93,399.058,39.085,385.82C15.143,345.045,3.539,298.958,3.784,252.953 c0.49-71.582,29.989-142.754,87.026-192.6C138.776,18.433,197.855-1.096,256.69,0.047c45.597,0.817,91.03,13.973,131.069,38.733 c22.063,13.564,42.41,30.724,60.305,51.153c9.724,11.114,18.386,22.799,25.822,34.974 C537.623,227.785,521.117,361.878,426.655,444.491z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="fill: rgb(237, 237, 236)"
|
||||
d="M107.7,89.244c99.915-87.35,248.817-74.175,333.815,23.051 c84.998,97.226,75.388,243.379-24.528,330.729c-99.915,87.35-251.727,82.317-336.725-14.908S7.784,176.594,107.7,89.244z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="fill: rgb(216, 216, 216)"
|
||||
d="M244.029,141.49c-17.92,37.27-63.032,51.341-100.302,33.421 c-37.27-17.92-53.234-61.357-35.315-98.627c17.92-37.27,62.835-54.046,100.105-36.126 C245.787,58.078,261.948,104.22,244.029,141.49z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="opacity: 0.06; fill: rgb(4, 0, 0)"
|
||||
d="M128.086,97.65c17.92-37.27,62.835-54.046,100.105-36.126 c4.127,1.984,7.994,4.316,11.586,6.942c-7.335-11.909-17.95-21.909-31.26-28.308c-37.27-17.92-82.185-1.144-100.105,36.126 c-15.805,32.872-5.247,70.538,23.036,91.265C118.963,147.091,116.789,121.146,128.086,97.65z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="fill: rgb(216, 216, 216)"
|
||||
d="M217.121,218.367c-1.17-5.733,2.71-11.178,8.442-12.348c5.733-1.17,11.248,2.359,12.418,8.091 c1.17,5.733-2.456,11.466-8.189,12.635C224.06,227.916,218.291,224.099,217.121,218.367z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="opacity: 0.5; fill: rgb(255, 255, 255)"
|
||||
d="M363.151,96.945c-1.17-5.733,2.71-11.178,8.442-12.348s11.248,2.359,12.418,8.091 c1.17,5.733-2.456,11.466-8.189,12.636C370.089,106.493,364.32,102.677,363.151,96.945z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="fill: rgb(216, 216, 216)"
|
||||
d="M282.752,398.389c8.691-7.598,21.813-6.256,29.411,2.435c7.598,8.691,6.926,21.591-1.765,29.189 c-8.691,7.598-22.059,6.972-29.657-1.719C273.143,419.603,274.061,405.987,282.752,398.389z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="opacity: 0.5; fill: rgb(255, 255, 255)"
|
||||
d="M58.327,220.961c-1.17-5.733,2.71-11.178,8.442-12.348 c5.733-1.17,11.248,2.359,12.418,8.091s-2.456,11.466-8.189,12.636C65.265,230.51,59.496,226.694,58.327,220.961z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="fill: rgb(216, 216, 216)"
|
||||
d="M468.947,281.701c-3.725,36.649-37.256,62.098-73.905,58.373 c-36.649-3.725-63.177-35.279-59.452-71.928c3.725-36.649,36.272-64.305,72.921-60.58 C445.16,211.292,472.673,245.052,468.947,281.701z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="fill: rgb(216, 216, 216)"
|
||||
d="M173.239,331.136c14.631,25.328,4.867,57.294-20.461,71.925 c-25.328,14.631-57.07,6.642-71.701-18.686c-14.631-25.328-6.526-58.257,18.802-72.888 C125.206,296.855,158.608,305.808,173.239,331.136z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="opacity: 0.06; fill: rgb(4, 0, 0)"
|
||||
d="M112.818,324.329c18.464-10.666,41.21-8.787,57.855,2.82 c-15.693-22.238-46.847-29.497-70.794-15.663c-25.328,14.631-33.433,47.561-18.802,72.888c4.04,6.993,9.388,12.657,15.541,16.895 c-0.915-1.299-1.788-2.644-2.602-4.052C79.385,371.89,87.49,338.96,112.818,324.329z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="opacity: 0.06; fill: rgb(4, 0, 0)"
|
||||
d="M349.701,282.093c3.725-36.649,36.272-64.305,72.921-60.579 c12.217,1.242,23.415,5.824,32.783,12.735c-11.007-14.534-27.694-24.73-46.893-26.682c-36.649-3.725-69.196,23.93-72.921,60.579 c-2.465,24.247,8.316,46.261,26.506,59.464C352.777,315.06,347.969,299.128,349.701,282.093z"
|
||||
/>
|
||||
<path
|
||||
transform="translate(0, 768)"
|
||||
style="opacity: 0.1; fill: rgb(4, 0, 0)"
|
||||
d="M254.81,381.707c-105.358,0-198.419-52.064-254.72-131.654 c-2.703,99.72,55.552,194.334,153.936,236.742c128.773,55.507,279.648,1.534,335.155-127.239 c15.267-35.419,21.657-72.747,20.288-109.416C453.162,329.68,360.13,381.707,254.81,381.707z"
|
||||
/>
|
||||
</g>
|
||||
<!-- From: https://www.svgrepo.com/svg/484356/sun -->
|
||||
<g class="dark-mode-svg">
|
||||
<path
|
||||
style="fill: rgb(191, 182, 30)"
|
||||
d="M258.373,448.122c-11.783,0-21.337,1.395-21.337,18.136c0,8.131,9.553,45.742,21.337,45.742 c11.784,0,21.336-37.611,21.336-45.742C279.709,449.518,270.156,448.122,258.373,448.122z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(191, 182, 30)"
|
||||
d="M352.653,422.86c-10.205,5.891-17.78,11.876-9.41,26.374c4.065,7.041,31.144,34.837,41.349,28.945 c10.205-5.892-0.328-43.241-4.393-50.282C371.829,413.4,362.858,416.968,352.653,422.86z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(191, 182, 30)"
|
||||
d="M448.046,344.432c-14.498-8.37-20.483-0.795-26.375,9.41c-5.892,10.205-9.46,19.176,5.038,27.546 c7.041,4.065,44.39,14.598,50.282,4.393C482.883,375.576,455.087,348.497,448.046,344.432z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(191, 182, 30)"
|
||||
d="M465.07,238.225c-16.741,0-18.136,9.553-18.136,21.337c0,11.784,1.396,21.336,18.136,21.336 c8.13,0,45.742-9.553,45.742-21.336C510.812,247.777,473.2,238.225,465.07,238.225z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(191, 182, 30)"
|
||||
d="M426.71,137.735c-14.498,8.37-10.93,17.341-5.038,27.546c5.892,10.204,11.877,17.78,26.375,9.41 c7.041-4.065,34.837-31.144,28.945-41.349C471.099,123.137,433.75,133.67,426.71,137.735z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(191, 182, 30)"
|
||||
d="M164.092,422.86c-10.205-5.892-19.176-9.46-27.546,5.038c-4.065,7.041-14.598,44.39-4.393,50.282 c10.205,5.892,37.283-21.904,41.349-28.945C181.872,434.737,174.297,428.752,164.092,422.86z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(191, 182, 30)"
|
||||
d="M424.226,259.561c0-45.799-18.564-87.263-48.577-117.276L141.097,376.837 c30.013,30.013,71.477,48.578,117.276,48.578C349.971,425.415,424.226,351.159,424.226,259.561z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(198, 186, 86)"
|
||||
d="M164.11,96.239c-10.143,5.855-19.05,9.401-27.297-4.618c-0.082-0.083-0.165-0.247-0.248-0.412 c-4.123-7.009-14.596-44.367-4.453-50.305c7.669-4.454,25.07,10.308,34.719,20.781c3.298,3.464,5.69,6.433,6.68,8.164 C181.84,84.364,174.336,90.384,164.11,96.239z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(198, 186, 86)"
|
||||
d="M279.729,52.861v0.577c-0.248,16.164-9.732,17.566-21.359,17.566 c-9.319,0-17.236-0.907-20.122-9.483c-0.824-2.227-1.237-5.113-1.237-8.66c0-5.03,3.629-21.276,9.154-32.987 c3.546-7.257,7.752-12.782,12.205-12.782c1.319,0,2.639,0.495,3.876,1.402C272.225,15.174,279.729,45.604,279.729,52.861z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(198, 186, 86)"
|
||||
d="M95.085,165.264c-5.938,10.226-11.875,17.813-26.39,9.401 c-3.958-2.227-14.432-11.793-21.854-21.524c-0.082-0.083-0.165-0.165-0.165-0.248c-5.69-7.504-9.484-15.091-6.928-19.545 c5.938-10.226,43.213,0.33,50.305,4.371c1.237,0.742,2.391,1.484,3.381,2.226C103.909,147.699,100.445,155.945,95.085,165.264z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(198, 186, 86)"
|
||||
d="M69.85,259.524c0,11.546-1.32,21.03-17.236,21.359h-0.907c-7.834,0-43.13-8.907-45.605-20.122 c-0.082,0-0.082,0-0.082,0c0-0.412-0.083-0.824-0.083-1.237c0-4.536,5.69-8.824,13.112-12.205 c11.711-5.525,27.709-9.071,32.657-9.071c4.701,0,8.164,0.742,10.721,2.062C69.108,243.773,69.85,251.113,69.85,259.524z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(198, 186, 86)"
|
||||
d="M68.7,344.432c-7.041,4.065-34.837,31.144-28.945,41.349c5.892,10.205,43.241-0.328,50.281-4.393 c14.498-8.37,10.93-17.341,5.038-27.546C89.183,343.637,83.197,336.062,68.7,344.432z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(198, 186, 86)"
|
||||
d="M352.653,96.263c10.205,5.892,19.176,9.46,27.546-5.038c4.065-7.041,14.598-44.39,4.393-50.282 c-10.205-5.892-37.284,21.904-41.349,28.945C334.873,84.386,342.448,90.371,352.653,96.263z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(198, 186, 86)"
|
||||
d="M258.373,93.708c-91.598,0-165.853,74.255-165.853,165.853 c0,45.799,18.563,87.262,48.577,117.276l234.552-234.552C345.635,112.271,304.172,93.708,258.373,93.708z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(239, 231, 72)"
|
||||
d="M252.408,440.964c-11.783,0-21.337,1.395-21.337,18.136c0,8.131,9.553,45.742,21.337,45.742 s21.336-37.611,21.336-45.742C273.744,442.36,264.191,440.964,252.408,440.964z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(239, 231, 72)"
|
||||
d="M346.688,415.702c-10.205,5.892-17.78,11.877-9.41,26.375c4.065,7.041,31.144,34.837,41.349,28.945 c10.205-5.892-0.328-43.241-4.393-50.282C365.864,406.242,356.893,409.81,346.688,415.702z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(239, 231, 72)"
|
||||
d="M442.081,337.274c-14.498-8.37-20.483-0.795-26.375,9.41c-5.892,10.205-9.46,19.176,5.038,27.546 c7.041,4.065,44.39,14.598,50.282,4.393C476.918,368.418,449.122,341.339,442.081,337.274z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(239, 231, 72)"
|
||||
d="M459.105,231.066c-16.741,0-18.136,9.553-18.136,21.337c0,11.784,1.395,21.336,18.136,21.336 c8.13,0,45.742-9.553,45.742-21.336C504.846,240.619,467.235,231.066,459.105,231.066z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(239, 231, 72)"
|
||||
d="M420.744,130.577c-14.497,8.37-10.93,17.341-5.038,27.546c5.892,10.205,11.877,17.78,26.375,9.41 c7.041-4.065,34.837-31.144,28.945-41.349C465.134,115.979,427.785,126.511,420.744,130.577z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(239, 231, 72)"
|
||||
d="M158.127,415.702c-10.205-5.892-19.176-9.46-27.546,5.038c-4.065,7.041-14.598,44.39-4.392,50.282 c10.205,5.892,37.283-21.904,41.349-28.945C175.907,427.578,168.332,421.594,158.127,415.702z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(239, 231, 72)"
|
||||
d="M418.261,252.403c0-45.799-18.564-87.263-48.577-117.276L135.132,369.679 c30.014,30.013,71.477,48.578,117.276,48.578C344.006,418.257,418.261,344.001,418.261,252.403z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(250, 242, 175)"
|
||||
d="M158.09,89.065c-7.67,4.453-14.679,7.587-21.277,2.557c-2.144-1.567-4.206-4.041-6.268-7.587 c-4.041-7.01-14.597-44.367-4.371-50.223c9.814-5.69,34.967,19.545,40.657,27.874c0.33,0.412,0.577,0.742,0.742,1.072 C175.903,77.189,168.316,83.209,158.09,89.065z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(250, 242, 175)"
|
||||
d="M273.709,45.687c0,0.577,0,1.155-0.083,1.65c-0.577,15.174-9.814,16.493-21.194,16.493 c-4.288,0-8.247-0.165-11.628-1.237c-0.907-0.247-1.732-0.659-2.556-1.072c-2.722-1.402-4.866-3.711-6.02-7.422 c-0.083-0.083,0-0.083,0-0.083c-0.742-2.227-1.155-5.03-1.155-8.329c0-4.865,3.464-20.452,8.824-32.08 c3.216-7.01,7.175-12.617,11.381-13.442C251.69,0.083,252.02,0,252.432,0c3.547,0,6.927,3.463,9.814,8.494 c0.99,1.649,1.897,3.464,2.804,5.443C270.328,25.482,273.709,40.904,273.709,45.687z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(250, 242, 175)"
|
||||
d="M89.147,158.09c-5.937,10.226-11.875,17.813-26.39,9.484c-2.969-1.732-9.648-7.505-15.916-14.432 c-0.082-0.083-0.165-0.165-0.165-0.248c-8.577-9.401-16.246-20.864-12.865-26.719c5.855-10.226,43.213,0.33,50.222,4.371 c5.195,3.051,8.164,6.185,9.401,9.401C95.662,145.637,92.858,151.658,89.147,158.09z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(250, 242, 175)"
|
||||
d="M63.83,252.432c0,11.793-1.402,21.277-18.142,21.277H45.44c-5.03-0.083-20.122-3.382-31.503-8.577 c-2.886-1.402-5.608-2.804-7.835-4.371c-0.082,0-0.082,0-0.082,0C2.309,258.205,0,255.401,0,252.432c0-0.33,0-0.742,0.165-1.072 c0.742-4.041,5.69-7.669,12.04-10.886c11.793-5.608,28.451-9.401,33.482-9.401c1.897,0,3.629,0.165,5.196,0.412 c6.762,0.99,9.978,4.288,11.545,8.824c0.412,1.072,0.66,2.309,0.825,3.546C63.748,246.412,63.83,249.381,63.83,252.432z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(250, 242, 175)"
|
||||
d="M84.034,374.237c-5.196,3.051-27.379,9.649-40.739,8.576c-1.567-0.083-2.969-0.33-4.288-0.742 c-2.392-0.66-4.206-1.815-5.195-3.464c-0.908-1.567-1.072-3.629-0.577-5.855c2.804-12.206,23.503-32.08,29.523-35.461 c2.969-1.732,5.608-2.804,7.917-3.216c7.917-1.732,12.453,2.969,16.659,9.566c0.577,0.99,1.237,1.979,1.814,3.051 c2.062,3.711,3.959,7.175,4.701,10.556C95.25,363.268,93.353,368.876,84.034,374.237z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(250, 242, 175)"
|
||||
d="M346.688,89.104c10.205,5.892,19.176,9.46,27.546-5.038c4.065-7.041,14.598-44.39,4.393-50.282 c-10.205-5.892-37.284,21.904-41.349,28.945C328.908,77.228,336.483,83.213,346.688,89.104z"
|
||||
/>
|
||||
<path
|
||||
style="fill: rgb(250, 242, 175)"
|
||||
d="M369.701,135.164l-0.743,0.742l-3.381,3.381L135.164,369.701 c-2.474-2.474-4.783-4.948-7.092-7.587c-6.185-7.009-11.793-14.514-16.741-22.513c-15.668-25.318-24.74-55.171-24.74-87.168 c0-91.621,74.221-165.842,165.842-165.842c29.936,0,58.057,7.917,82.385,21.936C347.6,115.784,359.31,124.773,369.701,135.164z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
6
src/assets/github.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512" aria-description="GitHub icon">
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
|
||||
<path
|
||||
d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3 .3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5 .3-6.2 2.3zm44.2-1.7c-2.9 .7-4.9 2.6-4.6 4.9 .3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3 .7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3 .3 2.9 2.3 3.9 1.6 1 3.6 .7 4.3-.7 .7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3 .7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3 .7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
6
src/assets/linkedin.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" aria-description="LinkedIn icon">
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
|
||||
<path
|
||||
d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 698 B |
6
src/assets/mastodon.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" aria-description="Mastodon icon">
|
||||
<!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
|
||||
<path
|
||||
d="M433 179.1c0-97.2-63.7-125.7-63.7-125.7-62.5-28.7-228.6-28.4-290.5 0 0 0-63.7 28.5-63.7 125.7 0 115.7-6.6 259.4 105.6 289.1 40.5 10.7 75.3 13 103.3 11.4 50.8-2.8 79.3-18.1 79.3-18.1l-1.7-36.9s-36.3 11.4-77.1 10.1c-40.4-1.4-83-4.4-89.6-54a102.5 102.5 0 0 1 -.9-13.9c85.6 20.9 158.7 9.1 178.8 6.7 56.1-6.7 105-41.3 111.2-72.9 9.8-49.8 9-121.5 9-121.5zm-75.1 125.2h-46.6v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.3V197c0-58.5-64-56.6-64-6.9v114.2H90.2c0-122.1-5.2-147.9 18.4-175 25.9-28.9 79.8-30.8 103.8 6.1l11.6 19.5 11.6-19.5c24.1-37.1 78.1-34.8 103.8-6.1 23.7 27.3 18.4 53 18.4 175z"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 853 B |
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 166 KiB |
14
src/entry-client.tsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Entry point for development
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import Body from "./Body";
|
||||
import Head from "./Head";
|
||||
|
||||
if (!import.meta.env.SSR) {
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
<Head />
|
||||
<Body />
|
||||
</StrictMode>,
|
||||
);
|
||||
}
|
22
src/entry-server.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Entry point for SSG
|
||||
import { renderToString } from "react-dom/server";
|
||||
import Body from "./Body";
|
||||
import Head from "./Head";
|
||||
import style from "./style.css?inline";
|
||||
|
||||
export const render = () => {
|
||||
const html =
|
||||
"<!doctype html>" +
|
||||
renderToString(
|
||||
<html lang="en">
|
||||
<head>
|
||||
<Head />
|
||||
<style type="text/css">{style}</style>
|
||||
</head>
|
||||
<body>
|
||||
<Body />
|
||||
</body>
|
||||
</html>,
|
||||
);
|
||||
return { html };
|
||||
};
|
42
style.css → src/style.css
Executable file → Normal file
|
@ -1,5 +1,34 @@
|
|||
:root {
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
Roboto,
|
||||
Oxygen,
|
||||
Ubuntu,
|
||||
Cantarell,
|
||||
"Open Sans",
|
||||
"Helvetica Neue",
|
||||
sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
:root {
|
||||
font-size: 1.5rem;
|
||||
color-scheme: light dark;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Material Light (https://github.com/dexpota/kitty-themes/blob/master/themes/Material.conf) */
|
||||
--light-color0: #212121;
|
||||
|
@ -187,7 +216,6 @@
|
|||
}
|
||||
|
||||
body {
|
||||
/* Actual useful styles */
|
||||
--highlight: var(--color6);
|
||||
color: var(--foreground);
|
||||
background: var(--background);
|
||||
|
@ -201,12 +229,13 @@ body {
|
|||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
|
||||
--anim-duration: 0.25s;
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
transition: color var(--anim-duration) ease, background-color var(--anim-duration) ease;
|
||||
transition:
|
||||
color var(--anim-duration) ease,
|
||||
background-color var(--anim-duration) ease;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,7 +318,7 @@ p {
|
|||
|
||||
.blocks {
|
||||
letter-spacing: -1px;
|
||||
line-height: 1lh;
|
||||
line-height: 0.9lh;
|
||||
}
|
||||
|
||||
br {
|
||||
|
@ -297,7 +326,7 @@ br {
|
|||
margin: 0;
|
||||
line-height: calc(1lh - 1px);
|
||||
:after {
|
||||
content: '\0200B';
|
||||
content: "\0200B";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,6 +373,9 @@ span {
|
|||
cursor: grab;
|
||||
transition-duration: var(--anim-duration);
|
||||
|
||||
svg {
|
||||
transition: all var(--anim-duration) ease;
|
||||
}
|
||||
svg:hover {
|
||||
filter: brightness(85%);
|
||||
}
|
34
src/vite-env.d.ts
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
/// <reference types="vite/client" />
|
||||
/// <reference types="vite-plugin-svgr/client" />
|
||||
|
||||
// Imagetools types inspired by: https://github.com/JonasKruckenberg/imagetools/issues/160
|
||||
// These only work for my specific imports
|
||||
declare module "*as=metadata" {
|
||||
interface Metadata {
|
||||
src: string;
|
||||
width: number;
|
||||
height: number;
|
||||
format: string;
|
||||
}
|
||||
const output: Metadata;
|
||||
export default output;
|
||||
}
|
||||
|
||||
declare module "*as=picture" {
|
||||
type Primaries = {
|
||||
avif: string;
|
||||
// jxl: string; // Broken right now
|
||||
webp: string;
|
||||
};
|
||||
type Fallback = {
|
||||
src: string;
|
||||
w: number;
|
||||
h: number;
|
||||
};
|
||||
type Picture = {
|
||||
sources: Primaries;
|
||||
img: Fallback;
|
||||
};
|
||||
const output: Picture;
|
||||
export default output;
|
||||
}
|
26
tsconfig.app.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
7
tsconfig.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./tsconfig.app.json" },
|
||||
{ "path": "./tsconfig.node.json" }
|
||||
]
|
||||
}
|
24
tsconfig.node.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2023"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
25
vite.config.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import react from "@vitejs/plugin-react";
|
||||
import { defineConfig } from "vite";
|
||||
import { createHtmlPlugin } from "vite-plugin-html";
|
||||
import { imagetools } from "vite-imagetools";
|
||||
import svgr from "vite-plugin-svgr";
|
||||
|
||||
export default defineConfig({
|
||||
base: "https://mmbradley.ca/",
|
||||
clearScreen: false,
|
||||
plugins: [
|
||||
createHtmlPlugin({
|
||||
minify: true,
|
||||
}),
|
||||
imagetools(),
|
||||
react(),
|
||||
svgr({
|
||||
svgrOptions: {
|
||||
plugins: ["@svgr/plugin-svgo", "@svgr/plugin-jsx"],
|
||||
svgoConfig: {
|
||||
floatPrecision: 2,
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|