@jeetkhinde/stardawn-ui 1.0.5
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/cli/index.js +142 -0
- package/components/BackgroundGlow.astro +54 -0
- package/components/BentoCard.astro +36 -0
- package/components/Button.astro +20 -0
- package/components/FeatureListItem.astro +56 -0
- package/components/Footer.astro +58 -0
- package/components/FooterLink.astro +14 -0
- package/components/Navbar.astro +223 -0
- package/components/OffsetCard.astro +27 -0
- package/components/PillTag.astro +16 -0
- package/components/SectionHeader.astro +45 -0
- package/components/ServiceHero.astro +41 -0
- package/components/SideNav.astro +50 -0
- package/components/StatusBadge.astro +14 -0
- package/package.json +29 -0
- package/registry.json +110 -0
package/cli/index.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {Command} from 'commander';
|
|
4
|
+
import {readFileSync, writeFileSync, mkdirSync, existsSync} from 'fs';
|
|
5
|
+
import {join, resolve, dirname} from 'path';
|
|
6
|
+
import {fileURLToPath} from 'url';
|
|
7
|
+
|
|
8
|
+
const program = new Command();
|
|
9
|
+
|
|
10
|
+
// When installed via npm/npx, components are bundled next to this file.
|
|
11
|
+
// cli/index.js → root is one level up → root/components/ and root/registry.json
|
|
12
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const BUNDLED_ROOT = resolve(__dirname, '..');
|
|
14
|
+
|
|
15
|
+
// ─── ANSI colors (no external deps) ─────────────────────────────────────────
|
|
16
|
+
const g = (s) => `\x1b[32m${s}\x1b[0m`; // green
|
|
17
|
+
const y = (s) => `\x1b[33m${s}\x1b[0m`; // yellow
|
|
18
|
+
const c = (s) => `\x1b[36m${s}\x1b[0m`; // cyan
|
|
19
|
+
const b = (s) => `\x1b[1m${s}\x1b[0m`; // bold
|
|
20
|
+
const d = (s) => `\x1b[2m${s}\x1b[0m`; // dim
|
|
21
|
+
const r = (s) => `\x1b[31m${s}\x1b[0m`; // red
|
|
22
|
+
|
|
23
|
+
// ─── Registry helpers ────────────────────────────────────────────────────────
|
|
24
|
+
function getRegistry(localPath) {
|
|
25
|
+
const root = localPath ? resolve(localPath) : BUNDLED_ROOT;
|
|
26
|
+
const file = join(root, 'registry.json');
|
|
27
|
+
if (!existsSync(file)) {
|
|
28
|
+
console.error(r(`✗ registry.json not found at: ${file}`));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
return JSON.parse(readFileSync(file, 'utf-8'));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getComponentSource(filename, localPath) {
|
|
35
|
+
const root = localPath ? resolve(localPath) : BUNDLED_ROOT;
|
|
36
|
+
return readFileSync(join(root, 'components', filename), 'utf-8');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ─── Core install logic ───────────────────────────────────────────────────────
|
|
40
|
+
function installComponent(name, registry, outputDir, localPath, installed) {
|
|
41
|
+
if (installed.has(name)) return;
|
|
42
|
+
|
|
43
|
+
const component = registry.components.find((c) => c.name === name);
|
|
44
|
+
if (!component) {
|
|
45
|
+
console.error(r(`✗ Unknown component: "${name}"`));
|
|
46
|
+
console.log(d(` Run ${c('stardawn-ui list')} to see available components.`));
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Install component dependencies first (recursive)
|
|
51
|
+
for (const dep of component.componentDeps) {
|
|
52
|
+
installComponent(dep, registry, outputDir, localPath, installed);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const source = getComponentSource(component.file, localPath);
|
|
56
|
+
|
|
57
|
+
if (!existsSync(outputDir)) {
|
|
58
|
+
mkdirSync(outputDir, {recursive: true});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const outPath = join(outputDir, component.file);
|
|
62
|
+
const isUpdate = existsSync(outPath);
|
|
63
|
+
|
|
64
|
+
writeFileSync(outPath, source, 'utf-8');
|
|
65
|
+
installed.add(name);
|
|
66
|
+
|
|
67
|
+
const status = isUpdate ? y('↻ updated') : g('✓ added');
|
|
68
|
+
const npmNote = component.npmDeps.length
|
|
69
|
+
? d(` [needs: ${component.npmDeps.join(', ')}]`)
|
|
70
|
+
: '';
|
|
71
|
+
console.log(` ${status} ${b(component.file)}${npmNote}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ─── Commands ─────────────────────────────────────────────────────────────────
|
|
75
|
+
program
|
|
76
|
+
.name('stardawn-ui')
|
|
77
|
+
.description('StarDawn UI — component installer for Astro + Tailwind projects')
|
|
78
|
+
.version('1.0.0');
|
|
79
|
+
|
|
80
|
+
// LIST -------------------------------------------------------------------------
|
|
81
|
+
program
|
|
82
|
+
.command('list')
|
|
83
|
+
.description('Show all available components')
|
|
84
|
+
.option('--local <path>', 'Use a local registry path instead of GitHub')
|
|
85
|
+
.action((opts) => {
|
|
86
|
+
const registry = getRegistry(opts.local);
|
|
87
|
+
|
|
88
|
+
// Group by category
|
|
89
|
+
const grouped = {};
|
|
90
|
+
for (const comp of registry.components) {
|
|
91
|
+
if (!grouped[comp.category]) grouped[comp.category] = [];
|
|
92
|
+
grouped[comp.category].push(comp);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
console.log(b('\nStarDawn UI — available components\n'));
|
|
96
|
+
for (const [cat, comps] of Object.entries(grouped)) {
|
|
97
|
+
console.log(c(` ${cat.toUpperCase()}`));
|
|
98
|
+
for (const comp of comps) {
|
|
99
|
+
const deps = comp.componentDeps.length
|
|
100
|
+
? d(` (needs: ${comp.componentDeps.join(', ')})`)
|
|
101
|
+
: '';
|
|
102
|
+
console.log(` ${b(comp.name.padEnd(22))}${d(comp.description)}${deps}`);
|
|
103
|
+
}
|
|
104
|
+
console.log();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// ADD --------------------------------------------------------------------------
|
|
109
|
+
program
|
|
110
|
+
.command('add <components...>')
|
|
111
|
+
.description('Add one or more components to your project')
|
|
112
|
+
.option('--local <path>', 'Use a local registry path instead of GitHub')
|
|
113
|
+
.option('--output <dir>', 'Output directory', 'src/components')
|
|
114
|
+
.action((components, opts) => {
|
|
115
|
+
const outputDir = resolve(process.cwd(), opts.output);
|
|
116
|
+
const registry = getRegistry(opts.local);
|
|
117
|
+
const installed = new Set();
|
|
118
|
+
|
|
119
|
+
console.log(b(`\nInstalling to ${d(outputDir)}\n`));
|
|
120
|
+
|
|
121
|
+
for (const name of components) {
|
|
122
|
+
installComponent(name, registry, outputDir, opts.local, installed);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Collect all npm deps across everything installed
|
|
126
|
+
const allNpmDeps = new Set();
|
|
127
|
+
for (const name of installed) {
|
|
128
|
+
const comp = registry.components.find((c) => c.name === name);
|
|
129
|
+
comp?.npmDeps.forEach((dep) => allNpmDeps.add(dep));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (allNpmDeps.size > 0) {
|
|
133
|
+
console.log(`\n${y('⚠')} Install required npm packages:`);
|
|
134
|
+
console.log(` ${c(`npm install ${[...allNpmDeps].join(' ')}`)}\n`);
|
|
135
|
+
} else {
|
|
136
|
+
console.log();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
console.log(g('Done!'));
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
program.parse();
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
export interface Props {
|
|
3
|
+
color1?: string;
|
|
4
|
+
color2?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
color1 = 'rgba(255,231,146,0.05)',
|
|
9
|
+
color2 = 'rgba(129,151,255,0.05)'
|
|
10
|
+
} = Astro.props;
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<!-- Background Accent Glows -->
|
|
14
|
+
<div class="glow-orb-1 fixed top-[-10%] right-[-10%] w-[50vw] h-[50vw] pointer-events-none z-0" style={`background: radial-gradient(circle at center, ${color1} 0%, rgba(14,14,14,0) 70%)`}></div>
|
|
15
|
+
<div class="glow-orb-2 fixed bottom-[-10%] left-[-10%] w-[40vw] h-[40vw] pointer-events-none z-0" style={`background: radial-gradient(circle at center, ${color2} 0%, rgba(14,14,14,0) 70%)`}></div>
|
|
16
|
+
|
|
17
|
+
<script>
|
|
18
|
+
// @ts-nocheck
|
|
19
|
+
if (typeof window !== 'undefined' && window.gsap) {
|
|
20
|
+
const orbs1 = document.querySelectorAll('.glow-orb-1');
|
|
21
|
+
const orbs2 = document.querySelectorAll('.glow-orb-2');
|
|
22
|
+
|
|
23
|
+
// Create performant quickTo setters for physics rendering
|
|
24
|
+
const movers = [];
|
|
25
|
+
|
|
26
|
+
orbs1.forEach(orb => {
|
|
27
|
+
movers.push({
|
|
28
|
+
x: window.gsap.quickTo(orb, "x", {duration: 1.5, ease: "power3"}),
|
|
29
|
+
y: window.gsap.quickTo(orb, "y", {duration: 1.5, ease: "power3"}),
|
|
30
|
+
factor: -80
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
orbs2.forEach(orb => {
|
|
35
|
+
movers.push({
|
|
36
|
+
x: window.gsap.quickTo(orb, "x", {duration: 2.5, ease: "power3.out"}),
|
|
37
|
+
y: window.gsap.quickTo(orb, "y", {duration: 2.5, ease: "power3.out"}),
|
|
38
|
+
factor: -140
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
window.addEventListener("mousemove", (e) => {
|
|
43
|
+
// Normalize mouse coordinates from -0.5 to 0.5
|
|
44
|
+
const xOffset = (e.clientX / window.innerWidth) - 0.5;
|
|
45
|
+
const yOffset = (e.clientY / window.innerHeight) - 0.5;
|
|
46
|
+
|
|
47
|
+
// Perform parallax shift
|
|
48
|
+
movers.forEach(mover => {
|
|
49
|
+
mover.x(xOffset * mover.factor);
|
|
50
|
+
mover.y(yOffset * mover.factor);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
</script>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Icon } from 'astro-icon/components';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
title: string;
|
|
6
|
+
icon: string;
|
|
7
|
+
accentColor: 'yellow' | 'blue';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { title, icon, accentColor } = Astro.props;
|
|
11
|
+
|
|
12
|
+
const shadowClass = accentColor === 'yellow'
|
|
13
|
+
? 'hover:shadow-[8px_8px_0px_0px_rgba(255,231,146,0.2)]'
|
|
14
|
+
: 'hover:shadow-[8px_8px_0px_0px_rgba(129,151,255,0.2)]';
|
|
15
|
+
|
|
16
|
+
const textAccentClass = accentColor === 'yellow' ? 'text-[#ffe792]' : 'text-[#8197ff]';
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
<div class={`group relative bg-[#141414] rounded-[2.5rem] p-8 md:p-10 outline outline-1 outline-white/10 transition-all duration-300 ease-out hover:-translate-y-1 ${shadowClass} flex flex-col h-full overflow-hidden`}>
|
|
20
|
+
<!-- Subtle glass highlight -->
|
|
21
|
+
<div class="absolute inset-0 bg-gradient-to-br from-white/[0.03] to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
|
22
|
+
|
|
23
|
+
<div class="relative z-10 flex flex-col h-full">
|
|
24
|
+
<div class={`mb-6 inline-flex items-center justify-center w-14 h-14 rounded-2xl bg-[#0e0e0e] outline outline-1 outline-white/10 group-hover:scale-110 transition-transform duration-300 ${textAccentClass}`}>
|
|
25
|
+
<Icon name={icon} class="w-7 h-7" />
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<h3 class="font-display font-bold text-2xl uppercase tracking-tighter mb-4 text-white group-hover:text-white/90 transition-colors">
|
|
29
|
+
{title}
|
|
30
|
+
</h3>
|
|
31
|
+
|
|
32
|
+
<div class="font-sans text-white/70 leading-relaxed flex-grow">
|
|
33
|
+
<slot />
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
href?: string;
|
|
4
|
+
variant?: 'primary' | 'secondary';
|
|
5
|
+
class?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const { href, variant = 'primary', class: className = '' } = Astro.props;
|
|
9
|
+
|
|
10
|
+
const baseStyles = "gsap-magnetic inline-flex items-center justify-center px-6 py-3 font-display font-bold uppercase tracking-wider text-sm transition-colors duration-300 outline outline-1";
|
|
11
|
+
const primaryStyles = "bg-[#ffe792] text-[#0e0e0e] outline-[#ffe792] hover:shadow-[6px_6px_0px_0px_rgba(255,231,146,0.4)]";
|
|
12
|
+
const secondaryStyles = "bg-transparent text-white outline-white/20 hover:bg-white/5 hover:shadow-[6px_6px_0px_0px_rgba(255,255,255,0.1)]";
|
|
13
|
+
|
|
14
|
+
const appliedStyles = `${baseStyles} ${variant === 'primary' ? primaryStyles : secondaryStyles} ${className}`;
|
|
15
|
+
const Tag = href ? 'a' : 'button';
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
<Tag href={href} class={appliedStyles}>
|
|
19
|
+
<slot />
|
|
20
|
+
</Tag>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Icon } from 'astro-icon/components';
|
|
3
|
+
|
|
4
|
+
export interface Props {
|
|
5
|
+
variant?: 'list' | 'bento' | 'detail' | 'simple';
|
|
6
|
+
icon?: string;
|
|
7
|
+
title?: string;
|
|
8
|
+
text?: string;
|
|
9
|
+
color?: string; // 'ffe792' or '8197ff'
|
|
10
|
+
class?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
variant = 'list',
|
|
15
|
+
icon = 'mdi:chevron-right',
|
|
16
|
+
title,
|
|
17
|
+
text,
|
|
18
|
+
color = 'ffe792',
|
|
19
|
+
class: className = ''
|
|
20
|
+
} = Astro.props;
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
{variant === 'bento' && (
|
|
24
|
+
<div class={`bg-white/5 p-4 rounded-2xl flex items-center gap-4 outline outline-1 outline-white/5 group-hover:bg-white/10 transition-colors ${className}`}>
|
|
25
|
+
{icon && <Icon name={icon} class={`text-[#${color}] w-5 h-5 shrink-0`} />}
|
|
26
|
+
<span class="font-display font-bold text-sm tracking-tight text-white">{title || text}</span>
|
|
27
|
+
</div>
|
|
28
|
+
)}
|
|
29
|
+
|
|
30
|
+
{variant === 'list' && (
|
|
31
|
+
<li class={`flex items-center gap-3 bg-white/5 p-4 rounded-2xl outline outline-1 outline-white/5 group-hover:bg-white/10 transition-colors ${className}`}>
|
|
32
|
+
{icon && <Icon name={icon} class={`text-[#${color}] w-5 h-5 shrink-0`} />}
|
|
33
|
+
<span class="font-display font-medium text-white/90">{text || title}</span>
|
|
34
|
+
</li>
|
|
35
|
+
)}
|
|
36
|
+
|
|
37
|
+
{variant === 'simple' && (
|
|
38
|
+
<li class={`flex items-start gap-4 text-white/70 ${className}`}>
|
|
39
|
+
{icon && <Icon name={icon} class={`text-[#${color}] mt-1 shrink-0 w-5 h-5`} />}
|
|
40
|
+
<span>{text || title}</span>
|
|
41
|
+
</li>
|
|
42
|
+
)}
|
|
43
|
+
|
|
44
|
+
{variant === 'detail' && (
|
|
45
|
+
<li class={`flex items-start gap-5 ${className}`}>
|
|
46
|
+
{icon && (
|
|
47
|
+
<div class={`bg-[#${color}]/10 p-3 rounded-2xl outline outline-1 outline-[#${color}]/20 shrink-0 group-hover:bg-[#${color}]/20 transition-colors`}>
|
|
48
|
+
<Icon name={icon} class={`w-7 h-7 text-[#${color}]`} />
|
|
49
|
+
</div>
|
|
50
|
+
)}
|
|
51
|
+
<div>
|
|
52
|
+
{title && <strong class="text-white block font-display text-lg uppercase tracking-tight mb-1">{title}</strong>}
|
|
53
|
+
<span class="text-white/60 text-sm leading-relaxed">{text}</span>
|
|
54
|
+
</div>
|
|
55
|
+
</li>
|
|
56
|
+
)}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Icon } from 'astro-icon/components';
|
|
3
|
+
import FooterLink from './FooterLink.astro';
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<footer class="w-full bg-[#0e0e0e] border-t border-white/10 relative z-10 mt-24 overflow-hidden">
|
|
7
|
+
<!-- Massive CTA Section -->
|
|
8
|
+
<a href="/#contact" class="group block w-full border-b border-white/10 relative overflow-hidden bg-[#0e0e0e] hover:bg-[#ffe792] transition-colors duration-700 ease-[cubic-bezier(0.76,0,0.24,1)]">
|
|
9
|
+
<div class="max-w-7xl mx-auto px-6 py-24 md:py-32 relative z-10 flex flex-col md:flex-row items-center justify-between gap-10">
|
|
10
|
+
<h2 class="text-5xl md:text-7xl lg:text-9xl font-display font-black tracking-tighter uppercase text-white group-hover:text-[#0e0e0e] transition-colors duration-700">
|
|
11
|
+
Schedule <br/> Free Call.
|
|
12
|
+
</h2>
|
|
13
|
+
<div class="w-24 h-24 md:w-32 md:h-32 rounded-full border-2 border-white/20 group-hover:border-[#0e0e0e]/20 flex items-center justify-center group-hover:scale-110 transition-all duration-700 group-hover:bg-[#0e0e0e]">
|
|
14
|
+
<Icon name="mdi:arrow-top-right" class="w-12 h-12 md:w-16 md:h-16 text-white group-hover:text-[#ffe792] transition-colors duration-700 group-hover:rotate-45" />
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</a>
|
|
18
|
+
|
|
19
|
+
<div class="max-w-7xl mx-auto px-6 py-24 flex flex-col md:flex-row justify-between items-start gap-16">
|
|
20
|
+
<div class="flex flex-col max-w-md">
|
|
21
|
+
<div class="text-5xl font-black mb-10 font-display tracking-tighter uppercase flex items-center gap-3 text-transparent bg-clip-text bg-gradient-to-r from-[#ffe792] to-[#8197ff]">
|
|
22
|
+
STARDAWN IT
|
|
23
|
+
</div>
|
|
24
|
+
<p class="text-white/60 font-sans text-xl leading-relaxed mb-10">
|
|
25
|
+
The leading edge of technical architecture and system engineering. We provide the kinetic foundation for the world's most innovative enterprises.
|
|
26
|
+
</p>
|
|
27
|
+
<p class="text-white/40 text-xs font-display uppercase tracking-widest">© {new Date().getFullYear()} STARDAWN IT. KINETIC ARCHITECTURE UI.</p>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="grid grid-cols-2 lg:grid-cols-3 gap-x-12 md:gap-x-24 gap-y-16">
|
|
30
|
+
<div class="flex flex-col gap-5">
|
|
31
|
+
<span class="font-display uppercase tracking-widest text-sm text-white font-bold mb-6">Company</span>
|
|
32
|
+
<FooterLink href="/">Home</FooterLink>
|
|
33
|
+
<FooterLink href="/about">About</FooterLink>
|
|
34
|
+
<FooterLink href="/blog">Blog</FooterLink>
|
|
35
|
+
<FooterLink href="/holiday">Holiday</FooterLink>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div class="flex flex-col gap-5">
|
|
39
|
+
<span class="font-display uppercase tracking-widest text-sm text-white font-bold mb-6">Services</span>
|
|
40
|
+
<FooterLink href="/services/connectwise-automate-consulting">ConnectWise Consult</FooterLink>
|
|
41
|
+
<FooterLink href="/services/rmm-admin">RMM Admin</FooterLink>
|
|
42
|
+
<FooterLink href="/services/noc-services">NOC Services</FooterLink>
|
|
43
|
+
<FooterLink href="/services/backup">Backup Management</FooterLink>
|
|
44
|
+
<a class="text-[#8197ff]/80 hover:text-[#8197ff] font-display uppercase tracking-widest text-sm hover:translate-x-2 transition-transform duration-200 flex items-center gap-2 group mt-2" href="/services">
|
|
45
|
+
View All Services <Icon name="mdi:arrow-right" class="w-4 h-4" />
|
|
46
|
+
</a>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div class="flex flex-col gap-5">
|
|
50
|
+
<span class="font-display uppercase tracking-widest text-sm text-white font-bold mb-6">Support & Legal</span>
|
|
51
|
+
<FooterLink href="/contact">Contact</FooterLink>
|
|
52
|
+
<FooterLink href="/faq">FAQ</FooterLink>
|
|
53
|
+
<FooterLink href="/privacy-policy">Privacy Policy</FooterLink>
|
|
54
|
+
<FooterLink href="/terms-of-service">Terms of Service</FooterLink>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</footer>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Icon } from 'astro-icon/components';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
href: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const { href } = Astro.props;
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<a class="text-white/60 hover:text-[#ffe792] font-display uppercase tracking-widest text-sm hover:translate-x-2 transition-transform duration-200 flex items-center gap-2 group" href={href}>
|
|
12
|
+
<Icon name="mdi:chevron-right" class="w-4 h-4 opacity-0 -ml-6 group-hover:opacity-100 group-hover:ml-0 transition-all duration-200" />
|
|
13
|
+
<slot />
|
|
14
|
+
</a>
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Button from './Button.astro';
|
|
3
|
+
import { Icon } from 'astro-icon/components';
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<nav class="sticky top-0 z-50 w-full bg-[#0e0e0e]/90 backdrop-blur-md border-b border-white/10">
|
|
7
|
+
<div class="max-w-7xl mx-auto px-6 h-20 flex items-center justify-between">
|
|
8
|
+
<a href="/" class="flex items-center gap-2 group">
|
|
9
|
+
<Icon name="mdi:star-four-points" class="w-6 h-6 text-[#ffe792] group-hover:rotate-90 transition-transform duration-500" />
|
|
10
|
+
<span class="font-display font-black text-xl tracking-tighter uppercase text-transparent bg-clip-text bg-gradient-to-r from-[#ffe792] to-[#8197ff]">StarDawn IT</span>
|
|
11
|
+
</a>
|
|
12
|
+
|
|
13
|
+
<div class="hidden lg:flex items-center gap-6 h-full">
|
|
14
|
+
<a href="/" class="font-sans text-sm font-medium text-white/70 hover:text-white transition-colors h-full flex items-center">Home</a>
|
|
15
|
+
<div class="services-nav-group relative h-full flex items-center">
|
|
16
|
+
<a href="/services" class="font-sans text-sm font-medium text-white/70 hover:text-white transition-colors flex items-center gap-1 py-8">
|
|
17
|
+
Services
|
|
18
|
+
<Icon name="mdi:chevron-down" class="service-chevron w-4 h-4 opacity-70 transition-transform duration-300" />
|
|
19
|
+
</a>
|
|
20
|
+
|
|
21
|
+
<!-- Dropdown Panel (Professional / Brutalist) -->
|
|
22
|
+
<div class="mega-menu-panel absolute top-[calc(100%-1rem)] md:left-0 lg:left-1/2 md:-translate-x-[20px] lg:-translate-x-1/2 w-[700px] lg:w-[1000px] bg-[#0e0e0e] border border-white/10 shadow-[8px_8px_0px_0px_rgba(255,231,146,0.1)] opacity-0 invisible translate-y-4 z-50">
|
|
23
|
+
<div class="grid grid-cols-4">
|
|
24
|
+
|
|
25
|
+
<!-- Left Info Pane -->
|
|
26
|
+
<div class="col-span-1 p-8 bg-[#141414] border-r border-white/10 flex flex-col justify-between">
|
|
27
|
+
<div>
|
|
28
|
+
<Icon name="mdi:star-four-points" class="w-8 h-8 text-[#ffe792] mb-6" />
|
|
29
|
+
<h3 class="font-display font-black text-2xl uppercase tracking-tighter text-white mb-4">Engineering<br/>Excellence</h3>
|
|
30
|
+
<p class="text-white/50 text-sm leading-relaxed font-light mb-8">
|
|
31
|
+
Comprehensive infrastructure management, automation, and growth solutions for elite MSPs.
|
|
32
|
+
</p>
|
|
33
|
+
</div>
|
|
34
|
+
<a href="/services" class="inline-flex items-center gap-2 text-xs font-display font-bold uppercase tracking-widest text-white hover:text-[#ffe792] transition-colors group/link w-max">
|
|
35
|
+
View All Services
|
|
36
|
+
<Icon name="mdi:arrow-right" class="w-4 h-4 group-hover/link:translate-x-1 transition-transform" />
|
|
37
|
+
</a>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<!-- Right Links Pane -->
|
|
41
|
+
<div class="col-span-3 p-8 grid grid-cols-3 gap-x-8">
|
|
42
|
+
|
|
43
|
+
<!-- Column 1 -->
|
|
44
|
+
<div class="flex flex-col gap-6">
|
|
45
|
+
<div>
|
|
46
|
+
<h4 class="text-[10px] font-display font-bold text-white/30 uppercase tracking-[0.2em] mb-4 border-b border-white/10 pb-2">RMM & MDM</h4>
|
|
47
|
+
<ul class="space-y-3">
|
|
48
|
+
<li>
|
|
49
|
+
<a href="/services/connectwise-automate-consulting" class="mega-menu-link group/navlink block w-max">
|
|
50
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#ffe792] transition-colors gap-2 flex items-center">
|
|
51
|
+
ConnectWise <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#ffe792]" />
|
|
52
|
+
</span>
|
|
53
|
+
</a>
|
|
54
|
+
</li>
|
|
55
|
+
<li>
|
|
56
|
+
<a href="/services/ninja-rmm-consulting" class="mega-menu-link group/navlink block w-max">
|
|
57
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#8197ff] transition-colors gap-2 flex items-center">
|
|
58
|
+
NinjaRMM <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#8197ff]" />
|
|
59
|
+
</span>
|
|
60
|
+
</a>
|
|
61
|
+
</li>
|
|
62
|
+
<li>
|
|
63
|
+
<a href="/services/datto-rmm-consulting" class="mega-menu-link group/navlink block w-max">
|
|
64
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#ffe792] transition-colors gap-2 flex items-center">
|
|
65
|
+
Datto RMM <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#ffe792]" />
|
|
66
|
+
</span>
|
|
67
|
+
</a>
|
|
68
|
+
</li>
|
|
69
|
+
<li>
|
|
70
|
+
<a href="/services/mac-mdm-consulting" class="mega-menu-link group/navlink block w-max">
|
|
71
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#ffe792] transition-colors gap-2 flex items-center">
|
|
72
|
+
Mac MDM <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#ffe792]" />
|
|
73
|
+
</span>
|
|
74
|
+
</a>
|
|
75
|
+
</li>
|
|
76
|
+
<li>
|
|
77
|
+
<a href="/services/other-rmm-consulting" class="mega-menu-link group/navlink block w-max">
|
|
78
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#8197ff] transition-colors gap-2 flex items-center">
|
|
79
|
+
Other RMM Tools <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#8197ff]" />
|
|
80
|
+
</span>
|
|
81
|
+
</a>
|
|
82
|
+
</li>
|
|
83
|
+
</ul>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<!-- Column 2 -->
|
|
88
|
+
<div class="flex flex-col gap-6">
|
|
89
|
+
<div>
|
|
90
|
+
<h4 class="text-[10px] font-display font-bold text-white/30 uppercase tracking-[0.2em] mb-4 border-b border-white/10 pb-2">Managed Operations</h4>
|
|
91
|
+
<ul class="space-y-3">
|
|
92
|
+
<li>
|
|
93
|
+
<a href="/services/rmm-admin" class="mega-menu-link group/navlink block w-max">
|
|
94
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#8197ff] transition-colors gap-2 flex items-center">
|
|
95
|
+
RMM Admin <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#8197ff]" />
|
|
96
|
+
</span>
|
|
97
|
+
</a>
|
|
98
|
+
</li>
|
|
99
|
+
<li>
|
|
100
|
+
<a href="/services/noc-services" class="mega-menu-link group/navlink block w-max">
|
|
101
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#ffe792] transition-colors gap-2 flex items-center">
|
|
102
|
+
NOC Services <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#ffe792]" />
|
|
103
|
+
</span>
|
|
104
|
+
</a>
|
|
105
|
+
</li>
|
|
106
|
+
<li>
|
|
107
|
+
<a href="/services/backup" class="mega-menu-link group/navlink block w-max">
|
|
108
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#8197ff] transition-colors gap-2 flex items-center">
|
|
109
|
+
Backup Management <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#8197ff]" />
|
|
110
|
+
</span>
|
|
111
|
+
</a>
|
|
112
|
+
</li>
|
|
113
|
+
</ul>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<!-- Column 3 -->
|
|
118
|
+
<div class="flex flex-col gap-6">
|
|
119
|
+
<div>
|
|
120
|
+
<h4 class="text-[10px] font-display font-bold text-white/30 uppercase tracking-[0.2em] mb-4 border-b border-white/10 pb-2">Growth & Talent</h4>
|
|
121
|
+
<ul class="space-y-3">
|
|
122
|
+
<li>
|
|
123
|
+
<a href="/services/msp-dedicated-technicians" class="mega-menu-link group/navlink block w-max">
|
|
124
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#ffe792] transition-colors gap-2 flex items-center">
|
|
125
|
+
Dedicated Techs <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#ffe792]" />
|
|
126
|
+
</span>
|
|
127
|
+
</a>
|
|
128
|
+
</li>
|
|
129
|
+
<li>
|
|
130
|
+
<a href="/services/msp-website-development" class="mega-menu-link group/navlink block w-max">
|
|
131
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#ffe792] transition-colors gap-2 flex items-center">
|
|
132
|
+
MSP Websites <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#ffe792]" />
|
|
133
|
+
</span>
|
|
134
|
+
</a>
|
|
135
|
+
</li>
|
|
136
|
+
<li>
|
|
137
|
+
<a href="/services/custom-it-tools" class="mega-menu-link group/navlink block w-max">
|
|
138
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#8197ff] transition-colors gap-2 flex items-center">
|
|
139
|
+
Custom IT Tools <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#8197ff]" />
|
|
140
|
+
</span>
|
|
141
|
+
</a>
|
|
142
|
+
</li>
|
|
143
|
+
<li>
|
|
144
|
+
<a href="/services/llm-training" class="mega-menu-link group/navlink block w-max">
|
|
145
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#8197ff] transition-colors gap-2 flex items-center">
|
|
146
|
+
LLM Training <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#8197ff]" />
|
|
147
|
+
</span>
|
|
148
|
+
</a>
|
|
149
|
+
</li>
|
|
150
|
+
<li>
|
|
151
|
+
<a href="/services/seo" class="mega-menu-link group/navlink block w-max">
|
|
152
|
+
<span class="font-display text-sm font-bold uppercase text-white group-hover/navlink:text-[#8197ff] transition-colors gap-2 flex items-center">
|
|
153
|
+
SEO Campaigns <Icon name="mdi:arrow-top-right" class="w-3 h-3 opacity-0 -translate-x-2 group-hover/navlink:opacity-100 group-hover/navlink:translate-x-0 transition-all text-[#8197ff]" />
|
|
154
|
+
</span>
|
|
155
|
+
</a>
|
|
156
|
+
</li>
|
|
157
|
+
</ul>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<a href="/#solutions" class="font-sans text-sm font-medium text-white/70 hover:text-white transition-colors h-full flex items-center">Solutions</a>
|
|
167
|
+
<a href="/about" class="font-sans text-sm font-medium text-white/70 hover:text-white transition-colors h-full flex items-center">About</a>
|
|
168
|
+
<a href="/blog" class="font-sans text-sm font-medium text-white/70 hover:text-white transition-colors h-full flex items-center">Blog</a>
|
|
169
|
+
<a href="/contact" class="font-sans text-sm font-medium text-white/70 hover:text-white transition-colors h-full flex items-center">Contact</a>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
<div class="flex items-center gap-4">
|
|
173
|
+
<Button href="/#contact" variant="primary" class="hidden lg:inline-flex">Client Portal</Button>
|
|
174
|
+
<button class="lg:hidden text-white/70 hover:text-white">
|
|
175
|
+
<Icon name="mdi:menu" class="w-6 h-6" />
|
|
176
|
+
</button>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
</nav>
|
|
180
|
+
|
|
181
|
+
<script>
|
|
182
|
+
// @ts-nocheck
|
|
183
|
+
if (typeof window !== 'undefined' && window.gsap) {
|
|
184
|
+
const servicesNav = document.querySelector('.services-nav-group');
|
|
185
|
+
const panel = document.querySelector('.mega-menu-panel');
|
|
186
|
+
const links = document.querySelectorAll('.mega-menu-link');
|
|
187
|
+
const chevron = document.querySelector('.service-chevron');
|
|
188
|
+
|
|
189
|
+
if (servicesNav && panel) {
|
|
190
|
+
// Setup GSAP Menu Timeline
|
|
191
|
+
const menuTl = window.gsap.timeline({ paused: true, defaults: { ease: "power3.out" } });
|
|
192
|
+
|
|
193
|
+
menuTl.to(panel, { autoAlpha: 1, y: 0, duration: 0.3 })
|
|
194
|
+
.to(chevron, { rotation: 180, duration: 0.3 }, "<")
|
|
195
|
+
.fromTo(links,
|
|
196
|
+
{ y: 15, opacity: 0 },
|
|
197
|
+
{ y: 0, opacity: 1, duration: 0.4, stagger: 0.04 },
|
|
198
|
+
"-=0.15"
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
let timeoutId;
|
|
202
|
+
servicesNav.addEventListener('mouseenter', () => {
|
|
203
|
+
clearTimeout(timeoutId);
|
|
204
|
+
menuTl.play();
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
servicesNav.addEventListener('mouseleave', () => {
|
|
208
|
+
// Add a tiny delay before closing to make it feel less jerky
|
|
209
|
+
timeoutId = setTimeout(() => menuTl.reverse(), 100);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// Accessibility: Also open on focus
|
|
213
|
+
servicesNav.addEventListener('focusin', () => menuTl.play());
|
|
214
|
+
servicesNav.addEventListener('focusout', () => {
|
|
215
|
+
setTimeout(() => {
|
|
216
|
+
if (!servicesNav.contains(document.activeElement)) {
|
|
217
|
+
menuTl.reverse();
|
|
218
|
+
}
|
|
219
|
+
}, 10);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
</script>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props {
|
|
3
|
+
color?: 'yellow' | 'blue';
|
|
4
|
+
class?: string;
|
|
5
|
+
as?: any;
|
|
6
|
+
noTranslate?: boolean;
|
|
7
|
+
rounded?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const {
|
|
11
|
+
color = 'yellow',
|
|
12
|
+
class: className = '',
|
|
13
|
+
as: Component = 'div',
|
|
14
|
+
noTranslate = false,
|
|
15
|
+
rounded = 'rounded-[2.5rem]'
|
|
16
|
+
} = Astro.props;
|
|
17
|
+
|
|
18
|
+
const shadowClass = color === 'yellow'
|
|
19
|
+
? 'hover:shadow-[8px_8px_0px_0px_rgba(255,231,146,0.2)]'
|
|
20
|
+
: 'hover:shadow-[8px_8px_0px_0px_rgba(129,151,255,0.2)]';
|
|
21
|
+
|
|
22
|
+
const translateClass = noTranslate ? '' : 'hover:-translate-y-1';
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
<Component class={`group bg-[#141414] ${rounded} overflow-hidden outline outline-1 outline-white/10 hover:bg-[#1a1a1a] transition-all duration-500 ${shadowClass} ${translateClass} ${className}`}>
|
|
26
|
+
<slot />
|
|
27
|
+
</Component>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
export interface Props {
|
|
3
|
+
text: string;
|
|
4
|
+
href?: string;
|
|
5
|
+
class?: string;
|
|
6
|
+
hoverColor?: string; // 'ffe792' or '8197ff'
|
|
7
|
+
}
|
|
8
|
+
const { text, href, class: className = '', hoverColor } = Astro.props;
|
|
9
|
+
const Element = href ? 'a' : 'span';
|
|
10
|
+
|
|
11
|
+
const defaultHover = href ? 'hover:bg-white/10 hover:outline-white/20 hover:scale-[1.05] transition-all duration-300 cursor-pointer'
|
|
12
|
+
: hoverColor ? `group-hover:outline-[#${hoverColor}]/40 transition-all` : 'transition-all group-hover:outline-white/40';
|
|
13
|
+
---
|
|
14
|
+
<Element href={href} class={`inline-flex items-center gap-2 bg-white/5 px-6 py-3 rounded-full text-xs font-display font-bold uppercase tracking-widest outline outline-1 outline-white/10 text-white ${defaultHover} ${className}`}>
|
|
15
|
+
{text}
|
|
16
|
+
</Element>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
export interface Props {
|
|
3
|
+
eyebrow: string;
|
|
4
|
+
eyebrowColor?: string; // 'ffe792' or '8197ff' or gradient 'from-[#ffe792] to-[#8197ff]'
|
|
5
|
+
titlePlain: string;
|
|
6
|
+
titleGradient?: string;
|
|
7
|
+
gradientColors?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
reveal?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
eyebrow,
|
|
15
|
+
eyebrowColor = 'from-[#ffe792] to-[#8197ff]',
|
|
16
|
+
titlePlain,
|
|
17
|
+
titleGradient,
|
|
18
|
+
gradientColors = 'from-[#ffe792] to-[#8197ff]',
|
|
19
|
+
description,
|
|
20
|
+
class: className = 'mb-24',
|
|
21
|
+
reveal = true
|
|
22
|
+
} = Astro.props;
|
|
23
|
+
|
|
24
|
+
// If eyebrowColor doesn't contain 'from-', assume it's a solid hex
|
|
25
|
+
const eyebrowClass = eyebrowColor.includes('from-')
|
|
26
|
+
? `text-transparent bg-clip-text bg-gradient-to-r ${eyebrowColor}`
|
|
27
|
+
: `text-[#${eyebrowColor}]`;
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
<div class={`${reveal ? 'gsap-reveal ' : ''}flex flex-col items-start gap-6 ${className}`}>
|
|
31
|
+
<span class={`font-display tracking-[0.2em] uppercase text-sm font-bold block ${eyebrowClass}`}>
|
|
32
|
+
{eyebrow}
|
|
33
|
+
</span>
|
|
34
|
+
<h2 class="text-white font-display text-5xl md:text-7xl lg:text-8xl font-black tracking-tighter leading-[0.9] uppercase">
|
|
35
|
+
{titlePlain}{titleGradient && (
|
|
36
|
+
<span> <span class={`text-transparent bg-clip-text bg-gradient-to-r ${gradientColors}`}>{titleGradient}</span>.</span>
|
|
37
|
+
)}
|
|
38
|
+
{!titleGradient && '.'}
|
|
39
|
+
</h2>
|
|
40
|
+
{description && (
|
|
41
|
+
<p class="text-white/70 text-xl md:text-2xl max-w-3xl mt-10 font-light leading-relaxed">
|
|
42
|
+
{description}
|
|
43
|
+
</p>
|
|
44
|
+
)}
|
|
45
|
+
</div>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Button from './Button.astro';
|
|
3
|
+
|
|
4
|
+
export interface Props {
|
|
5
|
+
badgeText: string;
|
|
6
|
+
badgeColor?: string; // e.g., 'ffe792' or '8197ff'
|
|
7
|
+
titlePlain: string;
|
|
8
|
+
titleGradient: string;
|
|
9
|
+
gradientColors?: string; // e.g., 'from-[#ffe792] to-[#8197ff]'
|
|
10
|
+
description: string;
|
|
11
|
+
buttonText?: string;
|
|
12
|
+
buttonHref?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
badgeText,
|
|
17
|
+
badgeColor = 'ffe792',
|
|
18
|
+
titlePlain,
|
|
19
|
+
titleGradient,
|
|
20
|
+
gradientColors = 'from-[#ffe792] to-[#8197ff]',
|
|
21
|
+
description,
|
|
22
|
+
buttonText = 'Get Detailed Pricing',
|
|
23
|
+
buttonHref = '/contact'
|
|
24
|
+
} = Astro.props;
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<section class="pt-16 lg:pt-24 pb-16 lg:pb-24 px-6 max-w-7xl mx-auto flex flex-col items-center text-center justify-center min-h-[calc(60vh-5rem)]">
|
|
28
|
+
<div class={`inline-flex items-center gap-2 px-3 py-1 rounded-full bg-[#${badgeColor}]/10 text-[#${badgeColor}] text-xs font-bold tracking-widest uppercase mb-8 outline outline-1 outline-[#${badgeColor}]/20`}>
|
|
29
|
+
<span class={`w-2 h-2 rounded-full bg-[#${badgeColor}] animate-pulse`}></span>
|
|
30
|
+
{badgeText}
|
|
31
|
+
</div>
|
|
32
|
+
<h1 class="font-display text-5xl md:text-7xl lg:text-8xl font-black uppercase tracking-tighter leading-[0.9] text-white mb-8">
|
|
33
|
+
{titlePlain} <span class={`text-transparent bg-clip-text bg-gradient-to-r ${gradientColors}`}>{titleGradient}</span>.
|
|
34
|
+
</h1>
|
|
35
|
+
<p class="text-white/70 text-xl md:text-2xl max-w-3xl mb-14 leading-relaxed font-light">
|
|
36
|
+
{description}
|
|
37
|
+
</p>
|
|
38
|
+
<div class="flex flex-col sm:flex-row gap-6 justify-center">
|
|
39
|
+
<Button href={buttonHref} variant="primary">{buttonText}</Button>
|
|
40
|
+
</div>
|
|
41
|
+
</section>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Icon } from 'astro-icon/components';
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<aside class="flex flex-col h-full p-6 border-r border-white/10 fixed left-0 top-0 z-40 bg-[#0e0e0e] w-72 hidden lg:flex">
|
|
6
|
+
<div class="mb-12">
|
|
7
|
+
<a href="/">
|
|
8
|
+
<h2 class="text-2xl font-black tracking-widest text-[#ffe792] font-display uppercase">STARDAWN IT</h2>
|
|
9
|
+
<p class="text-[10px] text-white/60 tracking-[0.2em] font-medium opacity-60">Technician Portal v2.0</p>
|
|
10
|
+
</a>
|
|
11
|
+
</div>
|
|
12
|
+
<nav class="flex-1 space-y-2">
|
|
13
|
+
<a class="text-white/60 hover:text-[#ffe792] px-4 py-3 flex items-center gap-3 transition-colors hover:bg-[#1a1a1a] hover:rounded-xl" href="#">
|
|
14
|
+
<Icon name="mdi:console" class="w-6 h-6" />
|
|
15
|
+
<span class="font-display uppercase tracking-tighter font-semibold">Dashboard</span>
|
|
16
|
+
</a>
|
|
17
|
+
<a class="bg-[#ffe792] text-[#0e0e0e] rounded-xl px-4 py-3 font-bold flex items-center gap-3 transition-all duration-300 scale-105 shadow-[0_0_20px_rgba(255,231,146,0.2)]" href="/services/msp-dedicated-technicians">
|
|
18
|
+
<Icon name="mdi:earth" class="w-6 h-6" />
|
|
19
|
+
<span class="font-display uppercase tracking-tighter font-bold">Offshore Talent</span>
|
|
20
|
+
</a>
|
|
21
|
+
<a class="text-white/60 hover:text-[#ffe792] px-4 py-3 flex items-center gap-3 transition-colors hover:bg-[#1a1a1a] hover:rounded-xl" href="#">
|
|
22
|
+
<Icon name="mdi:brain" class="w-6 h-6" />
|
|
23
|
+
<span class="font-display uppercase tracking-tighter font-semibold">Skill Bridge</span>
|
|
24
|
+
</a>
|
|
25
|
+
<a class="text-white/60 hover:text-[#ffe792] px-4 py-3 flex items-center gap-3 transition-colors hover:bg-[#1a1a1a] hover:rounded-xl" href="#">
|
|
26
|
+
<Icon name="mdi:hub" class="w-6 h-6" />
|
|
27
|
+
<span class="font-display uppercase tracking-tighter font-semibold">Integration</span>
|
|
28
|
+
</a>
|
|
29
|
+
<a class="text-white/60 hover:text-[#ffe792] px-4 py-3 flex items-center gap-3 transition-colors hover:bg-[#1a1a1a] hover:rounded-xl" href="#">
|
|
30
|
+
<Icon name="mdi:connection" class="w-6 h-6" />
|
|
31
|
+
<span class="font-display uppercase tracking-tighter font-semibold">Systems</span>
|
|
32
|
+
</a>
|
|
33
|
+
</nav>
|
|
34
|
+
<div class="mt-auto pt-6 border-t border-white/10 space-y-4">
|
|
35
|
+
<button class="w-full bg-[#ffe792] text-[#0e0e0e] font-bold py-4 rounded-xl flex items-center justify-center gap-2 hover:scale-[1.02] active:scale-95 transition-all">
|
|
36
|
+
<Icon name="mdi:rocket-launch" class="w-6 h-6" />
|
|
37
|
+
Deploy Resource
|
|
38
|
+
</button>
|
|
39
|
+
<div class="flex flex-col gap-1">
|
|
40
|
+
<a class="text-white/60 hover:text-white px-4 py-2 flex items-center gap-3 text-sm transition-colors" href="#">
|
|
41
|
+
<Icon name="mdi:book-open-page-variant" class="w-5 h-5" />
|
|
42
|
+
Docs
|
|
43
|
+
</a>
|
|
44
|
+
<a class="text-white/60 hover:text-white px-4 py-2 flex items-center gap-3 text-sm transition-colors" href="#">
|
|
45
|
+
<Icon name="mdi:help-circle-outline" class="w-5 h-5" />
|
|
46
|
+
Support
|
|
47
|
+
</a>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
</aside>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
export interface Props {
|
|
3
|
+
text: string;
|
|
4
|
+
color?: string; // e.g. 'ffe792' or '8197ff'
|
|
5
|
+
dotColor?: string;
|
|
6
|
+
class?: string;
|
|
7
|
+
}
|
|
8
|
+
const { text, color = 'ffe792', dotColor, class: className = '' } = Astro.props;
|
|
9
|
+
const finalDotColor = dotColor || color;
|
|
10
|
+
---
|
|
11
|
+
<div class={`inline-flex items-center gap-2 px-3 py-1 rounded-full bg-[#${color}]/10 text-[#${color}] text-xs font-bold tracking-widest uppercase mb-8 outline outline-1 outline-[#${color}]/20 ${className}`}>
|
|
12
|
+
<span class={`w-2 h-2 rounded-full bg-[#${finalDotColor}] animate-pulse`}></span>
|
|
13
|
+
{text}
|
|
14
|
+
</div>
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jeetkhinde/stardawn-ui",
|
|
3
|
+
"version": "1.0.5",
|
|
4
|
+
"description": "StarDawn UI — component installer for Astro + Tailwind MSP template sites",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"stardawn-ui": "cli/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"cli/index.js",
|
|
11
|
+
"components/**",
|
|
12
|
+
"registry.json"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18.0.0"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"astro",
|
|
19
|
+
"tailwind",
|
|
20
|
+
"msp",
|
|
21
|
+
"ui",
|
|
22
|
+
"components",
|
|
23
|
+
"cli"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"commander": "^12.0.0"
|
|
28
|
+
}
|
|
29
|
+
}
|
package/registry.json
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"baseUrl": "https://raw.githubusercontent.com/stardawn-it/stardawn-registry/main",
|
|
4
|
+
"components": [
|
|
5
|
+
{
|
|
6
|
+
"name": "button",
|
|
7
|
+
"file": "Button.astro",
|
|
8
|
+
"description": "Primary and secondary button with GSAP magnetic effect",
|
|
9
|
+
"category": "ui",
|
|
10
|
+
"componentDeps": [],
|
|
11
|
+
"npmDeps": []
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "pill-tag",
|
|
15
|
+
"file": "PillTag.astro",
|
|
16
|
+
"description": "Pill-shaped tag, optionally a link, with hover color support",
|
|
17
|
+
"category": "ui",
|
|
18
|
+
"componentDeps": [],
|
|
19
|
+
"npmDeps": []
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "status-badge",
|
|
23
|
+
"file": "StatusBadge.astro",
|
|
24
|
+
"description": "Animated pulsing status badge with custom color",
|
|
25
|
+
"category": "ui",
|
|
26
|
+
"componentDeps": [],
|
|
27
|
+
"npmDeps": []
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "section-header",
|
|
31
|
+
"file": "SectionHeader.astro",
|
|
32
|
+
"description": "Section heading with eyebrow label, gradient title, and description",
|
|
33
|
+
"category": "ui",
|
|
34
|
+
"componentDeps": [],
|
|
35
|
+
"npmDeps": []
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "background-glow",
|
|
39
|
+
"file": "BackgroundGlow.astro",
|
|
40
|
+
"description": "Parallax radial glow orbs that follow mouse cursor via GSAP",
|
|
41
|
+
"category": "ui",
|
|
42
|
+
"componentDeps": [],
|
|
43
|
+
"npmDeps": []
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "offset-card",
|
|
47
|
+
"file": "OffsetCard.astro",
|
|
48
|
+
"description": "Dark card container with offset hover shadow, yellow or blue accent",
|
|
49
|
+
"category": "ui",
|
|
50
|
+
"componentDeps": [],
|
|
51
|
+
"npmDeps": []
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "bento-card",
|
|
55
|
+
"file": "BentoCard.astro",
|
|
56
|
+
"description": "Bento-style card with icon, title, and slot content",
|
|
57
|
+
"category": "ui",
|
|
58
|
+
"componentDeps": [],
|
|
59
|
+
"npmDeps": ["astro-icon", "@iconify-json/mdi"]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "feature-list-item",
|
|
63
|
+
"file": "FeatureListItem.astro",
|
|
64
|
+
"description": "Feature list item in four variants: list, bento, detail, simple",
|
|
65
|
+
"category": "ui",
|
|
66
|
+
"componentDeps": [],
|
|
67
|
+
"npmDeps": ["astro-icon", "@iconify-json/mdi"]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "footer-link",
|
|
71
|
+
"file": "FooterLink.astro",
|
|
72
|
+
"description": "Animated footer nav link with sliding chevron icon",
|
|
73
|
+
"category": "navigation",
|
|
74
|
+
"componentDeps": [],
|
|
75
|
+
"npmDeps": ["astro-icon", "@iconify-json/mdi"]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"name": "service-hero",
|
|
79
|
+
"file": "ServiceHero.astro",
|
|
80
|
+
"description": "Full-width hero section for service pages with badge, gradient title, and CTA",
|
|
81
|
+
"category": "sections",
|
|
82
|
+
"componentDeps": ["button"],
|
|
83
|
+
"npmDeps": []
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "navbar",
|
|
87
|
+
"file": "Navbar.astro",
|
|
88
|
+
"description": "Sticky top navbar with mega-menu dropdown and GSAP animations",
|
|
89
|
+
"category": "navigation",
|
|
90
|
+
"componentDeps": ["button"],
|
|
91
|
+
"npmDeps": ["astro-icon", "@iconify-json/mdi"]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"name": "footer",
|
|
95
|
+
"file": "Footer.astro",
|
|
96
|
+
"description": "Full-width footer with CTA strip, nav columns, and company info",
|
|
97
|
+
"category": "navigation",
|
|
98
|
+
"componentDeps": ["footer-link"],
|
|
99
|
+
"npmDeps": ["astro-icon", "@iconify-json/mdi"]
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "side-nav",
|
|
103
|
+
"file": "SideNav.astro",
|
|
104
|
+
"description": "Fixed left sidebar navigation for portal/dashboard layouts",
|
|
105
|
+
"category": "navigation",
|
|
106
|
+
"componentDeps": [],
|
|
107
|
+
"npmDeps": ["astro-icon", "@iconify-json/mdi"]
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
}
|