/* Manichem: an MS-DOS screen in VGA text mode, hand-written, no framework.

   Sections:
   1. Fonts           4. Page parts: prompt, listings, errors
   2. Colors, base    5. Posts: Markdown output, code, media
   3. Header, menu    6. Forms, footer

   The colors are the VGA text-mode palette (the 16 colors every DOS program
   had), named in the custom properties below so they're easy to change. */


/* ---- 1. Fonts ---------------------------------------------------------------
   The VGA font (site name, nav, headings) is a pixel font, 8x16 pixels per
   character at 16px. It's only used at 16px or exact multiples (32px), so its
   pixels land on whole screen pixels and stay sharp. IBM Plex Mono is for
   everything you read. Both are served from static/fonts/ (licenses there). */

@font-face {
  font-family: "VGA";
  src: url("../fonts/WebPlus_IBM_VGA_8x16.woff") format("woff");
  font-display: swap; /* show text in the fallback font until this one arrives */
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/ibm-plex-mono-latin-400-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/ibm-plex-mono-latin-700-normal.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Mono";
  src: url("../fonts/ibm-plex-mono-latin-700-italic.woff2") format("woff2");
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}


/* ---- 2. Colors and base ------------------------------------------------------ */

:root {
  /* VGA palette. DOS's own dark gray (#555) is too faint for text on black,
     so readable secondary text uses a lighter gray, --dim. */
  --black: #000000;
  --blue: #0000aa;
  --gray: #aaaaaa; /* "light gray": normal text */
  --dim: #808080; /* secondary text: dates, prompt line */
  --line: #555555; /* "dark gray": rules and borders only */
  --white: #ffffff; /* "bright white": headings, bold */
  --cyan: #55ffff; /* links */
  --yellow: #ffff55; /* inline code, highlights, <DRAFT> */

  --vga: "VGA", "IBM Plex Mono", ui-monospace, monospace;
  --mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Menlo, Consolas, monospace;

  color-scheme: dark;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--black);
  -webkit-text-size-adjust: 100%;
}

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
  background: var(--black);
  color: var(--gray);
  font: 16px/1.6 var(--mono);
}

/* One 80-column screen, centered. Plex Mono characters are 0.6em wide, so
   80 of them at 16px take 48rem; plus 1rem of padding on each side. */
.screen {
  width: 100%;
  max-width: 50rem;
  margin-inline: auto;
  padding-inline: 1rem;
}

main {
  flex: 1;
  padding-block: 1.5rem 3rem;
}

p,
ul,
ol,
table,
blockquote {
  margin: 0 0 1rem;
}

/* A list inside a list item shouldn't add a gap before the next item. */
li > ul,
li > ol {
  margin-bottom: 0;
}

a {
  color: var(--cyan);
}

/* Hovered links turn to reverse video, like a highlighted menu item. */
a:hover {
  background: var(--cyan);
  color: var(--black);
  text-decoration: none;
}

strong,
b {
  color: var(--white);
}

::selection {
  background: var(--gray);
  color: var(--black);
}

:focus-visible {
  outline: 2px solid var(--yellow);
  outline-offset: 2px;
}

/* Headings in the VGA font. Page titles are double size, the way a VT100
   could print a line in double-width, double-height characters. */
h1,
h2,
h3,
h4 {
  margin: 2rem 0 0.75rem;
  color: var(--white);
  font-family: var(--vga);
  font-size: 16px;
  font-weight: normal;
  line-height: 1.25;
}

h1 {
  margin-top: 0;
  font-size: 32px;
}

/* Text that's only there for screen readers. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* "Skip to content": hidden until someone tabs to it with the keyboard. */
.skip-link {
  position: absolute;
  top: 0.5rem;
  left: -100vw;
  z-index: 20;
  padding: 0.25rem 0.5rem;
  background: var(--gray);
  color: var(--black);
}

.skip-link:focus {
  left: 0.5rem;
}


/* ---- 3. Header and the Recent menu --------------------------------------------- */

.site-header {
  border-bottom: 1px solid var(--line);
}

.site-nav {
  position: relative; /* anchors the menu on phones, see below */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  padding-block: 0.75rem;
  font-family: var(--vga);
}

.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-name {
  color: var(--white);
  text-decoration: none;
  text-transform: uppercase;
}

.site-nav > ul > li > a,
.menu summary {
  padding: 0 0.25rem;
  color: var(--gray);
  text-decoration: none;
}

/* The page you're on, and an open menu: reverse video. */
.site-nav a[aria-current="page"],
.menu[open] summary {
  background: var(--gray);
  color: var(--black);
}

/* Listed again here because the gray rule above outranks the plain
   a:hover rule, which would leave gray text on the cyan bar. */
.site-nav > ul > li > a:hover,
.menu summary:hover {
  background: var(--cyan);
  color: var(--black);
}

/* "Recent" is a <details> element: the browser opens and closes it, no
   JavaScript needed. Its default triangle is swapped for a DOS-style one. */
