@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;600;700;800&display=swap');

:root {
    color-scheme: light;
    --bg: #ecedf4;
    --bg-soft: #f5f6fa;
    --bg-muted: #e8eaf1;
    --bg-panel: #ffffff;
    --bg-dark: #0d142d;
    --bg-dark-soft: #1f243c;
    --border: #e4e6ee;
    --border-strong: #cfd4e2;
    --text: #0d142d;
    --muted: #4b5475;
    --accent: var(--tenant-accent, #1f65f4);
    --accent-alt: var(--tenant-accent-dark, #7150f7);
    --accent-ink: #5a3ce6;
    --accent-soft: #efecfe;
    --accent-hover: #144ab8;
    --grad: linear-gradient(120deg, #1f65f4 0%, #5059f6 55%, #7150f7 100%);
    --shadow: 0 4px 16px rgba(13, 20, 45, 0.08), 0 1px 3px rgba(13, 20, 45, 0.05);
    --shadow-sm: 0 1px 2px rgba(13, 20, 45, 0.05), 0 1px 1px rgba(13, 20, 45, 0.04);
    --field-bg: #ffffff;
    --field-bg-strong: #f8faff;
    --field-placeholder: #73809c;
    --button-dark-bg: #0d142d;
    --button-dark-border: #0d142d;
    --button-dark-bg-hover: #162041;
    --button-dark-text: #ffffff;
    --radius-sm: 8px;
    --radius-md: 12px;
    --radius-lg: 16px;
}

:root[data-theme='dark'] {
    color-scheme: dark;
    --bg: #09111f;
    --bg-soft: #0f1829;
    --bg-muted: #162338;
    --bg-panel: #121d31;
    --bg-dark: #070d18;
    --bg-dark-soft: #1c2842;
    --border: rgba(176, 190, 219, 0.16);
    --border-strong: rgba(176, 190, 219, 0.28);
    --text: #f7f9fe;
    --muted: #cad2e4;
    --accent-ink: #b3a6ff;
    --accent-soft: rgba(113, 80, 247, 0.16);
    --shadow: 0 10px 30px rgba(0, 0, 0, 0.32);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --field-bg: #0d1628;
    --field-bg-strong: #111b31;
    --field-placeholder: #93a0bd;
    --button-dark-bg: rgba(255, 255, 255, 0.1);
    --button-dark-border: rgba(255, 255, 255, 0.14);
    --button-dark-bg-hover: rgba(255, 255, 255, 0.16);
    --button-dark-text: #ffffff;
}

* {
    box-sizing: border-box;
}

html {
    background: var(--bg);
    min-height: 100%;
}

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    color: var(--text);
    font-family: 'Rubik', sans-serif;
    font-size: 14px;
    line-height: 1.5;
}

/* Sticky footer: short pages (e.g. empty roadmap) keep the footer
   pinned to the bottom of the viewport. */
body > main.shell-main {
    flex: 1 0 auto;
    width: min(100%, 1200px);
}

body > .site-footer {
    margin-top: auto;
}

body.dialog-scroll-locked {
    position: fixed;
    inset: 0;
    overflow: hidden;
    width: 100%;
}

a {
    color: inherit;
}

img {
    max-width: 100%;
    display: block;
}

button,
input,
textarea {
    font: inherit;
}

select {
    font: inherit;
}

/* The hidden attribute must always win - panels/cards set display:grid
   which would otherwise override the UA's [hidden] { display: none }. */
[hidden] {
    display: none !important;
}

.shell {
    width: min(100%, 1200px);
    margin: 0 auto;
    padding: 0 20px;
}

.shell-main {
    padding-top: 12px;
    padding-bottom: 24px;
}

.shell-main > * {
    min-width: 0;
}

.masthead {
    background: var(--bg-dark);
    color: #ffffff;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    position: sticky;
    top: 0;
    z-index: 20;
}

.masthead-inner {
    padding-top: 10px;
    padding-bottom: 10px;
}

.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

.topbar-main {
    display: flex;
    align-items: center;
    gap: 24px;
    min-width: 0;
    flex: 1 1 auto;
}

.brand {
    display: inline-grid;
    gap: 2px;
    text-decoration: none;
}

.brand-wordmark {
    display: inline-flex;
    align-items: baseline;
    direction: ltr;
    font-size: 1.6rem;
    line-height: 1;
    font-weight: 700;
    letter-spacing: 0.01em;
}

.brand-wordmark-init {
    color: #ffffff;
}

.brand-wordmark-max {
    background: linear-gradient(113deg, var(--accent) 0%, var(--accent-alt) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    color: transparent;
}

.brand-subtitle {
    color: rgba(255, 255, 255, 0.74);
    font-size: 0.92rem;
}

.nav-pills {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.nav-pills-inline {
    flex: 1 1 auto;
}

.portal-nav {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.portal-nav-inline {
    flex: 1 1 auto;
    align-items: center;
}

/* Wide desktop: center the main nav on the content axis so it reads as its
   own group, clearly separated from the "initMAX | Portal" brand on the left.
   The masthead shell shares the content column's centre, so absolutely
   centering the nav within .topbar lines it up with the page content below.
   Only applied above 1100px, where there is room on both sides of the nav so
   it never overlaps the brand or the action buttons; narrower desktops and
   the mobile toggle menu (<=720px) keep the nav in normal flow. */
@media (min-width: 1101px) {
    .topbar {
        position: relative;
    }

    .portal-nav-inline {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        flex: 0 0 auto;
        flex-wrap: nowrap;
        white-space: nowrap;
    }
}

.portal-nav-link {
    display: inline-flex;
    align-items: center;
    min-height: 34px;
    padding: 0 13px;
    font-size: 0.92rem;
    border-radius: 8px;
    text-decoration: none;
    color: rgba(255, 255, 255, 0.72);
    border: 1px solid rgba(255, 255, 255, 0.08);
    background: rgba(255, 255, 255, 0.03);
    transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.portal-nav-link:hover,
.portal-nav-link.is-active {
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.16);
    background: rgba(255, 255, 255, 0.08);
}

/* Russian nav labels ("Администрирование" etc.) run measurably wider than
   every other locale and overflow into the theme/language toggles above the
   1101px breakpoint where the nav is absolutely centered (see
   .portal-nav-inline). Tighten just this locale rather than reserving fixed
   space for everyone else, which fits comfortably as-is.
   Keyed off body[data-locale] rather than :lang() - the locale switcher is a
   Turbo-driven form submit, and Turbo replaces <body> wholesale on every
   visit (so a server-rendered attribute on <body> is correct immediately)
   but does not sync attributes on <html>, so :lang() only caught up after a
   full reload. */
[data-locale='ru'] .portal-nav-inline {
    gap: 4px;
}

[data-locale='ru'] .portal-nav-link {
    padding: 0 7px;
    font-size: 0.78rem;
}

.nav-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 34px;
    padding: 0 13px;
    font-size: 0.92rem;
    border-radius: 8px;
    text-decoration: none;
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: rgba(255, 255, 255, 0.04);
    color: rgba(255, 255, 255, 0.78);
    transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.nav-chip:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.18);
    color: #ffffff;
}

.topbar-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    flex-wrap: wrap;
    flex: 0 0 auto;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.theme-switcher,
.locale-switcher {
    position: relative;
    display: flex;
    align-items: center;
}

.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    background:
        radial-gradient(circle at top right, rgba(113, 80, 247, 0.24), transparent 42%),
        rgba(255, 255, 255, 0.08);
    color: #ffffff;
    cursor: pointer;
    transition: transform 0.2s ease, background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

.theme-toggle:hover,
.theme-toggle[aria-expanded='true'] {
    transform: translateY(-1px);
    background:
        radial-gradient(circle at top right, rgba(113, 80, 247, 0.28), transparent 42%),
        rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow: 0 16px 36px rgba(7, 13, 24, 0.24);
}

.theme-toggle-icon,
.theme-menu-icon,
.theme-menu-check,
.locale-toggle-flag,
.locale-menu-flag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.theme-toggle-icon svg {
    width: 20px;
    height: 20px;
}

.theme-menu {
    position: absolute;
    top: calc(100% + 14px);
    right: 0;
    min-width: 240px;
    max-width: calc(100vw - 40px);
    padding: 7px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    background:
        linear-gradient(180deg, rgba(48, 58, 79, 0.98) 0%, rgba(31, 39, 55, 0.98) 100%);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.36);
    backdrop-filter: blur(16px);
}

.theme-menu[hidden] {
    display: none;
}

.theme-menu-item {
    width: 100%;
    display: grid;
    grid-template-columns: 32px minmax(0, 1fr) 18px;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: #ffffff;
    text-align: left;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.theme-menu-item:hover {
    background: rgba(255, 255, 255, 0.06);
}

.theme-menu-item.is-selected {
    background:
        linear-gradient(90deg, rgba(31, 101, 244, 0.28) 0%, rgba(113, 80, 247, 0.14) 100%);
}

.theme-menu-icon {
    width: 32px;
    height: 32px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.7);
}

.theme-menu-item.is-selected .theme-menu-icon {
    background: rgba(255, 255, 255, 0.1);
    color: #ffffff;
}

.theme-menu-icon svg,
.theme-menu-check svg {
    width: 18px;
    height: 18px;
}

.theme-menu-copy {
    display: grid;
    gap: 2px;
}

.theme-menu-title {
    font-size: 0.95rem;
    font-weight: 500;
}

.theme-menu-caption {
    color: rgba(255, 255, 255, 0.72);
    font-size: 0.8rem;
}

.theme-menu-check {
    color: #ffffff;
    opacity: 0;
    transform: scale(0.85);
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.theme-menu-item.is-selected .theme-menu-check {
    opacity: 1;
    transform: scale(1);
}

.locale-toggle {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.12);
    /* Square frame matching .theme-toggle next to it; the flag sits inside
       as a small rounded chip. */
    border-radius: 8px;
    overflow: hidden;
    background:
        radial-gradient(circle at top right, rgba(31, 101, 244, 0.28), transparent 44%),
        rgba(255, 255, 255, 0.08);
    color: #ffffff;
    cursor: pointer;
    transition: transform 0.2s ease, background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

.locale-toggle:hover,
.locale-toggle[aria-expanded='true'] {
    transform: translateY(-1px);
    background:
        radial-gradient(circle at top right, rgba(31, 101, 244, 0.34), transparent 44%),
        rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow: 0 16px 36px rgba(7, 13, 24, 0.24);
}

/* The flag covers the whole control edge-to-edge (incl. the border zone) so
   sub-pixel rounding can never leave a dark crescent inside the circle. */
.locale-toggle-flag {
    display: inline-flex;
    width: 20px;
    height: 20px;
    border-radius: 5px;
    overflow: hidden;
}

.locale-toggle-flag svg {
    width: 100%;
    height: 100%;
}

.locale-menu-flag svg {
    width: 22px;
    height: 22px;
}

.locale-menu {
    position: absolute;
    top: calc(100% + 14px);
    right: 0;
    min-width: 190px;
    max-width: calc(100vw - 40px);
    max-height: min(70vh, 560px);
    overflow-y: auto;
    /* Scrollable but without a visible scrollbar. */
    scrollbar-width: none;
    padding: 6px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    background:
        linear-gradient(180deg, rgba(48, 58, 79, 0.98) 0%, rgba(31, 39, 55, 0.98) 100%);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.36);
    backdrop-filter: blur(16px);
}

.locale-menu[hidden] {
    display: none;
}

.locale-menu-item {
    width: 100%;
    display: grid;
    grid-template-columns: 22px minmax(0, 1fr);
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: #ffffff;
    text-decoration: none;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.locale-menu-item:hover {
    background: rgba(255, 255, 255, 0.06);
}

.locale-menu-item.is-selected {
    background:
        linear-gradient(90deg, rgba(31, 101, 244, 0.28) 0%, rgba(113, 80, 247, 0.14) 100%);
}

.locale-menu-flag {
    width: 22px;
    height: 22px;
    border-radius: 999px;
}

.locale-menu-copy {
    display: grid;
    gap: 2px;
}

.locale-menu-title {
    font-size: 0.92rem;
    font-weight: 500;
}

.locale-menu-caption {
    color: rgba(255, 255, 255, 0.72);
    font-size: 0.84rem;
}

.profile-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 32px;
    min-width: 0;
    max-width: 250px;
    padding: 2px 10px 2px 4px;
    border-radius: 8px;
    text-decoration: none;
    color: #ffffff;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background:
        radial-gradient(circle at top right, rgba(113, 80, 247, 0.24), transparent 42%),
        rgba(255, 255, 255, 0.06);
    cursor: pointer;
    font: inherit;
    transition: transform 0.2s ease, background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

/* Hover only - the route-active state gets its own quiet styling further
   down; this shared dark-glass gradient + lift + 36px shadow leaked onto the
   light masthead whenever /profile* was open, reading as a stuck-open menu
   (visual-audit finding on 4 pages). */
.profile-chip:hover {
    transform: translateY(-1px);
    background:
        radial-gradient(circle at top right, rgba(113, 80, 247, 0.28), transparent 42%),
        rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.18);
    box-shadow: 0 16px 36px rgba(7, 13, 24, 0.24);
}

.profile-chip-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    /* 24px avatar keeps the whole chip at 32px - the same control height
       as the theme/locale toggles next to it. */
    width: 24px;
    height: 24px;
    border-radius: 999px;
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-alt) 100%);
    color: #ffffff;
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    overflow: hidden;
}

.profile-chip-avatar-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
}

.profile-chip-copy {
    display: grid;
    gap: 1px;
    min-width: 0;
    flex: 1 1 auto;
}

.profile-chip-name {
    font-size: 0.84rem;
    font-weight: 600;
    line-height: 1.1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.profile-chip-role {
    color: rgba(255, 255, 255, 0.76);
    font-size: 0.7rem;
    line-height: 1.1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.profile-switcher {
    position: relative;
    display: flex;
    align-items: center;
}

.profile-chip-caret {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: rgba(255, 255, 255, 0.72);
}

.profile-chip-caret svg {
    width: 16px;
    height: 16px;
}

.profile-menu {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    width: 220px;
    max-width: calc(100vw - 40px);
    padding: 8px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    background:
        linear-gradient(180deg, rgba(48, 58, 79, 0.98) 0%, rgba(31, 39, 55, 0.98) 100%);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.36);
    backdrop-filter: blur(16px);
}

.profile-menu[hidden] {
    display: none;
}

.profile-menu-item {
    width: 100%;
    display: grid;
    grid-template-columns: 32px minmax(0, 1fr);
    align-items: center;
    gap: 10px;
    min-height: 0;
    padding: 8px 10px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: #ffffff;
    text-decoration: none;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.profile-menu-item:hover {
    background: rgba(255, 255, 255, 0.05);
}

.profile-menu-item.is-selected {
    background:
        linear-gradient(90deg, rgba(31, 101, 244, 0.24) 0%, rgba(113, 80, 247, 0.12) 100%);
}

.profile-menu-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.84);
}

.profile-menu-icon svg {
    width: 18px;
    height: 18px;
}

.profile-menu-copy {
    display: grid;
    gap: 0;
    min-width: 0;
}

.profile-menu-title {
    font-size: 0.94rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.button,
.button:visited {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    /* Repo scale: action buttons on repo.initmax.com are 28-30px tall with
       ~13px labels - the portal previously ran 38px/15px and read bulky. */
    min-height: 30px;
    padding: 0 14px;
    border: 0;
    border-radius: var(--radius-sm);
    text-decoration: none;
    font-weight: 600;
    font-size: 0.84rem;
    cursor: pointer;
    transition: transform 0.2s ease, background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}

.button:hover {
    transform: translateY(-1px);
}

.button.is-submitting,
.button.is-submitting:visited {
    pointer-events: none;
    cursor: progress;
}

.button.is-submitting:hover {
    transform: none;
}

.button-primary,
.button-primary:visited {
    background: var(--grad);
    color: #ffffff;
}

.button-primary:hover {
    filter: brightness(0.98);
}

.button-secondary,
.button-secondary:visited {
    background: linear-gradient(180deg, rgba(31, 101, 244, 0.16) 0%, rgba(113, 80, 247, 0.16) 100%);
    border: 1px solid rgba(31, 101, 244, 0.24);
    color: var(--text);
}

.button-ghost,
.button-ghost:visited {
    background: transparent;
    border: 1px solid var(--border-strong);
    color: var(--text);
}

.button-dark,
.button-dark:visited {
    background: var(--button-dark-bg);
    border: 1px solid var(--button-dark-border);
    color: var(--button-dark-text);
}

.button-dark:hover {
    background: var(--button-dark-bg-hover);
}

.button-icon-svg {
    font-size: 1.2rem;
    flex-shrink: 0;
}

.button-compact,
.button-compact:visited {
    min-height: 26px;
    padding: 0 10px;
    font-size: 0.8rem;
}

.inline-form,
.menu-form {
    margin: 0;
}

.menu-form {
    display: block;
}

.flash-list {
    display: grid;
    gap: 10px;
    margin-bottom: 20px;
}

.flash {
    padding: 14px 18px;
    border-radius: var(--radius-sm);
    border: 1px solid rgba(31, 101, 244, 0.16);
    background: rgba(31, 101, 244, 0.08);
    color: var(--text);
}

.hero-shell {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(320px, 0.9fr);
    gap: 20px;
    padding: 24px;
    border-radius: var(--radius-lg);
    background: var(--bg-panel);
    border: 1px solid var(--border);
    color: var(--text);
    box-shadow: var(--shadow-sm);
}

.page-hero {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(280px, 0.8fr);
    gap: 12px;
    padding: 6px 4px 2px;
    color: var(--text);
}

.page-hero-stack {
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
}

/* Toolbar row used on /support and similar pages: filter segments + a
   primary action button. Without this they stacked vertically inside the
   `.page-hero-stack` parent grid. */
.catalog-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: center;
    justify-content: space-between;
}
.catalog-toolbar .hero-actions {
    flex-shrink: 0;
}


.page-hero-admin {
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
}

.hero-copy {
    display: grid;
    align-content: start;
    gap: 12px;
    min-width: 0;
}

.hero-heading,
.page-title {
    margin: 0;
    /* Compact, consistent page headers: the previous clamp went up to 4.8rem
       which pushed actual content below the fold on every page. */
    font-size: clamp(1.2rem, 1.6vw, 1.45rem);
    line-height: 1.15;
    font-weight: 600;
}

.hero-heading {
    max-width: 11ch;
}

.hero-heading .gradient-text,
.gradient-text {
    background: linear-gradient(113deg, var(--accent) 0%, var(--accent-alt) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    color: transparent;
}

.hero-text,
.lead {
    margin: 0;
    max-width: 70ch;
    color: var(--muted);
    font-size: 0.86rem;
}

/* Catalog product hero: description is stored as "tagline\nlong description" -
   keep the author's line breaks so the tagline reads as its own line instead of
   running straight into the description sentence. */
.lead-preline {
    white-space: pre-line;
}

.eyebrow {
    display: inline-flex;
    align-items: center;
    width: fit-content;
    min-height: 22px;
    padding: 0 10px;
    border-radius: 999px;
    background: var(--accent-soft);
    border: 1px solid rgba(113, 80, 247, 0.22);
    color: var(--accent-ink);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.7rem;
    font-weight: 600;
}

.hero-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding-top: 6px;
}

/* When the actions are a direct hero child they fill the hero's second grid
   column, and the default flex-start pinned the buttons to the column's LEFT
   edge - i.e. floating mid-page, aligned to nothing (visual-audit: partner
   customers "Add customer"/"Back"). Pin them to the content's right edge and
   the hero's top. Scoped with `>` so .hero-actions inside auth cards and form
   panels keep their layout. */
.page-hero > .hero-actions {
    justify-self: end;
    justify-content: flex-end;
    align-self: start;
}



.hero-side {
    display: grid;
    gap: 16px;
    min-width: 0;
}

