Compare commits

..

16 Commits

Author SHA1 Message Date
d313bdcc32 Fix EXIF rotation
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-16 19:15:59 +01:00
19ce16fabb Fix hero spacing
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-14 23:54:35 +01:00
62882e5943 Update theme
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-14 23:32:19 +01:00
c50910bcec Update theme
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-14 22:01:44 +01:00
e56e1e8e51 Format
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-14 20:09:36 +01:00
3938d190d5 Add comments
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-14 19:40:37 +01:00
e7d8ece65d Add summary animation
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-14 11:17:14 +01:00
d9a3c4b4a1 Fix crash on missing hero
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-13 23:23:17 +00:00
8834c6dc21 Hide reading time when 0
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-13 22:44:48 +00:00
6353c33ae2 Add exif hero images
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-13 22:32:16 +00:00
08b8041c43 Update gallery page
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-13 21:36:59 +00:00
9905066046 Improve taxonomy handling
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-13 15:07:18 +01:00
4e37655a16 Fix unhighlighted code styles
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-13 15:07:18 +01:00
de272212ca Add shell prompt support
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-13 15:07:18 +01:00
8fac4841d4 Fix layout bugs
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-13 15:07:18 +01:00
c52639e38f Add image processing
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-09-13 15:07:15 +01:00
33 changed files with 837 additions and 766 deletions

View File

