/* Knowledge Base article styling
   Targets HTML produced by MarkdownRenderer.razor (Markdig output).
   Palette mirrors the codec-guide aesthetic so KB pages and /codec-guide feel like siblings.
   Dark-mode variants flip when [data-theme="dark"] is set on a parent (BlazorCommon convention).
*/

/* Theme variables live on .kb-doc (the outer wrapper used by both /kb home and the
   /kb/guides/... article views) so the dark-mode overrides apply everywhere — not
   just inside .kb-article. */
.kb-doc {
    --kb-text-strong: #0f172a;
    --kb-text: #334155;
    --kb-text-muted: #64748b;
    --kb-text-accent: #4338ca;

    --kb-surface: #ffffff;
    --kb-surface-subtle: #f8fafc;
    --kb-surface-accent: #eef2ff;

    --kb-border: #e2e8f0;
    --kb-border-strong: #cbd5e1;

    --kb-accent: #6366f1;
    --kb-accent-hover: #4f46e5;

    --kb-code-bg: #eef2ff;
    --kb-code-text: #4338ca;
    --kb-code-block-bg: #0f172a;
    --kb-code-block-text: #e2e8f0;

    --kb-table-header-bg: #eef2ff;
    --kb-table-header-text: #4338ca;
    --kb-table-row-hover: #f8fafc;

    --kb-callout-info-bg: #eef2ff;
    --kb-callout-info-text: #4338ca;
    --kb-callout-info-border: #c7d2fe;

    --kb-callout-warn-bg: #fef3c7;
    --kb-callout-warn-text: #92400e;
    --kb-callout-warn-border: #fde68a;

    --kb-callout-danger-bg: #fef2f2;
    --kb-callout-danger-text: #b91c1c;
    --kb-callout-danger-border: #fca5a5;

    --kb-link: #4f46e5;
    --kb-link-hover: #4338ca;
}

[data-theme="dark"] .kb-doc {
    --kb-text-strong: #f8fafc;
    --kb-text: #cbd5e1;
    --kb-text-muted: #9ca3af;
    --kb-text-accent: #c7d2fe;

    --kb-surface: rgba(255, 255, 255, 0.04);
    --kb-surface-subtle: rgba(255, 255, 255, 0.06);
    --kb-surface-accent: rgba(99, 102, 241, 0.12);

    --kb-border: rgba(255, 255, 255, 0.12);
    --kb-border-strong: rgba(255, 255, 255, 0.18);

    --kb-code-bg: rgba(99, 102, 241, 0.15);
    --kb-code-text: #e0e7ff;
    --kb-code-block-bg: #1e293b;
    --kb-code-block-text: #e2e8f0;

    --kb-table-header-bg: rgba(99, 102, 241, 0.12);
    --kb-table-header-text: #e0e7ff;
    --kb-table-row-hover: rgba(255, 255, 255, 0.03);

    --kb-callout-info-bg: rgba(99, 102, 241, 0.1);
    --kb-callout-info-text: #e0e7ff;
    --kb-callout-info-border: rgba(99, 102, 241, 0.4);

    --kb-callout-warn-bg: rgba(217, 119, 6, 0.15);
    --kb-callout-warn-text: #fde68a;
    --kb-callout-warn-border: rgba(217, 119, 6, 0.5);

    --kb-callout-danger-bg: rgba(185, 28, 28, 0.15);
    --kb-callout-danger-text: #fecaca;
    --kb-callout-danger-border: rgba(185, 28, 28, 0.5);

    /* Brighter link tone for dark mode — the default #4f46e5 reads almost black
       on the dark page background. Use a lighter indigo so links are legible. */
    --kb-link: #a5b4fc;
    --kb-link-hover: #c7d2fe;
}

.kb-article {
    color: var(--kb-text);
    background: transparent;
    font-size: 0.975rem;
    line-height: 1.65;
    max-width: 920px;
    margin: 0 auto;
    padding: 2rem 1.5rem 4rem;
}

/* Headings */
.kb-article h1,
.kb-article h2,
.kb-article h3,
.kb-article h4,
.kb-article h5,
.kb-article h6 {
    color: var(--kb-text-strong);
    font-weight: 600;
    line-height: 1.25;
    margin: 2rem 0 0.75rem;
    scroll-margin-top: 80px;
}

.kb-article h1 {
    font-size: 2.1rem;
    margin-top: 0;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--kb-border);
}

.kb-article h2 {
    font-size: 1.55rem;
    margin-top: 2.5rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px solid var(--kb-border);
}

.kb-article h3 { font-size: 1.25rem; }
.kb-article h4 { font-size: 1.075rem; }

/* Paragraphs and inline */
.kb-article p { margin: 0 0 1rem; }

.kb-article strong { color: var(--kb-text-strong); font-weight: 600; }

.kb-article a {
    color: var(--kb-link);
    text-decoration: none;
    border-bottom: 1px dotted var(--kb-link);
    transition: color 120ms ease, border-color 120ms ease;
}

.kb-article a:hover {
    color: var(--kb-link-hover);
    border-bottom-color: var(--kb-link-hover);
}

/* Lists */
.kb-article ul,
.kb-article ol {
    margin: 0 0 1rem;
    padding-left: 1.5rem;
}

.kb-article li { margin-bottom: 0.35rem; }
.kb-article li > p { margin-bottom: 0.35rem; }

.kb-article ul.contains-task-list {
    list-style: none;
    padding-left: 0.25rem;
}

.kb-article .task-list-item input[type="checkbox"] {
    margin-right: 0.5rem;
    transform: translateY(1px);
}

/* Inline code */
.kb-article code {
    background: var(--kb-code-bg);
    color: var(--kb-code-text);
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    font-family: "JetBrains Mono", "Fira Code", Consolas, Menlo, monospace;
    font-size: 0.875em;
}

/* Code block wrapper — added by JS around every <pre>. Owns the positioning context
   for the copy button. The wrapper does NOT scroll horizontally (the inner <pre>
   does), so the button stays anchored to the visible top-right of the code block
   even when the user pans the code sideways on a narrow screen. */
.kb-code-wrap {
    position: relative;
    margin: 0 0 1.25rem;
}

/* Code blocks */
.kb-article pre {
    background: var(--kb-code-block-bg);
    color: var(--kb-code-block-text);
    padding: 1rem 1.25rem;
    border-radius: 8px;
    overflow-x: auto;
    margin: 0;
    font-size: 0.875rem;
    line-height: 1.55;
    border: 1px solid var(--kb-border);
}

/* Copy button — attached via JS by BlazorCommon.kb.addCopyButtons(). Anchored to
   .kb-code-wrap (not the <pre>) so horizontal scrolling of code content doesn't move
   it. Hidden by default, revealed on hover of the wrap. Always visible briefly after
   a successful copy (the `.is-copied` state). */
.kb-copy-btn {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    width: 30px;
    height: 30px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 5px;
    color: rgba(226, 232, 240, 0.85);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    opacity: 0.55;
    transition: opacity 120ms ease, background 120ms ease, color 120ms ease, border-color 120ms ease;
    z-index: 1; /* sit above the code content during scroll */
}

.kb-code-wrap:hover .kb-copy-btn,
.kb-code-wrap:focus-within .kb-copy-btn,
.kb-copy-btn:focus-visible,
.kb-copy-btn:hover {
    opacity: 1;
}

.kb-copy-btn:hover {
    background: rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.22);
    color: #ffffff;
}

.kb-copy-btn:focus-visible {
    outline: 2px solid var(--kb-accent);
    outline-offset: 2px;
}

.kb-copy-btn.is-copied {
    opacity: 1;
    background: rgba(99, 102, 241, 0.25);
    border-color: rgba(99, 102, 241, 0.55);
    color: #ffffff;
}

/* Touch devices: no hover, so keep the copy button fully visible and bigger
   for easier tapping. Also gives a touch of breathing room around the icon. */
@media (hover: none), (max-width: 768px) {
    .kb-copy-btn {
        opacity: 1;
        width: 34px;
        height: 34px;
        top: 0.4rem;
        right: 0.4rem;
    }
}

.kb-article pre code {
    background: transparent;
    color: inherit;
    padding: 0;
    border-radius: 0;
    font-size: inherit;
}

