Files
Emil_Shanayev_Resume/components/Sections.tsx
T
EmilandClaude Sonnet 5 b5ffc67a82
Deploy to GitHub Pages / build (push) Canceled after 0s
Deploy to GitHub Pages / deploy (push) Canceled after 0s
Redesign the resume site as a 3D-editor viewport
New design: studio backdrop with a perspective floor and X/Z axis lines, an
orientation gizmo that orbits on scroll, Bricolage Grotesque and Instrument
Sans (bundled, no build-time network). Projects are laid out as plates by a
row planner that keeps every row full for any count; a demo image from the
repo root is shown when present, otherwise a generated voxel sculpture.
Text and projects still come live from Gitea.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XtcZtnG4GQA1d6mW5PNrS9
2026-09-20 21:37:35 +03:00

104 lines
3.6 KiB
TypeScript

import type { Resume } from '@/lib/types'
import styles from './sections.module.css'
export function Skills({ resume }: Readonly<{ resume: Resume }>) {
return (
<section className={styles.section} id="skills">
<div className={styles.shell}>
<h2 className={styles.title}>What I work with</h2>
<div className={styles.skills}>
{resume.skills.map((skill) => (
<article className={styles.skill} key={skill.title}>
<h3>{skill.title}</h3>
<p>{skill.text}</p>
<ul className={styles.tags}>{skill.stack.map((tag) => <li key={tag}>{tag}</li>)}</ul>
</article>
))}
</div>
</div>
</section>
)
}
export function Experience({ resume }: Readonly<{ resume: Resume }>) {
return (
<section className={styles.section} id="experience">
<div className={styles.shell}>
<h2 className={styles.title}>Experience</h2>
<div className={styles.entries}>
{resume.experience.map((entry) => (
<article className={styles.entry} key={entry.title}>
<p className={styles.meta}>{entry.meta}</p>
<div>
<h3>{entry.title}</h3>
<ul className={styles.list}>{entry.points.map((point) => <li key={point}>{point}</li>)}</ul>
</div>
</article>
))}
</div>
</div>
</section>
)
}
export function Education({ resume }: Readonly<{ resume: Resume }>) {
return (
<section className={styles.section} id="education">
<div className={styles.shell}>
<h2 className={styles.title}>Education and languages</h2>
<div className={styles.columns}>
<div>
<h3 className={styles.label}>Education</h3>
<div className={styles.stack}>
{resume.education.map((entry) => (
<div key={entry.institution}>
<p className={styles.strong}>{entry.institution}</p>
<p>{entry.program}</p>
<p className={styles.meta}>{entry.period}</p>
</div>
))}
</div>
</div>
<div>
<h3 className={styles.label}>Languages</h3>
<dl className={styles.languages}>
{resume.languages.map((language) => (
<div key={language.name}>
<dt>{language.name}</dt>
<dd>{language.level}</dd>
</div>
))}
</dl>
</div>
<div>
<h3 className={styles.label}>Interests</h3>
<p>{resume.interests.join(', ')}.</p>
</div>
</div>
</div>
</section>
)
}
export function Contact({ resume }: Readonly<{ resume: Resume }>) {
const [primary, ...others] = resume.contacts
return (
<footer className={styles.contact} id="contact">
<div className={styles.shell}>
<h2 className={styles.contactTitle}>Get in touch</h2>
<p className={styles.contactLead}>Email is the fastest way to reach me.</p>
<a className={styles.mail} href={primary.href}>{primary.value}</a>
<ul className={styles.contacts}>
{others.map((contact) => (
<li key={contact.value}>
<span>{contact.label}</span>
<a href={contact.href} target={contact.href.startsWith('http') ? '_blank' : undefined} rel="noreferrer">{contact.value}</a>
</li>
))}
</ul>
<p className={styles.legal}>© 2026 {resume.name}. The text and the projects on this page are read live from Gitea.</p>
</div>
</footer>
)
}