Archived
1
0
Fork 0

Compare commits

..

No commits in common. "491c7ba3c1b6b07e5eb6f9a9c96d496f81d2587b" and "d96b630aeee1910e01582566e77a981ba1e7a98f" have entirely different histories.

39 changed files with 220 additions and 8519 deletions

View file

@ -1,73 +0,0 @@
module.exports = {
env: {
es2020: true,
node: true,
'astro/astro': true,
},
plugins: ['simple-import-sort', 'unused-imports'],
extends: [
'plugin:astro/recommended',
'prettier',
'eslint:recommended',
'plugin:json/recommended',
'plugin:tailwindcss/recommended',
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
rules: {
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
'no-unused-vars': 'off', // or "@typescript-eslint/no-unused-vars": "off",
'unused-imports/no-unused-imports': 'error',
'unused-imports/no-unused-vars': [
'warn',
{
vars: 'all',
varsIgnorePattern: '^_',
args: 'after-used',
argsIgnorePattern: '^_',
},
],
},
overrides: [
{
// Define the configuration for `.astro` file.
files: ['*.astro'],
// Allows Astro components to be parsed.
parser: 'astro-eslint-parser',
// Parse the script in `.astro` as TypeScript by adding the following configuration.
// It's the setting you need when using TypeScript.
parserOptions: {
parser: '@typescript-eslint/parser',
extraFileExtensions: ['.astro'],
sourceType: 'module',
},
rules: {
// override/add rules settings here, such as:
// "astro/no-set-html-directive": "error"
'astro/no-conflict-set-directives': 'error',
'astro/no-unused-define-vars-in-style': 'error',
},
},
{
files: ['**/*.astro/*.js', '*.astro/*.js'],
env: {
browser: true,
es2020: true,
},
parserOptions: {
sourceType: 'module',
},
rules: {
// override/add rules settings here, such as:
// "no-unused-vars": "error"
// If you are using "prettier/prettier" rule,
// you don't need to format inside <script> as it will be formatted as a `.astro` file.
'prettier/prettier': 'off',
},
},
],
}

View file

@ -1,24 +0,0 @@
module.exports = {
plugins: [
require.resolve('prettier-plugin-astro'),
require.resolve('prettier-plugin-sort-imports'),
require.resolve('prettier-plugin-tailwindcss'),
],
overrides: [
{
files: '*.astro',
options: {
parser: 'astro',
},
},
],
pluginSearchDirs: false,
trailingComma: 'es5',
tabWidth: 4,
semi: false,
singleQuote: true,
printWidth: 80,
importOrder: ['^@core/(.*)$', '^@server/(.*)$', '^@ui/(.*)$', '^[./]'],
importOrderSeparation: true,
importOrderSortSpecifiers: true,
}

View file

@ -1,3 +0,0 @@
[tools]
node = 'lts'
pnpm = 'latest'

View file

@ -1,4 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

18
.vscode/launch.json vendored
View file

@ -1,11 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

View file

@ -1,7 +0,0 @@
{
"prettier.documentSelectors": ["**/*.astro"],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"files.associations": {
"*.mdx": "markdown"
}
}

View file

@ -12,6 +12,7 @@ npm create astro@latest -- --template basics
![basics](https://user-images.githubusercontent.com/4677417/186188965-73453154-fdec-4d6b-9c34-cb35c248ae5b.png)
## 🚀 Project Structure
Inside of your Astro project, you'll see the following folders and files:

View file

@ -1,36 +0,0 @@
import { defineConfig } from 'astro-imagetools/config'
export default defineConfig({
placeholder: 'blurred',
format: ['webp', 'jpg'],
fallbackFormat: 'png',
includeSourceFormat: false,
formatOptions: {
jpg: {
quality: 80,
},
png: {
quality: 80,
},
webp: {
quality: 50,
},
tracedSVG: {
function: 'trace',
options: {
background: '#fff',
color: '#000',
turnPolicy: 'black',
turdSize: 1,
alphaMax: 1,
optCurve: true,
threshold: 100,
blackOnWhite: false,
},
},
},
sizes: (breakpoints) => {
const maxWidth = breakpoints[breakpoints.length - 1]
return `(min-width: ${maxWidth}px) ${maxWidth}px, 100vw`
},
})

View file

@ -1,45 +1,8 @@
import mdx from '@astrojs/mdx'
import partytown from '@astrojs/partytown'
import prefetch from '@astrojs/prefetch'
import sitemap from '@astrojs/sitemap'
import tailwind from '@astrojs/tailwind'
import { defineConfig } from 'astro/config'
import compress from 'astro-compress'
import icon from 'astro-icon'
import { astroImageTools } from 'astro-imagetools'
import robotsTxt from 'astro-robots-txt'
import rehypeExternalLinks from 'rehype-external-links'
import { defineConfig } from 'astro/config';
import tailwind from "@astrojs/tailwind";
// https://astro.build/config
export default defineConfig({
site: 'https://ethanreece.com',
integrations: [
tailwind(),
astroImageTools,
robotsTxt(),
sitemap(),
prefetch(),
partytown(),
mdx({
syntaxHighlight: 'shiki',
shikiConfig: { theme: 'dracula' },
rehypePlugins: [
[
rehypeExternalLinks,
{
target: '_blank',
rel: ['noopener', 'noreferrer'],
},
],
],
}),
icon({
include: {
heroicons: ['*'],
'fa-brands': ['*'],
'simple-icons': ['*'],
},
}),
compress(),
],
})
integrations: [tailwind()]
});

