[READ-ONLY] Mirror of https://github.com/bombshell-dev/docs. bomb.sh/docs
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685@layer starlight, user;
@layer user.overrides { :root { --font-fallback: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; --sl-font: "Inter Variable", var(--font-fallback); --sl-font-heading: "polymath-display", sans-serif; --sl-font-mono: "dm-mono", ui-monospace, monospace;
--sl-color-text-heading: var(--heading-fill);
/* Heading baseline: one notch smaller than Starlight's wide-viewport scale; the full-size scale only applies at desktop widths (below) */ --sl-text-h1: var(--sl-text-5xl); --sl-text-h2: var(--sl-text-2xl); --sl-text-h3: var(--sl-text-xl); --sl-text-h4: var(--sl-text-lg); --sl-color-accent-hsl: 311 100% 50%; --sl-color-accent-low: hsl(var(--sl-color-accent-hsl) / 0.1); --sl-color-accent: hsl(var(--sl-color-accent-hsl) / 0.9); --sl-color-accent-high: hsl(var(--sl-color-accent-hsl) / 1);
--sl-color-bg: var(--background); --sl-color-bg-nav: var(--background); --sl-color-bg-sidebar: var(--background); --sl-color-bg-inline-code: var(--surface-inner-fill); --sl-color-bg-accent: var(--sl-color-accent-high); --sl-color-hairline-light: var(--surface-border-fill); --sl-color-hairline: var(--surface-border-fill); --sl-color-hairline-shade: var(--surface-border-fill);
--sl-icon-color: var(--heading-fill);
/* extra room for the hatched separator strip under the navbar */ --hatch-height: 0.75rem; --sl-nav-height: 4.25rem;
scrollbar-width: thin; scrollbar-gutter: stable; scrollbar-color: hsl(var(--sl-color-accent-hsl)) var(--surface-fill); }
::selection { background-color: var(--color-pink-100); color: var(--color-gray-100); }
/* bomb.sh viewport frame: 8px background strips + 1px grid border, drawn over everything (pointer-events: none) so scrolled content passes "behind" the frame exactly like on the marketing site */ body::before { content: ""; position: fixed; inset: 0; z-index: 101; pointer-events: none; background-image: /* fill strips */ linear-gradient(var(--background), var(--background)), linear-gradient(var(--background), var(--background)), linear-gradient(var(--background), var(--background)), linear-gradient(var(--background), var(--background)), /* border lines */ linear-gradient(var(--c-grid), var(--c-grid)), linear-gradient(var(--c-grid), var(--c-grid)), linear-gradient(var(--c-grid), var(--c-grid)), linear-gradient(var(--c-grid), var(--c-grid)); background-size: /* fill: top, bottom, left, right */ 100% var(--s-grid-padding), 100% var(--s-grid-padding), var(--s-grid-padding) 100%, var(--s-grid-padding) 100%, /* border: top, bottom, left, right */ 100% var(--s-grid-width), 100% var(--s-grid-width), var(--s-grid-width) 100%, var(--s-grid-width) 100%; background-position: top left, bottom left, top left, top right, 0 var(--s-grid-padding), 0 calc(100% - var(--s-grid-padding)), var(--s-grid-padding) 0, calc(100% - var(--s-grid-padding)) 0; background-repeat: no-repeat; }
/* bomb.sh hatched separator strip along the bottom of the navbar. Nav content stays centered across the full nav height; the strip overlays the bottom edge like the homepage separator. */ header.header::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: var(--hatch-height); border-top: var(--s-grid-width) solid var(--c-grid); --_size: var(--s-grid-width); --_space: 6px; background-image: repeating-linear-gradient( 45deg, transparent, transparent var(--_space), var(--c-grid-muted) var(--_space), var(--c-grid-muted) calc(var(--_space) + var(--_size)) ); pointer-events: none; }
/* Full-size heading scale on desktop viewports only */ @media (min-width: 72rem) { :root { --sl-text-h1: var(--sl-text-6xl); --sl-text-h2: var(--sl-text-4xl); --sl-text-h3: var(--sl-text-3xl); --sl-text-h4: var(--sl-text-2xl); } }
:is(h1, h2, h3, h4, h5, h6) { font-feature-settings: "ss03" on, "ss12" on; }
:is(h1, .starlight-sidebar-topics) { font-feature-settings: "ss01" on, "ss03" on, "ss09" on, "ss10" on, "ss12" on; font-family: var(--sl-font-heading); }
:is(.starlight-sidebar-topics li) { font: inherit; font-feature-settings: inherit; text-transform: lowercase; }
:is(h1) { --c-border: var(--heading-fill); --c-start: var(--heading-fill); --c-end: var(--heading-muted); --s-border: 1px; -webkit-text-stroke-color: var(--c-border); -webkit-text-stroke-width: var(--s-border); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-image: linear-gradient(to right, var(--c-start), var(--c-end)); letter-spacing: 0.1ch; }
:is(h2, h3, h4, h5, h6) { --c-start: var(--heading-fill); --c-end: color-mix(in srgb, var(--heading-fill) 35%, transparent); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-image: linear-gradient(to right, var(--c-start), var(--c-end)); letter-spacing: 0.1ch; }
:is(h1, h2, h3, h4, h5, h6) code { background-clip: border-box; -webkit-background-clip: border-box; -webkit-text-fill-color: var(--heading-fill); color: var(--heading-fill); }
/* Target specific elements */ .sl-nav-link, .site-title, .sl-doc-title, header h1 { font-family: var(--sl-font-heading); }
a.site-title { color: var(--heading-fill); }
/* Right sidebar (TOC) background gradient */ .right-sidebar { background: linear-gradient( to bottom, var(--panel-grad-start) 0%, var(--background) 100% ); }
starlight-toc nav > ul { border-left: 1px solid transparent; position: relative;
&::before { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: var(--border-050); background: linear-gradient( to bottom, var(--surface-border-highlight), var(--surface-border-fill) ); }
a { border-left: 2px solid transparent; border-radius: 0; }
[aria-current] { border-left-color: hsl(var(--sl-color-accent-hsl) / 0.9); font-weight: 600; color: var(--separator-fill); }
/* When the animated marker is active, the static per-link border is replaced by a single sliding indicator (injected by Head.astro). */ &.has-marker [aria-current] { border-left-color: transparent; }
.toc-marker { position: absolute; left: 0; width: 2px; background: hsl(var(--sl-color-accent-hsl) / 0.9); transition: top 250ms cubic-bezier(0.23, 1, 0.32, 1), height 250ms cubic-bezier(0.23, 1, 0.32, 1); pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .toc-marker { transition: none; } } }
p, li, td, blockquote { font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
/* Buttons — match the bomb.sh homepage hero CTAs */ .sl-link-button { border-radius: 0.33em; corner-shape: bevel; font-family: var(--sl-font); font-weight: 500; transition: color 120ms cubic-bezier(0.23, 1, 0.32, 1), background-color 120ms cubic-bezier(0.23, 1, 0.32, 1), border-color 120ms cubic-bezier(0.23, 1, 0.32, 1); }
.sl-link-button.primary { background: var(--color-white-100); color: var(--color-gray-100); border: var(--s-grid-width) solid var(--c-grid);
&:is(:hover, :focus-visible) { background: color-mix(in srgb, var(--color-pink-100) 30%, transparent); color: var(--color-pink-100); border-color: var(--color-pink-100); } }
.sl-link-button:not(.primary) { background: transparent; color: var(--color-gray-40); border: var(--s-grid-width) solid var(--color-gray-40);
&:is(:hover, :focus-visible) { background: var(--color-gray-80); color: var(--color-white-100); border-color: var(--color-white-100); } }
.sl-link-button > svg { fill: currentColor; }
/* Content links — white at rest, topic accent on hover */ .sl-markdown-content a:not(:where(.not-content *)) { color: var(--color-white-100); transition: color 120ms cubic-bezier(0.23, 1, 0.32, 1);
&:is(:hover, :focus-visible) { color: hsl(var(--sl-color-accent-hsl)); }
/* Links wrapping code chips: accent at rest (so the underline matches the chip), flipping to white on hover — the inverse of plain links */ &:has(> code) { color: hsl(var(--sl-color-accent-hsl));
&:is(:hover, :focus-visible) { color: var(--color-white-100);
& > code { --color: var(--color-white-100); } } } }
/* Inline code — bomb.sh gradient chip, tinted by the topic accent */ .sl-markdown-content code:not(:where(.not-content *)):not(pre *) { --color: hsl(var(--sl-color-accent-hsl)); font-family: var(--sl-font-mono); color: var(--color); transition: color 120ms cubic-bezier(0.23, 1, 0.32, 1), background 120ms cubic-bezier(0.23, 1, 0.32, 1); font-size-adjust: 0.5; background: linear-gradient( -45deg, color-mix(in srgb, var(--color) 25%, transparent) 0%, color-mix(in srgb, var(--color) 12%, transparent) 100% ); padding-inline: 0.25em; padding-block: 0.1em; border-radius: 4px; }
/* Search — a full-height section of the nav, delimited by vertical hairline bars, aligned with the main content column */ site-search { width: 100%; height: 100%; display: flex; align-items: center; }
/* Desktop with a TOC column: cap the search at the main content area so its right bar aligns with the content/TOC boundary (measured value from Head.astro; the calc is a close fallback that ignores scrollbar width) */ @media (min-width: 72rem) { :root[data-has-toc] site-search { max-width: var( --search-clamp, calc((100vw - 2 * var(--sl-sidebar-width) + var(--sl-content-width)) / 2) ); } }
@media (min-width: 50rem) { site-search button[data-open-modal] { border-radius: 0; max-width: 100%; height: 100%; border-block: none; border-inline: 1px solid var(--surface-border-fill); /* No fill — the nav's hatch strip stays visible through the section */ background-color: transparent; /* Stack above the nav's hatch strip so the bars stay unbroken, and nudge 1px left so the left bar overlaps the sidebar border exactly */ position: relative; z-index: 1; translate: -1px 0; } }
.cli-preview { padding: 1em; border: 1px solid var(--surface-border-fill); border-radius: 0.5em; white-space: pre; line-height: 1.2em; font-family: var(--sl-font-mono); background-color: var(--container-fill); color: var(--color-white-100); overflow-x: auto; max-width: 100%; }
/* Code frames — subtle gradient fade on terminal/editor title bars, matching the hatch-and-hairline chrome of the rest of the site */ .expressive-code .frame.is-terminal .header, .expressive-code .frame.has-title:not(.is-terminal) .header { background: linear-gradient( to bottom, transparent, color-mix(in srgb, var(--heading-fill) 7%, transparent) ); border-bottom: 1px solid var(--surface-border-fill); }
/* Twoslash hovercards — same panel language as the rest of the chrome */ .expressive-code .twoslash-popup-container { border-radius: var(--radius-100); box-shadow: 0 8px 24px color-mix(in srgb, #000 35%, transparent); }
.expressive-code .twoslash-popup-docs, .expressive-code .twoslash-popup-docs-tags { font-family: var(--sl-font); font-size: var(--sl-text-xs); }
.expressive-code .twoslash-popup-code { font-family: var(--sl-font-mono); }
.sidebar-pane { background: linear-gradient( to bottom, var(--panel-grad-start) 0%, var(--background) 100% );
a { border: 1px solid transparent; }
ul.top-level a:not([aria-current="page"]):is(:hover, :focus-visible) { --c-start: hsl(var(--sl-color-accent-hsl) / 100%); --c-end: hsl(var(--sl-color-accent-hsl) / 50%); border-color: var(--sl-color-accent); color: var(--color-gray-100); background: linear-gradient(to right, var(--c-start), var(--c-end)); }
[aria-current="page"] { --c-start: hsl(var(--sl-color-accent-hsl) / 5%); --c-end: hsl(var(--sl-color-accent-hsl) / 30%); color: var(--sl-color-accent); background: linear-gradient(to right, var(--c-start), var(--c-end)); border-color: var(--sl-color-accent); } }
[data-has-sidebar] header.header { padding-inline-end: 1rem; }
starlight-menu-button button { top: unset; bottom: calc( (var(--sl-mobile-toc-height) - var(--sl-menu-button-size)) / 2 ); background-color: var(--color-gray-80); }
mobile-starlight-toc nav { top: unset; bottom: 0; }
/* Light theme specific overrides for better readability */ :root[data-theme="light"] { --sl-color-text: var(--color-gray-100); --sl-color-text-muted: var(--color-gray-70); --sl-color-text-accent: var(--color-gray-90);
.sl-nav-link, .site-title, .sl-doc-title { color: var(--color-gray-100); }
input::placeholder { color: var(--color-gray-50); }
ul.top-level a:not([aria-current="page"]):is(:hover, :focus-visible) { color: var(--color-white-100); }
--sl-icon-color: var(--color-gray-100);
.sl-link-button.primary { background: var(--color-gray-100); color: var(--color-white-100); border-color: var(--color-gray-100);
&:is(:hover, :focus-visible) { background: color-mix(in srgb, var(--color-pink-100) 12%, transparent); color: var(--color-gray-100); border-color: var(--color-pink-100); } }
.sl-link-button:not(.primary) { background: transparent; color: var(--color-gray-70); border-color: var(--color-gray-40);
&:is(:hover, :focus-visible) { background: var(--color-gray-20); color: var(--color-gray-100); border-color: var(--color-gray-100); } } }
/* The plugin's own component style is unlayered, so directly overriding `color`/`background-color`/`border-color` here would always lose regardless of specificity. Instead, override the custom properties it reads (--sl-color-white, --sl-color-text-accent) scoped to this element — no competing declaration targets this element directly, so no layer/specificity fight happens. Hover/focus/current text color keeps the plugin's own accent-color behavior (now per-topic, see below); only the icon's background/border fill is disabled. */ .starlight-sidebar-topics { --sl-text-base: 1.25em; --sl-color-white: var(--heading-highlight); --sl-color-text-accent: transparent; }
.starlight-sidebar-topics a > div:not(.starlight-sidebar-topics-icon) { transition: transform 0.15s ease-out, opacity 0.15s ease-out; }
.starlight-sidebar-topics a:is(.starlight-sidebar-topics-current, :hover, :focus-visible) > div:not(.starlight-sidebar-topics-icon) { transform: translateX(3px); opacity: 1; }
/* Custom per-topic sidebar icons, replacing starlight-sidebar-topics' built-in Iconify icons. The plugin has no native custom-icon API (see https://github.com/HiDeoo/starlight-sidebar-topics/issues/5), so we hide its rendered <svg> and swap in our own via background-image, matched by the topic's link path (the only per-topic hook the plugin exposes). */ .starlight-sidebar-topics-icon svg { display: none; }
/* Each topic's icon is stored once in --icon and consumed two ways: as a `mask-image` filled with solid white at rest (a flat silhouette), and as a full-color `background-image` on hover/focus/current. */ a[href*="/clack/"] .starlight-sidebar-topics-icon { --icon: url("../assets/topics/clack.svg"); }
a[href*="/args/"] .starlight-sidebar-topics-icon { --icon: url("../assets/topics/args.svg"); }
a[href*="/tab/"] .starlight-sidebar-topics-icon { --icon: url("../assets/topics/tab.svg"); }
a[href*="/tty/"] .starlight-sidebar-topics-icon { --icon: url("../assets/topics/tty.svg"); }
.starlight-sidebar-topics-icon { --size: 1.25em; width: var(--size); height: var(--size); background-size: contain; background-repeat: no-repeat; background-position: center; mask-image: var(--icon); mask-size: contain; mask-repeat: no-repeat; mask-position: center; background-color: var(--heading-highlight); opacity: 0.7; }
a:is(.starlight-sidebar-topics-current, :hover, :focus-visible) .starlight-sidebar-topics-icon { mask-image: none; background-color: transparent; background-image: var(--icon); opacity: 1; }}
/* these rules must not be layered because the Starlight Sidebar Topics plugin doesn't use Cascade Layers */
/* each topic link carries its own accent so hover/current always shows the topic's color, not the current page's accent */.starlight-sidebar-topics a[href*="/clack/"] { --sl-color-accent-hsl: 184 100% 48%;}.starlight-sidebar-topics a[href*="/args/"] { --sl-color-accent-hsl: 52 100% 56%;}.starlight-sidebar-topics a[href*="/tab/"] { --sl-color-accent-hsl: 142 100% 47%;}.starlight-sidebar-topics a[href*="/tty/"] { --sl-color-accent-hsl: 300 100% 55%;}
:root[data-theme="light"] { .starlight-sidebar-topics a[href*="/clack/"] { --sl-color-accent-hsl: 184 100% 30%; } .starlight-sidebar-topics a[href*="/args/"] { --sl-color-accent-hsl: 45 100% 33%; } .starlight-sidebar-topics a[href*="/tab/"] { --sl-color-accent-hsl: 142 100% 28%; } .starlight-sidebar-topics a[href*="/tty/"] { --sl-color-accent-hsl: 300 100% 38%; }}
ul.starlight-sidebar-topics a:is(.starlight-sidebar-topics-current, :hover, :focus-visible) { color: hsl(var(--sl-color-accent-hsl) / 1);}
.starlight-sidebar-topics .starlight-sidebar-topics-icon { border: none;}
.starlight-sidebar-topics a { padding-block: 0.125em;}
.starlight-sidebar-topics li + li { margin-top: 0;}
/* Run the topics separator on the same horizontal line as the divider under the page title, so it reads as one continuous rule across sidebar and content. The min-height mirrors the first content panel's box: mobile-toc bar + panel padding (2 × 1.5rem) + h1 margin (1rem) + one h1 line (--sl-text-6xl × 1.2 line-height), minus the sidebar's own 1rem top padding. Applies wherever the sidebar is visible. */@media (min-width: 50rem) { .starlight-sidebar-topics { display: flex; flex-direction: column; /* Measured offset set by Head.astro (no static fallback — it would act as a floor and defeat the natural-height measurement; without JS the two rules are simply compact and unaligned). */ min-height: var(--topics-rule-offset, auto); }
.starlight-sidebar-topics::after { margin-top: auto; }
/* When the title panel grows to meet a taller topics column, anchor the title to the bottom of the available space, just above the shared rule */ main .content-panel:first-of-type { display: flex; flex-direction: column; justify-content: flex-end;
/* As a flex item the inner container would otherwise shrink to fit and its auto margins would center it */ & > .sl-container { width: 100%; } }}
/* Tablet only: drop the title panel's top padding and the h1's default top margin — they only add dead space above the title and force the topics list to stretch further to keep the shared rule aligned. Desktop keeps its larger title spacing. */@media (min-width: 50rem) and (max-width: 71.9375rem) { main .content-panel:first-of-type { padding-block-start: 0; }
main h1#_top { margin-top: 0; }}