This commit is contained in:
2024-08-19 16:05:58 -05:00
parent afe86bbcdc
commit de7031f447
60 changed files with 6306 additions and 0 deletions

8
src/pages/404.astro Normal file
View File

@@ -0,0 +1,8 @@
---
import Hero from '../components/Hero.astro';
import BaseLayout from '../layouts/BaseLayout.astro';
---
<BaseLayout title="Not Found" description="404 Error — this page was not found">
<Hero title="Page Not Found" tagline="Not found" />
</BaseLayout>

120
src/pages/about.astro Normal file
View File

@@ -0,0 +1,120 @@
---
import BaseLayout from '../layouts/BaseLayout.astro';
import ContactCTA from '../components/ContactCTA.astro';
import Hero from '../components/Hero.astro';
---
<BaseLayout title="About | Jeanine White" description="About Jeanine White Lorem Ipsum">
<div class="stack gap-20">
<main class="wrapper about">
<Hero
title="About"
tagline="Thanks for stopping by. Read below to learn more about myself and my background."
>
<img
width="1553"
height="873"
src="/assets/at-work.jpg"
alt="Jeanine White at work with a colleague"
/>
</Hero>
<section>
<h2 class="section-title">Background</h2>
<div class="content">
<p>
Lorem ipsum dolor sit amet, <a href="https://astro.build/">Astro</a> makes people happy.
Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Proin nibh nisl condimentum
id venenatis a condimentum vitae. Dapibus ultrices in iaculis nunc. Arcu odio ut sem nulla
pharetra diam sit amet. Diam quis enim lobortis scelerisque fermentum dui faucibus in ornare.
</p>
<p>
Arcu dui vivamus arcu felis bibendum ut tristique et egestas. Eget gravida cum sociis
natoque penatibus. Cras fermentum odio eu feugiat pretium nibh. Proin nibh nisl
condimentum id venenatis. Porta nibh venenatis cras sed felis eget velit. Id diam vel
quam elementum pulvinar etiam non.
</p>
<p>
Ultrices tincidunt arcu non sodales neque sodales ut. Sed enim ut sem viverra aliquet
eget sit amet. Lacus luctus accumsan tortor posuere ac ut consequat semper viverra.
Viverra accumsan in nisl nisi scelerisque eu ultrices. In massa tempor nec feugiat nisl
pretium fusce.
</p>
</div>
</section>
<section>
<h2 class="section-title">Education</h2>
<div class="content">
<p>Corporis voluptates tenetur laudantium.</p>
</div>
</section>
<section>
<h2 class="section-title">Skills</h2>
<div class="content">
<p>officia unde omnis</p>
</div>
</section>
</main>
<ContactCTA />
</div>
</BaseLayout>
<style>
.about {
display: flex;
flex-direction: column;
gap: 3.5rem;
}
img {
margin-top: 1.5rem;
border-radius: 1.5rem;
box-shadow: var(--shadow-md);
}
section {
display: flex;
flex-direction: column;
gap: 0.5rem;
color: var(--gray-200);
}
.section-title {
grid-column-start: 1;
font-size: var(--text-xl);
color: var(--gray-0);
}
.content {
grid-column: 2 / 4;
}
.content :global(a) {
text-decoration: 1px solid underline transparent;
text-underline-offset: 0.25em;
transition: text-decoration-color var(--theme-transition);
}
.content :global(a:hover),
.content :global(a:focus) {
text-decoration-color: currentColor;
}
@media (min-width: 50em) {
.about {
display: grid;
grid-template-columns: 1fr 60% 1fr;
}
.about > :global(:first-child) {
grid-column-start: 2;
}
section {
display: contents;
font-size: var(--text-lg);
}
}
</style>

252
src/pages/index.astro Normal file
View File

