improve UI

This commit is contained in:
padreug 2025-02-12 00:06:57 +01:00
parent b32c609a3b
commit f3eb1622eb
9 changed files with 320 additions and 231 deletions

View file

@ -79,7 +79,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
*/ */
workbox.precacheAndRoute([{ workbox.precacheAndRoute([{
"url": "index.html", "url": "index.html",
"revision": "0.3s1v9t4dfmo" "revision": "0.fnrrna5najg"
}], {}); }], {});
workbox.cleanupOutdatedCaches(); workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {

View file

@ -1,165 +1,182 @@
@import "tailwindcss"; @import "tailwindcss";
@layer base { @layer base {
:root { :root {
/* Catppuccin Latte */ --background: 227 92% 95%;
--color-background: #eff1f5; --foreground: 234 16% 35%;
--color-foreground: #4c4f69;
--color-card: #e6e9ef; --card: 225 23% 92%;
--color-card-foreground: #4c4f69; --card-foreground: 234 16% 35%;
--color-popover: #e6e9ef;
--color-popover-foreground: #4c4f69; --popover: 225 23% 92%;
--color-primary: #1e66f5;
--color-primary-foreground: #eff1f5;
--color-secondary: #ccd0da;
--color-secondary-foreground: #4c4f69;
--color-muted: #ccd0da;
--color-muted-foreground: #6c6f85;
--color-accent: #dc8a78;
--color-accent-foreground: #eff1f5;
--color-destructive: #d20f39;
--color-destructive-foreground: #eff1f5;
--color-border: #bcc0cc;
--color-input: #bcc0cc;
--color-ring: #1e66f5;
--radius: 0.5rem;
--popover: 220 23% 95%;
--popover-foreground: 234 16% 35%; --popover-foreground: 234 16% 35%;
/* Fallback colors for older browsers */
--fallback-background: #ffffff; --primary: 220 91% 54%;
--fallback-popover: #f5f5f5; --primary-foreground: 227 92% 95%;
--secondary: 227 23% 83%;
--secondary-foreground: 234 16% 35%;
--muted: 227 23% 83%;
--muted-foreground: 231 11% 47%;
--accent: 11 83% 67%;
--accent-foreground: 227 92% 95%;
--destructive: 347 87% 44%;
--destructive-foreground: 227 92% 95%;
--border: 228 17% 77%;
--input: 228 17% 77%;
--ring: 220 91% 54%;
--radius: 0.5rem;
} }
.dark { .dark {
/* Catppuccin Macchiato - we'll use the same colors for dark mode */ --background: 233 31% 18%;
--color-background: #24273a; --foreground: 227 68% 88%;
--color-foreground: #cad3f5;
--color-card: #1e2030;
--color-card-foreground: #cad3f5;
--color-popover: #1e2030;
--color-popover-foreground: #cad3f5;
--color-primary: #8aadf4;
--color-primary-foreground: #24273a;
--color-secondary: #363a4f;
--color-secondary-foreground: #cad3f5;
--color-muted: #363a4f;
--color-muted-foreground: #a5adcb;
--color-accent: #f4dbd6;
--color-accent-foreground: #24273a;
--color-destructive: #ed8796;
--color-destructive-foreground: #24273a;
--color-border: #363a4f;
--color-input: #363a4f;
--color-ring: #8aadf4;
--popover: 240 21% 15%;
--popover-foreground: 226 64% 88%;
/* Fallback colors for older browsers */
--fallback-background: #1e1e2e;
--fallback-popover: #313244;
}
--card: 234 32% 15%;
--card-foreground: 227 68% 88%;
--popover: 234 32% 15%;
--popover-foreground: 227 68% 88%;
--primary: 220 83% 76%;
--primary-foreground: 233 31% 18%;
--secondary: 233 25% 26%;
--secondary-foreground: 227 68% 88%;
--muted: 233 25% 26%;
--muted-foreground: 225 27% 72%;
--accent: 11 77% 90%;
--accent-foreground: 233 31% 18%;
--destructive: 351 74% 76%;
--destructive-foreground: 233 31% 18%;
--border: 233 25% 26%;
--input: 233 25% 26%;
--ring: 220 83% 76%;
}
}
@layer base {
* { * {
@apply box-border; @apply box-border;
} }
body { body {
@apply bg-background text-foreground; background-color: hsl(var(--background));
color: hsl(var(--foreground));
} }
} }
@utility bg-background { @layer utilities {
background-color: var(--color-background); .bg-background {
} background-color: hsl(var(--background));
}
.bg-foreground {
background-color: hsl(var(--foreground));
}
.bg-card {
background-color: hsl(var(--card));
}
.bg-card-foreground {
background-color: hsl(var(--card-foreground));
}
.bg-popover {
background-color: hsl(var(--popover));
}
.bg-popover-foreground {
background-color: hsl(var(--popover-foreground));
}
.bg-primary {
background-color: hsl(var(--primary));
}
.bg-primary-foreground {
background-color: hsl(var(--primary-foreground));
}
.bg-secondary {
background-color: hsl(var(--secondary));
}
.bg-secondary-foreground {
background-color: hsl(var(--secondary-foreground));
}
.bg-muted {
background-color: hsl(var(--muted));
}
.bg-muted-foreground {
background-color: hsl(var(--muted-foreground));
}
.bg-accent {
background-color: hsl(var(--accent));
}
.bg-accent-foreground {
background-color: hsl(var(--accent-foreground));
}
.bg-destructive {
background-color: hsl(var(--destructive));
}
.bg-destructive-foreground {
background-color: hsl(var(--destructive-foreground));
}
@utility text-foreground { .text-background {
color: var(--color-foreground); color: hsl(var(--background));
} }
.text-foreground {
color: hsl(var(--foreground));
}
.text-card {
color: hsl(var(--card));
}
.text-card-foreground {
color: hsl(var(--card-foreground));
}
.text-popover {
color: hsl(var(--popover));
}
.text-popover-foreground {
color: hsl(var(--popover-foreground));
}
.text-primary {
color: hsl(var(--primary));
}
.text-primary-foreground {
color: hsl(var(--primary-foreground));
}
.text-secondary {
color: hsl(var(--secondary));
}
.text-secondary-foreground {
color: hsl(var(--secondary-foreground));
}
.text-muted {
color: hsl(var(--muted));
}
.text-muted-foreground {
color: hsl(var(--muted-foreground));
}
.text-accent {
color: hsl(var(--accent));
}
.text-accent-foreground {
color: hsl(var(--accent-foreground));
}
.text-destructive {
color: hsl(var(--destructive));
}
.text-destructive-foreground {
color: hsl(var(--destructive-foreground));
}
/* Add other utility classes for colors */ @supports not (backdrop-filter: blur(1px)) {
@utility bg-card { .select-content {
background-color: var(--color-card); background-color: hsl(var(--background));
} }
@utility text-card-foreground {
color: var(--color-card-foreground);
}
@utility bg-primary {
background-color: var(--color-primary);
}
@utility text-primary-foreground {
color: var(--color-primary-foreground);
}
/* ... add other utility classes as needed ... */
/* :root { */
/* /* gruvbox light theme */ */
/* --color-background: hsl(32 92% 87%); /* bg0 */ */
/* --color-foreground: hsl(40 13% 23%); /* fg */ */
/**/
/* --color-card: hsl(39 59% 88%); /* bg1 */ */
/* --color-card-foreground: hsl(40 13% 23%); /* fg */ */
/**/
/* --color-popover: hsl(39 59% 88%); /* bg1 */ */
/* --color-popover-foreground: hsl(40 13% 23%); /* fg */ */
/**/
/* --color-primary: hsl(0 100% 31%); /* red */ */
/* --color-primary-foreground: hsl(40 92% 88%); /* bg */ */
/**/
/* --color-secondary: hsl(39 46% 81%); /* bg2 */ */
/* --color-secondary-foreground: hsl(40 13% 23%); /* fg */ */
/**/
/* --color-muted: hsl(37 29% 73%); /* bg3 */ */
/* --color-muted-foreground: hsl(40 4% 36%); /* gray */ */
/**/
/* --color-accent: hsl(40 71% 49%); /* yellow */ */
/* --color-accent-foreground: hsl(0 0% 16%); */
/**/
/* --color-destructive: hsl(0 76% 46%); /* bright_red */ */
/* --color-destructive-foreground: hsl(40 92% 88%); /* bg */ */
/**/
/* --color-border: hsl(33 14% 59%); /* fg4 */ */
/* --color-input: hsl(33 14% 59%); /* fg4 */ */
/* --color-ring: hsl(0 100% 31%); /* red */ */
/**/
/* --radius: 0.5rem; */
/* } */
/* .dark { */
/* /* gruvbox dark theme */ */
/* --color-background: hsl(0 0% 16%); /* bg0 */ */
/* --color-foreground: hsl(40 92% 88%); /* fg */ */
/**/
/* --color-card: hsl(0 7% 23%); /* bg1 */ */
/* --color-card-foreground: hsl(40 92% 88%); /* fg */ */
/**/
/* --color-popover: hsl(0 7% 23%); /* bg1 */ */
/* --color-popover-foreground: hsl(40 92% 88%); /* fg */ */
/**/
/* --color-primary: hsl(6 93% 59%); /* red */ */
/* --color-primary-foreground: hsl(0 0% 16%); /* bg */ */
/**/
/* --color-secondary: hsl(0 5% 29%); /* bg2 */ */
/* --color-secondary-foreground: hsl(40 92% 88%); /* fg */ */
/**/
/* --color-muted: hsl(20 6% 36%); /* bg3 */ */
/* --color-muted-foreground: hsl(33 14% 59%); /* gray */ */
/**/
/* --color-accent: hsl(42 95% 58%); /* yellow */ */
/* --color-accent-foreground: hsl(0 0% 16%); */
/**/
/* --color-destructive: hsl(6 93% 59%); /* bright_red */ */
/* --color-destructive-foreground: hsl(40 92% 88%); /* bg */ */
/**/
/* --color-border: hsl(24 10% 51%); /* fg4 */ */
/* --color-input: hsl(24 10% 51%); /* fg4 */ */
/* --color-ring: hsl(6 93% 59%); /* red */ */
/* } */
@supports not (backdrop-filter: blur(1px)) {
.select-content {
background-color: var(--fallback-background) !important;
} }
} }

64
src/assets/index.css.gruv Normal file
View file

@ -0,0 +1,64 @@
/* ... add other utility classes as needed ... */
/* :root { */
/* /* gruvbox light theme */ */
/* --color-background: hsl(32 92% 87%); /* bg0 */ */
/* --color-foreground: hsl(40 13% 23%); /* fg */ */
/**/
/* --color-card: hsl(39 59% 88%); /* bg1 */ */
/* --color-card-foreground: hsl(40 13% 23%); /* fg */ */
/**/
/* --color-popover: hsl(39 59% 88%); /* bg1 */ */
/* --color-popover-foreground: hsl(40 13% 23%); /* fg */ */
/**/
/* --color-primary: hsl(0 100% 31%); /* red */ */
/* --color-primary-foreground: hsl(40 92% 88%); /* bg */ */
/**/
/* --color-secondary: hsl(39 46% 81%); /* bg2 */ */
/* --color-secondary-foreground: hsl(40 13% 23%); /* fg */ */
/**/
/* --color-muted: hsl(37 29% 73%); /* bg3 */ */
/* --color-muted-foreground: hsl(40 4% 36%); /* gray */ */
/**/
/* --color-accent: hsl(40 71% 49%); /* yellow */ */
/* --color-accent-foreground: hsl(0 0% 16%); */
/**/
/* --color-destructive: hsl(0 76% 46%); /* bright_red */ */
/* --color-destructive-foreground: hsl(40 92% 88%); /* bg */ */
/**/
/* --color-border: hsl(33 14% 59%); /* fg4 */ */
/* --color-input: hsl(33 14% 59%); /* fg4 */ */
/* --color-ring: hsl(0 100% 31%); /* red */ */
/**/
/* --radius: 0.5rem; */
/* } */
/* .dark { */
/* /* gruvbox dark theme */ */
/* --color-background: hsl(0 0% 16%); /* bg0 */ */
/* --color-foreground: hsl(40 92% 88%); /* fg */ */
/**/
/* --color-card: hsl(0 7% 23%); /* bg1 */ */
/* --color-card-foreground: hsl(40 92% 88%); /* fg */ */
/**/
/* --color-popover: hsl(0 7% 23%); /* bg1 */ */
/* --color-popover-foreground: hsl(40 92% 88%); /* fg */ */
/**/
/* --color-primary: hsl(6 93% 59%); /* red */ */
/* --color-primary-foreground: hsl(0 0% 16%); /* bg */ */
/**/
/* --color-secondary: hsl(0 5% 29%); /* bg2 */ */
/* --color-secondary-foreground: hsl(40 92% 88%); /* fg */ */
/**/
/* --color-muted: hsl(20 6% 36%); /* bg3 */ */
/* --color-muted-foreground: hsl(33 14% 59%); /* gray */ */
/**/
/* --color-accent: hsl(42 95% 58%); /* yellow */ */
/* --color-accent-foreground: hsl(0 0% 16%); */
/**/
/* --color-destructive: hsl(6 93% 59%); /* bright_red */ */
/* --color-destructive-foreground: hsl(40 92% 88%); /* bg */ */
/**/
/* --color-border: hsl(24 10% 51%); /* fg4 */ */
/* --color-input: hsl(24 10% 51%); /* fg4 */ */
/* --color-ring: hsl(6 93% 59%); /* red */ */
/* } */

View file

@ -16,11 +16,7 @@ const props = withDefaults(defineProps<Props>(), {
</script> </script>
<template> <template>
<Primitive <Primitive :as="as" :as-child="asChild" :class="cn(buttonVariants({ variant, size }), props.class)">
:as="as"
:as-child="asChild"
:class="cn(buttonVariants({ variant, size }), props.class)"
>
<slot /> <slot />
</Primitive> </Primitive>
</template> </template>

View file

@ -43,44 +43,34 @@ const handleLogout = () => {
</DialogTrigger> </DialogTrigger>
<DialogContent class="sm:max-w-md"> <DialogContent class="sm:max-w-md">
<DialogHeader class="space-y-4"> <DialogHeader class="space-y-4">
<div class="mx-auto w-12 h-12 rounded-full bg-gradient-to-br from-red-500 to-orange-500 p-0.5 shadow-lg"> <div class="mx-auto w-12 h-12 rounded-full bg-gradient-to-br from-primary to-primary/80 p-0.5">
<div class="w-full h-full rounded-full bg-background flex items-center justify-center"> <div class="w-full h-full rounded-full bg-background flex items-center justify-center">
<ShieldAlert class="h-6 w-6 text-red-500" /> <ShieldAlert class="h-6 w-6 text-primary" />
</div> </div>
</div> </div>
<div class="text-center space-y-2"> <div class="text-center space-y-2">
<DialogTitle class="text-xl font-semibold text-red-500"> <DialogTitle class="text-xl font-semibold text-foreground">
Backup Required Backup Required
</DialogTitle> </DialogTitle>
<DialogDescription> <DialogDescription class="text-muted-foreground">
If you haven't saved your private key, you will permanently lose access to this chat history. Make sure to copy and securely store your private key before logging out. If you haven't saved your private key, you will permanently lose access to this chat history. Make sure to
copy and securely store your private key before logging out.
</DialogDescription> </DialogDescription>
</div> </div>
</DialogHeader> </DialogHeader>
<div class="flex flex-col gap-4 py-6"> <div class="flex flex-col gap-4 py-6">
<Button <Button class="w-full bg-muted hover:bg-muted/80 text-muted-foreground" variant="outline"
class="w-full" @click="copyPrivateKey">
variant="outline"
@click="copyPrivateKey"
>
<Copy v-if="!hasCopied" class="h-4 w-4 mr-2" /> <Copy v-if="!hasCopied" class="h-4 w-4 mr-2" />
<Check v-else class="h-4 w-4 mr-2" /> <Check v-else class="h-4 w-4 mr-2" />
{{ hasCopied ? 'Copied!' : 'Copy Private Key' }} {{ hasCopied ? 'Copied!' : 'Copy Private Key' }}
</Button> </Button>
</div> </div>
<DialogFooter class="flex flex-col sm:flex-row gap-2 sm:gap-3"> <DialogFooter class="flex flex-col sm:flex-row gap-2 sm:gap-3">
<Button <Button variant="ghost" @click="() => isOpen = false" class="flex-1 sm:flex-none hover:bg-muted">
variant="ghost"
@click="() => isOpen = false"
class="flex-1 sm:flex-none"
>
Cancel Cancel
</Button> </Button>
<Button <Button variant="destructive" @click="handleLogout" class="flex-1 sm:flex-none">
variant="destructive"
@click="handleLogout"
class="flex-1 sm:flex-none"
>
<LogOut class="h-4 w-4 mr-2" /> <LogOut class="h-4 w-4 mr-2" />
Logout Logout
</Button> </Button>
@ -92,7 +82,7 @@ const handleLogout = () => {
<style scoped> <style scoped>
/* Improved focus styles */ /* Improved focus styles */
:focus-visible { :focus-visible {
outline: 2px solid #cba6f7; outline: 2px solid hsl(var(--primary));
outline-offset: 2px; outline-offset: 2px;
transition: outline-offset 0.2s ease; transition: outline-offset 0.2s ease;
} }

View file

@ -1,12 +1,9 @@
export default { export default {
nav: { nav: {
title: 'Directorio Atitlán',
home: 'Inicio', home: 'Inicio',
directory: 'Directorio', directory: 'Directorio',
faq: 'Preguntas', faq: 'Preguntas',
support: 'Soporte', title: 'Directorio Atitlán'
login: 'Iniciar Sesión',
logout: 'Cerrar Sesión'
}, },
home: { home: {
title: 'Encuentra Aceptadores de Bitcoin Lightning', title: 'Encuentra Aceptadores de Bitcoin Lightning',
@ -17,7 +14,7 @@ export default {
selectTownPlaceholder: 'Selecciona tu ubicación...' selectTownPlaceholder: 'Selecciona tu ubicación...'
}, },
directory: { directory: {
title: 'Directorio', title: 'Directorio de Pagos Lightning',
subtitle: 'Encuentra lugares que aceptan pagos Bitcoin Lightning', subtitle: 'Encuentra lugares que aceptan pagos Bitcoin Lightning',
search: 'Buscar...', search: 'Buscar...',
categories: { categories: {

View file

@ -60,27 +60,52 @@ const filteredItems = computed(() => {
</script> </script>
<template> <template>
<div class="container mx-auto px-4 py-2 md:py-8"> <div class="px-0 md:container md:px-4 py-2 md:py-8">
<div class="space-y-4"> <div class="space-y-4 md:space-y-6">
<!-- Directory Header --> <!-- Directory Header -->
<div class="hidden md:block text-center space-y-2 mb-6"> <div class="text-center space-y-2 mb-2 md:mb-6">
<h1 class="text-2xl font-bold tracking-tight sm:text-3xl"> <h1 class="md:hidden text-lg font-semibold tracking-tight px-4">
{{ t('directory.title') }} {{ t('directory.title') }}
</h1> </h1>
<p class="text-sm sm:text-base text-muted-foreground"> <div class="hidden md:block space-y-2">
{{ t('directory.subtitle') }} <h1 class="text-2xl font-bold tracking-tight sm:text-3xl">
</p> {{ t('directory.title') }}
</h1>
<p class="text-sm sm:text-base text-muted-foreground">
{{ t('directory.subtitle') }}
</p>
</div>
</div> </div>
<!-- Sticky Container for Filter --> <!-- Sticky Container for Filter -->
<div class="sticky top-14 z-40 -mx-4 bg-background/95 backdrop-blur-sm border-b w-screen left-0"> <div class="sticky top-14 z-40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-b md:border-b-0 w-full shadow-sm transition-all duration-200">
<div class="container mx-auto px-4"> <div class="w-full">
<DirectoryFilter v-model:category="category" v-model:search="search" v-model:town="town" class="py-4" /> <DirectoryFilter v-model:category="category" v-model:search="search" v-model:town="town" class="py-3 px-4" />
</div> </div>
</div> </div>
<!-- Directory Grid --> <!-- Directory Grid -->
<DirectoryGrid :items="filteredItems" class="pt-4" /> <div class="pt-4 px-4 md:px-0">
<DirectoryGrid :items="filteredItems" class="transition-all duration-300" />
</div>
</div> </div>
</div> </div>
</template> </template>
<style scoped>
.fade-move,
.fade-enter-active,
.fade-leave-active {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
transform: translateY(10px);
}
.fade-leave-active {
position: absolute;
}
</style>

View file

@ -63,21 +63,24 @@ const towns = computed(() => [
</script> </script>
<template> <template>
<div class="container mx-auto px-4 py-8"> <div class="container mx-auto px-4 py-8 sm:py-12">
<div class="max-w-3xl mx-auto text-center space-y-6 sm:space-y-8"> <div class="max-w-3xl mx-auto text-center space-y-8 sm:space-y-12">
<h1 class="text-3xl font-bold tracking-tight sm:text-6xl"> <!-- Hero Section -->
{{ t('home.title') }} <div class="space-y-4">
</h1> <h1 class="text-4xl font-bold tracking-tight sm:text-6xl text-foreground animate-in fade-in slide-in-from-bottom-4 duration-1000 fill-mode-both">
{{ t('home.title') }}
</h1>
<p class="text-base sm:text-lg text-muted-foreground max-w-2xl mx-auto"> <p class="text-base sm:text-lg text-muted-foreground max-w-2xl mx-auto animate-in fade-in slide-in-from-bottom-4 duration-1000 delay-150 fill-mode-both">
{{ t('home.subtitle') }} {{ t('home.subtitle') }}
</p> </p>
</div>
<!-- Town Selector - Move above category buttons --> <!-- Town Selector -->
<div class="flex flex-col items-center gap-2"> <div class="flex flex-col items-center gap-3 animate-in fade-in slide-in-from-bottom-4 duration-1000 delay-300 fill-mode-both">
<h2 class="text-base font-medium text-muted-foreground">{{ t('home.selectTown') }}</h2> <h2 class="text-base font-medium text-muted-foreground">{{ t('home.selectTown') }}</h2>
<Select :model-value="currentTown" @update:model-value="setCurrentTown"> <Select :model-value="currentTown" @update:model-value="setCurrentTown">
<SelectTrigger class="w-[200px]"> <SelectTrigger class="w-[240px] h-11">
<SelectValue :placeholder="t('home.selectTownPlaceholder')" /> <SelectValue :placeholder="t('home.selectTownPlaceholder')" />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
@ -88,48 +91,45 @@ const towns = computed(() => [
</Select> </Select>
</div> </div>
<!-- Category Buttons - Adjust spacing --> <!-- Category Buttons -->
<div class="relative -mx-4 sm:mx-0"> <div class="relative mx-auto max-w-2xl pt-4 animate-in fade-in slide-in-from-bottom-4 duration-1000 delay-500 fill-mode-both">
<!-- Gradient Fade Edges --> <!-- Gradient Fade Edges -->
<div class="absolute left-0 top-0 bottom-0 w-4 bg-gradient-to-r from-background to-transparent z-10"></div> <div class="absolute left-0 top-0 bottom-0 w-4 bg-gradient-to-r from-background to-transparent z-10 sm:hidden"></div>
<div class="absolute right-0 top-0 bottom-0 w-4 bg-gradient-to-l from-background to-transparent z-10"></div> <div class="absolute right-0 top-0 bottom-0 w-4 bg-gradient-to-l from-background to-transparent z-10 sm:hidden"></div>
<!-- Scrollable Container --> <!-- Scrollable Container -->
<div class="flex overflow-x-auto gap-1 px-4 pb-4 <div class="flex overflow-x-auto gap-2 px-4 pb-4
[&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]
sm:justify-center"> sm:flex-wrap sm:justify-center sm:gap-4 sm:px-0">
<router-link <router-link v-for="category in categories" :key="category"
v-for="category in categories"
:key="category"
:to="`/directory?category=${category}&town=${currentTown}`" :to="`/directory?category=${category}&town=${currentTown}`"
class="group flex-shrink-0 w-[100px] sm:w-[120px]" class="flex-shrink-0 w-[100px] sm:w-[110px]">
> <Button variant="ghost" size="default"
<Button class="w-full h-20 sm:h-24 flex flex-col items-center justify-center gap-1.5 sm:gap-2.5
variant="ghost" hover:bg-accent hover:scale-105 active:scale-100 transition-all duration-200 group">
size="default" <component :is="categoryIcons[category]"
class="w-full h-20 sm:h-24 flex flex-col items-center justify-center gap-1 sm:gap-2 group-hover:bg-accent transition-colors" class="h-6 w-6 sm:h-7 sm:w-7 transition-transform duration-200 group-hover:scale-110"
> :class="categoryColors[category]" />
<component <span class="text-xs sm:text-sm font-medium text-muted-foreground group-hover:text-foreground transition-colors">
:is="categoryIcons[category]" {{ t(`directory.categories.${category}`) }}
class="h-6 w-6 sm:h-7 sm:w-7" </span>
:class="categoryColors[category]"
/>
<span class="text-xs sm:text-sm">{{ t(`directory.categories.${category}`) }}</span>
</Button> </Button>
</router-link> </router-link>
</div> </div>
</div> </div>
<!-- Move action buttons to bottom --> <!-- Action Buttons -->
<div class="flex flex-col sm:flex-row gap-2 sm:gap-4 justify-center mt-4"> <div class="flex flex-col sm:flex-row gap-3 sm:gap-4 justify-center pt-4 animate-in fade-in slide-in-from-bottom-4 duration-1000 delay-700 fill-mode-both">
<router-link to="/directory" <router-link to="/directory" class="sm:w-[160px]">
class="inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90"> <Button variant="default" size="lg" class="w-full font-medium">
{{ t('home.browse') }} {{ t('home.browse') }}
</Button>
</router-link> </router-link>
<router-link to="/faq" <router-link to="/faq" class="sm:w-[160px]">
class="inline-flex items-center justify-center rounded-md border border-input bg-background px-6 py-3 text-sm font-medium hover:bg-accent hover:text-accent-foreground"> <Button variant="outline" size="lg" class="w-full font-medium">
{{ t('home.learnMore') }} {{ t('home.learnMore') }}
</Button>
</router-link> </router-link>
</div> </div>
</div> </div>