.menu {
  position: relative;
}

.menu summary {
  cursor: pointer;
  list-style: none;
}

.menu summary::-webkit-details-marker {
  display: none;
}

.menu summary::after {
  content: " \25BC"; /* ▼ */
}

.menu ul {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 10;
  display: block;
  width: max-content;
  min-width: 18rem;
  max-width: min(28rem, calc(100vw - 2rem));
  padding: 0.25rem 0;
  background: var(--black);
  border: 3px double var(--gray); /* the ═ double line of DOS menus */
  font-family: var(--mono);
}

.menu li a,
.menu-empty {
  display: block;
  padding: 0.25rem 1rem;
  color: var(--gray);
  text-decoration: none;
}

.menu li a:hover {
  background: var(--cyan);
  color: var(--black);
}

.menu-divider {
  margin-top: 0.25rem;
  padding-top: 0.25rem;
  border-top: 1px solid var(--line);
}

/* On phones the menu spans the screen under the header, instead of hanging
   off "Recent" where it could run past the left edge. */
@media (max-width: 40rem) {
  .menu {
    position: static;
  }

  .menu ul {
    left: 1rem;
    right: 1rem;
    width: auto;
    min-width: 0;
    max-width: none;
  }
}


/* ---- 4. Page parts: prompt line, listings, errors ------------------------------ */

/* The DOS command that "made" the page, e.g. C:\MANICHEM>DIR POSTS */
.prompt {
  margin-bottom: 1.5rem;
  color: var(--dim);
  font-family: var(--vga);
  overflow-wrap: anywhere;
}

.tagline {
  margin-bottom: 2.5rem;
}

/* <DRAFT>, like DIR's <DIR> marker. Only ever seen while developing. */
.draft {
  color: var(--yellow);
  white-space: nowrap;
}

.draft-note {
  color: var(--dim);
}

/* " Directory of C:\MANICHEM\POSTS" (DIR starts it with a space) */
.dir-heading {
  margin: 0 0 1rem;
  color: var(--gray);
  white-space: pre-wrap;
}

/* DIR-style listings: plain columns, no borders. Long titles wrap inside
   their own column, so they stay aligned under the title. */
.dir {
  border-collapse: collapse;
  margin-bottom: 0.5rem;
}

.dir td {
  padding: 0 2ch 0.4rem 0;
  vertical-align: top;
}

.dir td:last-child {
  padding-right: 0;
}

.dir td:first-child,
.dir-number {
  white-space: nowrap;
}

.dir-number {
  text-align: right;
}

.dir-note {
  color: var(--dim);
}

/* "  2 file(s)   3,307 words": spaces are kept, as in DIR's own output. */
.dir-summary {
  white-space: pre-wrap;
}

.dos-error,
.dos-question {
  color: var(--white);
  font-family: var(--vga);
}

/* Abort, Retry, Ignore? as links: the letter, then what it does. */
.choices {
  padding: 0;
  list-style: none;
}

.choices a {
  text-decoration: none;
}

.choice-key {
  display: inline-block;
  width: 3ch;
  font-family: var(--vga);
}


/* ---- 5. Posts ----------------------------------------------------------------- */

.post-header {
  margin-bottom: 2rem;
}

.post-meta {
  margin: 0;
  color: var(--dim);
}

/* Table of contents in a double-line box, like a DOS dialog. */
.toc {
  margin-bottom: 2rem;
  padding: 0.75rem 1.25rem;
  border: 3px double var(--gray);
}

.toc-title {
  margin: 0 0 0.5rem;
  color: var(--white);
  font-family: var(--vga);
  text-transform: uppercase;
}

.toc ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.toc .toc-level-3 {
  padding-left: 2ch;
}

/* Everything inside .post-body comes from the Markdown renderer. */
.post-body {
  overflow-wrap: break-word; /* long URLs wrap instead of widening the page */
}

.post-body h2 {
  padding-bottom: 0.25rem;
  border-bottom: 1px solid var(--line);
}

.post-body h4 {
  color: var(--gray);
}

/* Leave a little room above a heading when a #link jumps to it. */
.post-body :is(h2, h3, h4) {
  scroll-margin-top: 1rem;
}

/* The "#" after each heading, to copy a link to that section. It only shows
   on hover or keyboard focus, so it doesn't clutter the page. */
.post-body .header-anchor {
  margin-left: 1ch;
  color: var(--dim);
  text-decoration: none;
  opacity: 0;
}

.post-body :is(h2, h3, h4):hover .header-anchor,
.post-body .header-anchor:focus {
  opacity: 1;
}

/* Inline `code` in yellow, the color of text in a Turbo C editor. */
.post-body :not(pre) > code,
.draft-note code {
  color: var(--yellow);
  font-family: var(--mono);
}

/* Code blocks. Each ``` block is a <pre class="highlight">; its colors
   come from pygments.css. */
