The Source
This is the Astro source code for the home page.
---
// @ts-nocheck
import Picture from '@components/Picture.astro';
import Layout from '@layouts/Layout.astro';
import LatestPost from '@components/posts/LatestPost.astro';
import TwoPosts from '@components/posts/TwoPosts.astro';
import TwoThings from '~/components/TwoThings.astro';
import Thing from '~/components/Thing.astro';
import ObfuMatic from 'obfumatic/astro';
import * as config from '~/config.js';
import Chevron from '@images/icons/chevron.svg';
import ogImage from '@images/iwantcandy.jpg';
import lollipop from '@images/lollipop.jpg';
import nosering from '@images/lollipop-nose-ring.jpg';
import redlight from '@images/red-light-lollipop.jpg';
---
<Layout bodyClass="home" ogImage={ogImage}>
<header id="site-head">
<Picture class="bgimage"
src={lollipop}
alt=""
widths={[800, 1200, 1600, 2400, 3200]}
sizes="100vw"
formats={['avif','jpg']}
quality="high"
fetchpriority="high"
/>
<div class="inner">
<h1 class="site-title">{config.siteTitle}</h1>
<div class="site-description">{config.siteDescription}</div>
<div class="site-menu">
<a class="btn" href="#intro">Hello</a>
<a class="btn" href="#latest">Latest</a>
<a class="btn" href="/blog/">Blog</a>
<a class="btn" href="/source/">Source</a>
</div>
<div id="header-arrow"><Chevron width="90" height="52" /></div>
</div>
</header>
<main>
<section id="intro">
<div class="content">
<h2>Hello</h2>
<p>Hi there. This is a development site where I’m just playing with stuff.
If you’re not me, <strong>there’s nothing for you here,</strong> unless you really want
to see if I’ve broken some CSS again.</p>
<p>Filler content in the <a href="/blog/">blog</a> section is AI-generated, so don’t
take it too seriously.</p>
</div>
</section>
<section id="latest">
<LatestPost />
</section>
<section id="more">
<TwoPosts offset={1} sectionClass="more-posts">
<Fragment slot="section-header">
More posts
</Fragment>
</TwoPosts>
<p><a href="/blog/">More posts...</a></p>
</section>
<section id="stuff">
<TwoThings>
<h3 slot="section-header">Lollipops</h3>
<Thing slot="left">
<Picture src={nosering} alt="Woman with nose ring licking a lollipop" maxSize="200" />
<p>A lollipop is pure magic - a sweet, colorful burst of happiness perched atop a little white stick, ready to transform any ordinary moment into one of childlike wonder.</p>
</Thing>
<Thing slot="right">
<p>The way it slowly dissolves, releasing its sugary bliss while painting your tongue in whimsical hues, makes it impossible not to smile with each delightful lick.</p>
<Picture src={redlight} alt="Woman lit in red licking a lollipop" maxSize="200" />
</Thing>
</TwoThings>
</section>
<section id="contact">
<div class="contact">
<h2>Contact</h2>
<p>
Use this <ObfuMatic email="foo@bar.com" text="fake email link" /> for testing.
</p>
</div>
</section>
</main>
</Layout>
<style>
#site-head {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
background-color: var(--site-head-bg-color);
margin-bottom: 0;
text-align: center;
}
#site-head .inner {
flex: 1 4 80%;
z-index: 1;
animation: fadeIn 0.3s;
position: relative;
top: 0;
}
.bgimage {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: top center;
animation: fadeIn 0.5s;
}
.site-title {
font-family: var(--display-font, var(--header-font, sans-serif));
font-weight: 700;
margin: 10px 0 5px 0;
font-size: var(--step-9);
letter-spacing: -2px;
color: var(--site-head-text-color);
text-shadow: 2px 2px 3px var(--site-head-shadow-color);
}
.site-description {
margin: 0;
font-size: 1.65rem;
line-height: 1.5em;
font-weight: 400;
font-family: var(--header-font), serif;
letter-spacing: 0;
color: var(--site-head-text-color);
text-shadow: 2px 2px 3px var(--site-head-shadow-color);
text-rendering: optimizeLegibility;
}
a.btn {
text-decoration: none;
color: var(--button-text-color);
background-color: var(--button-bg-color);
position: relative;
display: inline-block;
font-size: 16px;
letter-spacing: 1px;
border-radius: 6px;
margin: 0;
overflow: visible;
padding: 10px 20px 10px 20px;
margin-top: 30px;
font-family: var(--button-font, sans-serif);
text-transform: uppercase;
font-weight: 200;
box-shadow: 1px 1px 2px var(--site-head-shadow-color);
transition: background-color ease 0.25s;
}
a.btn:hover {
background-color: var(--button-hover-bg-color);
}
#header-arrow {
margin: 35px auto;
width: 90px;
cursor: pointer;
opacity: 0.6;
transition: opacity ease 0.3s;
/* filter: drop-shadow(2px 2px 3px var(--site-head-shadow-color)); */
}
#header-arrow:hover {
opacity: 0.9;
}
</style>
<script>
// @ts-nocheck
// Scroll to first section on arrow click
const arrow = document.querySelector('#header-arrow');
if (arrow) {
arrow.addEventListener('click', (e) => {
document.querySelector('section:not(section section):first-of-type')?.scrollIntoView({ behavior: 'smooth' });
e.preventDefault();
});
}
// Smooth scroll to anchor links
document.querySelectorAll('a[href^="#"]').forEach((link) => {
link.addEventListener('click', (e) => {
document.querySelector(e.currentTarget.hash)?.scrollIntoView({ behavior: 'smooth' });
e.preventDefault();
});
});
// Parallax effect on header
document.addEventListener('scroll', () => {
const offset = -(((window.scrollY / window.innerHeight) * 100) * 0.35);
document.querySelector('#site-head .inner').style.top = `${offset}px`;
});
</script>