/* Edara Extensions Portal v2.0 */
/* Auth0 SSO + Material Design 3 */

:root {
    /* Declared per theme (dark counterpart in .dark) so the browser paints its
       own widgets — scrollbars above all — to match. */
    color-scheme: light;

    /* ========================================
       MD3 Color System - Light Theme
       (Matched to EdaraPWA _theme.scss)
       ======================================== */

    /* Primary Tonal Palette */
    --primary: #00629d;
    --primary-hover: #004a78;
    --primary-container: #cfe5ff;
    --on-primary: #ffffff;
    --on-primary-container: #001d34;

    /* Secondary Tonal Palette */
    --secondary: #00658f;
    --secondary-container: #c8e6ff;
    --on-secondary: #ffffff;
    --on-secondary-container: #001e2e;

    /* Tertiary Tonal Palette */
    --tertiary: #775a00;
    --tertiary-container: #ffdf99;
    --on-tertiary: #ffffff;
    --on-tertiary-container: #251a00;

    /* Error Tonal Palette */
    --error: #ba1a1a;
    --error-container: #ffdad6;
    --on-error: #ffffff;
    --on-error-container: #410002;

    /* Success Tonal Palette */
    --success: #29823b;
    --success-container: #a8f5b0;
    --on-success: #ffffff;
    --on-success-container: #002108;

    /* Warning Tonal Palette */
    --warning: #e9a100;
    --warning-container: #ffeeba;
    --on-warning: #ffffff;
    --on-warning-container: #251a00;

    /* Surface Tokens */
    --surface: #fcfcff;
    --surface-dim: #dcdfe4;
    --surface-bright: #fcfcff;
    --surface-container-lowest: #ffffff;
    --surface-container-low: #f6f7fa;
    --surface-container: #f0f2f5;
    --surface-container-high: #eaedf1;
    --surface-container-highest: #e4e7ec;
    --surface-variant: #dee3eb;

    /* On Surface */
    --on-surface: #1a1c1e;
    --on-surface-variant: #42474e;

    /* Outline */
    --outline: #72777f;
    --outline-variant: #e0e0e0;

    /* Inverse */
    --inverse-surface: #2f3033;
    --inverse-on-surface: #f1f0f4;
    --inverse-primary: #99cbff;

    /* Background */
    --background: #f8f9fa;

    /* Header — Glassmorphic */
    --header-bg: rgba(252, 252, 255, 0.8);
    --header-text: var(--on-surface);

    /* Logo colors */
    --logo-emblem: var(--primary-hover);
    --logo-text: var(--on-surface);

    /* Typography — Dual Font */
    --font-family: 'Inter', 'Roboto', sans-serif;
    --font-headline: 'Manrope', sans-serif;


    /* Chart series — a fixed, colour-blind-validated order. Assigned to a source
       by catalog position and NEVER cycled: the set is validated for separation
       at eight slots (adjacent-pair CVD deltaE >= 8 in both modes), so a ninth
       series must fold into "Other" rather than reuse a hue. Light and dark are
       the same eight hues re-stepped for their surface, not an automatic flip. */
    --viz-1: #2a78d6;
    --viz-2: #eb6834;
    --viz-3: #1baf7a;
    --viz-4: #eda100;
    --viz-5: #e87ba4;
    --viz-6: #008300;
    --viz-7: #4a3aa7;
    --viz-8: #e34948;

    /* Layout */
    --header-height: 64px;

    /* Spacing */
    --space-none: 0;
    --space-xs: 4px;
    --space-s: 8px;
    --space-base: 16px;
    --space-m: 24px;
    --space-l: 32px;
    --space-xl: 40px;
    --space-xxl: 48px;

    /* Border radius (MD3 Shape System) */
    --radius-none: 0;
    --radius-xs: 4px;
    --radius-sm: 8px;
    --radius-md: 12px;
    --radius-lg: 16px;
    --radius-xl: 28px;
    --radius-full: 9999px;
    --radius-circle: 50%;

    /* Typography (MD3 Type Scale) */
    --typo-display-lg: 57px;
    --typo-display-md: 45px;
    --typo-display-sm: 36px;
    --typo-headline-lg: 32px;
    --typo-headline-md: 28px;
    --typo-headline-sm: 24px;
    --typo-title-lg: 22px;
    --typo-title-md: 16px;
    --typo-title-sm: 14px;
    --typo-body-lg: 16px;
    --typo-body-md: 14px;
    --typo-body-sm: 12px;
    --typo-label-lg: 14px;
    --typo-label-md: 12px;
    --typo-label-sm: 11px;
    --typo-label-xs: 10px;

    /* MD3 Elevation Shadows — Primary-tinted */
    --shadow-level0: none;
    --shadow-level1: 0 1px 4px rgba(0, 74, 120, 0.06);
    --shadow-level2: 0 8px 24px -4px rgba(0, 74, 120, 0.08);
    --shadow-level3: 0 12px 32px -4px rgba(0, 74, 120, 0.10);
    --shadow-ambient: 0 8px 24px -4px rgba(0, 0, 0, 0.04);
    --shadow-ambient-hover: 0 8px 24px -4px rgba(0, 0, 0, 0.08);
    --shadow-glow: 0 4px 12px rgba(0, 74, 120, 0.2);
    --shadow-search: 0 12px 32px -4px rgba(0, 74, 120, 0.06);
    --shadow-focus-ring: 0 0 0 2px rgba(0, 98, 157, 0.2);

    /* MD3 Motion */
    --ease-standard: cubic-bezier(0.2, 0.0, 0, 1.0);
    --ease-emphasized: cubic-bezier(0.2, 0.0, 0, 1.0);
    --duration-short4: 200ms;
    --duration-medium2: 300ms;
    --duration-long2: 500ms;

    /* Touch targets */
    --min-touch-target: 44px;
}

/* ========================================
   DARK MODE
   ======================================== */
.dark {
    /* The dark half of the :root color-scheme pair — without it the browser kept
       painting light scrollbars on the dark org list. */
    color-scheme: dark;

    --primary: #99cbff;
    --primary-hover: #67b1f4;
    --primary-container: #004a78;
    --on-primary: #003354;
    --on-primary-container: #cfe5ff;

    --secondary: #87ceff;
    --secondary-container: #004c6d;
    --on-secondary: #00344d;
    --on-secondary-container: #c8e6ff;

    --tertiary: #f7be00;
    --tertiary-container: #574500;
    --on-tertiary: #3f2e00;
    --on-tertiary-container: #ffdf99;

    --error: #ffb4ab;
    --error-container: #93000a;
    --on-error: #690005;
    --on-error-container: #ffdad6;

    --success: #8dd891;
    --success-container: #005318;
    --on-success: #003910;
    --on-success-container: #a8f5b0;

    --warning: #ffcc66;
    --warning-container: #5c4300;
    --on-warning: #3f2e00;
    --on-warning-container: #ffeeba;

    --surface: #1a1c1e;
    --surface-dim: #121416;
    --surface-bright: #383a3e;
    --surface-container-lowest: #0e1012;
    --surface-container-low: #1e2022;
    --surface-container: #282a2c;
    --surface-container-high: #323436;
    --surface-container-highest: #3d3f42;
    --surface-variant: #42474e;

    --on-surface: #e2e2e5;
    --on-surface-variant: #c2c7cf;

    --outline: #8c9199;
    --outline-variant: #3a3a3a;

    --inverse-surface: #e2e2e5;
    --inverse-on-surface: #1a1c1e;
    --inverse-primary: #00629d;

    --background: #1a1c1e;

    --header-bg: rgba(26, 28, 30, 0.8);
    --header-text: var(--on-surface);

    --logo-emblem: var(--primary);
    --logo-text: #ffffff;

    --viz-1: #3987e5;
    --viz-2: #d95926;
    --viz-3: #199e70;
    --viz-4: #c98500;
    --viz-5: #d55181;
    --viz-6: #008300;
    --viz-7: #9085e9;
    --viz-8: #e66767;
}

/* ========================================
   RESET
   ======================================== */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    -webkit-text-size-adjust: 100%;
    -webkit-tap-highlight-color: transparent;
    scroll-padding-top: var(--header-height);
}

body {
    font-family: var(--font-family);
    font-size: var(--typo-body-md);
    background: var(--background);
    color: var(--on-surface);
    min-height: 100vh;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

/* ========================================
   SAFE AREA INSETS (Notched phones)
   ======================================== */
@supports (padding: env(safe-area-inset-bottom)) {
    .app-layout {
        padding-bottom: env(safe-area-inset-bottom);
    }

    .app-header {
        padding-left: max(var(--space-base), env(safe-area-inset-left));
        padding-right: max(var(--space-base), env(safe-area-inset-right));
    }

    .login-screen {
        padding-bottom: max(var(--space-m), env(safe-area-inset-bottom));
    }
}

/* ========================================
   AUTH SCREENS (Login, Processing, Org Selector)
   ======================================== */

/* No z-index, deliberately. #mainApp is a .screen too and stays laid out beneath the
   app shell while it overlays (shell.js, z 1200) — give .screen a stacking order above
   that and mainApp covers the mounted app. The auth screens stay reachable instead by
   the shell standing down: showScreen in auth.js announces `auth:screen-shown` and
   shell.js exits on it. That also hands back body{overflow:hidden}, which an open app
   holds and which no z-index would return. */
.screen {
    min-height: 100vh;
}

.login-screen {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: var(--space-m);
    background: linear-gradient(
        180deg,
        var(--surface-container-lowest) 0%,
        var(--background) 100%
    );
}

.login-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    max-width: 400px;
    width: 100%;
    padding: var(--space-xl);
    background: var(--surface);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-level3);
    animation: cardFadeIn var(--duration-short4) var(--ease-standard);
}

.login-logo {
    width: 80px;
    height: 80px;
    margin-bottom: var(--space-m);
    border-radius: var(--radius-lg);
}

.login-title {
    font-size: var(--typo-headline-sm);
    font-weight: 700;
    font-family: var(--font-headline);
    color: var(--on-surface);
    margin-bottom: var(--space-s);
}

/* Edara brand lockup — full wordmark + subtitle (matches Stations) */
.edara-lockup {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    line-height: 1;
    text-align: start;
}
.edara-lockup-logo {
    height: 22px;
    width: auto;
    display: block;
}
/* Dark mode: the logo is a dark-gray wordmark — render it white so it reads on the dark header. */
.dark .edara-lockup-logo { filter: brightness(0) invert(1); }
.edara-lockup-sub {
    margin-inline-start: var(--lockup-indent, 36px);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: -0.01em;
    color: var(--on-surface-variant);
    margin-top: 2px;
}
.edara-lockup--login {
    margin: 8px auto 24px;
    gap: 6px;
}
.edara-lockup--login .edara-lockup-logo { height: 44px; }
.edara-lockup--login .edara-lockup-sub {
    font-size: 15px;
    font-weight: 500;
    letter-spacing: 0.01em;
    text-transform: none;
    margin-inline-start: 74px;
    margin-top: 4px;
    color: var(--on-surface-variant);
    -webkit-text-fill-color: currentColor;
    background: none;
}

.login-subtitle {
    font-size: 12px;
    font-weight: 400;
    color: var(--on-surface-variant);
    opacity: 0.75;
    line-height: 1.5;
    margin-top: var(--space-l);
    margin-bottom: var(--space-xl);
}

.login-btn {
    width: 100%;
    min-height: 48px;
    font-size: var(--typo-label-lg);
}

.login-footer {
    margin-top: var(--space-xl);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-s);
}

.social-links {
    display: flex;
    justify-content: center;
    gap: var(--space-s);
}

.social-links a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--radius-circle);
    color: var(--on-surface-variant);
    opacity: 0.5;
    text-decoration: none;
    transition: all var(--duration-short4);
}

.social-links a:hover {
    color: var(--primary);
    background: rgba(0, 0, 0, 0.08);
    opacity: 1;
}

.social-links .material-symbols-outlined {
    font-size: 16px;
}

.login-footer .copyright {
    font-size: 11px;
    color: var(--on-surface-variant);
    opacity: 0.7;
}

/* === ORG SELECTOR REDESIGN === */
.org-selector-card {
    padding: 32px 24px 24px;
}
.org-selector-icon {
    display: block;
    text-align: center;
    font-size: 40px;
    color: var(--primary);
    margin-bottom: 12px;
}
.org-selector-divider {
    height: 1px;
    background: var(--outline-variant);
    margin: 16px 0;
}
/* The login screen's subtitle spacing is generous because there it carries a full
   sentence. Here it is one email line, and that generosity read as dead space. */
.org-selector-card .login-subtitle {
    margin-top: var(--space-xs);
    margin-bottom: 0;
}
/* Filter field — the marketplace .search-box at picker scale. */
.search-box--compact {
    width: 100%;
    max-width: none;
    min-height: 40px;
    padding: var(--space-xs) var(--space-s);
    box-shadow: none;
    border: 1px solid var(--outline-variant);
}
.search-box--compact:focus-within { box-shadow: var(--shadow-focus-ring); }

.org-list {
    /* A multiple of the 55px row height, so the list never cuts a row in half. */
    --org-list-cap: min(52vh, 385px);
    width: 100%;
    display: flex;
    flex-direction: column;
    max-height: var(--org-list-cap);
    overflow-y: auto;
    /* scrollbar-color, not ::-webkit-scrollbar: once scrollbar-width is set,
       Chromium 121+ ignores the webkit pseudo-element rules. */
    scrollbar-width: thin;
    scrollbar-color: var(--outline-variant) transparent;
}
/* Held at the cap while the filter is on, so hiding rows never resizes the card. */
.org-list--fixed { height: var(--org-list-cap); }
.org-btn {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 10px 12px;
    background: none;
    border: none;
    border-left: 3px solid transparent;
    border-bottom: 1px solid var(--outline-variant);
    border-radius: 0;
    cursor: pointer;
    text-align: left;
    color: var(--on-surface);
    font-family: var(--font-family);
    transition: background 0.15s, border-color 0.15s;
}
/* display:flex beats [hidden]'s display:none, so a filtered-out row would still
   show without this. last-of-type, not last-child: the no-results <p> is the real
   last child. */
.org-btn[hidden] { display: none; }
.org-btn:last-of-type { border-bottom: none; }
.org-btn:hover, .org-btn:focus-visible {
    background: var(--surface-container-high);
    border-left-color: var(--primary);
    outline: none;
}
/* Initials tile — the only per-row visual anchor, since every org otherwise
   renders as the same word in the same weight. Hue is picked from the name. */
.org-btn-avatar {
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    border-radius: 9px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 600;
    background: var(--oa-bg);
    color: var(--oa-fg);
}
.oa-0 { --oa-bg: #e6f1fb; --oa-fg: #0c447c; }
.oa-1 { --oa-bg: #e1f5ee; --oa-fg: #085041; }
.oa-2 { --oa-bg: #eeedfe; --oa-fg: #3c3489; }
.oa-3 { --oa-bg: #faece7; --oa-fg: #712b13; }
.oa-4 { --oa-bg: #fbeaf0; --oa-fg: #72243e; }
.oa-5 { --oa-bg: #faeeda; --oa-fg: #633806; }
.dark .oa-0 { --oa-bg: #0c447c; --oa-fg: #b5d4f4; }
.dark .oa-1 { --oa-bg: #085041; --oa-fg: #9fe1cb; }
.dark .oa-2 { --oa-bg: #3c3489; --oa-fg: #cecbf6; }
.dark .oa-3 { --oa-bg: #712b13; --oa-fg: #f5c4b3; }
.dark .oa-4 { --oa-bg: #72243e; --oa-fg: #f4c0d1; }
.dark .oa-5 { --oa-bg: #633806; --oa-fg: #fac775; }
.org-btn-name {
    flex: 1;
    min-width: 0;
    font-size: 15px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.org-btn-chevron { font-size: 20px !important; color: var(--on-surface-variant); flex-shrink: 0; opacity: 1; }
.org-no-results {
    padding: 24px 8px;
    margin: 0;
    text-align: center;
    font-size: 13px;
    color: var(--on-surface-variant);
}
.org-signout-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    padding: 10px;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--on-surface-variant);
    font-size: 13px;
    font-family: var(--font-family);
    border-radius: 6px;
    transition: color 0.15s, background 0.15s;
}
.org-signout-btn:hover {
    color: var(--error);
    background: color-mix(in srgb, var(--error) 10%, transparent);
}
.org-signout-btn .material-symbols-outlined { font-size: 18px; }

/* ========================================
   EXPLORE (no-account) MODE
   Login "Explore" button, org skip link, zero-org empty state, the persistent
   sign-up banner, and the marketplace card footers.
   ======================================== */

/* Login screen: secondary "Explore without an account" under the filled sign-in button */
.login-explore-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    width: 100%;
    min-height: 44px;
    margin-top: var(--space-s);
    background: none;
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-full);
    color: var(--primary);
    font-size: var(--typo-label-lg);
    font-weight: 600;
    font-family: var(--font-family);
    cursor: pointer;
    transition: background var(--duration-short4), border-color var(--duration-short4);
}
.login-explore-btn:hover {
    background: color-mix(in srgb, var(--primary) 8%, transparent);
    border-color: var(--primary);
}
.login-explore-btn .material-symbols-outlined { font-size: 20px; }

/* Org text links: "Continue without selecting an organization" (multi-org picker) and
   "Explore the marketplace" (zero-org empty state) — the same borderless primary link. */
.org-skip-link, .org-empty-explore {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    padding: 12px;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--primary);
    font-size: 13px;
    font-weight: 600;
    font-family: var(--font-family);
    border-radius: 6px;
    transition: background var(--duration-short4);
}
/* Quieter than the shared rule above: skipping is the rare path, and as an
   accented full-width link it outshouted the org list it sits under. */
.org-skip-link {
    margin-top: var(--space-xs);
    color: var(--on-surface-variant);
    font-size: 12px;
    font-weight: 500;
}
.org-skip-link:hover, .org-empty-explore:hover { background: color-mix(in srgb, var(--primary) 8%, transparent); }
.org-skip-link .material-symbols-outlined, .org-empty-explore .material-symbols-outlined { font-size: 18px; }

/* Zero-org empty state (rendered into #organizationsList) */
.org-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-s);
    padding: var(--space-s) 0;
}
.org-empty-icon { font-size: 40px; color: var(--primary); }
.org-empty-title { font-size: 15px; font-weight: 700; color: var(--on-surface); margin: 0; }
.org-empty-sub { font-size: 13px; color: var(--on-surface-variant); margin: 0 0 var(--space-xs); line-height: 1.5; }
.org-empty-create {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    width: 100%;
    min-height: 44px;
    text-decoration: none;
    font-size: var(--typo-label-lg);
}
.org-empty-create .material-symbols-outlined { font-size: 20px; }
/* .org-empty-explore shares .org-skip-link's rules above. */

/* Persistent sign-up banner — fixed above the sticky header AND the app-shell (z 1200),
   so the primary sign-up handoff is never covered. body.explore-active offsets the
   layout by the banner height (a custom property inherited by header/shell). */
body.explore-active {
    --explore-banner-h: 44px;
    padding-top: var(--explore-banner-h);
}
body.explore-active .app-layout { min-height: calc(100vh - var(--explore-banner-h)); }
body.explore-active .app-header,
body.explore-active .ext-shell { top: var(--explore-banner-h); }
/* The shell is sized by height, not by top+bottom (see .ext-shell in shell.js), so
   offsetting `top` alone would push its full-viewport height below the fold — the
   exact fault that sizing change fixed. Take the banner off the height too. */
body.explore-active .ext-shell {
    height: calc(100vh - var(--explore-banner-h));
    height: calc(100dvh - var(--explore-banner-h));
}
/* Hidden until explore mode — single source of truth is body.explore-active (set in initApp). */
.explore-banner { display: none; }
body.explore-active .explore-banner { display: flex; }
.explore-banner {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 1300;
    height: var(--explore-banner-h, 44px);
    align-items: center;
    gap: var(--space-s);
    padding: 0 var(--space-base);
    background: var(--primary);
    color: var(--on-primary);
    font-size: 13px;
    overflow: hidden;
}
.explore-banner-icon { font-size: 18px; flex-shrink: 0; }
.explore-banner-text {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.explore-banner-cta {
    margin-inline-start: auto;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--on-primary);
    color: var(--primary);
    border: none;
    border-radius: var(--radius-full);
    padding: 6px 14px;
    font-size: 12px;
    font-weight: 700;
    font-family: var(--font-family);
    cursor: pointer;
    transition: opacity var(--duration-short4);
}
.explore-banner-cta:hover { opacity: 0.9; }
.explore-banner-cta .material-symbols-outlined { font-size: 16px; }
/* Secondary banner action (Request access / Sign out) — a quiet text link next to the
   single loud primary CTA. */
.explore-banner-secondary {
    flex-shrink: 0;
    background: none;
    border: none;
    color: inherit;
    font-family: var(--font-family);
    font-size: 12px;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
    opacity: 0.85;
    cursor: pointer;
    padding: 6px 4px;
}
.explore-banner-secondary:hover { opacity: 1; }
@media (max-width: 575px) {
    .explore-banner-text { display: none; }

}

/* Locked marketplace card (explore, no tenant): a recessive chip stating the reason
   (Sign in / Select organization / Ask your admin), not a loud filled CTA — so the eye
   lands on the actionable demo cards instead of a wall of identical buttons. */
.card-lock-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    padding: 9px 14px;
    background: var(--surface-container-high);
    color: var(--on-surface-variant);
    border: none;
    border-radius: var(--radius-sm);
    font-family: var(--font-family);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--duration-short4);
}
.card-lock-btn:hover:not([disabled]) { background: var(--surface-container-highest); color: var(--on-surface); }
.card-lock-btn[disabled] { cursor: default; opacity: 0.7; }
.card-lock-btn .material-symbols-outlined { font-size: 18px; }

/* Spinner */
@keyframes spin {
    to { transform: rotate(360deg); }
}

.spinner {
    width: 32px;
    height: 32px;
    border: 3px solid var(--outline-variant);
    border-top-color: var(--primary);
    border-radius: var(--radius-circle);
    animation: spin var(--duration-long2) linear infinite;
    margin-top: var(--space-base);
}

/* ========================================
   BUTTONS
   ======================================== */
.btn-filled {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-s);
    padding: var(--space-s) var(--space-m);
    border: none;
    border-radius: var(--radius-xl);
    background: var(--primary);
    color: var(--on-primary);
    font-size: var(--typo-label-lg);
    font-weight: 500;
    font-family: var(--font-family);
    cursor: pointer;
    transition: all var(--duration-short4) var(--ease-standard);
    min-height: var(--min-touch-target);
}

.btn-filled:hover {
    background: var(--primary-hover);
    box-shadow: var(--shadow-level1);
}

.btn-text {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-s);
    padding: var(--space-s) var(--space-base);
    border: none;
    border-radius: var(--radius-xl);
    background: transparent;
    color: var(--primary);
    font-size: var(--typo-label-lg);
    font-weight: 500;
    font-family: var(--font-family);
    cursor: pointer;
    transition: background var(--duration-short4) var(--ease-standard);
    min-height: var(--min-touch-target);
}

.btn-text:hover {
    background: rgba(0, 98, 157, 0.08);
}

/* ========================================
   MAIN APP LAYOUT
   ======================================== */
.app-layout {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background: var(--surface);
}

/* App Header */
.app-header {
    display: flex;
    align-items: center;
    height: var(--header-height);
    padding: 0 var(--space-base);
    background: var(--header-bg);
    -webkit-backdrop-filter: blur(20px);
    backdrop-filter: blur(20px);
    border-bottom: 1px solid color-mix(in srgb, var(--outline-variant) 15%, transparent);
    color: var(--header-text);
    position: sticky;
    top: 0;
    z-index: 100;
    gap: var(--space-base);
}

.header-start {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    gap: var(--space-s);
    min-width: 0;
}

.header-emblem {
    height: 24px;
    width: auto;
    flex-shrink: 0;
}

.header-title {
    font-family: var(--font-headline, 'Manrope', sans-serif);
    font-size: 16px;
    font-weight: 700;
    color: var(--on-surface);
    white-space: nowrap;
    margin: 0;
}

.brand-separator {
    opacity: 0.3;
    margin: 0 2px;
    font-weight: 300;
}

.header-divider {
    width: 1px;
    height: 20px;
    background: var(--outline-variant);
    opacity: 0.5;
    flex-shrink: 0;
}

.header-org {
    font-size: var(--typo-body-sm);
    font-weight: 500;
    color: var(--on-surface-variant);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.header-spacer {
    flex: 1;
}

.header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    flex-shrink: 0;
}


.icon-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--min-touch-target);
    height: var(--min-touch-target);
    border: none;
    border-radius: var(--radius-circle);
    background: transparent;
    cursor: pointer;
    color: var(--header-text);
    transition: background var(--duration-short4);
}

.icon-btn:hover {
    background: rgba(0, 0, 0, 0.06);
}

.dark .icon-btn:hover {
    background: rgba(255, 255, 255, 0.08);
}

.icon-btn .material-symbols-outlined {
    font-size: 22px;
}

/* User Avatar — the profile-menu trigger (a button showing the user's initials) */
.user-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: none;
    padding: 0;
    border-radius: var(--radius-circle);
    background: var(--primary-container);
    color: var(--on-primary-container);
    font-size: var(--typo-label-sm);
    font-weight: 600;
    font-family: var(--font-family);
    flex-shrink: 0;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: box-shadow var(--duration-short4);
}

.user-avatar:hover,
.profile-menu--open .user-avatar {
    box-shadow: 0 0 0 3px var(--outline-variant);
}

.user-avatar:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.dark .user-avatar {
    background: var(--primary);
    color: var(--on-primary);
}

/* ----- Profile menu — avatar-triggered dropdown (identity + org + actions).
   MD3 surface; mirrors the org-switcher menu look. Anchored to the header end
   via inset-inline-end so it flips correctly in RTL. ----- */
.profile-menu {
    position: relative;
    display: inline-flex;
}

@keyframes profile-menu-fade {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.profile-menu__panel {
    position: absolute;
    top: calc(100% + 8px);
    inset-inline-end: 0;
    min-width: 260px;
    max-width: 320px;
    background: var(--surface-container-low, var(--surface, #fff));
    border: 1px solid var(--outline-variant);
    border-radius: 16px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.08);
    padding: 8px;
    z-index: 1000;
    animation: profile-menu-fade 120ms ease-out;
}

.dark .profile-menu__panel {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.3);
}

.profile-menu__identity {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px 10px;
}

.profile-menu__avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--primary-container);
    color: var(--on-primary-container);
    font-weight: 600;
    font-size: 15px;
    flex: 0 0 auto;
}

.dark .profile-menu__avatar {
    background: var(--primary);
    color: var(--on-primary);
}

.profile-menu__id-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.profile-menu__name {
    font-size: 14px;
    font-weight: 600;
    color: var(--on-surface);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.profile-menu__email {
    font-size: 12px;
    color: var(--on-surface-variant);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.profile-menu__org {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 6px 12px;
}

.profile-menu__org-label {
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--on-surface-variant);
    opacity: 0.85;
}

.profile-menu__org-name {
    font-size: 13px;
    font-weight: 500;
    color: var(--on-surface);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.profile-menu__divider {
    height: 1px;
    background: var(--outline-variant);
    margin: 6px 4px;
}

.profile-menu__item {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 10px 12px;
    border: none;
    background: transparent;
    border-radius: 12px;
    cursor: pointer;
    color: var(--on-surface);
    font: inherit;
    font-size: 14px;
    text-align: start;
    text-decoration: none;
    transition: background 120ms ease;
}

.profile-menu__item:hover,
.profile-menu__item:focus-visible {
    background: var(--surface-container, rgba(0, 0, 0, 0.04));
    outline: none;
}

.profile-menu__item-icon {
    display: inline-flex;
    color: var(--on-surface-variant);
    flex: 0 0 auto;
}

/* Language and theme, folded in on a phone only — they duplicate header buttons that
   are still there above 575px. One wrapper, so the rows and their divider show and hide
   together; the phone block that hides those header buttons is what reveals it. */
.profile-menu__prefs {
    display: none;
}

/* ========================================
   PORTAL MAIN CONTENT
   ======================================== */
.portal-main {
    flex: 1;
    max-width: 1200px;
    width: 100%;
    margin: 0 auto;
    padding: 0 var(--space-base) var(--space-xl);
}

/* Hero Section */
.portal-hero {
    text-align: center;
    padding: var(--space-xl) var(--space-base) var(--space-l);
    background: var(--background);
}

.portal-title {
    font-size: var(--typo-display-md);
    font-weight: 800;
    font-family: var(--font-headline);
    color: var(--on-surface);
    letter-spacing: -0.02em;
    margin-bottom: var(--space-xs);
}

.portal-subtitle {
    font-size: var(--typo-body-lg);
    color: var(--on-surface-variant);
    margin-bottom: var(--space-m);
    max-width: 640px;
    margin-left: auto;
    margin-right: auto;
}

/* Search Box */
.search-box {
    display: flex;
    align-items: center;
    background: var(--surface-container-low);
    border: none;
    border-radius: var(--radius-full);
    padding: var(--space-base) var(--space-m);
    gap: var(--space-s);
    max-width: 520px;
    margin: 0 auto;
    min-height: 52px;
    box-shadow: var(--shadow-search);
    transition: box-shadow var(--duration-short4), background var(--duration-short4);
}

.search-box:focus-within {
    box-shadow: var(--shadow-search), var(--shadow-focus-ring);
    background: var(--surface-container-lowest);
}

.search-box .material-symbols-outlined {
    color: var(--on-surface-variant);
    font-size: 20px;
    flex-shrink: 0;
}

.search-box input {
    border: none;
    background: none;
    outline: none;
    font-size: var(--typo-body-md);
    width: 100%;
    color: var(--on-surface);
    font-family: var(--font-family);
}

.search-box input::placeholder {
    color: var(--on-surface-variant);
}

/* ========================================
   CATEGORIES FILTER
   ======================================== */
.categories-filter {
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    gap: var(--space-s);
    padding: var(--space-xs) var(--space-base);
    margin-bottom: var(--space-l);
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    justify-content: center;
}

.categories-filter::-webkit-scrollbar {
    display: none;
}

.category-btn {
    display: flex;
    align-items: center;
    gap: var(--space-s);
    padding: var(--space-s) var(--space-m);
    border: none;
    background: var(--surface-container-high);
    border-radius: var(--radius-full);
    cursor: pointer;
    font-size: var(--typo-label-lg);
    font-weight: 500;
    color: var(--on-surface-variant);
    transition: all var(--duration-short4);
    font-family: var(--font-family);
    white-space: nowrap;
    flex-shrink: 0;
    scroll-snap-align: start;
    min-height: 40px;
}

.category-btn:hover {
    background: var(--surface-container-highest);
    color: var(--on-surface);
}

.category-btn.active {
    background: var(--primary);
    color: var(--on-primary);
    box-shadow: var(--shadow-glow);
    font-weight: 600;
}

.category-btn .material-symbols-outlined {
    font-size: 18px;
}

.category-name {
    font-weight: 500;
}

/* ========================================
   SECTION HEADER
   ======================================== */
.section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 var(--space-base);
    margin-bottom: var(--space-base);
}

.section-header h2 {
    font-size: var(--typo-title-lg);
    font-weight: 700;
    font-family: var(--font-headline);
    color: var(--on-surface);
}

.extension-count {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    font-size: var(--typo-label-md);
    color: var(--on-surface-variant);
}

.count-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    height: 24px;
    padding: 0 6px;
    background: var(--surface-container-high);
    border-radius: var(--radius-full);
    font-size: var(--typo-label-sm);
    font-weight: 600;
    color: var(--on-surface);
}