BIN
bun.lockb Executable file

Binary file not shown.

View file

@ -1,57 +1,25 @@
{
"name": "ethanreece.com",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/mdx": "^0.19.7",
"@astrojs/partytown": "^1.2.3",
"@astrojs/prefetch": "^0.2.3",
"@astrojs/sitemap": "^1.3.3",
"@astrojs/tailwind": "^4.0.0",
"@fontsource-variable/jetbrains-mono": "^5.0.5",
"@tailwindcss/typography": "^0.5.9",
"astro": "^2.8.0",
"astro-auto-import": "^0.3.0",
"astro-compress": "^1.1.50",
"astro-imagetools": "^0.8.1",
"astro-navbar": "^2.0.1",
"astro-robots-txt": "^0.5.0",
"astro-seo": "^0.7.4",
"rehype-external-links": "^2.1.0",
"sharp": "^0.32.1",
"tailwind-bootstrap-grid": "^5.0.1",
"tailwindcss-hero-patterns": "^0.1.2"
},
"devDependencies": {
"@iconify-json/fa-brands": "^1.1.4",
"@iconify-json/heroicons": "^1.1.11",
"@iconify-json/simple-icons": "^1.1.59",
"@typescript-eslint/parser": "^5.61.0",
"astro-icon": "1.0.0-next.2",
"autoprefixer": "^10.4.14",
"concurrently": "^8.2.0",
"cssnano": "^6.0.1",
"eslint": "^8.44.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-astro": "^0.27.2",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-jsonc": "^2.9.0",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-simple-import-sort": "^10.0.0",
"eslint-plugin-tailwindcss": "^3.13.0",
"eslint-plugin-unused-imports": "^3.0.0",
"find-up": "^6.3.0",
"prettier": "^2.8.8",
"prettier-plugin-astro": "^0.10.0",
"prettier-plugin-sort-imports": "^1.7.2",
"prettier-plugin-tailwindcss": "^0.3.0",
"tailwindcss": "^3.3.2"
}
}
"name": "ethanreece.com",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/tailwind": "^3.1.3",
"astro": "^2.5.0",
"tailwindcss": "^3.0.24eslint-plugin-jsx-a11y"
},
"devDependencies": {
"@typescript-eslint/parser": "^5.59.7",
"eslint": "^8.41.0",
"eslint-plugin-astro": "^0.27.0",
"eslint-plugin-jsx-a11y": "^6.7.1",
"prettier": "^2.8.8",
"prettier-plugin-astro": "^0.9.0"
}
}

