Migrate from Bazel
This commit is contained in:
commit
016dbd0814
59 changed files with 7044 additions and 0 deletions
981
themes/retro-future/sass/style.scss
Normal file
981
themes/retro-future/sass/style.scss
Normal file
|
|
@ -0,0 +1,981 @@
|
|||
// ============================================================================
|
||||
// Retro-Future Theme
|
||||
// A modern, accessible theme with clean typography and thoughtful colors
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Custom Properties (CSS Variables)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
:root {
|
||||
// Color Palette - Light Mode
|
||||
--color-background: oklch(98.2% 0.014 85);
|
||||
--color-text: oklch(31.55% 0.009 17.62);
|
||||
--color-text-muted: oklch(50% 0.009 17.62);
|
||||
--color-primary: oklch(62.78% 0.12 226); // Blue
|
||||
--color-secondary: oklch(70.27% 0.192 13.7); // Orange
|
||||
--color-accent: oklch(86.59% 0.088 168.12); // Teal
|
||||
--color-highlight: rgb(210, 55, 81); // Red
|
||||
--color-border: oklch(85% 0.014 85);
|
||||
|
||||
// Code blocks
|
||||
--color-code-bg: #ffffff;
|
||||
--color-code-border: var(--color-primary);
|
||||
|
||||
// Syntax highlighting
|
||||
--color-syntax-string: oklch(50% 0.15 155);
|
||||
--color-syntax-number: oklch(55% 0.18 50);
|
||||
--color-syntax-function: oklch(48% 0.14 240);
|
||||
--color-syntax-keyword: oklch(52% 0.16 300);
|
||||
--color-syntax-comment: oklch(60% 0.02 85);
|
||||
|
||||
// Spacing Scale
|
||||
--space-xs: 0.25rem; // 4px
|
||||
--space-sm: 0.5rem; // 8px
|
||||
--space-md: 1rem; // 16px
|
||||
--space-lg: 1.5rem; // 24px
|
||||
--space-xl: 2rem; // 32px
|
||||
--space-2xl: 3rem; // 48px
|
||||
--space-3xl: 4rem; // 64px
|
||||
|
||||
// Typography Scale
|
||||
--font-size-sm: 0.875rem;
|
||||
--font-size-base: 1.25rem;
|
||||
--font-size-lg: 1.375rem;
|
||||
--font-size-xl: 1.5rem;
|
||||
--font-size-2xl: 1.75rem;
|
||||
--font-size-2-5xl: 1.875rem;
|
||||
--font-size-3xl: 2.25rem;
|
||||
--font-size-4xl: 3rem;
|
||||
--font-size-5xl: 4rem;
|
||||
|
||||
// Font Families
|
||||
--font-body: "Atkinson Hyperlegible Next", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
--font-display: "Bangers", "Comic Sans MS", cursive;
|
||||
--font-mono: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, monospace;
|
||||
|
||||
// Line Heights
|
||||
--line-height-tight: 1.25;
|
||||
--line-height-base: 1.6;
|
||||
|
||||
// Layout
|
||||
--layout-content-width: 52rem;
|
||||
--layout-padding: var(--space-md);
|
||||
|
||||
// Border Radius
|
||||
--radius-sm: 0.25rem;
|
||||
--radius-md: 0.5rem;
|
||||
|
||||
// Borders
|
||||
--border-accent-width: 4px;
|
||||
|
||||
// Transitions
|
||||
--transition-fast: 150ms ease;
|
||||
--transition-base: 250ms ease;
|
||||
|
||||
// Icons
|
||||
--icon-size: 18px;
|
||||
|
||||
// Header bio
|
||||
--bio-photo-size: 60px;
|
||||
--bio-photo-border: 3px;
|
||||
--bio-text-max-width: 300px;
|
||||
|
||||
// Scrollbar
|
||||
--scrollbar-size: 12px;
|
||||
--scrollbar-border: 2px;
|
||||
}
|
||||
|
||||
// Dark Mode
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--color-background: oklch(31.55% 0.009 17.62);
|
||||
--color-text: oklch(98.2% 0.014 85);
|
||||
--color-text-muted: oklch(70% 0.014 85);
|
||||
--color-primary: oklch(86.59% 0.088 168.12);
|
||||
--color-secondary: oklch(80.27% 0.192 13.7);
|
||||
--color-accent: oklch(62.78% 0.12 226);
|
||||
--color-highlight: rgb(240, 85, 111);
|
||||
--color-border: oklch(45% 0.009 17.62);
|
||||
--color-code-bg: #1a1a1a;
|
||||
--color-syntax-string: oklch(72% 0.15 155);
|
||||
--color-syntax-number: oklch(75% 0.14 50);
|
||||
--color-syntax-function: oklch(75% 0.12 240);
|
||||
--color-syntax-keyword: oklch(78% 0.12 300);
|
||||
--color-syntax-comment: oklch(55% 0.02 85);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Web Fonts
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible+Next:ital,wght@0,400;0,500;0,700;1,400;1,500;1,700&family=Bangers&display=swap');
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Reset & Base Styles
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
scrollbar-color: var(--color-primary) var(--color-background);
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--font-size-base);
|
||||
line-height: var(--line-height-base);
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-background);
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
// Text selection
|
||||
::selection {
|
||||
background-color: var(--color-primary);
|
||||
color: var(--color-background);
|
||||
}
|
||||
|
||||
// Scrollbar styling
|
||||
::-webkit-scrollbar {
|
||||
width: var(--scrollbar-size);
|
||||
height: var(--scrollbar-size);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--color-background);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--color-primary);
|
||||
border-radius: calc(var(--scrollbar-size) / 2);
|
||||
border: var(--scrollbar-border) solid var(--color-background);
|
||||
|
||||
&:hover {
|
||||
background: var(--color-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Typography
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: var(--font-body);
|
||||
font-weight: 700;
|
||||
line-height: var(--line-height-tight);
|
||||
margin-bottom: var(--space-md);
|
||||
color: var(--color-text);
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: clamp(var(--font-size-3xl), 5vw, var(--font-size-4xl));
|
||||
margin-top: var(--space-2xl);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: clamp(var(--font-size-2xl), 4vw, var(--font-size-3xl));
|
||||
margin-top: var(--space-xl);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(var(--font-size-xl), 3vw, var(--font-size-2xl));
|
||||
margin-top: var(--space-lg);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: var(--font-size-xl);
|
||||
margin-top: var(--space-lg);
|
||||
}
|
||||
|
||||
h5, h6 {
|
||||
font-size: var(--font-size-lg);
|
||||
margin-top: var(--space-md);
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: var(--space-md);
|
||||
text-wrap: pretty;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-primary);
|
||||
text-decoration: underline;
|
||||
text-decoration-thickness: 1px;
|
||||
text-underline-offset: 3px;
|
||||
transition: color var(--transition-fast);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px dashed var(--color-primary);
|
||||
outline-offset: 2px;
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
}
|
||||
|
||||
strong, b {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
em, i {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Code Blocks
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.9em;
|
||||
background-color: var(--color-code-bg);
|
||||
color: var(--color-highlight);
|
||||
padding: 0.125em 0.375em;
|
||||
border-radius: var(--radius-sm);
|
||||
border: 1px solid var(--color-code-border);
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--font-size-sm);
|
||||
line-height: var(--line-height-base);
|
||||
background-color: var(--color-code-bg);
|
||||
padding: var(--space-md);
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid var(--color-code-border);
|
||||
overflow: hidden;
|
||||
margin-bottom: var(--space-md);
|
||||
color: var(--color-text);
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
|
||||
code {
|
||||
background: none;
|
||||
padding: 0 0 0 1em;
|
||||
border: none;
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
grid-column: 2;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.line-numbers {
|
||||
grid-column: 1;
|
||||
text-align: right;
|
||||
padding-right: 1em;
|
||||
border-right: 1px solid var(--color-code-border);
|
||||
color: var(--color-text-muted);
|
||||
user-select: none;
|
||||
white-space: pre;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.code-block {
|
||||
margin-bottom: var(--space-md);
|
||||
|
||||
&__filename {
|
||||
background-color: var(--color-code-border);
|
||||
color: var(--color-code-bg);
|
||||
padding: var(--space-xs) var(--space-md);
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--font-size-base);
|
||||
font-weight: 600;
|
||||
border-radius: var(--radius-md) var(--radius-md) 0 0;
|
||||
border: 1px solid var(--color-code-border);
|
||||
border-bottom: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-bottom: 0;
|
||||
border-radius: 0 0 var(--radius-md) var(--radius-md);
|
||||
}
|
||||
|
||||
&__filename + pre {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Blockquotes & Asides
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
blockquote {
|
||||
border-left: var(--border-accent-width) solid var(--color-primary);
|
||||
padding-left: var(--space-md);
|
||||
margin: var(--space-lg) 0;
|
||||
font-style: italic;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.note {
|
||||
background-color: var(--color-code-bg);
|
||||
border-left: var(--border-accent-width) solid var(--color-secondary);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-lg);
|
||||
margin: var(--space-xl) 0;
|
||||
|
||||
&__title {
|
||||
font-weight: 700;
|
||||
font-size: var(--font-size-lg);
|
||||
color: var(--color-secondary);
|
||||
margin-bottom: var(--space-sm);
|
||||
}
|
||||
|
||||
&__content {
|
||||
color: var(--color-text);
|
||||
|
||||
p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&--note {
|
||||
border-left-color: var(--color-primary);
|
||||
.note__title { color: var(--color-primary); }
|
||||
}
|
||||
|
||||
&--info {
|
||||
border-left-color: var(--color-accent);
|
||||
.note__title { color: var(--color-accent); }
|
||||
}
|
||||
|
||||
&--warning {
|
||||
border-left-color: var(--color-highlight);
|
||||
.note__title { color: var(--color-highlight); }
|
||||
}
|
||||
|
||||
&--tip {
|
||||
border-left-color: var(--color-secondary);
|
||||
.note__title { color: var(--color-secondary); }
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Lists
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
ul, ol {
|
||||
margin-bottom: var(--space-md);
|
||||
padding-left: var(--space-xl);
|
||||
list-style-position: outside;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: var(--space-xs);
|
||||
}
|
||||
|
||||
article .post-content,
|
||||
.page-content,
|
||||
.section-content {
|
||||
ul {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
margin-left: 0;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "✦";
|
||||
color: var(--color-secondary);
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
left: -1.25em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style-position: outside;
|
||||
padding-left: 0;
|
||||
margin-left: 1.5em;
|
||||
|
||||
li::marker {
|
||||
color: var(--color-secondary);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration-style: wavy;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Layout
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.container {
|
||||
max-width: var(--layout-content-width);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-left: var(--layout-padding);
|
||||
padding-right: var(--layout-padding);
|
||||
}
|
||||
|
||||
main {
|
||||
min-height: 60vh;
|
||||
padding-bottom: var(--space-3xl);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Header
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.site-header {
|
||||
padding: var(--space-xl) 0;
|
||||
margin-bottom: var(--space-2xl);
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--space-xl);
|
||||
}
|
||||
|
||||
nav {
|
||||
margin-top: var(--space-md);
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
gap: var(--space-lg);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-primary);
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
transition: color var(--transition-base);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-secondary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&[aria-current="page"] {
|
||||
color: var(--color-highlight);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header-bio {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-md);
|
||||
|
||||
&__photo img {
|
||||
width: var(--bio-photo-size);
|
||||
height: var(--bio-photo-size);
|
||||
border-radius: 50%;
|
||||
border: var(--bio-photo-border) solid var(--color-accent);
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&__info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
|
||||
&__main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-weight: 600;
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
&__text {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-muted);
|
||||
line-height: var(--line-height-base);
|
||||
max-width: var(--bio-text-max-width);
|
||||
}
|
||||
|
||||
&__socials {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: var(--space-sm);
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
transition: all var(--transition-fast);
|
||||
color: var(--color-background);
|
||||
background-color: var(--color-primary);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-xs);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transform: rotateY(5deg) rotateX(10deg) rotateZ(5deg);
|
||||
box-shadow: 2px 4px 0px color-mix(in srgb, var(--color-border) 50%, transparent);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-highlight);
|
||||
transform: rotateY(0deg) rotateX(0deg) rotateZ(0deg) scale(1.1);
|
||||
}
|
||||
|
||||
svg {
|
||||
display: block;
|
||||
width: var(--icon-size);
|
||||
height: var(--icon-size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Page Title
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.page-title {
|
||||
font-family: var(--font-display);
|
||||
font-size: clamp(var(--font-size-4xl), 8vw, var(--font-size-5xl));
|
||||
font-weight: 400;
|
||||
color: var(--color-primary);
|
||||
margin: 0 0 var(--space-2xl) 0;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Articles
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
article header {
|
||||
margin-bottom: var(--space-2xl);
|
||||
|
||||
.post-title {
|
||||
margin-bottom: var(--space-sm);
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.post-meta,
|
||||
.post-meta__tags {
|
||||
color: var(--color-highlight);
|
||||
font-size: var(--font-size-base);
|
||||
line-height: var(--line-height-base);
|
||||
font-weight: 500;
|
||||
font-style: italic;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.post-meta {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: var(--space-sm);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.post-meta__tags {
|
||||
@extend %tag-list;
|
||||
}
|
||||
|
||||
.post-description {
|
||||
font-size: var(--font-size-lg);
|
||||
color: var(--color-text-muted);
|
||||
margin-top: var(--space-md);
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
.series-info {
|
||||
background-color: var(--color-code-bg);
|
||||
border-left: var(--border-accent-width) solid var(--color-accent);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-lg);
|
||||
margin-bottom: var(--space-2xl);
|
||||
|
||||
&__header {
|
||||
margin-bottom: var(--space-md);
|
||||
font-size: var(--font-size-base);
|
||||
|
||||
strong {
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
&__nav ol {
|
||||
list-style-position: inside;
|
||||
padding-left: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
margin-bottom: var(--space-xs);
|
||||
|
||||
&.current {
|
||||
font-weight: 600;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-text);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
&.current a {
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Post List
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Shared bullet styling
|
||||
%bullet-point {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: "✦";
|
||||
color: var(--color-secondary);
|
||||
position: absolute;
|
||||
left: -1.5em;
|
||||
font-size: 0.7em;
|
||||
top: 0.35em;
|
||||
}
|
||||
}
|
||||
|
||||
// Shared list link styling
|
||||
%list-link {
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
transition: color var(--transition-base);
|
||||
|
||||
&:hover {
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
// Shared tag list styling
|
||||
%tag-list {
|
||||
display: inline-flex;
|
||||
gap: 0;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-style: normal;
|
||||
|
||||
li {
|
||||
display: inline;
|
||||
|
||||
&:not(:last-child)::after {
|
||||
content: ",\00a0";
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.post-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
&__item {
|
||||
margin-bottom: var(--space-2xl);
|
||||
padding-bottom: var(--space-xl);
|
||||
}
|
||||
|
||||
&__title {
|
||||
@extend %bullet-point;
|
||||
margin: 0 0 var(--space-sm) 0;
|
||||
font-size: var(--font-size-2-5xl);
|
||||
line-height: var(--line-height-tight);
|
||||
font-weight: 600;
|
||||
|
||||
a {
|
||||
@extend %list-link;
|
||||
}
|
||||
}
|
||||
|
||||
&__series {
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-muted);
|
||||
margin: var(--space-xs) 0 var(--space-sm) 0;
|
||||
font-style: italic;
|
||||
|
||||
a {
|
||||
color: var(--color-primary);
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-secondary);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__meta {
|
||||
color: var(--color-highlight);
|
||||
font-size: var(--font-size-base);
|
||||
line-height: var(--line-height-base);
|
||||
font-weight: 500;
|
||||
font-style: italic;
|
||||
margin-bottom: var(--space-sm);
|
||||
letter-spacing: -0.02em;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: var(--space-sm);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&__description {
|
||||
color: var(--color-text-muted);
|
||||
margin-bottom: var(--space-md);
|
||||
}
|
||||
|
||||
&__tags {
|
||||
@extend %tag-list;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Taxonomy List
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.taxonomy-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
&__item {
|
||||
@extend %bullet-point;
|
||||
margin-bottom: var(--space-md);
|
||||
font-size: var(--font-size-xl);
|
||||
line-height: var(--line-height-tight);
|
||||
font-weight: 600;
|
||||
|
||||
a {
|
||||
@extend %list-link;
|
||||
}
|
||||
}
|
||||
|
||||
&__count {
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(--font-size-base);
|
||||
font-weight: 400;
|
||||
margin-left: var(--space-xs);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Images
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: var(--space-xl) auto;
|
||||
text-align: center;
|
||||
|
||||
img, video {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
margin-top: var(--space-sm);
|
||||
font-size: var(--font-size-sm);
|
||||
color: var(--color-text-muted);
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Mermaid Diagrams
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.mermaid {
|
||||
margin: var(--space-xl) 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Syntax Highlighting
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
pre code {
|
||||
.z-comment { color: var(--color-syntax-comment); font-style: italic; }
|
||||
.z-keyword,
|
||||
.z-keyword-constant,
|
||||
.z-keyword-declaration,
|
||||
.z-keyword-namespace,
|
||||
.z-keyword-pseudo,
|
||||
.z-keyword-reserved,
|
||||
.z-storage { color: var(--color-syntax-keyword); font-weight: 600; }
|
||||
.z-keyword-type,
|
||||
.z-storage-type { color: var(--color-syntax-function); font-weight: 600; }
|
||||
.z-constant,
|
||||
.z-constant-builtin,
|
||||
.z-constant-language,
|
||||
.z-constant-numeric,
|
||||
.z-constant-other { color: var(--color-syntax-number); }
|
||||
.z-constant-language { font-weight: 600; }
|
||||
.z-constant-character { color: var(--color-syntax-string); }
|
||||
.z-constant-regexp,
|
||||
.z-string-regexp { color: var(--color-highlight); }
|
||||
.z-entity,
|
||||
.z-entity-name,
|
||||
.z-entity-name-function,
|
||||
.z-entity-other,
|
||||
.z-entity-other-inherited-class,
|
||||
.z-support,
|
||||
.z-support-function,
|
||||
.z-support-type { color: var(--color-syntax-function); }
|
||||
.z-entity-name,
|
||||
.z-variable-language { font-weight: 600; }
|
||||
.z-entity-name-class,
|
||||
.z-entity-name-type,
|
||||
.z-entity-other-attribute-name,
|
||||
.z-support-class { color: var(--color-secondary); }
|
||||
.z-entity-name-tag { color: var(--color-syntax-keyword); }
|
||||
.z-invalid { color: var(--color-background); background-color: var(--color-highlight); }
|
||||
.z-invalid-deprecated { color: var(--color-background); background-color: var(--color-text-muted); }
|
||||
.z-markup { color: var(--color-text); }
|
||||
.z-markup-bold { color: var(--color-syntax-number); font-weight: 700; }
|
||||
.z-markup-deleted { color: var(--color-highlight); }
|
||||
.z-markup-heading { color: var(--color-highlight); font-weight: 600; }
|
||||
.z-markup-inserted { color: var(--color-syntax-string); }
|
||||
.z-markup-italic { color: var(--color-syntax-keyword); font-style: italic; }
|
||||
.z-markup-list { color: var(--color-highlight); }
|
||||
.z-markup-quote { color: var(--color-syntax-number); }
|
||||
.z-markup-raw { color: var(--color-syntax-string); }
|
||||
.z-meta { color: var(--color-text); }
|
||||
.z-string { color: var(--color-syntax-string); }
|
||||
.z-string-escape { color: var(--color-syntax-keyword); }
|
||||
.z-support-constant { color: var(--color-syntax-number); }
|
||||
.z-variable,
|
||||
.z-variable-parameter { color: var(--color-text); }
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Utilities
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.visually-hidden {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Pagination
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: var(--space-md);
|
||||
margin-top: var(--space-xl);
|
||||
|
||||
&__button {
|
||||
padding: var(--space-sm) var(--space-lg);
|
||||
background-color: var(--color-primary);
|
||||
color: var(--color-background);
|
||||
text-decoration: none;
|
||||
border-radius: var(--radius-md);
|
||||
font-weight: 600;
|
||||
transition: background-color var(--transition-fast);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-secondary);
|
||||
color: var(--color-background);
|
||||
}
|
||||
}
|
||||
|
||||
&__info {
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Responsive Design
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@media (max-width: 40rem) {
|
||||
:root {
|
||||
--layout-padding: var(--space-sm);
|
||||
}
|
||||
|
||||
.site-header nav ul {
|
||||
flex-direction: column;
|
||||
gap: var(--space-sm);
|
||||
}
|
||||
|
||||
article .post-content {
|
||||
ul {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 1.5em;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
62
themes/retro-future/templates/article.html
Normal file
62
themes/retro-future/templates/article.html
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
{% extends "base.html" %}
|
||||
{% import "macros.html" as macros %}
|
||||
|
||||
{% block title %}{{ page.title }} · {{ config.title }}{% endblock title %}
|
||||
|
||||
{% block description %}{{ page.description | default(value=page.summary) | default(value=config.description) }}{% endblock description %}
|
||||
|
||||
{% block content %}
|
||||
<article>
|
||||
<header>
|
||||
<h1 class="page-title">{{ page.title }}</h1>
|
||||
{{ macros::post_meta(page=page) }}
|
||||
{% if page.description %}
|
||||
<p class="post-description">{{ page.description }}</p>
|
||||
{% endif %}
|
||||
</header>
|
||||
|
||||
{% set path_parts = page.relative_path | split(pat="/") %}
|
||||
{% if path_parts | length > 2 %}
|
||||
{% set parent_dir = path_parts | slice(end=-2) | join(sep="/") %}
|
||||
{% set parent_section = get_section(path=parent_dir ~ "/_index.md") %}
|
||||
{% if parent_section and parent_section.extra.series %}
|
||||
<aside class="series-info">
|
||||
<div class="series-info__header">
|
||||
<strong>Part of the series:</strong> <a href="{{ parent_section.permalink }}">{{ parent_section.title }}</a>
|
||||
</div>
|
||||
<nav class="series-info__nav" aria-label="Series navigation">
|
||||
<ol>
|
||||
{% for p in parent_section.pages %}
|
||||
<li {% if p.permalink == page.permalink %}class="current"{% endif %}>
|
||||
<a href="{{ p.permalink }}" {% if p.permalink == page.permalink %}aria-current="page"{% endif %}>{{ p.title }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</nav>
|
||||
</aside>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<div class="post-content">
|
||||
{{ page.content | safe }}
|
||||
</div>
|
||||
</article>
|
||||
|
||||
{% if page.earlier or page.later %}
|
||||
<nav class="post-navigation" aria-label="Post navigation">
|
||||
{% if page.later %}
|
||||
<div class="post-navigation__prev">
|
||||
<span class="post-navigation__label">← Previous</span>
|
||||
<a href="{{ page.later.permalink }}">{{ page.later.title }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page.earlier %}
|
||||
<div class="post-navigation__next">
|
||||
<span class="post-navigation__label">Next →</span>
|
||||
<a href="{{ page.earlier.permalink }}">{{ page.earlier.title }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
134
themes/retro-future/templates/base.html
Normal file
134
themes/retro-future/templates/base.html
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ lang | default(value='en') }}">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}{{ config.title }}{% endblock title %}</title>
|
||||
<meta name="description" content="{% block description %}{{ config.description }}{% endblock description %}">
|
||||
<meta name="author" content="{{ config.author | default(value='') }}">
|
||||
|
||||
<link rel="icon" type="image/svg+xml" href="{{ get_url(path='favicon.svg', trailing_slash=false) }}">
|
||||
|
||||
{% if config.generate_feeds %}
|
||||
<link rel="alternate" type="application/atom+xml" title="{{ config.title }}" href="{{ get_url(path='atom.xml', trailing_slash=false) }}">
|
||||
{% endif %}
|
||||
|
||||
<link rel="stylesheet" href="{{ get_url(path='style.css', trailing_slash=false) }}">
|
||||
|
||||
{% block extra_head %}{% endblock extra_head %}
|
||||
|
||||
{% if config.extra.mermaid %}
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
mermaid.initialize({
|
||||
startOnLoad: true,
|
||||
theme: 'base',
|
||||
themeVariables: isDark ? {
|
||||
primaryColor: '#88c0d0', primaryTextColor: '#d8dee9', primaryBorderColor: '#5e81ac',
|
||||
lineColor: '#d08770', secondaryColor: '#81a1c1', tertiaryColor: '#b48ead',
|
||||
background: '#2e3440', mainBkg: '#3b4252', secondBkg: '#434c5e', tertiaryBkg: '#4c566a',
|
||||
textColor: '#d8dee9', border1: '#4c566a', border2: '#434c5e',
|
||||
note: '#ebcb8b', noteBorder: '#d08770', noteBkg: '#5e81ac'
|
||||
} : {
|
||||
primaryColor: '#62a0d8', primaryTextColor: '#2e3440', primaryBorderColor: '#4271ae',
|
||||
lineColor: '#d2a256', secondaryColor: '#d2a256', tertiaryColor: '#b48ead',
|
||||
background: '#ffffff', mainBkg: '#f5f5f5', secondBkg: '#e8e8e8', tertiaryBkg: '#d8d8d8',
|
||||
textColor: '#2e3440', border1: '#cccccc', border2: '#d8d8d8',
|
||||
note: '#d2a256', noteBorder: '#d2a256', noteBkg: '#f5f5f5'
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{% if config.extra.analytics.service == "plausible" %}
|
||||
<script defer data-domain="{{ config.extra.analytics.id }}" src="{{ config.extra.analytics.self_hosted_url }}/js/script.js"></script>
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.querySelectorAll('pre code').forEach(function(code) {
|
||||
const lines = code.textContent.split('\n');
|
||||
const lineCount = lines[lines.length - 1] === '' ? lines.length - 1 : lines.length;
|
||||
const lineNumbers = document.createElement('div');
|
||||
lineNumbers.className = 'line-numbers';
|
||||
lineNumbers.setAttribute('aria-hidden', 'true');
|
||||
for (let i = 1; i <= lineCount; i++) {
|
||||
lineNumbers.textContent += i + '\n';
|
||||
}
|
||||
code.parentElement.insertBefore(lineNumbers, code);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<header class="site-header">
|
||||
<div class="container">
|
||||
{% block header_nav %}
|
||||
<nav aria-label="Main navigation">
|
||||
<ul>
|
||||
<li><a href="{{ get_url(path='posts', trailing_slash=true) }}" {% if current_path is starting_with('/posts') %}aria-current="page"{% endif %}>Blog</a></li>
|
||||
{% for link in config.extra.nav_links | default(value=[]) %}
|
||||
<li><a href="{{ link.url }}" {% if current_path is starting_with(link.url) and link.url != '/' %}aria-current="page"{% endif %}>{{ link.name }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="header-bio">
|
||||
<div class="header-bio__photo">
|
||||
<picture>
|
||||
<source srcset="{{ get_url(path='images/me.webp') }}" type="image/webp">
|
||||
<img src="{{ get_url(path='images/me.jpg') }}" alt="{{ config.author }}">
|
||||
</picture>
|
||||
</div>
|
||||
<div class="header-bio__info">
|
||||
<div class="header-bio__main">
|
||||
<div class="header-bio__name">{{ config.author }}</div>
|
||||
{% if config.extra.bio %}
|
||||
<div class="header-bio__text">{{ config.extra.bio }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="header-bio__socials">
|
||||
{% for social in config.extra.socials %}
|
||||
<a href="{{ social.url }}" rel="me" aria-label="{{ social.name | capitalize }}">
|
||||
{% if social.icon == "github" %}
|
||||
<svg viewBox="0 0 24 24" width="20" height="20"><path fill="currentColor" d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
{% elif social.icon == "mastodon" %}
|
||||
<svg viewBox="0 0 24 24" width="20" height="20"><path fill="currentColor" d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z"/></svg>
|
||||
{% elif social.icon == "twitter" %}
|
||||
<svg viewBox="0 0 24 24" width="20" height="20"><path fill="currentColor" d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
|
||||
{% elif social.icon == "forgejo" %}
|
||||
<svg viewBox="0 0 212 212" width="20" height="20">
|
||||
<g transform="translate(6,6)" stroke="currentColor" fill="none">
|
||||
<path d="M58 168 v-98 a50 50 0 0 1 50-50 h20" stroke-width="25"/>
|
||||
<path d="M58 168 v-30 a50 50 0 0 1 50-50 h20" stroke-width="25"/>
|
||||
<circle cx="142" cy="20" r="18" stroke-width="15"/>
|
||||
<circle cx="142" cy="88" r="18" stroke-width="15"/>
|
||||
<circle cx="58" cy="180" r="18" stroke-width="15"/>
|
||||
</g>
|
||||
</svg>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% endfor %}
|
||||
{% if config.generate_feeds %}
|
||||
<a href="{{ get_url(path='atom.xml', trailing_slash=false) }}" aria-label="RSS Feed">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5">
|
||||
<circle cx="5" cy="19" r="2" fill="currentColor" stroke="none"/>
|
||||
<path d="M4 11a9 9 0 0 1 9 9"/>
|
||||
<path d="M4 4a16 16 0 0 1 16 16"/>
|
||||
</svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock header_nav %}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="container">
|
||||
{% block content %}{% endblock content %}
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
37
themes/retro-future/templates/index.html
Normal file
37
themes/retro-future/templates/index.html
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
{% extends "base.html" %}
|
||||
{% import "macros.html" as macros %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="page-title">Blog</h1>
|
||||
|
||||
{% if section.description %}
|
||||
<p class="section-description">{{ section.description }}</p>
|
||||
{% endif %}
|
||||
|
||||
<ul class="post-list">
|
||||
{% if paginator %}
|
||||
{% for page in paginator.pages %}
|
||||
{{ macros::post_list_item(page=page) }}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% set posts_section = get_section(path="posts/_index.md") %}
|
||||
{% for page in posts_section.pages %}
|
||||
{{ macros::post_list_item(page=page) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
{% if paginator %}
|
||||
<nav class="pagination" aria-label="Pagination">
|
||||
{% if paginator.previous %}
|
||||
<a href="{{ paginator.previous }}" rel="prev" class="pagination__button">Newer posts</a>
|
||||
{% endif %}
|
||||
|
||||
<span class="pagination__info">Page {{ paginator.current_index }} of {{ paginator.number_pagers }}</span>
|
||||
|
||||
{% if paginator.next %}
|
||||
<a href="{{ paginator.next }}" rel="next" class="pagination__button">Older posts</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
59
themes/retro-future/templates/macros.html
Normal file
59
themes/retro-future/templates/macros.html
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
{% macro post_list_item(page, show_tags=true, show_series=true) %}
|
||||
<li class="post-list__item">
|
||||
<h2 class="post-list__title">
|
||||
<a href="{{ page.permalink }}">{{ page.title }}</a>
|
||||
</h2>
|
||||
{% if show_series %}
|
||||
{% set path_parts = page.relative_path | split(pat="/") %}
|
||||
{% if path_parts | length > 2 %}
|
||||
{% set parent_dir = path_parts | slice(end=-2) | join(sep="/") %}
|
||||
{% set parent_section = get_section(path=parent_dir ~ "/_index.md") %}
|
||||
{% if parent_section and parent_section.extra.series %}
|
||||
<p class="post-list__series">Part of the series: <a href="{{ parent_section.permalink }}">{{ parent_section.title }}</a></p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<div class="post-list__meta">
|
||||
<time datetime="{{ page.date }}">{{ page.date | date(format="%B %d, %Y") }}</time>
|
||||
|
||||
{% if page.reading_time %}
|
||||
<span aria-hidden="true">·</span>
|
||||
<span>{{ page.reading_time }} min read</span>
|
||||
{% endif %}
|
||||
|
||||
{% if show_tags and page.taxonomies.tags %}
|
||||
<span aria-hidden="true">·</span>
|
||||
<ul class="post-list__tags">
|
||||
{% for tag in page.taxonomies.tags %}
|
||||
<li><a href="{{ get_taxonomy_url(kind='tags', name=tag) }}">{{ tag }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if page.description %}
|
||||
<p class="post-list__description">{{ page.description }}</p>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro post_meta(page, show_tags=true) %}
|
||||
<div class="post-meta">
|
||||
<time datetime="{{ page.date }}">{{ page.date | date(format="%B %d, %Y") }}</time>
|
||||
|
||||
{% if page.reading_time %}
|
||||
<span aria-hidden="true">·</span>
|
||||
<span>{{ page.reading_time }} min read</span>
|
||||
{% endif %}
|
||||
|
||||
{% if show_tags and page.taxonomies.tags %}
|
||||
<span aria-hidden="true">·</span>
|
||||
<ul class="post-meta__tags">
|
||||
{% for tag in page.taxonomies.tags %}
|
||||
<li><a href="{{ get_taxonomy_url(kind='tags', name=tag) }}">{{ tag }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
13
themes/retro-future/templates/page.html
Normal file
13
themes/retro-future/templates/page.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ page.title }} · {{ config.title }}{% endblock title %}
|
||||
|
||||
{% block description %}{{ page.description | default(value=page.summary) | default(value=config.description) }}{% endblock description %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="page-title">{{ page.title }}</h1>
|
||||
|
||||
<div class="page-content">
|
||||
{{ page.content | safe }}
|
||||
</div>
|
||||
{% endblock content %}
|
||||
37
themes/retro-future/templates/section.html
Normal file
37
themes/retro-future/templates/section.html
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ section.title }} · {{ config.title }}{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="page-title">{{ section.title }}</h1>
|
||||
|
||||
{% if section.content %}
|
||||
<div class="section-content">
|
||||
{{ section.content | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if section.pages %}
|
||||
<ul class="post-list">
|
||||
{% for page in section.pages %}
|
||||
<li class="post-list__item">
|
||||
<h2 class="post-list__title">
|
||||
<a href="{{ page.permalink }}">{{ page.title }}</a>
|
||||
</h2>
|
||||
{% set path_parts = page.relative_path | split(pat="/") %}
|
||||
{% if path_parts | length > 2 %}
|
||||
{% set parent_dir = path_parts | slice(end=-2) | join(sep="/") %}
|
||||
{% set parent_section = get_section(path=parent_dir ~ "/_index.md") %}
|
||||
{% if parent_section and parent_section.extra.series %}
|
||||
<p class="post-list__series">Part of the series: <a href="{{ parent_section.permalink }}">{{ parent_section.title }}</a></p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if page.description %}
|
||||
<p class="post-list__description">{{ page.description }}</p>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
28
themes/retro-future/templates/series.html
Normal file
28
themes/retro-future/templates/series.html
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{% extends "base.html" %}
|
||||
{% import "macros.html" as macros %}
|
||||
|
||||
{% block title %}{{ section.title }} · {{ config.title }}{% endblock title %}
|
||||
|
||||
{% block description %}{{ section.description | default(value=config.description) }}{% endblock description %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="page-title">{{ section.title }}</h1>
|
||||
|
||||
{% if section.description %}
|
||||
<p class="section-description">{{ section.description }}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if section.content %}
|
||||
<div class="section-content">
|
||||
{{ section.content | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<nav aria-label="Series navigation">
|
||||
<ol class="post-list">
|
||||
{% for page in section.pages %}
|
||||
{{ macros::post_list_item(page=page, show_series=false) }}
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</nav>
|
||||
{% endblock content %}
|
||||
6
themes/retro-future/templates/shortcodes/aside.html
Normal file
6
themes/retro-future/templates/shortcodes/aside.html
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<aside class="note note--{{ type | default(value='note') }}">
|
||||
<div class="note__title">{{ title | default(value=type | default(value="note") | capitalize) }}</div>
|
||||
<div class="note__content">
|
||||
{{ body | markdown | safe }}
|
||||
</div>
|
||||
</aside>
|
||||
1
themes/retro-future/templates/shortcodes/filename.html
Normal file
1
themes/retro-future/templates/shortcodes/filename.html
Normal file
|
|
@ -0,0 +1 @@
|
|||
<div class="code-block__filename">{{ body }}</div>
|
||||
4
themes/retro-future/templates/shortcodes/mermaid.html
Normal file
4
themes/retro-future/templates/shortcodes/mermaid.html
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<figure>
|
||||
<div class="mermaid">{{ body }}</div>
|
||||
{% if caption %}<figcaption>{{ caption }}</figcaption>{% endif %}
|
||||
</figure>
|
||||
16
themes/retro-future/templates/taxonomy_list.html
Normal file
16
themes/retro-future/templates/taxonomy_list.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ taxonomy.name | title }} · {{ config.title }}{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="page-title">{{ taxonomy.name | title }}</h1>
|
||||
|
||||
<ul class="taxonomy-list">
|
||||
{% for term in terms %}
|
||||
<li class="taxonomy-list__item">
|
||||
<a href="{{ term.permalink }}">{{ term.name }}</a>
|
||||
<span class="taxonomy-list__count">({{ term.pages | length }})</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock content %}
|
||||
14
themes/retro-future/templates/taxonomy_single.html
Normal file
14
themes/retro-future/templates/taxonomy_single.html
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{% extends "base.html" %}
|
||||
{% import "macros.html" as macros %}
|
||||
|
||||
{% block title %}{{ term.name }} · {{ taxonomy.name | title }} · {{ config.title }}{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="page-title">{{ taxonomy.name | title }}: {{ term.name }}</h1>
|
||||
|
||||
<ul class="post-list">
|
||||
{% for page in term.pages %}
|
||||
{{ macros::post_list_item(page=page, show_tags=false) }}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock content %}
|
||||
5
themes/retro-future/theme.toml
Normal file
5
themes/retro-future/theme.toml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
name = "retro-future"
|
||||
description = "A modern, accessible theme with clean typography and thoughtful color palette"
|
||||
license = "MIT"
|
||||
homepage = "https://enoent.fr"
|
||||
min_version = "0.21.0"
|
||||
Loading…
Add table
Add a link
Reference in a new issue