@@ -0,0 +1,252 @@
---
import { getCollection } from 'astro:content';
// Layout import — provides basic page elements: <head>, <nav>, <footer> etc.
import BaseLayout from '../layouts/BaseLayout.astro';
// Component Imports
import CallToAction from '../components/CallToAction.astro';
import Grid from '../components/Grid.astro';
import Hero from '../components/Hero.astro';
import Icon from '../components/Icon.astro';
import Pill from '../components/Pill.astro';
import PortfolioPreview from '../components/PortfolioPreview.astro';
// Page section components
import ContactCTA from '../components/ContactCTA.astro';
import Skills from '../components/Skills.astro';
// Content Fetching: List four most recent work projects
const projects = (await getCollection('work'))
.sort((a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf())
.slice(0, 4);
// Full Astro Component Syntax:
// https://docs.astro.build/basics/astro-components/
---
<BaseLayout>
<div class="stack gap-20 lg:gap-48">
<div class="wrapper stack gap-8 lg:gap-20">
<header class="hero">
<Hero
title="Hello, my name is Jeanine White"
tagline="I am a Creative Developer who is currently based in Portland, Oregon."
align="start"
>
<div class="roles">
<Pill><Icon icon="code" size="1.33em" /> Developer</Pill>
<Pill><Icon icon="microphone-stage" size="1.33em" /> Speaker</Pill>
<Pill><Icon icon="pencil-line" size="1.33em" /> Writer</Pill>
</div>
</Hero>
<img
alt="Jeanine White smiling in a red plaid shirt and tortoise shell glasses"
width="480"
height="620"
src="/assets/portrait.jpg"
/>
</header>
<Skills />
</div>
<main class="wrapper stack gap-20 lg:gap-48">
<section class="section with-background with-cta">
<header class="section-header stack gap-2 lg:gap-4">
<h3>Selected Work</h3>
<p>Take a look below at some of my featured work for clients from the past few years.</p>
</header>
<div class="gallery">
<Grid variant="offset">
{
projects.map((project) => (
<li>
<PortfolioPreview project={project} />
</li>
))
}
</Grid>
</div>
<div class="cta">
<CallToAction href="/work/">
View All
<Icon icon="arrow-right" size="1.2em" />
</CallToAction>
</div>
</section>
<section class="section with-background bg-variant">
<header class="section-header stack gap-2 lg:gap-4">
<h3>Mentions</h3>
<p>
I have been fortunate enough to receive praise for my work in several publications. Take
a look below to learn more.
</p>
</header>
<div class="gallery">
<Grid variant="small">
{
['Medium', 'BuzzFeed', 'The Next Web', 'awwwards.', 'TechCrunch'].map((brand) => (
<li class="mention-card">
<p>{brand}</p>
</li>
))
}
</Grid>
</div>
</section>
</main>
<ContactCTA />
</div>
</BaseLayout>
<style>
.hero {
display: flex;
flex-direction: column;
align-items: center;
gap: 2rem;
}
.roles {
display: none;
}
.hero img {
aspect-ratio: 5 / 4;
object-fit: cover;
object-position: top;
border-radius: 1.5rem;
box-shadow: var(--shadow-md);
}
@media (min-width: 50em) {
.hero {
display: grid;
grid-template-columns: 6fr 4fr;
padding-inline: 2.5rem;
gap: 3.75rem;
}
.roles {
margin-top: 0.5rem;
display: flex;
gap: 0.5rem;
}
.hero img {
aspect-ratio: 3 / 4;
border-radius: 4.5rem;
object-fit: cover;
}
}
/* ====================================================== */
.section {
display: grid;
gap: 2rem;
}
.with-background {
position: relative;
}
.with-background::before {
--hero-bg: var(--bg-image-subtle-2);
content: '';
position: absolute;
pointer-events: none;
left: 50%;
width: 100vw;
aspect-ratio: calc(2.25 / var(--bg-scale));
top: 0;
transform: translateY(-75%) translateX(-50%);
background:
url('/assets/backgrounds/noise.png') top center/220px repeat,
var(--hero-bg) center center / var(--bg-gradient-size) no-repeat,
var(--gray-999);
background-blend-mode: overlay, normal, normal, normal;
mix-blend-mode: var(--bg-blend-mode);
z-index: -1;
}
.with-background.bg-variant::before {
--hero-bg: var(--bg-image-subtle-1);
}
.section-header {
justify-self: center;
text-align: center;
max-width: 50ch;
font-size: var(--text-md);
color: var(--gray-300);
}
.section-header h3 {
font-size: var(--text-2xl);
}
@media (min-width: 50em) {
.section {
grid-template-columns: repeat(4, 1fr);
grid-template-areas: 'header header header header' 'gallery gallery gallery gallery';
gap: 5rem;
}
.section.with-cta {
grid-template-areas: 'header header header cta' 'gallery gallery gallery gallery';
}
.section-header {
grid-area: header;
font-size: var(--text-lg);
}
.section-header h3 {
font-size: var(--text-4xl);
}
.with-cta .section-header {
justify-self: flex-start;
text-align: left;
}
.gallery {
grid-area: gallery;
}
.cta {
grid-area: cta;
}
}
/* ====================================================== */
.mention-card {
display: flex;
height: 7rem;
justify-content: center;
align-items: center;
text-align: center;
border: 1px solid var(--gray-800);
border-radius: 1.5rem;
color: var(--gray-300);
background: var(--gradient-subtle);
box-shadow: var(--shadow-sm);
}
@media (min-width: 50em) {
.mention-card {
border-radius: 1.5rem;
height: 9.5rem;
}
}
</style>

39
src/pages/work.astro Normal file
View File

@@ -0,0 +1,39 @@
---
import { getCollection } from 'astro:content';
import BaseLayout from '../layouts/BaseLayout.astro';
import ContactCTA from '../components/ContactCTA.astro';
import PortfolioPreview from '../components/PortfolioPreview.astro';
import Hero from '../components/Hero.astro';
import Grid from '../components/Grid.astro';
const projects = (await getCollection('work')).sort(
(a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf(),
);
---
<BaseLayout
title="My Work | Jeanine White"
description="Learn about Jeanine White's most recent projects"
>
<div class="stack gap-20">
<main class="wrapper stack gap-8">
<Hero
title="My Work"
tagline="See my most recent projects below to get an idea of my past experience."
align="start"
/>
<Grid variant="offset">
{
projects.map((project) => (
<li>
<PortfolioPreview project={project} />
</li>
))
}
</Grid>
</main>
<ContactCTA />
</div>
</BaseLayout>

View File

@@ -0,0 +1,151 @@
---
import { type CollectionEntry, getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
import ContactCTA from '../../components/ContactCTA.astro';
import Hero from '../../components/Hero.astro';
import Icon from '../../components/Icon.astro';
import Pill from '../../components/Pill.astro';
interface Props {
entry: CollectionEntry<'work'>;
}
// This is a dynamic route that generates a page for every Markdown file in src/content/
// Read more about dynamic routes and this `getStaticPaths` function in the Astro docs:
// https://docs.astro.build/en/core-concepts/routing/#dynamic-routes
export async function getStaticPaths() {
const work = await getCollection('work');
return work.map((entry) => ({
params: { slug: entry.slug },
props: { entry },
}));
}
const { entry } = Astro.props;
const { Content } = await entry.render();
---
<BaseLayout title={entry.data.title} description={entry.data.description}>
<div class="stack gap-20">
<div class="stack gap-15">
<header>
<div class="wrapper stack gap-2">
<a class="back-link" href="/work/"><Icon icon="arrow-left" /> Work</a>
<Hero title={entry.data.title} align="start">
<div class="details">
<div class="tags">
{entry.data.tags.map((t) => <Pill>{t}</Pill>)}
</div>
<p class="description">{entry.data.description}</p>
</div>
</Hero>
</div>
</header>
<main class="wrapper">
<div class="stack gap-10 content">
{entry.data.img && <img src={entry.data.img} alt={entry.data.img_alt || ''} />}
<div class="content">
<Content />
</div>
</div>
</main>
</div>
<ContactCTA />
</div>
</BaseLayout>
<style>
header {
padding-bottom: 2.5rem;
border-bottom: 1px solid var(--gray-800);
}
.back-link {
display: none;
}
.details {
display: flex;
flex-direction: column;
padding: 0.5rem;
gap: 1.5rem;
justify-content: space-between;
align-items: center;
}
.tags {
display: flex;
gap: 0.5rem;
}
.description {
font-size: var(--text-lg);
max-width: 54ch;
}
.content {
max-width: 65ch;
margin-inline: auto;
}
.content > :global(* + *) {
margin-top: 1rem;
}
.content :global(h1),
.content :global(h2),
.content :global(h3),
.content :global(h4),
.content :global(h5) {
margin: 1.5rem 0;
}
.content :global(img) {
border-radius: 1.5rem;
box-shadow: var(--shadow-sm);
background: var(--gradient-subtle);
border: 1px solid var(--gray-800);
}
.content :global(blockquote) {
font-size: var(--text-lg);
font-family: var(--font-brand);
font-weight: 600;
line-height: 1.1;
padding-inline-start: 1.5rem;
border-inline-start: 0.25rem solid var(--accent-dark);
color: var(--gray-0);
}
.back-link,
.content :global(a) {
text-decoration: 1px solid underline transparent;
text-underline-offset: 0.25em;
transition: text-decoration-color var(--theme-transition);
}
.back-link:hover,
.back-link:focus,
.content :global(a:hover),
.content :global(a:focus) {
text-decoration-color: currentColor;
}
@media (min-width: 50em) {
.back-link {
display: block;
align-self: flex-start;
}
.details {
flex-direction: row;
gap: 2.5rem;
}
.content :global(blockquote) {
font-size: var(--text-2xl);
}
}
</style>