diff --git a/src/web/components/description.astro b/src/web/components/description.astro
index 8dd56e4..ee1cbd2 100644
--- a/src/web/components/description.astro
+++ b/src/web/components/description.astro
@@ -1,5 +1,6 @@
---
import Description from '@/components/description.astro';
+import { variantToClassName } from './typography.astro';
export interface Props {
content: string;
@@ -7,9 +8,6 @@ export interface Props {
}
const { content, class: className } = Astro.props;
-
-const baseClass =
- /* tw */ 'text-sm leading-relaxed font-normal text-gray-500 sm:text-base sm:leading-relaxed dark:text-gray-300';
---
-
+
diff --git a/src/web/components/download-button.astro b/src/web/components/download-button.astro
index 9c58632..8a2edf3 100644
--- a/src/web/components/download-button.astro
+++ b/src/web/components/download-button.astro
@@ -1,18 +1,21 @@
---
import type { DownloadButton } from '@/types/shared';
+import Typography from './typography.astro';
export interface Props extends DownloadButton {}
const { url, downloadedFileName, label } = Astro.props;
const classes = /* tw */ {
- main: 'inline-flex items-center px-4 h-10 text-base font-medium rounded-md shadow-sm text-white bg-primary-600 select-none cursor-pointer',
+ main: 'inline-flex items-center px-4 h-10 rounded-md shadow-sm bg-primary-600 select-none cursor-pointer',
hover: 'hover:bg-primary-700',
active: 'active:translate-y-px',
focus: 'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500',
};
+
+const className = Object.values(classes).join(' ');
---
-
+
{label}
-
+
diff --git a/src/web/components/labelled-value.astro b/src/web/components/labelled-value.astro
index e68ea5a..cc18513 100644
--- a/src/web/components/labelled-value.astro
+++ b/src/web/components/labelled-value.astro
@@ -1,5 +1,6 @@
---
import type { LabelledValue } from '@/types/shared';
+import Typography from './typography.astro';
export interface Props extends LabelledValue {}
@@ -8,15 +9,15 @@ const { label, value, url } = Astro.props;
const parsedValue = Array.isArray(value) ? value.join(', ') : value;
---
-
-
{label}:
+
diff --git a/src/web/components/tag.astro b/src/web/components/tag.astro
index 33ffc9b..660b28e 100644
--- a/src/web/components/tag.astro
+++ b/src/web/components/tag.astro
@@ -1,31 +1,27 @@
---
import type { Tag } from '@/types/shared';
import Icon from './icon.astro';
+import Typography from './typography.astro';
export interface Props extends Tag {}
const { name, description, icon, iconColor, url } = Astro.props;
-const className =
- /* tw */ 'flex h-6 w-fit items-center gap-x-1.5 rounded bg-gray-100 px-2.5 text-sm font-medium tracking-wide text-gray-700 dark:bg-gray-700 dark:text-gray-100';
+const className = /* tw */ 'flex h-6 w-fit items-center gap-x-1.5 rounded bg-gray-100 px-2.5 dark:bg-gray-700';
+const customProps = url
+ ? ({
+ href: url,
+ as: 'a',
+ target: '_blank',
+ rel: 'noopener noreferrer',
+ class: `${className} hover:bg-gray-200 dark:hover:bg-gray-600`,
+ } as const)
+ : {
+ class: className,
+ };
---
-{
- url ? (
-
- {icon && }
- {name}
-
- ) : (
-
- {icon && }
- {name}
-
- )
-}
+
+ {icon && }
+ {name}
+
diff --git a/src/web/components/tags-list.astro b/src/web/components/tags-list.astro
index 1a6227d..d8b699e 100644
--- a/src/web/components/tags-list.astro
+++ b/src/web/components/tags-list.astro
@@ -1,6 +1,7 @@
---
import type { TagsList } from '@/types/shared';
import Tag from './tag.astro';
+import Typography from './typography.astro';
export interface Props extends Omit
{
title?: TagsList['title'];
@@ -12,7 +13,7 @@ const { tags, title } = Astro.props;
{
title ? (
-
{title}:
+
{title}:
{tags.map((tag) => (
diff --git a/src/web/components/timestamp.astro b/src/web/components/timestamp.astro
index 7f7fc1f..a54a1c6 100644
--- a/src/web/components/timestamp.astro
+++ b/src/web/components/timestamp.astro
@@ -9,6 +9,6 @@ export interface Props {
const { dates } = Astro.props;
---
-
+
{formatDateRange(dates)}
diff --git a/src/web/components/typography.astro b/src/web/components/typography.astro
index f243742..e1fae2a 100644
--- a/src/web/components/typography.astro
+++ b/src/web/components/typography.astro
@@ -1,15 +1,5 @@
---
-type TypographyVariant =
- | 'main-title'
- | 'main-subtitle'
- | 'section-title'
- | 'section-subtitle'
- | 'item-title'
- | 'item-title-suffix'
- | 'item-subtitle'
- | 'tile-title'
- | 'tile-subtitle'
- | 'paragraph';
+type TypographyVariant = keyof typeof variantToElement;
const variantToElement = {
'main-title': 'h1',
@@ -17,33 +7,50 @@ const variantToElement = {
'section-title': 'h2',
'section-subtitle': 'h3',
'item-title': 'h3',
- 'item-title-suffix': 'span',
- 'item-subtitle': 'p',
+ 'item-subtitle-primary': 'p',
+ 'item-subtitle-secondary': 'p',
'tile-title': 'h4',
'tile-subtitle': 'p',
paragraph: 'p',
+ label: 'span',
+ value: 'span',
+ skill: 'span',
+ tag: 'div',
+ button: 'div',
} as const;
-const variantToClassName /* tw */ = {
+export const variantToClassName: Record /* tw */ = {
'main-title': 'text-3xl sm:text-4xl font-extrabold text-gray-900 dark:text-gray-100',
'main-subtitle': 'text-base sm:text-lg font-medium text-gray-700 dark:text-gray-100',
'section-title': 'text-3xl font-extrabold text-gray-900 dark:text-gray-100',
'section-subtitle': 'text-lg font-extrabold text-gray-900 dark:text-gray-100',
'item-title': 'text-xl font-extrabold text-gray-900 dark:text-gray-100',
- 'item-title-suffix': 'text-xl font-medium text-gray-700 dark:text-gray-100',
- 'item-subtitle': 'text-sm font-medium text-gray-700 dark:text-gray-100',
+ 'item-subtitle-primary': 'text-base font-semibold leading-snug text-gray-900 dark:text-gray-100',
+ 'item-subtitle-secondary': 'text-sm font-medium text-gray-700 dark:text-gray-100',
'tile-title': 'text-sm font-medium text-gray-700 dark:text-gray-200',
'tile-subtitle': 'text-sm font-normal text-gray-500 dark:text-gray-300',
paragraph: 'text-sm leading-relaxed font-normal text-gray-500 sm:text-base sm:leading-relaxed dark:text-gray-300',
+ label: 'text-base font-medium text-gray-700 dark:text-gray-300',
+ value: 'text-base font-normal text-gray-500 dark:text-gray-400',
+ skill: 'text-sm font-medium text-gray-700 dark:text-gray-300',
+ tag: 'text-sm font-medium tracking-wide text-gray-700 dark:text-gray-100',
+ button: 'text-base font-medium text-white',
};
-export interface Props extends Omit {
- variant?: TypographyVariant;
- component?: keyof JSX.IntrinsicElements;
+interface LinkProps {
+ href?: string;
+ target?: string;
+ rel?: string;
+ download?: string;
}
-const { variant = 'paragraph', component, ...props } = Astro.props;
-const Element = component ?? variantToElement[variant];
+export interface Props extends Omit, LinkProps {
+ as?: keyof JSX.IntrinsicElements;
+ variant?: TypographyVariant;
+}
+
+const { variant = 'paragraph', as, class: className, ...props } = Astro.props;
+const Element = as ?? variantToElement[variant];
---
-
+
diff --git a/src/web/sections/education/diploma.astro b/src/web/sections/education/diploma.astro
index 42c4e4d..933b7ca 100644
--- a/src/web/sections/education/diploma.astro
+++ b/src/web/sections/education/diploma.astro
@@ -17,7 +17,7 @@ const { title, institution, dates, description, links, image } = Astro.props;
{title}
-
{institution}
+
{institution}
diff --git a/src/web/sections/experience/job.astro b/src/web/sections/experience/job.astro
index 6670f29..a9004f4 100644
--- a/src/web/sections/experience/job.astro
+++ b/src/web/sections/experience/job.astro
@@ -18,7 +18,7 @@ const { role, company, dates, description, links, tagsList, image } = Astro.prop
{role}
-
{company}
+
{company}
diff --git a/src/web/sections/main/main-section.web.astro b/src/web/sections/main/main-section.web.astro
index 66123fb..21cc74e 100644
--- a/src/web/sections/main/main-section.web.astro
+++ b/src/web/sections/main/main-section.web.astro
@@ -7,6 +7,7 @@ import Photo from '@/components/photo.astro';
import SectionCard from '@/web/components/section-card.astro';
import TagsList from '@/web/components/tags-list.astro';
import Typography from '@/web/components/typography.astro';
+import LabelledValue from '@/web/components/labelled-value.astro';
export interface Props extends MainSection {}
@@ -43,16 +44,7 @@ const { action, config, description, details, fullName, image, links, role, tags
- {
- details.map(({ label: detailLabel, value }) => (
-
-
- {detailLabel}:
- {value}
-
-
- ))
- }
+ {details.map((detail) =>
)}
diff --git a/src/web/sections/skills/levelled-skill.astro b/src/web/sections/skills/levelled-skill.astro
index 4a6d85c..49dddea 100644
--- a/src/web/sections/skills/levelled-skill.astro
+++ b/src/web/sections/skills/levelled-skill.astro
@@ -15,9 +15,7 @@ const IconWrapper = url ? 'a' : 'div';
{icon && }
-
- {name}
-
+ {name}
{
description && (
diff --git a/src/web/sections/testimonials/testimonial.astro b/src/web/sections/testimonials/testimonial.astro
index 74957db..9a770d5 100644
--- a/src/web/sections/testimonials/testimonial.astro
+++ b/src/web/sections/testimonials/testimonial.astro
@@ -16,7 +16,7 @@ const { author, content, image, links, relation } = Astro.props;
{author}
- {relation}
+ {relation}
{