Skip to content

Commit 698e822

Browse files
committed
Add GitHub Pages landing page
1 parent d12dd51 commit 698e822

1 file changed

Lines changed: 278 additions & 0 deletions

File tree

index.html

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
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+
<title>envlint | Validate .env Files in CI</title>
7+
<meta name="description" content="Validate your .env files in CI before your app even starts. Works with any language. Schema-based validation for environment variables.">
8+
<link rel="preconnect" href="https://fonts.googleapis.com">
9+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10+
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
11+
<style>
12+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
13+
:root {
14+
--bg: #030014;
15+
--text: #ffffff;
16+
--accent-1: #14b8a6;
17+
--accent-2: #06b6d4;
18+
--accent-3: #22c55e;
19+
--card-bg: rgba(20, 184, 166, 0.08);
20+
--card-border: rgba(20, 184, 166, 0.2);
21+
}
22+
html { scroll-behavior: smooth; }
23+
body {
24+
font-family: 'Space Grotesk', -apple-system, sans-serif;
25+
background: var(--bg);
26+
color: var(--text);
27+
line-height: 1.6;
28+
overflow-x: hidden;
29+
}
30+
code, pre { font-family: 'JetBrains Mono', monospace; }
31+
.bg-gradient {
32+
position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: -1;
33+
}
34+
.bg-gradient::before {
35+
content: ''; position: absolute; width: 150%; height: 150%; top: -25%; left: -25%;
36+
background:
37+
radial-gradient(ellipse at 20% 30%, rgba(20, 184, 166, 0.25) 0%, transparent 50%),
38+
radial-gradient(ellipse at 80% 50%, rgba(6, 182, 212, 0.2) 0%, transparent 50%),
39+
radial-gradient(ellipse at 40% 80%, rgba(34, 197, 94, 0.15) 0%, transparent 50%);
40+
animation: gradient-shift 20s ease-in-out infinite;
41+
}
42+
@keyframes gradient-shift {
43+
0%, 100% { transform: translate(0, 0) rotate(0deg); }
44+
50% { transform: translate(2%, 2%) rotate(1deg); }
45+
}
46+
.container { max-width: 900px; margin: 0 auto; padding: 0 24px; }
47+
48+
.hero {
49+
min-height: 70vh; display: flex; flex-direction: column; justify-content: center;
50+
padding: 100px 0 60px; text-align: center;
51+
}
52+
.logo { font-size: 4rem; margin-bottom: 16px; }
53+
.hero h1 {
54+
font-size: clamp(2.5rem, 6vw, 4rem); font-weight: 700; margin-bottom: 16px;
55+
background: linear-gradient(135deg, var(--accent-1), var(--accent-2));
56+
-webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
57+
}
58+
.hero .tagline {
59+
font-size: 1.25rem; color: rgba(255,255,255,0.7); max-width: 600px; margin: 0 auto 32px;
60+
}
61+
.badges { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-bottom: 32px; }
62+
.badge {
63+
padding: 8px 16px; background: var(--card-bg); border: 1px solid var(--card-border);
64+
border-radius: 999px; font-size: 0.85rem; color: var(--accent-1);
65+
}
66+
.badge-highlight {
67+
background: rgba(34, 197, 94, 0.15); border-color: rgba(34, 197, 94, 0.3);
68+
color: #22c55e;
69+
}
70+
.buttons { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
71+
.btn {
72+
display: inline-flex; align-items: center; gap: 8px; padding: 14px 28px;
73+
border-radius: 12px; font-size: 1rem; font-weight: 600; text-decoration: none;
74+
transition: all 0.3s ease;
75+
}
76+
.btn-primary {
77+
background: linear-gradient(135deg, var(--accent-1), var(--accent-2)); color: white;
78+
}
79+
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 20px 40px rgba(20, 184, 166, 0.3); }
80+
.btn-secondary {
81+
background: var(--card-bg); color: white; border: 1px solid var(--card-border);
82+
}
83+
.btn-secondary:hover { border-color: var(--accent-1); }
84+
.btn svg { width: 20px; height: 20px; }
85+
86+
.install {
87+
background: var(--card-bg); border: 1px solid var(--card-border); border-radius: 16px;
88+
padding: 20px 24px; margin-bottom: 60px; display: flex; align-items: center;
89+
justify-content: space-between; gap: 16px; flex-wrap: wrap;
90+
}
91+
.install code { font-size: 1.1rem; color: var(--accent-3); }
92+
.install button {
93+
background: rgba(255,255,255,0.1); border: none; padding: 8px 16px;
94+
border-radius: 8px; color: white; cursor: pointer; font-size: 0.9rem;
95+
}
96+
.install button:hover { background: rgba(255,255,255,0.2); }
97+
98+
.features { padding: 60px 0; }
99+
.section-title { font-size: 2rem; font-weight: 700; text-align: center; margin-bottom: 48px; }
100+
.feature-grid {
101+
display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 24px;
102+
}
103+
.feature {
104+
background: var(--card-bg); border: 1px solid var(--card-border); border-radius: 16px;
105+
padding: 24px; transition: all 0.3s ease;
106+
}
107+
.feature:hover { border-color: var(--accent-1); transform: translateY(-4px); }
108+
.feature-icon { font-size: 2rem; margin-bottom: 12px; }
109+
.feature h3 { font-size: 1.1rem; margin-bottom: 8px; }
110+
.feature p { font-size: 0.9rem; color: rgba(255,255,255,0.7); }
111+
112+
.code-section { padding: 60px 0; }
113+
.code-block {
114+
background: #0d1117; border: 1px solid #30363d; border-radius: 12px; overflow: hidden;
115+
margin-bottom: 24px;
116+
}
117+
.code-header {
118+
background: #161b22; padding: 12px 16px; border-bottom: 1px solid #30363d;
119+
font-size: 0.85rem; color: rgba(255,255,255,0.6);
120+
}
121+
.code-block pre { padding: 20px; overflow-x: auto; font-size: 0.9rem; line-height: 1.6; }
122+
.code-block code { color: #e6edf3; }
123+
.comment { color: #8b949e; }
124+
.keyword { color: #ff7b72; }
125+
.string { color: #a5d6ff; }
126+
.key { color: #7ee787; }
127+
128+
.types { padding: 40px 0; }
129+
.type-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; }
130+
.type-tag {
131+
padding: 12px 16px; background: var(--card-bg); border: 1px solid var(--card-border);
132+
border-radius: 10px; text-align: center; font-size: 0.9rem; font-weight: 500;
133+
}
134+
135+
footer {
136+
padding: 40px 0; text-align: center; border-top: 1px solid var(--card-border); margin-top: 60px;
137+
}
138+
footer p { color: rgba(255,255,255,0.5); font-size: 0.9rem; }
139+
footer a { color: var(--accent-1); text-decoration: none; }
140+
footer a:hover { text-decoration: underline; }
141+
142+
@media (max-width: 600px) {
143+
.hero { padding: 60px 0 40px; min-height: auto; }
144+
.install { flex-direction: column; text-align: center; }
145+
}
146+
</style>
147+
</head>
148+
<body>
149+
<div class="bg-gradient"></div>
150+
151+
<section class="hero">
152+
<div class="container">
153+
<div class="logo"></div>
154+
<h1>envlint</h1>
155+
<p class="tagline">Validate your .env files in CI before your app even starts. Works with any language. Schema-based validation for environment variables.</p>
156+
<div class="badges">
157+
<span class="badge">Python CLI</span>
158+
<span class="badge">Language Agnostic</span>
159+
<span class="badge badge-highlight">CI/CD Ready</span>
160+
<span class="badge">GPL-3.0</span>
161+
</div>
162+
<div class="buttons">
163+
<a href="https://github.com/cainky/envlint" target="_blank" class="btn btn-primary">
164+
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
165+
View on GitHub
166+
</a>
167+
<a href="https://pypi.org/project/envlint/" target="_blank" class="btn btn-secondary">
168+
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg>
169+
PyPI Package
170+
</a>
171+
</div>
172+
</div>
173+
</section>
174+
175+
<div class="container">
176+
<div class="install">
177+
<code>pip install envlint</code>
178+
<button onclick="navigator.clipboard.writeText('pip install envlint')">Copy</button>
179+
</div>
180+
</div>
181+
182+
<section class="features">
183+
<div class="container">
184+
<h2 class="section-title">Features</h2>
185+
<div class="feature-grid">
186+
<div class="feature">
187+
<div class="feature-icon">🌐</div>
188+
<h3>Language Agnostic</h3>
189+
<p>One schema works across all your projects - Python, Node, Go, Ruby, or any stack.</p>
190+
</div>
191+
<div class="feature">
192+
<div class="feature-icon">🔒</div>
193+
<h3>Build-Time Validation</h3>
194+
<p>Catch missing or invalid env vars before deployment, not in production.</p>
195+
</div>
196+
<div class="feature">
197+
<div class="feature-icon"></div>
198+
<h3>Zero Runtime Impact</h3>
199+
<p>No dependencies or code changes needed. Just validate and deploy.</p>
200+
</div>
201+
<div class="feature">
202+
<div class="feature-icon">🔄</div>
203+
<h3>CI/CD Native</h3>
204+
<p>Exit codes designed for automation. Easy GitHub Actions integration.</p>
205+
</div>
206+
<div class="feature">
207+
<div class="feature-icon">📝</div>
208+
<h3>YAML Schema</h3>
209+
<p>Human-readable schema files with types, patterns, and defaults.</p>
210+
</div>
211+
<div class="feature">
212+
<div class="feature-icon">🚀</div>
213+
<h3>Auto-Generate Schema</h3>
214+
<p>Bootstrap from existing .env files with <code>envlint init</code>.</p>
215+
</div>
216+
</div>
217+
</div>
218+
</section>
219+
220+
<section class="types">
221+
<div class="container">
222+
<h2 class="section-title">Supported Types</h2>
223+
<div class="type-grid">
224+
<div class="type-tag">string</div>
225+
<div class="type-tag">integer</div>
226+
<div class="type-tag">float</div>
227+
<div class="type-tag">boolean</div>
228+
<div class="type-tag">url</div>
229+
<div class="type-tag">email</div>
230+
<div class="type-tag">port</div>
231+
<div class="type-tag">path</div>
232+
</div>
233+
</div>
234+
</section>
235+
236+
<section class="code-section">
237+
<div class="container">
238+
<h2 class="section-title">Quick Start</h2>
239+
<div class="code-block">
240+
<div class="code-header">.env.schema</div>
241+
<pre><code><span class="key">DATABASE_URL</span>:
242+
<span class="key">type</span>: <span class="string">url</span>
243+
<span class="key">required</span>: <span class="string">true</span>
244+
245+
<span class="key">API_PORT</span>:
246+
<span class="key">type</span>: <span class="string">port</span>
247+
<span class="key">default</span>: <span class="string">3000</span>
248+
249+
<span class="key">DEBUG</span>:
250+
<span class="key">type</span>: <span class="string">boolean</span>
251+
<span class="key">default</span>: <span class="string">false</span>
252+
253+
<span class="key">ADMIN_EMAIL</span>:
254+
<span class="key">type</span>: <span class="string">email</span>
255+
<span class="key">required</span>: <span class="string">true</span></code></pre>
256+
</div>
257+
<div class="code-block">
258+
<div class="code-header">Terminal</div>
259+
<pre><code><span class="comment"># Validate your .env file</span>
260+
$ envlint check
261+
<span class="string">✓ All 4 variables validated successfully</span>
262+
263+
<span class="comment"># Strict mode - fail on undefined vars</span>
264+
$ envlint check --strict
265+
266+
<span class="comment"># Generate schema from existing .env</span>
267+
$ envlint init --from-env</code></pre>
268+
</div>
269+
</div>
270+
</section>
271+
272+
<footer>
273+
<div class="container">
274+
<p>Built by <a href="https://kylecain.me">Kyle Cain</a> &middot; <a href="https://github.com/cainky/envlint">GitHub</a></p>
275+
</div>
276+
</footer>
277+
</body>
278+
</html>

0 commit comments

Comments
 (0)