/* ========================================
   EXTENSIONS GRID
   ======================================== */
.extensions-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-l);
    padding: 0 var(--space-base);
}

/* Card Entrance Animation */
@keyframes cardFadeIn {
    from {
        opacity: 0;
        transform: translateY(16px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Extension Card */
.extension-card {
    position: relative;
    background: var(--surface-container-lowest);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    border: none;
    box-shadow: none;
    transition: box-shadow 300ms var(--ease-standard), transform 300ms var(--ease-standard);
    opacity: 0;
    animation: cardFadeIn 400ms var(--ease-standard) forwards;
    animation-delay: calc(var(--card-index, 0) * 60ms);
}

.extension-card:hover {
    box-shadow: var(--shadow-ambient);
    transform: scale(1.02);
}

/* Card Body */
.card-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-s);
    padding: var(--space-m);
    flex: 1;
}

/* Rail pin — the same control as the one in ⌘K, so it matches it: push_pin, muted
   when the app is not in your rail, solid accent when it is. Never hidden until
   hover; on a pinned card the pin IS the answer to "is this in my rail?", and on an
   unpinned one it is the call to action — and touch has no hover to reveal it. */
.pin-btn {
    position: absolute;
    top: var(--space-s);
    inset-inline-end: var(--space-s);
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: var(--radius-circle);
    background: transparent;
    cursor: pointer;
    color: var(--on-surface-variant);
    opacity: 0.55;
    /* Deliberately NOT transitioning color. This pin's colour comes from --primary,
       which is redefined by the theme; with a transition on it the button keeps
       painting the old theme's colour after a toggle — a light-blue pin left on a
       dark card — until something else forces a recompute. The star this replaced
       never showed the bug because its active colour was a literal gold. */
    transition: opacity var(--duration-short4), background var(--duration-short4);
    z-index: 2;
}

.pin-btn:hover {
    background: var(--surface-variant);
    color: var(--on-surface);
    opacity: 1;
}

.pin-btn.active {
    color: var(--primary);
    opacity: 1;
}

/* Colour is inherited from .pin-btn.active — equal specificity to .pin-btn:hover,
   and it comes later in the cascade, so only the background needs stating here. */
.pin-btn.active:hover {
    background: color-mix(in srgb, var(--primary) 12%, transparent);
}

.pin-btn .material-symbols-outlined {
    font-size: 20px;
}

.card-header {
    display: flex;
    align-items: flex-start;
    gap: var(--space-base);
    /* Reserve room so a one-line title clears the absolutely-placed pin button */
    padding-inline-end: var(--space-l);
}

.extension-icon {
    width: 64px;
    height: 64px;
    background: color-mix(in srgb, var(--accent, var(--primary)) 10%, var(--surface-container-low));
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.extension-icon .material-symbols-outlined {
    color: var(--accent, var(--primary));
    font-size: 30px;
}

.extension-info {
    flex: 1;
    min-width: 0;
}

.extension-name {
    font-size: var(--typo-title-lg);
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--on-surface);
    margin-bottom: var(--space-xs);
}

.extension-meta {
    display: flex;
    align-items: center;
    gap: var(--space-s);
    flex-wrap: wrap;
}

.extension-category-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: var(--typo-label-sm);
    color: var(--on-surface-variant);
}

.extension-category-chip .material-symbols-outlined {
    font-size: 14px;
}

.extension-description {
    font-size: var(--typo-body-md);
    color: var(--on-surface-variant);
    line-height: 1.6;
    flex: 1;
}

.card-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding-top: var(--space-base);
    border-top: 1px solid color-mix(in srgb, var(--outline-variant) 40%, transparent);
    margin-top: auto;
}

.open-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    background: var(--primary);
    color: var(--on-primary);
    border: none;
    border-radius: var(--radius-full);
    padding: var(--space-s) var(--space-m);
    font-size: var(--typo-label-md);
    font-weight: 700;
    cursor: pointer;
    transition: all var(--duration-short4);
    font-family: var(--font-family);
    min-height: 36px;
}

.open-btn:hover {
    box-shadow: var(--shadow-glow);
}

.open-btn .material-symbols-outlined {
    font-size: 18px;
}

/* arrow_forward is directional, unlike the open_in_new it replaced for embeddable
   extensions, so it has to be mirrored in Arabic — same treatment as .product-open
   (below), which renders this identical affordance on Platform Home.
   Listed together rather than co-located per component because these buttons sit
   side by side: mirroring only the launch arrow left a connected card's arrow
   flipped next to an unmirrored one on the "Not set up" card in the same grid row,
   and the wizard's Open flipped while its own Next/Back did not.
   Scoped to the buttons, not to one glyph — .open-btn also carries play_arrow
   (explore-demo) and open_in_new (a non-embeddable extension), and mirroring a
   launch affordance is correct for those too. The footer's check_circle and
   link_off sit outside these buttons and are untouched. */
[dir="rtl"] .open-btn .material-symbols-outlined,
[dir="rtl"] .get-started-btn .material-symbols-outlined,
[dir="rtl"] .wizard-open-btn .material-symbols-outlined,
[dir="rtl"] .wizard-next-btn .material-symbols-outlined,
[dir="rtl"] .wizard-back-btn .material-symbols-outlined {
    transform: scaleX(-1);
}

/* ========================================
   EMPTY & ERROR STATES
   ======================================== */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: var(--space-xl) var(--space-base);
    color: var(--on-surface-variant);
    gap: var(--space-base);
    min-height: 30vh;
}

.empty-state .material-symbols-outlined {
    font-size: 48px;
    opacity: 0.5;
}

.empty-state p {
    font-size: var(--typo-body-lg);
    text-align: center;
}

.error-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: var(--space-xl) var(--space-base);
    color: var(--error);
    gap: var(--space-base);
}

.error-state .material-symbols-outlined {
    font-size: 48px;
}

/* ========================================
   RESPONSIVE - PHONE (up to 575px)
   ======================================== */
@media (max-width: 575px) {
    /* The header could not fit a phone: .header-start is flex-shrink:0, so when the
       lockup + org pill + four controls exceed the viewport the header did not
       compress — it overflowed, and the whole PAGE scrolled sideways (421px of
       content in 375px). Letting the start group shrink is the fix; the controls
       keep flex-shrink:0 so the 44px touch targets never squash, and the two
       flexible pieces truncate instead.

       The org pill's own cap is NOT set here — org-switcher.css loads after this
       file and re-declares that selector at equal specificity, so a copy here is
       dead. Its phone width lives with its own breakpoints. */
    .app-header {
        /* max(): keep the landscape safe-area guard from the @supports block above,
           which a bare padding-inline would have silently dropped. */
        padding-inline: max(10px, env(safe-area-inset-left)) max(10px, env(safe-area-inset-right));
    }
    .header-start { flex-shrink: 1; gap: var(--space-xs); }
    .edara-lockup { min-width: 0; }
    .edara-lockup-sub {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    #org-switcher-slot { min-width: 0; }

    /* Unified header: the crumb goes (.header-divider is hidden below already);
       the "Go to…" trigger stays — touch users have no shortcut — but collapses
       to a search icon button. */
    .hdr-crumb { display: none; }
    .hdr-goto { min-width: 0; padding: 0 9px; }
    .hdr-goto-label,
    .hdr-kbd-chip { display: none; }

    /* Header: compact for phone screens */
    :root {
        --header-height: 56px;
    }

    .header-emblem {
        height: 22px;
    }

    .header-title {
        font-size: 14px;
    }

    .header-divider {
        display: none;
    }

    .header-org {
        font-size: var(--typo-label-md);
        max-width: 100px;
    }

    .header-actions {
        gap: 0;
    }

    /* Language and theme move into the profile menu here. Measured at 375px the bar
       ran to 365px with neither the org pill nor the avatar counted, so those two
       overlapped the wordmark. What's New stays: its unread badge is the whole point
       and a notification two taps deep is not one. The org pill stays for the reason
       the app-shell keeps it too — which organization you are in is the check a
       cross-tenant mistake depends on, and it must be readable without a tap. */
    #langToggle,
    #themeToggle {
        display: none;
    }

    .profile-menu__prefs {
        display: block;
    }

    /* Login card: reduce padding for more content room */
    .login-card {
        padding: var(--space-l) var(--space-m);
    }

    .login-logo {
        width: 64px;
        height: 64px;
        margin-bottom: var(--space-base);
    }

    .login-title {
        font-size: var(--typo-title-lg);
    }

    /* Hero: tighter spacing */
    .portal-hero {
        padding: var(--space-m) var(--space-s) var(--space-base);
    }

    .portal-title {
        font-size: var(--typo-headline-md);
    }

    .portal-subtitle {
        font-size: var(--typo-body-sm);
    }

    /* Search box */
    .search-box {
        padding: var(--space-s) var(--space-base);
    }

    /* Section header */
    .section-header {
        padding: 0 var(--space-s);
    }

    .section-header h2 {
        font-size: var(--typo-title-md);
    }

    /* Main content: tighter horizontal padding */
    .portal-main {
        padding: 0 var(--space-s) var(--space-l);
    }

    /* Categories filter */
    .categories-filter {
        padding: var(--space-xs) var(--space-s);
        justify-content: flex-start;
    }

    /* Grid: reduce padding and gap */
    .extensions-grid {
        padding: 0 var(--space-s);
        gap: var(--space-s);
    }

    /* Card body: compact */
    .card-body {
        padding: var(--space-base);
    }

    .extension-icon {
        width: 40px;
        height: 40px;
    }

    .extension-icon .material-symbols-outlined {
        font-size: 20px;
    }

    .card-header {
        gap: var(--space-s);
    }
}

/* ========================================
   RESPONSIVE - TABLET (576px+)
   ======================================== */
@media (min-width: 576px) {
    .app-header {
        padding: 0 var(--space-m);
    }

    .header-emblem {
        height: 26px;
    }

    .portal-hero {
        padding: var(--space-l) var(--space-m) var(--space-m);
    }

    .extensions-grid {
        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    }
}

/* ========================================
   RESPONSIVE - DESKTOP (900px+)
   ======================================== */
@media (min-width: 900px) {
    .header-emblem {
        height: 28px;
    }

    .extensions-grid {
        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
        gap: var(--space-l);
    }
}

/* ========================================
   RESPONSIVE - LARGE (1200px+)
   ======================================== */
@media (min-width: 1200px) {
    .extensions-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* ========================================
   TOUCH DEVICE OPTIMIZATIONS
   ======================================== */
@media (hover: none) and (pointer: coarse) {
    .extension-card:hover {
        transform: none;
        box-shadow: none;
    }

    .category-btn:hover {
        background: var(--surface-container-high);
        color: var(--on-surface-variant);
    }

    .category-btn.active:hover {
        background: var(--primary);
        color: var(--on-primary);
    }

    /* Active/pressed feedback for touch */
    .extension-card:active {
        transform: scale(0.98);
    }

    .category-btn:active {
        transform: scale(0.95);
    }

    .org-btn:active {
        transform: scale(0.98);
    }

    .open-btn:active {
        opacity: 0.8;
    }
}

/* ========================================
   REDUCED MOTION
   ======================================== */
@media (prefers-reduced-motion: reduce) {
    .extension-card {
        animation: none;
        opacity: 1;
    }
}

/* ========================================
   CARD STATUS STATES
   ======================================== */

/* Loading spinner inside card footer */
.card-spinner {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    width: 100%;
    min-height: 40px;
}

.card-spinner-el {
    width: 20px;
    height: 20px;
    border-width: 2px;
    margin-top: 0;
}

/* Connected chip */
.connected-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--typo-label-md);
    font-weight: 700;
    color: var(--on-secondary-container);
    background: color-mix(in srgb, var(--secondary-container) 30%, transparent);
    border-radius: var(--radius-full);
    padding: 4px 12px;
}

.connected-chip .material-symbols-outlined {
    font-size: 8px;
    color: var(--success);
}

/* Error chip */
.error-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: var(--typo-label-md);
    font-weight: 500;
    color: var(--error);
    background: color-mix(in srgb, var(--error) 10%, transparent);
    border-radius: var(--radius-full);
    padding: 3px 10px 3px 6px;
}

.error-chip .material-symbols-outlined {
    font-size: 15px;
}

/* Coming Soon chip */
.coming-soon-chip,
.locked-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--typo-label-md);
    font-weight: 500;
    color: var(--on-surface-variant);
    background: var(--surface-variant);
    border-radius: var(--radius-full);
    padding: 4px 12px;
}

.coming-soon-chip .material-symbols-outlined,
.locked-chip .material-symbols-outlined {
    font-size: 16px;
}

.extension-card:has(.coming-soon-chip),
.extension-card:has(.locked-chip) {
    opacity: 0.7;
}

.extension-card:has(.coming-soon-chip) .extension-icon,
.extension-card:has(.coming-soon-chip) .extension-name,
.extension-card:has(.locked-chip) .extension-icon,
.extension-card:has(.locked-chip) .extension-name {
    filter: grayscale(0.4);
}

/* Row layout for connected/error footer (chip + buttons). The status chip is
   pushed to the start and the actions to the end, so the primary button lands
   on the same right edge as a lone Open button — connected or not, on any card
   width. No wrapping: the narrow workspace column would otherwise drop the
   disconnect icon to a second line and misalign the row. */
.card-footer-row {
    display: flex;
    align-items: center;
    gap: var(--space-s);
    width: 100%;
    flex-wrap: nowrap;
}

.card-footer-row > :first-child {
    margin-inline-end: auto;
}

/* ========================================
   MARKETPLACE CARD — COMPACT ANATOMY
   ========================================
   `.marketplace-card` is a variant of `.extension-card`, applied in
   renderExtensions(). It exists because three surfaces share that base class —
   this grid, the platform home's tiles, and the legacy host — so restyling the
   base rules would silently change two of them. It mirrors `.product-card`,
   which the home tiles already use for exactly this reason; naming the variant
   at the call site is what tells the next reader, from the template alone, that
   these cards have their own anatomy 400 lines further down this file.

   Cards used to size themselves to their text, so an 8-word description and a
   21-word one produced two different card heights in the same row and the grid
   stretched every sibling to the tallest. Every part is now a fixed size —
   including two reserved description lines whether or not the copy fills them —
   so equal height falls out of the anatomy instead of being imposed by a magic
   pixel value that the next font change would break. */
.marketplace-card .extension-icon {
    width: 48px;
    height: 48px;
}

.marketplace-card .extension-icon .material-symbols-outlined {
    font-size: 24px;
}

/* One line, always. At 64px the icon left the title too little room and
   "Price Checker", "Import Manager" and "External Share" all wrapped — the most
   visible unpolished detail on the page. min-width:0 is what lets the ellipsis
   happen at all: a flex item defaults to min-width:auto and refuses to shrink
   below its content. */