.post-body pre {
  margin: 0 0 1.5rem;
  padding: 1rem;
  overflow-x: auto; /* long lines scroll inside the box, not the page */
  font: 15px/1.5 var(--mono);
  tab-size: 4; /* browsers default to 8, too wide for C */
}

.post-body pre:not(.highlight) {
  border: 1px solid var(--line); /* a raw <pre> typed as HTML */
}

/* ``` blocks as Turbo C++ editor windows: blue (from pygments.css), a
   double-line frame, and the language as the window title, sitting on the
   top border like " C " in ═══ C ═══. Because the title hangs over the
   border, the window itself can't clip its contents, so the <code> inside
   does the sideways scrolling instead. */
.post-body pre.highlight {
  position: relative;
  margin-top: 1.75rem;
  padding: 0;
  overflow: visible;
  border: 3px double var(--gray);
}

.post-body pre.highlight > code {
  display: block;
  padding: 1rem 1rem 0.75rem;
  overflow-x: auto;
}

.post-body pre.highlight[data-lang]::before {
  content: attr(data-lang);
  position: absolute;
  top: -7px; /* centered on the 3px border: half of 16px, minus 1.5px */
  left: 50%;
  transform: translateX(-50%);
  padding: 0 1ch;
  background: var(--blue);
  color: var(--white);
  font: 16px/1 var(--vga);
  text-transform: uppercase;
}

.post-body img,
.post-body video {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 1.5rem auto;
}

.post-body audio {
  display: block;
  width: 100%;
  margin: 1.5rem 0;
}

.post-body blockquote {
  margin: 1.5rem 0;
  padding-left: 2ch;
  border-left: 2px solid var(--line);
}

.post-body blockquote > :last-child {
  margin-bottom: 0;
}

.post-body hr {
  margin: 2.5rem 0;
  border: 0;
  border-top: 1px solid var(--line);
}

/* Tables scroll sideways inside their box when they're wider than the
   column (on phones), instead of widening the whole page. */
.post-body .table-scroll {
  margin-bottom: 1.5rem;
  overflow-x: auto;
}

.post-body table {
  width: 100%;
  margin: 0;
  border-collapse: collapse;
}

.post-body th,
.post-body td {
  padding: 0.25rem 1ch;
  border: 1px solid var(--line);
  text-align: left;
}

.post-body th {
  color: var(--white);
}

/* Long code in a table cell may break anywhere, so most tables still fit. */
.post-body td code {
  overflow-wrap: anywhere;
}

/* "- [x]" task lists: checkboxes instead of bullets. */
.post-body .task-list-item {
  list-style: none;
}

.post-body .task-list-item-checkbox {
  margin: 0 1ch 0 -2.5ch;
  accent-color: var(--gray);
}

.post-body details > summary {
  color: var(--white);
  cursor: pointer;
}

/* Footnotes, collected at the bottom of the post. */
.post-body .footnotes {
  color: var(--dim);
  font-size: 14px;
}

.post-body .footnotes-sep {
  margin: 3rem 0 1rem;
}

/* Keys like <kbd>Ctrl</kbd>: reverse video, as on a DOS help screen. */
kbd {
  padding: 0 0.4ch;
  background: var(--gray);
  color: var(--black);
  font-family: var(--mono);
}

/* Matched words in search results, and ==highlights== if ever used. */
mark {
  background: var(--yellow);
  color: var(--black);
}

/* "< Older: ..." and "Newer: ... >" under a post. */
.post-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 3rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}

.post-nav-newer {
  margin-left: auto; /* stays on the right even without an "Older" link */
  text-align: right;
}

.all-posts {
  margin: 1.5rem 0 0;
}


/* ---- 6. Search form, results, footer ------------------------------------------- */

.search-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1ch;
  margin-bottom: 2rem;
  font-family: var(--vga);
}

.search-form input {
  flex: 1 1 16rem;
  min-width: 0;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--gray);
  border-radius: 0;
  background: var(--black);
  color: var(--white);
  font: 16px var(--mono);
}

.search-form button {
  padding: 0.25rem 1ch;
  border: 0;
  border-radius: 0;
  background: var(--gray);
  color: var(--black);
  font: 16px var(--vga);
  cursor: pointer;
}

.search-form button:hover {
  background: var(--white);
}

/* FIND's output: "---------- FILE.MD", then what matched. */
.find-result {
  margin-bottom: 1.5rem;
}

.find-result p {
  margin: 0;
}

.find-file {
  color: var(--dim);
  font-family: var(--vga);
  overflow-wrap: anywhere;
}

.site-footer {
  border-top: 1px solid var(--line);
  color: var(--dim);
  font-size: 14px;
}

.site-footer p {
  margin-block: 0; /* not `margin: 0`, which would undo .screen's centering */
  padding-block: 1rem;
}

.site-footer a {
  color: var(--dim);
}

.site-footer a:hover {
  background: var(--dim);
  color: var(--black);
}
