/* layout: no top bar on desktop, the sidebar carries logo and search, no dividers anywhere, a narrow reading column */ :root, :root[data-theme="light"] { --sl-content-width: 36rem; --sl-sidebar-width: 18.5rem; --sl-sidebar-pad-x: 3rem; /* one top inset shared by sidebar, content and table of contents */ --docs-top: 5rem; --sl-color-hairline: transparent; --sl-color-hairline-light: transparent; --sl-color-hairline-shade: transparent; } @media (min-width: 50rem) { :root[data-has-sidebar] { --sl-nav-height: 0rem; } :root[data-has-sidebar] .header { display: none; } } /* the landing page keeps a header, but it scrolls away with the page */ :root:not([data-has-sidebar]) .header { position: absolute; background: transparent; } .docs-header, .docs-header-end { display: flex; align-items: center; gap: 0.5rem; } .docs-header { justify-content: space-between; height: 100%; } ::selection { background-color: var(--color-background-info-subtle-hover); color: var(--color-foreground-default); } /* sidebar */ @media (min-width: 50rem) { .sidebar-content { padding-top: var(--docs-top); /* more gutter on the left, with the freed space taken from the invisible right side so the nav keeps its width and long labels don't wrap */ padding-inline: 5rem 1rem; gap: 1.75rem; } :root[data-has-sidebar] main > .content-panel:first-of-type { padding-top: var(--docs-top); /* the title panel and the body panel each add 1.5rem of padding, which leaves a 3rem gap under the title; trim it to the reference's 1rem */ padding-bottom: 0.5rem; } :root[data-has-sidebar] main > .content-panel:first-of-type + .content-panel { padding-top: 0.5rem; } .right-sidebar-panel { padding-top: var(--docs-top); } :root[data-has-sidebar] main > .content-panel:first-of-type h1 { margin-top: 0; } } /* the "On this page" label is just a bold entry, the same size as the links */ .right-sidebar-panel h2 { font-size: var(--sl-text-xs); font-weight: var(--font-weight-semibold); } /* every ToC entry aligns with the label: no indent for nested headings */ .right-sidebar-panel nav a { padding-inline-start: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .sidebar-top { align-items: center; justify-content: space-between; } .site-title { color: var(--sl-color-white); } /* search: a pill at the top of the sidebar that opens the search dialog */ .sidebar-search button[data-open-modal] { display: flex; width: 100%; height: 2rem; max-width: none; gap: 0.5rem; padding-inline: 0.75rem; border: 1px solid var(--color-border-default); border-radius: 9999px; background-color: var(--color-background-default); color: var(--color-foreground-subtle); font-size: 0.875rem; } .sidebar-search button[data-open-modal]:hover { border-color: var(--color-border-strong); color: var(--color-foreground-muted); } .sidebar-search button[data-open-modal] > span { display: block; } .sidebar-search button[data-open-modal] kbd { margin-inline-start: auto; background: transparent; color: var(--color-foreground-subtle); } /* the dialog takes the reading column's width, and its corners follow the input's radius out by the frame's padding, so the two curves are concentric */ site-search dialog { margin-top: 12vh; border: 1px solid var(--color-border-default); border-radius: calc(var(--radius-md) + var(--spacing-xs)); background-color: var(--color-background-default); box-shadow: 0 24px 48px -12px var(--color-shadow-ambient-strong); } @media (min-width: 50rem) { site-search dialog { max-width: var(--sl-content-width); min-height: 0; } site-search .dialog-frame { padding: var(--spacing-xs); } } site-search .dialog-frame { scrollbar-width: none; } site-search .dialog-frame::-webkit-scrollbar { display: none; } site-search dialog::backdrop { /* the web app's modal scrim: black in both themes, so dark mode dims rather than lightens the page behind the dialog */ background-color: rgb(0 0 0 / 0.4); -webkit-backdrop-filter: none; backdrop-filter: none; } /* the search dialog's input and results are set at the prose size. pagefind groups results by page; the page titles are hidden so the matches read as one flat list of cards, which only show a background on hover. the input follows the app's list search (Input with a search icon and a ghost clear button) */ #starlight__search { --pagefind-ui-border-radius: var(--radius-md); --search-match: #fef08a; } :root[data-theme="dark"] #starlight__search { --search-match: rgb(250 204 21 / 0.3); } #starlight__search .pagefind-ui__search-input { height: 2rem; padding-inline: 1.875rem 2rem; border: 0; background-color: var(--color-background-default); box-shadow: inset 0 0 0 1px var(--color-shadow-ring); font-size: var(--sl-text-body); transition: box-shadow 150ms; } #starlight__search input:focus { outline: none; box-shadow: inset 0 0 0 1px var(--color-border-strong), 0 0 0 1px var(--color-border-strong); } #starlight__search .pagefind-ui__search-input::placeholder { color: var(--color-foreground-placeholder); opacity: 1; } #starlight__search .pagefind-ui__form::before { top: 0.5625rem; left: 0.5rem; width: 0.875rem; height: 0.875rem; background-color: var(--color-foreground-subtle); } #starlight__search .pagefind-ui__search-clear { top: 0.25rem; right: 0.25rem; width: 1.5rem; height: 1.5rem; border-radius: var(--radius-sm); } #starlight__search .pagefind-ui__search-clear:hover { background-color: var(--color-background-inset); } #starlight__search .pagefind-ui__search-clear::before { background-color: var(--color-foreground-muted); mask-size: 0.875rem; -webkit-mask-size: 0.875rem; } #starlight__search .pagefind-ui__results-area { margin-top: var(--spacing-xs); } #starlight__search .pagefind-ui__message { height: auto; padding: 0 var(--spacing-sm) var(--spacing-xs); color: var(--color-foreground-subtle); font-size: var(--sl-text-sm); font-weight: 400; } #starlight__search :is(.pagefind-ui__results, .pagefind-ui__result-inner) { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.125rem; } #starlight__search .pagefind-ui__results > * + * { margin-top: 0; } #starlight__search .pagefind-ui__result-inner > .pagefind-ui__result-title { display: none; } #starlight__search .pagefind-ui__result-nested::before { content: none; } #starlight__search .pagefind-ui__result-nested { padding: 0.375rem var(--spacing-sm); border-radius: var(--radius-md); background-color: transparent; } #starlight__search .pagefind-ui__result-nested .pagefind-ui__result-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--sl-text-body); line-height: var(--sl-line-height); } #starlight__search .pagefind-ui__result-link[data-page]::before { position: static; content: attr(data-page) " / "; color: var(--color-foreground-muted); } #starlight__search .pagefind-ui__result-nested .pagefind-ui__result-link { color: var(--color-foreground-default); font-size: inherit; font-weight: var(--font-weight-medium); } #starlight__search .pagefind-ui__result-excerpt { min-width: 0; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--color-foreground-muted); font-size: var(--sl-text-body); line-height: var(--sl-line-height); } #starlight__search .pagefind-ui__result-excerpt[data-clipped]::before { content: "… "; } #starlight__search .pagefind-ui__result-excerpt[data-trails]::after { content: " …"; } #starlight__search mark { border-radius: 0.125rem; background-color: var(--search-match); color: inherit; font-weight: inherit; } #starlight__search .pagefind-ui__result-nested:is(:hover, [data-active]) { outline: none; background-color: var(--color-background-inset); } #starlight__search .pagefind-ui__result-title:not(:where(.pagefind-ui__result-nested *)):focus-within, #starlight__search .pagefind-ui__result-nested:focus-within { outline: none; } #starlight__search .pagefind-ui__result-nested a:focus-visible { outline: none; } #starlight__search .pagefind-ui__result-nested:has(a:focus-visible) { outline: 2px solid var(--color-border-focus); outline-offset: 2px; } /* results show a page of cards at a time (see Search.astro). while more can load, the last shown card fades out, and scrolling it into view loads more in place of pagefind's button */ #starlight__search .pagefind-ui__result-nested[data-overflow], #starlight__search .pagefind-ui__button { display: none; } #starlight__search .pagefind-ui__result-nested[data-faded] { mask-image: linear-gradient(to bottom, rgb(0 0 0 / 0.5), transparent); pointer-events: none; } /* the sidebar scrolls, but without a visible scrollbar */ .sidebar-pane { scrollbar-width: none; } .sidebar-pane::-webkit-scrollbar { display: none; } /* the mobile menu toggle is a ghost button */ starlight-menu-button button { background-color: transparent; box-shadow: none; border-radius: var(--radius-md); color: var(--color-foreground-muted); } starlight-menu-button button:hover, starlight-menu-button[aria-expanded="true"] button { background-color: var(--color-background-inset); } starlight-menu-button button:focus-visible { outline: 2px solid var(--color-border-focus); outline-offset: 2px; } /* on mobile the header reserves room for the fixed menu button, with a 0.5rem gap */ @media (max-width: 49.999rem) { :root[data-has-sidebar] .header { padding-inline-end: calc(0.5rem + var(--sl-nav-pad-x) + var(--sl-menu-button-size)); } } /* the nav: one size throughout, bold group headings, whitespace between groups */ .docs-nav { font-size: 0.875rem; line-height: 1.2; } .docs-nav ul { list-style: none; margin: 0; padding: 0; } .docs-nav > * + * { margin-top: 1.75rem; } .docs-nav h2, .docs-nav h3 { margin: 0 0 0.25rem; font-size: inherit; line-height: inherit; color: var(--color-foreground-default); } .docs-nav h2 { font-weight: var(--font-weight-semibold); } .docs-nav h3 { font-weight: var(--font-weight-medium); } .docs-nav .subgroup { margin-block: 0.75rem; } .docs-nav a { display: block; padding-block: 0.25rem; color: var(--color-foreground-muted); text-decoration: none; } .docs-nav a:hover { color: var(--color-foreground-default); } .docs-nav a[aria-current="page"] { color: var(--color-foreground-default); font-weight: var(--font-weight-medium); } /* content: markup.css does the typography. what's left is fitting it around the elements starlight adds */ /* body text sits a step below the brightest foreground; headings and links stay bright. markup.css sets the container colour and each heading's, so a rule on the container re-tints the prose without dimming the headings */ .markup { color: var(--color-foreground-muted); } /* tables take the web app's card/panel radius (--radius-md). the outer border sits on the table (a block scroll container), so its corners follow the radius cleanly: the cells keep only their inner rules and no border is clipped at the corners */ .markup table { border: 1px solid var(--color-border-default); border-radius: var(--radius-md); border-collapse: separate; border-spacing: 0; } /* code blocks are the same kind of panel, so match the table radius. markup.css gives every `pre` the smaller inline radius, which also wins over expressive-code's own border radius, so override it here */ .markup pre { border-radius: var(--radius-md); } /* keyboard keys follow kumo-svelte's prose `kbd`: a flat keycap -- a hairline border on the base surface, no inset shadow -- set in mono at 0.875em */ .markup kbd { padding: 0.125rem 0.375rem; border: 1px solid var(--color-border-default); border-radius: 0.25rem; background-color: var(--color-background-default); color: var(--color-foreground-default); font-family: var(--font-mono); font-size: 0.875em; font-weight: 400; line-height: inherit; box-shadow: none; } .markup :is(th, td) { border: 0; border-inline-end: 1px solid var(--color-border-default); border-block-end: 1px solid var(--color-border-default); } /* the last column and row drop their inner rules, the table border closes them */ .markup tr > :last-child { border-inline-end: 0; } .markup tbody tr:last-child > * { border-block-end: 0; } .markup :is(p, li, dd, blockquote) { overflow-wrap: break-word; } .markup :is(h1, h2, h3, h4, h5, h6) { text-wrap: balance; } /* starlight wraps each heading with its anchor link. the rule under a readme's h1 and h2 goes on the wrapper, so it spans the column */ .markup .sl-heading-wrapper { margin-top: var(--spacing-xl); margin-bottom: var(--spacing-sm); } .markup .sl-heading-wrapper > :is(h1, h2, h3, h4, h5, h6) { margin: 0; border: 0; padding: 0; } .markup .sl-heading-wrapper:is(.level-h1, .level-h2) { border-bottom: 1px solid var(--color-border-default); padding-bottom: var(--spacing-xs); } .markup > :first-child, .markup > .sl-heading-wrapper:first-child { margin-top: 0; } /* keep the shared markup styles' always-on underline: the text stays the brightest foreground, the underline is muted until hover, then brightens. this drops the indigo link-hover colour (web/src/markup.css). the heading anchor keeps its `#` */ .markup a:not(.sl-anchor-link) { color: var(--color-foreground-default); text-decoration-color: var(--color-foreground-muted); } .markup a:not(.sl-anchor-link):hover { color: var(--color-foreground-default); text-decoration-color: var(--color-foreground-default); } /* the anchor link, shown as tangled.org's `#` on hover */ .markup .sl-anchor-link { margin-inline-start: var(--spacing-xs); color: var(--color-foreground-placeholder); text-decoration: none; opacity: 0; transition: opacity 150ms; } .markup .sl-heading-wrapper:hover .sl-anchor-link, .markup .sl-anchor-link:focus-visible { opacity: 1; } .markup .sl-anchor-link svg { display: none; } .markup .sl-anchor-link::before { content: "#"; } /* asides, styled like tangled.org's github alerts */ .markup .starlight-aside { margin-block: var(--spacing-sm); padding: 0 0 0 var(--spacing-md); border: 0; border-inline-start: 2px solid var(--color-border-default); background: transparent; } .markup .starlight-aside__title { gap: 0; font-size: inherit; font-weight: var(--font-weight-semibold); } .markup .starlight-aside__icon { display: none; } .markup .starlight-aside--note, .markup .starlight-aside--tip { border-color: var(--color-background-info-emphasis); } .markup .starlight-aside--note .starlight-aside__title { color: var(--color-foreground-info); } .markup .starlight-aside--tip { border-color: var(--color-background-success-emphasis); } .markup .starlight-aside--tip .starlight-aside__title { color: var(--color-foreground-success); } .markup .starlight-aside--caution { border-color: var(--color-background-warning-emphasis); } .markup .starlight-aside--caution .starlight-aside__title { color: var(--color-foreground-warning); } .markup .starlight-aside--danger { border-color: var(--color-background-danger-emphasis); } .markup .starlight-aside--danger .starlight-aside__title { color: var(--color-foreground-danger); } /* no next/previous links at the foot of the page */ .pagination-links { display: none; } /* expressive code sets its own size on pre; markup.css sizes code at 0.875em of pre, so pre takes the body size and code lands on tangled.org's 13px */ .markup .expressive-code pre { font-size: 0.9375rem; } /* no copy button on code blocks */ .expressive-code .copy { display: none; } /* starlight sizes the heading wrapper with its own scale, which the anchor link inherits; match each level to the heading markup.css gives it */ .markup .sl-heading-wrapper.level-h1 { font-size: 1.5rem; } .markup .sl-heading-wrapper.level-h2 { font-size: 1.25rem; } .markup .sl-heading-wrapper.level-h3 { font-size: 1rem; } .markup .sl-heading-wrapper:is(.level-h4, .level-h5, .level-h6) { font-size: 0.8125rem; } /* starlight lets inline code break anywhere; in a table that splits short identifiers mid-word, so keep them whole and let the table scroll instead */ .markup :is(td, th) code { overflow-wrap: normal; white-space: nowrap; } body { text-wrap-style: pretty; }