Self-hostable website analytics on Django: a straightforward collector API, dashboards, a world map, and PDF reports.
analyticsdjangodockerhandcodedpythonself-hostedsqliteviteweb-analytics
1@use "../../../analytics/static_src/styles/variables" as *;
2
3// ── Home hero ──
4
5.hero {
6 position: relative;
7 background: #090806;
8 border-bottom: 1px solid rgba(107, 158, 120, 0.08);
9 padding: 4rem 0 4rem;
10
11 .hero-eyebrow {
12 display: inline-flex;
13 align-items: center;
14 gap: 0.55rem;
15 font-family: $font-family-monospace;
16 font-size: 0.72rem;
17 font-weight: 600;
18 letter-spacing: 0.12em;
19 text-transform: uppercase;
20 color: rgba(201, 168, 76, 0.85);
21 background: rgba(201, 168, 76, 0.06);
22 border: 1px solid $amber-border;
23 padding: 0.35rem 0.75rem;
24 border-radius: 999px;
25
26 .eyebrow-dot {
27 width: 6px; height: 6px; border-radius: 50%;
28 background: $green;
29 }
30 }
31
32 .hero-title {
33 font-size: clamp(2rem, 5vw, 3.2rem);
34 font-weight: 700;
35 line-height: 1.1;
36 color: $white;
37 letter-spacing: -0.01em;
38 margin-top: 1.5rem;
39
40 .accent { color: $green-bright; }
41 }
42
43 .hero-sub {
44 color: #a09890;
45 font-size: 1rem;
46 line-height: 1.7;
47 margin-top: 1.25rem;
48 max-width: 620px;
49 }
50
51 .hero-ctas {
52 display: flex;
53 gap: 0.75rem;
54 flex-wrap: wrap;
55 margin-top: 1.75rem;
56
57 .btn {
58 font-size: 0.82rem;
59 letter-spacing: 0.04em;
60 padding: 0.6rem 1.1rem;
61 }
62 }
63}
64
65// ── Feature tiles ──
66
67.feature {
68 background: #13120e;
69 border: 1px solid rgba(107, 158, 120, 0.08);
70 border-radius: $border-radius;
71 padding: 1.5rem;
72 height: 100%;
73 transition: border-color 250ms ease;
74
75 &:hover { border-color: rgba(107, 158, 120, 0.22); }
76
77 .feature-label {
78 font-family: $font-family-monospace;
79 font-size: 0.68rem;
80 font-weight: 600;
81 letter-spacing: 0.12em;
82 text-transform: uppercase;
83 color: rgba(201, 168, 76, 0.75);
84 }
85
86 .feature-title {
87 color: $white;
88 font-size: 1.05rem;
89 font-weight: 600;
90 margin-top: 0.5rem;
91 }
92
93 .feature-desc {
94 color: #a09890;
95 font-size: 0.88rem;
96 line-height: 1.65;
97 margin-top: 0.6rem;
98 margin-bottom: 0;
99 }
100}
101
102// ── Stat strip ──
103
104.stat-strip {
105 background: #0e0d0a;
106 border-top: 1px solid rgba(107, 158, 120, 0.06);
107 border-bottom: 1px solid rgba(107, 158, 120, 0.06);
108 padding: 1.5rem 0;
109
110 .stat { text-align: center; padding: 0 1rem; }
111
112 .stat-label {
113 font-family: $font-family-monospace;
114 font-size: 0.66rem;
115 font-weight: 600;
116 letter-spacing: 0.12em;
117 text-transform: uppercase;
118 color: #665f56;
119 }
120
121 .stat-value {
122 font-size: 1.75rem;
123 font-weight: 700;
124 color: $green-bright;
125 letter-spacing: -0.01em;
126 line-height: 1.2;
127 margin-top: 0.2rem;
128 }
129}
130
131// ── Changelog ──
132
133.changelog-entry {
134 display: grid;
135 grid-template-columns: 140px 1fr;
136 gap: 1.5rem;
137 padding: 1rem 0;
138 border-bottom: 1px solid rgba(107, 158, 120, 0.06);
139
140 @media (max-width: 575px) {
141 grid-template-columns: 1fr;
142 gap: 0.4rem;
143 }
144
145 .changelog-date {
146 font-family: $font-family-monospace;
147 font-size: 0.78rem;
148 color: rgba(201, 168, 76, 0.75);
149 letter-spacing: 0.04em;
150 }
151
152 ul { margin: 0; padding-left: 1.1rem; color: $gray-200; font-size: 0.9rem; }
153 li { margin-bottom: 0.3rem; }
154
155 code {
156 background: rgba(107, 158, 120, 0.08);
157 color: $green-bright;
158 padding: 0.05rem 0.35rem;
159 border-radius: 2px;
160 font-size: 0.85em;
161 }
162}
163
164// ── Docs (accordion + copy blocks) ──
165
166.docs-lead {
167 color: #a09890;
168 font-size: 0.95rem;
169 line-height: 1.75;
170 max-width: 720px;
171}
172
173.docs-accordion {
174 .accordion-item {
175 background: #13120e;
176 border: 1px solid rgba(107, 158, 120, 0.12);
177 margin-bottom: 0.5rem;
178 border-radius: $border-radius !important;
179 overflow: hidden;
180 }
181
182 .accordion-button {
183 background: #13120e;
184 font-family: $font-family-monospace;
185 font-size: 0.85rem;
186 letter-spacing: 0.02em;
187 color: $gray-200;
188
189 &::before {
190 content: '$ ';
191 color: $amber;
192 margin-right: 0.4rem;
193 }
194
195 &:not(.collapsed) {
196 background: rgba(107, 158, 120, 0.06);
197 color: $green-bright;
198 box-shadow: inset 0 -1px 0 rgba(107, 158, 120, 0.12);
199 }
200
201 &:focus {
202 box-shadow: 0 0 0 2px rgba(107, 158, 120, 0.15);
203 }
204 }
205}