@charset "utf-8";

/* ===========================================================================
   make.mistermills.tech

   Built on the same cream / umber / burnt-orange palette as mistermills.tech,
   but laid out for reading rather than for play: a fixed section menu on the
   left, a measured column of text in the middle, and the headings of the
   current page down the right.

   Sections, in order:
     1. Tokens          colours, type, spacing
     2. Reset & base
     3. Top bar
     4. Shell           the three-column frame
     5. Sidebar
     6. Article furniture   breadcrumbs, title block, meta
     7. Prose           everything markdown can produce
     8. Steps           the numbered-instruction treatment
     9. Callouts
    10. Code
    11. Cards & paging
    12. Right rail
    13. Search
    14. Footer
    15. Responsive
    16. Print
   ======================================================================== */


/* ---- 1. Tokens -------------------------------------------------------- */

:root {
  /* Light — the default, and the one that matches the main site. */
  --bg:          #F4EBDC;
  --bg-sunk:     #EAE0CD;
  --surface:     #FBF6EC;
  --surface-2:   #EFE4D0;

  --ink:         #2E2018;
  --ink-2:       #6A5641;
  --ink-3:       #927C63;

  --umber:       #8C6642;
  --accent:      #D4632C;
  --link:        #A8481C;

  --rule:        rgba(52, 36, 26, 0.14);
  --rule-strong: rgba(52, 36, 26, 0.28);
  --shadow:      0 1px 2px rgba(52, 36, 26, .05), 0 8px 24px -12px rgba(52, 36, 26, .18);

  /* Callout accents */
  --c-note:      #8C6642;
  --c-tip:       #4F6B3A;
  --c-warning:   #B07A16;
  --c-danger:    #B2361C;
  --c-safety:    #B2361C;
  --c-materials: #3D6076;
  --c-journal:   #6B4A78;

  /* Syntax highlighting */
  --tok-comment: #93806A;
  --tok-keyword: #A8481C;
  --tok-string:  #4F6B3A;
  --tok-number:  #8C6642;
  --tok-func:    #35566E;
  --tok-punct:   #7A6752;

  --mono:    'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  --display: 'Familjen Grotesk', 'Space Grotesk', system-ui, sans-serif;
  --body:    'Space Grotesk', system-ui, -apple-system, sans-serif;

  /* The mark. Held constant in both themes on purpose - a logo that changes
     colour with the reader's settings stops being a logo. */
  --brand-fill:  #34241A;
  --brand-ink:   #F1E7D6;
  --brand-hover: #E8873F;

  --sidebar-w: 262px;
  --rail-w:    212px;
  --gutter:    2.5rem;
  --measure:   68ch;
  --topbar-h:  60px;
  --radius:    14px;
}

:root[data-theme="dark"] {
  --bg:          #191310;
  --bg-sunk:     #120E0B;
  --surface:     #221A14;
  --surface-2:   #2B211A;

  --ink:         #EFE4D4;
  --ink-2:       #B9A38C;
  --ink-3:       #8D7862;

  --umber:       #C08D5E;
  --accent:      #E8873F;
  --link:        #F0A45E;

  --rule:        rgba(241, 231, 214, 0.13);
  --rule-strong: rgba(241, 231, 214, 0.26);
  --shadow:      0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px -12px rgba(0, 0, 0, .6);

  --c-note:      #C08D5E;
  --c-tip:       #9BBF7C;
  --c-warning:   #E0B24B;
  --c-danger:    #E4785C;
  --c-safety:    #E4785C;
  --c-materials: #7FB0CC;
  --c-journal:   #B98FC7;

  --tok-comment: #8D7862;
  --tok-keyword: #F0A45E;
  --tok-string:  #A9C98A;
  --tok-number:  #E0B080;
  --tok-func:    #8FBEDC;
  --tok-punct:   #A08A72;

  /* Lifted just enough to separate from the page behind it. */
  --brand-fill:  #3D2B1F;
}

/* Light is the default, whatever the device prefers. Most of this site is
   read in a lit classroom or printed, and the palette was drawn for paper.
   Dark is a deliberate choice on the toggle, remembered per browser. */


/* ---- 2. Reset & base -------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: calc(var(--topbar-h) + 1.5rem);
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  /* A column that always fills the window, so the footer is pushed to the
     bottom on a short page instead of floating under two lines of text. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.7;
  font-feature-settings: "kern" 1;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

img, svg, video { max-width: 100%; height: auto; }

a { color: var(--link); text-decoration-color: color-mix(in srgb, var(--link) 35%, transparent); text-underline-offset: .18em; }
a:hover { text-decoration-color: currentColor; }

:where(a, button, input, summary):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: var(--bg);
  padding: .6rem 1rem; border-radius: 0 0 8px 0; font-family: var(--mono); font-size: .8rem;
}
.skip:focus { left: 0; }

/* The MAKE mark. Applied to the wordmark, the footer, and the word wherever it
   opens a page title - never to the ordinary verb in a sentence. */
.brand {
  display: inline-block;
  padding: .08em .34em .12em;
  border-radius: .3em;
  background: var(--brand-fill);
  color: var(--brand-ink);
  transition: color .15s ease;
}
.brand:hover,
a:hover .brand,
a:focus-visible .brand { color: var(--brand-hover); }

/* Backgrounds do not print by default, which would leave cream text on white
   paper - that is, nothing at all. On paper it is simply the word. */
@media print {
  .brand {
    background: none !important;
    color: #000 !important;
    padding: 0 !important;
  }
}

