Procházet zdrojové kódy

Create the landing page

Lee Morgan před 2 týdny
rodič
revize
209ff6af5c
6 změnil soubory, kde provedl 379 přidání a 4 odebrání
  1. 6 0
      AGENTS.md
  2. 269 0
      src/app.css
  3. 5 1
      src/lib/assets/favicon.svg
  4. 1 0
      src/routes/+layout.js
  5. 41 1
      src/routes/+layout.svelte
  6. 57 2
      src/routes/+page.svelte

+ 6 - 0
AGENTS.md

@@ -78,3 +78,9 @@ k## Color Rules
 - **Motion**: Short, subtle transitions (150–200ms) on hover/focus. Avoid large animated elements.
 - **Accessibility**: Ensure accent blue meets contrast on dark surfaces. Provide visible focus outlines.
 
+# Code
+
+- Never use TypeScript
+
+# Other
+- Do not ever run the server, I will do that manually

+ 269 - 0
src/app.css

@@ -0,0 +1,269 @@
+:root {
+	--bg: #0a0a0a;
+	--surface: #141414;
+	--text: #f5f5f5;
+	--muted: #a0a0a0;
+	--accent: #4fc3f7;
+	--accent-hover: #81d4fa;
+	--border: #2a2a2a;
+
+	--font: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
+	--mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
+
+	--rail: 22rem;
+	--ease: 180ms ease;
+	--radius: 8px;
+}
+
+*,
+*::before,
+*::after {
+	box-sizing: border-box;
+}
+
+html {
+	color-scheme: dark;
+	background: var(--bg);
+}
+
+html,
+body {
+	margin: 0;
+	padding: 0;
+	min-height: 100%;
+}
+
+body {
+	font-family: var(--font);
+	font-size: 1rem;
+	font-weight: 400;
+	line-height: 1.65;
+	color: var(--text);
+	background: var(--bg);
+	-webkit-font-smoothing: antialiased;
+	-moz-osx-font-smoothing: grayscale;
+}
+
+::selection {
+	background: color-mix(in srgb, var(--accent) 35%, transparent);
+	color: var(--text);
+}
+
+h1,
+h2,
+p,
+dl,
+dt,
+dd {
+	margin: 0;
+}
+
+a {
+	color: var(--accent);
+	text-decoration: none;
+	transition: color var(--ease);
+}
+
+a:hover {
+	color: var(--accent-hover);
+	text-decoration: underline;
+	text-underline-offset: 0.18em;
+}
+
+:focus-visible {
+	outline: 2px solid var(--accent);
+	outline-offset: 3px;
+}
+
+.skip {
+	position: absolute;
+	left: 0.75rem;
+	top: 0.75rem;
+	z-index: 20;
+	padding: 0.5rem 0.75rem;
+	background: var(--surface);
+	border: 1px solid var(--border);
+	border-radius: var(--radius);
+	color: var(--text);
+	transform: translateY(-160%);
+}
+
+.skip:focus {
+	transform: none;
+	text-decoration: none;
+}
+
+.shell {
+	display: grid;
+	grid-template-columns: var(--rail) 1fr;
+	min-height: 100svh;
+}
+
+.rail {
+	position: sticky;
+	top: 0;
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	height: 100svh;
+	padding: 2rem 2rem 1.75rem;
+	border-right: 1px solid var(--border);
+}
+
+.rail-top {
+	display: flex;
+	flex-direction: column;
+	align-items: flex-start;
+	gap: 1.75rem;
+}
+
+.identity {
+	display: flex;
+	flex-direction: column;
+	gap: 0.45rem;
+}
+
+.identity h1 {
+	font-size: 1.25rem;
+	font-weight: 600;
+	letter-spacing: 0.03em;
+	line-height: 1.2;
+}
+
+.wordmark {
+	color: var(--text);
+	text-decoration: none;
+}
+
+.wordmark:hover {
+	color: var(--accent);
+	text-decoration: none;
+}
+
+.role {
+	font-size: 0.9375rem;
+	line-height: 1.45;
+	color: var(--muted);
+}
+
+.status {
+	display: inline-flex;
+	align-items: center;
+	gap: 0.5rem;
+	font-family: var(--mono);
+	font-size: 0.75rem;
+	letter-spacing: 0.06em;
+	color: var(--muted);
+}
+
+.status-dot {
+	width: 0.4rem;
+	height: 0.4rem;
+	background: var(--accent);
+}
+
+.place {
+	font-size: 0.875rem;
+	color: var(--muted);
+}
+
+.menu {
+	list-style: none;
+	margin: 0;
+	padding: 0;
+	display: flex;
+	flex-direction: column;
+	gap: 0.15rem;
+}
+
+.menu a {
+	color: var(--accent);
+	font-size: 1.125rem;
+	font-weight: 500;
+	line-height: 1.45;
+	text-decoration: none;
+	text-underline-offset: 0.18em;
+}
+
+.menu a:hover {
+	color: var(--accent-hover);
+	text-decoration: underline;
+}
+
+.rail-bottom {
+	display: flex;
+	flex-direction: column;
+	gap: 0.35rem;
+}
+
+.rail-bottom a {
+	color: var(--muted);
+	font-size: 0.875rem;
+}
+
+.rail-bottom a:hover {
+	color: var(--accent);
+}
+
+.btn {
+	display: inline-flex;
+	align-items: center;
+	padding: 0.5rem 0.75rem;
+	border-radius: var(--radius);
+	border: 1px solid transparent;
+	background: var(--accent);
+	color: var(--bg);
+	font: inherit;
+	font-size: 0.9375rem;
+	font-weight: 500;
+	letter-spacing: 0.01em;
+	text-decoration: none;
+	transition:
+		background var(--ease),
+		color var(--ease);
+}
+
+.btn:hover {
+	background: var(--accent-hover);
+	color: var(--bg);
+	text-decoration: none;
+}
+
+.page {
+	padding: 2rem clamp(1.5rem, 4vw, 4rem) 4rem;
+}
+
+@media (max-width: 860px) {
+	.shell {
+		grid-template-columns: 1fr;
+	}
+
+	.rail {
+		position: static;
+		height: auto;
+		border-right: 0;
+		border-bottom: 1px solid var(--border);
+		padding: 1.25rem 1.25rem 1.35rem;
+		gap: 1.25rem;
+	}
+
+	.rail-top {
+		gap: 1rem;
+	}
+
+	.rail-bottom {
+		display: none;
+	}
+
+	.page {
+		padding: 1.75rem 1.25rem 3rem;
+	}
+}
+
+@media (prefers-reduced-motion: reduce) {
+	*,
+	*::before,
+	*::after {
+		transition-duration: 0.01ms !important;
+	}
+}

