Update site look and feel

This commit is contained in:
Jake Runyan 2026-03-04 16:29:16 -08:00
parent 68f8b91c7b
commit 95c88d6a0d
14 changed files with 258 additions and 17820 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
/node_modules
/.pnp
.pnp.js
package-lock.json
# testing
/coverage

17661
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,62 +3,6 @@ body, html {
padding: 0;
font-family: Arial, sans-serif;
height: 100%;
}
nav ul {
list-style-type: none;
padding: 0;
display: flex;
gap: 20px;
background-color: #333;
margin: 0;
padding: 10px 20px;
}
nav ul li {
display: inline;
}
nav ul li a {
text-decoration: none;
color: white;
}
nav ul li a:hover {
text-decoration: underline;
}
.page {
padding: 20px;
}
.navbar {
display: flex;
justify-content: space-between; /* Space between links and icons */
align-items: center;
padding: 10px 20px;
background-color: #333; /* Background color */
color: white; /* Text color */
}
.nav-links a {
color: white; /* Link color */
margin: 0 15px; /* Spacing between links */
text-decoration: none; /* Remove underline */
}
.social-icons a {
margin-left: 15px; /* Spacing between icons */
}
.social-icons img {
width: 24px; /* Icon size */
height: 24px; /* Icon size */
transition: transform 0.2s; /* Animation on hover */
}
.social-icons img:hover {
transform: scale(1.1); /* Scale up on hover */
background-color: #0d0d0d;
color: #f0f0f0;
}

View File

