feat: refactor buttons, except for theme

This commit is contained in:
2026-02-14 22:09:49 -06:00
parent 2cdef1a553
commit 342ae8900a
21 changed files with 280 additions and 318 deletions

View File

@@ -1,5 +1,5 @@
--- ---
import PrimaryCTA from '@components/ui/buttons/PrimaryCTA.astro'; import GoLinkPrimary from '@components/ui/buttons/GoLinkPrimary.astro';
import Image from '@components/ui/images/Image.astro'; import Image from '@components/ui/images/Image.astro';
interface Props { interface Props {
@@ -39,6 +39,6 @@ const { title, subTitle, btnExists, btnTitle, btnURL, img, imgAlt } = Astro.prop
> >
{subTitle} {subTitle}
</p> </p>
{btnExists ? <PrimaryCTA title={btnTitle} url={btnURL} /> : null} {btnExists ? <GoLinkPrimary title={btnTitle} url={btnURL} /> : null}
</div> </div>
</section> </section>

View File

@@ -1,5 +1,5 @@
--- ---
import PrimaryCTA from '@components/ui/buttons/PrimaryCTA.astro'; import GoLinkPrimary from '@components/ui/buttons/GoLinkPrimary.astro';
import Image from '@components/ui/images/Image.astro'; import Image from '@components/ui/images/Image.astro';
interface Props { interface Props {
@@ -43,7 +43,7 @@ const {
> >
{subTitle} {subTitle}
</p> </p>
{btnExists ? <PrimaryCTA title={btnTitle} url={btnURL} /> : null} {btnExists ? <GoLinkPrimary title={btnTitle} url={btnURL} /> : null}
</div> </div>
{ {

View File

@@ -4,7 +4,7 @@ import Icon from '@components/ui/icons/icon.astro';
<button <button
type="button" type="button"
class="focus-visible:ring-secondary group inline-flex items-center rounded-lg p-2.5 text-neutral-600 ring-neutral-500 transition duration-300 outline-none hover:bg-neutral-100 focus:outline-none focus-visible:ring-1 focus-visible:outline-none dark:text-neutral-400 dark:ring-neutral-200 dark:hover:bg-neutral-700" class="button-base button-bg-blue group inline-flex items-center rounded-lg p-2.5"
data-bookmark-button="bookmark-button" data-bookmark-button="bookmark-button"
> >
<Icon name="bookmark" /> <Icon name="bookmark" />

View File

@@ -1,32 +0,0 @@
---
import { Icon } from 'astro-icon/components';
const { title, url } = Astro.props;
interface Props {
title?: string;
url?: string;
}
const baseClasses =
'group group-hover inline-flex items-center justify-center gap-x-3 rounded-full px-4 py-3 text-center text-sm font-medium text-neutral-200';
const borderClasses = 'border border-transparent';
const bgColorClasses =
'bg-gitea-primary hover:bg-gitea-secondary dark:bg-gitea-secondary dark:hover:bg-gitea-primary';
const shadowClasses = 'shadow-sm';
const fontSizeClasses = '2xl:text-base';
---
<a
class={`${baseClasses} ${borderClasses} ${bgColorClasses} ${shadowClasses} ${fontSizeClasses} `}
href={url}
target="_blank"
rel="noopener noreferrer"
>
<Icon name="pajamas:gitea" class="h-4 w-4 md:h-6 md:w-6" />
{title}
<Icon
name="mdi:keyboard-arrow-right"
class="h-3 w-3 translate-y-0.25 transition duration-300 group-hover:translate-x-1 md:h-5 md:w-5"
/>
</a>

View File

@@ -0,0 +1,31 @@
---
import { Icon } from 'astro-icon/components';
interface Props {
title?: string;
url?: string;
}
const { title, url } = Astro.props;
---
<a
class="button-base button-bg-gitea group inline-flex rounded-full gap-x-2"
href={url}
target="_blank"
rel="noopener noreferrer"
>
<div class="button-text-title flex relative items-center text-center">
<Icon
name="pajamas:gitea"
class="h-4 w-4 md:h-6 md:w-6"
/>
<span class="ml-2">
{title}
</span>
<Icon
name="mdi:keyboard-arrow-right"
class="button-hover-arrow"
/>
</div>
</a>

View File

@@ -1,31 +1,24 @@
--- ---
import Icon from '@components/ui/icons/icon.astro'; import Icon from '@components/ui/icons/icon.astro';
const { title, noArrow } = Astro.props;
interface Props { interface Props {
title?: string;
url?: string;
noArrow?: boolean; noArrow?: boolean;
addHome?: boolean;
} }
const baseClasses = const { noArrow } = Astro.props;
'group inline-flex items-center justify-center gap-x-2 rounded-lg px-4 py-3 text-sm font-bold text-neutral-50 ring-neutral-500 transition duration-300 focus-visible:ring outline-none';
const borderClasses = 'border border-transparent';
const bgColorClasses = 'bg-steel hover:bg-sky-800 active:bg-orange-500 dark:focus:outline-none';
const disableClasses = 'disabled:pointer-events-none disabled:opacity-50';
const fontSizeClasses = '2xl:text-base';
const ringClasses = 'dark:ring-neutral-200';
--- ---
<button <button
class={`${baseClasses} ${borderClasses} ${bgColorClasses} ${disableClasses} ${fontSizeClasses} ${ringClasses}`} class="button-base button-bg-blue group inline-flex rounded-lg gap-x-2"
id="back-button" id="back-button"
data-astro-prefetch data-astro-prefetch
> >
{noArrow ? null : <Icon name="arrowLeft" />} <div class="button-text-title flex relative items-center text-center">
{title} {noArrow ? null : <Icon name="arrowLeft" />}
<span class="ml-2">
Go Back
</span>
</div>
</button> </button>
<script> <script>

View File

@@ -0,0 +1,25 @@
---
import { Icon } from 'astro-icon/components';
interface Props {
url?: string;
}
const { url } = Astro.props;
---
<a
class="button-base button-bg-teal group inline-flex rounded-lg gap-x-2"
href={url}
data-astro-prefetch
>
<div class="button-text-title flex relative items-center text-center">
<Icon
name="mdi:home-variant-outline"
class="card-hover-icon-scale h-3 w-3 md:h-5 md:w-5"
/>
<span class="ml-2">
Return Home
</span>
</div>
</a>

View File

@@ -0,0 +1,29 @@
---
import { Icon } from 'astro-icon/components';
interface Props {
title?: string;
url?: string;
noArrow?: boolean;
}
const { title, url, noArrow } = Astro.props;
---
<a
class="button-base button-bg-teal group inline-flex rounded-lg gap-x-2"
href={url}
data-astro-prefetch
>
<div class="button-text-title flex relative items-center text-center">
<span class="mr-2">
{title}
</span>
{noArrow ? null : (
<Icon
name="mdi:keyboard-arrow-right"
class="button-hover-arrow"
/>
)}
</div>
</a>

View File

@@ -0,0 +1,20 @@
---
interface Props {
title?: string;
url?: string;
}
const { title, url } = Astro.props;
---
<a
class="button-base button-bg-neutral group inline-flex rounded-lg gap-x-2"
href={url}
data-astro-prefetch
>
<div class="button-text-title flex relative items-center text-center">
<span>
{title}
</span>
</div>
</a>

View File

@@ -1,45 +0,0 @@
---
import { Icon } from 'astro-icon/components';
const { title, url, noArrow, addHome, addClass } = Astro.props;
interface Props {
title?: string;
url?: string;
noArrow?: boolean;
addHome?: boolean;
addClass?: string;
}
const baseClasses =
'group inline-flex items-center justify-center gap-x-2 rounded-lg px-4 py-3 text-sm font-bold text-neutral-100 transition duration-300 ';
const borderClasses = 'border border-transparent';
const bgColorClasses = 'bg-bermuda hover:bg-turquoise dark:bg-turquoise dark:hover:bg-bermuda';
const disableClasses = 'disabled:pointer-events-none disabled:opacity-50';
const fontSizeClasses = '2xl:text-base';
const ringClasses = 'dark:ring-neutral-200';
---
<a
class={`${baseClasses} ${borderClasses} ${bgColorClasses} ${disableClasses} ${fontSizeClasses} ${ringClasses} ${addClass}`}
href={url}
data-astro-prefetch
>
{
addHome ? (
<Icon
name="mdi:home-variant-outline"
class="h-3 w-3 translate-y-0.25 transition duration-300 group-hover:translate-x-1 md:h-5 md:w-5"
/>
) : null
}
{title}
{
noArrow ? null : (
<Icon
name="mdi:keyboard-arrow-right"
class="h-3 w-3 translate-y-0.25 transition duration-300 group-hover:translate-x-1 md:h-5 md:w-5"
/>
)
}
</a>

View File

@@ -1,26 +0,0 @@
---
const { title, url } = Astro.props;
interface Props {
title?: string;
url?: string;
}
const baseClasses =
'inline-flex items-center justify-center gap-x-2 rounded-lg px-4 py-3 text-center text-sm font-medium text-neutral-600 shadow-sm outline-none ring-neutral-500 focus-visible:ring transition duration-300';
const borderClasses = 'border border-neutral-200';
const bgColorClasses = 'bg-neutral-300';
const hoverClasses = 'hover:bg-neutral-400/50 hover:text-neutral-600 active:text-neutral-700';
const disableClasses = 'disabled:pointer-events-none disabled:opacity-50';
const fontSizeClasses = '2xl:text-base';
const ringClasses = 'ring-neutral-500';
const darkClasses =
'dark:border-neutral-700 dark:bg-neutral-700 dark:text-neutral-300 dark:ring-neutral-200 dark:hover:bg-neutral-600 dark:focus:outline-none';
---
<a
class={`${baseClasses} ${borderClasses} ${bgColorClasses} ${hoverClasses} ${disableClasses} ${fontSizeClasses} ${ringClasses} ${darkClasses}`}
href={url}
>
{title}
</a>

View File

@@ -1,150 +1,51 @@
--- ---
import Icon from '@components/ui/icons/icon.astro'; import Icon from '@components/ui/icons/icon.astro';
const { pageTitle, title = 'Share' } = Astro.props;
interface Props {
pageTitle: string;
title?: string;
}
type SocialPlatform = { type SocialPlatform = {
name: string; name: string;
url: string; url: string;
svg: string; svg: string;
}; };
interface Props {
pageTitle: string;
}
const { pageTitle } = Astro.props;
const socialPlatforms: SocialPlatform[] = [ const socialPlatforms: SocialPlatform[] = [
{ {
name: 'Facebook', name: 'Facebook',
url: `https://www.facebook.com/share.php?u=${Astro.url}&title=${pageTitle}`, url: `https://www.facebook.com/sharer/sharer.php?u=${Astro.url}`,
svg: 'facebook', svg: 'facebook',
}, },
{ {
name: 'X', name: 'X',
url: `https://twitter.com/home/?status=${pageTitle}${Astro.url}`, url: `https://x.com/intent/tweet?url=${Astro.url}&text=${pageTitle}`,
svg: 'x', svg: 'x',
}, },
{ {
name: 'LinkedIn', name: 'LinkedIn',
url: `https://www.linkedin.com/shareArticle?mini=true&url=${Astro.url}&title=${pageTitle}`, url: `https://www.linkedin.com/sharing/share-offsite/?url=${Astro.url}`,
svg: 'linkedIn', svg: 'linkedIn',
}, },
]; ];
--- ---
<div class="hs-dropdown relative inline-flex [--auto-close:inside] [--placement:top-left]"> <div class="inline-flex items-center gap-x-2">
<button {
id="hs-dropup" socialPlatforms.map((platform) => (
type="button" <a
class="hs-dropdown-toggle inline-flex items-center gap-x-2 rounded-lg px-4 py-3 text-sm font-medium text-neutral-600 ring-neutral-500 transition duration-300 outline-none hover:bg-neutral-100 hover:text-neutral-700 focus-visible:ring dark:text-neutral-400 dark:ring-neutral-200 dark:hover:bg-neutral-700 dark:hover:text-neutral-300 dark:focus:outline-none" class="button-base-hidden group inline-flex rounded-lg gap-x-2"
> href={platform.url}
<Icon name="share" /> target="_blank"
rel="noopener noreferrer"
{title} title={`Share on ${platform.name}`}
</button>
<div
class="hs-dropdown-menu duration hs-dropdown-open:opacity-100 z-10 hidden w-72 divide-y divide-neutral-200 rounded-lg bg-neutral-50 p-2 opacity-0 shadow-md transition-[opacity,margin] dark:divide-neutral-700 dark:border dark:border-neutral-700 dark:bg-neutral-800"
aria-labelledby="hs-dropup"
>
<div class="py-2 first:pt-0 last:pb-0">
{
socialPlatforms.map((platform) => (
<a
class="flex items-center gap-x-3.5 rounded-lg px-3 py-2 text-sm text-neutral-700 hover:bg-neutral-200 focus:bg-neutral-100 focus:outline-none dark:text-neutral-300 dark:hover:bg-neutral-700 dark:hover:text-neutral-300 dark:focus:bg-neutral-700"
href={platform.url}
>
<Icon name={platform.svg} />
Share on {platform.name}
</a>
))
}
</div>
<div class="py-2 first:pt-0 last:pb-0">
<button
type="button"
class="js-clipboard hover:text-dark focus-visible:ring-secondary group inline-flex w-full items-center gap-x-3.5 rounded-lg px-3 py-2 text-sm text-neutral-700 hover:bg-neutral-200 focus:bg-neutral-100 focus:outline-none focus-visible:ring-1 focus-visible:outline-none dark:text-neutral-300 dark:hover:bg-neutral-700 dark:hover:text-neutral-300 dark:focus:bg-neutral-700"
data-clipboard-success-text="Copied"
> >
<svg <div class="button-text-title-hidden flex relative items-center text-center">
class="js-clipboard-default h-4 w-4 transition group-hover:rotate-6" <Icon name={platform.svg} class="h-5 w-5" />
width="24" </div>
height="24" </a>
viewBox="0 0 24 24" ))
fill="none" }
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect width="8" height="4" x="8" y="2" rx="1" ry="1"></rect>
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path>
</svg>
<svg
class="js-clipboard-success hidden h-4 w-4 text-neutral-700 dark:text-neutral-300"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
<span class="js-clipboard-success-text">Copy link</span>
</button>
</div>
</div>
</div> </div>
<!--Import the necessary Dropdown and Clipboard plugins-->
<!--https://preline.co/plugins/html/dropdown.html-->
<!--<script is:inline src="/scripts/vendor/preline/dropdown/index.js"></script>-->
<!-- https://clipboardjs.com/ -->
<!--<script is:inline src="/scripts/vendor/clipboard.min.js"></script>-->
<script is:inline>
(function () {
window.addEventListener('load', () => {
const $clipboards = document.querySelectorAll('.js-clipboard');
$clipboards.forEach((el) => {
const clipboard = new ClipboardJS(el, {
text: () => {
return window.location.href;
},
});
clipboard.on('success', () => {
const $default = el.querySelector('.js-clipboard-default');
const $success = el.querySelector('.js-clipboard-success');
const $successText = el.querySelector('.js-clipboard-success-text');
const successText = el.dataset.clipboardSuccessText || '';
let oldSuccessText;
if ($successText) {
oldSuccessText = $successText.textContent;
$successText.textContent = successText;
}
if ($default && $success) {
$default.style.display = 'none';
$success.style.display = 'block';
}
setTimeout(() => {
if ($successText && oldSuccessText) {
$successText.textContent = oldSuccessText;
}
if ($default && $success) {
$success.style.display = '';
$default.style.display = '';
}
}, 800);
});
});
});
})();
</script>

View File

@@ -55,7 +55,7 @@ const visitClass = visitSource ? 'card-hover-text-gitea' : 'card-hover-text-titl
)} )}
<div class="ml-6 flex"> <div class="ml-6 flex">
<div class="relative inline-block"> <div class="relative inline-block">
<div class={`card-text-title ${visitClass} flex relative mx-auto min-h-11 items-center font-semibold text-md sm:mx-0 sm:mt-4`}> <div class={`card-text-title ${visitClass} flex relative items-center mx-auto min-h-11 font-semibold text-md sm:mx-0 sm:mt-4`}>
{visitSource && <Icon name="pajamas:gitea" />} {visitSource && <Icon name="pajamas:gitea" />}
<span class="relative inline-block overflow-hidden ml-2"> <span class="relative inline-block overflow-hidden ml-2">
{visitText} {visitText}

View File

@@ -1,5 +1,5 @@
--- ---
import GiteaBtn from '@components/ui/buttons/GiteaBtn.astro'; import GiteaButton from '@components/ui/buttons/GiteaButton.astro';
const { title, subTitle, url } = Astro.props; const { title, subTitle, url } = Astro.props;
const btnTitle = 'Continue to Gitea'; const btnTitle = 'Continue to Gitea';
@@ -126,7 +126,7 @@ interface Props {
{ {
url && ( url && (
<div class="smooth-reveal-2 mt-8 flex justify-center gap-3"> <div class="smooth-reveal-2 mt-8 flex justify-center gap-3">
<GiteaBtn url={url} title={btnTitle} /> <GiteaButton url={url} title={btnTitle} />
</div> </div>
) )
} }

View File

@@ -1,5 +1,5 @@
--- ---
import PrimaryCTA from '@components/ui/buttons/PrimaryCTA.astro'; import GoLinkPrimary from '@components/ui/buttons/GoLinkPrimary.astro';
interface Props { interface Props {
title: string; title: string;
@@ -26,7 +26,7 @@ const { title, subTitle, btnExists, btnTitle, btnURL } = Astro.props;
{ {
btnExists ? ( btnExists ? (
<div class="smooth-reveal mt-4 md:mt-8"> <div class="smooth-reveal mt-4 md:mt-8">
<PrimaryCTA title={btnTitle} url={btnURL} /> <GoLinkPrimary title={btnTitle} url={btnURL} />
</div> </div>
) : null ) : null
} }

View File

@@ -1,6 +1,6 @@
--- ---
import PrimaryCTA from '@components/ui/buttons/PrimaryCTA.astro'; import GoLinkPrimary from '@components/ui/buttons/GoLinkPrimary.astro';
import SecondaryCTA from '@components/ui/buttons/SecondaryCTA.astro'; import GoLinkSecondary from '@components/ui/buttons/GoLinkSecondary.astro';
import Image from '@components/ui/images/Image.astro'; import Image from '@components/ui/images/Image.astro';
const { title, subTitle, primaryBtn, primaryBtnURL, secondaryBtn, secondaryBtnURL, src, alt } = const { title, subTitle, primaryBtn, primaryBtnURL, secondaryBtn, secondaryBtnURL, src, alt } =
@@ -39,8 +39,8 @@ const roundedClasses = Astro.props.rounded ? "rounded-xl" : null;
} }
<div class="smooth-reveal mt-7 grid w-full gap-3 sm:inline-flex"> <div class="smooth-reveal mt-7 grid w-full gap-3 sm:inline-flex">
{primaryBtn && <PrimaryCTA title={primaryBtn} url={primaryBtnURL} />} {primaryBtn && <GoLinkPrimary title={primaryBtn} url={primaryBtnURL} />}
{secondaryBtn && <SecondaryCTA title={secondaryBtn} url={secondaryBtnURL} />} {secondaryBtn && <GoLinkSecondary title={secondaryBtn} url={secondaryBtnURL} />}
</div> </div>
</div> </div>

View File

@@ -3,8 +3,8 @@ import { readSingleton } from '@directus/sdk';
import directus from '@lib/directus'; import directus from '@lib/directus';
import BaseLayout from '@layouts/BaseLayout.astro'; import BaseLayout from '@layouts/BaseLayout.astro';
import PrimaryCTA from '@components/ui/buttons/PrimaryCTA.astro';
import GoBack from '@/components/ui/buttons/GoBack.astro'; import GoBack from '@/components/ui/buttons/GoBack.astro';
import GoHome from '@/components/ui/buttons/GoHome.astro';
const global = await directus.request(readSingleton('site_global')); const global = await directus.request(readSingleton('site_global'));
--- ---
@@ -61,8 +61,8 @@ const global = await directus.request(readSingleton('site_global'));
<div <div
class="smooth-reveal mt-10 flex flex-col items-center justify-center gap-4 sm:flex-row" class="smooth-reveal mt-10 flex flex-col items-center justify-center gap-4 sm:flex-row"
> >
<GoBack title="Go Back" /> <GoBack/>
<PrimaryCTA title="Return Home" url={global.site_url} noArrow addHome /> <GoHome url={global.site_url} />
</div> </div>
</div> </div>
</div> </div>

View File

@@ -10,6 +10,7 @@ import { createHighlighter } from 'shiki';
import { getDirectusImageURL } from '@lib/directusFunctions'; import { getDirectusImageURL } from '@lib/directusFunctions';
import BaseLayout from '@layouts/BaseLayout.astro'; import BaseLayout from '@layouts/BaseLayout.astro';
import Image from '@components/ui/images/Image.astro'; import Image from '@components/ui/images/Image.astro';
import SocialShare from '@components/ui/buttons/SocialShare.astro';
import { formatDateTime } from '@support/time'; import { formatDateTime } from '@support/time';
export async function getStaticPaths() { export async function getStaticPaths() {
@@ -162,6 +163,9 @@ const content = marked.parse(post.content);
)) ))
} }
</div> </div>
<SocialShare
pageTitle={post.title}
/>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -7,7 +7,8 @@ import HeroSection from '@components/ui/sections/HeroSection.astro';
import FeaturesSection from '@components/ui/sections/FeaturesSection.astro'; import FeaturesSection from '@components/ui/sections/FeaturesSection.astro';
import WeatherSection from '@components/ui/sections/WeatherSection.astro'; import WeatherSection from '@components/ui/sections/WeatherSection.astro';
import LatestPosts from '@components/ui/sections/LatestPosts.astro'; import LatestPosts from '@components/ui/sections/LatestPosts.astro';
import HeroSectionAlt from '@components/ui/sections/HeroSectionAlt.astro'; import GiteaSection from '@components/ui/sections/GiteaSection.astro';
import homeImg from '@images/autumn_mountain.png'; import homeImg from '@images/autumn_mountain.png';
const global = await directus.request(readSingleton('site_global')); const global = await directus.request(readSingleton('site_global'));
@@ -55,7 +56,7 @@ const weather = await directus.request(readSingleton('site_weather'));
<LatestPosts /> <LatestPosts />
<HeroSectionAlt <GiteaSection
title="Follow me on Gitea" title="Follow me on Gitea"
subTitle="I love open source and have my code availabile on my Gitea server." subTitle="I love open source and have my code availabile on my Gitea server."
url="https://gitea.alexlebens.dev" url="https://gitea.alexlebens.dev"