+ 5 - 1
src/lib/assets/favicon.svg

@@ -1 +1,5 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"><title>svelte-logo</title><path d="M94.157 22.819c-10.4-14.885-30.94-19.297-45.792-9.835L22.282 29.608A29.92 29.92 0 0 0 8.764 49.65a31.5 31.5 0 0 0 3.108 20.231 30 30 0 0 0-4.477 11.183 31.9 31.9 0 0 0 5.448 24.116c10.402 14.887 30.942 19.297 45.791 9.835l26.083-16.624A29.92 29.92 0 0 0 98.235 78.35a31.53 31.53 0 0 0-3.105-20.232 30 30 0 0 0 4.474-11.182 31.88 31.88 0 0 0-5.447-24.116" style="fill:#ff3e00"/><path d="M45.817 106.582a20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.503 18 18 0 0 1 .624-2.435l.49-1.498 1.337.981a33.6 33.6 0 0 0 10.203 5.098l.97.294-.09.968a5.85 5.85 0 0 0 1.052 3.878 6.24 6.24 0 0 0 6.695 2.485 5.8 5.8 0 0 0 1.603-.704L69.27 76.28a5.43 5.43 0 0 0 2.45-3.631 5.8 5.8 0 0 0-.987-4.371 6.24 6.24 0 0 0-6.698-2.487 5.7 5.7 0 0 0-1.6.704l-9.953 6.345a19 19 0 0 1-5.296 2.326 20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.502 17.99 17.99 0 0 1 8.13-12.052l26.081-16.623a19 19 0 0 1 5.3-2.329 20.72 20.72 0 0 1 22.237 8.243 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-.624 2.435l-.49 1.498-1.337-.98a33.6 33.6 0 0 0-10.203-5.1l-.97-.294.09-.968a5.86 5.86 0 0 0-1.052-3.878 6.24 6.24 0 0 0-6.696-2.485 5.8 5.8 0 0 0-1.602.704L37.73 51.72a5.42 5.42 0 0 0-2.449 3.63 5.79 5.79 0 0 0 .986 4.372 6.24 6.24 0 0 0 6.698 2.486 5.8 5.8 0 0 0 1.602-.704l9.952-6.342a19 19 0 0 1 5.295-2.328 20.72 20.72 0 0 1 22.237 8.242 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-8.13 12.053l-26.081 16.622a19 19 0 0 1-5.3 2.328" style="fill:#fff"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-label="Lee Morgan">
+	<rect width="32" height="32" fill="#0A0A0A"/>
+	<rect x="7" y="6" width="3.5" height="20" fill="#4FC3F7"/>
+	<rect x="7" y="22.5" width="13" height="3.5" fill="#4FC3F7"/>
+</svg>

