Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
108 lines (94 loc) · 5.12 KB
/
Copy pathindex.html
File metadata and controls
108 lines (94 loc) · 5.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Lens</title>
<!--
Startup shell.
The renderer bundle has to download, parse and mount before React can draw
anything, and until then #root is empty — which read as the window being
broken for a second or two on every launch. The list already has a
skeleton, but it only appears once React is running, which is after the
part that looked blank.
So the same skeleton is painted here, in markup the browser can put on
screen before any of the app's JavaScript runs. React replaces it on
mount, and because the geometry matches what the real skeleton draws,
there is nothing to see at the handover.
The styles are inline on purpose: an external stylesheet is one more
round trip during exactly the window this is meant to cover. The two
scripts are small local files instead, because the packaged app's CSP
refuses inline script.
-->
<!-- A file rather than inline: the packaged app's CSP is script-src 'self',
which refuses inline script. A classic script still blocks parsing,
so it runs before the body is painted. -->
<script src="/boot-theme.js"></script>
<style>
:root { --boot-bg: #f1f1f4; --boot-surface: #fff; --boot-line: #eeeef0; --boot-fill: #e9e9ec; }
[data-theme='dark'] { --boot-bg: #131316; --boot-surface: #1b1b1f; --boot-line: #26262b; --boot-fill: #222227; }
html, body { height: 100%; margin: 0; background: var(--boot-bg); }
#boot {
position: fixed;
inset: 0;
display: flex;
background: var(--boot-bg);
/* Above nothing in particular — it is removed rather than layered
over, so it only needs to sit on its own. */
z-index: 1;
}
/* Fades out rather than vanishing, so the handover to React reads as the
same surface settling instead of a cut. */
#boot.boot-done { opacity: 0; transition: opacity .18s ease-out; pointer-events: none; }
/* Sidebar + list columns, at the widths the app itself uses so nothing
shifts when the real UI arrives. The list column follows the same
stored width the resizer writes. */
.boot-nav { width: var(--boot-nav-w, 220px); flex: 0 0 auto; border-right: 1px solid var(--boot-line); }
.boot-list { width: var(--boot-list-w, 420px); flex: 0 0 auto; border-right: 1px solid var(--boot-line); padding: 8px 12px; }
.boot-detail { flex: 1 1 auto; }
.boot-row {
height: 80px;
margin-bottom: 8px;
border: 1px solid var(--boot-line);
border-radius: 13px;
background: var(--boot-surface);
padding: 12px 16px;
box-sizing: border-box;
}
.boot-bar { height: 10px; border-radius: 5px; background: var(--boot-fill); }
/* One shared pulse. Rows are offset so the column breathes rather than
blinking in unison, which is the difference between "loading" and
"flickering". */
@keyframes boot-pulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
.boot-row { animation: boot-pulse 1.6s ease-in-out infinite; }
.boot-row:nth-child(2) { animation-delay: .08s; }
.boot-row:nth-child(3) { animation-delay: .16s; }
.boot-row:nth-child(4) { animation-delay: .24s; }
.boot-row:nth-child(5) { animation-delay: .32s; }
.boot-row:nth-child(6) { animation-delay: .40s; }
.boot-row:nth-child(7) { animation-delay: .48s; }
@media (prefers-reduced-motion: reduce) {
.boot-row { animation: none; opacity: .7; }
#boot.boot-done { transition: none; }
}
</style>
</head>
<body>
<div id="root"></div>
<div id="boot" aria-hidden="true">
<div class="boot-nav"></div>
<div class="boot-list" id="boot-list">
<div class="boot-row"><div class="boot-bar" style="width:62%"></div><div class="boot-bar" style="width:38%;margin-top:12px;height:8px"></div></div>
<div class="boot-row"><div class="boot-bar" style="width:74%"></div><div class="boot-bar" style="width:30%;margin-top:12px;height:8px"></div></div>
<div class="boot-row"><div class="boot-bar" style="width:55%"></div><div class="boot-bar" style="width:44%;margin-top:12px;height:8px"></div></div>
<div class="boot-row"><div class="boot-bar" style="width:68%"></div><div class="boot-bar" style="width:34%;margin-top:12px;height:8px"></div></div>
<div class="boot-row"><div class="boot-bar" style="width:58%"></div><div class="boot-bar" style="width:41%;margin-top:12px;height:8px"></div></div>
<div class="boot-row"><div class="boot-bar" style="width:71%"></div><div class="boot-bar" style="width:28%;margin-top:12px;height:8px"></div></div>
<div class="boot-row"><div class="boot-bar" style="width:64%"></div><div class="boot-bar" style="width:36%;margin-top:12px;height:8px"></div></div>
</div>
<div class="boot-detail"></div>
</div>
<script src="/boot-shell.js"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>