/* ==========================================================================
   Kedgeree, a modern theme for Haddock.
   Main documentation pages. Source pages are themed by kedgeree-source.css.

   Palette and bundled fonts live in kedgeree-tokens.css, loaded before this
   file. Here we only consume the --kg-* custom properties.
   ========================================================================== */

/* ==========================================================================
   Base
   ========================================================================== */
/* Reset, plus the structural rules Haddock's bundle relies on. */
* { margin: 0; padding: 0; }
*, *::before, *::after { box-sizing: border-box; }

/* Haddock's bundle uses these to toggle instances/synopsis. The bundle adds
   body.js-enabled only after load, so we also key off data-js, which boot stamps
   on <html> before first paint. Otherwise these labels paint then vanish in a
   reflow (most visible as the contents page's module tree settling). */
body.js-enabled .hide-when-js-enabled,
html[data-js] .hide-when-js-enabled { display: none; }
.hide { display: none; }
.show { display: inherit; }
.hidden { display: none !important; }
/* MathJax's corner "Processing math" load indicator. Math still typesets. */
#MathJax_Message { display: none !important; }

/* Collapse/expand chevrons. Haddock's bundle JS toggles .collapser (open) /
   .expander (closed) on the toggle controls. Drawn as an SVG chevron via
   mask-image (background-color is the ink) so every toggle matches. The bundled
   subset fonts have no triangle glyph. A matching .noexpander spacer keeps
   module names aligned in the module tree. */
.collapser, .expander, .details-toggle-control { cursor: pointer; }
.expander::before,
.collapser::before {
  content: "";
  display: inline-block;
  width: 0.7em;
  height: 1em;
  margin-right: 0.28em;
  vertical-align: -0.18em;
  background-color: var(--kg-fg-faint);
  -webkit-mask: var(--kg-chevron) left center / auto 0.66em no-repeat;
  mask: var(--kg-chevron) left center / auto 0.66em no-repeat;
}
.collapser::before {
  -webkit-mask-image: var(--kg-chevron-open);
  mask-image: var(--kg-chevron-open);
  -webkit-mask-size: 0.66em auto;
  mask-size: 0.66em auto;
}
.noexpander::before { content: ""; display: inline-block; width: 0.98em; }
/* In the JS path (boot stamps data-js before first paint) reserve the chevron's
   box on the bare toggle control, so a row does not shift sideways when the
   bundle later adds .collapser / .expander and the chevron grows in. Dimensions
   only, so .collapser / .expander still own the chevron itself. */
html[data-js] .details-toggle-control::before {
  content: "";
  display: inline-block;
  width: 0.7em;
  height: 1em;
  margin-right: 0.28em;
  vertical-align: -0.18em;
}
/* The module tree is always open once JS runs, so draw its open chevron up front.
   The contents page is then static from first paint, no chevron popping in per
   row. Same mask as .collapser::before, so it matches exactly. */
html[data-js] #module-list .details-toggle-control::before {
  background-color: var(--kg-fg-faint);
  -webkit-mask: var(--kg-chevron-open) left center / 0.66em auto no-repeat;
  mask: var(--kg-chevron-open) left center / 0.66em auto no-repeat;
}
/* Uniform hover for every toggle (module tree, instances, instance/Examples
   section headers, synopsis). Accent the chevron, brighten heading-style
   toggles. */
body.js-enabled .details-toggle-control:hover::before,
body.js-enabled #synopsis summary:hover::before { background-color: var(--kg-accent); }
/* The module-tree chevron is painted by an id-specific rule above, so its hover
   accent must match that specificity to win. */
body.js-enabled #module-list .details-toggle-control:hover::before { background-color: var(--kg-accent); }
body.js-enabled :is(h2, h3, h4, h5, h6).details-toggle-control { transition: color 0.12s ease; }
body.js-enabled :is(h2, h3, h4, h5, h6).details-toggle-control:hover { color: var(--kg-fg); }

/* Make native controls (checkboxes, scrollbars, form fields) match the theme. */
:root {
  color-scheme: light;
  /* One chevron icon for every toggle (mask-image, so background-color is the
     ink and it recolours on hover). */
  --kg-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 14' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1.6 2 6.2 7 1.6 12'/%3E%3C/svg%3E");
  --kg-chevron-open: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 8' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 1.6 7 6.2 12 1.6'/%3E%3C/svg%3E");
  /* Code glyph for the Source link (mask-image, inked by currentColor). */
  --kg-icon-source: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 6L2 12L8 18'/%3E%3Cpath d='M16 6L22 12L16 18'/%3E%3C/svg%3E");
}
html[data-resolved="dark"] { color-scheme: dark; }
@media (prefers-color-scheme: dark) {
  :root:not([data-resolved="light"]) { color-scheme: dark; }
}

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

body {
  margin: 0;
  background: var(--kg-bg);
  color: var(--kg-fg);
  font-family: var(--kg-font);
  font-size: 16px;
  line-height: 1.62;
  letter-spacing: 0.001em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;

  /* Three-row grid: header / (sidebar · main) / full-width footer. */
  display: grid;
  grid-template-columns: var(--kg-sidebar-w) minmax(0, 1fr);
  grid-template-rows: var(--kg-header-h) 1fr auto;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  min-height: 100vh;
}

/* No sidebar yet, or only a minimal mobile drawer (contents / index pages):
   collapse the desktop column. */
body:not(.kg-has-sidebar),
body.kg-sidebar-min {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "header"
    "main"
    "footer";
}
body.kg-sidebar-min #kg-sidebar { display: none; }

/* :link/:visited overrides Haddock's link color. */
a, a[href]:link { color: var(--kg-link); text-decoration: none; }
a[href]:visited { color: var(--kg-link-visited); }
a:hover, a[href]:hover { text-decoration: underline; }

code, pre, .src, tt, .hs-identifier, .keyword {
  font-family: var(--kg-mono);
}
/* Signatures keep operators literal (no -> ligature). Prose code blocks keep the
   font's ligatures, matching the hyperlinked source pages. */
.src, .hs-identifier, .keyword { font-variant-ligatures: none; }

/* Images and other media never overflow their column on a narrow screen. */
img, svg, video, iframe { max-width: 100%; height: auto; }

/* A lone over-long token (a 50-char identifier in prose, a bare URL) must wrap
   rather than push the page wider than the viewport. Code blocks and the
   scrolling sub-block signatures keep their own horizontal scroll, so they opt
   out. (.kg-sig breaks instead, see its rule.) */
body { overflow-wrap: anywhere; }
.src, pre { overflow-wrap: normal; }

::selection { background: var(--kg-accent-soft); }

/* ==========================================================================
   Header bar (Haddock's #package-header)
   ========================================================================== */
#package-header {
  grid-area: header;
  width: 100%;
  box-sizing: border-box;
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  height: var(--kg-header-h);
  padding: 0 1rem;
  background: color-mix(in srgb, var(--kg-bg-raised) 88%, transparent);
  backdrop-filter: saturate(1.2) blur(8px);
  border-bottom: 1px solid var(--kg-border);
  font-size: 0.9rem;
}

/* The brand (package name) is the nav title. Haddock's package caption
   ("pkgid: synopsis") duplicates it and its markup varies by version, so hide
   it rather than render or parse it. */
#package-header .caption { display: none; }

#package-header ul.links,
#package-header #page-menu {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  /* .kg-actions (margin-left:auto) does the right-alignment. The page menu sits
     after it with a small gap. Two auto margins would split the free space and
     float the search to the centre until the script ran. */
  margin: 0 0 0 0.5rem;
  padding: 0;
  list-style: none;
}

#package-header #page-menu li { margin: 0; color: var(--kg-fg-faint); }
/* Space the separators off the hover pills. */
#package-header #page-menu li + li::before { margin: 0 0.9rem; color: var(--kg-fg-faint); }

/* :link/:visited overrides Haddock's link color. */
#package-header #page-menu a,
#package-header #page-menu a:link,
#package-header #page-menu a:visited {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.5rem;
  margin: 0 -0.1rem;
  border-radius: var(--kg-radius-s);
  color: var(--kg-fg-muted);
}
#package-header #page-menu a:hover {
  background: var(--kg-accent-soft);
  color: var(--kg-fg);
  text-decoration: none;
}
/* Quick-jump may render its trigger as a <button> in the menu. */
#package-header #page-menu button {
  color: var(--kg-fg-muted);
  background: none;
  border: none;
  cursor: pointer;
  font: inherit;
}
#package-header #page-menu button:hover { color: var(--kg-fg); }
/* Our Instances dropdown: a <details> whose summary sits among the nav links,
   menu popping out below. */
#package-header #page-menu .kg-instances { position: relative; }
#package-header #page-menu .kg-instances > summary {
  list-style: none;
  padding: 0.3rem 0.5rem;
  margin: 0 -0.1rem;
  border-radius: var(--kg-radius-s);
  color: var(--kg-fg-muted);
  cursor: pointer;
}
#package-header #page-menu .kg-instances > summary::-webkit-details-marker { display: none; }
#package-header #page-menu .kg-instances > summary:hover,
#package-header #page-menu .kg-instances[open] > summary {
  background: var(--kg-accent-soft);
  color: var(--kg-fg);
}
.kg-instances-menu {
  position: absolute;
  top: calc(100% + 0.35rem);
  right: 0;
  margin: 0;
  padding: 0.3rem;
  list-style: none;
  background: var(--kg-bg-raised);
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius-s);
  box-shadow: 0 10px 30px var(--kg-shadow);
  min-width: 13rem;
  z-index: 60;
}
.kg-instances-menu li { margin: 0; }
.kg-instances-menu li + li::before { content: none; }
.kg-instances-menu button {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.4rem 0.55rem;
  border: none;
  background: none;
  border-radius: var(--kg-radius-s);
  color: var(--kg-fg-muted);
  cursor: pointer;
  font: inherit;
  white-space: nowrap;
}
.kg-instances-menu button:hover {
  background: var(--kg-accent-soft);
  color: var(--kg-fg);
}

/* Brand + theme toggle injected by kedgeree.js. */
.kg-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  color: var(--kg-fg);
}
.kg-brand svg { width: 1.4rem; height: 1.4rem; color: var(--kg-accent); }

/* Brand mark: a plain lambda for now. */
.kg-lambda {
  color: var(--kg-accent);
  font-family: var(--kg-mono);
  font-weight: 700;
  font-size: 1.15em;
  line-height: 1;
}

.kg-iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius-s);
  background: var(--kg-bg-raised);
  color: var(--kg-fg-muted);
  cursor: pointer;
}
.kg-iconbtn:hover { color: var(--kg-fg); border-color: var(--kg-border-strong); }
/* Button icons are masks from icons/*.svg, inked with currentColor. No inline
   SVG in the markup, so the same files serve the server-rendered and JS-built
   buttons. Each button picks its glyph via --kg-icon. */
.kg-menu-toggle::before,
.kg-theme::before,
.kg-search::before {
  content: "";
  flex: 0 0 auto;
  width: 1.1rem;
  height: 1.1rem;
  background-color: currentColor;
  -webkit-mask: var(--kg-icon) center / contain no-repeat;
  mask: var(--kg-icon) center / contain no-repeat;
}
.kg-menu-toggle { --kg-icon: url("icons/menu.svg"); }
.kg-theme { --kg-icon: url("icons/auto.svg"); }
html[data-theme="light"] .kg-theme { --kg-icon: url("icons/sun.svg"); }
html[data-theme="dark"] .kg-theme { --kg-icon: url("icons/moon.svg"); }

/* Header search trigger. */
.kg-search {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  height: 2rem;
  padding: 0 0.6rem;
  min-width: 12rem;
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius-s);
  background: var(--kg-bg-raised);
  color: var(--kg-fg-faint);
  cursor: text;
  font-size: 0.85rem;
}
.kg-search:hover { border-color: var(--kg-border-strong); }
.kg-search::before { --kg-icon: url("icons/search.svg"); width: 1rem; height: 1rem; }
.kg-search kbd { margin-left: auto; }

kbd {
  font-family: var(--kg-mono);
  font-size: 0.72rem;
  padding: 0.05rem 0.35rem;
  border: 1px solid var(--kg-border-strong);
  border-bottom-width: 2px;
  border-radius: 4px;
  background: var(--kg-bg-sunken);
  color: var(--kg-fg-muted);
}

/* ==========================================================================
   Sidebar (built by kedgeree.js)
   ========================================================================== */
#kg-sidebar {
  grid-area: sidebar;
  position: sticky;
  top: var(--kg-header-h);
  align-self: start;
  height: calc(100vh - var(--kg-header-h));
  overflow-y: auto;
  /* The full-height sticky sidebar reaches the viewport bottom, where the
     lifted footer (z-index) paints over it. Generous bottom padding lets the
     last nav items scroll up clear of that footer strip. */
  padding: 1.25rem 0.75rem 7rem 1.25rem;
  border-right: 1px solid var(--kg-border);
  background: var(--kg-bg);
  font-size: 0.875rem;
  overscroll-behavior: contain;
}

.kg-sb-title {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--kg-fg-faint);
  margin: 1.25rem 0 0.4rem;
}
.kg-sb-title:first-child { margin-top: 0; }

#kg-sidebar ul { list-style: none; margin: 0; padding: 0; }
#kg-sidebar li { margin: 0; }

#kg-sidebar a {
  display: block;
  padding: 0.22rem 0.5rem;
  border-radius: var(--kg-radius-s);
  color: var(--kg-fg-muted);
  border-left: 2px solid transparent;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#kg-sidebar a:hover { background: var(--kg-bg-sunken); color: var(--kg-fg); text-decoration: none; }
#kg-sidebar a.kg-active {
  color: var(--kg-accent-strong);
  background: var(--kg-accent-soft);
  border-left-color: var(--kg-accent);
  font-weight: 600;
}
#kg-sidebar .kg-sb-sub a { padding-left: 1.25rem; font-size: 0.83rem; }
/* Top-level section entries read as parents of the declarations nested under. */
#kg-sidebar .kg-sb-contents > li > a { color: var(--kg-fg); font-weight: 600; }

/* The original inline TOC is redundant once the sidebar exists. */
body.kg-has-sidebar #table-of-contents { display: none; }

/* Mobile drawer toggle (hidden on wide screens). */
.kg-menu-toggle { display: none; }

/* ==========================================================================
   Main content
   ========================================================================== */
#content {
  grid-area: main;
  width: 100%;
  /* min-width: 0 lets this grid item shrink below its content's intrinsic width,
     so wide code (example blocks, long signatures) scrolls inside its own box
     instead of forcing the whole page wider than the viewport. */
  min-width: 0;
  max-width: var(--kg-content-max);
  margin: 0 auto;
  padding: 2rem 1.5rem 4rem;
  box-sizing: border-box;
}

/* The sidebar's module-name entry jumps here. Keep it clear of the sticky
   header, like the section headings and declaration blocks. */
#module-header { scroll-margin-top: calc(var(--kg-header-h) + 1rem); }

#module-header .caption {
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0.25rem 0 1rem;
  color: var(--kg-fg);
}

#description .caption,
#synopsis > .caption,
.subs > .caption,
#interface .caption {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--kg-fg-faint);
}

