mirror of
https://github.com/kennethreitz/kennethreitz.org.git
synced 2026-06-05 22:50:17 +00:00
735 lines
25 KiB
HTML
735 lines
25 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>{% block title %}{{ title }} - Kenneth Reitz{% endblock %}</title>
|
||
|
||
<!-- SEO and Meta -->
|
||
<meta name="description" content="{% block description %}Kenneth Reitz - Creator of Requests and Certifi, trusted by millions of developers worldwide. Thoughts on technology, philosophy, and building software for humans.{% endblock %}" />
|
||
<meta name="author" content="Kenneth Reitz" />
|
||
|
||
<!-- OpenGraph -->
|
||
<meta property="og:title" content="{% block og_title %}{{ title }} - Kenneth Reitz{% endblock %}" />
|
||
<meta property="og:description" content="{% block og_description %}Creator of Requests and Certifi - libraries trusted by millions of developers worldwide{% endblock %}" />
|
||
<meta property="og:type" content="{% block og_type %}website{% endblock %}" />
|
||
<meta property="og:url" content="{% block og_url %}https://kennethreitz.org{% endblock %}" />
|
||
<meta property="og:image" content="{% block og_image %}https://kennethreitz.org/static/images/social-card.jpg{% endblock %}" />
|
||
<meta property="og:image:width" content="1200" />
|
||
<meta property="og:image:height" content="630" />
|
||
<meta property="og:site_name" content="Kenneth Reitz" />
|
||
|
||
<!-- Twitter Card -->
|
||
<meta name="twitter:card" content="{% block twitter_card %}summary_large_image{% endblock %}" />
|
||
<meta name="twitter:creator" content="@kennethreitz42" />
|
||
<meta name="twitter:title" content="{% block twitter_title %}{{ title }} - Kenneth Reitz{% endblock %}" />
|
||
<meta name="twitter:description" content="{% block twitter_description %}Creator of Requests and Certifi - libraries trusted by millions of developers worldwide{% endblock %}" />
|
||
<meta name="twitter:image" content="{% block twitter_image %}https://kennethreitz.org/static/images/social-card.jpg{% endblock %}" />
|
||
|
||
<!-- RSS Feed -->
|
||
<link rel="alternate" type="application/rss+xml" title="Kenneth Reitz - Essays & AI Writings" href="/feed.xml" />
|
||
|
||
<!-- Tufte CSS -->
|
||
<link rel="stylesheet" href="/static/tufte/tufte.css" />
|
||
|
||
<style>
|
||
/* Fix for ET Book font bold-italic rendering issues */
|
||
/* ET Book doesn't have a true bold-italic variant, so we disable faux bold */
|
||
strong em, em strong, b i, i b,
|
||
.subtitle strong em, .subtitle em strong,
|
||
.subtitle b i, .subtitle i b,
|
||
nav strong em, nav em strong,
|
||
h1 strong em, h1 em strong,
|
||
h2 strong em, h2 em strong,
|
||
h3 strong em, h3 em strong {
|
||
font-weight: normal !important;
|
||
font-style: italic !important;
|
||
}
|
||
|
||
/* For better readability, you could also use the semi-bold variant */
|
||
/* which ET Book does support, though still no bold-italic */
|
||
.subtitle em, .subtitle i,
|
||
nav em, nav i {
|
||
font-weight: 500; /* semi-bold instead of bold for italics */
|
||
}
|
||
|
||
/* Adjust content width for better sidenote spacing */
|
||
section > p,
|
||
section > footer,
|
||
section > table,
|
||
section > blockquote,
|
||
p,
|
||
blockquote,
|
||
.post-content > p,
|
||
.post-content > blockquote,
|
||
.post-content > ul,
|
||
.post-content > ol {
|
||
width: 55%;
|
||
}
|
||
|
||
section > dl,
|
||
section > ol,
|
||
section > ul,
|
||
.post-content > dl {
|
||
width: 50%;
|
||
}
|
||
|
||
/* Override for full-width elements when needed */
|
||
.post-content > h1,
|
||
.post-content > h2,
|
||
.post-content > h3,
|
||
.post-content > h4,
|
||
.post-content > h5,
|
||
.post-content > h6 {
|
||
width: 100%;
|
||
}
|
||
|
||
.sidenote,
|
||
.marginnote {
|
||
width: 38%;
|
||
margin-right: -42%;
|
||
margin-left: 2%;
|
||
}
|
||
|
||
/* Responsive adjustments */
|
||
@media (max-width: 1400px) {
|
||
section > p,
|
||
section > footer,
|
||
section > table,
|
||
section > blockquote,
|
||
p,
|
||
blockquote,
|
||
.post-content > p,
|
||
.post-content > blockquote,
|
||
.post-content > ul,
|
||
.post-content > ol {
|
||
width: 60%;
|
||
}
|
||
|
||
.sidenote,
|
||
.marginnote {
|
||
width: 33%;
|
||
margin-right: -37%;
|
||
margin-left: 2%;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 1200px) {
|
||
section > p,
|
||
section > footer,
|
||
section > table,
|
||
section > blockquote,
|
||
p,
|
||
blockquote,
|
||
.post-content > p,
|
||
.post-content > blockquote,
|
||
.post-content > ul,
|
||
.post-content > ol {
|
||
width: 70%;
|
||
}
|
||
|
||
.sidenote,
|
||
.marginnote {
|
||
width: 33%;
|
||
margin-right: -37%;
|
||
margin-left: 2%;
|
||
}
|
||
}
|
||
|
||
/* Breadcrumb styling */
|
||
.breadcrumbs {
|
||
font-size: 0.875rem;
|
||
color: #666;
|
||
margin: 1rem 0 2rem 0;
|
||
font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
|
||
}
|
||
|
||
.breadcrumbs a {
|
||
color: #666;
|
||
text-decoration: none;
|
||
background: none;
|
||
text-shadow: none;
|
||
}
|
||
|
||
.breadcrumbs a:hover {
|
||
color: #111;
|
||
}
|
||
|
||
.breadcrumb-separator {
|
||
margin: 0 0.5rem;
|
||
color: #999;
|
||
}
|
||
|
||
|
||
/* Mobile breadcrumb adjustments */
|
||
@media (max-width: 760px) {
|
||
.breadcrumbs {
|
||
font-size: 0.8rem;
|
||
margin: 0.75rem 0 1.5rem 0;
|
||
}
|
||
|
||
.breadcrumb-separator {
|
||
margin: 0 0.25rem;
|
||
}
|
||
}
|
||
|
||
/* Homepage subtitle spacing adjustment */
|
||
p.subtitle {
|
||
line-height: 1.6;
|
||
}
|
||
|
||
/* Navigation spacing adjustment */
|
||
header nav a {
|
||
margin-right: 1rem;
|
||
}
|
||
|
||
header nav a:last-child {
|
||
margin-right: 0;
|
||
}
|
||
|
||
/* Random post button styling */
|
||
.random-link {
|
||
font-size: 1.1rem;
|
||
}
|
||
|
||
/* Directory listing styling */
|
||
.directory-listing ul {
|
||
list-style: none;
|
||
padding-left: 0;
|
||
font-size: 0.95rem;
|
||
line-height: 1.8;
|
||
}
|
||
|
||
.directory-listing li {
|
||
margin-bottom: 0.75rem;
|
||
padding-left: 2rem;
|
||
position: relative;
|
||
font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
|
||
}
|
||
|
||
.directory-listing li::before {
|
||
content: attr(data-icon);
|
||
position: absolute;
|
||
left: 0;
|
||
color: #666;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.directory-listing a {
|
||
color: #444;
|
||
text-decoration: none;
|
||
font-weight: 400;
|
||
background: none;
|
||
text-shadow: none;
|
||
transition: color 0.2s ease;
|
||
}
|
||
|
||
.directory-listing a:hover {
|
||
color: #111;
|
||
}
|
||
|
||
.item-date {
|
||
font-size: 0.8rem;
|
||
color: #888;
|
||
font-style: italic;
|
||
margin-left: 0.75rem;
|
||
font-variant: small-caps;
|
||
letter-spacing: 0.02em;
|
||
}
|
||
|
||
.directory-listing h3 {
|
||
font-size: 1.3rem;
|
||
color: #333;
|
||
font-weight: 400;
|
||
font-style: italic;
|
||
margin-bottom: 1.5rem;
|
||
margin-top: 2.5rem;
|
||
}
|
||
|
||
/* Hide HR lines to prevent sidenote interference */
|
||
hr {
|
||
display: none;
|
||
}
|
||
|
||
|
||
/* Fix iframe overflow into sidenotes */
|
||
iframe {
|
||
max-width: 55% !important;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
@media (max-width: 1400px) {
|
||
iframe {
|
||
max-width: 60% !important;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 1200px) {
|
||
iframe {
|
||
max-width: 70% !important;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 760px) {
|
||
iframe {
|
||
max-width: 100% !important;
|
||
}
|
||
}
|
||
|
||
/* Footer spacing */
|
||
.footer-note {
|
||
margin-top: 3rem;
|
||
}
|
||
|
||
/* Fix excessive right padding on mobile */
|
||
@media (max-width: 760px) {
|
||
body {
|
||
padding-left: 8% !important;
|
||
padding-right: 8% !important;
|
||
width: 84% !important;
|
||
}
|
||
|
||
/* Hide sidenotes on narrow screens */
|
||
.sidenote,
|
||
.marginnote {
|
||
display: none;
|
||
}
|
||
|
||
/* Make content full width when sidenotes are hidden */
|
||
section > p,
|
||
section > footer,
|
||
section > table,
|
||
section > blockquote,
|
||
p,
|
||
blockquote,
|
||
.post-content > p,
|
||
.post-content > blockquote,
|
||
.post-content > ul,
|
||
.post-content > ol {
|
||
width: 100%;
|
||
}
|
||
|
||
section > dl,
|
||
section > ol,
|
||
section > ul,
|
||
.post-content > dl {
|
||
width: 100%;
|
||
}
|
||
}
|
||
|
||
/* Mobile font fixes */
|
||
@media (max-width: 760px) {
|
||
body, p, h1, h2, h3, h4, h5, h6 {
|
||
text-shadow: none !important;
|
||
-webkit-text-stroke: 0 !important;
|
||
-webkit-font-smoothing: antialiased;
|
||
-moz-osx-font-smoothing: grayscale;
|
||
text-rendering: optimizeLegibility;
|
||
}
|
||
|
||
/* Fix Tufte's complex link underlines on mobile */
|
||
a, a:link, a:visited,
|
||
.tufte-underline,
|
||
.hover-tufte-underline:hover {
|
||
text-shadow: none !important;
|
||
background: none !important;
|
||
text-decoration: underline !important;
|
||
text-decoration-thickness: 1px !important;
|
||
text-underline-offset: 2px !important;
|
||
}
|
||
|
||
/* Ensure no double font rendering */
|
||
* {
|
||
-webkit-transform: translateZ(0);
|
||
transform: translateZ(0);
|
||
}
|
||
}
|
||
|
||
/* Print Styles for Tufte CSS */
|
||
@media print {
|
||
* {
|
||
background: transparent !important;
|
||
color: black !important;
|
||
box-shadow: none !important;
|
||
text-shadow: none !important;
|
||
}
|
||
|
||
body {
|
||
font-size: 12pt;
|
||
line-height: 1.3;
|
||
margin: 0;
|
||
padding: 0;
|
||
background: white;
|
||
color: black;
|
||
width: 100% !important;
|
||
max-width: none !important;
|
||
}
|
||
|
||
/* Hide navigation and non-essential elements */
|
||
header nav,
|
||
.breadcrumbs,
|
||
.post-navigation,
|
||
.related-posts,
|
||
.footer-content,
|
||
.search-container {
|
||
display: none !important;
|
||
}
|
||
|
||
/* Optimize content for print */
|
||
section > p,
|
||
section > footer,
|
||
section > table,
|
||
section > blockquote,
|
||
p,
|
||
blockquote,
|
||
.post-content > p,
|
||
.post-content > blockquote,
|
||
.post-content > ul,
|
||
.post-content > ol {
|
||
width: 100% !important;
|
||
max-width: none !important;
|
||
}
|
||
|
||
section > dl,
|
||
section > ol,
|
||
section > ul,
|
||
.post-content > dl {
|
||
width: 100% !important;
|
||
}
|
||
|
||
/* Convert sidenotes to footnotes for print */
|
||
.sidenote,
|
||
.marginnote {
|
||
display: none !important;
|
||
}
|
||
|
||
/* Show sidenote content as footnotes at bottom */
|
||
.sidenote::before {
|
||
content: "["counter(sidenote-counter) "] ";
|
||
counter-increment: sidenote-counter;
|
||
}
|
||
|
||
/* Print-specific typography */
|
||
h1 {
|
||
font-size: 18pt;
|
||
margin: 24pt 0 12pt 0;
|
||
page-break-after: avoid;
|
||
}
|
||
|
||
h2 {
|
||
font-size: 16pt;
|
||
margin: 20pt 0 10pt 0;
|
||
page-break-after: avoid;
|
||
}
|
||
|
||
h3 {
|
||
font-size: 14pt;
|
||
margin: 16pt 0 8pt 0;
|
||
page-break-after: avoid;
|
||
}
|
||
|
||
p {
|
||
font-size: 12pt;
|
||
margin: 12pt 0;
|
||
text-align: justify;
|
||
orphans: 3;
|
||
widows: 3;
|
||
}
|
||
|
||
/* Print links with URLs */
|
||
a[href]:after {
|
||
content: " (" attr(href) ")";
|
||
font-size: 10pt;
|
||
color: #666;
|
||
}
|
||
|
||
a[href^="#"]:after,
|
||
a[href^="/"]:after {
|
||
content: "";
|
||
}
|
||
|
||
/* Blockquotes */
|
||
blockquote {
|
||
margin: 12pt 24pt;
|
||
padding: 0;
|
||
font-style: italic;
|
||
border-left: 2pt solid #ccc;
|
||
padding-left: 12pt;
|
||
}
|
||
|
||
/* Code blocks */
|
||
pre, code {
|
||
font-family: "Courier New", Courier, monospace;
|
||
font-size: 10pt;
|
||
background: #f5f5f5;
|
||
border: 1pt solid #ccc;
|
||
padding: 6pt;
|
||
}
|
||
|
||
pre {
|
||
white-space: pre-wrap;
|
||
page-break-inside: avoid;
|
||
}
|
||
|
||
/* Tables */
|
||
table {
|
||
border-collapse: collapse;
|
||
width: 100%;
|
||
font-size: 10pt;
|
||
}
|
||
|
||
th, td {
|
||
border: 1pt solid #ccc;
|
||
padding: 6pt;
|
||
text-align: left;
|
||
}
|
||
|
||
th {
|
||
background: #f0f0f0;
|
||
font-weight: bold;
|
||
}
|
||
|
||
/* Images */
|
||
img {
|
||
max-width: 100%;
|
||
height: auto;
|
||
page-break-inside: avoid;
|
||
}
|
||
|
||
/* Page breaks */
|
||
.page-break {
|
||
page-break-before: always;
|
||
}
|
||
|
||
/* Hide toggle inputs for sidenotes */
|
||
input[type="checkbox"].margin-toggle {
|
||
display: none !important;
|
||
}
|
||
|
||
label.margin-toggle {
|
||
display: none !important;
|
||
}
|
||
|
||
/* Header styling for print */
|
||
header h1 {
|
||
font-size: 20pt;
|
||
margin-bottom: 6pt;
|
||
}
|
||
|
||
.subtitle {
|
||
font-size: 14pt;
|
||
margin-bottom: 20pt;
|
||
font-style: italic;
|
||
}
|
||
|
||
/* Ensure proper spacing */
|
||
section {
|
||
margin-bottom: 20pt;
|
||
}
|
||
|
||
/* Lists */
|
||
ul, ol {
|
||
margin: 12pt 0;
|
||
padding-left: 20pt;
|
||
}
|
||
|
||
li {
|
||
margin: 6pt 0;
|
||
}
|
||
}
|
||
|
||
</style>
|
||
|
||
|
||
<!-- Structured Data (JSON-LD) -->
|
||
<script type="application/ld+json">
|
||
{
|
||
"@context": "https://schema.org",
|
||
"@type": "{% block schema_type %}WebSite{% endblock %}",
|
||
"name": "{% block schema_name %}Kenneth Reitz{% endblock %}",
|
||
"url": "https://kennethreitz.org{% block schema_url %}/{% endblock %}",
|
||
"description": "{% block schema_description %}Kenneth Reitz - Creator of Requests and Certifi, trusted by millions of developers worldwide. Thoughts on technology, philosophy, and building software for humans.{% endblock %}",
|
||
"author": {
|
||
"@type": "Person",
|
||
"name": "Kenneth Reitz",
|
||
"url": "https://kennethreitz.org",
|
||
"sameAs": [
|
||
"https://github.com/kennethreitz",
|
||
"https://twitter.com/kennethreitz42"
|
||
],
|
||
"jobTitle": "Python Developer",
|
||
"worksFor": {
|
||
"@type": "Organization",
|
||
"name": "Independent"
|
||
},
|
||
"knowsAbout": [
|
||
"Python Programming",
|
||
"API Design",
|
||
"Software Architecture",
|
||
"Open Source Development",
|
||
"Artificial Intelligence",
|
||
"Mental Health Advocacy"
|
||
]
|
||
},
|
||
"publisher": {
|
||
"@type": "Person",
|
||
"name": "Kenneth Reitz",
|
||
"url": "https://kennethreitz.org"
|
||
}{% block schema_extra %}{% endblock %}
|
||
}
|
||
</script>
|
||
|
||
{% block extra_head %}{% endblock %}
|
||
|
||
<!-- Analytics -->
|
||
<script type="text/javascript">
|
||
var _gauges = _gauges || [];
|
||
(function() {
|
||
var t = document.createElement('script');
|
||
t.type = 'text/javascript';
|
||
t.async = true;
|
||
t.id = 'gauges-tracker';
|
||
t.setAttribute('data-site-id', '65529a9abd1a3b3101979d52');
|
||
t.setAttribute('data-track-path', 'https://track.gaug.es/track.gif');
|
||
t.src = 'https://d2fuc4clr7gvcn.cloudfront.net/track.js';
|
||
var s = document.getElementsByTagName('script')[0];
|
||
s.parentNode.insertBefore(t, s);
|
||
})();
|
||
</script>
|
||
</head>
|
||
<body>
|
||
<article>
|
||
<header>
|
||
<nav>
|
||
<a href="/">Home</a>
|
||
<a href="/directory">Directory</a>
|
||
<a href="/archive">Archive</a>
|
||
<a href="/search">[search]</a>
|
||
<a href="/random" class="random-link">[random]</a>
|
||
<a href="/software">Software</a>
|
||
<a href="/artificial-intelligence">AI</a>
|
||
</nav>
|
||
|
||
{% if current_path or breadcrumbs %}
|
||
<div class="breadcrumbs">
|
||
<a href="/">Home</a>
|
||
{% if breadcrumbs %}
|
||
{% for crumb in breadcrumbs %}
|
||
<span class="breadcrumb-separator">›</span>
|
||
<a href="{{ crumb.url }}">{{ crumb.name }}</a>
|
||
{% endfor %}
|
||
{% elif current_path %}
|
||
{% set path_parts = current_path.strip('/').split('/') %}
|
||
{% for part in path_parts if part %}
|
||
<span class="breadcrumb-separator">›</span>
|
||
{% set partial_path = '/' + path_parts[:loop.index]|join('/') %}
|
||
<a href="{{ partial_path }}">{{ part }}</a>
|
||
{% endfor %}
|
||
{% endif %}
|
||
</div>
|
||
{% endif %}
|
||
</header>
|
||
|
||
<main>
|
||
{% block content %}{% endblock %}
|
||
</main>
|
||
|
||
<footer>
|
||
<div class="footer-content">
|
||
<div class="footer-note">
|
||
<p>© {{ "now"|strftime("%Y") }} Kenneth Reitz. Made with <a href="https://kjvstudy.org/book/1%20Corinthians/chapter/13">love</a>.</p>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
</article>
|
||
|
||
{% block extra_scripts %}{% endblock %}
|
||
|
||
<!-- Force light mode, especially on mobile -->
|
||
<style>
|
||
@media (prefers-color-scheme: dark) {
|
||
body {
|
||
background-color: #fff !important;
|
||
color: #111 !important;
|
||
}
|
||
|
||
h1, h2, h3, h4, h5, h6 {
|
||
color: #333 !important;
|
||
}
|
||
|
||
a {
|
||
color: #111 !important;
|
||
}
|
||
|
||
/* Force light backgrounds on all elements */
|
||
* {
|
||
background-color: transparent !important;
|
||
color: inherit !important;
|
||
}
|
||
|
||
/* Override any dark mode styling */
|
||
body, html {
|
||
background: #fff !important;
|
||
color: #111 !important;
|
||
}
|
||
}
|
||
|
||
/* Mobile-specific light mode enforcement */
|
||
@media (max-width: 760px) {
|
||
body {
|
||
background-color: #fff !important;
|
||
color: #111 !important;
|
||
}
|
||
|
||
* {
|
||
background-color: transparent !important;
|
||
}
|
||
|
||
body, html {
|
||
background: #fff !important;
|
||
color: #111 !important;
|
||
}
|
||
}
|
||
</style>
|
||
|
||
<!-- Simplified Color System (light themes only) -->
|
||
<script>
|
||
(function() {
|
||
// Check if user prefers light mode or is on mobile
|
||
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||
const isMobile = window.innerWidth <= 760;
|
||
|
||
// Force light mode on mobile or if user prefers dark (override their dark preference)
|
||
if (isMobile || prefersDark) {
|
||
document.body.style.backgroundColor = '#fff';
|
||
document.body.style.color = '#111';
|
||
return; // Skip color schemes entirely
|
||
}
|
||
|
||
const lightColorSchemes = [
|
||
'scheme-ocean',
|
||
'scheme-forest',
|
||
'scheme-sunset',
|
||
'scheme-lavender',
|
||
'scheme-rose',
|
||
'scheme-sage',
|
||
'scheme-amber'
|
||
];
|
||
|
||
// Get or generate a scheme based on the current page
|
||
let scheme = localStorage.getItem('current-color-scheme');
|
||
|
||
// Change scheme occasionally (20% chance on page load)
|
||
if (!scheme || Math.random() < 0.2) {
|
||
scheme = lightColorSchemes[Math.floor(Math.random() * lightColorSchemes.length)];
|
||
localStorage.setItem('current-color-scheme', scheme);
|
||
}
|
||
|
||
// Apply the scheme
|
||
document.body.className = (document.body.className + ' ' + scheme).trim();
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|