/* A page's number in a numbered section, as a small sibling of the mark above.
   Mono and tabular so the figures line up, with a min-width so 1 and 10 fill
   the same box and every title beside them starts at the same place. */
.numi {
  display: inline-block;
  min-width: 1.6em;
  padding: .12em .3em .16em;
  border-radius: .3em;
  background: var(--brand-fill);
  color: var(--brand-ink);
  font-family: var(--mono);
  font-size: .78em;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.25;
  text-align: center;
  margin-right: .5em;
  transition: color .15s ease;
}
a:hover .numi,
a:focus-visible .numi { color: var(--brand-hover); }

/* In the sidebar the number holds its own column, so a title that wraps to a
   second line lines up under itself rather than tucking under the badge. */
.sn-link:has(.numi) { display: flex; align-items: baseline; gap: .5em; }
.sn-link:has(.numi) .numi { flex: 0 0 auto; margin-right: 0; }

/* On a card, the same column treatment as the sidebar: a title of two or
   three lines wraps under itself rather than under the badge. */
.card h3:has(.numi) { display: flex; align-items: baseline; gap: .45em; }
.card h3:has(.numi) .numi { flex: 0 0 auto; margin-right: 0; font-size: .72em; }

/* Against the h1 it wants to be much smaller than the type it sits beside,
   and lifted off the baseline to sit with the capitals. */
h1 .numi {
  font-size: .46em;
  vertical-align: .34em;
  margin-right: .5rem;
}

@media print {
  .numi {
    background: none !important;
    color: #000 !important;
    padding: 0 !important;
    min-width: 0 !important;
  }
}

/* The small uppercase mono label used all over the site — the one piece of
   type that carries the family resemblance to mistermills.tech. */
.eyebrow {
  margin: 0 0 .5rem;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--umber);
}

kbd {
  font-family: var(--mono); font-size: .7rem; line-height: 1;
  padding: .22em .42em; border: 1px solid var(--rule-strong); border-radius: 4px;
  background: var(--surface); color: var(--ink-2);
}


/* ---- 3. Top bar ------------------------------------------------------- */

.topbar {
  position: sticky; top: 0; z-index: 50;
  height: var(--topbar-h);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  -webkit-backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--rule);
}
.topbar-in {
  max-width: 1500px; height: 100%; margin: 0 auto;
  padding: 0 var(--gutter);
  display: flex; align-items: center; gap: 1.5rem;
}

.wordmark {
  display: inline-flex; align-items: baseline; gap: .4rem;
  text-decoration: none; white-space: nowrap;
}
.wm-name {
  font-family: var(--display); font-weight: 700; font-size: 1.18rem;
  letter-spacing: -.01em; color: var(--ink);
}
/* `.wm-name` and `.brand` are both single classes, and this one comes later in
   the file - so without this the wordmark would paint dark ink on the dark
   badge and vanish. */
.wordmark .brand { color: var(--brand-ink); }
.wordmark:hover .brand, .wordmark:focus-visible .brand { color: var(--brand-hover); }
.wm-sep { font-family: var(--mono); color: var(--accent); font-size: .8rem; }
.wm-host {
  font-family: var(--mono); font-size: .68rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-3);
}

.toplinks { display: flex; align-items: center; gap: .3rem; margin-left: auto; }
.toplink {
  padding: .38rem .7rem; border-radius: 8px;
  font-size: .88rem; font-weight: 500; color: var(--ink-2); text-decoration: none;
}
.toplink:hover { background: var(--surface-2); color: var(--ink); }
.toplink.is-current { color: var(--ink); background: var(--surface-2); }

.topbar-tools { display: flex; align-items: center; gap: .4rem; }

.tool {
  display: inline-flex; align-items: center; gap: .45rem;
  height: 34px; padding: 0 .6rem;
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--rule); border-radius: 9px;
  font-family: var(--body); font-size: .82rem; cursor: pointer;
  transition: border-color .15s, color .15s;
}
.tool:hover { border-color: var(--rule-strong); color: var(--ink); }
.tool svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.tool.icon-only { padding: 0; width: 34px; justify-content: center; }
.tool kbd { margin-left: .1rem; }

.theme-toggle .i-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .i-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .i-moon { display: block; }


/* The section menu is collapsible at any width: on a wide screen it takes the
   column away entirely, which is the difference between a reference site and a
   page you can actually read. */
/* The menu goes away without the article moving. Keeping the grid columns
   exactly as they were is the whole trick: reclaiming the column would reflow
   the text mid-read, and losing your place is a worse price than a quiet strip
   of empty page. So the menu slides aside and the words stay put. */
@media (min-width: 901px) {
  .sidebar {
    transition: opacity .18s ease, transform .18s ease, visibility 0s;
  }
  :root.nav-collapsed .sidebar {
    opacity: 0;
    transform: translateX(-1.25rem);
    visibility: hidden;
    pointer-events: none;
    transition: opacity .18s ease, transform .18s ease, visibility 0s linear .18s;
  }
}
.menu-toggle svg { transition: transform .18s; }
:root.nav-collapsed .menu-toggle svg { transform: rotate(90deg); }
.menu-toggle { margin-right: .35rem; }


/* ---- 4. Shell --------------------------------------------------------- */

.shell {
  max-width: 1500px; margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr) var(--rail-w);
  gap: 3rem;
  align-items: start;
  flex: 1 0 auto;          /* take up the slack, so the footer is pushed down */
  width: 100%;
}


/* ---- 5. Sidebar ------------------------------------------------------- */