.highlight-card,
.panel,
.card,
.stat-card,
.feature-card,
.auth-card,
.auth-aside {
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow);
}

.highlight-card {
    padding: 22px;
    background: linear-gradient(180deg, rgba(31, 101, 244, 0.08) 0%, var(--bg-panel) 100%);
    border-color: var(--border);
    color: var(--text);
}

.highlight-card h2,
.highlight-card h3,
.panel h2,
.feature-card h2,
.auth-aside h2,
.auth-card h1 {
    margin: 0;
    font-weight: 600;
    /* Compact: panel headings one notch above body text, not browser 1.5em. */
    font-size: 1.05rem;
}

.highlight-list,
.detail-list,
.account-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 12px;
}

.highlight-list li,
.detail-list li,
.account-list li {
    display: flex;
    justify-content: space-between;
    gap: 12px;
}

.account-list.compact li {
    justify-content: flex-start;
    gap: 8px;
    flex-wrap: wrap;
}

.highlight-label {
    color: var(--muted);
}

.detail-label {
    color: var(--muted);
}

.auth-aside .detail-label {
    color: var(--muted);
}

.info-line-dark .detail-label {
    color: var(--muted);
}

.info-line-dark .detail-value {
    color: var(--text);
}

.highlight-value,
.detail-value {
    font-weight: 600;
}

.detail-value-wrap {
    overflow-wrap: anywhere;
}

.contact-card-shell {
    display: grid;
    grid-template-columns: 92px minmax(0, 1fr);
    gap: 18px;
    align-items: center;
    margin-top: 16px;
}

.contact-card-avatar {
    width: 92px;
    height: 92px;
    border-radius: 999px;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background:
        radial-gradient(circle at top right, rgba(113, 80, 247, 0.42), transparent 48%),
        linear-gradient(180deg, rgba(31, 101, 244, 0.32) 0%, rgba(255, 255, 255, 0.14) 100%);
    border: 1px solid rgba(255, 255, 255, 0.14);
    color: #ffffff;
    font-size: 1.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    box-shadow: 0 18px 36px rgba(7, 13, 24, 0.24);
}

.contact-card-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
}

.profile-summary-header {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 18px;
}

.profile-summary-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    border-radius: 999px;
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-alt) 100%);
    color: #ffffff;
    font-size: 1.5rem;
    font-weight: 700;
    overflow: hidden;
}

.profile-summary-avatar-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
}

.profile-summary-copy {
    display: grid;
    gap: 4px;
}

.profile-summary-copy strong {
    font-size: 1.08rem;
}

.contact-card-copy {
    display: grid;
    gap: 6px;
    min-width: 0;
}

.contact-card-tagline {
    color: var(--muted);
    font-size: 0.84rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.contact-card-name {
    margin: 0;
    font-size: clamp(1.55rem, 2vw, 2rem);
    line-height: 1.05;
}

.contact-card-role,
.contact-card-phone {
    color: var(--muted);
}

.contact-card-link {
    display: inline-flex;
    width: fit-content;
    max-width: 100%;
    align-items: center;
    min-height: 36px;
    padding: 0 14px;
    border-radius: 999px;
    text-decoration: none;
    color: var(--accent);
    background: var(--bg-soft);
    border: 1px solid var(--border);
    overflow-wrap: anywhere;
}

.contact-card-link:hover {
    background: var(--bg-muted);
}

.kpi-grid,
.feature-grid {
    display: grid;
    gap: 16px;
}

.kpi-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Plain .kpi-grid (provisioning page) often holds a single stat card. Fixed
   fractional columns left it stranded in the left column with empty space to
   its right; size columns to content and align them to the right edge so the
   card sits flush right instead of floating. Admin pages use .admin-kpi-grid
   and keep their own flex layout. */
.kpi-grid:not(.admin-kpi-grid) {
    grid-template-columns: repeat(auto-fit, 220px);
    justify-content: end;
}

.page-hero-admin .kpi-grid,
.admin-kpi-grid {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 6px;
    width: 100%;
}

.admin-kpi-grid .stat-card {
    display: flex;
    /* grow to fill the row edge-to-edge like the card grid below (basis auto
       keeps the nowrap labels their natural size, extra width trails right). */
    flex: 1 1 auto;
    align-items: baseline;
    gap: 6px;
    padding: 10px 12px;
}

.admin-kpi-grid .stat-label {
    margin-bottom: 0;
    font-size: 0.76rem;
    white-space: nowrap;
}

/* Secondary metric inside a KPI chip ("30 d: 35" next to the 24h value):
   divide it from the primary number, otherwise the row read as one glued
   value like "0 30" (visual-audit admin/07). */
.admin-kpi-grid .stat-card .muted.small {
    border-left: 1px solid var(--border-strong);
    padding-left: 8px;
    margin-left: 2px;
    white-space: nowrap;
}

.admin-kpi-grid .stat-value {
    font-size: 1.05rem;
}

.stat-card {
    padding: 10px 14px;
    background: var(--bg-panel);
    color: var(--text);
}

.stat-label {
    color: var(--muted);
    font-size: 0.8rem;
    margin-bottom: 4px;
}

.stat-value {
    font-size: 1.5rem;
    line-height: 1;
    font-weight: 600;
}

.section-block {
    margin-top: 12px;
}

.section-header {
    display: flex;
    align-items: end;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}

/* Bare section headings (h2 directly under .section-block, e.g.
   'Existing tokens', 'Pending', 'Customer groups') match .section-title. */
.section-block > h2,
.section-block > .stack-sm > h2 {
    margin: 0 0 8px;
    font-size: 1.1rem;
    line-height: 1.2;
}

.panel h3,
.subpanel h3 {
    margin: 0;
    font-size: 0.95rem;
}

.section-title {
    margin: 0;
    /* One step below .page-title so the H1 > H2 hierarchy reads clearly. */
    font-size: 1.1rem;
    line-height: 1.2;
    font-weight: 600;
}

.section-copy {
    margin: 4px 0 0;
    color: var(--muted);
    font-size: 0.85rem;
    max-width: 62ch;
}

/* Multi-paragraph docs copy (provisioning webhook sections): space the
   paragraphs so the text reads as distinct steps instead of one dense block. */
.section-copy-doc p {
    margin: 0;
}

.section-copy-doc p + p {
    margin-top: 8px;
}

.content-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(320px, 0.9fr);
    gap: 12px;
    min-width: 0;
    /* Top-align the columns (same as .detail-layout): the default stretch
       inflated the short aside card to the tall form's height, leaving
       hundreds of px of dead white space (visual-audit: profile, staff SSO,
       partner customer detail). */
    align-items: start;
}

.panel {
    padding: 14px 16px;
    min-width: 0;
}

.stack {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
}

.stack-sm {
    display: grid;
    gap: 8px;
}

.stack-xxs {
    display: grid;
    gap: 4px;
}

.release-item,
.event-item,
.feature-card,
.info-line,
.subpanel {
    padding: 8px 12px;
    border-radius: 8px;
    background: var(--bg-soft);
    border: 1px solid var(--border);
}

.panel-subtle {
    padding: 12px;
    border-radius: 12px;
    background: var(--bg-soft);
    border: 1px solid var(--border);
    box-shadow: none;
}

.release-header,
.event-header,
.info-line {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    align-items: start;
}

/* Long labels ('Update instructions') were wrapping into two lines while
   a long value next to them ran into the label column. Pin the label to
   a min column width + force its text to keep on one line, value flows
   right and wraps as needed. */
.info-line .detail-label {
    flex: 0 0 11rem;
    word-break: keep-all;
}
.info-line .detail-value {
    flex: 1 1 auto;
    text-align: right;
    /* Long email addresses ('tomas.hermanek@initmax.cz') and similarly
       long unbroken strings were overflowing past the right edge of the
       containing panel. anywhere lets the value wrap inside any glyph
       boundary without sacrificing readability for short values. */
    min-width: 0;
    overflow-wrap: anywhere;
    word-break: break-word;
}

.release-header > *,
.event-header > *,
.info-line > *,
.ticket-comment-head > *,
.download-row > * {
    min-width: 0;
}

.release-title,
.event-title {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.info-line-stack {
    align-items: flex-start;
}

.muted {
    color: var(--muted);
}

.auth-aside .muted {
    color: var(--muted);
}

.text-link {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}

.text-link-danger {
    color: #c93c3c;
}

:root[data-theme='dark'] .text-link-danger {
    color: #ffbaba;
}

.text-link-button {
    border: 0;
    background: transparent;
    padding: 0;
    font: inherit;
    cursor: pointer;
}

.small {
    font-size: 0.92rem;
}

.button-danger,
.button-danger:visited {
    /* .button has border:0; danger only set a border-color, so the outline
       never showed. Add width+style here so the thin border renders in both
       themes (colour is themed separately below). */
    border-width: 1px;
    border-style: solid;
    border-color: rgba(220, 60, 60, 0.35);
    color: #c93c3c;
}

.button-danger:hover {
    background: rgba(220, 60, 60, 0.08);
}

:root[data-theme='dark'] .button-danger,
:root[data-theme='dark'] .button-danger:visited {
    border-color: rgba(255, 120, 120, 0.3);
    color: #ffbaba;
}

:root[data-theme='dark'] .button-danger:hover {
    background: rgba(255, 120, 120, 0.08);
}

.table-actions {
    display: flex;
    /* One line - stacked action links made every row twice as tall.
       The .table-shell scrolls horizontally if space runs out. */
    flex-wrap: nowrap;
    align-items: center;
    justify-content: flex-end;
    gap: 10px 14px;
    white-space: nowrap;
}

.pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: fit-content;
    min-height: 24px;
    padding: 0 10px;
    font-size: 0.74rem;
    white-space: nowrap;
    border-radius: 999px;
    background: var(--accent-soft);
    border: 1px solid rgba(113, 80, 247, 0.2);
    color: var(--accent-ink);
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.pill-dark {
    background: var(--bg-dark);
    border-color: var(--bg-dark);
    color: #ffffff;
}

.pill-warning {
    background: rgba(255, 184, 77, 0.12);
    border-color: rgba(255, 184, 77, 0.28);
    color: #b47a00;
}

:root[data-theme='dark'] .pill-warning {
    color: #ffcf7d;
}

/* aozcm8s Downloads per-user: the two count pills read as a summary row. */
.count-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.feature-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.card-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
}

.product-card,
.version-card,
.form-panel {
    padding: 16px;
}

.form-panel {
    background: var(--bg-panel);
    border-color: rgba(176, 190, 219, 0.18);
}

.meta-grid {
    display: grid;
    gap: 12px;
}

.download-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 18px;
    border-radius: 1.2rem;
    border: 1px solid var(--border);
    background: var(--bg-soft);
}

.section-block-tight {
    margin-top: 20px;
}

.admin-link-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    /* Equal-height rows across the whole grid: without this each row only
       matched its own tallest card, so the last row (shorter descriptions)
       was noticeably shorter than the rows above it. 1fr makes every row take
       the tallest card's height, so all tiles are the same size. */
    grid-auto-rows: 1fr;
    gap: 16px;
}

.admin-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 8px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--bg-panel);
    box-shadow: var(--shadow-sm);
}

.admin-tab {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 32px;
    padding: 0 12px;
    font-size: 0.9rem;
    border-radius: 7px;
    border: 1px solid transparent;
    color: var(--muted);
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease, transform 0.18s ease;
}

.admin-tab:hover {
    color: var(--text);
    border-color: var(--border);
    background: rgba(31, 101, 244, 0.08);
    transform: translateY(-1px);
}

.admin-tab.is-active {
    color: #ffffff;
    border-color: rgba(111, 93, 247, 0.35);
    background: linear-gradient(113deg, var(--accent) 0%, var(--accent-alt) 100%);
    box-shadow: 0 14px 28px rgba(29, 76, 201, 0.24);
}

.admin-link-card {
    display: grid;
    /* Pin the heading row to its content (auto) and let the description take the
       rest (1fr). Cards in a row stretch to equal height, and without this the
       spare height was split into the heading row, so single-line titles like
       "Entitlements" floated with an oversized gap above their text while
       longer descriptions sat tight. Now the heading-to-text gap is a
       consistent 12px across every tile. */
    grid-template-rows: auto 1fr;
    gap: 12px;
    padding: 22px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--bg-panel);
    box-shadow: var(--shadow);
    text-decoration: none;
    color: var(--text);
    transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}

.admin-link-card:hover,
.admin-link-card.is-active {
    transform: translateY(-1px);
    border-color: rgba(31, 101, 244, 0.28);
    box-shadow: 0 24px 60px rgba(13, 20, 45, 0.12);
}

.admin-link-card h2 {
    margin: 0;
    font-size: 1.15rem;
}

.admin-link-card p {
    margin: 0;
    color: var(--muted);
}

/* ---------------------------------------------------------------------------
   Cursor spotlight on the admin hub cards - DESIGN PROPOSAL (Martin's idea).
   Decorative only: a soft glow in the portal accent colour follows the cursor
   across each card. Uses --accent so it respects the theme and tenant brand;
   the existing hover lift above is untouched. Driven by the "spotlight"
   Stimulus controller (sets --mx/--my). Wrapped in @media (hover: hover) so it
   never loads on touch devices. To remove the whole effect, delete this block
   plus the spotlight controller, its registration and data-controller in
   templates/admin/index.html.twig - nothing else depends on it.
   --------------------------------------------------------------------------- */
@media (hover: hover) {
    .admin-link-card {
        position: relative;
        overflow: hidden;
    }

    /* Keep the heading/description above the glow layer. */
    .admin-link-card > * {
        position: relative;
        z-index: 1;
    }

    .admin-link-card::before {
        content: "";
        position: absolute;
        inset: 0;
        pointer-events: none;
        opacity: 0;
        transition: opacity 0.25s ease;
        /* Fallback for browsers without color-mix(): a fixed translucent
           accent tint. Modern browsers override it with the tenant accent. */
        background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 50%),
            rgba(31, 101, 244, 0.16), transparent 60%);
        background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 50%),
            color-mix(in srgb, var(--accent) 16%, transparent), transparent 60%);
    }

    .admin-link-card:hover::before {
        opacity: 1;
    }
}

.admin-product-list {
    display: grid;
    gap: 18px;
}

.admin-product-card {
    display: grid;
    gap: 12px;
    padding: 18px;
}

/* Per-product editorial settings are secondary content - keep the inputs
   at toolbar height (38px) instead of the full 48px form scale so the
   card stays compact. */
.admin-product-settings input[type='url'] {
    min-height: 38px;
    max-width: 560px;
}

.admin-product-settings .checkbox-label {
    font-weight: 500;
}

.admin-product-settings p.muted.small {
    margin: 0;
    max-width: 64ch;
}

.admin-product-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 18px;
}

.admin-product-title-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.admin-product-title-row h2 {
    margin: 0;
    font-size: 1.2rem;
}

.admin-product-copy {
    margin: -6px 0 0;
}

.admin-product-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
}

.admin-product-version-list {
    display: grid;
    gap: 12px;
}

.admin-product-version-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    padding: 16px 18px;
    border-radius: 1.1rem;
    border: 1px solid var(--border);
    background: var(--bg-soft);
}

.admin-product-version-main {
    display: grid;
    gap: 6px;
    min-width: 0;
}

.admin-product-version-title {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.admin-product-version-meta {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    color: var(--muted);
    font-size: 0.88rem;
}

.changelog-list {
    display: grid;
    gap: 14px;
}

.changelog-item {
    padding: 18px;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--bg-soft);
}

.changelog-item h4 {
    margin: 12px 0 8px;
}

.section-header-compact {
    margin-bottom: 14px;
    align-items: start;
}

.section-title-sm {
    font-size: 1.1rem;
}

.version-changelog {
    display: grid;
    gap: 16px;
}

.changelog-highlight {
    display: grid;
    gap: 10px;
    padding: 18px 20px;
    border-radius: 10px;
    border: 1px solid rgba(113, 80, 247, 0.2);
    background:
        radial-gradient(circle at top right, rgba(113, 80, 247, 0.18), transparent 34%),
        linear-gradient(180deg, rgba(31, 101, 244, 0.08) 0%, rgba(255, 255, 255, 0.02) 100%),
        var(--bg-soft);
}

.changelog-highlight-label {
    color: var(--muted);
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.changelog-highlight-main {
    display: grid;
    gap: 6px;
}

.changelog-highlight-version {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    font-size: 1.08rem;
    font-weight: 700;
    color: var(--text);
}

.changelog-highlight-version span {
    color: var(--muted);
    font-size: 0.88rem;
    font-weight: 500;
}

.changelog-highlight p {
    margin: 0;
    color: var(--text);
    line-height: 1.6;
}

.changelog-feed {
    display: grid;
    gap: 12px;
}

.catalog-raw-changelog {
    display: grid;
    gap: 14px;
    padding: 18px 20px;
    border-radius: 1.2rem;
    border: 1px dashed var(--border);
    background: var(--bg-soft);
}

.catalog-raw-changelog h4 {
    margin: 0;
}

.catalog-raw-changelog-toggle {
    display: grid;
    gap: 12px;
}

.catalog-raw-changelog-toggle summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--text);
}

.catalog-raw-changelog-toggle pre {
    margin: 0;
    padding: 16px 18px;
    border-radius: 1rem;
    border: 1px solid var(--border);
    background: rgba(7, 13, 24, 0.14);
    color: var(--text);
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
    font-family: ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, monospace;
    font-size: 0.88rem;
    line-height: 1.55;
}

.changelog-entry {
    display: grid;
    grid-template-columns: 20px minmax(0, 1fr);
    gap: 14px;
    align-items: stretch;
}

.changelog-entry-rail {
    display: grid;
    justify-items: center;
    grid-template-rows: 18px minmax(0, 1fr);
}

.changelog-entry-dot {
    width: 12px;
    height: 12px;
    margin-top: 4px;
    border-radius: 999px;
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-alt) 100%);
    box-shadow: 0 0 0 5px rgba(31, 101, 244, 0.12);
}

.changelog-entry-line {
    width: 2px;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(180deg, rgba(31, 101, 244, 0.34) 0%, rgba(113, 80, 247, 0.08) 100%);
}

.changelog-entry-card {
    display: grid;
    gap: 12px;
    padding: 18px 20px;
    border-radius: 1.25rem;
    border: 1px solid var(--border);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.02) 0%, transparent 100%),
        var(--bg-soft);
}

.changelog-entry-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.changelog-entry-index {
    color: var(--muted);
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.08em;
}

.changelog-entry-card h4 {
    margin: 0;
    font-size: 1.02rem;
    line-height: 1.35;
}

.changelog-entry-card p {
    margin: 0;
    line-height: 1.65;
}

.changelog-history,
.changelog-history-entry-list {
    display: grid;
    gap: 12px;
}

.changelog-history-version {
    display: grid;
    gap: 12px;
    padding: 18px;
    border-radius: 1.25rem;
    border: 1px solid var(--border);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.03) 0%, transparent 100%),
        var(--bg-soft);
}