View File

@@ -1,5 +1,7 @@
@import 'tailwindcss'; @import 'tailwindcss';
@import 'preline/variants.css'; @import 'preline/variants.css';
@import './utilities.css';
@plugin '@tailwindcss/typography'; @plugin '@tailwindcss/typography';
@plugin '@tailwindcss/forms'; @plugin '@tailwindcss/forms';
@@ -10,11 +12,17 @@
/* Custom colors */ /* Custom colors */
@theme { @theme {
--color-midnight: #0c354d; --color-midnight: #0c354d;
--color-turquoise: #0da797; --color-ocean: #134e70;
--color-cobalt: #6c9cb0;
--color-steel: #4682b4; --color-steel: #4682b4;
--color-turquoise: #0da797;
--color-bermuda: #7fbab4; --color-bermuda: #7fbab4;
--color-desert: #f9deb2; --color-desert: #f9deb2;
--color-bronze: #9e7f5e; --color-bronze: #9e7f5e;
--color-gitea-primary: #609926; --color-gitea-primary: #609926;
--color-gitea-secondary: #4c7a33; --color-gitea-secondary: #4c7a33;
@@ -98,63 +106,6 @@
} }
} }
@utility card-base {
@apply rounded-xl transition-all duration-300
border border-neutral-100 dark:border-stone-500/20
bg-neutral-100/80 hover:bg-neutral-100 dark:bg-neutral-800/60 dark:hover:bg-neutral-800/90
shadow-xs hover:shadow-md dark:shadow-md dark:hover:shadow-lg
}
@utility card-hover-icon-color {
@apply transition-all duration-300
text-primary
group-hover:text-main
}
@utility card-hover-icon-scale {
@apply transition-all duration-300
drop-shadow-sm
group-hover:scale-110
}
@utility card-text-header {
@apply text-header
md:text-5xl
text-4xl
}
@utility card-text-header-minor {
@apply text-header
md:text-3xl
text-2xl
font-semibold
}
@utility card-text-header-description {
@apply text-primary
text-lg
text-pretty
}
@utility card-text-title {
@apply text-primary
font-bold
}
@utility card-text-description {
@apply text-secondary
}
@utility card-hover-text-title {
@apply transition-all duration-300
group-hover:text-main
}
@utility card-hover-text-gitea {
@apply transition-all duration-300
group-hover:text-gitea-primary
}
/* Content reveal animations */ /* Content reveal animations */
.smooth-reveal, .smooth-reveal,
.smooth-reveal-2, .smooth-reveal-2,