.navcol {
  position: sticky;
  top: var(--topbar-h);
  align-self: start;
  padding-top: 2.2rem;
}
.navcol .menu-toggle { margin-bottom: .9rem; }
.sidebar-in {
  max-height: calc(100vh - var(--topbar-h) - 6rem);
  overflow-y: auto;
  padding: 0 1rem 3rem 0;
  scrollbar-width: thin;
}

.sn-root { list-style: none; margin: 0; padding: 0; }
.sn-group + .sn-group, .sn-loose + .sn-group { margin-top: 1.6rem; }

.sn-group-link {
  display: block; padding: .18rem 0;
  font-family: var(--mono); font-size: 10.5px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--umber); text-decoration: none;
}
.sn-group-link:hover { color: var(--accent); }
.sn-group-link.is-current { color: var(--accent); }

.sn-pages { list-style: none; margin: .5rem 0 0; padding: 0 0 0 .05rem; border-left: 1px solid var(--rule); }
.sn-link {
  display: block; padding: .3rem 0 .3rem .85rem;
  margin-left: -1px; border-left: 2px solid transparent;
  font-size: .875rem; line-height: 1.45; color: var(--ink-2); text-decoration: none;
}
.sn-link:hover { color: var(--ink); border-left-color: var(--rule-strong); }
.sn-link.is-current {
  color: var(--ink); font-weight: 600;
  border-left-color: var(--accent);
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 9%, transparent), transparent 70%);
}
.sn-sub { margin: .55rem 0 .3rem .85rem; }
.sn-sub .sn-group-link { font-size: 10px; letter-spacing: .12em; color: var(--ink-3); }

.sn-outside { margin-top: 2.4rem; padding-top: 1.3rem; border-top: 1px solid var(--rule); }
.sn-out { display: block; padding: .26rem 0; font-size: .85rem; color: var(--ink-2); text-decoration: none; }
.sn-out:hover { color: var(--accent); }


/* ---- 6. Article furniture --------------------------------------------- */

.main { min-width: 0; padding: 2.2rem 0 4rem; }

.crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: .45rem;
  margin-bottom: 1.6rem;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
}
.crumbs a { color: var(--ink-3); text-decoration: none; }
.crumbs a:hover { color: var(--accent); }
.crumbs span[aria-current] { color: var(--ink-2); }
.crumb-sep { color: var(--rule-strong); }

.page-head { margin-bottom: 2.4rem; }
.page-head h1 {
  margin: 0;
  font-family: var(--display); font-weight: 700;
  font-size: clamp(1.9rem, 1.2rem + 2.4vw, 2.9rem);
  line-height: 1.1; letter-spacing: -.022em;
  text-wrap: balance;
}
.lede {
  margin: .9rem 0 0; max-width: var(--measure);
  font-size: 1.1rem; line-height: 1.6; color: var(--ink-2);
  text-wrap: pretty;
}

.pagemeta {
  display: flex; flex-wrap: wrap; gap: .45rem;
  margin-top: 1.5rem; padding-top: 1.2rem; border-top: 1px solid var(--rule);
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
}
.pagemeta span {
  padding: .3rem .6rem; border-radius: 6px;
  background: var(--surface-2); color: var(--ink-2);
}
.pagemeta .m-time { background: color-mix(in srgb, var(--accent) 14%, var(--surface)); color: var(--link); }
.pagemeta .m-level { background: color-mix(in srgb, var(--umber) 15%, var(--surface)); color: var(--umber); }

/* Assigned and due dates: outlined blocks with a label, on their own row, so
   they never read as one more tag. */
.pagemeta .m-dates {
  flex-basis: 100%;
  display: flex; flex-wrap: wrap; gap: .6rem;
  margin-bottom: .35rem;
}
.pagemeta .m-date {
  display: inline-flex; align-items: baseline; gap: .6rem;
  padding: .45rem .8rem; border-radius: 8px;
  background: none; border: 1.5px solid var(--rule); color: var(--ink);
  font-family: var(--display); font-size: .95rem; font-weight: 600;
  letter-spacing: 0; text-transform: none;
}
.pagemeta .m-date .m-date-label {
  padding: 0; border-radius: 0; background: none; color: var(--ink-3);
  font-family: var(--mono); font-size: 10.5px; font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase;
}
.pagemeta .m-due { border-color: var(--accent); }
.pagemeta .m-due .m-date-label { color: var(--link); }

/* Housekeeping for the author, kept out of the way at the foot of the page. */
.page-updated {
  margin: 1.4rem 0 0;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-3);
}


/* ---- 7. Prose --------------------------------------------------------- */

.prose { max-width: var(--measure); }
.prose > * { margin-block: 0 1.15rem; }
.prose > *:last-child { margin-bottom: 0; }

.prose h2, .prose h3, .prose h4 {
  font-family: var(--display); font-weight: 600;
  line-height: 1.22; letter-spacing: -.012em;
  scroll-margin-top: calc(var(--topbar-h) + 1.5rem);
  text-wrap: balance;
}
.prose h2 {
  margin-top: 3rem; padding-top: 1.4rem;
  border-top: 1px solid var(--rule);
  font-size: 1.55rem;
}
.prose h3 { margin-top: 2.2rem; font-size: 1.17rem; }
.prose h4 {
  margin-top: 1.8rem; font-size: .82rem; font-family: var(--mono);
  letter-spacing: .1em; text-transform: uppercase; color: var(--umber);
}
.prose h1:first-child, .prose h2:first-child { margin-top: 0; border-top: 0; padding-top: 0; }

/* Derived section numbers. Set in the same mono as every other label on the
   site, and a shade lighter than the heading, so they read as an index rather
   than as part of the sentence. */
