/* Islands skin for dashboard pages; legacy vars are remapped onto --jb-* tokens here, and jb-tokens.css flips them for the light theme. */

:root {
    --bg-base: var(--jb-bg-canvas);
    --bg-surface: var(--jb-bg-canvas);
    --bg-elevated: var(--jb-bg-raised);
    --bg-card: var(--jb-bg-inset);
    --solid-bg-card: var(--jb-bg-dialog);
    --glass-bg: var(--jb-bg-canvas);
    --glass-border: var(--jb-border);
    --accent: var(--jb-accent);
    --accent-hover: var(--jb-accent-hover);
    --accent-muted: color-mix(in srgb, var(--jb-accent) 15%, transparent);
    --accent-subtle: color-mix(in srgb, var(--jb-accent) 6%, transparent);
    --accent-glow: color-mix(in srgb, var(--jb-accent) 25%, transparent);
    --text-primary: var(--jb-fg);
    --text-secondary: var(--jb-fg-secondary);
    --text-tertiary: var(--jb-fg-secondary);
    --border: var(--jb-border);
    --border-subtle: var(--jb-border-island);
    --input-bg: var(--jb-bg-inset);
    --input-focus-bg: var(--jb-bg-inset);
    --input-focus-ring: transparent;
    --shadow-sm: none;
    --shadow-md: var(--jb-shadow-popup);
    --shadow-lg: var(--jb-shadow-dialog);
    --radius-sm: var(--jb-r-md);
    --radius-md: var(--jb-r-md);
    --radius-lg: var(--jb-r-panel);
    --sidebar-bg: var(--jb-bg-canvas);
    --sidebar-border: var(--jb-border);
    --sidebar-item-hover: var(--jb-bg-hover);
    --sidebar-item-active: var(--jb-bg-selected-muted);
    --sidebar-text-primary: var(--jb-fg);
    --sidebar-text-secondary: var(--jb-fg);
    --sidebar-text-tertiary: var(--jb-fg-secondary);
    --sidebar-compact-width: 56px;
    --duration-xfast: var(--jb-dur-in);
    --duration-fast: var(--jb-dur-in);
    --duration-normal: var(--jb-dur-out);
    --duration-slow: var(--jb-dur-out);
    --badge-approved: var(--jb-success);
    --badge-approved-bg: var(--jb-success-bg);
    --badge-vote: var(--jb-chart-2);
    --badge-vote-bg: color-mix(in srgb, var(--jb-chart-2) 18%, transparent);
    --badge-undenied: var(--jb-chart-5);
    --badge-undenied-bg: color-mix(in srgb, var(--jb-chart-5) 18%, transparent);
    --badge-feature: var(--jb-chart-1);
    --badge-feature-bg: color-mix(in srgb, var(--jb-chart-1) 18%, transparent);
    --badge-team: var(--jb-chart-1); /* indigo has no chart step; nearest by hex distance is chart-1 (blue), not chart-4 (purple) */
    --badge-team-bg: color-mix(in srgb, var(--jb-chart-1) 18%, transparent);
    --badge-comment: var(--jb-chart-4);
    --badge-comment-bg: color-mix(in srgb, var(--jb-chart-4) 18%, transparent);
    --badge-merged: var(--jb-chart-4);
    --badge-merged-bg: color-mix(in srgb, var(--jb-chart-4) 18%, transparent);
    --badge-denied: var(--jb-chart-7);
    --badge-denied-bg: color-mix(in srgb, var(--jb-chart-7) 18%, transparent);
    --badge-vote-removed: var(--jb-error);
    --badge-vote-removed-bg: var(--jb-error-bg);
    --badge-deleted: var(--jb-chart-3);
    --badge-deleted-bg: color-mix(in srgb, var(--jb-chart-3) 18%, transparent);
    --badge-unarchived: var(--jb-warning);
    --badge-unarchived-bg: var(--jb-warning-bg);
    --badge-moved: var(--jb-chart-6);
    --badge-moved-bg: color-mix(in srgb, var(--jb-chart-6) 18%, transparent);
    --badge-archived: var(--jb-chart-8);
    --badge-archived-bg: color-mix(in srgb, var(--jb-chart-8) 14%, transparent);
    --badge-view: var(--jb-chart-8);
    --badge-view-bg: color-mix(in srgb, var(--jb-chart-8) 14%, transparent);
    --error: var(--jb-error);
    --error-muted: var(--jb-error-bg);
    --warning: var(--jb-warning);
    --warning-muted: var(--jb-warning-bg);
    --success: var(--jb-success);
    --success-muted: var(--jb-success-bg);
    --scrollbar-thumb: var(--jb-border-control);
    --scrollbar-thumb-hover: var(--jb-border-raised);
    --gradient-glass: none;
    --gradient-subtle: none;
    --sidebar-width: var(--jb-sidebar-w);
    --info: var(--jb-accent); /* 15 of 23 call sites are load bearing status colour; jb-accent is nearest since JetBrains has no info hue */
    --info-muted: var(--jb-info-bg); /* the tint jb-tokens.css already built for modal-info-box and sample-banner */
    --space-1: var(--jb-sp-1);
    --space-2: var(--jb-sp-2);
    --space-3: var(--jb-sp-3);
    --space-4: var(--jb-sp-4);
    --space-5: var(--jb-sp-4); /* 20px sits equidistant between sp-4 (16) and sp-5 (24); sp-4 matches panel padding, this name's actual role */
    --space-6: var(--jb-sp-5);
    --space-8: var(--jb-sp-6);
    --space-10: var(--jb-sp-6); /* 40px sits equidistant between sp-6 (32) and sp-7 (48); sp-6 keeps the row as dense as every other row height in the file */
    --space-12: var(--jb-sp-7);
    --text-xs: var(--jb-t-1);
    --text-sm: var(--jb-t-3);
    --text-base: var(--jb-t-5);
    --text-lg: var(--jb-t-6);
    --text-xl: var(--jb-t-6); /* 20px is nearer t-6 (18, -2px) than t-7 (24, +4px); it labels a panel heading, not a page title */
}

html {
    scrollbar-gutter: stable;
}

body, button, input, select, textarea {
    font-family: var(--jb-font);
}

body {
    font-size: 13px;
}

h1, h2, h3, h4, h5, h6 {
    font-weight: 600;
}

:focus-visible {
    outline: 2px solid var(--jb-focus);
    outline-offset: -1px;
}
input:focus-visible, textarea:focus-visible, select:focus-visible {
    outline: 2px solid var(--jb-focus);
    outline-offset: -1px;
}

.sidebar {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
}

.main-content {
    border: none;
    box-shadow: none;
    /* bottom: clearance for the fixed status bar (--jb-h-control) plus a grid gap */
    padding: 0 var(--jb-sp-4) calc(var(--jb-h-control) + var(--jb-sp-4));
    overflow: visible;
}

.top-bar {
    height: 40px;
    margin-bottom: 16px;
    padding: 0;
    gap: 12px;
    position: sticky;
    top: 0;
    z-index: var(--jb-z-sticky);
    background: var(--jb-bg-toolbar);
    border-bottom: 1px solid var(--jb-border);
}
html.is-demo .top-bar {
    top: var(--demo-banner-h, 40px);
    /* The island gap under the demo strip is a slot the board scrolls through; paint it toolbar coloured. */
    box-shadow: 0 calc(-1 * var(--jb-island-gap)) 0 var(--jb-bg-toolbar);
}
/* The title shrinks rather than grows, so a count after it stays in the row; .top-bar-left holds the row open. */
.top-bar h1 {
    font-size: 13px;
    font-weight: 600;
    min-width: 0;
    flex: 0 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.top-bar svg {
    width: 20px;
    height: 20px;
}

.top-bar-right {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: none;
    margin-left: auto;
}
.toolbar-icon-btn {
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    display: grid;
    place-items: center;
    background: transparent;
    border: none;
    border-radius: var(--jb-r-lg);
    color: var(--jb-fg);
    cursor: default;
    text-decoration: none;
    transition: background-color var(--jb-dur-in) ease-out, color var(--jb-dur-in) ease-out;
}
.toolbar-icon-btn svg {
    width: 20px;
    height: 20px;
}
.toolbar-icon-btn:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.toolbar-icon-btn:active {
    background: var(--jb-bg-pressed);
}
.bulk-select-btn {
    background: transparent;
    border: none;
}
.bulk-select-btn.toolbar-icon-btn {
    box-sizing: border-box;
}
.bulk-select-btn:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.bulk-select-btn:active {
    background: var(--jb-bg-pressed);
}
.bulk-select-btn.active {
    background: var(--jb-bg-selected-muted);
    color: var(--jb-accent);
}
@media (pointer: coarse) {
    .toolbar-icon-btn,
    .toolbar-filter-toggle,
    .board-tab-add,
    .hamburger-btn,
    .roadmap-nav-btn {
        position: relative;
    }
    .toolbar-icon-btn::after,
    .toolbar-filter-toggle::after,
    .board-tab-add::after,
    .hamburger-btn::after,
    .roadmap-nav-btn::after {
        content: "";
        position: absolute;
        inset: -7px;
    }
}

.jb-tooltip {
    position: fixed;
    z-index: var(--jb-z-tooltip);
    background: var(--jb-bg-popup);
    border: 1px solid var(--jb-border);
    border-radius: var(--jb-r-sm);
    box-shadow: var(--jb-shadow-popup);
    padding: 12px 16px;
    max-width: 250px;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--jb-dur-tooltip) ease;
}
.jb-tooltip.visible { opacity: 1; }
.jb-tooltip strong {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--jb-fg);
}
.jb-tooltip span {
    display: block;
    font-size: 12px;
    color: var(--jb-fg-secondary);
    margin-top: 2px;
}

.button-group-button {
    height: var(--jb-h-control);
    padding: 0 8px;
    font-size: 13px;
    border-radius: var(--jb-r-md);
}
.button-group-button:hover { background-color: var(--jb-bg-hover); }

.top-bar-left {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
}
/* display:contents: Safari mis-measures this box's own intrinsic width whichever way it's asked for (auto, max-content, a fixed flex-basis), so the filter button always overflowed into the next toolbar icon. Removing the box lets its children flex directly inside .top-bar-right, where sizing is correct. Restored to a real flex box in the narrower layouts below, where it needs to size and wrap as one unit. */
.top-bar-tools {
    display: contents;
}
.toolbar-filters,
.top-bar-tools > .ob-open {
    flex-shrink: 0;
}
/* Safari older than 14.1 (still out there on customer machines) ignores flex gap entirely, so the search box and every toolbar button collapse edge to edge. */
@supports not (gap: 1px) {
    .top-bar-right > * + * { margin-left: 2px; }
    .top-bar-tools > * + * { margin-left: 8px; }
}
.top-bar-tools .toolbar-search {
    flex: 0 0 280px;
    max-width: 280px;
    height: 30px;
}
.board-tabs, .page-tabs {
    gap: 4px;
    padding: 0 0 3px;
    background: transparent;
    border: none;
    border-radius: 0;
    min-width: 0;
    max-width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    flex-wrap: nowrap;
    scrollbar-width: thin;
    scrollbar-color: var(--jb-alpha-w-40) transparent;
}
.board-tabs::-webkit-scrollbar, .page-tabs::-webkit-scrollbar { height: 3px; }
.board-tabs::-webkit-scrollbar-track, .page-tabs::-webkit-scrollbar-track { background: transparent; }
.board-tabs::-webkit-scrollbar-thumb, .page-tabs::-webkit-scrollbar-thumb { background: var(--jb-alpha-w-40); border-radius: 0; }
.board-tabs::-webkit-scrollbar-thumb:hover, .page-tabs::-webkit-scrollbar-thumb:hover { background: var(--jb-alpha-w-50); }
/* A tab strip in the top bar is already spaced by the bar, and the extra 16px would break a 40px row. */
.page-tabs {
    margin-bottom: 16px;
}
.top-bar-left .page-tabs {
    margin-bottom: 0;
}
.board-tab, .page-tab {
    flex: 0 0 auto;
    height: var(--jb-tab-pill-h);
    padding: 0 12px;
    border-radius: var(--jb-r-lg);
    font-size: 13px;
    font-weight: var(--jb-w-normal);
    color: var(--jb-fg-secondary);
    opacity: 0.75;
    background: transparent;
    box-shadow: none;
    transition: background-color var(--jb-dur-in) ease-out, opacity var(--jb-dur-in) ease-out;
}
.board-tab:hover, .page-tab:hover {
    opacity: 1;
    color: var(--jb-fg);
    background: var(--jb-tab-hover-bg);
}
.board-tab.active, .page-tab.active {
    opacity: 1;
    color: var(--jb-fg);
    font-weight: var(--jb-w-normal);
    background: var(--jb-tab-selected-bg);
    box-shadow: inset 0 0 0 1px var(--jb-tab-selected-border);
}
.board-tab-add {
    width: 28px;
    height: 28px;
    padding: 0;
    display: grid;
    place-items: center;
    border-radius: var(--jb-r-lg);
    border: none;
    background: transparent;
    color: var(--jb-fg-icon);
    font-size: 16px;
    flex-shrink: 0;
    transition: background-color var(--jb-dur-in) ease-out, color var(--jb-dur-in) ease-out;
}
.board-tab-add:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
    border-color: transparent;
}
.board-tab-add:active {
    background: var(--jb-bg-pressed);
}
.board-tab-upgrade {
    height: var(--jb-tab-pill-h);
    padding: 0 12px;
    border-radius: var(--jb-r-lg);
    border: none;
    background: transparent;
    color: var(--jb-link);
    font-size: 12px;
    font-weight: var(--jb-w-normal);
}
.board-tab-upgrade:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-link);
}

/* The admin gate pages carry this pair and load no other sheet, so the swap lives here rather than in inner-index.css. */
.logo-icon {
    width: 26px;
    height: 26px;
    border-radius: var(--radius-lg);
    object-fit: cover;
}

.logo-light {
    display: none;
}

[data-theme="light"] .logo-dark {
    display: none;
}

/* Inline, not block: the gate card centres its contents with text-align, which only reaches a line of text. */
[data-theme="light"] .logo-light {
    display: inline;
}

.sidebar-logo {
    height: 40px;
    min-height: 40px;
    padding: 0 16px 0 20px;
    border-bottom: none;
    margin-bottom: 0;
}
.sidebar-logo .logo-text {
    font-size: 13px;
    font-weight: var(--jb-w-medium);
    letter-spacing: normal;
    color: var(--jb-fg);
}
.sidebar-project-switcher {
    padding: 2px 0;
    border-bottom: none;
    margin-bottom: 2px;
}

.nav-item {
    height: 24px;
    padding: 0 12px;
    margin: 0 8px;
    border-radius: var(--jb-r-md);
    gap: 8px;
    font-size: 13px;
}
.nav-item.active {
    font-weight: var(--jb-w-normal);
}
.nav-item .nav-icon,
.nav-item:hover .nav-icon,
.nav-item.active .nav-icon { color: inherit; }
.nav-item .nav-label { line-height: 16px; }
/* How many things are waiting on this entry, filled rather than tinted so it survives the 56px rail, and always red. */
.nav-badge {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 18px;
    min-width: 18px;
    padding: 0 6px;
    border-radius: var(--jb-r-md);
    background: var(--jb-count-danger);
    color: var(--jb-fg-on-accent);
    font-size: 11px;
    font-weight: var(--jb-w-medium);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}
/* On a 56px rail the count rides the icon's corner, absolute and hung into the gutter so the icon stays recognisable. */
@media (min-width: 769px) {
    [data-sidebar="compact"] .nav-item { position: relative; }
    [data-sidebar="compact"] .nav-badge {
        position: absolute;
        top: -2px;
        right: -6px;
        height: 16px;
        min-width: 16px;
        padding: 0 4px;
        z-index: 1;
    }
}
.sidebar-tooltip { display: none !important; }

.nav-section-label {
    padding: 0;
    margin: 16px 20px 4px;
}
.nav-section-text {
    font-size: 11px;
    font-weight: var(--jb-w-medium);
    text-transform: none;
    letter-spacing: normal;
    color: var(--jb-fg-tertiary);
}

.project-switcher-trigger {
    height: 28px;
    width: calc(100% - 16px);
    /* border-compensated: 1px border + this padding renders --jb-sp-3 */
    padding: 0 calc(var(--jb-sp-3) - 1px);
    margin: 0 8px;
    gap: 8px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--jb-r-md);
    font-size: 13px;
    font-weight: var(--jb-w-semi);
    color: var(--jb-fg);
}
.project-trigger-name {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: left;
}
.sidebar-logo .logo-icon {
    display: none;
}
.project-item-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 18px;
    height: 18px;
    border-radius: var(--jb-r-sm);
    background: var(--jb-bg-selected-muted) !important;
    color: var(--jb-fg);
    font-size: 11px;
    font-weight: var(--jb-w-medium);
}
.project-switcher-trigger .project-chevron-icon {
    margin-left: auto;
}
.project-switcher-trigger .project-item-avatar {
    width: 20px;
    height: 20px;
    background: var(--jb-accent) !important;
    color: var(--jb-fg-on-accent);
    font-weight: var(--jb-w-semi);
}
.project-switcher-trigger:hover {
    background: var(--jb-bg-hover);
    border-color: transparent;
}
.project-chevron-icon {
    width: 16px;
    height: 16px;
    stroke-width: 1.5;
    color: var(--jb-fg-icon);
}
.sidebar-collapse-btn {
    background: transparent;
    border: none;
    border-radius: var(--jb-r-md);
    color: var(--jb-fg-icon);
}
.sidebar-collapse-btn:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.sidebar-collapse-btn svg {
    width: 16px;
    height: 16px;
    stroke-width: 1.5;
}
.project-switcher-dropdown {
    background: var(--jb-layer-2);
    border: 1px solid var(--jb-border);
    border-radius: var(--jb-r-md);
    box-shadow: var(--jb-shadow-dialog);
    padding: 6px;
    gap: 2px;
}
.project-switcher-dropdown .project-search-input {
    height: 28px;
    padding: 0 8px;
    margin-bottom: 6px;
    font-size: 13px;
    font-family: var(--jb-font);
    background: var(--jb-bg-inset);
    border: 1px solid var(--jb-border-control);
    border-radius: var(--jb-r-md);
    color: var(--jb-fg);
}
.project-switcher-dropdown .project-search-input:focus {
    border-color: var(--jb-focus);
    background: var(--jb-bg-inset);
}
:root:not([data-theme="light"]) .project-switcher-dropdown .project-search-input:not(:focus) {
    border-color: transparent;
}
.project-switcher-dropdown .project-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.project-switcher-dropdown .project-list-item {
    height: 24px;
    padding: 0 8px;
    font-size: 13px;
    border-radius: var(--jb-r-md);
    color: var(--jb-fg);
}
.project-switcher-dropdown .project-list-item:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.project-switcher-dropdown .project-list-item.active {
    background: var(--jb-bg-selected-muted);
    color: var(--jb-fg);
    font-weight: var(--jb-w-medium);
}
.project-switcher-dropdown .project-switcher-divider {
    display: none;
}
.project-switcher-dropdown .project-create-link {
    height: 24px;
    padding: 0 8px;
    font-size: 13px;
    border-radius: var(--jb-r-md);
    color: var(--jb-fg-secondary);
    margin-top: 6px;
}
.project-switcher-dropdown .project-create-link:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}

.sidebar-footer-item {
    height: 24px;
    padding: 0 12px;
    margin: 0 8px;
    border-radius: var(--jb-r-md);
    gap: 8px;
    font-size: 13px;
}
.sidebar-user {
    height: 24px;
    padding: 0 12px;
    margin: 0 8px;
    border-radius: var(--jb-r-md);
    gap: 8px;
}

/* The signed in user's initial, tinted from their name by the markup so the circle is finished in the first frame. */
.sidebar-user-avatar {
    background: color-mix(in srgb, var(--avatar-color, var(--jb-fg-secondary)) 24%, transparent);
    color: var(--avatar-color, var(--jb-fg));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--avatar-color, var(--jb-fg-secondary)) 45%, transparent);
    font-weight: var(--jb-w-medium);
    user-select: none;
}

/* Only the inactive half of the theme control is hidden, so the label follows whatever the sidebar or toolbar already says. */
html:not([data-theme="light"]) .theme-icon-moon,
html:not([data-theme="light"]) .theme-label-dark,
html[data-theme="light"] .theme-icon-sun,
html[data-theme="light"] .theme-label-light {
    display: none;
}

@media (min-width: 769px) {
    /* The footer sits where the script will move it, so a browser painting before the script runs shows no jump. */
    .sidebar-footer {
        position: fixed;
        top: 0;
        right: var(--jb-sp-4);
        left: auto;
        z-index: var(--jb-z-sticky);
        height: 40px;
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: 2px;
        padding: 0 8px;
        margin: 0;
        border: none;
        background: var(--jb-bg-toolbar);
    }
    html.is-demo .sidebar-footer {
        top: var(--demo-banner-h, 40px);
    }
    .sidebar-footer .nav-label,
    .sidebar-footer .sidebar-user-name {
        display: none;
    }
    .sidebar-footer .sidebar-footer-item,
    .sidebar-footer .sidebar-user {
        width: 30px;
        height: 30px;
        padding: 0;
        margin: 0;
        gap: 0;
        justify-content: center;
        border-radius: var(--jb-r-lg);
    }
    .sidebar-footer .sidebar-footer-item:hover,
    .sidebar-footer .sidebar-user:hover {
        background: var(--jb-bg-hover);
    }
    .sidebar-footer .sidebar-footer-item:active,
    .sidebar-footer .sidebar-user:active {
        background: var(--jb-bg-pressed);
    }
    .sidebar-footer .sidebar-user-avatar {
        width: 20px;
        height: 20px;
    }
    .top-bar > .sidebar-footer {
        position: static;
        top: auto;
        right: auto;
        left: auto;
        z-index: auto;
        height: 40px;
        margin: 0 0 0 24px;
        border: none;
        background: transparent;
    }
    .top-bar .sidebar-footer-item,
    .top-bar .sidebar-user,
    .top-bar .sidebar-upgrade {
        color: var(--jb-fg);
    }
    .top-bar .sidebar-footer-item:hover,
    .top-bar .sidebar-user:hover,
    .top-bar .sidebar-logout:hover {
        color: var(--jb-fg);
        background: var(--jb-bg-hover);
    }
    .top-bar .sidebar-footer svg {
        width: 20px;
        height: 20px;
        stroke-width: 1.5;
    }
}

/* Tablet 769 to 1100: two 40px rows, tabs with the user cluster then search and filters, placed after the min-769 block. */
@media (min-width: 769px) and (max-width: 1100px) {
    .top-bar {
        flex-wrap: wrap;
        height: auto;
        min-height: 80px;
        padding: 0;
        column-gap: 8px;
        row-gap: 0;
        align-items: center;
    }
    .top-bar-left {
        order: 1;
        flex: 1 1 240px;
        min-width: 0;
        height: 40px;
        display: flex;
        align-items: center;
    }
    .top-bar > .sidebar-footer {
        order: 2;
        flex: none;
        height: 40px;
        margin: 0;
    }
    .top-bar-right {
        order: 3;
        flex: 1 1 100%;
        min-width: 0;
        height: 40px;
        margin-left: 0;
        border-top: 1px solid var(--jb-border);
    }
    .top-bar-tools {
        display: flex;
        align-items: center;
        gap: 8px;
        flex: 1 1 auto;
        min-width: 0;
    }
    .top-bar-tools .toolbar-search {
        flex: 1 1 auto;
        min-width: 0;
        max-width: none;
    }
}

@media (min-width: 769px) {
    [data-sidebar="compact"] .nav-item,
    [data-sidebar="compact"] .project-switcher-trigger {
        width: 32px;
        height: 32px;
        padding: 0;
        margin: 0 auto;
        gap: 0;
        justify-content: center;
        border-radius: var(--jb-r-md);
    }
}
[data-sidebar="compact"] .nav-item .nav-icon {
    width: 24px;
    height: 24px;
}
[data-sidebar="compact"] .sidebar-collapse-btn svg {
    width: 24px;
    height: 24px;
    transform: none;
}
[data-sidebar="compact"] .project-switcher-trigger .project-item-avatar {
    width: 24px;
    height: 24px;
}

