Skip to content

Commit 36aba37

Browse files
authored
Landing page (#1)
1 parent 8ec458f commit 36aba37

3 files changed

Lines changed: 258 additions & 0 deletions

File tree

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ COPY --chmod=755 ./rel/docker-entrypoint.sh /entrypoint.sh
7676
# docker container can be started with arbitrary uid
7777
RUN mkdir -p /var/lib/plausible && chmod ugo+rw -R /var/lib/plausible
7878

79+
COPY --chmod=444 ./landing/index.html /app/landing/index.html
80+
7981
USER 999
8082
WORKDIR /app
8183
ENV LISTEN_IP=0.0.0.0

Procfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
web: /app/bin/plausible start
2+
web-landing: /bin/busybox httpd -f -c /dev/null -p 8000 -h /app/landing
23
release: /app/bin/plausible eval Plausible.Release.interweave_migrate

landing/index.html

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
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>Python Infra Analytics &mdash; PSF</title>
7+
<style>
8+
:root {
9+
--py-blue: #306998;
10+
--py-blue-dark: #1e4f72;
11+
--py-yellow: #ffd43b;
12+
--py-yellow-muted: #ffe873;
13+
--bg: #0f1117;
14+
--surface: #181b24;
15+
--surface-hover: #1f2330;
16+
--border: #2a2e3a;
17+
--text: #e2e4e9;
18+
--text-muted: #8b8fa3;
19+
--text-dim: #5c6070;
20+
}
21+
22+
* { margin: 0; padding: 0; box-sizing: border-box; }
23+
24+
body {
25+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
26+
background: var(--bg);
27+
color: var(--text);
28+
min-height: 100vh;
29+
display: flex;
30+
flex-direction: column;
31+
}
32+
33+
.hero {
34+
padding: 4rem 2rem 3rem;
35+
text-align: center;
36+
background: linear-gradient(180deg, rgba(48, 105, 152, 0.12) 0%, transparent 100%);
37+
border-bottom: 1px solid var(--border);
38+
}
39+
40+
.logo-row {
41+
display: flex;
42+
align-items: center;
43+
justify-content: center;
44+
gap: 1rem;
45+
margin-bottom: 1.5rem;
46+
}
47+
48+
.logo-row svg {
49+
flex-shrink: 0;
50+
}
51+
52+
.hero h1 {
53+
font-size: 1.75rem;
54+
font-weight: 700;
55+
letter-spacing: -0.02em;
56+
}
57+
58+
.hero h1 span {
59+
color: var(--py-yellow);
60+
}
61+
62+
.hero p {
63+
margin-top: 0.75rem;
64+
color: var(--text-muted);
65+
font-size: 1.05rem;
66+
max-width: 540px;
67+
margin-left: auto;
68+
margin-right: auto;
69+
line-height: 1.6;
70+
}
71+
72+
.main {
73+
flex: 1;
74+
max-width: 820px;
75+
width: 100%;
76+
margin: 0 auto;
77+
padding: 2.5rem 2rem;
78+
}
79+
80+
.section-label {
81+
font-size: 0.75rem;
82+
font-weight: 600;
83+
text-transform: uppercase;
84+
letter-spacing: 0.08em;
85+
color: var(--text-dim);
86+
margin-bottom: 1rem;
87+
}
88+
89+
.grid {
90+
display: grid;
91+
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
92+
gap: 0.75rem;
93+
}
94+
95+
.card {
96+
display: flex;
97+
align-items: center;
98+
gap: 0.875rem;
99+
padding: 1rem 1.125rem;
100+
background: var(--surface);
101+
border: 1px solid var(--border);
102+
border-radius: 10px;
103+
text-decoration: none;
104+
color: var(--text);
105+
transition: background 0.15s, border-color 0.15s, transform 0.15s;
106+
}
107+
108+
.card:hover {
109+
background: var(--surface-hover);
110+
border-color: var(--py-blue);
111+
transform: translateY(-1px);
112+
}
113+
114+
.card-icon {
115+
width: 40px;
116+
height: 40px;
117+
border-radius: 8px;
118+
background: rgba(48, 105, 152, 0.15);
119+
display: flex;
120+
align-items: center;
121+
justify-content: center;
122+
flex-shrink: 0;
123+
}
124+
125+
.card-icon svg {
126+
width: 20px;
127+
height: 20px;
128+
color: var(--py-blue);
129+
stroke: currentColor;
130+
fill: none;
131+
stroke-width: 1.75;
132+
stroke-linecap: round;
133+
stroke-linejoin: round;
134+
}
135+
136+
.card-body {
137+
min-width: 0;
138+
}
139+
140+
.card-title {
141+
font-size: 0.95rem;
142+
font-weight: 600;
143+
white-space: nowrap;
144+
overflow: hidden;
145+
text-overflow: ellipsis;
146+
}
147+
148+
.card-desc {
149+
font-size: 0.8rem;
150+
color: var(--text-muted);
151+
margin-top: 0.15rem;
152+
}
153+
154+
.footer {
155+
text-align: center;
156+
padding: 2rem;
157+
color: var(--text-dim);
158+
font-size: 0.8rem;
159+
border-top: 1px solid var(--border);
160+
}
161+
162+
.footer a {
163+
color: var(--text-muted);
164+
text-decoration: none;
165+
}
166+
167+
.footer a:hover {
168+
color: var(--py-yellow);
169+
}
170+
171+
@media (max-width: 480px) {
172+
.hero { padding: 2.5rem 1.25rem 2rem; }
173+
.hero h1 { font-size: 1.35rem; }
174+
.main { padding: 1.5rem 1.25rem; }
175+
.grid { grid-template-columns: 1fr; }
176+
}
177+
</style>
178+
</head>
179+
<body>
180+
181+
<header class="hero">
182+
<div class="logo-row">
183+
<img src="https://www.python.org/static/img/python-logo.png" alt="Python" height="48">
184+
</div>
185+
<h1>Python <span>Infra Analytics</span></h1>
186+
<p>
187+
Public web analytics for Python Software Foundation infrastructure.
188+
</p>
189+
</header>
190+
191+
<main class="main">
192+
<div class="section-label">Public Dashboards</div>
193+
<div class="grid">
194+
195+
<a class="card" href="/python.org">
196+
<div class="card-icon">
197+
<svg viewBox="0 0 24 24"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
198+
</div>
199+
<div class="card-body">
200+
<div class="card-title">python.org</div>
201+
<div class="card-desc">Main website</div>
202+
</div>
203+
</a>
204+
205+
<a class="card" href="/docs.python.org">
206+
<div class="card-icon">
207+
<svg viewBox="0 0 24 24"><path d="M4 19.5A2.5 2.5 0 016.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z"/></svg>
208+
</div>
209+
<div class="card-body">
210+
<div class="card-title">docs.python.org</div>
211+
<div class="card-desc">Documentation</div>
212+
</div>
213+
</a>
214+
215+
<a class="card" href="/devguide.python.org">
216+
<div class="card-icon">
217+
<svg viewBox="0 0 24 24"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>
218+
</div>
219+
<div class="card-body">
220+
<div class="card-title">devguide.python.org</div>
221+
<div class="card-desc">Developer guide</div>
222+
</div>
223+
</a>
224+
225+
<a class="card" href="/peps.python.org">
226+
<div class="card-icon">
227+
<svg viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
228+
</div>
229+
<div class="card-body">
230+
<div class="card-title">peps.python.org</div>
231+
<div class="card-desc">Enhancement proposals</div>
232+
</div>
233+
</a>
234+
235+
<a class="card" href="/packaging.python.org">
236+
<div class="card-icon">
237+
<svg viewBox="0 0 24 24"><path d="M21 16V8a2 2 0 00-1-1.73l-7-4a2 2 0 00-2 0l-7 4A2 2 0 003 8v8a2 2 0 001 1.73l7 4a2 2 0 002 0l7-4A2 2 0 0021 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
238+
</div>
239+
<div class="card-body">
240+
<div class="card-title">packaging.python.org</div>
241+
<div class="card-desc">Packaging user guide</div>
242+
</div>
243+
</a>
244+
245+
</div>
246+
</main>
247+
248+
<footer class="footer">
249+
<a href="https://www.python.org/psf/">Python Software Foundation</a>
250+
&nbsp;&middot;&nbsp;
251+
<a href="https://plausible.io">Powered by Plausible</a>
252+
</footer>
253+
254+
</body>
255+
</html>

0 commit comments

Comments
 (0)