.hnum {
  font-family: var(--mono);
  font-weight: 500;
  color: var(--umber);
  margin-right: .55em;
  font-variant-numeric: tabular-nums;
}
.prose h3 .hnum { font-size: .92em; }
.toc .hnum { margin-right: .4em; font-size: .92em; }

/* The little anchor the toc extension leaves next to each heading. */
.headerlink {
  margin-left: .45rem; opacity: 0; text-decoration: none;
  color: var(--ink-3); font-weight: 400;
  transition: opacity .15s;
}
h2:hover .headerlink, h3:hover .headerlink, h4:hover .headerlink,
.headerlink:focus-visible { opacity: 1; }

.prose p { text-wrap: pretty; }
.prose strong { font-weight: 600; color: var(--ink); }
.prose hr { height: 1px; border: 0; background: var(--rule); margin: 2.6rem 0; }

.prose blockquote {
  margin: 1.6rem 0; padding: .2rem 0 .2rem 1.3rem;
  border-left: 3px solid var(--umber);
  color: var(--ink-2); font-size: 1.03rem;
}
.prose blockquote > *:last-child { margin-bottom: 0; }

/* Unordered lists: a small square instead of a dot — quieter, and it echoes
   the squared-off feel of the rest of the site. */
.prose ul { list-style: none; padding-left: 1.35rem; }
.prose ul > li { position: relative; margin-bottom: .5rem; }
.prose ul > li::before {
  content: ""; position: absolute; left: -1.05rem; top: .62em;
  width: 6px; height: 6px; border-radius: 1px; background: var(--umber);
}
.prose li > ul, .prose li > ol { margin-top: .5rem; margin-bottom: .3rem; }

.prose dl { margin: 1.4rem 0; }
.prose dt { font-weight: 600; margin-top: 1rem; }
.prose dd { margin: .2rem 0 0 1.2rem; color: var(--ink-2); }

/* Figures */
.figure { margin: 2rem 0; }
.figure img {
  display: block; width: 100%;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--surface);
}
.figure figcaption {
  margin-top: .7rem; padding-left: .1rem;
  font-family: var(--mono); font-size: .74rem; line-height: 1.55;
  color: var(--ink-3);
}
/* An image used inside a sentence keeps its place in the line. */
.prose p > img { display: inline-block; vertical-align: middle; border-radius: 5px; }

/* Tables */
.table-scroll { overflow-x: auto; margin: 1.6rem 0; border: 1px solid var(--rule); border-radius: var(--radius); }
.prose table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.prose th, .prose td { padding: .68rem .9rem; text-align: left; border-bottom: 1px solid var(--rule); }
.prose th {
  background: var(--surface-2);
  font-family: var(--mono); font-size: .7rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-2);
  white-space: nowrap;
}
.prose tbody tr:last-child td { border-bottom: 0; }
.prose tbody tr:hover td { background: var(--surface); }

/* Footnotes */
.footnote { margin-top: 3rem; padding-top: 1.2rem; border-top: 1px solid var(--rule); font-size: .9rem; color: var(--ink-2); }
.footnote ol { padding-left: 1.2rem; }
.footnote-ref { text-decoration: none; font-size: .78em; vertical-align: super; }

/* A link that leaves the site gets a small arrow. */
a.external::after {
  content: "↗"; display: inline-block; margin-left: .18em;
  font-size: .78em; opacity: .55; text-decoration: none;
}

/* Task lists */
.prose ul.tasklist { padding-left: 0; }
.prose ul.tasklist > li { padding-left: 1.9rem; margin-bottom: .55rem; }
.prose ul.tasklist > li::before { display: none; }
.prose ul.tasklist input[type="checkbox"] {
  position: absolute; left: 0; top: .28em;
  width: 1.05rem; height: 1.05rem; margin: 0;
  accent-color: var(--accent); cursor: pointer;
}
.prose li.task.done { color: var(--ink-3); }


/* ---- 8. Steps --------------------------------------------------------- */
/* Every numbered list on the site is treated as a sequence of instructions,
   because on this site it always is. The numeral sits out in the gutter with a
   rule running between one step and the next, so a long procedure reads as a
   single thread rather than a wall of paragraphs. */

.prose ol {
  list-style: none;
  /* `--start` is set by the build from the list's own `start` attribute, so a
     list that resumes at four is numbered from four rather than from one. */
  counter-reset: step calc(var(--start, 1) - 1);
  padding-left: 0;
  margin: 1.8rem 0;
}
/* A list with no `start` of its own begins at one, even when it sits inside
   a step of a list that resumed partway, which would otherwise hand down
   its `--start`. */
.prose ol:not([start]) { --start: 1; }
.prose ol > li {
  counter-increment: step;
  position: relative;
  padding-left: 3.35rem;
  padding-bottom: 1.45rem;
}
.prose ol > li:last-child { padding-bottom: 0; }
.prose ol > li::before {
  content: counter(step);
  position: absolute; left: 0; top: -.12em;
  width: 2.15rem; height: 2.15rem;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--umber); color: var(--bg);
  font-family: var(--mono); font-size: .84rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
/* the thread between steps */
.prose ol > li::after {
  content: ""; position: absolute;
  left: calc(1.075rem - 1px); top: 2.45rem; bottom: .1rem;
  width: 2px; background: var(--rule);
}
.prose ol > li:last-child::after { display: none; }
.prose ol > li > *:last-child { margin-bottom: 0; }