/* Section headings (the # g:N anchors). */
#interface h1 {
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 2.5rem 0 0.5rem;
  padding-bottom: 0.4rem;
  /* A rule that starts defined under the heading and fades out to the right,
     softer than a hard full-width line. */
  background-image: linear-gradient(
    to right,
    var(--kg-border-strong),
    var(--kg-border) 30%,
    transparent 85%
  );
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 100% 1px;
  scroll-margin-top: calc(var(--kg-header-h) + 1rem);
}
#interface a:hover h1 { text-decoration: none; }

h2, h3, h4 { letter-spacing: -0.01em; }

/* Doc sub-headings (=== / ==== in doc comments, e.g. "Examples"). Collapsible
   via Haddock's details-toggle, hence the pointer cursor from
   .details-toggle-control. Real spacing and weight so they read as section
   labels rather than cramped bold text. */
.subheading {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--kg-fg);
  margin: 1.5rem 0 0.5rem;
}

p { margin: 0.7em 0; }

/* Prose blocks. Long identifiers / code-links must break rather than push the
   page wider than the viewport on narrow screens. */
.doc { color: var(--kg-fg); overflow-wrap: break-word; }
.doc p { margin: 0.6em 0; }
.doc strong { font-weight: 700; }
.doc code, .doc a { overflow-wrap: anywhere; }
/* The column is wide for code, so keep doc prose at a readable measure. Code
   blocks and tables inside docs keep the full width. */
.doc p,
.doc ul,
.doc ol,
.doc dl,
.doc blockquote { max-width: var(--kg-prose-max); }

/* Documentation lists (the reset clears list defaults). */
.doc ul, .doc ol { margin: 0.6em 0; padding-left: 1.6rem; }
.doc li { margin: 0.25em 0; }
.doc ul { list-style: disc; }
.doc ol { list-style: decimal; }
.doc ul ul { list-style: circle; }
.doc ul ul ul { list-style: square; }
.doc li > ul, .doc li > ol { margin: 0.25em 0; }

/* Inline code in prose. */
.doc code, .doc tt, p code, li code, td.doc code {
  background: var(--kg-code-bg);
  border: 1px solid var(--kg-border);
  border-radius: 5px;
  padding: 0.08em 0.36em;
  font-size: 0.9em;
}
.doc a code { color: var(--kg-link); }

/* Code blocks. */
pre {
  background: var(--kg-code-bg);
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius);
  padding: 0.9rem 1.1rem;
  margin: 1rem 0;
  overflow-x: auto;
  line-height: 1.5;
  font-size: 0.875rem;
}
/* Reset inline-code styling inside a code block. Without the .doc prefix this
   loses to .doc code on specificity, leaving the boxed, shrunken code that breaks
   the monospace grid the author aligned arrows to. font-size goes back to the
   block's so every glyph shares one cell width. */
.doc pre code, pre code { background: none; border: none; padding: 0; font-size: inherit; }

/* Interactive examples. Haddock renders >>> blocks as <pre class="screen">,
   with each input as <code class="prompt">&gt;&gt;&gt;</code><strong
   class="userinput">…</strong> and the expected output as the following text.
   Prompt faint and unselectable, input emphasised, output muted, so the block
   reads like a transcript. */
pre.screen {
  color: var(--kg-fg-muted);
}
pre.screen .prompt {
  color: var(--kg-fg-faint);
  font-weight: 400;
  user-select: none;
  -webkit-user-select: none;
}
pre.screen .userinput,
pre.screen .userinput code {
  color: var(--kg-fg);
  font-weight: 600;
}

blockquote {
  margin: 1rem 0;
  padding: 0.4rem 1rem;
  border-left: 3px solid var(--kg-accent);
  background: var(--kg-bg-sunken);
  border-radius: 0 var(--kg-radius-s) var(--kg-radius-s) 0;
  color: var(--kg-fg-muted);
}

/* ==========================================================================
   Declarations (the .top / .src signature blocks)
   ========================================================================== */
/* Each declaration: a flush signature with its doc and sub-items below, parted
   from the next by a divider. Positioning context for the Source link. */
.top {
  display: flex;
  flex-direction: column;
  position: relative;
  margin: 0;
  padding: 1.15rem 0;
  scroll-margin-top: calc(var(--kg-header-h) + 1rem);
}
.top + .top { border-top: 1px solid var(--kg-border); }

p.src,
.top > .src,
.subs .src,
td.src,
.decl {
  background: var(--kg-bg-raised);
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius);
  padding: 0.7rem 0.95rem;
  font-family: var(--kg-mono);
  font-size: 0.875rem;
  line-height: 1.45;
  overflow-x: auto;
}

/* Flush signature, no card framing (resets the shared box rule above). */
.top > .src {
  position: relative;
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
  padding-right: 2.25rem;
  overflow: visible;
}
/* Doc and sub-items sit flush at the left edge, grouped by their captions and
   dividers. */
/* Full-width signature. Soft-wraps with a hanging indent so a wrapped line lines
   up under the first token. An over-long token breaks rather than scrolling. */
.kg-sig {
  display: block;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  padding-left: 2ch;
  text-indent: -2ch;
}

/* Synopsis: an in-flow collapsible list of signatures. */
#synopsis {
  position: static;
  float: none;
  inset: auto;
  top: auto;
  right: auto;
  bottom: auto;
  width: auto;
  max-width: none;
  z-index: auto;
  margin: 1.5rem 0;
}
/* The summary is a bar, exactly like every other collapsible header (Examples,
   Instances, sub-headings) so all the expand/collapse affordances match. */
#synopsis summary {
  display: block;
  float: none;
  width: auto;
  height: auto;
  cursor: pointer;
  padding: 0.5rem 0.7rem;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--kg-fg);
  background: var(--kg-bg-raised) !important;
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius-s);
  list-style: none;
  user-select: none;
  transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
#synopsis summary:hover {
  border-color: var(--kg-accent);
  background: var(--kg-accent-soft) !important;
}
#synopsis summary::-webkit-details-marker { display: none; }
/* Same chevron icon as every other toggle (see :root --kg-chevron). */
#synopsis summary::before {
  content: "";
  display: inline-block;
  width: 0.7em;
  height: 1em;
  margin-right: 0.3em;
  vertical-align: -0.18em;
  background-color: var(--kg-fg-muted);
  -webkit-mask: var(--kg-chevron) left center / auto 0.66em no-repeat;
  mask: var(--kg-chevron) left center / auto 0.66em no-repeat;
}
#synopsis details[open] summary::before {
  -webkit-mask-image: var(--kg-chevron-open);
  mask-image: var(--kg-chevron-open);
  -webkit-mask-size: 0.66em auto;
  mask-size: 0.66em auto;
}
#synopsis ul.details-toggle { margin: 0.6rem 0 0; padding: 0.1rem 0.7rem; list-style: none; }
#synopsis li.src.short {
  background: none;
  border: none;
  padding: 0.18rem 0;
  font-family: var(--kg-mono);
  font-size: 0.82rem;
  white-space: pre-wrap;
  overflow-x: auto;
}

/* Keyword / identifier coloring in declarations and synopsis. */
.keyword, .hs-keyword { color: var(--kg-syn-keyword); font-style: normal; }
.src a.def, a.def { color: var(--kg-fg); font-weight: 600; }
.src a.def:hover { color: var(--kg-accent-strong); }

/* Type references in a signature are hyperlinks (Source/# links are excluded by
   class, the defined name has no href). Color them as types, matching the source
   pages, so signatures read as highlighted code. A faint underline keeps them
   obviously clickable, and it strengthens to the accent on hover. */
.src a[href]:not(.link):not(.selflink),
.src a[href]:not(.link):not(.selflink):visited {
  color: var(--kg-syn-type);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--kg-syn-type) 32%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
.src a[href]:not(.link):not(.selflink):hover {
  color: var(--kg-accent);
  text-decoration-color: currentColor;
}

/* The Source / # links. wrapSourceLinks (Rewrite.hs) groups each declaration's
   pair into a .kg-srclinks span, pinned to the top-right of the signature.
   text-indent: 0 keeps the box itself out of the signature's hanging indent. */
a.link, a.selflink {
  color: var(--kg-fg-faint);
  font-family: var(--kg-font);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.5;
}
a.link:hover, a.selflink:hover { color: var(--kg-accent); text-decoration: none; }

/* Source-link chip, pinned top-right of its signature (positioned below). The
   box turns relative and drops clipping so the chip can sit in the corner. */
.src:has(> .kg-srclinks) {
  position: relative;
  overflow: visible;
}
.kg-srclinks {
  position: absolute;
  right: 0.7rem;
  bottom: 0;
  transform: translateY(70%);
  display: inline-flex;
  align-items: center;
  gap: 0;
  padding: 0.22rem 0.28rem;
  background: var(--kg-bg-raised);
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius-s);
  box-shadow: 0 1px 2px var(--kg-shadow);
  text-indent: 0;
  z-index: 3;
  transition: border-color 0.12s ease, background-color 0.12s ease;
}
/* Render the Source link as a code glyph. The "Source" text stays (font-size 0)
   as the accessible name. */
.kg-srclinks a.link {
  display: inline-flex;
  font-size: 0;
  line-height: 0;
}
.kg-srclinks a.link::before {
  content: "";
  width: 0.92rem;
  height: 0.92rem;
  background-color: currentColor;
  -webkit-mask: var(--kg-icon-source) center / contain no-repeat;
  mask: var(--kg-icon-source) center / contain no-repeat;
}
/* Solid background and accent border on hover. */
.kg-srclinks:hover {
  background: var(--kg-border-strong);
  border-color: var(--kg-accent);
}
.kg-srclinks:hover a.link { color: var(--kg-accent); }
/* Pin every Source chip to the top-right of its signature, aligned with the
   first line. The signature reserves padding-right so they never overlap. */
.top > .src > .kg-srclinks,
.subs .src > .kg-srclinks,
[id="section.orphans"] td.src > .kg-srclinks {
  top: 0;
  right: 0;
  bottom: auto;
  transform: none;
}
.subs .src:has(> .kg-srclinks),
[id="section.orphans"] td.src:has(> .kg-srclinks) { padding-right: 2.25rem; }
/* On an instance card the chip tucks into the corner: match the card radius,
   square the inner edges. */
.instances td.src > .kg-srclinks,
[id="section.orphans"] td.src > .kg-srclinks {
  border-radius: 0 var(--kg-radius-s) 0 var(--kg-radius-s);
}
/* No-JS: the # permalink fades in on hover (hidden entirely when JS is live). */
.kg-srclinks a.selflink { opacity: 0; transition: opacity 0.12s; }
.src:hover .kg-srclinks a.selflink { opacity: 1; }
@media (hover: none) { .kg-srclinks a.selflink { opacity: 1; } }
/* JS makes the box its own anchor (see wireSelfAnchors), so hide the redundant
   # when JS is live. */
html[data-js] .kg-srclinks a.selflink { display: none; }
/* Anchor-link signatures take a faint hover highlight. A box-shadow spread adds
   breathing room with no margin/padding, so nothing shifts out of alignment. */
html[data-js] .src.kg-anchorable {
  cursor: pointer;
  border-radius: var(--kg-radius-s);
  transition: background-color 0.12s ease, box-shadow 0.12s ease;
}
html[data-js] .src.kg-anchorable:hover {
  background-color: var(--kg-bg-raised);
  box-shadow: 0 0 0 0.3rem var(--kg-bg-raised);
}
/* A re-export carries only a # selflink and no Source. With the # hidden, that
   pill would be empty, so drop it entirely when there is no Source link in it.
   The box is still its own anchor (wireSelfAnchors reads the hidden selflink). */
.kg-srclinks:not(:has(a.link)) { display: none; }
/* Inside an instance the links are redundant. Every # points at the class
   anchor (the same place for every instance), and a method's Source points at
   the class method already on the page. Drop both: hide every # here, and hide
   the method tags in the expanded body. The head keeps its Source, which is the
   one useful link, the instance's own definition. */
.instances .kg-srclinks a.selflink,
[id="section.orphans"] .kg-srclinks a.selflink { display: none; }
.instances td[colspan] .kg-srclinks,
[id="section.orphans"] td[colspan] .kg-srclinks { display: none; }

/* breakLongSigs (Rewrite.hs) breaks long signatures before each top-level
   operator. It marks the element it breaks (<p>, <td>, <dfn>), which needs
   pre-wrap so the breaks render. A <p> decl breaks with a bare newline and keeps
   .kg-sig's hanging indent, so a too-long broken line soft-wraps in line with the
   operators rather than back to the margin. Other elements use an explicit
   two-space indent. */
.kg-multiline { white-space: pre-wrap; }
/* The :: -> => operators (wrapped server-side by breakLongSigs). Colored to
   complete the signature syntax highlighting, and kept whole so a narrow viewport
   wraps at the spaces around them, never between a hyphen and its angle bracket. */
.kg-op { color: var(--kg-syn-operator); white-space: nowrap; }
/* A parenthesized group (a binder like (b :: k2), a tuple, a constraint context)
   stays whole, so a long signature soft-wraps between groups rather than inside
   one. An over-wide group scrolls with the rest of .kg-sig. */
.kg-grp { white-space: nowrap; }

/* ==========================================================================
   Sub-blocks: constructors, methods, instances
   ========================================================================== */
.subs { margin: 0.6rem 0 0; }
.subs.constructors table,
.subs.methods table,
.subs.fields table,
.subs.bundled-patterns table { width: 100%; border-collapse: collapse; }

.subs.constructors td,
.subs.methods td,
.subs.fields td,
.subs.bundled-patterns td {
  padding: 0.4rem 0;
  vertical-align: top;
}
/* Sub-item signatures drop the fill and borders to match the flush top-level
   ones. */
.subs td.src,
.subs .src {
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
  white-space: pre-wrap;
}
/* A divider between sub-items, set on the 2nd-and-later item, so the first has
   no line above and the last none below. */
.subs.methods .doc + .src,
.subs.methods .src + .src,
.subs.fields ul li + li,
.subs.constructors tr + tr,
.subs.bundled-patterns tr + tr {
  position: relative;
  margin-top: 1.4rem;
}
/* Draw it as a ::before line in the margin gap, so the item box starts at its
   text and the Source chip aligns to the first line. */
.subs.methods .doc + .src::before,
.subs.methods .src + .src::before,
.subs.fields ul li + li::before,
.subs.constructors tr + tr::before,
.subs.bundled-patterns tr + tr::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -0.7rem;
  border-top: 1px solid var(--kg-border);
}
.subs td.doc { color: var(--kg-fg-muted); }
.subs td.doc.empty { display: none; }

/* Constructors and bundled patterns stack at every width: signature on its own
   line (a code bar), description below. Side by side, a long signature squishes
   the prose. This also keeps them consistent with every other declaration, which
   puts the description on a new line. */
.subs.constructors table,
.subs.constructors tbody,
.subs.constructors tr,
.subs.constructors td,
.subs.bundled-patterns table,
.subs.bundled-patterns tbody,
.subs.bundled-patterns tr,
.subs.bundled-patterns td { display: block; }
.subs.constructors td.src,
.subs.bundled-patterns td.src { overflow-x: auto; }
.subs.constructors td.doc,
.subs.bundled-patterns td.doc { padding: 0.45rem 0.6rem 0.7rem; }
/* An Examples section in a constructor or bundled-pattern doc cell breaks out of
   the cell padding so it spans and aligns like the ones on functions, header and
   body together (otherwise the body reads narrower than its own header). */
.subs.constructors td.doc > :is(h2, h3, h4, h5, h6).details-toggle-control,
.subs.constructors td.doc > details,
.subs.bundled-patterns td.doc > :is(h2, h3, h4, h5, h6).details-toggle-control,
.subs.bundled-patterns td.doc > details {
  margin-left: -0.6rem;
  margin-right: -0.6rem;
}
.subs.constructors td.doc.empty,
.subs.bundled-patterns td.doc.empty { display: none; padding: 0; }

/* Record fields stack: signature above, description below. (Haddock renders
   these as a table, so the selectors target ul/li/dfn to override it.) */
.subs.fields { padding-left: 0; }
.subs.fields ul { display: block; margin: 0.3rem 0 0; list-style: none; }
.subs.fields ul li {
  display: block;
  padding: 0.5rem 0 0;
}
.subs.fields ul li:last-child { border-bottom: none; }
.subs.fields ul li dfn,
.subs.fields ul li dfn.src {
  display: block;
  background: none;
  border: none;
  padding: 0;
  font-family: var(--kg-mono);
  /* The field type reads lighter than the field name: normal weight and muted,
     so the bold, full-colour name (the a.def, styled separately) leads while the
     type recedes. <dfn> is italic by default, hard to read in mono. */
  font-weight: 400;
  font-style: normal;
  color: var(--kg-fg-muted);
  white-space: pre-wrap;
  overflow-x: auto;
}
.subs.fields ul li > .doc {
  display: block;
  padding: 0.4rem 0 0;
  color: var(--kg-fg-muted);
}
.subs.fields ul li > .doc p { margin: 0; }

/* ==========================================================================
   Instances: stacked accordion cards
   Haddock renders each instance as a head row (its signature + doc + a toggle)
   followed by a detail row (a <details> it shows/hides). We box each instance:
   the head is a rounded, clickable card. When open, the detail row joins it into
   one box (squared corners between them). Nested rows inside the body (associated
   types, method panels) are reset flat so we never stack cards inside cards.
   Open/closed comes from Haddock's JS, which adds .collapser / .expander to the
   toggle and toggles [open] on the detail <details>.
   ========================================================================== */
.subs.instances { margin-top: 1rem; }
/* Collapsible section headers (Examples, Instances, any sub-heading Haddock
   makes a details-toggle). One look for all of them. A full-width bar with the
   chevron reads as a clear, consistent expand/collapse affordance rather than
   plain bold text. */
:is(h2, h3, h4, h5, h6).details-toggle-control {
  display: block;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--kg-fg);
  margin: 1.2rem 0 0.6rem;
  padding: 0.5rem 0.7rem;
  background: var(--kg-bg-raised);
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius-s);
  cursor: pointer;
  user-select: none;
  transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
:is(h2, h3, h4, h5, h6).details-toggle-control:hover {
  color: var(--kg-fg);
  border-color: var(--kg-accent);
  background: var(--kg-accent-soft);
}
/* Ink the chevron a touch brighter than the faint default so the bar reads as
   actionable. Hover still accents it via the shared toggle rule. */
:is(h2, h3, h4, h5, h6).details-toggle-control.expander::before,
:is(h2, h3, h4, h5, h6).details-toggle-control.collapser::before { background-color: var(--kg-fg-muted); }
/* The native <summary> toggles are hide-when-js-enabled. Only the no-JS path
   sees them, where they ARE the disclosure control, so keep their native marker
   (we don't hide it). With JS they're display:none, replaced by the chevron. */

/* Block-ify the table so rows can be card pieces. */
/* display: block (not just on the rows/cells) so the table fills its column and
   its cells wrap, rather than sizing to a long instance head and overflowing.
   With table > tr and no explicit tbody, the anonymous row group keeps table
   layout otherwise, and a wide instance pushes the whole page sideways. */
.instances table,
[id="section.orphans"] table { display: block; width: 100%; border-collapse: collapse; }
.instances tbody, .instances tr, .instances td,
[id="section.orphans"] tbody,
[id="section.orphans"] tr,
[id="section.orphans"] td { display: block; width: auto; }
.instances td,
[id="section.orphans"] td { word-break: break-word; overflow-wrap: anywhere; }
.inst-left { display: inline; }

/* Head row = the accordion header (a rounded card top). */
/* The card is the header row (head then its doc). It is the positioning context
   for the Source chip. The head cell itself stays static. */
.instances tr:has(> td.src),
[id="section.orphans"] tr:has(> td.src) {
  position: relative;
  overflow: visible;
  margin-top: 1.2rem;
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius-s);
  background: var(--kg-bg-raised);
  transition: border-color 0.12s ease, background-color 0.12s ease;
}
.instances td.src:has(> .kg-srclinks),
[id="section.orphans"] td.src:has(> .kg-srclinks) { position: static; }
/* The header is the toggle only when JS runs (no-JS uses the native <summary>
   inside the body), so click affordances are gated on body.js-enabled. */
body.js-enabled .instances tr:has(> td.src),
body.js-enabled [id="section.orphans"] tr:has(> td.src) { cursor: pointer; }
body.js-enabled .instances tr:has(> td.src):hover,
body.js-enabled [id="section.orphans"] tr:has(> td.src):hover {
  border-color: var(--kg-accent);
  background: var(--kg-accent-soft);
}
/* Accent the chevron on hover too, so the header reads as a control. */
body.js-enabled .instances tr:has(> td.src):hover .expander::before,
body.js-enabled .instances tr:has(> td.src):hover .collapser::before,
body.js-enabled [id="section.orphans"] tr:has(> td.src):hover .expander::before,
body.js-enabled [id="section.orphans"] tr:has(> td.src):hover .collapser::before {
  background: var(--kg-accent);
}
/* (Direct-hover chevron accent is handled uniformly for every toggle near the
   .expander/.collapser definition, so instance chevrons match.) */
.instances td.src,
[id="section.orphans"] td.src {
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  padding: 0.55rem 0.75rem 0.55rem 0.85rem;
  font-size: 0.83rem;
}
/* (Chevron sizing/placement is unified at the .expander/.collapser definition.
   The instance card chevron inherits it and so lines up with the card rail.) */
/* The instance's own doc. Aligned to the card's content edge (the same left
   rail as the expanded body below it), not under the signature text, so a
   card's doc, "Defined in" line and sub-sections share one left edge across
   every instance. */
/* Below the head: a small gap above (down from the head) and bottom room for the
   Source tag hanging off the card's bottom edge. */
.instances td.doc,
[id="section.orphans"] td.doc {
  padding: 0.1rem 0.85rem 0.9rem;
  color: var(--kg-fg-muted);
  font-size: 0.85rem;
}
.instances td.doc.empty,
[id="section.orphans"] td.doc.empty { display: none; }
.instances td.doc p,
[id="section.orphans"] td.doc p { margin: 0.1rem 0; }

/* Open head: square the bottom so the detail body joins into one box. */
.instances tr:has(.collapser),
[id="section.orphans"] tr:has(.collapser) {
  border-bottom: none;
  border-radius: var(--kg-radius-s) var(--kg-radius-s) 0 0;
}

/* Detail row = the accordion body. Completes the box when open, gone when shut. */
.instances tr:has(> td[colspan]),
[id="section.orphans"] tr:has(> td[colspan]) {
  border: 1px solid var(--kg-border);
  border-top: none;
  border-radius: 0 0 var(--kg-radius-s) var(--kg-radius-s);
  background: var(--kg-bg-raised);
}
/* Hide a closed detail row only with JS (the chevron/header is the toggle then).
   Without JS the row stays put so its native <summary> toggle is reachable.
   Keyed on html[data-js] (boot stamps it before first paint), not the bundle's
   late body.js-enabled. Otherwise the closed rows show then vanish, shrinking
   the page and jolting everything below. Scope to the direct details so a nested
   open child doesn't keep a closed parent's empty box visible. */