/* Below 1200px the sidebar is compact regardless, so the collapse button and the header row that holds it both go. */
@media (max-width: 1200px) {
    .sidebar-logo { display: none; }
}
/* With that row gone the project avatar squares the rail off, centred in a band the height of the top bar. */
@media (min-width: 769px) and (max-width: 1200px) {
    .sidebar-project-switcher {
        display: grid;
        place-items: center;
        height: 40px;
        padding: 0;
        margin: 0;
    }
}

.sidebar-spacer { order: 1; }
.sidebar-footer { order: 3; }

.toolbar-search {
    height: var(--jb-h-control);
    background: var(--jb-bg-island);
    border: 1px solid var(--jb-border-control);
    border-radius: var(--jb-r-md);
    font-size: 13px;
    /* border-compensated: 1px border + this padding renders --jb-sp-3, matching the switcher trigger's inset */
    padding: 0 calc(var(--jb-sp-3) - 1px);
    max-width: 280px;
}
.toolbar-search-icon[fill="none"] {
    fill: none;
    color: var(--jb-fg);
    width: 20px;
    height: 20px;
}
.toolbar-input::placeholder {
    color: var(--jb-fg-secondary);
}
.toolbar-search:focus-within {
    border-color: transparent;
    box-shadow: none;
    outline: 2px solid var(--jb-focus);
    outline-offset: -1px;
}
.toolbar-input { font-size: 13px; }
.toolbar-input:focus-visible { outline: none; }
.toolbar-search-kbd {
    background: var(--jb-bg-inset);
    border: 1px solid var(--jb-border);
    border-radius: var(--jb-r-sm);
    color: var(--jb-fg-secondary);
}

.toolbar-filter-toggle {
    width: 30px;
    height: 30px;
    padding: 0;
    display: grid;
    place-items: center;
    background: transparent;
    border: none;
    border-radius: var(--jb-r-lg);
    color: var(--jb-fg-icon);
    cursor: default;
    position: relative;
}
.toolbar-filter-toggle:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.toolbar-filter-toggle:active {
    background: var(--jb-bg-pressed);
}
.toolbar-filter-toggle.active {
    background: transparent;
    color: var(--jb-accent);
}
.toolbar-filter-toggle.active:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.toolbar-filter-toggle.active:active {
    background: var(--jb-bg-pressed);
}
.toolbar-filter-toggle svg {
    width: 20px;
    height: 20px;
}
.toolbar-filter-toggle .filter-active-dot {
    position: absolute;
    top: 4px;
    right: 4px;
}

.toolbar-filter-popover {
    background: var(--jb-bg-popup);
    border: 1px solid var(--jb-border);
    border-radius: var(--jb-r-md);
    box-shadow: var(--jb-shadow-popup);
    padding: 12px;
    transform: none;
    transition: opacity var(--jb-dur-in) ease-out, visibility var(--jb-dur-in) ease-out;
}
.toolbar-filter-popover.active {
    transform: none;
}
.filter-popover-link {
    height: 24px;
    padding: 0 8px;
    border-radius: var(--jb-r-md);
    color: var(--jb-link);
}
.filter-popover-link:hover {
    background: var(--jb-bg-hover);
    text-decoration: none;
}
.toolbar-select {
    height: var(--jb-h-control);
    font-size: 13px;
    border-radius: var(--jb-r-md);
    background-color: var(--jb-bg-inset);
    border: 1px solid var(--jb-border-control);
}
.toolbar-select:hover {
    border-color: var(--jb-border-raised);
}
.toolbar-select:active {
    background-color: var(--jb-bg-pressed);
}

.roadmap-container {
    gap: var(--jb-island-gap);
    margin-top: 16px;
}

/* Getting started: the steps that make the sample board theirs, in the same drawer as the card guide. */
.gs-panel {
    z-index: var(--jb-z-dialog);
}
.gs-welcome {
    margin: 0 0 var(--jb-sp-4);
    font-size: var(--jb-t-4);
    line-height: var(--jb-lh-prose);
    color: var(--jb-fg);
}
.ob-progress {
    margin: 0 0 var(--jb-sp-5);
}
.ob-steps {
    display: grid;
    gap: var(--jb-sp-4);
    margin: 0;
    padding: 0;
    list-style: none;
}
.ob-step {
    display: grid;
    grid-template-columns: 16px minmax(0, 1fr) 72px;
    gap: var(--jb-sp-3);
    align-items: start;
}
.ob-step-mark {
    width: 16px;
    height: 16px;
    margin-top: 2px;
    border: 1.5px solid var(--jb-fg-tertiary);
    border-radius: 50%;
}
.ob-step--done .ob-step-mark {
    border-color: var(--jb-success);
    background: var(--jb-success);
}
.ob-step h3 {
    margin: 0;
    font-size: var(--jb-t-3);
    font-weight: var(--jb-w-medium);
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg);
}
.ob-step--done h3 {
    color: var(--jb-fg-tertiary);
    text-decoration: line-through;
}
.ob-step p {
    margin: 2px 0 0;
    font-size: var(--jb-t-2);
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-secondary);
}
.ob-step .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: center;
    width: 100%;
    min-width: 0;
    padding: 0;
}
.ob-steps-foot {
    margin: var(--jb-sp-5) 0 0;
    text-align: center;
}
.ob-steps-hide {
    padding: 0;
    background: none;
    border: 0;
    font: inherit;
    font-size: var(--jb-t-2);
    color: var(--jb-fg-tertiary);
    cursor: pointer;
}
.ob-steps-hide:hover {
    color: var(--jb-fg-secondary);
}
/* Sample data notice: an editor notification panel, tinted and separated by a hairline, sharing the radius of the islands above. */
.sample-banner {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-4);
    /* It owns the gap on both sides like an island, or it sits flat against whatever follows it. */
    margin-top: 16px;
    margin-bottom: 16px;
    padding: var(--jb-sp-2) var(--jb-sp-2) var(--jb-sp-2) var(--jb-sp-3);
    background: var(--jb-info-bg);
    border: 1px solid var(--jb-info-border);
    border-radius: var(--jb-r-panel);
}
/* Last in its container it needs no gap under it; the container's own padding is already there. */
.sample-banner:last-child { margin-bottom: 0; }
.sample-banner-text {
    flex: 1;
    margin: 0;
    font-size: 13px;
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-secondary);
}
.sample-banner-text strong {
    font-weight: var(--jb-w-semi);
    color: var(--jb-fg);
}
.sample-banner .btn {
    flex-shrink: 0;
}
/* The same strip in the warning tokens, because a security notice is a warning rather than information. */
.sample-banner--warn {
    background: var(--jb-warning-bg);
    border-color: var(--jb-warning-border);
}
@media (max-width: 640px) {
    .sample-banner {
        align-items: stretch;
        flex-direction: column;
        gap: var(--jb-sp-2);
    }
}

/* A generic skeleton vocabulary for rows, cards and panels; the stack owns the rhythm so no block carries a margin. */
.skeleton-stack {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.skeleton-stack.loose {
    gap: 16px;
}
.skeleton-block {
    width: 100%;
    height: 32px;
    margin: 0;
    border-radius: var(--jb-r-md);
}
.skeleton-text { height: 20px; }
.skeleton-title { height: 24px; }
.skeleton-control { height: 28px; }
.skeleton-row { height: 44px; }
.skeleton-card { height: 48px; }
.skeleton-panel { height: 96px; }
.skeleton-block.short { width: 60%; }
.skeleton-block.narrow { width: 35%; }
.skeleton-block.quarter { width: 25%; }
/* inner-index.css forces height on .skeleton-block.short at equal specificity, so this combination needs a three class rule to win. */
.skeleton-block.short.skeleton-text { height: 20px; }

/* An empty board is an island with centred text, not an illustration. */
.ob-empty-state {
    /* Fills the space under the top bar rather than stopping at the text, minus the bar, gaps and margins. */
    min-height: calc(100vh - var(--jb-toolbar-h) - var(--jb-sp-4) - var(--jb-sp-3) - var(--jb-island-gap));
    margin-top: 16px;
    padding: 48px 24px;
    background: var(--jb-bg-island);
    border: 1px solid var(--jb-border-island);
    border-radius: var(--jb-r-panel);
}
.ob-empty-message { gap: 0; }
.ob-empty-state h3 {
    margin: 0 0 6px;
    font-size: 16px;
    font-weight: var(--jb-w-semi);
    color: var(--jb-fg);
}
.ob-empty-state p {
    margin: 0 0 16px;
    max-width: 46ch;
    font-size: 13px;
    line-height: var(--jb-lh-prose);
    color: var(--jb-fg-secondary);
}
.ob-empty-hint {
    margin-top: 12px;
    font-size: 12px;
    color: var(--jb-fg-tertiary);
    opacity: 1;
}

/* The island surface, defined once: every page's primary content sits on one, with no shadow and the gap doing the separating. */
.jb-island {
    background: var(--jb-bg-island);
    border: 1px solid var(--jb-border-island);
    border-radius: var(--jb-r-panel);
}

/* Columns are lanes, so a board grows to the bottom of the window from the layout rather than a viewport calculation. */
.main-content:has(> .roadmap-scroll-wrapper) {
    display: flex;
    flex-direction: column;
}
.roadmap-scroll-wrapper {
    flex: 1;
    display: flex;
    flex-direction: column;
}
.roadmap-container { flex: 1; }

.kanban-column {
    background: var(--jb-bg-island);
    border: 1px solid var(--jb-border-island);
    border-radius: var(--jb-r-panel);
    padding: 12px 8px;
}
.kanban-column:not(:last-child)::after { display: none; }
.kanban-column.drag-over {
    background: var(--jb-bg-island);
    box-shadow: inset 0 0 0 1px var(--jb-focus);
}

.column-header {
    margin-bottom: 0;
    min-height: 32px;
    padding: 4px 4px 8px 8px;
}
.column-status-dot { display: none; }
.column-count,
.section-count {
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    background: var(--jb-bg-inset);
    border-radius: var(--jb-r-sm);
    font-size: 11px;
    color: var(--jb-fg-secondary);
}

.column-header-actions {
    gap: var(--jb-sp-1);
}
.column-action-btn:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.column-action-btn.delete-column-btn:hover {
    background: var(--jb-error-bg);
    color: var(--jb-error);
}

.column-content { gap: var(--jb-sp-2); }
.column-content,
.detail-panel-body,
/* The code block a new key is shown in gets the same scrollbar as everything else in the drawer. */
.share-code-block pre,
/* inner-index declares smooth scrolling universally, so page and tree changes are set back to instant here. */
.jbs-tree,
.jbs-content-body {
    scroll-behavior: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--jb-alpha-w-40) transparent;
}
.column-content::-webkit-scrollbar,
.detail-panel-body::-webkit-scrollbar,
.share-code-block pre::-webkit-scrollbar,
.jbs-tree::-webkit-scrollbar,
.jbs-content-body::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}
.column-content::-webkit-scrollbar-track,
.detail-panel-body::-webkit-scrollbar-track,
.share-code-block pre::-webkit-scrollbar-track,
.jbs-tree::-webkit-scrollbar-track,
.jbs-content-body::-webkit-scrollbar-track {
    background: transparent;
}
.column-content::-webkit-scrollbar-thumb,
.detail-panel-body::-webkit-scrollbar-thumb,
.share-code-block pre::-webkit-scrollbar-thumb,
.jbs-tree::-webkit-scrollbar-thumb,
.jbs-content-body::-webkit-scrollbar-thumb {
    background: var(--jb-alpha-w-40);
    border-radius: 0;
}
.column-content::-webkit-scrollbar-thumb:hover,
.detail-panel-body::-webkit-scrollbar-thumb:hover,
.share-code-block pre::-webkit-scrollbar-thumb:hover,
.jbs-tree::-webkit-scrollbar-thumb:hover,
.jbs-content-body::-webkit-scrollbar-thumb:hover {
    background: var(--jb-alpha-w-50);
}

.feature-card-roadmap {
    background: var(--jb-bg-raised);
    border: 1px solid var(--jb-border-control);
    border-radius: var(--jb-r-md);
    padding: var(--jb-sp-3) var(--jb-sp-4);
    box-shadow: none;
    transition: background-color var(--jb-dur-in) ease, border-color var(--jb-dur-in) ease;
}
.feature-card-roadmap:hover {
    border-color: var(--jb-border-raised);
    background: var(--jb-bg-hover);
    box-shadow: none;
    transform: none;
    z-index: 5;
}
.feature-card-roadmap.dragging {
    box-shadow: var(--jb-shadow-popup);
    border-color: var(--jb-accent);
    transform: none;
}
.feature-card-roadmap.denied {
    background: color-mix(in srgb, var(--jb-syntax-error) 8%, var(--jb-bg-raised));
    border-color: var(--jb-border-control);
}
.feature-card-roadmap.denied:hover {
    background: color-mix(in srgb, var(--jb-syntax-error) 12%, var(--jb-bg-hover));
    border-color: var(--jb-border-raised);
    box-shadow: none;
}
/* The developer response block, defined once here, with the denied case as a modifier rather than a second definition. */
.dev-response {
    margin-top: var(--jb-sp-3);
    margin-bottom: var(--jb-sp-2);
}
.dev-response-label {
    color: var(--jb-accent);
    font-size: 11px;
    font-weight: var(--jb-w-semi);
}
.dev-response--denied .dev-response-label {
    color: var(--jb-syntax-error);
}
.dev-response-text {
    color: var(--jb-fg-secondary);
    font-size: 12px;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* The heading and its two hover actions share one 24px row, so the legacy title's bottom margin goes. */
.feature-card-header {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 24px;
    margin-bottom: 6px;
}
.feature-card-title {
    font-size: 13px;
    font-weight: var(--jb-w-medium);
    flex: 1;
    min-width: 0;
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.feature-card-tags:not(:has(.feature-tag)) {
    display: none;
}
.feature-card-header-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    flex-shrink: 0;
    margin-left: auto;
}
.card-description {
    font-size: 12px;
    color: var(--jb-fg-secondary);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.feature-card-meta {
    border-top: none;
    padding-top: 8px;
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: space-between;
    gap: var(--jb-sp-2);
    align-items: center;
    font-size: 13px;
    color: var(--jb-fg-tertiary);
}
.feature-card-left {
    display: flex;
    flex-wrap: nowrap;
    gap: var(--jb-sp-2);
    align-items: center;
    min-width: 0;
}
.feature-card-roadmap:has(> .feature-card-tags .feature-tag) {
    margin-top: 14px;
}
.feature-card-tags {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--jb-sp-1);
    margin: -23px 0 5px;
}
.feature-card-tags > .feature-tag {
    height: 24px;
    padding: 0 10px;
    font-size: 13px;
    font-weight: var(--jb-w-medium);
    border-radius: var(--jb-r-sm);
    background: color-mix(in srgb, var(--tag-color, var(--jb-fg-tertiary)) 20%, var(--jb-bg-raised));
    color: var(--tag-color, var(--jb-fg-tertiary));
    border: 1px solid color-mix(in srgb, var(--tag-color, var(--jb-fg-tertiary)) 45%, var(--jb-border-control));
    border-bottom: 1px solid color-mix(in srgb, var(--tag-color, var(--jb-fg-tertiary)) 45%, var(--jb-border-control));
    cursor: pointer;
}
.feature-card-tags > .feature-tag.tag-filter-active {
    background: color-mix(in srgb, var(--tag-color, var(--jb-fg-tertiary)) 34%, var(--jb-bg-raised));
    border-color: var(--tag-color, var(--jb-fg-tertiary));
}
/* Revenue leads the chip row in the app's money green, and is a fact rather than a filter, so it is not clickable. */
.feature-card-tags > .feature-tag--mrr {
    --tag-color: var(--jb-success);
    cursor: default;
}
/* The paying count follows the revenue figure with its word, or a bare number reads as a second vote total. */
.feature-tag--mrr {
    gap: var(--jb-sp-1);
}
.feature-tag--mrr .mrr-from {
    opacity: 0.7;
}
.feature-tag--mrr .vote-icon {
    width: 11px;
    height: 11px;
}
.feature-tag {
    border-radius: var(--jb-r-sm);
    font-size: 13px;
    font-weight: var(--jb-w-medium);
}
.feature-tag {
    display: inline-flex;
    align-items: center;
    height: 22px;
    padding: 0 8px;
    border: none;
    border-radius: var(--jb-r-sm);
    font-size: 13px;
    background: color-mix(in srgb, var(--tag-color, var(--jb-fg-tertiary)) 22%, transparent);
    color: var(--tag-color, var(--jb-fg-tertiary));
}
.feature-tag:focus-visible {
    outline: 2px solid var(--jb-focus);
    outline-offset: -1px;
}
.detail-panel-tags .detail-tag {
    min-height: 0;
    height: 20px;
    padding: 0 6px;
    gap: 4px;
    border: none;
    border-radius: var(--jb-r-sm);
    font-size: 11px;
    font-weight: var(--jb-w-medium);
    background: color-mix(in srgb, var(--tag-color, var(--jb-fg-tertiary)) 22%, transparent);
    color: var(--tag-color, var(--jb-fg-tertiary));
}
.detail-panel-tags .detail-tag-date {
    background: color-mix(in srgb, var(--jb-syntax-constant) 15%, transparent);
    color: var(--jb-syntax-constant);
}
.detail-panel-tags .detail-tag-date.overdue {
    background: color-mix(in srgb, var(--jb-syntax-error) 15%, transparent);
    color: var(--jb-syntax-error);
    border: none;
}
/* A mark rather than a chip, so it does not read as a third thing to click and costs the line eleven pixels. */
.feature-tag-date {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    margin-bottom: var(--jb-sp-1);
    padding: 0;
    background: none;
    color: var(--jb-syntax-constant);
    font-size: var(--jb-t-1);
    font-weight: var(--jb-w-medium);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    flex-shrink: 0;
}
.feature-tag-date svg {
    width: 11px;
    height: 11px;
}
.feature-tag-date.overdue {
    color: var(--jb-error);
}
.feature-card-votes,
.card-score-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--jb-sp-1);
    height: 22px;
    padding: 0 6px;
    font-size: 13px;
    font-weight: var(--jb-w-medium);
    border-radius: var(--jb-r-sm);
}
.card-score-badge svg,
.feature-card-votes .vote-icon {
    width: 14px;
    height: 14px;
}
.feature-card-votes {
    color: var(--jb-syntax-number);
    background: color-mix(in srgb, var(--jb-syntax-number) 22%, transparent);
}
.card-score-badge-comments {
    color: var(--jb-syntax-string);
    background: color-mix(in srgb, var(--jb-syntax-string) 22%, transparent);
}
.card-score-badge-demand {
    color: var(--jb-syntax-metadata);
    background: color-mix(in srgb, var(--jb-syntax-metadata) 22%, transparent);
}
.card-score-badge-priority {
    color: var(--jb-syntax-keyword);
    background: color-mix(in srgb, var(--jb-syntax-keyword) 22%, transparent);
}
.card-score-badge-effort {
    color: var(--jb-syntax-string);
    background: color-mix(in srgb, var(--jb-syntax-string) 22%, transparent);
    font-variant-numeric: normal;
}
.feature-card-right {
    display: flex;
    flex-wrap: nowrap;
    gap: var(--jb-sp-2);
    align-items: center;
    margin-left: auto;
}
.feature-card-votes,
.card-score-badge-comments {
    color: var(--jb-fg-secondary);
    background: transparent;
}
/* On a card the two numbers a board is read for carry the heading's weight; in the drawer they match the readout. */
.card-metric .feature-card-votes,
.card-metric .card-score-badge-comments {
    color: var(--jb-fg);
    padding: 0;
}
/* A number and its annotating count are one thing, two pixels apart, so the pair reads as one number with a mark. */
.card-metric {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    min-width: 0;
}
.card-metric:not(:has(*)) {
    display: none;
}
/* The count is a mark on the number it annotates, the same blue in the drawer as on the card. */
.count-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    font-size: 13px;
    font-weight: var(--jb-w-semi);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}
/* It rides above the number like a footnote mark, a step smaller, so neither number covers the other. */
.card-metric .count-dot {
    align-self: flex-start;
    font-size: 11px;
}
.count-dot--weighted {
    color: var(--jb-count-accent-tint);
}
.count-dot--new {
    color: var(--jb-count-danger-tint);
}

.feature-card-new {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    min-height: 32px !important;
    max-height: 32px !important;
    padding: 0 8px !important;
    border: 1px solid var(--jb-border-control);
    border-radius: var(--jb-r-md);
    background: transparent;
    box-shadow: none;
    transition: background-color var(--jb-dur-in) ease-out, border-color var(--jb-dur-in) ease-out;
}
.feature-card-new:hover {
    background: var(--jb-bg-hover);
    border-color: var(--jb-border-raised);
    transform: none;
    box-shadow: none;
}
.feature-card-new-content {
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    width: auto;
    gap: 8px;
    text-align: left;
}
.plus-icon-feature {
    width: 16px;
    height: 16px;
    margin-bottom: 0;
    background: transparent;
    color: var(--jb-fg-icon);
    border-radius: var(--jb-r-sm);
}
.plus-icon-feature svg {
    width: 16px;
    height: 16px;
}
.feature-card-new:hover .plus-icon-feature {
    transform: none;
    background: transparent;
    color: var(--jb-fg);
}
.feature-card-new-content h3 {
    font-size: 12px;
    font-weight: var(--jb-w-normal);
    color: var(--jb-fg-secondary);
}
.feature-card-new:hover .feature-card-new-content h3 {
    color: var(--jb-fg);
}

.column-empty-state {
    border: none;
    padding: 8px 4px;
}
.column-empty-state:hover,
.kanban-column.drag-over .column-empty-state {
    border-color: transparent;
    color: var(--jb-fg-tertiary);
}
/* The custom board renders its empty state once and never touches it again, so a dragged card hides it without any script. */
.column-content:has(.feature-card-roadmap) .column-empty-state { display: none; }

.toggle-slider::before {
    background: var(--jb-fg-on-accent);
}

.btn-primary, .btn-secondary, .btn-danger,
.dashboard-comment-submit, .voter-load-more, .ob-empty-btn {
    min-height: var(--jb-h-control);
    min-width: var(--jb-w-button-min);
    padding: 0 14px;
    font-size: 13px;
    font-weight: var(--jb-w-normal);
    border-radius: var(--jb-r-md);
    cursor: default;
    transition: background-color var(--jb-dur-in) ease-out;
}
.btn-primary,
.dashboard-comment-submit,
.ob-empty-btn {
    background: var(--jb-accent);
    border: 1px solid var(--jb-accent);
    color: var(--jb-fg-on-accent);
}
.btn-primary:hover,
.dashboard-comment-submit:hover,
.ob-empty-btn:hover {
    background: var(--jb-accent-hover);
    border-color: var(--jb-accent-hover);
    opacity: 1;
    transform: none;
    box-shadow: none;
}
.btn-primary:active,
.dashboard-comment-submit:active,
.ob-empty-btn:active {
    background: var(--jb-accent-pressed);
    border-color: var(--jb-accent-pressed);
    transform: none;
}
.btn-secondary,
.voter-load-more {
    background: var(--jb-bg-raised);
    border: 1px solid var(--jb-border-control);
    color: var(--jb-fg);
}
.btn-secondary:hover,
.voter-load-more:hover {
    background: var(--jb-bg-hover);
    border-color: var(--jb-border-control);
    color: var(--jb-fg);
    transform: none;
}
.btn-secondary:active,
.voter-load-more:active {
    background: var(--jb-bg-pressed);
    transform: none;
}
.btn-danger {
    background: var(--jb-bg-raised);
    border: 1px solid var(--jb-error-border);
    color: var(--jb-error);
}
.btn-danger:hover,
.btn-danger:active {
    background: var(--jb-error-solid);
    border-color: var(--jb-error-solid);
    color: var(--jb-fg-on-accent);
    transform: none;
}
.btn-primary:disabled,
.btn-secondary:disabled,
.btn-danger:disabled,
.dashboard-comment-submit:disabled,
.ob-empty-btn:disabled,
.voter-load-more:disabled {
    background: transparent;
    border-color: var(--jb-border-control);
    color: var(--jb-fg-disabled);
}
.modal-footer .btn:hover,
.modal-footer .btn:active,
.modal-footer .share-btn:hover,
.modal-footer .share-btn:active {
    transform: none;
}

.feature-card-action-btn {
    width: 24px;
    height: 24px;
    display: grid;
    place-items: center;
    border-radius: var(--jb-r-md);
    opacity: 0;
    transition: opacity var(--jb-dur-in) ease-out, background-color var(--jb-dur-in) ease-out;
}
.feature-card-roadmap:hover .feature-card-action-btn,
.feature-card-roadmap:focus-within .feature-card-action-btn {
    opacity: 1;
}
.feature-card-action-btn:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.feature-card-action-btn:active {
    background: var(--jb-bg-pressed);
}
.feature-card-action-btn:hover .action-icon { transform: none; }
@media (pointer: coarse) {
    .feature-card-action-btn { opacity: 1; }
}

.modal-close,
.detail-panel-close {
    width: 28px;
    height: 28px;
    padding: 0 0 3px;
    display: grid;
    place-items: center;
    font-size: 20px;
    line-height: 1;
    color: var(--jb-fg-icon);
    border: none;
    background: transparent;
    border-radius: var(--jb-r-md);
}
.modal-close:hover,
.detail-panel-close:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
    transform: none;
}
.detail-panel-title-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
.detail-panel-edit-btn {
    width: 28px;
    height: 28px;
    padding: 0;
    display: grid;
    place-items: center;
    border: none;
    background: transparent;
    border-radius: var(--jb-r-md);
    color: var(--jb-fg-icon);
}
.detail-panel-edit-btn:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.card-guide-panel-header {
    padding: 16px 24px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0;
}

.wizard-steps {
    display: none;
}
.wizard-step-panel {
    display: block;
}
.wizard-step-panel.active {
    animation: none;
}
.wizard-step-panel + .wizard-step-panel {
    margin-top: var(--jb-sp-6);
}
.wizard-step-num {
    display: none;
}
.wizard-step-dot {
    height: var(--jb-tab-pill-h);
    padding: 0 12px;
    border-radius: var(--jb-r-lg);
    font-size: 13px;
    font-weight: var(--jb-w-normal);
    color: var(--jb-fg-secondary);
    opacity: 0.75;
    background: transparent;
    transition: background-color var(--jb-dur-in) ease-out, opacity var(--jb-dur-in) ease-out;
}
.wizard-step-dot:hover {
    opacity: 1;
    color: var(--jb-fg);
    background: var(--jb-tab-hover-bg);
}
.wizard-step-dot:active {
    background: var(--jb-bg-pressed);
}
.wizard-step-dot.active {
    opacity: 1;
    color: var(--jb-fg);
    background: var(--jb-tab-selected-bg);
    box-shadow: inset 0 0 0 1px var(--jb-tab-selected-border);
}
.wizard-step-dot.completed {
    opacity: 0.75;
    color: var(--jb-fg-secondary);
}

.progress-preset-btn,
.effort-btn-edit,
.modal-container-feature .progress-preset-btn,
.modal-container-feature .effort-btn-edit {
    flex: 0 1 auto;
    height: 28px;
    padding: 0 8px;
    font-size: 12px;
    border-radius: var(--jb-r-md);
    transition: background-color var(--jb-dur-in) ease, border-color var(--jb-dur-in) ease, color var(--jb-dur-in) ease;
}
.progress-preset-btn:hover,
.effort-btn-edit:hover,
.modal-container-feature .progress-preset-btn:hover,
.modal-container-feature .effort-btn-edit:hover {
    transform: none;
    background: var(--jb-bg-hover);
    border-color: var(--jb-border-raised);
}
.progress-preset-btn.active,
.effort-btn-edit.active,
.modal-container-feature .progress-preset-btn.active,
.modal-container-feature .effort-btn-edit.active {
    box-shadow: inset 0 0 0 1px var(--jb-tab-selected-border);
    background: var(--jb-tab-selected-bg);
    border-color: transparent;
    color: var(--jb-fg);
}

.card-overflow-menu {
    background: var(--jb-bg-popup);
    border: 1px solid var(--jb-border);
    border-radius: var(--jb-r-md);
    box-shadow: var(--jb-shadow-popup);
    padding: 4px;
    transform: none;
    transition: opacity var(--jb-dur-in) ease-out;
}
.card-overflow-item {
    height: 24px;
    padding: 0 8px;
    border-radius: var(--jb-r-md);
}
.card-overflow-item:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.card-overflow-danger:hover {
    background: var(--jb-error-bg);
}

.detail-panel-actions-menu {
    background: var(--jb-bg-popup);
    border: 1px solid var(--jb-border);
    padding: 4px;
    border-radius: var(--jb-r-md);
    box-shadow: var(--jb-shadow-popup);
}
.panel-action-item {
    height: 24px;
    padding: 0 8px;
    font-size: 13px;
    border-radius: var(--jb-r-md);
}

.move-popover,
.detail-move-wrapper .move-popover,
.detail-panel-actions-wrapper .move-popover {
    background: var(--jb-bg-popup);
    border: 1px solid var(--jb-border);
    border-radius: var(--jb-r-md);
    box-shadow: var(--jb-shadow-popup);
    padding: 4px;
    overflow: hidden;
}
.card-overflow-menu .move-popover {
    left: 100%;
    right: auto;
    top: 0;
    margin: 0 0 0 4px;
}
.card-overflow-menu .move-popover.move-popover--left {
    left: auto;
    right: 100%;
    margin: 0 4px 0 0;
}
.move-popover-option,
.detail-panel-actions-wrapper .move-popover-option {
    display: flex;
    align-items: center;
    height: 24px;
    padding: 0 8px;
    font-size: 13px;
    border-radius: var(--jb-r-md);
    color: var(--jb-fg);
    background: none;
}
.move-popover-option:hover:not(.current-column),
.detail-panel-actions-wrapper .move-popover-option:hover:not(.current-column) {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.move-popover-option.current-column,
.detail-panel-actions-wrapper .move-popover-option.current-column {
    color: var(--jb-fg-disabled);
    opacity: 1;
    cursor: default;
}

.bulk-action-bar .btn-primary,
.bulk-action-bar .btn-secondary,
.bulk-action-bar .btn-danger {
    height: var(--jb-h-control);
    font-size: 13px;
}

@media (max-width: 600px) {
    .wizard-footer .btn-secondary:has(.show-mobile) {
        min-width: 2.25rem;
    }
}

/* Every field in a step sits in one grid, so a single row gap sets the rhythm; wide controls span both columns. */
.wizard-form-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--jb-sp-5) var(--jb-sp-4);
    align-items: start;
}
.wizard-form-grid > .form-group-roadmap {
    min-width: 0;
    margin-bottom: 0;
}
.wizard-form-grid > .form-group-full {
    grid-column: 1 / -1;
}
.progress-row {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-2);
}
.progress-row > .progress-presets {
    flex: 1;
    min-width: 0;
}
@media (max-width: 600px) {
    .wizard-form-grid { grid-template-columns: minmax(0, 1fr); }
}
/* One bordered track with a selected pill replaces six bordered chips, which is the treatment the tab strip already uses. */
.progress-presets,
.effort-selector-edit {
    display: flex;
    flex-wrap: nowrap;
    gap: 2px;
    margin-top: 0;
    padding: 2px;
    background: var(--jb-bg-inset);
    border: 1px solid var(--jb-border-control);
    border-radius: var(--jb-r-md);
}
.progress-preset-btn,
.effort-btn-edit,
.modal-container-feature .progress-preset-btn,
.modal-container-feature .effort-btn-edit {
    flex: 1;
    min-width: 0;
    height: var(--jb-h-dense);
    padding: 0 var(--jb-sp-2);
    background: transparent;
    border: none;
    border-radius: var(--jb-r-md);
    color: var(--jb-fg-secondary);
    font-size: 12px;
    font-weight: var(--jb-w-normal);
    box-shadow: none;
    transform: none;
    transition: background-color var(--jb-dur-in) ease-out, color var(--jb-dur-in) ease-out;
}
.progress-preset-btn:hover,
.effort-btn-edit:hover,
.modal-container-feature .progress-preset-btn:hover,
.modal-container-feature .effort-btn-edit:hover {
    background: var(--jb-bg-hover);
    border-color: transparent;
    color: var(--jb-fg);
    transform: none;
}
.progress-preset-btn.active,
.effort-btn-edit.active,
.modal-container-feature .progress-preset-btn.active,
.modal-container-feature .effort-btn-edit.active {
    background: var(--jb-accent);
    border-color: transparent;
    color: var(--jb-fg-on-accent);
    box-shadow: none;
}
.form-input, .form-select {
    height: var(--jb-h-control);
    padding: 0 6px 0 9px;
    font-size: 13px;
    border-radius: var(--jb-r-md);
}
.form-select { padding-right: 32px; }
.form-textarea { font-size: 13px; border-radius: var(--jb-r-md); }
.form-label { font-size: 13px; font-weight: var(--jb-w-normal); }
.form-input:focus,
.form-select:focus,
.form-textarea:focus {
    border-color: transparent;
}
@media (pointer: coarse) {
    .form-input, .form-select, .form-textarea, .toolbar-input { font-size: 16px; }
}

/* One dimming layer for every floating surface: fixed over the viewport, blurred until text stops resolving, and tinted for the light theme. */
:root {
    --jb-backdrop-blur: 2px;
    --jb-backdrop-tint: color-mix(in srgb, var(--jb-gray-10) 32%, transparent);
    --jb-z-backdrop: 999;
    --jb-z-panel: 1000;
}
/* Without backdrop-filter the tint is the whole effect, so it is heavier; where the blur lands it steps back. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    :root {
        --jb-backdrop-tint: color-mix(in srgb, var(--jb-gray-10) 14%, transparent);
    }
}

.jb-backdrop,
.modal-overlay,
.panel-backdrop,
.sidebar-overlay,
.ob-welcome-overlay,
.ob-tour-overlay,
.demo-restriction-modal {
    position: fixed;
    inset: 0;
    z-index: var(--jb-z-backdrop);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: var(--jb-backdrop-tint);
    backdrop-filter: blur(var(--jb-backdrop-blur));
    -webkit-backdrop-filter: blur(var(--jb-backdrop-blur));
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    overscroll-behavior: contain;
    touch-action: none;
    /* --jb-dur-* collapse to 0ms under prefers-reduced-motion in jb-tokens.css, which is the whole of this layer's motion. */
    transition: opacity var(--jb-dur-out) var(--jb-ease-out),
                visibility var(--jb-dur-out) var(--jb-ease-out);
}
/* :where keeps the shown state at one class of weight, so the modifiers below can turn it off. */
.jb-backdrop:where(.active),
.modal-overlay:where(.active),
.panel-backdrop:where(.active),
.sidebar-overlay:where(.active),
.ob-welcome-overlay:where(.active),
.ob-tour-overlay:where(.active),
.demo-restriction-modal:where(.active) {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition-duration: var(--jb-dur-in);
    transition-timing-function: var(--jb-ease-in);
}
/* An overlay wrapping its own panel rides the panel layer and dims through its background, or a confirmation lands behind its drawer. */
.modal-overlay,
.ob-welcome-overlay,
.ob-tour-overlay,
.demo-restriction-modal {
    z-index: var(--jb-z-panel);
}
/* A drawer is a tool window, so it is an island: one width, floating with the island gap and the panel radius. */
:root {
    --drawer-w: 560px;
    --drawer-top: var(--jb-island-gap);
}
html.is-demo {
    --drawer-top: calc(var(--demo-banner-h, 40px) + var(--jb-island-gap));
}
.modal-container,
.modal-overlay .modal-content,
.detail-panel,
.card-guide-panel,
.vf-launcher-panel {
    position: fixed;
    top: var(--drawer-top);
    right: var(--jb-island-gap);
    bottom: var(--jb-island-gap);
    left: auto;
    width: var(--drawer-w);
    max-width: calc(100vw - var(--jb-island-gap) * 2);
    height: auto;
    max-height: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    background: var(--jb-bg-island);
    border: 1px solid var(--jb-border-island);
    border-radius: var(--jb-r-panel);
    box-shadow: var(--jb-shadow-dialog);
    overflow: hidden;
    transform: translateX(calc(100% + var(--jb-island-gap)));
    animation: none;
    transition: transform var(--jb-dur-out) ease;
}
.modal-overlay.active .modal-container,
.modal-overlay.active .modal-content,
.detail-panel.active,
.card-guide-panel.active,
.vf-launcher-panel.active {
    transform: translateX(0);
    animation: none;
    transition: transform var(--jb-dur-in) ease;
}
.modal-overlay.active .modal-body > form > * {
    animation: none;
}
.modal-container-feature,
.merge-modal .modal-container {
    width: var(--drawer-w);
    max-width: calc(100vw - var(--jb-island-gap) * 2);
}
.modal-body,
.detail-panel-body,
.card-guide-panel-body {
    overscroll-behavior: contain;
    overflow-x: hidden;
    padding: var(--jb-sp-5);
}
/* A form of three fields or fewer is a dialog in the middle of the screen; anything larger stays a drawer. */
.modal-overlay.is-dialog .modal-container {
    inset: 0;
    margin: auto;
    width: min(var(--drawer-w), calc(100vw - var(--jb-island-gap) * 2));
    height: fit-content;
    max-height: calc(100dvh - var(--jb-island-gap) * 2);
    opacity: 0;
    transform: scale(0.98);
    transition: transform var(--jb-dur-out) ease, opacity var(--jb-dur-out) ease;
}
.modal-overlay.is-dialog.active .modal-container {
    opacity: 1;
    transform: none;
}
/* The drawers carrying only prose shrink to their content, since a two line confirmation does not deserve the full viewport height. */
.modal-container:has(.modal-body-text),
.card-guide-panel {
    bottom: auto;
    max-height: calc(100dvh - var(--drawer-top) - var(--jb-island-gap));
}
@media (max-width: 768px) {
    .modal-container:has(.modal-body-text),
    .card-guide-panel {
        bottom: 0;
        max-height: none;
    }
    .modal-container,
    .modal-overlay .modal-content,
    .detail-panel,
    .card-guide-panel {
        top: 0;
        right: 0;
        bottom: 0;
        width: 100vw;
        max-width: 100vw;
        border: none;
        border-radius: 0;
        transform: translateX(100%);
    }
    html.is-demo .modal-container,
    html.is-demo .modal-overlay .modal-content,
    html.is-demo .detail-panel,
    html.is-demo .card-guide-panel {
        top: var(--demo-banner-h, 40px);
    }
    .modal-body,
    .detail-panel-body,
    .card-guide-panel-body { padding: var(--jb-sp-4); }
}

/* The scroll lock is on the root only: hiding body overflow moves the scrollport and drops the sticky top bar. */
html:has(.modal-overlay.active),
html:has(.detail-panel.active),
html:has(.card-guide-panel.active),
html:has(.jb-settings-dialog.active) {
    overflow: hidden;
}

.roadmap-bottom-bar.jb-statusbar {
    position: fixed;
    left: calc(var(--sidebar-width) + var(--layout-offset));
    right: 0;
    bottom: 0;
    top: auto;
    transform: none;
    width: auto;
    margin: 0;
    height: 28px;
    justify-content: flex-start;
    gap: 12px;
    padding: 0 12px;
    background: var(--jb-bg-canvas);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border: none;
    border-top: 1px solid var(--jb-border-island);
    border-radius: 0;
    box-shadow: none;
    z-index: var(--jb-z-sticky);
}
[data-sidebar="compact"] .roadmap-bottom-bar.jb-statusbar {
    left: calc(var(--sidebar-compact-width) + var(--layout-offset));
}
@media (max-width: 768px) {
    .roadmap-bottom-bar.jb-statusbar { left: 0; }
}
.roadmap-nav-btn {
    width: 22px;
    height: 22px;
    background: transparent;
    border: none;
    border-radius: var(--jb-r-md);
}
.roadmap-nav-btn:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.roadmap-dot:hover { opacity: 0.6; }
.roadmap-dot:active { opacity: 1; }
.roadmap-dot.active { background: var(--jb-accent); }
.roadmap-bottom-divider { background: var(--jb-border); }
.roadmap-bottom-hints {
    color: var(--jb-fg-tertiary);
    margin-left: auto;
}
.roadmap-bottom-hints kbd {
    background: var(--jb-bg-inset);
    border: 1px solid var(--jb-border);
    border-radius: var(--jb-r-sm);
}
@media (pointer: coarse) {
    .roadmap-bottom-hints,
    .roadmap-bottom-divider,
    .toolbar-search-kbd {
        display: none;
    }
}

.bulk-action-bar {
    background: var(--jb-bg-raised);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border: 1px solid var(--jb-border-raised);
    border-radius: var(--jb-r-panel);
    box-shadow: var(--jb-shadow-popup);
    flex-wrap: wrap;
    gap: 8px;
    padding: 8px 12px;
}
.bulk-action-bar .bulk-count-label {
    background: var(--jb-bg-inset);
    color: var(--jb-fg-secondary);
    font-size: 13px;
    font-weight: var(--jb-w-medium);
    border-radius: var(--jb-r-md);
    padding: 0 8px;
    height: var(--jb-h-control);
    display: inline-flex;
    align-items: center;
}
.bulk-action-bar .bulk-count-label span {
    color: var(--jb-fg);
    font-weight: var(--jb-w-semi);
}
.bulk-action-bar .btn {
    border-radius: var(--jb-r-md);
}
.bulk-action-bar .toolbar-select {
    height: var(--jb-h-control);
    font-size: 13px;
    width: auto;
    flex: 0 1 200px;
}
@media (min-width: 769px) {
    .bulk-action-bar { flex-wrap: nowrap; }
}

.toast {
    position: fixed;
    top: 52px;
    bottom: auto;
    left: auto;
    right: 16px;
    transform: none;
    animation: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: var(--jb-bg-raised);
    border: 1px solid var(--jb-border-raised);
    border-radius: var(--jb-r-md);
    color: var(--jb-fg);
    box-shadow: var(--jb-shadow-toast);
    font-size: 13px;
    width: clamp(300px, 90vw, 420px);
    overflow: hidden;
}
.card-progress-track {
    height: 4px;
    background: var(--jb-bg-inset);
    border-radius: var(--jb-r-sm);
}
.card-progress-fill {
    background: var(--jb-accent);
    border-radius: var(--jb-r-sm);
    animation: none;
    transition: width var(--jb-dur-out) ease;
}
.panel-progress-bar {
    height: 4px;
}
.toast.success,
.toast.error,
.toast.warning,
.toast.info,
.toast.celebration {
    border: 1px solid var(--jb-border-raised);
}
.toast.success .title { color: var(--jb-success); }
.toast.error .title { color: var(--jb-error); }
.toast.warning .title { color: var(--jb-warning); }
.toast.info .title { color: var(--jb-info); }
.toast.success .toast-progress-bar { background: var(--jb-success); }
.toast.error .toast-progress-bar { background: var(--jb-error); }
.toast.warning .toast-progress-bar { background: var(--jb-warning); }
.toast.info .toast-progress-bar { background: var(--jb-info); }
@media (max-width: 600px) {
    .toast {
        top: 52px;
        bottom: auto;
        left: 12px;
        right: 12px;
        transform: none;
        width: auto;
    }
}
html.is-demo .toast {
    top: calc(var(--demo-banner-h, 40px) + 52px);
}

.modal-info-box {
    background: var(--jb-info-bg);
    border: 1px solid var(--jb-info-border);
    border-radius: var(--jb-r-md);
    padding: var(--jb-sp-3);
}
.modal-info-box p,
.modal-body-text {
    color: var(--jb-fg);
    font-size: 13px;
    line-height: var(--jb-lh-prose);
}

/* The guide groups the way the detail panel does, with no rules, so the two drawers read as one system. */
/* The guide is reference, so it is rows of term and thing rather than stacked headings, and fits without scrolling. */
.guide-group + .guide-group {
    margin-top: var(--jb-sp-5);
}
.guide-group-title {
    margin: 0 0 var(--jb-sp-2);
    font-size: var(--jb-t-2);
    font-weight: var(--jb-w-medium);
    color: var(--jb-fg-tertiary);
}
.guide-rows {
    display: grid;
    gap: var(--jb-sp-2);
    margin: 0;
}
.guide-row {
    display: grid;
    grid-template-columns: 78px minmax(0, 1fr);
    gap: var(--jb-sp-3);
    align-items: center;
}
.guide-row dt {
    margin: 0;
    font-size: var(--jb-t-2);
    color: var(--jb-fg-tertiary);
}
.guide-row dd {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-2);
    margin: 0;
    font-size: var(--jb-t-3);
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-secondary);
}
/* The sample chip sits on the same line as the sentence explaining it, so the two can be matched without scanning. */
.guide-example {
    flex: none;
    display: flex;
    align-items: center;
    gap: 4px;
    height: 20px;
    margin: 0;
}
.guide-example > * {
    margin: 0;
}
.guide-example .card-progress-bar {
    align-items: center;
    width: 88px;
    gap: 6px;
}

.modal-info-box--warning {
    background: var(--jb-warning-bg);
    border-color: var(--jb-warning-border);
}
.modal-info-box--warning p { color: var(--jb-warning); }
.modal-info-box--error {
    background: var(--jb-error-bg);
    border-color: var(--jb-error-border);
}
.modal-info-box--error .panel-section-title { color: var(--jb-error); }
.modal-info-box p { margin: 0; }
.modal-info-box .panel-section-title { margin-bottom: var(--jb-sp-1); }

/* A banner earns its border because the colour carries meaning; a checkbox, tag list and note field do not. */
.modal-container .checkbox-group,
.modal-container-feature .checkbox-group,
.jb-settings-dialog .checkbox-group,
.plan-page .checkbox-group {
    margin: 0;
    padding: 0;
    background: none;
    border: none;
}
.modal-container .checkbox-group:hover,
.modal-container-feature .checkbox-group:hover,
.jb-settings-dialog .checkbox-group:hover,
.plan-page .checkbox-group:hover { background: none; }
.modal-container .checkbox-group label,
.modal-container-feature .checkbox-group label,
.jb-settings-dialog .checkbox-group label,
.plan-page .checkbox-group label {
    gap: 5px;
    margin: 0;
    font-size: 13px;
    font-weight: var(--jb-w-normal);
    color: var(--jb-fg);
}
.tags-list-section {
    padding: 0;
    margin-bottom: var(--jb-sp-6);
    border-bottom: none;
}
.new-tag-section { padding-top: 0; }
.modal-container .team-note-area {
    padding: 0;
    border-top: none;
    border-bottom: none;
}

/* Merge is a pick list: prose, the source stated plainly, then a bordered list with the inset pill selection. */
.merge-explanation {
    margin: 0 0 var(--jb-sp-5);
    padding: 0;
    background: none;
    border: none;
    border-radius: 0;
    font-size: 13px;
    line-height: var(--jb-lh-prose);
    color: var(--jb-fg-secondary);
}
.merge-explanation p { margin: 0; }
.merge-explanation p + p { margin-top: var(--jb-sp-2); }

/* The outcome sentence names both features once a target is picked, and is empty until then, hence :empty. */
.merge-outcome {
    margin: var(--jb-sp-3) 0 0;
    font-size: 13px;
    line-height: var(--jb-lh-prose);
    color: var(--jb-fg-secondary);
}
.merge-outcome:empty { display: none; }
.merge-source-info {
    margin: 0 0 var(--jb-sp-5);
    padding: 0;
    background: none;
    border: none;
    border-radius: 0;
}
.merge-source-label {
    margin-bottom: 2px;
    color: var(--jb-error);
    font-weight: var(--jb-w-medium);
    text-transform: none;
    letter-spacing: normal;
}
.merge-source-heading {
    font-size: 13px;
    font-weight: var(--jb-w-medium);
    color: var(--jb-fg);
}
.merge-source-votes {
    margin-top: 2px;
    color: var(--jb-fg-tertiary);
}

/* The picker takes the drawer's height instead of scrolling inside 260px; the body is the flex column and the target field grows. */
.merge-modal .modal-body {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.merge-modal .modal-body > .form-group-roadmap:last-child {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    margin-bottom: 0;
}
.merge-target-list {
    flex: 1;
    min-height: 96px;
    max-height: none;
    overflow-y: auto;
    margin-top: var(--jb-sp-2);
    padding: var(--jb-sp-1);
    background: var(--jb-bg-inset);
    border: 1px solid var(--jb-border-control);
    border-radius: var(--jb-r-md);
}
.merge-target-item {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-2);
    height: var(--jb-h-control);
    padding: 0 var(--jb-sp-2);
    border: none;
    border-radius: var(--jb-r-md);
    transition: background-color var(--jb-dur-in) ease-out;
}
.merge-target-item:hover { background: var(--jb-bg-hover); }
.merge-target-item.selected {
    background: var(--jb-bg-selected);
    border-left: none;
}
.merge-target-heading {
    flex: 1;
    min-width: 0;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--jb-fg);
}
.merge-target-type {
    display: inline-flex;
    align-items: center;
    flex: none;
    height: 18px;
    margin: 0;
    padding: 0 6px;
    border-radius: var(--jb-r-sm);
    font-weight: var(--jb-w-medium);
    background: color-mix(in srgb, var(--tag-color, var(--jb-fg-tertiary)) 22%, transparent);
    color: var(--tag-color, var(--jb-fg-tertiary));
}
.merge-target-stat {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    flex: none;
    min-width: 34px;
    justify-content: flex-end;
    font-size: 12px;
    color: var(--jb-fg-tertiary);
    font-variant-numeric: tabular-nums;
}
.merge-target-stat svg {
    width: 11px;
    height: 11px;
}
.merge-target-empty {
    padding: var(--jb-sp-2);
    font-size: 13px;
    color: var(--jb-fg-tertiary);
    text-align: left;
}

/* Every right side drawer wears the same chrome: a 40px header, a 16px content well, and a 12px by 16px action footer. */
.modal-header,
.card-guide-panel-header,
.detail-panel .jb-drawer-head {
    height: var(--jb-panel-head-h);
    min-height: var(--jb-panel-head-h);
    flex: none;
    display: flex;
    align-items: center;
    gap: var(--jb-sp-1);
    margin: 0;
    padding: 0 var(--jb-sp-2) 0 var(--jb-sp-5);
    border-bottom: 1px solid var(--jb-border);
}
.modal-footer,
.wizard-footer,
.detail-action-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--jb-sp-3);
    padding: var(--jb-sp-3) var(--jb-sp-5);
    border-top: 1px solid var(--jb-border);
}
.modal-footer > *,
.wizard-footer > *,
.detail-action-footer > * {
    margin: 0;
}
.modal-footer .btn,
.modal-footer .btn-primary,
.modal-footer .btn-secondary,
.modal-footer .btn-danger,
.modal-footer .share-btn,
.wizard-footer .btn,
.detail-action-footer .btn {
    min-height: var(--jb-h-control);
    margin: 0;
}
.wizard-footer-right {
    display: flex;
    gap: 8px;
    margin-left: auto;
}
.modal-footer-left,
.modal-footer .modal-footer-left,
.detail-action-footer .btn-danger {
    margin-right: auto;
}
.modal-container .form-group-roadmap,
.modal-container-feature .form-group-roadmap {
    margin-top: 0;
    margin-bottom: var(--jb-sp-5);
}
.modal-container .form-group-roadmap:last-child,
.modal-container-feature .form-group-roadmap:last-child,
.modal-container .wizard-form-grid > .form-group-roadmap,
.modal-container-feature .wizard-form-grid > .form-group-roadmap,
/* The row already owns the break under it, so its cells must not carry a second one. */
.modal-container .form-row > .form-group-roadmap,
.modal-container-feature .form-row > .form-group-roadmap {
    margin-bottom: 0;
}
.form-row {
    margin-bottom: var(--jb-sp-5);
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
/* Feature detail panel: a 40px bar, a meta row, the tab strip, a scrolling body, and a pinned 28px status strip. */

.detail-panel .detail-panel-header {
    padding: 0;
    border-bottom: 1px solid var(--jb-border);
}
.detail-panel .detail-panel-header > .jb-drawer-head:only-child {
    border-bottom: none;
}
.detail-panel .detail-panel-meta {
    padding: var(--jb-sp-3) var(--jb-sp-5) 0;
    margin: 0;
    gap: var(--jb-sp-2);
}
.detail-panel .detail-panel-tabs {
    padding: var(--jb-sp-3) var(--jb-sp-5);
}
/* The status is a tinted chip in the status colour, the shape the tags already use, so the dot goes. */
.detail-panel-status-badge {
    height: 20px;
    min-height: 0;
    padding: 0 6px;
    gap: 0;
    border: none;
    border-radius: var(--jb-r-sm);
    font-size: 11px;
    font-weight: var(--jb-w-medium);
    background: color-mix(in srgb, var(--status-color, var(--jb-fg-tertiary)) 22%, transparent);
    color: var(--status-color, var(--jb-fg-tertiary));
}
.detail-panel-actions-btn {
    height: var(--jb-h-control);
    min-height: var(--jb-h-control);
    padding: 0 10px;
    gap: 6px;
    border-radius: var(--jb-r-md);
    background: var(--jb-bg-raised);
    border: 1px solid var(--jb-border-control);
    color: var(--jb-fg);
}
.detail-panel-actions-btn:hover {
    background: var(--jb-bg-hover);
    border-color: var(--jb-border-raised);
}

.detail-panel-tabs {
    padding: 0;
    gap: 2px;
    background: none;
    border-bottom: none;
}
.detail-panel-tab {
    flex: none;
    height: 28px;
    padding: 0 12px;
    margin-bottom: 0;
    border-bottom: none;
    border-radius: var(--jb-r-md);
    background: transparent;
    color: var(--jb-fg-secondary);
    font-size: 13px;
    font-weight: var(--jb-w-normal);
    letter-spacing: normal;
    transition: background-color var(--jb-dur-in) ease-out, color var(--jb-dur-in) ease-out;
}
.detail-panel-tab:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.detail-panel-tab.active {
    font-weight: var(--jb-w-normal);
    background: var(--jb-tab-selected-bg);
    color: var(--jb-fg);
    box-shadow: inset 0 0 0 1px var(--jb-tab-selected-border);
    border-bottom-color: transparent;
}
.detail-panel-tabcontent.active {
    animation: none;
}
.tab-count {
    background: none;
    padding: 0;
    margin-left: 4px;
    color: var(--jb-fg-secondary);
    font-weight: var(--jb-w-normal);
    border-radius: 0;
}

/* Overview is a JetBrains inspector: titled separators between groups, and a two column grid keeping each label beside its value. */
.detail-panel .panel-description {
    font-size: 13px;
    line-height: var(--jb-lh-prose);
    color: var(--jb-fg);
    margin: 0 0 var(--jb-sp-5);
    white-space: pre-wrap;
}
.detail-panel .panel-section { margin: 0 0 var(--jb-sp-5); }
.detail-panel .panel-section:last-child { margin-bottom: 0; }
.detail-panel .panel-section.is-hidden { margin-bottom: 0; }
.panel-section-title {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-2);
    min-height: var(--jb-h-control);
    margin: 0 0 var(--jb-sp-2);
    font-size: 12px;
    font-weight: var(--jb-w-medium);
    color: var(--jb-fg-tertiary);
}
.panel-section-title::after {
    content: "";
    order: 2;
    flex: 1;
    height: 1px;
    background: var(--jb-border);
}
.panel-section-title--plain { min-height: 0; }
.panel-section-title--plain::after { content: none; }
.panel-prose {
    margin: 0;
    font-size: 13px;
    line-height: var(--jb-lh-prose);
    color: var(--jb-fg);
    white-space: pre-wrap;
}
/* Nothing to show is a sentence, not a faded italic. */
.panel-empty {
    margin: 0;
    font-size: 13px;
    color: var(--jb-fg-tertiary);
}

.panel-kv {
    display: grid;
    grid-template-columns: max-content minmax(0, max-content);
    column-gap: var(--jb-sp-5);
    align-items: center;
    margin: 0;
}
.panel-kv-row { display: contents; }
.panel-kv-row.is-hidden { display: none; }
.panel-kv-row dt {
    display: flex;
    align-items: center;
    min-height: var(--jb-row);
    margin: 0;
    font-size: 13px;
    color: var(--jb-fg-secondary);
}
.panel-kv-row dd {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    min-height: var(--jb-row);
    margin: 0;
    font-size: 13px;
    color: var(--jb-fg);
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}
/* Prioritization and Engagement stand side by side, each laying its pairs two to a line, which is the size the content wants. */
.panel-cols {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--jb-sp-5) var(--jb-sp-6);
    align-items: start;
    margin: 0 0 var(--jb-sp-5);
}
.detail-panel .panel-cols > .panel-section { margin-bottom: 0; }
/* One metric per line with the badge pinned right, so every value lines up under the one above it. */
.panel-kv--split {
    grid-template-columns: max-content minmax(0, 1fr);
    column-gap: var(--jb-sp-4);
}
/* The count has no badge, so it borrows the badge's six pixels of right inset to stay in the column. */
.panel-kv .count-dot {
    padding-right: 6px;
}
@media (max-width: 420px) {
    .panel-cols { grid-template-columns: minmax(0, 1fr); }
}

/* The value wears the badge the board card gives it, neutral for votes and comments, which carry no ranking meaning. */
.card-score-badge-neutral {
    background: transparent;
    color: var(--jb-fg-secondary);
}
.card-score-badge.is-unset {
    background: transparent;
    color: var(--jb-fg-disabled);
}

.panel-progress { margin-bottom: var(--jb-sp-3); }
.panel-progress.is-hidden { margin-bottom: 0; }
.panel-progress-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: var(--jb-row);
    font-size: 13px;
}
.panel-progress-label { color: var(--jb-fg-secondary); }
.panel-progress-value {
    color: var(--jb-fg);
    font-variant-numeric: tabular-nums;
}
.panel-progress-bar {
    height: 4px;
    border-radius: var(--jb-r-sm);
    background: var(--jb-bg-inset);
    overflow: hidden;
}
.panel-progress-fill {
    height: 100%;
    background: var(--jb-accent);
    border-radius: var(--jb-r-sm);
}

.tier-chart { margin: 0; }
.tier-chart-row {
    gap: var(--jb-sp-2);
    padding: 0;
    min-height: var(--jb-row);
}
.tier-chart-label {
    min-width: 96px;
    font-size: 12px;
    font-weight: var(--jb-w-normal);
    color: var(--jb-fg-secondary);
}
.tier-chart-mult {
    margin-left: 2px;
    padding: 0;
    background: none;
    border-radius: 0;
    font-size: 11px;
    font-weight: var(--jb-w-normal);
    color: var(--jb-fg-tertiary);
}
.tier-chart-bar-track {
    height: 4px;
    background: var(--jb-bg-inset);
    border-radius: var(--jb-r-sm);
}
/* One hue for every tier, since the row label already names it and a colour per tier would be decoration. */
.tier-chart-bar-fill {
    background: var(--jb-syntax-function);
    border-radius: var(--jb-r-sm);
}
.tier-chart-value {
    min-width: 24px;
    font-size: 12px;
    font-weight: var(--jb-w-normal);
    color: var(--jb-fg);
}
.tier-chart-total {
    margin-top: var(--jb-sp-2);
    padding-top: var(--jb-sp-2);
    border-top: 1px solid var(--jb-border);
    font-size: 12px;
    font-weight: var(--jb-w-medium);
    color: var(--jb-fg);
}

.panel-merged-item {
    padding: var(--jb-sp-2) 0;
    border-bottom: 1px solid var(--jb-border-island);
}
.panel-merged-item:last-child { border-bottom: none; }
.panel-merged-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--jb-sp-3);
}
.panel-merged-title {
    font-size: 13px;
    color: var(--jb-fg);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.panel-merged-votes {
    flex: none;
    font-size: 12px;
    color: var(--jb-fg-tertiary);
    font-variant-numeric: tabular-nums;
}
.panel-merged-desc {
    margin: 2px 0 0;
    font-size: 12px;
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-secondary);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Comments and Voters get a tab each, with their own search and filter, rather than a tally stacked under a conversation. */

.activity-search-row {
    display: flex;
    gap: var(--jb-sp-2);
    margin-bottom: var(--jb-sp-4);
}
.activity-search {
    flex: 1;
    min-width: 0;
    max-width: none;
    margin: 0;
}
.activity-search-row .toolbar-select {
    flex: none;
    width: auto;
    min-width: 0;
    max-width: 132px;
}
.activity-empty {
    margin: var(--jb-sp-2) 0;
    font-size: 13px;
    color: var(--jb-fg-secondary);
}
.activity-more {
    display: block;
    width: 100%;
    height: var(--jb-row);
    margin-top: var(--jb-sp-2);
    padding: 0;
    border: none;
    background: none;
    color: var(--jb-link);
    font-family: inherit;
    font-size: 12px;
    text-align: left;
    cursor: default;
}
.activity-more:hover { text-decoration: underline; }

.vote-item {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-2);
    height: 28px;
    margin: 0 -8px;
    padding: 0 8px;
    border-radius: var(--jb-r-md);
    font-size: 13px;
    color: var(--jb-fg);
}
.vote-item:hover { background: var(--jb-bg-hover); }
.vote-item-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.vote-item-date {
    margin-left: auto;
    flex: none;
    font-size: 11px;
    color: var(--jb-fg-tertiary);
    font-variant-numeric: tabular-nums;
}
.voter-type-badge,
.voter-weight-badge {
    display: inline-flex;
    align-items: center;
    flex: none;
    height: 18px;
    padding: 0 6px;
    border: none;
    border-radius: var(--jb-r-sm);
    font-size: 11px;
    font-weight: var(--jb-w-normal);
    text-transform: none;
    letter-spacing: normal;
}
.voter-tier-badge {
    background: var(--jb-bg-inset);
    color: var(--jb-fg-secondary);
}
.voter-mrr-badge {
    background: color-mix(in srgb, var(--jb-syntax-string) 22%, transparent);
    color: var(--jb-syntax-string);
}
.voter-weight-badge {
    background: color-mix(in srgb, var(--jb-syntax-function) 22%, transparent);
    color: var(--jb-syntax-function);
}

.comment-composer {
    padding: 0 0 var(--jb-sp-3);
    margin-bottom: var(--jb-sp-3);
    border-bottom: 1px solid var(--jb-border-island);
}
.comment-composer-row { gap: var(--jb-sp-2); }
.comment-composer-avatar {
    width: 24px;
    height: 24px;
    font-size: 11px;
    font-weight: var(--jb-w-medium);
    background: color-mix(in srgb, var(--avatar-color, var(--jb-fg-secondary)) 24%, transparent);
    color: var(--avatar-color, var(--jb-fg));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--avatar-color, var(--jb-fg-secondary)) 45%, transparent);
}
.dashboard-comment-input {
    min-height: 56px;
    padding: 6px 9px;
    background: var(--jb-bg-inset);
    border: 1px solid var(--jb-border-control);
    border-radius: var(--jb-r-md);
    font-size: 13px;
    line-height: 1.5;
}
.dashboard-comment-input:focus {
    border-color: transparent;
    box-shadow: none;
}
.comment-composer-footer { margin-top: var(--jb-sp-2); }

/* Nothing in a drawer is a card: a comment is prose behind a hairline, a vote a 28px list row. */
.comment-item {
    background: none;
    border: none;
    border-bottom: 1px solid var(--jb-border);
    border-radius: 0;
    padding: var(--jb-sp-2) 0;
    margin: 0;
}
.comment-item:last-child { border-bottom: none; }
.comment-item--reply {
    background: none;
    border: none;
    padding: var(--jb-sp-1) 0;
    margin: 0;
}
.comment-item-row {
    gap: var(--jb-sp-2);
    position: relative;
    padding-left: 12px;
}
.comment-item-head {
    display: flex;
    align-items: center;
    gap: 6px;
    min-height: 20px;
}
.comment-item-author {
    font-size: 13px;
    font-weight: var(--jb-w-medium);
    color: var(--jb-fg);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.comment-item-date {
    margin-left: auto;
    flex: none;
    font-size: 11px;
    color: var(--jb-fg-tertiary);
}
.comment-text {
    margin: 2px 0 0;
    font-size: 13px;
    line-height: var(--jb-lh-prose);
    color: var(--jb-fg-secondary);
    white-space: pre-wrap;
}
.comment-item-meta {
    gap: var(--jb-sp-2);
    margin-top: 2px;
    min-height: 20px;
}
/* The like control carries a count so it stays; destructive and navigational actions appear on hover, like a JetBrains row gutter. */
.comment-item-meta > button {
    opacity: 0;
    pointer-events: none;
    font-size: 11px;
    transition: opacity var(--jb-dur-in) ease-out;
}
.comment-item-meta > .comment-like-btn,
.comment-item:hover > .comment-item-row .comment-item-meta > button,
.comment-item:focus-within > .comment-item-row .comment-item-meta > button {
    opacity: 1;
    pointer-events: auto;
}
@media (pointer: coarse) {
    .comment-item-meta > button {
        opacity: 1;
        pointer-events: auto;
        min-height: var(--jb-row);
    }
}
/* Every commenter and voter takes a colour from the editor palette by name, so a thread reads as a room of people. */
.activity-list .avatar-circle {
    width: 20px;
    height: 20px;
    font-size: 11px;
    font-weight: var(--jb-w-medium);
    background: color-mix(in srgb, var(--avatar-color, var(--jb-fg-secondary)) 24%, transparent);
    color: var(--avatar-color, var(--jb-fg));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--avatar-color, var(--jb-fg-secondary)) 45%, transparent);
}
.comment-like-count {
    font-size: 11px;
    color: var(--jb-fg-tertiary);
    font-variant-numeric: tabular-nums;
}
.comment-role-badge,
.comment-item-you {
    display: inline-flex;
    align-items: center;
    height: 16px;
    padding: 0 5px;
    margin: 0;
    border-radius: var(--jb-r-sm);
    font-size: 11px;
    font-weight: var(--jb-w-normal);
    text-transform: none;
    letter-spacing: normal;
    vertical-align: baseline;
}
.comment-item-you {
    background: var(--jb-bg-inset);
    color: var(--jb-fg-secondary);
}
.comment-role-owner {
    background: color-mix(in srgb, var(--jb-accent) 22%, transparent);
    color: var(--jb-link);
}
.comment-role-editor {
    background: var(--jb-bg-inset);
    color: var(--jb-fg-secondary);
}
/* Written since the owner was last here, marked by a gutter dot that is reserved on every comment so nothing shifts. */
.comment-new-dot {
    position: absolute;
    left: 0;
    top: 7px;
    width: 6px;
    height: 6px;
    border-radius: var(--jb-r-md);
    background: var(--jb-count-danger);
}
.comment-item-reply {
    margin-left: 12px;
    padding-left: 12px;
    margin-top: var(--jb-sp-1);
}
.comment-thread-line {
    width: 1px;
    background: var(--jb-border);
    border-radius: 0;
}
.comment-reply-input {
    height: var(--jb-h-control);
    padding: 0 8px;
    background: var(--jb-bg-inset);
    border: 1px solid var(--jb-border-control);
    border-radius: var(--jb-r-md);
    font-size: 13px;
}
.comment-edit-textarea {
    width: 100%;
    min-height: 56px;
    padding: 6px 9px;
    background: var(--jb-bg-inset);
    border: 1px solid var(--jb-border-control);
    border-radius: var(--jb-r-md);
    color: var(--jb-fg);
    font-family: inherit;
    font-size: 13px;
    line-height: 1.5;
}
.comment-edit-btn-row {
    display: flex;
    gap: var(--jb-sp-2);
    margin-top: var(--jb-sp-2);
}
.comment-edit-save,
.comment-edit-cancel {
    height: var(--jb-h-control);
    padding: 0 12px;
    border-radius: var(--jb-r-md);
    border: 1px solid var(--jb-border-control);
    background: var(--jb-bg-raised);
    color: var(--jb-fg);
    font-family: inherit;
    font-size: 12px;
    cursor: default;
}
.comment-edit-save {
    background: var(--jb-accent);
    border-color: var(--jb-accent);
    color: var(--jb-fg-on-accent);
}

[data-theme="light"] .sidebar { box-shadow: none; }
[data-theme="light"] .roadmap-bottom-bar {
    background: var(--jb-bg-raised);
    border-color: var(--jb-border);
}
[data-theme="light"] .roadmap-bottom-bar.jb-statusbar {
    background: var(--jb-bg-canvas);
    border-color: transparent;
    border-top-color: var(--jb-border-island);
}
[data-theme="light"] .roadmap-nav-btn {
    background: transparent;
    border-color: transparent;
}
[data-theme="light"] .roadmap-bottom-divider { background: var(--jb-border); }
[data-theme="light"] .toolbar-search {
    background: var(--jb-bg-island);
    border-color: var(--jb-border-control);
}
[data-theme="light"] .toolbar-search-kbd {
    background: var(--jb-bg-inset);
    border-color: var(--jb-border);
}
[data-theme="light"] .toolbar-filter-toggle {
    background: transparent;
    border: none;
    box-shadow: none;
}
[data-theme="light"] .bulk-action-bar {
    background: var(--jb-bg-raised);
    border: 1px solid var(--jb-border-raised);
    box-shadow: var(--jb-shadow-popup);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
[data-theme="light"] .detail-panel,
[data-theme="light"] .card-guide-panel,
[data-theme="light"] .modal-container,
[data-theme="light"] .modal-overlay .modal-content {
    background: var(--jb-bg-island);
    border: 1px solid var(--jb-border-island);
    border-radius: var(--jb-r-panel);
    box-shadow: var(--jb-shadow-dialog);
}
@media (max-width: 768px) {
    [data-theme="light"] .detail-panel,
    [data-theme="light"] .card-guide-panel,
    [data-theme="light"] .modal-container,
    [data-theme="light"] .modal-overlay .modal-content {
        border: none;
        border-radius: 0;
    }
}


[data-theme="light"] .detail-panel-tabs { border-bottom: none; }
[data-theme="light"] .tab-count { background: none; }
/* The status hue is a fixed board hex rather than a theme token, so it is darkened on a white surface. */
[data-theme="light"] .detail-panel-status-badge {
    background: color-mix(in srgb, var(--status-color, var(--jb-fg-tertiary)) 15%, transparent);
    color: color-mix(in srgb, var(--status-color, var(--jb-fg-tertiary)) 62%, var(--jb-fg));
}

.modal-header h2,
.modal-title,
.detail-panel-heading,
.card-guide-panel-header h2 {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    font-weight: var(--jb-w-medium);
    letter-spacing: normal;
    line-height: 1.2;
    color: var(--jb-fg);
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* JetBrains form labels match the value's size and colour and sit left aligned above it, rather than shrunk and greyed. */
.modal-container .form-label,
.modal-container label,
.modal-container-feature .form-label,
.modal-container-feature label,
.jb-settings-dialog label {
    font-size: 13px;
    font-weight: var(--jb-w-normal);
    color: var(--jb-fg);
    margin-bottom: 6px;
    letter-spacing: normal;
    text-transform: none;
}
.modal-container .form-help,
.modal-container-feature .form-help {
    margin-top: 6px;
    font-size: 11px;
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-tertiary);
}
.modal-container .required { color: var(--jb-error); }
.modal-container-feature .form-input,
.modal-container-feature .form-select,
.modal-container-feature .form-textarea,
.modal-container-feature .progress-input {
    font-size: 13px;
}
.modal-container-feature .team-note-area {
    border-bottom: none;
}
.modal-container-feature .team-note-area > .collapsible-toggle {
    border: none;
    background: transparent;
    padding-left: 0;
    padding-right: 0;
}
.modal-container .form-textarea,
.modal-container-feature .form-textarea {
    min-height: 88px;
    padding: 6px 9px;
    line-height: var(--jb-lh-prose);
}
.progress-input {
    width: 64px;
    height: var(--jb-h-control);
    padding: 0 8px;
    text-align: left;
    font-size: 13px;
    border-radius: var(--jb-r-md);
}
@media (pointer: coarse) {
    .modal-container-feature .form-input,
    .modal-container-feature .form-select,
    .modal-container-feature .form-textarea,
    .modal-container-feature .progress-input {
        font-size: 16px;
    }
}
.tab-count { font-size: 11px; }
.detail-panel-actions-btn { font-size: 12px; }
.voter-type-badge { font-size: 11px; }
.merge-source-label { font-size: 11px; }
.merge-source-votes { font-size: 12px; }
.merge-target-heading { font-size: 13px; }
.merge-target-type { font-size: 11px; }
.bulk-count-label { font-size: 13px; }
.card-progress-text { font-size: 11px; }
.card-overflow-item { font-size: 12px; }
/* The same titled separator the detail panel uses, so a group header reads alike in either drawer. */
.form-section-label,
.tags-section-title {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-2);
    font-size: 12px;
    font-weight: var(--jb-w-medium);
    color: var(--jb-fg-tertiary);
    text-transform: none;
    letter-spacing: normal;
    padding: 0;
    border-top: none;
    margin: var(--jb-sp-6) 0 var(--jb-sp-3);
}
.form-section-label::after,
.tags-section-title::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--jb-border);
}
.wizard-step-panel .form-section-label:first-child { margin-top: 0; }
.team-note-badge { font-size: 11px; text-transform: none; letter-spacing: normal; }
.comment-item-you,
.comment-role-badge { font-size: 11px; }
@media (max-width: 600px) {
    .wizard-footer .btn-primary,
    .wizard-footer .btn-secondary { font-size: 13px; }
}
[data-theme="light"] .detail-panel-close:hover { background: var(--jb-bg-hover); }
[data-theme="light"] .detail-panel-actions-btn {
    border-color: var(--jb-border-control);
    background: var(--jb-bg-raised);
}
[data-theme="light"] .detail-panel-actions-menu {
    background: var(--jb-bg-popup);
    border-color: var(--jb-border);
    box-shadow: var(--jb-shadow-popup);
}
[data-theme="light"] .panel-action-item:hover { background: var(--jb-bg-hover); }
[data-theme="light"] .tab-count { background: var(--jb-bg-inset); }

html.theme-switching *,
html.theme-switching *::before,
html.theme-switching *::after {
    transition: none !important;
}

.top-bar-left:has(.board-tabs) h1 { display: none; }
.column-header h3 {
    text-transform: none;
    letter-spacing: normal;
}
.wizard-progress { display: none; }
.filter-popover-label,
.panel-section-title,
.panel-progress-label,
.detail-panel-status-badge {
    text-transform: none;
    letter-spacing: normal;
}
.bulk-checkbox {
    position: absolute;
    top: 6px;
    right: 6px;
    margin: 0;
    z-index: 3;
    border-radius: var(--jb-r-sm);
}
.bulk-checkbox:checked,
.bulk-checkbox:hover {
    box-shadow: none;
}
.feature-card-roadmap.bulk-mode-card {
    position: relative;
}
.feature-card-roadmap.bulk-selected {
    background: var(--jb-bg-selected-muted) !important;
    border-color: var(--jb-accent) !important;
    box-shadow: none !important;
}
.feature-card-roadmap.bulk-selected:hover {
    background: var(--jb-bg-selected) !important;
}
/* A re-ranked card travels to its new position rather than snapping; the movement is the signal, so the surface is untouched. */
.feature-card-roadmap.card-reranked {
    transition: transform var(--jb-dur-out) var(--jb-ease-out);
}

.drop-indicator {
    background: var(--jb-accent);
    border-radius: 0;
    box-shadow: none;
    animation: none;
}
.feature-card-roadmap.bulk-mode-card .feature-card-header-actions {
    display: none;
}
.bulk-count-label {
    background: var(--jb-bg-inset);
    color: var(--jb-fg-secondary);
}
[data-theme="light"] .bulk-count-label,
[data-theme="light"] .card-progress-track,
[data-theme="light"] .voter-tier-badge,
[data-theme="light"] .comment-item-you {
    box-shadow: inset 0 0 0 1px var(--jb-border);
}

@media (min-width: 769px) {
    .toolbar-filter-popover { right: 8px; }
}

.tags-section-title { margin: 0 0 var(--jb-sp-3); }
.tag-item { height: 32px; padding: 8px 12px; }
.tag-delete-btn {
    border-radius: var(--jb-r-lg);
}
.tag-delete-btn:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.tag-delete-btn .action-icon {
    width: 16px;
    height: 16px;
}

.voting-tier-accent-bar[data-accent="blue"] { background: var(--jb-chart-1); }
.wv-priority-bar[data-rank="1"] { background: linear-gradient(90deg, var(--jb-accent), var(--jb-chart-1)); }

/* The colour is restated here because the legacy sheet pins the light theme toast to a literal at equal specificity. */
[data-theme="light"] .toast {
    border-color: var(--jb-border-raised);
    color: var(--jb-fg);
}
[data-theme="light"] .project-switcher-trigger {
    background: transparent;
    border-color: transparent;
}

/* Mobile shell (<=768). Overrides inner-index 5834. */
@media (max-width: 768px) {
    /* The top padding is the fixed top bar's own height, measured by common.js, because the bar wraps to one, two or three rows. */
    .main-content { padding: calc(var(--phone-top-bar-h, 40px) + var(--jb-sp-2)) 8px 44px; }

    /* Anything the page scrolls to itself has to clear the same two strips, or a row lands under fixed chrome. */
    html { scroll-padding-top: calc(var(--phone-top-bar-h, 40px) + 48px); }

    /* No transform on .main-content: an element with one becomes the containing block for its fixed descendants and moves the top bar. */
    .main-content { animation: none; }

    .top-bar-right,
    .top-bar-tools {
        flex: 1 1 auto;
        min-width: 0;
    }
    .top-bar-tools {
        display: flex;
        align-items: center;
        gap: 8px;
    }

    /* A left cluster with nothing visible still takes a share of the row, so it leaves the row to the search. */
    .top-bar-left:empty,
    .top-bar-left:has(> .top-bar-page-name:only-child) { display: none; }

    /* Voters loses its tab strip on a phone, since the list is the page; ?tab=settings still opens the settings surface. */
    .top-bar-left:has(> .page-tabs > .page-tab[data-tab="voters"].active) { display: none; }
    .top-bar-tools .toolbar-search {
        flex: 1 1 auto;
        min-width: 0;
        max-width: none;
    }
    /* The popover is anchored to the full bleed top bar rather than the 30px button, with the page gutter written out. */
    .toolbar-filters { position: static; }
    .toolbar-filter-popover {
        right: var(--jb-sp-2);
        left: auto;
        min-width: 0;
        width: min(280px, calc(100vw - 32px));
    }

    /* Fixed rather than sticky, and under the mobile header: this page offers more than one scrolling ancestor a sticky bar could pick. */
    .top-bar {
        position: fixed;
        top: 40px;
        left: 0;
        right: 0;
        height: auto;
        min-height: 40px;
        padding: 0 8px var(--jb-sp-2);
        gap: 8px;
        margin-bottom: 0;
        flex-wrap: wrap;
    }
    html.is-demo .top-bar {
        top: calc(var(--demo-banner-h, 36px) + 40px);
    }
    .top-bar h1 {
        font-size: 13px;
        font-weight: 600;
    }

    /* The demo strip keeps the sentence and the exit button on a phone, and drops the tour link and the disclaimer. */
    html.is-demo { --demo-strip-h: 36px; }
    .demo-banner {
        padding: 0 var(--jb-sp-2);
    }
    .demo-banner-content {
        justify-content: space-between;
        gap: var(--jb-sp-2);
        max-width: none;
    }
    .demo-banner-text-group {
        min-width: 0;
        text-align: left;
    }
    .demo-banner-label { display: inline; }
    .demo-banner-text {
        display: block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 11px;
    }
    /* The tinted bar and the button already say this is not the product, so the icon in front goes. */
    .demo-banner-text > svg,
    .demo-banner-subtext { display: none; }
    .demo-banner-cta {
        height: 24px;
        padding: 0 var(--jb-sp-2);
        font-size: 11px;
    }

    .board-tab, .page-tab {
        height: var(--jb-tab-pill-h);
        padding: 0 12px;
        font-size: 13px;
    }
    .board-tab-add {
        width: 28px;
        height: 28px;
        padding: 0;
    }
    .board-tab-upgrade {
        height: var(--jb-tab-pill-h);
        padding: 0 12px;
        font-size: 12px;
    }

    .toolbar-filter-toggle,
    .bulk-select-btn {
        width: 30px;
        height: 30px;
        padding: 0;
    }
    .toolbar-search {
        height: var(--jb-h-control);
        min-height: var(--jb-h-control);
    }

    /* No hairline between the header and the top bar: they are one slab of chrome, and the pair's bottom edge is what matters. */
    .mobile-header {
        height: 40px;
        padding: 0 8px;
        background: var(--jb-bg-toolbar);
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        border-bottom: none;
    }
    body { padding-top: 40px; }
    html.is-demo body { padding-top: calc(var(--demo-banner-h, 34px) + 40px); }
    /* The wordmark says what the mark says, and on a 360px header that is 20px spent twice. */
    .mobile-header .logo-icon { display: none; }
    .mobile-header .logo-text {
        font-size: 13px;
        font-weight: var(--jb-w-medium);
        color: var(--jb-fg);
    }
    .mobile-header .hamburger-btn {
        width: 30px;
        height: 30px;
        padding: 0;
        display: grid;
        place-items: center;
        border-radius: var(--jb-r-md);
        color: var(--jb-fg);
    }
    .mobile-header .hamburger-btn:hover { background: var(--jb-bg-hover); }
    .mobile-header .hamburger-btn:active { background: var(--jb-bg-pressed); }

    .sidebar {
        width: 260px;
        background: var(--jb-bg-canvas);
        border-right: 1px solid var(--jb-border);
        box-shadow: var(--jb-shadow-dialog);
    }
    [data-sidebar="compact"] .sidebar { width: 260px; }
    /* The sidebar is a full width drawer here, so every rule squaring an item for the 56px rail is undone and rows take 36px. */
    .sidebar .nav-item,
    [data-sidebar="compact"] .nav-item,
    [data-sidebar="compact"] .sidebar-footer-item,
    .sidebar-footer .sidebar-user {
        height: 36px;
        width: auto;
        padding: 0 12px;
        margin: 0 8px;
        gap: 8px;
        border-radius: var(--jb-r-md);
        font-size: 13px;
        justify-content: flex-start;
        align-self: stretch;
    }
    [data-sidebar="compact"] .sidebar-user { justify-content: flex-start; }
    [data-sidebar="compact"] .nav-section-label {
        height: auto;
        margin: 0 20px 4px;
        border-bottom: none;
        overflow: visible;
    }
    /* The drawer runs the full height of the phone, so the safe area inset lifts logout above the home indicator. */
    .sidebar-footer {
        gap: var(--jb-sp-1);
        padding: var(--jb-sp-2) 0 calc(var(--jb-sp-2) + env(safe-area-inset-bottom));
    }

    .roadmap-container {
        gap: var(--jb-island-gap);
        margin-top: 8px;
    }
    .kanban-column { padding: 8px 6px; }
    .roadmap-bottom-bar.jb-statusbar {
        padding: 0 8px;
        gap: 8px;
        justify-content: center;
    }
    .roadmap-nav-btn {
        width: 24px;
        height: 24px;
    }
}

/* Settings dialog: a centred window carrying neither drawer class, with the shell flush on the canvas and the content pane as the island. */
.jb-settings-dialog {
    position: fixed;
    inset: 0;
    margin: auto;
    z-index: var(--jb-z-panel);
    width: min(1000px, 80vw);
    height: min(700px, 80vh);
    display: grid;
    grid-template-rows: var(--jb-toolbar-h) minmax(0, 1fr) auto;
    background: var(--jb-bg-canvas);
    border: 1px solid var(--jb-border-island);
    border-radius: var(--jb-r-panel);
    box-shadow: var(--jb-shadow-dialog);
    overflow: hidden;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--jb-dur-out) var(--jb-ease-out),
                visibility var(--jb-dur-out) var(--jb-ease-out);
}
.jb-settings-dialog.active {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition-duration: var(--jb-dur-in);
    transition-timing-function: var(--jb-ease-in);
}
/* The tree filter and the plan gate use the hidden attribute, which carries only UA weight and loses to any display here. */
.jb-settings-dialog [hidden], .plan-page [hidden] { display: none !important; }

.jbs-titlebar {
    position: relative;
    padding: 0 var(--jb-sp-2);
}
/* The title is taken out of flow and inset equally, so it centres across the whole bar rather than the remaining space. */
.jbs-title {
    position: absolute;
    inset: 0 var(--jb-sp-5);
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: var(--jb-lh-tight);
    pointer-events: none;
}
.jbs-titlebar .modal-close { margin-left: auto; }
.jb-settings-dialog .modal-close,
.jbs-confirm .modal-close { padding: 0; }

.jbs-body {
    display: grid;
    /* 21.7% is the ratio measured off the reference window, and it stops the longest category title truncating. */
    grid-template-columns: clamp(180px, 21.7%, 280px) minmax(0, 1fr);
    min-height: 0;
}

.jbs-tree-pane {
    display: flex;
    flex-direction: column;
    min-height: 0;
    border-right: 1px solid var(--jb-border);
}
.jbs-search {
    flex: none;
    min-width: 0;
    max-width: 400px;
    margin: var(--jb-sp-3);
}
.jbs-search .toolbar-search-icon {
    width: var(--jb-icon);
    height: var(--jb-icon);
    color: var(--jb-fg-icon);
}
.jbs-search .toolbar-input::placeholder { color: var(--jb-fg-placeholder); }
/* Not while focused: the ring straddles the border, which is transparent underneath so the two do not draw as one edge. */
.jbs-search:not(:focus-within):hover { border-color: var(--jb-border-raised); }

.jbs-tree {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding-bottom: var(--jb-sp-2);
}
/* The tree gives up its growth while the empty message is on screen, so the message takes the place the rows had. */
.jbs-tree:has(+ .jbs-tree-empty:not([hidden])) { flex: none; }
.jbs-tree-empty {
    flex: none;
    margin: 0;
    /* The same 3 plus level times 16 the rows use, at level two, where both group and leaf labels land. */
    padding: 0 var(--jb-sp-3) var(--jb-sp-3) calc(3px + 2 * 16px);
    /* The same size as the rows it replaces, and as the pane's own empty and error lines. */
    font-size: var(--jb-t-3);
    color: var(--jb-fg-secondary);
}
/* The indent is computed: the chevron slot lands at 3 plus level times 16, and a leaf's label follows the missing chevron. */
.jbs-row {
    display: flex;
    align-items: center;
    width: 100%;
    height: var(--jb-row);
    padding: 0 var(--jb-sp-3) 0 calc(3px + var(--jbs-level, 1) * 16px);
    border: none;
    border-radius: 0;
    background: transparent;
    color: var(--jb-fg);
    font-size: var(--jb-t-3);
    font-weight: var(--jb-w-normal);
    line-height: var(--jb-lh-tight);
    text-align: left;
    cursor: default;
}
.jbs-row:hover { background: var(--jb-bg-hover); }
.jbs-row-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Inherited rather than fixed, so the chevron brightens on hover and turns with the row when the row is selected. */
.jbs-group-row { color: var(--jb-fg-icon); }
.jbs-group-row:hover { color: var(--jb-fg); }
.jbs-group-row .jbs-row-label { color: var(--jb-fg); }
.jbs-chevron {
    flex: none;
    width: var(--jb-icon);
    height: var(--jb-icon);
    color: inherit;
    transform: rotate(90deg);
}
.jbs-group-row[aria-expanded="false"] .jbs-chevron { transform: none; }
.jbs-group-row[aria-expanded="false"] + .jbs-children { display: none; }
/* The settings tree is the one list whose selection fills the column edge to edge; every other keeps the inset pill. */
/* Unfocused uses --jb-bg-selected, since the inactive token matches the light theme shell and would make the selected row invisible. */
.jbs-leaf-row.selected { background: var(--jb-bg-selected); }
.jbs-tree-pane:focus-within .jbs-leaf-row.selected {
    background: var(--jb-accent);
    color: var(--jb-fg-on-accent);
}
.jbs-tree-pane:focus-within .jbs-leaf-row.selected .jbs-badge {
    background: var(--jb-alpha-w-30);
    color: var(--jb-fg-on-accent);
}
.jbs-badge {
    flex: none;
    min-width: var(--jb-icon);
    height: var(--jb-icon);
    padding: 0 var(--jb-sp-1);
    display: grid;
    place-items: center;
    background: var(--jb-bg-raised);
    border-radius: var(--jb-r-sm);
    font-size: var(--jb-t-1);
    color: var(--jb-fg-secondary);
}

.jbs-content-pane {
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    background: var(--jb-bg-island);
}
/* The page's own header, taller than the 40px panel head, carrying the page name at heading size. */
.jbs-content-head {
    flex: none;
    display: flex;
    align-items: center;
    gap: var(--jb-sp-2);
    height: 48px;
    /* A panel header holds its title at the content's left inset and its actions 8px from the edge. */
    padding: 0 var(--jb-sp-2) 0 var(--jb-sp-5);
    border-bottom: 1px solid var(--jb-border);
}
/* The trail, not just the leaf: two categories are both called Danger zone. */
.jbs-content-title {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--jb-sp-1);
    font-size: var(--jb-t-3);
    overflow: hidden;
}
/* The category is context for the page name, one step down and secondary, with the page name carrying the weight. */
.jbs-crumb-group {
    flex: none;
    font-size: var(--jb-t-2);
    color: var(--jb-fg-secondary);
    white-space: nowrap;
}
.jbs-crumb-sep {
    flex: none;
    color: var(--jb-fg-icon);
}
/* A separator with nothing before it is a chevron floating at the header's left edge during the fetch. */
.jbs-crumb-group:empty + .jbs-crumb-sep { display: none; }
.jbs-crumb-leaf {
    min-width: 0;
    font-size: var(--jb-t-5);
    font-weight: var(--jb-w-semi);
    line-height: var(--jb-lh-tight);
    letter-spacing: normal;
    color: var(--jb-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.jbs-content-nav {
    display: flex;
    gap: var(--jb-sp-1);
}
.jbs-nav-btn,
.jbs-help {
    width: var(--jb-h-dense);
    height: var(--jb-h-dense);
    padding: 0;
    display: grid;
    place-items: center;
    background: transparent;
    color: var(--jb-fg-icon);
    transition: background-color var(--jb-dur-in) var(--jb-ease-in),
                color var(--jb-dur-in) var(--jb-ease-in);
}
.jbs-nav-btn {
    border: none;
    border-radius: var(--jb-r-md);
    cursor: default;
}
/* The help control is an anchor shaped as a control: boxed and 28 tall, because it stands beside Cancel, Apply and OK. */
.jbs-help {
    width: var(--jb-h-control);
    height: var(--jb-h-control);
    border: 1px solid var(--jb-border-control);
    border-radius: var(--jb-r-md);
    text-decoration: none;
    cursor: default;
}
.jbs-nav-btn:hover,
.jbs-help:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.jbs-help:hover { cursor: pointer; }
.jbs-nav-btn:active { background: var(--jb-bg-pressed); }
.jbs-nav-btn:disabled {
    background: transparent;
    color: var(--jb-fg-disabled);
}

.jbs-content-body {
    flex: 1;
    min-height: 0;
    padding: var(--jb-sp-4) var(--jb-sp-5);
    overflow-y: auto;
    overflow-x: hidden;
    /* The scrollbar is reserved on every page, or the right edge every control aligns to moves 11px. */
    scrollbar-gutter: stable;
    overscroll-behavior: contain;
}
.jbs-gate,
.jbs-load-error {
    margin: 0;
    font-size: var(--jb-t-3);
    line-height: var(--jb-lh-prose);
    color: var(--jb-fg-secondary);
}
.jbs-load-error { color: var(--jb-error); }

/* A confirmation raised from inside the dialog sits one step above the panel layer and carries its own wash. */
.jbs-confirm {
    position: fixed;
    inset: 0;
    z-index: calc(var(--jb-z-panel) + 2);
    display: grid;
    place-items: center;
    padding: var(--jb-sp-4);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--jb-dur-out) var(--jb-ease-out),
                visibility var(--jb-dur-out) var(--jb-ease-out);
}
.jbs-confirm::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--jb-backdrop-tint);
    backdrop-filter: blur(var(--jb-backdrop-blur));
    -webkit-backdrop-filter: blur(var(--jb-backdrop-blur));
}
.jbs-confirm.active {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition-duration: var(--jb-dur-in);
    transition-timing-function: var(--jb-ease-in);
}
.jbs-confirm-box {
    position: relative;
    width: min(400px, 100%);
    display: flex;
    flex-direction: column;
    background: var(--jb-bg-dialog);
    border: 1px solid var(--jb-border-island);
    border-radius: var(--jb-r-panel);
    box-shadow: var(--jb-shadow-dialog);
    overflow: hidden;
}
.jbs-confirm-body {
    padding: var(--jb-sp-4) var(--jb-sp-5);
    font-size: var(--jb-t-3);
    line-height: var(--jb-lh-prose);
    color: var(--jb-fg);
}
.jbs-confirm-body p { margin: 0; }
/* The cancel survey is the one confirmation with a form in it, so it takes the drawer's width rather than the sentence's. */
.jbs-confirm-box--wide { width: min(560px, 100%); }
.jbs-confirm-body .cancel-why, .jbs-confirm-body .app-form-group { margin-top: var(--jb-sp-4); }
.jbs-confirm .cancel-reasons {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--jb-sp-4);
    margin-top: var(--jb-sp-2);
    padding: 0;
    background: none;
    border: none;
}
.jbs-confirm .cancel-reasons input {
    appearance: none;
    /* 18 is the shipping checkbox geometry, and the box sits outside the dialog that declares --jbs-check. */
    width: 18px;
    height: 18px;
    min-width: 18px;
    margin: 0;
    border: 1px solid var(--jb-border-control);
    border-radius: 50%;
    background: var(--jb-bg-inset);
}
.jbs-confirm .cancel-reasons label { font-weight: var(--jb-w-normal); }
.jbs-confirm .cancel-reasons input:hover { border-color: var(--jb-border-raised); }
.jbs-confirm .cancel-reasons input:checked { border: 4px solid var(--jb-accent); }
.jbs-confirm .cancel-reasons input:focus-visible { outline: 2px solid var(--jb-focus); outline-offset: -1px; }
.jbs-confirm-body .form-textarea { width: 100%; min-height: 0; margin-top: var(--jb-sp-1); }
@media (max-width: 600px) {
    .jbs-confirm .cancel-reasons { grid-template-columns: 1fr; }
}

/* The injected settings sections, corrected for geometry, type and grouping: two type sizes, one field width, and nothing leaking outside the dialog. */
/* The label column belongs to the page, declared here and borrowed by every section through subgrid, so the page has one left edge. */
.jb-settings-dialog .jbs-content-body {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    align-content: start;
    /* 18 and 5 are the shipping checkbox geometry from 04-app-components.md, not spacing scale values to be rounded. */
    --jbs-check: 18px;
    --jbs-gap: 5px;
    /* Where a checkbox row's label starts, and so where a dependent row indents to: 18 minus 1 plus 5 equals 22. */
    --jbs-nest: calc(var(--jbs-check) - 1px + var(--jbs-gap));
}

