/* tradecn.dev, every page. The palette and the two font stacks are on :root in each page's own <style>, both sides
   of the amber theme; the faces themselves are declared in fonts.css and served under /fonts/. Prose is the sans,
   code and the tag are the mono, the way the typography tokens divide them. */
* { box-sizing: border-box; }
html { background: var(--background); color: var(--foreground); font: 15px/1.55 var(--font-sans); -webkit-text-size-adjust: 100%; scroll-padding-top: 4.5rem; }
body { margin: 0; }
a { color: var(--primary); text-decoration: none; }
a:hover, a:focus-visible { text-decoration: underline; }
code, kbd { font-family: var(--font-mono); }
.wrap { margin: 0 auto; padding: 0 16px; max-width: 80rem; }

/* The header: the mark, the sections, and the links out. Sticky, so the docs never lose their way back. */
.site-header { position: sticky; top: 0; z-index: 10; background: var(--background); border-bottom: 1px solid var(--border); }
.site-header .wrap { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.5rem; padding-top: .75rem; padding-bottom: .75rem; }
.site-header .name { display: flex; align-items: center; gap: .6rem; margin: 0; font-size: 1.15rem; font-weight: 600; color: var(--foreground); }
.site-header .name:hover, .site-header .name:focus-visible { text-decoration: none; }
.site-header .name svg { width: 1.4rem; height: 1.4rem; color: var(--primary); flex: none; }
.site-header .name .slash { color: var(--primary); }
.site-header nav { display: flex; flex-wrap: wrap; gap: 1.1rem; }
.site-header nav a { color: var(--muted-foreground); }
.site-header nav a[aria-current] { color: var(--foreground); }
.site-header .side { margin-left: auto; align-items: center; }
/* The two icon-only controls, the GitHub mark and the mode button, share one square with the same hover and focus. */
.site-header nav .github, .mode-toggle { display: inline-flex; align-items: center; justify-content: center; width: 1.9rem; height: 1.9rem; margin: -.3rem 0; padding: 0; color: var(--muted-foreground); background: none; border: 0; border-radius: var(--radius); cursor: pointer; }
.site-header nav .github:hover, .site-header nav .github:focus-visible, .mode-toggle:hover, .mode-toggle:focus-visible { color: var(--foreground); background: var(--card); text-decoration: none; }
.site-header nav .github:focus-visible, .mode-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* The mark is drawn on a 16 px grid and shown at 16 px; the mode's circle sits inside a 24 px grid, so it gets more. */
.site-header nav .github svg { width: 1rem; height: 1rem; }
.mode-toggle svg { width: 1.05rem; height: 1.05rem; }
/* The Menu button, first in the header: on a phone it stands in for the name and the sections and opens the panel
   (below, with the docs). At a laptop's width, and without a script, it is not there. Its two lines are a cross while open. */
.menu-toggle { display: none; align-items: center; gap: .5rem; margin: -.3rem 0; padding: .3rem .5rem .3rem 0; font: inherit; font-weight: 500; color: var(--foreground); background: none; border: 0; border-radius: var(--radius); cursor: pointer; }
.menu-toggle svg { width: 1.15rem; height: 1.15rem; }
.menu-toggle .close-icon, .menu-toggle[aria-expanded="true"] .menu-icon { display: none; }
.menu-toggle[aria-expanded="true"] .close-icon { display: block; }
.menu-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* The mode. theme.js puts light or dark on <html>, from the reader's choice or the system; color-scheme then picks
   the side of every light-dark() pair in the page's palette, and the browser's own controls and scrollbars follow. */
:root.light { color-scheme: light; }
:root.dark { color-scheme: dark; }
/* Without the script the button would switch nothing, so it is not there; the palette still follows the system. */
html:not(.js) .mode-toggle { display: none; }

/* The two menus in the header, each a native select drawn as text and a chevron; the list it opens is the browser's own.
   The theme: the registry's themes, beside the mode button. theme.js puts the choice on <html> as data-theme; each
   page's palette carries a block per other theme keyed on it, and the previews carry every theme's two sides. The
   site's own theme is the :root palette itself, so a page with no script wears it.
   The version: every release with pages, first among the links, newest first, this page's showing, in the mono the
   tag is set in. site.js fills it from /versions.json at the root, and a pick goes to the same page under that release. */
.version-pick, .theme-pick { position: relative; display: inline-flex; align-items: center; margin: -.3rem 0; color: var(--muted-foreground); }
.version-pick:hover, .version-pick:focus-within, .theme-pick:hover, .theme-pick:focus-within { color: var(--foreground); }
/* field-sizing fits the control to the option showing rather than the longest name on the list, where the browser knows it; elsewhere the chevron sits a little further out. */
.version-select, .theme-select { appearance: none; -webkit-appearance: none; field-sizing: content; margin: 0; padding: .3rem 1.35rem .3rem .5rem; font: inherit; font-size: .9rem; color: inherit; background: none; border: 0; border-radius: var(--radius); cursor: pointer; }
.version-select { font-family: var(--font-mono); }
.version-select:hover, .version-select:focus-visible, .theme-select:hover, .theme-select:focus-visible { background: var(--card); }
.version-select:focus-visible, .theme-select:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.version-pick svg, .theme-pick svg { position: absolute; right: .4rem; width: .8rem; height: .8rem; pointer-events: none; }
/* Without the script the theme menu would change nothing, so it is not there; the page wears the site's own theme. The
   version menu stays, as the tag alone: one option and no chevron, which is the label the header always carried. */
html:not(.js) .theme-pick { display: none; }
html:not(.js) .version-pick svg { display: none; }
html:not(.js) .version-select { padding-right: .5rem; }

/* The search: a button in the header, and a dialog over every page's headings and text that it and mod+k open. */
.search-button { display: inline-flex; align-items: center; gap: .5rem; margin: -.3rem 0; padding: .3rem .6rem; font: inherit; font-size: .85rem; color: var(--muted-foreground); background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer; }
.search-button:hover, .search-button:focus-visible { color: var(--foreground); border-color: var(--primary); }
.search-button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.search-button svg, .search-box svg { width: .95rem; height: .95rem; flex: none; }
.search-button kbd, .search-close { font: inherit; font-size: .75rem; padding: .05rem .4rem; color: var(--muted-foreground); background: var(--background); border: 1px solid var(--border); border-radius: 4px; }
dialog.search { width: min(40rem, calc(100vw - 2rem)); max-height: min(70vh, 40rem); margin: 10vh auto auto; padding: 0; color: var(--foreground); background: var(--background); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: 0 1.5rem 4rem rgb(0 0 0 / .55); overflow: hidden; }
dialog.search[open] { display: flex; flex-direction: column; }
dialog.search::backdrop { background: rgb(0 0 0 / .6); }
.search-box { display: flex; align-items: center; gap: .6rem; padding: .65rem .9rem; border-bottom: 1px solid var(--border); color: var(--muted-foreground); }
.search-box input { flex: 1; min-width: 0; margin: 0; padding: .15rem 0; font: inherit; color: var(--foreground); background: none; border: 0; outline: none; appearance: none; -webkit-appearance: none; }
.search-box input::-webkit-search-cancel-button, .search-box input::-webkit-search-decoration { -webkit-appearance: none; }
.search-close { cursor: pointer; }
.search-close:hover, .search-close:focus-visible { color: var(--foreground); }
.search-close:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.search-results { overflow-y: auto; padding: .4rem; }
.search-page { padding: .6rem .6rem .25rem; font-size: .75rem; font-weight: 500; letter-spacing: .08em; text-transform: uppercase; color: var(--muted-foreground); }
.search-page .kind { margin-left: .5rem; font-weight: 400; letter-spacing: 0; text-transform: none; }
.search-results [role="option"] { display: block; padding: .45rem .6rem; color: var(--foreground); border-radius: var(--radius); }
.search-results [role="option"]:hover, .search-results [role="option"]:focus-visible { text-decoration: none; }
.search-results [role="option"][aria-selected="true"] { background: var(--card); }
.search-hit { display: block; }
.search-hit .parent { color: var(--muted-foreground); }
.search-snippet { display: block; overflow: hidden; font-size: .85rem; color: var(--muted-foreground); white-space: nowrap; text-overflow: ellipsis; }
.search-results mark { color: var(--primary); background: none; }
.search-note { margin: 0; padding: 1.5rem .6rem; text-align: center; color: var(--muted-foreground); }
/* Without the script the button would open nothing, so it is not there. The dialog stays closed on its own. */
html:not(.js) .search-button { display: none; }

/* The opening: one line, one paragraph, two ways in, then every item running. */
.hero { padding: 4.5rem 0 3rem; text-align: center; }
.badge { display: inline-block; padding: .2rem .75rem; font-size: .85rem; color: var(--foreground); background: var(--card); border: 1px solid var(--border); border-radius: 999px; }
.badge:hover, .badge:focus-visible { text-decoration: none; border-color: var(--primary); }
.hero h1 { margin: 1.25rem auto .75rem; max-width: 30ch; font-size: clamp(1.75rem, 4.5vw, 2.75rem); line-height: 1.15; font-weight: 600; letter-spacing: -.01em; }
.hero h1 code { color: var(--primary); }
.hero .lede { margin: 0 auto; max-width: 60ch; font-size: 1.1rem; color: var(--muted-foreground); }
.cta { display: flex; justify-content: center; gap: .75rem; margin: 1.75rem 0 0; }
.button { display: inline-block; padding: .5rem 1rem; color: var(--foreground); background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); }
.button.primary { color: var(--primary-foreground); background: var(--primary); border-color: var(--primary); }
.button:hover, .button:focus-visible { text-decoration: none; border-color: var(--primary); }
.showcase { display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 32rem), 1fr)); align-items: start; padding-bottom: 3rem; }
.showcase .card { margin: 0; padding: 0; border: 1px solid var(--border); border-radius: var(--radius); background: var(--background); overflow: hidden; }
.card-bar { display: flex; align-items: baseline; gap: .75rem; padding: .5rem .75rem; border-bottom: 1px solid var(--border); }
.card-bar .kind { font-size: .8rem; color: var(--muted-foreground); }
.card-bar .open { margin-left: auto; font-size: .85rem; color: var(--muted-foreground); }
.showcase iframe { display: block; width: 100%; height: 16rem; max-height: 36rem; border: 0; background: var(--background); transition: height .15s ease; }
/* The desk: one workspace with every item on it, the width of the page and as tall as it says, and under it the
   map from what is on screen to the docs, grouped the way the sidebar is. The bar wraps on a narrow screen. */
.showcase.desk { grid-template-columns: 1fr; }
/* A card is an article, and an article keeps its children to the reading measure; the desk and its bar take the whole width. */
.showcase .card > * { max-width: none; }
.showcase.desk .card-bar { flex-wrap: wrap; }
.showcase.desk .card-bar .open + .open { margin-left: 1rem; }
.desk-name { font-weight: 600; }
.showcase.desk iframe { height: 50rem; max-height: none; }
.desk-legend { padding: .6rem .75rem .75rem; border-top: 1px solid var(--border); font-size: .85rem; line-height: 1.9; }
.desk-legend p { margin: 0; }
.desk-legend .legend-group { margin-right: .35rem; color: var(--muted-foreground); }
.desk-legend a { margin-right: .35rem; }
.desk-legend code { color: var(--primary); overflow-wrap: normal; white-space: nowrap; }

/* The components index: every component's title linking its page, in columns, shadcn's shape. The names are the
   foreground, as the sidebar's are, and a row has room around it. */
.item-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 13rem), 1fr)); gap: 0 2rem; margin: 1.5rem 0; padding: 0; list-style: none; }
.item-list a { display: block; padding: .5rem 0; color: var(--foreground); }

footer.site-foot { padding: 1.5rem 0 3rem; font-size: .9rem; color: var(--muted-foreground); border-top: 1px solid var(--border); }
footer.site-foot p { margin: 0; }
.up { color: var(--up); }
.down { color: var(--down); }

/* The docs: the sections down the left, the page, and its headings down the right. */
.page { display: grid; grid-template-columns: 14rem minmax(0, 1fr) 13rem; gap: 3rem; padding-top: 1.5rem; max-width: 90rem; }
.sidebar, .toc { position: sticky; top: 4.5rem; align-self: start; max-height: calc(100vh - 4.5rem); overflow-y: auto; font-size: .9rem; }
/* What the sidebar holds for the phone's menu alone (the version and theme menus, Home and the sections) is not there
   at a laptop's width, where the header shows all of it; the opening page's panel holds nothing else, so it is not
   there at all. The panel takes focus when it opens, and needs no ring of its own for that. */