.marketplace-card .extension-info {
    min-width: 0;
}

.marketplace-card .extension-name {
    font-size: var(--typo-title-md);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Exactly two lines, reserved even when the copy is shorter. `flex: none` undoes
   the base rule's `flex: 1`, which would otherwise let the description claim the
   card's free space and defeat the fixed anatomy.

   The line box is pinned in PIXELS rather than left at the inherited 1.6 ratio,
   and 50px is deliberately not the 48px that two 24px lines imply: Arabic renders
   through the Cairo face, which overshoots its line box by about a pixel, and at
   exactly 48 that pixel is clipped off the descenders of the second line on every
   Arabic card. A fixed line box plus the spare pixel makes both scripts agree. */
.marketplace-card .extension-description {
    flex: none;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 24px;
    min-height: 50px;
}

/* Normalises the seven footer states to one height, so a card doesn't resize as
   its status resolves and two cards in different states still line up. 44px is
   the measured height of .card-lock-btn, the tallest of the footer controls;
   .open-btn's 36px and the loading spinner's 40px both fit inside it.

   Deliberately a literal and NOT var(--min-touch-target), which is also 44px
   today. That would be a coincidence of value, not a dependency: .card-lock-btn
   never reads the token — its height is emergent from `padding: 9px 14px` plus
   its content — so an accessibility bump of the touch-target minimum would grow
   this floor while leaving the button it is supposed to clear exactly where it
   is, opening dead space under every footer.
   (Alignment comes from the base .card-footer rule.) */
.marketplace-card .card-footer {
    min-height: calc(44px + var(--space-base));
}

/* The card is focusable so its details are reachable without a mouse; give that
   focus somewhere visible to land. :focus-visible, not :focus, so a mouse click
   does not leave a ring behind on every card the user merely pressed. */
.marketplace-card {
    cursor: pointer;
    /* Default slot: everything starts in "Discover" and groupConnectedFirst() lifts
       the connected ones out once the statuses are in. Ordering is done with `order`
       rather than by moving nodes — see that function for why. */
    order: 3;
}

/* Section headings for the connected-first grouping. Full-row grid items, so each
   one sits above its own group instead of beside a card. */
.grid-section-head {
    grid-column: 1 / -1;
    font-size: var(--typo-title-md);
    font-weight: 600;
    color: var(--on-surface-variant);
    align-self: end;
}

.grid-section-head[data-group="yours"] { order: 0; }
.grid-section-head[data-group="discover"] { order: 2; }

.marketplace-card:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* ========================================
   EXTENSION DETAIL SHEET
   ========================================
   The long version of a card. It exists because the card clamps its description
   to two lines — without somewhere for the fuller text to live, shortening the
   copy would lose it rather than move it. */
/* The scrim is the shared `.dialog-overlay` (toggled by `.open`), not a second one of
   its own — the disconnect dialog and team.js's modal already use it, and a parallel
   scrim would be one more place to change the dim or the fade.

   Only THIS instance is lifted, by id: raising `.dialog-overlay` itself would move the
   disconnect dialog and team.js's modal with it, which nobody asked for. (The wizard
   is not affected either way — it has its own `.wizard-overlay`.) An id is used
   because it beats `.dialog-overlay` outright, so the rule can't be quietly undone by
   either block moving in the file. 1400 clears the explore banner at 1300, which is
   fixed-position and was drawing over the sheet. */
#detailScrim { z-index: 1400; }

.detail-sheet {
    position: fixed;
    inset-block: 0;
    inset-inline-end: 0;
    width: min(420px, 100vw);
    z-index: 1401;   /* directly above its scrim */
    display: flex;
    flex-direction: column;
    background: var(--surface-container-lowest);
    box-shadow: var(--shadow-ambient);
    overflow-y: auto;
}

/* Load-bearing, despite looking like a browser default: the rule above sets
   `display: flex` from the author stylesheet, which outranks the UA stylesheet's
   `[hidden] { display: none }`. Without this the sheet would never hide. */
.detail-sheet[hidden] { display: none; }

/* The feedback SDK's launcher is `position: fixed` at `inset-inline-end: 24px` with
   z-index 99990 — the same corner the sheet occupies, in both directions, and far
   above anything this stylesheet could outrank. It was landing on top of the sheet's
   primary button. Hidden while the sheet is open rather than out-stacked: the sheet
   is aria-modal, so a control floating over it was not just overlapping, it stayed
   clickable through the scrim. Comes back when the sheet closes. */
body.sheet-open #ext-fb-fab { display: none; }
/* Same reason, for as long as an extension is mounted: the FAB is fixed at
   z-index 99990 and the shell is 1200, so ours floats over the extension's own
   frame — on a phone, directly on top of whatever that app pins to its bottom.
   Every embeddable extension ships this same SDK, so its own FAB is the one that
   belongs there. Set in shell.js on mount/unmount. */
body.ext-shell-open #ext-fb-fab { display: none; }

.detail-head {
    display: flex;
    align-items: flex-start;
    gap: var(--space-base);
    padding: var(--space-m);
    border-bottom: 1px solid var(--outline-variant);
}

.detail-titles { flex: 1; min-width: 0; }

.detail-titles h2 {
    font-family: var(--font-headline);
    font-size: var(--typo-title-lg);
    font-weight: 700;
}

.detail-meta {
    margin-top: var(--space-xs);
    font-size: var(--typo-body-md);
    color: var(--on-surface-variant);
}

.detail-body {
    padding: var(--space-m);
    display: flex;
    flex-direction: column;
    gap: var(--space-m);
    flex: 1;
}

/* No clamp here — this is the surface that exists to show the whole thing. */
.detail-desc {
    font-size: var(--typo-body-lg);
    line-height: 1.7;
    color: var(--on-surface-variant);
}

.detail-section h3 {
    font-size: var(--typo-label-md);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--on-surface-variant);
    margin-bottom: var(--space-s);
}

.detail-steps { list-style: none; display: flex; flex-direction: column; gap: var(--space-s); }

.detail-step {
    display: flex;
    align-items: center;
    gap: var(--space-s);
    padding: var(--space-s) var(--space-base);
    border-radius: var(--radius-sm);
    background: var(--surface-container-low);
    font-size: var(--typo-body-md);
}

.detail-step .material-symbols-outlined {
    font-size: 18px;
    color: var(--outline);
}

/* Link out to the extension's own user guide. It carries .detail-step as well, so
   the row IS a step row rather than a copy of one that drifts the next time that
   rule's padding changes — the sheet reads as one list of things about this app.
   Only what a link needs on top of it lives here. */
.detail-guide-link { color: var(--on-surface); text-decoration: none; }

.detail-guide-link:hover { background: var(--surface-container); }

/* Pushed to the trailing edge, and it flips with the writing direction. */
.detail-guide-go { margin-inline-start: auto; }

/* Sticks to the bottom so the primary action stays reachable on a long sheet.
   margin-top:auto is overridden — the flex column already positions this. */
.detail-foot {
    position: sticky;
    bottom: 0;
    margin-top: 0;
    padding: var(--space-base) var(--space-m);
    background: var(--surface-container-lowest);
    border-top: 1px solid var(--outline-variant);
}

@media (max-width: 600px) {
    .detail-sheet {
        inset-block-start: auto;
        width: 100vw;
        max-height: 88vh;
        border-start-start-radius: var(--radius-lg);
        border-start-end-radius: var(--radius-lg);
    }
}

/* The "not set up" status word. Deliberately plain text, not a filled chip like
   .connected-chip — it reports the absence of a state, and giving it the same
   visual weight as "Connected" would make every un-set-up card shout. */
.status-chip {
    font-size: var(--typo-label-md);
    font-weight: 600;
    color: var(--on-surface-variant);
}

/* Get Started button */
.get-started-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    background: var(--primary-container);
    color: var(--on-primary-container);
    border: none;
    border-radius: var(--radius-md);
    padding: 12px var(--space-m);
    font-size: var(--typo-body-md);
    font-weight: 700;
    cursor: pointer;
    transition: all var(--duration-short4);
    font-family: var(--font-family);
    min-height: 44px;
    width: 100%;
}

.get-started-btn:hover {
    background: var(--primary);
    color: var(--on-primary);
}

.get-started-btn .material-symbols-outlined {
    font-size: 18px;
}

/* Retry button */
.retry-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    color: var(--error);
    background: transparent;
    border: 1px solid var(--error);
    border-radius: var(--radius-full);
    padding: 5px var(--space-base);
    font-size: var(--typo-label-lg);
    font-weight: 500;
    cursor: pointer;
    font-family: var(--font-family);
    min-height: 40px;
    transition: background var(--duration-short4);
}

.retry-btn:hover {
    background: color-mix(in srgb, var(--error) 8%, transparent);
}

.retry-btn .material-symbols-outlined {
    font-size: 16px;
}

/* Disconnect icon button (surface variant) */
.icon-btn-surface {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: none;
    border-radius: var(--radius-circle);
    background: transparent;
    cursor: pointer;
    color: var(--on-surface-variant);
    transition: background var(--duration-short4);
    font-family: var(--font-family);
    flex-shrink: 0;
}

.icon-btn-surface:hover {
    background: var(--surface-container-high);
}

.icon-btn-surface .material-symbols-outlined {
    font-size: 18px;
    pointer-events: none;
}

/* Small inline spinner for buttons */
.btn-spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid rgba(255,255,255,0.4);
    border-top-color: #ffffff;
    border-radius: var(--radius-circle);
    animation: spin var(--duration-long2) linear infinite;
    vertical-align: middle;
    margin-right: 4px;
}

/* ========================================
   DISCONNECT DIALOG
   ======================================== */
.dialog-overlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 400;
    background: rgba(0, 0, 0, 0.45);
    align-items: center;
    justify-content: center;
    padding: var(--space-base);
    animation: fadeIn var(--duration-short4) var(--ease-standard);
    will-change: opacity;
}

.dialog-overlay.open {
    display: flex;
}

.dialog-panel {
    background: var(--surface);
    border-radius: var(--radius-xl);
    padding: var(--space-xl) var(--space-l);
    max-width: 400px;
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-base);
    box-shadow: var(--shadow-level3);
    animation: cardFadeIn var(--duration-short4) var(--ease-standard);
}

.dialog-icon {
    width: 56px;
    height: 56px;
    border-radius: var(--radius-circle);
    background: color-mix(in srgb, var(--error) 12%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.dialog-icon .material-symbols-outlined {
    font-size: 28px;
    color: var(--error);
}

.dialog-title {
    font-size: var(--typo-title-lg);
    font-weight: 600;
    color: var(--on-surface);
}

.dialog-body {
    font-size: var(--typo-body-md);
    color: var(--on-surface-variant);
    line-height: 1.6;
}

.dialog-error {
    display: none;
    width: 100%;
    font-size: var(--typo-body-sm);
    color: var(--error);
    background: color-mix(in srgb, var(--error) 8%, transparent);
    border-radius: var(--radius-sm);
    padding: var(--space-s) var(--space-base);
    text-align: left;
}

.dialog-actions {
    display: flex;
    gap: var(--space-s);
    justify-content: flex-end;
    width: 100%;
    margin-top: var(--space-s);
}

/* Danger button variant */
.btn-danger {
    background: var(--error);
}

.btn-danger:hover {
    background: var(--on-error-container);
}

/* ========================================
   ONBOARDING WIZARD
   ======================================== */
@keyframes wizardSlideUp {
    from {
        opacity: 0;
        transform: translateY(40px) scale(0.97);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

@keyframes fadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.wizard-overlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 300;
    background: rgba(0, 0, 0, 0.5);
    align-items: center;
    justify-content: center;
    padding: var(--space-base);
    animation: fadeIn var(--duration-short4) var(--ease-standard);
    will-change: opacity;
}

.wizard-overlay.open {
    display: flex;
}

.wizard-panel {
    background: var(--surface);
    border-radius: var(--radius-xl);
    width: 100%;
    max-width: 520px;
    max-height: 90vh;
    overflow-y: auto;
    position: relative;
    box-shadow: var(--shadow-level3);
    animation: wizardSlideUp var(--duration-medium2) var(--ease-emphasized);
    will-change: opacity, transform;
}

.wizard-close-btn {
    position: absolute;
    top: var(--space-s);
    right: var(--space-s);
    z-index: 10;
    color: var(--on-surface-variant);
}

.wizard-close-btn:hover {
    background: var(--surface-container-high);
}

.wizard-content {
    padding: var(--space-xl) var(--space-l) var(--space-l);
}

/* Progress indicator */
.wizard-progress {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    margin-bottom: var(--space-l);
}

.wizard-progress-step {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}

.wizard-progress-dot {
    width: 28px;
    height: 28px;
    border-radius: var(--radius-circle);
    border: 2px solid var(--outline-variant);
    background: var(--surface);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--typo-label-sm);
    font-weight: 600;
    color: var(--on-surface-variant);
    transition: all var(--duration-short4);
}

.wizard-progress-dot .material-symbols-outlined {
    font-size: 15px;
}

.wizard-progress-step.active .wizard-progress-dot {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--on-primary);
}

.wizard-progress-step.done .wizard-progress-dot {
    background: var(--success);
    border-color: var(--success);
    color: var(--on-success);
}

.wizard-progress-label {
    font-size: var(--typo-label-sm);
    color: var(--on-surface-variant);
    white-space: nowrap;
}

.wizard-progress-step.active .wizard-progress-label {
    color: var(--primary);
    font-weight: 500;
}

.wizard-progress-step.done .wizard-progress-label {
    color: var(--success);
}

.wizard-progress-line {
    height: 2px;
    flex: 1;
    min-width: 24px;
    background: var(--outline-variant);
    margin-bottom: 18px; /* align with dots, not labels */
    transition: background var(--duration-short4);
}

.wizard-progress-line.done {
    background: var(--success);
}

/* Wizard hero (welcome / complete) */
.wizard-hero {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-base);
    margin-bottom: var(--space-l);
}

.wizard-ext-icon {
    width: 72px;
    height: 72px;
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--accent, var(--primary)) 15%, var(--surface-container));
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.wizard-ext-icon .material-symbols-outlined {
    font-size: 36px;
    color: var(--accent, var(--primary));
}

.wizard-success-icon {
    width: 72px;
    height: 72px;
    border-radius: var(--radius-circle);
    background: color-mix(in srgb, var(--success) 15%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
}

.wizard-success-icon .material-symbols-outlined {
    font-size: 40px;
    color: var(--success);
}

.wizard-title {
    font-size: var(--typo-headline-sm);
    font-weight: 700;
    font-family: var(--font-headline);
    color: var(--on-surface);
    text-align: center;
}

.wizard-subtitle {
    font-size: var(--typo-body-md);
    color: var(--on-surface-variant);
    line-height: 1.6;
    text-align: center;
    max-width: 380px;
    margin: 0 auto;
}

/* Wizard actions row */
.wizard-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-s);
    margin-top: var(--space-l);
}

.wizard-actions-setup {
    justify-content: flex-start;
    margin-top: var(--space-base);
}

.wizard-next-btn,
.wizard-open-btn {
    min-width: 140px;
}

.wizard-back-btn {
    color: var(--on-surface-variant);
}

/* Inline error message */
.wizard-inline-error {
    font-size: var(--typo-body-sm);
    color: var(--error);
    margin-top: var(--space-xs);
}

/* Mode selection */
.mode-options {
    display: flex;
    flex-direction: column;
    gap: var(--space-s);
    margin-top: var(--space-base);
}