/* Grouping is whitespace: a label column, a control column and an optional comment, built with a grid rather than margins. */
/* The fetched fragment's root is a data holder, not a box, so it steps aside and the sections become the grid's children. */
.jb-settings-dialog .settings-fragment-root { display: contents; }
.jb-settings-dialog .jbs-content-body > *,
.jb-settings-dialog .settings-fragment-root > * { grid-column: 1 / -1; }
.jb-settings-dialog .app-section {
    display: grid;
    grid-template-columns: subgrid;
    column-gap: var(--jb-sp-3);
    /* Grid items do not collapse margins, so vertical spacing is declared once on the top of the thing that needs it. */
    row-gap: 0;
    align-items: start;
    margin: 0 0 var(--jb-sp-5);
    padding: 0;
    background: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
    transition: none;
    animation: none;
}
/* Anything that is not a label or its control owns the full width, wherever the wrappers leave it. */
.jb-settings-dialog .app-section > *,
.jb-settings-dialog .roadmap-only-appearance > *,
.jb-settings-dialog .settings-password-block > *,
.jb-settings-dialog .settings-subform > * { grid-column: 1 / -1; }
/* The wrappers hold script state rather than layout, so they step aside and their rows join the section's grid. */
.jb-settings-dialog .app-form-group,
.jb-settings-dialog .roadmap-only-appearance,
.jb-settings-dialog .settings-password-block,
.jb-settings-dialog .settings-subform { display: contents; }
.jb-settings-dialog .app-form-group > label {
    grid-column: 1;
    justify-self: start;
    /* Optical centring against a 28px control: the label's 18px line box needs 5px above to sit on the field's text. */
    padding-top: 5px;
}
.jb-settings-dialog .app-form-group > :not(label) { grid-column: 2; }
/* A field row and its label open together, 8 below whatever came before. */
.jb-settings-dialog .app-form-group > label,
.jb-settings-dialog .app-form-group > label + * { margin-top: var(--jb-sp-2); }
/* An error belongs to the field above it and sits against it. */
.jb-settings-dialog .app-form-group > .field-error { margin-top: var(--jb-sp-1); }
/* The trailing margin of whatever ends a section does not add itself to the gap the section already carries. */
.jb-settings-dialog .app-section > :last-child { margin-bottom: 0; }

/* The pane header already names the page, with the category in front, which a section heading cannot do. */
.jb-settings-dialog .app-section-title { display: none; }
/* A page carrying more than one section needs them named again; settings_dialog.js sets the class when it counts two. */
/* The title always opens its section, so the break between sections is the section's own. */
.jb-settings-dialog .jbs-multi .app-section-title { display: flex; margin: 0; }
/* Spacing goes on the bottom, since a hidden section still matches the sibling combinator and would push the first visible one down. */
.jb-settings-dialog .jbs-multi .app-section { margin-bottom: var(--jb-sp-6); }
/* settings_dialog.js marks the last section on screen, because :last-child would match whichever one happens to end the markup. */
.jb-settings-dialog .app-section.jbs-last,
.jb-settings-dialog .jbs-multi .app-section.jbs-last { margin-bottom: 0; }
/* Tinted icon chips on form headings are decoration, and the IDE's own settings headings carry none. */
.jb-settings-dialog .section-icon { display: none; }

/* The IDE's titled separator announces every group: a name, then a rule to the pane edge, drawn identically at both levels. */
.jb-settings-dialog .jbs-multi .app-section-title,
.jb-settings-dialog .subsection-heading,
.jb-settings-dialog .subsection-heading-spaced {
    display: flex;
    align-items: center;
    /* The title is one phrase split across spans, so the gap between them reads as a word space. */
    gap: var(--jb-sp-1);
    font-size: var(--jb-t-3);
    font-weight: var(--jb-w-semi);
    line-height: var(--jb-lh-tight);
    /* The legacy sheet tracks headings at -0.02em, which at 13px makes a heading read as a different typeface from its label. */
    letter-spacing: normal;
    color: var(--jb-fg);
}
.jb-settings-dialog .jbs-multi .app-section-title::after,
.jb-settings-dialog .subsection-heading::after,
.jb-settings-dialog .subsection-heading-spaced::after {
    content: "";
    flex: 1;
    height: 1px;
    margin-left: var(--jb-sp-2);
    background: var(--jb-border);
}
.jb-settings-dialog .app-section-description,
.app-section-description {
    margin: var(--jb-sp-2) 0 0;
    font-size: var(--jb-t-2);
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-secondary);
}
/* A danger zone is drawn as a bounded thing, so the border says where the danger starts and stops. */
/* The box has padding of its own, so it measures its one label itself rather than borrowing the page's columns. */
.jb-settings-dialog .danger-zone {
    grid-template-columns: max-content minmax(0, 1fr);
    padding: var(--jb-sp-4);
    border: 1px solid var(--jb-error-border);
    border-radius: var(--jb-r-md);
}
/* The heading carried the warning colour before it was hidden, so the lead line takes it over. */
.jb-settings-dialog .danger-zone .app-section-description { color: var(--jb-error); }
.jb-settings-dialog .danger-text { color: var(--jb-error); }
/* Inline code is a small radius surface, and one of two places the mono face belongs. */
.jb-settings-dialog .code-inline {
    padding: 0 var(--jb-sp-1);
    border-radius: var(--jb-r-sm);
    background: var(--jb-bg-inset);
    font-family: var(--jb-font-mono);
    font-size: var(--jb-t-2);
}
/* The dirty marker goes: it hangs off a section heading that six of the ten pages hide, and Apply already says the same. */
.jb-settings-dialog .unsaved-dot { display: none; }

/* Whether a group heading opens a section or follows one, the break above it is the same 24. */
.jb-settings-dialog .subsection-heading,
.jb-settings-dialog .subsection-heading-spaced {
    margin: var(--jb-sp-5) 0 0;
    padding: 0;
    border: none;
}

/* Four breaks and every gap is one of them: 0 in a list, 4 for help, 8 between rows, 24 before a group. */

.jb-settings-dialog .settings-form-row { gap: var(--jb-sp-2); }
.jb-settings-dialog .app-form-group label,
.jb-settings-dialog .color-picker-item label,
.app-form-group label {
    margin-bottom: 0;
    font-size: var(--jb-t-3);
    font-weight: var(--jb-w-normal);
    /* Every label, heading and help line is set, or a 13px label inherits the body's 1.5 and leaves its field's text. */
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg);
}
/* The colon is what tells the eye where the field's name stops and its value starts. */
.jb-settings-dialog .app-form-group > label::after,
.jb-settings-dialog .invite-link-generator-label::after { content: ":"; }
.jb-settings-dialog .color-picker-item label {
    display: block;
    margin-bottom: var(--jb-sp-1);
}
/* A help line introducing what follows opens 8 below its heading; one explaining the control above sits 4 under it. */
.jb-settings-dialog .help-text,
.jb-settings-dialog .help-text-indent,
.help-text {
    margin: var(--jb-sp-2) 0 0;
    font-size: var(--jb-t-2);
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-secondary);
    opacity: 1;
}
.jb-settings-dialog .app-form-group > .help-text,
.jb-settings-dialog .checkbox-group + .help-text,
.jb-settings-dialog .checkbox-group > .help-text-indent { margin-top: var(--jb-sp-1); }
.app-toggle-row {
    display: inline-flex;
    align-items: center;
    gap: var(--jb-sp-3);
    margin-top: var(--jb-sp-1);
}
.app-toggle-row .help-text { margin: 0; }
.app-field-row { display: flex; gap: var(--jb-sp-2); }
.app-field-row .form-input { flex: 1; }
/* Anything that is a block rather than a row opens 8 below what came before it. */
.jb-settings-dialog .settings-card-list,
.jb-settings-dialog .settings-tag-list,
.jb-settings-dialog .invite-link-generator,
.jb-settings-dialog .billing-plan-card,
.jb-settings-dialog .color-picker-grid { margin-top: var(--jb-sp-2); }
.jb-settings-dialog .help-text-indent,
.jb-settings-dialog .checkbox-group .help-text-indent { margin-left: var(--jbs-nest); }
.field-error {
    margin: var(--jb-sp-2) 0 0;
    font-size: var(--jb-t-2);
    color: var(--jb-error);
}

.jb-settings-dialog .app-text-input,
.jb-settings-dialog .color-text-input,
.jb-settings-dialog .toolbar-select,
.app-text-input {
    height: var(--jb-h-control);
    border-color: var(--jb-border-control);
    font-size: var(--jb-t-3);
}
/* The New UI field inset; the extra 3px on the left is what makes a JetBrains field read as centred. */
.jb-settings-dialog .app-text-input,
.jb-settings-dialog .color-text-input,
.app-text-input { padding: 2px 6px 2px 9px; }
/* A select that is a form field fills the column; one sitting inside a row is sized by its content. */
.jb-settings-dialog .toolbar-select {
    width: auto;
    min-width: 160px;
    max-width: 100%;
    padding: 0 var(--jb-sp-6) 0 9px;
    background-size: var(--jb-icon);
    background-position: right var(--jb-sp-2) center;
    cursor: default;
}
/* Every control fills its column to the pane's right inset, because the pane is already the measure inside a fixed width dialog. */
.jb-settings-dialog .app-form-group .app-text-input,
.jb-settings-dialog .app-form-group .toolbar-select { width: 100%; max-width: none; }
/* The one field sized to its content: it accepts a single known word, and the full column invited a sentence. */
.jb-settings-dialog .danger-zone .app-form-group .app-text-input { max-width: 160px; }
.jb-settings-dialog .settings-textarea,
.share-page .settings-textarea {
    min-height: 88px;
    max-width: none;
    padding: 6px 9px;
    border-color: var(--jb-border-control);
    font-size: var(--jb-t-3);
    line-height: var(--jb-lh-prose);
}
/* A field is a block, or it sits on the line box's baseline and leaves the descender gap below itself. */
.jb-settings-dialog .app-form-group > .app-text-input,
.jb-settings-dialog .app-form-group > .settings-textarea,
.jb-settings-dialog .app-form-group > .toolbar-select,
.share-page .app-text-input,
.share-page .settings-textarea { display: block; }
/* A field the user cannot edit reads as disabled text on the canvas, not as an editable field behind a veil. */
.jb-settings-dialog .input-disabled {
    background: var(--jb-bg-canvas);
    color: var(--jb-fg-disabled);
    opacity: 1;
    cursor: default;
}
/* The select already answers the pointer on hover, so a text field that does not is the odd one out. */
.jb-settings-dialog .app-text-input:hover:not(:disabled),
.jb-settings-dialog .settings-textarea:hover:not(:disabled),
.share-page .settings-textarea:hover:not(:disabled),
.jb-settings-dialog .color-text-input:hover:not(:disabled),
.jb-settings-dialog .color-input-wrapper input[type="color"]:hover,
.app-text-input:hover:not(:disabled) {
    border-color: var(--jb-border-raised);
}
.jb-settings-dialog .app-text-input:focus,
.jb-settings-dialog .settings-textarea:focus,
.share-page .settings-textarea:focus,
.jb-settings-dialog .color-text-input:focus,
.jb-settings-dialog .toolbar-select:focus,
.app-text-input:focus {
    border-color: transparent;
    box-shadow: none;
    outline: 2px solid var(--jb-focus);
    outline-offset: -1px;
}
/* Disabled is a colour, never a veil, or the control stops looking like a control at all. */
.jb-settings-dialog .app-text-input:disabled,
.jb-settings-dialog .settings-textarea:disabled,
.share-page .settings-textarea:disabled,
.jb-settings-dialog .color-text-input:disabled,
.jb-settings-dialog .toolbar-select:disabled,
.jb-settings-dialog .checkbox-group input[type="checkbox"]:disabled,
.app-text-input:disabled {
    background: var(--jb-bg-canvas);
    border-color: var(--jb-border);
    color: var(--jb-fg-disabled);
    opacity: 1;
}
.jb-settings-dialog .checkbox-group:has(input:disabled) label { color: var(--jb-fg-disabled); }
/* The confirmation field turns red once the word matches, without the legacy glow, which this system reserves for focus. */
.jb-settings-dialog .app-text-input.delete-input-valid,
.app-text-input.delete-input-valid {
    border-color: var(--jb-error);
    box-shadow: none;
}

/* --- Checkbox rows ------------------------------------------------------- */

.jb-settings-dialog .checkbox-group label,
.checkbox-group label {
    min-height: var(--jb-row);
    gap: var(--jbs-gap, 5px);
    cursor: default;
}
.jb-settings-dialog .checkbox-group input[type="checkbox"], .plan-page .checkbox-group input[type="checkbox"] { cursor: default; }
.jb-settings-dialog .checkbox-group input[type="checkbox"], .plan-page .checkbox-group input[type="checkbox"] {
    width: var(--jbs-check);
    height: var(--jbs-check);
    min-width: var(--jbs-check);
    border: 1px solid var(--jb-border-control);
    border-radius: var(--jb-r-sm);
    /* The same surface as the text fields beside it, matching this project's legacy fields rather than the reference token. */
    background: var(--jb-bg-inset);
    box-shadow: none;
}
.jb-settings-dialog .checkbox-group input[type="checkbox"]:hover, .plan-page .checkbox-group input[type="checkbox"]:hover {
    border-color: var(--jb-border-raised);
    box-shadow: none;
}
.jb-settings-dialog .checkbox-group input[type="checkbox"]:checked, .plan-page .checkbox-group input[type="checkbox"]:checked {
    background: var(--jb-accent);
    border-color: var(--jb-accent);
    box-shadow: none;
}
.jb-settings-dialog .checkbox-group input[type="checkbox"]:focus-visible, .plan-page .checkbox-group input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--jb-focus);
    outline-offset: -1px;
}
/* The tick appears with the box's fill in one frame, rather than scaling up like a toggle. */
.jb-settings-dialog .checkbox-group input[type="checkbox"]::after, .plan-page .checkbox-group input[type="checkbox"]::after { transition: none; }
.jb-settings-dialog .checkbox-group input[type="checkbox"]:checked::after, .plan-page .checkbox-group input[type="checkbox"]:checked::after {
    border-color: var(--jb-fg-on-accent);
}
/* A checkbox list is one control, so only the row opening a run takes the 8px break. */
.jb-settings-dialog .checkbox-group { margin-top: var(--jb-sp-2); }
.jb-settings-dialog .checkbox-group + .checkbox-group { margin-top: 0; }
/* The indent already says the rows are dependent, so the group adds no break on either side of itself. */
.jb-settings-dialog .checkbox-subgroup { margin: 0 0 0 var(--jbs-nest); }
.jb-settings-dialog .checkbox-subgroup + .checkbox-group { margin-top: 0; }
/* A tag list is data, so it gets the IDE's bordered scroll box and cannot bury the save button. */
.jb-settings-dialog .settings-tag-list {
    max-height: 168px;
    padding: var(--jb-sp-1) var(--jb-sp-2);
    overflow-y: auto;
    overscroll-behavior: contain;
    border: 1px solid var(--jb-border);
    border-radius: var(--jb-r-md);
    background: var(--jb-bg-inset);
}

/* Every button in the pane is 28 tall, 72 wide minimum, 13px, with a background hover and disabled as a colour. */

/* Apply owns saving and reports progress in the footer, so a second spinner would answer the same question twice. */
.jb-settings-dialog .share-btn.saving::after { display: none; }
/* An icon only button is square; the 72px minimum is for buttons carrying a word. */
.jb-settings-dialog .copy-link-btn {
    width: var(--jb-h-control);
    min-width: var(--jb-h-control);
    padding: 0;
}
.jb-settings-dialog .copy-link-btn.copied {
    border-color: var(--jb-success);
    color: var(--jb-success);
}
.jb-settings-dialog .share-btn[aria-disabled="true"]:hover { background: var(--jb-bg-hover); }
/* One primary per dialog, and it is OK in the footer, so every button inside the pane is neutral. */
.jb-settings-dialog .app-section a.share-btn,
.jb-settings-dialog .app-section .share-btn-primary {
    background: var(--jb-bg-raised);
    border-color: var(--jb-border-control);
    color: var(--jb-fg);
}
/* Apply and OK own saving, so settings_dialog.js marks the per section save buttons from the ids VFSettings publishes. */
.jb-settings-dialog .jbs-hidden-save { display: none; }
/* One gap between buttons, whichever row they sit in; these two were 8 and 12. */
.jb-settings-dialog .section-actions,
.jb-settings-dialog .section-actions-row,
.jb-settings-dialog .export-buttons {
    gap: var(--jb-sp-2);
    margin-top: var(--jb-sp-4);
}
/* A row whose only buttons are the hidden per section saves is not a row, and stops claiming its top margin. */
.jb-settings-dialog .section-actions:not(:has(.share-btn:not(.jbs-hidden-save))),
.jb-settings-dialog .section-actions-row:not(:has(.share-btn:not(.jbs-hidden-save))) {
    display: none;
}

/* A settings list is the one place the IDE draws a box, with rows separated by a hairline rather than carded. */
.jb-settings-dialog .settings-card-list:has(.member-card),
.jb-settings-dialog .settings-card-list:has(.invite-link-card) {
    border: 1px solid var(--jb-border);
    border-radius: var(--jb-r-md);
    overflow: hidden;
}
.jb-settings-dialog .member-card,
.jb-settings-dialog .invite-link-card {
    /* A row holding a 28px control and one holding only text are the same height, or the list looks hand assembled. */
    min-height: calc(var(--jb-h-control) + var(--jb-sp-4));
    gap: var(--jb-sp-2);
    padding: var(--jb-sp-2) var(--jb-sp-3);
    background: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
    transform: none;
    animation: none;
    transition: background-color var(--jb-dur-in) var(--jb-ease-in);
}
.jb-settings-dialog .member-card + .member-card,
.jb-settings-dialog .invite-link-card + .invite-link-card {
    border-top: 1px solid var(--jb-border);
}
.jb-settings-dialog .member-card:hover,
.jb-settings-dialog .invite-link-card:hover {
    background: var(--jb-bg-hover);
    border-color: var(--jb-border);
    box-shadow: none;
    transform: none;
}
.jb-settings-dialog .member-card-left { gap: var(--jb-sp-2); }
/* A list has columns, so the role control and the action beside it are placed by column rather than from the right edge. */
.jb-settings-dialog .member-actions {
    display: grid;
    grid-template-columns: 132px auto;
    align-items: center;
    justify-items: start;
    gap: var(--jb-sp-2);
}
.jb-settings-dialog .member-role-select { width: 100%; min-width: 0; }
/* One chip for every member, instead of hashing each name onto one of eight saturated literals that ignored the theme. */
.jb-settings-dialog .member-avatar {
    width: 24px;
    height: 24px;
    background: var(--jb-bg-hover);
    font-size: var(--jb-t-1);
    font-weight: var(--jb-w-medium);
    color: var(--jb-fg-secondary);
}
/* Name, address and join date are one line of a list row, wrapping only when the pane is genuinely narrow. */
.jb-settings-dialog .member-info {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: var(--jb-sp-2);
    row-gap: var(--jb-sp-1);
}
.jb-settings-dialog .member-name {
    font-size: var(--jb-t-3);
    font-weight: var(--jb-w-normal);
    color: var(--jb-fg);
}
.jb-settings-dialog .member-email,
.jb-settings-dialog .member-meta,
.jb-settings-dialog .invite-link-date {
    margin-top: 0;
    font-size: var(--jb-t-2);
    color: var(--jb-fg-secondary);
}
.jb-settings-dialog .member-actions { gap: var(--jb-sp-2); }
.jb-settings-dialog .member-role-select { min-width: 110px; }
.jb-settings-dialog .invite-link-url-row { gap: var(--jb-sp-2); }
.jb-settings-dialog .invite-link-url {
    padding: 0;
    background: none;
    font-size: var(--jb-t-2);
    color: var(--jb-fg-secondary);
}
.jb-settings-dialog .invite-link-meta { gap: var(--jb-sp-2); font-size: var(--jb-t-2); }
.jb-settings-dialog .invite-link-generator { gap: var(--jb-sp-2); margin-bottom: 0; }
.jb-settings-dialog .member-you-badge,
.jb-settings-dialog .member-count-badge,
.jb-settings-dialog .role-badge {
    padding: 0 var(--jb-sp-1);
    border: none;
    border-radius: var(--jb-r-sm);
    font-size: var(--jb-t-1);
    font-weight: var(--jb-w-normal);
    line-height: 18px;
    letter-spacing: normal;
}
/* A badge that only labels its own row carries no colour, since marking yourself and counting the list are facts. */
.jb-settings-dialog .member-you-badge,
.jb-settings-dialog .member-count-badge {
    background: var(--jb-bg-hover);
    color: var(--jb-fg-secondary);
}
.jb-settings-dialog .member-you-badge,
.jb-settings-dialog .member-count-badge {
    margin-left: 0;
    text-transform: none;
}
/* The legacy role colours are dark theme literals, so this is one chip with three text colours instead. */
.jb-settings-dialog .role-badge {
    background: var(--jb-bg-hover);
    color: var(--jb-fg-secondary);
}
.jb-settings-dialog .role-owner { color: var(--jb-warning); }
.jb-settings-dialog .role-editor { color: var(--jb-accent); }
/* An empty list is a sentence, not a dashed box with an icon in it. */
.jb-settings-dialog .share-empty-state {
    align-items: flex-start;
    gap: var(--jb-sp-1);
    padding: 0;
    border: none;
    text-align: left;
    font-size: var(--jb-t-2);
}
.jb-settings-dialog .share-empty-state-icon { display: none; }
.jb-settings-dialog .share-empty-state-title {
    font-size: var(--jb-t-3);
    font-weight: var(--jb-w-normal);
    color: var(--jb-fg);
}
.jb-settings-dialog .share-empty-state-desc {
    max-width: none;
    font-size: var(--jb-t-2);
}

/* --- Billing -------------------------------------------------------------- */

.jb-settings-dialog .billing-plan-card, .plan-page .billing-plan-card {
    gap: var(--jb-sp-3);
    padding: 0;
    background: none;
    border: none;
    border-radius: 0;
}
.jb-settings-dialog .billing-plan-name, .plan-page .billing-plan-name {
    font-size: var(--jb-t-3);
    font-weight: var(--jb-w-medium);
    color: var(--jb-fg);
}
/* The badge and the plan name are the same word on the same row, and the name reads as a sentence. */
.jb-settings-dialog .billing-plan-badge-area { display: none; }
.jb-settings-dialog .billing-plan-desc, .plan-page .billing-plan-desc,
.jb-settings-dialog .billing-plan-status, .plan-page .billing-plan-status {
    margin-top: var(--jb-sp-1);
    font-size: var(--jb-t-2);
    color: var(--jb-fg-secondary);
}
.jb-settings-dialog .billing-plan-status.billing-status-warning { color: var(--jb-warning); }

/* --- Appearance ----------------------------------------------------------- */

.jb-settings-dialog .color-picker-grid {
    max-width: 100%;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--jb-sp-3);
}
.jb-settings-dialog .color-input-wrapper { gap: var(--jb-sp-2); }
/* The font stack and the radius have no swatch, so they take the full width rather than leaving a hole. */
.jb-settings-dialog .color-picker-item:not(:has(input[type="color"])) .color-text-input,
.jb-settings-dialog .color-picker-item:not(:has(input[type="color"])) .toolbar-select {
    flex: 1;
    min-width: 0;
    max-width: none;
}
.jb-settings-dialog .color-input-wrapper input[type="color"] {
    width: var(--jb-h-control);
    height: var(--jb-h-control);
    border-color: var(--jb-border-control);
    border-radius: var(--jb-r-md);
}
/* A hex value, a font stack and a radius are data; nothing else in the pane takes the mono face. */
.jb-settings-dialog .color-text-input { font-family: var(--jb-font-mono); }
.jb-settings-dialog select.color-text-input { font-family: var(--jb-font); }
.jb-settings-dialog .field-reset-btn {
    width: var(--jb-h-control);
    height: var(--jb-h-control);
    border-color: var(--jb-border-control);
    border-radius: var(--jb-r-md);
    color: var(--jb-fg-icon);
    opacity: 1;
    cursor: default;
}
.jb-settings-dialog .field-reset-btn svg {
    width: var(--jb-icon);
    height: var(--jb-icon);
}
/* 400ms of spin is three times the interaction budget, and the field's value visibly changes on its own. */
.jb-settings-dialog .field-reset-btn.resetting svg { animation: none; }
/* The legacy transition lists colour and border but not background, so the fill snapped in while the glyph faded. */
.jb-settings-dialog .field-reset-btn {
    transition: background-color var(--jb-dur-in) var(--jb-ease-in),
                border-color var(--jb-dur-in) var(--jb-ease-in),
                color var(--jb-dur-in) var(--jb-ease-in);
}
.jb-settings-dialog .field-reset-btn:hover {
    background: var(--jb-bg-hover);
    border-color: var(--jb-border-raised);
    color: var(--jb-fg);
}
.jb-settings-dialog .field-reset-btn:active { background: var(--jb-bg-pressed); }
.jb-settings-dialog .appearance-preview {
    max-width: 100%;
    margin-top: var(--jb-sp-5);
}
.jb-settings-dialog .appearance-preview-grid { gap: var(--jb-sp-3); }
/* The preview is a scale model of the customer's public card, so it keeps that card's type and spacing but not its hover lift. */
.jb-settings-dialog .preview-card {
    transition: none;
    transform: none;
}
.jb-settings-dialog .preview-card:hover {
    transform: none;
    box-shadow: none;
}
/* Preview is a subsection heading; Dark and Light are captions, and all three start at the left edge like every other line. */
.jb-settings-dialog .appearance-preview-label {
    margin: 0 0 var(--jb-sp-3);
    font-size: var(--jb-t-3);
    font-weight: var(--jb-w-medium);
    line-height: var(--jb-lh-tight);
    letter-spacing: normal;
    text-transform: none;
    color: var(--jb-fg);
}
.jb-settings-dialog .preview-mode-label {
    margin: 0 0 var(--jb-sp-2);
    font-size: var(--jb-t-2);
    font-weight: var(--jb-w-normal);
    letter-spacing: normal;
    text-transform: none;
    text-align: left;
    color: var(--jb-fg-secondary);
}
.jb-settings-dialog .appearance-target-bar, .plan-page .appearance-target-bar {
    align-items: center;
    gap: var(--jb-sp-1);
    margin: 0 0 var(--jb-sp-2);
}
/* Two unlabelled pills do not say what they restyle, so the bar names itself. */
.jb-settings-dialog .appearance-target-label, .plan-page .appearance-target-label {
    margin-right: var(--jb-sp-2);
    font-size: var(--jb-t-3);
    color: var(--jb-fg-secondary);
}
/* The role select in the invite row is a field with a label, so the two sit on one line. */
.jb-settings-dialog .invite-link-generator { align-items: center; }
.jb-settings-dialog .invite-link-generator-label {
    font-size: var(--jb-t-3);
    color: var(--jb-fg);
}
.jb-settings-dialog .appearance-target-pill, .plan-page .appearance-target-pill {
    height: var(--jb-tab-pill-h);
    padding: 0 var(--jb-sp-3);
    border: none;
    font-size: var(--jb-t-3);
    color: var(--jb-fg-secondary);
    cursor: default;
    /* A tab strip switches instantly, and inner-index declares a 120ms cross fade here, so the reset is explicit. */
    transition: none;
}
.jb-settings-dialog .appearance-target-pill:hover, .plan-page .appearance-target-pill:hover {
    background: var(--jb-tab-hover-bg);
    color: var(--jb-fg);
}
.jb-settings-dialog .appearance-target-pill:active, .plan-page .appearance-target-pill:active { background: var(--jb-bg-pressed); }
.jb-settings-dialog .appearance-target-pill.active, .plan-page .appearance-target-pill.active {
    background: var(--jb-tab-selected-bg);
    box-shadow: inset 0 0 0 1px var(--jb-tab-selected-border);
    color: var(--jb-fg);
}

/* Every control that answers a hover answers a press, and every control that is not a link uses the arrow. */

.jb-settings-dialog .modal-close:active,
.jbs-confirm .modal-close:active,
.jbs-help:active,
.jbs-row:active { background: var(--jb-bg-pressed); }

.jb-settings-dialog .modal-close,
.jbs-confirm .modal-close,
.jb-settings-dialog a.share-btn,
.jb-settings-dialog .share-btn:disabled,
.jb-settings-dialog .color-input-wrapper input[type="color"] { cursor: default; }

@media (min-width: 769px) and (max-width: 1100px) {
    .jb-settings-dialog { width: 90vw; }
    .jbs-body { grid-template-columns: 180px minmax(0, 1fr); }
}

@media (max-width: 768px) {
    .jb-settings-dialog {
        margin: 0;
        width: auto;
        height: auto;
        border: none;
        border-radius: 0;
        /* Full bleed, so there is no edge for a shadow to fall from. */
        box-shadow: none;
    }
    html.is-demo .jb-settings-dialog { top: var(--demo-banner-h, 40px); }
    /* The column becomes a strip: the groups collapse and their leaves line up as one scrollable row of chips. */
    .jbs-body {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto minmax(0, 1fr);
    }
    .jbs-tree-pane {
        border-right: none;
        border-bottom: 1px solid var(--jb-border);
    }
    .jbs-search { max-width: none; }
    /* inner-index stacks the footer below 640px, but three 72px buttons fit on one row at every width this dialog supports. */
    .jb-settings-dialog .jbs-footer {
        flex-direction: row;
        padding: var(--jb-sp-3) var(--jb-sp-4);
    }
    /* The strip's scrollbar is hidden, its ends fade under a mask, and a chip stops a gutter short of the edge. */
    .jbs-tree {
        flex: none;
        display: flex;
        align-items: center;
        gap: var(--jb-sp-1);
        padding: 0 var(--jb-sp-3) var(--jb-sp-3);
        overflow-x: auto;
        overflow-y: hidden;
        scroll-padding: 0 var(--jb-sp-3);
        scrollbar-width: none;
        mask-image: linear-gradient(to right, transparent, rgb(0 0 0) var(--jb-sp-3), rgb(0 0 0) calc(100% - var(--jb-sp-3)), transparent);
    }
    .jbs-tree::-webkit-scrollbar { display: none; }
    .jbs-group,
    .jbs-children,
    .jbs-group-row[aria-expanded="false"] + .jbs-children { display: contents; }
    .jbs-group-row { display: none; }
    .jbs-row {
        flex: none;
        width: auto;
        height: var(--jb-h-control);
        padding: 0 var(--jb-sp-3);
        border-radius: var(--jb-r-lg);
    }
    .jbs-row-label { flex: none; }
    .jbs-leaf-row.selected,
    .jbs-tree-pane:focus-within .jbs-leaf-row.selected {
        background: var(--jb-tab-selected-bg);
        box-shadow: inset 0 0 0 1px var(--jb-tab-selected-border);
    }
    /* The strip already names the page and is one tap from any other, so the history arrows go and the trail takes the width. */
    .jbs-content-nav { display: none; }
    .jbs-content-head { padding: 0 var(--jb-sp-4); }
    .jbs-content-body { padding: var(--jb-sp-4); }
    /* A sheet cannot hold a label column beside a field, so the label goes above it and the pane is one column. */
    .jb-settings-dialog .jbs-content-body,
    .jb-settings-dialog .app-section,
    .jb-settings-dialog .danger-zone { grid-template-columns: minmax(0, 1fr); }
    .jb-settings-dialog .app-form-group > label {
        grid-column: 1;
        padding-top: 0;
    }
    /* The colon says the value follows on the same line, which above its field it does not. */
    .jb-settings-dialog .app-form-group > label::after { content: none; }
    .jb-settings-dialog .app-form-group > :not(label) { grid-column: 1; }
    .jb-settings-dialog .app-form-group > label + * { margin-top: var(--jb-sp-1); }
    /* Two preview cards side by side at sheet width are two crushed cards. */
    .jb-settings-dialog .appearance-preview-grid { grid-template-columns: minmax(0, 1fr); }
    /* The label takes its own line here, so the board pills wrap against the same left edge as everything else. */
    .jb-settings-dialog .appearance-target-bar {
        flex-wrap: wrap;
        row-gap: var(--jb-sp-1);
    }
    .jb-settings-dialog .appearance-target-label {
        flex: 1 0 100%;
        margin: 0;
    }
    /* The legacy sheet stacks these into columns below 768px, which stretches a 72px button to the sheet width. They stay rows. */
    .jb-settings-dialog .member-card,
    .jb-settings-dialog .invite-link-generator {
        flex-direction: row;
        align-items: center;
    }
    .jb-settings-dialog .member-actions { margin-top: 0; }
}

/* Density stays and the hit area grows: only the fixed size icon buttons need the reach at this width. */
@media (pointer: coarse) {
    .jbs-nav-btn,
    .jbs-help,
    .jb-settings-dialog .modal-close,
    .jbs-confirm .modal-close { position: relative; }
    .jbs-nav-btn::after {
        content: "";
        position: absolute;
        inset: calc((var(--jb-h-dense) - var(--jb-tap-min, 44px)) / 2);
    }
    .jbs-help::after,
    .jb-settings-dialog .modal-close::after,
    .jbs-confirm .modal-close::after {
        content: "";
        position: absolute;
        inset: calc((var(--jb-h-control) - var(--jb-tap-min, 44px)) / 2);
    }
}

/* The board lite view at 768 and below: both boards become sections of single line rows opening the same drawer, with onboarding left out. */

.lite-notice { display: none; }

@media (max-width: 768px) {
    /* One line of explanation sized like a toolbar row, so dismissing it is a courtesy rather than a relief. */
    .lite-notice {
        display: flex;
        align-items: center;
        gap: var(--jb-sp-2);
        min-height: 28px;
        margin-top: 8px;
        margin-bottom: var(--jb-island-gap);
        padding: var(--jb-sp-1) var(--jb-sp-1) var(--jb-sp-1) var(--jb-sp-2);
        background: var(--jb-info-bg);
        border: 1px solid var(--jb-info-border);
        border-radius: var(--jb-r-panel);
    }
    .lite-notice[hidden] { display: none; }
    .lite-notice-icon {
        flex-shrink: 0;
        color: var(--jb-fg-secondary);
    }
    .lite-notice-text {
        flex: 1;
        min-width: 0;
        margin: 0;
        font-size: 12px;
        line-height: var(--jb-lh-ui);
        color: var(--jb-fg-secondary);
    }
    .lite-notice-text strong {
        font-weight: var(--jb-w-semi);
        color: var(--jb-fg);
    }
    .lite-notice-close {
        flex-shrink: 0;
        display: grid;
        place-items: center;
        width: 22px;
        height: 22px;
        padding: 0;
        background: transparent;
        border: none;
        border-radius: var(--jb-r-sm);
        color: var(--jb-fg-tertiary);
    }
    .lite-notice-close:active {
        background: var(--jb-bg-pressed);
        color: var(--jb-fg);
    }

    /* One tinted strip at this width, so the onboarding goes and the last line releases the hold on the revenue chips. */
    .board-page .sample-banner,
    .gs-panel,
    .top-bar-tools > .ob-open { display: none; }

    /* Controls that only mean something against the full board, including the custom board's column renaming, deleting and adding. */
    .board-page .bulk-select-btn,
    .board-page .tag-manage-btn,
    .board-page .card-guide-btn,
    .board-page .add-column-btn,
    .board-page .column-header-actions,
    .board-page .feature-card-new,
    .board-page .roadmap-bottom-bar.jb-statusbar { display: none; }

    /* Each section is an island with an 8px inset on all four sides, its header inside that inset and 4px between rows. */
    .board-page .roadmap-container {
        display: flex;
        flex-direction: column;
        gap: var(--jb-island-gap);
        overflow: visible;
        scroll-snap-type: none;
        min-height: 0;
    }
    .board-page .kanban-column {
        width: auto !important;
        min-width: 0 !important;
        min-height: 0;
        padding: var(--jb-sp-2);
    }
    .board-page .column-header {
        min-height: 0;
        height: 24px;
        margin: 0 0 var(--jb-sp-1);
        padding: 0 var(--jb-sp-1);
    }
    .board-page .column-content {
        flex: none;
        min-height: 0;
        gap: var(--jb-sp-1);
    }

    /* A card is two lines: the chip row notched into the top edge, the heading, then the target date against the counts. */
    .board-page .feature-card-roadmap {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--jb-sp-1) var(--jb-sp-2);
        min-height: 44px;
        padding: var(--jb-sp-2);
    }
    .board-page .feature-card-roadmap:active {
        background: var(--jb-bg-pressed);
        border-color: var(--jb-border-raised);
    }
    .board-page .feature-card-roadmap:has(> .feature-card-tags .feature-tag) {
        margin-top: 12px;
    }
    .board-page .feature-card-tags {
        order: 1;
        flex: 1 0 100%;
        margin: -18px 0 -4px;
        gap: 3px;
    }
    .board-page .feature-card-header {
        order: 2;
        flex: 1 0 100%;
        min-height: 20px;
        min-width: 0;
        margin-bottom: 0;
    }
    /* Every child of the card is ordered here, or a child without an order would be placed above the tags and heading. */
    .board-page .dev-response {
        order: 3;
        flex: 1 0 100%;
        margin: 0 0 var(--jb-sp-2);
    }
    .board-page .feature-tag-date {
        order: 4;
        margin: 0;
    }
    .board-page .feature-card-meta {
        order: 5;
        flex: 1 1 auto;
        flex-wrap: nowrap;
        justify-content: flex-end;
        gap: var(--jb-sp-1);
        padding-top: 0;
    }
    .board-page .feature-card-right {
        flex-wrap: nowrap;
        margin-left: 0;
    }
    /* Chips lose the padding a mouse target needs and keep their labels, because at this width the card is the target. */
    .board-page .feature-card-tags > .feature-tag {
        height: 18px;
        padding: 0 6px;
    }

    /* Six badges share one line, so each chip is cut to its digits and wrapping is off on purpose. */
    .board-page .feature-card-meta .feature-card-left { gap: var(--jb-sp-1); }
    .board-page .feature-card-meta .feature-card-right { gap: 2px; }
    .board-page .feature-card-votes,
    .board-page .feature-card-meta .card-score-badge {
        gap: 2px;
        padding: 0 3px;
    }
    /* The count riding a number needs the number's own padding gone, or the two metrics run into each other. */
    .board-page .feature-card-meta .feature-card-votes,
    .board-page .feature-card-meta .card-score-badge-comments { padding: 0; }
    .board-page .feature-card-meta svg {
        width: 11px;
        height: 11px;
    }

    /* What the card does without: the section count already says a section is empty, and progress is one tap away. */
    .board-page .column-empty-state,
    .board-page .pinned-indicator,
    .board-page .card-description,
    .board-page .card-progress-bar,
    .board-page .feature-card-header-actions { display: none; }
}

/* The demo strip reads as one 40px line: the message centred, the disclaimer following it, and the button pinned to the right gutter. */

.demo-banner-label {
    color: var(--jb-fg);
    font-weight: var(--jb-w-medium);
}
.demo-banner-text {
    color: var(--jb-fg-secondary);
    opacity: 1;
}
/* The figure arrives from a request, so its placeholder is given the width it will need and the sentence does not slide. */
.demo-banner-timer {
    display: inline-block;
    min-width: 3ch;
    color: var(--jb-fg);
    font-weight: var(--jb-w-medium);
    font-variant-numeric: tabular-nums;
}

@media (min-width: 769px) {
    /* The strip matches the inset the merged footer keeps, so its button and the avatar below it share a right edge. */
    .demo-banner {
        padding-right: var(--jb-sp-5);
    }
    .demo-banner-content {
        display: grid;
        grid-template-columns: 1fr minmax(0, auto) 1fr;
        align-items: center;
        gap: var(--jb-sp-4);
        max-width: none;
        margin: 0;
    }
    .demo-banner-text-group {
        grid-column: 2;
        display: flex;
        align-items: baseline;
        gap: var(--jb-sp-2);
        min-width: 0;
        text-align: left;
    }
    .demo-banner-text,
    .demo-banner-subtext {
        flex: 0 1 auto;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .demo-banner-subtext {
        margin: 0;
        font-size: var(--jb-t-3);
    }
    /* One separator between the message and its aside, so the line reads as a sentence with a footnote. */
    .demo-banner-subtext::before {
        content: "\00B7";
        margin-right: var(--jb-sp-2);
    }
    .demo-banner-actions {
        grid-column: 3;
        justify-self: end;
    }
}

/* Restarting the tour is a borderless control in the corner rather than a link buried in the middle of the sentence. */
.demo-banner-actions {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-2);
}
.demo-banner-replay {
    display: inline-flex;
    align-items: center;
    height: var(--jb-h-control);
    padding: 0 var(--jb-sp-3);
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--jb-r-md);
    color: var(--jb-fg-secondary);
    font-family: inherit;
    font-size: var(--jb-t-3);
    font-weight: var(--jb-w-medium);
    line-height: 1;
    white-space: nowrap;
    cursor: default;
    transition: background var(--jb-dur-in) var(--jb-ease-in),
                color var(--jb-dur-in) var(--jb-ease-in);
}
.demo-banner-replay:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.demo-banner-replay:focus-visible {
    outline: 2px solid var(--jb-focus);
    outline-offset: -1px;
}
/* The tour does not run on a phone, so neither does its control; placed here because at equal weight the last rule wins. */
@media (max-width: 768px) {
    .demo-banner-replay { display: none; }
}
/* The tour dims the strip with the rest of the page, so the restart control is not reachable underneath. */
html.demo-tour-open .demo-banner-replay {
    visibility: hidden;
}

/* Between 769 and 1200 the sidebar is a rail, so the disclaimer is the part that waits for a wider window. */
@media (min-width: 769px) and (max-width: 1200px) {
    .demo-banner-subtext { display: none; }
}

/* The tour uses the popup this design system already has, with the dimming carried by the ring's own spread shadow. */

/* A shadow colour, written like the shadow tokens: the backdrop tint dims towards the island, which is already darker in dark theme. */
:root {
    --demo-tour-scrim: rgba(0, 0, 0, 0.72);
}
[data-theme="light"] {
    --demo-tour-scrim: rgba(0, 0, 0, 0.46);
}

/* Catches every click so a step cannot be pulled out from under itself, and sits below the ring. */
.demo-tour-block {
    position: fixed;
    inset: 0;
    z-index: 10000;
}

/* The dim is the whole signal: the hole takes the target's own corner radius, and no accent outline claims a selection. */
.demo-tour-ring {
    position: fixed;
    top: 0;
    left: 0;
    width: 0;
    height: 0;
    box-shadow: 0 0 0 100vmax var(--demo-tour-scrim);
    pointer-events: none;
    z-index: 10001;
    transition: top var(--jb-dur-tooltip) var(--jb-ease-in),
                left var(--jb-dur-tooltip) var(--jb-ease-in),
                width var(--jb-dur-tooltip) var(--jb-ease-in),
                height var(--jb-dur-tooltip) var(--jb-ease-in),
                border-radius var(--jb-dur-tooltip) var(--jb-ease-in),
                opacity var(--jb-dur-out) var(--jb-ease-out);
}
.demo-tour-ring.is-hidden {
    opacity: 0;
}
/* Coach mode: no dim and no click catching, the customer works the page and the ring points at the next control. */
.demo-tour-block.is-coach {
    pointer-events: none;
}
.demo-tour-ring.is-coach,
.demo-tour-ring.is-coach.is-tracking {
    box-shadow: 0 0 0 2px var(--jb-accent), 0 0 0 6px color-mix(in srgb, var(--jb-accent) 25%, transparent);
    transition: opacity var(--jb-dur-in) var(--jb-ease-in);
}
/* While the page scrolls the ring follows its target frame by frame, so a transition would leave it behind. */
.demo-tour-ring.is-tracking {
    transition: none;
}

.demo-tour-pop {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 10002;
    width: 320px;
    max-width: calc(100vw - 24px);
    padding: var(--jb-sp-3) var(--jb-sp-4);
    background: var(--jb-bg-island);
    border: 1px solid var(--jb-border);
    border-radius: var(--jb-r-panel);
    box-shadow: var(--jb-shadow-dialog);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--jb-dur-out) var(--jb-ease-out);
}
.demo-tour-pop.is-in {
    opacity: 1;
    pointer-events: auto;
    transition-duration: var(--jb-dur-in);
    transition-timing-function: var(--jb-ease-in);
}

/* Two borders of a rotated square draw the beak, and the overlap covers the panel's own border where they meet. */
.demo-tour-beak {
    position: absolute;
    width: 11px;
    height: 11px;
    background: var(--jb-bg-island);
    border: 1px solid var(--jb-border);
    transform: rotate(45deg);
}
.demo-tour-pop[data-side="bottom"] .demo-tour-beak {
    top: -6px;
    border-right-color: transparent;
    border-bottom-color: transparent;
}
.demo-tour-pop[data-side="top"] .demo-tour-beak {
    bottom: -6px;
    border-left-color: transparent;
    border-top-color: transparent;
}
.demo-tour-pop[data-side="right"] .demo-tour-beak {
    left: -6px;
    border-right-color: transparent;
    border-top-color: transparent;
}
.demo-tour-pop[data-side="left"] .demo-tour-beak {
    right: -6px;
    border-left-color: transparent;
    border-bottom-color: transparent;
}

.demo-tour-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--jb-sp-2);
    margin-bottom: var(--jb-sp-1);
}
.demo-tour-count {
    font-size: var(--jb-t-2);
    color: var(--jb-fg-tertiary);
    font-variant-numeric: tabular-nums;
}
.demo-tour-close {
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    margin-right: -6px;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: var(--jb-r-sm);
    color: var(--jb-fg-tertiary);
    cursor: default;
    transition: background var(--jb-dur-in) var(--jb-ease-in),
                color var(--jb-dur-in) var(--jb-ease-in);
}
.demo-tour-close:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}

.demo-tour-title {
    margin: 0 0 var(--jb-sp-2);
    font-size: var(--jb-t-4);
    font-weight: var(--jb-w-semi);
    line-height: var(--jb-lh-tight);
    color: var(--jb-fg);
}
.demo-tour-text {
    margin: 0 0 var(--jb-sp-4);
    font-size: var(--jb-t-4);
    line-height: var(--jb-lh-prose);
    color: var(--jb-fg-secondary);
}

/* The steps that make a claim read the card's own figures off the element, using the detail drawer's label and figure pairing. */
.demo-tour-stats {
    display: flex;
    gap: var(--jb-sp-5);
    margin: 0 0 var(--jb-sp-4);
    padding-top: var(--jb-sp-3);
    border-top: 1px solid var(--jb-border);
}
.demo-tour-stats[hidden] {
    display: none;
}
.demo-tour-stat dt {
    font-size: var(--jb-t-2);
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-tertiary);
}
.demo-tour-stat dd {
    margin: 0;
    font-size: var(--jb-t-5);
    font-weight: var(--jb-w-semi);
    line-height: var(--jb-lh-tight);
    color: var(--jb-fg);
    font-variant-numeric: tabular-nums;
}

.demo-tour-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--jb-sp-2);
}
.demo-tour-nav {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-2);
}
.demo-tour-skip,
.demo-tour-back,
.demo-tour-next,
.demo-tour-cta {
    display: inline-flex;
    align-items: center;
    height: var(--jb-h-control);
    padding: 0 var(--jb-sp-3);
    border: 1px solid transparent;
    border-radius: var(--jb-r-md);
    font-family: inherit;
    font-size: var(--jb-t-3);
    font-weight: var(--jb-w-medium);
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    cursor: default;
    transition: background var(--jb-dur-in) var(--jb-ease-in),
                color var(--jb-dur-in) var(--jb-ease-in);
}
.demo-tour-skip,
.demo-tour-back {
    background: transparent;
    color: var(--jb-fg-secondary);
}
.demo-tour-back {
    border-color: var(--jb-border-raised);
}
.demo-tour-skip:hover,
.demo-tour-back:not(:disabled):hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
}
.demo-tour-back:disabled {
    opacity: 0.4;
}
.demo-tour-next,
.demo-tour-cta {
    background: var(--jb-accent);
    border-color: var(--jb-accent);
    color: var(--jb-fg-on-accent);
}
.demo-tour-back[hidden],
.demo-tour-next[hidden],
.demo-tour-cta[hidden],
.demo-tour-pop[data-side="center"] .demo-tour-beak {
    display: none;
}
/* The welcome card is read before anything is lit, so it is wider, its close sits in the title row, and both choices stand together. */
.demo-tour-pop[data-side="center"] {
    width: 640px;
    padding: var(--jb-sp-7) var(--jb-sp-7) var(--jb-sp-6);
}
.demo-tour-pop[data-side="center"] .demo-tour-head {
    position: absolute;
    top: var(--jb-sp-4);
    right: var(--jb-sp-4);
    margin: 0;
}
.demo-tour-pop[data-side="center"] .demo-tour-title {
    margin-bottom: var(--jb-sp-3);
    padding-right: var(--jb-sp-6);
    font-size: var(--jb-t-7);
}
.demo-tour-pop[data-side="center"] .demo-tour-text {
    margin-bottom: var(--jb-sp-5);
    font-size: var(--jb-t-5);
    color: var(--jb-fg);
}
.demo-tour-pop[data-side="center"] .demo-tour-actions {
    justify-content: flex-end;
}
.demo-tour-pop[data-side="center"] .demo-tour-skip {
    border-color: var(--jb-border-raised);
}
.ob-open {
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: var(--jb-sp-2);
    height: var(--jb-h-control);
    padding: 0 var(--jb-sp-3);
    white-space: nowrap;
}
.ob-open .column-count {
    color: var(--jb-fg);
}
.demo-tour-next:hover,
.demo-tour-cta:hover {
    background: var(--jb-accent-hover);
    border-color: var(--jb-accent-hover);
}
.demo-tour-close:focus-visible,
.demo-tour-skip:focus-visible,
.demo-tour-back:focus-visible,
.demo-tour-next:focus-visible,
.demo-tour-cta:focus-visible {
    outline: 2px solid var(--jb-focus);
    outline-offset: -1px;
    border-color: transparent;
}