@@ -4,6 +4,7 @@ import Masonry from "masonry-layout";
const lightbox = new PhotoSwipeLightbox({ const lightbox = new PhotoSwipeLightbox({
gallery: ".lightbox", gallery: ".lightbox",
children: ".pswp-image", children: ".pswp-image",
bgOpacity: 1,
showAnimationDuration: 300, showAnimationDuration: 300,
hideAnimationDuration: 300, hideAnimationDuration: 300,
initialZoomLevel: "fit", initialZoomLevel: "fit",

View File

@@ -12,7 +12,7 @@ blockquote {
} }
p { p {
margin: 0 0 0.5rem 0; margin: 0.5rem 0 0.5rem 0;
} }
p:last-child { p:last-child {

View File

@@ -1,5 +1,4 @@
/* PreWrapper */ pre {
.chroma {
color: var(--text); color: var(--text);
background-color: var(--background-50); background-color: var(--background-50);
padding: 1rem; padding: 1rem;
@@ -7,411 +6,418 @@
overflow-x: auto; overflow-x: auto;
} }
/* Error */ /* PreWrapper */
.chroma .err { .chroma {
color: var(--accent-500); .line.prompt::before {
} content: "$ ";
}
/* LineLink */
.chroma .lnlinks { /* Error */
outline: none; .err {
text-decoration: none; color: var(--accent-600);
color: inherit; }
}
/* LineLink */
/* LineTableTD */ .lnlinks {
.chroma .lntd { outline: none;
vertical-align: top; text-decoration: none;
padding: 0; color: inherit;
margin: 0; }
border: 0;
} /* LineTableTD */
.lntd {
/* LineTable */ vertical-align: top;
.chroma .lntable { padding: 0;
border-spacing: 0; margin: 0;
padding: 0; border: 0;
margin: 0; }
border: 0;
} /* LineTable */
.lntable {
/* LineHighlight */ border-spacing: 0;
.chroma .hl { padding: 0;
background-color: var(--background-200); margin: 0;
} border: 0;
}
/* LineNumbersTable */
.chroma .lnt { /* LineHighlight */
white-space: pre; .hl {
-webkit-user-select: none; background-color: var(--background-100);
user-select: none; }
margin-right: 0.4em;
padding: 0 0.4em 0 0.4em; /* LineNumbersTable */
} .lnt {
white-space: pre;
/* LineNumbers */ -webkit-user-select: none;
.chroma .ln { user-select: none;
white-space: pre; margin-right: 0.4em;
-webkit-user-select: none; padding: 0 0.4em 0 0.4em;
user-select: none; }
margin-right: 0.4em;
padding: 0 0.4em 0 0.4em; /* LineNumbers */
color: color-mix(in srgb, var(--text) 50%, var(--background-50)); .ln {
} white-space: pre;
-webkit-user-select: none;
/* Line */ user-select: none;
.chroma .line { margin-right: 0.4em;
display: flex; padding: 0 0.4em 0 0.4em;
} color: color-mix(in srgb, var(--text) 50%, var(--background-50));
}
/* Keyword */
.chroma .k { /* Line */
color: var(--secondary-600); .line {
} display: flex;
}
/* KeywordConstant */
.chroma .kc { /* Keyword */
color: var(--primary-500); .k {
} color: var(--secondary-700);
}
/* KeywordDeclaration */
.chroma .kd { /* KeywordConstant */
color: var(--secondary-600); .kc {
} color: var(--primary-600);
}
/* KeywordNamespace */
.chroma .kn { /* KeywordDeclaration */
color: var(--secondary-600); .kd {
} color: var(--secondary-700);
}
/* KeywordPseudo */
.chroma .kp { /* KeywordNamespace */
color: var(--primary-500); .kn {
} color: var(--secondary-700);
}
/* KeywordReserved */
.chroma .kr { /* KeywordPseudo */
color: var(--secondary-600); .kp {
} color: var(--primary-600);
}
/* KeywordType */
.chroma .kt { /* KeywordReserved */
color: var(--secondary-600); .kr {
} color: var(--secondary-700);
}
/* Name */
.chroma .nc { /* KeywordType */
color: var(--accent-600); .kt {
font-weight: bold; color: var(--secondary-700);
} }
/* NameConstant */ /* Name */
.chroma .no { .nc {
color: var(--primary-500); color: var(--accent-700);
font-weight: bold; font-weight: bold;
} }
/* NameDecorator */ /* NameConstant */
.chroma .nd { .no {
color: var(--secondary-700); color: var(--primary-600);
font-weight: bold; font-weight: bold;
} }
/* NameEntity */ /* NameDecorator */
.chroma .ni { .nd {
color: var(--accent-600); color: var(--secondary-800);
} font-weight: bold;
}
/* NameException */
.chroma .ne { /* NameEntity */
color: var(--accent-600); .ni {
font-weight: bold; color: var(--accent-700);
} }
/* NameLabel */ /* NameException */
.chroma .nl { .ne {
color: var(--primary-500); color: var(--accent-700);
font-weight: bold; font-weight: bold;
} }
/* NameNamespace */ /* NameLabel */
.chroma .nn { .nl {
color: var(--secondary-600); color: var(--primary-600);
} font-weight: bold;
}
/* NameProperty */
.chroma .py { /* NameNamespace */
color: var(--primary-500); .nn {
} color: var(--secondary-700);
}
/* NameTag */
.chroma .nt { /* NameProperty */
color: var(--primary-600); .py {
} color: var(--primary-600);
}
/* NameVariable */
.chroma .nv { /* NameTag */
color: var(--primary-500); .nt {
} color: var(--primary-700);
}
/* NameVariableClass */
.chroma .vc { /* NameVariable */
color: var(--primary-500); .nv {
} color: var(--primary-600);
}
/* NameVariableGlobal */
.chroma .vg { /* NameVariableClass */
color: var(--primary-500); .vc {
} color: var(--primary-600);
}
/* NameVariableInstance */
.chroma .vi { /* NameVariableGlobal */
color: var(--primary-500); .vg {
} color: var(--primary-600);
}
/* NameVariableMagic */
.chroma .vm { /* NameVariableInstance */
color: var(--primary-500); .vi {
} color: var(--primary-600);
}
/* NameFunction */
.chroma .nf { /* NameVariableMagic */
color: var(--secondary-700); .vm {
font-weight: bold; color: var(--primary-600);
} }
/* NameFunctionMagic */ /* NameFunction */
.chroma .fm { .nf {
color: var(--secondary-700); color: var(--secondary-800);
font-weight: bold; font-weight: bold;
} }
/* Literal */ /* NameFunctionMagic */
.chroma .l { .fm {
color: var(--primary-600); color: var(--secondary-800);
} font-weight: bold;
}
/* LiteralDate */
.chroma .ld { /* Literal */
color: var(--primary-500); .l {
} color: var(--primary-700);
}
/* LiteralString */
.chroma .s { /* LiteralDate */
color: var(--primary-600); .ld {
} color: var(--primary-600);
}
/* LiteralStringAffix */
.chroma .sa { /* LiteralString */
color: var(--primary-500); .s {
} color: var(--primary-700);
}
/* LiteralStringBacktick */
.chroma .sb { /* LiteralStringAffix */
color: var(--primary-600); .sa {
} color: var(--primary-600);
}
/* LiteralStringChar */
.chroma .sc { /* LiteralStringBacktick */
color: var(--primary-600); .sb {
} color: var(--primary-700);
}
/* LiteralStringDelimiter */
.chroma .dl { /* LiteralStringChar */
color: var(--primary-500); .sc {
} color: var(--primary-700);
}
/* LiteralStringDoc */
.chroma .sd { /* LiteralStringDelimiter */
color: var(--primary-600); .dl {
} color: var(--primary-600);
}
/* LiteralStringDouble */
.chroma .s2 { /* LiteralStringDoc */
color: var(--primary-600); .sd {
} color: var(--primary-700);
}
/* LiteralStringEscape */
.chroma .se { /* LiteralStringDouble */
color: var(--primary-500); .s2 {
} color: var(--primary-700);
}
/* LiteralStringHeredoc */
.chroma .sh { /* LiteralStringEscape */
color: var(--primary-500); .se {
} color: var(--primary-600);
}
/* LiteralStringInterpol */
.chroma .si { /* LiteralStringHeredoc */
color: var(--primary-600); .sh {
} color: var(--primary-600);
}
/* LiteralStringOther */
.chroma .sx { /* LiteralStringInterpol */
color: var(--primary-600); .si {
} color: var(--primary-700);
}
/* LiteralStringRegex */
.chroma .sr { /* LiteralStringOther */
color: var(--primary-500); .sx {
} color: var(--primary-700);
}
/* LiteralStringSingle */
.chroma .s1 { /* LiteralStringRegex */
color: var(--primary-600); .sr {
} color: var(--primary-600);
}
/* LiteralStringSymbol */
.chroma .ss { /* LiteralStringSingle */
color: var(--primary-600); .s1 {
} color: var(--primary-700);
}
/* LiteralNumber */
.chroma .m { /* LiteralStringSymbol */
color: var(--primary-600); .ss {
} color: var(--primary-700);
}
/* LiteralNumberBin */
.chroma .mb { /* LiteralNumber */
color: var(--primary-600); .m {
} color: var(--primary-700);
}
/* LiteralNumberFloat */
.chroma .mf { /* LiteralNumberBin */
color: var(--primary-600); .mb {
} color: var(--primary-700);
}
/* LiteralNumberHex */
.chroma .mh { /* LiteralNumberFloat */
color: var(--primary-600); .mf {
} color: var(--primary-700);
}
/* LiteralNumberInteger */
.chroma .mi { /* LiteralNumberHex */
color: var(--primary-600); .mh {
} color: var(--primary-700);
}
/* LiteralNumberIntegerLong */
.chroma .il { /* LiteralNumberInteger */
color: var(--primary-600); .mi {
} color: var(--primary-700);
}
/* LiteralNumberOct */
.chroma .mo { /* LiteralNumberIntegerLong */
color: var(--primary-600); .il {
} color: var(--primary-700);
}
/* Operator */
.chroma .o { /* LiteralNumberOct */
color: var(--secondary-600); .mo {
font-weight: bold; color: var(--primary-700);
} }
/* OperatorWord */ /* Operator */
.chroma .ow { .o {
color: var(--secondary-600); color: var(--secondary-700);
font-weight: bold; font-weight: bold;
} }
/* Comment */ /* OperatorWord */
.chroma .c { .ow {
color: color-mix(in srgb, var(--text) 50%, var(--background-50)); color: var(--secondary-700);
font-style: italic; font-weight: bold;
} }
/* CommentHashbang */ /* Comment */
.chroma .ch { .c {
color: color-mix(in srgb, var(--text) 50%, var(--background-50)); color: color-mix(in srgb, var(--text) 50%, var(--background-50));
font-style: italic; font-style: italic;
} }
/* CommentMultiline */ /* CommentHashbang */
.chroma .cm { .ch {
color: color-mix(in srgb, var(--text) 50%, var(--background-50)); color: color-mix(in srgb, var(--text) 50%, var(--background-50));
font-style: italic; font-style: italic;
} }
/* CommentSingle */ /* CommentMultiline */
.chroma .c1 { .cm {
color: color-mix(in srgb, var(--text) 50%, var(--background-50)); color: color-mix(in srgb, var(--text) 50%, var(--background-50));
font-style: italic; font-style: italic;
} }
/* CommentSpecial */ /* CommentSingle */
.chroma .cs { .c1 {
color: color-mix(in srgb, var(--text) 50%, var(--background-50)); color: color-mix(in srgb, var(--text) 50%, var(--background-50));
font-weight: bold; font-style: italic;
font-style: italic; }
}
/* CommentSpecial */
/* CommentPreproc */ .cs {
.chroma .cp { color: color-mix(in srgb, var(--text) 50%, var(--background-50));
color: color-mix(in srgb, var(--text) 50%, var(--background-50)); font-weight: bold;
font-weight: bold; font-style: italic;
font-style: italic; }
}
/* CommentPreproc */
/* CommentPreprocFile */ .cp {
.chroma .cpf { color: color-mix(in srgb, var(--text) 50%, var(--background-50));
color: color-mix(in srgb, var(--text) 50%, var(--background-50)); font-weight: bold;
font-weight: bold; font-style: italic;
font-style: italic; }
}
/* CommentPreprocFile */
/* GenericDeleted */ .cpf {
.chroma .gd { color: color-mix(in srgb, var(--text) 50%, var(--background-50));
color: var(--accent-900); font-weight: bold;
background-color: var(--accent-300); font-style: italic;
} }
/* GenericEmph */ /* GenericDeleted */
.chroma .ge { .gd {
font-style: italic; color: var(--accent-900);
} background-color: var(--accent-300);
}
/* GenericError */
.chroma .gr { /* GenericEmph */
color: var(--accent-500); .ge {
} font-style: italic;
}
/* GenericHeading */
.chroma .gh { /* GenericError */
color: var(--primary-500); .gr {
font-weight: bold; color: var(--accent-600);
} }
/* GenericInserted */ /* GenericHeading */
.chroma .gi { .gh {
color: var(--primary-800); color: var(--primary-600);
background-color: var(--primary-200); font-weight: bold;
} }
/* GenericOutput */ /* GenericInserted */
.chroma .go { .gi {
color: color-mix(in srgb, var(--text) 70%, var(--background-50)); color: var(--primary-800);
} background-color: var(--primary-200);
}
/* GenericPrompt */
.chroma .gp { /* GenericOutput */
color: color-mix(in srgb, var(--text) 70%, var(--background-50)); .go {
} color: color-mix(in srgb, var(--text) 70%, var(--background-50));
}
/* GenericStrong */
.chroma .gs { /* GenericPrompt */
font-weight: bold; .gp {
} color: color-mix(in srgb, var(--text) 70%, var(--background-50));
}
/* GenericSubheading */
.chroma .gu { /* GenericStrong */
color: var(--primary-500); .gs {
} font-weight: bold;
}
/* GenericTraceback */
.chroma .gt { /* GenericSubheading */
color: var(--secondary-600); .gu {
} color: var(--primary-600);
}
/* GenericUnderline */
.chroma .gl { /* GenericTraceback */
text-decoration: underline; .gt {
color: var(--secondary-700);
}
/* GenericUnderline */
.gl {
text-decoration: underline;
}
} }

View File

@@ -1,143 +1,71 @@
:root { // https://www.realtimecolors.com/
--text: #050c0e;
--background: #f1f8fa;
--primary: #51a9c3;
--secondary: #d88fb9;
--accent: #ce7f71;
}
@media (prefers-color-scheme: dark) { :root {
:root { --text: #0d1416;
--text: #f0f8fa; --background: #fdfdfd;
--background: #050d0f; --primary: #669ca3;
--primary: #3c94af; --secondary: #a5abc9;
--secondary: #712853; --accent: #8d8cba;
--accent: #8d3e30;
}
} }
:root { :root {
--text-50: #ecf6f8; --text-50: #eff4f6;
--text-100: #daecf1; --text-100: #dfe9ec;
--text-200: #b4dae4; --text-200: #bfd4d9;
--text-300: #8fc7d6; --text-300: #9fbec6;
--text-400: #69b4c9; --text-400: #7ea8b4;
--text-500: #44a1bb; --text-500: #5e92a1;
--text-600: #368196; --text-600: #4b7581;
--text-700: #296170; --text-700: #395860;
--text-800: #1b414b; --text-800: #263b40;
--text-900: #0e2025; --text-900: #131d20;
--text-950: #071013; --text-950: #090f10;
--background-50: #ecf6f8; --background-50: #f0f5f5;
--background-100: #daecf1; --background-100: #e0ebeb;
--background-200: #b4dae4; --background-200: #c2d6d6;
--background-300: #8fc7d6; --background-300: #a3c2c2;
--background-400: #69b4c9; --background-400: #85adad;
--background-500: #44a1bb; --background-500: #669999;
--background-600: #368196; --background-600: #527a7a;
--background-700: #296170; --background-700: #3d5c5c;
--background-800: #1b414b; --background-800: #293d3d;
--background-900: #0e2025; --background-900: #141f1f;
--background-950: #071013; --background-950: #0a0f0f;
--primary-50: #ecf6f8; --primary-50: #eff5f5;
--primary-100: #d9ecf2; --primary-100: #dfeaec;
--primary-200: #b3d9e5; --primary-200: #bfd6d9;
--primary-300: #8dc6d8; --primary-300: #9fc1c6;
--primary-400: #67b4cb; --primary-400: #80adb3;
--primary-500: #41a1be; --primary-500: #60989f;
--primary-600: #348198; --primary-600: #4d7a80;
--primary-700: #276072; --primary-700: #395b60;
--primary-800: #1a404c; --primary-800: #263d40;
--primary-900: #0d2026; --primary-900: #131e20;
--primary-950: #071013; --primary-950: #0a0f10;
--secondary-50: #f8ecf3; --secondary-50: #eff0f5;
--secondary-100: #f2d9e8; --secondary-100: #dfe1ec;
--secondary-200: #e4b4d0; --secondary-200: #bfc4d9;
--secondary-300: #d78eb9; --secondary-300: #9fa6c6;
--secondary-400: #ca68a1; --secondary-400: #8088b3;
--secondary-500: #bd428a; --secondary-500: #606a9f;
--secondary-600: #97356e; --secondary-600: #4d5580;
--secondary-700: #712853; --secondary-700: #394060;
--secondary-800: #4b1b37; --secondary-800: #262b40;
--secondary-900: #260d1c; --secondary-900: #131520;
--secondary-950: #13070e; --secondary-950: #0a0b10;
--accent-50: #f8eeec; --accent-50: #efeff5;
--accent-100: #f2ddd9; --accent-100: #dfdfec;
--accent-200: #e5bbb3; --accent-200: #c0bfd9;
--accent-300: #d8988d; --accent-300: #a09fc6;
--accent-400: #cb7667; --accent-400: #8080b3;
--accent-500: #be5441; --accent-500: #61609f;
--accent-600: #984334; --accent-600: #4d4d80;
--accent-700: #723227; --accent-700: #3a3960;
--accent-800: #4c221a; --accent-800: #272640;
--accent-900: #26110d; --accent-900: #131320;
--accent-950: #130807; --accent-950: #0a0a10;
}
@media (prefers-color-scheme: dark) {
:root {
--text-50: #061113;
--text-100: #0d2126;
--text-200: #19424d;
--text-300: #266373;
--text-400: #338599;
--text-500: #40a6bf;
--text-600: #66b8cc;
--text-700: #8cc9d9;
--text-800: #b3dbe6;
--text-900: #d9edf2;
--text-950: #ecf6f9;
--background-50: #061113;
--background-100: #0d2126;
--background-200: #19424d;
--background-300: #266373;
--background-400: #338599;
--background-500: #40a6bf;
--background-600: #66b8cc;
--background-700: #8cc9d9;
--background-800: #b3dbe6;
--background-900: #d9edf2;
--background-950: #ecf6f9;
--primary-50: #071013;
--primary-100: #0d2026;
--primary-200: #1a404c;
--primary-300: #276072;
--primary-400: #348198;
--primary-500: #41a1be;
--primary-600: #67b4cb;
--primary-700: #8dc6d8;
--primary-800: #b3d9e5;
--primary-900: #d9ecf2;
--primary-950: #ecf6f8;
--secondary-50: #13070e;
--secondary-100: #260d1c;
--secondary-200: #4b1b37;
--secondary-300: #712853;
--secondary-400: #97356e;
--secondary-500: #bd428a;
--secondary-600: #ca68a1;
--secondary-700: #d78eb9;
--secondary-800: #e4b4d0;
--secondary-900: #f2d9e8;
--secondary-950: #f8ecf3;
--accent-50: #130807;
--accent-100: #26110d;
--accent-200: #4c221a;
--accent-300: #723227;
--accent-400: #984334;
--accent-500: #be5441;
--accent-600: #cb7667;
--accent-700: #d8988d;
--accent-800: #e5bbb3;
--accent-900: #f2ddd9;
--accent-950: #f8eeec;
}
} }

View File

@@ -59,6 +59,38 @@ p {
margin: 1.5rem 0 1.5rem 0; margin: 1.5rem 0 1.5rem 0;
} }
li:not(:last-child) { li {
margin-bottom: 0.5rem; margin: 0.5rem 0 0.5rem 0;
}
details {
background-color: var(--background-50);
padding: 1rem 1.5rem 1rem 1.5rem;
border-radius: 0.5rem;
p {
margin: 0.5rem 0 0.5rem 0;
}
summary {
margin: 0.5rem;
font-weight: bold;
display: inline-flex;
align-items: center;
gap: 0.5rem;
cursor: pointer;
}
summary::before {
content: "";
border-width: 0.4rem;
border-style: solid;
border-color: transparent transparent transparent var(--text);
transition: transform 0.3s ease;
transform-origin: 25% 50%;
}
&[open] summary::before {
transform: rotate(90deg);
}
} }

55
assets/sass/details.scss Normal file
View File

@@ -0,0 +1,55 @@
main.with-details {
max-width: $width-wide;
margin: 0 auto;
padding: 2rem;
> .content {
width: 100%;
padding: 0;
}
$width-sidebar: ($width-wide - $width-content) / 2 - 2rem;
display: grid;
grid-template-columns: $width-sidebar $width-content $width-sidebar;
column-gap: 2rem;
.title {
font-size: 1.75rem;
margin: 0;
}
.length {
color: color-mix(in srgb, var(--text) 70%, var(--background));
margin: 0.5rem 0 0.5rem 0;
font-size: 0.8rem;
}
}
@media (max-width: $width-wide) {
main.with-details {
display: block;
padding: 0;
> .details {
max-width: $width-content;
margin: 0 auto;
padding: 2rem;
}
> .content {
padding: 2rem;
}
}
}
@media (max-width: $width-mobile) {
main.with-details {
> .details {
padding: 1rem;
}
> .content {
padding: 0 1rem 1rem 1rem;
}
}
}

View File

@@ -13,7 +13,7 @@
font-size: 0.85rem; font-size: 0.85rem;
color: color-mix(in srgb, var(--text) 30%, var(--background)); color: color-mix(in srgb, var(--text) 50%, var(--background));
a { a {
color: inherit; color: inherit;
@@ -36,6 +36,7 @@
list-style: none; list-style: none;
li { li {
margin: 0;
font-size: 0.85rem; font-size: 0.85rem;
} }
} }

View File

@@ -7,22 +7,6 @@
margin: 0; margin: 0;
font-size: 2.5rem; font-size: 2.5rem;
} }
.meta {
font-size: 0.8rem;
.date {
color: var(--text-600);
}
.duration {
color: color-mix(in srgb, var(--text) 50%, var(--background));
}
}
.captioned-image {
padding-top: 1.5rem;
}
} }
.hero + .content { .hero + .content {
@@ -31,6 +15,6 @@
@media (max-width: $width-mobile) { @media (max-width: $width-mobile) {
.hero { .hero {
padding: 1rem; padding: 1rem 1rem 0 1rem;
} }
} }

View File

@@ -10,7 +10,7 @@ img {
figcaption { figcaption {
text-align: center; text-align: center;
padding-top: 0.5rem; padding-top: 1rem;
color: color-mix(in srgb, var(--text) 50%, var(--background)); color: color-mix(in srgb, var(--text) 70%, var(--background));
} }
} }

View File

@@ -1,64 +1,17 @@
main.with-meta {
max-width: $width-wide;
margin: 0 auto;
padding: 2rem;
> .content {
padding: 0;
}
$width-sidebar: ($width-wide - $width-content) / 2 - 2rem;
display: grid;
grid-template-columns: $width-sidebar $width-content $width-sidebar;
column-gap: 2rem;
h1 {
font-size: 1.75rem;
}
.length {
color: color-mix(in srgb, var(--text) 50%, var(--background));
margin: 0.25rem 0;
font-size: 0.8rem;
}
}
@media (max-width: $width-wide) {
main.with-meta {
display: block;
padding: 0;
> .meta {
max-width: $width-content;
margin: 0 auto;
padding: 2rem;
}
> .content {
padding: 2rem;
}
}
}
@media (max-width: $width-mobile) {
main.with-meta {
> .meta {
padding: 1rem;
}
> .content {
padding: 0 1rem 1rem 1rem;
}
}
}
.list { .list {
.post { .post {
display: block; display: block;
color: inherit;
> a {
color: inherit;
}
> a:hover {
color: var(--text-800);
}
&:not(:first-child) { &:not(:first-child) {
margin-top: 4rem; margin: 4rem 0 4rem 0;
} }
.title { .title {
@@ -67,38 +20,20 @@ main.with-meta {
} }
.summary { .summary {
margin-top: 0.5rem; margin: 0.5rem 0 0.5rem 0;
}
.meta {
margin-top: 1rem;
font-size: 0.8rem;
.date {
color: var(--text-600);
}
.duration {
color: color-mix(in srgb, var(--text) 50%, var(--background));
}
} }
.heading-anchor { .heading-anchor {
display: none; display: none;
} }
} }
.post:hover .title,
.post:hover .summary {
color: var(--text-800);
}
} }
@media (max-width: $width-mobile) { @media (max-width: $width-mobile) {
.list { .list {
.post { .post {
&:not(:first-child) { &:not(:first-child) {
margin-top: 2rem; margin: 2rem 0 2rem 0;
} }
.title { .title {

View File

@@ -11,7 +11,9 @@ $width-wide: 75rem;
@import "blockquote"; @import "blockquote";
@import "code"; @import "code";
@import "table"; @import "table";
@import "meta";
@import "details";
@import "list"; @import "list";
@import "gallery"; @import "gallery";

20
assets/sass/meta.scss Normal file
View File

@@ -0,0 +1,20 @@
.meta {
margin: 1rem 0 1rem 0;
font-size: 0.8rem;
.date {
color: var(--text);
}
.tag {
color: var(--primary-600);
}
.tag:hover {
color: var(--primary-800);
}
.duration {
color: color-mix(in srgb, var(--text) 70%, var(--background));
}
}

View File

@@ -18,13 +18,13 @@
position: fixed; position: fixed;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
height: 5rem; height: auto;
padding: 1rem 2rem; padding: 1rem 2rem;
text-align: center; text-align: center;
line-height: 1.5rem; line-height: 1.5rem;
.meta { .meta {
font-size: 0.7rem; margin: 0;
} }
a { a {

View File

@@ -0,0 +1,4 @@
{{ $result := transform.HighlightCodeBlock . }}
{{ $pattern := `(?s)<span class="line"([^>]*)>(\s*<span[^>]*>)?\$ (.*?)(</span>\s*)</span>` }}
{{ $processed := replaceRE $pattern `<span class="line prompt"$1>$2$3$4</span>` $result.Wrapped }}
{{ $processed | safeHTML }}

View File

@@ -1,7 +1,3 @@
{{ partial "components/image/index.html" (dict "page" .Page "image" (dict {{ $data := partial "components/image/process.html" (dict "page" .Page "src" .Destination) }}
"src" .Destination {{ partial "components/image/index.html" (merge $data (dict "caption" .Text "title" .Title)) }}
"caption" .Text
"alt" .Title
))
}}
{{- /* chomp trailing newline */ -}} {{- /* chomp trailing newline */ -}}

View File

@@ -1,8 +1,8 @@
{{ define "main" }} {{ define "main" }}
{{ $withMeta := default true .Params.withMeta }} {{ $details := default true .Params.details }}
<main class="{{- if $withMeta -}}with-meta{{- end -}}"> <main class="{{- if $details -}}with-details{{- end -}}">
{{ if $withMeta }} {{ if $details }}
{{ partial "components/list/meta.html" . }} {{ partial "components/list/details.html" . }}
{{ end }} {{ end }}
<div class="content"> <div class="content">
{{ partial "posts/list.html" . }} {{ partial "posts/list.html" . }}

View File

@@ -3,6 +3,10 @@
{{ partial "components/hero/index.html" . }} {{ partial "components/hero/index.html" . }}
<div class="content"> <div class="content">
{{ .Content }} {{ .Content }}
{{ if (default true .Params.comments) }}
{{ partial "comments.html" . }}
{{ end }}
</div> </div>
{{ partial "components/postnav/index.html" . }} {{ partial "components/postnav/index.html" . }}
</main> </main>

View File

@@ -0,0 +1,5 @@
<details class="toc">
<summary>Post Contents</summary>
{{ .Page.TableOfContents }}
</details>
{{- /* chomp trailing newline */ -}}

View File

@@ -0,0 +1,25 @@
{{ $src := "" }}
{{ if .IsNamedParams }}
{{ $src = .Get "src" }}
{{ else }}
{{ $src = .Get 0 }}
{{ end }}
{{ $title := "" }}
{{ if .IsNamedParams }}
{{ $title = .Get "title" }}
{{ else }}
{{ $title = .Get 1 }}
{{ end }}
{{ $alt := "" }}
{{ if .IsNamedParams }}
{{ $alt = .Get "alt" }}
{{ else }}
{{ $alt = .Get 1 }}
{{ end }}
{{ $data := partial "components/image/process.html" (dict "page" .Page "src" $src) }}
{{ $caption := partial "components/image/exif.html" $data.original }}
{{ partial "components/image/index.html" (merge $data (dict "caption" $caption "title" $title "alt" $alt)) }}
{{- /* chomp trailing newline */ -}}

View File

@@ -1,2 +1 @@
<sub>{{ .Get 0 | markdownify }}</sub> <sub>{{ .Get 0 | markdownify }}</sub> {{- /* chomp trailing newline */ -}}
{{- /* chomp trailing newline */ -}}

View File

@@ -1,2 +1 @@
<sup>{{ .Get 0 | markdownify }}</sup> <sup>{{ .Get 0 | markdownify }}</sup> {{- /* chomp trailing newline */ -}}
{{- /* chomp trailing newline */ -}}

View File

@@ -1,10 +1,16 @@
{{ define "main" }} {{ define "main" }}
{{ $withMeta := default true .Params.withMeta }} {{ $details := default true .Params.details }}
<main class="{{- if $withMeta -}}with-meta{{- end -}}"> <main class="{{- if $details -}}with-details{{- end -}}">
{{ if $withMeta }} {{ if $details }}
{{ partial "components/list/meta.html" . }} {{ partial "components/list/details.html" . }}
{{ end }} {{ end }}
<div class="{{- if $withMeta -}}content{{- else -}}content wide{{- end -}}"> <div
class="{{- if $details -}}
content
{{- else -}}
content wide
{{- end -}}"
>
{{ partial "gallery/list.html" . }} {{ partial "gallery/list.html" . }}
</div> </div>
</main> </main>

View File

View File

@@ -1,9 +1,17 @@
<section class="hero"> <section class="hero">
<h1 class="title">{{ .Title }}</h1> <h1 class="title">{{ .Title }}</h1>
<div class="meta"> {{ partial "components/meta/index.html" . }}
<span class="date">{{ .Date | time.Format ":date_medium" }}</span>
&middot; {{ $hero := partial "components/hero/process.html" .Params.hero }}
<span class="duration">{{ printf "%d MIN READ" .ReadingTime }}</span> {{ if $hero.src }}
</div> {{ $data := partial "components/image/process.html" (dict "page" .Page "src" $hero.src) }}
{{ partial "components/image/index.html" (dict "page" .Page "image" .Params.hero) }}
{{ $final := merge $data $hero }}
{{ if $hero.exif }}
{{ $caption := partial "components/image/exif.html" $data.original }}
{{ $final = merge $final (dict "caption" $caption) }}
{{ end }}
{{ partial "components/image/index.html" $final }}
{{ end }}
</section> </section>

View File

@@ -0,0 +1,17 @@
{{- $src := "" -}}
{{- $caption := "" -}}
{{- $title := "" -}}
{{- $alt := "" -}}
{{- $exif := false -}}
{{- if reflect.IsMap . -}}
{{- $src = .src -}}
{{- $caption = .caption -}}
{{- $title = .title -}}
{{- $alt = .alt -}}
{{- $exif = .exif | default false -}}
{{- else -}}
{{- $src = . -}}
{{- end -}}
{{- return dict "src" $src "caption" $caption "title" $title "alt" $alt "exif" $exif -}}

View File

@@ -0,0 +1,22 @@
{{ $exif := .Exif.Tags }}
{{ $make := $exif.Make }}
{{ $model := $exif.Model }}
{{ $lensMake := $exif.LensMake }}
{{ $lensModel := $exif.LensModel }}
{{ $lens := "" }}
{{ if ne $make $lensMake }}
{{ $lens = printf "%s %s" $lensMake $lensModel }}
{{ else }}
{{ $lens = $lensModel }}
{{ end }}
{{ $focal := printf "%.1f" (float $exif.FocalLength) }}
{{ $focal35 := printf "%.1f" (float $exif.FocalLengthIn35mmFormat) }}
{{ $shutter := printf "%d" $exif.ExposureTime }}
{{ $aperture := printf "%d" $exif.FNumber }}
{{ $iso := printf "%d" $exif.ISO }}
{{ return printf "%s %s, %s @ %s mm (%s mm), %s s, f/%s, ISO %s" $make $model $lens $focal $focal35 $shutter $aperture $iso }}

View File

@@ -1,58 +1,26 @@
{{- $page := .page -}} {{- $caption := .caption | default "" -}}
{{- $image := .image -}} {{- $title := .title | default $caption | plainify -}}
{{- $alt := .alt | default $title | plainify -}}
{{- $src := $image -}}
{{- $caption := "" -}}
{{- $title := "" -}}
{{- $alt := "" -}}
{{- if reflect.IsMap $image -}} <figure class="captioned-image lightbox">
{{- $src = $image.src | default "" -}} <a
{{- $caption = $image.caption | default "" -}} href="{{- .full.RelPermalink -}}"
{{- $title = $image.title | default $caption | default "" -}} data-pswp-src="{{- .full.RelPermalink -}}"
{{- $alt = $image.alt | default $title | default "" -}} data-pswp-width="{{- .full.Width -}}"
{{- end -}} data-pswp-height="{{- .full.Height -}}"
class="pswp-image"
{{- if $src -}} >
{{- $isRemote := strings.HasPrefix $src "http" -}} <img
src="{{- .thumb.RelPermalink -}}"
{{- if $isRemote -}} width="{{- .thumb.Width -}}"
{{- $remote := resources.GetRemote $src -}} height="{{- .thumb.Height -}}"
{{- $image = resources.Copy (printf "static/3rd-party/%s" $remote.Name) $remote -}} loading="lazy"
{{- else -}} {{ with $title }}title="{{- . -}}"{{ end }}
{{- $image = ($page.Resources.Get $src) | default (resources.Get $src) -}} {{ with $alt }}alt="{{- . -}}"{{ end }}
{{- end -}} />
{{- end -}} </a>
{{ with $caption }}
{{- with $image -}} <figcaption>{{ . | safeHTML }}</figcaption>
{{ $full := . | images.Filter (images.Process "webp q90") }} {{ end }}
</figure>
{{ $thumb := . }}
{{- if gt .Width 2000 -}}
{{- $thumb = . | images.Filter (images.Process "resize 2000x webp q75") -}}
{{- else -}}
{{- $thumb = . | images.Filter (images.Process "webp q75") -}}
{{- end -}}
<figure class="captioned-image lightbox">
<a
href="{{- .RelPermalink -}}"
data-pswp-src="{{- .RelPermalink -}}"
data-pswp-width="{{- .Width -}}"
data-pswp-height="{{- .Height -}}"
class="pswp-image"
>
<img
src="{{- $thumb.RelPermalink -}}"
width="{{- .Width -}}"
height="{{- .Height -}}"
loading="lazy"
{{ with $title }}title="{{- . -}}"{{ end }}
{{ with $alt }}alt="{{- . -}}"{{ end }}
/>
</a>
{{ with $caption }}
<figcaption>{{ . | safeHTML }}</figcaption>
{{ end }}
</figure>
{{- end -}}

View File

@@ -0,0 +1,27 @@
{{- $page := .page -}}
{{- $src := .src -}}
{{- $original := "" -}}
{{- $isRemote := strings.HasPrefix $src "http" -}}
{{- if $isRemote -}}
{{- $remote := resources.GetRemote $src -}}
{{- $original = resources.Copy (printf "static/3rd-party/%s" $remote.Name) $remote -}}
{{- else -}}
{{- $original = ($page.Resources.Get $src) | default (resources.Get $src) -}}
{{- end -}}
{{- $rotate := images.AutoOrient -}}
{{- $processFull := images.Process "webp q90" -}}
{{- $full := $original | images.Filter (slice $rotate $processFull) -}}
{{- $processThumb := "" -}}
{{- if gt $original.Width 2000 -}}
{{- $processThumb = images.Process "resize 2000x webp q75" -}}
{{- else -}}
{{- $processThumb = images.Process "webp q75" -}}
{{- end -}}
{{- $thumb := $original | images.Filter (slice $rotate $processThumb) -}}
{{- return dict "original" $original "full" $full "thumb" $thumb -}}

View File

@@ -1,5 +1,5 @@
<section class="meta"> <section class="details">
<h1>{{ .Page.Title }}</h1> <h1 class="title">{{ .Page.Title }}</h1>
<p class="length">A {{ .Kind }} with {{ len .Pages }} items</p> <p class="length">A {{ .Kind }} with {{ len .Pages }} items</p>
{{ .Content }} {{ .Content }}
</section> </section>

View File

@@ -0,0 +1,22 @@
<div class="meta">
<span class="date">{{ .Date | time.Format ":date_medium" }}</span>
{{ if eq .Kind "page" }}
{{ range .Params.tags }}
&middot;
<a href="/tags/{{ . | urlize }}" class="tag">{{ . }}</a>
{{ end }}
{{ if ge .ReadingTime 1 }}
&middot;
<span class="duration">
{{ printf "%d min. read" .ReadingTime }}
</span>
{{ end }}
{{ else }}
{{ $count := len .Pages }}
<span class="duration">
{{ printf "%d %s" $count (cond (eq $count 1) "item" "items") }}
</span>
{{ end }}
</div>

View File

@@ -1,21 +1,26 @@
{{ $pages := .CurrentSection.Pages.ByDate.Reverse }} {{ $pages := .CurrentSection.Pages.ByDate.Reverse }}
<div class="postnav"> <div class="postnav">
{{ with $pages.Prev . }} {{ with $pages.Prev . }}
<a href="{{ .RelPermalink }}"> {{ if eq .Kind "page" }}
<div class="previous"> <a href="{{ .RelPermalink }}">
<p class="caption">Previous Post</p> <div class="previous">
<p class="title">{{ .Title }}</p> <p class="caption">Previous Post</p>
</div> <p class="title">{{ .Title }}</p>
</a> </div>
</a>
{{ end }}
{{ end }} {{ end }}
{{ with $pages.Next . }} {{ with $pages.Next . }}
<a href="{{ .RelPermalink }}"> {{ if eq .Kind "page" }}
<div class="next"> <a href="{{ .RelPermalink }}">
<p class="caption">Next Post</p> <div class="next">
<p class="title">{{ .Title }}</p> <p class="caption">Next Post</p>
</div> <p class="title">{{ .Title }}</p>
</a> </div>
</a>
{{ end }}
{{ end }} {{ end }}
</div> </div>

View File

@@ -2,34 +2,36 @@
<div class="grid-sizer"></div> <div class="grid-sizer"></div>
{{ range sort .Pages "Date" "desc" }} {{ range sort .Pages "Date" "desc" }}
{{ if not .Params.private }} {{ if not .Params.private }}
{{ $page := . }} {{ $hero := partial "components/hero/process.html" .Params.hero }}
{{ $imageData := partial "components/image/reflect.html" .Params.hero }} {{ if $hero.src }}
{{ with $imageData.image }} {{ $data := partial "components/image/process.html" (dict "page" . "src" $hero.src) }}
{{- $caption := .Title -}}
{{- $title := $hero.title | default $caption | plainify -}}
{{- $alt := $hero.alt | default $title | plainify -}}
<div class="image grid-item"> <div class="image grid-item">
<a <a
href="{{- $page.RelPermalink -}}" href="{{- .RelPermalink -}}"
data-pswp-src="{{- .RelPermalink -}}" data-pswp-src="{{- $data.full.RelPermalink -}}"
data-pswp-width="{{- .Width -}}" data-pswp-width="{{- $data.full.Width -}}"
data-pswp-height="{{- .Height -}}" data-pswp-height="{{- $data.full.Height -}}"
class="pswp-image" class="pswp-image"
> >
<img <img
src="{{- .RelPermalink -}}" src="{{- $data.thumb.RelPermalink -}}"
width="{{- .Width -}}" width="{{- $data.thumb.Width -}}"
height="{{- .Height -}}" height="{{- $data.thumb.Height -}}"
loading="lazy" loading="lazy"
{{ with $imageData.title }}title="{{- . -}}"{{ end }} {{ with $title }}title="{{- . -}}"{{ end }}
{{ with $imageData.alt }}alt="{{- . -}}"{{ end }} {{ with $alt }}alt="{{- . -}}"{{ end }}
/> />
</a> </a>
<div class="pswp-caption-content"> <div class="pswp-caption-content">
<div> <div>
{{ upper $page.Title }} <a href="{{- .RelPermalink -}}">{{ $caption }}</a>
<div class="meta"> {{ partial "components/meta/index.html" . }}
{{ $page.Date | time.Format ":date_medium" }}
&middot;
<a href="{{- $page.RelPermalink -}}">View Post</a>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,15 +1,13 @@
<div class="list"> <div class="list">
{{ range sort .Pages "Date" "desc" }} {{ range sort .Pages "Date" "desc" }}
{{ if not .Params.private }} {{ if not .Params.private }}
<a href="{{- .RelPermalink -}}" class="post"> <div class="post">
<h1 class="title">{{ .Title }}</h1> <a href="{{- .RelPermalink -}}">
<div class="summary">{{ .Summary | plainify }}</div> <h1 class="title">{{ .Title }}</h1>
<div class="meta"> <div class="summary">{{ .Summary | plainify }}</div>
<span class="date">{{ .Date | time.Format ":date_medium" }}</span> </a>
&middot; {{ partial "components/meta/index.html" . }}
<span class="duration">{{ printf "%d MIN READ" .ReadingTime }}</span> </div>
</div>
</a>
{{ end }} {{ end }}
{{ end }} {{ end }}
</div> </div>