html[data-js] .instances tr:has(> td[colspan]):not(:has(> td[colspan] > details[open])),
html[data-js] [id="section.orphans"] tr:has(> td[colspan]):not(:has(> td[colspan] > details[open])) {
  display: none;
}
.instances td[colspan],
[id="section.orphans"] td[colspan] { padding: 1.1rem 0.85rem 0.7rem; }
/* Per-instance "Instance details" summary: hide-when-js-enabled, so its native
   marker only shows under no-JS, where it is the disclosure control. Kept. */
/* "Defined in ..." provenance, quiet. */
.instances td[colspan] > details > p,
[id="section.orphans"] td[colspan] > details > p {
  margin: 0.4rem 0 0.5rem;
  color: var(--kg-fg-faint);
  font-size: 0.78rem;
}

/* Inside the body, nested rows (associated-type / method sub-tables) are flat,
   not their own cards. */
.instances td[colspan] tr,
[id="section.orphans"] td[colspan] tr {
  margin: 0;
  border: none;
  border-radius: 0;
  background: none;
}
.instances td[colspan] td.src,
[id="section.orphans"] td[colspan] td.src { padding: 0.15rem 0; }
.instances td[colspan] td.doc,
[id="section.orphans"] td[colspan] td.doc { padding: 0 0 0.3rem 1.2rem; }
.instances td[colspan] .subs,
[id="section.orphans"] td[colspan] .subs { margin: 0.3rem 0 0.5rem; }
.instances td[colspan] .subs > .caption,
[id="section.orphans"] td[colspan] .subs > .caption { margin-bottom: 0.2rem; }
.instances td[colspan] .subs.methods,
[id="section.orphans"] td[colspan] .subs.methods {
  padding: 0.4rem 0.7rem;
  background: var(--kg-bg-sunken);
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius-s);
}
.instances td[colspan] .subs.methods p.src,
[id="section.orphans"] td[colspan] .subs.methods p.src {
  background: none;
  border: none;
  box-shadow: none;
  border-radius: 0;
  padding: 0.12rem 0;
  font-size: 0.82rem;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* ==========================================================================
   Info table (Safe Haskell etc.)
   ========================================================================== */
table.info {
  float: right;
  margin: 0 0 1rem 1rem;
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius-s);
  background: var(--kg-bg-sunken);
  font-size: 0.78rem;
  color: var(--kg-fg-muted);
  border-collapse: collapse;
}
table.info th, table.info td { padding: 0.25rem 0.6rem; text-align: left; }
table.info th { font-weight: 600; color: var(--kg-fg-faint); }

/* "@since" / deprecation notes. */
.doc em { color: var(--kg-fg-muted); }

/* ==========================================================================
   Footer
   ========================================================================== */
#footer {
  grid-area: footer;
  grid-column: 1 / -1;
  /* kedgeree.js appends the sidebar after #footer, so without a stacking
     context the sticky sidebar paints over the footer at the page bottom.
     Lift the footer above it with a solid background. */
  position: relative;
  z-index: 45;
  margin-top: 2rem;
  padding: 1.5rem;
  border-top: 1px solid var(--kg-border);
  color: var(--kg-fg-faint);
  font-size: 0.8rem;
  text-align: center;
  background: var(--kg-bg);
}
#footer a { color: var(--kg-fg-muted); }
/* Keep the credit (and its emoji) together so it never wraps mid-phrase. */
.kg-credit { white-space: nowrap; }

/* Anchor-target highlight (Haddock's default is an unreadable yellow band). */
:target {
  background: var(--kg-accent-soft) !important;
  border-radius: var(--kg-radius-s);
  scroll-margin-top: calc(var(--kg-header-h) + 1rem);
}
:target:hover { background: var(--kg-accent-soft) !important; }

/* ==========================================================================
   Search / help overlays (kedgeree.js)
   ========================================================================== */
.kg-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding-top: 12vh;
  background: rgba(15, 12, 28, 0.45);
  backdrop-filter: blur(2px);
}
.kg-overlay.kg-open { display: flex; }

.kg-help-card {
  width: min(34rem, 92vw);
  background: var(--kg-bg-raised);
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius);
  box-shadow: 0 18px 50px var(--kg-shadow);
  padding: 1.25rem 1.5rem;
  color: var(--kg-fg);
}
.kg-help-card h2 { margin: 0 0 0.75rem; font-size: 1.1rem; }
.kg-help-card dl { display: grid; grid-template-columns: auto 1fr; gap: 0.5rem 1rem; margin: 0; }
.kg-help-card dt { text-align: right; }
.kg-help-card dd { margin: 0; color: var(--kg-fg-muted); }

/* Suppress Haddock's native quick-jump (we provide our own search). */
#search, #search-form, #search-results { display: none !important; }

/* Hide Haddock's legacy theme switcher. */
#style-menu { display: none !important; }

/* The "Instances" preferences dropdown (#preferences-menu): a buttons row plus
   two checkbox rows. Haddock hard-codes a light-blue panel with no internal
   spacing. Re-theme it and lay it out properly.
   Structure:  .dropdown-menu > div > { div(2 buttons), div(checkbox+span)… } */
.dropdown-menu {
  position: fixed;
  top: calc(var(--kg-header-h) + 0.45rem) !important;
  right: 0.75rem !important;
  z-index: 50 !important;
  min-width: 19rem;
  max-width: min(24rem, calc(100vw - 1.5rem));
  padding: 0.85rem !important;
  background: var(--kg-bg-raised) !important;
  border: 1px solid var(--kg-border) !important;
  border-radius: var(--kg-radius) !important;
  box-shadow: 0 16px 40px var(--kg-shadow);
  color: var(--kg-fg);
  font-size: 0.85rem;
}
/* Outer wrapper stacks the rows, each inner div is one row. */
.dropdown-menu > div { display: flex; flex-direction: column; gap: 0.7rem; }
.dropdown-menu > div > div { display: flex; align-items: flex-start; gap: 0.6rem; }
/* The two action buttons share a row. */
.dropdown-menu > div > div:first-child { gap: 0.5rem; flex-wrap: wrap; }
.dropdown-menu button {
  flex: 0 0 auto;
  border: 1px solid var(--kg-border) !important;
  border-radius: var(--kg-radius-s) !important;
  background: var(--kg-bg-sunken) !important;
  color: var(--kg-fg) !important;
  padding: 0.45rem 0.95rem !important;
  font: inherit;
  line-height: 1.4;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}
.dropdown-menu button:hover {
  background: var(--kg-accent-soft) !important;
  color: var(--kg-accent-strong) !important;
  border-color: var(--kg-accent) !important;
}
.dropdown-menu input[type="checkbox"] {
  flex: 0 0 auto;
  width: 1rem;
  height: 1rem;
  margin: 0.15rem 0 0 !important;
  accent-color: var(--kg-accent);
  cursor: pointer;
}
.dropdown-menu label,
.dropdown-menu span { line-height: 1.35; cursor: pointer; }

/* In-page contents box. Once kedgeree.js builds the sidebar this is hidden
   (body.kg-has-sidebar), so it only shows in the no-JS fallback. Style it as a
   clean, intentional card rather than Haddock's raw bulleted list. */
#table-of-contents { margin: 1.25rem 0 1.75rem; }
#contents-list {
  background: var(--kg-bg-sunken);
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius);
  padding: 1rem 1.25rem;
}
#contents-list .caption {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--kg-fg-faint);
  margin: 0 0 0.5rem;
  cursor: pointer;
}
#contents-list ul { list-style: none; margin: 0; padding: 0; }
#contents-list li { margin: 0; }
#contents-list a {
  display: block;
  padding: 0.2rem 0.4rem;
  border-radius: var(--kg-radius-s);
  color: var(--kg-fg-muted);
}
#contents-list a:hover {
  background: var(--kg-bg-raised);
  color: var(--kg-fg);
  text-decoration: none;
}
#synopsis ul,
#synopsis ul li.src { background: transparent; }
.subs .subs p.src { background: var(--kg-code-bg); }
/* A method's default-signature block (DefaultSignatures) is a continuation of the
   method, not a nested code list, so de-box it to match the method above and drop
   the empty caption Haddock emits for it. */
