mirror of
https://github.com/avinal/avinal.github.io.git
synced 2026-07-04 07:40:09 +05:30
f5e739494a
Assisted by Claude Code Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
242 lines
8.9 KiB
Plaintext
242 lines
8.9 KiB
Plaintext
---
|
|
/**
|
|
* Combined hero card: profile + about/skills + social links.
|
|
* Mirrors jay.fish's left hero section — everything about the person in one card.
|
|
*/
|
|
|
|
interface Skill {
|
|
icon: string;
|
|
title: string;
|
|
desc: string;
|
|
svgPath: string;
|
|
}
|
|
|
|
interface SocialLink {
|
|
label: string;
|
|
href: string;
|
|
icon: string;
|
|
}
|
|
|
|
interface Props {
|
|
name: string;
|
|
role: string;
|
|
bio: string;
|
|
avatarUrl?: string;
|
|
}
|
|
|
|
const { name, role, bio, avatarUrl } = Astro.props;
|
|
|
|
const about: Skill[] = [
|
|
{ icon: "cloud", title: "Cloud Native", desc: "Leading Builds for OpenShift at Red Hat", svgPath: '<path d="M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z"/>' },
|
|
{ icon: "cpu", title: "Kernel & Toolchain", desc: "Linux kernel, GCC & glibc contributor", svgPath: '<rect x="4" y="4" width="16" height="16" rx="2" ry="2"/><rect x="9" y="9" width="6" height="6"/><line x1="9" y1="1" x2="9" y2="4"/><line x1="15" y1="1" x2="15" y2="4"/><line x1="9" y1="20" x2="9" y2="23"/><line x1="15" y1="20" x2="15" y2="23"/><line x1="20" y1="9" x2="23" y2="9"/><line x1="20" y1="14" x2="23" y2="14"/><line x1="1" y1="9" x2="4" y2="9"/><line x1="1" y1="14" x2="4" y2="14"/>' },
|
|
{ icon: "code", title: "Open Source", desc: "GSoC alumnus & mentor, Campus Expert", svgPath: '<polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/>' },
|
|
{ icon: "server", title: "Self-hosting", desc: "Fedora daily driver, homelab everything", svgPath: '<rect x="2" y="2" width="20" height="8" rx="2" ry="2"/><rect x="2" y="14" width="20" height="8" rx="2" ry="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/>' },
|
|
];
|
|
|
|
const tools: Skill[] = [
|
|
{ icon: "terminal", title: "Languages", desc: "C/C++, Go, Bash", svgPath: '<polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/>' },
|
|
{ icon: "pen-tool", title: "Editor", desc: "Helix, Zellij, lazygit", svgPath: '<path d="M12 19l7-7 3 3-7 7-3-3z"/><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"/><path d="M2 2l7.586 7.586"/><circle cx="11" cy="11" r="2"/>' },
|
|
{ icon: "settings", title: "Platforms", desc: "Fedora, Git, CMake, GitHub Actions", svgPath: '<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/>' },
|
|
];
|
|
|
|
const links: SocialLink[] = [
|
|
{ label: "GitHub", href: "https://github.com/avinal", icon: "github" },
|
|
{ label: "LinkedIn", href: "https://linkedin.com/in/avinal", icon: "linkedin" },
|
|
{ label: "Twitter", href: "https://twitter.com/Avinal_", icon: "twitter" },
|
|
{ label: "WakaTime", href: "https://wakatime.com/@avinal", icon: "wakatime" },
|
|
{ label: "RSS", href: "/rss.xml", icon: "rss" },
|
|
];
|
|
---
|
|
|
|
<div class="hero-card card">
|
|
<!-- Identity -->
|
|
<div class="hero-identity">
|
|
{avatarUrl ? (
|
|
<img src={avatarUrl} alt={name} class="hero-avatar" width="64" height="64" />
|
|
) : (
|
|
<div class="hero-avatar hero-avatar-fallback" aria-hidden="true">{name.charAt(0)}</div>
|
|
)}
|
|
<div>
|
|
<h1 class="hero-name">{name}</h1>
|
|
<p class="hero-role">{role}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<p class="hero-bio">{bio}</p>
|
|
|
|
<!-- Skills columns -->
|
|
<div class="hero-skills">
|
|
<div class="skills-col">
|
|
<h3 class="col-heading">About</h3>
|
|
<ul class="skill-list">
|
|
{about.map(({ svgPath, title, desc }) => (
|
|
<li class="skill-item">
|
|
<svg class="skill-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><Fragment set:html={svgPath} /></svg>
|
|
<div>
|
|
<strong>{title}</strong>
|
|
<span class="skill-desc">{desc}</span>
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
<div class="skills-col">
|
|
<h3 class="col-heading">Tools & Stack</h3>
|
|
<ul class="skill-list">
|
|
{tools.map(({ svgPath, title, desc }) => (
|
|
<li class="skill-item">
|
|
<svg class="skill-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><Fragment set:html={svgPath} /></svg>
|
|
<div>
|
|
<strong>{title}</strong>
|
|
<span class="skill-desc">{desc}</span>
|
|
</div>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Social links -->
|
|
<div class="hero-links">
|
|
{links.map(({ label, href, icon }) => (
|
|
<a href={href} class="link-btn" target={href.startsWith("http") ? "_blank" : undefined} rel={href.startsWith("http") ? "noopener noreferrer" : undefined} aria-label={label}>
|
|
<svg class="link-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
{icon === "github" && <path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/>}
|
|
{icon === "linkedin" && <Fragment><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"/><rect x="2" y="9" width="4" height="12"/><circle cx="4" cy="4" r="2"/></Fragment>}
|
|
{icon === "twitter" && <path d="M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z"/>}
|
|
{icon === "wakatime" && <Fragment><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z" fill="none"/><path d="M7.5 14.5l2-4 2 3 2-5 2.5 6" stroke-linejoin="round"/></Fragment>}
|
|
{icon === "rss" && <Fragment><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1"/></Fragment>}
|
|
</svg>
|
|
{label}
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.hero-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-5);
|
|
}
|
|
|
|
.hero-identity {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-4);
|
|
}
|
|
|
|
.hero-avatar {
|
|
width: 64px;
|
|
height: 64px;
|
|
border-radius: var(--radius-full);
|
|
object-fit: cover;
|
|
border: 2px solid var(--border);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.hero-avatar-fallback {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background-color: var(--accent);
|
|
color: white;
|
|
font-size: var(--text-2xl);
|
|
font-weight: 700;
|
|
}
|
|
|
|
.hero-name {
|
|
font-size: var(--text-xl);
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.hero-role {
|
|
font-size: var(--text-sm);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.hero-bio {
|
|
color: var(--text-secondary);
|
|
font-size: var(--text-sm);
|
|
line-height: var(--leading-relaxed);
|
|
}
|
|
|
|
.hero-skills {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: var(--space-6);
|
|
}
|
|
|
|
@media (max-width: 600px) {
|
|
.hero-skills { grid-template-columns: 1fr; }
|
|
}
|
|
|
|
.col-heading {
|
|
font-size: var(--text-xs);
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.08em;
|
|
color: var(--accent);
|
|
margin-bottom: var(--space-3);
|
|
}
|
|
|
|
.skill-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-3);
|
|
}
|
|
|
|
.skill-item {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: var(--space-2);
|
|
font-size: var(--text-sm);
|
|
}
|
|
|
|
.skill-icon {
|
|
flex-shrink: 0;
|
|
margin-top: 2px;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.skill-item strong {
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
margin-right: var(--space-1);
|
|
}
|
|
|
|
.skill-desc {
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.hero-links {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-2);
|
|
padding-top: var(--space-2);
|
|
border-top: 1px solid var(--border);
|
|
}
|
|
|
|
.link-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--space-2);
|
|
padding: var(--space-1) var(--space-3);
|
|
font-size: var(--text-xs);
|
|
font-weight: 500;
|
|
color: var(--text-secondary);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius-md);
|
|
text-decoration: none;
|
|
transition: all var(--duration-fast) var(--ease-out);
|
|
}
|
|
|
|
.link-btn:hover {
|
|
color: var(--text);
|
|
border-color: var(--border-strong);
|
|
background-color: var(--bg-surface-hover);
|
|
}
|
|
|
|
.link-icon { flex-shrink: 0; }
|
|
</style>
|