.menu-only, .sidebar.menu { display: none; }
.sidebar:focus { outline: none; }
/* The sections. A group is a muted heading in sentence case and its pages are the foreground, so the two read apart at
   a glance; the current page sits on a filled block and a hover shows the same, shadcn's shape. The headings down the
   right wear the same heading; their links stay muted, as shadcn's do. */
.sidebar h2, .toc h2 { margin: .5rem 0 .35rem; font-size: .8rem; font-weight: 500; color: var(--muted-foreground); }
.sidebar h2 { padding: 0 .5rem; }
.sidebar h2 a { color: inherit; }
.sidebar ul, .toc ul { list-style: none; margin: 0 0 1.25rem; padding: 0; }
.sidebar li + li { margin-top: .1rem; }
.sidebar li a { display: inline-block; padding: .25rem .5rem; color: var(--foreground); border-radius: var(--radius); }
.sidebar li a:hover, .sidebar li a:focus-visible { background: var(--muted); text-decoration: none; }
.sidebar li a:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.sidebar li a[aria-current="page"] { background: var(--muted); }
.toc li { padding: .15rem 0; }
.toc a { color: var(--muted-foreground); }
.toc ul ul { margin: 0; padding-left: .9rem; }
.toc code { font-size: .95em; }
article { min-width: 0; padding-bottom: 4rem; }
/* The prose keeps its measure; the preview, the components index, and the generated tables take the whole column. */
article > :not(.preview) { max-width: 72ch; }
article > .item-list, article > .table { max-width: none; }
article h1 { margin: .5rem 0 .5rem; font-size: 1.75rem; font-weight: 600; letter-spacing: -.01em; }
/* The opening paragraph under the title is the page's lede. */
article > h1 + p { margin: 0 0 1.5rem; font-size: 1.05rem; color: var(--muted-foreground); }
article h2 { margin: 2.25rem 0 .75rem; font-size: 1.15rem; font-weight: 600; }
article h3 { margin: 1.75rem 0 .5rem; font-size: 1rem; font-weight: 600; }
article h1 a, article h2 a, article h3 a { color: inherit; }
article p, article li { line-height: 1.65; }
article ul, article ol { padding-left: 1.4rem; }
article li { margin: .35rem 0; }
article li::marker { color: var(--muted-foreground); }
/* Inline code can break inside a long token (a registry URL is 40 characters of mono), so a phone never scrolls the page sideways; a pre never wraps, so its blocks still scroll in their own box. */
article code { padding: .1em .35em; background: var(--card); color: var(--card-foreground); border: 1px solid var(--border); border-radius: var(--radius); font-size: .95em; overflow-wrap: anywhere; }
article pre { margin: 0; padding: .9rem 2.75rem .9rem 1rem; overflow: auto; background: var(--card); color: var(--card-foreground); border: 1px solid var(--border); border-radius: var(--radius); line-height: 1.5; }
article pre code { padding: 0; background: none; border: 0; font-size: 1em; }
article blockquote { margin: 1rem 0; padding: 0 1rem; border-left: 2px solid var(--primary); color: var(--muted-foreground); }
article table { border-collapse: collapse; width: 100%; }
article th, article td { padding: .5rem .75rem .5rem 0; text-align: left; vertical-align: top; border-bottom: 1px solid var(--border); }
article th { color: var(--muted-foreground); font-weight: 500; }
article hr { border: 0; border-top: 1px solid var(--border); margin: 2rem 0; }
/* Previous and next, as arrows beside the title and as named links at the foot. */
.arrows { float: right; display: flex; gap: .35rem; margin: .5rem 0 0 1rem; }
.arrows a, .arrows span { display: inline-flex; align-items: center; justify-content: center; width: 1.9rem; height: 1.9rem; color: var(--muted-foreground); border: 1px solid var(--border); border-radius: var(--radius); }
.arrows a:hover, .arrows a:focus-visible { color: var(--foreground); text-decoration: none; background: var(--card); }
.arrows span { opacity: .35; }
.arrows svg { width: 1rem; height: 1rem; }
.pager { display: flex; justify-content: space-between; gap: 1rem; margin-top: 3rem; }
.pager a { padding: .5rem .8rem; border: 1px solid var(--border); border-radius: var(--radius); color: var(--foreground); }
.pager a:hover, .pager a:focus-visible { text-decoration: none; background: var(--card); }
.built-on { margin-top: 2rem; color: var(--muted-foreground); }
.foot { margin-top: 3rem; padding-top: 1rem; border-top: 1px solid var(--border); font-size: .9rem; color: var(--muted-foreground); }
/* Every table sits in a wrapper that scrolls sideways, so a wide one never widens the page itself. */
.table { margin: 1rem 0; overflow-x: auto; }
.table table { margin: 0; }
/* Preserve identifiers and leave prose room to wrap; the wrapper scrolls when those columns no longer fit. */
.table code { font-size: .9em; overflow-wrap: normal; }
.table code.identifier { white-space: nowrap; }
.table td:last-child:not(:first-child) { min-width: 14rem; }
/* API references opt in: names and defaults stay visible, descriptions get a full line, and long signatures open separately. */
.api-reference h3 { margin-top: 2.5rem; padding-top: 1rem; border-top: 1px solid var(--border); font-size: 1.15rem; }
.api-reference h4 { margin: 1.5rem 0 .35rem; font-size: 1rem; font-weight: 600; }
.api-reference h4 a { color: inherit; }
.api-reference :is(h3, h4, dt, .api-meta) code { padding: 0; border: 0; background: none; }
.api-props { margin: 1rem 0; }
.api-prop { display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem 1.25rem; padding: .85rem 0; border-top: 1px solid var(--border); }
.api-prop:last-child { border-bottom: 1px solid var(--border); }
.api-prop dt { font-weight: 600; }
.api-prop dt a { color: inherit; }
.api-prop dd { margin: 0; min-width: 0; }
.api-meta { display: flex; flex-wrap: wrap; gap: .25rem 1.25rem; font-size: .85rem; color: var(--muted-foreground); }
.api-meta code { color: inherit; }
.api-description { flex-basis: 100%; line-height: 1.65; }
.api-details { margin: .75rem 0; }
.api-details summary { width: fit-content; color: var(--muted-foreground); cursor: pointer; }
.api-details summary:hover { color: var(--foreground); }
.api-details summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 4px; border-radius: var(--radius); }
.api-details .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.api-details[open] > summary { margin-bottom: .75rem; color: var(--foreground); }
.api-details > :not(summary) { margin-left: 1rem; }
.api-description .api-details { margin-bottom: 0; font-size: .9rem; }
.api-signature { padding: .75rem; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); }
.api-signature code { padding: 0; border: 0; background: none; }
.api-expand { padding: .35rem .65rem; font: inherit; font-size: .85rem; color: var(--muted-foreground); background: none; border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer; }
.api-expand:hover { color: var(--foreground); }
.api-expand:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* The tokens table on the Theming page: a color beside a swatch of it, on one line; a font stack wraps at its commas, or the value column would take the width and leave the items that add it one to a line. */
.tokens td:first-child { white-space: nowrap; }
.tokens td code, .dependencies td code { white-space: nowrap; }
.tokens td code.stack { white-space: normal; }
.swatch { display: inline-block; width: .9em; height: .9em; margin-right: .4em; vertical-align: -.1em; border: 1px solid var(--border); border-radius: 2px; }

