Compare commits
No commits in common. "main" and "layout" have entirely different histories.
20
README.md
20
README.md
|
@ -1,10 +1,18 @@
|
||||||
# Jessica OnLine 3.0
|
# JOL
|
||||||
|
|
||||||
This free ~~disc~~ repository entitles you to 10 **FREE** hours of Jessica OnLine!
|
To start your Phoenix server:
|
||||||
|
|
||||||
A blogthing that exists at [jess.canady.tech](https://jess.canady.tech).
|
* Run `mix setup` to install and setup dependencies
|
||||||
|
* Start Phoenix endpoint with `mix phx.server` or inside IEx with `iex -S mix phx.server`
|
||||||
|
|
||||||
This is where I write about me. Writing software, playing games, cooking food, being a parent and a partner, and being a giant trans lesbian.
|
Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.
|
||||||
|
|
||||||
> Meet my one-eyed lesbian dad!
|
Ready to run in production? Please [check our deployment guides](https://hexdocs.pm/phoenix/deployment.html).
|
||||||
> --Alex, my eldest son and fiercest champio
|
|
||||||
|
## Learn more
|
||||||
|
|
||||||
|
* Official website: https://www.phoenixframework.org/
|
||||||
|
* Guides: https://hexdocs.pm/phoenix/overview.html
|
||||||
|
* Docs: https://hexdocs.pm/phoenix
|
||||||
|
* Forum: https://elixirforum.com/c/phoenix-forum
|
||||||
|
* Source: https://github.com/phoenixframework/phoenix
|
||||||
|
|
18
TAGS.md
18
TAGS.md
|
@ -1,18 +0,0 @@
|
||||||
# JOL Taxonomy
|
|
||||||
|
|
||||||
Jessica OnLine endorses use of the following taxonomy categories:
|
|
||||||
|
|
||||||
* family
|
|
||||||
* games
|
|
||||||
* hardware
|
|
||||||
* howto
|
|
||||||
* shit's on fire yo
|
|
||||||
* software
|
|
||||||
* trans
|
|
||||||
* review
|
|
||||||
|
|
||||||
## Changelog
|
|
||||||
|
|
||||||
### 2024-08-25
|
|
||||||
|
|
||||||
Added initial list of tags.
|
|
|
@ -1,5 +1,56 @@
|
||||||
.footer {
|
.footer {
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
text-align: center;
|
opacity: 0.5;
|
||||||
opacity: 0.5;
|
}
|
||||||
|
.footer__inner {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 0;
|
||||||
|
width: 760px;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.footer__inner {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.footer a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
.footer .copyright {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
.footer .copyright--user {
|
||||||
|
margin: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.footer .copyright > *:first-child:not(:only-child) {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.footer .copyright > *:first-child:not(:only-child) {
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.footer .copyright {
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.footer .copyright-theme-sep {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.footer .copyright-theme {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
83
assets/css/sass/buttons.css
Normal file
83
assets/css/sass/buttons.css
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
.button-container {
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto; }
|
||||||
|
|
||||||
|
button,
|
||||||
|
.button,
|
||||||
|
a.button {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 8px 18px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
appearance: none;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
/* variants */
|
||||||
|
/* sizes */ }
|
||||||
|
button.outline,
|
||||||
|
.button.outline,
|
||||||
|
a.button.outline {
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
padding: 8px 18px; }
|
||||||
|
button.outline :hover,
|
||||||
|
.button.outline :hover,
|
||||||
|
a.button.outline :hover {
|
||||||
|
transform: none;
|
||||||
|
box-shadow: none; }
|
||||||
|
button.primary,
|
||||||
|
.button.primary,
|
||||||
|
a.button.primary {
|
||||||
|
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08); }
|
||||||
|
button.primary:hover,
|
||||||
|
.button.primary:hover,
|
||||||
|
a.button.primary:hover {
|
||||||
|
box-shadow: 0 2px 6px rgba(50, 50, 93, 0.21), 0 1px 3px rgba(0, 0, 0, 0.08); }
|
||||||
|
button.link,
|
||||||
|
.button.link,
|
||||||
|
a.button.link {
|
||||||
|
background: none;
|
||||||
|
font-size: 1rem; }
|
||||||
|
button.small,
|
||||||
|
.button.small,
|
||||||
|
a.button.small {
|
||||||
|
font-size: .8rem; }
|
||||||
|
button.wide,
|
||||||
|
.button.wide,
|
||||||
|
a.button.wide {
|
||||||
|
min-width: 200px;
|
||||||
|
padding: 14px 24px; }
|
||||||
|
|
||||||
|
a.read-more,
|
||||||
|
a.read-more:hover,
|
||||||
|
a.read-more:active {
|
||||||
|
display: inline-flex;
|
||||||
|
background: none;
|
||||||
|
box-shadow: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 20px 0;
|
||||||
|
max-width: 100%; }
|
||||||
|
|
||||||
|
.code-toolbar {
|
||||||
|
margin-bottom: 20px; }
|
||||||
|
.code-toolbar .toolbar-item a {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 3px 8px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
appearance: none;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none; }
|
92
assets/css/sass/buttons.scss
Normal file
92
assets/css/sass/buttons.scss
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
.button-container {
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
.button,
|
||||||
|
a.button {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 8px 18px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
appearance: none;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
/* variants */
|
||||||
|
|
||||||
|
&.outline {
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
padding: 8px 18px;
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
transform: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.primary {
|
||||||
|
box-shadow: 0 4px 6px rgba(50, 50, 93, .11), 0 1px 3px rgba(0, 0, 0, .08);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 2px 6px rgba(50, 50, 93, .21), 0 1px 3px rgba(0, 0, 0, .08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.link {
|
||||||
|
background: none;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* sizes */
|
||||||
|
|
||||||
|
&.small {
|
||||||
|
font-size: .8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.wide {
|
||||||
|
min-width: 200px;
|
||||||
|
padding: 14px 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.read-more,
|
||||||
|
a.read-more:hover,
|
||||||
|
a.read-more:active {
|
||||||
|
display: inline-flex;
|
||||||
|
background: none;
|
||||||
|
box-shadow: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 20px 0;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-toolbar {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.toolbar-item a {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 3px 8px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
appearance: none;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
14
assets/css/sass/color/background_auto.scss
Normal file
14
assets/css/sass/color/background_auto.scss
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
:root {
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
--background: white;
|
||||||
|
|
||||||
|
--color: #101010;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
--background: #101010;
|
||||||
|
|
||||||
|
--color: #A9B7C6;
|
||||||
|
}
|
||||||
|
}
|
3
assets/css/sass/color/background_blue.scss
Normal file
3
assets/css/sass/color/background_blue.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
:root {
|
||||||
|
--background: #1D212C;
|
||||||
|
}
|
5
assets/css/sass/color/background_dark.scss
Normal file
5
assets/css/sass/color/background_dark.scss
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
:root {
|
||||||
|
--background: #101010;
|
||||||
|
|
||||||
|
--color: #A9B7C6;
|
||||||
|
}
|
3
assets/css/sass/color/background_green.scss
Normal file
3
assets/css/sass/color/background_green.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
:root {
|
||||||
|
--background: #1F222A;
|
||||||
|
}
|
3
assets/css/sass/color/background_light.scss
Normal file
3
assets/css/sass/color/background_light.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
:root {
|
||||||
|
--background: #f0f0f0;
|
||||||
|
}
|
3
assets/css/sass/color/background_orange.scss
Normal file
3
assets/css/sass/color/background_orange.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
:root {
|
||||||
|
--background: #222129;
|
||||||
|
}
|
3
assets/css/sass/color/background_pink.scss
Normal file
3
assets/css/sass/color/background_pink.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
:root {
|
||||||
|
--background: #21202C;
|
||||||
|
}
|
3
assets/css/sass/color/background_red.scss
Normal file
3
assets/css/sass/color/background_red.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
:root {
|
||||||
|
--background: #221F29;
|
||||||
|
}
|
29
assets/css/sass/color/blue-auto.scss
Normal file
29
assets/css/sass/color/blue-auto.scss
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
:root {
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
--accent: rgb(35,176,255);
|
||||||
|
--accent-alpha-70: rgba(35,176,255,.7);
|
||||||
|
--accent-alpha-20: rgba(35,176,255,.2);
|
||||||
|
|
||||||
|
--background: #101010;
|
||||||
|
--color: #f0f0f0;
|
||||||
|
--border-color: rgba(255,240,224,.125);
|
||||||
|
|
||||||
|
div.logo {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
--accent: rgb(32,128,192);
|
||||||
|
--accent-alpha-70: rgba(32,128,192,.7);
|
||||||
|
--accent-alpha-20: rgba(32,128,192,.2);
|
||||||
|
|
||||||
|
--background: white;
|
||||||
|
--color: #201030;
|
||||||
|
--border-color: rgba(0,0,16,.125);
|
||||||
|
|
||||||
|
div.logo {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
assets/css/sass/color/blue-light.scss
Normal file
12
assets/css/sass/color/blue-light.scss
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
:root {
|
||||||
|
--accent: rgb(32,128,192);
|
||||||
|
--accent-alpha-70: rgba(32,128,192,.7);
|
||||||
|
--accent-alpha-20: rgba(32,128,192,.2);
|
||||||
|
|
||||||
|
--background: white;
|
||||||
|
--color: #1D212C;
|
||||||
|
--border-color: rgba(0, 0, 0, .1);
|
||||||
|
div.logo {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
9
assets/css/sass/color/blue.scss
Normal file
9
assets/css/sass/color/blue.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
:root {
|
||||||
|
--accent: rgb(35,176,255);
|
||||||
|
--accent-alpha-70: rgba(35,176,255,.7);
|
||||||
|
--accent-alpha-20: rgba(35,176,255,.2);
|
||||||
|
|
||||||
|
--background: #1D212C;
|
||||||
|
--color: white;
|
||||||
|
--border-color: rgba(255, 255, 255, .1);
|
||||||
|
}
|
29
assets/css/sass/color/green-auto.scss
Normal file
29
assets/css/sass/color/green-auto.scss
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
:root {
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
--accent: rgb(120,226,160);
|
||||||
|
--accent-alpha-70: rgba(120,226,160,.7);
|
||||||
|
--accent-alpha-20: rgba(120,226,160,.2);
|
||||||
|
|
||||||
|
--background: #101010;
|
||||||
|
--color: #f0f0f0;
|
||||||
|
--border-color: rgba(255,240,224,.125);
|
||||||
|
|
||||||
|
div.logo {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
--accent: rgb(24, 192, 128);
|
||||||
|
--accent-alpha-70: rgba(24, 192, 128,.7);
|
||||||
|
--accent-alpha-20: rgba(24, 192, 128,.2);
|
||||||
|
|
||||||
|
--background: white;
|
||||||
|
--color: #201030;
|
||||||
|
--border-color: rgba(0,0,16,.125);
|
||||||
|
|
||||||
|
div.logo {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
assets/css/sass/color/green-light.scss
Normal file
12
assets/css/sass/color/green-light.scss
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
:root {
|
||||||
|
--accent: rgb(24, 192, 128);
|
||||||
|
--accent-alpha-70: rgba(24, 192, 128,.7);
|
||||||
|
--accent-alpha-20: rgba(24, 192, 128,.2);
|
||||||
|
|
||||||
|
--background: white;
|
||||||
|
--color: #1D212C;
|
||||||
|
--border-color: rgba(0, 0, 0, .1);
|
||||||
|
div.logo {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
9
assets/css/sass/color/green.scss
Normal file
9
assets/css/sass/color/green.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
:root {
|
||||||
|
--accent: rgb(120,226,160);
|
||||||
|
--accent-alpha-70: rgba(120,226,160,.7);
|
||||||
|
--accent-alpha-20: rgba(120,226,160,.2);
|
||||||
|
|
||||||
|
--background: #1F222A;
|
||||||
|
--color: white;
|
||||||
|
--border-color: rgba(255, 255, 255, .1);
|
||||||
|
}
|
29
assets/css/sass/color/orange-auto.scss
Normal file
29
assets/css/sass/color/orange-auto.scss
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
:root {
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
--accent: rgb(255,168,106);
|
||||||
|
--accent-alpha-70: rgba(255,168,106,.7);
|
||||||
|
--accent-alpha-20: rgba(255,168,106,.2);
|
||||||
|
|
||||||
|
--background: #101010;
|
||||||
|
--color: #f0f0f0;
|
||||||
|
--border-color: rgba(255,240,224,.125);
|
||||||
|
|
||||||
|
div.logo {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
--accent: rgb(240,128,48);
|
||||||
|
--accent-alpha-70: rgba(240,128,48,.7);
|
||||||
|
--accent-alpha-20: rgba(240,128,48,.2);
|
||||||
|
|
||||||
|
--background: white;
|
||||||
|
--color: #201030;
|
||||||
|
--border-color: rgba(0,0,16,.125);
|
||||||
|
|
||||||
|
div.logo {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
assets/css/sass/color/orange-light.scss
Normal file
12
assets/css/sass/color/orange-light.scss
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
:root {
|
||||||
|
--accent: rgb(240,128,48);
|
||||||
|
--accent-alpha-70: rgba(240,128,48,.7);
|
||||||
|
--accent-alpha-20: rgba(240,128,48,.2);
|
||||||
|
|
||||||
|
--background: white;
|
||||||
|
--color: #1D212C;
|
||||||
|
--border-color: rgba(0, 0, 0, .1);
|
||||||
|
div.logo {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
9
assets/css/sass/color/orange.scss
Normal file
9
assets/css/sass/color/orange.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
:root {
|
||||||
|
--accent: rgb(255,168,106);
|
||||||
|
--accent-alpha-70: rgba(255,168,106,.7);
|
||||||
|
--accent-alpha-20: rgba(255,168,106,.2);
|
||||||
|
|
||||||
|
--background: #222129;
|
||||||
|
--color: white;
|
||||||
|
--border-color: rgba(255, 255, 255, .1);
|
||||||
|
}
|
29
assets/css/sass/color/pink-auto.scss
Normal file
29
assets/css/sass/color/pink-auto.scss
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
:root {
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
--accent: rgb(224,64,192);
|
||||||
|
--accent-alpha-70: rgba(224,64,192);
|
||||||
|
--accent-alpha-20: rgba(224,64,192,.2);
|
||||||
|
|
||||||
|
--background: #101010;
|
||||||
|
--color: #f0f0f0;
|
||||||
|
--border-color: rgba(255,240,224,.125);
|
||||||
|
|
||||||
|
div.logo {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
--accent: rgb(238,114,241);
|
||||||
|
--accent-alpha-70: rgba(238,114,241,.7);
|
||||||
|
--accent-alpha-20: rgba(238,114,241,.2);
|
||||||
|
|
||||||
|
--background: white;
|
||||||
|
--color: #201030;
|
||||||
|
--border-color: rgba(0,0,16,.125);
|
||||||
|
|
||||||
|
div.logo {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
assets/css/sass/color/pink-light.scss
Normal file
12
assets/css/sass/color/pink-light.scss
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
:root {
|
||||||
|
--accent: rgb(224,64,192);
|
||||||
|
--accent-alpha-70: rgba(224,64,192);
|
||||||
|
--accent-alpha-20: rgba(224,64,192,.2);
|
||||||
|
|
||||||
|
--background: white;
|
||||||
|
--color: #1D212C;
|
||||||
|
--border-color: rgba(0, 0, 0, .1);
|
||||||
|
div.logo {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
9
assets/css/sass/color/pink.scss
Normal file
9
assets/css/sass/color/pink.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
:root {
|
||||||
|
--accent: rgb(238,114,241);
|
||||||
|
--accent-alpha-70: rgba(238,114,241,.7);
|
||||||
|
--accent-alpha-20: rgba(238,114,241,.2);
|
||||||
|
|
||||||
|
--background: #21202C;
|
||||||
|
--color: white;
|
||||||
|
--border-color: rgba(255, 255, 255, .1);
|
||||||
|
}
|
29
assets/css/sass/color/red-auto.scss
Normal file
29
assets/css/sass/color/red-auto.scss
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
:root {
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
--accent: rgb(255,98,102);
|
||||||
|
--accent-alpha-70: rgba(255,98,102,.7);
|
||||||
|
--accent-alpha-20: rgba(255,98,102,.2);
|
||||||
|
|
||||||
|
--background: #101010;
|
||||||
|
--color: #f0f0f0;
|
||||||
|
--border-color: rgba(255,240,224,.125);
|
||||||
|
|
||||||
|
div.logo {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
--accent: rgb(240,48,64);
|
||||||
|
--accent-alpha-70: rgba(240,48,64,.7);
|
||||||
|
--accent-alpha-20: rgba(240,48,64,.2);
|
||||||
|
|
||||||
|
--background: white;
|
||||||
|
--color: #201030;
|
||||||
|
--border-color: rgba(0,0,16,.125);
|
||||||
|
|
||||||
|
div.logo {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
assets/css/sass/color/red-light.scss
Normal file
12
assets/css/sass/color/red-light.scss
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
:root {
|
||||||
|
--accent: rgb(240,48,64);
|
||||||
|
--accent-alpha-70: rgba(240,48,64,.7);
|
||||||
|
--accent-alpha-20: rgba(240,48,64,.2);
|
||||||
|
|
||||||
|
--background: white;
|
||||||
|
--color: #1D212C;
|
||||||
|
--border-color: rgba(0, 0, 0, .1);
|
||||||
|
div.logo {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
9
assets/css/sass/color/red.scss
Normal file
9
assets/css/sass/color/red.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
:root {
|
||||||
|
--accent: rgb(255,98,102);
|
||||||
|
--accent-alpha-70: rgba(255,98,102,.7);
|
||||||
|
--accent-alpha-20: rgba(255,98,102,.2);
|
||||||
|
|
||||||
|
--background: #221F29;
|
||||||
|
--color: white;
|
||||||
|
--border-color: rgba(255, 255, 255, .1);
|
||||||
|
}
|
27
assets/css/sass/font-hack-subset.css
Normal file
27
assets/css/sass/font-hack-subset.css
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*!
|
||||||
|
* Hack typeface https://github.com/source-foundry/Hack
|
||||||
|
* License: https://github.com/source-foundry/Hack/blob/master/LICENSE.md
|
||||||
|
*/
|
||||||
|
/* FONT PATHS
|
||||||
|
* -------------------------- */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
/* Use full version (not a subset) for unicode icon support */
|
||||||
|
src: url("fonts/hack-regular.woff2?sha=3114f1256") format("woff2"), url("fonts/hack-regular.woff?sha=3114f1256") format("woff");
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal; }
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url("fonts/hack-bold-subset.woff2?sha=3114f1256") format("woff2"), url("fonts/hack-bold-subset.woff?sha=3114f1256") format("woff");
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal; }
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url("fonts/hack-italic-subset.woff2?sha=3114f1256") format("woff2"), url("fonts/hack-italic-webfont.woff?sha=3114f1256") format("woff");
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: italic; }
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url("fonts/hack-bolditalic-subset.woff2?sha=3114f1256") format("woff2"), url("fonts/hack-bolditalic-subset.woff?sha=3114f1256") format("woff");
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: italic; }
|
34
assets/css/sass/font-hack-subset.scss
Normal file
34
assets/css/sass/font-hack-subset.scss
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*!
|
||||||
|
* Hack typeface https://github.com/source-foundry/Hack
|
||||||
|
* License: https://github.com/source-foundry/Hack/blob/master/LICENSE.md
|
||||||
|
*/
|
||||||
|
/* FONT PATHS
|
||||||
|
* -------------------------- */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
/* Use full version (not a subset) for unicode icon support */
|
||||||
|
src: url('fonts/hack-regular.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-regular.woff?sha=3114f1256') format('woff');
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url('fonts/hack-bold-subset.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-bold-subset.woff?sha=3114f1256') format('woff');
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url('fonts/hack-italic-subset.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-italic-webfont.woff?sha=3114f1256') format('woff');
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url('fonts/hack-bolditalic-subset.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-bolditalic-subset.woff?sha=3114f1256') format('woff');
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
26
assets/css/sass/font-hack.css
Normal file
26
assets/css/sass/font-hack.css
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*!
|
||||||
|
* Hack typeface https://github.com/source-foundry/Hack
|
||||||
|
* License: https://github.com/source-foundry/Hack/blob/master/LICENSE.md
|
||||||
|
*/
|
||||||
|
/* FONT PATHS
|
||||||
|
* -------------------------- */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url("fonts/hack-regular.woff2?sha=3114f1256") format("woff2"), url("fonts/hack-regular.woff?sha=3114f1256") format("woff");
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal; }
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url("fonts/hack-bold.woff2?sha=3114f1256") format("woff2"), url("fonts/hack-bold.woff?sha=3114f1256") format("woff");
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal; }
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url("fonts/hack-italic.woff2?sha=3114f1256") format("woff2"), url("fonts/hack-italic.woff?sha=3114f1256") format("woff");
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: italic; }
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url("fonts/hack-bolditalic.woff2?sha=3114f1256") format("woff2"), url("fonts/hack-bolditalic.woff?sha=3114f1256") format("woff");
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: italic; }
|
33
assets/css/sass/font-hack.scss
Normal file
33
assets/css/sass/font-hack.scss
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*!
|
||||||
|
* Hack typeface https://github.com/source-foundry/Hack
|
||||||
|
* License: https://github.com/source-foundry/Hack/blob/master/LICENSE.md
|
||||||
|
*/
|
||||||
|
/* FONT PATHS
|
||||||
|
* -------------------------- */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url('fonts/hack-regular.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-regular.woff?sha=3114f1256') format('woff');
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url('fonts/hack-bold.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-bold.woff?sha=3114f1256') format('woff');
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url('fonts/hack-italic.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-italic.woff?sha=3114f1256') format('woff');
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Hack';
|
||||||
|
src: url('fonts/hack-bolditalic.woff2?sha=3114f1256') format('woff2'), url('fonts/hack-bolditalic.woff?sha=3114f1256') format('woff');
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
40
assets/css/sass/footer.css
Normal file
40
assets/css/sass/footer.css
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
.footer {
|
||||||
|
flex-grow: 0;
|
||||||
|
opacity: .5; }
|
||||||
|
.footer__inner {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 0;
|
||||||
|
width: 760px;
|
||||||
|
max-width: 100%; }
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.footer__inner {
|
||||||
|
flex-direction: column; } }
|
||||||
|
.footer a {
|
||||||
|
color: inherit; }
|
||||||
|
.footer .copyright {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 1rem; }
|
||||||
|
.footer .copyright--user {
|
||||||
|
margin: auto;
|
||||||
|
text-align: center; }
|
||||||
|
.footer .copyright > *:first-child:not(:only-child) {
|
||||||
|
margin-right: 10px; }
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.footer .copyright > *:first-child:not(:only-child) {
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0; } }
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.footer .copyright {
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 10px; } }
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.footer .copyright-theme-sep {
|
||||||
|
display: none; } }
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.footer .copyright-theme {
|
||||||
|
font-size: 0.75rem; } }
|
62
assets/css/sass/footer.scss
Normal file
62
assets/css/sass/footer.scss
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
flex-grow: 0;
|
||||||
|
opacity: .5;
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 0;
|
||||||
|
width: 760px;
|
||||||
|
max-width: 100%;
|
||||||
|
|
||||||
|
@media (max-width: $tablet-max-width) {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 1rem;
|
||||||
|
|
||||||
|
&--user {
|
||||||
|
margin: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > *:first-child:not(:only-child) {
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
@media (max-width: $tablet-max-width) {
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $tablet-max-width) {
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright-theme-sep {
|
||||||
|
@media (max-width: $tablet-max-width) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyright-theme {
|
||||||
|
@media (max-width: $tablet-max-width) {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
61
assets/css/sass/header.css
Normal file
61
assets/css/sass/header.css
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative; }
|
||||||
|
.header__inner {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between; }
|
||||||
|
.header__logo {
|
||||||
|
display: flex;
|
||||||
|
flex: 1; }
|
||||||
|
.header__logo:after {
|
||||||
|
content: '';
|
||||||
|
background: repeating-linear-gradient(90deg, var(--accent), var(--accent) 2px, transparent 0, transparent 16px);
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
right: 10px; }
|
||||||
|
.header__logo a {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
max-width: 100%; }
|
||||||
|
.header .menu {
|
||||||
|
margin: 20px 0; }
|
||||||
|
.header .menu__inner {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0; }
|
||||||
|
.header .menu__inner li.active {
|
||||||
|
color: var(--accent-alpha-70); }
|
||||||
|
.header .menu__inner li:not(:last-of-type) {
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
flex: 0 0 auto; }
|
||||||
|
.header .menu__sub-inner {
|
||||||
|
position: relative;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0; }
|
||||||
|
.header .menu__sub-inner:not(:only-child) {
|
||||||
|
margin-left: 20px; }
|
||||||
|
.header .menu__sub-inner-more {
|
||||||
|
position: absolute;
|
||||||
|
background: var(--background);
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
color: white;
|
||||||
|
border: 2px solid;
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px;
|
||||||
|
list-style: none;
|
||||||
|
z-index: 99;
|
||||||
|
top: 35px;
|
||||||
|
left: 0; }
|
||||||
|
.header .menu__sub-inner-more-trigger {
|
||||||
|
color: var(--accent);
|
||||||
|
user-select: none;
|
||||||
|
cursor: pointer; }
|
||||||
|
.header .menu__sub-inner-more li {
|
||||||
|
margin: 0;
|
||||||
|
padding: 5px;
|
||||||
|
white-space: nowrap; }
|
96
assets/css/sass/header.scss
Normal file
96
assets/css/sass/header.scss
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
@mixin menu {
|
||||||
|
position: absolute;
|
||||||
|
background: var(--background);
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
color: white;
|
||||||
|
border: 2px solid;
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px;
|
||||||
|
list-style: none;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__logo {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
background: repeating-linear-gradient(90deg, var(--accent), var(--accent) 2px, transparent 0, transparent 16px);
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
margin: 20px 0;
|
||||||
|
|
||||||
|
&__inner {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
&.active {
|
||||||
|
color: var(--accent-alpha-70);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:last-of-type) {
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__sub-inner {
|
||||||
|
position: relative;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
&:not(:only-child) {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-more {
|
||||||
|
@include menu;
|
||||||
|
top: 35px;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
&-trigger {
|
||||||
|
color: var(--accent);
|
||||||
|
user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 0;
|
||||||
|
padding: 5px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
assets/css/sass/home.css
Normal file
4
assets/css/sass/home.css
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
div.homepage {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(20em, 1fr));
|
||||||
|
grid-gap: 3em; }
|
5
assets/css/sass/home.scss
Normal file
5
assets/css/sass/home.scss
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
div.homepage {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(20em, 1fr));
|
||||||
|
grid-gap: 3em;
|
||||||
|
}
|
7
assets/css/sass/logo.css
Normal file
7
assets/css/sass/logo.css
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-decoration: none;
|
||||||
|
background: var(--accent);
|
||||||
|
color: black;
|
||||||
|
padding: 5px 10px; }
|
8
assets/css/sass/logo.scss
Normal file
8
assets/css/sass/logo.scss
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-decoration: none;
|
||||||
|
background: var(--accent);
|
||||||
|
color: black;
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
66
assets/css/sass/main.css
Normal file
66
assets/css/sass/main.css
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
Error: wrong number of arguments (1 for 3) for `rgb'
|
||||||
|
on line 242 of main.scss
|
||||||
|
|
||||||
|
237: padding: 40px;
|
||||||
|
238: max-width: 864px;
|
||||||
|
239: // min-height: 100vh;
|
||||||
|
240: margin: 2em auto;
|
||||||
|
241:
|
||||||
|
242: background: rgb(0 0 0 / .4);
|
||||||
|
243:
|
||||||
|
244: @media (max-width: $phone-max-width) {
|
||||||
|
245: padding: 20px;
|
||||||
|
246: margin: 0 auto;
|
||||||
|
247: }
|
||||||
|
|
||||||
|
Backtrace:
|
||||||
|
main.scss:242
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/script/tree/funcall.rb:311:in `reformat_argument_error'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/script/tree/funcall.rb:158:in `rescue in _perform'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/script/tree/funcall.rb:127:in `_perform'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/script/tree/node.rb:50:in `perform'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:398:in `visit_prop'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `block in visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `block in with_base'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:135:in `with_frame'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `with_base'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `block (2 levels) in visit_rule'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `map'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `block in visit_rule'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:179:in `with_environment'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:438:in `visit_rule'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `block in visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `block in with_base'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:135:in `with_frame'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `with_base'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:52:in `block in visit_children'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:52:in `map'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:52:in `visit_children'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:167:in `block in visit_children'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:179:in `with_environment'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:166:in `visit_children'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `block in visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:186:in `visit_root'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:157:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:10:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/root_node.rb:36:in `css_tree'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/root_node.rb:20:in `render'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/engine.rb:290:in `render'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/exec/sass_scss.rb:396:in `run'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/exec/sass_scss.rb:63:in `process_result'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/exec/base.rb:50:in `parse'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/exec/base.rb:18:in `parse!'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/bin/sass:13:in `<top (required)>'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/bin/sass:25:in `load'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/bin/sass:25:in `<main>'
|
||||||
|
*/
|
||||||
|
body:before {
|
||||||
|
white-space: pre;
|
||||||
|
font-family: monospace;
|
||||||
|
content: "Error: wrong number of arguments (1 for 3) for `rgb'\A on line 242 of main.scss\A \A 237: padding: 40px;\A 238: max-width: 864px;\A 239: // min-height: 100vh;\A 240: margin: 2em auto;\A 241: \A 242: background: rgb(0 0 0 / .4);\A 243: \A 244: @media (max-width: $phone-max-width) {\A 245: padding: 20px;\A 246: margin: 0 auto;\A 247: }"; }
|
263
assets/css/sass/main.scss
Normal file
263
assets/css/sass/main.scss
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
html {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after {
|
||||||
|
box-sizing: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: Hack, DejaVu Sans Mono, Monaco, Consolas, Ubuntu Mono, monospace;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.54;
|
||||||
|
// background-color: var(--background);
|
||||||
|
color: var(--color);
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
|
||||||
|
@media (max-width: $phone-max-width) {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg {
|
||||||
|
background: radial-gradient(at right top, #F68EF0, #74B9DF);
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
min-height: 100vh;
|
||||||
|
min-height: 100dvh;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4, h5, h6 {
|
||||||
|
font-size: 1.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
display: table;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 25px 0;
|
||||||
|
|
||||||
|
&.left, img {
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.center, img {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right, img {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
background: var(--accent);
|
||||||
|
color: var(--background);
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: Hack, DejaVu Sans Mono, Monaco, Consolas, Ubuntu Mono, monospace;
|
||||||
|
font-feature-settings: normal;
|
||||||
|
background: var(--accent-alpha-20);
|
||||||
|
padding: 1px 6px;
|
||||||
|
margin: 0 2px;
|
||||||
|
font-size: .95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
font-family: Hack, DejaVu Sans Mono, Monaco, Consolas, Ubuntu Mono, monospace;
|
||||||
|
padding: 20px;
|
||||||
|
font-size: .95rem;
|
||||||
|
overflow: auto;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, .1);
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, .1);
|
||||||
|
|
||||||
|
@media (max-width: $phone-max-width) {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
border-top: 1px solid var(--accent);
|
||||||
|
border-bottom: 1px solid var(--accent);
|
||||||
|
margin: 40px 0;
|
||||||
|
padding: 25px;
|
||||||
|
|
||||||
|
@media (max-width: $phone-max-width) {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: '”';
|
||||||
|
font-family: Georgia, serif;
|
||||||
|
font-size: 3.875rem;
|
||||||
|
position: absolute;
|
||||||
|
left: -40px;
|
||||||
|
top: -20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p:first-of-type {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p:last-of-type {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
p:before {
|
||||||
|
content: '>';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: -25px;
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
table-layout: fixed;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
margin: 40px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table, th, td {
|
||||||
|
border: 1px dashed var(--accent);
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul, ol {
|
||||||
|
margin-left: 30px;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $phone-max-width) {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ol ol {
|
||||||
|
list-style-type: lower-alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 40px;
|
||||||
|
max-width: 864px;
|
||||||
|
// min-height: 100vh;
|
||||||
|
margin: 2em auto;
|
||||||
|
|
||||||
|
background: rgb(0 0 0 / .4);
|
||||||
|
|
||||||
|
@media (max-width: $phone-max-width) {
|
||||||
|
padding: 20px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
background: var(--border-color);
|
||||||
|
height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
57
assets/css/sass/pagination.css
Normal file
57
assets/css/sass/pagination.css
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
.pagination {
|
||||||
|
margin-top: 50px; }
|
||||||
|
.pagination__title {
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
margin: 100px 0 20px; }
|
||||||
|
.pagination__title-h {
|
||||||
|
text-align: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 5px 10px;
|
||||||
|
background: var(--background);
|
||||||
|
font-size: .8rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .1em;
|
||||||
|
z-index: 1; }
|
||||||
|
.pagination__title hr {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 15px;
|
||||||
|
z-index: 0; }
|
||||||
|
.pagination__buttons {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center; }
|
||||||
|
@media (max-width: 683px) {
|
||||||
|
.pagination__buttons {
|
||||||
|
flex-direction: column; } }
|
||||||
|
|
||||||
|
.button {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 1rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
max-width: 40%;
|
||||||
|
padding: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
appearance: none; }
|
||||||
|
@media (max-width: 683px) {
|
||||||
|
.button {
|
||||||
|
max-width: 80%; } }
|
||||||
|
.button + .button {
|
||||||
|
margin-left: 10px; }
|
||||||
|
.button a {
|
||||||
|
display: flex;
|
||||||
|
padding: 8px 16px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden; }
|
||||||
|
.button__text {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden; }
|
77
assets/css/sass/pagination.scss
Normal file
77
assets/css/sass/pagination.scss
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
@import 'variables';
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
margin-top: 50px;
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
margin: 100px 0 20px;
|
||||||
|
|
||||||
|
&-h {
|
||||||
|
text-align: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 5px 10px;
|
||||||
|
background: var(--background);
|
||||||
|
font-size: .8rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .1em;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 15px;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__buttons {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
@media (max-width: $phone-max-width) {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 1rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
max-width: 40%;
|
||||||
|
padding: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
appearance: none;
|
||||||
|
|
||||||
|
@media (max-width: $phone-max-width) {
|
||||||
|
max-width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ .button {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: flex;
|
||||||
|
padding: 8px 16px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
79
assets/css/sass/post.css
Normal file
79
assets/css/sass/post.css
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
@charset "UTF-8";
|
||||||
|
.posts {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto; }
|
||||||
|
|
||||||
|
.post {
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
margin: 20px auto;
|
||||||
|
padding: 20px 0; }
|
||||||
|
@media (max-width: 899px) {
|
||||||
|
.post {
|
||||||
|
max-width: 660px; } }
|
||||||
|
.post:not(:last-of-type) {
|
||||||
|
border-bottom: 1px solid var(--border-color); }
|
||||||
|
.post .post-meta, .post .post-meta-inline {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: var(--accent-alpha-70); }
|
||||||
|
.post-meta-inline {
|
||||||
|
display: inline; }
|
||||||
|
.post-title {
|
||||||
|
--border: 2px dashed var(--accent);
|
||||||
|
position: relative;
|
||||||
|
color: var(--accent);
|
||||||
|
margin: 0 0 15px;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
border-bottom: var(--border);
|
||||||
|
font-weight: normal; }
|
||||||
|
.post-title a {
|
||||||
|
text-decoration: none; }
|
||||||
|
.post .post-tags, .post .post-tags-inline {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 1rem;
|
||||||
|
opacity: .5; }
|
||||||
|
.post-tags {
|
||||||
|
display: block; }
|
||||||
|
.post-tags-inline {
|
||||||
|
display: inline; }
|
||||||
|
@media (max-width: 683px) {
|
||||||
|
.post-tags-inline {
|
||||||
|
display: block; } }
|
||||||
|
.post-content {
|
||||||
|
margin-top: 30px; }
|
||||||
|
.post-cover {
|
||||||
|
border: 20px solid var(--accent);
|
||||||
|
background: transparent;
|
||||||
|
margin: 40px 0;
|
||||||
|
padding: 20px; }
|
||||||
|
@media (max-width: 683px) {
|
||||||
|
.post-cover {
|
||||||
|
padding: 10px;
|
||||||
|
border-width: 10px; } }
|
||||||
|
.post ul {
|
||||||
|
list-style: none; }
|
||||||
|
.post ul li:before {
|
||||||
|
content: '►';
|
||||||
|
position: absolute;
|
||||||
|
left: -20px;
|
||||||
|
color: var(--accent); }
|
||||||
|
|
||||||
|
.post--regulation h1 {
|
||||||
|
justify-content: center; }
|
||||||
|
.post--regulation h2 {
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 10px; }
|
||||||
|
.post--regulation h2 + h2 {
|
||||||
|
margin-top: -10px;
|
||||||
|
margin-bottom: 20px; }
|
||||||
|
|
||||||
|
.post-list .post-date {
|
||||||
|
color: var(--accent);
|
||||||
|
text-decoration: none; }
|
||||||
|
.post-list a {
|
||||||
|
text-decoration: none; }
|
||||||
|
.post-list .post-list-title {
|
||||||
|
text-decoration: underline; }
|
||||||
|
.post-list .post-tag {
|
||||||
|
text-decoration: underline; }
|
135
assets/css/sass/post.scss
Normal file
135
assets/css/sass/post.scss
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
.posts {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post {
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
margin: 20px auto;
|
||||||
|
padding: 20px 0;
|
||||||
|
|
||||||
|
@media (max-width: $tablet-max-width) {
|
||||||
|
max-width: 660px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:last-of-type) {
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
%meta {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
color: var(--accent-alpha-70);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-meta {
|
||||||
|
@extend %meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-meta-inline {
|
||||||
|
@extend %meta;
|
||||||
|
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
--border: 2px dashed var(--accent);
|
||||||
|
position: relative;
|
||||||
|
color: var(--accent);
|
||||||
|
margin: 0 0 15px;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
border-bottom: var(--border);
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%tags {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 1rem;
|
||||||
|
opacity: .5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tags {
|
||||||
|
@extend %tags;
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tags-inline {
|
||||||
|
@extend %tags;
|
||||||
|
|
||||||
|
display: inline;
|
||||||
|
|
||||||
|
@media (max-width: $phone-max-width) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-content {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-cover {
|
||||||
|
border: 20px solid var(--accent);
|
||||||
|
background: transparent;
|
||||||
|
margin: 40px 0;
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
@media (max-width: $phone-max-width) {
|
||||||
|
padding: 10px;
|
||||||
|
border-width: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li:before {
|
||||||
|
content: '►';
|
||||||
|
position: absolute;
|
||||||
|
left: -20px;
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post--regulation {
|
||||||
|
h1 {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
&+ h2 {
|
||||||
|
margin-top: -10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-list {
|
||||||
|
.post-date {
|
||||||
|
color: var(--accent);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-list-title {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-tag {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
69
assets/css/sass/style.css
Normal file
69
assets/css/sass/style.css
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
Error: wrong number of arguments (1 for 3) for `rgb'
|
||||||
|
on line 242 of main.scss
|
||||||
|
from line 5 of style.scss
|
||||||
|
|
||||||
|
Backtrace:
|
||||||
|
main.scss:242
|
||||||
|
style.scss:5
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/script/tree/funcall.rb:311:in `reformat_argument_error'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/script/tree/funcall.rb:158:in `rescue in _perform'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/script/tree/funcall.rb:127:in `_perform'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/script/tree/node.rb:50:in `perform'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:398:in `visit_prop'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `block in visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `block in with_base'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:135:in `with_frame'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `with_base'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `block (2 levels) in visit_rule'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `map'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `block in visit_rule'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:179:in `with_environment'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:438:in `visit_rule'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `block in visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `block in with_base'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:135:in `with_frame'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `with_base'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:325:in `block (2 levels) in visit_import'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:325:in `map'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:325:in `block in visit_import'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:88:in `block in with_import'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:135:in `with_frame'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:88:in `with_import'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:322:in `visit_import'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `block in visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `block in with_base'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:135:in `with_frame'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `with_base'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:52:in `block in visit_children'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:52:in `map'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:52:in `visit_children'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:167:in `block in visit_children'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:179:in `with_environment'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:166:in `visit_children'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `block in visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:186:in `visit_root'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:157:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:10:in `visit'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/root_node.rb:36:in `css_tree'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/tree/root_node.rb:20:in `render'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/engine.rb:290:in `render'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/exec/sass_scss.rb:396:in `run'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/exec/sass_scss.rb:63:in `process_result'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/exec/base.rb:50:in `parse'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/lib/sass/exec/base.rb:18:in `parse!'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/lib/ruby/gems/3.3.0/gems/sass-3.7.4/bin/sass:13:in `<top (required)>'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/bin/sass:25:in `load'
|
||||||
|
/home/jess/.asdf/installs/ruby/3.3.0/bin/sass:25:in `<main>'
|
||||||
|
*/
|
||||||
|
body:before {
|
||||||
|
white-space: pre;
|
||||||
|
font-family: monospace;
|
||||||
|
content: "Error: wrong number of arguments (1 for 3) for `rgb'\A on line 242 of main.scss\A from line 5 of style.scss"; }
|
9
assets/css/sass/style.scss
Normal file
9
assets/css/sass/style.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
@import 'buttons';
|
||||||
|
|
||||||
|
@import 'header';
|
||||||
|
@import 'logo';
|
||||||
|
@import 'main';
|
||||||
|
@import 'post';
|
||||||
|
@import 'pagination';
|
||||||
|
@import 'footer';
|
||||||
|
@import 'home';
|
0
assets/css/sass/variables.css
Normal file
0
assets/css/sass/variables.css
Normal file
2
assets/css/sass/variables.scss
Normal file
2
assets/css/sass/variables.scss
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
$phone-max-width: 683px;
|
||||||
|
$tablet-max-width: 899px;
|
File diff suppressed because it is too large
Load diff
|
@ -7,8 +7,6 @@
|
||||||
# General application configuration
|
# General application configuration
|
||||||
import Config
|
import Config
|
||||||
|
|
||||||
config :elixir, :time_zone_database, Tz.TimeZoneDatabase
|
|
||||||
|
|
||||||
config :jol,
|
config :jol,
|
||||||
namespace: JOL,
|
namespace: JOL,
|
||||||
ecto_repos: [JOL.Repo],
|
ecto_repos: [JOL.Repo],
|
||||||
|
|
|
@ -58,8 +58,7 @@ config :jol, JOLWeb.Endpoint,
|
||||||
patterns: [
|
patterns: [
|
||||||
~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$",
|
~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$",
|
||||||
~r"priv/gettext/.*(po)$",
|
~r"priv/gettext/.*(po)$",
|
||||||
~r"lib/jol_web/(controllers|live|components)/.*(ex|heex)$",
|
~r"lib/jol_web/(controllers|live|components)/.*(ex|heex)$"
|
||||||
~r"posts/*/.*(md)$"
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
36
fly.toml
36
fly.toml
|
@ -10,30 +10,26 @@ kill_signal = 'SIGTERM'
|
||||||
[build]
|
[build]
|
||||||
|
|
||||||
[deploy]
|
[deploy]
|
||||||
release_command = '/app/bin/migrate'
|
release_command = '/app/bin/migrate'
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
PHX_HOST = 'jess.canady.tech'
|
PHX_HOST = 'jol.fly.dev'
|
||||||
PORT = '8080'
|
PORT = '8080'
|
||||||
|
|
||||||
[http_service]
|
[http_service]
|
||||||
internal_port = 8080
|
internal_port = 8080
|
||||||
force_https = true
|
force_https = true
|
||||||
auto_stop_machines = "stop"
|
auto_stop_machines = true
|
||||||
auto_start_machines = true
|
auto_start_machines = true
|
||||||
min_machines_running = 0
|
min_machines_running = 0
|
||||||
processes = ['app']
|
processes = ['app']
|
||||||
|
|
||||||
[[http_service.checks]]
|
[http_service.concurrency]
|
||||||
timeout = "30s"
|
type = 'connections'
|
||||||
grace_period = "30s"
|
hard_limit = 1000
|
||||||
|
soft_limit = 1000
|
||||||
[http_service.concurrency]
|
|
||||||
type = 'connections'
|
|
||||||
hard_limit = 1000
|
|
||||||
soft_limit = 1000
|
|
||||||
|
|
||||||
[[vm]]
|
[[vm]]
|
||||||
memory = '1gb'
|
memory = '1gb'
|
||||||
cpu_kind = 'shared'
|
cpu_kind = 'shared'
|
||||||
cpus = 1
|
cpus = 1
|
||||||
|
|
|
@ -2,10 +2,6 @@ defmodule JOL.Blog do
|
||||||
alias JOL.Blog.Post
|
alias JOL.Blog.Post
|
||||||
alias JOL.Blog.Parser
|
alias JOL.Blog.Parser
|
||||||
|
|
||||||
defmodule NotFoundError do
|
|
||||||
defexception [:message, plug_status: 404]
|
|
||||||
end
|
|
||||||
|
|
||||||
use NimblePublisher,
|
use NimblePublisher,
|
||||||
build: Post,
|
build: Post,
|
||||||
from: Application.app_dir(:jol, "priv/posts/**/*.md"),
|
from: Application.app_dir(:jol, "priv/posts/**/*.md"),
|
||||||
|
@ -15,37 +11,9 @@ defmodule JOL.Blog do
|
||||||
@posts Enum.sort_by(@posts, & &1.date, {:desc, Date})
|
@posts Enum.sort_by(@posts, & &1.date, {:desc, Date})
|
||||||
@tags @posts |> Enum.flat_map(& &1.tags) |> Enum.uniq() |> Enum.sort()
|
@tags @posts |> Enum.flat_map(& &1.tags) |> Enum.uniq() |> Enum.sort()
|
||||||
|
|
||||||
@spec all_posts() :: [
|
@spec posts() :: []
|
||||||
%Post{
|
def posts, do: @posts
|
||||||
author: String.t(),
|
|
||||||
body: String.t(),
|
@spec unique_tag_list() :: []
|
||||||
date: DateTime.t(),
|
|
||||||
draft: false | nil,
|
|
||||||
slug: String.t(),
|
|
||||||
tags: [String.t()],
|
|
||||||
title: String.t()
|
|
||||||
}
|
|
||||||
]
|
|
||||||
def all_posts, do: @posts
|
|
||||||
def unique_tag_list, do: @tags
|
def unique_tag_list, do: @tags
|
||||||
|
|
||||||
def recent_posts(num \\ 10) do
|
|
||||||
Enum.take(all_posts(), num)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_post_by_slug!(slug) do
|
|
||||||
Enum.find(all_posts(), &(&1.slug == slug)) ||
|
|
||||||
raise NotFoundError, "post ``slug=#{slug}` not found"
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_posts_by_tag!(tag) do
|
|
||||||
case Enum.filter(all_posts(), &(tag in &1.tags)) do
|
|
||||||
[] -> raise NotFoundError, "posts tagged `#{tag}` not found"
|
|
||||||
posts -> posts
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def format_date(date) do
|
|
||||||
Calendar.strftime(date, "%Y-%m-%d")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,8 +24,7 @@ defmodule JOL.Blog.Parser do
|
||||||
title: toml_attrs["title"],
|
title: toml_attrs["title"],
|
||||||
draft: toml_attrs["draft"],
|
draft: toml_attrs["draft"],
|
||||||
tags: toml_attrs["taxonomies"]["tags"],
|
tags: toml_attrs["taxonomies"]["tags"],
|
||||||
date: toml_attrs["date"],
|
date: toml_attrs["date"]
|
||||||
slug: toml_attrs["slug"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parsed_body = String.trim(body)
|
parsed_body = String.trim(body)
|
||||||
|
|
|
@ -1,25 +1,8 @@
|
||||||
defmodule JOL.Blog.Post do
|
defmodule JOL.Blog.Post do
|
||||||
@enforce_keys [:author, :title, :body, :tags, :date, :slug, :lede]
|
@enforce_keys [:title, :body, :draft, :date, :tags]
|
||||||
defstruct [:author, :draft, :title, :body, :tags, :date, :slug, :lede]
|
defstruct [:title, :body, :draft, :date, :tags]
|
||||||
|
|
||||||
def build(_filename, attrs, body) do
|
def build(_filename, attrs, body) do
|
||||||
struct!(
|
struct!(__MODULE__, [body: body] ++ Map.to_list(attrs))
|
||||||
__MODULE__,
|
|
||||||
[author: "Jessica Phoenix Canady", body: body, lede: extract_lede(body)] ++
|
|
||||||
Map.to_list(attrs)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp extract_lede(text) do
|
|
||||||
case Regex.named_captures(~r/(?<lede>.*)\n<!-- more -->/s, text) do
|
|
||||||
%{"lede" => lede} ->
|
|
||||||
lede
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
text
|
|
||||||
|> String.split()
|
|
||||||
|> Enum.take(50)
|
|
||||||
|> Enum.join(" ")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
defmodule JOLWeb.Components.Blog do
|
|
||||||
@moduledoc """
|
|
||||||
This module holds various ways of rendering a `JOL.Blog.Post`.
|
|
||||||
|
|
||||||
See the `blog` directory for the available templates.`
|
|
||||||
"""
|
|
||||||
|
|
||||||
use JOLWeb, :html
|
|
||||||
|
|
||||||
embed_templates "blog/*"
|
|
||||||
end
|
|
|
@ -1,3 +0,0 @@
|
||||||
<div class="post_summary">
|
|
||||||
<h3><%= @post.title %></h3>
|
|
||||||
</div>
|
|
|
@ -1,3 +0,0 @@
|
||||||
<div class="post_summary">
|
|
||||||
<h3 class="title"><%= @blog.title %></h3>
|
|
||||||
</div>
|
|
|
@ -14,9 +14,9 @@
|
||||||
|
|
||||||
<nav class="menu">
|
<nav class="menu">
|
||||||
<ul class="menu__inner">
|
<ul class="menu__inner">
|
||||||
<li class="active"><a href={~p"/"}>home</a></li>
|
<li class="active"><a href="">home</a></li>
|
||||||
<li><a href={~p"/tags/"}>tags</a></li>
|
<li><a href={~p"/tags/"}>tags</a></li>
|
||||||
<li><a href={~p"/blog/"}>blog archive</a></li>
|
<li><a href={~p"/archive/"}>blog archive</a></li>
|
||||||
<li><a href={~p"/about/"}>about</a></li>
|
<li><a href={~p"/about/"}>about</a></li>
|
||||||
<li><a href={~p"/now/"}>now</a></li>
|
<li><a href={~p"/now/"}>now</a></li>
|
||||||
<li><a href="https://forge.sigill.zone/phoenix/">code</a></li>
|
<li><a href="https://forge.sigill.zone/phoenix/">code</a></li>
|
||||||
|
@ -27,14 +27,15 @@
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="post">
|
<%= @inner_content %>
|
||||||
<%= @inner_content %>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
|
<div class="footer__inner">
|
||||||
<div class="copyright copyright--user">
|
<div class="copyright copyright--user">
|
||||||
<a href={~p"/colophon/"}>Built with</a> trans dork love.
|
Built with trans dork love.
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
defmodule JOLWeb.BlogController do
|
|
||||||
use JOLWeb, :controller
|
|
||||||
|
|
||||||
alias JOL.Blog
|
|
||||||
|
|
||||||
def index(conn, _params) do
|
|
||||||
render(conn, "index.html", page_title: "You Asked For Posts", posts: Blog.recent_posts())
|
|
||||||
end
|
|
||||||
|
|
||||||
def show(conn, %{"slug" => slug}) do
|
|
||||||
post = Blog.get_post_by_slug!(slug)
|
|
||||||
render(conn, "show.html", page_title: post.title, post: post)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
defmodule JOLWeb.BlogHTML do
|
|
||||||
use JOLWeb, :html
|
|
||||||
|
|
||||||
embed_templates "blog_html/*"
|
|
||||||
end
|
|
|
@ -1,9 +0,0 @@
|
||||||
<h1 class="post-title">Post Archive</h1>
|
|
||||||
|
|
||||||
<%= for post <- @posts do %>
|
|
||||||
<div class="post-summary">
|
|
||||||
<p class="post-date"><date><%= JOL.Blog.format_date(post.date) %></date></p>
|
|
||||||
<h3> <.link href={~p"/blog/#{post.slug}"}><%= post.title %> </.link> </h3>
|
|
||||||
<p><%= raw post.lede %></p>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
|
@ -1,13 +0,0 @@
|
||||||
<.link href={~p"/blog"}>← All posts</.link>
|
|
||||||
|
|
||||||
<h1><%= @post.title %></h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<date><%= JOL.Blog.format_date(@post.date) %></date>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<%= raw @post.body %>
|
|
||||||
|
|
||||||
<p class="post-tags">
|
|
||||||
Filed under: <%= Enum.join(@post.tags, ", ") %>
|
|
||||||
</p>
|
|
|
@ -1,12 +0,0 @@
|
||||||
defmodule JOLWeb.FeedController do
|
|
||||||
use JOLWeb, :controller
|
|
||||||
|
|
||||||
def feed(conn, _params) do
|
|
||||||
feed = JOL.Blog.all_posts()
|
|
||||||
|> JOLWeb.Feeds.build_feed()
|
|
||||||
|
|
||||||
conn
|
|
||||||
|> put_resp_content_type("text/xml")
|
|
||||||
|> send_resp(200, feed)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,24 +1,22 @@
|
||||||
defmodule JOLWeb.PageController do
|
defmodule JOLWeb.PageController do
|
||||||
|
require Logger
|
||||||
use JOLWeb, :controller
|
use JOLWeb, :controller
|
||||||
|
|
||||||
@spec home(Plug.Conn.t(), any()) :: Plug.Conn.t()
|
@spec home(Plug.Conn.t(), any()) :: Plug.Conn.t()
|
||||||
def home(conn, _params) do
|
def home(conn, _params) do
|
||||||
conn
|
conn
|
||||||
|> render(:home, page_title: "Welcome!", posts: JOL.Blog.recent_posts())
|
|> assign(:page_title, "Home")
|
||||||
|
|> render(:home)
|
||||||
end
|
end
|
||||||
|
|
||||||
def about(conn, _params) do
|
@spec tags(Plug.Conn.t(), any()) :: Plug.Conn.t()
|
||||||
conn
|
def tags(conn, _params) do
|
||||||
|> render(:about, page_title: "The Life and Times of Jessica Phoenix Canady")
|
Logger.debug(JOL.Blog.posts())
|
||||||
end
|
Logger.debug(JOL.Blog.unique_tag_list())
|
||||||
|
|
||||||
def now(conn, _params) do
|
|
||||||
conn
|
conn
|
||||||
|> render(:now, page_title: "Current Status")
|
|> assign(:tags, JOL.Blog.unique_tag_list())
|
||||||
end
|
|> assign(:page_title, "Post Tags")
|
||||||
|
|> render(:tags)
|
||||||
def colophon(conn, _params) do
|
|
||||||
conn
|
|
||||||
|> render(:colophon, page_title: "about:jol")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
<h1 class="post-title">About Jessica</h1>
|
|
||||||
|
|
||||||
<p>I'm <strong>Jessica Phoenix Canady</strong>, a web development dork who lives in Columbus Ohio with her wife, two boys, and two cats.</p>
|
|
||||||
<p>I write web software (mostly in Elixir and Ruby), dork around with server infrastructure and security, and play music on keys and synths. I also play the occasional video game and hand of poker.</p>
|
|
||||||
<p>For eleven years of my earlier life I built CoverMyMeds, from inception to acquisition in 2017. I was responsible for much of the early dev culture and processes, as well as the backend that manages sending faxes; the backend for the electronic prior auth systems, the PA workflow software <em>Central</em>, and a ton more I can no longer recall.</p>
|
|
||||||
<h2 id="selected-histories">Selected Histories</h2>
|
|
||||||
<h3 id="chapter-onestumbled-into-life">Chapter One<br>Stumbled Into Life</h3>
|
|
||||||
<ul>
|
|
||||||
<li>Webmistress'd and wrote copy for several websites (including Comic Town's, see below) back when the Web was wild and new and I was young <del>and brave</del>.</li>
|
|
||||||
<li>Matriculated at the world-renowned DeVry University (<em>cough</em>) and graduated just as the first dot-com bubble burst.</li>
|
|
||||||
<li>Clerked at a comic book store, the glorious Comic Town in Columbus OH, when it was at its various Morse Rd locations. Pour one out for a real one. <strong>RIP Comic Town, 199x-2023.</strong> </li>
|
|
||||||
</ul>
|
|
||||||
<h3 id="chapter-2she-thinks-she-s-grown-up">Chapter 2<br>She Thinks She's Grown Up</h3>
|
|
||||||
<ul>
|
|
||||||
<li>After finding their help wanted ad on Craigslist, annoyed the dorks at Innova Partners until they gave me a job as a developer at their consultancy. They lured me with the promise of free lunch every day.</li>
|
|
||||||
<li>❤️ Got married to my high school sweetheart and best friend, Kelli. ❤️</li>
|
|
||||||
<li>Ran the Columbus Ruby Brigade (as a volunteer emcee, a board member, and President of the board) for some years, running their meetings and booking speakers. </li>
|
|
||||||
<li>Had two children, Alex and Quentin. I thought I knew what love was, then I laid eyes on my babies, and I realized I had no idea until that moment. Funnily enough this happened with both kids, four years apart.</li>
|
|
||||||
<li>Helped Innova write a ton of software for a project called CoverMyMeds. This turned into a product that we turned into a company that, in 2017, got bought by McKesson for one-point-four billion dollars.</li>
|
|
||||||
</ul>
|
|
||||||
<h3 id="chapter-3the-light-inside-is-burnt-out-but-she-still-works">Chapter 3<br>The Light Inside is Burnt Out but She Still Works</h3>
|
|
||||||
<ul>
|
|
||||||
<li>Began transitioning my gender, which has been the best thing I've ever done for my mental health.</li>
|
|
||||||
<li>As their VP of Engineering, spent two years building the tech and team at <a href="https://prescribefit.com">Prescribe FIT</a> here in Columbus OH. I left that position in early 2023, now I'm just an investor.</li>
|
|
||||||
</ul>
|
|
|
@ -1,27 +0,0 @@
|
||||||
<h1 class="post-title">about:jol</h1>
|
|
||||||
|
|
||||||
<h2>The Software</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Jessica OnLine is pwoered by a <a href="https://forge.sigill.zone/phoenix/jol/">custom Elixir/Phoenix application</a>. Feel free to look through the implementation and take what makes sense for you -- not all of it will even be <em>good</em>, let alone correct for what you want to do, but hopefully it's helpful.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The point of the app is to find the sweet spot between "easy to update but overly complex to manage and style" Wordpress, and "Markup rules until I have to upload images" static site generators.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>The Editor</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Mostly written in <a href="https://www.gnu.org/software/emacs/">Emacs</a> with the <a href="https://github.com/doomemacs/doomemacs">DOOM</a> configuration framework, which pre-configures Magit and evil-mode and a bunch of amazing tools.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If you're not into editors older than you are, try <a href="https://zed.dev">Zed</a>, a modern editor that's fast and extensible. As a JOL-approved application you can find the demo version on the installation medium you were sent.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Font</h2>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Displayed in the beautiful <a href="https://berkeleygraphics.com/typefaces/berkeley-mono/">Berkeley Mono</a> typeface by Berkeley Graphics. Unless you're reading in an RSS reader, a browser's reader mode, or you've defined custom fonts (does anyone still do that? Do browsers even still let you?)
|
|
||||||
</p>
|
|
|
@ -8,16 +8,6 @@
|
||||||
<p>I write here about those things, about general tech dorkery, and about my experience with being <strong>super</strong> trans and learning who I am.</p>
|
<p>I write here about those things, about general tech dorkery, and about my experience with being <strong>super</strong> trans and learning who I am.</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2>Recent Posts</h2>
|
|
||||||
<ul class="recent-posts">
|
|
||||||
<%= for post <- @posts do %>
|
|
||||||
<li>
|
|
||||||
<date><%= JOL.Blog.format_date(post.date) %></date>
|
|
||||||
<.link href={~p"/blog/#{post.slug}"}><%= post.title %> </.link>
|
|
||||||
</li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
<h1 class="post-title">Current Status</h1>
|
|
||||||
|
|
||||||
<p>Last update: 22 Aug 2024 • from the Canady House in Uptown Westerville</p>
|
|
||||||
|
|
||||||
<h2>Reading</h2>
|
|
||||||
<p><a href="http://www.penguinrandomhouse.com/books/554241/the-bright-sword-by-lev-grossman/?cktype=prod&ref=PRH115DBB8203CD&linkid=PRH115DBB8203CD&cdi=4DF51DB6C8882719E0534FD66B0A1B04&template_id=28415&aid=randohouseinc9932-20">THE BRIGHT SWORD</a> by Lev Grossman.</p>
|
|
||||||
|
|
||||||
<p>I've read everything he's written since THE MAGICIANS, which is easily in my Top 3 Books, and his take on the Arthurian legends is so far hitting all the right buttons for me. (<em>Minor</em> spoiler, but any Aruthurian take with a trans Dinadan is automatically winning.)</p>
|
|
||||||
|
|
||||||
<h2>Tech</h2>
|
|
||||||
<p>Mostly just <a href="https://forge.sigill.zone/phoenix/jol/"> this site</a>, but I'm doing a lot of homelab stuff, mostly via <a href="https://portainer.io">Portainer</a>, which makes deploying containers really easy. And it's not Kubernetes!</p>
|
|
||||||
|
|
||||||
<h2>Gaming</h2>
|
|
||||||
<p>I <em>really</em> wanna run a <a href="https://poweredbylesbians.com/">Thirsty Sword Lesbian</a> campaign. And a monthly poker game. But organizing groups for both is, to put it mildly, fucking impossible.</p>
|
|
||||||
|
|
||||||
<p>Recently, I finished playing <a href="https://store.steampowered.com/app/2008920/Lorelei_and_the_Laser_Eyes/">LORELAI AND THE LASER EYES</a>. If you're into fiendish puzzles, mysterious narratives, incredible gameplay...just look play the damn game, it's amazing.</p>
|
|
||||||
|
|
||||||
<h2>Miscellanea</h2>
|
|
||||||
<ul>
|
|
||||||
<li>A lot of energy is going into personal family issues at the moment, which is good and necessary but also tiring.</li>
|
|
||||||
<li>Invisalign, at least for me, is absolutely worth the money, it turns out.</li>
|
|
||||||
<li>Without further imrpovement, my lingual frenectomy was...not.</li>
|
|
||||||
<li>It's weird having actual hope about the future of the country. It's not a lot but it's <em>there</em> in a way it wasn't when Biden was failing to meaningfully challenge Trump. Harris/Walz is a breath of fresh air.</li>
|
|
||||||
</ul>
|
|
|
@ -3,7 +3,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<%= for tag <- @tags do %>
|
<%= for tag <- @tags do %>
|
||||||
<li class="tag-list">
|
<li class="tag-list">
|
||||||
<a href={~p"/tags/#{tag}"}><%= tag %></a>
|
<a href="#"><%= tag %></a>
|
||||||
</li>
|
</li>
|
||||||
<% end %>
|
<% end %>
|
||||||
</ul>
|
</ul>
|
|
@ -1,18 +0,0 @@
|
||||||
defmodule JOLWeb.TagController do
|
|
||||||
use JOLWeb, :controller
|
|
||||||
|
|
||||||
def index(conn, _params) do
|
|
||||||
conn
|
|
||||||
|> render(:index,
|
|
||||||
page_title: "Jess Uses These Tags",
|
|
||||||
tags: JOL.Blog.unique_tag_list)
|
|
||||||
end
|
|
||||||
|
|
||||||
def tag(conn, %{"tag" => tag}) do
|
|
||||||
conn
|
|
||||||
|> render(:tag,
|
|
||||||
tag: tag,
|
|
||||||
page_title: "Posts Filed Under #{tag}",
|
|
||||||
posts: JOL.Blog.get_posts_by_tag!(tag))
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
defmodule JOLWeb.TagHTML do
|
|
||||||
use JOLWeb, :html
|
|
||||||
|
|
||||||
embed_templates "tag_html/*"
|
|
||||||
end
|
|
|
@ -1,9 +0,0 @@
|
||||||
<h1 class="post-title">Filed Under "<%= @tag %>"</h1>
|
|
||||||
|
|
||||||
<%= for post <- @posts do %>
|
|
||||||
<div class="post-summary">
|
|
||||||
<p class="post-date"><date><%= post.date %></date></p>
|
|
||||||
<h3> <.link href={~p"/blog/#{post.slug}"}><%= post.title %> </.link> </h3>
|
|
||||||
<p><%= raw post.lede %></p>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
|
@ -1,20 +0,0 @@
|
||||||
defmodule JOLWeb.Feeds do
|
|
||||||
use Phoenix.VerifiedRoutes, endpoint: JOLWeb.Endpoint, router: JOLWeb.Router
|
|
||||||
alias Atomex.{Feed, Entry}
|
|
||||||
|
|
||||||
def build_feed(posts) do
|
|
||||||
Feed.new(url(~p"/"), DateTime.utc_now, "Jessica Online")
|
|
||||||
|> Feed.author("Jessica Phoenix Canady", email: "jess@canady.tech")
|
|
||||||
|> Feed.link(url(~p"/feed.xml"), rel: "self")
|
|
||||||
|> Feed.entries(Enum.map(posts, &build_entry/1))
|
|
||||||
|> Feed.build()
|
|
||||||
|> Atomex.generate_document()
|
|
||||||
end
|
|
||||||
|
|
||||||
defp build_entry(post) do
|
|
||||||
Entry.new(url(~p"/blog/#{post.slug}"), post.date, post.title)
|
|
||||||
|> Entry.author(post.author, uri: url(~p"/"))
|
|
||||||
|> Entry.content(post.body, type: "html")
|
|
||||||
|> Entry.build()
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -14,31 +14,21 @@ defmodule JOLWeb.Router do
|
||||||
plug :accepts, ["json"]
|
plug :accepts, ["json"]
|
||||||
end
|
end
|
||||||
|
|
||||||
pipeline :feeds do
|
|
||||||
plug :accepts, ["xml"]
|
|
||||||
end
|
|
||||||
|
|
||||||
scope "/", JOLWeb do
|
scope "/", JOLWeb do
|
||||||
pipe_through :browser
|
pipe_through :browser
|
||||||
|
|
||||||
get "/", PageController, :home
|
get "/", PageController, :home
|
||||||
|
get "/tags", PageController, :tags
|
||||||
get "/archive", PageController, :archive
|
get "/archive", PageController, :archive
|
||||||
get "/about", PageController, :about
|
get "/about", PageController, :about
|
||||||
get "/now", PageController, :now
|
get "/now", PageController, :now
|
||||||
get "/colophon", PageController, :colophon
|
get "/code", PageController, :code
|
||||||
|
|
||||||
get "/tags", TagController, :index
|
|
||||||
get "/tags/:tag", TagController, :tag
|
|
||||||
|
|
||||||
get "/blog", BlogController, :index
|
|
||||||
get "/blog/:slug", BlogController, :show
|
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/", JOLWeb do
|
# Other scopes may use custom stacks.
|
||||||
pipe_through :feeds
|
# scope "/api", JOLWeb do
|
||||||
|
# pipe_through :api
|
||||||
get "/feed.xml", FeedController, :feed
|
# end
|
||||||
end
|
|
||||||
|
|
||||||
# Enable LiveDashboard and Swoosh mailbox preview in development
|
# Enable LiveDashboard and Swoosh mailbox preview in development
|
||||||
if Application.compile_env(:jol, :dev_routes) do
|
if Application.compile_env(:jol, :dev_routes) do
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
defmodule Mix.Tasks.GenPost do
|
|
||||||
@moduledoc "gen_post: Generate a new blog post."
|
|
||||||
@shortdoc "Generates a new blog post. Takes the title, and generates the rest."
|
|
||||||
|
|
||||||
use Mix.Task
|
|
||||||
|
|
||||||
@impl Mix.Task
|
|
||||||
def run([title]) do
|
|
||||||
dir = Application.app_dir(:jol, "priv/posts/blog/")
|
|
||||||
|
|
||||||
slug = title
|
|
||||||
|> String.downcase()
|
|
||||||
|> String.replace(" ", "-")
|
|
||||||
|> String.replace(~r/[^a-zA-Z0-9 -]/, "")
|
|
||||||
|
|
||||||
pubdate = DateTime.now!("America/New_York")
|
|
||||||
filename = "#{slug}.md"
|
|
||||||
filepath = "#{dir}/#{filename}"
|
|
||||||
|
|
||||||
if File.exists?(filepath) do
|
|
||||||
IO.puts(:stderr, "Already exists: priv/posts/blog/#{filename}")
|
|
||||||
IO.puts(:stderr, "Stop reusing blog titles!")
|
|
||||||
else
|
|
||||||
content = """
|
|
||||||
+++
|
|
||||||
slug = "#{slug}"
|
|
||||||
title = "#{title}"
|
|
||||||
date = #{DateTime.to_iso8601(pubdate)}
|
|
||||||
draft = false
|
|
||||||
|
|
||||||
[taxonomies]
|
|
||||||
# An array of quoted strings
|
|
||||||
tags = []
|
|
||||||
+++
|
|
||||||
|
|
||||||
"""
|
|
||||||
File.write(filepath, content)
|
|
||||||
IO.puts "Created: #{dir}#{filename}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
4
mix.exs
4
mix.exs
|
@ -59,9 +59,7 @@ defmodule JOL.MixProject do
|
||||||
{:dns_cluster, "~> 0.1.1"},
|
{:dns_cluster, "~> 0.1.1"},
|
||||||
{:bandit, "~> 1.2"},
|
{:bandit, "~> 1.2"},
|
||||||
{:nimble_publisher, "~> 1.1.0"},
|
{:nimble_publisher, "~> 1.1.0"},
|
||||||
{:toml, "~> 0.7"},
|
{:toml, "~> 0.7"}
|
||||||
{:atomex, "~> 0.3.0"},
|
|
||||||
{:tz, "~> 0.27"}
|
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
12
mix.lock
12
mix.lock
|
@ -1,8 +1,6 @@
|
||||||
%{
|
%{
|
||||||
"atomex": {:hex, :atomex, "0.3.0", "19b5d1a2aef8706dbd307385f7d5d9f6f273869226d317492c396c7bacf26402", [:mix], [{:xml_builder, "~> 2.0.0", [hex: :xml_builder, repo: "hexpm", optional: false]}], "hexpm", "025dbc3a3e99380894791a093019f535d0ef6cf1916f6ec1b778ac107fcfc3e4"},
|
|
||||||
"bandit": {:hex, :bandit, "1.5.2", "ed0a41c43a9e529c670d0fd48371db4027e7b80d43b1942893e17deb8bed0540", [:mix], [{:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "35ddbdce7e8a2a3c6b5093f7299d70832a43ed2f4a1852885a61d334cab1b4ad"},
|
"bandit": {:hex, :bandit, "1.5.2", "ed0a41c43a9e529c670d0fd48371db4027e7b80d43b1942893e17deb8bed0540", [:mix], [{:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "35ddbdce7e8a2a3c6b5093f7299d70832a43ed2f4a1852885a61d334cab1b4ad"},
|
||||||
"castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"},
|
"castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"},
|
||||||
"certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"},
|
|
||||||
"db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"},
|
"db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"},
|
||||||
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
|
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
|
||||||
"dns_cluster": {:hex, :dns_cluster, "0.1.3", "0bc20a2c88ed6cc494f2964075c359f8c2d00e1bf25518a6a6c7fd277c9b0c66", [:mix], [], "hexpm", "46cb7c4a1b3e52c7ad4cbe33ca5079fbde4840dedeafca2baf77996c2da1bc33"},
|
"dns_cluster": {:hex, :dns_cluster, "0.1.3", "0bc20a2c88ed6cc494f2964075c359f8c2d00e1bf25518a6a6c7fd277c9b0c66", [:mix], [], "hexpm", "46cb7c4a1b3e52c7ad4cbe33ca5079fbde4840dedeafca2baf77996c2da1bc33"},
|
||||||
|
@ -15,21 +13,16 @@
|
||||||
"finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"},
|
"finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"},
|
||||||
"floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"},
|
"floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"},
|
||||||
"gettext": {:hex, :gettext, "0.24.0", "6f4d90ac5f3111673cbefc4ebee96fe5f37a114861ab8c7b7d5b30a1108ce6d8", [:mix], [{:expo, "~> 0.5.1", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "bdf75cdfcbe9e4622dd18e034b227d77dd17f0f133853a1c73b97b3d6c770e8b"},
|
"gettext": {:hex, :gettext, "0.24.0", "6f4d90ac5f3111673cbefc4ebee96fe5f37a114861ab8c7b7d5b30a1108ce6d8", [:mix], [{:expo, "~> 0.5.1", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "bdf75cdfcbe9e4622dd18e034b227d77dd17f0f133853a1c73b97b3d6c770e8b"},
|
||||||
"hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"},
|
|
||||||
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized"]},
|
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized"]},
|
||||||
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
|
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
|
||||||
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
|
|
||||||
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
|
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
|
||||||
"makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"},
|
"makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"},
|
||||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
|
||||||
"mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"},
|
"mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"},
|
||||||
"mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"},
|
|
||||||
"mint": {:hex, :mint, "1.6.0", "88a4f91cd690508a04ff1c3e28952f322528934be541844d54e0ceb765f01d5e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "3c5ae85d90a5aca0a49c0d8b67360bbe407f3b54f1030a111047ff988e8fefaa"},
|
"mint": {:hex, :mint, "1.6.0", "88a4f91cd690508a04ff1c3e28952f322528934be541844d54e0ceb765f01d5e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "3c5ae85d90a5aca0a49c0d8b67360bbe407f3b54f1030a111047ff988e8fefaa"},
|
||||||
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
|
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
|
||||||
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
|
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
|
||||||
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
|
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
|
||||||
"nimble_publisher": {:hex, :nimble_publisher, "1.1.0", "49dee0f30536140268996660a5927d0282946949c35c88ccc6da11a19231b4b6", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "80fb42d8d1e34f41ff29fc2a1ae6ab86ea7b764b3c2d38e5268a43cf33825782"},
|
"nimble_publisher": {:hex, :nimble_publisher, "1.1.0", "49dee0f30536140268996660a5927d0282946949c35c88ccc6da11a19231b4b6", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "80fb42d8d1e34f41ff29fc2a1ae6ab86ea7b764b3c2d38e5268a43cf33825782"},
|
||||||
"parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
|
|
||||||
"phoenix": {:hex, :phoenix, "1.7.12", "1cc589e0eab99f593a8aa38ec45f15d25297dd6187ee801c8de8947090b5a9d3", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "d646192fbade9f485b01bc9920c139bfdd19d0f8df3d73fd8eaf2dfbe0d2837c"},
|
"phoenix": {:hex, :phoenix, "1.7.12", "1cc589e0eab99f593a8aa38ec45f15d25297dd6187ee801c8de8947090b5a9d3", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "d646192fbade9f485b01bc9920c139bfdd19d0f8df3d73fd8eaf2dfbe0d2837c"},
|
||||||
"phoenix_ecto": {:hex, :phoenix_ecto, "4.6.1", "96798325fab2fed5a824ca204e877b81f9afd2e480f581e81f7b4b64a5a477f2", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.17", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "0ae544ff99f3c482b0807c5cec2c8289e810ecacabc04959d82c3337f4703391"},
|
"phoenix_ecto": {:hex, :phoenix_ecto, "4.6.1", "96798325fab2fed5a824ca204e877b81f9afd2e480f581e81f7b4b64a5a477f2", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.17", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "0ae544ff99f3c482b0807c5cec2c8289e810ecacabc04959d82c3337f4703391"},
|
||||||
"phoenix_html": {:hex, :phoenix_html, "4.1.1", "4c064fd3873d12ebb1388425a8f2a19348cef56e7289e1998e2d2fa758aa982e", [:mix], [], "hexpm", "f2f2df5a72bc9a2f510b21497fd7d2b86d932ec0598f0210fed4114adc546c6f"},
|
"phoenix_html": {:hex, :phoenix_html, "4.1.1", "4c064fd3873d12ebb1388425a8f2a19348cef56e7289e1998e2d2fa758aa982e", [:mix], [], "hexpm", "f2f2df5a72bc9a2f510b21497fd7d2b86d932ec0598f0210fed4114adc546c6f"},
|
||||||
|
@ -41,7 +34,6 @@
|
||||||
"plug": {:hex, :plug, "1.16.0", "1d07d50cb9bb05097fdf187b31cf087c7297aafc3fed8299aac79c128a707e47", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cbf53aa1f5c4d758a7559c0bd6d59e286c2be0c6a1fac8cc3eee2f638243b93e"},
|
"plug": {:hex, :plug, "1.16.0", "1d07d50cb9bb05097fdf187b31cf087c7297aafc3fed8299aac79c128a707e47", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cbf53aa1f5c4d758a7559c0bd6d59e286c2be0c6a1fac8cc3eee2f638243b93e"},
|
||||||
"plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"},
|
"plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"},
|
||||||
"postgrex": {:hex, :postgrex, "0.18.0", "f34664101eaca11ff24481ed4c378492fed2ff416cd9b06c399e90f321867d7e", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "a042989ba1bc1cca7383ebb9e461398e3f89f868c92ce6671feb7ef132a252d1"},
|
"postgrex": {:hex, :postgrex, "0.18.0", "f34664101eaca11ff24481ed4c378492fed2ff416cd9b06c399e90f321867d7e", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "a042989ba1bc1cca7383ebb9e461398e3f89f868c92ce6671feb7ef132a252d1"},
|
||||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
|
|
||||||
"swoosh": {:hex, :swoosh, "1.16.7", "9dd0c172b4519a023f58e94d3ea79480b469dd4c0cd5369fabfbfd2e39bf5545", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.1.0", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.4 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "21073982816cff3410e90c0d80ebfd5a0bf4839c7b39db20bc69a6df123bbf35"},
|
"swoosh": {:hex, :swoosh, "1.16.7", "9dd0c172b4519a023f58e94d3ea79480b469dd4c0cd5369fabfbfd2e39bf5545", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.1.0", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.4 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "21073982816cff3410e90c0d80ebfd5a0bf4839c7b39db20bc69a6df123bbf35"},
|
||||||
"tailwind": {:hex, :tailwind, "0.2.2", "9e27288b568ede1d88517e8c61259bc214a12d7eed271e102db4c93fcca9b2cd", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "ccfb5025179ea307f7f899d1bb3905cd0ac9f687ed77feebc8f67bdca78565c4"},
|
"tailwind": {:hex, :tailwind, "0.2.2", "9e27288b568ede1d88517e8c61259bc214a12d7eed271e102db4c93fcca9b2cd", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "ccfb5025179ea307f7f899d1bb3905cd0ac9f687ed77feebc8f67bdca78565c4"},
|
||||||
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
|
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
|
||||||
|
@ -49,10 +41,6 @@
|
||||||
"telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"},
|
"telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"},
|
||||||
"thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"},
|
"thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"},
|
||||||
"toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"},
|
"toml": {:hex, :toml, "0.7.0", "fbcd773caa937d0c7a02c301a1feea25612720ac3fa1ccb8bfd9d30d822911de", [:mix], [], "hexpm", "0690246a2478c1defd100b0c9b89b4ea280a22be9a7b313a8a058a2408a2fa70"},
|
||||||
"tz": {:hex, :tz, "0.27.1", "d8091d0c2d4f590e010c94830c3d842f548b4872a5b92028d74f0d0a3887aebe", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:mint, "~> 1.6", [hex: :mint, repo: "hexpm", optional: true]}], "hexpm", "215c9120dab5b7f7db4c93e91085c290b2efe478e147d84285a6583fd220727f"},
|
|
||||||
"tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"},
|
|
||||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
|
||||||
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
|
"websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"},
|
||||||
"websock_adapter": {:hex, :websock_adapter, "0.5.6", "0437fe56e093fd4ac422de33bf8fc89f7bc1416a3f2d732d8b2c8fd54792fe60", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "e04378d26b0af627817ae84c92083b7e97aca3121196679b73c73b99d0d133ea"},
|
"websock_adapter": {:hex, :websock_adapter, "0.5.6", "0437fe56e093fd4ac422de33bf8fc89f7bc1416a3f2d732d8b2c8fd54792fe60", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "e04378d26b0af627817ae84c92083b7e97aca3121196679b73c73b99d0d133ea"},
|
||||||
"xml_builder": {:hex, :xml_builder, "2.0.0", "371ed27bb63bf0598dbaf3f0c466e5dc7d16cb4ecb68f06a67f953654062e21b", [:mix], [], "hexpm", "baeb5c8d42204bac2b856ffd50e8cda42d63b622984538d18d92733e4e790fbd"},
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
+++
|
|
||||||
slug = "ruining-your-keyspace"
|
|
||||||
title = "Ruining Your Keyspace For Fun And Profit"
|
|
||||||
date = 2024-09-03T12:51:23.952866-04:00
|
|
||||||
draft = false
|
|
||||||
|
|
||||||
[taxonomies]
|
|
||||||
# An array of quoted strings
|
|
||||||
tags = ["tales", "cmm", "software"]
|
|
||||||
+++
|
|
||||||
|
|
||||||
![Apparently the Hulu activation codes can/could accidentally include hilarious stuff like 6 F A G S E X!](/images/hulu_badwords.jpg)
|
|
||||||
|
|
||||||
Oh, the memories.
|
|
||||||
|
|
||||||
One of the early design decisions at CoverMyMeds was to generate alphanumeric keys for each Prior Auth, to ease communication about them. We figured trying to get pharmacists to read UUIDs to folks over the phone was a losing proposition. Because it was early, we just slapped together a quick "generate key, check for existence, loop back and generate again if used" routine and shipped it.
|
|
||||||
|
|
||||||
As seems obvious in retrospect, we eventaully also generated a key that included the f-slur. Luckily, it was sent to an early partner who found this hilarious instead of wildly offensive. Having dodged a company-ending bullets -- not the first, for damn sure not the last -- we brainstormed a list of offensive words that could be generated, and denylisted them.
|
|
||||||
|
|
||||||
I mean, that's usually the end of the story, but this one has a fun addendum. Our "PA Key" keyspace, which was previously limited to "all the possible combinations of letters/numbers in our strict format," got even smaller after we implemented the denylist. That, plus some new partnerships that turned into gangbusters growth, meant that we had nearly no time between the "hey we're almost out of keys to use for PAs" alarm, and actually being completely out of keys.
|
|
||||||
|
|
||||||
Remember, our key generation routine now looked like "generate key, discard and retry if on denylist, discard and retry if already used." This happened inline during the POST request to create a new Prior Auth, which meant **all of our apache threads across all our production servers** were spinning, constantly regenerating keys. We'd DOSed ourselves. And it took us *a good while* to figure out the cause.
|
|
||||||
|
|
||||||
Lessons learned: maybe don't block the inital database CREATE waiting for keyspace to free up. Or maybe it was to just not have a feasibly bounded keyspace in the first place? I dunno, we just changed our key format to give us more keyspace and set up more alarms.
|
|
|
@ -1,34 +0,0 @@
|
||||||
+++
|
|
||||||
slug = "thoughts-on-zed"
|
|
||||||
title = "Zed: Early Thoughts"
|
|
||||||
date = 2024-08-24T15:37:07.509694-04:00
|
|
||||||
draft = false
|
|
||||||
|
|
||||||
[taxonomies]
|
|
||||||
# An array of quoted strings
|
|
||||||
tags = ["software", "review"]
|
|
||||||
+++
|
|
||||||
|
|
||||||
![](/images/zed-screenshot.png)
|
|
||||||
|
|
||||||
I've been using [Zed](https://zed.dev) a bit, and as a software developer on the internet, I have *thoughts.*
|
|
||||||
|
|
||||||
I'm using it to write Elixir/Phoenix, HTML/CSS, and some Markdown, and it's trying to take the place of the venerable Emacs (running [DOOM](https://github.com/doomemacs/doomemacs)).
|
|
||||||
|
|
||||||
In no particular order:
|
|
||||||
|
|
||||||
* A truly open-source editor! Written in Rust! Finally, a modern editor that isn't a Microsoft embrace/extend/extinguish vector!
|
|
||||||
* Goddammit is that a Github sign-in link? Shit.
|
|
||||||
* The built-in vim mode isn't bad, but it pales in comparison to `evil-mode`. Specifically I can't highlight a region and `:%s/search/replace/g` inside it.
|
|
||||||
* I think having `:` open the command palette is a bad idea. The way one uses the command palette vs vim-style commands has less overlap than you'd think.
|
|
||||||
* It's pretty! Look I'm not immune to eye-candy, and Emacs has always ranked low in that area.
|
|
||||||
* I'm not getting anything from elixir-ls. Even *Emacs* automatically installs and sets that up so...y'know, damn. Two demerits, Mr. Zed.
|
|
||||||
* Same with speling check in things like Markdown files.
|
|
||||||
* Like most things, it ignores the "Emacs-keys" GTK setting &emdash; not being a GTK app I'm not shocked, but things like Firefox respect it, so it *can* be done. Ctrl-A not going to beginning of line, for instance.
|
|
||||||
* Not sure I love this though:
|
|
||||||
|
|
||||||
![the Zed Roadmap for 2024 includes "embrace AI" as one of the three items on the list.](/images/zed-roadmap-2024.png)
|
|
||||||
|
|
||||||
I'm running solo at the moment so I haven't tried any of the "multiplayer" remote-pairing stuff. I *believe* it's behind a Github-login though, and I wish that weren't the case.
|
|
||||||
|
|
||||||
Overall: three stars, worthy of your time and attention, also please stop using Microsoft products.
|
|
|
@ -1,5 +1,4 @@
|
||||||
+++
|
+++
|
||||||
slug = "mumble_voice_chat"
|
|
||||||
title = "LAN Voice Chat with Mumble"
|
title = "LAN Voice Chat with Mumble"
|
||||||
date = 2024-04-16 11:51:33-04:00
|
date = 2024-04-16 11:51:33-04:00
|
||||||
draft = false
|
draft = false
|
|
@ -1,5 +1,4 @@
|
||||||
+++
|
+++
|
||||||
slug = "odyssey_ark_gen2_kvm"
|
|
||||||
title = "HOWTO: Use the KVM in the Odyssey Ark Gen2"
|
title = "HOWTO: Use the KVM in the Odyssey Ark Gen2"
|
||||||
draft = false
|
draft = false
|
||||||
date = 2024-01-02 14:00:00-05:00
|
date = 2024-01-02 14:00:00-05:00
|
|
@ -1,6 +1,5 @@
|
||||||
+++
|
+++
|
||||||
title = "HOWTO: Fix Steam Deck Unresponsive Touchscreen"
|
title = "HOWTO: Fix Steam Deck Unresponsive Touchscreen"
|
||||||
slug = "fix_steam_deck_touchscreen"
|
|
||||||
date = 2024-01-07 13:40:00-05:00
|
date = 2024-01-07 13:40:00-05:00
|
||||||
|
|
||||||
[taxonomies]
|
[taxonomies]
|
|
@ -1,6 +1,5 @@
|
||||||
+++
|
+++
|
||||||
title = "The Names We Discard"
|
title = "The Names We Discard"
|
||||||
slug = "names_we_discard"
|
|
||||||
date = 2024-01-30 15:53:22-05:00
|
date = 2024-01-30 15:53:22-05:00
|
||||||
|
|
||||||
[taxonomies]
|
[taxonomies]
|
Binary file not shown.
Before Width: | Height: | Size: 31 KiB |
Binary file not shown.
Before Width: | Height: | Size: 153 KiB |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue