/* =========================================================================
   PythonMusic / PEM  —  custom chrome on top of Material

   Palette & type ported from jythonmusic.me (WordPress Twenty Eleven):
     near-black nav · white content on a grey page · #1982d1 blue accent ·
     light dropdowns · Helvetica system stack.

   Layout (dimensions adapted, not copied):
     - Banner (Material "announce" slot) — scrolls away.
     - Header (sticky) = title row + inline hover mega-menu = one bar.
     - Two-tone body: grey page background shows behind the LEFT contextual
       nav; the main content sits on a white panel.

   Scaling (two breakpoints, both Material's): below 60em the nav folds into the
   drawer and the panel is full-width. At/above 60em the text column is FIXED;
   the interior inset grows from 60em to 80.6em (widening the panel), then locks;
   past 80.6em the page centres and the grey gutters grow. A left nav, when
   present, is a fixed-width bookmark that shifts the aligned bands right without
   resizing the column. See the layout variables below.
   ========================================================================= */

/* ----- Palette ------------------------------------------------------------ */
:root,
[data-md-color-scheme="default"] {
  --md-primary-fg-color:        #222222;   /* header / nav bar */
  --md-primary-fg-color--light: #373737;
  --md-primary-fg-color--dark:  #0a0a0a;
  --md-primary-bg-color:        #ffffff;   /* text on the nav bar */

  --md-accent-fg-color:         #1982d1;   /* hover accent (blue) */
  --md-typeset-a-color:         #1982d1;   /* body links (blue) */
  --md-typeset-color:           #373737;   /* body text */

  --pm-page-bg:        #e4e6e9;   /* grey page behind the panel and in the gutters */
  --pm-page-top-gap:   2rem;      /* grey gap above the banner */

  /* --- Scaling knobs (tune these) ----------------------------------------- */
  --pm-col:            42rem;     /* readable text column — fixed at and above 60em */
  --pm-pad-min:        2rem;      /* interior inset at or below 60em */
  --pm-pad-max:        7rem;      /* interior inset at and above 80.6em */
  --pm-gutter:         1rem;      /* minimum window-edge gutter */
  --pm-nav-w:          9rem;      /* left-nav "bookmark" width */
  --pm-nav-gap:        1rem;      /* gap between the nav and the panel */
  --pm-content-pad-top: 3.5rem;   /* text inset from the panel top */

  /* --- Derived ------------------------------------------------------------- */
  /* Interior inset: pad-min up to 60em, ramping to pad-max by 80.6em
     (slope = (pad-max − pad-min) / (80.6 − 60)em = 5 / 20.6 ≈ 0.2427). */
  --pm-pad:      clamp(var(--pm-pad-min),
                       calc(var(--pm-pad-min) + (100% - 60rem) * 0.2427),
                       var(--pm-pad-max));
  --pm-panel:    calc(var(--pm-col) + 2 * var(--pm-pad));     /* band width: column + both insets */
  --pm-nav-foot: calc(var(--pm-nav-w) + var(--pm-nav-gap));   /* width the nav adds left of the panel */

  /* Panel perimeter hairline, one box-shadow per side so each band composes only
     the edges it needs (see "Panel outline"). */
  --pm-panel-edge-color: rgba(0, 0, 0, 0.10);
  --pm-edge-left:   -1px 0 0 var(--pm-panel-edge-color);
  --pm-edge-right:   1px 0 0 var(--pm-panel-edge-color);
  --pm-edge-top:     0 -1px 0 var(--pm-panel-edge-color);
  --pm-edge-bottom:  0 1px 0 var(--pm-panel-edge-color);
}

/* ----- Typography (Helvetica, light weight, per the original) ------------- */
:root { --md-text-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }

.md-typeset { font-weight: 300; line-height: 1.625; }
.md-typeset b,
.md-typeset strong { font-weight: 700; }
.md-typeset h1,
.md-typeset h2,
.md-typeset h3,
.md-typeset h4 { color: #111111; font-weight: 700; }

/* =========================================================================
   Material layout baseline — our starting point
   ---------------------------------------------------------------------------
   We keep Material's CSS bundle for content (.md-typeset), search, the mobile
   drawer, and code-copy, and re-skin only the DESKTOP chrome on top. The
   Material defaults the rules below inherit from or cancel:

     .md-grid              centres every band and caps its width. Cancelled (see
                           "Cancel Material's grid"); each band then offsets
                           itself into the shared column.
     .md-header            sticky, full-width, --md-primary-fg-color background
                           -> capped to content width, offset into the column.
     .md-banner            announce slot, full-width, scrolls away
                           -> capped to content width, offset into the column.
     .md-sidebar--primary  desktop = left nav column; mobile = drawer
                           -> hidden on desktop; our .pm-localnav replaces it.
     .md-sidebar--secondary  right ToC
                           -> folded into the primary by the toc.integrate feature.
     .md-content           flex child, fills remaining width, no background
                           -> fixed-width white panel on the grey page.

   Material has several responsive steps; we collapse them to the single
   threshold below. Under it, mobile = stock Material.
   ========================================================================= */

/* =========================================================================
   Two-tone background
   ========================================================================= */
/* Grey under everything so it shows in the gutters beside the content-width
   header and banner (desktop); behind the content panel it's covered by white. */
body { background-color: var(--pm-page-bg); }

.md-main {
  background-color: var(--pm-page-bg);                     /* grey page */
  display: flex;
  flex-direction: column;                                  /* let the inner grid fill full height */
}
.md-content {
  background-color: #ffffff;                               /* white content panel */
  /* Interior side inset (box-sizing: border-box). The text column is the panel
     minus twice this; as the inset grows 60em->80.6em the panel widens while the
     column holds, so growth lands in the inset, not the text. */
  padding-inline: var(--pm-pad);
}

/* Roomier content: more interior padding than Material's tight 0 .8rem so the
   text has breathing room inside the white pane. The text column fills the box
   inside its scaling side inset (above) — no width cap of its own, so it widens
   and narrows with the box rather than holding a fixed width. */
.md-content__inner {
  /* Cap the text column at --pm-col at ALL widths and centre it. Below 60em the
     panel is full-bleed (mobile), so this keeps the column at its fixed width as
     the window approaches 60em — crossing the breakpoint the column doesn't move,
     only the panel narrows and the gutters appear. At/above 60em the panel is
     already --pm-col wide inside its inset, so this is a no-op there. */
  max-width: var(--pm-col);
  margin: 0 auto 3rem;
  padding-top: var(--pm-content-pad-top);
}
.md-main__inner {
  /* Fill .md-main down to the footer (robust vs Material's height:100%). The
     grid's centring + width cap that would otherwise shrink-wrap this under the
     flex-column parent are cancelled in "Cancel Material's grid" above. */
  flex: 1 0 auto;
  margin-top: 0;   /* drop Material's top margin so the content reaches the nav bar */
}

/* =========================================================================
   Panel outline — banner, header, content, and footer share one hairline
   rectangle around the whole aligned column (desktop, where the bands sit over
   the grey page). Left + right on every band draw the continuous sides; the
   banner adds the top edge and the footer the bottom, closing the rectangle. The
   footer's top is kept too — it doubles as the content/footer divider. Internal
   dividers between the other regions come from their colour changes.
   ========================================================================= */
@media screen and (min-width: 60em) {
  .md-banner  { box-shadow: var(--pm-edge-left), var(--pm-edge-right), var(--pm-edge-top); }
  .md-header  { box-shadow: var(--pm-edge-left), var(--pm-edge-right); }
  .md-content { box-shadow: var(--pm-edge-left), var(--pm-edge-right); }
  .pm-footer  { box-shadow: var(--pm-edge-left), var(--pm-edge-right),
                            var(--pm-edge-top), var(--pm-edge-bottom); }
}

/* ----- Media embeds: responsive 16:9 iframe (YouTube / Vimeo) -------------
   Usage: <iframe class="pm-video" src="https://www.youtube.com/embed/ID" allowfullscreen></iframe> */
.pm-video { width: 100%; aspect-ratio: 16 / 9; border: 0; }

/* ----- Demo screencasts: responsive, but keep each clip's own shape --------
   For program demos whose recordings aren't 16:9 (e.g. small instrument GUIs).
   Set the clip's natural size per-embed so it shrinks responsively but never
   exceeds its source size or gets stretched:
   <iframe class="pm-demo" style="max-width: 270px; aspect-ratio: 270 / 151" ...></iframe> */
.pm-demo { width: 100%; height: auto; border: 0; display: block; }

/* ----- Banner: a single full-width image, no overlaid text ----------------- */
.md-banner { background-color: #000000; }   /* black behind the image, in case of gaps */
/* Drop Material's inner margin/padding so the image reaches the banner's edges
   (the grid cancel only zeroed the left/right margins, not these). */
.md-banner__inner { margin: 0; padding: 0; }
/* The link wraps the image as a block so there's no inline descender gap; the
   image spans the banner's width and its height follows from the aspect ratio. */
.pm-banner-link { display: block; }
.pm-banner-img { display: block; width: 100%; height: auto; }

/* =========================================================================
   Header bar + global mega-menu
   ========================================================================= */
.md-header { background: linear-gradient(#252525, #0a0a0a); }   /* dark gradient like #access */

/* The site title lives only in the drawer, never the nav bar (desktop or mobile).
   It was the header's height anchor, so pin the inner row to the standard bar
   height — otherwise the bar grows to fit the mega-menu / search instead. */
.md-header__title { display: none; }
.md-header__inner { height: 2.4rem; }

/* Desktop: breathing room left of the mega-menu and right of the search box
   (mobile keeps Material's tight edge spacing for the hamburger / search icon). */
@media screen and (min-width: 60em) {
  .md-header__inner { padding-left: 2rem; padding-right: 2rem; }
}

/* ----- Search box: colors from JythonMusic's header field.
   Resting/hover = grey box (#666) with light text; focused = light box (#f9f9f9)
   with dark (#222) text — matching JM, where the field lightens on focus and the
   resting placeholder is the browser's light default. */

/* resting + hover */
.md-search__form,
.md-search__form:hover            { background-color: #666666; }
.md-search__input                 { color: #eeeeee; }
.md-search__input::placeholder    { color: #cccccc; }
.md-search__icon,
.md-search__input ~ .md-search__icon { color: #dddddd; }

/* focused (search opened) */
[data-md-toggle="search"]:checked ~ .md-header .md-search__form              { background-color: #f9f9f9; }
[data-md-toggle="search"]:checked ~ .md-header .md-search__input             { color: #222222; }
[data-md-toggle="search"]:checked ~ .md-header .md-search__input::placeholder{ color: #666666; }
[data-md-toggle="search"]:checked ~ .md-header .md-search__icon,
[data-md-toggle="search"]:checked ~ .md-header .md-search__input ~ .md-search__icon { color: #222222; }

.pm-megamenu {
  display: flex;
  align-items: stretch;
  align-self: stretch;       /* fill the bar height so item highlights match it (header__inner is align-items:center) */
  margin-right: auto;        /* push search to the far right */
  color: #eeeeee;            /* light text on the dark bar */
}
.pm-megamenu__inner { position: relative; display: flex; align-items: stretch; }

.pm-megamenu__list { list-style: none; margin: 0; padding: 0; }
.pm-megamenu__item { position: relative; }

.pm-megamenu__label,
.pm-megamenu__link {
  display: block;
  padding: 0.55rem 0.9rem;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
  font-size: 0.72rem;
  cursor: pointer;
}

/* Top-level items fill the header height so the whole cell is a hover target. */
.pm-megamenu__inner > .pm-megamenu__list > .pm-megamenu__item { display: flex; align-items: stretch; }
.pm-megamenu__inner > .pm-megamenu__list > .pm-megamenu__item > .pm-megamenu__label,
.pm-megamenu__inner > .pm-megamenu__list > .pm-megamenu__item > .pm-megamenu__link {
  display: flex;
  align-items: center;
}

/* Hover (all levels) = blue, like the original nav. */
.pm-megamenu .pm-megamenu__item:hover > .pm-megamenu__label,
.pm-megamenu .pm-megamenu__item:hover > .pm-megamenu__link {
  background-color: #1982d1;
  color: #ffffff;
}
.pm-megamenu__link--active { font-weight: 700; box-shadow: inset 0 -3px 0 #1982d1; }

/* Top-level horizontal bar */
.pm-megamenu__inner > .pm-megamenu__list { display: flex; align-items: stretch; }

/* Nested submenus — light panels (#f9f9f9), hidden until hover. */
.pm-megamenu__list .pm-megamenu__list {
  display: none;
  position: absolute;
  min-width: 12rem;
  background-color: #f9f9f9;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.2);
  z-index: 10;
}
.pm-megamenu__list .pm-megamenu__list .pm-megamenu__label,
.pm-megamenu__list .pm-megamenu__list .pm-megamenu__link { color: #444444; font-size: 0.66rem; }
.pm-megamenu__list .pm-megamenu__list .pm-megamenu__item { border-bottom: 1px dotted #dddddd; }
.pm-megamenu__list .pm-megamenu__list .pm-megamenu__item:last-child { border-bottom: none; }

/* Separators (sentinel "sep:" nav entries; see navtools.py). A dashes-only title is
   a plain rule; any other title is a small grouped subheading. Space sits ABOVE the
   rule (giving it presence, grouping it with the items above) but it is flush BELOW:
   a gap below would push the next row's hover highlight down past the divider. */
.pm-megamenu__sep { list-style: none; margin: 0; border-top: 4px solid #cccccc; }
/* The item just above a divider drops its dotted rule so the two don't stack. */
.pm-megamenu__list .pm-megamenu__list .pm-megamenu__item:has(+ .pm-megamenu__sep) { border-bottom: none; }
.pm-megamenu__sep--labeled {
  margin: 0; border-top: none;
  padding: 0.35rem 0.7rem 0.15rem;
}
.pm-megamenu__sep-label {
  font-size: 0.55rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; color: #999999;
}

/* Level 2 drops down; level 3+ flies out to the right (depth-agnostic) */
.pm-megamenu__inner > .pm-megamenu__list
  > .pm-megamenu__item > .pm-megamenu__list { top: 100%; left: 0; }
.pm-megamenu__list .pm-megamenu__list .pm-megamenu__list { top: 0; left: 100%; }
.pm-megamenu__item:hover > .pm-megamenu__list { display: block; }
.pm-megamenu__list .pm-megamenu__list .pm-megamenu__item { display: block; }

/* Affordance carets — CSS triangles, not font glyphs, so each is a real box:
   the flex label (top level) and vertical-align (submenus) centre it cleanly in
   the row, and its size is the border widths — resizing never shifts the centring
   the way a glyph's baseline does. Colour follows the text via currentColor. */
.pm-megamenu__item--has-children > .pm-megamenu__label::after {
  content: "";
  display: inline-block;
  vertical-align: middle;        /* centre on the text in the block submenu rows */
  margin-left: 0.4rem;
  opacity: 0.7;
  /* default ▸ — points right (submenu items) */
  border-top: 0.25rem solid transparent;
  border-bottom: 0.25rem solid transparent;
  border-left: 0.30rem solid currentColor;
}
/* Top-level items: ▾ — points down */
.pm-megamenu__inner > .pm-megamenu__list
  > .pm-megamenu__item--has-children > .pm-megamenu__label::after {
  border-top: 0.30rem solid currentColor;
  border-bottom: 0;
  border-left: 0.25rem solid transparent;
  border-right: 0.25rem solid transparent;
}
.pm-megamenu__item--capped > .pm-megamenu__label { opacity: 0.6; cursor: default; }

/* Hide the mega-menu below 60em — Material's hamburger drawer takes over. */
@media screen and (max-width: 59.984375em) {
  .pm-megamenu { display: none; }
}

/* =========================================================================
   Cancel Material's grid — the single seam against its layout
   ---------------------------------------------------------------------------
   Drop .md-grid's auto side-margins + width cap on every band (header, banner,
   content, footer) so each can size and offset itself. This applies at ALL
   widths on purpose: our .md-main is a flex column (for the footer-fill), and a
   flex child with `margin: 0 auto` (the grid default) stops stretching and
   shrink-wraps to its content — which on mobile pulls the white content box in to
   the text column and exposes the grey page behind the inset. Below the desktop
   threshold the bands are full-width anyway, so cancelling the (non-binding) cap
   changes nothing visible there. */
.md-grid { margin-inline: 0; max-width: none; }

/* Desktop: the four bands — header, banner, content, footer — share one column,
   sized and positioned to the panel. Default is the nav-less case: centre the
   panel and shrink it with the window, keeping a grey gutter each side. Explicit
   width (not just max-width) keeps the sticky header from shrink-wrapping and
   collapsing the megamenu's margin-right:auto spacer; min() stays definite. */
@media screen and (min-width: 60em) {
  .md-header,
  .md-banner,
  .md-content,
  .pm-footer {
    width: min(var(--pm-panel), 100% - 2 * var(--pm-gutter));
    max-width: var(--pm-panel);
    margin-inline: auto;
  }

  /* Nav pages: a fixed-width bookmark fills the left slack and the panel shifts
     right by its footprint. --pm-panel-left is the panel's left edge — the
     nav+panel group centres once the window can hold it, else pins --pm-gutter
     from the edge. Set on body so the bands (header/banner outside .md-container)
     and the nav all inherit it. */
  body:has(.pm-localnav) {
    --pm-panel-left: max(var(--pm-gutter) + var(--pm-nav-foot),
                         (100% - var(--pm-panel)) / 2 + var(--pm-nav-foot) / 2);
  }
  /* Standalone bands offset to the panel's left edge. (.md-content flows in the
     grid row after the nav, so it's positioned in the .pm-localnav block below.) */
  body:has(.pm-localnav) .md-header,
  body:has(.pm-localnav) .md-banner,
  .md-container:has(.pm-localnav) .pm-footer {
    width: min(var(--pm-panel), 100% - var(--pm-panel-left) - var(--pm-gutter));
    margin-left: var(--pm-panel-left);
    margin-right: 0;
  }

  /* Grey gap above the banner (padding on the announce wrapper, not a top margin,
     to avoid margin-collapse so the grey reliably shows). */
  [data-md-component="announce"] { padding-top: var(--pm-page-top-gap); }
}

/* =========================================================================
   Contextual left column  (.pm-localnav) — desktop only, sits over the grey
   ========================================================================= */
.pm-localnav { display: none; }   /* mobile: hidden, drawer handles nav */

@media screen and (min-width: 60em) {
  .pm-localnav {
    display: block;
    align-self: flex-start;
    flex-shrink: 0;
    width: var(--pm-nav-w);
    padding: 1.2rem 0;
    position: sticky;
    top: 2.4rem;               /* clear the single-row header */
    /* Cap to the viewport (below the pinned header) and scroll independently,
       so long navs don't require scrolling the page to reach the bottom. */
    max-height: calc(100vh - 2.4rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    margin-left: calc(var(--pm-panel-left) - var(--pm-nav-foot));   /* the left slack */
  }

  /* Material's primary sidebar is the MOBILE drawer; hide its desktop column,
     and the now-redundant hamburger. */
  .md-sidebar--primary,
  .md-header [for="__drawer"] { display: none; }

  /* Content fills the panel and reaches the footer. Nav-less width and centring
     come from the shared band rule above; on nav pages it flows after the
     bookmark in the grid row, so its only offset is the gap to the nav. */
  .md-content { flex: 0 1 auto; align-self: stretch; }
  .md-container:has(.pm-localnav) .md-content {
    width: min(var(--pm-panel), 100% - var(--pm-panel-left) - var(--pm-gutter));
    margin-left: var(--pm-nav-gap);
    margin-right: 0;
  }

  /* Material re-sets the inner side margins at its sidebar-adjacent breakpoints;
     zero them (auto -> 0, since the inner fills its box) so the inset is set only
     by our padding on .md-content, not by Material's fixed inner margin. */
  [dir=ltr] .md-sidebar--primary:not([hidden]) ~ .md-content > .md-content__inner,
  [dir=ltr] .md-sidebar--secondary:not([hidden]) ~ .md-content > .md-content__inner,
  [dir=rtl] .md-sidebar--primary:not([hidden]) ~ .md-content > .md-content__inner,
  [dir=rtl] .md-sidebar--secondary:not([hidden]) ~ .md-content > .md-content__inner {
    margin-left: auto;
    margin-right: auto;
  }
}

.pm-localnav__list { list-style: none; margin: 0; padding: 0; }

/* Indent each nested level of the tree, with a faint guide line. */
.pm-localnav__list .pm-localnav__list {
  margin: 0.1rem 0 0.25rem 0.55rem;
  padding-left: 0.45rem;
  border-left: 1px solid var(--md-default-fg-color--lightest);
}

.pm-localnav__link,
.pm-localnav__section {
  display: block;
  padding: 0.25rem 0.6rem;
  font-size: 0.7rem;
  color: var(--md-default-fg-color--light);
  text-decoration: none;
}
.pm-localnav__section { font-weight: 700; opacity: 0.7; }
.pm-localnav__link:hover { color: #1982d1; }
.pm-localnav__link--active { color: #1982d1; font-weight: 700; }

/* Separators (sentinel "sep:" nav entries; see navtools.py): a plain rule, or a
   small grouped subheading when the entry carries a label. */
.pm-localnav__sep { list-style: none; margin: 0.4rem 0.6rem; border-top: 2px solid rgba(0, 0, 0, 0.15); }
.pm-localnav__sep--labeled { margin: 0.5rem 0 0.1rem; border-top: none; padding: 0.25rem 0.6rem 0; }
.pm-localnav__sep-label {
  font-size: 0.58rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--md-default-fg-color--light); opacity: 0.65;
}

/* =========================================================================
   Material default overrides
   ========================================================================= */

/* Hold the base font size constant — Material steps it up at 100em/125em,
   which reads as a jarring jump when widening the window. */
@media screen and (min-width: 100em) { html { font-size: 125%; } }
@media screen and (min-width: 125em) { html { font-size: 125%; } }

/* Logo removed from the nav bar. Material shows .md-header__button.md-logo at its
   wide breakpoint, so hide it explicitly (mobile never showed it anyway). In the
   mobile drawer, drop the logo too but keep the site-name title — the logo is
   absolutely positioned, so display:none leaves the title's height and padding
   untouched and the drawer's geometry unchanged. */
.md-header__button.md-logo,
.md-nav--primary .md-nav__title .md-logo { display: none; }

/* Tighten the drawer's site-title bar now the logo is gone: larger title text and
   roughly half the (logo-era) top padding, with the height shrinking to fit. The
   direct-child selector hits only the top-level site title, not the nested section
   titles, which keep their top room for the back-arrow. */
.md-nav--primary > .md-nav__title {
  font-size: 1.1rem;
  padding-top: 1.5rem;
  height: auto;
}

/* Tables always span their container (Material sizes them to content). */
.md-typeset__table { display: block; }
.md-typeset table:not([class]) { display: table; width: 100%; }

/* Horizontal rules only — no vertical/column borders — with thicker rules
   above and below the header row. (collapse so the thick header rule wins at
   the header/body boundary instead of doubling with the first row's border.) */
.md-typeset table:not([class]) {
  border-collapse: collapse;
  border-left: none;
  border-right: none;
  border-radius: 0;
}
.md-typeset table:not([class]) th,
.md-typeset table:not([class]) td {
  border-left: none;
  border-right: none;
}
.md-typeset table:not([class]) th {
  border-top: 0.12rem solid var(--md-typeset-table-color);
  border-bottom: 0.12rem solid var(--md-typeset-table-color);
}

/* =========================================================================
   Code syntax-highlighting knobs
   One color per Pygments token group (Material's mapping). Every value below is
   Material's current default, so this changes nothing as-is — tweak any line to
   recolor that group across all code blocks. The classes/examples after each
   show what it affects; "= #xxxxxx" notes the color a var currently resolves to.
   ========================================================================= */
:root,
[data-md-color-scheme="default"] {
  --md-code-fg-color: #36464e;            /* default code text                                    */
  --md-code-bg-color: #f5f5f5;            /* code block background                                */

  /* Vivid groups */
  --md-code-hl-keyword-color:  #3f6ec6;   /* keywords: from import def class if  (.k .kn .kd .kr .kt .kp .nd .nt) */
  --md-code-hl-function-color: #a846b9;   /* def/class/module names: def NAME(), class NAME, pkg  (.nf .nc .nn .ne) */
  --md-code-hl-constant-color: #6e59d9;   /* builtins & constants: True None len hex  (.nb .bp .no) */
  --md-code-hl-number-color:   #d52a2a;   /* numbers: 1 3.14 0xFF  (.m .mi .mf .mh .mo .mb .il) */
  --md-code-hl-string-color:   #1c7d4d;   /* strings: "..." '...'  (.s .s1 .s2 .sb .sc .si .ss .l) */
  --md-code-hl-special-color:  #db1457;   /* escapes / regex / preprocessor  (.se .sr .sh .sx .cp) */

  /* Muted groups — these are why a bare `obj.method()` looks uncolored:
     names resolve to the default text color, and operators/punctuation to grey. */
  --md-code-hl-name-color:        var(--md-code-fg-color);            /* names: variables, attributes, method calls  (.n .kc)  = #36464e */
  --md-code-hl-operator-color:    #3f6ec6;  /* operators: . = + - *  (.o .ow) */
  --md-code-hl-punctuation-color: var(--md-default-fg-color--light);  /* punctuation: ( ) , : [ ]  (.p)               = #0000008a */
  --md-code-hl-comment-color:     #388022;  /* comments / docstrings: # ...  (.c .c1 .cm .ch .cs .sd) */
  --md-code-hl-variable-color:    var(--md-default-fg-color--light);  /* attrs / vars: @decorator self.x  (.na .nv .vc .vg .vi)  = #0000008a */
  --md-code-hl-generic-color:     var(--md-default-fg-color--light);  /* generic / diff output  (.ge .gh .go .gp .gr .gs .gt .gu) = #0000008a */

  --md-code-hl-color: #4287ff;            /* highlighted-line background accent (linenums hl_lines) */
}

/* =========================================================================
   Footer — JythonMusic-style. Restricted to the content width and aligned
   under it: left column = Reference (book cover + citation); right column =
   License and Source Code stacked.
   ========================================================================= */
.md-footer { background-color: var(--pm-page-bg); }                              /* grey surround, matches the page */
.pm-footer {
  background-color: var(--md-code-bg-color);   /* light band, same as code blocks */
  color: var(--md-typeset-color);              /* body text colour */
  /* Width, alignment, and perimeter hairline come from the shared band rule and
     "Panel outline" — the footer is one of the four aligned bands. */
}

.pm-footer__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem 2.5rem;
  padding: 1.5rem 2rem;                 /* matches the content box's 2rem text inset */
}
/* Reference and the License/Source stack each take a third; the remaining third
   stays blank on the right (neither column grows). Widen the stack's basis if
   its content ends up taller than Reference. */
.pm-footer__col--reference { flex: 0 1 33.33%; min-width: 13rem; }
.pm-footer__stack          { flex: 0 1 33.33%; min-width: 13rem; display: flex; flex-direction: column; gap: 1rem; }

.pm-footer__reference { display: flex; gap: 1rem; align-items: flex-start; }
.pm-footer__cover     { width: 84px; height: auto; flex-shrink: 0; }
.pm-footer__cc        { height: 1.6em; width: auto; vertical-align: middle; margin-right: 0.4rem; }

.pm-footer__title {
  margin: 0 0 0.4rem;
  font-size: 0.72rem;
  font-weight: 700;
  color: #666666;
}
.pm-footer p { margin: 0; font-size: 0.6rem; line-height: 1.6; }
.pm-footer a { color: #1982d1; }
.pm-footer a:hover { text-decoration: underline; }