/* A code block: the pre, a copy button over its top-right corner, and for a command the package-manager tabs above it. */
.code { position: relative; margin: 1rem 0; }
.copy { position: absolute; top: .45rem; right: .45rem; display: inline-flex; align-items: center; justify-content: center; width: 1.75rem; height: 1.75rem; padding: 0; color: var(--muted-foreground); background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer; }
.copy:hover, .copy:focus-visible, .copy[data-copied] { color: var(--foreground); }
.copy:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.copy svg { width: 1rem; height: 1rem; }
.copy .check-icon, .copy[data-copied] .copy-icon { display: none; }
.copy[data-copied] .check-icon { display: block; }
/* Line numbers, shadcn's shape: a block in a language the site colors counts its lines down a gutter that stays put while
   a long line scrolls under it, in the block's own background so the code passes behind. The number is drawn, not text, so
   a selection or the copy button takes the code alone, and its alternative text is empty, so a screen reader reads the code
   alone too. The grid puts each line on a row of its own and leaves the newlines
   between the spans unrendered; the copy button still reads them from the text. The block's own left padding moves into
   the gutter, which is wide enough for the longest file's four digits, and a source's final newline is not a line. A
   command has no gutter, and a text tree (the composition diagrams) keeps its connectors on plain lines. */
.code:not(.command) pre:has(> code > .line) { padding-left: 0; }
.code:not(.command) code:has(> .line) { display: grid; counter-reset: line; }
.code:not(.command) .line::before { counter-increment: line; content: counter(line) / ""; display: inline-block; width: calc(1rem + 4ch); padding-right: 1.25rem; text-align: right; color: var(--muted-foreground); background: var(--card); position: sticky; left: 0; user-select: none; }
.code:not(.command) .line:last-child:empty { display: none; }
.command { border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); }
.command pre { border: 0; border-radius: 0; background: none; }
.command .copy { top: .35rem; }
.managers { display: flex; align-items: center; gap: .15rem; padding: .35rem 2.75rem .35rem .5rem; border-bottom: 1px solid var(--border); color: var(--muted-foreground); }
.managers .prompt { width: 1rem; height: 1rem; margin: 0 .4rem 0 .2rem; flex: none; }
.managers [role="tab"] { font: inherit; font-size: .85rem; color: var(--muted-foreground); background: none; border: 1px solid transparent; padding: .15rem .5rem; border-radius: var(--radius); cursor: pointer; }
.managers [role="tab"][aria-selected="true"] { color: var(--foreground); background: var(--background); border-color: var(--border); }
.managers [role="tab"]:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
/* One command shows: the page's data-pm, which site.js sets from the reader's last choice before the body parses. npm until then. */
.command pre[data-pm] { display: none; }
html:not([data-pm]) .command pre[data-pm="npm"], html[data-pm="npm"] .command pre[data-pm="npm"], html[data-pm="pnpm"] .command pre[data-pm="pnpm"], html[data-pm="yarn"] .command pre[data-pm="yarn"], html[data-pm="bun"] .command pre[data-pm="bun"] { display: block; }
/* Without the script the tabs and the buttons would do nothing, so they are not there. */
html:not(.js) .copy, html:not(.js) .managers { display: none; }
/* Installation: Command / Manual as underline tabs. */
.tabs-bar { display: flex; gap: 1.25rem; margin: .75rem 0 1rem; border-bottom: 1px solid var(--border); }
.tabs-bar [role="tab"] { font: inherit; color: var(--muted-foreground); background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; padding: .35rem 0; cursor: pointer; }
.tabs-bar [role="tab"][aria-selected="true"] { color: var(--foreground); border-bottom-color: var(--foreground); }
.tabs-bar [role="tab"]:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
html:not(.js) .tabs-bar { display: none; }
html:not(.js) .tabs [role="tabpanel"][hidden] { display: block; }
/* Manual's steps, shadcn's shape: each numbered in a circle that sits on a rule down their left edge, what to do beside
   the number and the blocks to do it with under it. On a phone the rule goes and the number stands at the start of
   the line, so the blocks keep the column's width. */