/* A list nested inside a step is an aside, not a new procedure. */
.prose li ol { margin: .6rem 0; }
.prose li ol > li { padding-left: 1.7rem; padding-bottom: .45rem; }
.prose li ol > li::before {
  content: counter(step) ".";
  width: auto; height: auto; top: 0; left: 0;
  background: none; color: var(--umber);
  font-size: .82rem; display: block;
}
.prose li ol > li::after { display: none; }


/* ---- 9. Callouts ------------------------------------------------------ */
/* Written as:  !!! warning "Optional custom heading" */

.admonition {
  --call: var(--c-note);
  margin: 1.8rem 0; padding: 1.1rem 1.3rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-left: 4px solid var(--call);
  border-radius: 6px var(--radius) var(--radius) 6px;
}
.admonition > *:last-child { margin-bottom: 0; }
.admonition-title {
  margin: 0 0 .5rem;
  font-family: var(--mono); font-size: 10.5px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--call);
}
.admonition p { font-size: .96rem; }
.admonition li { margin-bottom: .3rem; }
.admonition li > p { margin-bottom: .3rem; }
.admonition li > p:last-child { margin-bottom: 0; }

.admonition.tip, .admonition.hint       { --call: var(--c-tip); }
.admonition.warning, .admonition.caution { --call: var(--c-warning); }
.admonition.danger, .admonition.error   { --call: var(--c-danger); }
.admonition.safety                      { --call: var(--c-safety); }
.admonition.materials, .admonition.info { --call: var(--c-materials); }
.admonition.journal                     { --call: var(--c-journal); }

/* Safety notices are the one thing on this site that should be impossible to
   skim past, so they get filled rather than outlined. */
.admonition.safety, .admonition.danger {
  background: color-mix(in srgb, var(--c-danger) 9%, var(--surface));
  border-color: color-mix(in srgb, var(--c-danger) 28%, transparent);
  border-left-color: var(--call);
}

/* A journal prompt is an instruction to write something, not background
   reading, so it is filled rather than outlined. */
.admonition.journal {
  background: color-mix(in srgb, var(--c-journal) 8%, var(--surface));
  border-color: color-mix(in srgb, var(--c-journal) 26%, transparent);
  border-left-color: var(--call);
}

/* "You will need" reads better as a checklist than as prose. */
.admonition.materials ul.tasklist > li { margin-bottom: .35rem; }


/* ---- 10. Code --------------------------------------------------------- */

.prose code {
  font-family: var(--mono); font-size: .86em;
  padding: .14em .38em; border-radius: 5px;
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--rule);
  word-break: break-word;
}

.highlight, .prose pre {
  position: relative;
  margin: 1.6rem 0;
  background: var(--surface-2);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
}
.prose pre { padding: 0; }
.highlight pre, .prose > pre {
  margin: 0; padding: 1.05rem 1.2rem;
  overflow-x: auto;
  font-family: var(--mono); font-size: .84rem; line-height: 1.65;
  tab-size: 4;
}
.prose pre code {
  padding: 0; background: none; border: 0; font-size: inherit;
}

.copy-code {
  position: absolute; top: .5rem; right: .5rem;
  padding: .28rem .55rem;
  font-family: var(--mono); font-size: .66rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-3); background: var(--surface); cursor: pointer;
  border: 1px solid var(--rule); border-radius: 6px;
  opacity: 0; transition: opacity .15s, color .15s;
}
.highlight:hover .copy-code, .prose pre:hover .copy-code, .copy-code:focus-visible { opacity: 1; }
.copy-code:hover { color: var(--ink); }
.copy-code.done { color: var(--c-tip); opacity: 1; }

/* Pygments tokens, mapped onto the palette so code belongs to the page. */
.highlight .c, .highlight .c1, .highlight .cm, .highlight .cs, .highlight .cp { color: var(--tok-comment); font-style: italic; }
.highlight .k, .highlight .kd, .highlight .kn, .highlight .kc, .highlight .kr, .highlight .kt { color: var(--tok-keyword); font-weight: 500; }
.highlight .s, .highlight .s1, .highlight .s2, .highlight .sb, .highlight .sc, .highlight .sd, .highlight .se, .highlight .si, .highlight .sx { color: var(--tok-string); }
.highlight .m, .highlight .mi, .highlight .mf, .highlight .mh, .highlight .mo, .highlight .il { color: var(--tok-number); }
.highlight .nf, .highlight .nc, .highlight .nn, .highlight .nd { color: var(--tok-func); }
.highlight .nb, .highlight .bp { color: var(--tok-keyword); }
.highlight .nt { color: var(--tok-keyword); }
.highlight .na, .highlight .nv, .highlight .vi { color: var(--tok-func); }
.highlight .o, .highlight .ow, .highlight .p { color: var(--tok-punct); }
.highlight .gd { color: var(--c-danger); }
.highlight .gi { color: var(--c-tip); }
.highlight .err { color: var(--c-danger); }


/* ---- 11. Cards & paging ----------------------------------------------- */

.cards {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(255px, 1fr));
  margin: 2.6rem 0 0;
}
.card {
  display: block; padding: 1.15rem 1.25rem 1.3rem;
  background: var(--surface);
  border: 1px solid var(--rule); border-radius: var(--radius);
  text-decoration: none; color: inherit;
  transition: border-color .16s, transform .16s, box-shadow .16s;
}
.card:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  transform: translateY(-2px);
  box-shadow: var(--shadow);
}
.card h3 {
  margin: 0; font-family: var(--display); font-size: 1.06rem; font-weight: 600;
  line-height: 1.28; color: var(--ink);
}
.card p { margin: .5rem 0 0; font-size: .89rem; line-height: 1.55; color: var(--ink-2); }
.card .eyebrow { margin-bottom: .45rem; }
.card-section { background: color-mix(in srgb, var(--umber) 7%, var(--surface)); }