.mode-option {
    display: flex;
    align-items: center;
    gap: var(--space-base);
    padding: var(--space-base);
    border: 2px solid var(--outline-variant);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--duration-short4);
    position: relative;
}

.mode-option input[type="radio"] {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.mode-option:hover {
    border-color: var(--outline);
    background: var(--surface-container-low);
}

.mode-option.selected {
    border-color: var(--primary);
    background: color-mix(in srgb, var(--primary) 6%, transparent);
}

.mode-option-icon {
    font-size: 24px;
    color: var(--on-surface-variant);
    flex-shrink: 0;
}

.mode-option.selected .mode-option-icon {
    color: var(--primary);
}

.mode-option-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
}

.mode-option-label {
    font-size: var(--typo-body-md);
    font-weight: 500;
    color: var(--on-surface);
}

.mode-option-desc {
    font-size: var(--typo-body-sm);
    color: var(--on-surface-variant);
    line-height: 1.4;
}

.mode-option-check {
    font-size: 20px;
    color: var(--primary);
    opacity: 0;
    transition: opacity var(--duration-short4);
    flex-shrink: 0;
}

.mode-option.selected .mode-option-check {
    opacity: 1;
}

/* Setup steps list */
.setup-steps-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-s);
    margin-top: var(--space-base);
}

.setup-step-card {
    display: flex;
    align-items: center;
    gap: var(--space-base);
    padding: var(--space-base);
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-md);
    background: var(--surface-container-low);
    transition: border-color var(--duration-short4), background var(--duration-short4);
}

.setup-step-card.step-loading {
    background: var(--surface-container);
}

.setup-step-card.step-success {
    border-color: var(--success);
    background: color-mix(in srgb, var(--success) 6%, transparent);
}

.setup-step-card.step-error {
    border-color: var(--error);
    background: color-mix(in srgb, var(--error) 6%, transparent);
}

.setup-step-icon {
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    position: relative;
}

.setup-step-icon .spinner {
    width: 20px;
    height: 20px;
    border-width: 2px;
    margin: 0;
}

.setup-step-pending-icon {
    font-size: 22px;
    color: var(--on-surface-variant);
}

.setup-step-success-icon {
    font-size: 22px;
    color: var(--success);
}

.setup-step-error-icon {
    font-size: 22px;
    color: var(--error);
}

.setup-step-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
}

.setup-step-label {
    font-size: var(--typo-body-md);
    font-weight: 500;
    color: var(--on-surface);
}

.setup-step-msg {
    font-size: var(--typo-body-sm);
    color: var(--error);
    line-height: 1.4;
}

.setup-step-retry {
    font-size: var(--typo-label-md);
    color: var(--error);
    min-height: 32px;
    padding: 4px var(--space-s);
    flex-shrink: 0;
}

.setup-step-retry .material-symbols-outlined {
    font-size: 14px;
}

/* Wizard step-level subtitle (mode + setup steps) */
.wizard-step-mode .wizard-title,
.wizard-step-setup .wizard-title {
    text-align: left;
    margin-bottom: var(--space-xs);
}

.wizard-step-mode .wizard-subtitle,
.wizard-step-setup .wizard-subtitle {
    text-align: left;
    margin: 0;
}

/* ========================================
   WIZARD RESPONSIVE
   ======================================== */
@media (max-width: 575px) {
    .wizard-panel {
        max-height: 95vh;
        border-radius: var(--radius-lg);
    }

    .wizard-content {
        padding: var(--space-l) var(--space-base) var(--space-base);
    }

    .wizard-title {
        font-size: var(--typo-title-lg);
    }

    .wizard-progress-label {
        font-size: 10px;
    }

    .wizard-progress-line {
        min-width: 16px;
    }

    .dialog-panel {
        padding: var(--space-l) var(--space-base);
    }
}

@media (prefers-reduced-motion: reduce) {
    .wizard-panel {
        animation: none;
    }

    .dialog-overlay,
    .wizard-overlay {
        animation: none;
    }
}

/* Login language toggle — subtle pill at bottom of login footer */
.login-lang-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 12px auto 0;
    padding: 6px 14px;
    border: none;
    border-radius: 999px;
    background: transparent;
    cursor: pointer;
    color: var(--on-surface-variant, #49454f);
    opacity: 0.7;
    transition: opacity 0.2s, background 0.2s;
}
.login-lang-toggle:hover {
    opacity: 1;
    background: rgba(0, 0, 0, 0.05);
}
.dark .login-lang-toggle:hover {
    background: rgba(255, 255, 255, 0.08);
}

/* Language toggle — AR | EN text label */
.lang-toggle-label {
    font-family: var(--font-family);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.3px;
    white-space: nowrap;
}
[dir="rtl"] .lang-toggle-label { direction: ltr; }
[dir="rtl"] .login-lang-toggle {
    right: auto;
    left: var(--space-base, 16px);
}

/* ========================================
   RTL LAYOUT OVERRIDES — [dir="rtl"]
   Applied automatically when Arabic language is active.
   ======================================== */

[dir="rtl"] {
    --font-family: 'Cairo', sans-serif;
    --font-headline: 'Cairo', sans-serif;
}

[dir="rtl"] body,
[dir="rtl"] input,
[dir="rtl"] button,
[dir="rtl"] select,
[dir="rtl"] textarea {
    font-family: 'Cairo', sans-serif;
    font-weight: 500;
    line-height: 1.7;
    letter-spacing: 0;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

[dir="rtl"] .material-symbols-outlined {
    direction: ltr;
}

/* Organization selector */
[dir="rtl"] .org-btn {
    border-left: none;
    border-right: 3px solid transparent;
    text-align: right;
}
[dir="rtl"] .org-btn:hover, [dir="rtl"] .org-btn:focus {
    border-right-color: var(--primary);
    border-left-color: transparent;
}
[dir="rtl"] .org-btn-chevron { transform: scaleX(-1); }
[dir="rtl"] .org-signout-btn { font-weight: 600; }

/* Dialog error text */
[dir="rtl"] .dialog-error {
    text-align: right;
}

/* Wizard titles */
[dir="rtl"] .wizard-step-mode .wizard-title,
[dir="rtl"] .wizard-step-setup .wizard-title,
[dir="rtl"] .wizard-step-mode .wizard-subtitle,
[dir="rtl"] .wizard-step-setup .wizard-subtitle {
    text-align: right;
}

/* Retry button */
[dir="rtl"] .retry-btn {
    margin-left: 0;
    margin-right: auto;
}

/* Dialog actions — keep flex-end but flip */
[dir="rtl"] .dialog-actions {
    justify-content: flex-start;
}

/* What's New bell — header unread dot */
.wn-bell {
    position: relative;
}

/* The megaphone points somewhere, so it mirrors — the same rule this file already
   applies to the up-link chevron and the wizard arrows. The bell it replaced was
   symmetric, which is why no rule existed for this control before.
   Only the GLYPH flips: .wn-bell-badge is a sibling positioned with inset-inline-end,
   which already moves it to the logical corner. Flipping the button instead would
   double-move the dot, to the wrong one. */
[dir="rtl"] .wn-bell .material-symbols-outlined {
    transform: scaleX(-1);
}
.wn-bell-badge {
    position: absolute;
    top: 7px;
    inset-inline-end: 7px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--error);
    border: 2px solid var(--surface);
    pointer-events: none;
}
.wn-bell-badge[hidden] {
    display: none;
}

/* ============================================
   WHAT'S NEW VIEW (#whatsNewMain)
   The cross-extension changelog. Lived in a <style> block in whats-new.html
   until 2026-08-05, when the page became a view inside the shell — it is here
   rather than injected by whats-new-view.js because CSS-in-JS is what keeps
   style-src pinned to 'unsafe-inline' (see security-headers.conf).
   Hero and back-link reuse .portal-hero / .portal-title / .mp-uplink; only the
   feed's own layout lives here.
   ============================================ */
/* The explore banner says "you're exploring Edara with sample data". What's New is the
   real, public changelog — identical for every visitor, no tenant data in it — so that
   claim would be a lie, and an anonymous deep link to /whats-new enters explore mode
   precisely so the page stays readable without an account. Suppressing the banner alone
   is not enough: body.explore-active also reserves space for it, which would leave a gap.
   Zeroing the VARIABLE rather than each offset it feeds is what keeps this from rotting —
   every rule keyed off --explore-banner-h (body padding, .app-layout min-height,
   .app-header top, .ext-shell top and height) follows, including ones added later.
   body.explore-active itself stays set, so leaving the view restores everything. */
body.wn-view-active .explore-banner { display: none; }
body.wn-view-active.explore-active { --explore-banner-h: 0px; }

.wn-layout {
    display: flex;
    align-items: flex-start;
    gap: 32px;
    margin-top: 24px;
}

/* Extension filter — a sticky rail beside the feed on desktop. */
.wn-sidebar {
    position: sticky;
    top: 84px;
    flex: 0 0 232px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.wn-sidebar-title {
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--on-surface-variant);
    padding: 0 12px 8px;
}
.wn-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    text-align: start;
    cursor: pointer;
    padding: 9px 12px;
    border: none;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--on-surface-variant);
    font-size: 14px;
    font-weight: 500;
    transition: background var(--duration-short4), color .15s;
}
.wn-nav-item:hover {
    background: var(--surface-container);
}
.wn-nav-item[aria-pressed="true"] {
    background: var(--primary-container);
    color: var(--on-primary-container);
    font-weight: 600;
}
.wn-nav-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}
.wn-nav-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.wn-nav-count {
    margin-inline-start: auto;
    font-size: 12px;
    opacity: .65;
    font-variant-numeric: tabular-nums;
}

/* Feed */
.wn-content {
    flex: 1 1 auto;
    min-width: 0;
}
.wn-list {
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.wn-card {
    display: flex;
    gap: 16px;
    background: var(--surface-container-low);
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-lg);
    padding: 18px 20px;
    box-shadow: var(--shadow-ambient);
}
.wn-card-media {
    flex-shrink: 0;
    width: 240px;
    max-width: 38%;
}
.wn-card-media img {
    width: 100%;
    height: auto;
    border-radius: var(--radius-md);
    display: block;
    border: 1px solid var(--outline-variant);
    cursor: zoom-in;
    transition: transform .12s;
}
.wn-card-media img:hover {
    transform: scale(1.015);
}
.wn-card-body {
    min-width: 0;
    flex: 1;
}
.wn-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}
.wn-ext {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--on-surface-variant);
}
.wn-ext-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
}
.wn-badge {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: 2px 8px;
    border-radius: var(--radius-full);
}
.wn-badge--feature {
    background: var(--primary-container);
    color: var(--on-primary-container);
}
.wn-badge--improvement {
    background: color-mix(in srgb, #2E7D32 18%, transparent);
    color: #2E7D32;
}
.wn-badge--fix {
    background: color-mix(in srgb, #ED6C02 18%, transparent);
    color: #ED6C02;
}
.dark .wn-badge--improvement {
    color: #95d39a;
}
.dark .wn-badge--fix {
    color: #ffb74d;
}
.wn-date {
    font-size: 12px;
    color: var(--on-surface-variant);
    margin-inline-start: auto;
}
.wn-card-title {
    font-size: 17px;
    font-weight: 600;
    color: var(--on-surface);
    margin: 0 0 6px;
    line-height: 1.35;
}
.wn-card-text {
    font-size: 14px;
    color: var(--on-surface-variant);
    margin: 0;
    line-height: 1.6;
}

/* Click-to-expand lightbox for demo media */
.wn-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(16px, 4vw, 48px);
    background: rgba(0, 0, 0, .82);
    cursor: zoom-out;
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    animation: wn-fade .12s ease;
}
.wn-lightbox img {
    max-width: min(1100px, 96vw);
    max-height: 92vh;
    border-radius: var(--radius-md);
    box-shadow: 0 24px 64px rgba(0, 0, 0, .5);
}
.wn-lightbox-close {
    position: absolute;
    top: 16px;
    inset-inline-end: 20px;
    width: 40px;
    height: 40px;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, .15);
    color: #fff;
    font-size: 22px;
    cursor: pointer;
}
.wn-lightbox-close:hover {
    background: rgba(255, 255, 255, .28);
}
@keyframes wn-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Per-topic reactions (negative / neutral / positive) + optional inline comment */
.wn-reactions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 14px;
    flex-wrap: wrap;
}
.wn-react-prompt {
    font-size: 13px;
    color: var(--on-surface-variant);
    margin-inline-end: 2px;
}
.wn-react-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 36px;
    padding: 2px 10px;
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-full);
    background: transparent;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: background .15s, border-color .15s, transform .12s;
}
.wn-react-btn:hover {
    background: var(--surface-container);
}
.wn-react-btn.is-active {
    background: var(--primary-container);
    border-color: var(--primary);
    transform: scale(1.06);
}
.wn-comment {
    display: flex;
    gap: 8px;
    margin-top: 10px;
    align-items: center;
}
.wn-comment-input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 8px 12px;
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--on-surface);
    font-size: 14px;
    font-family: inherit;
}
.wn-comment-input:focus {
    outline: none;
    border-color: var(--primary);
}
.wn-comment-send {
    flex-shrink: 0;
    padding: 8px 16px;
    border: none;
    border-radius: var(--radius-full);
    background: var(--primary);
    color: var(--on-primary);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}
.wn-comment-send:disabled {
    opacity: .6;
    cursor: default;
}
.wn-comment-thanks {
    margin-top: 10px;
    font-size: 13px;
    font-weight: 500;
    color: var(--success);
}

.wn-empty,
.wn-loading {
    text-align: center;
    color: var(--on-surface-variant);
    padding: 64px 0;
}
.wn-footer {
    text-align: center;
    color: var(--on-surface-variant);
    font-size: 12px;
    margin-top: 48px;
}

/* Stack the filter above the feed on narrow viewports — a horizontal chip row. */
@media (max-width: 820px) {
    .wn-layout {
        flex-direction: column;
        gap: 16px;
    }
    .wn-sidebar {
        position: static;
        flex-basis: auto;
        flex-direction: row;
        flex-wrap: nowrap;
        overflow-x: auto;
        gap: 8px;
        padding-bottom: 4px;
        -webkit-overflow-scrolling: touch;
    }
    .wn-sidebar-title {
        display: none;
    }
    .wn-nav-item {
        width: auto;
        white-space: nowrap;
        border: 1px solid var(--outline-variant);
        border-radius: var(--radius-full);
        padding: 7px 14px;
    }
    .wn-nav-count {
        display: none;
    }
}

@media (max-width: 640px) {
    .wn-card {
        flex-direction: column;
    }
    .wn-card-media {
        width: 100%;
        max-width: 100%;
    }
    .wn-date {
        margin-inline-start: 0;
    }
}

/* ============================================
   Platform Home (portal.edara.io)
   Reuses .portal-main / .portal-hero / .extension-card /
   .coming-soon-chip — only the deltas live here.
   ============================================ */
.platform-hero {
    text-align: start;
}

.platform-hero .portal-subtitle {
    margin-inline: 0;
}

.products-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--space-m);
}

.product-card {
    padding: var(--space-m);
    gap: var(--space-s);
}

.product-card[role="button"] {
    cursor: pointer;
}

.product-icon {
    width: 56px;
    height: 56px;
}

.product-name {
    font-size: var(--typo-title-lg);
    font-weight: 700;
    color: var(--on-surface);
    display: flex;
    align-items: center;
    gap: var(--space-s);
}

.product-count {
    font-size: 12px;
    font-weight: 700;
    background: color-mix(in srgb, var(--accent, var(--primary)) 15%, var(--surface-container-low));
    color: var(--accent, var(--primary));
    border-radius: var(--radius-full);
    padding: 2px 8px;
}

.product-tagline {
    font-size: var(--typo-body-md);
    color: var(--on-surface-variant);
    flex: 1;
}

.product-open {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-weight: 600;
    color: var(--accent, var(--primary));
}

.product-open .material-symbols-outlined {
    font-size: 18px;
}

[dir="rtl"] .product-open .material-symbols-outlined {
    transform: scaleX(-1);
}

/* .locked-chip shares the coming-soon treatment: both mean "here, but not now",
   so a closed card reads as closed rather than broken. */
.product-card .coming-soon-chip,
.product-card .locked-chip {
    align-self: flex-start;
}

/* Platform host: the header brand is the up-affordance. In the marketplace view
   it's clickable (up to the platform home); on the home there's nowhere up to go.
   The level crumb itself is a standalone element after the org pill — see the
   UNIFIED HEADER section at the end of this file. */
.platform-host .app-header .edara-lockup {
    flex-direction: row;
    align-items: center;
    gap: 8px;
    padding: 5px 10px;
    margin-inline-start: -10px;
    border-radius: var(--radius-full);
    transition: background var(--duration-short4);
}

html.platform-host body:not(.platform-home-active) .app-header .edara-lockup {
    cursor: pointer;
}

html.platform-host body:not(.platform-home-active) .app-header .edara-lockup:hover {
    background: var(--surface-container-low);
}

/* View transitions (platform host): a short fade-rise when moving between the
   platform home and the marketplace, so level changes read as navigation. */
@keyframes viewFadeIn {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

html.platform-host #platformMain,
html.platform-host #marketplaceMain,
html.platform-host .ext-shell {
    animation: viewFadeIn 240ms var(--ease-standard);
}

@media (prefers-reduced-motion: reduce) {
    html.platform-host #platformMain,
    html.platform-host #marketplaceMain,
    html.platform-host .ext-shell {
        animation: none;
    }
}

/* Platform-host login: brand is just "Edara" — no "Extensions" sub-line */
.platform-host .edara-lockup--login .edara-lockup-sub {
    display: none;
}

/* ========================================
   MARKETPLACE WORKSPACE (portal.edara.io)
   On the platform host the marketplace reads as a nested product workspace — a
   left category rail + results column, the big hero demoted to a slim search
   toolbar, and an up-link to the platform home. The two layout wrappers are
   display:contents by default, so extensions.edara.io renders the classic
   single-column marketplace with zero change.
   ======================================== */
.mp-body,
.mp-results {
    display: contents;
}

/* Shared "up one level" link — the marketplace, Team, and What's New all use it.
   The styling used to live entirely under .platform-host with `display: none` as the
   base rule, which was fine while every view carrying one was platform-host-only. What's
   New is not: it is reachable from the header bell on extensions.edara.io too, and there
   the link rendered but was invisible — its only way out of a leaf view. So the component
   is unconditional now and only the MARKETPLACE's instance is host-gated, below. */
.mp-uplink {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    width: fit-content;
    margin: var(--space-base) var(--space-base) 0;
    padding: 6px 12px 6px 6px;
    border-radius: var(--radius-full);
    color: var(--on-surface-variant);
    font-size: var(--typo-label-lg);
    font-weight: 500;
    text-decoration: none;
    transition: background var(--duration-short4);
}

.mp-uplink:hover {
    background: var(--surface-container-low);
    color: var(--on-surface);
}

.mp-uplink .material-symbols-outlined {
    font-size: 18px;
}

[dir="rtl"] .mp-uplink .material-symbols-outlined {
    transform: scaleX(-1);
}

/* Hero → slim, left-aligned search toolbar (drop the centered title + subtitle) */
.platform-host #marketplaceMain .portal-hero {
    text-align: start;
    padding: var(--space-xs) var(--space-base) var(--space-base);
}

.platform-host #marketplaceMain .portal-title,
.platform-host #marketplaceMain .portal-subtitle {
    display: none;
}

.platform-host #marketplaceMain .search-box {
    margin: 0;
    max-width: 440px;
}

/* Category "active" reads as a soft nav highlight (not the pill's primary glow)
   at every width — including the mobile chip row. */
.platform-host #marketplaceMain .category-btn.active {
    background: var(--secondary-container);
    color: var(--on-secondary-container);
    box-shadow: none;
}

/* Two-column workspace from 861px up. Below that the base cascade already gives
   the classic stacked layout + horizontal category chips, so there is no
   separate mobile block to keep in sync. */
@media (min-width: 861px) {
    .platform-host .mp-body {
        display: grid;
        grid-template-columns: 216px minmax(0, 1fr);
        column-gap: var(--space-l);
        align-items: start;
        padding: 0 var(--space-base);
    }

    .platform-host .mp-results {
        display: block;
        min-width: 0;
    }

    /* Left rail — reuses #categoriesNav + .category-btn as a vertical nav */
    .platform-host #categoriesNav {
        flex-direction: column;
        gap: 2px;
        overflow: visible;
        padding: 0;
        margin: 0;
        position: sticky;
        top: calc(var(--header-height) + var(--space-base));
    }

    .platform-host #marketplaceMain .category-btn {
        width: 100%;
        justify-content: flex-start;
        min-height: 42px;
        border-radius: var(--radius-md);
        background: transparent;
    }

    .platform-host #marketplaceMain .category-btn:hover {
        background: var(--surface-container-high);
    }

    /* Results sit flush in their column — the rail + column-gap provide the gutter */
    .platform-host #marketplaceMain .section-header,
    .platform-host #marketplaceMain .extensions-grid {
        padding-inline: 0;
    }
}

/* ============================================ */
/* Team members (org user management)           */
/* ============================================ */
.team-hero-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-base);
    flex-wrap: wrap;
}
.team-hero-titles { min-width: 0; }
.team-invite-btn { flex-shrink: 0; }

.team-body {
    max-width: 1120px;
    margin-inline: auto;
    padding-inline: var(--space-base);
    padding-block-end: var(--space-xl);
}

/* Toolbar: search grows; status segments + role/sort selects wrap on narrow */
.team-toolbar {
    display: flex;
    align-items: center;
    gap: var(--space-s);
    flex-wrap: wrap;
    margin-block-end: var(--space-base);
}

/* Reuses .search-box (structure, tokens, focus behavior) at list scale */
.team-search {
    flex: 1 1 220px;
    min-width: 0;
    max-width: 340px;
    margin: 0;
    min-height: 44px;
    padding: 0 var(--space-base);
    box-shadow: none;
}
.team-search:focus-within { box-shadow: var(--shadow-focus-ring); }
.team-search input { font-size: 0.9rem; }

/* Segmented status filter (All / Active / Pending) */
.team-seg {
    display: inline-flex;
    padding: 3px;
    gap: 2px;
    background: var(--surface-container-high);
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-full);
}
.team-seg-btn {
    padding: 7px 14px;
    border: none;
    border-radius: var(--radius-full);
    background: transparent;
    color: var(--on-surface-variant);
    font-family: var(--font-family);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}
.team-seg-btn:hover { color: var(--on-surface); }
.team-seg-btn.is-active {
    background: var(--surface-container-lowest);
    color: var(--primary);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
}

/* Native role/sort selects, styled to match the toolbar */
.team-select {
    height: 44px;
    padding-inline: var(--space-base) 34px;
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-md);
    background-color: var(--surface-container-lowest);
    color: var(--on-surface);
    font-family: var(--font-family);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    appearance: none;
    outline: none;
    max-width: 200px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23808896' stroke-width='2' stroke-linecap='round'><path d='m7 10 5 5 5-5'/></svg>");
    background-repeat: no-repeat;
    background-position: right 12px center;
}
[dir="rtl"] .team-select { background-position: left 12px center; }
.team-select:focus-visible { box-shadow: var(--shadow-focus-ring); border-color: var(--primary); }

.team-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-xl);
}

.team-error {
    background: var(--error-container);
    color: var(--on-error-container);
    border-radius: var(--radius-md);
    padding: var(--space-base);
    font-size: 0.9rem;
    margin-block-end: var(--space-base);
}

/* Table shell + shared column grid so the header row and body rows align */
.team-table {
    background: var(--surface-container-lowest);
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-lg);
    overflow: hidden;
}
.team-thead,
.team-row {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1.7fr) 132px 92px;
    align-items: center;
    gap: var(--space-base);
}
.team-thead {
    padding: 10px var(--space-m);
    background: var(--surface-container-high);
    border-block-end: 1px solid var(--outline-variant);
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--on-surface-variant);
}
.team-thead .team-th-actions { text-align: end; }

.team-list { display: flex; flex-direction: column; }

.team-row {
    padding: 10px var(--space-m);
    border-block-end: 1px solid var(--outline-variant);
    transition: background 0.12s ease;
}
.team-row:last-child { border-block-end: none; }
.team-row:hover { background: var(--surface-container-low); }

.team-avatar {
    flex-shrink: 0;
    inline-size: 36px;
    block-size: 36px;
    border-radius: var(--radius-circle);
    background: var(--primary-container);
    color: var(--on-primary-container);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.8rem;
    font-weight: 600;
}
.team-avatar .material-symbols-outlined { font-size: 20px; }
.team-avatar--lg { inline-size: 64px; block-size: 64px; font-size: 1.25rem; }
.team-avatar--lg .material-symbols-outlined { font-size: 32px; }

/* Member cell: avatar + email, whole cell opens details */
.team-cell-member {
    display: flex;
    align-items: center;
    gap: var(--space-s);
    min-width: 0;
    background: none;
    border: none;
    padding: 0;
    font-family: var(--font-family);
    text-align: start;
    cursor: pointer;
}
.team-email {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--on-surface);
}
.team-cell-member:hover .team-email { color: var(--primary); }

/* Roles cell: up to 2 chips + a "+N" overflow pill (opens details) */
.team-cell-roles {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    overflow: hidden;
}

.team-role-chip {
    display: inline-flex;
    align-items: center;
    max-width: 100%;
    padding: 3px 10px;
    border-radius: var(--radius-full);
    border: 1px solid var(--outline-variant);
    background: var(--surface-container-low);
    color: var(--on-surface-variant);
    font-size: 0.75rem;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.team-role-chip--admin {
    border-color: transparent;
    background: var(--primary-container);
    color: var(--on-primary-container);
    font-weight: 600;
}
.team-role-chip--skel { inline-size: 72px; border-color: transparent; }

.team-more-btn {
    flex: none;
    padding: 3px 9px;
    border-radius: var(--radius-full);
    border: 1px dashed var(--outline);
    background: transparent;
    color: var(--on-surface-variant);
    font-family: var(--font-family);
    font-size: 0.72rem;
    font-weight: 700;
    cursor: pointer;
    white-space: nowrap;
}
.team-more-btn:hover { border-color: var(--primary); color: var(--primary); }

.team-roles-muted {
    font-size: 0.75rem;
    color: var(--on-surface-variant);
    opacity: 0.7;
}

.team-cell-status { display: flex; }
.team-chip {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    border-radius: var(--radius-full);
    font-size: 0.75rem;
    font-weight: 600;
}
.team-chip .material-symbols-outlined { font-size: 16px; }
.team-chip--ok { background: var(--success-container); color: var(--on-success-container); }
.team-chip--pending { background: var(--surface-container-high); color: var(--on-surface-variant); }

.team-row-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-xs);
}

/* Destructive affordance: the remove button telegraphs danger on hover/focus */
.team-row-actions .team-remove-btn:hover,
.team-row-actions .team-remove-btn:focus-visible {
    background: var(--error-container);
    color: var(--on-error-container);
}

/* Loading skeletons (list) — shimmer via opacity so it works in both themes */
@keyframes team-shimmer {
    0%, 100% { opacity: 0.45; }
    50% { opacity: 1; }
}
.team-skel {
    background: var(--surface-container-high);
    border-radius: var(--radius-full);
    animation: team-shimmer 1.4s ease-in-out infinite;
}
.team-skel--line { inline-size: min(200px, 70%); block-size: 14px; }
.team-skel--chip { inline-size: 84px; block-size: 24px; border-radius: var(--radius-full); }
.team-row--skel .team-avatar { background: var(--surface-container-high); }

/* Footer: range label + numbered pager */
.team-pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-base);
    flex-wrap: wrap;
    margin-block-start: var(--space-base);
}
.team-range {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--on-surface-variant);
}
.team-pager-btns { display: flex; align-items: center; gap: 4px; }
.team-pager-btn {
    min-width: 36px;
    height: 36px;
    padding: 0 10px;
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-sm);
    background: var(--surface-container-lowest);
    color: var(--on-surface);
    font-family: var(--font-family);
    font-size: 0.85rem;
    font-weight: 700;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.team-pager-btn:hover:not(:disabled):not(.is-active) { background: var(--surface-container-high); }
.team-pager-btn.is-active {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--on-primary, #fff);
}
.team-pager-btn:disabled { opacity: 0.4; cursor: default; }
.team-pager-btn .material-symbols-outlined { font-size: 18px; }
[dir="rtl"] .team-pager-btn .material-symbols-outlined { transform: scaleX(-1); }
.team-pager-ellipsis {
    min-width: 20px;
    text-align: center;
    color: var(--on-surface-variant);
    font-weight: 700;
}

.team-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-s);
    padding: var(--space-xxl) var(--space-base);
    color: var(--on-surface-variant);
    text-align: center;
}
.team-empty .material-symbols-outlined { font-size: 44px; opacity: 0.7; }

/* MD3 dialog shell: tonal-icon header + pinned footer with a single scrollable body,
   so a long role list scrolls inside a height-capped dialog (actions never scroll away). */
.team-modal {
    display: flex;
    flex-direction: column;
    inline-size: 100%;
    max-inline-size: 480px;
    max-block-size: min(88vh, 680px);
    background: var(--surface);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-level3);
    overflow: hidden;
    text-align: start;
    animation: cardFadeIn var(--duration-short4) var(--ease-standard);
}
.team-modal--sm { max-inline-size: 420px; }
.team-modal-head {
    display: flex;
    align-items: flex-start;
    gap: var(--space-base);
    padding: var(--space-l) var(--space-l) var(--space-base);
}
.team-modal-icon {
    flex: none;
    inline-size: 44px;
    block-size: 44px;
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
}
.team-modal-icon .material-symbols-outlined { font-size: 24px; }
.team-modal-icon--brand { background: var(--primary-container); color: var(--on-primary-container); }
.team-modal-icon--danger { background: var(--error-container); color: var(--on-error-container); }
.team-modal-titles { flex: 1; min-width: 0; padding-block-start: 2px; }
.team-modal-title {
    margin: 0;
    font-size: var(--typo-title-lg);
    font-weight: 600;
    color: var(--on-surface);
}
.team-modal-sub {
    margin: 3px 0 0;
    font-size: var(--typo-body-sm);
    color: var(--on-surface-variant);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Reuses the shared .icon-btn (size, transparent bg, light+dark hover); only the header
   placement and a muted tint are modal-specific. */
.team-modal-close { flex: none; color: var(--on-surface-variant); }
.team-modal-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 0 var(--space-l) var(--space-base);
}
.team-modal-actions {
    display: flex;
    gap: var(--space-s);
    justify-content: flex-end;
    padding: var(--space-base) var(--space-l) var(--space-l);
    border-block-start: 1px solid var(--outline-variant);
}
.team-field-label {
    display: block;
    margin-block: var(--space-base) var(--space-xs);
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--on-surface-variant);
}
.team-input {
    inline-size: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    border: 1px solid var(--outline);
    border-radius: var(--radius-sm);
    background: var(--surface-container-lowest);
    color: var(--on-surface);
    font-family: var(--font-family);
    font-size: 0.95rem;
}
.team-input:focus {
    outline: 2px solid var(--primary);
    outline-offset: -1px;
    border-color: var(--primary);
}