/* Tables */
.kb-article table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    margin: 1rem 0 1.5rem;
    border: 1px solid var(--kb-border);
    border-radius: 8px;
    overflow: hidden;
    font-size: 0.925rem;
}

.kb-article thead th {
    background: var(--kb-table-header-bg);
    color: var(--kb-table-header-text);
    font-weight: 600;
    text-align: left;
    padding: 0.65rem 0.85rem;
    border-bottom: 1px solid var(--kb-border);
}

.kb-article tbody td {
    padding: 0.6rem 0.85rem;
    border-top: 1px solid var(--kb-border);
    vertical-align: top;
}

.kb-article tbody tr:hover { background: var(--kb-table-row-hover); }
.kb-article tbody tr:first-child td { border-top: none; }

/* Blockquotes — used as default callout */
.kb-article blockquote {
    margin: 1rem 0 1.25rem;
    padding: 0.9rem 1.1rem;
    border-left: 4px solid var(--kb-accent);
    background: var(--kb-callout-info-bg);
    color: var(--kb-callout-info-text);
    border-radius: 0 6px 6px 0;
}

.kb-article blockquote > :last-child { margin-bottom: 0; }

/* Custom callouts via Markdig generic attributes:
   > Be careful here.
   {.callout-warn}
*/
.kb-article .callout-info {
    background: var(--kb-callout-info-bg);
    color: var(--kb-callout-info-text);
    border-left: 4px solid var(--kb-accent);
    padding: 0.9rem 1.1rem;
    border-radius: 0 6px 6px 0;
    margin: 1rem 0 1.25rem;
}

.kb-article .callout-warn {
    background: var(--kb-callout-warn-bg);
    color: var(--kb-callout-warn-text);
    border-left: 4px solid var(--kb-callout-warn-border);
    padding: 0.9rem 1.1rem;
    border-radius: 0 6px 6px 0;
    margin: 1rem 0 1.25rem;
}

.kb-article .callout-danger {
    background: var(--kb-callout-danger-bg);
    color: var(--kb-callout-danger-text);
    border-left: 4px solid var(--kb-callout-danger-border);
    padding: 0.9rem 1.1rem;
    border-radius: 0 6px 6px 0;
    margin: 1rem 0 1.25rem;
}

/* Images and figures */
.kb-article img {
    max-width: 100%;
    height: auto;
    border-radius: 6px;
    border: 1px solid var(--kb-border);
    margin: 0.5rem 0;
}

.kb-article figure { margin: 1rem 0; }
.kb-article figcaption {
    color: var(--kb-text-muted);
    font-size: 0.875rem;
    text-align: center;
    margin-top: 0.4rem;
}

/* Horizontal rules */
.kb-article hr {
    border: none;
    border-top: 1px solid var(--kb-border);
    margin: 2rem 0;
}

/* Header anchor links (Markdig auto-identifiers) */
.kb-article h1 a,
.kb-article h2 a,
.kb-article h3 a,
.kb-article h4 a {
    color: inherit;
    border-bottom: none;
}

/* Guide frame: two independent scroll columns. The outer .kb-doc has overflow:auto
   from BlazorCommon, but the frame fills it (height:100%) and clips its own
   overflow — so the page itself never scrolls. Each column scrolls internally.
   This is the same pattern the Accounts page uses with Telerik grids: the window
   knows the viewport size, and content scroll stays inside its panel. */
.kb-guide-frame {
    display: grid;
    grid-template-columns: 340px minmax(0, 1fr);
    gap: 1.5rem;
    padding: 0 1.5rem;
    height: 100%;
    overflow: hidden;
}

/* Mobile overrides live at the BOTTOM of this file (see end) so they always win
   the cascade against the base column/prev-next rules which are defined below. */

/* Sidebar column: scrolls internally if the tree is taller than the viewport. */
.kb-guide-sidebar-col {
    overflow-y: auto;
    padding: 1.5rem 0;
    min-height: 0; /* required so a flex/grid child can shrink and scroll properly */
}

/* Article column: scrolls internally. Flex column so prev/next can push to the
   bottom on short articles via margin-top: auto. No bottom padding — the prev/next
   nav sits flush at the column edge. */