.changelog-history-version-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.changelog-history-version-title {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.changelog-history-entry {
    display: grid;
    gap: 8px;
    padding: 14px 16px;
    border-radius: 1rem;
    border: 1px solid var(--border);
    background: var(--bg-panel);
}

.changelog-history-entry p {
    margin: 0;
    line-height: 1.65;
}

.catalog-toolbar-unified {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px;
    border-radius: 10px;
    background: var(--bg-soft);
    border: 1px solid var(--border);
}

.catalog-toolbar-unified .catalog-search-field {
    grid-column: 2 / 3;
    justify-self: stretch;
    min-width: 0;
    width: auto;
    max-width: 100%;
}

.catalog-toolbar-unified .catalog-segmented {
    grid-column: 1 / 2;
    justify-self: start;
}

.catalog-toolbar-unified > .button {
    white-space: nowrap;
    /* Match the 34px control height of the segments / search / version
       dropdown sitting in the same row. */
    min-height: 34px;
}

.catalog-toolbar-unified .catalog-version-select {
    grid-column: 3 / 4;
    justify-self: end;
    width: 100%;
}

.catalog-toolbar-unified > .button-ghost {
    grid-column: 1 / -1;
    justify-self: end;
}

.catalog-version-select {
    height: 34px;
    min-height: 34px;
    padding: 0 44px 0 14px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18' fill='none'%3E%3Cpath d='M4.5 6.75L9 11.25L13.5 6.75' stroke='%234b5475' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 14px center / 18px 18px,
        var(--field-bg);
    color: var(--text);
    font: inherit;
    font-size: 0.86rem;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}

/* ---- Product detail redesign: hero facts, 2-col layout, install tabs,
   release accordion, sidebar. ---- */
.detail-hero {
    align-items: flex-start;
}

.detail-hero-title {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.detail-facts {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.detail-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 18px;
    align-items: start;
    /* Same breathing room below the hero facts as between sections. */
    margin-top: 12px;
}

@media (max-width: 1020px) {
    .detail-layout {
        grid-template-columns: 1fr;
    }
}

/* No screenshots -> no sidebar; main content takes the full width
   instead of leaving an empty 320px gap on the right. */
.detail-layout-single {
    grid-template-columns: minmax(0, 1fr);
}

/* Full-width gallery row (screenshots moved from the sidebar into the
   main column) - small fixed-size thumbnails, the click-through lightbox
   shows the full image. */
/* Wide gallery: all shots side by side in one filled row, wrapping on
   narrow screens. Higher specificity (.screenshot-grid.screenshot-grid-wide)
   so it wins over the base .screenshot-grid 2-column grid regardless of
   source order - otherwise small thumbs marooned left in half-width cells
   leave a big empty gap. */
.screenshot-grid.screenshot-grid-wide {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 12px;
    align-items: start;
}

.screenshot-grid.screenshot-grid-wide a {
    width: auto;
}

/* Show the whole screenshot (no edge cropping) at natural aspect ratio -
   overrides the base .screenshot-grid 16/10 cover crop. */
.screenshot-grid.screenshot-grid-wide img {
    aspect-ratio: auto;
    object-fit: contain;
    height: auto;
}

.detail-card {
    display: grid;
    gap: 12px;
    padding: 18px;
}

.detail-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
}

.detail-card .section-copy {
    margin: 0;
}

.detail-tabs .catalog-segment {
    padding: 0 12px;
    font-size: 0.8rem;
}

/* Two-step install picker: 1) OS, 2) edition - one shared OS selection
   recycled by both the FREE and PRO instructions. */
.install-steps {
    display: grid;
    gap: 8px;
}

.install-step {
    /* Fixed label column so both segmented controls start at the same x. */
    display: grid;
    grid-template-columns: 210px minmax(0, 1fr);
    align-items: center;
    gap: 12px;
}

.install-step-label {
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
}

/* Consistent button sizes across both steps - short labels (FREE, SUSE)
   otherwise render as stubby pills next to the long ones. */
.install-step .catalog-segment {
    min-width: 92px;
    justify-content: center;
}

@media (max-width: 640px) {
    .install-step {
        grid-template-columns: minmax(0, 1fr);
        /* a3o3gy6: match the portal's standard 6px label->control spacing. */
        gap: 6px;
    }
}

/* Grid items default to min-width:auto, so a wide child (code snippet,
   segmented tabs) can blow the card past the viewport on phones. */
.detail-card > * {
    min-width: 0;
}

/* Edition row when PRO is not licensed: FREE pill + Buy PRO button. */
.install-step-buy {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

/* Phone widths: the nowrap KPI chips can out-grow a 390px viewport - let them
   wrap. (Segmented controls wrap globally at <=500px near the end of the
   file, which covers the old detail-tabs-only rule that lived here.) */
@media (max-width: 480px) {
    .admin-kpi-grid .stat-card {
        flex-wrap: wrap;
        max-width: 100%;
    }

    .admin-kpi-grid .stat-label {
        white-space: normal;
    }

    /* aozcm8s: the two count pills stretch as equal halves of the row. */
    .count-pills .pill {
        flex: 1;
    }
}

.release-list {
    display: grid;
    /* Releases render as individual boxes - breathing room between them. */
    gap: 8px;
}

/* Release items are standalone boxes (full border from the shared
   .release-item box rule) - the old divider border-top rules clipped the
   first box's top edge. */

.release-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 9px 2px;
    cursor: pointer;
    list-style: none;
}

.release-summary::-webkit-details-marker {
    display: none;
}

.release-summary-main {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.release-summary-caret {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--muted);
    border-bottom: 2px solid var(--muted);
    transform: rotate(45deg);
    transition: transform 0.15s ease;
}

.release-item[open] > .release-summary .release-summary-caret {
    transform: rotate(-135deg);
}

.release-body {
    padding: 4px 2px 20px;
}

.release-summary-text {
    margin: 0;
}

.release-downloads {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

/* Each edition gets its own bordered group so FREE downloads and the PRO
   block don't blur into one row of buttons. */
.download-group-inline {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 8px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-soft);
}

.screenshot-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
}

.screenshot-grid a {
    display: block;
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    background: var(--bg-soft);
}

.screenshot-grid img {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    transition: transform 0.15s ease;
}

.screenshot-grid a:hover img {
    transform: scale(1.03);
}

/* Inline screenshot slideshow (product detail): one shot at a time in a
   sliding track that auto-advances, with prev/next arrows + dot indicators,
   replacing the static 6-up grid. */
.screenshot-viewport {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-soft);
    /* Keep the gallery compact + centred so a wide screenshot doesn't span
       the whole card width. */
    max-width: 760px;
    margin: 0 auto;
}

/* Horizontal track of full-width slides; the controller translates it by
   -index*100% and the transition gives the slide effect. */
.screenshot-track {
    display: flex;
    transition: transform 0.45s ease;
}

.screenshot-slide {
    flex: 0 0 100%;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Cap the height so a large retina screenshot doesn't dominate the page. */
.screenshot-slide img {
    display: block;
    width: 100%;
    height: auto;
    max-height: 400px;
    object-fit: contain;
}

.slideshow-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    opacity: 0.85;
}

.slideshow-nav:hover {
    opacity: 1;
}

.slideshow-prev {
    left: 10px;
}

.slideshow-next {
    right: 10px;
}

.slideshow-dots {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-top: 10px;
}

.slideshow-dot {
    width: 13px;
    height: 13px;
    padding: 0;
    border-radius: 50%;
    border: 1px solid var(--border);
    background: var(--bg-soft);
    cursor: pointer;
    transition: background 0.15s ease, transform 0.15s ease;
}

.slideshow-dot.is-active {
    background: var(--accent, #1f65f4);
    border-color: var(--accent, #1f65f4);
    transform: scale(1.2);
}

.detail-links {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* PRO unlock panel on the product detail. */
.pro-unlock-panel {
    display: grid;
    gap: 8px;
    margin-bottom: 14px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-soft);
}

.pro-unlock-fields {
    display: flex;
    /* Bottom-align: the select carries a small label above it, so buttons
       must sit on the select row, not the centre of the whole field. */
    align-items: end;
    gap: 10px;
    flex-wrap: wrap;
}

.pro-unlock-field {
    display: grid;
    gap: 4px;
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 600;
}

.pro-unlock-field input,
.pro-unlock-field select {
    /* Explicit height caps the native macOS <select> metrics (min-height alone
       lets it render ~40px there); unifies with the portal's 34px controls. */
    height: 34px;
    min-height: 34px;
    min-width: 240px;
    padding: 0 12px;
    border: 1px solid var(--border-strong);
    border-radius: 8px;
    background: var(--field-bg);
    color: var(--text);
    font: inherit;
    font-size: 0.88rem;
}

.pro-unlock-fields .button {
    min-height: 34px;
}

.pro-unlock-field select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5.25 7 9.25l4-4' stroke='%2393A0BD' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 36px;
    cursor: pointer;
}

.pro-unlock-panel .muted.small,
.pro-unlock-note {
    margin: 0;
}

.pro-unlock-note {
    color: var(--accent);
    font-size: 0.85rem;
    font-weight: 600;
}

/* Compact download buttons (DEB / RPM / ZIP) in the version aside. */
.download-group {
    display: grid;
    gap: 6px;
    align-content: start;
}

.download-buttons {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    flex-wrap: wrap;
}

.download-buttons .button {
    min-width: 64px;
}

.download-group-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* Screenshot lightbox dialog. */
.lightbox-dialog {
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 16px;
    background: transparent;
    max-width: min(1100px, calc(100vw - 32px));
    max-height: calc(100vh - 32px);
    overflow: hidden;
}

.lightbox-dialog::backdrop {
    background: rgba(7, 13, 24, 0.72);
    backdrop-filter: blur(4px);
}

.lightbox-shell {
    position: relative;
    display: grid;
    gap: 10px;
    padding: 14px;
    background: var(--bg-panel);
}

.lightbox-image {
    /* Fixed gallery stage: small/odd-sized images sit centered on the
       stage instead of collapsing the dialog to a few pixels. */
    width: min(1000px, calc(100vw - 80px));
    height: min(640px, calc(100vh - 160px));
    object-fit: contain;
    border-radius: 10px;
    background: var(--bg-soft);
}

.lightbox-close {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 2;
}

.lightbox-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
}

/* Custom dropdown (select_controller) - menu panel matches the masthead
   menus, trigger reuses the .catalog-version-select look. */
.select-field {
    position: relative;
}

.select-toggle {
    display: inline-flex;
    align-items: center;
    text-align: left;
    cursor: pointer;
    width: 100%;
}

.select-menu {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 30;
    min-width: 100%;
    max-height: 320px;
    overflow-y: auto;
    padding: 6px;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--bg-panel);
    box-shadow: var(--shadow);
}

.select-menu[hidden] {
    display: none;
}

.select-menu-item {
    display: block;
    width: 100%;
    padding: 8px 10px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 0.95rem;
    text-align: left;
    cursor: pointer;
    white-space: nowrap;
}

.select-menu-item:hover {
    background: var(--bg-soft);
}

.select-menu-item[aria-selected='true'] {
    color: var(--accent);
    font-weight: 600;
    background: var(--accent-soft);
}

.catalog-segmented {
    display: inline-grid;
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    align-items: center;
    gap: 5px;
    width: fit-content;
    max-width: 100%;
    padding: 3px;
    border-radius: 10px;
    background: var(--bg-soft);
    border: 1px solid var(--border);
}

.catalog-segment {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 26px + 2x3px shell padding + 2x1px border = 34px outer - the repo
       filter-chip height; search field and version select match. */
    min-height: 26px;
    min-width: 0;
    padding: 0 14px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--muted);
    text-decoration: none;
    font-weight: 600;
    font-family: inherit;
    font-size: 0.86rem;
    white-space: nowrap;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

.catalog-segment:hover {
    color: var(--text);
}

.catalog-segment.is-active {
    color: #ffffff;
    background: var(--grad);
    box-shadow: var(--shadow-sm);
}

.catalog-filter-field {
    display: grid;
    gap: 6px;
    min-width: min(100%, 220px);
}

.catalog-filter-label {
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.catalog-inline-filter select {
    display: block;
    width: 100%;
    min-height: 38px;
    padding: 0 40px 0 14px;
    border-radius: 8px;
    border: 1px solid var(--border-strong);
    background:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5.25 7 9.25l4-4' stroke='%2393A0BD' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 14px center,
        var(--field-bg);
    color: var(--text);
    font: inherit;
    line-height: 1.2;
    appearance: none;
    -webkit-appearance: none;
}

.catalog-search-field {
    display: flex;
    align-items: center;
    border-radius: 8px;
    border: 1px solid var(--border-strong);
    background: var(--field-bg);
    overflow: hidden;
}

.catalog-search-input {
    flex: 1;
    min-width: 0;
    min-height: 32px;
    padding: 0 14px;
    border: 0;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 0.95rem;
    line-height: 1.2;
    outline: none;
}

.catalog-search-input::placeholder {
    color: var(--field-placeholder);
}

.catalog-search-button {
    display: flex;
    align-items: center;
    justify-content: center;
    /* 28px + 2x2px margin + 2x1px field border = 34px outer height,
       matching the segmented switch in the same toolbar. */
    width: 28px;
    height: 28px;
    flex-shrink: 0;
    border: 0;
    border-radius: 6px;
    margin: 2px;
    background: var(--accent);
    color: #ffffff;
    cursor: pointer;
}

.catalog-search-button:hover {
    filter: brightness(1.1);
}

.catalog-list-shell {
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--bg-panel);
    box-shadow: var(--shadow);
    overflow: hidden;
}

.catalog-list-head,
.catalog-row-main {
    /* NAME | EDITION | VERSION | RELEASED | ZABBIX | ACTIONS - the first
       four mirror the homepage releases table order. The actions column is
       FIXED width: minmax(..., auto) resolves differently for the head and
       each row (content-driven), which skewed every column before. */
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) 140px 100px 110px 110px 230px;
    gap: 14px;
    align-items: center;
}

.catalog-row-editions {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
    min-width: 0;
}

.catalog-list-head {
    /* Same scale as .home-release-head so every list table looks alike.
       No border-bottom - the first row's border-top is the divider. */
    padding: 10px 16px;
    background: var(--bg-soft);
    color: var(--muted);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.catalog-list {
    display: grid;
}

.catalog-row {
    padding: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    border-top: 1px solid var(--border);
}

.catalog-row-main {
    padding: 10px 16px;
}

.catalog-row-title {
    display: grid;
    gap: 8px;
    min-width: 0;
    align-self: start;
}

.catalog-row-heading {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.catalog-row-heading h2 {
    margin: 0;
    /* Same scale as .home-release-name so all list tables read alike. */
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.2;
    overflow-wrap: anywhere;
}

.catalog-row-link {
    color: inherit;
    text-decoration: none;
}

.catalog-row-link:hover {
    color: var(--accent);
    text-decoration: underline;
}

.catalog-row-subtitle {
    max-width: 36ch;
    color: var(--muted);
    font-size: 0.88rem;
    line-height: 1.45;
    overflow-wrap: anywhere;
}

.hero-note {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 14px;
    color: rgba(255, 255, 255, 0.72);
}

.catalog-row-zabbix {
    display: flex;
    align-items: center;
    align-content: center;
    gap: 8px;
    flex-wrap: wrap;
}

.catalog-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Same height as .pill so fact rows read as one line. */
    min-height: 24px;
    padding: 0 10px;
    border-radius: 999px;
    background: var(--bg-soft);
    border: 1px solid var(--border);
    color: var(--text);
    font-size: 0.78rem;
    font-weight: 600;
}

.catalog-row-meta {
    /* No decorative left divider/indent - cell content must start at the
       same x as the column label in the head row. */
    display: grid;
    gap: 4px;
    min-width: 0;
    min-height: 0;
    justify-items: start;
}

.catalog-row-value {
    font-size: 1.02rem;
    font-weight: 700;
    line-height: 1.3;
    overflow-wrap: anywhere;
}

.catalog-row-meta-copy {
    color: var(--muted);
    font-size: 0.88rem;
    line-height: 1.45;
}

.catalog-row-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    flex-wrap: wrap;
    justify-self: end;
}

.catalog-row-actions .button,
.catalog-row-actions .button:visited {
    min-width: 0;
}

.status-stack {
    display: grid;
    gap: 6px;
    justify-items: start;
}

.status-note {
    color: var(--muted);
    font-size: 0.82rem;
    line-height: 1.35;
}

.catalog-dialog {
    width: min(920px, calc(100vw - 32px));
    /* arytp5r: hug the content instead of stretching to a fixed 860px - short
       changelogs read compact, long ones still scroll at the cap. */
    max-height: min(860px, calc(100vh - 32px));
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 16px;
    background: transparent;
    overflow: hidden;
    overscroll-behavior: contain;
}

.catalog-dialog::backdrop {
    background: rgba(7, 13, 24, 0.64);
    backdrop-filter: blur(4px);
}

.catalog-dialog-shell {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    max-height: min(860px, calc(100vh - 32px));
    background: var(--bg-panel);
    color: var(--text);
}

.catalog-dialog-header {
    display: flex;
    align-items: start;
    justify-content: space-between;
    gap: 14px;
    padding: 14px 16px 12px;
    border-bottom: 1px solid var(--border);
    /* Repo chrome: plain light/dark panel header driven by theme vars,
       not the old navy gradient with hardcoded white copy. */
    background: var(--bg-panel);
    color: var(--text);
}

.catalog-dialog-header h2,
.catalog-dialog-version h3,
.catalog-dialog-item h4 {
    margin: 0;
    /* Compact dialog headings - browser default 1.5em read as shouting. */
    font-size: 1.05rem;
}

.catalog-dialog-eyebrow {
    margin-bottom: 12px;
}

.catalog-dialog-close {
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-soft);
    color: var(--muted);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.catalog-dialog-close:hover {
    color: var(--text);
    border-color: var(--border-strong);
}

/* The close button sits in the dialog's rounded corner; on modal open the
   browser focus ring is clipped to a stray arc. Use a clean inset ring that
   stays inside the button instead. */
.catalog-dialog-close:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 2px var(--accent);
    border-color: var(--accent);
}

.catalog-dialog-body {
    display: grid;
    gap: 12px;
    /* arytp5r: never stretch rows apart even at the height cap. */
    align-content: start;
    padding: 14px 16px 16px;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-y;
}

.catalog-dialog-version {
    display: grid;
    gap: 16px;
    padding: 20px;
    border-radius: 12px;
    border: 1px solid var(--border);
    background: var(--bg-soft);
}

.catalog-dialog-version-header {
    display: flex;
    align-items: start;
    justify-content: space-between;
    gap: 14px;
}

.catalog-dialog-version-title {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.catalog-dialog-changelog {
    display: grid;
    gap: 12px;
}

.catalog-dialog-item {
    display: grid;
    gap: 10px;
    padding: 16px 18px;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--bg-panel);
}

/* Roadmap as a vertical timeline: a gradient rail runs down the left,
   each period hangs off it with a node dot, items indent to the right. */
.roadmap-timeline {
    position: relative;
    display: grid;
    gap: 30px;
    padding-left: 30px;
}

