Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion _includes/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,29 @@

<title>{% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %}</title>
<meta name="description" content="{{ page.excerpt | default: site.description | strip_html | normalize_whitespace | truncate: 160 | escape }}">
<meta name="theme-color" content="#424242" >
<meta name="theme-color" content="#424242" id="theme-color-meta">
<meta name="color-scheme" content="light dark">

<!-- Set the theme before the stylesheet paints anything, so a dark-mode
visitor never sees a flash of the light page. assets/js/theme.js does
the same resolution for the toggle; keep the two in step. -->
<script>
(function () {
var pref;
try { pref = localStorage.getItem("theme"); } catch (e) {}
if (pref !== "light" && pref !== "dark") pref = "system";
var theme = pref === "system"
? (window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light")
: pref;
var root = document.documentElement;
root.setAttribute("data-theme", theme);
root.setAttribute("data-theme-pref", pref);
if (theme === "dark") {
document.getElementById("theme-color-meta").setAttribute("content", "#1b1b1d");
}
})();
</script>
<script src="{{ "/assets/js/theme.js" | relative_url }}" defer></script>

<link rel="stylesheet" href="{{ "/assets/main.css" | relative_url }}">
<link rel="canonical" href="{{ page.url | replace:'index.html','' | absolute_url }}">
Expand Down
35 changes: 35 additions & 0 deletions _includes/header.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<header class="site-header" role="banner">

<div class="wrapper">
{%- assign default_paths = site.pages | map: "path" -%}
{%- assign page_paths = site.header_pages | default: default_paths -%}
<a class="site-title" rel="author" href="{{ "/" | relative_url }}">{{ site.title | escape }}</a>

{%- if page_paths -%}
<nav class="site-nav">
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger">
<span class="menu-icon">
<svg viewBox="0 0 18 15" width="18px" height="15px">
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
</svg>
</span>
</label>

<div class="trigger">
{%- for path in page_paths -%}
{%- assign my_page = site.pages | where: "path", path | first -%}
{%- if my_page.title -%}
<a class="page-link" href="{{ my_page.url | relative_url }}">{{ my_page.title | escape }}</a>
{%- endif -%}
{%- endfor -%}
<button type="button" class="theme-toggle" id="theme-toggle" hidden aria-label="Theme: System" title="Theme: System">
<svg class="theme-icon theme-icon-light" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>
<svg class="theme-icon theme-icon-dark" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
<svg class="theme-icon theme-icon-system" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 3a9 9 0 0 1 0 18z" class="theme-icon-fill"/></svg>
</button>
</div>
</nav>
{%- endif -%}
</div>
</header>
120 changes: 120 additions & 0 deletions _sass/_syntax-dark.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Dark syntax colors: output of `bundle exec rougify style github.dark --scope .highlight` (rouge 4.7.0).
// Included from dark-theme.scss inside the dark-theme mixin.
@mixin syntax-dark {
.highlight table td { padding: 5px; }
.highlight table pre { margin: 0; }
.highlight, .highlight .w {
color: #c9d1d9;
background-color: #161b22;
}
.highlight .k, .highlight .kd, .highlight .kn, .highlight .kp, .highlight .kr, .highlight .kt, .highlight .kv {
color: #ff7b72;
}
.highlight .gr {
color: #f0f6fc;
}
.highlight .gd {
color: #ffdcd7;
background-color: #67060c;
}
.highlight .nb {
color: #ffa657;
}
.highlight .nc {
color: #ffa657;
}
.highlight .no {
color: #ffa657;
}
.highlight .nn {
color: #ffa657;
}
.highlight .sr {
color: #7ee787;
}
.highlight .na {
color: #7ee787;
}
.highlight .nt {
color: #7ee787;
}
.highlight .gi {
color: #aff5b4;
background-color: #033a16;
}
.highlight .ges {
font-weight: bold;
font-style: italic;
}
.highlight .kc {
color: #79c0ff;
}
.highlight .l, .highlight .ld, .highlight .m, .highlight .mb, .highlight .mf, .highlight .mh, .highlight .mi, .highlight .il, .highlight .mo, .highlight .mx {
color: #79c0ff;
}
.highlight .sb {
color: #79c0ff;
}
.highlight .bp {
color: #79c0ff;
}
.highlight .ne {
color: #79c0ff;
}
.highlight .nl {
color: #79c0ff;
}
.highlight .py {
color: #79c0ff;
}
.highlight .nv, .highlight .vc, .highlight .vg, .highlight .vi, .highlight .vm {
color: #79c0ff;
}
.highlight .o, .highlight .ow {
color: #79c0ff;
}
.highlight .gh {
color: #1f6feb;
font-weight: bold;
}
.highlight .gu {
color: #1f6feb;
font-weight: bold;
}
.highlight .s, .highlight .sa, .highlight .sc, .highlight .dl, .highlight .sd, .highlight .s2, .highlight .se, .highlight .sh, .highlight .sx, .highlight .s1, .highlight .ss {
color: #a5d6ff;
}
.highlight .nd {
color: #d2a8ff;
}
.highlight .nf, .highlight .fm {
color: #d2a8ff;
}
.highlight .err {
color: #f0f6fc;
background-color: #8e1519;
}
.highlight .c, .highlight .ch, .highlight .cd, .highlight .cm, .highlight .cp, .highlight .cpf, .highlight .c1, .highlight .cs {
color: #8b949e;
}
.highlight .gl {
color: #8b949e;
}
.highlight .gt {
color: #8b949e;
}
.highlight .ni {
color: #c9d1d9;
}
.highlight .si {
color: #c9d1d9;
}
.highlight .ge {
color: #c9d1d9;
font-style: italic;
}
.highlight .gs {
color: #c9d1d9;
font-weight: bold;
}
}
205 changes: 205 additions & 0 deletions _sass/dark-theme.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// Dark theme (issue #117).
//
// Minima 2.5 compiles its colors into the CSS and runs lighten()/darken() on
// them, so its Sass variables can't be swapped for CSS custom properties.
// Dark mode is therefore a set of override rules, scoped so the light CSS is
// left exactly as minima emits it.
//
// Which theme applies is decided by `data-theme` on <html>, set before first
// paint by the script in _includes/head.html and changed by assets/js/theme.js.
// Without JavaScript there is no `data-theme`, and the media query at the
// bottom follows the OS setting instead.

@import "syntax-dark";

// Every foreground/background pair below meets WCAG AA (4.5:1) or better.
$dark-background-color: #1b1b1d; // also the theme-color meta value in dark
$dark-text-color: #e3e3e3; // 13.4:1
$dark-brand-color: #6ea8fe; // 7.1:1
$dark-visited-color: #8fb0e0;
$dark-grey-color: #a0a0a0; // 6.6:1, post meta and footer
$dark-grey-color-light: #3a3a3d; // borders
$dark-grey-color-dark: #c8c8c8; // site title, 10.3:1
$dark-code-background: #161b22; // matches rouge github.dark

@mixin dark-theme {
color-scheme: dark;

body {
color: $dark-text-color;
background-color: $dark-background-color;
}

a {
color: $dark-brand-color;

&:visited {
color: $dark-visited-color;
}

&:hover {
color: $dark-text-color;
}
}

blockquote {
color: $dark-grey-color;
border-left-color: $dark-grey-color-light;
}

pre,
code {
border-color: $dark-grey-color-light;
background-color: $dark-code-background;
}

hr {
border-color: $dark-grey-color-light;
}

.svg-icon {
fill: $dark-grey-color;
}

table {
color: #d0d0d0;
border-color: $dark-grey-color-light;

tr:nth-child(even) {
background-color: #232326;
}

th {
background-color: #26262a;
border-color: #444448;
border-bottom-color: #55555a;
}

td {
border-color: $dark-grey-color-light;
}
}

.site-header {
border-top-color: $dark-grey-color-dark;
border-bottom-color: $dark-grey-color-light;
}

.site-title {
&,
&:visited {
color: $dark-grey-color-dark;
}
}

.site-nav {
.page-link,
.theme-toggle {
color: $dark-text-color;
}

@include media-query($on-palm) {
background-color: $dark-background-color;
border-color: $dark-grey-color-light;

.menu-icon > svg {
fill: $dark-grey-color-dark;
}
}
}

.site-footer {
border-top-color: $dark-grey-color-light;
}

.footer-col-wrapper,
.post-meta {
color: $dark-grey-color;
}

@include syntax-dark;

// github.dark leaves these two unset, which would keep minima's light
// colors (#888, #555) on the dark code background.
.highlight .go {
color: #8b949e;
}

.highlight .gp {
color: #c9d1d9;
}
}

html[data-theme="dark"] {
@include dark-theme;
}

// Keeps native controls and scrollbars light when a visitor picks Light on a
// dark OS; the color-scheme meta would otherwise let the browser follow the OS.
html[data-theme="light"] {
color-scheme: light;
}

// No JavaScript: no data-theme attribute, so follow the OS setting.
@media (prefers-color-scheme: dark) {
html:not([data-theme]) {
@include dark-theme;
}
}

/**
* Theme toggle button (in _includes/header.html)
*/
.theme-toggle {
padding: 0;
border: 0;
background: none;
color: $text-color;
font: inherit;
line-height: $base-line-height;
cursor: pointer;
vertical-align: middle;

// The class rule would otherwise beat the UA's [hidden] { display: none }.
&[hidden] {
display: none;
}

&:focus-visible {
outline: 2px solid currentColor;
outline-offset: 2px;
border-radius: 3px;
}

@include media-query($on-palm) {
margin-left: 20px;
padding: 5px 10px;
}
}

.theme-icon {
display: none;
fill: none;
stroke: currentColor;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
vertical-align: middle;
}

.theme-icon-fill {
fill: currentColor;
}

html[data-theme-pref="light"] .theme-icon-light,
html[data-theme-pref="dark"] .theme-icon-dark,
html[data-theme-pref="system"] .theme-icon-system {
display: inline-block;
}

// Colors fade only while theme.js has this class on <html> (just after a
// click), so page loads and navigation never animate.
html.theme-transition,
html.theme-transition * {
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease !important;
}
Loading
Loading