Literate CSS
One of the benefits of writing my blog in Org-Mode in Emacs, is that my blog posts are a functional literate programming environment. Which is pretty handy for keeping track of things like "how does my CSS work", for example.
Well, in general Org-Mode injects a basic set of CSS into web pages as it exports them, but I'm planning to amend that slightly as I go forward. Meaning this blog post will be a bit of a living document, evolving over time. Hi, future me! Hope you like it.
We're going to cheat a bit and use a "classless CSS framework" (water.css is going to be my first attempt). This means we can remove a lot of default styling, and focus only on the more specific classes org adds. The entire unminified water.css file is included at the end of this file so that it gets bundled together with my custom css. I may build a workflow to minimize the results in the future, but honestly it seems a false optimization right now.
Load fonts early to avoid glitches and spacing issues:
@font-face { font-family: charter; font-style: normal; font-weight: normal; font-stretch: normal; src: url('/fonts/charter_regular.woff2') format('woff2'); } @font-face { font-family: charter; font-style: italic; font-weight: normal; font-stretch: normal; src: url('/fonts/charter_italic.woff2') format('woff2'); } @font-face { font-family: charter; font-style: normal; font-weight: bold; font-stretch: normal; src: url('/fonts/charter_bold.woff2') format('woff2'); } @font-face { font-family: charter; font-style: italic; font-weight: bold; font-stretch: normal; src: url('/fonts/charter_bold_italic.woff2') format('woff2'); } @font-face { font-family: source_code_pro; font-style: regular; font-weight: normal; src: url('/fonts/SourceCodePro-Regular.otf.woff2') format('woff2'); }
Colour variables, so we don't need to keep on repeating them and we have some consistency.
/** * These colors are taken from `water.css`, rearranged to * my liking and expanded a bit for code highlighting. * * Automatic version: * Uses light theme by default but switches to dark theme * if a system-wide theme preference is set on the user's device. */ :root { /* re-usable names for quickly experimenting */ --dominant-base: #EC0000; --complement-base: #00BD00; --secondary-base: #EC6B00; --secondary-complement-base: #008E8E; --dominant: color-mix(in oklab, var(--dominant-base), var(--mixin-foreground) 10%); --complement: color-mix(in oklab, var(--complement-base), var(--mixin-foreground) 25%); --secondary: color-mix(in oklab, var(--secondary-base), var(--mixin-foreground) 25%); --secondary-complement: color-mix(in oklab, var(--secondary-complement-base), var(--mixin-foreground) 10%); --mixin-foreground: black; --mixin-background: white; --nearly-foreground: 98%; --mostly-foreground: 95%; --half-foreground: 50%; --slightly-foreground: 25%; --nearly-background: 99%; --mostly-background: 94%; --half-background: 50%; --slightly-background: 25%; --text-main: color-mix(in oklab, var(--dominant), var(--mixin-foreground) var(--nearly-foreground)); --text-bright: color-mix(in oklab, var(--dominant), var(--mixin-foreground) var(--mostly-foreground)); --text-muted: color-mix(in oklab, var(--dominant), var(--mixin-background) var(--slightly-background)); --background-body: color-mix(in oklab, var(--complement-base), var(--mixin-background) var(--nearly-background)); --background: color-mix(in oklab, var(--complement-base), var(--mixin-background) var(--mostly-background)); --background-alt: color-mix(in oklab, var(--complement-base), var(--mixin-background) var(--half-background)); --code-keyword: var(--dominant); --code-value: var(--complement); --code-type: var(--secondary); --code-comment: var(--secondary-complement); --code-punctuation: var(--text-main); --code-background: var(--background); --code: var(--text-main); --selection: var(--complement); --links: var(--secondary); --focus: var(--secondary); --border: var(--secondary-complement); --animation-duration: 0.1s; --button-base: var(--background-alt); --button-hover: color-mix(in oklab,var(--background-alt), var(--mixin-foreground) var(--slightly-foreground)); --form-placeholder: var(--text-muted); --form-text: var(--text-main); --variable: var(--code); --highlight: var(--complement); --select-arrow: url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23161f27'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E"); } @media (prefers-color-scheme: dark) { :root { --mixin-foreground: white; --mixin-background: #121212; --dominant: color-mix(in oklab, var(--dominant-base), var(--mixin-foreground)); --complement: color-mix(in oklab, var(--complement-base), var(--mixin-foreground)); --secondary: color-mix(in oklab, var(--secondary-base), var(--mixin-foreground)); --secondary-complement: color-mix(in oklab, var(--secondary-complement-base), var(--mixin-foreground)); --nearly-foreground: 98%; --mostly-foreground: 95%; --half-foreground: 50%; --slightly-foreground: 25%; --nearly-background: 90%; --mostly-background: 75%; --half-background: 20%; --slightly-background: 10%; } }
Responsive text and content sizes from the absolutely amazing Practical Typography from Matthew Butterick.
html { font-size: 2.4vw; height: 100%; } /** Make sure that while font size scales smoothly, it never gets * too big or small. */ @media all and (min-width:1000px) { html { font-size: 24px; } } @media all and (max-width:670px) { html{ font-size: 18px; } } body { margin: 20px auto; padding: 0 0.5rem; max-width: 1000px; min-height: 100%; position: relative; z-index: -10000; -webkit-font-smoothing: subpixel-antialiased; /* corrects safari rendering */ font-family: charter, serif; font-weight: normal; line-height: 1.4; word-wrap: break-word; color: var(--text-main); background: var(--background-body); text-rendering: optimizeLegibility; }
My nice little "go home" header needs some CSS to get it looking as cute as I'd want it.
img.home-logo { width: 50px; height: 50px; padding: 3px; background: white; border-radius: 10px; } #org-div-home-and-up { font-size: 70%; display: flex; flex-direction: row; align-items: center; justify-content: flex-end; gap: 10px; }
Adding some horizontal rules helps keep sections separate.
header::after { content: ""; display: block; height: 1px; width: 100%; background: var(--border); } /* The class given to divs containing a top level org heading */ .outline-2 { border-top: 1px solid var(--border); padding-top: 10px; }
Keeping the minimalist footer neat:
/* positioning only, the rest of the header styling is defined in the default water css below */ #my-contacts { display: flex; flex-flow: row wrap; align-items: center; gap: 20px; }
Code colouring. There's a slightly interesting quirk here as each language can define its own custom token types as well as the more general shared set. We get around that by using fairly permissive attribute selectors to categorise classes within source blocks (for example, colouring all spans with a class including the string keyword or primitive the same way rather than rather a separate rule for .org-typescript-primitive
).
/* This class is applied to a wrapper div around code blocks */ .org-src-container { color: var(--text-main); word-wrap: normal; } /** Combines with the language specific rules below to add a "tab" * showing the language contained in the code block */ .org-src-container:before { display: block; font-style: italic; font-size: 0.8em; width: fit-content; padding: 5px; border-bottom: solid 1px var(--code-value); color: var(--text-muted); margin-bottom: 0px; background-color: var(--code-background); border-radius: 8px 8px 0px 0px; } pre.src { font-family: source_code_pro, monospace; font-weight: normal; font-size: 0.8rem; position: relative; white-space: pre; margin: 0px; /* Code can be long; especially on mobile, it might need to scroll */ overflow-x: auto; background-color: var(--code-background); padding: 5px; border-radius: 0px 0px 8px 8px; margin-top: 0px; color: var(--code); } code { font-size: 80%; } pre.src { /* Rule for keywords etc */ & > span[class*="keyword"], & > span[class*="access-modifier"] { color: var(--code-keyword); } /* Rule for as many literal values as I can think of */ & > span[class*="string"], & > span[class*="constant"], & > span[class*="number"] { color: var(--code-value); } /* Rule for punctuation */ & > span[class*="punctuation"], & > span[class*="rainbow"], & > span[class*="bracket"] { color: var(--code-punctuation); } /* Rule for comments */ & > span[class*="comment"] { color: var(--code-comment); } /* Rule for types etc */ & > span[class*="type"], & > span[class*="attribute"], & > span[class*="tag"], & > span[class*="primitive"], & > span[class*="property"], & > span[class*="builtin"] { color: var(--code-type); } }
Everything below this point is modified from the default org style sheet, that normally gets embedded into every page. I'm going to separate it out here so that I can start hacking on it, and then set the export not to inject it every time.
.todo { font-family: monospace; color: red; } .done { font-family: monospace; color: green; } .priority { font-family: monospace; color: orange; } .tag { background-color: #eee; font-family: monospace; padding: 2px; font-size: 80%; font-weight: normal; } .timestamp { color: #bebebe; } .timestamp-kwd { color: #5f9ea0; } .org-right { margin-left: auto; margin-right: 0px; text-align: right; } .org-left { margin-left: 0px; margin-right: auto; text-align: left; } .org-center { margin-left: auto; margin-right: auto; text-align: center; } #postamble p, #preamble p { font-size: 90%; margin: .2em; } p.verse { margin-left: 3%; } /* Languages per Org manual */ .org-src-container:has(pre.src-asymptote):before { content: 'Asymptote'; } .org-src-container:has(pre.src-awk):before { content: 'Awk'; } .org-src-container:has(pre.src-C):before { content: 'C'; } /* pre.src-C++ doesn't work in CSS */ .org-src-container:has(pre.src-clojure):before { content: 'Clojure'; } .org-src-container:has(pre.src-css):before { content: 'CSS'; } .org-src-container:has(pre.src-D):before { content: 'D'; } .org-src-container:has(pre.src-ditaa):before { content: 'ditaa'; } .org-src-container:has(pre.src-dot):before { content: 'Graphviz'; } .org-src-container:has(pre.src-calc):before { content: 'Emacs Calc'; } .org-src-container:has(pre.src-emacs-lisp):before { content: 'Emacs Lisp'; } .org-src-container:has(pre.src-fortran):before { content: 'Fortran'; } .org-src-container:has(pre.src-gnuplot):before { content: 'gnuplot'; } .org-src-container:has(pre.src-haskell):before { content: 'Haskell'; } .org-src-container:has(pre.src-hledger):before { content: 'hledger'; } .org-src-container:has(pre.src-java):before { content: 'Java'; } .org-src-container:has(pre.src-js):before { content: 'Javascript'; } .org-src-container:has(pre.src-latex):before { content: 'LaTeX'; } .org-src-container:has(pre.src-ledger):before { content: 'Ledger'; } .org-src-container:has(pre.src-lisp):before { content: 'Lisp'; } .org-src-container:has(pre.src-lilypond):before { content: 'Lilypond'; } .org-src-container:has(pre.src-lua):before { content: 'Lua'; } .org-src-container:has(pre.src-matlab):before { content: 'MATLAB'; } .org-src-container:has(pre.src-mscgen):before { content: 'Mscgen'; } .org-src-container:has(pre.src-ocaml):before { content: 'Objective Caml'; } .org-src-container:has(pre.src-octave):before { content: 'Octave'; } .org-src-container:has(pre.src-org):before { content: 'Org mode'; } .org-src-container:has(pre.src-oz):before { content: 'OZ'; } .org-src-container:has(pre.src-plantuml):before { content: 'Plantuml'; } .org-src-container:has(pre.src-processing):before { content: 'Processing.js'; } .org-src-container:has(pre.src-python):before { content: 'Python'; } .org-src-container:has(pre.src-R):before { content: 'R'; } .org-src-container:has(pre.src-ruby):before { content: 'Ruby'; } .org-src-container:has(pre.src-sass):before { content: 'Sass'; } .org-src-container:has(pre.src-scheme):before { content: 'Scheme'; } .org-src-container:has(pre.src-screen):before { content: 'Gnu Screen'; } .org-src-container:has(pre.src-sed):before { content: 'Sed'; } .org-src-container:has(pre.src-sh):before { content: 'shell'; } .org-src-container:has(pre.src-sql):before { content: 'SQL'; } .org-src-container:has(pre.src-sqlite):before { content: 'SQLite'; } /* additional languages in org.el's org-babel-load-languages alist */ .org-src-container:has(pre.src-forth):before { content: 'Forth'; } .org-src-container:has(pre.src-io):before { content: 'IO'; } .org-src-container:has(pre.src-J):before { content: 'J'; } .org-src-container:has(pre.src-makefile):before { content: 'Makefile'; } .org-src-container:has(pre.src-maxima):before { content: 'Maxima'; } .org-src-container:has(pre.src-perl):before { content: 'Perl'; } .org-src-container:has(pre.src-picolisp):before { content: 'Pico Lisp'; } .org-src-container:has(pre.src-scala):before { content: 'Scala'; } .org-src-container:has(pre.src-shell):before { content: 'Shell Script'; } .org-src-container:has(pre.src-ebnf2ps):before { content: 'ebfn2ps'; } /* additional language identifiers per "defun org-babel-execute" in ob-*.el */ .org-src-container:has(pre.src-cpp):before { content: 'C++'; } .org-src-container:has(pre.src-abc):before { content: 'ABC'; } .org-src-container:has(pre.src-coq):before { content: 'Coq'; } .org-src-container:has(pre.src-groovy):before { content: 'Groovy'; } /* additional language identifiers from org-babel-shell-names in ob-shell.el: ob-shell is the only babel language using a lambda to put the execution function name together. */ .org-src-container:has(pre.src-bash):before { content: 'bash'; } .org-src-container:has(pre.src-csh):before { content: 'csh'; } .org-src-container:has(pre.src-ash):before { content: 'ash'; } .org-src-container:has(pre.src-dash):before { content: 'dash'; } .org-src-container:has(pre.src-ksh):before { content: 'ksh'; } .org-src-container:has(pre.src-mksh):before { content: 'mksh'; } .org-src-container:has(pre.src-posh):before { content: 'posh'; } /* Additional Emacs modes also supported by the LaTeX listings package */ .org-src-container:has(pre.src-ada):before { content: 'Ada'; } .org-src-container:has(pre.src-asm):before { content: 'Assembler'; } .org-src-container:has(pre.src-caml):before { content: 'Caml'; } .org-src-container:has(pre.src-delphi):before { content: 'Delphi'; } .org-src-container:has(pre.src-html):before { content: 'HTML'; } .org-src-container:has(pre.src-idl):before { content: 'IDL'; } .org-src-container:has(pre.src-mercury):before { content: 'Mercury'; } .org-src-container:has(pre.src-metapost):before { content: 'MetaPost'; } .org-src-container:has(pre.src-modula-2):before { content: 'Modula-2'; } .org-src-container:has(pre.src-pascal):before { content: 'Pascal'; } .org-src-container:has(pre.src-ps):before { content: 'PostScript'; } .org-src-container:has(pre.src-prolog):before { content: 'Prolog'; } .org-src-container:has(pre.src-simula):before { content: 'Simula'; } .org-src-container:has(pre.src-tcl):before { content: 'tcl'; } .org-src-container:has(pre.src-tex):before { content: 'TeX'; } .org-src-container:has(pre.src-plain-tex):before { content: 'Plain TeX'; } .org-src-container:has(pre.src-verilog):before { content: 'Verilog'; } .org-src-container:has(pre.src-vhdl):before { content: 'VHDL'; } .org-src-container:has(pre.src-xml):before { content: 'XML'; } .org-src-container:has(pre.src-nxml):before { content: 'XML'; } /* add a generic configuration mode; LaTeX export needs an additional (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */ .org-src-container:has(pre.src-conf):before { content: 'Configuration File'; } /* added manually after generation */ .org-src-container:has(pre.src-typescript):before { content: 'TypeScript'; } .org-src-container:has(pre.src-fsharp):before { content: 'F#'; } .org-src-container:has(pre.src-nix):before { content: 'nix'; } .org-src-container:has(pre.src-procfile):before { content: 'procfile'; } .org-src-container:has(pre.src-yaml):before { content: 'yaml'; } caption.t-above { caption-side: top; } caption.t-bottom { caption-side: bottom; } th.org-right { text-align: center; } th.org-left { text-align: center; } th.org-center { text-align: center; } td.org-right { text-align: right; } td.org-left { text-align: left; } td.org-center { text-align: center; } .footpara { display: inline; } .footdef { margin-bottom: 1em; } .figure { padding: 1em; } .figure p { text-align: center; } .equation-container { display: table; text-align: center; width: 100%; } .equation { vertical-align: middle; } .equation-label { display: table-cell; text-align: right; vertical-align: middle; } .inlinetask { padding: 10px; border: 2px solid gray; margin: 10px; background: #ffffcc; } .linenr { font-size: smaller } .code-highlighted { background-color: #ffff00; } .org-info-js_info-navigation { border-style: none; } #org-info-js_console-label { font-size: 10px; font-weight: bold; white-space: nowrap; } .org-info-js_search-highlight { background-color: #ffff00; color: #000000; font-weight: bold; } .org-svg { width: 90%; }
This is the contents of the MIT licensed `water.css` file that we're choosing to use, and which aren't already included above!
button { transition: background-color 0.1s linear, border-color 0.1s linear, color 0.1s linear, box-shadow 0.1s linear, transform 0.1s ease; transition: background-color var(--animation-duration) linear, border-color var(--animation-duration) linear, color var(--animation-duration) linear, box-shadow var(--animation-duration) linear, transform var(--animation-duration) ease; } @media (prefers-color-scheme: dark) { button { transition: background-color 0.1s linear, border-color 0.1s linear, color 0.1s linear, box-shadow 0.1s linear, transform 0.1s ease; transition: background-color var(--animation-duration) linear, border-color var(--animation-duration) linear, color var(--animation-duration) linear, box-shadow var(--animation-duration) linear, transform var(--animation-duration) ease; } } input { transition: background-color 0.1s linear, border-color 0.1s linear, color 0.1s linear, box-shadow 0.1s linear, transform 0.1s ease; transition: background-color var(--animation-duration) linear, border-color var(--animation-duration) linear, color var(--animation-duration) linear, box-shadow var(--animation-duration) linear, transform var(--animation-duration) ease; } @media (prefers-color-scheme: dark) { input { transition: background-color 0.1s linear, border-color 0.1s linear, color 0.1s linear, box-shadow 0.1s linear, transform 0.1s ease; transition: background-color var(--animation-duration) linear, border-color var(--animation-duration) linear, color var(--animation-duration) linear, box-shadow var(--animation-duration) linear, transform var(--animation-duration) ease; } } textarea { transition: background-color 0.1s linear, border-color 0.1s linear, color 0.1s linear, box-shadow 0.1s linear, transform 0.1s ease; transition: background-color var(--animation-duration) linear, border-color var(--animation-duration) linear, color var(--animation-duration) linear, box-shadow var(--animation-duration) linear, transform var(--animation-duration) ease; } @media (prefers-color-scheme: dark) { textarea { transition: background-color 0.1s linear, border-color 0.1s linear, color 0.1s linear, box-shadow 0.1s linear, transform 0.1s ease; transition: background-color var(--animation-duration) linear, border-color var(--animation-duration) linear, color var(--animation-duration) linear, box-shadow var(--animation-duration) linear, transform var(--animation-duration) ease; } } h1 { font-size: 2.2em; margin-top: 0; } h1, h2, h3, h4, h5, h6 { margin-bottom: 12px; margin-top: 24px; } h1 { color: #000; color: var(--text-bright); } @media (prefers-color-scheme: dark) { h1 { color: #fff; color: var(--text-bright); } } h2 { color: #000; color: var(--text-bright); } @media (prefers-color-scheme: dark) { h2 { color: #fff; color: var(--text-bright); } } h3 { color: #000; color: var(--text-bright); } @media (prefers-color-scheme: dark) { h3 { color: #fff; color: var(--text-bright); } } h4 { color: #000; color: var(--text-bright); } @media (prefers-color-scheme: dark) { h4 { color: #fff; color: var(--text-bright); } } h5 { color: #000; color: var(--text-bright); } @media (prefers-color-scheme: dark) { h5 { color: #fff; color: var(--text-bright); } } h6 { color: #000; color: var(--text-bright); } @media (prefers-color-scheme: dark) { h6 { color: #fff; color: var(--text-bright); } } strong { color: #000; color: var(--text-bright); } @media (prefers-color-scheme: dark) { strong { color: #fff; color: var(--text-bright); } } h1, h2, h3, h4, h5, h6, b, strong, th { font-weight: 600; } q::before { content: none; } q::after { content: none; } blockquote { border-left: 4px solid #0096bfab; border-left: 4px solid var(--focus); margin: 1.5em 0; padding: 0.5em 1em; } @media (prefers-color-scheme: dark) { blockquote { border-left: 4px solid #0096bfab; border-left: 4px solid var(--focus); } } q { border-left: 4px solid #0096bfab; border-left: 4px solid var(--focus); margin: 1.5em 0; padding: 0.5em 1em; font-style: italic; } @media (prefers-color-scheme: dark) { q { border-left: 4px solid #0096bfab; border-left: 4px solid var(--focus); } } blockquote > footer { font-style: normal; border: 0; } blockquote cite { font-style: normal; } address { font-style: normal; } a[href^='mailto\:']::before { content: '📧 '; } a[href^='tel\:']::before { content: '📞 '; } a[href^='sms\:']::before { content: '💬 '; } mark { background-color: #ff0; background-color: var(--highlight); border-radius: 2px; padding: 0 2px 0 2px; color: #000; } @media (prefers-color-scheme: dark) { mark { background-color: #efdb43; background-color: var(--highlight); } } a > code, a > strong { color: inherit; } button, select, input[type='submit'], input[type='reset'], input[type='button'], input[type='checkbox'], input[type='range'], input[type='radio'] { cursor: pointer; } input, select { display: block; } [type='checkbox'], [type='radio'] { display: initial; } input { color: #1d1d1d; color: var(--form-text); background-color: #efefef; background-color: var(--background); font-family: inherit; font-size: inherit; margin-right: 6px; margin-bottom: 6px; padding: 10px; border: none; border-radius: 6px; outline: none; } @media (prefers-color-scheme: dark) { input { background-color: #161f27; background-color: var(--background); } } @media (prefers-color-scheme: dark) { input { color: #fff; color: var(--form-text); } } button { color: #1d1d1d; color: var(--form-text); background-color: #efefef; background-color: var(--background); font-family: inherit; font-size: inherit; margin-right: 6px; margin-bottom: 6px; padding: 10px; border: none; border-radius: 6px; outline: none; } @media (prefers-color-scheme: dark) { button { background-color: #161f27; background-color: var(--background); } } @media (prefers-color-scheme: dark) { button { color: #fff; color: var(--form-text); } } textarea { color: #1d1d1d; color: var(--form-text); background-color: #efefef; background-color: var(--background); font-family: inherit; font-size: inherit; margin-right: 6px; margin-bottom: 6px; padding: 10px; border: none; border-radius: 6px; outline: none; } @media (prefers-color-scheme: dark) { textarea { background-color: #161f27; background-color: var(--background); } } @media (prefers-color-scheme: dark) { textarea { color: #fff; color: var(--form-text); } } select { color: #1d1d1d; color: var(--form-text); background-color: #efefef; background-color: var(--background); font-family: inherit; font-size: inherit; margin-right: 6px; margin-bottom: 6px; padding: 10px; border: none; border-radius: 6px; outline: none; } @media (prefers-color-scheme: dark) { select { background-color: #161f27; background-color: var(--background); } } @media (prefers-color-scheme: dark) { select { color: #fff; color: var(--form-text); } } button { background-color: #d0cfcf; background-color: var(--button-base); padding-right: 30px; padding-left: 30px; } @media (prefers-color-scheme: dark) { button { background-color: #0c151c; background-color: var(--button-base); } } input[type='submit'] { background-color: #d0cfcf; background-color: var(--button-base); padding-right: 30px; padding-left: 30px; } @media (prefers-color-scheme: dark) { input[type='submit'] { background-color: #0c151c; background-color: var(--button-base); } } input[type='reset'] { background-color: #d0cfcf; background-color: var(--button-base); padding-right: 30px; padding-left: 30px; } @media (prefers-color-scheme: dark) { input[type='reset'] { background-color: #0c151c; background-color: var(--button-base); } } input[type='button'] { background-color: #d0cfcf; background-color: var(--button-base); padding-right: 30px; padding-left: 30px; } @media (prefers-color-scheme: dark) { input[type='button'] { background-color: #0c151c; background-color: var(--button-base); } } button:hover { background: #9b9b9b; background: var(--button-hover); } @media (prefers-color-scheme: dark) { button:hover { background: #040a0f; background: var(--button-hover); } } input[type='submit']:hover { background: #9b9b9b; background: var(--button-hover); } @media (prefers-color-scheme: dark) { input[type='submit']:hover { background: #040a0f; background: var(--button-hover); } } input[type='reset']:hover { background: #9b9b9b; background: var(--button-hover); } @media (prefers-color-scheme: dark) { input[type='reset']:hover { background: #040a0f; background: var(--button-hover); } } input[type='button']:hover { background: #9b9b9b; background: var(--button-hover); } @media (prefers-color-scheme: dark) { input[type='button']:hover { background: #040a0f; background: var(--button-hover); } } input[type='color'] { min-height: 2rem; padding: 8px; cursor: pointer; } input[type='checkbox'], input[type='radio'] { height: 1em; width: 1em; } input[type='radio'] { border-radius: 100%; } input { vertical-align: top; } label { vertical-align: middle; margin-bottom: 4px; display: inline-block; } input:not([type='checkbox']):not([type='radio']), input[type='range'], select, button, textarea { -webkit-appearance: none; } textarea { display: block; margin-right: 0; box-sizing: border-box; resize: vertical; } textarea:not([cols]) { width: 100%; } textarea:not([rows]) { min-height: 40px; height: 140px; } select { background: #efefef url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23161f27'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50% / 12px no-repeat; background: var(--background) var(--select-arrow) calc(100% - 12px) 50% / 12px no-repeat; padding-right: 35px; } @media (prefers-color-scheme: dark) { select { background: #161f27 url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50% / 12px no-repeat; background: var(--background) var(--select-arrow) calc(100% - 12px) 50% / 12px no-repeat; } } @media (prefers-color-scheme: dark) { select { background: #161f27 url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50% / 12px no-repeat; background: var(--background) var(--select-arrow) calc(100% - 12px) 50% / 12px no-repeat; } } @media (prefers-color-scheme: dark) { select { background: #161f27 url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50% / 12px no-repeat; background: var(--background) var(--select-arrow) calc(100% - 12px) 50% / 12px no-repeat; } } @media (prefers-color-scheme: dark) { select { background: #161f27 url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50% / 12px no-repeat; background: var(--background) var(--select-arrow) calc(100% - 12px) 50% / 12px no-repeat; } } select::-ms-expand { display: none; } select[multiple] { padding-right: 10px; background-image: none; overflow-y: auto; } input:focus { box-shadow: 0 0 0 2px #0096bfab; box-shadow: 0 0 0 2px var(--focus); } @media (prefers-color-scheme: dark) { input:focus { box-shadow: 0 0 0 2px #0096bfab; box-shadow: 0 0 0 2px var(--focus); } } select:focus { box-shadow: 0 0 0 2px #0096bfab; box-shadow: 0 0 0 2px var(--focus); } @media (prefers-color-scheme: dark) { select:focus { box-shadow: 0 0 0 2px #0096bfab; box-shadow: 0 0 0 2px var(--focus); } } button:focus { box-shadow: 0 0 0 2px #0096bfab; box-shadow: 0 0 0 2px var(--focus); } @media (prefers-color-scheme: dark) { button:focus { box-shadow: 0 0 0 2px #0096bfab; box-shadow: 0 0 0 2px var(--focus); } } textarea:focus { box-shadow: 0 0 0 2px #0096bfab; box-shadow: 0 0 0 2px var(--focus); } @media (prefers-color-scheme: dark) { textarea:focus { box-shadow: 0 0 0 2px #0096bfab; box-shadow: 0 0 0 2px var(--focus); } } input[type='checkbox']:active, input[type='radio']:active, input[type='submit']:active, input[type='reset']:active, input[type='button']:active, input[type='range']:active, button:active { transform: translateY(2px); } input:disabled, select:disabled, button:disabled, textarea:disabled { cursor: not-allowed; opacity: 0.5; } ::-moz-placeholder { color: #949494; color: var(--form-placeholder); } :-ms-input-placeholder { color: #949494; color: var(--form-placeholder); } ::-ms-input-placeholder { color: #949494; color: var(--form-placeholder); } ::placeholder { color: #949494; color: var(--form-placeholder); } @media (prefers-color-scheme: dark) { ::-moz-placeholder { color: #a9a9a9; color: var(--form-placeholder); } :-ms-input-placeholder { color: #a9a9a9; color: var(--form-placeholder); } ::-ms-input-placeholder { color: #a9a9a9; color: var(--form-placeholder); } ::placeholder { color: #a9a9a9; color: var(--form-placeholder); } } fieldset { border: 1px #0096bfab solid; border: 1px var(--focus) solid; border-radius: 6px; margin: 0; margin-bottom: 12px; padding: 10px; } @media (prefers-color-scheme: dark) { fieldset { border: 1px #0096bfab solid; border: 1px var(--focus) solid; } } legend { font-size: 0.9em; font-weight: 600; } input[type='range'] { margin: 10px 0; padding: 10px 0; background: transparent; } input[type='range']:focus { outline: none; } input[type='range']::-webkit-slider-runnable-track { width: 100%; height: 9.5px; -webkit-transition: 0.2s; transition: 0.2s; background: #efefef; background: var(--background); border-radius: 3px; } @media (prefers-color-scheme: dark) { input[type='range']::-webkit-slider-runnable-track { background: #161f27; background: var(--background); } } input[type='range']::-webkit-slider-thumb { box-shadow: 0 1px 1px #000, 0 0 1px #0d0d0d; height: 20px; width: 20px; border-radius: 50%; background: #dbdbdb; background: var(--border); -webkit-appearance: none; margin-top: -7px; } @media (prefers-color-scheme: dark) { input[type='range']::-webkit-slider-thumb { background: #526980; background: var(--border); } } input[type='range']:focus::-webkit-slider-runnable-track { background: #efefef; background: var(--background); } @media (prefers-color-scheme: dark) { input[type='range']:focus::-webkit-slider-runnable-track { background: #161f27; background: var(--background); } } input[type='range']::-moz-range-track { width: 100%; height: 9.5px; -moz-transition: 0.2s; transition: 0.2s; background: #efefef; background: var(--background); border-radius: 3px; } @media (prefers-color-scheme: dark) { input[type='range']::-moz-range-track { background: #161f27; background: var(--background); } } input[type='range']::-moz-range-thumb { box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d; height: 20px; width: 20px; border-radius: 50%; background: #dbdbdb; background: var(--border); } @media (prefers-color-scheme: dark) { input[type='range']::-moz-range-thumb { background: #526980; background: var(--border); } } input[type='range']::-ms-track { width: 100%; height: 9.5px; background: transparent; border-color: transparent; border-width: 16px 0; color: transparent; } input[type='range']::-ms-fill-lower { background: #efefef; background: var(--background); border: 0.2px solid #010101; border-radius: 3px; box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d; } @media (prefers-color-scheme: dark) { input[type='range']::-ms-fill-lower { background: #161f27; background: var(--background); } } input[type='range']::-ms-fill-upper { background: #efefef; background: var(--background); border: 0.2px solid #010101; border-radius: 3px; box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d; } @media (prefers-color-scheme: dark) { input[type='range']::-ms-fill-upper { background: #161f27; background: var(--background); } } input[type='range']::-ms-thumb { box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d; border: 1px solid #000; height: 20px; width: 20px; border-radius: 50%; background: #dbdbdb; background: var(--border); } @media (prefers-color-scheme: dark) { input[type='range']::-ms-thumb { background: #526980; background: var(--border); } } input[type='range']:focus::-ms-fill-lower { background: #efefef; background: var(--background); } @media (prefers-color-scheme: dark) { input[type='range']:focus::-ms-fill-lower { background: #161f27; background: var(--background); } } input[type='range']:focus::-ms-fill-upper { background: #efefef; background: var(--background); } @media (prefers-color-scheme: dark) { input[type='range']:focus::-ms-fill-upper { background: #161f27; background: var(--background); } } a { text-decoration: none; color: #0076d1; color: var(--links); } @media (prefers-color-scheme: dark) { a { color: #41adff; color: var(--links); } } a:hover { text-decoration: underline; } code { background: #efefef; background: var(--background); color: #000; color: var(--code); padding: 2.5px 5px; border-radius: 6px; } @media (prefers-color-scheme: dark) { code { color: #ffbe85; color: var(--code); } } @media (prefers-color-scheme: dark) { code { background: #161f27; background: var(--background); } } samp { background: #efefef; background: var(--background); color: #000; color: var(--code); padding: 2.5px 5px; border-radius: 6px; font-size: 1em; } @media (prefers-color-scheme: dark) { samp { color: #ffbe85; color: var(--code); } } @media (prefers-color-scheme: dark) { samp { background: #161f27; background: var(--background); } } time { background: #efefef; background: var(--background); color: #000; color: var(--code); padding: 2.5px 5px; border-radius: 6px; font-size: 1em; } @media (prefers-color-scheme: dark) { time { color: #ffbe85; color: var(--code); } } @media (prefers-color-scheme: dark) { time { background: #161f27; background: var(--background); } } pre > code { padding: 10px; display: block; overflow-x: auto; } var { color: #39a33c; color: var(--variable); font-style: normal; font-family: monospace; } @media (prefers-color-scheme: dark) { var { color: #d941e2; color: var(--variable); } } kbd { background: #efefef; background: var(--background); border: 1px solid #dbdbdb; border: 1px solid var(--border); border-radius: 2px; color: #363636; color: var(--text-main); padding: 2px 4px 2px 4px; } @media (prefers-color-scheme: dark) { kbd { color: #dbdbdb; color: var(--text-main); } } @media (prefers-color-scheme: dark) { kbd { border: 1px solid #526980; border: 1px solid var(--border); } } @media (prefers-color-scheme: dark) { kbd { background: #161f27; background: var(--background); } } img, video { max-width: 100%; height: auto; } hr { border: none; border-top: 1px solid #dbdbdb; border-top: 1px solid var(--border); } @media (prefers-color-scheme: dark) { hr { border-top: 1px solid #526980; border-top: 1px solid var(--border); } } table { border-collapse: collapse; margin-bottom: 10px; width: 100%; table-layout: fixed; } table caption { text-align: left; } td, th { padding: 6px; text-align: left; vertical-align: top; word-wrap: break-word; } thead { border-bottom: 1px solid #dbdbdb; border-bottom: 1px solid var(--border); } @media (prefers-color-scheme: dark) { thead { border-bottom: 1px solid #526980; border-bottom: 1px solid var(--border); } } tfoot { border-top: 1px solid #dbdbdb; border-top: 1px solid var(--border); } @media (prefers-color-scheme: dark) { tfoot { border-top: 1px solid #526980; border-top: 1px solid var(--border); } } tbody tr:nth-child(even) { background-color: #efefef; background-color: var(--background); } @media (prefers-color-scheme: dark) { tbody tr:nth-child(even) { background-color: #161f27; background-color: var(--background); } } tbody tr:nth-child(even) button { background-color: #f7f7f7; background-color: var(--background-alt); } @media (prefers-color-scheme: dark) { tbody tr:nth-child(even) button { background-color: #1a242f; background-color: var(--background-alt); } } tbody tr:nth-child(even) button:hover { background-color: #fff; background-color: var(--background-body); } @media (prefers-color-scheme: dark) { tbody tr:nth-child(even) button:hover { background-color: #202b38; background-color: var(--background-body); } } ::-webkit-scrollbar { height: 10px; width: 10px; } ::-webkit-scrollbar-track { background: #efefef; background: var(--background); border-radius: 6px; } @media (prefers-color-scheme: dark) { ::-webkit-scrollbar-track { background: #161f27; background: var(--background); } } ::-webkit-scrollbar-thumb { background: rgb(170, 170, 170); background: var(--scrollbar-thumb); border-radius: 6px; } @media (prefers-color-scheme: dark) { ::-webkit-scrollbar-thumb { background: #040a0f; background: var(--scrollbar-thumb); } } @media (prefers-color-scheme: dark) { ::-webkit-scrollbar-thumb { background: #040a0f; background: var(--scrollbar-thumb); } } ::-webkit-scrollbar-thumb:hover { background: #9b9b9b; background: var(--scrollbar-thumb-hover); } @media (prefers-color-scheme: dark) { ::-webkit-scrollbar-thumb:hover { background: rgb(0, 0, 0); background: var(--scrollbar-thumb-hover); } } @media (prefers-color-scheme: dark) { ::-webkit-scrollbar-thumb:hover { background: rgb(0, 0, 0); background: var(--scrollbar-thumb-hover); } } ::-moz-selection { background-color: #9e9e9e; background-color: var(--selection); color: #000; color: var(--text-bright); } ::selection { background-color: #9e9e9e; background-color: var(--selection); color: #000; color: var(--text-bright); } @media (prefers-color-scheme: dark) { ::-moz-selection { color: #fff; color: var(--text-bright); } ::selection { color: #fff; color: var(--text-bright); } } @media (prefers-color-scheme: dark) { ::-moz-selection { background-color: #1c76c5; background-color: var(--selection); } ::selection { background-color: #1c76c5; background-color: var(--selection); } } details { display: flex; flex-direction: column; align-items: flex-start; background-color: #f7f7f7; background-color: var(--background-alt); padding: 10px 10px 0; margin: 1em 0; border-radius: 6px; overflow: hidden; } @media (prefers-color-scheme: dark) { details { background-color: #1a242f; background-color: var(--background-alt); } } details[open] { padding: 10px; } details > :last-child { margin-bottom: 0; } details[open] summary { margin-bottom: 10px; } summary { display: list-item; background-color: #efefef; background-color: var(--background); padding: 10px; margin: -10px -10px 0; cursor: pointer; outline: none; } @media (prefers-color-scheme: dark) { summary { background-color: #161f27; background-color: var(--background); } } summary:hover, summary:focus { text-decoration: underline; } details > :not(summary) { margin-top: 0; } summary::-webkit-details-marker { color: #363636; color: var(--text-main); } @media (prefers-color-scheme: dark) { summary::-webkit-details-marker { color: #dbdbdb; color: var(--text-main); } } dialog { background-color: #f7f7f7; background-color: var(--background-alt); color: #363636; color: var(--text-main); border: none; border-radius: 6px; border-color: #dbdbdb; border-color: var(--border); padding: 10px 30px; } @media (prefers-color-scheme: dark) { dialog { border-color: #526980; border-color: var(--border); } } @media (prefers-color-scheme: dark) { dialog { color: #dbdbdb; color: var(--text-main); } } @media (prefers-color-scheme: dark) { dialog { background-color: #1a242f; background-color: var(--background-alt); } } dialog > header:first-child { background-color: #efefef; background-color: var(--background); border-radius: 6px 6px 0 0; margin: -10px -30px 10px; padding: 10px; text-align: center; } @media (prefers-color-scheme: dark) { dialog > header:first-child { background-color: #161f27; background-color: var(--background); } } dialog::-webkit-backdrop { background: #0000009c; -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); } dialog::backdrop { background: #0000009c; -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); } footer { border-top: 1px solid #dbdbdb; border-top: 1px solid var(--border); padding-top: 10px; color: #70777f; color: var(--text-muted); } @media (prefers-color-scheme: dark) { footer { color: #a9b1ba; color: var(--text-muted); } } @media (prefers-color-scheme: dark) { footer { border-top: 1px solid #526980; border-top: 1px solid var(--border); } } body > footer { margin-top: 40px; } @media print { body, pre, code, summary, details, button, input, textarea { background-color: #fff; } button, input, textarea { border: 1px solid #000; } body, h1, h2, h3, h4, h5, h6, pre, code, button, input, textarea, footer, summary, strong { color: #000; } summary::marker { color: #000; } summary::-webkit-details-marker { color: #000; } tbody tr:nth-child(even) { background-color: #f2f2f2; } a { color: #00f; text-decoration: underline; } }
And I think that's all we need for now.