
/* ---- Open Color (yeun.github.io/open-color) ----
   The whole palette, so a colour is chosen from a scale rather than invented, and so nothing
   below has to carry a raw hex. Not theme-dependent: these are the paints, the two blocks
   underneath decide which ones this site uses where. */
:root {
  --oc-white: #ffffff; --oc-black: #000000;
  --oc-gray-0: #f8f9fa; --oc-gray-1: #f1f3f5; --oc-gray-2: #e9ecef; --oc-gray-3: #dee2e6; --oc-gray-4: #ced4da; --oc-gray-5: #adb5bd; --oc-gray-6: #868e96; --oc-gray-7: #495057; --oc-gray-8: #343a40; --oc-gray-9: #212529;
  --oc-red-0: #fff5f5; --oc-red-1: #ffe3e3; --oc-red-2: #ffc9c9; --oc-red-3: #ffa8a8; --oc-red-4: #ff8787; --oc-red-5: #ff6b6b; --oc-red-6: #fa5252; --oc-red-7: #f03e3e; --oc-red-8: #e03131; --oc-red-9: #c92a2a;
  --oc-pink-0: #fff0f6; --oc-pink-1: #ffdeeb; --oc-pink-2: #fcc2d7; --oc-pink-3: #faa2c1; --oc-pink-4: #f783ac; --oc-pink-5: #f06595; --oc-pink-6: #e64980; --oc-pink-7: #d6336c; --oc-pink-8: #c2255c; --oc-pink-9: #a61e4d;
  --oc-grape-0: #f8f0fc; --oc-grape-1: #f3d9fa; --oc-grape-2: #eebefa; --oc-grape-3: #e599f7; --oc-grape-4: #da77f2; --oc-grape-5: #cc5de8; --oc-grape-6: #be4bdb; --oc-grape-7: #ae3ec9; --oc-grape-8: #9c36b5; --oc-grape-9: #862e9c;
  --oc-violet-0: #f3f0ff; --oc-violet-1: #e5dbff; --oc-violet-2: #d0bfff; --oc-violet-3: #b197fc; --oc-violet-4: #9775fa; --oc-violet-5: #845ef7; --oc-violet-6: #7950f2; --oc-violet-7: #7048e8; --oc-violet-8: #6741d9; --oc-violet-9: #5f3dc4;
  --oc-indigo-0: #edf2ff; --oc-indigo-1: #dbe4ff; --oc-indigo-2: #bac8ff; --oc-indigo-3: #91a7ff; --oc-indigo-4: #748ffc; --oc-indigo-5: #5c7cfa; --oc-indigo-6: #4c6ef5; --oc-indigo-7: #4263eb; --oc-indigo-8: #3b5bdb; --oc-indigo-9: #364fc7;
  --oc-blue-0: #e7f5ff; --oc-blue-1: #d0ebff; --oc-blue-2: #a5d8ff; --oc-blue-3: #74c0fc; --oc-blue-4: #4dabf7; --oc-blue-5: #339af0; --oc-blue-6: #228be6; --oc-blue-7: #1c7ed6; --oc-blue-8: #1971c2; --oc-blue-9: #1864ab;
  --oc-cyan-0: #e3fafc; --oc-cyan-1: #c5f6fa; --oc-cyan-2: #99e9f2; --oc-cyan-3: #66d9e8; --oc-cyan-4: #3bc9db; --oc-cyan-5: #22b8cf; --oc-cyan-6: #15aabf; --oc-cyan-7: #1098ad; --oc-cyan-8: #0c8599; --oc-cyan-9: #0b7285;
  --oc-teal-0: #e6fcf5; --oc-teal-1: #c3fae8; --oc-teal-2: #96f2d7; --oc-teal-3: #63e6be; --oc-teal-4: #38d9a9; --oc-teal-5: #20c997; --oc-teal-6: #12b886; --oc-teal-7: #0ca678; --oc-teal-8: #099268; --oc-teal-9: #087f5b;
  --oc-green-0: #ebfbee; --oc-green-1: #d3f9d8; --oc-green-2: #b2f2bb; --oc-green-3: #8ce99a; --oc-green-4: #69db7c; --oc-green-5: #51cf66; --oc-green-6: #40c057; --oc-green-7: #37b24d; --oc-green-8: #2f9e44; --oc-green-9: #2b8a3e;
  --oc-lime-0: #f4fce3; --oc-lime-1: #e9fac8; --oc-lime-2: #d8f5a2; --oc-lime-3: #c0eb75; --oc-lime-4: #a9e34b; --oc-lime-5: #94d82d; --oc-lime-6: #82c91e; --oc-lime-7: #74b816; --oc-lime-8: #66a80f; --oc-lime-9: #5c940d;
  --oc-yellow-0: #fff9db; --oc-yellow-1: #fff3bf; --oc-yellow-2: #ffec99; --oc-yellow-3: #ffe066; --oc-yellow-4: #ffd43b; --oc-yellow-5: #fcc419; --oc-yellow-6: #fab005; --oc-yellow-7: #f59f00; --oc-yellow-8: #f08c00; --oc-yellow-9: #e67700;
  --oc-orange-0: #fff4e6; --oc-orange-1: #ffe8cc; --oc-orange-2: #ffd8a8; --oc-orange-3: #ffc078; --oc-orange-4: #ffa94d; --oc-orange-5: #ff922b; --oc-orange-6: #fd7e14; --oc-orange-7: #f76707; --oc-orange-8: #e8590c; --oc-orange-9: #d9480f;
}

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

/* ---- Theme variables: the only place a colour is chosen ---- */
/* The greys are docify's dark palette: its page is #1d1d1d and its surfaces, borders and muted text
   come from Tailwind's neutral ramp, which has no hue in it at all. The light theme is the same ramp
   read from the other end, for the same reason: the site's own colours are few and they say
   something, so a page that carried a tint of its own would be saying something too. */
:root[data-theme="dark"] {
  --bg:          #1d1d1d;
  --bg-home:     #1d1d1d;
  --bg2:         #262626;
  --bg3:         #333333;
  --bg4:         #3d3d3d;
  --border:      #333333;
  --border2:     #404040;
  --text:        #e6e6e6;
  --text2:       #d4d4d4;
  --text3:       #a3a3a3;
  --text4:       #737373;
  --card-bg:     #262626;
  --card-border: #333333;
  --card-hover:  #2e2e2e;
  --card-detail: #1b1b1b;
  --card-split:  #2b2b2b;
  /* The ground of an obsolete member's whole card: the page's own, so the card reads as the page
     showing through rather than a card worth stopping at. Named for the inherited cards that wore
     it first and have since gone back to the common ground. */
  --card-inherited: var(--bg);
  --fullname:    #737373;
  /* Light against a dark page, where the light theme's kind ink is dark against a light one: a
     drawing has to sit above its ground either way. Its text goes the other way for the same
     reason - see --kind-ink. */
  --kind:        var(--oc-gray-4);
  --kind-ink:    var(--oc-gray-9);
  --flash:       #2196f3;
  --scrollbar:   #404040;
  --tok-keyword: #c4a7fd;
  --tok-string:  #7ee2b0;
  --tok-comment: #8a8a8a;
  --tok-number:  #fbbf77;
  --tok-meta:    #d8b4fe;
  --tok-type:    #7dd3fc;
  --tok-func:    #dcdcaa;
  --tok-punct:   #9e9e9e;
  --ext-ref:     #9a9a9a;
  --mark-bg:     var(--oc-yellow-4);
  --mark-fg:     var(--oc-gray-9);
  --accent:      #2196f3;
}
:root[data-theme="light"] {
  --bg:          #f8f8f8;
  --bg-home:     #ffffff;
  --bg2:         #ffffff;
  --bg3:         #f1f1f1;
  --bg4:         #e8e8e8;
  --border:      #e5e5e5;
  --border2:     #d4d4d4;
  --text:        #262626;
  --text2:       #3d3d3d;
  --text3:       #737373;
  --text4:       #a3a3a3;
  --card-bg:     #ffffff;
  --card-border: #e5e5e5;
  --card-hover:  #f8f8f8;
  --card-detail: #fbfbfb;
  --card-split:  #efefef;
  --card-inherited: var(--bg);
  --fullname:    #a3a3a3;
  --kind:        var(--oc-gray-7);
  --kind-ink:    var(--oc-white);
  --flash:       #0ea5e9;
  --scrollbar:   #d4d4d4;
  --tok-keyword: #7c3aed;
  --tok-string:  #0a7c52;
  --tok-comment: #64748b;
  --tok-number:  #b45309;
  --tok-meta:    #9333ea;
  --tok-type:    #0369a1;
  --tok-func:    #795e26;
  --tok-punct:   #64748b;
  --ext-ref:     #5b7086;
  --mark-bg:     var(--oc-yellow-2);
  --mark-fg:     var(--oc-gray-9);
  --accent:      #1364c4;
}

/* ---- Badge colours ----
   Written from lib/theme.js, so the palette is stated once and every badge, filter pill and search
   row reads it from here rather than carrying a colour of its own. Outside the two theme blocks
   because a colour means the same thing under either one. The one that did need saying twice is
   not a colour but the end of a range - the kind ink - and it is up there with --flash, where a
   theme states what its ends are. */
:root {
  --badge-explicit: var(--oc-blue-4);
  --note-obsolete: var(--oc-orange-5);
}

/* The header keeps one colour under both themes: it is chrome rather than content, and holding it
   fixed is what makes the light and dark pages read as the same site. Taken from docify. */
:root {
  --nav-bg:      #353535;
  --nav-fg:      #ffffff;
  --nav-field:   rgba(255, 255, 255, 0.15);
  --nav-focus:   rgba(255, 255, 255, 0.25);
  --nav-hover:   rgba(255, 255, 255, 0.10);
  --nav-dim:     rgba(255, 255, 255, 0.60);
  --nav-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}

body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: var(--bg); color: var(--text); display: flex; flex-direction: column; height: 100vh; overflow: hidden; transition: background 0.2s, color 0.2s; }
/* The landing page is a sheet of prose with no cards or panels on it, so it does without the faint
   tint the other pages need to hold theirs. --bg-home matches --bg under the dark theme. */
body.home { background: var(--bg-home); }

.skip-link { position: absolute; left: -9999px; top: 0; z-index: 100; background: var(--bg2); color: var(--text); padding: 0.5rem 1rem; border: 1px solid var(--border2); }
.skip-link:focus { left: 0; }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible { outline: 2px solid var(--flash); outline-offset: 2px; }

/* ---- Header ---- */
header { background: var(--nav-bg); color: var(--nav-fg); padding: 0.6rem 0.9rem; display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; z-index: 20; }
header h1, header .site-title { font-size: 1.05rem; font-weight: 500; flex: 1; min-width: 0; }
header .site-title a { display: flex; align-items: center; gap: 0.5rem; min-width: 0; padding: 0.2rem 0.4rem; border-radius: 4px; color: var(--nav-fg); text-decoration: none; }
header .site-title a:hover { background: var(--nav-hover); color: var(--nav-fg); }
header .site-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Sized here rather than trusted from the file, so any logo.svg lands at the same height. An SVG
   drawn with currentColor inherits the header colour, including the hover. */
.site-logo { display: inline-flex; align-items: center; flex-shrink: 0; }
.site-logo svg { display: block; width: 1.4rem; height: 1.4rem; }
/* Both variants ship in the markup when a dark one was given; only one is ever laid out, so the
   hidden one costs no gap in the flex row. */
:root[data-theme="dark"] .site-logo-light, :root[data-theme="light"] .site-logo-dark { display: none; }
/* One height for the whole header row. Set here rather than left to each control's own padding,
   because a select, an input and a button each size themselves differently. Vertical padding is
   dropped in favour of centring, so the height is exactly what it says. */
#asm-filter, #search, #version-filter, #version-current, #whatsnew-link, #theme-switch, #sidebar-toggle { height: 30px; }

/* ---- Sidebar toggle ----
   The theme toggle's face, before the title and against the column it shows and hides. */
#sidebar-toggle { display: inline-flex; align-items: center; justify-content: center; width: 30px; padding: 0; border: none; border-radius: 4px; background: var(--nav-field); color: var(--nav-fg); cursor: pointer; flex-shrink: 0; }
#sidebar-toggle:hover { background: var(--nav-focus); }
/* A filled mark, unlike the stroked moon and sun beside it: the path carries its own weight. */
#sidebar-toggle svg { display: block; width: 1.05rem; height: 1.05rem; fill: currentColor; }

