yaxa-svelte 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -8
- package/dist/components/elements/Badge.svelte +2 -1
- package/dist/components/elements/Badge.svelte.d.ts +2 -1
- package/dist/components/elements/Button.svelte +3 -2
- package/dist/components/elements/Button.svelte.d.ts +3 -2
- package/dist/components/elements/Icon.svelte +41 -7
- package/dist/components/elements/Icon.svelte.d.ts +11 -4
- package/dist/components/forms/Input.svelte +3 -2
- package/dist/components/forms/Input.svelte.d.ts +3 -2
- package/dist/components/forms/Select.svelte +3 -2
- package/dist/components/forms/Select.svelte.d.ts +3 -2
- package/dist/components/layout/Divider.svelte +9 -5
- package/dist/components/layout/Divider.svelte.d.ts +4 -3
- package/dist/components/layout/Footer.svelte +98 -5
- package/dist/components/legal/LegalDocument.svelte +341 -0
- package/dist/components/legal/LegalDocument.svelte.d.ts +21 -0
- package/dist/components/navigation/Breadcrumb.svelte +4 -2
- package/dist/components/navigation/Breadcrumb.svelte.d.ts +3 -2
- package/dist/components/navigation/CommandPalette.svelte +3 -1
- package/dist/components/navigation/CommandPalette.svelte.d.ts +2 -1
- package/dist/components/navigation/DropdownMenu.svelte +3 -1
- package/dist/components/navigation/DropdownMenu.svelte.d.ts +2 -1
- package/dist/components/navigation/Pagination.svelte +15 -7
- package/dist/components/navigation/Pagination.svelte.d.ts +5 -2
- package/dist/components/navigation/Tabs.svelte +3 -1
- package/dist/components/navigation/Tabs.svelte.d.ts +2 -1
- package/dist/components/overlays/Accordion.svelte +10 -8
- package/dist/components/overlays/Accordion.svelte.d.ts +5 -4
- package/dist/components/overlays/Alert.svelte +2 -1
- package/dist/components/overlays/Alert.svelte.d.ts +2 -1
- package/dist/components/overlays/ContextMenu.svelte +2 -2
- package/dist/components/overlays/ContextMenu.svelte.d.ts +2 -1
- package/dist/index.d.ts +18 -2
- package/dist/index.js +2 -1
- package/dist/site/config.d.ts +29 -0
- package/dist/site/config.js +35 -0
- package/dist/site/schema.d.ts +11 -0
- package/dist/site/schema.js +23 -0
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -35,14 +35,14 @@ _Nuxt UI v4 & Nuxt UI Pro Equivalent for SvelteKit 2.7+ & Svelte 5 with Built-in
|
|
|
35
35
|
|
|
36
36
|
### 1. Install Dependencies
|
|
37
37
|
|
|
38
|
-
Install `yaxa-svelte` along with Tailwind CSS v4 and
|
|
38
|
+
Install `yaxa-svelte` along with Tailwind CSS v4 and `@lucide/svelte`:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
# Core package
|
|
42
|
-
pnpm add yaxa-svelte
|
|
41
|
+
# Core package & icons
|
|
42
|
+
pnpm add yaxa-svelte @lucide/svelte
|
|
43
43
|
|
|
44
|
-
# Tailwind CSS v4
|
|
45
|
-
pnpm add -D tailwindcss @tailwindcss/vite @tailwindcss/typography
|
|
44
|
+
# Tailwind CSS v4 (Dev Dependencies)
|
|
45
|
+
pnpm add -D tailwindcss @tailwindcss/vite @tailwindcss/typography
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
_(Optional full-stack SaaS features: `pnpm add better-auth drizzle-orm @polar-sh/sdk resend`)_
|
|
@@ -51,17 +51,16 @@ _(Optional full-stack SaaS features: `pnpm add better-auth drizzle-orm @polar-sh
|
|
|
51
51
|
|
|
52
52
|
### 2. Configure `vite.config.ts`
|
|
53
53
|
|
|
54
|
-
Add Tailwind CSS
|
|
54
|
+
Add Tailwind CSS to your Vite plugins:
|
|
55
55
|
|
|
56
56
|
```ts
|
|
57
57
|
// vite.config.ts
|
|
58
58
|
import { sveltekit } from '@sveltejs/kit/vite';
|
|
59
59
|
import tailwindcss from '@tailwindcss/vite';
|
|
60
|
-
import Icons from 'unplugin-icons/vite';
|
|
61
60
|
import { defineConfig } from 'vite';
|
|
62
61
|
|
|
63
62
|
export default defineConfig({
|
|
64
|
-
plugins: [tailwindcss(),
|
|
63
|
+
plugins: [tailwindcss(), sveltekit()]
|
|
65
64
|
});
|
|
66
65
|
```
|
|
67
66
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { tv, type VariantProps } from '../../utils/cn';
|
|
3
3
|
import type { Snippet } from 'svelte';
|
|
4
|
+
import type { IconSource } from './Icon.svelte';
|
|
4
5
|
|
|
5
6
|
export const badgeVariants = tv({
|
|
6
7
|
base: 'inline-flex items-center font-medium select-none transition-colors duration-150',
|
|
@@ -150,7 +151,7 @@
|
|
|
150
151
|
|
|
151
152
|
export type BadgeProps = VariantProps<typeof badgeVariants> & {
|
|
152
153
|
dot?: boolean;
|
|
153
|
-
icon?:
|
|
154
|
+
icon?: IconSource;
|
|
154
155
|
class?: string;
|
|
155
156
|
children?: Snippet;
|
|
156
157
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type VariantProps } from '../../utils/cn';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { IconSource } from './Icon.svelte';
|
|
3
4
|
export declare const badgeVariants: import("tailwind-variants").TVReturnType<{
|
|
4
5
|
variant: {
|
|
5
6
|
solid: "text-white";
|
|
@@ -66,7 +67,7 @@ export declare const badgeVariants: import("tailwind-variants").TVReturnType<{
|
|
|
66
67
|
}, undefined>>;
|
|
67
68
|
export type BadgeProps = VariantProps<typeof badgeVariants> & {
|
|
68
69
|
dot?: boolean;
|
|
69
|
-
icon?:
|
|
70
|
+
icon?: IconSource;
|
|
70
71
|
class?: string;
|
|
71
72
|
children?: Snippet;
|
|
72
73
|
};
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { tv, type VariantProps } from '../../utils/cn';
|
|
3
3
|
import type { Snippet } from 'svelte';
|
|
4
4
|
import type { HTMLButtonAttributes, HTMLAnchorAttributes } from 'svelte/elements';
|
|
5
|
+
import type { IconSource } from './Icon.svelte';
|
|
5
6
|
|
|
6
7
|
export const buttonVariants = tv({
|
|
7
8
|
base: 'inline-flex items-center justify-center font-medium transition-all duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 select-none active:scale-[0.98]',
|
|
@@ -195,8 +196,8 @@
|
|
|
195
196
|
href?: string;
|
|
196
197
|
loading?: boolean;
|
|
197
198
|
disabled?: boolean;
|
|
198
|
-
icon?:
|
|
199
|
-
trailingIcon?:
|
|
199
|
+
icon?: IconSource;
|
|
200
|
+
trailingIcon?: IconSource;
|
|
200
201
|
type?: 'button' | 'submit' | 'reset';
|
|
201
202
|
class?: string;
|
|
202
203
|
leading?: Snippet;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type VariantProps } from '../../utils/cn';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { IconSource } from './Icon.svelte';
|
|
3
4
|
export declare const buttonVariants: import("tailwind-variants").TVReturnType<{
|
|
4
5
|
variant: {
|
|
5
6
|
solid: "shadow-xs text-white";
|
|
@@ -92,8 +93,8 @@ export type ButtonProps = VariantProps<typeof buttonVariants> & {
|
|
|
92
93
|
href?: string;
|
|
93
94
|
loading?: boolean;
|
|
94
95
|
disabled?: boolean;
|
|
95
|
-
icon?:
|
|
96
|
-
trailingIcon?:
|
|
96
|
+
icon?: IconSource;
|
|
97
|
+
trailingIcon?: IconSource;
|
|
97
98
|
type?: 'button' | 'submit' | 'reset';
|
|
98
99
|
class?: string;
|
|
99
100
|
leading?: Snippet;
|
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import type { Component, Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
export type IconSource =
|
|
5
|
+
string | Component<{ class?: string; size?: string | number; [key: string]: any }>;
|
|
3
6
|
|
|
4
|
-
interface
|
|
5
|
-
name?:
|
|
7
|
+
export interface IconProps {
|
|
8
|
+
name?: IconSource;
|
|
9
|
+
icon?: IconSource;
|
|
6
10
|
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number;
|
|
7
11
|
class?: string;
|
|
8
12
|
children?: Snippet;
|
|
13
|
+
[key: string]: unknown;
|
|
9
14
|
}
|
|
15
|
+
</script>
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
<script lang="ts">
|
|
18
|
+
let {
|
|
19
|
+
name,
|
|
20
|
+
icon,
|
|
21
|
+
size = 'md',
|
|
22
|
+
class: className = '',
|
|
23
|
+
children,
|
|
24
|
+
...restProps
|
|
25
|
+
}: IconProps = $props();
|
|
12
26
|
|
|
13
27
|
let sizeClass = $derived.by(() => {
|
|
14
28
|
if (typeof size === 'number') return `w-[${size}px] h-[${size}px]`;
|
|
@@ -27,6 +41,18 @@
|
|
|
27
41
|
}
|
|
28
42
|
});
|
|
29
43
|
|
|
44
|
+
let IconComponent = $derived.by(() => {
|
|
45
|
+
if (icon && typeof icon !== 'string') return icon;
|
|
46
|
+
if (name && typeof name !== 'string') return name;
|
|
47
|
+
return null;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
let stringIconName = $derived.by(() => {
|
|
51
|
+
if (typeof icon === 'string') return icon;
|
|
52
|
+
if (typeof name === 'string') return name;
|
|
53
|
+
return null;
|
|
54
|
+
});
|
|
55
|
+
|
|
30
56
|
// Common built-in SVGs for immediate zero-config use
|
|
31
57
|
const builtInIcons: Record<string, string> = {
|
|
32
58
|
check:
|
|
@@ -66,14 +92,21 @@
|
|
|
66
92
|
<span class="inline-flex shrink-0 items-center justify-center {sizeClass} {className}">
|
|
67
93
|
{@render children()}
|
|
68
94
|
</span>
|
|
69
|
-
{:else if
|
|
95
|
+
{:else if IconComponent}
|
|
96
|
+
{@const RenderIcon = IconComponent}
|
|
97
|
+
<RenderIcon
|
|
98
|
+
class="inline-flex shrink-0 items-center justify-center {sizeClass} {className}"
|
|
99
|
+
{...restProps}
|
|
100
|
+
/>
|
|
101
|
+
{:else if stringIconName && builtInIcons[stringIconName]}
|
|
70
102
|
<svg
|
|
71
103
|
class="inline-flex shrink-0 items-center justify-center {sizeClass} {className}"
|
|
72
104
|
viewBox="0 0 24 24"
|
|
73
105
|
fill="none"
|
|
74
106
|
aria-hidden="true"
|
|
107
|
+
{...restProps}
|
|
75
108
|
>
|
|
76
|
-
{@html builtInIcons[
|
|
109
|
+
{@html builtInIcons[stringIconName]}
|
|
77
110
|
</svg>
|
|
78
111
|
{:else}
|
|
79
112
|
<svg
|
|
@@ -81,6 +114,7 @@
|
|
|
81
114
|
viewBox="0 0 24 24"
|
|
82
115
|
fill="none"
|
|
83
116
|
aria-hidden="true"
|
|
117
|
+
{...restProps}
|
|
84
118
|
>
|
|
85
119
|
<circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2" stroke-dasharray="4 4" />
|
|
86
120
|
</svg>
|
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { Component, Snippet } from 'svelte';
|
|
2
|
+
export type IconSource = string | Component<{
|
|
3
|
+
class?: string;
|
|
4
|
+
size?: string | number;
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
}>;
|
|
7
|
+
export interface IconProps {
|
|
8
|
+
name?: IconSource;
|
|
9
|
+
icon?: IconSource;
|
|
4
10
|
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number;
|
|
5
11
|
class?: string;
|
|
6
12
|
children?: Snippet;
|
|
13
|
+
[key: string]: unknown;
|
|
7
14
|
}
|
|
8
|
-
declare const Icon:
|
|
15
|
+
declare const Icon: Component<IconProps, {}, "">;
|
|
9
16
|
type Icon = ReturnType<typeof Icon>;
|
|
10
17
|
export default Icon;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { tv, type VariantProps } from '../../utils/cn';
|
|
3
3
|
import type { Snippet } from 'svelte';
|
|
4
4
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
5
|
+
import type { IconSource } from '../elements/Icon.svelte';
|
|
5
6
|
|
|
6
7
|
export const inputVariants = tv({
|
|
7
8
|
base: 'w-full rounded-lg border bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-100 placeholder:text-neutral-400 dark:placeholder:text-neutral-500 focus:outline-none focus:ring-2 transition-all duration-150 disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-neutral-50 dark:disabled:bg-neutral-950',
|
|
@@ -30,8 +31,8 @@
|
|
|
30
31
|
export type InputProps = Omit<HTMLInputAttributes, 'size'> &
|
|
31
32
|
VariantProps<typeof inputVariants> & {
|
|
32
33
|
value?: string | number;
|
|
33
|
-
icon?:
|
|
34
|
-
trailingIcon?:
|
|
34
|
+
icon?: IconSource;
|
|
35
|
+
trailingIcon?: IconSource;
|
|
35
36
|
loading?: boolean;
|
|
36
37
|
clearable?: boolean;
|
|
37
38
|
prefix?: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type VariantProps } from '../../utils/cn';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
4
|
+
import type { IconSource } from '../elements/Icon.svelte';
|
|
4
5
|
export declare const inputVariants: import("tailwind-variants").TVReturnType<{
|
|
5
6
|
size: {
|
|
6
7
|
xs: "text-xs py-1 px-2";
|
|
@@ -43,8 +44,8 @@ export declare const inputVariants: import("tailwind-variants").TVReturnType<{
|
|
|
43
44
|
}, undefined>>;
|
|
44
45
|
export type InputProps = Omit<HTMLInputAttributes, 'size'> & VariantProps<typeof inputVariants> & {
|
|
45
46
|
value?: string | number;
|
|
46
|
-
icon?:
|
|
47
|
-
trailingIcon?:
|
|
47
|
+
icon?: IconSource;
|
|
48
|
+
trailingIcon?: IconSource;
|
|
48
49
|
loading?: boolean;
|
|
49
50
|
clearable?: boolean;
|
|
50
51
|
prefix?: string;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { tv, type VariantProps } from '../../utils/cn';
|
|
3
|
+
import type { IconSource } from '../elements/Icon.svelte';
|
|
3
4
|
|
|
4
5
|
export interface SelectOption {
|
|
5
6
|
value: string;
|
|
6
7
|
label: string;
|
|
7
|
-
icon?:
|
|
8
|
+
icon?: IconSource;
|
|
8
9
|
disabled?: boolean;
|
|
9
10
|
}
|
|
10
11
|
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
value?: string;
|
|
34
35
|
options?: SelectOption[];
|
|
35
36
|
placeholder?: string;
|
|
36
|
-
icon?:
|
|
37
|
+
icon?: IconSource;
|
|
37
38
|
disabled?: boolean;
|
|
38
39
|
name?: string;
|
|
39
40
|
class?: string;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type VariantProps } from '../../utils/cn';
|
|
2
|
+
import type { IconSource } from '../elements/Icon.svelte';
|
|
2
3
|
export interface SelectOption {
|
|
3
4
|
value: string;
|
|
4
5
|
label: string;
|
|
5
|
-
icon?:
|
|
6
|
+
icon?: IconSource;
|
|
6
7
|
disabled?: boolean;
|
|
7
8
|
}
|
|
8
9
|
export declare const selectVariants: import("tailwind-variants").TVReturnType<{
|
|
@@ -40,7 +41,7 @@ export type SelectProps = VariantProps<typeof selectVariants> & {
|
|
|
40
41
|
value?: string;
|
|
41
42
|
options?: SelectOption[];
|
|
42
43
|
placeholder?: string;
|
|
43
|
-
icon?:
|
|
44
|
+
icon?: IconSource;
|
|
44
45
|
disabled?: boolean;
|
|
45
46
|
name?: string;
|
|
46
47
|
class?: string;
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
<script lang="ts">
|
|
1
|
+
<script module lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
import
|
|
3
|
+
import type { IconSource } from '../elements/Icon.svelte';
|
|
4
4
|
|
|
5
|
-
interface
|
|
5
|
+
export interface DividerProps {
|
|
6
6
|
label?: string;
|
|
7
|
-
icon?:
|
|
7
|
+
icon?: IconSource;
|
|
8
8
|
orientation?: 'horizontal' | 'vertical';
|
|
9
9
|
class?: string;
|
|
10
10
|
children?: Snippet;
|
|
11
11
|
}
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<script lang="ts">
|
|
15
|
+
import Icon from '../elements/Icon.svelte';
|
|
12
16
|
|
|
13
17
|
let {
|
|
14
18
|
label,
|
|
@@ -16,7 +20,7 @@
|
|
|
16
20
|
orientation = 'horizontal',
|
|
17
21
|
class: className = '',
|
|
18
22
|
children
|
|
19
|
-
}:
|
|
23
|
+
}: DividerProps = $props();
|
|
20
24
|
</script>
|
|
21
25
|
|
|
22
26
|
{#if orientation === 'vertical'}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
|
|
2
|
+
import type { IconSource } from '../elements/Icon.svelte';
|
|
3
|
+
export interface DividerProps {
|
|
3
4
|
label?: string;
|
|
4
|
-
icon?:
|
|
5
|
+
icon?: IconSource;
|
|
5
6
|
orientation?: 'horizontal' | 'vertical';
|
|
6
7
|
class?: string;
|
|
7
8
|
children?: Snippet;
|
|
8
9
|
}
|
|
9
|
-
declare const Divider: import("svelte").Component<
|
|
10
|
+
declare const Divider: import("svelte").Component<DividerProps, {}, "">;
|
|
10
11
|
type Divider = ReturnType<typeof Divider>;
|
|
11
12
|
export default Divider;
|
|
@@ -16,21 +16,37 @@
|
|
|
16
16
|
|
|
17
17
|
let currentConfig = $derived(config || getSiteConfig());
|
|
18
18
|
let currentYear = new Date().getFullYear();
|
|
19
|
+
|
|
20
|
+
let company = $derived(currentConfig.company);
|
|
21
|
+
let legal = $derived(currentConfig.legal);
|
|
22
|
+
let legalLinks = $derived(legal?.links);
|
|
23
|
+
let entityName = $derived(company?.legalName || currentConfig.name);
|
|
24
|
+
|
|
25
|
+
let hasLegalLinks = $derived(
|
|
26
|
+
Boolean(
|
|
27
|
+
legalLinks?.privacy || legalLinks?.terms || legalLinks?.refunds || legalLinks?.impressum
|
|
28
|
+
)
|
|
29
|
+
);
|
|
19
30
|
</script>
|
|
20
31
|
|
|
21
32
|
<footer
|
|
22
33
|
class="border-t border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-950 {className}"
|
|
23
34
|
>
|
|
24
35
|
<Container size="lg" class="py-12 md:py-16">
|
|
25
|
-
<div class="grid grid-cols-1 gap-8 md:grid-cols-4">
|
|
36
|
+
<div class="grid grid-cols-1 gap-8 md:grid-cols-4 lg:grid-cols-5">
|
|
26
37
|
<!-- Brand Info -->
|
|
27
|
-
<div class="space-y-4 md:col-span-2">
|
|
38
|
+
<div class="space-y-4 md:col-span-2 lg:col-span-2">
|
|
28
39
|
<a href="/" class="inline-flex items-center gap-2.5 font-bold tracking-tight">
|
|
29
40
|
<Logo size="sm" showText text={currentConfig.name} />
|
|
30
41
|
</a>
|
|
31
42
|
<p class="max-w-sm text-base text-neutral-600 dark:text-neutral-400">
|
|
32
43
|
{currentConfig.description}
|
|
33
44
|
</p>
|
|
45
|
+
{#if legal?.morNotice}
|
|
46
|
+
<p class="text-xs text-neutral-500 dark:text-neutral-500">
|
|
47
|
+
{legal.morNotice}
|
|
48
|
+
</p>
|
|
49
|
+
{/if}
|
|
34
50
|
</div>
|
|
35
51
|
|
|
36
52
|
<!-- Quick Links -->
|
|
@@ -50,6 +66,57 @@
|
|
|
50
66
|
</ul>
|
|
51
67
|
</div>
|
|
52
68
|
|
|
69
|
+
<!-- Legal Links -->
|
|
70
|
+
{#if hasLegalLinks}
|
|
71
|
+
<div>
|
|
72
|
+
<h3 class="text-base font-semibold text-neutral-900 dark:text-white">
|
|
73
|
+
Legal & Compliance
|
|
74
|
+
</h3>
|
|
75
|
+
<ul class="mt-4 space-y-2.5 text-sm text-neutral-600 dark:text-neutral-400">
|
|
76
|
+
{#if legalLinks?.privacy}
|
|
77
|
+
<li>
|
|
78
|
+
<a
|
|
79
|
+
href={legalLinks.privacy}
|
|
80
|
+
class="transition-colors hover:text-primary-600 dark:hover:text-primary-400"
|
|
81
|
+
>
|
|
82
|
+
Privacy Policy
|
|
83
|
+
</a>
|
|
84
|
+
</li>
|
|
85
|
+
{/if}
|
|
86
|
+
{#if legalLinks?.terms}
|
|
87
|
+
<li>
|
|
88
|
+
<a
|
|
89
|
+
href={legalLinks.terms}
|
|
90
|
+
class="transition-colors hover:text-primary-600 dark:hover:text-primary-400"
|
|
91
|
+
>
|
|
92
|
+
Terms of Service
|
|
93
|
+
</a>
|
|
94
|
+
</li>
|
|
95
|
+
{/if}
|
|
96
|
+
{#if legalLinks?.refunds}
|
|
97
|
+
<li>
|
|
98
|
+
<a
|
|
99
|
+
href={legalLinks.refunds}
|
|
100
|
+
class="transition-colors hover:text-primary-600 dark:hover:text-primary-400"
|
|
101
|
+
>
|
|
102
|
+
Cancellation & Refunds
|
|
103
|
+
</a>
|
|
104
|
+
</li>
|
|
105
|
+
{/if}
|
|
106
|
+
{#if legalLinks?.impressum}
|
|
107
|
+
<li>
|
|
108
|
+
<a
|
|
109
|
+
href={legalLinks.impressum}
|
|
110
|
+
class="transition-colors hover:text-primary-600 dark:hover:text-primary-400"
|
|
111
|
+
>
|
|
112
|
+
Impressum
|
|
113
|
+
</a>
|
|
114
|
+
</li>
|
|
115
|
+
{/if}
|
|
116
|
+
</ul>
|
|
117
|
+
</div>
|
|
118
|
+
{/if}
|
|
119
|
+
|
|
53
120
|
<!-- Socials & Newsletter -->
|
|
54
121
|
<div>
|
|
55
122
|
<h3 class="text-base font-semibold text-neutral-900 dark:text-white">Community</h3>
|
|
@@ -86,11 +153,37 @@
|
|
|
86
153
|
</div>
|
|
87
154
|
</div>
|
|
88
155
|
|
|
156
|
+
<!-- Footer Bottom Identification Bar -->
|
|
89
157
|
<div
|
|
90
|
-
class="mt-12 flex flex-col items-center justify-between border-t border-neutral-200 pt-8 text-
|
|
158
|
+
class="mt-12 flex flex-col items-center justify-between gap-4 border-t border-neutral-200 pt-8 text-xs text-neutral-500 sm:flex-row dark:border-neutral-800 dark:text-neutral-400"
|
|
91
159
|
>
|
|
92
|
-
<
|
|
93
|
-
|
|
160
|
+
<div class="flex flex-wrap items-center justify-center gap-x-3 gap-y-1 sm:justify-start">
|
|
161
|
+
<span>© {currentYear} {entityName}.</span>
|
|
162
|
+
{#if company?.address}
|
|
163
|
+
<span>· {company.address}</span>
|
|
164
|
+
{/if}
|
|
165
|
+
{#if company?.vatNumber}
|
|
166
|
+
<span>· VAT: {company.vatNumber}</span>
|
|
167
|
+
{/if}
|
|
168
|
+
{#if company?.registrationCourt}
|
|
169
|
+
<span>· {company.registrationCourt}</span>
|
|
170
|
+
{/if}
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<div class="flex flex-wrap items-center justify-center gap-4">
|
|
174
|
+
{#if legalLinks?.privacy}
|
|
175
|
+
<a href={legalLinks.privacy} class="hover:underline">Privacy</a>
|
|
176
|
+
{/if}
|
|
177
|
+
{#if legalLinks?.terms}
|
|
178
|
+
<a href={legalLinks.terms} class="hover:underline">Terms</a>
|
|
179
|
+
{/if}
|
|
180
|
+
{#if legalLinks?.refunds}
|
|
181
|
+
<a href={legalLinks.refunds} class="hover:underline">Refunds</a>
|
|
182
|
+
{/if}
|
|
183
|
+
{#if legalLinks?.impressum}
|
|
184
|
+
<a href={legalLinks.impressum} class="hover:underline">Impressum</a>
|
|
185
|
+
{/if}
|
|
186
|
+
</div>
|
|
94
187
|
</div>
|
|
95
188
|
</Container>
|
|
96
189
|
</footer>
|