Moved to keeping the SVGs in repo
Some checks failed
Docker Deploy / build-and-push (push) Failing after 3m7s

This commit is contained in:
2026-02-12 13:15:34 -07:00
parent b15dce4cd4
commit 62dcec8202
13 changed files with 324 additions and 793 deletions

View File

@@ -3,8 +3,6 @@ import { defineConfig } from "astro/config";
import vue from "@astrojs/vue";
import node from "@astrojs/node";
import tailwindcss from "@tailwindcss/vite";
import icon from "astro-icon";
import yeskunallumami from "@yeskunall/astro-umami";
import partytown from "@astrojs/partytown";
const isDev = process.env.NODE_ENV === "development";
@@ -17,12 +15,10 @@ export default defineConfig({
},
integrations: [
vue(),
icon(),
partytown(),
yeskunallumami({
id: "c7e24af4-5f14-4881-9c25-85a97abda9f1",
hostUrl: "https://analytics.atri.dad",
withPartytown: true,
partytown({
config: {
forward: ["umami.track"],
},
}),
],

View File

@@ -9,24 +9,20 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/node": "10.0.0-beta.2",
"@astrojs/node": "10.0.0-beta.4",
"@astrojs/partytown": "^2.1.4",
"@astrojs/vue": "6.0.0-beta.0",
"@astrojs/vue": "6.0.0-beta.1",
"@fontsource-variable/inter": "^5.2.8",
"@fontsource-variable/roboto-slab": "^5.2.8",
"@heroicons/vue": "^2.2.0",
"@tailwindcss/vite": "^4.1.18",
"@yeskunall/astro-umami": "^0.0.7",
"astro": "6.0.0-beta.9",
"astro-icon": "^1.1.5",
"motion-v": "^1.10.2",
"astro": "6.0.0-beta.11",
"motion-v": "^1.10.3",
"nodemailer": "^8.0.1",
"tailwindcss": "^4.1.18",
"vue": "^3.5.28"
},
"devDependencies": {
"@iconify-json/heroicons": "^1.2.3",
"@types/node": "^25.2.2",
"@types/node": "^25.2.3",
"@types/nodemailer": "^7.0.9",
"daisyui": "^5.5.18"
}

947
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
---
import { siteConfig } from "../config/site";
import { Icon } from "astro-icon/components";
import Icon from "./Icon.astro";
import { Image } from "astro:assets";
---
@@ -17,7 +17,7 @@ import { Image } from "astro:assets";
class="btn btn-ghost btn-circle lg:hidden"
aria-label="Open menu"
>
<Icon name="heroicons:bars-3-bottom-left" class="h-5 w-5" />
<Icon name="bars-3-bottom-left" class="h-5 w-5" />
</div>
<ul
tabindex="0"

25
src/components/Icon.astro Normal file
View File

@@ -0,0 +1,25 @@
---
import { icons, type IconName } from "../config/icons";
interface Props {
name: IconName;
class?: string;
"class:list"?: any;
}
const { name, class: className, "class:list": classList } = Astro.props;
const svg = icons[name];
if (!svg) {
throw new Error(`Icon "${name}" not found in icon registry`);
}
---
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
class:list={[className, classList]}
aria-hidden="true"
set:html={svg}
/>

28
src/components/Icon.vue Normal file
View File

@@ -0,0 +1,28 @@
<script setup lang="ts">
import { computed } from "vue";
import { icons, type IconName } from "../config/icons";
const props = defineProps<{
name: IconName;
class?: string;
}>();
const svg = computed(() => {
const content = icons[props.name];
if (!content) {
console.error(`Icon "${props.name}" not found in icon registry`);
}
return content;
});
</script>
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
:class="props.class"
aria-hidden="true"
v-html="svg"
/>
</template>

View File

@@ -1,19 +1,19 @@
---
import { Icon } from "astro-icon/components";
import Icon from "../Icon.astro";
import { siteConfig } from "../../config/site";
import Section from "../Section.astro";
const features = [
{
icon: "heroicons:bolt",
icon: "bolt",
...siteConfig.whyUs.cards[0],
},
{
icon: "heroicons:check-circle",
icon: "check-circle",
...siteConfig.whyUs.cards[1],
},
{
icon: "heroicons:users",
icon: "users",
...siteConfig.whyUs.cards[2],
},
];

View File

@@ -1,11 +1,6 @@
<script setup lang="ts">
import { ref } from "vue";
import {
XCircleIcon,
CheckCircleIcon,
PaperAirplaneIcon,
EnvelopeIcon,
} from "@heroicons/vue/24/outline";
import Icon from "../Icon.vue";
import { siteConfig } from "../../config/site";
const firstName = ref("");
@@ -249,15 +244,15 @@ ${message.value}`,
{{ siteConfig.contact.form.sending }}
</template>
<template v-else-if="status === 'success'">
<CheckCircleIcon class="w-5 h-5" />
<Icon name="check-circle" class="w-5 h-5" />
{{ siteConfig.contact.form.success }}
</template>
<template v-else-if="status === 'error'">
<XCircleIcon class="w-5 h-5" />
<Icon name="x-circle" class="w-5 h-5" />
{{ errorMessage || siteConfig.contact.form.error }}
</template>
<template v-else>
<PaperAirplaneIcon class="w-5 h-5" />
<Icon name="paper-airplane" class="w-5 h-5" />
{{ siteConfig.contact.form.submit }}
</template>
</button>
@@ -273,7 +268,7 @@ ${message.value}`,
:href="`mailto:${siteConfig.contact.direct.email}`"
class="link font-medium inline-flex items-center gap-2 text-base-content hover:text-primary"
>
<EnvelopeIcon class="w-5 h-5" />
<Icon name="envelope" class="w-5 h-5" />
{{ siteConfig.contact.direct.email }}
</a>
</div>

View File

@@ -1,6 +1,6 @@
---
import { siteConfig } from "../../config/site";
import { Icon } from "astro-icon/components";
import Icon from "../Icon.astro";
import Section from "../Section.astro";
import RotatingText from "../RotatingText.vue";
import StatusIndicator from "../StatusIndicator.vue";
@@ -56,14 +56,14 @@ const rotatingText = (siteConfig.hero as any).rotatingText as
href="#contact"
class="btn btn-accent btn-lg shadow-lg shadow-accent/25 hover:shadow-xl hover:shadow-accent/30"
>
<Icon name="heroicons:bolt" class="w-5 h-5" />
<Icon name="bolt" class="w-5 h-5" />
{siteConfig.hero.cta}
</a>
<a
href="#services"
class="btn btn-outline btn-lg border-white text-white hover:bg-white hover:text-neutral hover:border-white transition-all duration-300"
>
<Icon name="heroicons:chevron-down" class="w-5 h-5" />
<Icon name="chevron-down" class="w-5 h-5" />
{siteConfig.hero.secondaryCta}
</a>
</div>

View File

@@ -1,6 +1,6 @@
---
import { siteConfig } from "../../config/site";
import { Icon } from "astro-icon/components";
import Icon from "../Icon.astro";
import Section from "../Section.astro";
const variantStyles: Record<string, string> = {

27
src/config/icons.ts Normal file
View File

@@ -0,0 +1,27 @@
export const icons = {
bolt: `<path d="M3.75 13.5L14.25 2.25L12 10.5H20.25L9.75 21.75L12 13.5H3.75Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
"chevron-down": `<path d="M19.5 8.25L12 15.75L4.5 8.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
"bars-3-bottom-left": `<path d="M3.75 6.75H20.25M3.75 12H20.25M3.75 17.25H12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
"computer-desktop": `<path d="M9 17.25V18.2574C9 19.053 8.68393 19.8161 8.12132 20.3787L7.5 21H16.5L15.8787 20.3787C15.3161 19.8161 15 19.053 15 18.2574V17.25M21 5.25V15C21 16.2426 19.9926 17.25 18.75 17.25H5.25C4.00736 17.25 3 16.2426 3 15V5.25M21 5.25C21 4.00736 19.9926 3 18.75 3H5.25C4.00736 3 3 4.00736 3 5.25M21 5.25V12C21 13.2426 19.9926 14.25 18.75 14.25H5.25C4.00736 14.25 3 13.2426 3 12V5.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
"device-phone-mobile": `<path d="M10.5 1.5H8.25C7.00736 1.5 6 2.50736 6 3.75V20.25C6 21.4926 7.00736 22.5 8.25 22.5H15.75C16.9926 22.5 18 21.4926 18 20.25V3.75C18 2.50736 16.9926 1.5 15.75 1.5H13.5M10.5 1.5V3H13.5V1.5M10.5 1.5H13.5M10.5 20.25H13.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
"cog-6-tooth": `<path d="M9.59356 3.94014C9.68397 3.39768 10.1533 3.00009 10.7033 3.00009H13.2972C13.8472 3.00009 14.3165 3.39768 14.4069 3.94014L14.6204 5.22119C14.6828 5.59523 14.9327 5.9068 15.2645 6.09045C15.3387 6.13151 15.412 6.17393 15.4844 6.21766C15.8095 6.41393 16.2048 6.47495 16.5604 6.34175L17.7772 5.88587C18.2922 5.69293 18.8712 5.9006 19.1462 6.37687L20.4432 8.6233C20.7181 9.09957 20.6085 9.70482 20.1839 10.0544L19.1795 10.8812C18.887 11.122 18.742 11.4938 18.7491 11.8726C18.7498 11.915 18.7502 11.9575 18.7502 12.0001C18.7502 12.0427 18.7498 12.0852 18.7491 12.1275C18.742 12.5064 18.887 12.8782 19.1795 13.119L20.1839 13.9458C20.6085 14.2953 20.7181 14.9006 20.4432 15.3769L19.1462 17.6233C18.8712 18.0996 18.2922 18.3072 17.7772 18.1143L16.5604 17.6584C16.2048 17.5252 15.8095 17.5862 15.4844 17.7825C15.412 17.8263 15.3387 17.8687 15.2645 17.9097C14.9327 18.0934 14.6828 18.4049 14.6204 18.779L14.4069 20.06C14.3165 20.6025 13.8472 21.0001 13.2972 21.0001H10.7033C10.1533 21.0001 9.68397 20.6025 9.59356 20.06L9.38005 18.779C9.31771 18.4049 9.06774 18.0934 8.73597 17.9097C8.66179 17.8687 8.58847 17.8263 8.51604 17.7825C8.19101 17.5863 7.79568 17.5252 7.44011 17.6584L6.22325 18.1143C5.70826 18.3072 5.12926 18.0996 4.85429 17.6233L3.55731 15.3769C3.28234 14.9006 3.39199 14.2954 3.81657 13.9458L4.82092 13.119C5.11343 12.8782 5.25843 12.5064 5.25141 12.1276C5.25063 12.0852 5.25023 12.0427 5.25023 12.0001C5.25023 11.9575 5.25063 11.915 5.25141 11.8726C5.25843 11.4938 5.11343 11.122 4.82092 10.8812L3.81657 10.0544C3.39199 9.70484 3.28234 9.09958 3.55731 8.62332L4.85429 6.37688C5.12926 5.90061 5.70825 5.69295 6.22325 5.88588L7.4401 6.34176C7.79566 6.47496 8.19099 6.41394 8.51603 6.21767C8.58846 6.17393 8.66179 6.13151 8.73597 6.09045C9.06774 5.9068 9.31771 5.59523 9.38005 5.22119L9.59356 3.94014Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M15 12C15 13.6569 13.6569 15 12 15C10.3431 15 9 13.6569 9 12C9 10.3432 10.3431 9.00001 12 9.00001C13.6569 9.00001 15 10.3432 15 12Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
lifebuoy: `<path d="M16.7124 4.3299C17.2999 4.69153 17.8548 5.12691 18.364 5.63604C18.8731 6.14517 19.3085 6.70012 19.6701 7.28763M16.7124 4.3299L13.2636 8.46838M16.7124 4.3299C13.8316 2.5567 10.1684 2.5567 7.28763 4.3299M19.6701 7.28763L15.5316 10.7364M19.6701 7.28763C21.4433 10.1684 21.4433 13.8316 19.6701 16.7124M15.5316 10.7364C15.3507 10.2297 15.0574 9.75408 14.6517 9.34835C14.2459 8.94262 13.7703 8.6493 13.2636 8.46838M15.5316 10.7364C15.8228 11.5519 15.8228 12.4481 15.5316 13.2636M13.2636 8.46838C12.4481 8.17721 11.5519 8.17721 10.7364 8.46838M15.5316 13.2636C15.3507 13.7703 15.0574 14.2459 14.6517 14.6517C14.2459 15.0574 13.7703 15.3507 13.2636 15.5316M15.5316 13.2636L19.6701 16.7124M19.6701 16.7124C19.3085 17.2999 18.8731 17.8548 18.364 18.364C17.8548 18.8731 17.2999 19.3085 16.7124 19.6701M16.7124 19.6701L13.2636 15.5316M16.7124 19.6701C13.8316 21.4433 10.1684 21.4433 7.28763 19.6701M13.2636 15.5316C12.4481 15.8228 11.5519 15.8228 10.7364 15.5316M10.7364 15.5316C10.2297 15.3507 9.75408 15.0574 9.34835 14.6517C8.94262 14.2459 8.6493 13.7703 8.46838 13.2636M10.7364 15.5316L7.28763 19.6701M7.28763 19.6701C6.70012 19.3085 6.14517 18.8731 5.63604 18.364C5.12691 17.8548 4.69153 17.2999 4.3299 16.7124M4.3299 16.7124L8.46838 13.2636M4.3299 16.7124C2.5567 13.8316 2.5567 10.1684 4.3299 7.28763M8.46838 13.2636C8.17721 12.4481 8.17721 11.5519 8.46838 10.7364M8.46838 10.7364C8.6493 10.2297 8.94262 9.75408 9.34835 9.34835C9.75408 8.94262 10.2297 8.6493 10.7364 8.46838M8.46838 10.7364L4.3299 7.28763M10.7364 8.46838L7.28763 4.3299M7.28763 4.3299C6.70012 4.69153 6.14517 5.12691 5.63604 5.63604C5.12691 6.14517 4.69153 6.70013 4.3299 7.28763" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
"check-circle": `<path d="M9 12.75L11.25 15L15 9.75M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
users: `<path d="M15 19.1276C15.8329 19.37 16.7138 19.5 17.625 19.5C19.1037 19.5 20.5025 19.1576 21.7464 18.5478C21.7488 18.4905 21.75 18.4329 21.75 18.375C21.75 16.0968 19.9031 14.25 17.625 14.25C16.2069 14.25 14.956 14.9655 14.2136 16.0552M15 19.1276V19.125C15 18.0121 14.7148 16.9658 14.2136 16.0552M15 19.1276C15 19.1632 14.9997 19.1988 14.9991 19.2343C13.1374 20.3552 10.9565 21 8.625 21C6.29353 21 4.11264 20.3552 2.25092 19.2343C2.25031 19.198 2.25 19.1615 2.25 19.125C2.25 15.6042 5.10418 12.75 8.625 12.75C11.0329 12.75 13.129 14.085 14.2136 16.0552M12 6.375C12 8.23896 10.489 9.75 8.625 9.75C6.76104 9.75 5.25 8.23896 5.25 6.375C5.25 4.51104 6.76104 3 8.625 3C10.489 3 12 4.51104 12 6.375ZM20.25 8.625C20.25 10.0747 19.0747 11.25 17.625 11.25C16.1753 11.25 15 10.0747 15 8.625C15 7.17525 16.1753 6 17.625 6C19.0747 6 20.25 7.17525 20.25 8.625Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
"x-circle": `<path d="M9.75 9.75L14.25 14.25M14.25 9.75L9.75 14.25M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
"paper-airplane": `<path d="M5.99972 12L3.2688 3.12451C9.88393 5.04617 16.0276 8.07601 21.4855 11.9997C16.0276 15.9235 9.884 18.9535 3.26889 20.8752L5.99972 12ZM5.99972 12L13.5 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
envelope: `<path d="M21.75 6.75V17.25C21.75 18.4926 20.7426 19.5 19.5 19.5H4.5C3.25736 19.5 2.25 18.4926 2.25 17.25V6.75M21.75 6.75C21.75 5.50736 20.7426 4.5 19.5 4.5H4.5C3.25736 4.5 2.25 5.50736 2.25 6.75M21.75 6.75V6.99271C21.75 7.77405 21.3447 8.49945 20.6792 8.90894L13.1792 13.5243C12.4561 13.9694 11.5439 13.9694 10.8208 13.5243L3.32078 8.90894C2.65535 8.49945 2.25 7.77405 2.25 6.99271V6.75" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>`,
} as const;
export type IconName = keyof typeof icons;

View File

@@ -1,3 +1,5 @@
import type { IconName } from "./icons";
type Card = {
title: string;
content: string;
@@ -59,9 +61,9 @@ export const siteConfig = {
secondaryCta: "View Services",
trustedText: "Trusted expertise in",
features: [
{ icon: "heroicons:computer-desktop", text: "Web Development" },
{ icon: "heroicons:device-phone-mobile", text: "Mobile Apps" },
{ icon: "heroicons:cog-6-tooth", text: "DevOps" },
{ icon: "computer-desktop", text: "Web Development" },
{ icon: "device-phone-mobile", text: "Mobile Apps" },
{ icon: "cog-6-tooth", text: "DevOps" },
],
},
@@ -72,28 +74,28 @@ export const siteConfig = {
title: "Web Development",
content: "Functional, accessible, and beautiful websites.",
variant: "primary",
icon: "heroicons:computer-desktop",
icon: "computer-desktop",
},
{
title: "Mobile App Development",
content: "iOS, Android, and cross-platform mobile applications.",
variant: "secondary",
icon: "heroicons:device-phone-mobile",
icon: "device-phone-mobile",
},
{
title: "DevOps",
content: "From CI/CD pipelines to end-to-end automation.",
variant: "secondary",
icon: "heroicons:cog-6-tooth",
icon: "cog-6-tooth",
},
{
title: "IT Support Processes",
content:
"Expert technical guidance backed by over a decade of experience.",
variant: "primary",
icon: "heroicons:lifebuoy",
icon: "lifebuoy",
},
] as (Card & { icon: string })[],
] as (Card & { icon: IconName })[],
},
whyUs: {

View File

@@ -15,6 +15,8 @@ const { title = siteConfig.name, description = siteConfig.description } =
const metaTitle =
title === siteConfig.name ? title : `${title} | ${siteConfig.name}`;
const isProd = import.meta.env.PROD;
---
<!doctype html>
@@ -26,6 +28,15 @@ const metaTitle =
<meta name="generator" content={Astro.generator} />
<meta name="description" content={description} />
<title>{metaTitle}</title>
{isProd && (
<script
type="text/partytown"
defer
src="https://analytics.atri.dad/script.js"
data-website-id="c7e24af4-5f14-4881-9c25-85a97abda9f1"
data-astro-rerun
></script>
)}
</head>
<body class="min-h-screen flex flex-col bg-base-100 font-sans antialiased">
<Header />