.kb-guide-main {
    overflow-y: auto;
    padding: 1.5rem 0.5rem 0 0;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

/* No sticky here anymore — the sidebar column itself scrolls internally, so the tree
   stays exactly where it is regardless of any other scroll behavior on the page. */
.kb-sidebar {
    padding: 0.5rem 0.5rem 1rem 0;
    border-right: 1px solid #e2e8f0;
    font-size: 0.9rem;
}

.kb-sidebar-title {
    font-size: 1rem;
    font-weight: 700;
    margin: 0 0 0.5rem;
    padding: 0.25rem 0.5rem;
    color: #0f172a;
}

.kb-sidebar-title a { color: inherit; text-decoration: none; }
.kb-sidebar-title a:hover { color: #4f46e5; }

/* Search input */
.kb-sidebar-search-wrap {
    position: relative;
    margin: 0 0.5rem 0.75rem 0;
}

.kb-sidebar-search {
    width: 100%;
    padding: 0.4rem 1.8rem 0.4rem 0.6rem;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
    background: #ffffff;
    color: #0f172a;
    font-size: 0.85rem;
    outline: none;
    transition: border-color 80ms ease, box-shadow 80ms ease;
}

.kb-sidebar-search::placeholder { color: #94a3b8; }

.kb-sidebar-search:focus {
    border-color: #6366f1;
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
}

.kb-sidebar-search-clear {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: #64748b;
    cursor: pointer;
    font-size: 1.1rem;
    line-height: 1;
    padding: 0 4px;
    border-radius: 3px;
}

.kb-sidebar-search-clear:hover { color: #4f46e5; background: rgba(99, 102, 241, 0.08); }

[data-theme="dark"] .kb-sidebar-search {
    background: rgba(255,255,255,0.04);
    border-color: rgba(255,255,255,0.1);
    color: #f8fafc;
}

[data-theme="dark"] .kb-sidebar-search::placeholder { color: #64748b; }

[data-theme="dark"] .kb-sidebar-search:focus {
    border-color: #6366f1;
    box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.25);
}

[data-theme="dark"] .kb-sidebar-search-clear { color: #94a3b8; }
[data-theme="dark"] .kb-sidebar-search-clear:hover { color: #c7d2fe; background: rgba(99,102,241,0.18); }

/* "Search article content for X" link below the filter input — appears only when filter is active */
.kb-sidebar-fulltext {
    display: block;
    margin: 0 0.5rem 0.75rem 0;
    padding: 0.4rem 0.6rem;
    font-size: 0.8rem;
    background: rgba(99, 102, 241, 0.08);
    border: 1px dashed rgba(99, 102, 241, 0.3);
    border-radius: 6px;
    color: #4f46e5;
    text-decoration: none;
    line-height: 1.35;
}

.kb-sidebar-fulltext:hover {
    background: rgba(99, 102, 241, 0.15);
    border-color: rgba(99, 102, 241, 0.5);
}

[data-theme="dark"] .kb-sidebar-fulltext {
    color: #c7d2fe;
    background: rgba(99, 102, 241, 0.12);
    border-color: rgba(99, 102, 241, 0.4);
}

/* "Clear search" link in the results header */
.kb-clear-search {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.15rem 0.6rem;
    font-size: 0.8rem;
    border: 1px solid var(--kb-border);
    border-radius: 4px;
    color: var(--kb-text-muted);
    text-decoration: none;
    transition: border-color 80ms ease, color 80ms ease, background 80ms ease;
}

.kb-clear-search:hover {
    border-color: var(--kb-accent);
    color: var(--kb-accent);
    background: var(--kb-surface-subtle);
}

/* Search results page */
.kb-search-results {
    list-style: none;
    padding: 0;
    margin: 1rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
}

.kb-search-hit-link {
    display: block;
    padding: 0.85rem 1rem;
    border: 1px solid var(--kb-border);
    border-radius: 8px;
    background: var(--kb-surface);
    color: var(--kb-text-strong);
    text-decoration: none;
    transition: border-color 120ms ease, background 120ms ease;
}

.kb-search-hit-link:hover {
    border-color: var(--kb-accent);
    background: var(--kb-surface-subtle);
}

.kb-search-hit-title {
    display: block;
    font-weight: 600;
    font-size: 1rem;
    margin-bottom: 0.2rem;
}

.kb-search-hit-badge {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.05rem 0.4rem;
    font-size: 0.7rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: var(--kb-callout-info-bg);
    color: var(--kb-callout-info-text);
    border-radius: 3px;
    vertical-align: middle;
}

.kb-search-hit-path {
    display: block;
    color: var(--kb-text-muted);
    font-size: 0.8rem;
    margin-bottom: 0.35rem;
    font-family: "JetBrains Mono", "Fira Code", Consolas, Menlo, monospace;
}

.kb-search-hit-snippet {
    display: block;
    color: var(--kb-text);
    font-size: 0.9rem;
    line-height: 1.5;
}

.kb-search-hit-snippet mark,
.kb-search-hit-title mark {
    background: #fef08a;
    color: #422006;
    padding: 0 2px;
    border-radius: 2px;
}

[data-theme="dark"] .kb-search-hit-snippet mark,
[data-theme="dark"] .kb-search-hit-title mark {
    background: rgba(250, 204, 21, 0.35);
    color: #fef9c3;
}

/* Tree */
.kb-toc {
    list-style: none;
    padding: 0;
    margin: 0;
}

/* Nested lists get an indented left rule */
.kb-toc .kb-toc {
    margin-left: 0.85rem;
    border-left: 1px solid #e2e8f0;
    padding-left: 0.25rem;
}

.kb-toc-item {
    margin: 0;
    padding: 0;
}

.kb-toc-row {
    display: flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.18rem 0.4rem;
    border-radius: 4px;
    transition: background 80ms ease;
}

.kb-toc-row:hover {
    background: rgba(99, 102, 241, 0.06);
}

.kb-toc-link {
    flex: 1 1 auto;
    color: #334155;
    text-decoration: none;
    line-height: 1.35;
    border-bottom: none;
    padding: 0.1rem 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kb-toc-link:hover { color: #4f46e5; }

/* Chevron button */
.kb-toc-chevron {
    background: none;
    border: none;
    padding: 0;
    width: 18px;
    height: 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: #94a3b8;
    border-radius: 3px;
    transition: transform 160ms ease, color 80ms ease, background 80ms ease;
    flex: 0 0 18px;
}

.kb-toc-chevron:hover {
    color: #4f46e5;
    background: rgba(99, 102, 241, 0.12);
}

.kb-toc-item.is-expanded > .kb-toc-row > .kb-toc-chevron {
    transform: rotate(90deg);
}

/* Reserve space for items without a chevron so labels align */
.kb-toc-chevron-spacer {
    width: 18px;
    flex: 0 0 18px;
    display: inline-block;
}

/* Section nodes are visually distinct */
.kb-toc-item.is-section > .kb-toc-row > .kb-toc-link {
    font-weight: 600;
    color: #1e293b;
}

/* Top-level items (direct children of the guide root) are bold regardless of whether
   they're a section or a leaf article — visually marking the major guide chapters. */
.kb-toc-item.is-top-level > .kb-toc-row > .kb-toc-link {
    font-weight: 700;
    color: #0f172a;
}

.kb-toc-item.is-active > .kb-toc-row {
    background: rgba(99, 102, 241, 0.14);
}

.kb-toc-item.is-active > .kb-toc-row > .kb-toc-link {
    color: #4f46e5;
    font-weight: 600;
}

[data-theme="dark"] .kb-toc-item.is-top-level > .kb-toc-row > .kb-toc-link { color: #f8fafc; }

[data-theme="dark"] .kb-sidebar { border-right-color: rgba(255,255,255,0.08); }
[data-theme="dark"] .kb-sidebar-title { color: #f8fafc; }
[data-theme="dark"] .kb-toc .kb-toc { border-left-color: rgba(255,255,255,0.08); }
[data-theme="dark"] .kb-toc-link { color: #cbd5e1; }
[data-theme="dark"] .kb-toc-row:hover { background: rgba(99, 102, 241, 0.12); }
[data-theme="dark"] .kb-toc-item.is-section > .kb-toc-row > .kb-toc-link { color: #f8fafc; }
[data-theme="dark"] .kb-toc-item.is-active > .kb-toc-row { background: rgba(99, 102, 241, 0.22); }
[data-theme="dark"] .kb-toc-item.is-active > .kb-toc-row > .kb-toc-link { color: #c7d2fe; }
[data-theme="dark"] .kb-toc-chevron { color: #64748b; }
[data-theme="dark"] .kb-toc-chevron:hover { color: #c7d2fe; background: rgba(99,102,241,0.18); }

/* Guide main column */
/* Guide article width: a touch wider than the base .kb-article (920px) so
   code blocks and wide tables have breathing room without paragraphs becoming
   uncomfortably long. Caps everything (paragraphs, code, tables, lists) to
   the same width so the right edge stays aligned. */
.kb-guide-main .kb-article { padding: 0 0.5rem; max-width: 1120px; margin: 0; }
.kb-guide-lede { color: #64748b; font-size: 1.05rem; margin: 0 0 1.25rem; }
[data-theme="dark"] .kb-guide-lede { color: #9ca3af; }

/* Breadcrumb (inside guide pages) */
.kb-breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.875rem;
    color: #64748b;
    margin: 0 auto 0.75rem;
    padding: 0 0.5rem;
    max-width: 920px;
}

.kb-breadcrumb a {
    color: #4f46e5;
    text-decoration: none;
    border-bottom: none;
}

.kb-breadcrumb a:hover { text-decoration: underline; }
.kb-breadcrumb-sep { color: #cbd5e1; }
.kb-breadcrumb-current { color: #0f172a; font-weight: 500; }

[data-theme="dark"] .kb-breadcrumb { color: #9ca3af; }
[data-theme="dark"] .kb-breadcrumb a { color: #c7d2fe; }
[data-theme="dark"] .kb-breadcrumb-sep { color: rgba(255,255,255,0.18); }
[data-theme="dark"] .kb-breadcrumb-current { color: #f8fafc; }

/* Previous / Next nav — anchored to the bottom of the article column.
   `margin-top: auto` (inside the flex-column .kb-guide-main) pushes it to the
   bottom whenever the article is shorter than the column. `position: sticky;
   bottom: 0` keeps it pinned to the viewport bottom when scrolling a long
   article. Container is transparent — only the button cards have visible styling
   so the article behind the gap stays readable. */
.kb-prev-next {
    display: grid;
    /* minmax(0, 1fr) lets the columns shrink below their content's min-content
       width. Without the explicit 0 min, grid items default to min-content
       (the longest non-breaking title), pushing the bar wider than its parent
       and bleeding off the right edge of the viewport on narrow screens. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0.75rem;
    margin: auto 0 0;  /* margin-top: auto pushes to bottom of flex column */
    padding: 0;
    background: transparent;
    border: none;
    position: sticky;
    bottom: 0;
    z-index: 5;
    pointer-events: none; /* let clicks through the empty gap */
    flex-shrink: 0;
    /* Match the article's max-width so the bar aligns to the same right edge
       as paragraphs / code blocks / tables instead of sprawling to the full
       column width. */
    max-width: 1120px;
    width: 100%;
}

/* Re-enable clicks on the actual button cards */
.kb-prev-next > a,
.kb-prev-next > span {
    pointer-events: auto;
}

.kb-prev-next > a,
.kb-prev-next > span {
    display: block;
    padding: 0.55rem 1rem;
    border: 1px solid var(--kb-border);
    border-radius: 8px;
    background: var(--kb-surface);
    text-decoration: none;
    color: var(--kb-text-strong);
    transition: border-color 120ms ease, transform 120ms ease, background 120ms ease;
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
}

[data-theme="dark"] .kb-prev-next > a,
[data-theme="dark"] .kb-prev-next > span {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}

.kb-prev-next > a:hover {
    border-color: var(--kb-accent);
    background: var(--kb-surface-subtle);
    transform: translateY(-1px);
}

.kb-prev { text-align: left; }
.kb-next { text-align: right; }

.kb-prev-next-label {
    display: block;
    font-size: 0.7rem;
    color: var(--kb-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 0.05rem;
}

.kb-prev-next-title { display: block; font-weight: 600; }

/* Empty placeholder span (rendered when there's no prev or no next so the grid
   keeps two columns and the existing button stays on its side) — hide the
   styled box but keep the grid cell so the visible button doesn't reflow. */
.kb-prev-next > span:empty {
    visibility: hidden;
    pointer-events: none;
}

/* KB index / catalog */
.kb-index {
    max-width: 920px;
    margin: 0 auto;
    padding: 2rem 1.5rem 4rem;
    color: var(--kb-text);
}

.kb-index h1 {
    margin: 0 0 1.5rem;
    color: var(--kb-text-strong);
    font-size: 2rem;
    font-weight: 700;
}

.kb-category {
    margin-bottom: 2rem;
}

.kb-category h2 {
    font-size: 0.85rem;
    color: var(--kb-text-muted);
    margin: 0 0 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 600;
}

.kb-article-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 0.85rem;
}

.kb-article-list a {
    display: block;
    padding: 1rem 1.1rem;
    border: 1px solid var(--kb-border);
    border-radius: 8px;
    background: var(--kb-surface);
    color: var(--kb-text-strong);
    text-decoration: none;
    transition: border-color 120ms ease, transform 120ms ease, background 120ms ease;
}

.kb-article-list a:hover {
    border-color: var(--kb-accent);
    background: var(--kb-surface-subtle);
    transform: translateY(-1px);
}

/* Guide landing: prose sections, one per top-level entry. Each section is an H2
   linking to its destination, a paragraph of intro prose, and a "Read more" link.
   Mirrors the codec-guide section rhythm — flowing reading material rather than
   a TOC grid of cards. */
.kb-landing-section {
    margin: 1.5rem 0 2rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--kb-border);
}

.kb-landing-section:last-child {
    border-bottom: none;
    margin-bottom: 0;
}

.kb-landing-section h2 {
    margin-top: 0;
    margin-bottom: 0.5rem;
    padding-bottom: 0;
    border-bottom: none;
    font-size: 1.4rem;
}

.kb-landing-section h2 a {
    color: var(--kb-text-strong);
    border-bottom: none;
    text-decoration: none;
}

.kb-landing-section h2 a:hover {
    color: var(--kb-accent);
}

.kb-landing-section p {
    color: var(--kb-text);
    line-height: 1.65;
}

.kb-landing-section-link {
    margin-top: 0.4rem;
    margin-bottom: 0;
    font-size: 0.925rem;
}

.kb-landing-section-link a {
    color: var(--kb-link);
    border-bottom: none;
    font-weight: 500;
}

.kb-landing-section-link a:hover {
    color: var(--kb-link-hover);
    border-bottom: none;
}

/* Kept: used by the KB home page (/kb) to render guide/article cards. */
.kb-card-desc {
    display: block;
    color: var(--kb-text-muted);
    font-size: 0.875rem;
    font-weight: normal;
    margin-top: 0.35rem;
    line-height: 1.45;
}

/* =====================================================================
   MOBILE OVERRIDES — must come AFTER all base rules so they win the cascade.
   Don't move these earlier in the file.
   ===================================================================== */
@media (max-width: 900px) {
    /* Frame stops being a fixed-height clipped grid; becomes natural-height column
       flow so .kb-doc (which has overflow:auto from BlazorCommon's layout) becomes
       the scroll context for the whole KB page on mobile. */
    .kb-guide-frame {
        grid-template-columns: 1fr;
        grid-template-rows: auto auto;
        overflow: visible;
        height: auto;
    }

    /* Sidebar tree appears AFTER the article on mobile, with a clear visual break.
       No bottom-padding reservation now that the prev/next bar is native sticky
       inside the article column — the bar scrolls up off-screen with the article
       and the tree owns the full lower viewport when reached. */
    .kb-guide-sidebar-col {
        order: 2;
        max-height: none;
        overflow-y: visible;
        border-top: 1px solid var(--kb-border);
        margin-top: 1.5rem;
        /* Bottom padding clears the fixed prev/next bar so the last item in
           the sidebar tree is fully visible/scrollable instead of being
           covered by the bar. */
        padding: 1rem 0 calc(3.5rem + env(safe-area-inset-bottom) + 1rem);
    }

    /* Main column on mobile: block flow in body-scroll layout. Bottom padding
       reserves space for the position:fixed prev/next bar so the last bit of
       article content isn't hidden behind it. */
    .kb-doc .kb-guide-main {
        order: 1;
        overflow: visible !important;
        display: block;
        padding: 1rem 0 calc(3.5rem + env(safe-area-inset-bottom));
    }

    /* Prev/next on mobile: position:fixed at viewport bottom. The slide-up
       when sidebar enters viewport is handled by the CSS scroll-driven
       animation defined at the bottom of this file. */
    .kb-prev-next {
        position: fixed !important;
        left: 0 !important;
        right: 0 !important;
        bottom: 0 !important;
        top: auto !important;
        margin: 0 !important;
        padding: 0.5rem 1rem calc(env(safe-area-inset-bottom) + 0.5rem);
        gap: 0.5rem;
        max-width: none;
        background: transparent;
        z-index: 100;
    }

    /* Compact button cards: tighter padding, single-line title, no separate label row.
       Title gets the directional arrow inline so each button is just one row tall. */
    .kb-prev-next > a,
    .kb-prev-next > span {
        padding: 0.5rem 0.75rem;
        font-size: 0.85rem;
        line-height: 1.25;
    }
    .kb-prev-next .kb-prev-next-label {
        display: none;
    }
    .kb-prev-next .kb-prev-next-title {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .kb-prev .kb-prev-next-title::before {
        content: "← ";
        opacity: 0.7;
    }
    .kb-next .kb-prev-next-title::after {
        content: " →";
        opacity: 0.7;
    }

    /* Demo iframes on mobile: viewport-width-bounded with a height that fits
       the compact mobile layout each demo defines internally. Demos should
       size their own content to fit in roughly this envelope. */
    .kb-doc iframe {
        width: 100% !important;
        max-width: 100%;
        height: 460px !important;
    }

    /* Tables on mobile: scroll horizontally instead of overflowing the column
       or word-wrapping every cell into unreadable stacks. display:block makes
       the table itself a scrolling container; inner thead/tbody/tr/td keep
       their table-* display so column layout still works inside.
       border-radius dropped because it doesn't clip block-display elements. */
    .kb-article table {
        display: block;
        overflow-x: auto;
        border-radius: 0;
        max-width: 100%;
    }
    /* Headers stay on one line so column titles read cleanly; body cells wrap
       normally so long descriptions don't blow out table width. The combo
       gives users a reasonable width to scroll horizontally to see all columns
       without one cell making the table absurdly wide. */
    .kb-article thead th {
        white-space: nowrap;
    }
}

/* Base iframe behavior (desktop + mobile): never overflow the article column.
   Mobile-specific min-height lives in the @media block above. */
.kb-doc iframe {
    display: block;
    max-width: 100%;
}

/* Mobile prev/next slide-up — CSS scroll-driven animation.
   The bar is position:fixed bottom:0 (always at viewport bottom). As the
   sidebar tree enters the viewport from below, this animation translates the
   bar up by the same amount the sidebar has crossed in — so bar.bottom always
   equals sidebar.top. Pixel-perfect tracking on the compositor thread, no JS,
   no iOS scroll-event throttling. Supported on iOS Safari 17.5+, Chrome 115+,
   Edge 115+. On older browsers @supports gates it out and the bar just stays
   fixed (acceptable fallback — covers a bit of the sidebar tree at most). */
html {
    timeline-scope: --kb-bar-sidebar-tl;
}
@supports (animation-timeline: view()) {
    @media (max-width: 900px) {
        @keyframes kb-bar-track-sidebar {
            from { transform: translateY(0); }
            to { transform: translateY(-100vh); }
        }
        .kb-prev-next {
            animation: kb-bar-track-sidebar linear;
            animation-timeline: --kb-bar-sidebar-tl;
            /* entry-crossing spans the sidebar's leading edge crossing the
               viewport from bottom to top — viewport-height worth of scroll,
               during which translateY goes 0 -> -100vh in lockstep. */
            animation-range: entry-crossing 0% entry-crossing 100%;
        }
        .kb-guide-sidebar-col {
            view-timeline-name: --kb-bar-sidebar-tl;
        }
    }
}