/* The home page's assignment board: `[[assignments]]` in the markdown. */
.prose .assignments {
  margin: 1.8rem 0;
  padding: 1.1rem 1.3rem 1.25rem;
  background: var(--surface);
  border: 1px solid var(--rule); border-radius: var(--radius);
}
.prose .assignments .asg-heading {
  margin: 0 0 .7rem; padding: 0; border: 0;
  font-family: var(--mono); font-size: .72rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--link);
}
.assignments .asg-list { display: grid; gap: .45rem; }
.prose .assignments .asg-item {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: .25rem 1rem;
  padding: .65rem .85rem;
  border: 1px solid var(--rule); border-radius: 10px;
  background: var(--surface);
  color: var(--ink); text-decoration: none;
  transition: border-color .16s;
}
.prose .assignments .asg-item:hover { border-color: color-mix(in srgb, var(--accent) 55%, transparent); }
.assignments .asg-title { font-family: var(--display); font-weight: 600; font-size: 1rem; line-height: 1.3; }
/* Which section an entry is from, set like the label on a search result. */
.assignments .asg-section {
  display: block; margin-bottom: .2rem;
  font-family: var(--mono); font-size: 9.5px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--umber);
}
.assignments .asg-when {
  font-family: var(--mono); font-size: .72rem; letter-spacing: .04em;
  color: var(--ink-2); white-space: nowrap;
}
.prose .assignments .asg-soon { border-color: var(--accent); border-width: 1.5px; }
.assignments .asg-soon .asg-when { color: var(--link); font-weight: 600; }
.prose .assignments .asg-empty { margin: 0; color: var(--ink-3); font-size: .92rem; }

.assignments .asg-late {
  margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid var(--rule);
}
.prose .assignments .asg-late .asg-heading { color: var(--c-danger); }
.prose .assignments .asg-late .asg-item { padding: .45rem .85rem; background: none; }
.assignments .asg-late .asg-title { font-size: .92rem; font-weight: 500; color: var(--ink-2); }
.assignments .asg-late .asg-when { color: var(--c-danger); }

.prevnext {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;
  margin: 3.5rem 0 0; padding-top: 1.8rem; border-top: 1px solid var(--rule);
}
.pn {
  display: block; padding: .9rem 1.1rem;
  border: 1px solid var(--rule); border-radius: var(--radius);
  text-decoration: none; color: inherit;
  transition: border-color .16s;
}
.pn:hover { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.pn-next { text-align: right; }
.pn-title { display: block; font-weight: 600; font-size: .95rem; line-height: 1.35; color: var(--ink); }

.page-foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: .8rem;
  margin-top: 2.5rem; padding-top: 1.4rem; border-top: 1px solid var(--rule);
}
.edit-link {
  font-family: var(--mono); font-size: .72rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-3); text-decoration: none;
}
.edit-link:hover { color: var(--accent); }
.print-button {
  margin-left: auto;
  font-family: var(--mono); font-size: .7rem; letter-spacing: .08em; text-transform: uppercase;
}


/* ---- 12. Right rail --------------------------------------------------- */

.rail { position: sticky; top: var(--topbar-h); align-self: start; }
.toc {
  max-height: calc(100vh - var(--topbar-h) - 3rem);
  overflow-y: auto;
  padding: 2.9rem 0 2rem 1.3rem;
  border-left: 1px solid var(--rule);
  scrollbar-width: thin;
}
.toc ul { list-style: none; margin: 0; padding: 0; }
.toc a {
  display: block; padding: .28rem 0;
  font-size: .82rem; line-height: 1.45;
  color: var(--ink-3); text-decoration: none;
  transition: color .14s;
}
.toc a:hover { color: var(--ink); }
.toc .toc-l1 a { padding-left: .85rem; font-size: .78rem; }
.toc a.is-active { color: var(--accent); font-weight: 600; }


/* ---- 13. Search ------------------------------------------------------- */

.searchbox {
  width: min(640px, calc(100vw - 2rem));
  margin: 12vh auto auto;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  box-shadow: 0 24px 70px -20px rgba(0, 0, 0, .45);
}
.searchbox::backdrop { background: rgba(20, 14, 10, .48); backdrop-filter: blur(2px); }

.search-form {
  display: flex; align-items: center; gap: .7rem;
  padding: .85rem 1rem; border-bottom: 1px solid var(--rule);
}
.search-icon { width: 17px; height: 17px; flex: none; fill: none; stroke: var(--ink-3); stroke-width: 1.6; stroke-linecap: round; }
#search-input {
  flex: 1; min-width: 0;
  border: 0; background: none; outline: none;
  font-family: var(--body); font-size: 1rem; color: var(--ink);
}
#search-input::placeholder { color: var(--ink-3); }
#search-input::-webkit-search-cancel-button { display: none; }
.search-close {
  flex: none; padding: .2rem .45rem;
  font-family: var(--mono); font-size: .68rem;
  color: var(--ink-3); background: var(--surface);
  border: 1px solid var(--rule); border-radius: 5px; cursor: pointer;
}

