@salmansaeed/nexa 1.0.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/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@salmansaeed/nexa",
3
+ "version": "1.0.0",
4
+ "description": "Nexa CLI for scaffolding React/Vite apps, components, services, and contexts with a cleaner UI and prebuilt structure",
5
+ "bin": {
6
+ "nexa": "bin/nexa.js"
7
+ },
8
+ "type": "module",
9
+ "files": [
10
+ "bin",
11
+ "template",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "start": "node ./bin/nexa.js"
16
+ },
17
+ "keywords": [
18
+ "cli",
19
+ "scaffold",
20
+ "react",
21
+ "vite",
22
+ "components",
23
+ "contexts",
24
+ "services",
25
+ "layout",
26
+ "responsive",
27
+ "header",
28
+ "navbar",
29
+ "prebuilt",
30
+ "ui"
31
+ ],
32
+ "author": "Salman Saeed, Conscious Neurons LLC",
33
+ "license": "MIT",
34
+ "preferGlobal": true,
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/algosal/Nexa.js.git"
38
+ },
39
+ "homepage": "https://github.com/algosal/Nexa.js#readme",
40
+ "bugs": {
41
+ "url": "https://github.com/algosal/Nexa.js/issues"
42
+ },
43
+ "engines": {
44
+ "node": ">=18"
45
+ }
46
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": ".",
4
+ "paths": {
5
+ "@/*": ["src/*"],
6
+ "components/*": ["src/components/*"],
7
+ "services/*": ["src/services/*"],
8
+ "contexts/*": ["src/contexts/*"]
9
+ }
10
+ },
11
+ "include": ["src"]
12
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * File: nexa.config.js
3
+ * Purpose: Vite configuration for Nexa-generated apps.
4
+ */
5
+
6
+ import { defineConfig } from "vite";
7
+ import react from "@vitejs/plugin-react";
8
+
9
+ export default defineConfig({
10
+ root: ".",
11
+ base: "/",
12
+ plugins: [react()],
13
+ server: {
14
+ port: 4321,
15
+ },
16
+ build: {
17
+ outDir: "dist",
18
+ },
19
+ clearScreen: false,
20
+ });
Binary file
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="icon" type="image/png" href="/favicon.png" />
7
+ <link rel="manifest" href="/manifest.json" />
8
+ <title>AG App</title>
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ <script type="module" src="/src/main.jsx"></script>
13
+ </body>
14
+ </html>
Binary file
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "AG App",
3
+ "short_name": "AG",
4
+ "start_url": ".",
5
+ "display": "standalone",
6
+ "background_color": "#0a0f24",
7
+ "theme_color": "#ffd700",
8
+ "icons": [
9
+ {
10
+ "src": "/logo.png",
11
+ "sizes": "192x192",
12
+ "type": "image/png"
13
+ },
14
+ {
15
+ "src": "/logo.png",
16
+ "sizes": "512x512",
17
+ "type": "image/png"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,117 @@
1
+ :root {
2
+ --nexa-bg: #07111f;
3
+ --nexa-bg-elevated: #0d1b2d;
4
+ --nexa-surface: rgba(255, 255, 255, 0.04);
5
+
6
+ --nexa-primary: #3ee7ff;
7
+ --nexa-primary-soft: #8bf4ff;
8
+
9
+ --nexa-accent: #ffcf5a;
10
+ --nexa-accent-soft: #ffe29a;
11
+
12
+ --nexa-text: #eaf4ff;
13
+ --nexa-text-dim: #93a7bd;
14
+
15
+ --nexa-border: rgba(62, 231, 255, 0.18);
16
+ --nexa-glow: rgba(62, 231, 255, 0.28);
17
+ }
18
+
19
+ *,
20
+ *::before,
21
+ *::after {
22
+ box-sizing: border-box;
23
+ }
24
+
25
+ html,
26
+ body,
27
+ #root {
28
+ margin: 0;
29
+ padding: 0;
30
+ min-height: 100%;
31
+ width: 100%;
32
+ }
33
+
34
+ body {
35
+ background: var(--nexa-bg);
36
+ color: var(--nexa-text);
37
+ }
38
+
39
+ *::-webkit-scrollbar {
40
+ display: none;
41
+ }
42
+
43
+ /* ====== App Shell ====== */
44
+ .app-container {
45
+ --app-sidebar-width: 220px;
46
+
47
+ font-family: "Share Tech Mono", monospace;
48
+ background: var(--nexa-bg);
49
+ color: var(--nexa-text);
50
+ min-height: 100vh;
51
+ position: relative;
52
+ line-height: 1.6;
53
+ }
54
+
55
+ /* ====== Content Wrapper ====== */
56
+ .app-scrollable-content {
57
+ margin-left: var(--app-sidebar-width);
58
+ min-height: 100vh;
59
+ width: calc(100% - var(--app-sidebar-width));
60
+ padding: 0;
61
+ transition:
62
+ margin-left 0.3s ease,
63
+ width 0.3s ease,
64
+ padding 0.3s ease;
65
+ }
66
+
67
+ /* ====== Main Content Area ====== */
68
+ .app-main-content {
69
+ width: 100%;
70
+ min-height: 100vh;
71
+ padding: 0;
72
+ transition: padding 0.3s ease;
73
+ }
74
+
75
+ /* ====== Utility Text Classes ====== */
76
+ .app-text-highlight {
77
+ color: var(--nexa-accent);
78
+ }
79
+
80
+ .app-text-cyan {
81
+ color: var(--nexa-primary);
82
+ }
83
+
84
+ .app-link {
85
+ color: var(--nexa-primary);
86
+ text-decoration: none;
87
+ }
88
+
89
+ .app-link:hover {
90
+ color: var(--nexa-accent);
91
+ }
92
+
93
+ /* ====== Optional Shared Surface Utility ====== */
94
+ .app-surface {
95
+ background: var(--nexa-surface);
96
+ border: 1px solid var(--nexa-border);
97
+ border-radius: 12px;
98
+ backdrop-filter: blur(10px);
99
+ }
100
+
101
+ /* ====== Mobile Adjustments ====== */
102
+ @media (max-width: 768px) {
103
+ .app-scrollable-content {
104
+ margin-left: 0;
105
+ width: 100%;
106
+ padding: 0;
107
+ }
108
+
109
+ .app-main-content {
110
+ width: 100%;
111
+ padding: 0;
112
+ }
113
+
114
+ .app-dynamic-header {
115
+ display: block;
116
+ }
117
+ }
@@ -0,0 +1,44 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { Routes, Route } from "react-router-dom";
3
+ import AppNavbar from "./components/Navbar/Navbar";
4
+ import AppDynamicHeader from "./components/DynamicHeader/DynamicHeader";
5
+ import Home from "./components/Home/Home";
6
+ import Nexa from "./components/Nexa/Nexa";
7
+ import "./App.css";
8
+
9
+ const MOBILE_BREAKPOINT = 768;
10
+
11
+ const App = () => {
12
+ const getIsMobile = () =>
13
+ typeof window !== "undefined" && window.innerWidth <= MOBILE_BREAKPOINT;
14
+
15
+ const [isMobile, setIsMobile] = useState(() => getIsMobile());
16
+
17
+ useEffect(() => {
18
+ const handleResize = () => {
19
+ setIsMobile(getIsMobile());
20
+ };
21
+
22
+ window.addEventListener("resize", handleResize);
23
+ return () => window.removeEventListener("resize", handleResize);
24
+ }, []);
25
+
26
+ return (
27
+ <div className="app-container">
28
+ <AppNavbar isMobile={isMobile} />
29
+
30
+ <div className="app-scrollable-content">
31
+ <AppDynamicHeader isMobile={isMobile} />
32
+
33
+ <main className="app-main-content">
34
+ <Routes>
35
+ <Route path="/" element={<Home />} />
36
+ <Route path="/nexa" element={<Nexa />} />
37
+ </Routes>
38
+ </main>
39
+ </div>
40
+ </div>
41
+ );
42
+ };
43
+
44
+ export default App;
@@ -0,0 +1,55 @@
1
+ .app-dynamic-header {
2
+ position: sticky;
3
+ top: 0;
4
+ z-index: 2000;
5
+ width: 100%;
6
+ background: #0a0f24;
7
+ border-bottom: 1px solid #00ffff;
8
+ }
9
+
10
+ .app-dh-inner {
11
+ padding: 20px 24px;
12
+ }
13
+
14
+ .app-dh-title {
15
+ margin: 0;
16
+ font-size: 26px;
17
+ font-weight: 700;
18
+ color: #00ffff;
19
+ }
20
+
21
+ .app-dh-subtitle {
22
+ margin-top: 6px;
23
+ font-size: 13px;
24
+ color: #9ca3af;
25
+ }
26
+
27
+ .app-dh-highlight {
28
+ color: #ffd700;
29
+ }
30
+
31
+ /* Tooltip */
32
+ .app-dh-title-wrapper {
33
+ position: relative;
34
+ display: inline-block;
35
+ }
36
+
37
+ .app-dh-tooltip {
38
+ visibility: hidden;
39
+ opacity: 0;
40
+ position: absolute;
41
+ bottom: -28px;
42
+ left: 0;
43
+ background: #000;
44
+ color: #00ffff;
45
+ padding: 6px 10px;
46
+ font-size: 12px;
47
+ border-radius: 4px;
48
+ white-space: nowrap;
49
+ transition: opacity 0.2s ease;
50
+ }
51
+
52
+ .app-dh-title-wrapper:hover .app-dh-tooltip {
53
+ visibility: visible;
54
+ opacity: 1;
55
+ }
@@ -0,0 +1,39 @@
1
+ import React from "react";
2
+ import { useLocation } from "react-router-dom";
3
+ import { routeMeta } from "../../config/routeMeta";
4
+ import "./DynamicHeader.css";
5
+
6
+ const AppDynamicHeader = ({ isMobile }) => {
7
+ const location = useLocation();
8
+
9
+ const currentMeta = routeMeta[location.pathname] || {
10
+ title: "Nexa",
11
+ subtitle: "",
12
+ tooltip: "",
13
+ };
14
+
15
+ return (
16
+ <header
17
+ key={location.pathname}
18
+ className={`app-dynamic-header ${isMobile ? "app-dynamic-header-mobile" : ""}`}
19
+ >
20
+ <div className="app-dh-inner">
21
+ <div className="app-dh-title-wrapper">
22
+ <h1 className="app-dh-title" title={currentMeta.tooltip || ""}>
23
+ {currentMeta.title}
24
+ </h1>
25
+
26
+ {currentMeta.tooltip && (
27
+ <span className="app-dh-tooltip">{currentMeta.tooltip}</span>
28
+ )}
29
+ </div>
30
+
31
+ {currentMeta.subtitle && (
32
+ <p className="app-dh-subtitle">{currentMeta.subtitle}</p>
33
+ )}
34
+ </div>
35
+ </header>
36
+ );
37
+ };
38
+
39
+ export default AppDynamicHeader;
@@ -0,0 +1,189 @@
1
+ .home-page {
2
+ min-height: calc(100vh - 120px);
3
+ display: flex;
4
+ align-items: center;
5
+ justify-content: center;
6
+ padding: 24px;
7
+ }
8
+
9
+ .nexa-intro {
10
+ text-align: center;
11
+ display: flex;
12
+ flex-direction: column;
13
+ align-items: center;
14
+ justify-content: center;
15
+ }
16
+
17
+ .nexa-logo-wrap {
18
+ position: relative;
19
+ width: 190px;
20
+ height: 190px;
21
+ display: grid;
22
+ place-items: center;
23
+ margin-bottom: 20px;
24
+ border-radius: 40px;
25
+ background: radial-gradient(
26
+ circle at center,
27
+ rgba(62, 231, 255, 0.1),
28
+ rgba(255, 255, 255, 0.02)
29
+ );
30
+ box-shadow:
31
+ 0 0 60px rgba(62, 231, 255, 0.1),
32
+ inset 0 0 30px rgba(255, 255, 255, 0.025);
33
+ overflow: hidden;
34
+ }
35
+
36
+ /* mild convex / glass lens feel */
37
+ .nexa-logo-convex {
38
+ position: absolute;
39
+ inset: 10%;
40
+ border-radius: 28px;
41
+ background: radial-gradient(
42
+ circle at 35% 28%,
43
+ rgba(255, 255, 255, 0.16),
44
+ rgba(255, 255, 255, 0.04) 28%,
45
+ rgba(255, 255, 255, 0.01) 52%,
46
+ rgba(0, 0, 0, 0.04) 100%
47
+ );
48
+ box-shadow:
49
+ inset 0 2px 10px rgba(255, 255, 255, 0.06),
50
+ inset 0 -10px 18px rgba(0, 0, 0, 0.12);
51
+ pointer-events: none;
52
+ }
53
+
54
+ .nexa-logo {
55
+ margin: 0;
56
+ font-size: 7rem;
57
+ line-height: 1;
58
+ font-weight: 800;
59
+ letter-spacing: -0.08em;
60
+ color: var(--nexa-primary);
61
+ text-shadow:
62
+ 0 0 10px rgba(62, 231, 255, 0.28),
63
+ 0 0 24px rgba(62, 231, 255, 0.14);
64
+
65
+ transform: scale(0.2);
66
+ opacity: 0;
67
+ filter: blur(14px);
68
+ animation: nexaReveal 1.2s ease-out forwards;
69
+ }
70
+
71
+ /* keep the shine, which already looks good */
72
+ .nexa-logo-shine {
73
+ position: absolute;
74
+ inset: -40%;
75
+ background: linear-gradient(
76
+ 110deg,
77
+ transparent 35%,
78
+ rgba(255, 255, 255, 0.04) 45%,
79
+ rgba(255, 255, 255, 0.35) 50%,
80
+ rgba(255, 255, 255, 0.04) 55%,
81
+ transparent 65%
82
+ );
83
+ transform: translateX(-140%) rotate(12deg);
84
+ animation: nexaShine 1.6s ease 0.65s forwards;
85
+ pointer-events: none;
86
+ }
87
+
88
+ .nexa-wordmark {
89
+ margin: 0 0 8px;
90
+ font-size: clamp(2.2rem, 5vw, 3.8rem);
91
+ font-weight: 700;
92
+ letter-spacing: -0.04em;
93
+ color: var(--nexa-text);
94
+ opacity: 0;
95
+ transform: translateY(10px);
96
+ animation: fadeUp 0.7s ease 0.8s forwards;
97
+ }
98
+
99
+ .nexa-tagline {
100
+ margin: 0;
101
+ font-size: 1rem;
102
+ color: var(--nexa-text-dim);
103
+ letter-spacing: 0.02em;
104
+ opacity: 0;
105
+ transform: translateY(10px);
106
+ animation: fadeUp 0.7s ease 1s forwards;
107
+ }
108
+
109
+ .nexa-credit {
110
+ margin-top: 10px;
111
+ font-size: 0.82rem;
112
+ color: var(--nexa-text-dim);
113
+ opacity: 0;
114
+ transform: translateY(10px);
115
+ animation: fadeUp 0.7s ease 1.2s forwards;
116
+ }
117
+
118
+ .nexa-credit span {
119
+ color: var(--nexa-accent);
120
+ font-weight: 600;
121
+ }
122
+
123
+ @keyframes nexaReveal {
124
+ 0% {
125
+ transform: scale(0.2);
126
+ opacity: 0;
127
+ filter: blur(14px);
128
+ }
129
+ 55% {
130
+ transform: scale(1.08);
131
+ opacity: 1;
132
+ filter: blur(0);
133
+ }
134
+ 100% {
135
+ transform: scale(1);
136
+ opacity: 1;
137
+ filter: blur(0);
138
+ }
139
+ }
140
+
141
+ @keyframes nexaShine {
142
+ 0% {
143
+ transform: translateX(-140%) rotate(12deg);
144
+ opacity: 0;
145
+ }
146
+ 20% {
147
+ opacity: 1;
148
+ }
149
+ 100% {
150
+ transform: translateX(140%) rotate(12deg);
151
+ opacity: 0;
152
+ }
153
+ }
154
+
155
+ @keyframes fadeUp {
156
+ to {
157
+ opacity: 1;
158
+ transform: translateY(0);
159
+ }
160
+ }
161
+
162
+ @media (max-width: 768px) {
163
+ .home-page {
164
+ min-height: calc(100vh - 100px);
165
+ padding: 16px;
166
+ }
167
+
168
+ .nexa-logo-wrap {
169
+ width: 160px;
170
+ height: 160px;
171
+ border-radius: 32px;
172
+ }
173
+
174
+ .nexa-logo-convex {
175
+ border-radius: 22px;
176
+ }
177
+
178
+ .nexa-logo {
179
+ font-size: 5.8rem;
180
+ }
181
+
182
+ .nexa-wordmark {
183
+ font-size: 2.3rem;
184
+ }
185
+
186
+ .nexa-tagline {
187
+ font-size: 0.92rem;
188
+ }
189
+ }
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ import "./Home.css";
3
+
4
+ const Home = () => {
5
+ return (
6
+ <section className="home-page">
7
+ <div className="nexa-intro">
8
+ <div className="nexa-logo-wrap">
9
+ <div className="nexa-logo-convex" />
10
+ <div className="nexa-logo-shine" />
11
+ <h1 className="nexa-logo">N</h1>
12
+ </div>
13
+
14
+ <h2 className="nexa-wordmark">Nexa</h2>
15
+ <p className="nexa-tagline">Cleaner UI. Prebuilt structure.</p>
16
+ <p className="nexa-credit">
17
+ A product of <span>Conscious Neurons</span>
18
+ </p>
19
+ </div>
20
+ </section>
21
+ );
22
+ };
23
+
24
+ export default Home;