yefeme 0.8.5 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 626185be9bed83f48402ae2ee070050a10747bcaf7873e189ac4137c3d35e3d3
4
- data.tar.gz: fba5761afaa71d5d584c7954361b73c28d89198b5d843aee715b2d82580f3748
3
+ metadata.gz: a53d4e13b572c6fc98aa23ab01246954cb507ada25c039b2bbe23b411940f1e0
4
+ data.tar.gz: b0d9f04c159ffbb0461de0d3f7bc4c196d076b4e6306e617c853cc7793402878
5
5
  SHA512:
6
- metadata.gz: f4306e011c6624393f37d15a981dbb182db2145d368a6a6ce3ea7f5c93ba6f9ba41be46e9d69d67b9d80fdd8ce7f912064bad377749add50341d3a3ba6367ce4
7
- data.tar.gz: 22822ada310aca330d7495c24bd208cb87183b764e1ea393e43b890cc1ba675f3d4ba3dd13db015b57e2a103a57c09fb2dc53620a897d18b44e1584f92f1850b
6
+ metadata.gz: 452d2b3a08470c568cf4ac73bdd7c029fef5e44ff0f3526c0cc2d23d301e14e15e4772f9bf78f8d190d9e95882477b0f401a36bf25eff9a674af6323b124bcdf
7
+ data.tar.gz: edbda65379bb1406841d8bb83c951a59b3e28be7238befc54623000169cd14ab033572fbb1fd8fed43c3e69923f1c2b6db4fca983b819294281fa413541095a2
data/README.md CHANGED
@@ -77,7 +77,7 @@ images:
77
77
  ---
78
78
  ```
79
79
 
80
- The theme decodes each BlurHash in the browser and displays it as an immediate placeholder behind the full thumbnail. Scalar image IDs remain supported for existing sites, but do not provide intrinsic sizing or placeholder information.
80
+ The theme decodes each BlurHash in the browser and displays it as an immediate placeholder behind the full thumbnail. Selecting a thumbnail opens the shoot in a full-screen lightbox with button, keyboard, and swipe navigation. Scalar image IDs remain supported for existing sites, but do not provide intrinsic sizing or placeholder information.
81
81
 
82
82
  ## Contributing
83
83
 
@@ -89,11 +89,11 @@ To set up your environment to develop this theme, run `bundle install`.
89
89
 
90
90
  Your theme is setup just like a normal Jekyll site! To test your theme, run `bundle exec jekyll serve` and open your browser at `http://localhost:4000`. This starts a Jekyll server using your theme. Add pages, documents, data, etc. like normal to test your theme's contents. As you make modifications to your theme and to your content, your site will regenerate and you should see the changes in the browser after a refresh, just like normal.
91
91
 
92
- When your theme is released, only the files in `_layouts`, `_includes`, and `_sass` tracked with Git will be released.
92
+ Gem releases are built from a clean checkout and include the tracked theme layouts, includes, Sass, and browser assets selected by `yefeme.gemspec`. The release workflow verifies the package and rejects site content from `_posts` or `_shoots`.
93
93
 
94
94
  ## Releasing
95
95
 
96
- Gem releases are published by GitHub Actions using RubyGems Trusted Publishing.
96
+ Gem releases are published by the [`Release gem`](.github/workflows/release.yml) GitHub Actions workflow using RubyGems Trusted Publishing. Publishing uses short-lived credentials, so the repository does not need a `RUBYGEMS_API_KEY` secret.
97
97
 
98
98
  1. Update the version in `yefeme.gemspec` and merge the change to `master`.
99
99
  2. Create and push the matching version tag, for example:
@@ -103,9 +103,9 @@ Gem releases are published by GitHub Actions using RubyGems Trusted Publishing.
103
103
  git push origin v0.8.5