.search-results { max-height: min(56vh, 460px); overflow-y: auto; padding: .4rem; }
.search-hit {
  display: block; padding: .6rem .75rem; border-radius: 9px;
  text-decoration: none; color: inherit;
}
.search-hit:hover, .search-hit.is-active { background: var(--surface-2); }
.search-hit .hit-section {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--umber);
}
.search-hit .hit-title { display: block; font-weight: 600; font-size: .95rem; line-height: 1.3; }
.search-hit .hit-text {
  display: block; margin-top: .12rem;
  font-size: .82rem; line-height: 1.45; color: var(--ink-2);
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.search-hit mark { background: color-mix(in srgb, var(--accent) 26%, transparent); color: inherit; border-radius: 2px; }
.search-empty { padding: 1.6rem 1rem; text-align: center; color: var(--ink-3); font-size: .9rem; }
.search-hint {
  margin: 0; padding: .55rem 1rem; border-top: 1px solid var(--rule);
  font-size: .72rem; color: var(--ink-3);
}
.search-hint kbd { margin-right: .2rem; }


/* ---- 14. Footer ------------------------------------------------------- */

.sitefoot { flex: none; margin-top: 2rem; border-top: 1px solid var(--rule); background: var(--bg-sunk); }
.sitefoot-in {
  max-width: 1500px; margin: 0 auto; padding: 2rem var(--gutter);
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 1rem;
}
.foot-name { margin: 0; font-family: var(--display); font-weight: 600; font-size: .95rem; }
.foot-meta {
  margin: 0; display: flex; flex-wrap: wrap; gap: 1.1rem;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-3);
}
.foot-meta a { color: var(--ink-3); text-decoration: none; }
.foot-meta a:hover { color: var(--accent); }

.scrim {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(20, 14, 10, .45);
  border: 0;
}


/* ---- 15. Responsive --------------------------------------------------- */

@media (max-width: 1180px) {
  .shell { grid-template-columns: var(--sidebar-w) minmax(0, 1fr); gap: 2.5rem; }
  .rail { display: none; }

  /* Every section is a link in the top bar, and at this width they no longer
     fit beside the full search button. Search drops to its icon, as it does
     on a phone, and the links close up. */
  .topbar-in { gap: 1rem; }
  .toplinks { gap: .1rem; }
  .toplink { padding: .38rem .5rem; }
  .tool .tool-text, .tool kbd { display: none; }
  .search-open { padding: 0; width: 34px; justify-content: center; }
}

/* Narrower still, the links need the room the host name takes. Below 900px
   the links have gone to the drawer, so the host name comes back. */
@media (min-width: 901px) and (max-width: 1000px) {
  .wordmark .wm-sep, .wordmark .wm-host { display: none; }
}