.roadmap-timeline::before {
    content: '';
    position: absolute;
    left: 9px;
    top: 8px;
    bottom: 8px;
    width: 2px;
    border-radius: 2px;
    background: linear-gradient(180deg, var(--accent) 0%, var(--accent-alt, #7150f7) 100%);
    opacity: 0.45;
}

.roadmap-period {
    position: relative;
}

.roadmap-period::before {
    content: '';
    position: absolute;
    left: -27px;
    top: 5px;
    width: 14px;
    height: 14px;
    border-radius: 999px;
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-alt, #7150f7) 100%);
    box-shadow: 0 0 0 4px var(--accent-soft);
}

.roadmap-period-heading {
    font-size: 1.2rem;
    font-weight: 700;
    margin: 0 0 12px;
}

.roadmap-items {
    display: grid;
    gap: 10px;
}

.roadmap-card {
    position: relative;
    overflow: hidden;
    display: grid;
    gap: 8px;
    padding: 14px 16px;
    border-radius: 12px;
    border: 1px solid var(--border);
    background: var(--bg-soft);
    transition: border-color 0.15s ease, transform 0.15s ease;
    /* Status color shown as a TOP line (per status) - readable at a glance
       without hunting for the pill on the right. */
    --roadmap-status-color: var(--border);
}

.roadmap-card::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: var(--roadmap-status-color);
}

.roadmap-card-released {
    --roadmap-status-color: #22c55e;
}

.roadmap-card-planned {
    --roadmap-status-color: var(--accent);
}

.roadmap-card-feedback_welcome {
    --roadmap-status-color: var(--accent-alt, #7150f7);
}

/* In-progress: a soft travelling sine wave along the top edge in the status
   colour - reads as "actively being worked on" without the shimmer look. */
.roadmap-card-in_progress::before {
    height: 6px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='6' viewBox='0 0 36 6'%3E%3Cpath d='M0 3 Q9 0 18 3 T36 3' fill='none' stroke='%23f59e0b' stroke-width='1.4'/%3E%3C/svg%3E") repeat-x 0 0;
    background-size: 36px 6px;
    animation: roadmap-wave-travel 2.4s linear infinite;
}

@keyframes roadmap-wave-travel {
    from { background-position-x: 0; }
    to { background-position-x: -36px; }
}

@media (prefers-reduced-motion: reduce) {
    .roadmap-card-in_progress::before {
        animation: none;
        background-position-x: 0;
    }
}

.roadmap-filter {
    margin-bottom: 14px;
}

/* a6vwq0y: filter now lives in the hero toolbar next to Suggest-an-idea. */
.catalog-toolbar .roadmap-filter {
    margin-bottom: 0;
}
.roadmap-toolbar .hero-actions {
    margin-left: auto;
}

/* Confirm dialog (styled window.confirm replacement) - small and centered. */
.confirm-dialog {
    width: min(400px, calc(100vw - 32px));
}

.button-danger-solid {
    background: #dc2626;
    border-color: #dc2626;
}

.button-danger-solid:hover {
    background: #b91c1c;
    border-color: #b91c1c;
}

/* Slim feedback strip under the install card on the product detail. */
.feedback-strip {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    flex-wrap: wrap;
    padding: 8px 14px;
    border: 1px dashed var(--border-strong);
    border-radius: 10px;
    font-size: 0.88rem;
}

.roadmap-card:hover {
    border-color: var(--border-strong);
    transform: translateX(2px);
}

.roadmap-card-header {
    display: flex;
    /* Status pill stacks under the title (full title width) on every viewport,
       matching mobile - was space-between which floated the pill far right. */
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
}

.roadmap-card h3,
.roadmap-card p {
    margin: 0;
}

.pill-planned {
    background: rgba(100, 160, 255, 0.10);
    border-color: rgba(100, 160, 255, 0.28);
    color: #2b6cb0;
}

:root[data-theme='dark'] .pill-planned {
    color: #90cdf4;
}

.pill-in_progress {
    background: rgba(255, 184, 77, 0.12);
    border-color: rgba(255, 184, 77, 0.28);
    color: #b47a00;
}

:root[data-theme='dark'] .pill-in_progress {
    color: #ffcf7d;
}

.pill-released {
    background: rgba(72, 187, 120, 0.12);
    border-color: rgba(72, 187, 120, 0.28);
    color: #276749;
}

:root[data-theme='dark'] .pill-released {
    color: #9ae6b4;
}

.pill-feedback_welcome {
    background: rgba(159, 122, 234, 0.12);
    border-color: rgba(159, 122, 234, 0.28);
    color: #6b46c1;
}

:root[data-theme='dark'] .pill-feedback_welcome {
    color: #d6bcfa;
}

.pill-sm {
    min-height: 24px;
    padding: 0 8px;
    font-size: 0.7rem;
}

.tag-gray {
    background: rgba(120, 120, 140, 0.12);
    border-color: rgba(120, 120, 140, 0.28);
    color: #4a4a5a;
}

:root[data-theme='dark'] .tag-gray {
    color: #b0b0c0;
}

.tag-blue {
    background: rgba(66, 133, 244, 0.12);
    border-color: rgba(66, 133, 244, 0.28);
    color: #1a56db;
}

:root[data-theme='dark'] .tag-blue {
    color: #93bbfd;
}

.tag-green {
    background: rgba(52, 168, 83, 0.12);
    border-color: rgba(52, 168, 83, 0.28);
    color: #1e6f3e;
}

:root[data-theme='dark'] .tag-green {
    color: #81d89e;
}

.tag-orange {
    background: rgba(234, 134, 45, 0.12);
    border-color: rgba(234, 134, 45, 0.28);
    color: #9c4d10;
}

:root[data-theme='dark'] .tag-orange {
    color: #f5b877;
}

.tag-purple {
    background: rgba(139, 92, 246, 0.12);
    border-color: rgba(139, 92, 246, 0.28);
    color: #6b21a8;
}

:root[data-theme='dark'] .tag-purple {
    color: #c4b5fd;
}

.tag-red {
    background: rgba(220, 53, 69, 0.12);
    border-color: rgba(220, 53, 69, 0.28);
    color: #991b1b;
}

:root[data-theme='dark'] .tag-red {
    color: #fca5a5;
}

.tag-teal {
    background: rgba(20, 184, 166, 0.12);
    border-color: rgba(20, 184, 166, 0.28);
    color: #0f766e;
}

:root[data-theme='dark'] .tag-teal {
    color: #5eead4;
}

.tag-pink {
    background: rgba(236, 72, 153, 0.12);
    border-color: rgba(236, 72, 153, 0.28);
    color: #9d174d;
}

:root[data-theme='dark'] .tag-pink {
    color: #f9a8d4;
}

.tag-color-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.tag-color-option {
    cursor: pointer;
}

.tag-color-option input[type="radio"] {
    display: none;
}

.tag-color-option input[type="radio"]:checked + .pill {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.roadmap-card-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.idea-dialog {
    width: min(560px, calc(100vw - 32px));
    max-height: min(880px, calc(100svh - 28px));
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 16px;
    background: transparent;
    overflow: hidden;
}

.idea-dialog::backdrop {
    background: rgba(7, 13, 24, 0.64);
    backdrop-filter: blur(4px);
}

.idea-dialog-shell {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    background: var(--bg-panel);
    color: var(--text);
    max-height: min(880px, calc(100svh - 28px));
}

.idea-dialog .muted {
    color: var(--muted);
}

:root[data-theme='dark'] .idea-dialog .muted {
    color: rgba(255, 255, 255, 0.72);
}

.idea-dialog-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    padding: 16px 18px 12px;
    border-bottom: 1px solid var(--border);
}

.idea-dialog-header h2 {
    margin: 0;
}

.idea-dialog-body {
    padding: 16px 18px 18px;
    overflow-y: auto;
}

.roadmap-idea-intro {
    display: grid;
    gap: 4px;
    max-width: 34rem;
}

.roadmap-idea-intro h2 {
    font-size: 1.05rem;
    line-height: 1.2;
    letter-spacing: -0.01em;
}

.roadmap-idea-intro .muted {
    margin: 0;
    max-width: 32rem;
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.5;
}

:root[data-theme='dark'] .roadmap-idea-intro .muted {
    color: rgba(255, 255, 255, 0.78);
}

.idea-dialog-close {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    font-size: 1.1rem;
}

.idea-dialog .catalog-dialog-close {
    border: 1px solid var(--border);
    background: var(--bg-muted);
    color: var(--text);
}

.idea-dialog .catalog-dialog-close:hover {
    background: var(--field-bg-strong);
    border-color: var(--border-strong);
}

:root[data-theme='dark'] .idea-dialog .catalog-dialog-close {
    border-color: rgba(255, 255, 255, 0.1);
    background: rgba(255, 255, 255, 0.08);
    color: #ffffff;
}

:root[data-theme='dark'] .idea-dialog .catalog-dialog-close:hover {
    background: rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.16);
}

.roadmap-idea-form {
    display: grid;
    gap: 12px;
}

.roadmap-idea-fields {
    display: grid;
    gap: 10px;
}

.roadmap-idea-textarea {
    min-height: 110px;
}

.roadmap-idea-meta-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 14px;
}

.roadmap-idea-meta-grid .field {
    min-width: 0;
}

.roadmap-idea-errors {
    padding: 8px 12px;
    border-radius: 8px;
    border: 1px solid rgba(201, 60, 60, 0.3);
    background: rgba(201, 60, 60, 0.12);
}

.idea-dialog-actions {
    display: flex;
    flex-wrap: wrap;
    /* Dialog/popup action buttons live on the right. */
    justify-content: flex-end;
    gap: 12px;
    padding-top: 2px;
}

.roadmap-idea-success {
    display: grid;
    gap: 12px;
    padding: 6px 0 2px;
    text-align: left;
}

.roadmap-idea-success h2 {
    margin: 0;
    font-size: 1.3rem;
    line-height: 1.15;
}

.roadmap-idea-success .muted {
    margin: 0;
    max-width: 30rem;
}

.roadmap-idea-form .field label {
    font-size: 0.85rem;
    font-weight: 600;
}

.roadmap-idea-form .field input,
.roadmap-idea-form .field textarea {
    background: var(--field-bg-strong);
}

.roadmap-idea-form .field input {
    min-height: 38px;
}

.roadmap-idea-form .field textarea {
    padding-top: 8px;
}

.roadmap-idea-form .button {
    min-height: 38px;
}

.idea-dialog .button-ghost,
.idea-dialog .button-ghost:visited {
    border-color: var(--border-strong);
    color: var(--text);
    background: transparent;
}

.idea-dialog .button-ghost:hover {
    background: var(--bg-muted);
}

:root[data-theme='dark'] .idea-dialog .button-ghost,
:root[data-theme='dark'] .idea-dialog .button-ghost:visited {
    border-color: rgba(255, 255, 255, 0.18);
    color: #ffffff;
}

:root[data-theme='dark'] .idea-dialog .button-ghost:hover {
    background: rgba(255, 255, 255, 0.08);
}

.filter-form {
    display: grid;
    align-content: start;
    gap: 10px;
    padding: 22px;
    border-radius: var(--radius-md);
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.08);
}

.section-title-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.filter-form label {
    font-size: 0.9rem;
    color: rgba(255, 255, 255, 0.76);
}

.filter-inline {
    display: flex;
    gap: 12px;
    align-items: center;
}

/* Catalog compatibility filter select: match the button-primary height,
   border radius and font so the dropdown and the "Apply" button look
   like a single matched control row instead of a raw OS select + button. */
.filter-inline select {
    appearance: none;
    -webkit-appearance: none;
    padding: 10px 36px 10px 14px;
    border-radius: var(--radius-md);
    border: 1px solid rgba(255, 255, 255, 0.18);
    background: rgba(255, 255, 255, 0.05) url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2016%2016%27%20fill%3D%27%23b4c5ea%27%3E%3Cpath%20d%3D%27M3.5%206h9l-4.5%205z%27%2F%3E%3C%2Fsvg%3E") no-repeat right 12px center / 12px 12px;
    color: var(--text);
    font: inherit;
    line-height: 1.2;
    cursor: pointer;
    min-height: 42px;
}
.filter-inline select:focus {
    outline: 2px solid var(--blue, #1f65f4);
    outline-offset: 1px;
}

.table-shell {
    overflow-x: auto;
    overflow-y: hidden;
    /* min-width:0 lets the shell shrink below the table's min-width so it
       scrolls INSIDE instead of widening the page on mobile (flexbox/grid
       min-width:auto trap - same as the footer/token fixes). */
    min-width: 0;
    max-width: 100%;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--bg-panel);
    box-shadow: var(--shadow);
}

/* Long event logs would otherwise stretch the page for 90+ rows. Bound the
   height and let the body scroll while the header stays pinned. */
.table-shell-scroll {
    overflow-y: auto;
    max-height: 520px;
}

.table-shell-scroll .table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
}

/* Keep file-path cells from blowing out the row width. */
.table-cell-path {
    max-width: 280px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Single-line cell for values that must never wrap mid-token (timestamps,
   emails, "Q2 2026" periods) - wrapped cells gave rows wildly different
   heights, worst in the squeezed mobile table (visual-audit: admin users). */
.table-cell-nowrap {
    white-space: nowrap;
}

.table {
    width: 100%;
    border-collapse: collapse;
}

.table th,
.table td {
    padding: 7px 12px;
    font-size: 0.86rem;
    text-align: left;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}

.table th {
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    background: var(--bg-soft);
}

.table tbody tr:last-child td {
    border-bottom: 0;
}

/* Stacked download-stats tables (per-edition, per-product matrix, per-product
   totals) share fixed column widths so their columns line up vertically when
   read top to bottom. Values stay left-aligned under their headers. */
.table-stats {
    table-layout: fixed;
}

.table-stats th:first-child,
.table-stats td:first-child {
    width: 40%;
}

.table-stats th:not(:first-child),
.table-stats td:not(:first-child) {
    width: 30%;
}

.contact-table-person {
    display: grid;
    grid-template-columns: 56px minmax(0, 1fr);
    gap: 14px;
    align-items: center;
}

.contact-table-avatar {
    width: 56px;
    height: 56px;
    border-radius: 999px;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, rgba(31, 101, 244, 0.12), rgba(113, 80, 247, 0.18));
    border: 1px solid var(--border);
    color: var(--accent);
    font-weight: 700;
}

.contact-table-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
}

.empty-state {
    padding: 22px;
    border-radius: 1.2rem;
    border: 1px dashed var(--border-strong);
    background: var(--bg-soft);
    color: var(--muted);
}

.ticket-reply-input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.ticket-reply-dropzone,
.ticket-comment-editor,
.upload-dropzone {
    width: 100%;
    display: grid;
    gap: 6px;
    padding: 14px;
    min-height: 64px;
    align-content: center;
    border-radius: 10px;
    border: 1px dashed var(--border-strong);
    background:
        linear-gradient(180deg, rgba(31, 101, 244, 0.05) 0%, rgba(113, 80, 247, 0.04) 100%),
        var(--bg-soft);
    transition: border-color 0.2s ease, background-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.ticket-reply-dropzone {
    border-style: dashed;
    text-align: left;
    cursor: pointer;
    color: var(--text);
}

.upload-dropzone-shell {
    position: relative;
    display: grid;
}

.upload-dropzone-shell.is-disabled {
    cursor: not-allowed;
}

.field input.upload-dropzone-input {
    position: absolute;
    inset-inline-start: 0;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.ticket-reply-dropzone:hover,
.ticket-reply-dropzone.is-dragover,
.ticket-comment-editor.is-dragover,
.upload-dropzone:hover,
.upload-dropzone.is-dragover {
    border-color: rgba(31, 101, 244, 0.46);
    background:
        linear-gradient(180deg, rgba(31, 101, 244, 0.08) 0%, rgba(113, 80, 247, 0.06) 100%),
        var(--bg-soft);
    box-shadow: 0 18px 42px rgba(10, 16, 28, 0.1);
}

.upload-dropzone:focus-visible {
    outline: 2px solid rgba(31, 101, 244, 0.5);
    outline-offset: 3px;
}

.upload-dropzone.is-disabled {
    cursor: not-allowed;
    border-style: solid;
    border-color: var(--border);
    background: var(--bg-soft);
    box-shadow: none;
}

.upload-dropzone.is-disabled .upload-dropzone-title,
.upload-dropzone.is-disabled .upload-dropzone-copy {
    color: var(--muted);
}

.ticket-reply-dropzone-title,
.upload-dropzone-title {
    font-size: 1.04rem;
    font-weight: 700;
}

.ticket-reply-dropzone-copy,
.upload-dropzone-copy {
    color: var(--muted);
    font-size: 0.94rem;
    line-height: 1.55;
}

.ticket-comment-textarea {
    min-height: 180px;
    border: 0;
    background: transparent;
    resize: vertical;
    padding: 0;
    box-shadow: none;
}

.ticket-comment-textarea:focus {
    outline: none;
    box-shadow: none;
}

.ticket-comment-editor-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.ticket-comment-card {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    gap: 14px;
    padding: 18px 0;
    border-bottom: 1px solid var(--border);
}

.ticket-comment-card:first-child {
    padding-top: 0;
}

.ticket-comment-card:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

.ticket-comment-avatar {
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: linear-gradient(135deg, var(--accent) 0%, var(--accent-alt) 100%);
    color: #ffffff;
    font-weight: 700;
}

.ticket-comment-body {
    display: grid;
    gap: 8px;
    min-width: 0;
}

.ticket-comment-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.ticket-comment-copy {
    margin: 0;
    white-space: pre-wrap;
}

.feature-card {
    padding: 22px;
}

.feature-card .pill {
    margin-bottom: 14px;
}

.feature-card h2 {
    margin-bottom: 10px;
}

.auth-layout {
    display: grid;
    grid-template-columns: minmax(0, 0.95fr) minmax(320px, 0.85fr);
    gap: 18px;
    align-items: stretch;
    min-height: calc(100vh - 260px);
}

/* Error pages (404/403/500/...): one compact centered card, natural height -
   no aside and no viewport-filling min-height (those belong to the login
   auth-layout only). Visual-audit finding customer/09. */
.error-layout {
    display: grid;
    justify-content: center;
    padding: 26px 0;
}

.error-layout .auth-card {
    width: min(100%, 560px);
    padding: 26px 28px;
    /* atw7qr3/a8w56wv: the error card reads centered (illustration, eyebrow,
       title, copy, buttons, meta) on desktop and mobile alike. */
    text-align: center;
}

.error-layout .error-illustration {
    margin-left: auto;
    margin-right: auto;
}

.error-layout .hero-actions {
    justify-content: center;
}

/* ata0bdc: disconnected-plug illustration on the error card (navy line-art +
   accent sparks; inherits --text/--accent so it works in light and dark). */
.error-illustration {
    display: block;
    width: 104px;
    height: auto;
    margin: 0 0 14px;
}

.auth-card,
.auth-aside {
    padding: 30px;
}

.auth-card {
    background:
        radial-gradient(circle at top right, rgba(113, 80, 247, 0.14), transparent 28%),
        linear-gradient(180deg, #ffffff 0%, var(--bg-soft) 100%);
}

.auth-aside {
    background:
        radial-gradient(circle at top right, rgba(113, 80, 247, 0.12), transparent 30%),
        linear-gradient(180deg, var(--bg-soft) 0%, var(--bg-panel) 100%);
    border-color: var(--border);
    color: var(--text);
}

.auth-sso-callout {
    display: grid;
    gap: 8px;
}

.field {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 5px;
    margin-bottom: 0;
    align-content: start;
}

.field-span-full {
    grid-column: 1 / -1;
}

.field label {
    color: var(--text);
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.3;
}

/* Required-field marker: Symfony adds .required to labels of required fields,
   so a single rule marks every mandatory field across the portal. */
.field label.required::after {
    content: " *";
    color: var(--danger, #f2555a);
    font-weight: 700;
}

.field-label-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.field-label-row label {
    margin: 0;
}

.field-label-help {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 999px;
    border: 1px solid var(--border-strong);
    background: var(--bg-soft);
    color: var(--muted);
    font-size: 0.8rem;
    font-weight: 700;
    line-height: 1;
    cursor: help;
    user-select: none;
    flex: 0 0 auto;
}

.field-label-help:hover,
.field-label-help:focus-visible {
    border-color: var(--accent);
    color: var(--accent);
    outline: none;
    box-shadow: 0 0 0 4px rgba(31, 101, 244, 0.12);
}

.field input {
    display: block;
    width: 100%;
    min-height: 38px;
    padding: 0 12px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--field-bg);
    color: var(--text);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
    transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
}

.field input:hover,
.field input:focus,
.field textarea:hover,
.field textarea:focus,
.field select:hover,
.field select:focus {
    outline: none;
    border-color: var(--accent);
    /* background-color (not the background shorthand) so the select chevron
       background-image survives hover/focus. */
    background-color: var(--field-bg-strong);
    box-shadow: 0 0 0 4px rgba(31, 101, 244, 0.12);
}

.field input:disabled,
.field textarea:disabled,
.field select:disabled {
    cursor: not-allowed;
    color: var(--muted);
    background: var(--bg-soft);
    border-color: var(--border);
    box-shadow: none;
    opacity: 1;
}

.field input:disabled::placeholder,
.field textarea:disabled::placeholder {
    color: var(--muted);
}

.field textarea,
.field select {
    display: block;
    width: 100%;
    min-height: 38px;
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--field-bg);
    color: var(--text);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
    font: inherit;
    line-height: 1.35;
    max-width: 100%;
}

.field textarea {
    min-height: 110px;
    resize: vertical;
}

.field select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5.25 7 9.25l4-4' stroke='%2393A0BD' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 36px;
}

.field input::placeholder,
.field textarea::placeholder {
    color: var(--field-placeholder);
    opacity: 1;
}

.field input[type='radio'] {
    width: 18px;
    min-height: 18px;
    height: 18px;
    padding: 0;
}

.field:has(input[type='radio']) > div {
    display: grid;
    gap: 10px;
}

.field:has(input[type='radio']) > div > label {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--field-bg-strong);
}