/* The magnifier sits inside the field, so the field owns the position it is measured against. */
header form[role="search"] { position: relative; display: flex; align-items: center; flex-shrink: 0; }
#search { width: 16rem; padding: 0 2rem 0 0.7rem; border: none; border-radius: 4px; background: var(--nav-field); color: var(--nav-fg); font-size: 0.85rem; outline: none; }
#search::placeholder { color: var(--nav-dim); }
#search:focus { background: var(--nav-focus); }
/* type=search draws a platform clear button; the magnifier already occupies that corner. */
#search::-webkit-search-cancel-button, #search::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
/* A filled mark like the sidebar toggle's: the path carries its own weight. */
.nav-search-icon { position: absolute; right: 0.55rem; top: 50%; transform: translateY(-50%); width: 1.05rem; height: 1.05rem; pointer-events: none; fill: var(--nav-dim); }

/* The magnifier's corner while the index is on the wire, which on a static host is a wait the
   first query sits through. The ring takes the magnifier's exact footprint and ink, so the swap
   reads as the same mark set turning. Held invisible for the first beat: a cached index answers
   faster than a flash can be read, and the ring is for the wait a reader can feel. */
/* One mark at a time in the magnifier's corner: the magnifier while the box is empty, the clear
   mark while it holds anything, and the spinner over either while the index loads. */
.nav-search-clear { position: absolute; right: 0.55rem; top: 50%; transform: translateY(-50%); display: none; appearance: none; border: none; background: none; padding: 0; width: 1.05rem; height: 1.05rem; cursor: pointer; color: var(--nav-dim); }
.nav-search-clear:hover { color: var(--nav-fg); }
.nav-search-clear svg { display: block; width: 100%; height: 100%; fill: currentColor; }
header form[role="search"].filled .nav-search-icon { display: none; }
header form[role="search"].filled .nav-search-clear { display: block; }
header form[role="search"].index-loading .nav-search-icon { visibility: hidden; }
header form[role="search"].index-loading .nav-search-clear { visibility: hidden; }
header form[role="search"].index-loading::after { content: ''; position: absolute; right: 0.55rem; top: 50%; width: 1.05rem; height: 1.05rem; margin-top: calc(1.05rem / -2); border: 2px solid var(--nav-dim); border-top-color: transparent; border-radius: 50%; pointer-events: none; opacity: 0; animation: search-spin 0.7s linear infinite, search-spin-in 0s linear 0.15s forwards; }
@keyframes search-spin { to { transform: rotate(360deg); } }
@keyframes search-spin-in { to { opacity: 1; } }
/* Motion is the one thing this drawing is made of, so reduced motion gets a slower turn rather
   than a still ring that would read as a broken icon. */
@media (prefers-reduced-motion: reduce) {
  header form[role="search"].index-loading::after { animation-duration: 2.5s, 0s; }
}

/* ---- Header search results ----
   Hangs off the form, which is the positioned element, and takes the page's colours rather than
   the header's: it is content the header happens to be pointing at, not part of the bar.

   Anchored to the field's right edge rather than its left. The panel is nearly twice the width of
   the field it drops from, and the field sits at the right end of the header with the selectors and
   the theme toggle after it - so hung off the left, the extra width ran off the right of the site
   and a body that does not scroll sideways cut it off. Rightward there is nothing to grow into;
   leftward there is the whole of the title's slack, which is where the width has to come from. */
.nav-results { position: absolute; top: calc(100% + 0.35rem); right: 0; width: 30rem; max-width: 80vw; max-height: 70vh; overflow-y: auto; z-index: 40; background: var(--bg2); border: 1px solid var(--border2); border-radius: 5px; box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28); padding: 0.25rem; }
.nav-results[hidden] { display: none; }
.nav-result { display: flex; align-items: center; gap: 0.45rem; padding: 0.35rem 0.5rem; border-radius: 4px; font-size: 0.82rem; color: var(--text); text-decoration: none; }
.nav-result:hover, .nav-result.active { background: var(--bg3); }
.nav-result-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Pushed to the far end and allowed to shrink first, so a long namespace never crowds the name. */
.nav-result-ns { margin-left: auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: monospace; font-size: 0.7rem; color: var(--text4); }
.nav-results-more { display: block; margin-top: 0.15rem; padding: 0.4rem 0.5rem; border-top: 1px solid var(--border); font-size: 0.76rem; color: var(--text3); text-decoration: none; }
.nav-results-more:hover { color: var(--flash); }
.nav-empty { padding: 0.5rem; font-size: 0.82rem; color: var(--text3); }

/* ---- Header selects ---- */
/* appearance:none drops the platform arrow so both selects can carry the same chevron; the popup
   itself is still drawn by the OS, which is the one part a <select> cannot be styled into. */
#asm-filter, #version-filter { appearance: none; -webkit-appearance: none; border: none; border-radius: 4px; padding: 0 1.5rem 0 0.65rem; font-size: 0.82rem; font-weight: 500; cursor: pointer; outline: none; flex-shrink: 0; background-color: var(--accent); color: #ffffff; background-image: var(--nav-chevron); background-repeat: no-repeat; background-position: right 0.4rem center; background-size: 0.75rem; }
#asm-filter { max-width: 18rem; }
#asm-filter:hover, #version-filter:hover { filter: brightness(1.1); }
/* Any version but the newest wears the warning's orange, so a reader never forgets they chose an older one. */
#version-filter.older { background-color: var(--note-obsolete); }
/* The popup is an OS menu, so its options need colours that do not assume the dark bar. */
#asm-filter option, #version-filter option { background: var(--bg2); color: var(--text); }
/* A site offering one version says so here instead. The same face as the select it stands in for,
   without the chevron or the hover, since there is nothing to open. */
#version-current { display: inline-flex; align-items: center; border-radius: 4px; padding: 0 0.65rem; font-size: 0.82rem; font-weight: 500; flex-shrink: 0; background-color: var(--accent); color: #ffffff; }

/* On the search field's face rather than the accent: it goes somewhere, it does not choose anything. */
#whatsnew-link { display: inline-flex; align-items: center; border-radius: 4px; padding: 0 0.65rem; font-size: 0.82rem; font-weight: 500; flex-shrink: 0; white-space: nowrap; text-decoration: none; background: var(--nav-field); color: var(--nav-fg); }
#whatsnew-link:hover, #whatsnew-link[aria-current="page"] { background: var(--nav-focus); }

/* ---- What's New ---- */
/* No breadcrumbs above it, so the head brings its own room at the top. */
.whatsnew-head .page-head-brief { padding-top: 1.1rem; }
/* Shown once the list has arrived, since until then there is nothing for it to filter. */
.whatsnew-filter { display: none; margin-top: 0.75rem; }
/* The header search's height, across the whole head. */
.whatsnew-filter .derived-filter { height: 30px; padding-top: 0; padding-bottom: 0; font-size: 0.85rem; }
.whatsnew-filter.ready { display: block; }
.whatsnew-note { margin: 0.3rem 0 0; font-size: 0.8rem; color: var(--text3); }
.whatsnew-list, .whatsnew-members { list-style: none; margin: 0; padding: 0; }
.whatsnew-type { padding: 0.45rem 0; border-bottom: 1px solid var(--border); }
.whatsnew-members { margin: 0.3rem 0 0 1.6rem; }
.whatsnew-row { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; font-size: 0.88rem; }
.whatsnew-members .whatsnew-row { font-size: 0.82rem; padding: 0.12rem 0; }
.whatsnew-row > a { color: var(--text); text-decoration: none; overflow-wrap: anywhere; }
.whatsnew-row > a:hover { color: var(--flash); }
.whatsnew-type > .whatsnew-row > a { font-family: monospace; }
.whatsnew-sig { color: var(--text4); }

/* ---- Theme switch ---- */
/* A track on the search field's face with the lit segment raised out of it, rather than the accent
   the two selects above wear: those are jumps that change what is being read, and this only changes
   how it looks. The track is what groups the three into one control - without it they would read as
   three loose glyphs in a row, which is what the header is already full of.

   The radios themselves are never drawn. They are kept in the layout rather than display:none'd,
   because a control that is not laid out cannot be focused, and the arrow keys moving between the
   three is the whole reason they are radios. */