@media (max-width: 900px) {
  :root { --gutter: 1.5rem; }
  body { font-size: 16.5px; }

  .shell { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .toplinks { display: none; }

  /* Below this width the menu is a drawer again, so the collapsed state must
     not also be hiding it - the drawer does its own showing and hiding. */
  :root.nav-collapsed .sidebar {
    opacity: 1; visibility: visible; pointer-events: auto; transform: none;
  }
  .shell, :root.nav-collapsed .shell { grid-template-columns: minmax(0, 1fr); }

  /* The section menu becomes a drawer. */
  .sidebar {
    position: fixed; top: var(--topbar-h); left: 0; bottom: 0; z-index: 45;
    width: min(84vw, 320px);
    background: var(--bg);
    border-right: 1px solid var(--rule);
    transform: translateX(-100%);
    transition: transform .22s cubic-bezier(.4, 0, .2, 1);
    visibility: hidden;
  }
  body.menu-open .sidebar { transform: none; visibility: visible; }
  .sidebar-in {
    max-height: none; height: 100%; padding: 1.6rem 1.4rem 3rem;
    overscroll-behavior: contain;   /* the end of the menu is not the page */
  }

  /* .navcol is sticky, and a sticky element keeps its children's z-index to
     itself. The drawer's 45 only counted inside the column, so the scrim at 40
     sat over the drawer and took every tap and swipe meant for it. Lifting the
     column puts the drawer above the scrim. */
  .navcol { z-index: 45; }

  .main { padding-top: 1.6rem; }
  .prevnext { grid-template-columns: 1fr; }
  .pn-next { text-align: left; }
  .prose ol > li { padding-left: 2.9rem; }
  .prose ol > li::before { width: 1.95rem; height: 1.95rem; font-size: .8rem; }
  .prose ol > li::after { left: calc(.975rem - 1px); top: 2.25rem; }
}

@media (min-width: 901px) { .scrim { display: none; } }


/* ---- 16. Print -------------------------------------------------------- */
/* Handouts get printed. What comes out should be the instructions, on paper,
   with the URLs of any links spelled out so they survive the trip. */

@media print {
  /* `:root[data-theme="dark"]` is more specific than a bare `:root`, so a
     plain :root block here loses to it and dark pages print dark - unreadable
     on a black-and-white classroom printer. Matching that specificity, and
     coming later in the file, is what actually forces paper to be paper. */
  :root,
  :root[data-theme="dark"],
  :root[data-theme="light"] {
    --bg: #fff;        --bg-sunk: #fff;
    --surface: #fff;   --surface-2: #f2f2f2;
    --ink: #000;       --ink-2: #333;        --ink-3: #555;
    --umber: #000;     --accent: #000;       --link: #000;
    --rule: #bbb;      --rule-strong: #777;  --shadow: none;
    --c-note: #000;    --c-tip: #000;        --c-warning: #000;
    --c-danger: #000;  --c-safety: #000;     --c-materials: #000;
    --c-journal: #000;
    --tok-comment: #555; --tok-keyword: #000; --tok-string: #333;
    --tok-number: #333;  --tok-func: #000;    --tok-punct: #333;
  }
  .topbar, .sidebar, .rail, .prevnext, .page-foot, .page-updated, .sitefoot, .searchbox, .scrim, .skip, .headerlink { display: none !important; }

  body { font-size: 11pt; background: #fff; color: #000; }
  .shell { display: block; max-width: none; padding: 0; }
  .main { padding: 0; }
  .prose, .lede { max-width: none; }

  .crumbs { margin-bottom: .6rem; }
  .page-head { margin-bottom: 1.2rem; }

  a { color: #000; text-decoration: underline; }
  .prose a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 8.5pt; color: #555; word-break: break-all; }

  .prose h2, .prose h3, .figure, .admonition, .highlight, .prose pre, .prose tr { break-inside: avoid; }
  .prose h2, .prose h3 { break-after: avoid; }
  .prose ol > li { break-inside: avoid; }
  .prose ol > li::before { background: #000 !important; color: #fff !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .admonition { border: 1px solid #999; border-left: 4px solid #000; }
  .figure img { border: 1px solid #ccc; }
}


/* ---- 17. Carousels ----------------------------------------------------- */
/* Written as a fenced block of ordinary images:
       ::: carousel "Optional heading"
       ![alt](images/a.jpg "First")
       :::
   Until the script upgrades it, it is simply the pictures stacked in order,
   which is a perfectly good fallback and what printing gets. */

.carousel { margin: 2rem 0; }
.carousel > .figure { margin: 0 0 1rem; }
.carousel > .figure:last-child { margin-bottom: 0; }

.carousel.is-ready {
  position: relative;
  margin: 2.2rem 0;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}
.carousel.is-ready .car-viewport { overflow: hidden; }
.carousel.is-ready .car-track {
  display: flex;
  transition: transform .34s cubic-bezier(.4, 0, .2, 1);
}
@media (prefers-reduced-motion: reduce) {
  .carousel.is-ready .car-track { transition: none; }
}
.carousel.is-ready > .car-viewport > .car-track > .figure {
  flex: 0 0 100%;
  min-width: 0;
  margin: 0;
  padding: 0;
}
.carousel.is-ready .figure img {
  border: 0; border-radius: 0;
  aspect-ratio: 16 / 10;
  object-fit: contain;
  background: var(--bg-sunk);
}
.carousel.is-ready .figure figcaption {
  margin: 0; padding: .8rem 1rem;
  border-top: 1px solid var(--rule);
  min-height: 2.9rem;
}

.car-heading {
  padding: .7rem 1rem .1rem;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--umber);
}

.car-nav {
  position: absolute; top: 0; bottom: 3rem;
  width: 3.2rem; border: 0; cursor: pointer;
  display: grid; place-items: center;
  background: none; color: var(--ink);
  opacity: 0; transition: opacity .16s;
}
.carousel.is-ready:hover .car-nav, .car-nav:focus-visible { opacity: 1; }
.car-nav[disabled] { opacity: 0 !important; cursor: default; }
.car-prev { left: 0; }
.car-next { right: 0; }
.car-nav span {
  display: grid; place-items: center;
  width: 2.1rem; height: 2.1rem; border-radius: 50%;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  border: 1px solid var(--rule-strong);
  backdrop-filter: blur(4px);
  font-size: 1rem; line-height: 1;
}

.car-bar {
  display: flex; align-items: center; gap: .8rem;
  padding: .55rem 1rem;
  border-top: 1px solid var(--rule);
  background: var(--surface-2);
}
.car-dots { display: flex; gap: .38rem; margin-right: auto; }
.car-dot {
  width: 7px; height: 7px; padding: 0; border: 0; border-radius: 50%;
  background: var(--rule-strong); cursor: pointer;
}
.car-dot.is-on { background: var(--accent); }
.car-count {
  font-family: var(--mono); font-size: .68rem; letter-spacing: .1em;
  color: var(--ink-3); font-variant-numeric: tabular-nums;
}

/* Printing gets every slide, since paper cannot be swiped. */
@media print {
  .carousel.is-ready { border: 0; }
  .carousel.is-ready .car-viewport { overflow: visible; }
  .carousel.is-ready .car-track { display: block; transform: none !important; }
  .carousel.is-ready .figure img { aspect-ratio: auto; }
  .car-nav, .car-bar { display: none; }
}


/* ---- 18. Hover images -------------------------------------------------- */
/* Written as  ?[the tinned tip](images/tip.jpg "caption")  — a picture the
   reader can call up without losing their place in a set of steps. */

.hoverpic {
  cursor: help;
  border-bottom: 1px dashed var(--umber);
  color: var(--ink);
}
.hoverpic::after {
  content: "◉";
  margin-left: .18em; font-size: .62em; vertical-align: .28em;
  color: var(--accent);
}
.hoverpic:hover, .hoverpic:focus-visible { border-bottom-color: var(--accent); }

#hoverpic-pop {
  position: fixed; z-index: 90;
  width: min(340px, calc(100vw - 2rem));
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--rule-strong);
  border-radius: 10px;
  box-shadow: 0 18px 44px -14px rgba(0, 0, 0, .5);
  opacity: 0; transform: translateY(4px);
  transition: opacity .14s, transform .14s;
  pointer-events: none;
}
#hoverpic-pop.is-open { opacity: 1; transform: none; }
#hoverpic-pop img { display: block; width: 100%; border-radius: 6px; }
#hoverpic-pop .hp-cap {
  padding: .45rem .3rem .2rem;
  font-family: var(--mono); font-size: .68rem; line-height: 1.5; color: var(--ink-3);
}

/* On paper a hover image is useless, so it becomes a plain marked phrase. */
@media print {
  .hoverpic { border-bottom: 0; }
  .hoverpic::after { content: ""; }
  #hoverpic-pop { display: none; }
}