.steps { margin: 1.5rem 0 0 1.125rem; padding: 0 0 0 2rem; border-left: 1px solid var(--border); list-style: none; counter-reset: step; }
.steps > li { position: relative; margin: 0; counter-increment: step; }
.steps > li + li { margin-top: 2rem; }
.steps > li > p:first-child { margin: 0; font-weight: 500; }
.steps > li > p:first-child::before { content: counter(step); position: absolute; top: -.3rem; left: calc(-2rem - .5px); translate: -50% 0; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; width: 2.25rem; height: 2.25rem; font: 500 .875rem/1 var(--font-mono); color: var(--foreground); background: var(--muted); border: 4px solid var(--background); border-radius: 50%; }
/* A block to copy from under Manual, a file or the stylesheet, shadcn's shape: a header with the block's language mark
   where a command's prompt stands, then the file's path, Expand and the copy button at the header's end. Under it the
   code, collapsed to its first lines under a fade with Expand again over it (a button for the mouse; the Tab key and a
   screen reader meet the first), the code inert; opened, the whole block however long, with Collapse where Expand was.
   The copy button takes the whole block either way. A block short enough to show whole has nothing to expand: site.js
   measures it against the clip and marks it, and its clip and its buttons go. */
.source { position: relative; margin: 1rem 0; border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); }
.source figcaption { position: relative; min-height: calc(2.45rem + 1px); padding: .35rem .75rem .35rem 2.1rem; font-size: .85rem; line-height: 1.75rem; color: var(--muted-foreground); border-bottom: 1px solid var(--border); }
.source figcaption svg { position: absolute; top: .725rem; left: .7rem; width: 1rem; height: 1rem; }
.source figcaption code { padding: 0; font-size: 1em; color: inherit; background: none; border: 0; }
/* The header's first line keeps clear of the buttons at its end, as wide as Collapse and the copy button, or the copy
   button alone on a block that shows whole; a path too long for it breaks after a slash and goes on under them. */