/* Role picker: a scrollable checklist with a "N selected" / Clear all header */
.team-picker-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-block: var(--space-base) var(--space-xs);
}
.team-picker-count { font-size: 0.8rem; font-weight: 700; color: var(--primary); }
.team-picker-clear {
    background: none;
    border: none;
    padding: 0;
    color: var(--on-surface-variant);
    font-family: var(--font-family);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
}
.team-picker-clear:hover { color: var(--error); }
.team-picker-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    /* No inner scroll: the modal body is the single scroll region, so a role-heavy list
       scrolls with the form instead of creating a nested scrollbar. */
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-md);
    padding: 4px;
}
.team-role-opt {
    display: flex;
    align-items: center;
    gap: var(--space-s);
    padding: 9px 10px;
    border-radius: var(--radius-sm);
    font-size: 0.9rem;
    color: var(--on-surface);
    cursor: pointer;
}
.team-role-opt:hover { background: var(--surface-container-high); }
.team-role-opt input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}
.team-role-opt-box {
    flex: none;
    inline-size: 20px;
    block-size: 20px;
    border-radius: 6px;
    border: 2px solid var(--outline);
    display: flex;
    align-items: center;
    justify-content: center;
    color: transparent;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.team-role-opt-box .material-symbols-outlined { font-size: 16px; }
.team-role-opt input:checked + .team-role-opt-box {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--on-primary, #fff);
}
.team-role-opt input:focus-visible + .team-role-opt-box { box-shadow: var(--shadow-focus-ring); }
.team-role-opt-label { flex: 1; min-width: 0; }

/* Member details dialog */
.team-details-head {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-s);
    padding-block: var(--space-s) var(--space-base);
}
.team-details-email {
    font-size: 1rem;
    font-weight: 600;
    color: var(--on-surface);
    word-break: break-all;
    text-align: center;
}
.team-details-label {
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--on-surface-variant);
    margin-block: var(--space-base) var(--space-xs);
}
.team-details-roles {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.team-dialog-error {
    color: var(--error);
    font-size: 0.85rem;
    margin-block-start: var(--space-s);
    min-block-size: 1em;
}

.team-toast {
    position: fixed;
    inset-block-end: 24px;
    inset-inline: 0;
    margin-inline: auto;
    width: max-content;
    max-width: 90vw;
    background: var(--inverse-surface);
    color: var(--inverse-on-surface);
    padding: 12px 20px;
    border-radius: var(--radius-full);
    font-size: 0.9rem;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.24);
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.2s ease, transform 0.2s ease;
    pointer-events: none;
    /* Above every full-screen surface: the app shell (1200) and the Ctrl/Cmd+K
       switcher (1300) both cover the viewport, and a toast raised from inside
       either of them is the one message the user must not miss. Nothing should
       ever occlude a toast, so this is deliberately the top of the scale. */
    z-index: 1500;
}
.team-toast--show { opacity: 1; transform: translateY(0); }

/* Mobile: drop the header row and stack each row into a card */
@media (max-width: 720px) {
    .team-thead { display: none; }
    .team-row {
        grid-template-columns: 1fr auto;
        grid-template-areas:
            "member actions"
            "roles roles"
            "status status";
        gap: var(--space-xs) var(--space-s);
        padding: var(--space-base) var(--space-base);
    }
    .team-cell-member { grid-area: member; }
    .team-row-actions { grid-area: actions; align-self: start; }
    .team-cell-roles { grid-area: roles; flex-wrap: wrap; overflow: visible; }
    .team-cell-status { grid-area: status; }
    .team-search { max-width: none; flex-basis: 100%; }
    .team-select { flex: 1; max-width: none; }
}

/* ============================================ */
/* Platform-home Manage rail (org admins)       */
/* ============================================ */
.platform-layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-l);
}
/* Desktop: product tiles on the left, a fixed-width Manage rail on the right. */
@media (min-width: 900px) {
    .platform-layout {
        grid-template-columns: minmax(0, 1fr) 260px;
        align-items: start;
    }
}
.platform-content { min-width: 0; }

/* A subtle card so a single item still reads as an intentional panel (and it scales
   cleanly if more Manage items are added later). Matches the product-tile language. */
.manage-rail {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    padding: var(--space-s);
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-lg);
    background: var(--surface-container-lowest);
}
.manage-rail-label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--on-surface-variant);
    padding: var(--space-xs) var(--space-s);
}
/* display:flex beats [hidden]; Finance (staff only) and, for finance staff who
   aren't admins, Team and Plans are hidden with the attribute. */
.manage-rail-item[hidden] { display: none; }
.manage-rail-item {
    display: flex;
    align-items: center;
    gap: var(--space-base);
    inline-size: 100%;
    padding: 12px var(--space-s);
    border: none;
    background: none;
    border-radius: var(--radius-sm);
    color: var(--on-surface);
    font-family: var(--font-family);
    font-size: 0.95rem;
    font-weight: 500;
    text-align: start;
    cursor: pointer;
    transition: background 0.15s ease;
}
.manage-rail-item:hover { background: var(--surface-container-high); }
.manage-rail-item .material-symbols-outlined { color: var(--on-surface-variant); }

/* ============================================ */
/* Plans (/plans) — price book + current plan   */
/* ============================================ */
.plans-body {
    max-width: 1120px;
    margin-inline: auto;
    padding-inline: var(--space-base);
    padding-block-end: var(--space-xl);
}
.plans-notice {
    display: flex;
    align-items: center;
    gap: var(--space-s);
    background: var(--tertiary-container);
    color: var(--on-tertiary-container);
    border-radius: var(--radius-md);
    padding: var(--space-s) var(--space-base);
    margin-block-end: var(--space-base);
}
.plans-notice--error { background: var(--error-container); color: var(--on-error-container); }
.plans-notice .btn-text, .plans-notice .btn-filled { margin-inline-start: auto; flex-shrink: 0; }
.plans-action {
    min-height: 40px;
    border: 1px solid var(--outline);
    border-radius: var(--radius-full);
    background: none;
    color: var(--primary);
    font-family: var(--font-family);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
}
.plans-action--primary { background: var(--primary); color: var(--on-primary); border-color: var(--primary); }
.plans-action:disabled { opacity: 0.6; cursor: progress; }
.plans-kind { display: flex; gap: var(--space-base); margin-block-end: var(--space-s); }
.plans-kind label { display: flex; align-items: center; gap: var(--space-xs); cursor: pointer; }
.plans-dialog-text { margin: 0; line-height: 1.5; }
.finance-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-base);
    flex-wrap: wrap; margin-block-end: var(--space-base); }
.finance-toolbar .btn-filled { display: inline-flex; align-items: center; gap: var(--space-xs); }
.finance-scroll { overflow-x: auto; border: 1px solid var(--outline-variant); border-radius: var(--radius-lg); }
.finance-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.finance-table th, .finance-table td { padding: var(--space-s) var(--space-base); text-align: start;
    border-block-end: 1px solid var(--outline-variant); vertical-align: top; }
.finance-table th { color: var(--on-surface-variant); font-weight: 600; background: var(--surface-container-low); }
.finance-num { text-align: end !important; white-space: nowrap; }
.finance-muted { color: var(--on-surface-variant); font-size: 0.82rem; }
/* min(220px,100%): one card per row on a phone instead of overflowing it */
.plans-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr));
    gap: var(--space-base);
}
.plans-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-s);
    min-width: 0;
    padding: var(--space-base);
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-lg);
    background: var(--surface-container-lowest);
}
.plans-card.is-current { border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.plans-card.is-wanted { border-color: var(--tertiary); box-shadow: inset 0 0 0 1px var(--tertiary); }
.plans-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-s); flex-wrap: wrap; }
.plans-card-name { font-size: 1.1rem; font-weight: 700; margin: 0; }
.plans-badge {
    font-size: 0.75rem;
    font-weight: 600;
    padding: 2px var(--space-s);
    border-radius: var(--radius-full);
}
.plans-badge-current { background: var(--primary-container); color: var(--on-primary-container); }
.plans-badge-wanted { background: var(--tertiary-container); color: var(--on-tertiary-container); }
.plans-card-price { display: flex; flex-direction: column; }
.plans-price { font-size: 1.25rem; font-weight: 700; }
.plans-lines { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-xs); flex: 1; }
.plans-lines li { display: flex; align-items: center; gap: var(--space-s); font-size: 0.9rem; }
.plans-lines .material-symbols-outlined { font-size: 18px; color: var(--primary); }
.plans-choose {
    min-height: 40px;
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-full);
    background: none;
    color: var(--on-surface-variant);
    font-family: var(--font-family);
    font-size: 0.85rem;
    cursor: not-allowed;
}
/* Edara leads: the main subscription, read-only. */
.plans-edara {
    padding: var(--space-l);
    border-radius: var(--radius-lg);
    background: var(--surface-container-low);
    border: 1px solid var(--outline-variant);
    margin-block-end: var(--space-xl);
}
.plans-edara-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-base); flex-wrap: wrap; }
.plans-edara-name { font-size: 1.5rem; font-weight: 700; margin: 0; }
.plans-edara-sub { color: var(--on-surface-variant); margin: var(--space-xs) 0 0; }
.plans-edara-facts { list-style: none; margin: var(--space-base) 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-s) var(--space-l); }
.plans-edara-facts li { display: flex; align-items: center; gap: var(--space-s); }
.plans-edara-facts .material-symbols-outlined { font-size: 20px; color: var(--primary); }
.plans-edara-note { font-size: 0.9rem; color: var(--on-surface-variant); margin: var(--space-base) 0 0; }

/* Extensions weigh less: a compact row each; plans open on request. */
.plans-section-title { font-size: 1.1rem; font-weight: 600; margin: 0; }
.plans-section-sub { color: var(--on-surface-variant); font-size: 0.9rem; margin: var(--space-xs) 0 var(--space-base); }
.plans-ext-list { list-style: none; margin: 0 0 var(--space-base); padding: 0; display: flex; flex-direction: column; gap: var(--space-s); }
.plans-ext { border: 1px solid var(--outline-variant); border-radius: var(--radius-lg); background: var(--surface-container-lowest); scroll-margin-top: calc(var(--header-height) + var(--space-base)); }
.plans-ext-row {
    display: flex;
    align-items: center;
    gap: var(--space-base);
    padding: var(--space-s) var(--space-base);
    min-height: 48px;
    cursor: pointer;
    list-style: none;
}
.plans-ext-row::-webkit-details-marker { display: none; }
.plans-ext-row:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: var(--radius-lg); }
.plans-ext-name { font-weight: 600; }
.plans-ext-glance { color: var(--on-surface-variant); font-size: 0.9rem; min-width: 0; flex: 1; }
.plans-ext-toggle { display: flex; align-items: center; gap: var(--space-xs); color: var(--primary); font-size: 0.9rem; font-weight: 500; flex-shrink: 0; }
.plans-ext-toggle .material-symbols-outlined { transition: transform .15s ease; }
.plans-ext[open] .plans-ext-toggle .material-symbols-outlined { transform: rotate(180deg); }
.plans-ext .plans-ext-when-open, .plans-ext[open] .plans-ext-when-closed { display: none; }
.plans-ext[open] .plans-ext-when-open { display: inline; }
.plans-ext-body { padding: 0 var(--space-base) var(--space-base); }
@media (max-width: 600px) {
    .plans-ext-row { flex-wrap: wrap; }
    .plans-ext-glance { flex-basis: 100%; order: 3; }
    .plans-ext-toggle { margin-inline-start: auto; }
}
.plans-rep-note { margin: 0; font-size: 0.9rem; color: var(--on-surface-variant); }
.plans-footnote { font-size: 0.85rem; color: var(--on-surface-variant); }


/* ========================================
   ANALYTICS VIEW (/analytics)
   ========================================
   One organization's own usage, one card per extension that answers the
   org-summary contract. Everything below is shape-driven — no rule names an
   extension — so a new source needs no CSS. */

.an-layout { display: flex; flex-direction: column; gap: var(--space-base); }

.an-bar {
    display: flex; align-items: center; gap: var(--space-base); flex-wrap: wrap;
    margin-bottom: var(--space-xs);
}
.an-subline { color: var(--on-surface-variant); font-size: var(--typo-body-md); margin: 0; }

.an-seg {
    display: inline-flex; margin-inline-start: auto; padding: 3px; gap: 2px;
    border: 1px solid var(--outline-variant); border-radius: var(--radius-full);
    background: var(--surface-container-lowest);
}
.an-seg button {
    border: 0; background: transparent; color: var(--on-surface-variant); cursor: pointer;
    padding: 5px 14px; border-radius: var(--radius-full); font: inherit; font-weight: 550;
    min-height: var(--min-touch-target, 36px);
}
.an-seg button:hover { background: var(--surface-container); }
.an-seg button[aria-pressed="true"] {
    background: var(--secondary-container); color: var(--on-secondary-container);
}

.an-card {
    background: var(--surface-container-lowest);
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-lg);
    padding: var(--space-m);
}
/* --- The product-area tabs -------------------------------------------------- */
/* Scrolls rather than wraps: a wrapped tab strip changes the page's height as areas
   are added, and the whole point of Overview is that its height does not move. */
.an-tabs {
    display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none;
    border-bottom: 1px solid var(--outline-variant);
}
.an-tabs::-webkit-scrollbar { display: none; }
.an-tab {
    border: 0; background: transparent; cursor: pointer; white-space: nowrap;
    padding: 10px 14px 12px; font: 500 14px var(--font-family);
    color: var(--on-surface-variant); position: relative;
    display: inline-flex; align-items: center; gap: 8px;
}
.an-tab:hover { color: var(--on-surface); }
.an-tab[aria-selected="true"] { color: var(--primary); font-weight: 600; }
.an-tab[aria-selected="true"]::after {
    content: ''; position: absolute; inset-inline: 10px; bottom: -1px; height: 3px;
    border-radius: 3px 3px 0 0; background: var(--primary);
}
.an-tab i { width: 9px; height: 9px; border-radius: 50%; display: block; flex: none; }
.an-tab-count { color: var(--on-surface-variant); font-weight: 400; font-size: 12.5px; }

/* --- Overview: one card per product area ------------------------------------ */
.an-groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 12px; }
.an-group-card {
    display: grid; grid-template-columns: 1fr 104px; gap: 12px; align-items: center;
    background: var(--surface-container-lowest); border: 1px solid var(--outline-variant);
    border-radius: var(--radius-lg); padding: 14px 16px;
    text-align: start; cursor: pointer; font: inherit; color: inherit;
}
.an-group-card:hover { background: var(--surface-container-low); }
.an-group-name { display: inline-flex; align-items: center; gap: 8px; font-weight: 650; }
.an-group-name i { width: 10px; height: 10px; border-radius: 50%; display: block; flex: none; }
.an-group-total {
    font-size: 22px; font-weight: 650; letter-spacing: -.01em;
    font-variant-numeric: tabular-nums; margin-top: 4px;
}
/* After .an-group-total, not before: same specificity, so source order decides,
   and the weight is the point — a state must not be set like a number. */