.field select[multiple] {
    min-height: 224px;
    padding: 14px 16px;
    background-image: none;
    padding-right: 16px;
}

.field select[multiple] option {
    padding: 10px 12px;
}

.field-help {
    color: var(--muted);
    font-size: 0.78rem;
    line-height: 1.45;
}

.field-lock-notice {
    align-items: start;
    gap: 10px;
}

.field-errors {
    display: grid;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
    color: #de6d8d;
    font-size: 0.88rem;
    font-weight: 500;
}

.field-checkbox {
    align-self: end;
}

.checkbox-field {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 38px;
    padding: 0 12px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.02) 0%, transparent 100%),
        var(--field-bg);
}

.checkbox-field input[type='checkbox'] {
    width: 20px;
    min-height: 20px;
    height: 20px;
    margin: 0;
    padding: 0;
    border-radius: 6px;
    accent-color: var(--accent);
    flex: 0 0 auto;
}

.checkbox-field-label {
    margin: 0;
    font-size: 0.98rem;
    font-weight: 600;
    line-height: 1.45;
}

/* Expanded choice groups (portal_theme choice_widget_expanded, e.g. roadmap
   Tags): flow the .checkbox-field chips in a wrapping row instead of the bare
   unstyled inputs the default layout emitted. */
.choice-checkbox-group {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 10px;
}

.form-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px 14px;
    align-items: start;
}

/* Single-column variant: every field stacks full width (used by the admin
   user edit form, which sits in the narrower left column of a two-column
   layout). */
.form-grid-single {
    grid-template-columns: minmax(0, 1fr);
}

/* Admin user edit: form on the left, user summary panel on the right. The
   summary is a read-only overview, so the form gets the wider column. */
.user-edit-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.5fr) minmax(300px, 1fr);
    gap: 10px;
    align-items: start;
}

/* New-user mode: no summary aside, so the two-column grid left the form in a
   60% track next to bare background - collapse to one column. */
.user-edit-layout-single {
    grid-template-columns: minmax(0, 1fr);
}

.user-edit-summary {
    padding: 16px;
}

/* Summary rows: let the value (e.g. the email) take the space it needs so it
   stays on one line, instead of the label reserving a fixed width and forcing
   the email to wrap mid-word. Very long values still wrap as a last resort
   rather than overflowing the panel. */
.user-edit-summary .info-line .detail-label {
    flex: 0 0 auto;
    white-space: nowrap;
}

.user-edit-summary .info-line .detail-value {
    flex: 1 1 auto;
    min-width: 0;
    word-break: normal;
    overflow-wrap: anywhere;
}

/* Admin action buttons in the narrow summary column: a 2-column grid with
   equal-width, full-cell buttons keeps them aligned regardless of how many
   there are (3 or 4) or how long each label is. */
.user-edit-summary .hero-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.user-edit-summary .hero-actions > * {
    width: 100%;
}

.user-edit-summary .hero-actions .button {
    width: 100%;
    justify-content: center;
    text-align: center;
}

@media (max-width: 900px) {
    .user-edit-layout {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Section headings inside a .form-grid (e.g. New customer: Account / Primary
   contact / Configuration). Muted uppercase label with a rule to its right,
   spanning both grid columns. Matches the existing .changelog-highlight-label
   look; adds top spacing so groups read as distinct sections. */
.form-section-head {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 18px;
    margin-bottom: 6px;
    color: var(--muted);
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.form-section-head:first-child {
    margin-top: 0;
}

.form-section-head::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--border);
}

.form-actions {
    margin-top: 10px;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.support-intake-grid {
    /* Single column - the explainer aside was removed. */
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
}

.support-intake-grid > form {
    min-width: 0;
}

.support-intake-main {
    display: grid;
    gap: 22px;
}

.support-intake-section {
    display: grid;
    /* ah8l4r2: pull the descriptive copy closer to its fields (was 10px). */
    gap: 6px;
    padding-top: 2px;
}

.support-intake-section[hidden] {
    display: none !important;
}

.support-intake-section + .support-intake-section {
    padding-top: 22px;
    border-top: 1px solid var(--border);
}

.support-intake-header {
    display: grid;
    gap: 4px;
}

.support-intake-header h2 {
    margin: 0;
    font-size: 1.05rem;
}

.support-intake-header p {
    margin: 0;
}

.support-request-type-row select {
    min-height: 38px;
    font-size: 0.95rem;
    font-weight: 600;
}

.support-request-flow {
    display: grid;
    gap: 8px;
    padding: 16px 18px;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--bg-soft);
}

.support-request-flow[hidden] {
    display: none;
}

.support-request-flow p {
    margin: 0;
}

.support-version-hint {
    margin-top: -6px;
}

.support-version-advice {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 18px 20px;
    border-radius: 1.2rem;
    border: 1px solid rgba(31, 101, 244, 0.22);
    background:
        radial-gradient(circle at top right, rgba(113, 80, 247, 0.14), transparent 34%),
        linear-gradient(180deg, rgba(31, 101, 244, 0.07) 0%, transparent 100%),
        var(--bg-soft);
}

.support-version-advice[hidden] {
    display: none;
}

.support-version-advice-copy {
    display: grid;
    gap: 8px;
}

.support-version-advice-copy p {
    margin: 0;
}

.support-confirmation-wrap[hidden] {
    display: none;
}

.support-confirmation-field .checkbox-field {
    min-height: 72px;
    align-items: start;
    padding-top: 16px;
    padding-bottom: 16px;
}

.support-intake-aside {
    display: grid;
    gap: 18px;
    position: sticky;
    top: 118px;
    max-height: calc(100svh - 136px);
    overflow: auto;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.support-intake-aside::-webkit-scrollbar {
    display: none;
}

.support-intake-checklist {
    display: grid;
    gap: 12px;
}

.support-intake-checklist-item {
    display: grid;
    gap: 8px;
    padding: 16px 18px;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--bg-soft);
}

.support-intake-checklist-item p {
    margin: 0;
}

.support-form-state {
    display: grid;
    gap: 8px;
    padding: 16px 18px;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--bg-soft);
}

.support-form-state p,
.support-form-state ul {
    margin: 0;
}

.support-form-error-list {
    display: grid;
    gap: 6px;
    padding-left: 18px;
}

.support-form-state-error {
    border-color: rgba(201, 60, 60, 0.22);
    background: linear-gradient(180deg, rgba(201, 60, 60, 0.07) 0%, transparent 100%), var(--bg-soft);
}

.support-submit-state {
    margin: -2px 0 0;
    font-size: 0.96rem;
    color: var(--muted);
}

.support-submit-state[hidden] {
    display: none;
}

.version-grid {
    grid-template-columns: minmax(0, 1.25fr) minmax(280px, 0.8fr);
}

.auth-meta {
    margin-top: 20px;
    display: grid;
    gap: 10px;
}

.site-footer {
    background: var(--bg-dark);
    color: #ffffff;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
    margin-top: 24px;
}

.footer-grid {
    display: grid;
    grid-template-columns: 1.1fr repeat(2, minmax(180px, 0.6fr));
    gap: 24px;
    padding-top: 32px;
    padding-bottom: 32px;
}

.footer-label {
    display: block;
    color: rgba(255, 255, 255, 0.74);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.75rem;
    margin-bottom: 10px;
}

.footer-brand p,
.footer-col p,
.footer-col a {
    margin: 0;
    color: rgba(255, 255, 255, 0.82);
    text-decoration: none;
}

.footer-col {
    display: grid;
    gap: 10px;
    align-content: start;
}

.footer-phone-list {
    display: grid;
    gap: 10px;
}

.footer-phone-link {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

.footer-phone-flag {
    width: 22px;
    height: 22px;
    flex: 0 0 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.footer-phone-flag svg {
    width: 100%;
    height: 100%;
    display: block;
}

.footer-phone-copy {
    min-width: 0;
}

.footer-meta {
    padding-top: 14px;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.72);
    font-size: 0.88rem;
}

.mt-xs {
    margin-top: 6px;
}

.mt-sm {
    margin-top: 14px;
}

.stat-value-compact {
    font-size: 1.35rem;
}

.nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.06);
    color: #ffffff;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

.nav-toggle:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.18);
}

.nav-toggle svg {
    width: 22px;
    height: 22px;
}

.mt-md {
    margin-top: 16px;
}

.mt-lg {
    margin-top: 24px;
}

.mb-sm {
    margin-bottom: 18px;
}

.pre-wrap {
    white-space: pre-wrap;
}

.button-full {
    width: 100%;
}

.info-line-dark {
    background: var(--bg-muted);
    border-color: var(--border);
}

.auth-aside .info-line-dark {
    background: var(--bg-soft);
    border-color: var(--border);
}

.auth-aside .info-line-dark .detail-label {
    color: var(--muted);
}

.auth-aside .info-line-dark .detail-value {
    color: var(--text);
}

.eyebrow-light {
    background: var(--bg-soft);
    border-color: var(--border);
    color: var(--muted);
}

.page-title-auth {
    font-size: clamp(2.2rem, 4vw, 3.4rem);
}

.auth-aside-title {
    font-size: clamp(1.8rem, 3vw, 2.7rem);
    line-height: 1.1;
}

/* ab1vu0s: "Latest releases" teaser heading on the login aside. */
.auth-aside-subtitle {
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
}

:root[data-theme='dark'] .auth-card {
    background:
        radial-gradient(circle at top right, rgba(113, 80, 247, 0.18), transparent 28%),
        linear-gradient(180deg, #121b2e 0%, #0f1829 100%);
    border-color: rgba(176, 190, 219, 0.16);
}

:root[data-theme='dark'] .form-panel {
    background: var(--bg-panel);
    border-color: rgba(176, 190, 219, 0.18);
}

@media (max-width: 1080px) {
    .topbar {
        flex-wrap: wrap;
    }

    .topbar-main {
        width: 100%;
        flex-wrap: wrap;
    }

    .nav-pills,
    .portal-nav {
        width: 100%;
    }
}

@media (max-width: 960px) {
    .hero-shell,
    .page-hero,
    .content-grid,
    .auth-layout,
    .footer-grid,
    .feature-grid,
    .card-grid,
    .form-grid,
    .version-grid {
        grid-template-columns: 1fr;
    }

    .hero-shell,
    .page-hero,
    .auth-card,
    .auth-aside,
    .panel {
        padding: 24px;
    }

    .catalog-list-head {
        display: none;
    }

    .contact-card-shell,
    .contact-table-person {
        grid-template-columns: 1fr;
    }

    .contact-card-avatar,
    .contact-table-avatar {
        justify-self: start;
    }

    .catalog-row-main {
        grid-template-columns: 1fr;
        align-items: start;
    }

    .catalog-row-meta {
        min-height: 0;
        padding-left: 0;
        border-left: 0;
    }

    .catalog-row-actions {
        justify-content: start;
    }

    .table {
        min-width: 760px;
    }

    .release-header,
    .event-header,
    .info-line,
    .download-row,
    .catalog-dialog-version-header,
    .support-version-advice {
        flex-direction: column;
        align-items: flex-start;
        /* In column direction the desktop space-between pins the label to the
           top and the value to the bottom of a stretched box (visual-audit H2:
           mobile profile stat boxes with ~180px of blank middle). Hug content. */
        justify-content: flex-start;
        gap: 4px;
    }

    /* The REAL height culprit: the desktop label column width (flex: 0 0 11rem)
       becomes a 176px HEIGHT once the row flips to column direction - flex-basis
       follows the main axis. Reset both cells to natural size, left-aligned. */
    .info-line .detail-label,
    .info-line .detail-value {
        flex: 0 0 auto;
        text-align: left;
    }

    .support-intake-aside {
        position: static;
        top: auto;
    }
}

@media (max-width: 720px) {
    .nav-toggle {
        display: inline-flex;
    }

    .portal-nav-inline,
    .nav-pills-inline {
        display: none;
        width: 100%;
        order: 10;
    }

    /* Open nav = absolute dropdown panel below the topbar (same anchoring
       trick as .topbar-actions .profile-switcher). Inline it inflated
       .topbar-main's max-content width, which collapsed the second grid
       column and made the theme + language toggles vanish while the menu was
       open (visual-audit mobile/11). */
    .portal-nav-inline.is-open,
    .nav-pills-inline.is-open {
        display: flex;
        flex-direction: column;
        gap: 4px;
        position: absolute;
        left: 0;
        right: 0;
        top: 100%;
        z-index: 40;
        margin-top: 6px;
        padding: 10px;
        background: var(--bg-panel);
        border: 1px solid var(--border);
        border-radius: 12px;
        box-shadow: var(--shadow);
    }

    .shell-main {
        padding-top: 20px;
    }

    .hero-shell {
        padding: 22px;
        border-radius: var(--radius-md);
    }

    .hero-heading {
        max-width: none;
    }

    .kpi-grid {
        grid-template-columns: 1fr 1fr;
    }

    .idea-dialog {
        width: min(100vw - 20px, 720px);
        max-height: calc(100svh - 18px);
    }

    .idea-dialog-shell {
        max-height: calc(100svh - 18px);
    }

    .idea-dialog-header {
        padding: 24px 22px 20px;
    }

    .idea-dialog-body {
        padding: 22px;
    }

    .roadmap-idea-intro h2 {
        font-size: clamp(1.8rem, 9vw, 2.7rem);
    }

    .roadmap-idea-intro .muted {
        font-size: 1rem;
    }

    .roadmap-idea-meta-grid {
        grid-template-columns: 1fr;
    }

    .idea-dialog-actions {
        align-items: stretch;
    }

    .topbar-actions,
    .hero-actions,
    .section-header,
    .filter-inline,
    .download-row {
        align-items: stretch;
    }

    .catalog-toolbar-unified {
        grid-template-columns: auto minmax(0, 1fr) auto auto;
    }

    .catalog-toolbar-unified .catalog-segmented {
        grid-auto-columns: max-content;
    }

    .catalog-toolbar-unified .catalog-search-field {
        grid-column: 2 / 3;
        width: clamp(180px, 28vw, 320px);
    }

    .catalog-toolbar-unified .catalog-version-select {
        grid-column: 3 / 4;
    }

    .catalog-toolbar-unified > .button-primary {
        grid-column: 4 / 5;
    }

    .catalog-toolbar-unified > .button-ghost {
        grid-column: 1 / -1;
        justify-self: start;
    }
}

@media (max-width: 560px) {
    .catalog-toolbar-unified {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .catalog-toolbar-unified .catalog-search-field {
        grid-column: 1 / -1;
    }

    .catalog-toolbar-unified .catalog-version-select {
        grid-column: 1 / 2;
    }

    .catalog-toolbar-unified > .button-primary {
        grid-column: 2 / 3;
    }

    .catalog-dialog-header,
    .catalog-dialog-body {
        padding-left: 20px;
        padding-right: 20px;
    }

    .changelog-entry {
        grid-template-columns: 14px minmax(0, 1fr);
        gap: 12px;
    }

    .changelog-entry-card,
    .changelog-highlight {
        padding: 16px 16px 18px;
    }

    .feature-grid,
    .admin-link-grid {
        grid-template-columns: 1fr;
    }

    .idea-dialog-header {
        gap: 16px;
        padding: 22px 18px 18px;
    }

    .idea-dialog-body {
        padding: 18px 18px 20px;
    }

    .idea-dialog-close {
        width: 48px;
        height: 48px;
        font-size: 1.75rem;
    }

    .roadmap-idea-textarea {
        min-height: 160px;
    }

    .admin-product-header,
    .admin-product-version-row {
        flex-direction: column;
        align-items: stretch;
    }

    .admin-product-actions,
    .admin-product-version-row form,
    .admin-product-version-row .button {
        width: 100%;
    }
}

@media (max-width: 560px) {
    .kpi-grid {
        grid-template-columns: 1fr;
    }

    /* as3m1ow provisioning: the desktop 220px right-aligned rule (0,2,0) beat
       the plain mobile rule above; match its specificity so the stat card
       fills the full row on phones. */
    .kpi-grid:not(.admin-kpi-grid) {
        grid-template-columns: 1fr;
        justify-content: stretch;
    }

    .button,
    .button:visited,
    .nav-chip,
    .portal-nav-link,
    .profile-chip {
        width: 100%;
    }

    .topbar-actions,
    .hero-actions,
    .portal-nav,
    .topbar-main,
    .profile-switcher {
        width: 100%;
    }

    .catalog-segment {
        flex: 1 1 0;
        min-width: 0;
        padding-inline: 12px;
    }

    .catalog-row-main {
        padding: 18px;
    }

    .catalog-row-actions {
        width: 100%;
    }

    .catalog-row-actions .button,
    .catalog-row-actions .button:visited {
        width: 100%;
    }

    .idea-dialog-actions .button,
    .idea-dialog-actions .button:visited {
        width: 100%;
    }

    .ticket-comment-editor-footer {
        align-items: flex-start;
        flex-direction: column;
    }

    .theme-menu {
        right: 0;
    }

    .contact-card-link,
    .profile-chip-name,
    .profile-chip-role,
    .profile-summary-copy strong,
    .profile-summary-copy span,
    .detail-value {
        overflow-wrap: anywhere;
    }
}

/* Catalog detail enrichment (widget_meta) - integrates "What's new" /
 * screenshots / changelog into the existing section-block visual flow.
 */
.changelog-rendered {
    padding: 1rem 1.25rem;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(176, 190, 219, 0.12);
}
.changelog-rendered h1,
.changelog-rendered h2,
.changelog-rendered h3 { margin-top: 0.5em; }
/* Markdown headings inside rendered changelogs are content, not page
   structure - cap them well below the page H1/H2 scale. Applies both to
   the hero "What's new" block (.changelog-rendered) and the per-version
   changelog HTML mirrored from the repo (.changelog-html-body). */
.changelog-rendered h1,
.changelog-html-body h1 { font-size: 1.25rem; }
.changelog-rendered h2,
.changelog-html-body h2 { font-size: 1.15rem; }
.changelog-rendered h3,
.changelog-html-body h3 { font-size: 1rem; }
.changelog-html-body h1,
.changelog-html-body h2,
.changelog-html-body h3 { margin-top: 0.5em; margin-bottom: 0.35em; }
.changelog-html-body ul { padding-left: 1.4em; margin: 0.35em 0; }
/* The per-version changelog HTML opens with its own <h2>X.Y.Z</h2> heading,
   which duplicates the version pill already shown in the release-card header
   right above it (visual-audit finding: version printed twice per card). */
.changelog-html-body > h2:first-child { display: none; }
.changelog-rendered ul { padding-left: 1.4em; }
.changelog-rendered code {
    background: rgba(255, 255, 255, 0.06);
    padding: 0 0.3em;
    border-radius: 3px;
    font-size: 0.9em;
}
.section-meta {
    margin-top: 0.5em;
    font-size: 0.85em;
}
.screenshot-strip {
    display: flex;
    gap: 0.75em;
    overflow-x: auto;
    padding-bottom: 0.5em;
}
.screenshot-strip a {
    flex: 0 0 auto;
}
.screenshot-strip img {
    max-height: 160px;
    border-radius: 8px;
    border: 1px solid rgba(176, 190, 219, 0.18);
    box-shadow: 0 4px 12px rgba(6, 12, 26, 0.18);
}


/* Values in status/info panels (emails, urls) must wrap instead of
   overflowing their card. */
.info-line dd,
.status-list strong,
.status-value {
    overflow-wrap: anywhere;
}

/* Release approvals: status pills, JSON preview and decision forms. */
.pill-success {
    background: rgba(72, 187, 120, 0.12);
    border-color: rgba(72, 187, 120, 0.28);
    color: #276749;
}

:root[data-theme='dark'] .pill-success {
    color: #9ae6b4;
}

.pill-danger {
    background: rgba(220, 60, 60, 0.10);
    border-color: rgba(220, 60, 60, 0.28);
    color: #c93c3c;
}

:root[data-theme='dark'] .pill-danger {
    color: #ffbaba;
}

.code-block {
    margin: 0;
    padding: 14px 16px;
    border-radius: 12px;
    background: var(--bg-soft);
    border: 1px solid var(--border);
    font-size: 0.85rem;
    line-height: 1.5;
    overflow-x: auto;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.decision-forms {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 18px;
}

.eyebrow-link,
.eyebrow-link:visited {
    color: inherit;
    text-decoration: none;
}

.eyebrow-link:hover {
    text-decoration: underline;
}

/* Row actions: keep each action label on one line. */
.table-actions a,
.table-actions .text-link-button {
    white-space: nowrap;
}

/* a99dwsb: users action column condensed to icon buttons; title/aria-label
   carry the label. Scoped so other .table-actions tables are untouched. */
.table-actions-compact {
    gap: 2px;
}
.table-actions-compact .icon-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 6px;
    border-radius: var(--radius-sm);
    line-height: 0;
    transition: background-color 0.15s ease;
}
.table-actions-compact .icon-action:hover {
    background: var(--accent-soft);
}
.table-actions-compact .icon-action.text-link-danger:hover {
    background: rgba(201, 60, 60, 0.10);
}
.table-actions-compact .action-icon {
    display: block;
    width: 1.15rem;
    height: 1.15rem;
}

/* Plain form-stack forms (entitlements grant, release decision):
   reuse the .field look without the Symfony form theme markup. */
.form-stack {
    display: grid;
    gap: 12px;
    max-width: 560px;
}

.form-stack label {
    display: grid;
    gap: 5px;
    color: var(--text);
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.3;
}

.form-stack input,
.form-stack select,
.form-stack textarea {
    display: block;
    width: 100%;
    /* Match the segmented controls (choice-segments) height. */
    min-height: 38px;
    padding: 0 12px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--field-bg);
    color: var(--text);
    font: inherit;
    font-weight: 400;
    transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
}

.form-stack select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5.25 7 9.25l4-4' stroke='%2393A0BD' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 16px center;
    padding-right: 44px;
}