.source figcaption::before { content: ""; float: right; width: 7.25rem; height: 1.75rem; }
.source[data-fits] figcaption::before { width: 2.05rem; }
.source figcaption span { white-space: nowrap; }
/* The copy button stands in the header, so its block is the whole figure, not the code under it. */
.source .code { position: static; margin: 0; }
.source pre { padding-right: 1rem; border: 0; border-radius: 0; background: none; }
.source .copy { top: .35rem; }
.source[data-collapsed]:not([data-fits]) pre { max-height: 16rem; overflow: hidden; }
.expand { position: absolute; top: .35rem; right: 2.75rem; height: 1.75rem; padding: 0 .55rem; font: inherit; font-size: .85rem; color: var(--muted-foreground); background: var(--card); border: 0; border-radius: var(--radius); cursor: pointer; }
.expand::after { content: ""; position: absolute; top: .3rem; right: -.3rem; bottom: .3rem; border-left: 1px solid var(--border); }
.expand:hover, .expand:focus-visible { color: var(--foreground); }
.expand:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.expand-foot { position: absolute; right: 0; bottom: 0; left: 0; display: flex; align-items: center; justify-content: center; height: 5rem; font: inherit; font-size: .85rem; color: var(--muted-foreground); background: linear-gradient(to bottom, color-mix(in oklab, var(--card) 70%, transparent), var(--card)); border: 0; border-radius: 0 0 calc(var(--radius) - 1px) calc(var(--radius) - 1px); cursor: pointer; }
.expand-foot:hover { color: var(--foreground); }
.source:not([data-collapsed]) .expand-foot, .source[data-fits] .expand, .source[data-fits] .expand-foot { display: none; }
/* Without the script the buttons would do nothing, so they are not there and a block scrolls inside itself. */
html:not(.js) .expand, html:not(.js) .expand-foot { display: none; }
html:not(.js) .source figcaption::before { content: none; }
html:not(.js) .source[data-collapsed] pre { max-height: 24rem; overflow: auto; }
/* The live preview, shadcn's shape: the item running in an iframe sized by the height it reports (the embed page
   centers the demo and keeps at least 22rem), and its source under the frame. Collapsed, the first lines show
   through a fade with View Code over them and nothing in them reachable; opened, for good, as shadcn's is, the source
   scrolling inside the card at shadcn's height, with its copy button. */
.preview { margin: 1.25rem 0 2rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--background); overflow: hidden; }
.preview iframe { display: block; width: 100%; height: 22rem; border: 0; background: var(--background); transition: height .15s ease; }
.preview-code { position: relative; border-top: 1px solid var(--border); background: var(--card); }
.preview-code .code { margin: 0; }
/* The opened source takes focus so the Tab order reads on from it; the ring sits inside the card's edge. */
.preview-code-body:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
/* Opened, the source scrolls inside the card at shadcn's height, enough to read through and select from, rather than
   running the page's length; collapsed, the body's clip shows the first lines and the pre has no scrollbar of its own. */