7629
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +0,0 @@
module.exports = {
plugins: {
autoprefixer: {},
cssnano: {},
},
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 MiB

View file

@ -1,22 +0,0 @@
---
import { Icon } from 'astro-icon/components'
export interface Props {
link: string
icon?: string
external?: boolean
}
const { link, icon, external } = Astro.props
const buttonPaddingX = 'md:px-[.75rem] px-[.5rem] md:gap-[.5rem] gap-[.5rem]'
const buttonPaddingY = 'py-[.5rem]'
---
<a
href={link}
target={external ? '_blank' : '_self'}
rel={external ? 'noopener noreferrer' : ''}
class={`flex flex-row items-center rounded hover:bg-background-hover hover:text-font-hover focus-visible:bg-background-hover focus-visible:text-font-hover focus-visible:outline-none ${buttonPaddingX} ${buttonPaddingY}`}
>
{icon && <Icon name={icon} />}
<slot />
</a>

63
src/components/Card.astro Normal file
View file

@ -0,0 +1,63 @@
---
export interface Props {
title: string;
body: string;
href: string;
}
const { href, title, body } = Astro.props;
---
<li class="link-card">
<a href={href}>
<h2>
{title}
<span>&rarr;</span>
</h2>
<p>
{body}
</p>
</a>
</li>
<style>
.link-card {
list-style: none;
display: flex;
padding: 0.25rem;
background-color: white;
background-image: none;
background-size: 400%;
border-radius: 0.6rem;
background-position: 100%;
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
}
.link-card > a {
width: 100%;
text-decoration: none;
line-height: 1.4;
padding: 1rem 1.3rem;
border-radius: 0.35rem;
color: #111;
background-color: white;
opacity: 0.8;
}
h2 {
margin: 0;
font-size: 1.25rem;
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
p {
margin-top: 0.5rem;
margin-bottom: 0;
color: #444;
}
.link-card:is(:hover, :focus-within) {
background-position: 0;
background-image: var(--accent-gradient);
}
.link-card:is(:hover, :focus-within) h2 {
color: rgb(var(--accent));
}
</style>

View file

@ -1,30 +0,0 @@
---
const paddingX = 'px-[.75rem]'
const paddingY = 'py-[.5rem]'
interface NavItem {
text: string
link: string
}
const links: NavItem[] = [{ text: 'site credits', link: '/credits' }]
const year = new Date().getFullYear()
---
<section>
<footer class={`flex bg-background-light ${paddingX} ${paddingY}`}>
<span class="mr-auto">Copyright Ethan Reece {year}</span>
<nav>
{
links.map((link) => (
<a
href={link.link}
class="hover:underline focus-visible:underline focus-visible:outline-none"
>
{link.text}
</a>
))
}
</nav>
</footer>
</section>

View file

@ -1,4 +0,0 @@
export interface NavItem {
text: string
link: string
}

View file

@ -1,50 +0,0 @@
---
import ButtonSecondary from '../../ButtonSecondary.astro'
interface NavItem {
text: string
link: string
}
const homeText = 'Ethan Reece'
const links: NavItem[] = [
{ text: 'About Me', link: '/#about' },
{ text: 'Projects', link: '/#projects' },
{ text: 'Experience', link: '/#experience' },
{ text: 'Hobbies', link: '/#hobbies' },
{ text: 'Contact Me', link: '/#contact' },
]
const paddingX = 'px-[.75rem]'
const paddingY = 'py-[.25rem]'
const spacing = 'space-x-[.25rem]'
const mainButtonPaddingX = 'px-[.75rem]'
const mainButtonPaddingY = 'py-[.5rem]'
---
<section class="fixed z-navbar w-full backdrop-blur-sm">
<div
class={`max-h-navbar-h bg-background-light ${paddingX} ${paddingY} opacity-80`}
>
<nav
class={`flex w-full items-center whitespace-nowrap font-normal ${spacing}`}
>
<a
href="/"
rel="prefetch"
class=`mr-auto text-[1.25rem] font-bold hover:underline focus-visible:underline focus-visible:outline-none ${mainButtonPaddingX} ${mainButtonPaddingY}`
>{homeText}</a
>
<div class={`sm:flex items-center hidden ${spacing}`}>
{
links.map((link) => (
<ButtonSecondary link={link.link}>
{link.text}
</ButtonSecondary>
))
}
</div>
</nav>
</div>
</section>

View file

@ -1,8 +0,0 @@
---
layout: './Section.astro'
title: 'About Me'
slug: 'about'
background: true
---
I am a sophomore at the University of Texas at Dallas who loves programming and tech in general. Although web development and web hosting are my main interests, I enjoy branching out and exploring other ways to work with technology and create things.

View file

@ -1,14 +0,0 @@
---
layout: './Section.astro'
title: 'Contact Me'
slug: 'contact'
background: true
---
import Socials from './Socials.astro'
Are you looking for help on a web project, or interested in learning more about myself or my projects?
Feel free to contact or follow me at any time using these links:
<Socials />

View file

@ -1,34 +0,0 @@
---
layout: './Section.astro'
title: 'Experience & Skills'
slug: 'experience'
background: true
---
import Subsection from './Subsection.astro'
Although I am most familiar with JavaScript and C#, I have used several other programming languages [i.e. Java, Python, C++, Kotlin] and can quickly learn new ones.
I have also used multiple web frameworks. I am most familiar with Express.js and React, but I have also used ASP.NET, Astro, and a bit of Django and Next.js. I plan to become more familiar with Django, Rails, and Laravel for backend along with Svelte and SolidJS for frontend.
I am also familiar with Linux since I use Arch Linux on my laptop and work with Linux Debian VMs on my server. Along with that, I have worked with PostgreSQL and MS SQL in my projects and at work, and I have also touched Google Cloud and Azure, using them for my self-hosted cloud, a cybersecurity course, and for work-related tasks.
Although I have learned most of these skills in my spare time, I have also used them in my internships:
<Subsection title="Scrumfish" subtitle="Nampa, ID" url="https://scrumfish.com/">
Worked on backend and frontend for multiple projects using ASP.NET, MS SQL,
and React to create APIs, a login system with MFA, and functional frontend
components. Rewrote part of a web app to open EPUB documents, enable users
to highlight text and comment, and position those comments relative to the
highlighted text.
</Subsection>
<Subsection
title="R-Technics"
subtitle="Boise, ID"
url="https://www.rtechnics.com/"
>
Performed Windows server maintenance tasks and created a prototype in C# to
pull song data using the SongSelect API, which was later integrated into the
company's main product.
</Subsection>

View file

@ -1,48 +0,0 @@
---
// @ts-ignore
import { Picture } from 'astro-imagetools/components'
const viewHeight = 'md:h-[30rem] sm:h-[15rem] h-[17rem]'
const padding = 'p-[1rem] pb-[3.5rem] md:p-[2rem] sm:pb-[2rem]'
const textMainSize = 'text-[2rem]'
const textEmphasisSize = 'md:text-[4rem] text-[3rem]'
const textEmphasisLineHeight = 'leading-[3.5rem]'
const text = ['Hello', ', I am', 'Ethan Reece', 'and I do ', 'web stuff', '.']
const image = '../public/images/index/myself.png'
const imageAlt = 'black and white portrait of myself'
---
<section class={`w-full ${viewHeight} ${padding}`}>
<header
class="mx-auto flex h-full max-w-page-w items-center text-center sm:max-w-[32rem] sm:text-left md:max-w-page-w"
>
<h1 class={`font-medium ${textMainSize} w-full sm:w-auto`}>
<i
><b><u>{text[0]}</u></b><span class="text-font-light"
>{text[1]}</span
></i
>
<br />
<b
class={`font-extrabold ${textEmphasisSize} ${textEmphasisLineHeight}`}
>{text[2]}</b
>
<br />
<i
><span class="text-font-light">{text[3]}</span>
<b class="font-extrabold"><u>{text[4]}</u></b></i
><span class="text-font-light">{text[5]}</span>
</h1>
<div class="ml-auto hidden h-full sm:flex">
<Picture
src={image}
alt={imageAlt}
fit="cover"
layout="fill"
placeholder="none"
/>
</div>
</header>
</section>

View file

@ -1,8 +0,0 @@
---
layout: './Section.astro'
title: 'Hobbies'
slug: 'hobbies'
background: false
---
Besides programming and working with technology, I enjoy biking and playing Minecraft modpacks. Biking gives me a way to explore the outdoors while traveling to where I need to go, and it is also less costly and more environmentally sustainable than travelling via car.

View file

@ -1,57 +0,0 @@
---
layout: './Section.astro'
title: 'Projects'
slug: 'projects'
background: false
---
import Subsection from './Subsection.astro'
My biggest personal project so far is building a server to self-host my cloud ecosystem. My server uses a Proxmox hypervisor along with Linux Debian VMs and Docker containers running services such as TrueNAS, Syncthing, Nextcloud, Plex, Forejo, Pterodactyl, GoToSocial, Lemmy, and others. To get around carrier-grade NAT limitations, I host a VPN using Google Cloud and use nftables to route traffic so I can make services publicly accessible.
I also have other projects viewable on multiple git platforms, most of which came from hackathons, game jams, and school projects. Of these, the most interesting are:
<Subsection
title="FFmpeg automated build system"
subtitle="R-Technics 2023"
url="https://github.com/rtechnics/ffmpeg"
>
GitHub Actions workflow that automatically checks for the latest FFmpeg
release tag, cross-compiles it for Windows using automatically compiled
OpenSSL libraries from another workflow, and generates a WiX installer and
NuGet package for internal business use.
</Subsection>
<Subsection
title="GroceRead"
subtitle="HackAI, UTD 2023"
url="https://devpost.com/software/groceread"
>
Android app intended to help visually-impaired people navigate grocery
stores by telling the user the product the phone camera is pointed at. Uses
Chooch API for object detection.
</Subsection>
<Subsection
title="Med-Terms"
subtitle="Axxess Hackathon, UTD 2023"
url="https://devpost.com/software/med-terms"
>
Educational chatbot that teaches anatomical terminology and suggests others
for the user to learn about. Wrote the API layer of the backend using
Django, and created most of the frontend using React.
</Subsection>
<Subsection
title="Score Tracker"
subtitle="HS senior project"
url="https://git.sudoer.ch/sudoer777/score-tracker"
>
Web app that allows coaches of HS sports teams to submit game scores. Scores
would then be publicly viewable on the app's homepage and could be managed
through an admin interface. Created with Express.js, PostgreSQL, and vanilla
JavaScript for frontend. This was my first personal web project developed
from scratch.
</Subsection>
Some other projects and activities I have worked on include [Med Check [MetroHacks 2022]](https://devpost.com/software/medcheck-sopt84), [WitchBlade [UTD SGDA 2023 Spring Jam]](https://itch.io/jam/spring23-jam/rate/1968464), [Dungeons & Debuffs [UTD SGDA 2022 Thanksgiving Jam]](https://itch.io/jam/sgda-thanksgiving-jam/rate/1810971), [ZipVersionControl [FLL #1790, yrs 2017-2019]](https://github.com/TheEthan8or/ZipVersionControl), FIRST Tech Challenge robotics [2021-2022], and FIRST Lego League robotics [2013-2019, #1790].

View file

@ -1,32 +0,0 @@
---
import type { MDXLayoutProps } from 'astro'
type Props = MDXLayoutProps<{
title: string
slug: string
background: boolean
}>
const { title, slug, background } = Astro.props.frontmatter
const fontSize = 'text-[1rem]'
const fontSizeH2 = 'text-[1.5rem]'
const paddingT = 'pt-[1.5rem]'
const paddingB = 'pb-[2.5rem]'
const anchorDistance = 'mt-[-5rem] pt-[5rem]'
---
<section
class={`px-screen-x ${paddingT} ${paddingB} ${fontSize} ${
background ? 'bg-background-dark' : ''
}`}
>
<div class={anchorDistance} id={slug}>
<div class={`mx-auto max-w-page-w space-y-paragraph prose`}>
<h2 class={`font-bold ${fontSizeH2}`}>
{title}
</h2>
<slot />
</div>
</div>
</section>

View file

@ -1,91 +0,0 @@
---
import ButtonSecondary from '../../ButtonSecondary.astro'
interface SocialExtra {
name: string
url: string
external?: boolean
}
interface Social {
name?: string
profile: string
url: string
extra?: SocialExtra[]
icon?: string
}
const socials: Social[] = [
{
name: 'Email',
profile: 'contact@ethanreece.com',
url: 'mailto:contact@ethanreece.com',
icon: 'heroicons:envelope-solid',
extra: [
{
name: 'PGP key',
url: '',
},
],
},
{
name: 'GitHub (Personal)',
profile: 'Sudoer777',
url: 'https://gh.sudoer.ch/sudoer777',
icon: 'fa-brands:github',
},
{
name: 'GitHub (R-Technics)',
profile: 'ethanreece-rtechnics',
url: 'https://gh.sudoer.ch/ethanreece-rtechnics',
icon: 'heroicons:briefcase-solid',
},
{
name: 'GitHub (Scrumfish)',
profile: 'ethanreece-scrumfish',
url: 'https://gh.sudoer.ch/ethanreece-scrumfish',
icon: 'heroicons:briefcase-solid',
},
{
name: 'Forgejo',
profile: 'me@git.sudoer.ch',
url: 'https://git.sudoer.ch/me',
icon: 'simple-icons:forgejo',
},
{
name: 'Mastodon (GoToSocial)',
profile: '@me@gts.sudoer.ch',
url: 'https://elk.sudoer.ch/@me@gts.sudoer.ch',
icon: 'fa-brands:mastodon',
},
{
name: 'Devpost',
profile: 'sudoer777',
url: 'https://devpost.com/sudoer777',
icon: 'simple-icons:devpost',
},
{
name: 'LinkedIn',
profile: '-ethanreece-',
url: 'https://www.linkedin.com/in/-ethanreece-/',
icon: 'fa-brands:linkedin',
},
]
---
<div class="not-prose flex flex-col">
{
socials.map((s) => (
<div class="flex">
<ButtonSecondary link={s.url} external={true} icon={s.icon}>
<b class="font-extrabold">{s.name}:</b>
{s.profile}
</ButtonSecondary>
{s.extra &&
s.extra.map((e) => (
<ButtonSecondary link={e.url} external={e.external}>
[{e.name}]
</ButtonSecondary>
))}
</div>
))
}
</div>

View file

@ -1,40 +0,0 @@
---
export interface Props {
title: string
subtitle: string
url: string | null
}
const { title, subtitle, url } = Astro.props
const fontSize = 'text-[.9rem]'
const fontSizeH3 = 'text-[1.4rem]'
const fontSpacing = 'leading-[1.5rem]'
const margin = 'm-[-1rem] p-[1rem]'
const background = 'bg-[#00000020]'
---
<a
href={url}
target="_blank"
rel="noopener noreferrer"
class={`block md:rounded ${
url &&
`hover:bg-background-hover hover:text-font-hover focus-visible:bg-background-hover focus-visible:text-font-hover focus-visible:outline-none not-prose no-underline font-extralight`
} ${fontSize} ${margin} ${background}`}
>
<div class={`mx-auto w-full md:w-auto max-w-page-w space-y-paragraph`}>
<span class={`flex flex-col`}>
<h3 class={`font-bold ${fontSizeH3}`}>{title}</h3>
{
subtitle && (
<span class={`font-thin italic ${fontSpacing}`}>
{subtitle}
</span>
)
}
</span>
<slot />
</div>
</a>

2
src/env.d.ts vendored
View file

@ -1,3 +1 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />
/// <reference types="astro-imagetools" />

View file

@ -1,28 +0,0 @@
---
import type { MDXLayoutProps } from 'astro'
import Base from './Base.astro'
type Props = MDXLayoutProps<{
title: string
description: string
}>
const { title, description } = Astro.props.frontmatter
---
<Base title={`${title} - Ethan Reece`} description={description}>
<article class="prose mx-auto px-screen-x">
<div class="mx-auto max-w-page-w">
<section>
<header>
<h1>
{title}
</h1>
</header>
</section>
<section>
<slot />
</section>
</div>
</article>
</Base>

View file

@ -1,33 +0,0 @@
---
import { SEO } from 'astro-seo'
import Footer from '../components/content/global/Footer.astro'
import Navbar from '../components/content/global/Navbar.astro'
import Background from './properties/Background.astro'
import Head from './properties/Head.astro'
export interface Props {
title: string
description: string
}
const { title, description } = Astro.props
import '@fontsource-variable/jetbrains-mono'
---
<!DOCTYPE html>
<html lang="en">
<Head title={title} description={description}>
<SEO title={title} description={description} />
</Head>
<body class="min-h-screen w-screen font-main font-light text-font">
<Background>
<Navbar />
<main class="mb-auto pt-navbar-h">
<slot />
</main>
<Footer class="mb-auto" />
</Background>
</body>
</html>

36
src/layouts/Layout.astro Normal file
View file

@ -0,0 +1,36 @@
---
export interface Props {
title: string;
}
const { title } = Astro.props;
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="description" content="Astro description">
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body>
<slot />
</body>
</html>
<style is:global>
:root {
--accent: 124, 58, 237;
--accent-gradient: linear-gradient(45deg, rgb(var(--accent)), #da62c4 30%, white 60%);
}
html {
font-family: system-ui, sans-serif;
background-color: #F6F6F6;
}
code {
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
Bitstream Vera Sans Mono, Courier New, monospace;
}
</style>

View file

@ -1,11 +0,0 @@
---
const pattern = 'heropattern-circuitboard-pattern'
---
<div class="min-h-screen bg-background">
<div
class={`flex min-h-screen w-full bg-circuitboard bg-repeat flex-col ${pattern}`}
>
<slot />
</div>
</div>

View file

@ -1,7 +0,0 @@
<head>
<slot />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
</head>

View file

@ -1,22 +0,0 @@
---
layout: '../layouts/Article.astro'
title: 'Site Credits'
---
This site was built using the following tools:
| | |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| **Framework:** | Astro with TypeScript and MDX |
| **Runtime:** | Node.js |
| **Version management:** | rtx |
| **Package management:** | pnpm |
| **Layout:** | Tailwind CSS (with Astro extension) |
| **Font:** | JetBrains Mono (using Fontsource) |
| **Icons:** | Hero Icons, Font Awesome Brands, Simple Icons (using Astro Icon) |
| **Circuitboard Pattern:** | Hero Patterns |
| **IDE:** | VSCodium |
| **Code formatting:** | Prettier, ESLint, Astro MDX |
| **Optimization:** | Astro Prefetch, Astro Sitemap, Astro Imagetools (using Sharp), Astro Robots.txt, Astro SEO, Astro Compress, Autoprefixer, CSSNano |
| **Contact Frontends** | Elk (Mastodon/GoToSocial), GotHub (GitHub) |
| **Source code:** | [On Forgejo](https://git.sudoer.ch/me/ethanreece.com) |

View file

@ -1,24 +1,81 @@
---
import Hero from '../components/content/index/Hero.astro'
import About from '../components/content/index/About.mdx'
import Projects from '../components/content/index/Projects.mdx'
import Experience from '../components/content/index/Experience.mdx'
import Hobbies from '../components/content/index/Hobbies.mdx'
import Contact from '../components/content/index/Contact.mdx'
import Base from '../layouts/Base.astro'
const title = 'Ethan Reece'
const description = ''
import Layout from '../layouts/Layout.astro';
import Card from '../components/Card.astro';
---
<Base title={title} description={description}>
<article>
<Hero />
<About />
<Projects />
<Experience />
<Hobbies />
<Contact />
</article>
</Base>
<Layout title="Welcome to Astro.">
<main>
<h1>Welcome to <span class="text-gradient">Astro</span></h1>
<p class="instructions">
To get started, open the directory <code>src/pages</code> in your project.<br />
<strong>Code Challenge:</strong> Tweak the "Welcome to Astro" message above.
</p>
<ul role="list" class="link-card-grid">
<Card
href="https://docs.astro.build/"
title="Documentation"
body="Learn how Astro works and explore the official API docs."
/>
<Card
href="https://astro.build/integrations/"
title="Integrations"
body="Supercharge your project with new frameworks and libraries."
/>
<Card
href="https://astro.build/themes/"
title="Themes"
body="Explore a galaxy of community-built starter themes."
/>
<Card
href="https://astro.build/chat/"
title="Community"
body="Come say hi to our amazing Discord community. ❤️"
/>
</ul>
</main>
</Layout>
<style>
main {
margin: auto;
padding: 1.5rem;
max-width: 60ch;
}
h1 {
font-size: 3rem;
font-weight: 800;
margin: 0;
}
.text-gradient {
background-image: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 400%;
background-position: 0%;
}
.instructions {
line-height: 1.6;
margin: 1rem 0;
border: 1px solid rgba(var(--accent), 25%);
background-color: white;
padding: 1rem;
border-radius: 0.4rem;
}
.instructions code {
font-size: 0.875em;
font-weight: bold;
background: rgba(var(--accent), 12%);
color: rgb(var(--accent));
border-radius: 4px;
padding: 0.3em 0.45em;
}
.instructions strong {
color: rgb(var(--accent));
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 1rem;
padding: 0;
}
</style>

View file

@ -1,68 +0,0 @@
/** @type {import('tailwindcss').Config} */
const heropatterns = require('tailwindcss-hero-patterns/src/patterns')
module.exports = {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {
typography: {
DEFAULT: {
css: {
color: 'black',
fontWeight: '200',
h1: {
paddingTop: '1rem',
},
'a:hover': {
background: 'black',
color: 'white',
textDecoration: 'none',
},
},
},
},
},
heroPatterns: {
circuitboard: heropatterns.circuitboard,
},
heroPatternsOpacities: ['100'],
heroPatternColors: ['font'],
colors: {
background: '#dbf6db',
'background-dark': '#bbd8bb',
'background-light': '#ffffff',
'background-hover': '#000000cc',
font: '#000000',
'font-light': '#004f07',
'font-hover': '#ffffff',
pattern: 'rgba(0,0,0,.02)',
},
fontFamily: {
main: ['JetBrains Mono Variable', 'monospace'],
},
backgroundSize: {
contain: 'contain',
circuitboard: '40rem',
},
spacing: {
'screen-x': '1rem',
'screen-y': '1.5rem',
'navbar-h': '4rem',
paragraph: '1rem',
},
maxWidth: {
'page-w': '45rem',
},
zIndex: {
navbar: '100',
},
screens: {
sm: '640px',
md: '768px',
},
},
plugins: [
require('tailwindcss-hero-patterns'),
require('@tailwindcss/typography'),
],
}

View file

@ -1,3 +1,3 @@
{
"extends": "astro/tsconfigs/strict"
}
"extends": "astro/tsconfigs/strict"
}