Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions src/components/IconLinkCard.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
---
// Icon + label + action link card. Shared by About and Contact.
// Surface + hover-lift come from the global .card / .card--interactive classes.
interface Props {
href?: string | null;
/** SVG path `d` for a 24×24 viewBox icon */
icon: string;
label: string;
action: string;
}
const { href, icon, label, action } = Astro.props;
const external = !!href && href.startsWith('http');
---

<a
href={href ?? undefined}
class="card card--interactive icon-link-card"
target={external ? '_blank' : undefined}
rel={external ? 'noreferrer' : undefined}
>
<span class="ilc-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="22" height="22"><path d={icon}></path></svg>
</span>
<span class="ilc-label">{label}</span>
<span class="ilc-action">{action}</span>
<span class="ilc-arrow" aria-hidden="true">→</span>
</a>

<style>
.icon-link-card {
position: relative;
display: grid;
grid-template-columns: 56px 1fr 28px;
grid-template-areas:
'icon label arrow'
'icon action arrow';
column-gap: 16px;
row-gap: 2px;
align-items: center;
padding: 22px;
border-radius: var(--radius-lg);
overflow: hidden;
}
.icon-link-card::before {
content: '';
position: absolute;
inset: 0 auto 0 0;
width: 3px;
background: var(--accent);
transform: scaleY(0);
transform-origin: top;
transition: transform 0.22s ease;
}
.icon-link-card:hover::before {
transform: scaleY(1);
}
.icon-link-card:hover .ilc-action,
.icon-link-card:hover .ilc-arrow,
.icon-link-card:hover .ilc-icon {
color: var(--accent);
}
.icon-link-card:hover .ilc-icon {
border-color: var(--accent);
}
.icon-link-card:hover .ilc-arrow {
transform: translateX(4px);
}

.ilc-icon {
grid-area: icon;
display: inline-flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
border-radius: 10px;
background: var(--paper);
border: 1px solid var(--line);
color: var(--ink-2);
transition:
color 0.15s ease,
border-color 0.15s ease;
}
.ilc-icon svg {
display: block;
fill: currentColor;
}
.ilc-label {
grid-area: label;
font-family: var(--font-mono);
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--ink-3);
align-self: end;
}
.ilc-action {
grid-area: action;
font-family: var(--font-display);
font-size: 20px;
color: var(--ink);
line-height: 1.15;
word-break: break-word;
align-self: start;
transition: color 0.15s ease;
}
.ilc-arrow {
grid-area: arrow;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--font-mono);
font-size: 18px;
color: var(--ink-3);
transition:
transform 0.18s ease,
color 0.15s ease;
}

@media (max-width: 620px) {
.icon-link-card {
padding: 18px;
}
}
</style>
28 changes: 28 additions & 0 deletions src/components/Stat.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
// A single number + label stat (hero counters, etc.).
interface Props {
value: number | string;
label: string;
}
const { value, label } = Astro.props;
---

<div class="stat">
<div class="stat-value">{value}</div>
<div class="stat-label">{label}</div>
</div>

<style>
.stat-value {
font-family: var(--font-display);
font-size: 28px;
line-height: 1;
color: var(--ink);
}
.stat-label {
margin-top: 6px;
font-family: var(--font-mono);
font-size: 12px;
color: var(--ink-3);
}
</style>
44 changes: 44 additions & 0 deletions src/components/Step.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
// A numbered process step (see the Contribute page).
interface Props {
n: string;
title: string;
body: string;
}
const { n, title, body } = Astro.props;
---

<div class="process-step">
<div class="process-step-num">{n}</div>
<div>
<h3 class="process-step-title">{title}</h3>
<p class="process-step-body">{body}</p>
</div>
</div>

<style>
.process-step {
display: grid;
grid-template-columns: 80px 1fr;
gap: 24px;
padding: 24px 0;
border-top: 1px solid var(--line);
}
.process-step-num {
font-family: var(--font-mono);
font-size: 12px;
color: var(--accent);
}
.process-step-title {
font-family: var(--font-display);
font-size: 26px;
margin: 0 0 8px;
font-weight: 400;
}
.process-step-body {
font-size: 15px;
color: var(--ink-2);
margin: 0;
line-height: 1.6;
}
</style>
135 changes: 4 additions & 131 deletions src/pages/about.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
import BaseLayout from '@/layouts/BaseLayout.astro';
import IconLinkCard from '@/components/IconLinkCard.astro';
import { SITE } from '@/lib/site';