104
104
  ```
105
105
 
106
- The release workflow verifies that the tag matches the gemspec, builds and inspects the package from a clean checkout, publishes it to RubyGems, and waits for the release to propagate.
106
+ The release workflow verifies that the tag matches the gemspec, builds and inspects the package from a clean checkout, publishes it to RubyGems, and waits until the release is available from RubyGems indexes.
107
107
 
108
- Before the first automated release, configure `yefim/yefeme` as a trusted publisher for the `yefeme` gem on RubyGems.org. Use `release.yml` as the workflow filename and `release` as the GitHub environment. The environment can require approval to retain a human release gate.
108
+ Trusted Publishing is configured for `yefim/yefeme`, the `release.yml` workflow, and the `release` GitHub environment. Configure required reviewers on that environment if releases should retain a manual approval gate.
109
109
 
110
110
  ## License
111
111
 
@@ -0,0 +1,208 @@
1
+ <template id="shoot-lightbox-template">
2
+ <style>
3
+ * {
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ .modal {
8
+ align-items: flex-end;
9
+ background: #fff;
10
+ display: flex;
11
+ gap: 1rem;
12
+ height: 100%;
13
+ inset: 0;
14
+ justify-content: center;
15
+ padding: 1rem;
16
+ position: fixed;
17
+ transition: opacity 0.25s, visibility 0.25s;
18
+ width: 100%;
19
+ z-index: 1000;
20
+ }
21
+
22
+ .modal.hidden {
23
+ opacity: 0;
24
+ pointer-events: none;
25
+ visibility: hidden;
26
+ }
27
+
28
+ button {
29
+ align-items: center;
30
+ background: #999;
31
+ border: 0;
32
+ border-radius: 50%;
33
+ color: #fff;
34
+ cursor: pointer;
35
+ display: flex;
36
+ height: 2rem;
37
+ justify-content: center;
38
+ padding: 0;
39
+ position: relative;
40
+ width: 2rem;
41
+ z-index: 2;
42
+ }
43
+
44
+ button svg {
45
+ display: block;
46
+ fill: none;
47
+ height: 1.125rem;
48
+ shape-rendering: geometricPrecision;
49
+ stroke: currentColor;
50
+ stroke-linecap: round;
51
+ stroke-linejoin: round;
52
+ stroke-width: 2.25;
53
+ width: 1.125rem;
54
+ }
55
+
56
+ button:focus-visible {
57
+ outline: 2px solid currentColor;
58
+ outline-offset: 3px;
59
+ }
60
+
61
+ button[disabled] {
62
+ background: #eee;
63
+ cursor: default;
64
+ }
65
+
66
+ .close {
67
+ position: absolute;
68
+ right: max(1rem, env(safe-area-inset-right));
69
+ top: max(1rem, env(safe-area-inset-top));
70
+ }
71
+
72
+ .track {
73
+ display: flex;
74
+ height: 100%;
75
+ inset: 0;
76
+ overflow-x: auto;
77
+ overflow-y: hidden;
78
+ position: absolute;
79
+ scroll-snap-type: x mandatory;
80
+ scrollbar-width: none;
81
+ width: 100%;
82
+ -webkit-overflow-scrolling: touch;
83
+ }
84
+
85
+ .track::-webkit-scrollbar {
86
+ display: none;
87
+ }
88
+
89
+ .slide {
90
+ align-items: center;
91
+ display: flex;
92
+ flex: 0 0 100%;
93
+ justify-content: center;
94
+ position: relative;
95
+ scroll-snap-align: center;
96
+ }
97
+
98
+ .slide img {
99
+ height: auto;
100
+ left: 50%;
101
+ max-height: calc(100vh - 5rem);
102
+ max-height: calc(100dvh - 5rem);
103
+ max-width: 98vw;
104
+ max-width: 98dvw;
105
+ object-fit: contain;
106
+ opacity: var(--resolution-opacity, 1);
107
+ position: absolute;
108
+ top: 50%;
109
+ touch-action: pan-x;
110
+ transform: translate(-50%, calc(-50% - 1.5rem));
111
+ transition: opacity 0.3s ease;
112
+ user-select: none;
113
+ width: auto;
114
+ -webkit-user-drag: none;
115
+ }
116
+
117
+ .slide img.high-resolution {
118
+ --resolution-opacity: 0;
119
+ }
120
+
121
+ .slide img.high-resolution.loaded {
122
+ --resolution-opacity: 1;
123
+ }
124
+
125
+ .slide img.dragging {
126
+ opacity: calc(var(--resolution-opacity, 1) * var(--drag-opacity, 1));
127
+ transform: translate(-50%, calc(-50% - 1.5rem)) translateY(var(--drag-y, 0));
128
+ transition: none;
129
+ }
130
+
131
+ .slide img.dismissing {
132
+ transition: opacity 0.2s ease-out, transform 0.2s ease-out;
133
+ }
134
+
135
+ .status {
136
+ clip: rect(0 0 0 0);
137
+ clip-path: inset(50%);
138
+ height: 1px;
139
+ overflow: hidden;
140
+ position: absolute;
141
+ white-space: nowrap;
142
+ width: 1px;
143
+ }
144
+
145
+ @media (orientation: landscape) {
146
+ .modal {
147
+ align-items: center;
148
+ justify-content: space-between;
149
+ }
150
+
151
+ .slide img {
152
+ max-height: 98vh;
153
+ max-height: 98dvh;
154
+ max-width: calc(98vw - 6rem);
155
+ max-width: calc(98dvw - 6rem);
156
+ transform: translate(-50%, -50%);
157
+ }
158
+
159
+ .slide img.dragging {
160
+ transform: translate(-50%, -50%) translateY(var(--drag-y, 0));
161
+ }
162
+ }
163
+
164
+ @media (prefers-color-scheme: dark) {
165
+ .modal {
166
+ background: #000;
167
+ }
168
+
169
+ button {
170
+ background: #666;
171
+ }
172
+
173
+ button[disabled] {
174
+ background: #333;
175
+ color: #000;
176
+ }
177
+ }
178
+
179
+ @media (prefers-reduced-motion: reduce) {
180
+ .modal,
181
+ .slide img.dismissing {
182
+ transition: none;
183
+ }
184
+ }
185
+ </style>
186
+
187
+ <div class="modal hidden" role="dialog" aria-label="Photo viewer" aria-hidden="true" tabindex="-1">
188
+ <div class="track"></div>
189
+ <button class="previous" type="button" aria-label="Previous photo">
190
+ <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
191
+ <path d="M15 18l-6-6 6-6"></path>
192
+ </svg>
193
+ </button>
194
+ <button class="next" type="button" aria-label="Next photo">
195
+ <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
196
+ <path d="M9 6l6 6-6 6"></path>
197
+ </svg>
198
+ </button>
199
+ <button class="close" type="button" aria-label="Close photo viewer">
200
+ <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
201
+ <path d="M6 6l12 12M18 6L6 18"></path>
202
+ </svg>
203
+ </button>
204
+ <p class="status" aria-live="polite"></p>
205
+ </div>
206
+ </template>
207
+
208
+ <shoot-lightbox></shoot-lightbox>
data/_layouts/shoot.html CHANGED
@@ -10,7 +10,7 @@ layout: entry
10
10
  {% for image in page.images %}
11
11
  {% assign image_id = image["id"] | default: image %}
12
12
  {% assign base = "https://imagedelivery.net/" | append: site.cf_images_account_hash | append: "/" | append: image_id | append: "/" %}
13
- <a class="tile" href="{{ base }}{{ xl }}" target="_blank" rel="noopener">
13
+ <a class="tile" href="{{ base }}{{ xl }}">
14
14
  <img
15
15
  src="{{ base }}{{ thumb }}"
16
16
  {% if image["width"] and image["height"] %}
@@ -28,3 +28,6 @@ layout: entry
28
28
  {% endfor %}
29
29
  </div>
30
30
  </main>
31
+
32
+ {% include light-box.html %}
33
+ <script defer src="{{ "/assets/lightbox.js" | relative_url }}"></script>
data/_sass/yefeme.scss CHANGED
@@ -24,6 +24,11 @@ body {
24
24
  font-family: "Libre Baskerville", serif;
25
25
  }
26
26
 
27
+ html.lightbox-open,
28
+ html.lightbox-open body {
29
+ overflow: hidden;
30
+ }
31
+
27
32
  li,
28
33
  ol,
29
34
  ul {
@@ -367,6 +372,7 @@ article {
367
372
  background: #f6f6f6;
368
373
  border-radius: 8px;
369
374
  break-inside: avoid;
375
+ cursor: zoom-in;
370
376
  display: block;
371
377
  margin-bottom: 12px;
372
378
  overflow: hidden;
@@ -0,0 +1,305 @@
1
+ (function () {
2
+ "use strict";
3
+
4
+ if (!window.customElements || window.customElements.get("shoot-lightbox")) return;
5
+
6
+ var VERTICAL_DRAG_DISTANCE = 10;
7
+
8
+ function getImage(photo) {
9
+ return photo.querySelector("img");
10
+ }
11
+
12
+ class ShootLightbox extends HTMLElement {
13
+ constructor() {
14
+ super();
15
+
16
+ var template = document.getElementById("shoot-lightbox-template");
17
+ if (!template) return;
18
+
19
+ this.attachShadow({ mode: "open" });
20
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
21
+ }
22
+
23
+ connectedCallback() {
24
+ if (!this.shadowRoot) return;
25
+
26
+ this.photos = Array.from(document.querySelectorAll(".portfolio-day .tile"));
27
+ if (!this.photos.length) return;
28
+
29
+ this.currentPhoto = 0;
30
+ this.modal = this.shadowRoot.querySelector(".modal");
31
+ this.track = this.shadowRoot.querySelector(".track");
32
+ this.previousButton = this.shadowRoot.querySelector(".previous");
33
+ this.nextButton = this.shadowRoot.querySelector(".next");
34
+ this.closeButton = this.shadowRoot.querySelector(".close");
35
+ this.status = this.shadowRoot.querySelector(".status");
36
+
37
+ this.buildSlides();
38
+ this.bindEvents();
39
+ this.updateControls();
40
+ }
41
+
42
+ buildSlides() {
43
+ this.photos.forEach((photo) => {
44
+ var sourceImage = getImage(photo);
45
+ if (!sourceImage) return;
46
+
47
+ var slide = document.createElement("div");
48
+ var image = sourceImage.cloneNode(true);
49
+
50
+ slide.className = "slide";
51
+ image.loading = "eager";
52
+ image.decoding = "async";
53
+ image.draggable = false;
54
+ this.bindImageEvents(image);
55
+
56
+ slide.appendChild(image);
57
+ this.track.appendChild(slide);
58
+ });
59
+
60
+ this.slides = Array.from(this.track.querySelectorAll(".slide"));
61
+ }
62
+
63
+ bindImageEvents(image) {
64
+ image.addEventListener("click", (event) => event.stopPropagation());
65
+ image.addEventListener("touchstart", this.startTouch, { passive: true });
66
+ image.addEventListener("touchmove", this.dragVertically, { passive: false });
67
+ image.addEventListener("touchend", this.endTouch);
68
+ image.addEventListener("touchcancel", this.resetGesture);
69
+ }
70
+
71
+ loadHighResolutionImage(slide, photo) {
72
+ if (!slide || !photo.href || slide.dataset.highResolutionRequested) return;
73
+
74
+ var preview = slide.querySelector("img");
75
+ if (!preview) return;
76
+
77
+ slide.dataset.highResolutionRequested = "true";
78
+
79
+ var image = preview.cloneNode(true);
80
+ var revealed = false;
81
+
82
+ image.classList.remove("blurhash-loaded");
83
+ image.classList.add("high-resolution");
84
+ image.removeAttribute("data-blurhash");
85
+ image.removeAttribute("style");
86
+ image.removeAttribute("srcset");
87
+ image.removeAttribute("sizes");
88
+ image.setAttribute("alt", "");
89
+ image.setAttribute("aria-hidden", "true");
90
+ image.loading = "eager";
91
+ image.decoding = "async";
92
+ image.draggable = false;
93
+ this.bindImageEvents(image);
94
+
95
+ var reveal = () => {
96
+ if (revealed) return;
97
+ revealed = true;
98
+
99
+ var decoded = typeof image.decode === "function" ? image.decode().catch(() => {}) : Promise.resolve();
100
+ decoded.then(() => {
101
+ window.requestAnimationFrame(() => image.classList.add("loaded"));
102
+ });
103
+ };
104
+
105
+ image.addEventListener("load", reveal, { once: true });
106
+ image.addEventListener("error", () => {
107
+ delete slide.dataset.highResolutionRequested;
108
+ image.remove();
109
+ }, { once: true });
110
+
111
+ slide.appendChild(image);
112
+ image.src = photo.href;
113
+ if (image.complete && image.naturalWidth) reveal();
114
+ }
115
+
116
+ bindEvents() {
117
+ this.photos.forEach((photo, index) => {
118
+ photo.addEventListener("click", (event) => this.open(event, index));
119
+ });
120
+
121
+ this.previousButton.addEventListener("click", this.previous);
122
+ this.nextButton.addEventListener("click", this.next);
123
+ this.closeButton.addEventListener("click", this.close);
124
+ this.modal.addEventListener("click", this.close);
125
+ this.track.addEventListener("scroll", this.onScroll, { passive: true });
126
+ document.addEventListener("keydown", this.onKeydown);
127
+ window.addEventListener("resize", this.onResize, { passive: true });
128
+ }
129
+
130
+ open(event, index) {
131
+ event.preventDefault();
132
+
133
+ this.previouslyFocused = document.activeElement;
134
+ this.updateCurrentPhoto(index, "auto");
135
+ this.modal.classList.remove("hidden");
136
+ this.modal.setAttribute("aria-hidden", "false");
137
+ document.documentElement.classList.add("lightbox-open");
138
+ this.loadHighResolutionImage(this.slides[this.currentPhoto], this.photos[this.currentPhoto]);
139
+ this.modal.focus({ preventScroll: true });
140
+ }
141
+
142
+ close = (event) => {
143
+ if (event) {
144
+ event.preventDefault();
145
+ event.stopPropagation();
146
+ }
147
+
148
+ if (this.modal.classList.contains("hidden")) return;
149
+
150
+ this.modal.classList.add("hidden");
151
+ this.modal.setAttribute("aria-hidden", "true");
152
+ document.documentElement.classList.remove("lightbox-open");
153
+ this.resetGesture();
154
+
155
+ if (this.previouslyFocused) this.previouslyFocused.focus({ preventScroll: true });
156
+ };
157
+
158
+ next = (event) => {
159
+ event.preventDefault();
160
+ event.stopPropagation();
161
+ if (!this.isLastPhoto()) this.updateCurrentPhoto(this.currentPhoto + 1);
162
+ };
163
+
164
+ previous = (event) => {
165
+ event.preventDefault();
166
+ event.stopPropagation();
167
+ if (!this.isFirstPhoto()) this.updateCurrentPhoto(this.currentPhoto - 1);
168
+ };
169
+
170
+ isFirstPhoto() {
171
+ return this.currentPhoto <= 0;
172
+ }
173
+
174
+ isLastPhoto() {
175
+ return this.currentPhoto >= this.photos.length - 1;
176
+ }
177
+
178
+ updateCurrentPhoto(index, behavior) {
179
+ this.currentPhoto = Math.max(0, Math.min(this.photos.length - 1, index));
180
+ this.track.scrollTo({
181
+ left: this.currentPhoto * this.track.clientWidth,
182
+ behavior: behavior || "smooth"
183
+ });
184
+ this.updateControls();
185
+ this.loadHighResolutionImage(this.slides[this.currentPhoto], this.photos[this.currentPhoto]);
186
+ }
187
+
188
+ updateControls() {
189
+ this.previousButton.disabled = this.isFirstPhoto();
190
+ this.nextButton.disabled = this.isLastPhoto();
191
+ this.status.textContent = "Photo " + (this.currentPhoto + 1) + " of " + this.photos.length;
192
+ }
193
+
194
+ onKeydown = (event) => {
195
+ if (this.modal.classList.contains("hidden")) return;
196
+
197
+ if (event.key === "ArrowLeft") this.previous(event);
198
+ if (event.key === "ArrowRight") this.next(event);
199
+ if (event.key === "Escape") this.close(event);
200
+ };
201
+
202
+ onScroll = () => {
203
+ window.clearTimeout(this.scrollSyncTimeout);
204
+ this.scrollSyncTimeout = window.setTimeout(() => {
205
+ var width = this.track.clientWidth || window.innerWidth;
206
+ this.currentPhoto = Math.max(
207
+ 0,
208
+ Math.min(this.photos.length - 1, Math.round(this.track.scrollLeft / width))
209
+ );
210
+ this.updateControls();
211
+ this.loadHighResolutionImage(this.slides[this.currentPhoto], this.photos[this.currentPhoto]);
212
+ }, 100);
213
+ };
214
+
215
+ onResize = () => {
216
+ if (this.modal.classList.contains("hidden")) return;
217
+ this.updateCurrentPhoto(this.currentPhoto, "auto");
218
+ };
219
+
220
+ startTouch = (event) => {
221
+ if (event.touches.length !== 1) return;
222
+
223
+ this.touchStartX = event.touches[0].clientX;
224
+ this.touchStartY = event.touches[0].clientY;
225
+ this.gestureDirection = "undecided";
226
+ };
227
+
228
+ dragVertically = (event) => {
229
+ if (event.touches.length !== 1 || this.gestureDirection === "horizontal") return;
230
+
231
+ var deltaX = Math.abs(event.touches[0].clientX - this.touchStartX);
232
+ var deltaY = Math.abs(event.touches[0].clientY - this.touchStartY);
233
+
234
+ if (this.gestureDirection === "undecided") {
235
+ if (deltaX < VERTICAL_DRAG_DISTANCE && deltaY < VERTICAL_DRAG_DISTANCE) return;
236
+ this.gestureDirection = deltaX > deltaY ? "horizontal" : "vertical";
237
+ }
238
+
239
+ if (this.gestureDirection !== "vertical") return;
240
+
241
+ event.preventDefault();
242
+ this.track.style.scrollSnapType = "none";
243
+ this.track.style.overflowX = "hidden";
244
+ this.applyVerticalDrag(event.touches[0].clientY - this.touchStartY);
245
+ };
246
+
247
+ applyVerticalDrag(distance) {
248
+ var images = this.currentImages();
249
+ if (!images.length) return;
250
+
251
+ var maxDrag = window.innerHeight * 0.5;
252
+ var opacity = Math.max(0, Math.min(1, 1 - Math.abs(distance) / maxDrag));
253
+
254
+ images.forEach((image) => {
255
+ image.classList.add("dragging");
256
+ image.style.setProperty("--drag-y", distance + "px");
257
+ image.style.setProperty("--drag-opacity", opacity);
258
+ });
259
+ }
260
+
261
+ endTouch = (event) => {
262
+ if (this.gestureDirection !== "vertical") return;
263
+
264
+ var distance = event.changedTouches[0].clientY - this.touchStartY;
265
+ var dismissDistance = Math.min(window.innerHeight * 0.3, 150);
266
+
267
+ if (Math.abs(distance) < dismissDistance) {
268
+ this.resetGesture();
269
+ return;
270
+ }
271
+
272
+ var images = this.currentImages();
273
+ if (!images.length) return;
274
+
275
+ images.forEach((image) => {
276
+ image.classList.add("dismissing");
277
+ image.style.setProperty("--drag-y", (distance > 0 ? distance + 200 : distance - 200) + "px");
278
+ image.style.setProperty("--drag-opacity", "0");
279
+ });
280
+ window.setTimeout(() => this.close(), 200);
281
+ };
282
+
283
+ currentImages() {
284
+ var slide = this.slides && this.slides[this.currentPhoto];
285
+ return slide ? Array.from(slide.querySelectorAll("img")) : [];
286
+ }
287
+
288
+ resetGesture = () => {
289
+ this.currentImages().forEach((image) => {
290
+ image.classList.remove("dragging", "dismissing");
291
+ image.style.removeProperty("--drag-y");
292
+ image.style.removeProperty("--drag-opacity");
293
+ });
294
+
295
+ if (this.track) {
296
+ this.track.style.removeProperty("scroll-snap-type");
297
+ this.track.style.removeProperty("overflow-x");
298
+ }
299
+
300
+ this.gestureDirection = "undecided";
301
+ };
302
+ }
303
+
304
+ window.customElements.define("shoot-lightbox", ShootLightbox);
305
+ }());
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yefeme
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.5
4
+ version: 0.8.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yefim Vedernikoff
@@ -36,6 +36,7 @@ files:
36
36
  - _includes/email.svg
37
37
  - _includes/github.svg
38
38
  - _includes/head.html
39
+ - _includes/light-box.html
39
40
  - _includes/logo.svg
40
41
  - _includes/twitter.svg
41
42
  - _layouts/default.html
@@ -46,6 +47,7 @@ files:
46
47
  - _sass/highlight.scss
47
48
  - _sass/yefeme.scss
48
49
  - assets/blurhash.js
50
+ - assets/lightbox.js
49
51
  - assets/main.scss
50
52
  - index.md
51
53
  homepage: https://github.com/yefim/yefeme