.theme-switch { display: inline-flex; align-items: center; gap: 2px; padding: 2px; border-radius: 4px; background: var(--nav-field); flex-shrink: 0; }
.theme-switch input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.theme-switch label { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 3px; color: var(--nav-dim); cursor: pointer; }
.theme-switch label svg { display: block; width: 0.95rem; height: 0.95rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* Dim until asked for, so the one that is on is the only one at full strength: three lit icons
   would say the site was in three states at once. Hover brightens without filling, which keeps the
   raised segment the only thing wearing a background. */
.theme-switch label:hover { color: var(--nav-fg); }
.theme-switch input:checked + label { background: var(--nav-focus); color: var(--nav-fg); }
/* The ring belongs on the drawing, since the input it would land on is a pixel wide and invisible. */
.theme-switch input:focus-visible + label { outline: 2px solid var(--flash); outline-offset: 2px; }

/* ---- Filter bar ---- */
/* Lives in the content column, so it takes that column's width and none of the header's padding.
   Drawn as the tabs the example panel uses for its languages: both rows say what the block under
   them shows, and one shape for the two is one thing to learn. The kind's colour goes on the marker
   rather than the label, because a constructor's grey reads as a marker and not as legible text. */
.filter-bar { margin-bottom: 1.1rem; display: flex; gap: 0.25rem; align-items: center; flex-wrap: wrap; border-bottom: 1px solid var(--border); }
/* A display of its own outranks the browser's rule for the attribute, so hidden has to be said here
   or the bar the search page hides stays on the page as an empty rule across the column. */
.filter-bar[hidden], .filter-btn[hidden] { display: none; }
.filter-btn { appearance: none; background: none; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; padding: 0.4rem 0.8rem; font: inherit; font-size: 0.82rem; font-weight: 500; color: var(--text3); cursor: pointer; }
.filter-btn:hover { color: var(--text); }
/* A kind's tab is underlined in the ink the marks it filters are drawn in, so the tab and its rows
   read as one thing and follow a retuned palette together. All filters nothing in particular and
   keeps the accent. */
.filter-btn.active { color: var(--text); border-bottom-color: var(--kind); }
.filter-btn.active[data-kind="all"] { border-bottom-color: var(--flash); }
/* The switches at the bar's right end, which hide whole classes of member rather than kinds. On
   wears the active tabs' underline, each in the ink of what it shows - the warning's orange under
   Obsolete, the All tab's accent under Inherited - sitting on the bar's rule the way the tabs'
   does; off fades the bar to the border grey, a switch drawn in the off position, so half a list
   going missing never reads as the type having less API. The wrapper stretches to the bar's
   height so the underline lands on the rule instead of floating above it. */
.member-toggles { margin-left: auto; align-self: stretch; display: flex; gap: 0.35rem; }
/* One width for both states, because the label gains weight when the switch is on: text that
   resizes under the pointer walks the row, and a control should hold still while it is used. */
.toggle-btn { appearance: none; background: none; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; width: 4.5rem; padding: 0.4rem 0; text-align: center; font: inherit; font-size: 0.78rem; color: var(--text3); cursor: pointer; }
.toggle-btn:hover { color: var(--text); }
/* On also carries the tabs' weight, so a live switch reads in the bar's own voice and a dead one
   a step quieter. */
.toggle-btn[aria-pressed="true"] { font-weight: 500; }
#toggle-obsolete[aria-pressed="true"], #whatsnew-obsolete[aria-pressed="true"] { border-bottom-color: var(--note-obsolete); }
#whatsnew-added[aria-pressed="true"] { border-bottom-color: var(--oc-green-6); }
#toggle-inherited[aria-pressed="true"] { border-bottom-color: var(--flash); }
.toggle-btn[aria-pressed="false"] { border-bottom-color: var(--border2); }
.asm-legend { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; margin-left: 0.5rem; }
.legend-item { display: flex; align-items: center; gap: 0.3rem; font-size: 0.75rem; color: var(--text3); white-space: nowrap; text-decoration: none; }
.legend-item:hover { color: var(--text); }
.legend-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

/* ---- Layout ---- */
.layout { display: flex; flex: 1; overflow: hidden; }

/* ---- Sidebar ---- */
/* Scrolls, but never draws a bar: the tree is a narrow column and a gutter inside it costs more
   than it tells you. The three properties cover Firefox, old Edge and the WebKit/Blink family. */
.sidebar { width: 280px; min-width: 150px; max-width: 600px; background: var(--bg2); overflow-y: auto; overflow-x: hidden; scrollbar-width: none; -ms-overflow-style: none; flex-shrink: 0; }
.sidebar::-webkit-scrollbar { display: none; }
/* Hidden as a fact about the whole page rather than the column: the attribute lives on the root so
   the head script can put a remembered state back before the sidebar is even parsed, and the handle
   goes with the column it resizes. */
:root[data-sidebar="hidden"] .sidebar,
:root[data-sidebar="hidden"] .resize-handle { display: none; }
/* ?plain=true: the page alone, for a host that embeds it and brings its own navigation. */
:root[data-plain] header,
:root[data-plain] .skip-link,
:root[data-plain] .sidebar,
:root[data-plain] .resize-handle,
:root[data-plain] .breadcrumbs { display: none; }
/* Pinned, like the rows under it: it acts on the whole tree, so it is no use only while the top of
   the tree is in view. Opaque and above the pinned rows, which pass beneath it. Its height is
   written on rather than left to the contents, because those rows pin against it - see --tree-bar.
   Anything added here that makes the bar taller - a second row of controls, a taller field - is a
   change to --tree-bar and nothing else: the rows read their offsets from it. */
.sidebar-toolbar { position: sticky; top: 0; z-index: 3; height: var(--tree-bar); background: var(--bg2); padding: 0.3rem 0.6rem; display: flex; gap: 0.4rem; align-items: center; }
/* Written the way the group headings under it are: it is one rung further out on the same ladder,
   naming what kind of name the column lists. */
.sidebar-title { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; color: var(--text3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* At the right end of the bar, and bare until pointed at: the bar is quiet chrome, and a drawn
   face on its one control would be the loudest thing in the column. The border surfacing under
   the pointer is what says it is a button; transparent rather than absent, so nothing shifts. */
#collapse-all-btn { flex-shrink: 0; margin-left: auto; background: none; border: 1px solid transparent; color: var(--text2); width: 1.5rem; height: 1.5rem; padding: 0; border-radius: 4px; cursor: pointer; display: flex; align-items: center; justify-content: center; }
#collapse-all-btn:hover:not(:disabled) { border-color: var(--border2); }
/* Still in the bar when everything is shut - a control that vanishes reads as the bar changing
   shape - just drawn back until a group opens and gives it something to do. */
#collapse-all-btn:disabled { opacity: 0.35; cursor: default; }
#collapse-all-btn svg { display: block; width: 1rem; height: 1rem; }
.resize-handle { width: 4px; background: var(--border); cursor: col-resize; flex-shrink: 0; transition: background 0.15s; user-select: none; -webkit-user-select: none; }
.resize-handle:hover, .resize-handle.dragging { background: var(--flash); }

/* ---- Tree ---- */
.tree-ns { border-bottom: 1px solid var(--border); }
/* Sits above the groups rather than inside one, so it gets the group row's padding back. */
.tree-overview .tree-type-label { padding: 0.5rem 0.75rem; }
.tree-ns-label { display: flex; align-items: center; gap: 0.4rem; padding: 0.5rem 0.75rem; cursor: pointer; font-size: 0.72rem; font-weight: 700; color: var(--text3); text-transform: uppercase; user-select: none; background: var(--bg2); border: none; width: 100%; text-align: left; font-family: inherit; }
.tree-ns-label:hover { background: var(--bg3); color: var(--text); }
/* A namespace row, which is a step in the nesting rather than a heading over it: written like the
   type rows under it and marked with the namespace drawing, so the tree reads as one tree. The rule
   between groups goes with the heading look - forty of them under a list of rows is a grid, not a
   separation - which leaves category mode's headings as the two modes' visible difference. */
.tree-ns-plain { border-bottom: none; }
/* A square, so the rotation below turns about its centre and the arrow does not drift sideways. */
.tree-arrow { display: inline-flex; align-items: center; justify-content: center; width: 1rem; height: 1rem; flex-shrink: 0; transition: transform 0.15s; }
/* Drawn past its own box: the box is the layout - the arrow column every indent is measured
   from - and the glyph is the picture, made bigger without the column moving. It stays centred,
   so it spends the overflow evenly and the rotation still turns it in place. */
.tree-arrow svg { display: block; width: 1.275rem; height: 1.275rem; fill: currentColor; }
/* docify swaps a chevron-right for a chevron-down; rotating the one is the same picture. */
.tree-arrow.collapsed { transform: rotate(-90deg); }
/* The go-elsewhere arrow: never rotated, because it always means the same leaving. At the member
   rows' own scale rather than the chevron's - it ends those rows, it does not open them. */
.goto-arrow { display: inline-flex; align-items: center; justify-content: center; width: 1rem; height: 1rem; flex-shrink: 0; }
.goto-arrow svg { display: block; width: 0.85rem; height: 0.85rem; fill: currentColor; }
.tree-arrow-spacer { display: inline-block; width: 1rem; flex-shrink: 0; }
.tree-ns-children.collapsed { display: none; }
/* Where a group's rows should be, when the fetch that carries them did not arrive. */
.tree-empty { padding: 0.28rem 0.75rem 0.28rem 1.75rem; font-size: 0.78rem; color: var(--text2); }
.tree-type-label { display: flex; align-items: center; padding: 0.28rem 0.75rem; cursor: default; user-select: none; background: var(--bg2); }
.tree-type-label:hover { background: var(--bg3); }
/* A namespace row is a type row with a namespace on it: the same box, the same drawing column, and
   the same split between an arrow that opens it and a name that goes to its page. */
.tree-link, .tree-ns-link { color: var(--text2); text-decoration: none; font-size: 0.82rem; display: flex; align-items: center; gap: 0.35rem; flex: 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.tree-link:hover, .tree-ns-link:hover { color: var(--text); }
.tree-link.active, .tree-ns-link.active { color: var(--flash); font-weight: 600; }
/* The kind drawings, on the column the lettered squares used to hold: the same box, so the tree's
   left edge is one column whether a row wears a drawing, the Overview page's mark or neither.
   Painted here rather than by whatever draws one: every kind is one ink, so a colour written onto
   each of the hundreds of icons a page carries would be the same string a hundred times over. */
.kind-icon { display: block; width: 1.1rem; height: 1.1rem; flex-shrink: 0; color: var(--kind); }
/* A step up on a card, where the name beside it is a heading rather than a row: the drawing holds
   its own against the larger text instead of sitting under it, and lands about where the word it
   replaced did. */
.member-header .kind-icon { width: 1.25rem; height: 1.25rem; }
/* Declared, never drawn. Taken out of the flow rather than hidden with display, which is the one
   thing that has ever stopped a <use> resolving. */
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.tree-badge { display: inline-flex; align-items: center; justify-content: center; width: 1.1rem; height: 1.1rem; border-radius: 3px; font-size: 0.6rem; font-weight: 800; color: white; flex-shrink: 0; }
/* From the same scale as everything else, rather than the one slate left over from before it: the
   Overview mark is filled where the kinds are drawn, and that is the whole of what sets it apart. */
.tree-badge-doc { background: var(--oc-gray-8); }
/* A lettered square rather than a drawing, there being no drawing for a category: on the kind ink,
   with the ink's own text, so it sits with the marks below it under either theme. */
.tree-badge-cat { background: var(--kind); color: var(--kind-ink); }
/* The static mark: the badge's shape drawn rather than filled, so it reads as something said about
   the kind badge beside it and never as a kind of its own. */
.tree-badge-static { background: none; border: 1px solid var(--text4); color: var(--text3); }
.tree-badge svg { display: block; width: 0.72rem; height: 0.72rem; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
/* The member rows hang off the arrow that opened them, which is the one thing left on screen saying
   where the list came from once its type has scrolled away. Drawn once from the container rather
   than a segment per row: the rows are a single run and the line through them is a single line.
   Placed on the arrow's centre - the row's 0.75rem edge plus half the 1rem arrow column - which is
   0.75rem clear of where the names start. */
.tree-type-children { position: relative; padding-left: 0.25rem; }
.tree-type-children::before { content: ''; position: absolute; left: 1.25rem; top: 0; bottom: 0; border-left: 1px solid var(--border2); }
.tree-type-children.collapsed { display: none; }
/* The tree's own ink, the same one the type rows above them are written in: a member row is a row
   like any other, and dimming the whole list said 'less important' about every member there is.
   What dimming is for here is the inherited rows, which are a second list drawn into the first. */
.tree-child-link { display: flex; align-items: center; gap: 0.35rem; padding: 0.2rem 0.75rem 0.2rem 1.75rem; color: var(--text2); text-decoration: none; font-size: 0.77rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tree-child-link:hover { background: var(--bg3); color: var(--text); }
.tree-child-link.active { color: var(--flash); }
/* One flex item holding both, so the row's gap does not open between the name and its '('. */
.tree-child-link .tree-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* A shade back from the name, so an overload's parameters read as the tiebreaker they are, with
   a hair of space in front - the row's own 0.35rem gap was far too much. */
.tree-child-link .tree-sig { color: var(--text4); margin-left: 0.12rem; }
.tree-toggle, .tree-ns-toggle { background: none; border: none; padding: 0; cursor: pointer; color: inherit; display: inline-flex; align-items: center; }
/* An inherited row is drawn the way a declared one is: it lands on a full card on this same page,
   and which page first declared the member is that card's business to say. An obsolete row dims
   mark and name together - a row kept only to be recognized. Whether either shows at all follows
   the header's toggles: see applyTreeFilters. */
.tree-child-obsolete { color: var(--text4); }
.tree-child-obsolete .kind-icon, .tree-child-obsolete .tree-badge { opacity: 0.3; }
.tree-child-obsolete:hover { color: var(--text2); }
/* The arrow at an inherited row's end, which leads to the declaring type: held at the right
   edge, and quiet until the pointer asks. */
.tree-child-goto { margin-left: auto; flex-shrink: 0; color: var(--text4); }
.tree-child-goto:hover { color: var(--text); }

/* ---- Tree: a branch names itself while you are inside it ---- */
/* A namespace of a few hundred types, or a type of a few hundred members, is taller than the column
   it is read in, so the row naming it is off screen for most of the scrolling. Both rows hold their
   place instead - the namespace or category at the top, the type on the line under it - and each
   only for as long as its own contents are on screen, so passing out of a branch hands the two
   slots to the next one.
   Where the type row pins is where the group row ends, so the two are one number. The two group
   shapes are not the same height - a category heading is text and an arrow at 0.5rem padding, a
   namespace row is a kind drawing at 0.28rem - so the number is written per shape, and written onto
   the row as a height as well, which is what keeps the offset and the height from drifting apart
   into a gap or an overlap. The toolbar is the first of the pinned slots and stacks the same way,
   so both offsets are measured from the bottom of it. --tree-bar carries a little slack over what
   the button needs, since a clipped control costs more than a hair of extra bar. */
.sidebar { --tree-bar: 2.2rem; --tree-head: 2rem; }
.tree-ns-plain { --tree-head: 1.66rem; }
.tree-ns-label { min-height: var(--tree-head); }
.tree-ns-plain > .tree-type-label { min-height: var(--tree-head); }
/* Stacked, so the outer row covers the inner one and both cover the guide line running past them.
   The Overview row is left out: it is a group of one row with nothing under it, so pinning it buys
   no name and only puts it over the row below. */
.tree-ns > .tree-ns-label,
.tree-ns:not(.tree-overview) > .tree-type-label { position: sticky; top: var(--tree-bar); z-index: 2; }
.tree-type > .tree-type-label { position: sticky; top: calc(var(--tree-bar) + var(--tree-head)); z-index: 1; }

/* ---- Main content ---- */
/* No padding at the top. It sits inside the scrollport, so a sticky child stops below it and
   leaves a gap under the navbar with content scrolling through. The space moves to the first
   child instead, where it scrolls away like everything else. */
/* --gutter is the column's side padding, which the blocks bled out to its edges give back. */
.main-content { --gutter: 1.5rem; flex: 1; overflow-y: auto; padding: 0 var(--gutter) 1.5rem; }
.main-content > :first-child { margin-top: 1.5rem; }
/* The breadcrumbs and the filter bar, pinned while the page scrolls under them.

   Spacing is padding rather than margin throughout: a margin on a sticky box is a transparent
   strip that content shows through on its way past, and the negative side margins are what let the
   background reach the edges of a column that is otherwise padded. */
.main-content > .main-sticky { position: sticky; top: 0; z-index: 6; background: var(--bg); margin: 0 calc(-1 * var(--gutter)); padding: 1.5rem var(--gutter) 0.7rem; }
.main-sticky > :last-child { margin-bottom: 0; }
.main-content::-webkit-scrollbar { width: 6px; }
.main-content::-webkit-scrollbar-thumb { background: var(--scrollbar); border-radius: 3px; }
.ns-section { margin-bottom: 2.5rem; }
.ns-heading { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; color: var(--text3); margin-bottom: 1rem; padding-bottom: 0.4rem; border-bottom: 1px solid var(--border); }
.type-section { margin-bottom: 1.25rem; }
/* No rule down the left and no indent to hold one: the heading already groups these. */
.type-children { margin-top: 0.4rem; }

/* ---- Breadcrumbs ---- */
/* Nudged left onto the same optical edge as the title row under them, whose arrow spends its
   drawing's whitespace the same way. */
.breadcrumbs { font-size: 0.78rem; color: var(--text4); margin-bottom: 1rem; margin-left: -0.25rem; }
.breadcrumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: 0.3rem; padding: 0; }
.breadcrumbs a { color: var(--text3); text-decoration: none; }
.breadcrumbs a:hover { color: var(--flash); }
.breadcrumbs li::after { content: "/"; margin-left: 0.3rem; color: var(--border2); }
.breadcrumbs li:last-child::after { content: ""; }
/* The assembly and namespace crumbs wear their icons. Flexed because kind icons are drawn block,
   and sized down from their row size to the trail's smaller type. */
.breadcrumbs li:has(.kind-icon), .breadcrumbs li:has(.kind-icon) > a { display: inline-flex; align-items: center; }
.breadcrumbs .kind-icon { width: 1rem; height: 1rem; margin-right: 0.3rem; }

/* ---- Page heading ---- */
.page-title { font-size: 1.45rem; font-weight: 650; color: var(--text); letter-spacing: -0.01em; word-break: break-word; }
/* Ancestors run off the right of the title rather than wrapping under it: the chain is context for
   the name, and a deep one must not push the rest of a sticky header down the page.

   Centred rather than sat on the title's baseline, because the title is a row of its own now and a
   row's baseline is whatever its first item's happens to be - here a drawing, whose baseline is its
   bottom edge, and not agreed on between browsers. Centring asks nothing of either box. */
.page-title-row { display: flex; align-items: center; column-gap: 0.45rem; }
.page-title { flex: 0 1 auto; min-width: 0; }
/* A type's name is one thing however long it runs - 'CodeEditor<TDoc, TView, …>' names one type -
   so it goes off the side rather than down the page: wrapping it would take the declaration and
   the description with it, and this line is the top of a header that has a height to keep.

   Scrolled without a bar, because the bar would sit under a heading it is nothing to do with and
   be visible on every page to serve the few that overflow. The end of a name is decoration
   compared with its beginning; anyone who wants it can drag the line or shift-wheel it.

   Held to seven tenths of the row, so what the name overruns is its own box and never the chain
   beside it: a long one starts scrolling at that mark instead of taking the width and leaving the
   type's ancestry a stub. */
.page-title-row .page-title { max-width: 70%; white-space: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -ms-overflow-style: none; }
.page-title-row .page-title::-webkit-scrollbar { width: 0; height: 0; }
/* The edge a long name runs past, faded rather than marked with an ellipsis: an ellipsis says the
   rest was cut off, and here the rest is a drag away. Worn only while something is actually past
   the edge - the script takes it off at the end of the run, and never puts it on a name that fits,
   where a fade over the last letters would read as a defect. */
.page-title-row .page-title.title-clipped { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent); }
/* Nudged onto the name's baseline. Centring the row put the chain's own middle level with the
   title's, and small text centred against large reads high - the two sit on a line together only
   once the smaller one comes down. An offset rather than baseline alignment, since the title is a
   row whose baseline browsers do not agree on; relative, so it moves without moving anything else. */
/* Ellipsised where it runs out of room: the chain has nowhere to scroll to, so a deep one was
   being cut mid-word with nothing to say it had been. The mark is the whole difference between a
   name that ends there and a name that carries on. */
.type-chain { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.78rem; position: relative; top: 0.2rem; }
/* Dimmer than the name it leads to: this is where the type came from, not what the page is about.
   Dropped a hair against the separators: those are middle-aligned, which centres them on the
   lowercase letters' middle, and these are capitalised names whose optical centre sits above that. */
.type-chain .see-ref { font-family: inherit; color: var(--text3); position: relative; top: 0.08rem; }
.type-chain .see-ref:hover { color: var(--flash); text-decoration: underline; }
/* The tree's chevron, at the tree's size, turned to point back the way the chain reads. Aligned
   by its middle so the box centres on the names whatever size it is - the box is far taller than
   the letters, and sitting it on their baseline hoists the glyph above the line. */
.chain-sep { display: inline-flex; align-items: center; justify-content: center; width: 1.5rem; height: 1.5rem; vertical-align: middle; color: var(--text4); transform: rotate(90deg); }
.chain-sep svg { display: block; width: 1.275rem; height: 1.275rem; fill: currentColor; }
.page-title .page-kind { font-size: 0.6em; font-weight: 500; color: var(--text4); margin-left: 0.5rem; }
/* The drawing at its largest, since this is the one place a page says what it is about rather than
   listing things.

   Its title becomes a row to carry it, rather than the drawing sitting in a line of text: at this
   size it is taller than the letters, so aligning it by their baseline both leaves it low and
   stretches the line box under it. A row centres the two against each other and neither has to know
   the other's size. Only the titles that carry a drawing - a type's and a member's - are rows; the
   rest are a name and a small word after it, which reads as the line it is. */
.page-title:has(.kind-icon) { display: flex; align-items: center; gap: 0.5rem; }
.page-title .kind-icon { width: 1.75rem; height: 1.75rem; }
/* ---- Page head: the derived tree ---- */
/* The arrow in front of the name, and the hierarchy it opens. One button shape for the title's
   arrow and every branch inside the tree: each is the tree-arrow in a bare button, so a branch
   opens with the same gesture that opened the tree. */
.derived-toggle { display: inline-flex; align-items: center; justify-content: center; background: none; border: none; padding: 0; cursor: pointer; color: var(--text3); flex-shrink: 0; }
.derived-toggle:hover { color: var(--flash); }
/* Sized to be found, not just to match: this arrow is the only way into the derived tree, and at
   the tree's size - or even the kind drawing's 1.75rem - it read as ornament next to 1.45rem
   letters. The negative margins spend the whitespace the drawing carries inside its own box: the
   left puts the glyph's edge on the head's, the right closes it up on the kind drawing without
   giving up the row's gap everywhere else. */
.page-title-row > .derived-toggle { margin: 0 -0.48rem 0 -0.67rem; }
.page-title-row > .derived-toggle .tree-arrow { width: 2rem; height: 2rem; }
/* Stroked over its own fill: a bolder cut of the same chevron, not a second drawing, so the
   title's arrow and the branch arrows still turn the same shape. */
.page-title-row > .derived-toggle .tree-arrow svg { width: 1.75rem; height: 1.75rem; stroke: currentColor; stroke-width: 2; stroke-linejoin: round; }
.derived-tree { margin-top: 0.4rem; }
/* Capped and scrolling in place past the cap, on the intro's reasoning: the tree lives in the
   pinned brief, and a hierarchy of a hundred types opened out would otherwise stand a headerful
   of names over the list the reader came to read. The box holds the rows alone - the filter sits
   above it rather than inside it, so the rows' scrollbar stops short of the field. */
.derived-scroll { max-height: 19.5rem; overflow: auto; scrollbar-width: thin; }
/* Both closed shapes named here: 'collapsed' hides nothing on its own anywhere in this sheet,
   each tree scopes its own reading of it. */
.derived-tree.collapsed, .derived-tree ul.collapsed { display: none; }
.derived-tree ul { list-style: none; margin: 0; padding: 0; }
/* The rows are the sidebar's - the same label and link boxes at the same sizes - so the two trees
   read as one drawing. Only the ground differs: the sidebar's bg2 is its column's, and inside the
   head's card it would stripe every row. The arrows take the row's ink for the same reason. */
.derived-tree .tree-type-label { background: none; }
.derived-tree .derived-toggle { color: inherit; }
/* The shared link path's anchor, dressed as a tree row's name the way the chain dresses it: the
   row's own ink and letters, and clipped rather than wrapped - a deep row has already spent the
   width its depth costs. */
.derived-tree .see-ref { font-family: inherit; color: inherit; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* One nesting step is one arrow column. The line hangs a branch's children off the arrow that
   opened them, on the arrow's centre - the label's 0.75rem edge plus half the 1rem arrow - and
   that number holds at every depth, because each list starts where its parent row did. */
.derived-tree ul ul { position: relative; padding-left: 1rem; }
.derived-tree ul ul::before { content: ''; position: absolute; left: 1.25rem; top: 0; bottom: 0; border-left: 1px solid var(--border2); }
/* Above the scrolling box rather than pinned inside it - what a sticky row cannot do is get out
   of the way of the box's own scrollbar. Positioned for the two corner marks. The field is the
   header search's, at the tree's scale and the tree's width: borderless, its mark at the right,
   and on the focus grey at rest - the caret comes and goes without the ground jumping under it. */
.derived-filter-row { position: relative; padding: 0 0 0.3rem; }
.derived-filter { display: block; width: 100%; padding: 0.38rem 2rem 0.38rem 0.6rem; font: inherit; font-size: 0.8rem; color: var(--text); background: var(--bg3); border: none; border-radius: 4px; outline: none; }
.derived-filter::placeholder { color: var(--text4); }
/* One corner, two marks: the funnel names the field while it is empty, and the moment there is
   anything to clear, the same funnel crossed out clears it - one drawing in one box, so the
   corner never shifts under the swap. */
.derived-filter-row.filled .derived-filter-icon { display: none; }
.derived-filter-clear { display: none; position: absolute; right: 0.55rem; top: calc(50% - 0.15rem); transform: translateY(-50%); appearance: none; border: none; background: none; cursor: pointer; padding: 0; width: 1rem; height: 1rem; color: var(--text3); }
.derived-filter-row.filled .derived-filter-clear { display: inline-flex; align-items: center; justify-content: center; }
.derived-filter-clear:hover { color: var(--text); }
.derived-filter-clear svg { display: block; width: 1rem; height: 1rem; }
/* The site-wide ring outranks a class, so it is declined at its own game: the header search
   escapes it by id, this field by doubling up. */
.derived-filter:focus-visible { outline: none; }
/* The corner the mark draws in is spoken for, so the native clear button goes the way the header
   search sends it. */
.derived-filter::-webkit-search-cancel-button, .derived-filter::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
/* Centred on the field, not the row: the row's bottom padding pulls its middle 0.15rem low. */
.derived-filter-icon { position: absolute; right: 0.55rem; top: calc(50% - 0.15rem); transform: translateY(-50%); width: 1rem; height: 1rem; pointer-events: none; color: var(--text4); }
/* While a query is typed the tree answers it alone: every branch is held open with its arrow
   turned to say so, and the script leaves standing only the rows that match or lead to one. The
   collapsed state under this is untouched, so clearing the box hands back the tree as it was. */
.derived-tree.filtering ul.collapsed { display: block; }
.derived-tree.filtering .tree-arrow.collapsed { transform: none; }
.page-subtitle { font-family: monospace; font-size: 0.76rem; color: var(--fullname); margin-top: 0.3rem; word-break: break-all; }
.page-intro { color: var(--text2); font-size: 0.93rem; line-height: 1.6; margin-top: 0.6rem; }
.page-head { margin-bottom: 1.6rem; }
/* The type's identity stays on screen while its members scroll under it. Bled out to the gutters,
   because .main-content is padded and content would otherwise scroll past either side of it. */
/* Sticks under the breadcrumbs and filter rather than at the top of the column, and below them in
   the stack so it slides beneath rather than over. The offset is measured, not written here: the
   block above is as tall as its filter bar wraps to. */
.page-head.sticky-head { position: sticky; top: var(--sticky-top, 0px); z-index: 5; background: var(--bg); margin: 0 calc(-1 * var(--gutter)) 1.2rem; padding: 0.75rem var(--gutter); border-bottom: 1px solid var(--border2); display: flex; flex-direction: column; max-height: 55vh; }
/* Everything above the members rides here - what the type relates to, what it is parameterised on,
   what it says about itself - so it holds still while they scroll under it. Capped, because a type
   with six paragraphs of remarks would otherwise pin a headerful of prose over the viewport and
   leave the list nowhere to go; past the cap the head scrolls within itself. */
/* A cap of its own, not just the head's: the head's 55vh is shared with the brief, so a detail
   block long enough to claim what the brief does not - eighteen type parameters, or relations on a
   type deep in a hierarchy - could still stand half a screen tall before anything stopped it, which
   is a headerful of context over a list the reader came to read. Past this it scrolls in place. */
.page-head-body { min-height: 0; max-height: 20vh; padding-top: 0.5rem; overflow-y: auto; scrollbar-width: thin; }
/* The head is a card the width of the column: the name, the declaration and the description on the
   card's own ground, and everything that details the type - what it relates to, what it is
   parameterised on, its remarks - under a hairline on the page's, exactly as a member card splits.
   The negative margins are the head's padding given back, so the ground reaches its edges.

   Outside the scrolling part, both because the identity is what the head is for and because a
   block reaching past its container's edges is a horizontal scrollbar the moment that container
   is the thing that scrolls. */
.page-head-brief { flex-shrink: 0; background: var(--card-bg); border-bottom: 1px solid var(--card-split); margin: -0.75rem calc(-1 * var(--gutter)) 0; padding: 0.35rem var(--gutter) 0.75rem; }
/* The one part of the brief with no length of its own: a summary written as three paragraphs would
   carry the tabs, and with them the members, off the bottom of the screen - and the brief cannot
   shrink, because the name and the declaration are what the head is for. Five lines, then it
   scrolls in place, so the head is the same height whatever the type says about itself. */
.page-head-brief .page-intro { max-height: calc(1.6em * 5); overflow-y: auto; scrollbar-width: thin; }
/* Five lines is right for prose and wrong for a summary that draws a diagram, so the cap comes off
   on request. Opening it unpins the whole head as well: a full-height description held over the
   viewport would leave the members nowhere to go, so an opened head scrolls away like any other
   block and the members follow it. */
.page-head.sticky-head.intro-open { position: static; max-height: none; }
.page-head.sticky-head.intro-open .page-head-brief .page-intro { max-height: none; overflow: visible; }
/* The detail comes off its cap with it. Nothing is being held over the viewport once the head has
   been unpinned, so a second scrolling box inside a block that now scrolls with the page is only a
   second place to have to scroll. */
.page-head.sticky-head.intro-open .page-head-body { max-height: none; overflow: visible; }
/* At the description's top-right corner rather than under it, and the corner is the one edge of the
   box that opening it does not move: the text grows downwards, so the pointer is still on the
   button afterwards and closing it again is a second click in the same place. The room it sits in
   is a row of its own above it, at the right: over the text it covered a word, and beside the text
   it cost every line the width of a label.

   The row is above rather than below because that is the edge of the box that opening it does not
   move - the text grows downwards - and it is anchored right, so 'Show all' becoming the longer
   'Show less' grows leftwards. Between them the pointer does not have to follow the button
   anywhere: closing it again is a second click where the first one landed.

   It takes the gap the description was leaving under the declaration rather than adding a row to a
   head whose height is the whole point of the cap. */
.page-head-intro { display: flex; flex-direction: column; }
.page-head-intro:has(.intro-more:not([hidden])) .page-intro { margin-top: 0.1rem; }
.intro-more { align-self: flex-end; margin-top: 0.35rem; display: inline-flex; align-items: center; gap: 0.15rem; padding: 0; background: none; border: none; cursor: pointer; font: inherit; font-size: 0.75rem; white-space: nowrap; color: var(--text4); }
.intro-more[hidden] { display: none; }
.intro-more:hover { color: var(--flash); }
.intro-more-arrow { display: inline-flex; width: 1rem; height: 1rem; transition: transform 0.15s; }
.intro-more-arrow svg { display: block; width: 0.85rem; height: 0.85rem; fill: currentColor; }
.intro-open .intro-more-arrow { transform: rotate(180deg); }
/* The breadcrumbs are the top of that card rather than a strip above it, so they take the same
   ground - but only where there is a head to belong to, which is a type page.

   Closed up against the title too: the gap under them was holding two blocks apart, and now that
   the trail and the name are on one ground it was only pushing the name down the page. */
.main-content:has(.page-head-brief) > .main-sticky { background: var(--card-bg); padding-bottom: 0.3rem; }
.page-head.sticky-head .declaration { margin-top: 0.6rem; margin-bottom: 0; }
/* The kinds sit on the head's own rule rather than above it, so the tabs and the members they
   filter are the two sides of one line. The pull is the head's bottom padding, plus the pixel that
   puts the marker over that rule instead of under it. Outside the scrolling part, so a long head
   cannot carry the tabs off with it. */
.page-head.sticky-head .filter-bar { flex-shrink: 0; margin: 0.7rem 0 calc(-0.75rem - 1px); border-bottom: none; }

.chip { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.75rem; color: var(--text3); background: var(--bg3); border-radius: 3px; padding: 0.1rem 0.55rem; text-decoration: none; }
a.chip:hover { color: var(--flash); }
/* When an API arrived, at the far end of the row: it says something about the API's history rather
   than about how it is written - everything about how it is written is on the declaration - and
   the left of the row is where a reader scanning down a list of members is already looking. The
   same chip closes a type page's title row, so the fact is in the same place whether the type is
   being read or listed.

   In the grey the assembly name and the anchor use: this is a fact to be looked up on the one row
   that raised the question, not read down the column. Never shrunk: it is a handful of characters,
   and a long chain or signature beside it has somewhere else to give. Where something already
   claims the end of the row
   - the assembly name on a type card, the Example button on a member's - it sits beside that
   instead, because two auto margins in one row split the free space between them and leave both
   adrift.

   With the panel gone the chip's right padding is only air, holding the text short of the inset
   the row's other content ends at. Dropped, so the fact ends at the row's own edge. */
.chip-since { margin-left: auto; flex-shrink: 0; color: var(--text4); background: transparent; padding-right: 0; }
/* The deprecated mark in the warning's own orange, wherever it rides - the half of the since
   chip that parts when the API arrived from when it stopped being the way, and the bare word
   atop an inherited card's provenance. */
.chip-deprecated { color: var(--note-obsolete); }
/* What's New's arrival mark, in its Added switch's green. */
.chip-added { color: var(--oc-green-6); }
.inherited-from .chip-deprecated { margin-bottom: 0.15rem; }
.asm-name ~ .chip-since, .chip-action ~ .chip-since, .chip-refs ~ .chip-since { margin-left: 0; }
/* Where a type is used, at the end of its title row ahead of the version it arrived in. */
.chip-refs { margin-left: auto; flex-shrink: 0; padding-top: 0.18rem; padding-bottom: 0.18rem; }
#refs .ns-heading { margin: 1.5rem 0 0.25rem; }
/* The groups have no kind ink of their own, so every tab underlines in the accent All uses. */
.refs-tabs .filter-btn.active { border-bottom-color: var(--flash); }

/* ---- Category overview doc ---- */
.cat-doc { background: var(--card-bg); border: 1px solid var(--card-border); border-radius: 8px; padding: 1.1rem 1.4rem; margin-bottom: 1.25rem; line-height: 1.7; font-size: 0.88rem; color: var(--text2); scroll-margin-top: 1rem; }
.cat-doc h1,.cat-doc h2,.cat-doc h3,.cat-doc h4 { color: var(--text); margin: 0.9rem 0 0.4rem; font-size: 1rem; }
.cat-doc h1 { font-size: 1.15rem; }
.cat-doc h1:first-child, .cat-doc h2:first-child { margin-top: 0; }
.cat-doc p { margin: 0.4rem 0; }
.cat-doc ul, .cat-doc ol { margin: 0.4rem 0 0.4rem 1.25rem; }
.cat-doc li { margin: 0.2rem 0; }
.cat-doc code { font-family: monospace; font-size: 0.82rem; background: var(--bg3); padding: 0.1rem 0.3rem; border-radius: 3px; }
.cat-doc pre { background: var(--bg3); border-radius: 6px; padding: 0.75rem 1rem; overflow-x: auto; margin: 0.6rem 0; }
.cat-doc pre code { background: none; padding: 0; }
.cat-doc a { color: var(--flash); text-decoration: none; }
.cat-doc a:hover { text-decoration: underline; }
.cat-doc blockquote { border-left: 3px solid var(--border2); padding-left: 0.9rem; color: var(--text3); margin: 0.6rem 0; }
.cat-doc hr { border: none; border-top: 1px solid var(--border); margin: 1rem 0; }
.cat-doc img { max-width: 100%; height: auto; }
/* The landing page's authored prose: the same typography, without the card around it. */
.cat-doc.site-intro { background: none; border: none; border-radius: 0; padding: 0; margin-bottom: 0; }
.tree-cat-doc-link { font-style: italic; }
/* The active row is already marked; italics on top of that reads as a second, unrelated state. */
.tree-cat-doc-link.active { font-style: normal; }

/* ---- Diagrams ---- */
/* Drawn by d2 at build time, so what lands here is an svg carrying its own palette for both
   themes. Nothing is coloured from this end; the only job is fitting it to the column.

   The svg keeps the size it was drawn at rather than filling the width, since a diagram of three
   boxes blown up to the width of the page reads as a poster. max-width brings the other case back
   in, and the scroll is for a diagram too wide to shrink legibly. */
.diagram { margin: 0.9rem 0; overflow-x: auto; }
.diagram svg { max-width: 100%; height: auto; }

/* ---- Math ---- */
/* Typeset to MathML at build time, so what follows is the browser's own rendering of it and the
   only work left is placing the block and letting a long equation scroll rather than overflow.
   Temml's stylesheet, below, is the part that corrects for how each engine draws it. */
.math-display { margin: 0.9rem 0; overflow-x: auto; }
math {
  font-family: "Cambria Math", 'STIXTwoMath-Regular', 'NotoSansMath-Regular', math;
  font-style: normal;
  font-weight: normal;
  line-height: normal;
  font-size-adjust: none;
  text-indent: 0;
  text-transform: none;
  letter-spacing: normal;
  word-wrap: normal;
  direction: ltr;
  /* Prevent Firefox from omitting the dot on i or j. */
  font-feature-settings: "dtls" off;
}

math * {
  border-color: currentColor;
}

/* display: block is necessary in Firefox and Safari.
 * Not in Chromium, which recognizes display: "block math" written inline. */
 math.tml-display {
  display: block;
  width: 100%;
}

*.mathcal {
  /* NotoSans */
  font-feature-settings: 'ss01';
}

math .mathscr {
  font-family: "Temml";
}

mo.tml-prime {
  font-family: Temml;
}

/* Cramped superscripts in WebKit */
mfrac > :nth-child(2),
msqrt,
mover > :first-child {
  math-shift: compact
}

.menclose {
  display: inline-block;
  position: relative;
  padding: 0.5ex 0ex;
}
.tml-cancelto {
  display: inline-block;
  position: absolute;
  top: 0;
  left: 0;
  padding: 0.5ex 0ex;
  background-color: currentColor;
  /* Use the SVG as an alpha mask (painted by background-color) */
  -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><defs><marker id='a' markerHeight='5' markerUnits='strokeWidth' markerWidth='7' orient='auto' refX='7' refY='2.5'><path fill='black' d='m0 0 7 2.5L0 5z'/></marker></defs><line x2='100%25' y1='100%25' stroke='black' stroke-width='.06em' marker-end='url(%23a)' vector-effect='non-scaling-stroke'/></svg>");
          mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><defs><marker id='a' markerHeight='5' markerUnits='strokeWidth' markerWidth='7' orient='auto' refX='7' refY='2.5'><path fill='black' d='m0 0 7 2.5L0 5z'/></marker></defs><line x2='100%25' y1='100%25' stroke='black' stroke-width='.06em' marker-end='url(%23a)' vector-effect='non-scaling-stroke'/></svg>");
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;
          mask-size: 100% 100%;
  -webkit-mask-position: 0 0;
          mask-position: 0 0;
}

@supports (-moz-appearance: none) {
  /* \vec w/o italic correction for Firefox */
  .tml-vec {
    transform: scale(0.75)
  }
  /* Fix \cancelto in Firefox */
  .ff-narrow {
    width: 0em;
  }
  .ff-nudge-left {
    margin-left: -0.2em;
  }
  /* Squash hidden mrows in \bordermatrix. Messes with centering, but necessary to squash. */
  .ff-squash mtd {
    display: block;
    height: 0;
  }
}

@supports (not (-moz-appearance: none)) {
  /* Chromium and WebKit */
  /* prime vertical alignment */
  mo.tml-prime {
    font-family: Temml;
  }
  /* Italic correction on superscripts */
  .tml-sml-pad {
    padding-left: 0.05em;
  }
  .tml-med-pad {
    padding-left: 0.10em;
  }
  .tml-lrg-pad {
    padding-left: 0.15em;
  }
}

@supports (-webkit-backdrop-filter: blur(1px)) {
  /* WebKit vertical & italic correction on accents */
  .wbk-acc {
    /* lower by x-height distance */
    transform: translate(0em, 0.431em);
  }
  .wbk-sml {
    transform: translate(0.07em, 0);
  }
  .wbk-sml-acc {
    transform: translate(0.07em, 0.431em);
  }
  .wbk-sml-vec {
    transform: scale(0.75) translate(0.07em, 0);
  }
  .wbk-med {
    transform: translate(0.14em, 0);
  }
  .wbk-med-acc {
    transform: translate(0.14em, 0.431em);
  }
  .wbk-med-vec {
    transform: scale(0.75) translate(0.14em, 0);
  }
  .wbk-lrg {
    transform: translate(0.21em, 0);
  }
  .wbk-lrg-acc {
    transform: translate(0.21em, 0.431em);
  }
  .wbk-lrg-vec {
    transform: scale(0.75) translate(0.21em, 0);
  }
}

/* \cancel & \phase use background images. Get them to print. */
menclose {
  -webkit-print-color-adjust: exact;  /* Chrome & Edge */
          print-color-adjust: exact;
}

/* Array cell justification in Firefox & WebKit */
.tml-right {
  text-align: right;
}
.tml-left {
  text-align: left;
}

/* For CD labels that grow to the left in Firefox and WebKit */
.tml-shift-left { margin-left:-200% }

/* Styles for Chromium only */
@supports (not (-webkit-backdrop-filter: blur(1px))) and (not (-moz-appearance: none)) {
  /* Italic correction on accents */
  .chr-sml {
    transform: translate(0.07em, 0)
  }
  .chr-sml-vec {
    transform: scale(0.75) translate(0.07em, 0)
  }
  .chr-med {
    transform: translate(0.14em, 0)
  }
  .chr-med-vec {
    transform: scale(0.75) translate(0.14em, 0)
  }
  .chr-lrg {
    transform: translate(0.21em, 0)
  }
  .chr-lrg-vec {
    transform: scale(0.75) translate(0.21em, 0)
  }

  /* For CD labels that grow to the left */
  .tml-shift-left { margin-left:-100% }

  /* MathML Core & Chromium do not support the MathML 3.0 element <menclose> attributes. */
  /* So use styles. */
  menclose {
    position: relative;
    padding: 0.5ex 0ex;
  }
  
    .tml-overline {
    padding: 0.1em 0 0 0;
    border-top: 0.065em solid;
  }

  .tml-underline {
    padding: 0 0 0.1em 0;
    border-bottom: 0.065em solid;
  }

  .tml-cancel {
    display: inline-block;
    position: absolute;
    left: 0.5px;
    bottom: 0;
    width: 100%;
    height: 100%;
    background-color: currentColor;
  }
  .upstrike {
    clip-path: polygon(0.05em 100%, 0em calc(100% - 0.05em), calc(100% - 0.05em) 0em, 100% 0.05em);
  }
  .downstrike {
    clip-path: polygon(0em 0.05em, 0.05em 0em, 100% calc(100% - 0.05em), calc(100% - 0.05em) 100%);
  }
  .sout {
    clip-path: polygon(0em calc(55% + 0.0333em), 0em calc(55% - 0.0333em), 100% calc(55% - 0.0333em), 100% calc(55% + 0.0333em));
  }
  .tml-xcancel {
    clip-path: polygon(0.05em 0em, 0em 0.05em, calc(50% - 0.05em) 50%, 0em calc(100% - 0.05em), 0.05em 100%, 50% calc(50% + 0.05em), calc(100% - 0.05em) 100%, 100% calc(100% - 0.05em), calc(50% + 0.05em) 50%, 100% 0.05em, calc(100% - 0.05em) 0%, 50% calc(50% - 0.05em));
  }

  .longdiv-top {
    border-top: 0.067em solid;
    padding: 0.1em 0.2em 0.2em 0.433em;
  }
  .longdiv-arc {
    position: absolute;
    top: 0;
    bottom: 0.1em;
    left: -0.4em;
    width: 0.7em;
    border: 0.067em solid;
    transform: translateY(-0.067em);
    border-radius: 70%;
    clip-path: inset(0 0 0 0.4em);
    box-sizing: border-box;}
    .menclose {display: inline-block;
    text-align: left;
    position: relative;
  }
  
  .phasor-bottom {
    border-bottom: 0.067em solid;
    padding: 0.2em 0.2em 0.1em 0.6em;
  }
  .phasor-angle {
    display: inline-block;
    position: absolute;
    left: 0.5px;
    bottom: -0.04em;
    height: 100%;
    aspect-ratio: 0.5;
    background-color: currentColor;
    clip-path: polygon(0.05em 100%, 0em calc(100% - 0.05em), calc(100% - 0.05em) 0em, 100% 0.05em);
  }

  .tml-fbox {
    padding: 3pt;
    border: 1px solid;
  }

  .circle-pad {
    padding: 0.267em;
  }
  .textcircle {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    border: 0.067em solid;
    border-radius: 50%;
   }

   .actuarial {
    padding: 0.03889em 0.03889em 0 0.03889em;
    border-width: 0.08em 0.08em 0em 0em;
    border-style: solid;
    margin-right: 0.03889em;
   }

   /* Stretch \widetilde */
  .tml-tilde-2 {
    transform: scale(2.0, 1.1)
  }
  .tml-tilde-3 {
    transform: scale(3.0, 1.1)
  }
  .tml-tilde-4 {
    transform: scale(4.0, 1.1)
  }
  /* Stretch \widehat */
  .tml-hat-1 {
    transform: scale(1.9, 1.0)
  }
  .tml-hat-2 {
    transform: scale(3.9, 1.0)
  }
  .tml-hat-3 {
    transform: scale(5.8, 1.0)
  }
  .tml-hat-4 {
    transform: scale(7.8, 1.0)
  }
  
  /* set array cell justification */
  .tml-right {
    text-align: -webkit-right;
  }
  .tml-left {
    text-align: -webkit-left;
  }
}

.special-fraction {
  font-family: 'STIX TWO', 'Times New Roman', Times, Tinos, serif;
}

/* flex-wrap for line-breaking in Chromium */
math {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
}
math > mrow {
  padding: 0.5ex 0ex;
}

/* Default mtd top padding is 0.5ex per MathML-Core and user-agent CSS */
/* We adjust for jot and small */
mtable.tml-jot mtd {
  padding-top: 0.7ex;
  padding-bottom: 0.7ex;
}
mtable.tml-small mtd {
  padding-top: 0.35ex;
  padding-bottom: 0.35ex;
}

/* Firefox */
@-moz-document url-prefix() {
  /* Avoid flex-wrap */
  math { display: inline; }
  math > mrow { padding: 0 }
  /* Adjust Firefox spacing between array rows */
  mtd, mtable.tml-small mtd { padding-top: 0; padding-bottom: 0; }
  mtable.tml-jot mtd { padding-top: 0.2ex; padding-bottom: 0.ex; }
}

/* AMS environment auto-numbering via CSS counter. */
.tml-eqn::before {
  counter-increment: tmlEqnNo;
  content: "(" counter(tmlEqnNo) ")";
}

body {
  counter-reset: tmlEqnNo;
}

/* ---- Member cards ---- */
/* No hover state: the card is not a target, only the name and the anchor inside it are.
   Clipped, so the half below can reach the border on three sides and still take the corners. */
.member { --pad-y: 0.9rem; --pad-x: 1.1rem; background: var(--card-bg); border: 1px solid var(--card-border); border-radius: 8px; padding: var(--pad-y) var(--pad-x); margin-bottom: 0.6rem; overflow: hidden; transition: box-shadow 0.15s; scroll-margin-top: var(--anchor-offset, 1rem); }
.member:target { box-shadow: 0 0 0 3px var(--flash); }
/* Two grounds inside the one border: what identifies the member on the card, and everything that
   details it a shade off it under a rule. A reader running down a list reads the name, the
   declaration and the sentence under it, so the parameters and returns are given a shade to be
   skipped by until the reader has stopped at the one they were looking for. A slot of its own
   rather than the page's --bg, since how far it steps off the card is the whole of its job.

   The negative margins are the card's padding given back, so the ground reaches the border rather
   than floating inside it as a second panel. */
.member-detail { background: var(--card-detail); border-top: 1px solid var(--card-split); margin: 0.85rem calc(-1 * var(--pad-x)) calc(-1 * var(--pad-y)); padding: 0.7rem var(--pad-x) 0.85rem; }
.member-detail > :first-child { margin-top: 0; }
/* Bordered in the badge's own colour, so the card and the badge on it read as one mark. */
.member.explicit-impl { border-color: var(--badge-explicit); }
/* An inherited member wears the declared members' full card, ground and all: what it shows is
   the member itself, and the reader who found the name they were looking for should not have to
   leave the page to read the rest. What still tells it apart at a glance is the provenance
   segment at the top right naming the type that declared it, doubling as the card's one real
   link through to where the member is documented and owns its anchor - a link the script widens
   to the whole card, which is why the card takes the pointer cursor and the hover. */
.member.inherited { cursor: pointer; }
/* Under the pointer the border lights up: the card is one click through to where the member is
   documented, and the lit edge is what says so before a word is read. */
.member.inherited:hover { border-color: var(--flash); }
/* The head row seats the member's identity and the provenance side by side; the detail block sits
   below it and spans the card, so the segment reaches only as deep as the part it annotates. */
.inherited-head { display: flex; }
.inherited-head > .member-main { flex: 1; min-width: 0; }
/* The detail keeps the card's ground: its own shade exists to step the block off a card, and an
   obsolete card's ground is the page's - there is nothing to step off of. */
.member.obsolete .member-detail { background: transparent; }
/* An obsolete member keeps its card but loses its voice: the inherited cards' ground and the
   reading text stepped down to grey, so a reader scanning the list passes it the way they pass
   what the page does not own. The note under the name still says why in the warning's colour. */
.member.obsolete { background: var(--card-inherited); color: var(--text3); }
.member.obsolete .member-name, .member.obsolete .member-name a, .member.obsolete .summary { color: var(--text3); }
/* The declaration and the detail go grey whole - syntax paint, section text, parameter names and
   type links alike: colour is what says a line is worth reading, and this card is kept only to be
   recognized. Swept with the universal selector rather than left to the card's colour, because
   the pieces - .section, .param-name, .see-ref and the rest - each set a colour of their own, and
   inheritance does not outrank a rule. The links still work and underline under the pointer,
   affordance enough for a deprecated API. The obsolete note sits outside these blocks and keeps
   its orange: the warning is the one thing on the card still speaking at full voice. */
.member.obsolete .declaration, .member.obsolete .declaration *, .member.obsolete .member-detail, .member.obsolete .member-detail * { color: var(--text3); }
.member.obsolete .see-ref { color: var(--text3); }
/* Dimmer than the card's own text: which base a member came from answers a question the reader
   only asks once they have found the name they were looking for.

   Two stacked lines, 'inherited from' over the type it names, seated at the top of the head row
   where the label sits level with the member's name, and the tree's arrow ahead of the name
   saying the same thing it says there: this leads to the type that declared the member. Sized
   by its own two lines - with no split line to keep straight down the list, a fixed column would
   only hold the member's space open - and the name is shown whole: naming where the member came
   from is the segment's one job, and a name cut to fit does it halfway. Capped at under half the
   card and wrapping past the cap, so a long generic name folds onto more lines instead of
   crowding out the member it annotates. */
.inherited-from { flex: 0 0 auto; max-width: 45%; display: flex; flex-direction: column; align-items: flex-end; padding: 0 0 0 0.9rem; font-size: 0.72rem; color: var(--text4); text-decoration: none; }
.inherited-from > span { max-width: 100%; text-align: right; overflow-wrap: anywhere; }
/* Lit in the accent and drawn only under the pointer: the hovered border already says the card
   leads somewhere, and this says where the reader will land. A step larger than the tree draws
   it, and out of the flow entirely - seated just left of the name and centred on it - because a
   drawing taller than the name's line would stretch that line every time it appeared, and the
   name must not stir when the pointer arrives. */
.inherited-from-type { position: relative; }
.inherited-from-type .goto-arrow { display: none; position: absolute; right: 100%; top: 50%; margin-top: -0.6rem; width: 1.2rem; height: 1.2rem; color: var(--flash); }
.inherited-from-type .goto-arrow svg { width: 1.05rem; height: 1.05rem; }
.member.inherited:hover .inherited-from-type .goto-arrow { display: inline-flex; }
/* The type is the payload of the two lines, so it takes the reading colour and a step up in
   size; saying the card leads somewhere is the border's job, not the text's. */
.inherited-from-type { font-size: 0.78rem; color: var(--text3); margin-top: 0.15rem; }
.member-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.2rem; flex-wrap: wrap; }
/* Every badge and chip is a mark rather than words: double-clicking the name beside one is a reader
   picking up that name to paste somewhere, and 'class' riding along with it is never what they
   meant. */
.explicit-badge, .tree-badge, .chip { user-select: none; -webkit-user-select: none; }
/* The small pill, worn by Explicit alone. */
.explicit-badge { padding: 0.1rem 0.4rem; border-radius: 3px; font-size: 0.62rem; font-weight: 600; color: white; background: var(--badge-explicit); letter-spacing: 0.02em; }
/* Which assembly a card's type came from, pushed to the far end of its header. Grey and unadorned:
   it is there to be looked up rather than looked at, and it shares the row with a name that is the
   point of the card. It brightens on hover, since it does lead somewhere. */
.asm-name { margin-left: auto; padding-left: 0.5rem; font-size: 0.7rem; color: var(--text4); white-space: nowrap; text-decoration: none; }
.asm-name:hover { color: var(--text2); }
.member-name { font-size: 0.97rem; font-weight: 600; color: var(--text); }
/* The interface an explicit implementation came from is a link, but it is also part of a heading. */
.member-name .see-ref { font-family: inherit; }
.member-name .see-ref:hover { text-decoration: underline; }
.member-name a { color: var(--text); text-decoration: none; }
.member-name a:hover { color: var(--flash); }
/* The permalink, kept out of sight until the card is pointed at: a column of hashes down a list of
   sixty members is noise, and the only one worth drawing is the one being read. */
.member-anchor { color: var(--text4); text-decoration: none; font-size: 0.8rem; opacity: 0; }
/* Drawn outright rather than faded, and drawn by hover alone. Both are the same symptom: a # left
   lit on a card the pointer had long since left, somewhere down the page, for no reason a reader
   could see. The fade was what Safari kept - it went on painting a faded-in mark after the hover it
   belonged to had gone, where a plain repaint goes when the hover does. Focus was the rest of it:
   clicking the mark leaves it focused, and :focus-visible still counts a click that follows any
   keyboard use, so the reveal is the pointer's alone and the mark is out of the tab order to match.
   Anything put back here has to be checked in Safari, which is the one that let it show. */
.member:hover .member-anchor { opacity: 1; }
.member-anchor:hover { color: var(--flash); }
.member-fullname { font-size: 0.72rem; color: var(--fullname); font-family: monospace; margin-top: 0.4rem; margin-bottom: 0.45rem; word-break: break-all; }
.summary { color: var(--text2); line-height: 1.6; font-size: 0.88rem; }
.remarks { color: var(--text3); font-size: 0.83rem; margin-top: 0.4rem; }
.section { margin-top: 0.55rem; font-size: 0.83rem; color: var(--text2); }
/* A URL or a long identifier in prose breaks rather than running off the card. */
.member-name, .summary, .remarks, .section, .page-intro, .cat-doc, .note { overflow-wrap: anywhere; }
.section-label { font-weight: 700; color: var(--text3); }
/* No rule under each row: a parameter list runs to three or four short lines, and ruling them turns
   a small table into a grid to be read across rather than a set of names to be scanned down. */
table.params { margin-top: 0.3rem; border-collapse: collapse; width: 100%; }
table.params td, table.params th { padding: 0.22rem 0.4rem; vertical-align: top; text-align: left; }
/* The name and its type take what they need and nothing more - 1% is shorthand for shrink-to-fit
   against the nowrap below - so what is left goes to the description, which is what runs out of
   room first and is the only column with anything to wrap. */
table.params td.param-name { width: 1%; }
/* The cell already pads after the type; the span's own padding would double the gap. */
.param-name .param-type { padding-right: 0; }
/* Body colour, not the link blue it used to borrow: a parameter name is not a link. */
.param-name { font-family: monospace; font-size: 0.8rem; color: var(--text); white-space: nowrap; padding-right: 0.75rem; }
.param-type { font-family: monospace; font-size: 0.78rem; color: var(--text3); white-space: nowrap; padding-right: 0.75rem; }
/* Types inside a signature underline on hover rather than recolouring, so the token keeps its
   syntax colour and the declaration does not turn into a row of links. */
.declaration a, .r-sig a { color: inherit; text-decoration: none; }
.declaration a:hover, .r-sig a:hover { text-decoration: underline; }
/* A type reference is a link, not a code chip: no panel behind it, and it takes the size of
   whatever it sits in, so the same type reads the same in a table, a Remarks paragraph and an
   Implements row. */
.see-ref { font-family: monospace; color: var(--flash); text-decoration: none; }
a.see-ref:hover { text-decoration: underline; }
/* A framework type on Microsoft Learn: blue-grey, so it sits behind the links into this site. */
.see-ref-out { color: var(--ext-ref); }
/* A type from a package that is neither documented here nor part of the framework: nowhere to send
   a reader, so it is greyed to the back of the three - a name being reported, not offered. */
.see-ref-none { color: var(--text4); }
.see-ref-external::after { content: "\2197"; font-size: 0.85em; opacity: 0.6; }
.param-ref { font-family: monospace; font-size: 0.82rem; background: var(--bg3); padding: 0.1rem 0.3rem; border-radius: 3px; color: #0ea5e9; font-style: italic; }
.langword-ref { font-family: monospace; font-size: 0.82rem; background: var(--bg3); padding: 0.1rem 0.3rem; border-radius: 3px; color: var(--tok-keyword); }
.hidden { display: none !important; }
[hidden] { display: none !important; }

/* ---- Declarations and code ---- */
/* No panel behind it: the monospace and the token colours already say this is code, and a filled
   box on every card turned a list of members into a list of boxes inside boxes. */
/* A long signature still scrolls sideways, but nothing is drawn to say so: the block is one or two
   lines tall, and a bar under it is a third of its height spent on furniture. Wheel, trackpad,
   touch and a keyboard all still reach the rest of it. */
.declaration { font-family: monospace; font-size: 0.82rem; color: var(--text2); margin-top: 1rem; margin-bottom: 0.75rem; overflow-x: auto; white-space: pre; scrollbar-width: none; -ms-overflow-style: none; }
.declaration::-webkit-scrollbar { display: none; }
.member .declaration { font-size: 0.78rem; }
pre { background: var(--bg3); border: 1px solid var(--border); border-radius: 6px; padding: 0.75rem 1rem; overflow-x: auto; margin: 0.6rem 0; }
pre code { font-family: monospace; font-size: 0.8rem; line-height: 1.55; background: none; padding: 0; }
code { font-family: monospace; }
.tok-keyword { color: var(--tok-keyword); }
.tok-string { color: var(--tok-string); }
.tok-comment { color: var(--tok-comment); font-style: italic; }
.tok-number { color: var(--tok-number); }
.tok-meta, .tok-decorator { color: var(--tok-meta); }
.tok-type { color: var(--tok-type); }
.tok-func { color: var(--tok-func); }
.tok-punct { color: var(--tok-punct); }

/* ---- Notes, tables, lists in doc content ---- */
.note { border-left: 3px solid var(--flash); background: var(--bg3); padding: 0.5rem 0.8rem; margin: 0.6rem 0; font-size: 0.85rem; }
.note-label { display: block; font-size: 0.65rem; font-weight: 700; text-transform: uppercase; color: var(--flash); margin-bottom: 0.15rem; }
/* The one note that is a warning rather than an aside, and the one mark the page gives the fact.
   Removed is obsolete with the compiler's answer changed from a warning to an error, not a
   different fact, so it reads the same. Its ground is the warning's own orange thinned to a wash
   rather than the asides' grey - translucent, so the one value warms either theme's ground, and a
   browser without color-mix falls back to the grey. */
.note-obsolete, .note-removed { border-left-color: var(--note-obsolete); background: color-mix(in srgb, var(--note-obsolete) 12%, transparent); }
.note-obsolete .note-label, .note-removed .note-label { color: var(--note-obsolete); }
.table-scroll { overflow-x: auto; margin: 0.6rem 0; }
.table-scroll table { border-collapse: collapse; width: 100%; font-size: 0.85rem; }
.table-scroll th, .table-scroll td { text-align: left; padding: 0.3rem 0.5rem; border-bottom: 1px solid var(--border); }

/* ---- Examples ----
   Tabs rather than one block after another: the same example in three languages is three ways of
   saying one thing, and stacking them makes a reader scroll past two of them to reach theirs. */
/* Pushed to the far end of the header row, away from the name that identifies the member.

   Painted and hovered as the header's own buttons are, because it is the same kind of thing: the
   one control on a card otherwise made entirely of description. Set a size up from the Since chip
   it can share the row's end with, which is a label rather than a thing to press. */
.chip-action { background: var(--accent); color: var(--oc-white); font-weight: 500; padding: 0.18rem 0.65rem; margin-left: auto; }
a.chip-action:hover { background: var(--accent); color: var(--oc-white); filter: brightness(1.1); }
.example-tabs { display: flex; gap: 0.25rem; flex-wrap: wrap; border-bottom: 1px solid var(--border); margin: 0.8rem 0 0; }
.example-tab { appearance: none; border: none; background: none; cursor: pointer; font: inherit; font-size: 0.82rem; font-weight: 500; color: var(--text3); padding: 0.4rem 0.8rem; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.example-tab:hover { color: var(--text); }
.example-tab.active { color: var(--flash); border-bottom-color: var(--flash); }
.example-panel { margin-top: 0.8rem; }

/* ---- Examples dock ----
   A column of the layout rather than a thing floating over it, so opening an example narrows the
   member list instead of hiding it and the two can be read against each other. */
/* Width comes from a custom property rather than an inline style, so dragging it cannot outrank
   the narrow-screen rule below that turns the dock into a full-screen overlay. */
.example-dock { position: relative; width: var(--example-dock-width, 42%); min-width: 320px; max-width: 900px; flex-shrink: 0; display: flex; flex-direction: column; background: var(--bg2); border-left: 1px solid var(--border); overflow: hidden; }
/* Straddles the dock's own left edge instead of taking a column of its own, so it appears and
   disappears with the dock and costs the layout nothing while closed. */
.example-resize { position: absolute; left: 0; top: 0; bottom: 0; width: 5px; cursor: col-resize; background: transparent; transition: background 0.15s; z-index: 1; user-select: none; -webkit-user-select: none; }
.example-resize:hover, .example-resize.dragging { background: var(--flash); }
.example-dock-head { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.9rem; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.example-dock-title { display: flex; align-items: center; gap: 0.4rem; min-width: 0; font-size: 0.85rem; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The dock's title is the example page's heading, moved: the drawing comes with it and has to come
   down to the size of a strip this shallow, rather than the title-sized one it arrives at. */
.example-dock-title .kind-icon { width: 1.1rem; height: 1.1rem; flex-shrink: 0; }
/* The member the example is for, wherever the code calls it. */
.example-panel mark { padding: 0 0.1rem; }
.example-dock-open { margin-left: auto; font-size: 0.74rem; color: var(--text3); text-decoration: none; flex-shrink: 0; }
.example-dock-open:hover { color: var(--flash); }
.example-dock-close { appearance: none; border: none; background: none; cursor: pointer; font-size: 1.6rem; line-height: 1; color: var(--text3); padding: 0 0.3rem; flex-shrink: 0; }
.example-dock-close:hover { color: var(--text); }
.example-dock-body { overflow: auto; padding: 0 0.9rem 1.2rem; }
.example-dock-body .ns-heading { display: none; }
.example-dock-body .example-panel { margin-top: 0; }
/* Too narrow to give away 42% of it, so the dock takes the width and the content waits behind. */
@media (max-width: 900px) {
  .example-dock { position: fixed; inset: 0; width: auto; min-width: 0; max-width: none; z-index: 30; border-left: none; }
  /* Nothing to drag when it covers the window. */
  .example-resize { display: none; }
}
.example-missing { font-size: 0.85rem; color: var(--text3); font-style: italic; }

/* ---- Enum values and operators ----
   Two tables of members that a card would have padded out rather than filled. */
.enum-table th, .op-table th { color: var(--text3); font-size: 0.72rem; font-weight: 700; text-transform: uppercase; }
.enum-table td, .op-table td { padding: 0.45rem 0.5rem; vertical-align: top; }
/* In the body font, like every other member name on the page: the monospace it wore said 'code' a
   second time, when the row it heads is already a value and a number. */
.enum-table .enum-name { font-weight: 600; color: var(--text); white-space: nowrap; }
/* Name and mark on one line, hung from the top of the cell so they sit with the first line of the
   description beside them rather than in the middle of it. The drawing is a shade under the one the
   member cards wear, which keeps a row the height of its text. */
.enum-table .enum-name-row { display: inline-flex; align-items: center; gap: 0.4rem; vertical-align: top; }
.enum-table .enum-name-row .kind-icon { width: 0.95rem; height: 0.95rem; }
/* The expression is the row's identity, so it carries the weight. It is split across three cells
   and closed in on the symbol from both sides, which is what puts every symbol in the table on one
   vertical line; the padding is tightened so the three still read as one expression. */
.op-table .op-left, .op-table .op-mark, .op-table .op-right { font-family: monospace; font-weight: 600; color: var(--text); white-space: nowrap; }
.op-table .op-left { text-align: right; padding-right: 0.1rem; }
.op-table .op-mark { text-align: center; padding-left: 0.3rem; padding-right: 0.3rem; color: var(--tok-keyword); }
.op-table .op-right { text-align: left; padding-left: 0.1rem; }
.enum-table .enum-value { font-family: monospace; white-space: nowrap; text-align: right; }
/* The operand and result columns are types, and read as the signatures they came out of. Kept on
   one line like the operand cells beside them: a generic broken at its comma reads as two types. */
.op-table .op-types { font-family: monospace; font-size: 0.8rem; color: var(--text2); white-space: nowrap; }
/* Both tables end in the description, which is the only column with prose to wrap, so every column
   before it is shrunk to what it holds - 1% against the nowrap above, the way table.params does it.
   Left to share the width evenly, five columns of short strings take most of the row and the one
   column that had something to say gets what is left. A type too long for the room scrolls, which
   is what the .table-scroll around it is for. */
.enum-table .enum-name, .enum-table .enum-value { width: 1%; }
.op-table .op-left, .op-table .op-mark, .op-table .op-right, .op-table .op-types { width: 1%; }
/* Rows are what the sidebar links at, so a jumped-to value marks itself the way a card does. */
.enum-table tbody tr, .op-table tbody tr { scroll-margin-top: var(--anchor-offset, 1rem); }
.enum-table tbody tr:target, .op-table tbody tr:target { background: var(--bg3); }
.summary ul, .summary ol, .remarks ul, .remarks ol, .section ul, .section ol { margin: 0.3rem 0 0.3rem 1.25rem; }
dl { margin: 0.3rem 0; }
dt { font-weight: 650; color: var(--text2); margin-top: 0.35rem; }
dd { margin-left: 1rem; color: var(--text3); }

/* ---- Cards grid (home / assembly pages) ---- */
.card-grid { display: grid; gap: 0.6rem; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); }
.nav-card { background: var(--card-bg); border: 1px solid var(--card-border); border-radius: 8px; padding: 0.8rem 1rem; text-decoration: none; display: block; transition: background 0.15s, border-color 0.15s; }
.nav-card:hover { background: var(--card-hover); border-color: var(--border2); }
.nav-card-title { font-size: 0.92rem; font-weight: 600; color: var(--text); word-break: break-word; }
.nav-card-meta { font-size: 0.76rem; color: var(--text3); margin-top: 0.25rem; }
.plain-list { list-style: none; padding: 0; }
.plain-list li { border-bottom: 1px solid var(--border); }
.plain-list li:last-child { border-bottom: none; }
.plain-list a { display: flex; align-items: center; gap: 0.4rem; padding: 0.4rem 0.2rem; color: var(--text2); text-decoration: none; font-size: 0.86rem; }
.plain-list a:hover { color: var(--flash); }
.plain-list .count { margin-left: auto; font-size: 0.74rem; color: var(--text4); }
/* The name column is as wide as the longest name; each row spans both columns so its rule runs across. */
.ns-described { display: grid; grid-template-columns: max-content 1fr; column-gap: 1.5rem; }
.ns-described li { display: grid; grid-template-columns: subgrid; grid-column: 1 / -1; align-items: start; }
.ns-described .ns-summary { padding: 0.33rem 0 0.4rem; font-size: 0.82rem; line-height: 1.5; color: var(--text3); }
/* Too narrow for two columns, so the summary drops under its name. */
@media (max-width: 640px) {
  .ns-described { display: block; }
  .ns-described li { display: block; }
  .ns-described .ns-summary { margin: -0.2rem 0 0 1.7rem; padding-top: 0; }
}

/* ---- Search ---- */
#search-page-input { width: 100%; max-width: 32rem; padding: 0.5rem 0.8rem; font-size: 0.95rem; background: var(--bg2); color: var(--text); border: 1px solid var(--border2); border-radius: 6px; outline: none; }
#search-page-input:focus { border-color: var(--flash); }
.search-results { list-style: none; padding: 0; margin-top: 1rem; }
.search-results li { padding: 0.7rem 0; border-bottom: 1px solid var(--border); }
/* The badge centres against the name rather than sitting on its baseline. */
.search-results .r-head { display: flex; align-items: center; gap: 0.4rem; }
.search-results .r-name { font-weight: 600; color: var(--text); text-decoration: none; }
.search-results .r-name:hover { color: var(--flash); }
.search-results .r-sig { font-family: monospace; font-size: 0.78rem; color: var(--text2); margin: 0.5rem 0; word-break: break-word; }
.search-results .r-summary { font-size: 0.84rem; color: var(--text3); margin-top: 0.25rem; }
.search-results .r-ns { font-family: monospace; font-size: 0.74rem; color: var(--fullname); margin-top: 0.45rem; word-break: break-all; }
/* The end of what is drawn. Not a result, so it carries neither a result's rule nor its padding. */
.search-results li.search-more { padding: 1rem 0 0; border-bottom: none; text-align: center; }
.search-more-btn { font: inherit; font-size: 0.84rem; color: var(--text2); background: var(--bg2); border: 1px solid var(--border2); border-radius: 6px; padding: 0.45rem 1rem; cursor: pointer; transition: color 0.15s, border-color 0.15s; }
.search-more-btn:hover { color: var(--text); border-color: var(--flash); }
/* Open Color yellow, on gray 9: yellow 4 under the dark theme, the lighter yellow 2 under light.
   Opaque, and it sets its own foreground rather than inheriting. A match inside a signature lands
   within a .tok-* span, so 'color: inherit' would leave a saturated token colour sitting on the
   mark - legible on plain text, invisible on a keyword.
   No padding: a match crossing a token boundary is emitted as two adjacent marks, and side padding
   would open a seam in the middle of what should read as one run. */
mark { background: var(--mark-bg); color: var(--mark-fg); border-radius: 2px; }
.search-status { color: var(--text3); font-size: 0.84rem; margin-top: 0.8rem; }

/* ---- Phones ---- */
@media (max-width: 800px) {
  /* The tree has no room beside the page, so its button lays it over the page instead. */
  .layout { position: relative; }
  .sidebar, .resize-handle { display: none; }
  :root[data-sidebar-open] .sidebar { display: block; position: absolute; top: 0; bottom: 0; left: 0; z-index: 25; max-width: 85vw; box-shadow: 0 0 28px rgba(0, 0, 0, 0.35); }

  /* Search folds to its magnifier and opens across the header when tapped, giving the title back
     its room. It stays open while its results are up, so a tap on one does not move it away. */
  header { position: relative; }
  #search { width: 30px; padding: 0; color: transparent; }
  #search::placeholder { color: transparent; }
  .nav-search-icon, header form[role="search"].index-loading::after { right: calc((30px - 1.05rem) / 2); }
  header form[role="search"].filled .nav-search-icon { display: block; }
  header form[role="search"].filled .nav-search-clear { display: none; }
  header form[role="search"]:is(:focus-within, :has(.nav-results:not([hidden]))) { position: absolute; top: 0; bottom: 0; left: 0.9rem; right: 0.9rem; z-index: 1; background: var(--nav-bg); }
  header form[role="search"]:is(:focus-within, :has(.nav-results:not([hidden]))) #search { width: 100%; padding: 0 2rem 0 0.7rem; color: var(--nav-fg); }
  header form[role="search"]:is(:focus-within, :has(.nav-results:not([hidden]))) #search::placeholder { color: var(--nav-dim); }
  header form[role="search"]:is(:focus-within, :has(.nav-results:not([hidden]))) .nav-search-icon,
  header form[role="search"]:is(:focus-within, :has(.nav-results:not([hidden]))).index-loading::after { right: 0.55rem; }
  header form[role="search"].filled:is(:focus-within, :has(.nav-results:not([hidden]))) .nav-search-icon { display: none; }
  header form[role="search"].filled:is(:focus-within, :has(.nav-results:not([hidden]))) .nav-search-clear { display: block; }
  .nav-results { max-width: none; width: 100%; }

  /* Width is what a phone is short of, so the padding gives it back to the text. */
  .main-content { --gutter: 0.75rem; }
  .member { --pad-y: 0.75rem; --pad-x: 0.8rem; }
  .cat-doc { padding: 0.9rem; }
  .summary ul, .summary ol, .remarks ul, .remarks ol, .section ul, .section ol, .cat-doc ul, .cat-doc ol { margin-left: 1rem; }
  dd { margin-left: 0.6rem; }
  .cat-doc blockquote { padding-left: 0.6rem; }

  /* Height is cheaper than width here, so the head's blocks get room to read as separate. */
  .breadcrumbs { margin-bottom: 1.25rem; }
  .main-content:has(.page-head-brief) > .main-sticky { padding-bottom: 0.6rem; }
  .page-intro, .page-head.sticky-head .declaration { margin-top: 0.9rem; }
  .intro-more { margin-top: 0.7rem; }
  .page-head.sticky-head .filter-bar { margin-top: 1rem; }

  /* Beside the member it took nearly half the card; under it, one line. */
  .inherited-head { flex-direction: column; }
  .inherited-from { max-width: none; flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 0.3rem; padding: 0; margin-top: 0.5rem; }
  .inherited-from > span { text-align: left; }
  .inherited-from-type { margin-top: 0; }
}