/* The phone list row: Voters and Activity become two lines, the subject with its timestamp above everything that qualifies it. */

@media (max-width: 768px) {
    .activity-item {
        flex-wrap: wrap;
        height: auto;
        min-height: 44px;
        padding: var(--jb-sp-2) var(--jb-sp-3);
        column-gap: var(--jb-sp-2);
        row-gap: var(--jb-sp-1);
    }
    .activity-item + .activity-item::before {
        left: var(--jb-sp-3);
        right: var(--jb-sp-3);
    }

    /* A 24px marker in a 32px gutter, centred against the whole row because it marks the whole row. */
    .activity-item:has(> .activity-icon-wrapper) { padding-left: 44px; }
    .activity-item > .activity-icon-wrapper {
        position: absolute;
        left: var(--jb-sp-3);
        top: 50%;
        transform: translateY(-50%);
    }

    .activity-item > .activity-item-title {
        order: 1;
        flex: 1 1 auto;
        min-width: 0;
    }
    .activity-item > .activity-item-time {
        order: 2;
        flex: 0 0 auto;
        margin-left: auto;
        font-size: 11px;
    }
    .activity-item::after {
        content: "";
        order: 3;
        flex: 0 0 100%;
        height: 0;
    }
    /* Everything that is not the subject or the time is evidence and drops to the second line, whatever a renderer adds. */
    .activity-item > :not(.activity-icon-wrapper):not(.activity-item-title):not(.activity-item-time) {
        order: 4;
        flex: 0 1 auto;
        min-width: 0;
        font-size: 11px;
    }
    .activity-item > .activity-badge,
    .activity-item > .voter-type-badge,
    .activity-item > .voter-lifecycle-badge {
        height: 18px;
        padding: 0 6px;
    }
    .activity-item > .activity-item-actor {
        max-width: none;
        color: var(--jb-fg-secondary);
    }
    /* On a desktop row this takes the slack so the counts meet the timestamp; on its own line there is none. */
    .activity-item > .voter-row-meta {
        flex: 0 1 auto;
        text-align: left;
    }
}

/* Three targets under the 24 by 24 floor, grown by an invisible reach except the range buttons, which grow two real pixels. */

@media (pointer: coarse) {
    .lite-notice-close,
    .mobile-header-logo { position: relative; }
    .lite-notice-close::after {
        content: "";
        position: absolute;
        inset: calc((22px - var(--jb-tap-min, 44px)) / 2);
    }
    .mobile-header-logo::after {
        content: "";
        position: absolute;
        inset: calc((20px - var(--jb-tap-min, 44px)) / 2) 0;
    }
    .chart-range-btn { height: var(--jb-h-dense); }
}

/* Hover on a touch screen never ends, so under a coarse pointer the row takes a pressed fill instead. */

@media (pointer: coarse) {
    .activity-item:hover { background: none; }
    .activity-item-clickable:active { background: var(--jb-bg-pressed); }
}

/* The page name comes back only at the widths where the rail is unlabelled and the page has no tab strip. */

.top-bar-page-name { display: none; }

@media (min-width: 769px) and (max-width: 1200px) {
    .top-bar-page-name {
        display: block;
        flex: 0 1 auto;
        margin: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}

/* On a phone the insights rail sits above the list and arrives shut, remembering its state per screen; above 768 it cannot collapse. */

.rail-collapse {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-1);
    min-width: 0;
    margin: 0;
    padding: 0;
    background: none;
    border: none;
    color: inherit;
    font: inherit;
    text-align: left;
}
.rail-collapse-chevron {
    display: none;
    flex-shrink: 0;
    color: var(--jb-fg-tertiary);
}

/* The figures give up their own island to the section holding them, as a stat list already does. */
.rail-section > .changelog-stat-strip {
    margin: 0;
    padding: 0;
    background: none;
    border: none;
    border-radius: 0;
}
.changelog-insights { margin-bottom: var(--jb-island-gap); }
.changelog-insights .rail-section-head { display: none; }

@media (max-width: 768px) {
    .page-with-rail .insights-rail { order: -1; }

    .changelog-insights .rail-section-head { display: flex; }

    /* Shut, the section is its head alone, so only the height moves, and the figures carry the sixteen the list rows start at. */
    .insights-rail .rail-section { padding: 0 var(--jb-sp-4); }
    .insights-rail .rail-section-head { margin-bottom: 0; }
    .insights-rail .rail-section > :not(.rail-section-head) {
        padding: var(--jb-sp-1) 0 var(--jb-sp-3);
    }

    /* The rail closes by clipping so there is a height to travel between; common.js writes the measured one and 38 is the fallback. */
    .insights-rail > * { flex: 0 0 auto; }
    .insights-rail.is-collapsed { height: 38px; }
    .insights-rail.is-collapsed,
    .insights-rail.is-sliding { overflow: hidden; }

    /* Opening and closing are different gestures, and the tokens already say so: arriving is quick, leaving takes a moment longer. */
    .insights-rail.is-sliding { transition: height var(--jb-dur-in) var(--jb-ease-in); }
    .insights-rail.is-sliding.is-collapsed {
        transition: height var(--jb-dur-out) var(--jb-ease-out);
    }

    /* The content is drawn in full from the first frame, so the fade underneath keeps the reveal from being a wipe. */
    .insights-rail.is-sliding:not(.is-collapsed) .rail-section > :not(.rail-section-head),
    .insights-rail.is-sliding:not(.is-collapsed) .insights-rail-body {
        animation: collapsible-fade-in var(--jb-dur-in) var(--jb-ease-in) both;
    }

    /* Clipped is not gone, so once closed the box stops existing for everything except layout, which still measures it. */
    .insights-rail.is-collapsed:not(.is-sliding) .rail-section > :not(.rail-section-head),
    .insights-rail.is-collapsed:not(.is-sliding) .insights-rail-body { visibility: hidden; }

    /* The head is the target, all of it: a 36px row whose right half does nothing still reads as tappable. */
    .rail-collapse {
        flex: 1 1 auto;
        min-height: 36px;
    }
    .rail-collapse-chevron {
        display: block;
        transition: transform var(--jb-dur-in) var(--jb-ease-in);
    }

    .insights-rail.is-collapsed .rail-collapse-chevron { transform: rotate(-90deg); }
    .insights-rail.is-collapsed .chart-range-btns { display: none; }
}

/* On a phone the Voters settings row wraps itself: the text takes a 200px floor and the control cluster may not shrink. */

@media (max-width: 768px) {
    .wv-row {
        flex-wrap: wrap;
        row-gap: var(--jb-sp-2);
        padding: var(--jb-sp-2) var(--jb-sp-3);
    }
    .wv-row-text {
        flex: 1 1 200px;
        min-width: 200px;
    }
    .wv-row-aside {
        flex: 0 0 auto;
        flex-wrap: wrap;
    }
    .wv-panel-head,
    .wv-panel-foot { padding: var(--jb-sp-3); }
}

/* On a phone a release entry notches its chips above a two line heading, and the four figures go two by two. */

@media (max-width: 768px) {
    .release-row-head { flex-wrap: wrap; }
    .release-row-badges {
        order: -1;
        flex: 1 0 100%;
    }
    .release-row-title {
        flex: 1 0 100%;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        white-space: normal;
        line-height: var(--jb-lh-tight);
    }

    .changelog-stat-strip { padding: var(--jb-sp-3); }
}

/* Four figures still fit across 768 and stop somewhere under 600, which is where they become two by two. */
@media (max-width: 600px) {
    .changelog-stat-strip {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* The five plan pages are a door: no sidebar, no board, one island centred on the canvas under a bare top bar. */

.plan-page {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--jb-bg-canvas);
}
.plan-page .top-bar {
    position: sticky;
    top: 0;
    height: 40px;
    padding: 0 var(--jb-sp-4);
    margin-bottom: 0;
    background: var(--jb-bg-canvas);
    border-bottom: 1px solid var(--jb-border);
}
.plan-page-content {
    width: min(720px, calc(100vw - var(--jb-sp-4) * 2));
    margin: var(--jb-sp-5) auto var(--jb-sp-6);
}
.plan-page-content--narrow { width: min(480px, calc(100vw - var(--jb-sp-4) * 2)); }
.plan-page-content--wide { width: min(960px, calc(100vw - var(--jb-sp-4) * 2)); }
.plan-page-content--wide { text-align: center; }
.plan-page-content--wide .appearance-target-bar { justify-content: center; }
.plan-page-content--wide .plan-tiles { text-align: left; }
.plan-page-content > p, .plan-page .kanban-column > p {
    margin: 0 0 var(--jb-sp-4);
    font-size: var(--jb-t-3);
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-secondary);
}
.plan-page-content--wide > p { font-size: var(--jb-t-4); color: var(--jb-fg); }
/* A one island page spaces its children with the island's own gap, so nothing inside brings a margin of its own. */
.plan-page .kanban-column > h1, .plan-page .kanban-column > p, .plan-page .kanban-column > .section-actions { margin: 0; }
/* Below 768 the app grows this box so the board's search field can fill it; the door has no search, only two icons. */
.plan-page .top-bar-right { justify-content: flex-end; }
/* The board sizes a column at a fixed 360px so it can be dragged; on the door the island is the content column. */
.plan-cards-island {
    width: auto;
    min-width: 0;
    min-height: 0;
    gap: var(--jb-sp-3);
    padding: var(--jb-sp-3);
}
/* The dialog's rows are one line tall, so centring reads; on the door the button lines up with the plan name. */
.plan-page .billing-plan-card { align-items: flex-start; }
/* Three rows read as one bounded list, the way the team list already separates its members. */
.plan-cards-island .billing-plan-card + .billing-plan-card {
    border-top: 1px solid var(--jb-border);
    padding-top: var(--jb-sp-3);
}
/* Three plan tiles side by side, Pro in the middle carrying the badge, the accent edge and the one filled button. */
.plan-tiles {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--jb-island-gap);
    margin-top: var(--jb-sp-4);
}
.plan-tiles > .billing-plan-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--jb-sp-3);
    margin: 0;
    padding: var(--jb-sp-4);
    background: var(--jb-bg-island);
    border: 1px solid var(--jb-border-island);
    border-radius: var(--jb-r-panel);
}
.jb-settings-dialog .plan-tiles > .billing-plan-card {
    background: var(--jb-bg-island);
    border-color: var(--jb-border-control);
}
.plan-tiles > .billing-plan-card[data-plan="PRO"] {
    background: var(--jb-info-bg);
    border-color: var(--jb-info-border);
}
.plan-tiles > .billing-plan-card[data-plan="PRO"] .plan-features { color: var(--jb-fg); }
.plan-tiles > .billing-plan-card[data-plan="PRO"] .plan-features li::before { background-color: var(--jb-accent); }
.plan-tiles .billing-plan-details {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-width: 0;
}
.plan-tile-badge {
    position: absolute;
    top: -11px;
    left: var(--jb-sp-4);
    height: 22px;
    background: var(--jb-accent);
    color: var(--jb-fg-on-accent);
    font-size: var(--jb-t-2);
}
.plan-tiles .billing-plan-name { font-size: var(--jb-t-3); font-weight: var(--jb-w-medium); }
.billing-plan-price {
    display: flex;
    align-items: baseline;
    gap: var(--jb-sp-1);
    margin-top: var(--jb-sp-1);
}
.billing-plan-price .billing-plan-amount {
    margin: 0;
    font-size: var(--jb-t-7);
    font-weight: var(--jb-w-semi);
    line-height: var(--jb-lh-tight);
    font-variant-numeric: tabular-nums;
    color: var(--jb-fg);
}
.billing-plan-price .billing-plan-per {
    margin: 0;
    font-size: var(--jb-t-3);
    color: var(--jb-fg-secondary);
}
.plan-tiles .billing-plan-note { margin-top: var(--jb-sp-1); }
.plan-save {
    display: inline-flex;
    align-items: center;
    height: 18px;
    margin-left: var(--jb-sp-1);
    padding: 0 var(--jb-sp-1);
    border-radius: var(--jb-r-sm);
    font-size: var(--jb-t-1);
    font-weight: var(--jb-w-medium);
    background: var(--jb-bg-inset);
    color: var(--jb-fg-secondary);
}
.plan-tiles .plan-features, .checkout-summary .plan-features {
    flex: 1;
    gap: var(--jb-sp-2);
    margin: var(--jb-sp-3) 0 0;
    padding-top: var(--jb-sp-3);
    border-top: 1px solid var(--jb-border);
    font-size: var(--jb-t-3);
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-secondary);
}
.plan-tiles .plan-features li, .checkout-summary .plan-features li {
    padding-left: var(--jb-sp-5);
    font-size: inherit;
    color: inherit;
}
.plan-tiles .plan-features li::before, .checkout-summary .plan-features li::before {
    width: 16px;
    height: 16px;
    min-width: 16px;
    border-radius: 0;
    background-color: var(--jb-fg-tertiary);
    background-image: none;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center / 14px no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center / 14px no-repeat;
}
.plan-tiles .plan-features li.feature-dim { color: var(--jb-fg-disabled); }
.plan-tiles .plan-features li.feature-dim::before {
    background-color: var(--jb-fg-disabled);
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3C/svg%3E");
}
.plan-tiles .plan-choose { width: 100%; }
.plan-tiles .plan-current {
    display: flex;
    align-items: center;
    justify-content: center;
    height: var(--jb-h-control);
    margin: 0;
}
@media (max-width: 768px) {
    .plan-tiles { grid-template-columns: 1fr; }
    .plan-tiles > [data-plan="PRO"] { order: -1; }
}
/* The summary is one tile's worth of facts beside the card form; the list does not grow, the link is quiet. */
.checkout-summary .plan-features { flex: 0 0 auto; }
.checkout-summary > p { margin: 0; }
.checkout-summary .sample-banner { margin: 0; }
.checkout-summary > a { font-size: var(--jb-t-3); color: var(--jb-fg-secondary); text-decoration: none; }
.checkout-summary > a:hover { color: var(--jb-fg); }
.checkout-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
    gap: var(--jb-island-gap);
    align-items: start;
}
@media (max-width: 768px) {
    .checkout-layout { grid-template-columns: 1fr; }
}
/* Sign in, sign up, reset, invite, admin and not found: one narrow island holding a form on the money pages' shell. */
.plan-page-content--narrow .plan-cards-island > .share-btn { width: 100%; }
.plan-page .app-form-group { margin: 0; }
[aria-invalid="true"] { border-color: var(--jb-error); }
/* The checkbox geometry the dialog declares on its body, so the door's one checkbox is the same 18px box. */
.plan-page .checkbox-group { --jbs-check: 18px; }
/* The project tile is a link and the thanks banner is hidden until a payment lands; the legacy sheet gives both a display of their own. */
a.np-card { text-decoration: none; color: inherit; }
.np-upgrade-banner[hidden] { display: none; }
/* The phone band pads the body for a mobile header the door does not render. */
@media (max-width: 768px) {
    body.plan-page { padding-top: 0; }
    html.is-demo body.plan-page { padding-top: var(--demo-banner-h); }
}

/* Share and Embed is three stacked panels using the board's own island geometry, with every action beside its field and one button colour. */

.share-grid {
    display: flex;
    flex-direction: column;
    gap: var(--jb-island-gap);
    margin-top: var(--jb-sp-4);
}

/* The board column, exactly. */
.share-page .app-section {
    margin: 0;
    padding: var(--jb-sp-3) var(--jb-sp-2);
    background: var(--jb-bg-island);
    border: 1px solid var(--jb-border-island);
    border-radius: var(--jb-r-panel);
    box-shadow: none;
    transition: none;
}
/* An island is a container, not a control, and answers the pointer with nothing. */
.share-page .app-section:hover {
    border-color: var(--jb-border-island);
    box-shadow: none;
}

/* The column header: a name, whatever counts it, and the way out to the documentation that explains it. */
.share-panel-head {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-2);
    min-height: 32px;
    padding: var(--jb-sp-1) var(--jb-sp-1) var(--jb-sp-2) var(--jb-sp-2);
}
.share-panel-head h2 {
    flex: 1;
    min-width: 0;
    margin: 0;
    font-size: var(--jb-t-3);
    font-weight: var(--jb-w-semi);
    line-height: var(--jb-lh-tight);
    letter-spacing: normal;
    color: var(--jb-fg);
}
.share-page .app-section a.share-panel-doc,
.share-panel-doc {
    display: grid;
    place-items: center;
    width: var(--jb-row);
    height: var(--jb-row);
    flex: none;
    border-radius: var(--jb-r-md);
    color: var(--jb-fg-secondary);
    text-decoration: none;
    transition: background-color var(--jb-dur-in) ease-out, color var(--jb-dur-in) ease-out;
}
.share-page .app-section a.share-panel-doc:hover,
.share-panel-doc:hover {
    background: var(--jb-bg-hover);
    color: var(--jb-fg);
    text-decoration: none;
}

/* The column's content, where a group of fields opens 24 below the one before it. */
.share-panel-body {
    display: flex;
    flex-direction: column;
    gap: var(--jb-sp-5);
    padding: 0 var(--jb-sp-2) var(--jb-sp-1);
}
/* The one line of prose in a panel, uncapped so two panels do not start their fields on different rows. */
.share-panel-lead {
    margin: 0;
    font-size: var(--jb-t-2);
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-secondary);
}

/* One field, its label and whatever explains it, with vertical space declared once on the top of what needs it. */
.share-field { display: flex; flex-direction: column; min-width: 0; }
.share-field > label {
    margin-bottom: 6px;
    font-size: var(--jb-t-3);
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg);
}
.share-field > .help-text { margin-top: var(--jb-sp-1); }
.share-actions { display: flex; gap: var(--jb-sp-2); margin-top: var(--jb-sp-4); }
.share-field > .sso-token-result { margin-top: var(--jb-sp-4); }

/* The demo's version of this page names what is behind the lock rather than only refusing. */
.share-locked-icon { flex: none; color: var(--jb-fg-tertiary); }
.share-locked-list {
    display: grid;
    gap: var(--jb-sp-2);
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: var(--jb-t-2);
    line-height: var(--jb-lh-ui);
    color: var(--jb-fg-secondary);
}
.share-locked-list li {
    display: grid;
    grid-template-columns: 96px 1fr;
    gap: var(--jb-sp-3);
}
.share-locked-list strong { font-weight: var(--jb-w-medium); color: var(--jb-fg); }

/* A credential and the controls that act on it, on one line. */
.share-row { display: flex; align-items: center; gap: var(--jb-sp-2); }
.share-row .app-text-input { flex: 1; min-width: 0; }
.share-row .share-btn { flex: none; min-width: 0; padding: 0 var(--jb-sp-3); }

/* The rows attribute is the height, so these two textareas keep the three short lines they ask for. */
.share-page .settings-textarea { min-height: 0; }

/* A key is data, and data is monospaced here. */
.share-mono { font-family: var(--jb-font-mono); }

/* The drawer that names a key and the one that shows it once, both stacking labels above fields with actions in the footer. */
.detail-panel > .modal-footer { flex: none; }
.detail-panel > .modal-footer[hidden] { display: none; }
.panel-form .app-form-group > label { display: block; margin-bottom: 6px; }
.panel-form .app-form-group > .app-text-input { display: block; width: 100%; }

/* The copy button floats over the code block's top right corner, so the block needs a gutter for it. */
.share-code-block pre { padding-right: var(--jb-sp-7); }

/* The API keys get one box with a hairline between rows, never a card each, because the box is the list's bounds. */
.share-keys:has(.share-key) {
    border: 1px solid var(--jb-border);
    border-radius: var(--jb-r-md);
}
.share-key {
    display: flex;
    align-items: center;
    gap: var(--jb-sp-2);
    padding: var(--jb-sp-2);
}
.share-key + .share-key { border-top: 1px solid var(--jb-border); }
.share-key-main { flex: 1; min-width: 0; }
.share-key-name {
    display: block;
    font-size: var(--jb-t-3);
    color: var(--jb-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.share-key-meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--jb-sp-2);
    margin-top: 2px;
    font-size: var(--jb-t-1);
    color: var(--jb-fg-secondary);
    font-variant-numeric: tabular-nums;
}
.share-key-actions { display: flex; gap: var(--jb-sp-1); flex: none; }
/* An empty list inside a panel of fields is a sentence, not a dashed box with an icon. */
.share-key-empty {
    margin: 0;
    font-size: var(--jb-t-2);
    color: var(--jb-fg-secondary);
}

/* The result of a token check, which is the one table left on this page. */
.share-page .share-table td { border-bottom: none; }

@media (max-width: 768px) {
    /* The key field takes a floor and the buttons may not shrink, so the row wraps only where they genuinely do not fit. */
    .share-row { flex-wrap: wrap; }
    .share-row .app-text-input { min-width: 240px; }
    .share-key { flex-wrap: wrap; }

    .share-locked-list li { grid-template-columns: 1fr; gap: 0; }
}

/* The list and pager containers collapse while empty, so two empty children do not spend two gaps under the placeholder. */

.collapses-when-empty:empty {
    display: none;
}

/* A placeholder block is the height of a release row's three lines, or the page moves when the rows land. */

.changelog-releases-placeholder {
    padding: var(--jb-sp-4);
}

.changelog-releases-placeholder .skeleton-block {
    height: 72px;
}

.changelog-releases-placeholder .skeleton-block:last-child {
    margin-bottom: 0;
}

.vf-launcher {
    position: fixed;
    right: var(--jb-sp-4);
    bottom: var(--jb-sp-7);
    z-index: var(--jb-z-panel);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    background: var(--jb-accent);
    border: 1px solid var(--jb-accent);
    border-radius: var(--jb-r-pill);
    color: var(--jb-fg-on-accent);
    box-shadow: var(--jb-shadow-dialog);
}

.vf-launcher:hover {
    background: var(--jb-accent-hover);
    border-color: var(--jb-accent-hover);
}

.vf-launcher-panel {
    z-index: var(--jb-z-panel);
    width: 420px;
}

.vf-launcher-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: var(--jb-panel-head-h);
    padding: 0 var(--jb-sp-3);
    border-bottom: 1px solid var(--jb-border);
}

.vf-launcher-title {
    font-size: 13px;
    color: var(--jb-fg);
}

.vf-launcher-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: var(--jb-r-sm);
    color: var(--jb-fg-icon);
}

.vf-launcher-close:hover {
    background: var(--jb-bg-hover);
}

.vf-launcher-bar {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--jb-sp-2);
    padding: var(--jb-sp-2) var(--jb-sp-3) 0;
}

.vf-launcher-bar .page-tabs {
    margin: 0;
}

.vf-launcher-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--jb-sp-3);
}

@media (prefers-reduced-motion: no-preference) {
    .vf-launcher-body > div {
        transition: opacity 220ms ease;
    }
}

/* The panel is one column wide, so the board's own auto-fit grid must not split it into two. */
.vf-launcher-body .vf-columns {
    grid-template-columns: 1fr;
}

.vf-launcher-foot {
    padding: var(--jb-sp-3);
    border-top: 1px solid var(--jb-border);
}

.vf-launcher-foot .btn-primary {
    width: 100%;
}
