jekyll-project-stack-portfolio 0.1.2
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 +7 -0
- data/LICENSE +674 -0
- data/README.md +121 -0
- data/_includes/components/sidebar/cd.svg +55 -0
- data/_includes/components/sidebar/footer.html +49 -0
- data/_includes/components/sidebar/menu_icon.svg +11 -0
- data/_includes/components/sidebar/noteback.png +0 -0
- data/_includes/components/sidebar/notebook.svg +38 -0
- data/_includes/components/sidebar/project-stack.html +14 -0
- data/_includes/components/sidebar/shelf.html +5 -0
- data/_includes/components/sidebar/sidebar.html +83 -0
- data/_includes/components/sidebar/tape.svg +30 -0
- data/_includes/components/sidebar/theme_toggle_icon.svg +14 -0
- data/_includes/content-top.html +0 -0
- data/_includes/footer-right.html +0 -0
- data/_includes/page_hero.html +0 -0
- data/_layouts/default.html +33 -0
- data/_layouts/page.html +21 -0
- data/_layouts/project.html +19 -0
- data/_plugins/stack_row.rb +134 -0
- data/_sass/_base.scss +152 -0
- data/_sass/_layout.scss +746 -0
- data/_sass/_stack-presets.custom.scss +38 -0
- data/_sass/_stack-presets.scss +30 -0
- data/_sass/_variables.scss +146 -0
- data/assets/css/main.scss +7 -0
- data/assets/project_media/big-texture/death.jpg +0 -0
- data/assets/project_media/big-texture/gallery1/6e45aa_2d63c32a00ed4ab49590e74545dfe0bd~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery1/6e45aa_3ce67d3715f6488ca748d87d8b973281~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery1/6e45aa_5fd34f6dae054cf384c34a462df487b6~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery1/6e45aa_6b21e564fc7e4130b320f7cebc97590f~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery1/6e45aa_7a23e2fb6bc8469382f7415958f4b2ff~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_182bb86e17d14a02b13b09c065698ad5~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_29d1730d24804e4ea0cba6174da2ff41~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_46c6f5f1ec3747fa80fe0ed6fc44e593~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_49faf78a26424cd598df86ed195be94e~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_54222db8edf44b07a2fd7d02bd562620~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_54ebf8bc0e404ac1a7a092752d6450a3~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_69a17c7f86fa4466a014d60023a33e84~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_a09cce390fb2418a94321c6a08a0ab8d~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_a6570c26358d4589adda437790eeb13d~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_cd25051953bf4336af52073532315d2f~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_eea363e1a8204dbabdf409d04aeaeab4~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_f98381967c8943d7a78018deadc5f6f4~mv2 (1).jpg +0 -0
- data/assets/project_media/big-texture/gallery2/6e45aa_ff278e4dbe5749aab8c44ee3a089e466~mv2 (1).jpg +0 -0
- data/assets/project_media/updated-albums/hero_vid.mp4 +0 -0
- data/assets/project_media/zombie-film/image.png +0 -0
- data/assets/project_media/zombie-film/script.fountain +26 -0
- data/assets/site_media/darkwall.jpg +0 -0
- data/assets/site_media/favicon.png +0 -0
- data/assets/site_media/lightwall.png +0 -0
- data/assets/site_media/noteback.png +0 -0
- data/assets/site_media/play_vid.mp4 +0 -0
- data/assets/site_media/shelf.png +0 -0
- data/lib/jekyll-project-stack-portfolio.rb +7 -0
- data/lib/project-stack-portfolio/version.rb +5 -0
- metadata +155 -0
data/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
## Run demo site locally
|
|
2
|
+
```
|
|
3
|
+
bundle install
|
|
4
|
+
bundle exec jekyll serve --livereload
|
|
5
|
+
```
|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
# jekyll-project-stack-portfolio
|
|
9
|
+
|
|
10
|
+
This theme is a little retro flavored and is designed to be a portfolio for projects, rather than a blog. It displays a stack of projects on the sidebar as a visual stack of VHS tapes, notebooks or (double) CD cases.
|
|
11
|
+
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
# Features
|
|
15
|
+
|
|
16
|
+
* Dark mode toggle
|
|
17
|
+
* Mobile friendly
|
|
18
|
+
* SEO friendly
|
|
19
|
+
* Sooo customizable you can spend so much time procrastinating
|
|
20
|
+
|
|
21
|
+
# Setup/Configure/Customize
|
|
22
|
+
|
|
23
|
+
There are a few things you need in place to get this theme working. The default Jekyll quickstart build will set you up with _posts directory. For this theme, you need to create a `_projects` directory in the root of your repository. Then add this to your `_config.yml` file:
|
|
24
|
+
|
|
25
|
+
``` yaml
|
|
26
|
+
collections:
|
|
27
|
+
projects:
|
|
28
|
+
output: true
|
|
29
|
+
permalink: /projects/:name/
|
|
30
|
+
|
|
31
|
+
defaults:
|
|
32
|
+
- scope:
|
|
33
|
+
path: ""
|
|
34
|
+
type: "projects"
|
|
35
|
+
values:
|
|
36
|
+
layout: "project"
|
|
37
|
+
```
|
|
38
|
+
This allows Jekyll to recognize markdown files in the `_projects` directory as a collection of project pages.
|
|
39
|
+
|
|
40
|
+
A project's stack style is set in the frontmatter of each project markdown page.
|
|
41
|
+
|
|
42
|
+
``` yaml
|
|
43
|
+
---
|
|
44
|
+
layout: project
|
|
45
|
+
type: vhs #<---- makes this as a VHS tape in the stack
|
|
46
|
+
stack_style: tape #<---- style class preset
|
|
47
|
+
title: "Sketches". #<---- Text on the spine of the tape (and page title)
|
|
48
|
+
show_title: true. #<---- show the title on the page (or not)
|
|
49
|
+
draft: false #<---- if true, this project will not be displayed in the stack
|
|
50
|
+
---
|
|
51
|
+
```
|
|
52
|
+
#### type:
|
|
53
|
+
|
|
54
|
+
Valid values are `vhs`, `notebook`, `cd`. Up to you, maybe vhs for video projects, notebook for art or writing, cd for music.
|
|
55
|
+
|
|
56
|
+
#### stack_style:
|
|
57
|
+
|
|
58
|
+
There are a few built-in `stack_style` presets are defined in the plugin - `tape`, `notebook`, `cd`. And if you omit the stack_syle, the item will fall back to a plain default. Probably what you want to do, though, is create your own presets.
|
|
59
|
+
|
|
60
|
+
Make a new file in your repository at `_sass/_stack-presets.custom.scss` and copy the following into it:
|
|
61
|
+
|
|
62
|
+
``` css
|
|
63
|
+
// Stack style and color customization.
|
|
64
|
+
/*
|
|
65
|
+
Name styles as a single word like .tape1
|
|
66
|
+
In the project .md file set the stack_style to that value (no .) `stack_style: tape1`
|
|
67
|
+
Tape color vars map to the VHS label bars from left to right.
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
*/
|
|
71
|
+
.tape1 {
|
|
72
|
+
--tab_unlocked: 1; // 0 or 1 to set whether the VHS lock tab is removed
|
|
73
|
+
--color1: #305198;
|
|
74
|
+
--color2: #305198;
|
|
75
|
+
--color3: #305198;
|
|
76
|
+
--color4: #305198;
|
|
77
|
+
--color5: #305198;
|
|
78
|
+
|
|
79
|
+
--color6: #305198
|
|
80
|
+
;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.notebook1 {
|
|
84
|
+
--notebook-color: #c74719;
|
|
85
|
+
--label-color: #ffa008;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.cd1 {
|
|
89
|
+
--color1: #5036f5;
|
|
90
|
+
--color2: #12176a;
|
|
91
|
+
--label-color: #f7f0e5;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Each class in that file is a preset that can be used in the frontmatter of a project markdown file.
|
|
96
|
+
|
|
97
|
+
You only need to specify the variables you want to override.
|
|
98
|
+
|
|
99
|
+
e.g.
|
|
100
|
+
```
|
|
101
|
+
---- project1.md ---
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
type: vhs
|
|
105
|
+
stack_style: redtape
|
|
106
|
+
title: "Project One"
|
|
107
|
+
---
|
|
108
|
+
...
|
|
109
|
+
|
|
110
|
+
---- _sass/_stack-presets.custom.scss ---
|
|
111
|
+
|
|
112
|
+
.redtape {
|
|
113
|
+
--tab_unlocked: 0;
|
|
114
|
+
--color1: #be2c2c;
|
|
115
|
+
--color5: #be2c2c;
|
|
116
|
+
--color6: #be2c2c;
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+

|
|
120
|
+
|
|
121
|
+
Tape and cd also have additional style variables for extra decorative text on the label. see `_sass/_stack-presets.custom.scss` for some examples
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="778.507" height="129.16" viewBox="-290.65 -42.581 778.507 129.16">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="a" x1="-274.755" x2="-274.755" y1="-13.373" y2="-6.218" gradientUnits="userSpaceOnUse" spreadMethod="pad">
|
|
4
|
+
<stop offset="0" stop-color="#d8d8d8"/>
|
|
5
|
+
<stop offset="1" stop-color="#7b7b7b"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="b" x1="-274.755" x2="-274.755" y1="-13.373" y2="-6.218" gradientTransform="translate(746.188)" gradientUnits="userSpaceOnUse" spreadMethod="pad">
|
|
8
|
+
<stop offset="0" stop-color="#d8d8d8"/>
|
|
9
|
+
<stop offset="1" stop-color="#7b7b7b"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
<linearGradient id="c" x1="98.315" x2="98.315" y1="-42.581" y2="13.228" gradientUnits="userSpaceOnUse">
|
|
12
|
+
<stop offset="0" stop-color="#d8d8d8"/>
|
|
13
|
+
<stop offset="1" stop-color="#7b7b7b"/>
|
|
14
|
+
</linearGradient>
|
|
15
|
+
<linearGradient id="d" x1="98.496" x2="98.496" y1="-31.392" y2="27.051" gradientUnits="userSpaceOnUse">
|
|
16
|
+
<stop offset="0" stop-color="#d8d8d8"/>
|
|
17
|
+
<stop offset="1" stop-color="#7b7b7b"/>
|
|
18
|
+
</linearGradient>
|
|
19
|
+
<linearGradient id="f" x1="-274.755" x2="-274.755" y1="-13.373" y2="-6.218" gradientTransform="translate(.565 -43.997)" gradientUnits="userSpaceOnUse" spreadMethod="pad">
|
|
20
|
+
<stop offset="0" stop-color="#d8d8d8"/>
|
|
21
|
+
<stop offset="1" stop-color="#7b7b7b"/>
|
|
22
|
+
</linearGradient>
|
|
23
|
+
<linearGradient id="g" x1="-274.755" x2="-274.755" y1="-13.373" y2="-6.218" gradientTransform="translate(746.754 -43.997)" gradientUnits="userSpaceOnUse" spreadMethod="pad">
|
|
24
|
+
<stop offset="0" stop-color="#d8d8d8"/>
|
|
25
|
+
<stop offset="1" stop-color="#7b7b7b"/>
|
|
26
|
+
</linearGradient>
|
|
27
|
+
<linearGradient id="h" x1="98.315" x2="98.315" y1="-42.581" y2="13.228" gradientTransform="matrix(1 0 0 -1 .565 43.997)" gradientUnits="userSpaceOnUse">
|
|
28
|
+
<stop offset="0" stop-color="#d8d8d8"/>
|
|
29
|
+
<stop offset="1" stop-color="#7b7b7b"/>
|
|
30
|
+
</linearGradient>
|
|
31
|
+
<linearGradient id="e" x1="98.496" x2="98.496" y1="-31.392" y2="27.051" gradientTransform="matrix(1 0 0 -1 .565 43.997)" gradientUnits="userSpaceOnUse">
|
|
32
|
+
<stop offset="0" stop-color="#d8d8d8"/>
|
|
33
|
+
<stop offset="1" stop-color="#7b7b7b"/>
|
|
34
|
+
</linearGradient>
|
|
35
|
+
<radialGradient id="i" cx="98.702" cy="21.609" r="365.552" gradientTransform="translate(.726 .56)" gradientUnits="userSpaceOnUse">
|
|
36
|
+
<stop offset="0" stop-color="#d8d8d8"/>
|
|
37
|
+
<stop offset="1" stop-color="#7b7b7b"/>
|
|
38
|
+
</radialGradient>
|
|
39
|
+
</defs>
|
|
40
|
+
<path d="M-289.5-41.486h776.797V85.889H-289.5z" fill="#333"/>
|
|
41
|
+
<path d="M-280.08-13.373h10.649v7.155h-10.649z" fill="url(#a)"/>
|
|
42
|
+
<path d="M466.107-13.373h10.649v7.155h-10.649z" fill="url(#b)"/>
|
|
43
|
+
<path d="M-289.65-42.581h8.363v.057h759.619v.012h7.948a1 1 0 0 1 1 1v53.74a1 1 0 0 1-1 1h-7.363a1 1 0 0 1-1-1v-45.389h-759.204v45.32a1 1 0 0 1-1 1h-7.363a1 1 0 0 1-1-1v-53.74a1 1 0 0 1 1-1Z" fill="url(#c)" fill-rule="evenodd" fill-opacity="0.7"/>
|
|
44
|
+
<path d="M487.193 14.298v9.753a3 3 0 0 1-3 3H-287.2a3 3 0 0 1-3-3v-9.753h10.11v-45.531h10.677v45.531h735.35v-45.69h10.677v45.69Z" fill="url(#d)" fill-rule="evenodd" fill-opacity="0.73"/>
|
|
45
|
+
<path d="M487.758 29.7v-9.753a3 3 0 0 0-3-3H-286.64c-1.65 0-3 1.343-3 3V29.7h10.11v45.531h10.68V29.7h735.352v45.69h10.677V29.7z" fill="url(#e)" fill-rule="evenodd" fill-opacity="0.73"/>
|
|
46
|
+
<path d="M-279.52-57.371h10.649v7.155h-10.649z" fill="url(#f)" transform="scale(1 -1)"/>
|
|
47
|
+
<path d="M466.672-57.37h10.649v7.155h-10.649z" fill="url(#g)" transform="matrix(1 0 0 -1 0 104.725)"/>
|
|
48
|
+
<path d="M-289.09 86.579h8.37v-.057h759.617v-.012h7.948a1 1 0 0 0 1-1V31.77a1 1 0 0 0-1-1h-7.363a1 1 0 0 0-1 1v45.389H-280.72v-45.32c0-.552-.45-1-1-1h-7.37c-.55 0-1 .448-1 1v53.74c0 .552.45 1 1 1Z" fill="url(#h)" fill-rule="evenodd" fill-opacity="0.7"/>
|
|
49
|
+
<path id="label" d="M-264.55-30.294h724.834s1.999 4.75 1.763 49.654c-.276 52.505-1.763 56.071-1.763 56.071H-264.55s-1.8-6.287-1.79-52.863c0-46.576 1.79-52.862 1.79-52.862Z" fill="var(--label-color, #fff)"/>
|
|
50
|
+
<path id="color1" d="M372.384-30.413h88.658s.964 33.691.968 50.243c.004 18.692-.968 55.482-.968 55.482h-88.658s2.434-6.114 2.434-52.69-2.434-53.035-2.434-53.035Z" fill="var(--color1, #f01111)"/>
|
|
51
|
+
<path id="color2" d="M-264.32-30.406h123.41s-2.867 4.924-2.907 49.828c-.05 52.505 2.907 55.897 2.907 55.897h-123.41s-2-6.211-2-52.787 2-52.938 2-52.938Z" fill="var(--color2, #ea3333)"/>
|
|
52
|
+
<path d="M-266.86-32.502h728.398v9.434H-266.86z" fill="#2f2f2f" fill-opacity="0.6"/>
|
|
53
|
+
<path d="M-266.31-40.262h728.512v9.434H-266.31z" fill="#2f2f2f" fill-opacity="0.2" transform="scale(1 -1)"/>
|
|
54
|
+
<path d="M-266.12-30.649h731.103V74.982H-266.12z" fill="url(#i)" fill-opacity="0.2"/>
|
|
55
|
+
</svg>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<footer class="sidebar-footer">
|
|
2
|
+
<div class="sidebar-footer-left">
|
|
3
|
+
<button class="btn theme-toggle" type="button" id="theme-toggle" aria-label="Toggle dark mode" aria-pressed="false">
|
|
4
|
+
<span class="theme-pill" aria-hidden="true">
|
|
5
|
+
{% include components/sidebar/theme_toggle_icon.svg %}
|
|
6
|
+
</span>
|
|
7
|
+
</button>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div class="sidebar-footer-right">
|
|
11
|
+
{% include footer-right.html %}
|
|
12
|
+
</div>
|
|
13
|
+
</footer>
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
(function () {
|
|
17
|
+
var storageKey = "site-theme";
|
|
18
|
+
var root = document.documentElement;
|
|
19
|
+
var toggle = document.getElementById("theme-toggle");
|
|
20
|
+
|
|
21
|
+
if (!toggle) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getPreference() {
|
|
26
|
+
var saved = localStorage.getItem(storageKey);
|
|
27
|
+
return saved === "dark" ? "dark" : "light";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function setPreference(theme) {
|
|
31
|
+
localStorage.setItem(storageKey, theme);
|
|
32
|
+
root.setAttribute("data-theme", theme);
|
|
33
|
+
refreshUI();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function refreshUI() {
|
|
37
|
+
var current = getPreference();
|
|
38
|
+
toggle.setAttribute("data-theme-preference", current);
|
|
39
|
+
toggle.setAttribute("data-resolved-theme", current);
|
|
40
|
+
toggle.setAttribute("aria-pressed", current === "dark" ? "true" : "false");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
toggle.addEventListener("click", function () {
|
|
44
|
+
setPreference(getPreference() === "dark" ? "light" : "dark");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
refreshUI();
|
|
48
|
+
})();
|
|
49
|
+
</script>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg class="sidebar-menu-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
|
|
2
|
+
<g class="menu-icon-hamburger">
|
|
3
|
+
<line class="menu-line" x1="4" y1="7" x2="20" y2="7"></line>
|
|
4
|
+
<line class="menu-line" x1="4" y1="12" x2="20" y2="12"></line>
|
|
5
|
+
<line class="menu-line" x1="4" y1="17" x2="20" y2="17"></line>
|
|
6
|
+
</g>
|
|
7
|
+
<g class="menu-icon-close">
|
|
8
|
+
<line class="menu-line" x1="6" y1="6" x2="18" y2="18"></line>
|
|
9
|
+
<line class="menu-line" x1="18" y1="6" x2="6" y2="18"></line>
|
|
10
|
+
</g>
|
|
11
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="523.6 708 1325 100">
|
|
2
|
+
<defs>
|
|
3
|
+
<filter id="notebook-weathered-edge">
|
|
4
|
+
<feTurbulence type="fractalNoise" baseFrequency="0.04" numOctaves="4" result="noise" />
|
|
5
|
+
<feDisplacementMap in="SourceGraphic" in2="noise" scale="2" />
|
|
6
|
+
</filter>
|
|
7
|
+
<filter id="dirt-alpha-map" x="524.073" y="709.92" width="1279.85" height="98.468" filterUnits="userSpaceOnUse"
|
|
8
|
+
color-interpolation-filters="sRGB">
|
|
9
|
+
<feColorMatrix in="SourceGraphic" type="luminanceToAlpha" result="lumaAlpha" />
|
|
10
|
+
<feComponentTransfer in="lumaAlpha" result="invAlpha">
|
|
11
|
+
<feFuncA type="table" tableValues="1 0" />
|
|
12
|
+
</feComponentTransfer>
|
|
13
|
+
<feComponentTransfer in="invAlpha" result="contrastAlpha">
|
|
14
|
+
<feFuncA type="linear" slope="1.35" intercept="-0.12" />
|
|
15
|
+
</feComponentTransfer>
|
|
16
|
+
<feFlood flood-color="#ffffff" result="white" />
|
|
17
|
+
<feComposite in="white" in2="contrastAlpha" operator="in" />
|
|
18
|
+
</filter>
|
|
19
|
+
<mask id="bg-dirt-mask" x="524.073" y="709.92" width="1279.85" height="98.468"
|
|
20
|
+
maskUnits="userSpaceOnUse" maskContentUnits="userSpaceOnUse" style="mask-type: alpha;">
|
|
21
|
+
<image href="/assets/site_media/noteback.png" x="524.073" y="709.92" width="1279.85" height="98.468"
|
|
22
|
+
preserveAspectRatio="none" filter="url(#dirt-alpha-map)" />
|
|
23
|
+
</mask>
|
|
24
|
+
</defs>
|
|
25
|
+
<g filter="url(#notebook-weathered-edge)">
|
|
26
|
+
<rect id="bg" width="1279.85" height="98.468" x="524.073" y="709.92" rx="5" ry="5"
|
|
27
|
+
fill="var(--notebook-color, #f23131)" />
|
|
28
|
+
<path id="tophighlight" d="M530.131 708.7h1268.06a5 5 0 0 1 5 5v6.926H525.131V713.7a5 5 0 0 1 5-5Z"
|
|
29
|
+
fill="#ddd" fill-opacity="0.58" />
|
|
30
|
+
<path id="bottomhighlight" d="M523.636 795.54h1278.06v3.713H523.636z" fill="#d5d5d5" fill-opacity="0.58" />
|
|
31
|
+
</g>
|
|
32
|
+
<rect id="dirt" width="1279.85" height="98.468" x="524.073" y="709.92" rx="5" ry="5"
|
|
33
|
+
fill="#000" fill-opacity="0.48" mask="url(#bg-dirt-mask)" />
|
|
34
|
+
<path id="label" d="M615.637 725.21h940.318v64.429H615.637z" fill="var(--label-color, #fff)" />
|
|
35
|
+
<path id="tape"
|
|
36
|
+
d="m574.136 710.45 9.476 5.379-7.574 8.135 9.475 5.378-7.574 8.134 9.476 5.378-7.574 8.134 9.476 5.378-7.574 8.135 9.476 5.378-7.573 8.134 9.475 5.378-7.573 8.134 9.475 5.379-7.573 8.135 4.475 3.378 1011.305 1.001-8.33-6.772 7.67-4.772-8.34-6.772 7.67-4.772-8.34-6.772 7.67-4.772-8.34-6.772 7.67-4.772-8.33-6.772 7.66-4.771-8.33-6.772 7.66-4.772-8.33-6.772 7.66-4.772-8.33-6.772 5.97-6.998z"
|
|
37
|
+
fill="#ccd0c0" fill-opacity="0.5" />
|
|
38
|
+
</svg>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{% assign stack_projects = include.projects | default: site.projects %}
|
|
2
|
+
|
|
3
|
+
<div class="project-stack">
|
|
4
|
+
{% if stack_projects.size > 0 %}
|
|
5
|
+
{% for project in stack_projects %}
|
|
6
|
+
{% if project.draft != true %}
|
|
7
|
+
{% stack_row type=project.type project=project current_url=include.current_url %}
|
|
8
|
+
{% endif %}
|
|
9
|
+
{% endfor %}
|
|
10
|
+
{% else %}
|
|
11
|
+
<p style="color: #9898b8; font-style: italic; margin-top: 2rem;">Projects incoming - check back soon.</p>
|
|
12
|
+
{% endif %}
|
|
13
|
+
{% include components/sidebar/shelf.html %}
|
|
14
|
+
</div>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<aside class="site-sidebar" id="site-sidebar" data-menu-open="false">
|
|
2
|
+
<header class="sidebar-header">
|
|
3
|
+
<div class="sidebar-name">
|
|
4
|
+
<a
|
|
5
|
+
{% if page.url contains '/about' or page.url contains 'projects' %}
|
|
6
|
+
href="{{ '/' | relative_url }}"
|
|
7
|
+
{% else %}
|
|
8
|
+
href="{{ '/about' | relative_url }}" style="cursor:help"
|
|
9
|
+
{% endif %}>
|
|
10
|
+
<h1>{{ site.title }}</h1>
|
|
11
|
+
</a>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<button
|
|
15
|
+
class="sidebar-menu-toggle"
|
|
16
|
+
id="sidebar-menu-toggle"
|
|
17
|
+
type="button"
|
|
18
|
+
aria-controls="sidebar-menu-content"
|
|
19
|
+
aria-expanded="false"
|
|
20
|
+
aria-label="Open menu">
|
|
21
|
+
{% include components/sidebar/menu_icon.svg %}
|
|
22
|
+
</button>
|
|
23
|
+
</header>
|
|
24
|
+
|
|
25
|
+
<div class="sidebar-menu-content" id="sidebar-menu-content">
|
|
26
|
+
{% include components/sidebar/project-stack.html projects=site.projects current_url=page.url %}
|
|
27
|
+
</div>
|
|
28
|
+
{% include components/sidebar/footer.html %}
|
|
29
|
+
</aside>
|
|
30
|
+
|
|
31
|
+
<script>
|
|
32
|
+
(function () {
|
|
33
|
+
var mobileQuery = window.matchMedia("(max-width: 800px)");
|
|
34
|
+
var sidebar = document.getElementById("site-sidebar");
|
|
35
|
+
var toggle = document.getElementById("sidebar-menu-toggle");
|
|
36
|
+
|
|
37
|
+
if (!sidebar || !toggle) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function setOpenState(isOpen) {
|
|
42
|
+
sidebar.setAttribute("data-menu-open", isOpen ? "true" : "false");
|
|
43
|
+
toggle.setAttribute("aria-expanded", isOpen ? "true" : "false");
|
|
44
|
+
toggle.setAttribute("aria-label", isOpen ? "Close menu" : "Open menu");
|
|
45
|
+
document.body.classList.toggle("sidebar-menu-open", isOpen && mobileQuery.matches);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function closeOnDesktop() {
|
|
49
|
+
if (!mobileQuery.matches) {
|
|
50
|
+
setOpenState(false);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
toggle.addEventListener("click", function () {
|
|
55
|
+
var currentlyOpen = sidebar.getAttribute("data-menu-open") === "true";
|
|
56
|
+
setOpenState(!currentlyOpen);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
sidebar.addEventListener("click", function (event) {
|
|
60
|
+
if (!mobileQuery.matches || sidebar.getAttribute("data-menu-open") !== "true") {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (event.target.closest("a")) {
|
|
65
|
+
setOpenState(false);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
document.addEventListener("keydown", function (event) {
|
|
70
|
+
if (event.key === "Escape" && sidebar.getAttribute("data-menu-open") === "true") {
|
|
71
|
+
setOpenState(false);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (typeof mobileQuery.addEventListener === "function") {
|
|
76
|
+
mobileQuery.addEventListener("change", closeOnDesktop);
|
|
77
|
+
} else if (typeof mobileQuery.addListener === "function") {
|
|
78
|
+
mobileQuery.addListener(closeOnDesktop);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
setOpenState(false);
|
|
82
|
+
})();
|
|
83
|
+
</script>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-375.83 -543.84 1280.31 182.217" width="1280.31" height="182.217">
|
|
2
|
+
<defs>
|
|
3
|
+
<filter id="weathered-edge">
|
|
4
|
+
<feTurbulence type="fractalNoise" baseFrequency="0.04" numOctaves="4" result="noise"></feTurbulence>
|
|
5
|
+
<feDisplacementMap in="SourceGraphic" in2="noise" scale="2"></feDisplacementMap>
|
|
6
|
+
</filter>
|
|
7
|
+
<filter id="ink-grain">
|
|
8
|
+
<feTurbulence type="fractalNoise" baseFrequency="0.8" numOctaves="3" result="rawNoise"></feTurbulence>
|
|
9
|
+
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 -2.5" in="rawNoise" result="grainMask"></feColorMatrix>
|
|
10
|
+
<feComposite operator="in" in="SourceGraphic" in2="grainMask"></feComposite>
|
|
11
|
+
</filter>
|
|
12
|
+
</defs>
|
|
13
|
+
<rect id="shading" x="-375.83" y="-543.84" width="1280.31" height="182.217" stroke="#000" stroke-width="6px" fill="#3b3b3b" rx="21" ry="21"></rect>
|
|
14
|
+
<rect id="bg" x="-348.03" y="-540.85" width="1224.63" height="176.764" fill="#252525" rx="21" ry="21"></rect>
|
|
15
|
+
<path id="tabhole" fill="#000" d="M-243.58-455.95h63.673v78.748h-63.673z"></path>
|
|
16
|
+
<rect id="tab" x="-235.46" y="-433.93" width="47.428" height="59.515" style="opacity: var(--tab_unlocked, 1); fill: rgb(37, 37, 37);" rx="1" ry="1"></rect>
|
|
17
|
+
<path id="midline" stroke="#000" d="m-375.146-456.012 1278.06-.984"></path>
|
|
18
|
+
<g filter="url(#weathered-edge)">
|
|
19
|
+
<rect id="label" x="-148.48" y="-524.14" width="962.097" height="144.125" fill="#fff" rx="9" ry="9"></rect>
|
|
20
|
+
</g>
|
|
21
|
+
<path id="color1" style="fill: var(--color1, #fff);" d="M-106.04-524.28h-33.736a9 9 0 0 0-9 9v126.407a9 9 0 0 0 9 9H-106.04z"></path>
|
|
22
|
+
<path id="color2" style="fill: var(--color2, #fff);" d="M -108.14 -379.87 L -65.4 -379.87 L -65.4 -524.28 L -108.14 -524.28 L -108.14 -379.87 Z"></path>
|
|
23
|
+
<path id="color3" style="fill: var(--color3, #fff);" d="M -69 -379.87 L -26.264 -379.87 L -26.264 -524.28 L -69 -524.28 L -69 -379.87 Z"></path>
|
|
24
|
+
<path id="color4" style="fill: var(--color4, #fff);" d="M 689.914 -524.28 L 732.65 -524.28 L 732.65 -379.87 L 689.914 -379.87 L 689.914 -524.28 Z"></path>
|
|
25
|
+
<path id="color5" style="fill: var(--color5, #fff);" d="M 730.006 -524.28 L 772.742 -524.28 L 772.742 -379.87 L 730.006 -379.87 L 730.006 -524.28 Z"></path>
|
|
26
|
+
<path id="color6" style="fill: var(--color6, #fff);" d="M770.654-524.28h33.736a9 9 0 0 1 9 9v126.407a9 9 0 0 1-9 9h-33.736z"></path>
|
|
27
|
+
<g filter="url(#ink-grain)" >
|
|
28
|
+
<rect id="bg-2" x="-348.03" y="-540.85" width="1224.63" height="176.764" style="fill-opacity:.1;fill:#777" rx="21" ry="21"></rect>
|
|
29
|
+
</g>
|
|
30
|
+
</svg>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<svg viewBox="0 0 64 32" role="presentation" focusable="false">
|
|
2
|
+
<rect class="theme-pill-track" x="1" y="1" width="62" height="30" rx="15" stroke-width="2"></rect>
|
|
3
|
+
<g class="theme-pill-sun" transform="translate(10 10)" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
|
|
4
|
+
<circle cx="6" cy="6" r="3.4"></circle>
|
|
5
|
+
<line x1="6" y1="0.2" x2="6" y2="-2.2"></line>
|
|
6
|
+
<line x1="6" y1="12.2" x2="6" y2="14.6"></line>
|
|
7
|
+
<line x1="0.2" y1="6" x2="-2.2" y2="6"></line>
|
|
8
|
+
<line x1="12.2" y1="6" x2="14.6" y2="6"></line>
|
|
9
|
+
</g>
|
|
10
|
+
<g class="theme-pill-moon" transform="translate(42 10)" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
|
|
11
|
+
<path d="M9.2 2.2a5.8 5.8 0 1 0 0 7.6 6.9 6.9 0 1 1 0-7.6z"></path>
|
|
12
|
+
</g>
|
|
13
|
+
<circle class="theme-pill-thumb" cx="16" cy="16" r="11"></circle>
|
|
14
|
+
</svg>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>{% if page.title %}{{ page.title }} | {{ site.title }}{% else %}{{ site.title }}{% endif %}</title>
|
|
7
|
+
<meta name="description" content="{% if page.description %}{{ page.description }}{% else %}{{ site.description }}{% endif %}">
|
|
8
|
+
<script>
|
|
9
|
+
(function () {
|
|
10
|
+
var storageKey = "site-theme";
|
|
11
|
+
var savedTheme = localStorage.getItem(storageKey);
|
|
12
|
+
var initialTheme = savedTheme === "light" || savedTheme === "dark" || savedTheme === "system" ? savedTheme : "light";
|
|
13
|
+
document.documentElement.setAttribute("data-theme", initialTheme);
|
|
14
|
+
})();
|
|
15
|
+
</script>
|
|
16
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
17
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
18
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
19
|
+
<link rel="stylesheet" href="{{ '/assets/css/main.css' | relative_url }}">
|
|
20
|
+
<link rel="icon" type="image/png" href="{{ '/assets/site_media/favicon.png' | relative_url }}">
|
|
21
|
+
{% seo %}
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
<div class="site-wrapper">
|
|
25
|
+
{% include components/sidebar/sidebar.html %}
|
|
26
|
+
<main class="site-main" id="main-content">
|
|
27
|
+
{% include content-top.html %}
|
|
28
|
+
{{ content }}
|
|
29
|
+
</main>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
</body>
|
|
33
|
+
</html>
|
data/_layouts/page.html
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
---
|
|
4
|
+
<article class="article">
|
|
5
|
+
<header class="page-header">
|
|
6
|
+
<div class="header-text-wrapper">
|
|
7
|
+
<h1 class="page-title">{{ page.title }}</h1>
|
|
8
|
+
{% if page.description %}
|
|
9
|
+
<p class="page-desc">{{ page.description }}</p>
|
|
10
|
+
{% endif %}
|
|
11
|
+
</div>
|
|
12
|
+
{% if page.image %}
|
|
13
|
+
<div class="header-image-wrapper">
|
|
14
|
+
<img src="{{ page.image | relative_url }}" alt="{{ page.title }}" style="height: 300px; width: auto;">
|
|
15
|
+
</div>
|
|
16
|
+
{% endif %}
|
|
17
|
+
</header>
|
|
18
|
+
<div class="page-content">
|
|
19
|
+
{{ content }}
|
|
20
|
+
</div>
|
|
21
|
+
</article>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: default
|
|
3
|
+
---
|
|
4
|
+
<article class="article">
|
|
5
|
+
<header class="page-header">
|
|
6
|
+
<div class="header-text-wrapper">
|
|
7
|
+
{% if page.show_title %}
|
|
8
|
+
<h1 class="page-title">{{ page.title }}</h1>
|
|
9
|
+
{% endif %}
|
|
10
|
+
{% include page_hero.html %}
|
|
11
|
+
{% if page.description %}
|
|
12
|
+
<p class="page-desc" style="color: var(--text-secondary, #9898b8); font-size: 1.1rem; margin-top: 0.5rem;">{{ page.description }}</p>
|
|
13
|
+
{% endif %}
|
|
14
|
+
</div>
|
|
15
|
+
</header>
|
|
16
|
+
<div class="page-content">
|
|
17
|
+
{{ content }}
|
|
18
|
+
</div>
|
|
19
|
+
</article>
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'cgi'
|
|
4
|
+
|
|
5
|
+
# Registers the `stack_row` Liquid tag.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# {% stack_row project=project current_url=include.current_url %}
|
|
9
|
+
# {% stack_row tape project=project current_url=include.current_url %}
|
|
10
|
+
# {% stack_row notebook project=project current_url=include.current_url %}
|
|
11
|
+
# {% stack_row cd project=project current_url=include.current_url %}
|
|
12
|
+
#
|
|
13
|
+
# The row type can be passed explicitly or inferred from the project's `type`
|
|
14
|
+
# front matter. Supported types: tape/vhs, notebook, and cd.
|
|
15
|
+
# Named parameters are resolved as Liquid variables from the calling context.
|
|
16
|
+
#
|
|
17
|
+
# Transform limits and seed are read from _config.yml:
|
|
18
|
+
# stack_transform:
|
|
19
|
+
# seed: 42
|
|
20
|
+
# translate_max: 20
|
|
21
|
+
|
|
22
|
+
module Jekyll
|
|
23
|
+
class StackRowTag < Liquid::Tag
|
|
24
|
+
STACK_SVG_FILES = {
|
|
25
|
+
'tape' => 'tape.svg',
|
|
26
|
+
'vhs' => 'tape.svg',
|
|
27
|
+
'notebook' => 'notebook.svg',
|
|
28
|
+
'cd' => 'cd.svg'
|
|
29
|
+
}.freeze
|
|
30
|
+
|
|
31
|
+
def initialize(tag_name, markup, tokens)
|
|
32
|
+
super
|
|
33
|
+
parts = markup.strip.split(/\s+/, 2)
|
|
34
|
+
|
|
35
|
+
if parts[0].to_s.include?('=')
|
|
36
|
+
@row_type = ''
|
|
37
|
+
@raw_params = markup.to_s
|
|
38
|
+
else
|
|
39
|
+
@row_type = parts[0].to_s.strip
|
|
40
|
+
@raw_params = parts[1].to_s
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def render(context)
|
|
45
|
+
params = {}
|
|
46
|
+
@raw_params.scan(/(\w+)=([\w.]+)/) do |key, val|
|
|
47
|
+
params[key] = context[val]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
project = params['project']
|
|
51
|
+
current_url = params['current_url'].to_s
|
|
52
|
+
return '' if project.nil?
|
|
53
|
+
|
|
54
|
+
site = context.registers[:site]
|
|
55
|
+
cfg = Jekyll.configuration.dig("project-stack-portfolio", "stack_transform") || {}
|
|
56
|
+
seed = cfg.fetch('seed', 42).to_i
|
|
57
|
+
tx_max = cfg.fetch('translate_max', 20).to_f
|
|
58
|
+
|
|
59
|
+
project_url = project.url.to_s
|
|
60
|
+
translate_x = seeded_rand("#{project_url}tx", seed, -tx_max, tx_max)
|
|
61
|
+
|
|
62
|
+
is_current = current_url.include?(project_url)
|
|
63
|
+
link_class = is_current ? 'project-stack-item disabled' : 'project-stack-item'
|
|
64
|
+
style_class = project['stack_style'].to_s.strip
|
|
65
|
+
stack_type = normalize_stack_type(params['type'] || @row_type || project['type'])
|
|
66
|
+
art_class = ['project-stack-item-art', style_class].reject(&:empty?).join(' ')
|
|
67
|
+
row_class = ['project-stack-item-row', "project-stack-item-row--#{stack_type}"].join(' ')
|
|
68
|
+
link_class = [link_class, "project-stack-item--#{stack_type}"].join(' ')
|
|
69
|
+
baseurl = site.config['baseurl'].to_s
|
|
70
|
+
href = "#{baseurl}#{project_url}"
|
|
71
|
+
title = CGI.escape_html(project['title'].to_s.upcase)
|
|
72
|
+
stack_svg = read_stack_svg(site, stack_type)
|
|
73
|
+
|
|
74
|
+
<<~HTML
|
|
75
|
+
<div class="#{row_class}">
|
|
76
|
+
<a class="#{link_class}" style="transform: translateX(#{translate_x}px);" href="#{href}">
|
|
77
|
+
<div class="#{art_class}" aria-hidden="true">
|
|
78
|
+
#{stack_svg}
|
|
79
|
+
<div class="stack-item-text stack-item-text1 stack-item-text1--#{stack_type}"></div>
|
|
80
|
+
<div class="stack-item-text stack-item-text2 stack-item-text2--#{stack_type}"></div>
|
|
81
|
+
<div class="stack-item-text stack-item-text3 stack-item-text3--#{stack_type}"></div>
|
|
82
|
+
<div class="stack-item-text stack-item-text4 stack-item-text4--#{stack_type}"></div>
|
|
83
|
+
<div class="stack-item-text stack-item-text5 stack-item-text5--#{stack_type}"></div>
|
|
84
|
+
<div class="stack-item-text stack-item-text6 stack-item-text6--#{stack_type}"></div>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="project-stack-item-label" aria-hidden="true">
|
|
87
|
+
<svg viewBox="0 0 500 50" width="100%" role="presentation" focusable="false">
|
|
88
|
+
<text x="0" y="40" font-size="40" font-weight="700" textLength="100%" lengthAdjust="spacingAndGlyphs">#{title}</text>
|
|
89
|
+
</svg>
|
|
90
|
+
</div>
|
|
91
|
+
</a>
|
|
92
|
+
</div>
|
|
93
|
+
HTML
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
def normalize_stack_type(value)
|
|
99
|
+
case value.to_s.downcase.strip
|
|
100
|
+
when 'notebook'
|
|
101
|
+
'notebook'
|
|
102
|
+
when 'cd'
|
|
103
|
+
'cd'
|
|
104
|
+
when 'vhs', 'tape'
|
|
105
|
+
'tape'
|
|
106
|
+
else
|
|
107
|
+
'tape'
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Deterministic pseudo-random float in [min, max] keyed on input string + seed.
|
|
112
|
+
# Byte-based hash is stable across Ruby versions (String#hash is randomized).
|
|
113
|
+
def seeded_rand(input, seed, min, max)
|
|
114
|
+
stable = input.bytes.each_with_index.inject(0) { |acc, (b, i)| acc + b * (31**i) }
|
|
115
|
+
rng = Random.new(seed + stable)
|
|
116
|
+
(rng.rand * (max - min) + min).round(2)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def read_stack_svg(site, stack_type)
|
|
120
|
+
svg_file = STACK_SVG_FILES.fetch(stack_type, STACK_SVG_FILES['tape'])
|
|
121
|
+
site_svg_path = File.join(site.source, '_includes', 'components', 'sidebar', svg_file)
|
|
122
|
+
return File.read(site_svg_path).strip if File.exist?(site_svg_path)
|
|
123
|
+
|
|
124
|
+
gem_svg_path = File.expand_path("../_includes/components/sidebar/#{svg_file}", __dir__)
|
|
125
|
+
return File.read(gem_svg_path).strip if File.exist?(gem_svg_path)
|
|
126
|
+
|
|
127
|
+
''
|
|
128
|
+
rescue Errno::ENOENT
|
|
129
|
+
''
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
Liquid::Template.register_tag('stack_row', Jekyll::StackRowTag)
|