.subs.default p.src { background: none; }
.subs.default > .caption { display: none; }
.subs.default { margin-top: 0.35rem; }

/* ==========================================================================
   Coverage for the rest of Haddock's surfaces
   ========================================================================== */

/* Deprecation / warning notices. */
.warning {
  margin: 1rem 0;
  padding: 0.7rem 1rem;
  border: 1px solid color-mix(in srgb, #d98a2b 40%, var(--kg-border));
  border-left: 3px solid #d98a2b;
  border-radius: var(--kg-radius-s);
  background: color-mix(in srgb, #d98a2b 10%, var(--kg-bg-raised));
  color: var(--kg-fg);
  font-size: 0.9rem;
}

/* Per-argument documentation. Stack each argument: the type (a signature that
   can be long and would crowd a two-column table) on its own line as a code
   bar, its description below. Far more readable than side by side.
   Mirrors the constructor/field treatment. */
/* Per-argument docs continue the signature directly, so sit them tight under it. */
.subs.arguments { margin-top: 0.25rem; }
.subs.arguments table,
.subs.arguments tbody,
.subs.arguments tr,
.subs.arguments td { display: block; width: auto; }
.subs.arguments table { width: 100%; }
.subs.arguments tr { margin: 0.6rem 0 0; }
.subs.arguments td.src {
  background: var(--kg-code-bg);
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius-s);
  padding: 0.4rem 0.6rem;
  white-space: pre-wrap;
  overflow-x: auto;
}
.subs.arguments td.doc {
  padding: 0.35rem 0.2rem 0;
  color: var(--kg-fg-muted);
}
.subs.arguments td.doc.empty { display: none; }
.subs.arguments td.doc p { margin: 0; }

/* Alphabetical index page (#index): a clean two-column list, not boxed cards. */
#index > .caption {
  font-size: 1.6rem; font-weight: 700; color: var(--kg-fg); margin-bottom: 1rem;
}
#index table { border-collapse: collapse; }
#index td { vertical-align: baseline; padding: 0.16rem 0; }
#index td.src {
  background: none; border: none; border-radius: 0;
  padding: 0.16rem 1.5rem 0.16rem 0;
  font-family: var(--kg-mono); font-size: 0.9rem; white-space: nowrap;
}
/* Disambiguation sub-entries (e.g. "1 (Type/Class)") indent under their name. */
#index td.alt {
  padding: 0.12rem 1.5rem 0.12rem 1.6rem;
  color: var(--kg-fg-muted);
  font-size: 0.85rem;
  white-space: nowrap;
}
#index td.module { color: var(--kg-fg-faint); }
#alphabet ul {
  list-style: none; display: flex; flex-wrap: wrap; gap: 0.25rem;
  margin: 0 0 1.25rem; padding: 0;
}
#alphabet li { margin: 0; }
#alphabet a { display: inline-block; padding: 0.1rem 0.5rem; border-radius: var(--kg-radius-s); }
#alphabet a:hover { background: var(--kg-accent-soft); text-decoration: none; }

/* Contents page module tree (#module-list). */
#module-list > .caption {
  font-size: 1.6rem; font-weight: 700; color: var(--kg-fg); margin-bottom: 0.5rem;
}
#module-list #module-list > .caption {
  font-size: 0.72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.07em; color: var(--kg-fg-faint); margin: 1.25rem 0 0.3rem;
}
#module-list ul { list-style: none; margin: 0; padding-left: 0; }
#module-list details > ul { padding-left: 1.3rem; }
/* Newer Haddock wraps submodules in a <details>. Keep it flush (and tame
   Chrome's ::details-content wrapper) so a module's submodules don't open a
   vertical gap before the next top-level module. */
#module-list details { margin: 0; padding: 0; }
#module-list details::details-content { margin: 0; padding: 0; }
#module-list li { margin: 0; }
#module-list .module {
  display: block;
  padding: 0.2rem 0.4rem;
  margin: 0 -0.4rem;
  border-radius: var(--kg-radius-s);
  white-space: nowrap;
  transition: background-color 0.12s ease;
}
/* Hover highlight, consistent with the other collapsible toggles: tint the row
   and accent the chevron. */
#module-list .module:hover { background: var(--kg-accent-soft); }
#module-list .module:hover .expander::before,
#module-list .module:hover .collapser::before { background-color: var(--kg-accent); }

/* Fixity annotations (infixl 6 …). */
/* Residual Haddock float-clear element (stripped server-side, hidden as a guard). */
.rightedge { display: none; }
/* Haddock appends the operator fixity inline at the end of the signature. Drop it
   to its own line below so it never wraps as part of the type. */
.fixity {
  display: block;
  margin-top: 0.35rem;
  text-indent: -2ch;
  color: var(--kg-fg-faint);
  font-size: 0.78rem;
  font-style: normal;
}

/* LANGUAGE extension list in the module header (Haddock's --show-extensions).
   It renders inside the floated info table, so keep it compact. */
.extension-list { margin: 0.4rem 0 0 1.2rem; }
.extension-list li { font-family: var(--kg-mono); font-size: 0.85rem; }

/* "Minimal complete definition" is class metadata, not a real declaration.
   Haddock emits a caption + a .src list of methods. Render it as one quiet
   inline note instead of an uppercased caption stacked over a full code card.
   (#interface-scoped to outrank the generic .caption / .src rules.) */
#interface .subs.minimal { margin: 0.5rem 0 0; }
#interface .subs.minimal .caption {
  display: inline;
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
  color: var(--kg-fg-faint);
}
#interface .subs.minimal .caption::after { content: ":\00a0"; }
#interface .subs.minimal p.src {
  display: inline;
  margin: 0;
  padding: 0;
  background: none;
  border: none;
  box-shadow: none;
  border-radius: 0;
  font-size: 0.85rem;
}

/* Definition lists used in docs (argument descriptions etc.). */
.doc dl { margin: 0.6em 0; }
.doc dt { font-weight: 600; color: var(--kg-fg); }
.doc dd { margin: 0 0 0.5em 1.5em; color: var(--kg-fg-muted); }

/* Doc tables. */
.doc table { border-collapse: collapse; margin: 0.8em 0; display: block; max-width: 100%; overflow-x: auto; }
.doc th, .doc td { border: 1px solid var(--kg-border); padding: 0.35rem 0.6rem; }
.doc th { background: var(--kg-bg-sunken); }

/* ==========================================================================
   Polish
   ========================================================================== */

/* Drop Haddock's left border on doc text. */
.top > .doc,
.subs > .doc,
.subs,
.subs ul li > .doc {
  border-left: none;
}
.top > .doc,
.subs > .doc {
  padding-left: 0;
  margin: 0.5rem 0 0;
}

/* Visible keyboard focus everywhere (accessibility + polish). */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
.kg-search:focus-visible,
#kg-sidebar a:focus-visible {
  outline: 2px solid var(--kg-accent);
  outline-offset: 2px;
  border-radius: var(--kg-radius-s);
}
:focus:not(:focus-visible) { outline: none; }

/* Restrained transitions on interactive chrome. */
a,
.kg-iconbtn,
.kg-search,
#kg-sidebar a,
#package-header #page-menu a,
.top > .src,
.top > .doc,
a.selflink {
  transition: color 0.12s ease, background-color 0.12s ease,
    border-color 0.12s ease, box-shadow 0.12s ease, opacity 0.12s ease;
}