.form-stack input:hover,
.form-stack input:focus,
.form-stack select:hover,
.form-stack select:focus,
.form-stack textarea:hover,
.form-stack textarea:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--field-bg-strong);
    box-shadow: 0 0 0 4px rgba(31, 101, 244, 0.12);
}

.form-stack small {
    font-weight: 400;
}

.form-stack .button {
    justify-self: start;
}

/* Downloads admin: chart container. */
.downloads-chart-shell {
    position: relative;
    height: 260px;
    padding: 14px 16px;
    background: var(--bg-soft);
    border: 1px solid var(--border);
    border-radius: 12px;
}

/* One-time secrets / warnings inside a panel. */
.panel-warning {
    border-color: rgba(255, 184, 77, 0.45);
    background: rgba(255, 184, 77, 0.08);
}

/* Equal-width variant of content-grid (notifications segments). */
.content-grid-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* aa18zch staff-sso: collapse at the same breakpoint as the base .content-grid
   so the two panels stack instead of cramping side by side on phones/tablets. */
@media (max-width: 960px) {
    .content-grid-2 {
        grid-template-columns: 1fr;
    }
}

/* Ghost buttons on the masthead (e.g. the "Return to admin" exit-impersonation
   button). The masthead is theme-adaptive - white in light mode, dark in dark
   mode - so the text/border must follow --text; a hardcoded white vanished on
   the white light-mode masthead. */
.masthead .button-ghost,
.masthead .button-ghost:visited {
    border-color: var(--border-strong);
    color: var(--text);
}

.masthead .button-ghost:hover {
    background: var(--bg-soft);
}

/* Inline checkbox option (products settings, broadcast form). */
.checkbox-label,
.form-stack label.checkbox-label {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: 500;
}

.form-stack .checkbox-label input,
.checkbox-label input[type='checkbox'] {
    width: auto;
    min-height: 0;
    accent-color: var(--accent);
}

/* Plain-markup form fields (roadmap admin, broadcast). Same look as .field. */
.form-label {
    display: block;
    font-weight: 600;
    margin-bottom: 10px;
}

.form-control {
    display: block;
    width: 100%;
    /* Unified portal control height (matches segmented/buttons/selects at 34px). */
    min-height: 34px;
    padding: 6px 12px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--field-bg);
    color: var(--text);
    font: inherit;
    transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
}

/* form-control selects get the same chevron as .field selects; multiple
   selects render as listboxes without it. */
select.form-control {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5.25 7 9.25l4-4' stroke='%2393A0BD' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 36px;
    cursor: pointer;
}

select.form-control[multiple],
.field select[multiple] {
    background-image: none;
    padding-right: 12px;
    min-height: 160px;
}

.form-control:hover,
.form-control:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--field-bg-strong);
    box-shadow: 0 0 0 4px rgba(31, 101, 244, 0.12);
}


/* Circle flag icons (assets/icons/flags). */
.flag-icon {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    display: block;
}

.locale-toggle-flag .flag-icon {
    width: 100%;
    height: 100%;
}

.locale-menu-flag .flag-icon {
    width: 28px;
    height: 28px;
}

.footer-phone-flag .flag-icon {
    width: 18px;
    height: 18px;
}

/* ---- Entitlements grant card ---- */
.grant-form h2 {
    margin: 0;
}

.grant-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 18px;
    align-items: start;
}

.grant-field {
    display: grid;
    gap: 8px;
    align-content: start;
}

.grant-field-wide {
    grid-column: span 2;
}

.grant-label {
    font-weight: 600;
    font-size: 0.95rem;
}

.grant-field select,
.grant-field input[type='text'],
.grant-field input[type='date'] {
    display: block;
    width: 100%;
    /* ahj6a3s: 38px to match the Validity segments + Grant button in the row
       below (portal-standard field height), so the filter row lines up. */
    height: 38px;
    min-height: 38px;
    padding: 0 14px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--field-bg);
    color: var(--text);
    font: inherit;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

/* Without appearance:none the OS paints its native select chrome (double
   caret, squared corners) and ignores the border/radius above. */
.grant-field select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5.25 7 9.25l4-4' stroke='%2393A0BD' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    padding-right: 40px;
}

.grant-field select:focus,
.grant-field input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 4px rgba(31, 101, 244, 0.12);
}

/* Token expiry presets on /profile/tokens - same conditional-reveal
   pattern as the entitlement grant form below. */
.token-expiry-field {
    display: grid;
    gap: 10px;
}

.token-expiry-label {
    color: var(--text);
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.3;
}

/* .form-stack label sets display:grid at higher specificity, so the
   hide/reveal pair must match it. */
.form-stack .token-expiry-custom,
.token-expiry-custom {
    display: none;
    max-width: 200px;
}

/* Portal-styled datepicker (the native date popup cannot be themed). */
.datepicker {
    position: relative;
}

.datepicker-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 30;
    width: 252px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-panel);
    box-shadow: var(--shadow);
}

.datepicker-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    margin-bottom: 8px;
}

.datepicker-month {
    font-size: 0.85rem;
    font-weight: 600;
}

.datepicker-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
}

.datepicker-dow {
    text-align: center;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--muted);
    padding: 2px 0;
}

.datepicker-day {
    min-height: 28px;
    padding: 0;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 0.82rem;
    cursor: pointer;
}

.datepicker-day:hover:not(:disabled) {
    background: var(--bg-soft);
}

.datepicker-day.is-selected {
    background: var(--accent);
    color: #ffffff;
    font-weight: 600;
}

.datepicker-day:disabled {
    color: var(--muted);
    opacity: 0.4;
    cursor: not-allowed;
}

/* Issue-token form: fields side by side, button on the same baseline. */
.token-issue-form {
    display: grid;
    gap: 8px;
}

.token-issue-row,
.inline-add-row {
    display: flex;
    align-items: end;
    gap: 14px;
    flex-wrap: wrap;
}

.token-issue-field,
.inline-add-field {
    display: grid;
    gap: 5px;
}

.token-issue-field input[type='text'],
.inline-add-field input[type='text'],
.inline-add-field input[type='email'] {
    min-height: 38px;
    width: 240px;
    max-width: 100%;
    padding: 0 12px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--field-bg);
    color: var(--text);
    font: inherit;
}

.token-issue-row .button,
.inline-add-row .button {
    min-height: 38px;
}

/* Native date input: portal font + the same 38px control height as the
   segments next to it; the browser popup calendar inherits the font. */
.token-expiry-custom input[type='date'] {
    font-family: 'Rubik', sans-serif;
    font-size: 0.86rem;
    min-height: 38px;
    width: 170px;
    padding: 0 10px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--field-bg);
    color: var(--text);
}

.token-expiry-custom input[type='date']::-webkit-calendar-picker-indicator {
    cursor: pointer;
    opacity: 0.7;
}

.form-stack .token-expiry-field:has(input[name='expiry'][value='custom']:checked) .token-expiry-custom,
.token-expiry-field:has(input[name='expiry'][value='custom']:checked) .token-expiry-custom {
    display: grid;
}

/* Conditional fields - no JS, driven by the checked radio. The custom
   valid-to date moved to the shared datepicker component. */
.grant-custom-slug {
    display: none;
}

.grant-form:has(input[name='edition'][value='custom']:checked) .grant-custom-slug {
    display: grid;
}

.grant-footer {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    padding-top: 4px;
}

/* Generic segmented radio control (repo switcher-tab look). */
.choice-segments {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
    width: fit-content;
    max-width: 100%;
    padding: 4px;
    border-radius: 10px;
    background: var(--bg-soft);
    border: 1px solid var(--border);
}

.choice-segment {
    position: relative;
    display: inline-flex;
}

.choice-segment input {
    position: absolute;
    opacity: 0;
    inset: 0;
    cursor: pointer;
}

.choice-segment span {
    display: inline-flex;
    align-items: center;
    /* 28px inner + 4px wrap padding + 1px borders = 38px total, matching
       the standard field/button height in form rows. */
    min-height: 28px;
    padding: 0 12px;
    border-radius: 7px;
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--muted);
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.choice-segment input:checked + span {
    color: #ffffff;
    background: var(--grad);
}

.choice-segment input:focus-visible + span {
    box-shadow: 0 0 0 3px rgba(31, 101, 244, 0.3);
}

/* Panel heading with trailing count pill. */
.panel-heading-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.panel-heading-row h2 {
    margin: 0;
}

/* Table embedded inside a panel - drop the double chrome. */
.table-shell-flat {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
}

/* Real initMAX logo (same SVG as repo.initmax.com chrome). */
.brand-logo svg {
    height: 26px;
    width: auto;
    aspect-ratio: 1581 / 432;
    display: block;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 12px;
}

.brand .brand-subtitle {
    border-left: 1px solid rgba(255, 255, 255, 0.18);
    padding-left: 12px;
    font-size: 0.85rem;
}

.brand-logo-footer svg {
    height: 30px;
}

/* Rectangular rounded flags for the footer phone list. */
.flag-rect {
    width: 22px;
    height: 16.5px;
    border-radius: 4px;
    display: block;
}

.footer-phone-flag .flag-rect {
    width: 100%;
    height: 100%;
}

.footer-phone-flag {
    border-radius: 4px;
    overflow: hidden;
}

/* Update cards on the dashboard are links to the catalog detail. */
.feature-card-link {
    text-decoration: none;
    color: inherit;
    display: grid;
    gap: 10px;
    align-content: start;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.feature-card-link:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow);
}


/* Masthead actions share one 36px height. */
.topbar-actions .button {
    min-height: 36px;
    padding: 0 14px;
    font-size: 0.92rem;
}

/* ---- Home (dashboard) - repo-style content-first layout ---- */
.home-intro {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(260px, 1fr);
    gap: 24px;
    align-items: start;
    padding: 28px 30px;
    border-radius: var(--radius-lg);
    background:
        radial-gradient(circle at top right, rgba(113, 80, 247, 0.28), transparent 32%),
        linear-gradient(135deg, #0d142d 0%, #131c3d 100%);
    color: #ffffff;
    border: 1px solid rgba(255, 255, 255, 0.06);
    box-shadow: var(--shadow);
}

.home-title {
    margin: 0;
    font-size: clamp(1.7rem, 2.6vw, 2.3rem);
    line-height: 1.12;
    font-weight: 700;
}

.home-intro .lead {
    color: rgba(255, 255, 255, 0.76);
}

.home-intro .button-ghost-dark,
.home-intro .button-ghost-dark:visited {
    border-color: rgba(255, 255, 255, 0.26);
    color: #ffffff;
    background: rgba(255, 255, 255, 0.04);
}

.home-intro .button-ghost-dark:hover {
    background: rgba(255, 255, 255, 0.1);
}

/* Stat chips inside the dark intro: translucent on navy. */
.home-intro .stat-card {
    background: rgba(255, 255, 255, 0.05);
    border-color: rgba(255, 255, 255, 0.12);
    box-shadow: none;
    color: #ffffff;
}

.home-intro .stat-card .stat-label {
    color: rgba(255, 255, 255, 0.66);
}

.home-intro .stat-card .stat-value {
    color: #ffffff;
}

.home-intro-copy {
    display: grid;
    gap: 10px;
}

.home-intro-stats {
    justify-content: end;
    align-content: start;
}

.home-release-list {
    display: grid;
}

/* Partner dashboard: agreement facts as one row of compact tiles. */
.panel-heading-actions {
    margin-left: auto;
    display: flex;
    gap: 8px;
}

.partner-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 8px;
}

.partner-fact {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 12px;
    border-radius: 8px;
    background: var(--bg-soft);
    border: 1px solid var(--border);
    text-decoration: none;
    color: inherit;
}

.partner-fact strong {
    font-size: 1.05rem;
}

a.partner-fact {
    transition: border-color 0.15s ease;
}

a.partner-fact:hover {
    border-color: var(--accent);
}

.partner-fact-quota {
    color: var(--muted);
    font-size: 0.85rem;
    font-weight: 600;
}

