Something went wrong. Try again.
https://clembs.com
Something went wrong. Try again.
4.6 kB · 220 lines
Astro
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221---import Book from '@assets/icons/book.svg';import External from '@assets/icons/external.svg';import { getLocaleFromUrl, useTranslations } from '@i18n';import type { ImageMetadata } from 'astro';import { Image } from 'astro:assets';import Button from './Button.astro';
interface Props { key: string; date: 'tba' | (string & {}); contract: | 'freelance' | 'internship' | 'full-time' | 'college-project' | 'personal-project' | 'volunteering' | (string & {}); baseHue: number; chromaOverride?: number; projectUrl?: string; articleUrl?: string; icon: ImageMetadata; image?: ImageMetadata & { alt: string };}
const { key, date, contract, baseHue, projectUrl, articleUrl, icon, image, chromaOverride } = Astro.props;
const lang = getLocaleFromUrl(Astro.url);const t = useTranslations(lang);
const styles = [`--base-hue: ${baseHue}`];if (chromaOverride !== undefined) { styles.push(`--chroma: ${chromaOverride}`);}---
<article style={styles.join(';')}> <div class="about"> <div class="key-info"> { icon && ( <Image src={icon} class:list={[{ pixelate: key === 'mecanume' }, 'icon']} alt="" draggable="false" /> ) }
<div> <h3>{t(`projects.${key}.title`)}</h3>
<span class="small-text"> {date === 'tba' ? t('tba') : date} • {t(contract)} </span> </div> </div>
<dl> <dt class="small-text">{t('about')}</dt> <dd>{t(`projects.${key}.about`)}</dd>
<dt class="small-text">{t('roles')}</dt> <dd>{t(`projects.${key}.roles`)}</dd> </dl>
<div class="buttons" role="group"> { !!articleUrl && ( <Button href={articleUrl}> <Book /> {t('read_article')} </Button> ) } { !!projectUrl && ( <Button href={projectUrl} target="_blank" rel="noopener noreferrer" variant={articleUrl ? 'secondary' : 'primary'} aria-label={t('view_project')} > <External /> {!articleUrl && t('view_project')} </Button> ) } </div> </div>
{ image && ( <div class="banner"> <Image src={image} alt={image.alt} draggable="false" /> </div> ) }</article>
<style lang="scss"> @use '../styles/mixins.scss' as *;
article { @include generate-colors(var(--base-hue));
display: grid; grid-template-columns: auto 1fr; inline-size: 100%; overflow: hidden;
border-radius: 2.5rem; background-color: var(--color-40); border: 1px solid var(--color-500); color: var(--color-850);
@media (max-width: 800px) { grid-template-columns: auto; border-radius: 0; margin-inline: calc(0px - clamp(1rem, 5vw, 3rem)); width: calc(100% + clamp(1rem, 5vw, 3rem) * 2); border-inline: none;
&:not(:last-child) { border-block-end: none; } } }
.about { display: flex; flex-direction: column; padding: 1rem; max-width: 45ch;
.key-info { display: flex; gap: 0.75rem; align-items: center; padding: 0.5rem;
img { inline-size: 52px; block-size: 52px; border-radius: 1rem; &.pixelate { image-rendering: pixelated; } } h3 { margin-inline-end: 0.125rem; } .small-text { color: var(--color-600); } }
dl { padding-block: 1rem; padding-inline: 0.5rem;
dt { color: var(--color-600); text-transform: uppercase; font-weight: 600; letter-spacing: -0.01em; margin-block-end: 0.25rem; }
dd:not(:last-child) { margin-block-end: 0.75lh; } }
[role='group'] { display: flex; gap: 0.25rem; flex-wrap: wrap;
.chip { display: inline-flex; align-items: center; gap: 0.75rem;
border: 2px solid var(--color-100); background-color: var(--color-100); border-radius: 1.5rem;
padding: 0.5rem 0.75rem; color: var(--color-700); white-space: nowrap;
:global(svg) { width: 1rem; height: 1rem; fill: var(--color-700); } } }
.buttons { margin-block-start: auto; } }
.banner { padding: 1rem; img { object-fit: cover; border-radius: 1.5rem; aspect-ratio: 16 / 9; } }</style>