Files
kennethreitz 9570f95595 Full-content RSS, article time meta, rel=me, font preloads
- feed.xml items carry the complete rendered essay in content:encoded,
  with absolute URLs and sidenotes flattened to inline parentheticals
- article:published_time from dated filenames, modified_time from mtime
- rel=me identity links for GitHub and Twitter
- Preload both et-book woffs to close the Palatino flash

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 01:28:57 -04:00

799 lines
22 KiB
HTML

{% extends "base.html" %}
{% block og_title %}{{ title }}{% endblock %}
{% block og_description %}{% if description %}{{ description[:160] }}{% else %}{{ content | striptags | truncate(160) }}{% endif %}{% endblock %}
{% block og_type %}article{% endblock %}
{% block og_url %}https://kennethreitz.org{{ request.path }}{% endblock %}
{% block og_image %}https://kennethreitz.org/og-image{{ request.path }}.png{% endblock %}
{% block twitter_title %}{{ title }}{% endblock %}
{% block twitter_description %}{% if description %}{{ description[:160] }}{% else %}{{ content | striptags | truncate(160) }}{% endif %}{% endblock %}
{% block twitter_image %}https://kennethreitz.org/og-image{{ request.path }}.png{% endblock %}
{% block og_image_alt %}{{ title }} - An article by Kenneth Reitz{% endblock %}
{% block extra_meta %}{% if published_iso %}<meta property="article:published_time" content="{{ published_iso }}" />
{% endif %}{% if modified_iso %}<meta property="article:modified_time" content="{{ modified_iso }}" />{% endif %}{% endblock %}
{% block description %}{% if description %}{{ description }}{% else %}{{ content | striptags | truncate(200) }}{% endif %}{% endblock %}
{% block schema_type %}Article{% endblock %}
{% block schema_name %}{{ title }}{% endblock %}
{% block schema_url %}{{ current_path }}{% endblock %}
{% block schema_description %}{% if metadata.description %}{{ metadata.description }}{% else %}{{ title }} - An essay by Kenneth Reitz{% endif %}{% endblock %}
{% block schema_extra %},
"headline": "{{ title }}",
"articleSection": "{% if 'artificial-intelligence' in current_path %}AI & Consciousness{% elif 'essays' in current_path %}Essays{% elif 'poetry' in current_path %}Poetry{% elif 'software' in current_path %}Software{% elif 'music' in current_path %}Music{% else %}Writing{% endif %}",
"wordCount": {{ (content | length / 5) | int }},
{% if metadata and metadata.date %}
"datePublished": "{{ metadata.date[0] if metadata.date is iterable and metadata.date is not string else metadata.date }}",
"dateModified": "{{ metadata.date[0] if metadata.date is iterable and metadata.date is not string else metadata.date }}",
{% endif %}
"keywords": {% if 'artificial-intelligence' in current_path %}["artificial intelligence", "consciousness", "AI philosophy", "human-AI collaboration", "machine learning"]{% elif 'mental-health' in current_path %}["mental health", "bipolar disorder", "neurodivergent", "tech industry wellness", "psychology"]{% elif 'poetry' in current_path %}["poetry", "creative writing", "verse", "contemplation", "language"]{% elif 'software' in current_path %}["software development", "Python", "open source", "programming", "API design"]{% elif 'music' in current_path %}["music", "audio", "creative arts", "sound design"]{% elif 'essays' in current_path %}["technology", "software development", "Python", "philosophy", "programming"]{% else %}["writing", "thoughts", "contemplation", "technology"]{% endif %},
"inLanguage": "en-US",
"isAccessibleForFree": true,
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://kennethreitz.org{{ current_path }}"
},
"image": {
"@type": "ImageObject",
"url": "https://kennethreitz.org/og-image{{ current_path }}.png",
"width": 1200,
"height": 630
}{% endblock %}
{% block extra_head %}
<style>
/* Tufte-style typography - minimal and elegant */
.post-header {
margin-bottom: 3rem;
width: 100%;
}
.post-title-container {
display: flex;
align-items: flex-start;
gap: 1rem;
margin-bottom: 0.5rem;
width: 70%;
}
.post-title-icon {
width: 48px;
height: 48px;
flex-shrink: 0;
margin-left: -4rem;
}
.post-title-text {
flex: 1;
display: flex;
flex-direction: column;
}
article h1 {
font-size: 3.2rem;
font-style: italic;
font-weight: 400;
line-height: 1;
margin: 0;
color: #111;
text-rendering: optimizeLegibility;
}
.post-subtitle {
font-variant: small-caps;
font-size: 1.1rem;
color: #666;
letter-spacing: 0.1em;
margin-bottom: 3rem;
display: flex;
align-items: center;
gap: 1.5rem;
}
.reading-time-badge {
font-variant: normal;
font-size: 0.85rem;
background: #e8f4f8;
padding: 0.25rem 0.6rem;
border-radius: 3px;
letter-spacing: normal;
font-weight: 400;
font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
}
.themes-dropdown {
position: relative;
display: inline-block;
}
.themes-badge {
font-variant: normal;
font-size: 0.85rem;
background: #dcfce7;
color: #16a34a;
padding: 0.25rem 0.6rem;
border-radius: 3px;
letter-spacing: normal;
font-weight: 400;
font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
border: none;
cursor: pointer;
transition: background 0.2s ease;
}
.themes-badge:hover {
background: #bbf7d0;
}
.formats-label {
font-variant: small-caps;
font-size: 0.85rem;
color: #666;
margin-left: 0.5rem;
letter-spacing: 0.05em;
font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
}
.pdf-badge,
.markdown-badge {
font-variant: normal;
font-size: 0.85rem;
padding: 0.25rem 0.6rem;
border-radius: 3px;
letter-spacing: normal;
font-weight: 400;
font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
text-decoration: none;
transition: background 0.2s ease;
display: inline-block;
margin-left: 0.5rem;
}
.pdf-badge {
background: #fef3c7;
color: #d97706;
}
.pdf-badge:hover {
background: #fde68a;
}
.markdown-badge {
background: #e0e7ff;
color: #4338ca;
}
.markdown-badge:hover {
background: #c7d2fe;
}
.themes-dropdown-content {
display: none;
position: absolute;
background-color: white !important;
min-width: 200px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
border: 1px solid #ddd;
border-radius: 4px;
z-index: 9999;
margin-top: 0.25rem;
top: 100%;
left: 0;
}
.themes-dropdown-content a {
color: #333;
padding: 0.5rem 1rem;
text-decoration: none;
display: block;
transition: background 0.2s ease;
font-variant: normal;
letter-spacing: normal;
font-size: 0.9rem;
}
.themes-dropdown-content a:hover {
background-color: #dcfce7;
}
.themes-dropdown-content.show {
display: block;
}
@media (max-width: 768px) {
.post-subtitle {
flex-wrap: wrap;
gap: 0.75rem;
}
.reading-time-badge,
.themes-badge,
.pdf-badge,
.markdown-badge {
font-size: 0.8rem;
padding: 0.2rem 0.5rem;
}
.pdf-badge,
.markdown-badge {
display: none;
}
.themes-dropdown-content {
min-width: 150px;
font-size: 0.85rem;
}
}
body.light-mode article h1 {
color: #111 !important;
}
body.light-mode .post-subtitle {
color: #666 !important;
}
body.light-mode .reading-time-badge {
background: #e8f4f8 !important;
color: inherit !important;
}
body.light-mode .themes-badge {
background: #dcfce7 !important;
color: #16a34a !important;
}
body.light-mode .themes-badge:hover {
background: #bbf7d0 !important;
}
body.light-mode .pdf-badge {
background: #fef3c7 !important;
color: #d97706 !important;
}
body.light-mode .pdf-badge:hover {
background: #fde68a !important;
}
body.light-mode .markdown-badge {
background: #e0e7ff !important;
color: #4338ca !important;
}
body.light-mode .markdown-badge:hover {
background: #c7d2fe !important;
}
body.light-mode .themes-dropdown-content {
background-color: white !important;
border-color: #ddd !important;
}
body.light-mode .themes-dropdown-content a {
color: #333 !important;
}
body.light-mode .themes-dropdown-content a:hover {
background-color: #dcfce7 !important;
}
body.light-mode .directory-listing {
border-bottom-color: #eee !important;
}
body.light-mode .directory-listing h2,
body.light-mode .directory-about h2 {
color: #666 !important;
}
body.light-mode .items-list a {
color: #333 !important;
}
body.light-mode .items-list a:hover {
color: #000 !important;
}
body.light-mode .parent-navigation {
border-top-color: #eee !important;
}
body.light-mode .parent-link {
color: #666 !important;
}
body.light-mode .parent-link:hover {
color: #333 !important;
}
body.dark-mode article h1 {
color: #e5e5e5;
}
body.dark-mode .post-subtitle {
color: #999;
}
body.dark-mode .reading-time-badge {
background: #1a2d33;
color: #67e8f9;
}
body.dark-mode .themes-badge {
background: #1a3d1a;
color: #4ade80;
}
body.dark-mode .themes-badge:hover {
background: #204d20;
}
body.dark-mode .pdf-badge {
background: #3d2e1a;
color: #fbbf24;
}
body.dark-mode .pdf-badge:hover {
background: #4d3920;
}
body.dark-mode .markdown-badge {
background: #1e293b;
color: #818cf8;
}
body.dark-mode .markdown-badge:hover {
background: #2d3748;
}
body.dark-mode .formats-label {
color: #999;
}
body.dark-mode .themes-dropdown-content {
background-color: #1a1a1a !important;
border-color: #333;
}
body.dark-mode .themes-dropdown-content a {
color: #ccc;
}
body.dark-mode .themes-dropdown-content a:hover {
background-color: #1a3d1a;
}
body.dark-mode .directory-listing {
border-bottom-color: #2a2a2a;
}
body.dark-mode .directory-listing h2,
body.dark-mode .directory-about h2 {
color: #999;
}
body.dark-mode .items-list a {
color: #ccc;
}
body.dark-mode .items-list a:hover {
color: #fff;
}
body.dark-mode .parent-navigation {
border-top-color: #2a2a2a;
}
body.dark-mode .parent-link {
color: #999;
}
body.dark-mode .parent-link:hover {
color: #ccc;
}
@media (prefers-color-scheme: dark) {
article h1 {
color: #e5e5e5;
}
.post-subtitle {
color: #999;
}
.reading-time-badge {
background: #1a2d33;
color: #67e8f9;
}
.themes-badge {
background: #1a3d1a;
color: #4ade80;
}
.themes-badge:hover {
background: #204d20;
}
.pdf-badge {
background: #3d2e1a;
color: #fbbf24;
}
.pdf-badge:hover {
background: #4d3920;
}
.markdown-badge {
background: #1e293b;
color: #818cf8;
}
.markdown-badge:hover {
background: #2d3748;
}
.themes-dropdown-content {
background-color: #1a1a1a !important;
border-color: #333;
}
.themes-dropdown-content a {
color: #ccc;
}
.themes-dropdown-content a:hover {
background-color: #1a3d1a;
}
}
/* Text alignment */
section p,
article p:not(.sidenote):not(.marginnote) {
text-align: justify;
text-justify: inter-word;
hyphens: auto;
-webkit-hyphens: auto;
-ms-hyphens: auto;
word-break: normal;
overflow-wrap: break-word;
margin-left: 0 !important;
margin-right: auto !important;
}
/* Asterism HR styling */
article hr {
width: 65%;
max-width: 65%;
margin: 4rem 0;
}
/* Directory listing - appears at top when items exist */
.directory-listing {
margin-bottom: 3rem;
padding-bottom: 2rem;
border-bottom: 1px solid #eee;
width: 65%;
}
.directory-listing h2 {
font-size: 1.1rem;
margin-bottom: 1.25rem;
font-weight: 400;
font-variant: small-caps;
letter-spacing: 0.05em;
color: #666;
}
.items-list {
list-style: none;
padding-left: 0;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 0.75rem 1.5rem;
}
.items-list li {
margin-bottom: 0;
}
.items-list a {
display: flex;
align-items: center;
gap: 0.6rem;
text-decoration: none;
color: #333;
transition: color 0.2s ease;
padding: 0.4rem 0;
}
.items-list a:hover {
color: #000;
}
.item-icon {
width: 22px;
height: 22px;
flex-shrink: 0;
}
.item-name {
line-height: 1.3;
font-size: 0.95rem;
}
/* About section that follows directory listing */
.directory-about {
margin-top: 0;
}
.directory-about h2 {
font-size: 1.1rem;
margin-bottom: 1.25rem;
font-weight: 400;
font-variant: small-caps;
letter-spacing: 0.05em;
color: #666;
}
/* Parent navigation */
.parent-navigation {
margin-top: 4rem;
padding-top: 2rem;
border-top: 1px solid #eee;
width: 65%;
}
.parent-link {
display: flex;
align-items: center;
gap: 0.75rem;
text-decoration: none;
color: #666;
font-size: 0.95rem;
font-style: italic;
transition: color 0.2s ease;
}
.parent-link:hover {
color: #333;
}
.parent-icon {
width: 20px;
height: 20px;
flex-shrink: 0;
}
.parent-text {
line-height: 1.2;
}
@media (max-width: 760px) {
article h1 {
font-size: 2.5rem;
width: 100%;
}
.post-subtitle {
font-size: 1rem;
margin-bottom: 2rem;
}
.post-title-container {
width: 100%;
gap: 0.75rem;
}
.post-title-icon {
margin-left: 0;
width: 32px;
height: 32px;
}
article hr {
width: 100%;
max-width: 100%;
}
section p,
article p:not(.sidenote):not(.marginnote) {
width: 100% !important;
max-width: 100% !important;
}
.directory-listing {
width: 100%;
margin-bottom: 2rem;
padding-bottom: 1.5rem;
}
.directory-listing h2,
.directory-about h2 {
font-size: 1rem;
}
.items-list {
grid-template-columns: 1fr;
}
.parent-navigation {
width: 100%;
margin-top: 3rem;
padding-top: 1.5rem;
}
.parent-link {
font-size: 0.9rem;
}
.parent-icon {
width: 18px;
height: 18px;
}
}
</style>
<script>
// When arriving at a page with a hash pointing to a sidenote, auto-open it
document.addEventListener('DOMContentLoaded', function() {
if (window.location.hash) {
const sidenoteId = window.location.hash.substring(1);
const checkbox = document.getElementById(sidenoteId);
if (checkbox && checkbox.type === 'checkbox') {
// Check the checkbox to reveal the sidenote
checkbox.checked = true;
// Find the label or parent paragraph to scroll to
const label = document.querySelector(`label[for="${sidenoteId}"]`);
const scrollTarget = label ? label : checkbox.parentElement;
// Scroll to the sidenote after a brief delay
setTimeout(() => {
if (scrollTarget) {
scrollTarget.scrollIntoView({behavior: 'smooth', block: 'center'});
}
// Highlight the sidenote permanently
const sidenote = checkbox.nextElementSibling;
if (sidenote && sidenote.classList.contains('sidenote')) {
const isDark = document.body.classList.contains('dark-mode') ||
window.matchMedia('(prefers-color-scheme: dark)').matches;
if (isDark) {
// Baller dark mode styling with golden glow
sidenote.style.background = 'linear-gradient(135deg, rgba(255, 215, 0, 0.15), rgba(255, 193, 7, 0.12))';
sidenote.style.color = '#ffd700';
sidenote.style.textShadow = '0 0 20px rgba(255, 215, 0, 0.3)';
sidenote.style.borderLeft = '2px solid rgba(255, 215, 0, 0.4)';
sidenote.style.paddingLeft = '0.75rem';
} else {
sidenote.style.backgroundColor = 'rgba(255, 235, 59, 0.3)';
sidenote.style.color = '#111';
}
sidenote.style.transition = 'all 0.3s ease';
}
}, 100);
}
}
// Themes dropdown
const themesButton = document.querySelector('.themes-badge');
const themesDropdown = document.querySelector('.themes-dropdown-content');
if (themesButton && themesDropdown) {
themesButton.addEventListener('click', function(e) {
e.stopPropagation();
themesDropdown.classList.toggle('show');
});
// Close dropdown when clicking outside
document.addEventListener('click', function() {
themesDropdown.classList.remove('show');
});
}
});
</script>
{% endblock %}
{% block content %}
<article>
<div class="post-title-container">
{% if unique_icon %}
<img src="{{ unique_icon }}" alt="Icon for {{ title }}" class="post-title-icon">
{% endif %}
<div class="post-title-text">
<h1>{{ title }}</h1>
</div>
</div>
{% if metadata and metadata.date %}
<div class="post-subtitle">
{{ metadata.date if metadata.date is string else metadata.date[0] }}
{% if reading_time %}
<span class="reading-time-badge">{{ reading_time }} min read</span>
{% endif %}
{% if article_themes and article_themes|length > 0 %}
<div class="themes-dropdown">
<button class="themes-badge">{{ article_themes|length }} theme{{ 's' if article_themes|length != 1 else '' }}</button>
<div class="themes-dropdown-content">
{% for theme in article_themes %}
<a href="/archive/themes#{{ theme.name|replace(' ', '-') }}">{{ theme.name }}</a>
{% endfor %}
</div>
</div>
{% endif %}
{% if pdf_available %}
<a href="{{ request.path }}.pdf" class="pdf-badge" title="Download as PDF">PDF</a>
{% endif %}
<a href="{{ request.path }}.md" class="markdown-badge" title="View Markdown source">Markdown</a>
</div>
{% endif %}
{% if items %}
<div class="directory-listing">
<h2>In This Section</h2>
<ul class="items-list">
{% for item in items %}
<li class="item {% if item.is_dir %}folder{% else %}file{% endif %}">
<a href="{{ item.url_path }}">
{% if item.unique_icon %}
<img src="{{ item.unique_icon }}" alt="{{ item.name }}" class="item-icon">
{% endif %}
<span class="item-name">{{ item.display_name or item.name }}</span>
</a>
</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if items and content and content|striptags|trim %}
<div class="directory-about">
<h2>About</h2>
</div>
{% endif %}
<section>
{{ content | safe }}
</section>
{% if related_posts %}
<section class="related-essays">
<h2>Keep Reading</h2>
<ul>
{% for p in related_posts %}
<li>
{% if p.unique_icon %}<img src="{{ p.unique_icon }}" alt="" class="related-icon">{% endif %}
<a href="{{ p.url }}">{{ p.title }}</a>
</li>
{% endfor %}
</ul>
</section>
{% endif %}
<!-- Comments disabled for now -->
{% if parent_directory %}
<div class="parent-navigation">
<a href="{{ parent_directory.url }}" class="parent-link">
{% if parent_directory.icon %}
<img src="{{ parent_directory.icon }}" alt="Parent directory icon" class="parent-icon">
{% endif %}
<span class="parent-text">← {{ parent_directory.display_name }}</span>
</a>
</div>
{% endif %}
</article>
{% endblock %}