const GITHUB_URL = 'https://github.com/HumbleBee14';
Expand Down Expand Up @@ -77,31 +78,14 @@ const links = [
</p>

<p>
This site is open source, MIT-licensed for the code, and Creative Commons / All Rights
Reserved per author for the writing. No paywalls, no popups, no "10x your ML career"
funnels. Just notes from the workbench.
Everything here is © its respective author, all rights reserved. No paywalls, no popups, no
"10x your ML career" funnels. Just notes from the workbench.
</p>

<div class="about-links">
{
links.map((c) => (
<a
href={c.href}
class="about-card"
target={c.href?.startsWith('http') ? '_blank' : undefined}
rel={c.href?.startsWith('http') ? 'noreferrer' : undefined}
>
<span class="about-icon" aria-hidden="true">
<svg viewBox="0 0 24 24" width="22" height="22">
<path d={c.icon} />
</svg>
</span>
<span class="about-label">{c.label}</span>
<span class="about-action">{c.action}</span>
<span class="about-arrow" aria-hidden="true">
</span>
</a>
<IconLinkCard href={c.href} icon={c.icon} label={c.label} action={c.action} />
))
}
</div>
Expand Down Expand Up @@ -205,122 +189,11 @@ const links = [
grid-template-columns: repeat(2, 1fr);
gap: 14px;
}
.about-card {
position: relative;
display: grid;
grid-template-columns: 56px 1fr 28px;
grid-template-areas:
'icon label arrow'
'icon action arrow';
column-gap: 16px;
row-gap: 2px;
align-items: center;
padding: 22px;
border: 1px solid var(--line);
border-radius: var(--radius-lg);
background: var(--paper-2);
color: inherit !important;
text-decoration: none;
overflow: hidden;
transition:
transform 0.18s ease,
border-color 0.18s ease,
box-shadow 0.18s ease,
background 0.18s ease;
}
.about-card {
border-bottom: 1px solid var(--line);
}
.about-card::before {
content: '';
position: absolute;
inset: 0 auto 0 0;
width: 3px;
background: var(--accent);
transform: scaleY(0);
transform-origin: top;
transition: transform 0.22s ease;
}
.about-card:hover {
transform: translateY(-2px);
border-color: var(--accent);
background: var(--paper);
box-shadow: 0 8px 24px -14px color-mix(in srgb, var(--accent) 40%, transparent);
}
.about-card:hover::before {
transform: scaleY(1);
}
.about-card:hover .about-action,
.about-card:hover .about-arrow,
.about-card:hover .about-icon {
color: var(--accent);
}
.about-card:hover .about-icon {
border-color: var(--accent);
}
.about-card:hover .about-arrow {
transform: translateX(4px);
}

.about-icon {
grid-area: icon;
display: inline-flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
border-radius: 10px;
background: var(--paper);
border: 1px solid var(--line);
color: var(--ink-2);
transition:
color 0.15s ease,
border-color 0.15s ease;
}
.about-icon svg {
display: block;
fill: currentColor;
}
.about-label {
grid-area: label;
font-family: var(--font-mono);
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--ink-3);
align-self: end;
}
.about-action {
grid-area: action;
font-family: var(--font-display);
font-size: 20px;
color: var(--ink);
line-height: 1.15;
word-break: break-word;
align-self: start;
transition: color 0.15s ease;
}
.about-arrow {
grid-area: arrow;
display: inline-flex;
align-items: center;
justify-content: center;
font-family: var(--font-mono);
font-size: 18px;
color: var(--ink-3);
transition:
transform 0.18s ease,
color 0.15s ease;
}

@media (max-width: 620px) {
.about-links {
grid-template-columns: 1fr;
gap: 10px;
}
.about-card {
padding: 18px;
}
.about-body {
font-size: 16px;
}
Expand Down
17 changes: 1 addition & 16 deletions src/pages/authors/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const contributors = authors
<div class="contributors-grid">
{
contributors.map((c) => (
<a href={`/authors/${c.id}`} class="contributor-card">
<a href={`/authors/${c.id}`} class="card card--interactive contributor-card">
<div class="contributor-avatar" aria-hidden="true">
{c.data.avatar ? (
<img src={c.data.avatar} alt="" loading="lazy" decoding="async" />
Expand Down Expand Up @@ -90,22 +90,7 @@ const contributors = authors
grid-template-columns: 64px 1fr;
gap: 18px;
padding: 22px;
border: 1px solid var(--line);
border-radius: var(--radius-lg);
background: var(--paper-2);
color: inherit;
text-decoration: none;
transition:
transform 0.18s ease,
border-color 0.18s ease,
background 0.18s ease,
box-shadow 0.18s ease;
}
.contributor-card:hover {
transform: translateY(-2px);
border-color: var(--accent);
background: var(--paper);
box-shadow: 0 8px 24px -14px color-mix(in srgb, var(--accent) 40%, transparent);
}
.contributor-avatar {
width: 56px;
Expand Down
Loading
Loading