.an-group-none { color: var(--on-surface-variant); font-weight: 500; }
.an-group-meta { color: var(--on-surface-variant); font-size: var(--typo-body-sm, 12.5px); }
.an-group-go {
    grid-column: 1 / -1; color: var(--primary); font: 500 12.5px var(--font-family);
    display: inline-flex; align-items: center; gap: 4px;
}
.an-group-go .material-symbols-outlined { font-size: 15px; }
/* The one directional glyph on this page — it must point the way the reader reads. */
[dir="rtl"] .an-group-go .material-symbols-outlined { transform: scaleX(-1); }

/* --- Overview band -------------------------------------------------------- */
/* The head carries the scale toggle, which must not squash the title on a phone. */
.an-combined .an-head { flex-wrap: wrap; }
.an-scale button { padding: 5px 12px; font-size: 12px; }
.an-hero { margin-top: 14px; }
.an-hero .an-kpi { background: transparent; padding: 0; }
.an-hero .an-kpi-value { font-size: 26px; }

/* --- A source at rest ------------------------------------------------------ */
.an-rows { display: flex; flex-direction: column; gap: 8px; }
.an-row {
    background: var(--surface-container-lowest); border: 1px solid var(--outline-variant);
    border-radius: var(--radius-lg); overflow: hidden;
}
/* Four fixed columns and one flexible: the figures share what is left so a long
   extension name never pushes the sparkline out of the row. */
.an-row-head {
    display: grid; grid-template-columns: 30px minmax(0, 1fr) max-content 104px 24px;
    align-items: center; gap: 12px; padding: 10px 14px; cursor: pointer;
    list-style: none; width: 100%; text-align: start;
}
.an-row-head::-webkit-details-marker { display: none; }
.an-row-head:hover { background: var(--surface-container-low); }
.an-row-titles { min-width: 0; }
.an-row-name {
    font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.an-row-note { color: var(--on-surface-variant); font-size: var(--typo-body-sm, 12px); }
/* A GRID of two fixed columns, not a flex row: flex sizes each pair to its own
   content, so "Lookups 9" and "Active labels 16" started at different x on adjacent
   rows and the eye had nothing to run down. */
/* A GRID of two FIXED columns. Fixed is the whole point — the figures have to start at
   the same x on every row or the column cannot be scanned — so an over-wide child must
   degrade INSIDE its track rather than widening it. `minmax(…, max-content)` was tried
   and is worse: it only acts once something exceeds 116px, and what it does then is
   break the alignment the track exists for, on one row, silently.
   116px is measured against what the shipped sources actually send: the widest label is
   "Recipient sign-ins" at 89px, the widest value "1,840,000 EGP" at 107px.
   `min-width: 0` is what makes the containment work — a grid item defaults to a
   min-content floor, which is why a fixed track overflowed instead of clipping. */
.an-row-figures { display: grid; grid-template-columns: repeat(2, 116px); gap: 12px; }
.an-row-figures .an-kpi { background: transparent; padding: 0; min-width: 0; }
/* The label truncates — it is repeated in full when the row is expanded. The value
   does not: an elided number ("1,840,00…") is worse than a wrapped one, so a long
   value breaks at its space instead ("1,840,000" / "EGP"). */
.an-row-figures .an-kpi-label {
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* tabular-nums HERE and not on the big KPI tiles: these are a column of numbers that
   must align down the page, which is the one case the proportional default loses to. */
.an-row-figures .an-kpi-value { font-size: 16px; font-variant-numeric: tabular-nums; }
.an-row-figures .an-kpi-label, .an-row-figures .an-kpi-delta { font-size: 11.5px; }
.an-spark { width: 104px; height: 28px; display: block; }
.an-chev { color: var(--on-surface-variant); justify-self: end; transition: transform .15s ease; }
.an-row[open] .an-chev { transform: rotate(180deg); }
.an-row-body { padding: 0 14px 14px; border-top: 1px solid var(--outline-variant); }
.an-row-body .an-kpis { margin-top: 14px; }
.an-row-foot { margin-top: 14px; }
.an-quiet .an-row-name { color: var(--on-surface-variant); }

/* Below the figures' comfortable width the sparkline earns its place more than a
   second number does, so the figures stand down before it does. */
@media (max-width: 720px) {
    .an-row-head { grid-template-columns: 30px minmax(0, 1fr) 104px 24px; }
    .an-row-figures { display: none; }
}

/* --- Crosshair + tooltip --------------------------------------------------- */
.an-cross { stroke: var(--outline); stroke-width: 1; opacity: .6; }
.an-cross-dot { stroke: var(--surface-container-lowest); stroke-width: 2; }
.an-tip {
    position: fixed; z-index: 1400; display: none; pointer-events: none;
    min-width: 168px; padding: 8px 10px;
    background: var(--surface-container-lowest); color: var(--on-surface);
    border: 1px solid var(--outline-variant); border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .18); font-size: 12px;
}
.an-tip.open { display: block; }
.an-tip h5 { font-size: 12px; font-weight: 600; margin-bottom: 4px; }
.an-tip div { display: flex; align-items: center; gap: 7px; padding: 1px 0; }
.an-tip i { width: 10px; height: 3px; border-radius: 2px; display: block; flex: none; }
.an-tip b { margin-inline-start: auto; font-variant-numeric: tabular-nums; }

.an-head { display: flex; align-items: center; gap: var(--space-s); margin-bottom: var(--space-base); }
.an-icon {
    width: 38px; height: 38px; border-radius: var(--radius-md); flex: 0 0 auto;
    display: grid; place-items: center; color: #fff;
}
.an-icon-neutral { background: var(--on-surface-variant); }
/* The rail-sized variant a collapsed row wears. */
.an-icon-sm { width: 30px; height: 30px; border-radius: 9px; }
.an-icon-sm .material-symbols-outlined { font-size: 17px; }
.an-icon .material-symbols-outlined { font-size: 20px; }
.an-name { font-weight: 650; font-size: var(--typo-title-sm, 15px); }
.an-sub { color: var(--outline); font-size: var(--typo-body-sm, 12.5px); }
.an-open {
    margin-inline-start: auto; color: var(--primary); text-decoration: none;
    font-size: var(--typo-body-sm, 13px); font-weight: 550;
    border: 1px solid var(--outline-variant); border-radius: var(--radius-full);
    padding: 6px 12px; white-space: nowrap;
}
.an-open:hover { background: var(--surface-container-low); }

.an-kpis {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: var(--space-s); margin-bottom: var(--space-base);
}
.an-kpi { background: var(--surface-container-low); border-radius: var(--radius-md); padding: 12px 14px; }
.an-kpi-label { color: var(--on-surface-variant); font-size: var(--typo-body-sm, 12.5px); }
.an-kpi-value { font-size: 22px; font-weight: 650; letter-spacing: -.01em; }
/* Direction, not judgement: the portal cannot know whether up is good for a
   metric it has never heard of, so a delta is never green or red. */
.an-kpi-delta { color: var(--outline); font-size: 12px; font-weight: 600; margin-top: 2px; }

.an-body { display: grid; grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr); gap: var(--space-m); }
.an-body > *:only-child { grid-column: 1 / -1; }
.an-chart-block h4, .an-list h4 {
    font-size: var(--typo-body-sm, 12.5px); font-weight: 650;
    color: var(--on-surface-variant); margin: 0 0 var(--space-s);
}
.an-chart { display: block; width: 100%; height: auto; }
.an-grid { stroke: var(--outline-variant); stroke-width: 1; }
.an-baseline { stroke: var(--outline); stroke-width: 1; opacity: .5; }
.an-axis { font-size: 10px; fill: var(--outline); font-variant-numeric: tabular-nums; }

.an-legend { display: flex; gap: var(--space-base); flex-wrap: wrap; margin-top: var(--space-xs); }
.an-legend-item {
    display: inline-flex; align-items: center; gap: 6px;
    color: var(--on-surface-variant); font-size: var(--typo-body-sm, 12.5px);
}
.an-legend-item i, .an-dot { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }

.an-lists { display: flex; flex-direction: column; gap: var(--space-base); }
.an-list-row {
    display: flex; align-items: baseline; gap: var(--space-s); padding: 6px 0;
    border-bottom: 1px solid var(--surface-container-high);
}
.an-list-row:last-child { border-bottom: 0; }
.an-list-name { font-weight: 550; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.an-list-sub {
    color: var(--outline); font-size: 12px; flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.an-list-count { margin-inline-start: auto; font-weight: 650; font-variant-numeric: tabular-nums; color: var(--on-surface-variant); }

.an-share { display: flex; gap: 2px; height: 14px; border-radius: 7px; overflow: hidden; margin: var(--space-xs) 0 var(--space-s); }
.an-share span { display: block; min-width: 3px; }
.an-share-note {
    color: var(--on-surface-variant); font-size: var(--typo-body-sm, 12px);
    margin-bottom: var(--space-xs);
}

/* Configured but silent, or unreachable. Both are ordinary states here: the page
   lists every configured source, so "nothing yet" must look deliberate rather than
   broken — a dashed edge and a muted glyph, otherwise the same row as its
   neighbours. (This was the CARD shape until the rows landed; the padding and flex
   it used to carry stacked on top of the row's own and left it taller and more
   indented than everything beside it.) */
.an-quiet { border-style: dashed; }
.an-quiet .an-icon { opacity: .55; }
/* Three columns, not five: nothing to expand, so no figures and no chevron. */
.an-row-static { grid-template-columns: 30px minmax(0, 1fr) auto; cursor: default; }
.an-row-static:hover { background: transparent; }
.an-state { color: var(--outline); font-size: 12px; font-weight: 600; white-space: nowrap; }
.an-error { border-style: solid; }
.an-error .an-state { color: var(--error); }

.an-empty {
    display: flex; flex-direction: column; align-items: center; gap: var(--space-s);
    padding: var(--space-xl) var(--space-m); text-align: center;
    color: var(--on-surface-variant);
    border: 1px dashed var(--outline-variant); border-radius: var(--radius-lg);
}
.an-empty .material-symbols-outlined { font-size: 40px; color: var(--outline); }

@media (max-width: 860px) {
    .an-body { grid-template-columns: 1fr; }
    .an-seg { margin-inline-start: 0; }
}

/* The Sources control. The page is the admin's to curate, and this is where that is
   said: one menu listing every candidate, ticked when it is on the page. Quiet on
   purpose — it shares the query row with the period picker and must not out-shout it. */
.an-src { position: relative; flex: 0 0 auto; }
.an-src-btn {
    display: inline-flex; align-items: center; gap: 6px;
    /* Same touch floor and weight as .an-seg button, the control it stands beside —
       the weight folded into the `font` shorthand below. The two are not the same
       height: .an-seg wraps its buttons in padding and a border. */
    min-height: var(--min-touch-target, 36px);
    border: 1px solid var(--outline-variant); border-radius: var(--radius-full);
    padding-block: 7px; padding-inline: 12px 14px;
    background: transparent; cursor: pointer;
    color: var(--on-surface-variant); font: 550 13px var(--font-family);
}
.an-src-btn:hover { color: var(--on-surface); background: var(--surface-container-low); }
.an-src-btn .material-symbols-outlined { font-size: 18px; }
.an-src-menu {
    position: absolute; top: calc(100% + 6px); inset-inline-end: 0; min-width: 240px;
    display: none; z-index: 30; padding: 6px;
    background: var(--surface-container-lowest); border: 1px solid var(--outline-variant);
    border-radius: var(--radius-md); box-shadow: 0 8px 24px rgba(0,0,0,0.18);
}
.an-src-menu.open { display: block; }
.an-src-menu button {
    display: flex; align-items: center; gap: 10px; width: 100%; text-align: start;
    border: 0; background: transparent; padding: 8px 10px; border-radius: var(--radius-sm);
    font: inherit; font-size: var(--typo-body-sm, 13px); color: var(--on-surface); cursor: pointer;
}
.an-src-menu button:hover { background: var(--surface-container-low); }
/* Which product area a source belongs to, so BI Reports reads as Edara 2.0's. Drawn
   only when there is more than one area in the list — renderSourceControl decides. */
.an-src-area + .an-src-area { margin-top: 4px; padding-top: 6px; border-top: 1px solid var(--outline-variant); }
/* Matched to .edara-org-switcher__menu-header — the portal's other dropdown section
   heading, on the same surface. */
.an-src-area-head {
    padding: 4px 10px 5px; color: var(--on-surface-variant);
    font: 600 10px var(--font-family); text-transform: uppercase; letter-spacing: .08em;
}
/* Reserved, not conditional: a tick that takes its space only when set makes every
   name in the menu shift as sources are toggled. */
.an-src-tick { margin-inline-start: auto; font-size: 18px; color: var(--primary); visibility: hidden; }
.an-src-menu [aria-checked="true"] .an-src-tick { visibility: visible; }
.an-src-ico {
    width: 26px; height: 26px; border-radius: 7px; display: grid; place-items: center;
    color: #fff; flex: 0 0 auto;
}
.an-src-ico .material-symbols-outlined { font-size: 15px; }

/* ========================================
   UNIFIED HEADER (prototype — branch proto/unified-header)
   One slot order on every level, matching the app-shell bar (.ext-shell-bar):
   [brand] [org] | [> crumb] ... [Ctrl K] | [utilities]
   ======================================== */

/* The level crumb moves out of the brand lockup (#hdrCrumbExt in index.html), so
   the header lockup is brand-only and the org pill sits inside the brand cluster,
   not at a breadcrumb level. Platform host only: the legacy host keeps its classic
   lockup (and gets no crumb — its marketplace IS the top level, so a crumb would
   imply an up that does not exist there). The login lockup keeps its sub. */
.platform-host .app-header .edara-lockup-sub { display: none; }

html:not(.platform-host) .header-start .hdr-crumb,
html:not(.platform-host) .header-start .header-divider { display: none; }

/* Explore mode / pre-mount: no org pill means no hairline fencing an empty cluster
   (same guard as .es-org:empty in shell.js; `~` so a later insertion between slot
   and divider doesn't silently break it). */
.header-start #org-switcher-slot:empty ~ .header-divider { display: none; }

.hdr-crumb {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 5px 10px;
    color: var(--on-surface-variant);
    font: 500 13px/1.2 var(--font-family, system-ui);
    white-space: nowrap;
}

.hdr-crumb::before {
    content: '\203A';
    color: var(--outline);
    font-size: 15px;
    line-height: 1;
}

[dir="rtl"] .hdr-crumb::before { content: '\2039'; }

/* Level 1 (platform home) is brand-only; the crumb appears from level 2. The way
   up is the brand, exactly as in the shell bar. */
.platform-home-active .hdr-crumb,
.platform-home-active .header-start .header-divider { display: none; }

/* Switcher affordance at every level: a search-shaped "Go to…" pill. The shell bar
   already advertises the shortcut (.es-kbd); this control is the one non-keyboard
   users can discover — the kbd suffix only teaches the shortcut. */
.hdr-goto {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 36px;
    padding: 0 8px;
    padding-inline-start: 12px;
    border: 1px solid var(--outline-variant);
    border-radius: var(--radius-full);
    background: transparent;
    cursor: pointer;
    color: var(--on-surface-variant);
    min-width: 170px;
    transition: background var(--duration-short4, 150ms);
}

.hdr-goto:hover { background: var(--surface-container-low); }

.hdr-goto .material-symbols-outlined { font-size: 18px; }

.hdr-goto-label {
    flex: 1;
    text-align: start;
    font: 400 13px var(--font-family, system-ui);
}

.hdr-kbd-chip {
    font: 500 11px var(--font-family, system-ui);
    color: var(--on-surface-variant);
    border: 1px solid var(--outline-variant);
    border-radius: 6px;
    padding: 3px 7px;
}

