tangled
alpha
login
or
join now
fruno.win
/
webbed-site
0
fork
atom
My personal website
0
fork
atom
overview
issues
pulls
pipelines
Revamp prompt
fruno.win
2 months ago
1f222985
0a7146ed
verified
This commit was signed with the committer's
known signature
.
fruno.win
SSH Key Fingerprint:
SHA256:5b6v+Iyponbm0lKHzwf2Aox/KTUzgno4BrnS3CYd6ys=
1/1
publish.yaml
success
26s
+84
-116
4 changed files
expand all
collapse all
unified
split
assets
style.css
src
blog.gleam
feed.gleam
page.gleam
+47
-88
assets/style.css
···
177
177
}
178
178
}
179
179
180
180
+
ul {
181
181
+
display: flex;
182
182
+
list-style-type: none;
183
183
+
margin: 0;
184
184
+
padding: 0;
185
185
+
186
186
+
a {
187
187
+
border-radius: var(--s-3);
188
188
+
color: var(--color-fg);
189
189
+
190
190
+
&:visited {
191
191
+
color: inherit;
192
192
+
}
193
193
+
}
194
194
+
}
195
195
+
180
196
#prompt-left .prompt-rounded-left {
181
197
background: var(--color-primary);
182
198
}
183
199
184
200
#prompt-left {
185
201
display: flex;
186
186
-
color: var(--color-bg);
202
202
+
max-width: 60%;
187
203
188
204
#prompt-user {
189
205
display: flex;
···
202
218
#prompt-dir {
203
219
display: flex;
204
220
background: var(--color-secondary);
221
221
+
overflow: hidden;
222
222
+
white-space: nowrap;
223
223
+
224
224
+
li {
225
225
+
margin: 0 var(--s-4);
226
226
+
227
227
+
&:last-child {
228
228
+
overflow: hidden;
229
229
+
text-overflow: ellipsis;
230
230
+
}
231
231
+
}
232
232
+
233
233
+
li, a { color: var(--color-bg) }
205
234
206
235
& + .prompt-pointed-right {
207
236
background: linear-gradient(90deg, var(--color-secondary) 25%, var(--color-bg) 0 100%);
···
258
287
}
259
288
260
289
#nav {
261
261
-
view-transition-name: nav;
262
262
-
flex-grow: 100;
263
263
-
display: flex;
264
264
-
265
290
ul {
266
266
-
display: flex;
267
267
-
list-style-type: none;
268
268
-
margin: 0;
269
269
-
padding: 0;
270
291
gap: 1ch;
271
271
-
272
272
-
a {
273
273
-
padding: 0 1ch;
274
274
-
border-radius: var(--s-3);
275
275
-
color: var(--color-fg);
292
292
+
}
293
293
+
294
294
+
a {
295
295
+
padding: 0 1ch;
296
296
+
text-decoration: none;
276
297
277
277
-
&:visited {
278
278
-
color: inherit;
279
279
-
}
298
298
+
&:hover {
299
299
+
color: var(--color-bg);
300
300
+
background: var(--color-fg);
301
301
+
}
302
302
+
}
280
303
281
281
-
/*
282
282
-
* Pseudo background element we can animate during page transitions
283
283
-
*/
284
284
-
&.active::before {
285
285
-
view-transition-name: nav-active-bg;
286
286
-
border-radius: var(--s-3);
287
287
-
content: "";
288
288
-
position: absolute;
289
289
-
top: 0;
290
290
-
left: 0;
291
291
-
height: 100%;
292
292
-
width: 100%;
293
293
-
z-index: 50;
294
294
-
background: var(--color-fg);
295
295
-
}
296
296
-
297
297
-
&.active {
298
298
-
position: relative;
299
299
-
color: var(--color-bg);
300
300
-
background: var(--color-fg);
301
301
-
}
302
302
-
303
303
-
span {
304
304
-
position: relative;
305
305
-
z-index: 100;
306
306
-
}
307
307
-
308
308
-
&:hover {
309
309
-
color: var(--color-bg);
310
310
-
background: var(--color-fg);
311
311
-
}
312
312
-
}
313
313
-
};
304
304
+
flex-grow: 100;
305
305
+
display: flex;
314
306
}
315
307
316
308
.cursor {
···
330
322
331
323
/* I wanted to avoid breakpoints, but I can't figure out a way around this one */
332
324
@media (max-width: 700px) {
325
325
+
#prompt-right { display: none !important }
326
326
+
#prompt-left { max-width: 100% !important }
327
327
+
333
328
main { padding-bottom: var(--s3) }
334
329
335
330
#navbar {
···
353
348
}
354
349
}
355
350
356
356
-
@media (max-width: 380px) {
357
357
-
#prompt-right { display: none !important }
351
351
+
@keyframes blink {
352
352
+
50% { visibility: hidden }
358
353
}
359
354
360
355
@view-transition {
361
356
navigation: auto;
362
357
}
363
363
-
364
364
-
@keyframes blink {
365
365
-
50% { visibility: hidden }
366
366
-
}
367
367
-
368
368
-
@keyframes slide-out-up {
369
369
-
from { transform: translateY(0) }
370
370
-
to { transform: translateY(min(-100vh, -100%)) }
371
371
-
}
372
372
-
373
373
-
@keyframes slide-in-up {
374
374
-
from { transform: translateY(100vh) }
375
375
-
to { transform: translateY(0) }
376
376
-
}
377
377
-
378
378
-
::view-transition-old(main-content) {
379
379
-
animation: 80ms ease-in both slide-out-up;
380
380
-
}
381
381
-
382
382
-
::view-transition-new(main-content) {
383
383
-
animation: 80ms ease-in both slide-in-up;
384
384
-
/* Wait for slide-out to complete before sliding in */
385
385
-
animation-delay: 80ms;
386
386
-
}
387
387
-
388
388
-
::view-transition-group(navbar) {
389
389
-
z-index: 10;
390
390
-
}
391
391
-
392
392
-
::view-transition-group(nav-active-bg) {
393
393
-
z-index: 50;
394
394
-
}
395
395
-
396
396
-
::view-transition-group(nav) {
397
397
-
z-index: 100;
398
398
-
}
+1
-1
src/blog.gleam
···
81
81
True -> {
82
82
let item =
83
83
html.li([], [
84
84
-
html.a([attribute.href("/blog/" <> post.slug)], [
84
84
+
html.a([attribute.href("/blog/" <> post.slug), attribute.style("view-transition-name", "nav-blog-post")], [
85
85
html.text(post.slug),
86
86
html.text(".djot"),
87
87
]),
+1
-1
src/feed.gleam
···
45
45
46
46
atomb.Feed(
47
47
id: id(feed_uuid()),
48
48
-
title: "fruno.win",
48
48
+
title: "fruno's blog",
49
49
updated:,
50
50
subtitle: Some(atomb.TextContent(
51
51
atomb.Text,
+35
-26
src/page.gleam
···
23
23
24
24
pub fn route(page: Page) {
25
25
case page {
26
26
-
Index -> "/"
26
26
+
Index -> "/index"
27
27
Blog -> "/blog/"
28
28
Dots -> "/dots"
29
29
BlogPost(post) -> "/blog/" <> post.slug
···
32
32
33
33
pub fn title(page: Page) {
34
34
case page {
35
35
-
Index -> "/index"
36
36
-
Blog -> "/blog/"
37
37
-
Dots -> "/.dots"
35
35
+
Index -> "webbed site"
36
36
+
Blog -> "blog"
37
37
+
Dots -> ".dots"
38
38
BlogPost(post) -> post.title
39
39
}
40
40
}
41
41
42
42
+
fn nav_id(page: Page) {
43
43
+
"nav-"
44
44
+
<> case page {
45
45
+
Index -> "index"
46
46
+
Blog -> "blog"
47
47
+
Dots -> "dots"
48
48
+
BlogPost(_) -> "blog-post"
49
49
+
}
50
50
+
}
51
51
+
42
52
pub type SiteInfo {
43
53
SiteInfo(posts: List(blog.Post), meta: Context)
44
54
}
···
51
61
attribute.name("viewport"),
52
62
attribute.content("width=device-width, initial-scale=1.0"),
53
63
]),
54
54
-
html.title([], "fruno | " <> title(page)),
64
64
+
html.title([], title(page) <> " | fruno"),
55
65
preload_font("InclusiveSans"),
56
66
preload_font("InclusiveSans-Italic"),
57
67
preload_font("Myna"),
···
100
110
}
101
111
102
112
fn navbar(page: Page, meta: Context) -> Element(msg) {
113
113
+
let #(breadcrumbs, links) = case page {
114
114
+
Index -> #([Index], [Blog, Dots])
115
115
+
Blog -> #([Index, Blog], [])
116
116
+
Dots -> #([Index, Dots], [])
117
117
+
BlogPost(_) -> #([Index, Blog, page], [])
118
118
+
}
119
119
+
103
120
html.nav([attribute.id("navbar")], [
104
104
-
prompt_left(),
105
105
-
nav(page),
121
121
+
prompt_left(breadcrumbs),
122
122
+
nav(links),
106
123
prompt_right(meta),
107
124
])
108
125
}
109
126
110
110
-
fn prompt_left() -> Element(msg) {
127
127
+
fn prompt_left(breadcrumbs: List(Page)) -> Element(msg) {
111
128
html.div([attribute.id("prompt-left")], [
112
129
html.div([attribute.id("prompt-user")], [
113
130
html.text("fruno"),
114
131
]),
115
132
html.div([attribute.class("prompt-pointed-right")], [html.div([], [])]),
116
116
-
html.div([attribute.id("prompt-dir")], [
117
117
-
html.text("~/webbed_site"),
133
133
+
html.ul([attribute.id("prompt-dir")], [
134
134
+
html.text("~"),
135
135
+
..list.flat_map(breadcrumbs, fn(page) { [html.text("/"), nav_link(page)] })
118
136
]),
119
137
html.div([attribute.class("prompt-pointed-right")], [html.div([], [])]),
120
138
])
121
139
}
122
140
123
123
-
fn nav(page: Page) -> Element(msg) {
141
141
+
fn nav(links: List(Page)) -> Element(msg) {
124
142
html.div([attribute.id("nav")], [
125
143
html.span([attribute.id("nav-chevron")], [html.text(">")]),
126
126
-
html.span([], [html.text("/")]),
127
144
html.span([attribute.class("cursor")], []),
128
128
-
html.ul([], [
129
129
-
nav_link(page, Index),
130
130
-
nav_link(page, Blog),
131
131
-
nav_link(page, Dots),
132
132
-
]),
145
145
+
html.ul([], list.map(links, nav_link)),
133
146
])
134
147
}
135
148
136
136
-
fn nav_link(active: Page, link: Page) {
137
137
-
let is_active = case active, link {
138
138
-
BlogPost(_), Blog -> True
139
139
-
_, _ if link == active -> True
140
140
-
_, _ -> False
141
141
-
}
142
142
-
149
149
+
fn nav_link(link: Page) {
143
150
html.li([], [
144
151
html.a(
145
152
[
146
153
attribute.href(route(link)),
147
147
-
attribute.classes([#("active", is_active)]),
154
154
+
attribute.style("view-transition-name", nav_id(link)),
155
155
+
],
156
156
+
[
157
157
+
html.text(title(link)),
148
158
],
149
149
-
[html.span([], [html.text(title(link))])],
150
159
),
151
160
])
152
161
}