.partner-fact-over {
    color: var(--danger, #e5484d);
}

.quota-warning {
    color: var(--danger, #e5484d);
}

/* Enhanced selects: hide the native control (still holds the form value),
   the trigger mirrors the select.form-control field look. */
.select-enhanced > select {
    position: absolute !important;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.select-enhanced {
    display: block;
}

.select-enhanced-toggle {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 38px;
    padding: 8px 36px 8px 12px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background-color: var(--field-bg);
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5.25 7 9.25l4-4' stroke='%2393A0BD' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
}

.select-enhanced-toggle:hover,
.select-enhanced-toggle:focus {
    outline: none;
    border-color: var(--accent);
    background-color: var(--field-bg-strong);
    box-shadow: 0 0 0 4px rgba(31, 101, 244, 0.12);
}

.select-enhanced-toggle:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.select-enhanced-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.select-enhanced-menu {
    left: 0;
    right: auto;
    min-width: 100%;
    max-width: 360px;
}

.select-enhanced-menu .select-menu-item:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Releases as a real table: shared column template for header + rows. */
.home-release-shell {
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-panel);
    /* Scroll horizontally whenever the fixed-column grid is wider than the
       shell (the wide 6-col admin-products grid clips between 641-880px, not
       just on phones), instead of clipping columns off with overflow:hidden. */
    overflow-x: auto;
    overflow-y: hidden;
}

.home-release-head,
.home-release-row {
    display: grid;
    grid-template-columns: minmax(200px, 1fr) 140px 110px 130px 30px;
    align-items: center;
    gap: 12px;
    padding: 8px 16px;
}

.home-release-head {
    padding-top: 10px;
    padding-bottom: 10px;
    background: var(--bg-soft);
    color: var(--muted);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.home-release-empty {
    margin: 0;
    padding: 14px 16px;
}

/* Dividers as border-TOP on every row (not bottom-with-last-child-exception):
   each row band is then pixel-identical including the last one. */
.home-release-row {
    text-decoration: none;
    color: inherit;
    border-top: 1px solid var(--border);
    transition: background-color 0.15s ease;
}

.home-release-product {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

/* /admin/products as the same grid table, plus an expandable settings
   strip per product. */
.admin-products-head,
.admin-products-row {
    display: grid;
    grid-template-columns: minmax(220px, 1fr) 130px 100px 110px 130px 90px 16px;
    align-items: center;
    gap: 12px;
    padding: 8px 16px;
}

/* ao3ccfo: the product row IS the <details> summary; Settings expands inline
   with a caret at the end instead of a separate second line. */
summary.admin-products-row {
    cursor: pointer;
    list-style: none;
}
summary.admin-products-row::-webkit-details-marker {
    display: none;
}
.admin-products-caret {
    justify-self: center;
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--muted);
    border-bottom: 2px solid var(--muted);
    transform: rotate(45deg);
    transition: transform 0.15s ease;
}
.admin-products-item[open] > summary .admin-products-caret {
    transform: rotate(-135deg);
}

.admin-products-head {
    padding-top: 10px;
    padding-bottom: 10px;
    background: var(--bg-soft);
    color: var(--muted);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.admin-products-row {
    border-top: 1px solid var(--border);
}

.admin-products-row.is-hidden-product .home-release-name {
    color: var(--muted);
}

.admin-products-name {
    display: grid;
    min-width: 0;
}

.admin-products-name .muted.small {
    line-height: 1.2;
}

.admin-products-actions {
    justify-self: end;
}

.admin-products-extra {
    /* No own borders - the following product row's border-top divides. */
}

.admin-products-extra > summary {
    padding: 6px 16px 10px;
    color: var(--muted);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    list-style-position: inside;
}

.admin-products-extra > summary:hover {
    color: var(--accent);
}

.admin-products-extra-body {
    display: grid;
    gap: 14px;
    padding: 4px 16px 16px;
}

.admin-products-version-visibility {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.home-release-list .home-release-row:last-of-type {
    border-bottom: 0;
}

.home-release-row:hover {
    background: var(--bg-soft);
}

.home-release-editions {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
    min-width: 0;
}

.pill-edition {
    font-size: 0.66rem;
    padding: 2px 8px;
    letter-spacing: 0.04em;
}

.pill-edition.pill-free {
    background: rgba(34, 197, 94, 0.14);
    border-color: rgba(34, 197, 94, 0.36);
    color: #15803d;
}

:root[data-theme='dark'] .pill-edition.pill-free {
    color: #4ade80;
}

/* Ownership state inside the PRO pill: green check = active entitlement,
   muted padlock = PRO not licensed. Hover the pill for the explanation. */
.pill-pro-owned svg,
.pill-pro-locked svg {
    margin-left: 4px;
    flex-shrink: 0;
}

.pill-pro-owned svg {
    color: #16a34a;
}

.pill-pro-locked svg {
    color: var(--muted);
}

/* 'Owned' badge - active entitlement of the viewer's organization. */
.pill-edition.pill-owned {
    background: #16a34a;
    border-color: #16a34a;
    color: #ffffff;
}

.pill-edition.pill-pro {
    background: var(--accent-soft);
    border-color: rgba(113, 80, 247, 0.36);
    color: var(--accent-alt, #7150f7);
}

.home-release-icon {
    width: 26px;
    height: 26px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 7px;
    font-size: 0.8rem;
    font-weight: 700;
    color: #ffffff;
    background: var(--grad);
}

.home-release-name {
    font-weight: 600;
    min-width: 0;
}

.home-release-summary {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.home-release-arrow {
    grid-column: -2;
    justify-self: end;
    color: var(--accent);
    font-weight: 600;
}

/* /partner/customers as the same list table as releases/products. */
.customers-head,
.customers-row {
    grid-template-columns: minmax(180px, 1fr) 150px 64px 120px 84px 24px;
}

/* The shared .home-release-arrow pins itself to grid-column -2; in this
   6-column table that would land it on the status cell. Let it flow into
   its own trailing column instead. */
.customers-row .home-release-arrow {
    grid-column: auto;
}

.customers-name {
    display: grid;
    min-width: 0;
}

.customers-name .muted.small {
    line-height: 1.2;
}

.customers-cell {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.customers-num {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.pill-status-active {
    background: rgba(34, 197, 94, 0.14);
    border-color: rgba(34, 197, 94, 0.36);
    color: #15803d;
}

:root[data-theme='dark'] .pill-status-active {
    color: #4ade80;
}

.pill-status-disabled {
    background: var(--bg-soft);
    border-color: var(--border);
    color: var(--muted);
}

/* Advanced/secondary fields tucked away so partners aren't faced with
   technical inputs (external ref) at the same weight as the name. */
.advanced-disclosure {
    padding-top: 6px;
}

.advanced-disclosure > summary {
    cursor: pointer;
    color: var(--muted);
    font-size: 0.85rem;
    font-weight: 600;
    padding: 6px 0;
    list-style-position: inside;
}

.advanced-disclosure > summary:hover {
    color: var(--accent);
}

.advanced-disclosure-body {
    padding-top: 6px;
}

/* Current-access list: one compact row per product with inline revoke. */
.access-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--bg-soft);
}

.access-row-copy {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.access-row-name {
    font-weight: 600;
}

/* /admin/notifications campaign list - same table language, with a
   recipients disclosure folded under each row. */
.notify-head,
.notify-row {
    grid-template-columns: minmax(180px, 1fr) 90px 110px 110px 320px;
}

/* Dozens of releases otherwise stretch the page - bound the list and let
   it scroll under a pinned header (same pattern as the downloads log). */
.notify-table {
    max-height: 560px;
    overflow-y: auto;
}

.notify-table .notify-head {
    position: sticky;
    top: 0;
    z-index: 1;
}

.notify-actions {
    display: inline-flex;
    gap: 8px;
    justify-self: end;
    flex-wrap: wrap;
}

.notify-recipients {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}

.notify-recipients .small {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
}

/* Masthead action buttons (Sign in) match the 32px toggle squares. */
.masthead .button {
    min-height: 32px;
    padding: 0 14px;
}

/* Guest row in the PRO unlock panel: helper text centres against the
   button instead of hanging on the bottom edge of the row. */
.pro-unlock-fields > .muted {
    align-self: center;
}

.contact-strip {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.contact-strip-person {
    display: flex;
    align-items: center;
    gap: 12px;
}

.contact-strip-avatar {
    width: 46px;
    height: 46px;
    border-radius: 999px;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--accent-soft);
    color: var(--accent-ink);
    font-weight: 600;
    flex-shrink: 0;
    box-shadow: 0 0 0 2px var(--bg-panel), 0 0 0 4px rgba(113, 80, 247, 0.55);
}

.contact-strip-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.contact-strip-copy {
    display: grid;
    line-height: 1.35;
}

.contact-strip-actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.contact-strip-link {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.contact-strip-icon {
    flex-shrink: 0;
    color: var(--accent);
    opacity: 0.9;
}

@media (max-width: 860px) {
    .home-intro {
        grid-template-columns: minmax(0, 1fr);
    }

    .home-intro-stats {
        justify-content: start;
    }
}

/* =====================================================================
   Repo-chrome override: white slim masthead, text nav, light dropdowns,
   slim one-line footer. Mirrors repo.initmax.com/zabbix.
   ===================================================================== */
.masthead {
    background: var(--bg-panel);
    color: var(--text);
    border-bottom: 1px solid var(--border);
}

.brand-logo-light { display: block; }
.brand-logo-dark { display: none; }

:root[data-theme='dark'] .brand-logo-light { display: none; }
:root[data-theme='dark'] .brand-logo-dark { display: block; }

.brand .brand-subtitle {
    color: var(--muted);
    border-left: 1px solid var(--border);
}

.portal-nav-link,
.nav-chip {
    border: 0;
    background: transparent;
    color: var(--muted);
    font-weight: 500;
    min-height: 32px;
    padding: 0 10px;
}

.portal-nav-link:hover,
.portal-nav-link.is-active,
.nav-chip:hover {
    background: transparent;
    border-color: transparent;
    color: var(--accent);
}

.portal-nav-link.is-active {
    font-weight: 600;
}

.theme-toggle,
.locale-toggle,
.nav-toggle {
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text);
}

.theme-toggle:hover,
.locale-toggle:hover,
.nav-toggle:hover {
    border-color: var(--border-strong);
    background: var(--bg-soft);
}

.profile-chip {
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text);
}

.profile-chip:hover {
    background: var(--bg-soft);
    transform: none;
    box-shadow: none;
    border-color: var(--border-strong);
}

/* Quiet route-active state (like .portal-nav-link.is-active): accent border +
   soft accent wash, no lift/shadow - the old gradient+shadow read as a
   stuck-open menu. Token-driven, so it adapts to dark theme too. */
.profile-chip.is-active {
    border-color: var(--accent);
    background: var(--accent-soft);
    transform: none;
    box-shadow: none;
}

.profile-chip-name,
.profile-menu-title {
    color: var(--text);
}

.profile-chip-role {
    color: var(--muted);
}

/* Dropdown menus: light panels instead of dark glass. */
.locale-menu,
.profile-menu,
.theme-menu {
    background: var(--bg-panel);
    border: 1px solid var(--border);
    color: var(--text);
    box-shadow: var(--shadow);
}

.locale-menu-item,
.profile-menu-item,
.theme-menu-item {
    color: var(--text);
}

.locale-menu-item:hover,
.profile-menu-item:hover,
.theme-menu-item:hover {
    background: var(--bg-soft);
}

.locale-menu-title,
.theme-menu-title {
    color: var(--text);
}

.locale-menu-caption,
.theme-menu-caption {
    color: var(--muted);
}

.theme-menu-icon,
.profile-menu-icon {
    background: var(--bg-soft);
    color: var(--muted);
}

.theme-menu-item.is-selected .theme-menu-icon {
    background: var(--accent-soft);
    color: var(--accent);
}

/* Accent check mark stays visible on both the light panel and the
   selected-item gradient (the old hardcoded white vanished on light). */
.theme-menu-check {
    color: var(--accent);
}

.locale-menu-flag {
    background: var(--bg-soft);
}

/* Slim one-line footer. */
.site-footer {
    background: var(--bg-panel);
    color: var(--text);
    border-top: 1px solid var(--border);
    margin-top: 24px;
}

.footer-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    flex-wrap: wrap;
    padding-top: 16px;
    padding-bottom: 16px;
}

.footer-bar-left {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}

.footer-bar-logo svg {
    height: 20px;
}

.footer-bar-links {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.footer-bar-links a {
    color: var(--muted);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}

.footer-bar-links a:hover {
    color: var(--accent);
}

.footer-bar .footer-phone-flag {
    width: 18px;
    height: 13.5px;
    display: inline-flex;
}

/* Centered landing hero (repo style). */
.home-intro {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    text-align: center;
    background: transparent;
    border: 0;
    box-shadow: none;
    color: var(--text);
    padding: 14px 20px 2px;
}

.home-kicker {
    color: var(--accent-ink);
    text-transform: uppercase;
    letter-spacing: 0.14em;
    font-size: 0.78rem;
    font-weight: 600;
}

.home-title {
    font-size: clamp(1.6rem, 2.6vw, 2.1rem);
    font-weight: 700;
    color: var(--text);
}

/* Logged-in greeting: one slim line, content right below it. */
.home-title-auth {
    font-size: 1.3rem;
}

.home-intro .lead {
    color: var(--muted);
    max-width: 62ch;
}

.home-intro-copy {
    justify-items: center;
}

.home-intro .hero-actions {
    justify-content: center;
}

.home-intro .button-ghost-dark,
.home-intro .button-ghost-dark:visited {
    border: 1px solid var(--border-strong);
    color: var(--text);
    background: var(--bg-panel);
}

.home-intro .button-ghost-dark:hover {
    background: var(--bg-soft);
}

.home-intro-stats {
    justify-content: center;
}

.home-intro .stat-card {
    background: var(--bg-panel);
    border-color: var(--border);
    color: var(--text);
    box-shadow: var(--shadow-sm);
}

.home-intro .stat-card .stat-label {
    color: var(--muted);
}

.home-intro .stat-card .stat-value {
    color: var(--text);
}

/* Older versions fold on the product detail. */
.older-versions {
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-md);
}

.older-versions > summary {
    cursor: pointer;
    list-style: none;
    padding: 14px 18px;
    font-weight: 600;
    color: var(--accent);
}

.older-versions > summary::-webkit-details-marker {
    display: none;
}

.older-versions > summary::before {
    content: '+';
    display: inline-block;
    width: 1.2em;
    font-weight: 700;
}

.older-versions[open] > summary::before {
    content: '\2212';
}

.older-versions-stack {
    padding: 0 14px 14px;
}

/* Copy-to-clipboard blocks (install snippets, tokens). */
.copy-block {
    position: relative;
}

.copy-block pre {
    margin: 0;
    padding-right: 84px;
}

.copy-button {
    position: absolute;
    top: 8px;
    /* axqnnqy: align the button's right edge with the code text boundary
       (16px content inset) instead of floating 8px off it. */
    right: 16px;
    z-index: 2;
    min-height: 24px;
    padding: 0 10px;
    border: 1px solid var(--border-strong);
    border-radius: 8px;
    background: var(--bg-panel);
    color: var(--muted);
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}

.copy-button:hover {
    color: var(--accent);
    border-color: var(--accent);
}

.copy-button.is-copied {
    color: #276749;
    border-color: rgba(72, 187, 120, 0.5);
    background: rgba(72, 187, 120, 0.1);
}

:root[data-theme='dark'] .copy-button.is-copied {
    color: #9ae6b4;
}


.locale-menu::-webkit-scrollbar {
    display: none;
}

/* Segmented switches/filters (.catalog-segmented) flow their segments in a
   non-wrapping grid column, so on narrow phones the row overflows to the right
   and drags the whole page with it. Below 500px, let the segment row scroll
   horizontally instead of overflowing - segments keep their full size and stay
   readable, and a scrollbar shows the row can be swiped sideways. Desktop and
   tablet are untouched. */
@media (max-width: 500px) {
    /* Wrap instead of horizontal scroll: the macOS/iOS overlay scrollbar is
       invisible, so a scrolling segmented control just looked like a clipped
       one ("Owned" cut mid-word - visual-audit mobile/02). Wrapping matches
       what the detail-tabs variant already did. */
    .catalog-segmented {
        display: flex;
        flex-wrap: wrap;
        max-width: 100%;
    }

    .catalog-segmented .catalog-segment {
        flex: 0 0 auto;
    }
}

/* List tables (.home-release-shell: /dashboard releases, /admin products,
   /partner customers) are grids with fixed-width columns wider than a phone
   viewport. The shell had overflow: hidden, so on narrow screens the extra
   columns were simply clipped with no way to reach them. Below 900px, let the
   shell scroll horizontally so a scrollbar appears and the hidden columns can
   be swiped into view. Desktop is untouched. */
@media (max-width: 900px) {
    .home-release-shell {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Once the shell scrolls, each row only stretched to the visible width, so
       its top divider line and hover background stopped at the fold - scrolled
       past that point the table lost its horizontal rules and looked broken.
       Stretch every row/head to the content width so the dividers run the full
       length and the table keeps its structure across the whole scroll. */
    .home-release-shell .home-release-head,
    .home-release-shell .home-release-row {
        min-width: max-content;
    }
}

/* On phones the topbar wrapped .topbar-actions (theme toggle + language +
   profile) onto its own line, leaving the moon and flag icons floating alone
   on a second row while there was empty space next to the hamburger on the
   first row. Below 720px (where the hamburger already appears), lay the topbar
   out as a two-column grid: brand+hamburger on the left of row 1, theme+
   language on the right of row 1, and the wide profile chip anchored across
   the full width on row 2. `minmax(0, 1fr)` on the actions column and a
   wrapping flex keep it from overflowing even while impersonating (an extra
   "exit impersonation" button). Desktop and tablet are untouched. */
@media (max-width: 720px) {
    .topbar {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        align-items: center;
        column-gap: 12px;
        position: relative;
        padding-bottom: 46px;
    }

    .topbar-main {
        grid-column: 1;
        grid-row: 1;
        min-width: max-content;
        width: auto;
    }

    .topbar-actions {
        grid-column: 2;
        grid-row: 1;
        min-width: 0;
        display: flex;
        flex-wrap: wrap;
        justify-content: flex-end;
        align-items: center;
        gap: 8px;
        width: auto;
    }

    /* Profile chip is wide; anchor it across the full width on the second row
       so the icons stay compact on the first row. */
    .topbar-actions .profile-switcher {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        width: auto;
    }

    /* Exit-impersonation button (only present while impersonating): let it size
       to content and its label stay on one line, without stretching the row. */
    .topbar-actions .inline-form {
        flex: 0 1 auto;
    }

    .topbar-actions .inline-form .button {
        white-space: nowrap;
    }
}

/* Phones: the shared list-tables (dashboard releases, admin products, admin
   notifications, partner customers) all use .home-release-shell with a fixed
   multi-column grid (~640-840px wide). On a ~340px card that grid was clipped
   by the shell's `overflow:hidden`, cutting off Version/Released/actions with
   no way to reach them. Keep the grid intact but let the shell scroll
   horizontally instead of clipping. */
@media (max-width: 640px) {
    .home-release-shell {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    .home-release-head,
    .home-release-row {
        min-width: 600px;
    }

    .admin-products-head,
    .admin-products-row {
        min-width: 800px;
    }
}

/* Masthead Sign-in: full "Sign in" button on desktop; on phones - where the
   nav collapses to the hamburger and the top bar gets tight - it shrinks to a
   compact icon-only button (person glyph), matching the theme/locale toggles,
   so the whole bar stays on one row instead of wrapping the big blue button. */
a.masthead-signin {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

a.masthead-signin .masthead-signin-icon {
    display: none;
    align-items: center;
    justify-content: center;
}

a.masthead-signin .masthead-signin-icon svg {
    width: 18px;
    height: 18px;
}

@media (max-width: 720px) {
    a.masthead-signin {
        gap: 0;
        width: 34px;
        min-width: 34px;
        height: 34px;
        min-height: 34px;
        padding: 0;
        border-radius: 9px;
    }

    a.masthead-signin .masthead-signin-label {
        display: none;
    }

    a.masthead-signin .masthead-signin-icon {
        display: inline-flex;
    }
}

/* Stacked field label used by the broadcast composer (the <label> wraps its
   caption text + the control). Was relying on an undefined `.field-label`
   class, so labels had no weight/gap; match the .grant-label weight and the
   standard field spacing, and keep the control's own (non-bold) font. */
.field-label {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--text);
}

.field-label > .form-control,
.field-label > input,
.field-label > select,
.field-label > textarea {
    font-weight: 400;
}

/* ============================================================
   Review round 2 - mobile polish (visual-review-kit feedback)
   ============================================================ */
@media (max-width: 720px) {
    /* #1 Topbar profile chip -> avatar-only, inline with the theme/locale
       icons on the first row (no full-width second row + no reserved space). */
    .topbar {
        padding-bottom: 0;
    }

    .topbar-actions .profile-switcher {
        position: static;
        left: auto;
        right: auto;
        bottom: auto;
        width: auto;
    }

    .profile-chip {
        width: auto;
        padding: 3px;
        gap: 0;
    }

    .profile-chip-copy,
    .profile-chip-caret {
        display: none;
    }
}

@media (max-width: 560px) {
    /* #3/#4/#5 Catalog toolbar: every control full-width, and the version
       dropdown and Apply button share a row as equal, same-height halves. */
    .catalog-toolbar-unified {
        grid-template-columns: 1fr 1fr;
    }

    .catalog-toolbar-unified .catalog-segmented {
        grid-column: 1 / -1;
    }

    .catalog-toolbar-unified .catalog-search-field {
        grid-column: 1 / -1;
        width: 100%;
        justify-self: stretch;
    }

    .catalog-toolbar-unified .catalog-version-select {
        grid-column: 1 / 2;
    }

    .catalog-toolbar-unified > .button-primary {
        grid-column: 2 / 3;
    }

    .catalog-toolbar-unified > .button-ghost {
        grid-column: 1 / -1;
        justify-self: stretch;
    }

    .catalog-toolbar-unified .catalog-version-select,
    .catalog-toolbar-unified > .button {
        height: 34px;
        min-height: 34px;
    }

    /* Keep the version label on one line inside the narrower mobile control. */
    .catalog-toolbar-unified .catalog-version-select {
        white-space: nowrap;
        font-size: 0.78rem;
    }

    /* #8 Hero action buttons (e.g. roadmap "Suggest an idea") full-width -
       the button lives inside a controller <div>, so widen the wrapper too. */
    .page-hero .hero-actions > div,
    .home-intro .hero-actions > div {
        width: 100%;
    }

    /* #2 Dashboard contact strip: shrink the line and drop the long tagline so
       just the role stays - one clean line under the name. */
    .contact-strip-copy .muted.small {
        font-size: 0.78rem;
        line-height: 1.35;
    }

    .contact-strip-tagline {
        display: none;
    }
}

/* ============================================================
   Review round 3 - mobile polish v2 (visual-review-kit batch 2)
   ============================================================ */
@media (max-width: 560px) {
    /* atzmpy7 Roadmap: let long card titles use the full header width
       (stack the status pill below the title on phones). */
    .roadmap-card-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 6px;
    }

    /* atu635c Support: stretch the All/Active/Closed status filter to full
       width so it spans the row like the Create-ticket button below it.
       Scoped to .catalog-toolbar so the catalog/detail-tabs segmenteds are safe. */
    .catalog-toolbar .catalog-segmented {
        display: flex;
        width: 100%;
        max-width: 100%;
    }

    .catalog-toolbar .catalog-segmented .catalog-segment {
        flex: 1 1 0;
        min-width: 0;
    }

    /* ao8lh0g Repo tokens: stack the Label/expiry fields full-width on mobile
       (the flex row wraps; give each field the whole row so the input fills it). */
    .token-issue-row .token-issue-field {
        flex: 1 1 100%;
    }

    .token-issue-field input[type='text'] {
        width: 100%;
    }

    /* apytear Repo tokens: unify control heights to the 34px portal standard
       (the token dropdown/select + Issue-token button were taller than the rest). */
    .pro-unlock-field input,
    .pro-unlock-field select,
    .token-issue-row .button {
        min-height: 34px;
        line-height: 1.2;
    }

    /* au2rm39 Repo tokens: tighten the usage intro so it stops sprawling. */
    .detail-card .section-copy {
        font-size: 0.8rem;
    }

    /* am2oqyh Footer: keep the contact links (e-mail + phones) on ONE line
       instead of wrapping to two rows; scroll sideways since three intl
       numbers cannot all fit legibly across 390px. */
    .site-footer .footer-contact-line {
        display: flex;
        flex-wrap: nowrap;
        align-items: center;
        gap: 10px;
        /* min-width:0 lets this flex item shrink below its content width so
           overflow-x scrolls INSIDE it instead of widening the whole page
           (the flexbox min-width:auto trap that broke mobile layout). */
        min-width: 0;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }

    /* Also stop the links row itself from forcing width on narrow phones. */
    .footer-bar-links {
        min-width: 0;
        max-width: 100%;
    }

    .site-footer .footer-contact-line::-webkit-scrollbar {
        display: none;
    }

    .site-footer .footer-contact-line a {
        flex: 0 0 auto;
    }
}

@media (max-width: 500px) {
    /* a82fo7j / ano3fmp / a4vu4im OS picker (Debian/RHEL/SUSE) on dashboard
       install, catalog show + repo tokens: distribute the full card width so
       the three segments share it evenly and SUSE can never clip past the edge.
       Long labels wrap to two lines inside their own segment. Replaces the old
       nowrap+overflow-x:auto whose invisible scrollbar just read as clipped SUSE. */
    .catalog-segmented.detail-tabs {
        display: flex;
        flex-wrap: nowrap;
        align-items: stretch;
        width: 100%;
        min-width: 0;
        max-width: 100%;
        /* a3o3gy6: match the base .catalog-segmented inter-segment gap. */
        gap: 5px;
    }

    .detail-tabs .catalog-segment {
        flex: 1 1 0;
        min-width: 0;
        padding: 4px 6px;
        font-size: 0.72rem;
        line-height: 1.15;
        white-space: normal;
        text-align: center;
    }

    /* the install picker forces min-width:92px on desktop; release it here. */
    .install-step .catalog-segment {
        min-width: 0;
    }
}

/* ============================================================
   Review round 5 - visual-review-kit batch 4
   ============================================================ */

/* a23az9n catalog changelog dialog: guard mirrored repo HTML from clipping
   (the dialog is overflow:hidden) - pre/table/code scroll or wrap instead. */
.changelog-html-body { overflow-wrap: anywhere; }
.changelog-html-body pre,
.changelog-html-body table { display: block; max-width: 100%; overflow-x: auto; }
.changelog-html-body code { overflow-wrap: anywhere; }
.catalog-row-zabbix { min-width: 0; }

/* arktpvj entitlements: the Edition segmented fills its grid cell so
   Org | Product | Edition span the full filter row, 34px like the dropdowns. */
.grant-field:not(.grant-field-wide) .choice-segments { width: 100%; }
.grant-field:not(.grant-field-wide) .choice-segment { flex: 1 1 0; }
.grant-field:not(.grant-field-wide) .choice-segment span {
    width: 100%;
    justify-content: center;
    /* arktpvj: 28px inner + 8px padding + 2px border = 38px, matching the
       Org/Product dropdowns so Edition fills the row at the same height. */
    min-height: 28px;
}

/* apvmzlm entitlements: Grant button sits beside the Validity control on one row. */
.grant-validity-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 18px 24px;
}
.grant-validity-row .grant-footer {
    padding-top: 0;
}

/* aqu9yuw entitlements: collapse the empty trailing actions column so the
   right-aligned Valid-until values reach the panel's right edge. */
.table-shell-flat .table th:last-child,
.table-shell-flat .table td:last-child {
    width: 1px;
    white-space: nowrap;
    padding-right: 0;
    padding-left: 0;
}

@media (max-width: 640px) {
    /* a7pktw2 admin-contacts: tighten the wrapped admin-tab rows (was ~36px pitch). */
    .admin-tabs { gap: 2px; padding: 6px; }
    .admin-tab { min-height: 24px; font-size: 0.82rem; }
}

@media (max-width: 560px) {
    /* adtixnq admin-catalog: keep the two sync buttons on ONE row as equal halves. */
    .hero-actions-inline { flex-wrap: nowrap; }
    .hero-actions-inline > form { flex: 1 1 0; min-width: 0; }
    .hero-actions-inline > form > .button { width: 100%; padding-left: 10px; padding-right: 10px; }

    /* ahuzdpq admin-catalog: tighten the gap between the hero actions and the
       admin sub-nav on phones (shared .section-block-tight top margin was 20px). */
    .page-hero + .section-block-tight { margin-top: 10px; }
}

@media (max-width: 480px) {
    /* a7rxszk admin-downloads: tighten the stacked KPI gap on phones + drop the
       per-card shadow so the stacked chips read as a tight group, not floating
       cards with gaps of shadow between them. */
    .admin-kpi-grid { gap: 4px; }
    .admin-kpi-grid .stat-card { box-shadow: none; }
}

/* ============================================================
   Review round 4 - desktop admin polish (visual-review-kit batch 3)
   ============================================================ */

/* ar8bd7l Roadmap intro on one line (shared .lead 70ch cap forced a wrap). */
.roadmap-lead {
    max-width: none;
}

/* aqt1sir Repo tokens: Label field was a fixed 240px box next to the
   content-sized Kind control; give the two fields equal width. DESKTOP ONLY -
   on mobile the round-3 rule stacks them full-width; applying this there made
   the Kind segments nowrap and overflowed the page. */
@media (min-width: 561px) {
    .token-issue-row .token-issue-field:has(#token_label),
    .token-issue-row .token-issue-field:has(input[name='kind']) {
        flex: 1 1 0;
        min-width: 0;
    }
    .token-issue-row .token-issue-field:has(#token_label) input[type='text'] {
        width: 100%;
    }
    .token-issue-row .token-issue-field:has(input[name='kind']) .choice-segments {
        flex-wrap: nowrap;
    }
}

/* av81l15 Entitlements: right-align the Valid-until column to use the space. */
.table-shell-flat .table th:nth-child(5),
.table-shell-flat .table td:nth-child(5) {
    text-align: right;
}

/* a5jxh3c Contacts: center cells vertically against the tall avatar/scope cell. */
.table-contacts td {
    vertical-align: middle;
}

/* a4ucqj9 Users: center every body cell against the tall wrapped cell. */
.table-vmiddle td {
    vertical-align: middle;
}

/* acsn1vx Admin roadmap: center cells; atkrzqv let the row actions fill space. */
.admin-roadmap-table td {
    vertical-align: middle;
}
.admin-roadmap-table .table-actions > .button,
.admin-roadmap-table .table-actions > .inline-form {
    flex: 1 1 0;
}
.admin-roadmap-table .table-actions .inline-form {
    display: flex;
}
.admin-roadmap-table .table-actions .inline-form > .button {
    flex: 1 1 auto;
}

/* aby0i7k/ao1rxan Partner customer detail: stretch short right-column asides to
   fill the row height instead of leaving a gray gap (scoped, not global). */
.content-grid-fill {
    align-items: stretch;
}

/* a6vwirj Partner customer detail: the top row reads as two EQUAL columns
   (Customer settings | Effective contact) instead of the default 1.3/0.9
   split. Scoped so every other content-grid keeps the asymmetric layout. */
.content-grid-even {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /* alnqvpy: the shorter Effective-contact panel stretches to the settings
       panel's height so the row reads as one block. */
    align-items: stretch;
}

@media (max-width: 960px) {
    .content-grid-even {
        grid-template-columns: 1fr;
    }
}

/* a2u38jn Partner customer detail: empty-state cell full-bleed to the shell. */
.table-empty-cell {
    padding: 0;
}

/* ============================================================
   Review round 6 - visual-review-kit batch 5
   ============================================================ */

/* ajcvtqv catalog list: right-align the Actions header over its right-aligned
   action buttons (the column content sits flex-end). */
.catalog-list-head span:last-child {
    text-align: right;
}

@media (max-width: 560px) {
    /* aqsyikk catalog cards: tighten the stacked rows so each product card is
       more compact on phones (was 14px between every stacked cell). */
    .catalog-row-main {
        gap: 6px;
    }

    /* agozxqv roadmap + auryixt SYSTEMIC admin-mobile gap: the bare (background-
       less) hero inherited the 24px card padding on phones, leaving a dead band
       above the title and below the lead on every page. Match the desktop 6/x/2
       rhythm and keep the full-bleed sides. */
    .page-hero {
        padding: 6px 0 2px;
    }

    /* al4qr9z admin sub-nav: unify the gap BELOW the sub-nav card with the 10px
       hero->sub-nav gap above it. :has(> .admin-tabs) scopes this to the admin
       sub-nav so other .section-block-tight uses stay untouched. */
    .section-block-tight:has(> .admin-tabs) + .section-block {
        margin-top: 10px;
    }
}

@media (max-width: 500px) {
    /* ailg6ea OS segmented: content-width (compact) instead of equal thirds so
       SUSE has no big empty gap; all three still fit on one centered line. */
    .catalog-segmented.detail-tabs {
        justify-content: center;
    }
    .detail-tabs .catalog-segment {
        flex: 0 0 auto;
        white-space: nowrap;
    }
}

/* ============================================================
   Review round 7 - visual-review-kit batch 6
   ============================================================ */
@media (max-width: 560px) {
    /* awcak5a roadmap: tighten the hero's internal spacing. */
    .page-hero-stack {
        gap: 10px;
    }

    /* amrddri dashboard: the Send-feedback button was centered at content width.
       The whole chain is content-sized/centered - .home-intro-copy is a centered
       grid item AND its own grid centres children - so widen the copy column,
       then stretch the actions row + button. Text keeps text-align:center. */
    .home-intro-copy {
        justify-self: stretch;
        width: 100%;
    }
    .home-intro .hero-actions {
        justify-self: stretch;
        width: 100%;
    }
    .home-intro .hero-actions > div,
    .home-intro .hero-actions .button {
        width: 100%;
    }
}

@media (max-width: 500px) {
    /* av691nz install card EDITION picker (FREE/PRO/ALL, the 2nd step): fill the
       row so the short labels don't leave centered dead space. Scoped to the
       last install-step so the OS picker stays content-width (ailg6ea). */
    .install-steps .install-step:last-child .catalog-segment {
        flex: 1 1 auto;
    }

    /* abnut6a / aod4u86 repo tokens: keep the Kind and Expires choice-segments
       on ONE row (they wrapped to two); equal segments, shrink labels to fit. */
    .token-issue-row .choice-segments {
        flex-wrap: nowrap;
        min-width: 0;
        /* a7hjkr7: fill the full-width field so Kind + Expires span the row like
           the Issue-token button (base rule is width:fit-content). */
        width: 100%;
    }
    .token-issue-row .choice-segment {
        flex: 1 1 0;
        min-width: 0;
    }
    .token-issue-row .choice-segment span {
        padding-left: 6px;
        padding-right: 6px;
        font-size: 0.68rem;
        line-height: 1.15;
        white-space: normal;
        text-align: center;
        justify-content: center;
    }
}

/* ============================================================
   Review batch B - 27-item round (mobile spacing + desktop alignment)
   ============================================================ */

/* aspx5f1 + a8hp9ho dashboard mobile: Send-feedback button matches the panel
   width (drop home-intro side padding) + tighter vertical rhythm around it. */
@media (max-width: 560px) {
    .home-intro {
        padding: 8px 0 0;
    }
    .home-intro-copy {
        gap: 6px;
    }
    .home-intro .hero-actions {
        padding-top: 2px;
    }
}

/* afqnrtd catalog desktop: indent pill/chip-bearing header cells so the label
   sits over the pill TEXT (11px inset), matching the plain-text columns. */
.catalog-list-head span:nth-child(2),
.catalog-list-head span:nth-child(3),
.catalog-list-head span:nth-child(5) {
    padding-left: 11px;
}

/* awdoqd0 + apprjt3 catalog: unwrap the Changelog dialog box so it is a direct
   flex child of the row actions (full-width stacked on mobile like Detail). */
.catalog-row-actions > [data-controller="dialog"] {
    display: contents;
}

@media (max-width: 560px) {
    /* acc91th catalog-detail: FREE pill + Buy-PRO cluster left, button shrinks
       to its label - kills the empty gap between them. */
    .install-step-buy .button,
    .install-step-buy .button:visited {
        width: auto;
    }

    /* a19841z: on phones the code text uses the full block width (less wrapping)
       and the Copy button lives in a reserved top strip, not eating width. */
    .copy-block pre {
        padding-right: 16px;
        padding-top: 40px;
    }

    /* aenlq50 catalog-detail: send-feedback strip full width. */
    .feedback-strip {
        align-items: stretch;
    }
    .feedback-strip > div {
        width: 100%;
    }

    /* az4pyc7 roadmap mobile: filter segments stretch full-width in equal
       columns to match the Suggest-an-idea button; smaller padding+font keep
       'In progress (4)' on one line inside a third. */
    .catalog-toolbar .roadmap-filter {
        width: 100%;
        max-width: 100%;
        grid-auto-columns: minmax(0, 1fr);
    }
    .catalog-toolbar .roadmap-filter .catalog-segment {
        min-width: 0;
        padding-inline: 6px;
        font-size: 0.8rem;
        white-space: nowrap;
    }
    .roadmap-toolbar {
        gap: 10px;
    }
    .roadmap-toolbar .hero-actions {
        padding-top: 0;
    }
    [data-controller="roadmap-filter"] > .section-block {
        margin-top: 6px;
    }
}

/* ============================================================
   Review batch C - catalog width/filter/meta + roadmap tag +TAG button
   ============================================================ */

/* a2u56na catalog desktop: align the unified toolbar edges with the product
   list panel below (cancel .page-hero's 4px side padding on the toolbar only). */
@media (min-width: 961px) {
    .catalog-toolbar-unified {
        width: auto;
        margin-inline: -4px;
    }
}

@media (max-width: 560px) {
    /* aagu107 catalog mobile: segmented filter fills the full toolbar width. */
    .catalog-toolbar-unified .catalog-segmented {
        grid-column: 1 / -1;
        display: flex;
        width: 100%;
        max-width: 100%;
        justify-self: stretch;
    }
    .catalog-toolbar-unified .catalog-segmented .catalog-segment {
        flex: 1 1 0;
        min-width: 0;
    }

    /* aeiifi5 catalog mobile: lay the card meta cells (edition/version/date/
       zabbix) into a 2-col grid instead of a cramped left cluster; title and
       actions span full width. */
    .catalog-row-main {
        gap: 6px 14px;
        grid-template-columns: 1fr 1fr;
    }
    .catalog-row-title,
    .catalog-row-actions {
        grid-column: 1 / -1;
    }
}

/* asz44fw roadmap form: the "+ Add tag" button sits on the label's line. */
.tag-field-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
}

/* aaya5th / a5apil2 / aa2mlhw / a71t7m8 profile mobile: the two profile cards
   collapse to one column and keep 24px panel padding, stacking ~60px of dead
   space between every section. Tighten the card system on phones. */
@media (max-width: 560px) {
    .version-grid {
        gap: 10px;
    }
    .version-grid > .panel {
        padding: 16px;
    }
    .version-grid .section-block-tight {
        margin-top: 12px;
    }
}

/* ============================================================
   Review batch D - missed export items (dashboard/catalog/roadmap mobile)
   ============================================================ */
@media (max-width: 560px) {
    /* a4843lu dashboard: keep the "initMAX · Zabbix Premium Partner" eyebrow on
       one line down to ~320px (uppercase + letter-spacing was the cause). */
    .home-kicker {
        font-size: 0.68rem;
        letter-spacing: 0.08em;
        white-space: nowrap;
    }

    /* a211o2q dashboard: the account-manager email/phone contact buttons stacked
       onto two rows; collapse them to compact icon buttons on one row (mailto/tel
       still fire on tap; full address stays in title/aria-label). */
    .contact-strip-actions {
        gap: 8px;
    }
    .contact-strip-link {
        flex: 0 0 auto;
        min-width: 0;
        padding: 0 12px;
    }
    .contact-strip-link > span {
        display: none;
    }

    /* a5mto0d / aryhwgm / aigzby6 catalog: stack the toolbar into a single
       full-width column so every control (segments, search, version, Apply,
       Reset) spans the box at the unified 34px height - no side gap, no size
       mismatch, nothing pushed to a cramped half-row. */
    .catalog-toolbar-unified {
        grid-template-columns: 1fr;
    }
    .catalog-toolbar-unified .catalog-segmented,
    .catalog-toolbar-unified .catalog-search-field,
    .catalog-toolbar-unified .catalog-version-field,
    .catalog-toolbar-unified > .button-primary,
    .catalog-toolbar-unified > .button-ghost {
        grid-column: 1 / -1;
        width: 100%;
        justify-self: stretch;
    }
    .catalog-toolbar-unified .catalog-version-select,
    .catalog-toolbar-unified > .button {
        width: 100%;
        height: 34px;
        min-height: 34px;
    }

    /* aaa8ykh roadmap: Suggest-an-idea button full-width (scoped to the roadmap
       toolbar so the home hero CTAs are not affected). */
    .roadmap-toolbar .hero-actions,
    .roadmap-toolbar .hero-actions > div,
    .roadmap-toolbar .hero-actions .button-primary {
        width: 100%;
    }
}

/* ============================================================
   Review batch E - spacing pass (catalog-detail / support mobile)
   ============================================================ */
@media (max-width: 560px) {
    /* ajzi5xp catalog-detail: the hero facts sat ~60px above the first card;
       pull the first section up toward the Zabbix version chip. */
    .detail-hero {
        padding-bottom: 6px;
    }
    .detail-layout {
        margin-top: 4px;
    }

    /* afp1ram catalog-detail: the snippet text was inset 16px past the card body
       copy; trim the block's left padding so `wget ...` lines up closer. */
    .detail-card .copy-block pre {
        padding-left: 8px;
    }

    /* ax6lww6 support index: the ticket-table panel keeps 24px padding when it
       collapses to one column, stacking dead space above/around it - tighten,
       scoped to .support-list so the other 56 panels are untouched. */
    .support-list {
        margin-top: 8px;
    }
    .support-list .panel {
        padding: 16px;
    }
}

/* ============================================================
   Review batch F - customers filter/search, products mobile card, tags gap
   ============================================================ */

/* a7idv0t partner customers: one-row filter form (segments + partner dropdown +
   search + apply); wraps gracefully and stacks on phones. */
.customers-filter-form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    min-width: 0;
    flex: 1 1 auto;
}

.customers-search {
    height: 34px;
    min-height: 34px;
    min-width: 200px;
    padding: 0 12px;
    border-radius: 8px;
    border: 1px solid var(--border-strong);
    background: var(--field-bg);
    color: var(--text);
    font: inherit;
    font-size: 0.88rem;
}

.customers-filter-form .catalog-version-select {
    width: auto;
}

@media (max-width: 560px) {
    .customers-filter-form {
        width: 100%;
    }

    .customers-filter-form .catalog-segmented,
    .customers-filter-form .catalog-version-select,
    .customers-filter-form .customers-search,
    .customers-filter-form .button {
        width: 100%;
    }

    .customers-filter-form .catalog-segmented .catalog-segment {
        flex: 1 1 0;
        min-width: 0;
    }
}

/* aans7mx roadmap-tags: unify the create-panel -> table gap with the standard
   12px section rhythm. */
.section-block > .panel + .table-shell {
    margin-top: 12px;
}

/* aj0tzb6 admin-products mobile: the 800px row forced a hidden horizontal
   scroll (only NAME+EDITION visible, caret off-screen - read as broken).
   Re-lay the row as a compact two-line card: name+status on top, editions +
   Show/Hide below, caret centered on the right. Version/date live in the
   expanded settings body context. */
@media (max-width: 560px) {
    .admin-products-head {
        display: none;
    }

    .admin-products-head,
    .admin-products-row {
        min-width: 0;
    }

    .admin-products-row {
        grid-template-columns: minmax(0, 1fr) auto 16px;
        grid-template-areas:
            "name status caret"
            "editions actions caret";
        row-gap: 6px;
    }

    .admin-products-row > .home-release-product { grid-area: name; }
    .admin-products-row > .home-release-editions { grid-area: editions; }
    .admin-products-row > :nth-child(3),
    .admin-products-row > :nth-child(4) { display: none; }
    .admin-products-row > .admin-products-status { grid-area: status; justify-self: end; }
    .admin-products-row > .admin-products-actions { grid-area: actions; justify-self: end; }
    .admin-products-row > .admin-products-caret { grid-area: caret; align-self: center; }
}
