aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclarkzjw <[email protected]>2023-02-28 21:54:53 -0800
committerclarkzjw <[email protected]>2023-02-28 22:34:04 -0800
commite0a69eb031316ae145f1c40319bceb8ec520ad44 (patch)
tree6f436581b4c29b61ba4d82e09a7eecdc4f73fb24
parent6a77e4e0494e14fdbe1cb7847d2880132714d568 (diff)
downloadphoto-e0a69eb031316ae145f1c40319bceb8ec520ad44.tar.gz
init project structure
-rw-r--r--.well-known/webfinger0
-rw-r--r--404.html20
-rw-r--r--CNAME1
-rw-r--r--Gemfile4
-rw-r--r--Gemfile.lock260
-rw-r--r--_config.yml10
-rw-r--r--_data/photos.json0
-rw-r--r--_includes/line.html3
-rw-r--r--_layouts/default.html37
-rw-r--r--_layouts/redirect.html1
-rw-r--r--assets/icon.pngbin0 -> 25823 bytes
-rw-r--r--assets/new.scss679
-rw-r--r--assets/site.js32
-rw-r--r--assets/syntax.css225
-rw-r--r--assets/valid-rss-rogers.pngbin0 -> 3712 bytes
-rw-r--r--feeds/photos.xml31
-rw-r--r--index.html73
-rw-r--r--package.json3
-rwxr-xr-xstart2
19 files changed, 1381 insertions, 0 deletions
diff --git a/.well-known/webfinger b/.well-known/webfinger
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/.well-known/webfinger
diff --git a/404.html b/404.html
new file mode 100644
index 0000000..3b25d38
--- /dev/null
+++ b/404.html
@@ -0,0 +1,20 @@
1<!doctype html>
2<html>
3 <head>
4 <meta content="width=device-width, initial-scale=1.0, user-scalable=no" name="viewport">
5 <meta content="text/html; charset=utf-8" http-equiv="content-type">
6 <meta content="@clarkzjw" property="og:title">
7 <meta content="https://pixel.jinwei.me" property="og:url">
8 <title>404</title>
9 </head>
10 <body>
11 <main>
12 <h1 class="h1">
13 404<span class="blink">|</span>
14 </h1>
15 <a href="/">&leftarrow;</a>
16 </main>
17 <link href="/assets/new.css" rel="stylesheet" type="text/css">
18 <link href="https://fonts.googleapis.com/css?family=Cousine&display=swap" rel="stylesheet">
19 </body>
20</html>
diff --git a/CNAME b/CNAME
new file mode 100644
index 0000000..fbffb78
--- /dev/null
+++ b/CNAME
@@ -0,0 +1 @@
pixel.jinwei.me
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..d770067
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,4 @@
1source 'https://rubygems.org'
2
3gem "webrick"
4gem 'github-pages', group: :jekyll_plugins
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..a4ee6d5
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,260 @@
1GEM
2 remote: https://rubygems.org/
3 specs:
4 activesupport (7.0.4.2)
5 concurrent-ruby (~> 1.0, >= 1.0.2)
6 i18n (>= 1.6, < 2)
7 minitest (>= 5.1)
8 tzinfo (~> 2.0)
9 addressable (2.8.1)
10 public_suffix (>= 2.0.2, < 6.0)
11 coffee-script (2.4.1)
12 coffee-script-source
13 execjs
14 coffee-script-source (1.11.1)
15 colorator (1.1.0)
16 commonmarker (0.23.8)
17 concurrent-ruby (1.2.2)
18 dnsruby (1.61.9)
19 simpleidn (~> 0.1)
20 em-websocket (0.5.3)
21 eventmachine (>= 0.12.9)
22 http_parser.rb (~> 0)
23 ethon (0.16.0)
24 ffi (>= 1.15.0)
25 eventmachine (1.2.7)
26 execjs (2.8.1)
27 faraday (2.7.4)
28 faraday-net_http (>= 2.0, < 3.1)
29 ruby2_keywords (>= 0.0.4)
30 faraday-net_http (3.0.2)
31 ffi (1.15.5)
32 forwardable-extended (2.6.0)
33 gemoji (3.0.1)
34 github-pages (228)
35 github-pages-health-check (= 1.17.9)
36 jekyll (= 3.9.3)
37 jekyll-avatar (= 0.7.0)
38 jekyll-coffeescript (= 1.1.1)
39 jekyll-commonmark-ghpages (= 0.4.0)
40 jekyll-default-layout (= 0.1.4)
41 jekyll-feed (= 0.15.1)
42 jekyll-gist (= 1.5.0)
43 jekyll-github-metadata (= 2.13.0)
44 jekyll-include-cache (= 0.2.1)
45 jekyll-mentions (= 1.6.0)
46 jekyll-optional-front-matter (= 0.3.2)
47 jekyll-paginate (= 1.1.0)
48 jekyll-readme-index (= 0.3.0)
49 jekyll-redirect-from (= 0.16.0)
50 jekyll-relative-links (= 0.6.1)
51 jekyll-remote-theme (= 0.4.3)
52 jekyll-sass-converter (= 1.5.2)
53 jekyll-seo-tag (= 2.8.0)
54 jekyll-sitemap (= 1.4.0)
55 jekyll-swiss (= 1.0.0)
56 jekyll-theme-architect (= 0.2.0)
57 jekyll-theme-cayman (= 0.2.0)
58 jekyll-theme-dinky (= 0.2.0)
59 jekyll-theme-hacker (= 0.2.0)
60 jekyll-theme-leap-day (= 0.2.0)
61 jekyll-theme-merlot (= 0.2.0)
62 jekyll-theme-midnight (= 0.2.0)
63 jekyll-theme-minimal (= 0.2.0)
64 jekyll-theme-modernist (= 0.2.0)
65 jekyll-theme-primer (= 0.6.0)
66 jekyll-theme-slate (= 0.2.0)
67 jekyll-theme-tactile (= 0.2.0)
68 jekyll-theme-time-machine (= 0.2.0)
69 jekyll-titles-from-headings (= 0.5.3)
70 jemoji (= 0.12.0)
71 kramdown (= 2.3.2)
72 kramdown-parser-gfm (= 1.1.0)
73 liquid (= 4.0.4)
74 mercenary (~> 0.3)
75 minima (= 2.5.1)
76 nokogiri (>= 1.13.6, < 2.0)
77 rouge (= 3.26.0)
78 terminal-table (~> 1.4)
79 github-pages-health-check (1.17.9)
80 addressable (~> 2.3)
81 dnsruby (~> 1.60)
82 octokit (~> 4.0)
83 public_suffix (>= 3.0, < 5.0)
84 typhoeus (~> 1.3)
85 html-pipeline (2.14.3)
86 activesupport (>= 2)
87 nokogiri (>= 1.4)
88 http_parser.rb (0.8.0)
89 i18n (1.12.0)
90 concurrent-ruby (~> 1.0)
91 jekyll (3.9.3)
92 addressable (~> 2.4)
93 colorator (~> 1.0)
94 em-websocket (~> 0.5)
95 i18n (>= 0.7, < 2)
96 jekyll-sass-converter (~> 1.0)
97 jekyll-watch (~> 2.0)
98 kramdown (>= 1.17, < 3)
99 liquid (~> 4.0)
100 mercenary (~> 0.3.3)
101 pathutil (~> 0.9)
102 rouge (>= 1.7, < 4)
103 safe_yaml (~> 1.0)
104 jekyll-avatar (0.7.0)
105 jekyll (>= 3.0, < 5.0)
106 jekyll-coffeescript (1.1.1)
107 coffee-script (~> 2.2)
108 coffee-script-source (~> 1.11.1)
109 jekyll-commonmark (1.4.0)
110 commonmarker (~> 0.22)
111 jekyll-commonmark-ghpages (0.4.0)
112 commonmarker (~> 0.23.7)
113 jekyll (~> 3.9.0)
114 jekyll-commonmark (~> 1.4.0)
115 rouge (>= 2.0, < 5.0)
116 jekyll-default-layout (0.1.4)
117 jekyll (~> 3.0)
118 jekyll-feed (0.15.1)
119 jekyll (>= 3.7, < 5.0)
120 jekyll-gist (1.5.0)
121 octokit (~> 4.2)
122 jekyll-github-metadata (2.13.0)
123 jekyll (>= 3.4, < 5.0)
124 octokit (~> 4.0, != 4.4.0)
125 jekyll-include-cache (0.2.1)
126 jekyll (>= 3.7, < 5.0)
127 jekyll-mentions (1.6.0)
128 html-pipeline (~> 2.3)
129 jekyll (>= 3.7, < 5.0)
130 jekyll-optional-front-matter (0.3.2)
131 jekyll (>= 3.0, < 5.0)
132 jekyll-paginate (1.1.0)
133 jekyll-readme-index (0.3.0)
134 jekyll (>= 3.0, < 5.0)
135 jekyll-redirect-from (0.16.0)
136 jekyll (>= 3.3, < 5.0)
137 jekyll-relative-links (0.6.1)
138 jekyll (>= 3.3, < 5.0)
139 jekyll-remote-theme (0.4.3)
140 addressable (~> 2.0)
141 jekyll (>= 3.5, < 5.0)
142 jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
143 rubyzip (>= 1.3.0, < 3.0)
144 jekyll-sass-converter (1.5.2)
145 sass (~> 3.4)
146 jekyll-seo-tag (2.8.0)
147 jekyll (>= 3.8, < 5.0)
148 jekyll-sitemap (1.4.0)
149 jekyll (>= 3.7, < 5.0)
150 jekyll-swiss (1.0.0)
151 jekyll-theme-architect (0.2.0)
152 jekyll (> 3.5, < 5.0)
153 jekyll-seo-tag (~> 2.0)
154 jekyll-theme-cayman (0.2.0)
155 jekyll (> 3.5, < 5.0)
156 jekyll-seo-tag (~> 2.0)
157 jekyll-theme-dinky (0.2.0)
158 jekyll (> 3.5, < 5.0)
159 jekyll-seo-tag (~> 2.0)
160 jekyll-theme-hacker (0.2.0)
161 jekyll (> 3.5, < 5.0)
162 jekyll-seo-tag (~> 2.0)
163 jekyll-theme-leap-day (0.2.0)
164 jekyll (> 3.5, < 5.0)
165 jekyll-seo-tag (~> 2.0)
166 jekyll-theme-merlot (0.2.0)
167 jekyll (> 3.5, < 5.0)
168 jekyll-seo-tag (~> 2.0)
169 jekyll-theme-midnight (0.2.0)
170 jekyll (> 3.5, < 5.0)
171 jekyll-seo-tag (~> 2.0)
172 jekyll-theme-minimal (0.2.0)
173 jekyll (> 3.5, < 5.0)
174 jekyll-seo-tag (~> 2.0)
175 jekyll-theme-modernist (0.2.0)
176 jekyll (> 3.5, < 5.0)
177 jekyll-seo-tag (~> 2.0)
178 jekyll-theme-primer (0.6.0)
179 jekyll (> 3.5, < 5.0)
180 jekyll-github-metadata (~> 2.9)
181 jekyll-seo-tag (~> 2.0)
182 jekyll-theme-slate (0.2.0)
183 jekyll (> 3.5, < 5.0)
184 jekyll-seo-tag (~> 2.0)
185 jekyll-theme-tactile (0.2.0)
186 jekyll (> 3.5, < 5.0)
187 jekyll-seo-tag (~> 2.0)
188 jekyll-theme-time-machine (0.2.0)
189 jekyll (> 3.5, < 5.0)
190 jekyll-seo-tag (~> 2.0)
191 jekyll-titles-from-headings (0.5.3)
192 jekyll (>= 3.3, < 5.0)
193 jekyll-watch (2.2.1)
194 listen (~> 3.0)
195 jemoji (0.12.0)
196 gemoji (~> 3.0)
197 html-pipeline (~> 2.2)
198 jekyll (>= 3.0, < 5.0)
199 kramdown (2.3.2)
200 rexml
201 kramdown-parser-gfm (1.1.0)
202 kramdown (~> 2.0)
203 liquid (4.0.4)
204 listen (3.8.0)
205 rb-fsevent (~> 0.10, >= 0.10.3)
206 rb-inotify (~> 0.9, >= 0.9.10)
207 mercenary (0.3.6)
208 minima (2.5.1)
209 jekyll (>= 3.5, < 5.0)
210 jekyll-feed (~> 0.9)
211 jekyll-seo-tag (~> 2.1)
212 minitest (5.17.0)
213 nokogiri (1.14.2-x86_64-linux)
214 racc (~> 1.4)
215 octokit (4.25.1)
216 faraday (>= 1, < 3)
217 sawyer (~> 0.9)
218 pathutil (0.16.2)
219 forwardable-extended (~> 2.6)
220 public_suffix (4.0.7)
221 racc (1.6.2)
222 rb-fsevent (0.11.2)
223 rb-inotify (0.10.1)
224 ffi (~> 1.0)
225 rexml (3.2.5)
226 rouge (3.26.0)
227 ruby2_keywords (0.0.5)
228 rubyzip (2.3.2)
229 safe_yaml (1.0.5)
230 sass (3.7.4)
231 sass-listen (~> 4.0.0)
232 sass-listen (4.0.0)
233 rb-fsevent (~> 0.9, >= 0.9.4)
234 rb-inotify (~> 0.9, >= 0.9.7)
235 sawyer (0.9.2)
236 addressable (>= 2.3.5)
237 faraday (>= 0.17.3, < 3)
238 simpleidn (0.2.1)
239 unf (~> 0.1.4)
240 terminal-table (1.8.0)
241 unicode-display_width (~> 1.1, >= 1.1.1)
242 typhoeus (1.4.0)
243 ethon (>= 0.9.0)
244 tzinfo (2.0.6)
245 concurrent-ruby (~> 1.0)
246 unf (0.1.4)
247 unf_ext
248 unf_ext (0.0.8.2)
249 unicode-display_width (1.8.0)
250 webrick (1.8.1)
251
252PLATFORMS
253 x86_64-linux
254
255DEPENDENCIES
256 github-pages
257 webrick
258
259BUNDLED WITH
260 2.4.6
diff --git a/_config.yml b/_config.yml
new file mode 100644
index 0000000..345b52e
--- /dev/null
+++ b/_config.yml
@@ -0,0 +1,10 @@
1title: Clarkzjw
2description: Clarkzjw's Photo Blog
3url: https://pixel.jinwei.me
4permalink: /posts/:title
5timezone: America/Vancouver
6kramdown:
7 hard_wrap: true
8sass:
9 sass_dir: assets
10 style: :compressed
diff --git a/_data/photos.json b/_data/photos.json
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/_data/photos.json
diff --git a/_includes/line.html b/_includes/line.html
new file mode 100644
index 0000000..86b7116
--- /dev/null
+++ b/_includes/line.html
@@ -0,0 +1,3 @@
1<li class="js-line line" id="L{{ include.i }}">
2 <div>{{ include.content }}</div>
3</li>
diff --git a/_layouts/default.html b/_layouts/default.html
new file mode 100644
index 0000000..168424f
--- /dev/null
+++ b/_layouts/default.html
@@ -0,0 +1,37 @@
1<!doctype html>
2<html lang="en">
3 <head>
4 <meta content="width=device-width, initial-scale=1.0" name="viewport">
5 <meta content="text/html; charset=utf-8" http-equiv="content-type">
6 <link rel="icon" href="/assets/icon.png" type="image/png" sizes="24x24">
7 <link href="/assets/new.css" rel="stylesheet" type="text/css">
8 <meta content="summary" name="twitter:card">
9 <meta content="{{ site.title }}" name="twitter:title">
10 <title>Photos</title>
11 <meta content="{{ site.title }}" property="og:title">
12 <meta content="blog" property="og:type">
13 <meta content="{{ site.description }}" name="description">
14 <link href="https://fonts.googleapis.com/css2?family=Readex+Pro&display=swap" rel="stylesheet">
15
16 </head>
17 <body class="{% if page.root != true %}post-body{% endif %}" data-page-title="{{ page.title }}">
18 <header>
19 <h1 class="h1">
20 {{ page.title }}
21 </h1>
22 </header>
23 <main>
24 {{ content }}
25 </main>
26 <footer>
27 <hr class="hr">
28 {% capture label %}View source{% endcapture %}
29 Jinwei Zhao
30 (<a href="https://cgit.jinwei.me/clarkzjw/photo/">{{ label }}</a>)
31 </footer>
32
33 {% if page.root %}
34 <script defer type="module" src="/assets/site.js"></script>
35 {% endif %}
36 </body>
37</html>
diff --git a/_layouts/redirect.html b/_layouts/redirect.html
new file mode 100644
index 0000000..3e2238f
--- /dev/null
+++ b/_layouts/redirect.html
@@ -0,0 +1 @@
<meta http-equiv="refresh" content="0; url={{ page.redirect_to }}">
diff --git a/assets/icon.png b/assets/icon.png
new file mode 100644
index 0000000..f182cc1
--- /dev/null
+++ b/assets/icon.png
Binary files differ
diff --git a/assets/new.scss b/assets/new.scss
new file mode 100644
index 0000000..73c4ed8
--- /dev/null
+++ b/assets/new.scss
@@ -0,0 +1,679 @@
1---
2---
3
4:root {
5 --backgroundColor: #fdfdfd;
6 --textColor: #303030;
7 --secondaryTextColor: #404040;
8 --mutedTextColor: #707070;
9 --subtleBackgroundColor: #f5f5f5;
10 --heartedBackgroundColor: #ffe2e2;
11 --selectionBackgroundColor: #ffc;
12 --linkColor: #2357cd;
13 --borderColor: #ccc;
14 --hrColor: #888;
15 --activeColor: #74d274;
16 --langBackgroundColor: #eeeeee;
17 --langShadowColor: transparent;
18 --logoColor: #cccccc;
19 --photoBackground: #f4f4f4;
20}
21
22@media (prefers-color-scheme: dark) {
23 :root {
24 --backgroundColor: #151615;
25 --textColor: #dbdfdf;
26 --secondaryTextColor: #cfd5d5;
27 --mutedTextColor: #b4b6b8;
28 --subtleBackgroundColor: #3a3b3b;
29 --heartedBackgroundColor: #652222;
30 --selectionBackgroundColor: #19446b;
31 --linkColor: #6eb8ff;
32 --borderColor: #414141;
33 --hrColor: #888;
34 --activeColor: #74d274;
35 --langBackgroundColor: #2c2c2c;
36 --langShadowColor: #0b0c0b33;
37 --logoColor: #555555;
38 --photoBackground: #1a1a1a;
39 }
40}
41
42body {
43 background: var(--backgroundColor);
44 color: var(--textColor);
45 line-height: 1.7em;
46 padding: 0 2.5em;
47 margin: 0;
48 font-size: 18px;
49 word-wrap: break-word;
50}
51
52body, kbd {
53 font-family: system-ui, sans-serif;
54}
55
56a {
57 color: var(--linkColor);
58}
59
60::selection {
61 background: var(--selectionBackgroundColor);
62}
63
64header {
65 padding-top: 2.5em;
66}
67
68footer {
69 padding-bottom: 2.5em;
70}
71
72main {
73 padding-top: 1em;
74 padding-bottom: 3em;
75}
76
77header,
78main,
79footer {
80 max-width: 36em;
81 margin: auto;
82}
83
84h1, h2, h3, h4, h5, h6, .font {
85 font-family: 'Readex Pro', sans-serif;
86}
87
88.plain {
89 font-family: system-ui, sans-serif
90}
91
92h1, h2, h3, h4, h5, h6 {
93 margin: 1.4em 0 1em 0;
94 font-weight: normal;
95}
96
97.logo {
98 width: 2em;
99
100 path {
101 stroke: var(--logoColor);
102 }
103}
104
105.logo-container {
106 display: flex;
107 align-items: center;
108}
109
110.post-body {
111 .logo-container {
112 line-height: 1em;
113 color: var(--mutedTextColor);
114 }
115
116 .logo {
117 width: 1em;
118 margin-left: .8em;
119 margin-right: .4em;
120
121 path {
122 stroke: var(--mutedTextColor);
123 stroke-width: 22;
124 }
125 }
126
127 .h1 {
128 font-size: 1.5rem;
129 }
130}
131
132.h1 {
133 font-size: 1.2rem;
134 font-weight: normal;
135 margin-bottom: 0;
136}
137
138.text {
139 margin-right: .4rem;
140 font-size: inherit;
141 font-weight: normal;
142 display: inline-block;
143 margin-top: 0;
144}
145
146.terminal .line {
147 padding: 0;
148 margin-bottom: 1em;
149 line-height: 1.6em;
150}
151
152.terminal {
153 list-style: none;
154 padding-left: 0;
155
156 li {
157 padding: .1rem 0;
158 }
159
160 ul {
161 margin-top: 0.5rem;
162 }
163}
164
165.hr {
166 border: 0;
167 border-left: .7rem solid var(--textColor);
168 height: .7rem;
169 margin: 3rem 0;
170}
171
172.notes {
173 list-style: none;
174 margin: 0;
175 padding: 0;
176
177 .note {
178 border-bottom: 1px solid var(--borderColor);
179 padding-bottom: 3em;
180 margin-top: 3em;
181 }
182}
183
184.targeted {
185 color: var(--activeColor);
186 margin-right: .2em;
187 display: inline;
188}
189
190.note {
191 scroll-margin: 2em;
192
193 &:last-of-type {
194 border-bottom: 0;
195 }
196
197 .targeted {
198 display: none;
199 }
200
201 &:target .targeted {
202 display: inline;
203 }
204 p:first-child, blockquote:first-child { margin-top: 0; }
205 p:last-child, blockquote:last-child, img:last-child { margin-bottom: 0; }
206}
207
208.note-heading {
209 font-size: .8em;
210 line-height: 1;
211 font-weight: normal;
212 margin: 0;
213 color: var(--mutedTextColor);
214
215 a {
216 color: inherit;
217 text-decoration: none;
218 }
219}
220
221blockquote {
222 &::before {
223 content: '“';
224 font-size: 2rem;
225 position: absolute;
226 margin-left: -.5em;
227 color: var(--secondaryTextColor);
228 font-family: sans-serif;
229 }
230}
231
232img {
233 max-width: 100%;
234 margin: 1em 0;
235
236 &[width] {
237 margin: 0;
238 vertical-align: middle;
239 }
240}
241
242hr {
243 margin: 2em 0;
244 border: 0;
245 border-bottom: 1px solid var(--hrColor);
246}
247
248.pagination {
249 margin-top: 4em;
250}
251
252article {
253 font-family: system-ui, sans-serif;
254 font-size: 16px;
255}
256
257.smol {
258 font-size: .8em;
259 font-weight: normal;
260}
261
262.task-list-item-checkbox {
263 margin-right: .5em;
264 vertical-align: middle;
265}
266
267.entry-title {
268 margin: 0;
269}
270
271.entry {
272 margin-bottom: 3em;
273}
274
275.lang {
276 font-size: .8rem;
277 display: inline-flex;
278 margin-top: 2em;
279 white-space: nowrap;
280 box-shadow: 0 5px 15px var(--langShadowColor);
281
282 a[aria-current] {
283 color: var(--textColor);
284
285 &:before {
286 content: "●";
287 color: var(--activeColor);
288 }
289 }
290
291 a {
292 background-color: var(--langBackgroundColor);
293 border-color: var(--borderColor);
294 color: var(--mutedTextColor);
295 padding: 4px 16px;
296 margin-right: 1px;
297 text-decoration: none;
298
299 &:first-child {
300 border-top-left-radius: 6px;
301 border-bottom-left-radius: 6px;
302 }
303
304 &:last-child {
305 border-top-right-radius: 6px;
306 border-bottom-right-radius: 6px;
307 }
308
309 &:hover {
310 background: var(--langBackgroundColor);
311 }
312
313 &:focus {
314 z-index: 1;
315 }
316
317 &:before {
318 content: "○";
319 color: var(--borderColor);
320 padding-right: 10px;
321 }
322 }
323}
324
325.styled-link {
326 margin-left: .4rem;
327 font-size: .7em;
328}
329
330time {
331 font-size: .8em;
332 color: var(--mutedTextColor);
333}
334
335.desc {
336 color: var(--mutedTextColor);
337 font-size: 0.8em;
338}
339
340@keyframes flash {
341 0% {
342 opacity: 0;
343 }
344
345 50% {
346 opacity: 1;
347 }
348
349 100% {
350 opacity: 1;
351 }
352}
353
354.timestamp-colon {
355 animation-name: flash;
356 animation-duration: 2s;
357 animation-timing-function: step-end;
358 animation-iteration-count: infinite;
359}
360
361@media (prefers-reduced-motion: reduce) {
362 .timestamp-colon {
363 animation-name: none;
364 }
365}
366
367.offsetthis {
368 vertical-align: super;
369 font-size: .6em;
370}
371
372.photos {
373 display: flex;
374 gap: 1em;
375 flex-wrap: nowrap;
376 overflow: auto;
377 align-items: center;
378
379 .image-link {
380 flex-shrink: 0;
381 }
382
383 img {
384 background-color: var(--photoBackground);
385 }
386}
387
388figure {
389 margin: 1em 0 3em;
390
391 img {
392 margin: 0 auto;
393 max-height: calc(100vh - 6em);
394 background-color: var(--photoBackground);
395 display: block;
396 }
397
398 .image-link {
399 display: block;
400 width: fit-content;
401 margin: auto;
402 }
403
404 p {
405 margin-bottom: 0;
406 }
407}
408
409[data-page-title="Photos"] {
410 header, main, footer {
411 max-width: 100%;
412 }
413
414 input {
415 position: absolute;
416 left: -100px;
417
418 &:checked + label path {
419 fill: var(--activeColor);
420 }
421
422 &:focus + label {
423 outline: auto;
424 outline-color: var(--activeColor);
425 }
426 }
427
428 label {
429 top: -50px;
430 left: 100px;
431 padding: .5em;
432 cursor: pointer;
433 position: relative;
434 display: inline-flex;
435 }
436
437 label path {
438 fill: var(--logoColor);
439 }
440}
441
442.photos-wrapper {
443 &:focus { outline: none; }
444 scroll-behavior: smooth;
445 margin-top: -40px;
446 clear: both;
447 text-align: center;
448}
449
450.back-link {
451 text-decoration: none;
452 color: var(--textColor);
453 background-color: var(--langBackgroundColor);
454 width: 1.6em;
455 text-align: center;
456 line-height: 1.6em;
457 aspect-ratio: 1/1;
458 display: inline-block;
459 border-radius: 4em;
460}
461
462[value*="grid"]:checked ~ .photos-wrapper {
463 display: grid;
464 column-gap: 2.5em;
465 grid-template-columns: repeat(2, 1fr);
466 // https://caniuse.com/mdn-css_properties_grid-template-rows_masonry
467 grid-template-rows: masonry;
468
469 figure {
470 margin-bottom: 0;
471 }
472
473 img {
474 max-height: none;
475 height: auto;
476 }
477}
478
479[value="grid3fr"]:checked ~ .photos-wrapper {
480 grid-template-columns: repeat(3, 1fr);
481}
482
483[value="x-scroll"]:checked ~ .photos-wrapper {
484 display: flex;
485 overflow: auto;
486 gap: 1.5em;
487 scroll-snap-type: x mandatory;
488 scroll-snap-align: center;
489
490 figure {
491 scroll-snap-align: center;
492 margin-bottom: 0;
493 flex-shrink: 0;
494
495 &:has(.portrait) figcaption {
496 max-width: calc(100vh * 0.667 - 6em);
497 margin: auto;
498 }
499
500 &:has(.landscape) figcaption {
501 max-width: calc(100vw * 0.667 - 2em);
502 margin: auto;
503 }
504 }
505
506
507 img {
508 max-height: calc(100vh - 6em);
509 max-width: calc(100vw - 5em);
510 flex-shrink: 0;
511 }
512}
513
514figcaption {
515 padding: .5em 1em;
516
517 p {
518 margin: 0;
519 }
520}
521
522// This ensures that
523// 1. screens that are too short
524// 2. screens that are not tall enough to display the full width of a 3:2 image
525// at height: (100v - 6em) height
526// don't get the option to use horizontal scroll.
527
528// https://github.com/web-platform-tests/wpt/pull/34865
529// @media (max-height: 540px), (max-width: calc((100vh - 6em) * 1.5)) {
530@media (max-height: 540px), (max-width: calc(100vh * 1.4)) {
531 body {
532 padding: 0 2em;
533 }
534
535 .photos-wrapper {
536 margin-left: -2em;
537 margin-right: -2em;
538
539 img {
540 max-height: none;
541
542 &.landscape {
543 height: calc(100vw / 1.5);
544 }
545 &.portrait {
546 height: calc(100vw / 0.667);
547 }
548 &.square {
549 height: 100vw;
550 }
551 }
552 }
553
554 [name="layout"] {
555 &, + label { visibility: hidden; }
556 }
557}
558
559.stories {
560 display: flex;
561 gap: 1em;
562 align-items: center;
563 overflow: auto;
564 padding: 10px;
565 margin: -10px;
566}
567
568open-stories {
569 .count {
570 font-size: 0.8em;
571 }
572 &::part(dialog):focus {
573 outline: none;
574 }
575
576 &:not(:defined),
577 &::part(button) {
578 font-family: system-ui, sans-serif;
579 border: 1px solid var(--borderColor);
580 box-shadow: inset 0 0 0 2px var(--backgroundColor);
581 color: var(--textColor);
582 background: var(--subtleBackgroundColor);
583 padding: 1em 0;
584 text-align: center;
585 height: 76px;
586 width: 76px;
587 border-radius: 50%;
588 font-size: 0.65em;
589 box-sizing: border-box;
590 align-items: center;
591 display: flex;
592 flex-direction: column;
593 flex-shrink: 0;
594 transition: all .3s;
595 text-transform: lowercase;
596 line-height: normal;
597 justify-content: center;
598 cursor: pointer;
599
600 &:hover {
601 background: var(--linkColor);
602 color: var(--backgroundColor);
603 transform: scale(1.05);
604 }
605 }
606
607
608 &:not([is-highlight])::part(button) {
609 border-color: var(--secondaryTextColor);
610 }
611
612 &:not(.is-read):not(.is-empty):not([is-highlight])::part(button) {
613 border-color: var(--linkColor);
614 }
615
616
617 &.is-empty::part(button) {
618 pointer-events: none;
619 opacity: 0.5;
620 overflow: hidden;
621 position: relative;
622
623 &:before {
624 display: block;
625 content: '';
626 border-left: 1px solid var(--mutedTextColor);
627 position: absolute;
628 transform: rotate(-45deg);
629 top: 0;
630 left: 0;
631 width: 150%;
632 height: 150%;
633 transform-origin: top left;
634 }
635 }
636}
637
638.monospace {
639 font-family: ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
640 font-size: 0.9em;
641}
642
643open-heart.text-open-heart {
644 display: inline;
645 margin-left: 1em;
646 transition: all .4s;
647
648 &:not([disabled]):hover {
649 cursor: pointer;
650 color: var(--activeColor);
651 }
652
653 .on { display: none; }
654
655 &[aria-pressed="true"] {
656 border-color: var(--heartedBackgroundColor);
657 .on { display: initial; }
658 .off { display: none; }
659 }
660
661 &[count]::after {
662 content: "(" attr(count) ")";
663 }
664}
665
666kbd {
667 border: 1px solid var(--borderColor);
668 padding: 1px 4px;
669 border-radius: 3px;
670 box-shadow: 0 1px;
671 font-size: 0.9em;
672}
673
674nav {
675 display: flex;
676 flex-wrap: wrap;
677 column-gap: .6em;
678 margin: .6em 0;
679}
diff --git a/assets/site.js b/assets/site.js
new file mode 100644
index 0000000..4e72511
--- /dev/null
+++ b/assets/site.js
@@ -0,0 +1,32 @@
1function settime() {
2 const timestamp = document.querySelector('[data-timestamp-text]')
3 if (!timestamp || !('Intl' in window)) return
4
5 const options = {
6 timeZone: "Asia/Taipei",
7 timeStyle: "short",
8 hour12: false
9 }
10
11 // https://gist.github.com/muan/e7414b6241f088090acd916ed965540e
12 let time = new Intl.DateTimeFormat(navigator.language || "zh-TW", options).format(new Date())
13
14 // https://bugs.chromium.org/p/chromium/issues/detail?id=1262801
15 if (time.match(/^24:/)) time = time.replace('24:', '00:')
16
17 // Setting interpolated string instead of just the time because
18 // if there's no JS there should be no mentions of current time
19 const text = timestamp.getAttribute('data-timestamp-text').replace('{time}', time)
20 timestamp.innerHTML = text.replace(':', '<span class="timestamp-colon" data-colon>:</span>')
21
22 const now = new Date()
23 const sec = now.getSeconds()
24 const secondIsEven = sec % 2 === 0
25 const colon = document.querySelector('[data-colon]')
26 if (colon) colon.style.animationDelay = `${(secondIsEven ? 0 : 1000) - now.getMilliseconds()}ms`
27
28 const delay = 60000 - ((sec * 1000) + now.getMilliseconds())
29 setTimeout(settime, delay)
30}
31
32settime()
diff --git a/assets/syntax.css b/assets/syntax.css
new file mode 100644
index 0000000..de3ac90
--- /dev/null
+++ b/assets/syntax.css
@@ -0,0 +1,225 @@
1
2pre, code {
3 font-family: 'Menlo', monospace;
4}
5
6code {
7 font-size: 0.85em;
8}
9
10pre code {
11 font-size: 0.9em;
12}
13
14:root {
15 --syntaxBackground: #ffffff;
16 --hll: #ffffcc;
17 --c: #999988;
18 --err: #a61717;
19 --errBackground: #e3d2d2;
20 --k: #000000;
21 --o: #000000;
22 --cm: #999988;
23 --cp: #999999;
24 --c1: #999988;
25 --cs: #999999;
26 --gd: #000000;
27 --ge: #000000;
28 --gr: #aa0000;
29 --gh: #999999;
30 --gi: #000000;
31 --go: #888888;
32 --gp: #555555;
33 --gu: #aaaaaa;
34 --gt: #aa0000;
35 --kc: #000000;
36 --kd: #000000;
37 --kn: #000000;
38 --kp: #000000;
39 --kr: #000000;
40 --kt: #445588;
41 --m: #009999;
42 --s: #d01040;
43 --na: #008080;
44 --nb: #0086B3;
45 --nc: #445588;
46 --no: #008080;
47 --nd: #3c5d5d;
48 --ni: #800080;
49 --ne: #990000;
50 --nf: #990000;
51 --nl: #990000;
52 --nn: #555555;
53 --nt: #000080;
54 --nv: #008080;
55 --ow: #000000;
56 --w: #bbbbbb;
57 --mf: #009999;
58 --mh: #009999;
59 --mi: #009999;
60 --mo: #009999;
61 --sb: #d01040;
62 --sc: #d01040;
63 --sd: #d01040;
64 --s2: #d01040;
65 --se: #d01040;
66 --sh: #d01040;
67 --si: #d01040;
68 --sx: #d01040;
69 --sr: #009926;
70 --s1: #d01040;
71 --ss: #990073;
72 --bp: #999999;
73 --vc: #008080;
74 --vg: #008080;
75 --vi: #008080;
76 --il: #009999;
77}
78
79@media (prefers-color-scheme: dark) {
80 :root {
81 --syntaxBackground: #121615;
82 --hll: #002b36;
83 --c: #586e75;
84 --err: #e3d2d2;
85 --errBackground: #a61717;
86 --k: #859900;
87 --o: #859900;
88 --cm: #586e75;
89 --c1: #586e75;
90 --gd: #ffdddd;
91 --ge: #2aa198;
92 --gh: #cb4b16;
93 --gi: #ddffdd;
94 --gu: #cb4b16;
95 --m: #74b9b9;
96 --s: #9faf74;
97 --kc: #cb4b16;
98 --kd: #2aa198;
99 --kn: #2aa198;
100 --kp: #2aa198;
101 --kr: #2aa198;
102 --nb: #b58900;
103 --no: #cb4b16;
104 --ni: #cb4b16;
105 --ne: #cb4b16;
106 --nf: #cb4b16;
107 --nl: #cb4b16;
108 --nt: #7aa1ad;
109 --ow: #2aa198;
110 --sb: #586e75;
111 --sc: #586e75;
112 --sd: #586e75;
113 --s2: #586e75;
114 --se: #586e75;
115 --sh: #586e75;
116 --si: #586e75;
117 --sx: #586e75;
118 }
119}
120
121div.highlight {
122 overflow: hidden;
123 position: relative;
124 margin: 0;
125 background-color: var(--syntaxBackground);
126 padding: .6em 1em;
127 border-radius: 6px;
128 tab-size: 2;
129}
130
131.highlight .gutter {
132 padding-right: 1em;
133 color: #aaa;
134 border-right: 3px solid var(--syntaxBackground);
135}
136
137.highlight .code {
138 padding-left: 1em;
139}
140
141.highlight pre {
142 overflow: auto;
143 margin-top: 0;
144 margin-bottom: 0;
145}
146
147code {
148 background: var(--syntaxBackground);
149 padding: .2em .6em;
150 border-radius: 4px;
151 vertical-align: middle;
152}
153
154p code {
155 vertical-align: inherit;
156}
157
158pre code {
159 padding: 0;
160 word-wrap: initial;
161 background: transparent;
162}
163
164.hll { background-color: var(--hll) }
165.c { color: var(--c); font-style: italic } /* Comment */
166.err { color: var(--err); background-color: var(--errBackground) } /* Error */
167.k { color: var(--k); font-weight: bold } /* Keyword */
168.o { color: var(--o); font-weight: bold } /* Operator */
169.cm { color: var(--cm); font-style: italic } /* Comment.Multiline */
170.cp { color: var(--cp); font-weight: bold; font-style: italic } /* Comment.Preproc */
171.c1 { color: var(--c1); font-style: italic } /* Comment.Single */
172.cs { color: var(--cs); font-weight: bold; font-style: italic } /* Comment.Special */
173.gd { color: var(--k); background-color: var(--gd) } /* Generic.Deleted */
174.ge { color: var(--ge); font-style: italic } /* Generic.Emph */
175.gr { color: var(--gr) } /* Generic.Error */
176.gh { color: var(--gh) } /* Generic.Heading */
177.gi { color: var(--k); background-color: var(--gi) } /* Generic.Inserted */
178.go { color: var(--go) } /* Generic.Output */
179.gp { color: var(--gp) } /* Generic.Prompt */
180.gs { font-weight: bold } /* Generic.Strong */
181.gu { color: var(--gu) } /* Generic.Subheading */
182.gt { color: var(--gt) } /* Generic.Traceback */
183.kc { color: var(--kc); font-weight: bold } /* Keyword.Constant */
184.kd { color: var(--kd); font-weight: bold } /* Keyword.Declaration */
185.kn { color: var(--kn); font-weight: bold } /* Keyword.Namespace */
186.kp { color: var(--kp); font-weight: bold } /* Keyword.Pseudo */
187.kr { color: var(--kr); font-weight: bold } /* Keyword.Reserved */
188.kt { color: var(--kt); font-weight: bold } /* Keyword.Type */
189.m { color: var(--m) } /* Literal.Number */
190.s { color: var(--s) } /* Literal.String */
191.na { color: var(--na) } /* Name.Attribute */
192.nb { color: var(--nb) } /* Name.Builtin */
193.nc { color: var(--nc); font-weight: bold } /* Name.Class */
194.no { color: var(--no) } /* Name.Constant */
195.nd { color: var(--nd); font-weight: bold } /* Name.Decorator */
196.ni { color: var(--ni) } /* Name.Entity */
197.ne { color: var(--ne); font-weight: bold } /* Name.Exception */
198.nf { color: var(--nf); font-weight: bold } /* Name.Function */
199.nl { color: var(--nl); font-weight: bold } /* Name.Label */
200.nn { color: var(--nn) } /* Name.Namespace */
201.nt { color: var(--nt) } /* Name.Tag */
202.nv { color: var(--nv) } /* Name.Variable */
203.ow { color: var(--ow); font-weight: bold } /* Operator.Word */
204.w { color: var(--w) } /* Text.Whitespace */
205.mf { color: var(--mf) } /* Literal.Number.Float */
206.mh { color: var(--mh) } /* Literal.Number.Hex */
207.mi { color: var(--mi) } /* Literal.Number.Integer */
208.mo { color: var(--mo) } /* Literal.Number.Oct */
209.sb { color: var(--sb) } /* Literal.String.Backtick */
210.sc { color: var(--sc) } /* Literal.String.Char */
211.sd { color: var(--sd) } /* Literal.String.Doc */
212.s2 { color: var(--s2) } /* Literal.String.Double */
213.se { color: var(--se) } /* Literal.String.Escape */
214.sh { color: var(--sh) } /* Literal.String.Heredoc */
215.si { color: var(--si) } /* Literal.String.Interpol */
216.sx { color: var(--sx) } /* Literal.String.Other */
217.sr { color: var(--sr) } /* Literal.String.Regex */
218.s1 { color: var(--s1) } /* Literal.String.Single */
219.ss { color: var(--ss) } /* Literal.String.Symbol */
220.bp { color: var(--bp) } /* Name.Builtin.Pseudo */
221.vc { color: var(--vc) } /* Name.Variable.Class */
222.vg { color: var(--vg) } /* Name.Variable.Global */
223.vi { color: var(--vi) } /* Name.Variable.Instance */
224.il { color: var(--il) } /* Literal.Number.Integer.Long */
225
diff --git a/assets/valid-rss-rogers.png b/assets/valid-rss-rogers.png
new file mode 100644
index 0000000..8ce6d12
--- /dev/null
+++ b/assets/valid-rss-rogers.png
Binary files differ
diff --git a/feeds/photos.xml b/feeds/photos.xml
new file mode 100644
index 0000000..c89ec48
--- /dev/null
+++ b/feeds/photos.xml
@@ -0,0 +1,31 @@
1---
2permalink: /photos.xml
3---
4<?xml version="1.0" encoding="UTF-8"?>
5{% capture srcbase %}src="{{site.url}}/{% endcapture %}
6<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
7 <channel>
8 <title>@clarkzjw's photos</title>
9 <description>Photos</description>
10 {% assign photos = site.data.photos | slice: 0, 10 %}
11 <lastBuildDate>{{ photos.first.createdAt | date_to_rfc822 }}</lastBuildDate>
12 <atom:link href="{{ site.url }}/feed.xml" rel="self" type="application/rss+xml" />
13 <link>{{ site.url }}/photos.xml</link>
14 {% for photo in photos limit:10 %}
15 <item>
16 <title>{{ photo.caption | markdownify | strip_html | xml_escape }}</title>
17 <description>
18 {% capture content %}
19 <a href="{{ photo.path }}/public">
20 <img src="{{ photo.path }}/public" width="100%" alt="{{ photo.alt }}"/>
21 </a>
22 {% endcapture %}
23 {{ content | xml_escape }}{{ openheart | xml_escape }}
24 </description>
25 <pubDate>{{ photo.createdAt | date_to_rfc822 }}</pubDate>
26 <link>{{ site.url }}/photos#P{{ photo.guid }}</link>
27 <guid isPermaLink="true">{{ site.url }}/photos#P{{ photo.guid }}</guid>
28 </item>
29 {% endfor %}
30 </channel>
31</rss>
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..8071de9
--- /dev/null
+++ b/index.html
@@ -0,0 +1,73 @@
1---
2layout: default
3title: Photos
4---
5
6<input type="radio" name="layout" value="y-scroll" id="y-scroll" checked>
7<label for="y-scroll">
8 <svg width="15" height="15" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg"><title>vertical scroll</title><path d="M55 0a5 5 0 0 1 5 5v31a5 5 0 0 1-5 5H5a5 5 0 0 1-5-5V5a5 5 0 0 1 5-5h50ZM55 47a5 5 0 0 1 5 5v8H0v-8a5 5 0 0 1 5-5h50Z" fill="#D9D9D9"/></svg>
9</label>
10<input type="radio" name="layout" value="x-scroll" id="x-scroll">
11<label for="x-scroll">
12 <svg width="15" height="15" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg"><title>horizontal scroll</title><path d="M0 5a5 5 0 0 1 5-5h30a5 5 0 0 1 5 5v50a5 5 0 0 1-5 5H5a5 5 0 0 1-5-5V5ZM47 5a5 5 0 0 1 5-5h8v60h-8a5 5 0 0 1-5-5V5Z" fill="#D9D9D9"/></svg>
13</label>
14<input type="radio" name="layout" value="grid2fr" id="grid2fr">
15<label for="grid2fr">
16 <svg width="15" height="15" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg"><title>grid 2 columns</title><path d="M0 37c0-2 2-4 4-4h19c2 0 4 2 4 4v19c0 2-2 4-4 4H4c-2 0-4-2-4-4V37zM0 4c0-2 2-4 4-4h19c2 0 4 2 4 4v19c0 2-2 4-4 4H4c-2 0-4-2-4-4V4zM33 37c0-2 2-4 4-4h19c2 0 4 2 4 4v19c0 2-2 4-4 4H37c-2 0-4-2-4-4V37zM33 4c0-2 2-4 4-4h19c2 0 4 2 4 4v19c0 2-2 4-4 4H37c-2 0-4-2-4-4V4z" fill="#D9D9D9"/></svg>
17</label>
18<input type="radio" name="layout" value="grid3fr" id="grid3fr">
19<label for="grid3fr">
20 <svg width="15" height="15" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg"><title>grid 3 columns</title><path d="M22 4c0-2 2-4 4-4h8c2 0 4 2 4 4v8c0 2-2 4-4 4h-8c-2 0-4-2-4-4V4zM0 26c0-2 2-4 4-4h8c2 0 4 2 4 4v8c0 2-2 4-4 4H4c-2 0-4-2-4-4v-8zM22 26c0-2 2-4 4-4h8c2 0 4 2 4 4v8c0 2-2 4-4 4h-8c-2 0-4-2-4-4v-8zM0 48c0-2 2-4 4-4h8c2 0 4 2 4 4v8c0 2-2 4-4 4H4c-2 0-4-2-4-4v-8zM44 26c0-2 2-4 4-4h8c2 0 4 2 4 4v8c0 2-2 4-4 4h-8c-2 0-4-2-4-4v-8zM22 48c0-2 2-4 4-4h8c2 0 4 2 4 4v8c0 2-2 4-4 4h-8c-2 0-4-2-4-4v-8zM44 48c0-2 2-4 4-4h8c2 0 4 2 4 4v8c0 2-2 4-4 4h-8c-2 0-4-2-4-4v-8zM0 4c0-2 2-4 4-4h8c2 0 4 2 4 4v8c0 2-2 4-4 4H4c-2 0-4-2-4-4V4zM44 4c0-2 2-4 4-4h8c2 0 4 2 4 4v8c0 2-2 4-4 4h-8c-2 0-4-2-4-4V4z" fill="#D9D9D9"/></svg>
21</label>
22
23<div class="photos-wrapper" id="photos">
24
25{% assign photos = site.data.photos %}
26{% for photo in photos %}
27<figure id="P{{ photo.guid }}">
28 <a href="{{ photo.path }}" class="image-link">
29 <img
30 src="{{ photo.path }}"
31 height="{{ photo.height }}"
32 style="aspect-ratio: {{ photo.ratio }}"
33 alt="{{ photo.alt }}"
34 title="{{ photo.alt }}"
35 class="{{ photo.orientation }}"
36 loading="lazy">
37 </a>
38 <figcaption>
39 {{ photo.caption | strip | markdownify }}
40 <span class="desc photo-metadata">
41 {{ photo.createdAt | date: "%Y/%m/%d (%a)" }}
42 </span>
43 </figcaption>
44</figure>
45{% endfor %}
46
47</div>
48
49<script>
50 const photos = document.querySelector('#photos')
51 const xScroll = document.querySelector('#x-scroll')
52
53 // move scroll area into viewport and user focus
54 document.addEventListener('change', function(event) {
55 if (xScroll.checked) {
56 photos.scrollIntoView()
57 photos.setAttribute('tabindex', '-1')
58 photos.focus()
59
60 photos.addEventListener('blur', function() {
61 photos.blur()
62 }, {once: true})
63 }
64 })
65
66 // return focus
67 document.addEventListener('keydown', function(event) {
68 if (event.key === 'Escape' && xScroll.checked && photos.contains(event.target)) {
69 xScroll.focus()
70 window.scrollTo(0, 0)
71 }
72 })
73</script>
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..3dbc1ca
--- /dev/null
+++ b/package.json
@@ -0,0 +1,3 @@
1{
2 "type": "module"
3}
diff --git a/start b/start
new file mode 100755
index 0000000..e6bda98
--- /dev/null
+++ b/start
@@ -0,0 +1,2 @@
1bundle
2bundle exec jekyll server -w --future
Powered by cgit v1.2.3 (git 2.41.0)