/* Slim, themed scrollbars. */
#kg-sidebar,
pre,
#synopsis ul.details-toggle,
.kg-search-list {
  scrollbar-width: thin;
  scrollbar-color: var(--kg-border-strong) transparent;
}
#kg-sidebar::-webkit-scrollbar,
pre::-webkit-scrollbar,
.kg-search-list::-webkit-scrollbar { width: 10px; height: 10px; }
#kg-sidebar::-webkit-scrollbar-thumb,
pre::-webkit-scrollbar-thumb,
.kg-search-list::-webkit-scrollbar-thumb {
  background: var(--kg-border-strong);
  border-radius: 8px;
  border: 3px solid transparent;
  background-clip: content-box;
}
#kg-sidebar::-webkit-scrollbar-thumb:hover,
pre::-webkit-scrollbar-thumb:hover {
  background: var(--kg-fg-faint);
  background-clip: content-box;
}

/* JS-built header actions + sidebar home. */
.kg-actions { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; }
/* Scoped under #kg-sidebar so it outranks `#kg-sidebar a` (an id selector).
   Otherwise the flush padding-left below silently loses to it, and the λ pushes
   the heading text in past the nav options. */
#kg-sidebar .kg-sb-home {
  display: flex;
  align-items: center;
  /* Keep the heading content flush at the rail (so off-module headings sit one
     level out, not indented), but let the active/hover highlight reach a little
     further left via the negative margin (absorbed by the sidebar's own left
     padding), so the λ has breathing room from the highlight's edge rather than
     touching it. The λ sits in a fixed-width box so the heading text lands at a
     predictable spot, left of the nav options, whatever the glyph width. */
  margin: 0 0 0.5rem -0.4rem;
  padding-left: 0.4rem;
  color: var(--kg-fg);
}
#kg-sidebar .kg-sb-home .kg-lambda { flex: none; width: 0.9rem; }

/* Search overlay. */
.kg-search-overlay .kg-help-card { width: min(40rem, 94vw); padding: 0; overflow: hidden; }
.kg-search-input {
  width: 100%;
  border: none;
  border-bottom: 1px solid var(--kg-border);
  padding: 0.9rem 1.1rem;
  font-size: 1rem;
  font-family: var(--kg-font);
  background: transparent;
  color: var(--kg-fg);
  caret-color: var(--kg-accent);
  outline: none;
}
.kg-search-list { list-style: none; margin: 0; padding: 0.4rem; max-height: 56vh; overflow: auto; }
.kg-sr > a {
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
  padding: 0.35rem 0.6rem;
  border-radius: var(--kg-radius-s);
  color: var(--kg-fg);
}
.kg-sr-name { font-family: var(--kg-mono); font-weight: 600; }
.kg-sr-mod { margin-left: auto; color: var(--kg-fg-faint); font-size: 0.8rem; }
.kg-sr-sel > a { background: var(--kg-accent-soft); }
.kg-sr-sel > a .kg-sr-name { color: var(--kg-accent-strong); }
.kg-sr-empty, .kg-sr-hint { padding: 0.7rem 0.6rem; color: var(--kg-fg-faint); font-size: 0.85rem; }
.kg-sr-hint kbd { margin: 0 0.1rem; }

/* Footer credit. */
.kg-credit a { color: var(--kg-fg-muted); }
.kg-credit a:hover { color: var(--kg-accent); }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 60rem) {
  body,
  body:not(.kg-has-sidebar) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "header"
      "main"
      "footer";
  }

  /* The header's text nav is redundant on mobile (Contents/Index live in the
     drawer + search), and it's what blows out the width. Hide it. */
  #package-header #page-menu { display: none; }
  #package-header { gap: 0.5rem; }
  .kg-actions { gap: 0.4rem; }

  #kg-sidebar {
    position: fixed;
    top: var(--kg-header-h);
    left: 0;
    width: min(20rem, 82vw);
    height: calc(100vh - var(--kg-header-h));
    z-index: 50;
    transform: translateX(-102%);
    transition: transform 0.18s ease;
    box-shadow: 0 12px 40px var(--kg-shadow);
  }
  body.kg-nav-open #kg-sidebar { transform: translateX(0); }
  /* The minimal drawer is hidden on desktop but available here. */
  body.kg-sidebar-min #kg-sidebar { display: block; }

  /* Dim backdrop behind the open drawer. */
  body.kg-nav-open::after {
    content: "";
    position: fixed;
    inset: var(--kg-header-h) 0 0 0;
    background: rgba(10, 8, 20, 0.4);
    z-index: 45;
  }

  .kg-menu-toggle { display: inline-flex; }
  .kg-search { min-width: 0; flex: 1 1 auto; }
  .kg-search .kg-search-label, .kg-search kbd { display: none; }
  /* Keep the package name, but truncate it if it is very long. */
  .kg-brand > span:not(.kg-lambda) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 42vw;
  }
}

@media (max-width: 48rem) {
  /* Non-row code (constructors, fields) scrolls rather than wrapping. */
  .subs.constructors td.src,
  .subs.fields dfn.src { overflow-x: auto; white-space: pre-wrap; }

  .instances table { table-layout: auto; }
  .instances td[colspan] .subs.methods { padding: 0.5rem 0.6rem; }

  /* Drop the grouping rail on narrow screens: declarations stack tightly enough
     to read as units, and the rail + indent only eats horizontal space here. */
  .top { background-image: none; padding-left: 0; }
}

@media (max-width: 34rem) {
  #package-header { gap: 0.4rem; padding: 0 0.6rem; }
  #content { padding: 1.25rem 1rem 3rem; }
  #module-header .caption { font-size: 1.5rem; }
  table.info { float: none; margin: 0 0 1rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* ==========================================================================
   Multi-package landing page (kedgeree --landing)
   ========================================================================== */
body.kg-landing {
  display: block;
  max-width: 56rem;
  margin: 0 auto;
  padding: 3rem 1.5rem 5rem;
}
.kg-landing-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 2rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--kg-border);
}
.kg-landing-heading { min-width: 0; }
.kg-landing-header h1 {
  margin: 0;
  font-size: 2rem;
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--kg-fg);
}
/* Optional one-line project description, under the title. */
.kg-landing-desc {
  margin: 0.45rem 0 0;
  max-width: 46rem;
  font-size: 1.05rem;
  line-height: 1.5;
  color: var(--kg-fg-muted);
}
/* Keep the theme toggle level with the title rather than the top of the line. */
.kg-landing-header .kg-actions { margin-top: 0.35rem; }
.kg-pkg-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.kg-pkg {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.85rem 1.1rem;
  border: 1px solid var(--kg-border);
  border-radius: var(--kg-radius);
  background: var(--kg-bg-raised);
  color: var(--kg-fg);
  text-decoration: none;
  transition: border-color 0.12s ease, background-color 0.12s ease;
}
.kg-pkg:hover {
  border-color: var(--kg-accent);
  background: var(--kg-bg-sunken);
}
.kg-pkg-text { flex: 1; min-width: 0; }
.kg-pkg-name {
  display: block;
  font-family: var(--kg-mono);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--kg-fg);
  overflow: hidden;
  text-overflow: ellipsis;
}
.kg-pkg:hover .kg-pkg-name { color: var(--kg-accent-strong); }
/* Optional one-line synopsis read from the package's .cabal. */
.kg-pkg-desc {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--kg-fg-muted);
}
/* The same chevron icon as every toggle, here as a quiet "go" affordance. */
.kg-pkg::after {
  content: "";
  flex: none;
  margin-left: auto;
  width: 0.7em;
  height: 0.9em;
  background-color: var(--kg-fg-faint);
  -webkit-mask: var(--kg-chevron) center / contain no-repeat;
  mask: var(--kg-chevron) center / contain no-repeat;
}
.kg-pkg:hover::after { background-color: var(--kg-accent); }