.preview-code pre { border: 0; border-radius: 0; background: none; max-height: 18rem; }
.preview-code[data-collapsed] pre { overflow: hidden; }
/* View Code stands over the collapsed lines until it opens them, and site.js then takes it away. */
.view-code { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font: inherit; font-size: .85rem; color: var(--foreground); background: var(--background); border: 1px solid var(--border); border-radius: var(--radius); padding: .4rem .9rem; cursor: pointer; }
.view-code:hover { background: var(--muted); }
.view-code:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.preview-code[data-collapsed] .preview-code-body { max-height: 8rem; overflow: hidden; -webkit-mask-image: linear-gradient(to bottom, rgb(0 0 0 / .55), transparent 95%); mask-image: linear-gradient(to bottom, rgb(0 0 0 / .55), transparent 95%); }
.preview-code[data-collapsed] .copy { display: none; }
/* Without the script the button would do nothing, so the source is simply there. */
html:not(.js) .preview-code[data-collapsed] .preview-code-body { max-height: none; -webkit-mask-image: none; mask-image: none; }
html:not(.js) .preview-code[data-collapsed] pre { overflow: auto; }
html:not(.js) .view-code { display: none; }

@media (max-width: 72rem) {
  .page { grid-template-columns: 14rem minmax(0, 1fr); }
  .toc { display: none; }
}
@media (max-width: 48rem) {
  .page { grid-template-columns: 1fr; gap: 1.5rem; }
  .hero { padding-top: 2.5rem; }
  .cta { flex-wrap: wrap; }
  /* Manual's steps give up their rule: each number stands at the start of its line, and a longer line hangs under the text. */
  .steps { margin-left: 0; padding-left: 0; border-left: 0; }
  .steps > li > p:first-child { padding-left: 2rem; text-indent: -2rem; }
  .steps > li > p:first-child::before { position: static; translate: none; width: 1.5rem; height: 1.5rem; margin-right: .5rem; text-indent: 0; border: 0; }
  /* On a phone the search is its icon, and the dialog takes the screen. */
  .search-button span, .search-button kbd { display: none; }
  .search-button { padding: .3rem .45rem; }
  dialog.search { margin: 1rem auto auto; max-height: calc(100vh - 2rem); }
  /* The header folds: the Menu button stands in for the name and the sections, and the version and theme menus
     move into the panel it opens, so the header is one row: the button, then the search, the GitHub mark, and the mode button. */
  html.js .menu-toggle { display: inline-flex; }
  html.js .site-header .name, html.js .site-header nav[aria-label="Sections"], html.js .site-header .version-pick, html.js .site-header .theme-pick { display: none; }
  /* The panel is the sidebar, out of the page until the button opens it, then over the page from under the header to
     the bottom of the screen, edge to edge, scrolling on its own while the page behind holds still. site.js measures
     the header into --header-height, since it is one row, or two on the narrowest phone. The two menus lead, then
     Home and the sections, then the docs groups, each name at a thumb's size, the current page in the primary. */
  html.js .sidebar { display: none; }
  html.js[data-menu="open"], html.js[data-menu="open"] body { overflow: hidden; }
  /* align-self: stretch, because the sidebar's own align-self: start would size a fixed box to its content instead of filling the insets. */
  html.js[data-menu="open"] .sidebar { display: block; position: fixed; top: var(--header-height, 3.25rem); right: 0; bottom: 0; left: 0; z-index: 9; align-self: stretch; max-height: none; padding: .5rem 16px 3rem; overflow-y: auto; font-size: 1rem; background: color-mix(in oklab, var(--background) 92%, transparent); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
  html.js .menu-only { display: block; }
  .menu-settings { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; margin: .75rem 0 .5rem; }
  .menu-settings .version-pick, .menu-settings .theme-pick { margin: 0; color: var(--foreground); background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); }
  html.js .sidebar h2 { margin: 1.5rem 0 .5rem; padding: 0; }
  html.js .sidebar li + li { margin-top: 0; }
  html.js .sidebar li a { display: block; padding: .4rem 0; font-size: 1.4rem; font-weight: 500; line-height: 1.3; border-radius: 0; }
  html.js .sidebar li a:hover, html.js .sidebar li a:focus-visible, html.js .sidebar li a[aria-current="page"] { color: var(--primary); background: none; }
  /* Without a script the button would open nothing, so it is not there, and the sidebar stays in the page as it
     was: every group wrapped above the article, the version and theme menus in the header. */
  html:not(.js) .sidebar { position: static; max-height: none; }
  html:not(.js) .sidebar ul { display: flex; flex-wrap: wrap; gap: .1rem .25rem; }
  html:not(.js) .sidebar li + li { margin-top: 0; }
}