@ -1,12 +1,10 @@
import React, { useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import './App.css';
import Navbar from './components/Navbar';
import Home from './components/Home';
import About from './components/About';
import Projects from './components/Projects';
import instagramIcon from './static/instagram-icon.png';
import githubIcon from './static/github-icon.png';
import youtubeIcon from './static/youtube-icon.png';
function App() {
useEffect(() => {
@ -16,24 +14,7 @@ function App() {
return (
<Router>
<div className="App">
<nav className="navbar">
<div className="nav-links">
<Link to="/">Home</Link>
<Link to="/projects">Projects</Link>
<Link to="/about">About</Link>
</div>
<div className="social-icons">
<a href="https://www.instagram.com/jakeswestcoast" target="_blank" rel="noopener noreferrer" title="Instagram">
<img src={instagramIcon} alt="Instagram" />
</a>
<a href="https://github.com/runyanjake/jakeswestcoast" target="_blank" rel="noopener noreferrer" title="GitHub">
<img src={githubIcon} alt="GitHub" />
</a>
<a href="https://www.youtube.com/@jakeswestcoast" target="_blank" rel="noopener noreferrer" title="YouTube">
<img src={youtubeIcon} alt="YouTube" />
</a>
</div>
</nav>
<Navbar />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />

View File

@ -1,3 +1,31 @@
.page {
padding: 20px;
}
.about-page {
min-height: 100vh;
padding: 74px 24px 80px;
}
.about-header {
text-align: center;
padding: 60px 0 40px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
margin-bottom: 48px;
}
.about-header h1 {
font-size: clamp(2rem, 5vw, 4rem);
font-weight: bold;
margin: 0;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.about-body {
max-width: 680px;
margin: 0 auto;
}
.about-body p {
font-size: 1.1rem;
line-height: 1.9;
color: rgba(255, 255, 255, 0.7);
margin: 0;
}

View File

@ -2,9 +2,13 @@ import './About.css';
function About() {
return (
<div className="page">
<h1>About</h1>
<p>Welcome to my mountaineering diary! I'm Jake, a rider from the Bay Area. I love road, mountain, and gravel cycling around my home mountains and anywhere that has cool trails & views.</p>
<div className="about-page">
<div className="about-header">
<h1>About</h1>
</div>
<div className="about-body">
<p>Welcome to my mountaineering diary! I'm Jake, a rider from the Bay Area. I love road, mountain, and gravel cycling around my home mountains and anywhere that has cool trails &amp; views.</p>
</div>
</div>
);
}

View File

@ -31,10 +31,12 @@
font-size: 4vw;
font-weight: bold;
margin: 0;
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6);
}
.home-content p {
font-size: 1vw;
font-weight: bold;
margin: 0;
text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);
}

54
src/components/Navbar.css Normal file
View File

@ -0,0 +1,54 @@
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 24px;
background: rgba(0, 0, 0, 0.25);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
color: white;
}
.nav-links a {
color: white;
margin: 0 16px;
text-decoration: none;
font-size: 0.95rem;
letter-spacing: 0.05em;
text-transform: uppercase;
opacity: 0.85;
transition: opacity 0.2s;
}
.nav-links a:hover {
opacity: 1;
}
.social-icons {
display: flex;
align-items: center;
gap: 16px;
}
.social-icons a {
display: flex;
align-items: center;
opacity: 0.8;
transition: opacity 0.2s, transform 0.2s;
}
.social-icons a:hover {
opacity: 1;
transform: scale(1.1);
}
.social-icons img {
width: 20px;
height: 20px;
}

30
src/components/Navbar.js Normal file
View File

@ -0,0 +1,30 @@
import { Link } from 'react-router-dom';
import './Navbar.css';
import instagramIcon from '../static/instagram-icon.png';
import githubIcon from '../static/github-icon.png';
import youtubeIcon from '../static/youtube-icon.png';
function Navbar() {
return (
<nav className="navbar">
<div className="nav-links">
<Link to="/">Home</Link>
<Link to="/projects">Projects</Link>
<Link to="/about">About</Link>
</div>
<div className="social-icons">
<a href="https://www.instagram.com/jakeswestcoast" target="_blank" rel="noopener noreferrer" title="Instagram">
<img src={instagramIcon} alt="Instagram" />
</a>
<a href="https://github.com/runyanjake/jakeswestcoast" target="_blank" rel="noopener noreferrer" title="GitHub">
<img src={githubIcon} alt="GitHub" />
</a>
<a href="https://www.youtube.com/@jakeswestcoast" target="_blank" rel="noopener noreferrer" title="YouTube">
<img src={youtubeIcon} alt="YouTube" />
</a>
</div>
</nav>
);
}
export default Navbar;

View File

@ -1,40 +1,35 @@
.page {
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.projects-page {
min-height: 100vh;
padding: 74px 24px 80px;
}
.projects-header {
text-align: center;
padding: 60px 0 40px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
margin-bottom: 48px;
}
.projects-header h1 {
font-size: clamp(2rem, 5vw, 4rem);
font-weight: bold;
margin: 0 0 12px;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.projects-header p {
margin: 0;
font-size: 0.95rem;
color: rgba(255, 255, 255, 0.5);
letter-spacing: 0.04em;
}
.video-cards {
display: flex;
flex-wrap: wrap;
gap: 20px;
gap: 28px;
justify-content: center;
max-width: 1200px;
margin: 0 auto;
}
.video-card {
border: 1px solid #ccc;
border-radius: 8px;
padding: 10px;
width: 100%; /* Full width for the card */
max-width: 560px; /* Max width to match the video */
text-align: center;
position: relative; /* Positioning for the iframe */
overflow: hidden; /* Hide overflow */
}
/* Responsive iframe */
.video-card iframe {
width: 100%; /* Full width for the iframe */
height: auto; /* Maintain aspect ratio */
aspect-ratio: 16 / 9; /* Maintain 16:9 aspect ratio */
}
/* Responsive styles */
@media (max-width: 600px) {
.video-card {
width: 100%; /* Full width on small screens */
}
}

View File

@ -1,52 +1,26 @@
import './Projects.css';
import React from 'react';
import VideoCard from './VideoCard';
import videos from '../data/videos';
function Projects() {
const videos = [
{
title: 'The Bay Tour',
url: 'https://www.youtube.com/watch?v=xhDQMUUZdio',
description: 'A full loop of the bay area, starting in the South Bay and continuing counterclockwise over the 150 mile stretch.',
},
{
title: 'America\'s Most Beautiful Bike Ride',
url: 'https://www.youtube.com/watch?v=O4eEIqxIGCs',
description: 'Footage from the 2024 America\'s Most Beautiful Bike Ride in Lake Tahoe. 80 miles of beautiful scenery and lake views.',
},
{
title: 'Alpine Dam',
url: 'https://www.youtube.com/watch?v=_z7g9PyfrK8',
description: 'A relaxed group ride into Marin county to Alpine Dam. Lots of climbing from city to dam to the ridgeline.',
},
{
title: 'China Camp',
url: 'https://www.youtube.com/watch?v=6CkZZhwRLcQ',
description: 'A return to gravel, in the form of a road ride from Berkeley to China Camp State Park, on the south side of the San Pablo Bay. Excellent miles, and great gravel trails, with pleasant weather to top it all off.',
},
];
return (
<div className="page">
<h1>Projects</h1>
<p>Some of the larger projects we've done over the history of my channel.</p>
<div className="projects-page">
<div className="projects-header">
<h1>Projects</h1>
<p>Some of the larger projects we've done over the history of my channel.</p>
</div>
<div className="video-cards">
{videos.map((video, index) => (
<div className="video-card" key={index}>
<h2>{video.title}</h2>
<iframe
width="560"
height="315"
src={`https://www.youtube.com/embed/${video.url.split('v=')[1]}`}
title={video.description}
frameBorder="0"
allowFullScreen
></iframe>
<p>{video.description}</p>
</div>
{videos.map((video) => (
<VideoCard
key={video.url}
title={video.title}
url={video.url}
description={video.description}
/>
))}
</div>
</div>
);
}
export default Projects;
export default Projects;

View File

@ -0,0 +1,40 @@
.video-card {
background: #1a1a1a;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 12px;
overflow: hidden;
width: 100%;
max-width: 560px;
transition: transform 0.25s ease, border-color 0.25s ease;
}
.video-card:hover {
transform: translateY(-4px);
border-color: rgba(255, 255, 255, 0.2);
}
.video-card iframe {
width: 100%;
height: auto;
aspect-ratio: 16 / 9;
display: block;
}
.video-card-info {
padding: 16px 20px 20px;
}
.video-card-info h2 {
margin: 0 0 8px;
font-size: 1rem;
font-weight: 600;
letter-spacing: 0.03em;
color: #f0f0f0;
}
.video-card-info p {
margin: 0;
font-size: 0.875rem;
line-height: 1.65;
color: rgba(255, 255, 255, 0.5);
}

View File

@ -0,0 +1,22 @@
import './VideoCard.css';
function VideoCard({ title, url, description }) {
const videoId = url.split('v=')[1];
return (
<div className="video-card">
<iframe
src={`https://www.youtube.com/embed/${videoId}`}
title={title}
frameBorder="0"
allowFullScreen
></iframe>
<div className="video-card-info">
<h2>{title}</h2>
<p>{description}</p>
</div>
</div>
);
}
export default VideoCard;

24
src/data/videos.js Normal file
View File

@ -0,0 +1,24 @@
const videos = [
{
title: 'The Bay Tour',
url: 'https://www.youtube.com/watch?v=xhDQMUUZdio',
description: 'A full loop of the bay area, starting in the South Bay and continuing counterclockwise over the 150 mile stretch.',
},
{
title: "America's Most Beautiful Bike Ride",
url: 'https://www.youtube.com/watch?v=O4eEIqxIGCs',
description: "Footage from the 2024 America's Most Beautiful Bike Ride in Lake Tahoe. 80 miles of beautiful scenery and lake views.",
},
{
title: 'Alpine Dam',
url: 'https://www.youtube.com/watch?v=_z7g9PyfrK8',
description: 'A relaxed group ride into Marin county to Alpine Dam. Lots of climbing from city to dam to the ridgeline.',
},
{
title: 'China Camp',
url: 'https://www.youtube.com/watch?v=6CkZZhwRLcQ',
description: 'A return to gravel, in the form of a road ride from Berkeley to China Camp State Park, on the south side of the San Pablo Bay. Excellent miles, and great gravel trails, with pleasant weather to top it all off.',
},
];
export default videos;