110
src/styles/utilities.css Normal file
View File

@@ -0,0 +1,110 @@
/* Button classes */
@utility button-base {
@apply transition-all duration-300
border border-transparent
shadow-sm hover:shadow-md dark:shadow-md dark:hover:shadow-lg
px-4 py-3
}
@utility button-base-hidden {
@apply transition-all duration-300
border border-transparent
hover:bg-neutral-100 dark:hover:bg-neutral-700
p-2
}
@utility button-hover-arrow {
@apply translate-y-px transition duration-300
group-hover:translate-x-1
h-3 w-3 md:h-5 md:w-5
}
@utility button-text-title {
@apply text-neutral-200 2xl:text-base
text-sm font-bold
}
@utility button-text-title-hidden {
@apply transition-all duration-300
text-neutral-600 group-hover:text-neutral-700 dark:text-neutral-400 dark:group-hover:text-neutral-300 2xl:text-base
text-sm font-medium
}
@utility button-bg-blue {
@apply transition-all duration-300
bg-cobalt hover:bg-steel dark:bg-steel dark:hover:bg-cobalt
}
@utility button-bg-teal {
@apply transition-all duration-300
bg-bermuda hover:bg-turquoise dark:bg-turquoise dark:hover:bg-bermuda
}
@utility button-bg-neutral {
@apply transition-all duration-300
border border-neutral-100 dark:border-stone-500/20
bg-neutral-100/80 hover:bg-neutral-100 dark:bg-neutral-800/60 dark:hover:bg-neutral-800/90
}
@utility button-bg-gitea {
@apply transition-all duration-300
bg-gitea-primary hover:bg-gitea-secondary dark:bg-gitea-secondary dark:hover:bg-gitea-primary
}
/* Card classes */
@utility card-base {
@apply rounded-xl
border border-neutral-100 dark:border-stone-500/20
bg-neutral-100/80 hover:bg-neutral-100 dark:bg-neutral-800/60 dark:hover:bg-neutral-800/90
shadow-xs hover:shadow-md dark:shadow-md dark:hover:shadow-lg
}
@utility card-hover-icon-color {
@apply transition-all duration-300
text-primary
group-hover:text-main
}
@utility card-hover-icon-scale {
@apply transition-all duration-300
drop-shadow-sm
group-hover:scale-110
}
@utility card-text-header {
@apply text-header
md:text-5xl
text-4xl
}
@utility card-text-header-minor {
@apply text-header
md:text-3xl
text-2xl
font-semibold
}
@utility card-text-header-description {
@apply text-primary
text-lg
text-pretty
}
@utility card-text-title {
@apply text-primary
font-bold
}
@utility card-hover-text-title {
@apply transition-all duration-300
group-hover:text-main
}
@utility card-hover-text-gitea {
@apply transition-all duration-300
group-hover:text-gitea-primary
}
@utility card-text-description {
@apply text-secondary
}