+ 1 - 0
src/routes/+layout.js

@@ -0,0 +1 @@
+export const prerender = true;

+ 41 - 1
src/routes/+layout.svelte

@@ -1,4 +1,5 @@
 <script>
+	import '../app.css';
 	import favicon from '#lib/assets/favicon.svg';
 
 	let { children } = $props();
@@ -6,6 +7,45 @@
 
 <svelte:head>
 	<link rel="icon" href={favicon} />
+	<meta name="theme-color" content="#0A0A0A" />
+	<meta name="color-scheme" content="dark" />
 </svelte:head>
 
-{@render children()}
+<a class="skip" href="#main">Skip to content</a>
+
+<div class="shell">
+	<aside class="rail">
+		<div class="rail-top">
+			<div class="identity">
+				<h1><a class="wordmark" href="/">Lee Morgan</a></h1>
+				<p class="role">Web developer &amp; systems administrator</p>
+			</div>
+			<p class="status">
+				<span class="status-dot" aria-hidden="true"></span>
+				Available for work
+			</p>
+			<p class="place">Murrells Inlet, SC</p>
+			<nav aria-label="Site">
+				<ul class="menu">
+					<li><a href="/">Projects</a></li>
+					<li><a href="/">Blog</a></li>
+					<li><a href="/">Gallery</a></li>
+					<li><a href="/">Currency</a></li>
+					<li><a href="/">Resume/CV</a></li>
+					<li><a href="/">Git</a></li>
+					<li><a href="/">LinkedIn</a></li>
+				</ul>
+			</nav>
+			<a class="btn" href="mailto:lee@leemorgan.dev">Get in touch</a>
+		</div>
+		<div class="rail-bottom">
+			<a href="mailto:lee@leemorgan.dev">lee@leemorgan.dev</a>
+		</div>
+	</aside>
+
+	<div class="page">
+		<main id="main">
+			{@render children()}
+		</main>
+	</div>
+</div>

+ 57 - 2
src/routes/+page.svelte

@@ -1,2 +1,57 @@
-<h1>Welcome to SvelteKit</h1>
-<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
+<svelte:head>
+	<title>Lee Morgan — Web developer &amp; systems administrator</title>
+	<meta
+		name="description"
+		content="Lee Morgan is a web developer and systems administrator based in Murrells Inlet, South Carolina. Currently building and operating BLACKLIST.AERO."
+	/>
+</svelte:head>
+
+<article class="copy">
+	<p class="lede">
+		I currently work as a web developer and systems administrator for
+		<a href="https://www.blacklist.aero/" rel="noopener noreferrer" target="_blank">BLACKLIST.AERO</a>,
+		the Global Aviation Register of Defaulter Companies.
+	</p>
+
+	<p>
+		The platform serves as a public registry and self-regulation tool for the aviation industry,
+		helping companies track and address non-payment issues involving airport services, ground
+		handling, fueling, and related obligations. In this role I handle the technical side of the
+		platform—building and maintaining the web application, managing Linux servers, and working with
+		the underlying databases—so the register remains reliable and accessible for verified claimants
+		and industry users.
+	</p>
+
+	<p>
+		Professionally I focus on web development, Linux server management, database administration, and
+		full-stack application development. On the backend I primarily use Rust with the Actix
+		framework; on the frontend I work with Svelte or straightforward HTML, CSS, and JavaScript; and
+		for data I typically use MongoDB. Outside of the day job I run Debian servers at home and use
+		Debian with i3 on my desktop, which keeps me hands-on with efficient, lightweight Linux
+		environments and practical systems administration.
+	</p>
+
+	<p>
+		I’m based in Murrells Inlet, South Carolina, and I’m open to new work. Whether that means
+		additional project-based development, contract systems work, or a longer-term role, I’m
+		interested in opportunities that involve building reliable web applications, managing Linux
+		infrastructure, or working with databases and backend systems.
+	</p>
+</article>
+
+<style>
+	.copy {
+		max-width: 40rem;
+	}
+
+	.copy p + p {
+		margin-top: 1.5rem;
+	}
+
+	.lede {
+		font-size: 1.25rem;
+		font-weight: 500;
+		line-height: 1.5;
+		letter-spacing: 0.01em;
+	}
+</style>