/* ══════════════════════════════════════════════════════════════════════════════════════════════════════════════
   Opera admin — global styles.

   1. Design tokens (--op-*): one set for the light theme (:root / [data-bs-theme=light]) and one for the dark theme
      ([data-bs-theme=dark]); data-bs-theme on <html> is the choice «Sistema / Chiaro / Scuro» of ThemeSwitch (App.razor,
      docs/07 «Aspetto»), for the admin pages and the viewer windows alike. Components use ONLY these variables (never a
      hard-coded colour), so both themes stay one product: retune a colour, radius or shadow here and every page follows.
      A colour a theme needs of its own is a new token defined in BOTH sets.
   2. Bootstrap bridge: Bootstrap's own variables are mapped onto the tokens (font, text levels, borders, radii,
      primary colour, buttons, tables, cards, tabs, modals).
   3. Shared components (trees, property sections, status badges, stats, stage timeline, drop zone, federations...).
   4. IFC class icons (per-family --ifc-<family> colours).
   No web fonts, no CDN: system font stacks only (the product runs on-prem and offline).
   ══════════════════════════════════════════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────── 1. tokens ───────────────────────── */

:root,
[data-bs-theme=light] {
    /* typography */
    --op-font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif;
    --op-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
    --op-text-2xs: 0.6875rem; /* 11px: counters, badges */
    --op-text-xs: 0.75rem;    /* 12px: labels, captions, section titles */
    --op-text-sm: 0.8125rem;  /* 13px: dense tables, trees, properties */
    --op-text-md: 0.875rem;   /* 14px: panels */
    --op-text-base: 0.9375rem;/* 15px: body */
    --op-text-lg: 1.0625rem;  /* 17px: panel titles */
    --op-text-xl: 1.5rem;     /* 24px: page titles */

    /* spacing, radii, motion */
    --op-space-1: 0.25rem;
    --op-space-2: 0.5rem;
    --op-space-3: 0.75rem;
    --op-space-4: 1rem;
    --op-space-5: 1.5rem;
    --op-radius-sm: 4px;
    --op-radius: 6px;
    --op-radius-lg: 10px;
    --op-radius-pill: 999px;
    --op-dur: 120ms;
    --op-ease: cubic-bezier(0.2, 0, 0, 1);

    /* surfaces, borders, text */
    --op-bg: #ffffff;
    --op-surface: #ffffff;
    --op-surface-2: #f5f7fa;
    --op-surface-3: #eceff4;
    --op-hover: #f1f4f8;
    --op-selected: #e4edfc;
    --op-selected-hover: #d9e6fb;
    --op-border: #e1e5eb;
    --op-border-strong: #cbd2dc;
    --op-text: #1b2130;
    --op-text-2: #586274;    /* 6.1:1 on white */
    --op-text-3: #6b7587;    /* 4.7:1 on white */

    /* accent (brand blue) and states */
    --op-accent: #1f63d6;        /* text / links: 5.5:1 on white */
    --op-accent-hover: #1850b3;
    --op-accent-fill: #1f63d6;   /* filled buttons, badges (white text ≥ 4.5:1) */
    --op-accent-soft: #e4edfc;
    --op-on-accent: #ffffff;
    --op-focus: #2f7bff;         /* focus rings (≥ 3:1 against the surfaces) */
    --op-ring: 0 0 0 2px var(--op-surface), 0 0 0 4px var(--op-focus);
    --op-mark: #ffe58f;          /* search matches */
    --op-warn: #9a6700;

    /* elevation */
    --op-shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06);
    --op-shadow: 0 1px 3px rgba(16, 24, 40, 0.1), 0 1px 2px rgba(16, 24, 40, 0.06);
    --op-shadow-lg: 0 16px 40px rgba(16, 24, 40, 0.18), 0 2px 8px rgba(16, 24, 40, 0.08);

    /* chrome of the sidebar of the admin pages (dark in both themes; the viewer windows have --op-bar*) and brand mark */
    --op-chrome: #111722;
    --op-chrome-2: #171e2b;
    --op-chrome-border: rgba(255, 255, 255, 0.07);
    --op-chrome-text: #c3cbd8;
    --op-brand-1: #8cbcff;
    --op-brand-2: #3f80f2;
    --op-brand-3: #1c4cb4;

    /* chrome of the viewer windows (top bar, ribbon, vertical side tabs, panel headers): light in the light theme, the
       dark chrome of the viewer in the dark one. The sidebar of the admin pages keeps --op-chrome (dark in both). */
    --op-bar: #eef1f5;                 /* top bar, tab strip of the ribbon */
    --op-bar-2: #f8f9fb;               /* ribbon body and active tab, side tabs, panel headers */
    --op-bar-hover: rgba(16, 24, 40, 0.06);
    --op-text-strong: #0d1220;         /* hovered / emphasised labels (white in the dark theme) */
    --op-border-hover: #aeb7c4;
    /* a tool, toggle or option that is on */
    --op-active-bg: rgba(31, 99, 214, 0.12);
    --op-active-border: rgba(31, 99, 214, 0.5);
    --op-active-fg: #1850b3;           /* 6.6:1 on white */
    /* surfaces floating over the 3D scene (tool menu, flyouts, legends, statistics, chips, floating panels): their own
       near-opaque panel, readable on any scene background */
    --op-float-bg: rgba(255, 255, 255, 0.95);
    --op-float-fg: #1b2130;
    --op-shadow-float: 0 0.5rem 1.5rem rgba(16, 24, 40, 0.18), 0 0 0 1px rgba(16, 24, 40, 0.04);
    --op-backdrop: rgba(16, 24, 40, 0.32);   /* behind modal dialogs */
    --op-danger-float-bg: rgba(253, 238, 236, 0.97);
    --op-danger-float-fg: #b1261b;
    --op-danger-float-border: #ef9f95;
    /* the stage behind the canvas (seen while a model loads; the scene background is the viewer setting) */
    --op-stage-bg: radial-gradient(circle at 50% 40%, #ffffff 0%, #e3e8ef 72%);

    /* trees (solid colours: the "type" badge of the IFC icons is knocked out with the row background) */
    --op-tree-bg: var(--op-surface);
    --op-tree-hover: var(--op-hover);
    --op-tree-selected: var(--op-selected);
    --op-tree-selected-bar: var(--op-accent);
    --op-count-bg: var(--op-surface-3);
    --op-count-fg: var(--op-text-2);

    /* tones: soft semantic colours for statuses, severities, counters and callouts (fg ≥ 4.5:1 on its bg). The same
       names exist in the dark set, so a ".tone-danger" badge reads the same on the admin pages and in the viewer. */
    --op-success-fg: #17633a;
    --op-success-bg: #e8f6ee;
    --op-success-border: #bfe4cd;
    --op-success-dot: #1f9d55;
    --op-warning-fg: #7a4f00;
    --op-warning-bg: #fdf4de;
    --op-warning-border: #f1d79c;
    --op-warning-dot: #e0a100;
    --op-danger-fg: #b1261b;
    --op-danger-bg: #fdeeec;
    --op-danger-border: #f5c9c3;
    --op-danger-dot: #d92d20;
    --op-info-fg: #0a5f78;
    --op-info-bg: #e4f4f8;
    --op-info-border: #b7dfea;
    --op-info-dot: #1597bb;
    --op-neutral-fg: #4a5467;
    --op-neutral-bg: #eef1f5;
    --op-neutral-border: #dce1e8;
    --op-neutral-dot: #8a94a6;
    --op-accent-fg: #1850b3;
    --op-accent-bg: #e8effc;
    --op-accent-border: #c6d7f7;
    --op-accent-dot: #1f63d6;
    /* origins of the checks (tags beside the groups of problems): hues kept apart from the severities */
    --op-violet-fg: #6b35b8;
    --op-violet-bg: #f2ebfc;
    --op-violet-border: #dccbf4;
    --op-teal-fg: #0f6e66;
    --op-teal-bg: #e3f4f2;
    --op-teal-border: #bde3dd;

    /* IFC schemas (chips): not statuses, so they borrow the calm hues of the IFC icon families */
    --op-schema-ifc2x3: #6f42c1;
    --op-schema-ifc4: #1f63d6;
    --op-schema-ifc4x3: #0b7c83;
    --op-schema-other: #52627a;

    /* sticky offsets: page tables stick under the top bar. --op-page-top is what stays fixed above the page: the top bar,
       on phones also the bar of the sidebar (--op-mobile-bar-h, brand and menu button) */
    --op-topbar-h: 3.5rem;
    --op-mobile-bar-h: 3.5rem;
    --op-page-top: var(--op-topbar-h);
    --op-zebra: #fafbfc;

    /* ── Bootstrap bridge ── */
    --bs-body-font-family: var(--op-font-sans);
    --bs-font-sans-serif: var(--op-font-sans);
    --bs-font-monospace: var(--op-font-mono);
    --bs-body-font-size: var(--op-text-base);
    --bs-body-line-height: 1.5;
    --bs-body-color: var(--op-text);
    --bs-body-color-rgb: 27, 33, 48;
    --bs-emphasis-color: #0d1220;
    --bs-secondary-color: var(--op-text-2);
    --bs-tertiary-color: var(--op-text-3);
    --bs-border-color: var(--op-border);
    --bs-border-color-translucent: rgba(16, 24, 40, 0.1);
    --bs-border-radius: var(--op-radius);
    --bs-border-radius-sm: var(--op-radius-sm);
    --bs-border-radius-lg: var(--op-radius-lg);
    --bs-primary: #1f63d6;
    --bs-primary-rgb: 31, 99, 214;
    --bs-link-color: var(--op-accent);
    --bs-link-color-rgb: 31, 99, 214;
    --bs-link-hover-color: var(--op-accent-hover);
    --bs-link-hover-color-rgb: 24, 80, 179;
    --bs-focus-ring-color: rgba(47, 123, 255, 0.35);
    --bs-heading-color: var(--op-text);

    /* legacy aliases (older component styles) */
    --opera-border: var(--op-border);
    --opera-muted-bg: var(--op-surface-2);
    --opera-selected: var(--op-selected);
    --opera-accent: var(--op-accent);
}

@media (max-width: 640.98px) {
    :root {
        --op-page-top: calc(var(--op-mobile-bar-h) + var(--op-topbar-h));
    }
}

[data-bs-theme=dark] {
    --op-bg: #12161d;
    --op-surface: #181d25;
    --op-surface-2: #1e242d;
    --op-surface-3: #2a313c;
    --op-hover: #232a34;
    --op-selected: #1c3a6c;
    --op-selected-hover: #214379;
    --op-border: #2a313c;
    --op-border-strong: #3b4351;
    --op-text: #e6e9ef;
    --op-text-2: #a4adbb;    /* 7.4:1 on the panels */
    --op-text-3: #838d9c;    /* 4.8:1 on the panels */

    --op-accent: #5b97ff;        /* links on the panels: 5.9:1 */
    --op-accent-hover: #7eadff;
    --op-accent-fill: #2d6ce0;   /* white text 4.8:1 */
    --op-accent-soft: rgba(91, 151, 255, 0.16);
    --op-focus: #6aa3ff;
    --op-mark: rgba(255, 193, 7, 0.36);
    --op-warn: #f0c050;

    --op-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --op-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
    --op-shadow-lg: 0 18px 48px rgba(0, 0, 0, 0.55), 0 2px 8px rgba(0, 0, 0, 0.35);

    --op-chrome: #0f131a;
    --op-chrome-2: #141922;

    --op-bar: #0f131a;
    --op-bar-2: #141922;
    --op-bar-hover: rgba(255, 255, 255, 0.1);
    --op-text-strong: #ffffff;
    --op-border-hover: #4a5364;
    --op-active-bg: rgba(91, 151, 255, 0.22);
    --op-active-border: rgba(91, 151, 255, 0.55);
    --op-active-fg: #ffffff;
    --op-float-bg: rgba(17, 21, 28, 0.93);
    --op-float-fg: #e6e9ef;
    --op-shadow-float: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(0, 0, 0, 0.25);
    --op-backdrop: rgba(11, 15, 22, 0.42);
    --op-danger-float-bg: rgba(60, 18, 22, 0.94);
    --op-danger-float-fg: #ffd0d0;
    --op-danger-float-border: rgba(255, 120, 120, 0.55);
    --op-stage-bg: radial-gradient(circle at 50% 40%, #293142 0%, #12161d 72%);

    --op-tree-bg: #151a21;
    --op-tree-hover: #212833;
    --op-tree-selected: #1c3a6c;
    --op-tree-selected-bar: #5b97ff;
    --op-count-bg: #262d38;
    --op-count-fg: #aeb6c3;

    /* tones on the dark panels: tinted, never a saturated block (fg ≥ 4.5:1 on the tinted panel) */
    --op-success-fg: #74d9a0;
    --op-success-bg: rgba(62, 207, 130, 0.13);
    --op-success-border: rgba(62, 207, 130, 0.3);
    --op-success-dot: #3ecf82;
    --op-warning-fg: #f1c65a;
    --op-warning-bg: rgba(240, 180, 41, 0.13);
    --op-warning-border: rgba(240, 180, 41, 0.3);
    --op-warning-dot: #f0b429;
    --op-danger-fg: #ff9a91;
    --op-danger-bg: rgba(255, 107, 94, 0.14);
    --op-danger-border: rgba(255, 107, 94, 0.32);
    --op-danger-dot: #ff6b5e;
    --op-info-fg: #74d3ea;
    --op-info-bg: rgba(76, 195, 224, 0.13);
    --op-info-border: rgba(76, 195, 224, 0.3);
    --op-info-dot: #4cc3e0;
    --op-neutral-fg: #b8c0cc;
    --op-neutral-bg: rgba(255, 255, 255, 0.07);
    --op-neutral-border: rgba(255, 255, 255, 0.13);
    --op-neutral-dot: #8a94a6;
    --op-accent-fg: #a3c6ff;
    --op-accent-bg: rgba(91, 151, 255, 0.15);
    --op-accent-border: rgba(91, 151, 255, 0.34);
    --op-accent-dot: #5b97ff;
    --op-violet-fg: #cdb4ff;
    --op-violet-bg: rgba(160, 120, 255, 0.16);
    --op-violet-border: rgba(160, 120, 255, 0.36);
    --op-teal-fg: #7fdccf;
    --op-teal-bg: rgba(60, 200, 180, 0.14);
    --op-teal-border: rgba(60, 200, 180, 0.34);

    --op-schema-ifc2x3: #b99cf2;
    --op-schema-ifc4: #7eadff;
    --op-schema-ifc4x3: #52d0cb;
    --op-schema-other: #b1bfd0;

    --op-zebra: rgba(255, 255, 255, 0.025);

    --bs-body-bg: var(--op-surface);
    --bs-body-bg-rgb: 24, 29, 37;
    --bs-body-color: var(--op-text);
    --bs-body-color-rgb: 230, 233, 239;
    --bs-emphasis-color: #ffffff;
    --bs-secondary-color: var(--op-text-2);
    --bs-tertiary-color: var(--op-text-3);
    --bs-secondary-bg: var(--op-surface-3);
    --bs-tertiary-bg: var(--op-surface-2);
    --bs-border-color: var(--op-border);
    --bs-border-color-translucent: rgba(255, 255, 255, 0.1);
    --bs-link-color: var(--op-accent);
    --bs-link-color-rgb: 91, 151, 255;
    --bs-link-hover-color: var(--op-accent-hover);
    --bs-link-hover-color-rgb: 126, 173, 255;
    --bs-heading-color: var(--op-text);
    --bs-focus-ring-color: rgba(106, 163, 255, 0.4);
}

@media (prefers-reduced-motion: reduce) {
    :root {
        --op-dur: 0ms;
    }
}

/* ───────────────────────── 2. base and Bootstrap components ───────────────────────── */

html, body {
    font-family: var(--op-font-sans);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, .h1, h2, .h2, h3, .h3 {
    letter-spacing: -0.012em;
    font-weight: 600;
}

h1:focus {
    outline: none;
}

.h3 {
    font-size: var(--op-text-xl);
}

code {
    color: var(--op-text);
    background: var(--op-surface-3);
    padding: 0.05em 0.3em;
    border-radius: var(--op-radius-sm);
}

pre code {
    color: inherit;
    background: none;
    padding: 0;
}

a, .btn-link {
    color: var(--op-accent);
}

    a:hover, .btn-link:hover {
        color: var(--op-accent-hover);
    }

/* focus: a clear ring for keyboard users (WCAG 2.4.7), nothing on mouse clicks. Listed per element type on purpose: a
   bare ":focus-visible" (or "::selection") rule is matched against every element and measurably slows the style
   recalculation of the virtualized tree rows. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--op-focus);
    outline-offset: 2px;
}

.btn:focus-visible,
.btn-check:focus-visible + .btn,
.btn-link.nav-link:focus-visible,
.nav-link:focus-visible,
.page-link:focus-visible,
.btn-close:focus-visible {
    outline: none;
    box-shadow: var(--op-ring);
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
    border-color: var(--op-focus);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--op-focus) 28%, transparent);
}

.form-control, .form-select {
    border-color: var(--op-border-strong);
}

.form-control-sm, .form-select-sm {
    font-size: var(--op-text-sm);
}

.form-check-input:checked {
    background-color: var(--op-accent-fill);
    border-color: var(--op-accent-fill);
}

/* buttons */
.btn {
    --bs-btn-font-weight: 500;
    --bs-btn-border-radius: var(--op-radius);
    transition: color var(--op-dur) var(--op-ease), background-color var(--op-dur) var(--op-ease),
        border-color var(--op-dur) var(--op-ease), box-shadow var(--op-dur) var(--op-ease);
}

.btn-sm {
    --bs-btn-font-size: var(--op-text-sm);
    --bs-btn-padding-y: 0.25rem;
    --bs-btn-padding-x: 0.625rem;
    --bs-btn-border-radius: var(--op-radius);
}

.btn-primary {
    --bs-btn-color: var(--op-on-accent);
    --bs-btn-bg: var(--op-accent-fill);
    --bs-btn-border-color: var(--op-accent-fill);
    --bs-btn-hover-color: var(--op-on-accent);
    --bs-btn-hover-bg: var(--op-accent-hover);
    --bs-btn-hover-border-color: var(--op-accent-hover);
    --bs-btn-active-color: var(--op-on-accent);
    --bs-btn-active-bg: var(--op-accent-hover);
    --bs-btn-active-border-color: var(--op-accent-hover);
    --bs-btn-disabled-color: var(--op-on-accent);
    --bs-btn-disabled-bg: var(--op-accent-fill);
    --bs-btn-disabled-border-color: var(--op-accent-fill);
    box-shadow: var(--op-shadow-sm);
}

.btn-outline-primary {
    --bs-btn-color: var(--op-accent);
    --bs-btn-border-color: color-mix(in srgb, var(--op-accent) 55%, transparent);
    --bs-btn-hover-color: var(--op-on-accent);
    --bs-btn-hover-bg: var(--op-accent-fill);
    --bs-btn-hover-border-color: var(--op-accent-fill);
    --bs-btn-active-color: var(--op-on-accent);
    --bs-btn-active-bg: var(--op-accent-fill);
    --bs-btn-active-border-color: var(--op-accent-fill);
    --bs-btn-disabled-color: var(--op-accent);
    --bs-btn-disabled-border-color: var(--op-border-strong);
}

.btn-outline-secondary {
    --bs-btn-color: var(--op-text);
    --bs-btn-bg: var(--op-surface);
    --bs-btn-border-color: var(--op-border-strong);
    --bs-btn-hover-color: var(--op-text);
    --bs-btn-hover-bg: var(--op-hover);
    --bs-btn-hover-border-color: var(--op-border-strong);
    --bs-btn-active-color: var(--op-text);
    --bs-btn-active-bg: var(--op-surface-3);
    --bs-btn-active-border-color: var(--op-border-strong);
    --bs-btn-disabled-color: var(--op-text-3);
    --bs-btn-disabled-bg: var(--op-surface);
    --bs-btn-disabled-border-color: var(--op-border);
}

.btn-outline-danger {
    --bs-btn-bg: var(--op-surface);
    --bs-btn-border-color: color-mix(in srgb, var(--bs-danger) 45%, transparent);
}

/* tables */
.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--op-text);
    --bs-table-border-color: var(--op-border);
    --bs-table-hover-bg: var(--op-hover);
    --bs-table-hover-color: var(--op-text);
    --bs-table-striped-bg: var(--op-surface-2);
}

    .table > thead th {
        font-size: var(--op-text-xs);
        font-weight: 600;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        color: var(--op-text-2);
        border-bottom-color: var(--op-border-strong);
        vertical-align: bottom;
    }

    .table a:not(.btn) {
        text-decoration: none;
    }

        .table a:not(.btn):hover {
            text-decoration: underline;
        }

.table > caption.visually-hidden {
    caption-side: top;
}

/* data tables of the admin pages: sticky header (under the top bar, or at the top of a scrolling container with
   .op-table-scroll), subtle zebra, tabular figures; numbers right-aligned with .num, monospace only for ids */
.op-table {
    --bs-table-striped-bg: var(--op-zebra);
    --bs-table-hover-bg: var(--op-hover);
    font-variant-numeric: tabular-nums;
    margin-bottom: 0;
}

    .op-table > thead > tr > th {
        position: sticky;
        top: var(--op-sticky-top, var(--op-page-top));
        z-index: 2;
        background: var(--op-surface);
        box-shadow: inset 0 -1px 0 var(--op-border-strong);
        border-bottom-width: 0;
        white-space: nowrap;
        padding-top: 0.55rem;
        padding-bottom: 0.45rem;
    }

    .op-table > tbody > tr > td,
    .op-table > tbody > tr > th {
        padding-top: 0.6rem;
        padding-bottom: 0.6rem;
    }

    .op-table.table-sm > tbody > tr > td,
    .op-table.table-sm > tbody > tr > th {
        padding-top: 0.35rem;
        padding-bottom: 0.35rem;
    }

    .op-table > tbody > tr:last-child > * {
        border-bottom-width: 0;
    }

    .op-table .num {
        text-align: right;
        white-space: nowrap;
    }

    .op-table .sub {
        display: block;
        font-size: var(--op-text-xs);
        color: var(--op-text-3);
        margin-top: 0.1rem;
    }

    .op-table .row-actions {
        text-align: right;
        white-space: nowrap;
        width: 1%;
    }

    .op-table.table-hover > tbody > tr {
        transition: background-color var(--op-dur) var(--op-ease);
    }

/* below lg a .table-responsive-lg card scrolls horizontally: it becomes the sticky container, its header sticks at 0 */
@media (max-width: 991.98px) {
    .table-responsive-lg > .op-table {
        --op-sticky-top: 0px;
    }
}

.op-table-scroll {
    --op-sticky-top: 0px;
    overflow: auto;
    scrollbar-width: thin;
}

/* a table inside a card: the card draws the frame, the table fills it */
.table-card {
    /* the containing block of what the cells position absolutely (the visually hidden headers of the action columns):
       under 992 px the card scrolls sideways (table-responsive-lg) and keeps them inside, otherwise they would widen the
       page on phones (and the fixed bars would slide with the zoomed-out page) */
    position: relative;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    background: var(--op-surface);
    box-shadow: var(--op-shadow-sm);
}

    .table-card > .op-table > thead > tr > th:first-child,
    .table-card > .op-table > tbody > tr > *:first-child,
    .table-card > div > .op-table > thead > tr > th:first-child,
    .table-card > div > .op-table > tbody > tr > *:first-child {
        padding-left: 0.9rem;
    }

    .table-card > .op-table > thead > tr > th:last-child,
    .table-card > .op-table > tbody > tr > *:last-child,
    .table-card > div > .op-table > thead > tr > th:last-child,
    .table-card > div > .op-table > tbody > tr > *:last-child {
        padding-right: 0.9rem;
    }

    .table-card > .op-table > thead > tr > th:first-child {
        border-top-left-radius: var(--op-radius-lg);
    }

    .table-card > .op-table > thead > tr > th:last-child {
        border-top-right-radius: var(--op-radius-lg);
    }

/* below lg the page tables scroll sideways inside their card, so their header stops sticking (acceptable on narrow windows) */
@media (max-width: 991.98px) {
    .table-card.table-responsive-lg {
        overflow-x: auto;
    }

        .table-card.table-responsive-lg > .op-table > thead > tr > th {
            position: static;
        }
}

/* cards: white sheets with a hairline border; their title is a small label, like the viewer panel headers */
.card {
    --bs-card-border-color: var(--op-border);
    --bs-card-border-radius: var(--op-radius-lg);
    --bs-card-inner-border-radius: calc(var(--op-radius-lg) - 1px);
    --bs-card-cap-bg: var(--op-surface-2);
    --bs-card-bg: var(--op-surface);
    box-shadow: var(--op-shadow-sm);
}

.card-title.h6,
h2.card-title,
h3.card-title {
    font-size: var(--op-text-xs);
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--op-text-2);
    margin-bottom: var(--op-space-3);
}

/* breadcrumb */
.breadcrumb {
    --bs-breadcrumb-divider-color: var(--op-text-3);
    --bs-breadcrumb-item-active-color: var(--op-text-2);
    --bs-breadcrumb-item-padding-x: 0.4rem;
}

    .breadcrumb a {
        text-decoration: none;
    }

        .breadcrumb a:hover {
            text-decoration: underline;
        }

/* badges, alerts, list groups, pagination */
.badge {
    font-weight: 600;
    letter-spacing: 0.01em;
}

.alert {
    --bs-alert-border-radius: var(--op-radius);
    --bs-alert-padding-y: 0.65rem;
    --bs-alert-padding-x: 0.9rem;
}

/* alerts follow the tones: the same soft callout on the light pages and on the dark viewer */
.alert-success { --bs-alert-color: var(--op-success-fg); --bs-alert-bg: var(--op-success-bg); --bs-alert-border-color: var(--op-success-border); --bs-alert-link-color: var(--op-success-fg); }
.alert-warning { --bs-alert-color: var(--op-warning-fg); --bs-alert-bg: var(--op-warning-bg); --bs-alert-border-color: var(--op-warning-border); --bs-alert-link-color: var(--op-warning-fg); }
.alert-danger { --bs-alert-color: var(--op-danger-fg); --bs-alert-bg: var(--op-danger-bg); --bs-alert-border-color: var(--op-danger-border); --bs-alert-link-color: var(--op-danger-fg); }
.alert-info { --bs-alert-color: var(--op-info-fg); --bs-alert-bg: var(--op-info-bg); --bs-alert-border-color: var(--op-info-border); --bs-alert-link-color: var(--op-info-fg); }
.alert-secondary,
.alert-light { --bs-alert-color: var(--op-text-2); --bs-alert-bg: var(--op-surface-2); --bs-alert-border-color: var(--op-border); --bs-alert-link-color: var(--op-accent); }

    .alert strong {
        color: inherit;
    }

.op-badge {
    --tone-fg: var(--op-neutral-fg);
    --tone-bg: var(--op-neutral-bg);
    --tone-border: var(--op-neutral-border);
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.12rem 0.45rem;
    border-radius: var(--op-radius-sm);
    font-size: var(--op-text-2xs);
    font-weight: 600;
    line-height: 1.35;
    white-space: nowrap;
    vertical-align: middle;
    color: var(--tone-fg);
    background: var(--tone-bg);
    box-shadow: inset 0 0 0 1px var(--tone-border);
    font-variant-numeric: tabular-nums;
}

    .op-badge.pill {
        border-radius: var(--op-radius-pill);
        padding-inline: 0.5rem;
    }

    .op-badge.mono {
        font-family: var(--op-font-mono);
        font-weight: 500;
    }

    .op-badge .op-icon {
        width: 0.8rem;
        height: 0.8rem;
    }

.op-dot {
    display: inline-block;
    flex: 0 0 auto;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--tone-dot, var(--op-neutral-dot));
}

/* numeric counter next to a label (tabs, sections, filters) */
.op-count {
    --tone-fg: var(--op-count-fg);
    --tone-bg: var(--op-count-bg);
    display: inline-block;
    min-width: 1.35rem;
    padding: 0 0.4rem;
    border-radius: var(--op-radius-pill);
    font-size: var(--op-text-2xs);
    font-weight: 600;
    line-height: 1.15rem;
    text-align: center;
    color: var(--tone-fg);
    background: var(--tone-bg);
    font-variant-numeric: tabular-nums;
}

    .op-count.tone-danger,
    .op-count.tone-warning,
    .op-count.tone-accent,
    .op-count.tone-success,
    .op-count.tone-info {
        box-shadow: inset 0 0 0 1px var(--tone-border);
    }

/* callout: an alert with an icon, for notes that explain a state (e.g. "IFC unito non disponibile") */
.op-callout {
    --tone-fg: var(--op-text-2);
    --tone-bg: var(--op-surface-2);
    --tone-border: var(--op-border);
    display: flex;
    gap: 0.6rem;
    align-items: flex-start;
    padding: 0.6rem 0.8rem;
    border-radius: var(--op-radius);
    border: 1px solid var(--tone-border);
    background: var(--tone-bg);
    color: var(--tone-fg);
    font-size: var(--op-text-sm);
    line-height: 1.45;
}

    .op-callout > .op-icon {
        margin-top: 0.1rem;
        color: var(--tone-dot, currentColor);
    }

    .op-callout strong {
        color: inherit;
    }

/* the dark viewer windows still use a few Bootstrap .text-bg-* badges: give them the tinted tones instead of saturated
   blocks (the tree-row counters keep their own lighter rule, no box-shadow per row) */
[data-bs-theme=dark] .badge.text-bg-success:not(.tree-sources) { color: var(--op-success-fg) !important; background-color: var(--op-success-bg) !important; box-shadow: inset 0 0 0 1px var(--op-success-border); }
[data-bs-theme=dark] .badge.text-bg-warning:not(.tree-sources) { color: var(--op-warning-fg) !important; background-color: var(--op-warning-bg) !important; box-shadow: inset 0 0 0 1px var(--op-warning-border); }
[data-bs-theme=dark] .badge.text-bg-danger:not(.tree-sources) { color: var(--op-danger-fg) !important; background-color: var(--op-danger-bg) !important; box-shadow: inset 0 0 0 1px var(--op-danger-border); }
[data-bs-theme=dark] .badge.text-bg-info:not(.tree-sources) { color: var(--op-info-fg) !important; background-color: var(--op-info-bg) !important; box-shadow: inset 0 0 0 1px var(--op-info-border); }
[data-bs-theme=dark] .badge.text-bg-primary:not(.tree-sources) { color: var(--op-accent-fg) !important; background-color: var(--op-accent-bg) !important; box-shadow: inset 0 0 0 1px var(--op-accent-border); }
[data-bs-theme=dark] .badge.text-bg-secondary:not(.tree-sources),
[data-bs-theme=dark] .badge.text-bg-light:not(.tree-sources) { color: var(--op-neutral-fg) !important; background-color: var(--op-neutral-bg) !important; box-shadow: inset 0 0 0 1px var(--op-neutral-border); }

.list-group {
    --bs-list-group-border-color: var(--op-border);
    --bs-list-group-active-bg: var(--op-accent-fill);
    --bs-list-group-active-border-color: var(--op-accent-fill);
    --bs-list-group-action-hover-bg: var(--op-hover);
}

.pagination {
    --bs-pagination-active-bg: var(--op-accent-fill);
    --bs-pagination-active-border-color: var(--op-accent-fill);
    --bs-pagination-color: var(--op-accent);
    --bs-pagination-border-color: var(--op-border-strong);
}

.progress {
    --bs-progress-bg: var(--op-surface-3);
    --bs-progress-bar-bg: var(--op-accent-fill);
    --bs-progress-border-radius: var(--op-radius-pill);
}

.placeholder {
    border-radius: var(--op-radius-sm);
    background-color: var(--op-text-3);
    opacity: 0.22;
}

/* modals (rendered by Blazor, see Shared/Modal.razor): above the floating windows (.pk-dialog, z-index 1060, of the SDK),
   since a modal asks something of a window (the confirmation of a deletion), below the toasts (1090) */
.modal {
    --bs-modal-zindex: 1075;
    --bs-modal-bg: var(--op-surface);
    --bs-modal-border-color: var(--op-border);
    --bs-modal-border-radius: var(--op-radius-lg);
    --bs-modal-inner-border-radius: calc(var(--op-radius-lg) - 1px);
    --bs-modal-header-border-color: var(--op-border);
    --bs-modal-footer-border-color: var(--op-border);
    --bs-modal-header-padding: 0.85rem 1.25rem;
    --bs-modal-padding: 1.25rem;
}

    .modal .modal-content.shadow {
        box-shadow: var(--op-shadow-lg) !important;
    }

    .modal .modal-title {
        font-weight: 600;
        letter-spacing: -0.01em;
    }

.modal-backdrop {
    --bs-backdrop-zindex: 1070;
    --bs-backdrop-bg: #0b0f16;
    --bs-backdrop-opacity: 0.5;
}

.modal.d-block {
    overflow-y: auto;
}

.modal:focus {
    outline: none;
}

/* forms: validation */
.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--op-success-dot);
}

.invalid {
    outline: 1px solid var(--op-danger-dot);
}

.validation-message {
    color: var(--op-danger-fg);
}

.darker-border-checkbox.form-check-input {
    border-color: var(--op-text-3);
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "Si è verificato un errore."
    }

/* ───────────────────────── 3. Opera components ───────────────────────── */

.content {
    padding-top: 1.25rem;
}

.skip-link {
    position: absolute;
    top: 0.5rem;
    left: 0.5rem;
    z-index: 2000;
    background: var(--op-surface);
    padding: 0.5rem 1rem;
    border-radius: var(--op-radius);
    box-shadow: var(--op-ring);
}

#main-content:focus {
    outline: none;
}

.min-w-0 {
    min-width: 0;
}

/* status of a version: soft badge with a coloured dot (StatusBadge) */
.status-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.22rem 0.55rem 0.22rem 0.45rem;
    border-radius: var(--op-radius-pill);
    font-size: var(--op-text-2xs);
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    vertical-align: middle;
    color: var(--st-fg);
    background: var(--st-bg);
    box-shadow: inset 0 0 0 1px var(--st-border);
}

    .status-badge::before {
        content: "";
        flex: 0 0 auto;
        width: 0.45rem;
        height: 0.45rem;
        border-radius: 50%;
        background: var(--st-dot);
    }

    .status-badge.has-spinner::before {
        display: none;
    }

    .status-badge .spinner-grow-sm {
        width: 0.5rem;
        height: 0.5rem;
        margin: 0 !important;
        color: var(--st-dot);
    }

.status-success { --st-fg: var(--op-success-fg); --st-bg: var(--op-success-bg); --st-border: var(--op-success-border); --st-dot: var(--op-success-dot); }
.status-primary { --st-fg: var(--op-accent-fg); --st-bg: var(--op-accent-bg); --st-border: var(--op-accent-border); --st-dot: var(--op-accent-dot); }
.status-danger { --st-fg: var(--op-danger-fg); --st-bg: var(--op-danger-bg); --st-border: var(--op-danger-border); --st-dot: var(--op-danger-dot); }
.status-warning { --st-fg: var(--op-warning-fg); --st-bg: var(--op-warning-bg); --st-border: var(--op-warning-border); --st-dot: var(--op-warning-dot); }
.status-secondary { --st-fg: var(--op-neutral-fg); --st-bg: var(--op-neutral-bg); --st-border: var(--op-neutral-border); --st-dot: var(--op-neutral-dot); }

/* ── pager ── */
.pager-input {
    width: 5rem;
}

/* ── stage timeline: proportional bar + dense list ── */
.stage-bar {
    display: flex;
    gap: 2px;
    height: 0.5rem;
    margin: 0.1rem 0 0.85rem;
    border-radius: var(--op-radius-pill);
    overflow: hidden;
    background: var(--op-surface-3);
}

.stage-seg {
    flex: 1 1 0;
    min-width: 3px;
    background: var(--op-border-strong);
}

    .stage-seg.seg-done {
        background: var(--op-accent-fill);
    }

        .stage-seg.seg-done:nth-child(even) {
            background: color-mix(in srgb, var(--op-accent-fill) 62%, var(--op-surface));
        }

    .stage-seg.seg-current {
        background: repeating-linear-gradient(-45deg, var(--op-accent-fill) 0 6px, color-mix(in srgb, var(--op-accent-fill) 55%, var(--op-surface)) 6px 12px);
        background-size: 17px 100%;
        animation: stage-stripes 0.9s linear infinite;
    }

    .stage-seg.seg-failed {
        background: var(--op-danger-dot);
    }

    .stage-seg.seg-cancelled {
        background: var(--op-warning-dot);
    }

    .stage-seg.seg-pending {
        background: var(--op-surface-3);
    }

@keyframes stage-stripes {
    to { background-position: 17px 0; }
}

.stage-timeline .stage {
    display: flex;
    gap: 0.6rem;
    position: relative;
    padding-bottom: 0.5rem;
}

    .stage-timeline .stage:not(:last-child)::before {
        content: "";
        position: absolute;
        left: calc(0.5625rem - 1px);
        top: 1.3rem;
        bottom: 0.1rem;
        width: 2px;
        border-radius: 1px;
        background: var(--op-border);
    }

    .stage-timeline .stage-done:not(:last-child)::before {
        background: color-mix(in srgb, var(--op-success-dot) 40%, var(--op-border));
    }

.stage-marker {
    flex: 0 0 1.125rem;
    height: 1.125rem;
    margin-top: 0.1rem;
    border-radius: 50%;
    border: 1.5px solid var(--op-border-strong);
    background: var(--op-surface);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.62rem;
    font-weight: 700;
    line-height: 1;
    color: #fff;
}

.stage-body {
    flex: 1;
    min-width: 0;
}

.stage-line {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    min-width: 0;
    font-size: var(--op-text-sm);
    line-height: 1.35rem;
}

.stage-name {
    flex: 0 0 auto;
    font-weight: 600;
    color: var(--op-text);
}

.stage-desc {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--op-text-3);
    font-size: var(--op-text-xs);
}

.stage-duration {
    flex: 0 0 auto;
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    font-size: var(--op-text-xs);
    color: var(--op-text-2);
}

.stage-message {
    margin-top: 0.2rem;
    font-size: var(--op-text-xs);
    color: var(--op-text-2);
}

.stage-error {
    margin-top: 0.25rem;
    padding: 0.4rem 0.55rem;
    border-radius: var(--op-radius-sm);
    font-size: var(--op-text-xs);
    color: var(--op-danger-fg);
    background: var(--op-danger-bg);
    word-break: break-word;
}

.stage-total {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.35rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--op-border);
    font-size: var(--op-text-xs);
    color: var(--op-text-2);
}

    .stage-total strong {
        color: var(--op-text);
        font-variant-numeric: tabular-nums;
    }

.stage-done .stage-marker {
    background: var(--op-success-dot);
    border-color: var(--op-success-dot);
}

.stage-current .stage-marker {
    background: var(--op-surface);
    border: 2px solid var(--op-accent-fill);
    animation: stage-pulse 1.4s ease-in-out infinite;
}

    .stage-current .stage-marker::after {
        content: "";
        width: 0.4rem;
        height: 0.4rem;
        border-radius: 50%;
        background: var(--op-accent-fill);
    }

.stage-current .stage-name {
    color: var(--op-accent);
}

.stage-failed .stage-marker {
    background: var(--op-danger-dot);
    border-color: var(--op-danger-dot);
}

.stage-failed .stage-name,
.stage-failed .stage-duration {
    color: var(--op-danger-fg);
}

.stage-cancelled .stage-marker {
    background: var(--op-warning-dot);
    border-color: var(--op-warning-dot);
}

.stage-skipped .stage-marker {
    border-style: dashed;
}

.stage-pending .stage-name,
.stage-skipped .stage-name {
    color: var(--op-text-2);
    font-weight: 500;
}

@keyframes stage-pulse {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--op-accent-fill) 45%, transparent); }
    50% { box-shadow: 0 0 0 0.3rem color-mix(in srgb, var(--op-accent-fill) 0%, transparent); }
}

@media (prefers-reduced-motion: reduce) {
    .stage-current .stage-marker,
    .stage-seg.seg-current { animation: none; }
}

/* ── stats: counter tiles (version page, viewer info dialog) and KPI tiles (home) ── */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
    gap: 0.5rem;
}

/* one row of tiles when there is room (version page) */
.stats-grid.stats-row {
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
}

.details-quality {
    margin-top: auto;
    padding-top: 1rem;
}

.details-subtitle {
    font-size: var(--op-text-xs);
    font-weight: 600;
    color: var(--op-text-2);
    margin: 0 0 0.45rem;
}

.stat-cell {
    display: flex;
    min-width: 0;
}

.stat-tile {
    --tone-fg: var(--op-text);
    --tone-dot: var(--op-text-3);
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    width: 100%;
    min-width: 0;
    padding: 0.55rem 0.75rem 0.6rem;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    background: var(--op-surface);
    box-shadow: var(--op-shadow-sm);
    text-align: left;
    color: var(--op-text);
    overflow: hidden;
}

    /* diagnostic tiles with something to report: a slim coloured stripe and the value in the tone */
    .stat-tile[class*=tone-]::before {
        content: "";
        position: absolute;
        inset: 0 auto 0 0;
        width: 3px;
        background: var(--tone-dot);
    }

    .stat-tile[class*=tone-] .stat-value {
        color: var(--tone-fg);
    }

    .stat-tile.is-link {
        cursor: pointer;
        transition: border-color var(--op-dur) var(--op-ease), box-shadow var(--op-dur) var(--op-ease), transform var(--op-dur) var(--op-ease);
    }

        .stat-tile.is-link:hover {
            border-color: var(--op-border-strong);
            box-shadow: var(--op-shadow);
        }

        .stat-tile.is-link::after {
            content: "";
            position: absolute;
            top: 0.7rem;
            right: 0.7rem;
            width: 0.35rem;
            height: 0.35rem;
            border-right: 1.5px solid var(--op-text-3);
            border-top: 1.5px solid var(--op-text-3);
            transform: rotate(45deg);
            opacity: 0;
            transition: opacity var(--op-dur) var(--op-ease);
        }

        .stat-tile.is-link:hover::after,
        .stat-tile.is-link:focus-visible::after {
            opacity: 1;
        }

.stat-label {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    min-width: 0;
    font-size: var(--op-text-xs);
    font-weight: 500;
    color: var(--op-text-2);
    white-space: nowrap;
}

    .stat-label > span {
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .stat-label .op-icon {
        width: 0.85rem;
        height: 0.85rem;
        color: var(--op-text-3);
    }

.stat-value {
    font-size: 1.3rem;
    font-weight: 650;
    letter-spacing: -0.015em;
    font-variant-numeric: tabular-nums;
    line-height: 1.25;
}

.stat-sub {
    font-size: var(--op-text-2xs);
    color: var(--op-text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── key/value ── */
.kv-table {
    font-size: var(--op-text-md);
}

    .kv-table th {
        width: 38%;
        font-weight: 500;
        color: var(--op-text-2);
    }

    .kv-table > tbody > tr:last-child > * {
        border-bottom-width: 0;
    }

/* ── tabs: underlined, no boxes; optional icon and counter ── */
.tabset .nav-tabs {
    scrollbar-width: thin;
    gap: 0.15rem;
    border-bottom: 1px solid var(--op-border);
}

    .tabset .nav-tabs .nav-link {
        display: inline-flex;
        align-items: center;
        gap: 0.45rem;
        border: 0;
        border-radius: var(--op-radius) var(--op-radius) 0 0;
        margin: 0;
        padding: 0.55rem 0.8rem;
        color: var(--op-text-2);
        font-weight: 500;
        font-size: var(--op-text-md);
        background: none;
        transition: color var(--op-dur) var(--op-ease), box-shadow var(--op-dur) var(--op-ease), background-color var(--op-dur) var(--op-ease);
    }

        .tabset .nav-tabs .nav-link:hover {
            color: var(--op-text);
            background: var(--op-surface-2);
            box-shadow: inset 0 -2px 0 var(--op-border-strong);
        }

        .tabset .nav-tabs .nav-link.active {
            color: var(--op-accent);
            background: none;
            box-shadow: inset 0 -2px 0 var(--op-accent);
        }

        .tabset .nav-tabs .nav-link:focus-visible {
            box-shadow: inset 0 0 0 2px var(--op-focus);
        }

        .tabset .nav-tabs .nav-link .tab-icon {
            color: var(--op-text-3);
            transition: color var(--op-dur) var(--op-ease);
        }

        .tabset .nav-tabs .nav-link:hover .tab-icon {
            color: var(--op-text-2);
        }

        .tabset .nav-tabs .nav-link.active .tab-icon {
            color: var(--op-accent);
        }

/* ── trees (LazyTree): rows are virtualized, keep them light (no per-row shadows, filters or transitions) ── */
.lazy-tree {
    overflow-y: auto;
    overflow-x: hidden;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    background: var(--op-tree-bg);
    min-height: 20rem;
    position: relative;
    font-size: var(--op-text-sm);
    color: var(--op-text);
    scrollbar-width: thin;
    --ifc-knockout: var(--op-tree-bg);
}

    /* the tree scroller always has a definite size (explicit height, or a flex basis in the viewer): containment makes it
       a relayout boundary, so the rows swapped by the virtualization never re-lay out the rest of the page */
    .lazy-tree[role=tree] {
        contain: strict;
    }

    .lazy-tree:focus-visible {
        outline: 2px solid var(--op-focus);
        outline-offset: 1px;
    }

.tree-row {
    height: 28px;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding-right: 0.4rem;
    white-space: nowrap;
    cursor: pointer;
    box-sizing: border-box;
    border-left: 2px solid transparent;
    user-select: none;
}

    .tree-row:hover {
        background: var(--op-tree-hover);
        --ifc-knockout: var(--op-tree-hover);
    }

    .tree-row.selected {
        background: var(--op-tree-selected);
        border-left-color: var(--op-tree-selected-bar);
        --ifc-knockout: var(--op-tree-selected);
    }

        .tree-row.selected .tree-label {
            font-weight: 600;
        }

.lazy-tree:focus-visible .tree-row.active,
.lazy-tree:focus .tree-row.active {
    outline: 1px solid color-mix(in srgb, var(--op-focus) 70%, transparent);
    outline-offset: -1px;
}

.tree-toggle {
    flex: 0 0 1rem;
    text-align: center;
    font-size: 0.875rem;
    color: var(--op-text-2);
}

    .tree-toggle:hover {
        color: var(--op-text);
    }

.tree-icon {
    width: 16px;
    height: 16px;
}

.tree-label {
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.tree-class {
    font-family: var(--op-font-mono);
    font-size: var(--op-text-2xs);
    color: var(--op-text-3);
    flex: 0 0 auto;
}

.tree-count {
    margin-left: auto;
    flex: 0 0 auto;
    min-width: 1.35rem;
    font-size: var(--op-text-2xs);
    line-height: 1.1rem;
    padding: 0 0.35rem;
    border-radius: var(--op-radius-pill);
    background: var(--op-count-bg);
    color: var(--op-count-fg);
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.tree-row.selected .tree-count {
    background: color-mix(in srgb, var(--op-tree-selected-bar) 22%, transparent);
    color: var(--op-text);
}

.placeholder-row {
    cursor: default;
    padding-left: 1.5rem;
}

/* loading state of a tree: a few skeleton rows */
.tree-skeleton {
    padding: 0.35rem 0;
}

    .tree-skeleton .tree-row {
        cursor: default;
    }

        .tree-skeleton .tree-row:hover {
            background: none;
        }

.tree-empty {
    padding: 1.25rem 1rem;
    text-align: center;
    color: var(--op-text-2);
    font-size: var(--op-text-sm);
}

.tree-row.match .tree-label {
    font-weight: 600;
}

.tree-mark {
    padding: 0 1px;
    border-radius: 2px;
    background: var(--op-mark);
    color: inherit;
}

.class-filter {
    max-width: 11rem;
}

.search-results-list {
    max-height: 14rem;
    overflow-y: auto;
}

.result-meta {
    font-size: 0.72rem;
}

.search-results .list-group-item.active .result-meta {
    color: color-mix(in srgb, var(--op-on-accent) 85%, transparent) !important;
}


/* ── property panels (Esplora tab and viewer): collapsible sections with a chevron, cards for the sets ── */
.element-panel {
    min-height: 20rem;
}

.panel-header {
    padding-bottom: 0.6rem;
    border-bottom: 1px solid var(--op-border);
}

.panel-section {
    margin-top: 0.75rem;
}

    .panel-section > summary,
    .pset > summary {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.4rem;
        list-style: none;
        cursor: pointer;
        user-select: none;
    }

        .panel-section > summary::-webkit-details-marker,
        .pset > summary::-webkit-details-marker {
            display: none;
        }

        /* chevron: rotates when the section is open */
        .panel-section > summary::before,
        .pset > summary::before {
            content: "";
            flex: 0 0 auto;
            width: 0.4rem;
            height: 0.4rem;
            margin: 0 0.2rem 0 0.1rem;
            border-right: 1.5px solid currentColor;
            border-bottom: 1.5px solid currentColor;
            color: var(--op-text-3);
            transform: rotate(-45deg);
            transition: transform var(--op-dur) var(--op-ease);
        }

        .panel-section[open] > summary::before,
        .pset[open] > summary::before {
            transform: translateY(-0.12rem) rotate(45deg);
        }

    .panel-section > summary {
        font-weight: 600;
        padding: 0.25rem 0;
    }

        .panel-section > summary:hover::before,
        .pset > summary:hover::before {
            color: var(--op-text);
        }

.pset {
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius);
    background: var(--op-surface);
    padding: 0.2rem 0.6rem;
    margin-bottom: 0.45rem;
}

    .pset > summary {
        padding: 0.3rem 0;
    }

    .pset[open] > summary {
        border-bottom: 1px solid var(--op-border);
        margin-bottom: 0.25rem;
    }

.attr-table th, .pset-table th {
    white-space: nowrap;
}

.pset-table thead th, .attr-table thead th {
    font-size: var(--op-text-2xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--op-text-2);
    font-weight: 600;
}

.complex-property {
    background: var(--op-surface-2);
}

.step-line {
    white-space: pre-wrap;
    word-break: break-all;
    background: #151b26;
    color: #d8dee9;
    padding: 0.75rem 4.5rem 0.75rem 0.85rem;
    border-radius: var(--op-radius);
    font-size: 0.8rem;
    line-height: 1.55;
    max-height: 16rem;
    overflow-y: auto;
}

.copy-button {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
}

.ref-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
    gap: 0.1rem 0.75rem;
}

/* ── type stats ── */
.type-filter {
    width: 18rem;
    max-width: 100%;
}

.issue-rows {
    max-height: 28rem;
}

.load-errors {
    max-height: calc(100vh - var(--op-page-top) - 9rem);
    min-height: 12rem;
}

.type-stats {
    max-height: calc(100vh - var(--op-page-top) - 9rem);
    min-height: 16rem;
}

.pct-col {
    min-width: 10rem;
}

.pct-bar {
    height: 0.45rem;
    background: var(--op-surface-3);
    border-radius: var(--op-radius-pill);
    overflow: hidden;
    min-width: 3rem;
}

    .pct-bar > span {
        display: block;
        height: 100%;
        border-radius: inherit;
        background: var(--op-accent-fill);
    }

.pct-text {
    width: 3.5rem;
    text-align: right;
}

.sort-button {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    color: inherit;
}

    .sort-button:hover {
        color: var(--op-text);
    }

    .sort-button.active {
        color: var(--op-accent);
    }

.sort-glyph {
    font-size: 0.6rem;
    opacity: 0.55;
}

.sort-button.active .sort-glyph {
    opacity: 1;
}

.sort-button:focus-visible {
    outline: 2px solid var(--op-focus);
}

/* search input with a leading icon */
.search-field {
    position: relative;
}

    .search-field > .op-icon {
        position: absolute;
        left: 0.55rem;
        top: 50%;
        transform: translateY(-50%);
        color: var(--op-text-3);
        pointer-events: none;
    }

    .search-field > .form-control {
        padding-left: 1.85rem;
    }

/* ── federations ── */
.member-swatch {
    display: inline-block;
    width: 0.75rem;
    height: 0.75rem;
    border-radius: 50%;
    vertical-align: -0.05rem;
    margin-right: 0.3rem;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15);
    flex: 0 0 auto;
}

    .member-swatch.small {
        width: 0.55rem;
        height: 0.55rem;
        margin-right: 0;
    }

    .member-swatch.dashed {
        background: transparent;
        border: 2px dashed;
    }

.member-hidden > td {
    opacity: 0.55;
}

.mode-select {
    min-width: 10rem;
}

.version-picker {
    max-height: 55vh;
    overflow-y: auto;
}

.tree-sources {
    flex: 0 0 auto;
    font-size: 0.68rem;
    cursor: help;
}

    /* federated tree of the admin page: tinted, no per-row shadow */
    .tree-sources:not(.text-bg-info) {
        color: var(--op-info-fg);
        background: var(--op-info-bg);
    }

/* keyboard help under the trees */
.tree-help {
    margin-top: 0.35rem;
    font-size: var(--op-text-xs);
    color: var(--op-text-3);
}

    .tree-help kbd {
        display: inline-block;
        min-width: 1.2rem;
        margin: 0 0.1rem;
        padding: 0 0.25rem;
        border-radius: var(--op-radius-sm);
        border: 1px solid var(--op-border-strong);
        border-bottom-width: 2px;
        background: var(--op-surface);
        color: var(--op-text-2);
        font-family: var(--op-font-sans);
        font-size: 0.68rem;
        line-height: 1.1rem;
        text-align: center;
    }

.tabset .nav-tabs .nav-link {
    scroll-margin-top: calc(var(--op-page-top) + 1rem);
}

.scene-plan svg {
    display: block;
    width: 100%;
    height: auto;
    max-height: 26rem;
    background:
        linear-gradient(var(--op-surface-2), var(--op-surface-2));
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
}

.scene-plan text {
    font-family: var(--op-font-sans);
    fill: var(--op-text);
    paint-order: stroke;
    stroke: var(--op-surface-2);
    stroke-width: 0.35em;
    stroke-linejoin: round;
}

.plan-scene-origin line {
    stroke: var(--op-text-3);
}

.plan-scene-origin text {
    fill: var(--op-text-2);
}

.plan-north polygon {
    fill: var(--op-text);
}

.plan-scale line {
    stroke: var(--op-text);
}

.plan-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    margin-top: 0.5rem;
}

.source-card .kv-table th {
    width: 7rem;
}

@media (max-width: 991.98px) {
    .lazy-tree {
        height: 55vh !important;
    }
}

/* ── admin pages: headers, KPI, activity, uploads, empty/loading states, chips ── */

/* page header: icon, title, meta line (dot-separated), actions */
.page-header {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.75rem 1rem;
    margin-bottom: 1.1rem;
}

.page-heading {
    display: flex;
    align-items: flex-start;
    gap: 0.8rem;
    flex: 1 1 22rem;
    min-width: 0;
}

.page-icon {
    --tone-fg: var(--op-accent);
    --tone-bg: var(--op-accent-bg);
    --tone-border: var(--op-accent-border);
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--op-radius-lg);
    color: var(--tone-fg);
    background: var(--tone-bg);
    box-shadow: inset 0 0 0 1px var(--tone-border);
}

    .page-icon .op-icon,
    .page-icon .ifc-icon {
        width: 1.3rem;
        height: 1.3rem;
    }

.page-title {
    font-size: var(--op-text-xl);
    font-weight: 650;
    letter-spacing: -0.015em;
    line-height: 1.2;
    margin: 0;
    word-break: break-word;
}

.page-subtitle {
    margin: 0.2rem 0 0;
    color: var(--op-text-2);
    font-size: var(--op-text-md);
}

.page-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem 0.55rem;
    margin-top: 0.35rem;
    font-size: var(--op-text-sm);
    color: var(--op-text-2);
    font-variant-numeric: tabular-nums;
}

    .page-meta > .meta-item {
        display: inline-flex;
        align-items: center;
        gap: 0.3rem;
        white-space: nowrap;
    }

        .page-meta > .meta-item .op-icon {
            width: 0.85rem;
            height: 0.85rem;
            color: var(--op-text-3);
        }

    .page-meta > .meta-item + .meta-item::before {
        content: "";
        width: 3px;
        height: 3px;
        margin-right: 0.25rem;
        border-radius: 50%;
        background: var(--op-border-strong);
    }

.page-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
}

    .page-actions .vr {
        align-self: stretch;
        margin: 0.2rem 0.15rem;
        opacity: 1;
        background: var(--op-border);
    }

/* buttons with an icon; square icon-only buttons */
.btn > .op-icon {
    margin-right: 0.35rem;
    vertical-align: -0.16em;
}

.btn.btn-icon {
    display: inline-grid;
    place-items: center;
    width: 2.1rem;
    height: 2.1rem;
    padding: 0;
}

    .btn.btn-icon.btn-sm {
        width: 1.95rem;
        height: 1.95rem;
    }

    .btn.btn-icon > .op-icon {
        margin: 0;
    }

.btn-ghost {
    --bs-btn-color: var(--op-text-2);
    --bs-btn-bg: transparent;
    --bs-btn-border-color: transparent;
    --bs-btn-hover-color: var(--op-text);
    --bs-btn-hover-bg: var(--op-surface-3);
    --bs-btn-hover-border-color: transparent;
    --bs-btn-active-color: var(--op-text);
    --bs-btn-active-bg: var(--op-surface-3);
    --bs-btn-active-border-color: transparent;
    --bs-btn-disabled-color: var(--op-text-3);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: transparent;
}

    .btn-ghost.danger {
        --bs-btn-hover-color: var(--op-danger-fg);
        --bs-btn-hover-bg: var(--op-danger-bg);
        --bs-btn-active-color: var(--op-danger-fg);
        --bs-btn-active-bg: var(--op-danger-bg);
    }

.btn-outline-warning {
    --bs-btn-color: var(--op-warning-fg);
    --bs-btn-bg: var(--op-surface);
    --bs-btn-border-color: color-mix(in srgb, var(--op-warning-dot) 60%, transparent);
    --bs-btn-hover-color: var(--op-warning-fg);
    --bs-btn-hover-bg: var(--op-warning-bg);
    --bs-btn-hover-border-color: var(--op-warning-dot);
    --bs-btn-active-color: var(--op-warning-fg);
    --bs-btn-active-bg: var(--op-warning-bg);
    --bs-btn-active-border-color: var(--op-warning-dot);
}

/* a labelled group of related buttons: "Scarica | Originale | IFC ricostruito | Altro schema…" */
.btn-labelled-group {
    display: inline-flex;
    align-items: stretch;
}

    .btn-labelled-group > .group-label {
        display: inline-flex;
        align-items: center;
        gap: 0.3rem;
        padding: 0 0.55rem;
        border: 1px solid var(--op-border-strong);
        border-right: 0;
        border-radius: var(--op-radius) 0 0 var(--op-radius);
        background: var(--op-surface-2);
        color: var(--op-text-2);
        font-size: var(--op-text-xs);
        font-weight: 600;
        white-space: nowrap;
    }

        .btn-labelled-group > .group-label .op-icon {
            width: 0.85rem;
            height: 0.85rem;
        }

    .btn-labelled-group > .btn-group > .btn:first-child {
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
    }

/* segmented control (radio groups of btn-check): a track with a raised chip for the checked option */
.segmented {
    /* narrow screens: the options go on more lines instead of widening the page */
    flex-wrap: wrap;
    max-width: 100%;
    padding: 2px;
    gap: 2px;
    border-radius: calc(var(--op-radius) + 2px);
    background: var(--op-surface-3);
}

    .segmented > .btn {
        --bs-btn-color: var(--op-text-2);
        --bs-btn-bg: transparent;
        --bs-btn-border-color: transparent;
        --bs-btn-hover-color: var(--op-text);
        --bs-btn-hover-bg: color-mix(in srgb, var(--op-surface) 55%, transparent);
        --bs-btn-hover-border-color: transparent;
        --bs-btn-active-color: var(--op-text);
        --bs-btn-active-bg: var(--op-surface);
        --bs-btn-active-border-color: transparent;
        --bs-btn-disabled-color: var(--op-text-3);
        --bs-btn-disabled-border-color: transparent;
        border-radius: var(--op-radius) !important;
        margin-left: 0 !important;
        display: inline-flex;
        align-items: center;
        gap: 0.35rem;
        font-weight: 500;
    }

    .segmented > .btn-check:checked + .btn {
        color: var(--op-text);
        background: var(--op-surface);
        border-color: transparent;
        box-shadow: var(--op-shadow-sm), 0 0 0 1px var(--op-border);
    }

    .segmented > .btn-check:focus-visible + .btn {
        box-shadow: var(--op-ring);
    }

    .segmented > .btn-check:disabled + .btn {
        opacity: 0.5;
    }

    .segmented .op-count:not([class*=tone-]) {
        background: color-mix(in srgb, var(--op-surface) 60%, var(--op-surface-3));
    }

    .segmented > .btn-check:checked + .btn .op-count:not([class*=tone-]) {
        background: var(--op-surface-3);
    }

/* section heading inside a page: small label, counter, actions on the right */
.section-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.6rem;
}

    .section-head > h2,
    .section-head > h3 {
        display: inline-flex;
        align-items: center;
        gap: 0.45rem;
        margin: 0;
        font-size: var(--op-text-md);
        font-weight: 650;
        color: var(--op-text);
    }

    .section-head .op-icon {
        color: var(--op-text-3);
    }

    .section-head .section-note {
        font-size: var(--op-text-xs);
        color: var(--op-text-3);
    }

/* card with a title row (home side panels, upload) */
.panel-card {
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    background: var(--op-surface);
    box-shadow: var(--op-shadow-sm);
}

.panel-card-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.65rem 0.9rem;
    border-bottom: 1px solid var(--op-border);
}

    .panel-card-head > h2,
    .panel-card-head > h3 {
        display: inline-flex;
        align-items: center;
        gap: 0.45rem;
        margin: 0 auto 0 0;
        font-size: var(--op-text-xs);
        font-weight: 600;
        letter-spacing: 0.07em;
        text-transform: uppercase;
        color: var(--op-text-2);
    }

        .panel-card-head > h2 .op-icon,
        .panel-card-head > h3 .op-icon {
            color: var(--op-text-3);
        }

.panel-card-body {
    padding: 0.75rem 0.9rem;
}

/* KPI tiles (home): icon disc + label, value, detail */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11.25rem, 1fr));
    gap: 0.6rem;
    margin-bottom: 1.25rem;
}

.kpi {
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
    min-width: 0;
    padding: 0.8rem 0.9rem;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    background: var(--op-surface);
    box-shadow: var(--op-shadow-sm);
    color: var(--op-text);
    text-decoration: none;
}

a.kpi {
    transition: border-color var(--op-dur) var(--op-ease), box-shadow var(--op-dur) var(--op-ease);
}

    a.kpi:hover {
        color: var(--op-text);
        border-color: var(--op-border-strong);
        box-shadow: var(--op-shadow);
    }

.kpi-icon {
    --tone-fg: var(--op-accent);
    --tone-bg: var(--op-accent-bg);
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--op-radius);
    color: var(--tone-fg);
    background: var(--tone-bg);
}

    .kpi-icon .op-icon {
        width: 1.15rem;
        height: 1.15rem;
    }

.kpi-body {
    min-width: 0;
    flex: 1;
}

.kpi-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--op-text-xs);
    font-weight: 500;
    color: var(--op-text-2);
}

.kpi-value {
    overflow-wrap: anywhere;
    font-size: 1.45rem;
    font-weight: 650;
    letter-spacing: -0.02em;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

    .kpi-value .kpi-suffix {
        margin-left: 0.3em;
    }

    .kpi-value small {
        font-size: var(--op-text-sm);
        font-weight: 500;
        color: var(--op-text-2);
        letter-spacing: 0;
    }

.kpi-detail {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.2rem 0.6rem;
    margin-top: 0.15rem;
    font-size: var(--op-text-xs);
    color: var(--op-text-3);
    font-variant-numeric: tabular-nums;
}

    .kpi-detail .op-dot {
        margin-right: 0.25rem;
    }

    .kpi-detail > span {
        display: inline-flex;
        align-items: center;
        min-width: 0;
        overflow-wrap: anywhere; /* long details wrap inside the tile, never over the next one */
    }

/* stacked share bar (versions by status) */
.share-bar {
    display: flex;
    gap: 2px;
    height: 0.35rem;
    margin-top: 0.45rem;
    border-radius: var(--op-radius-pill);
    overflow: hidden;
    background: var(--op-surface-3);
}

    .share-bar > span {
        min-width: 3px;
        background: var(--tone-dot);
    }

/* recent activity / queue lists */
.activity-list {
    list-style: none;
    margin: 0;
    padding: 0.25rem 0;
}

    .activity-list > li {
        display: flex;
        gap: 0.65rem;
        align-items: flex-start;
        padding: 0.45rem 0.9rem;
    }

        .activity-list > li + li {
            border-top: 1px solid color-mix(in srgb, var(--op-border) 60%, transparent);
        }

.activity-icon {
    --tone-fg: var(--op-neutral-fg);
    --tone-bg: var(--op-neutral-bg);
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 1.6rem;
    height: 1.6rem;
    margin-top: 0.05rem;
    border-radius: 50%;
    color: var(--tone-fg);
    background: var(--tone-bg);
}

    .activity-icon .op-icon {
        width: 0.85rem;
        height: 0.85rem;
    }

.activity-body {
    flex: 1;
    min-width: 0;
    font-size: var(--op-text-sm);
    line-height: 1.35;
}

    .activity-body a {
        font-weight: 600;
        text-decoration: none;
        word-break: break-word;
    }

        .activity-body a:hover {
            text-decoration: underline;
        }

.activity-title {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.activity-verb {
    color: var(--tone-fg);
    font-weight: 500;
}

.activity-meta {
    display: block;
    margin-top: 0.1rem;
    font-size: var(--op-text-xs);
    color: var(--op-text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.activity-time {
    flex: 0 0 auto;
    font-size: var(--op-text-xs);
    color: var(--op-text-3);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* name cell of the models / versions tables */
.name-cell {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    min-width: 0;
}

.name-icon {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 1.9rem;
    height: 1.9rem;
    margin-top: 0.05rem;
    border-radius: var(--op-radius);
    color: var(--op-text-2);
    background: var(--op-surface-2);
    box-shadow: inset 0 0 0 1px var(--op-border);
}

    .name-icon .op-icon {
        width: 1rem;
        height: 1rem;
    }

.name-text {
    min-width: 0;
}

    /* one line, cut with an ellipsis (the full name in the tooltip): a long name never widens the table */
    .name-text > a {
        display: block;
        font-weight: 600;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

.model-description,
.name-text > a {
    max-width: 16rem;
}

/* Tables in a column next to a side panel: the less important columns hide by the width of their card (container
   queries), not of the window, so a table never scrolls or spills over the side panel at common widths. */
.table-card {
    container-type: inline-size;
}

@container (max-width: 1060px) {
    .op-table .cq-hide-1060 { display: none; }
}

@container (max-width: 880px) {
    .op-table .cq-hide-880 { display: none; }
}

@container (max-width: 800px) {
    .op-table .cq-hide-800 { display: none; }
}

@container (max-width: 700px) {
    .op-table .cq-hide-700 { display: none; }
    .op-table .model-description,
    .op-table .name-text > a { max-width: 12rem; }
    .op-table .status-col { min-width: 0; }
}

@media (min-width: 1600px) {
    .model-description,
    .name-text > a {
        max-width: 26rem;
    }
}

.error-snippet {
    max-width: 18rem;
}

.status-col {
    min-width: 10rem;
}

.file-col {
    min-width: 12rem;
}

.name-col {
    min-width: 15rem;
}

.version-number {
    display: inline-block;
    min-width: 1.9rem;
    padding: 0.05rem 0.35rem;
    border-radius: var(--op-radius-sm);
    background: var(--op-surface-3);
    color: var(--op-text);
    font-size: var(--op-text-xs);
    font-weight: 650;
    text-align: center;
    text-decoration: none;
    font-variant-numeric: tabular-nums;
}

a.version-number:hover {
    background: var(--op-accent-bg);
    color: var(--op-accent);
    text-decoration: none !important;
}

.hash {
    font-family: var(--op-font-mono);
    font-size: var(--op-text-2xs);
    color: var(--op-text-3);
}

/* IFC schema chip */
.schema-chip {
    --schema: var(--op-schema-other);
    display: inline-block;
    padding: 0.08rem 0.4rem;
    border-radius: var(--op-radius-sm);
    font-family: var(--op-font-mono);
    font-size: var(--op-text-2xs);
    font-weight: 600;
    letter-spacing: 0.02em;
    line-height: 1.4;
    white-space: nowrap;
    color: var(--schema);
    background: color-mix(in srgb, var(--schema) 9%, var(--op-surface));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--schema) 28%, transparent);
    vertical-align: middle;
}

.schema-ifc2x3 { --schema: var(--op-schema-ifc2x3); }
.schema-ifc4 { --schema: var(--op-schema-ifc4); }
.schema-ifc4x3 { --schema: var(--op-schema-ifc4x3); }

/* empty state */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    padding: 2rem 1.5rem;
    border: 1px dashed var(--op-border-strong);
    border-radius: var(--op-radius-lg);
    text-align: center;
    color: var(--op-text-2);
    background: var(--op-surface-2);
    font-size: var(--op-text-md);
}

    .empty-state.compact {
        padding: 1.1rem 1rem;
        font-size: var(--op-text-sm);
    }

    .empty-state > p:last-child {
        margin-bottom: 0;
    }

.empty-state-icon {
    --tone-fg: var(--op-text-3);
    --tone-bg: var(--op-surface);
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-bottom: 0.25rem;
    border-radius: 50%;
    color: var(--tone-fg);
    background: var(--tone-bg);
    box-shadow: inset 0 0 0 1px var(--op-border), var(--op-shadow-sm);
}

    .empty-state-icon .op-icon {
        width: 1.3rem;
        height: 1.3rem;
    }

    .empty-state.compact .empty-state-icon {
        width: 2.2rem;
        height: 2.2rem;
    }

.empty-state-title {
    font-weight: 600;
    color: var(--op-text);
}

.empty-state-text {
    max-width: 34rem;
}

.empty-state-actions:empty {
    display: none;
}

.empty-state-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 0.6rem;
}

/* loading */
.loading-state {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    color: var(--op-text-2);
    font-size: var(--op-text-sm);
    margin: 0.5rem 0;
}

    .loading-state .spinner-border {
        width: 0.9rem;
        height: 0.9rem;
        border-width: 0.14em;
        color: var(--op-accent);
    }

.loading-lines {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    padding: 0.5rem 0;
}

    .loading-lines .placeholder {
        height: 0.8rem;
    }

/* ── uploads: compact drop zone, one card per file ── */
.drop-zone {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1rem 1.1rem;
    border: 1.5px dashed var(--op-border-strong);
    border-radius: var(--op-radius-lg);
    background: var(--op-surface-2);
    transition: background-color var(--op-dur) var(--op-ease), border-color var(--op-dur) var(--op-ease), box-shadow var(--op-dur) var(--op-ease);
}

    .drop-zone.drag-over {
        border-color: var(--op-accent);
        border-style: solid;
        background: var(--op-accent-bg);
        box-shadow: 0 0 0 4px color-mix(in srgb, var(--op-accent) 14%, transparent);
    }

        .drop-zone.drag-over .drop-zone-icon {
            transform: translateY(-2px);
            color: var(--op-on-accent);
            background: var(--op-accent-fill);
        }

    .drop-zone.disabled {
        opacity: 0.6;
    }

    .drop-zone.attention {
        animation: drop-attention 1.4s var(--op-ease) 2;
    }

    .drop-zone input:focus-visible ~ .drop-zone-action label {
        box-shadow: var(--op-ring);
    }

.drop-zone-icon {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    color: var(--op-accent);
    background: var(--op-surface);
    box-shadow: inset 0 0 0 1px var(--op-border), var(--op-shadow-sm);
    transition: transform var(--op-dur) var(--op-ease), background-color var(--op-dur) var(--op-ease), color var(--op-dur) var(--op-ease);
}

    .drop-zone-icon .op-icon {
        width: 1.25rem;
        height: 1.25rem;
    }

.drop-zone-text {
    flex: 1;
    min-width: 0;
}

.drop-zone-prompt {
    font-weight: 600;
    color: var(--op-text);
}

.drop-zone-hint {
    font-size: var(--op-text-xs);
    color: var(--op-text-2);
    margin-top: 0.1rem;
}

.drop-zone-action {
    flex: 0 0 auto;
}

@keyframes drop-attention {
    0%, 100% { box-shadow: 0 0 0 0 transparent; border-color: var(--op-border-strong); }
    40% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--op-accent) 22%, transparent); border-color: var(--op-accent); }
}

@media (max-width: 575.98px) {
    .drop-zone {
        flex-direction: column;
        text-align: center;
    }
}

/* uploads of the "Nuovo modello" / "Nuova nuvola di punti" buttons, above the list (only when there are some) */
.new-models-uploads:has(.upload-list) {
    margin-bottom: 1rem;
    padding: 0.25rem 0.9rem 0.6rem;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    background: var(--op-surface);
    box-shadow: var(--op-shadow-sm);
}

.upload-list {
    list-style: none;
    margin: 0.75rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.upload-item {
    display: flex;
    gap: 0.7rem;
    align-items: flex-start;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius);
    background: var(--op-surface);
}

    .upload-item.is-failed {
        border-color: var(--op-danger-border);
        background: color-mix(in srgb, var(--op-danger-bg) 45%, var(--op-surface));
    }

    .upload-item.is-done {
        border-color: var(--op-success-border);
    }

.upload-file-icon {
    --tone-fg: var(--op-text-2);
    --tone-bg: var(--op-surface-2);
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--op-radius);
    color: var(--tone-fg);
    background: var(--tone-bg);
}

.upload-main {
    flex: 1;
    min-width: 0;
}

.upload-title {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.5rem;
}

.upload-name {
    font-weight: 600;
    font-size: var(--op-text-sm);
    word-break: break-word;
    margin-right: auto;
}

.upload-size {
    font-size: var(--op-text-xs);
    color: var(--op-text-3);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.upload-detail {
    margin-top: 0.2rem;
    font-size: var(--op-text-xs);
    color: var(--op-text-2);
    font-variant-numeric: tabular-nums;
}

    .upload-detail.text-danger {
        color: var(--op-danger-fg) !important;
    }

/* ── version page: current-version hero (model page), details grid ── */
.hero-card {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.25rem;
    padding: 0.85rem 1rem;
    margin-bottom: 1.25rem;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    background: linear-gradient(135deg, var(--op-accent-bg) 0%, var(--op-surface) 55%);
    box-shadow: var(--op-shadow-sm);
}

.hero-main {
    flex: 1 1 18rem;
    min-width: 0;
}

.hero-label {
    font-size: var(--op-text-2xs);
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--op-text-2);
}

.hero-title {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.6rem;
    margin-top: 0.15rem;
    font-weight: 600;
}

    .hero-title a {
        color: var(--op-text);
        text-decoration: none;
        word-break: break-word;
    }

        .hero-title a:hover {
            color: var(--op-accent);
        }

.hero-figures {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.4rem;
}

.hero-figure {
    display: flex;
    flex-direction: column;
    font-variant-numeric: tabular-nums;
}

    .hero-figure strong {
        font-size: var(--op-text-lg);
        font-weight: 650;
        line-height: 1.2;
    }

    .hero-figure span {
        font-size: var(--op-text-2xs);
        color: var(--op-text-2);
    }

.hero-actions {
    display: flex;
    gap: 0.4rem;
}

/* definition grid: label above value, two or three columns (version details) */
.kv-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    gap: 0.75rem 1.25rem;
    margin: 0;
}

    .kv-grid > div {
        min-width: 0;
    }

    .kv-grid dt {
        font-size: var(--op-text-xs);
        font-weight: 500;
        color: var(--op-text-2);
        margin-bottom: 0.1rem;
    }

    .kv-grid dd {
        margin: 0;
        font-size: var(--op-text-md);
        word-break: break-word;
        font-variant-numeric: tabular-nums;
    }

    .kv-grid .wide {
        grid-column: 1 / -1;
    }

    .kv-grid .hash-value {
        font-family: var(--op-font-mono);
        font-size: var(--op-text-xs);
        color: var(--op-text-2);
        word-break: break-all;
    }

/* LoGeoRef as a 5-step meter (10 address · 20 lat/long · 30 site placement · 40 context · 50 map conversion) */
.georef-meter {
    display: inline-flex;
    gap: 3px;
    vertical-align: middle;
}

    .georef-meter > span {
        width: 1.1rem;
        height: 0.45rem;
        border-radius: 2px;
        background: var(--op-surface-3);
        box-shadow: inset 0 0 0 1px var(--op-border);
    }

        .georef-meter > span.on {
            background: var(--tone-dot, var(--op-accent-dot));
            box-shadow: none;
        }

.georef-level {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.85rem;
    padding: 0.75rem 0.9rem;
    margin-bottom: 1rem;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    background: var(--op-surface);
    box-shadow: var(--op-shadow-sm);
}

    .georef-level .level-value {
        font-size: var(--op-text-lg);
        font-weight: 650;
        font-variant-numeric: tabular-nums;
    }

/* modal: short fade and lift on open (none with reduced motion) */
.modal.d-block .modal-content {
    animation: modal-in 160ms var(--op-ease);
}

.modal-backdrop.show {
    animation: backdrop-in 160ms var(--op-ease);
}

@keyframes modal-in {
    from { opacity: 0; transform: translateY(6px) scale(0.985); }
    to { opacity: 1; transform: none; }
}

@keyframes backdrop-in {
    from { opacity: 0; }
    to { opacity: var(--bs-backdrop-opacity); }
}

@media (prefers-reduced-motion: reduce) {
    .modal.d-block .modal-content,
    .modal-backdrop.show,
    .drop-zone.attention {
        animation: none;
    }
}

.modal-header .modal-icon {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    margin-right: 0.65rem;
    border-radius: 50%;
    color: var(--tone-fg, var(--op-accent));
    background: var(--tone-bg, var(--op-accent-bg));
}

/* confirmation dialog: icon and message side by side */
.confirm-body {
    display: flex;
    gap: 0.85rem;
    align-items: flex-start;
}

.confirm-icon {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 50%;
    color: var(--tone-fg);
    background: var(--tone-bg);
}

    .confirm-icon .op-icon {
        width: 1.2rem;
        height: 1.2rem;
    }

/* radio cards (conversion target schema) */
.choice-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.choice-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
    padding: 0.65rem 0.8rem 0.7rem 2.2rem;
    position: relative;
    border: 1px solid var(--op-border-strong);
    border-radius: var(--op-radius-lg);
    background: var(--op-surface);
    color: var(--op-text);
    text-align: left;
    transition: border-color var(--op-dur) var(--op-ease), box-shadow var(--op-dur) var(--op-ease), background-color var(--op-dur) var(--op-ease);
}

    .choice-card::before {
        content: "";
        position: absolute;
        left: 0.8rem;
        top: 0.85rem;
        width: 0.9rem;
        height: 0.9rem;
        border-radius: 50%;
        border: 1.5px solid var(--op-border-strong);
        background: var(--op-surface);
    }

    .choice-card:hover:not(:disabled) {
        border-color: var(--op-accent);
    }

    .choice-card[aria-checked=true] {
        border-color: var(--op-accent);
        background: var(--op-accent-bg);
        box-shadow: 0 0 0 1px var(--op-accent);
    }

        .choice-card[aria-checked=true]::before {
            border: 4px solid var(--op-accent-fill);
        }

    .choice-card .choice-title {
        font-weight: 650;
    }

    .choice-card .choice-text {
        font-size: var(--op-text-xs);
        color: var(--op-text-2);
    }

/* stacked radio cards with a counter (bulk reprocessing, «Rielabora…») */
.choice-cards-stacked {
    grid-template-columns: 1fr;
}

.choice-card .choice-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
}

.choice-card .choice-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.15rem 0.9rem;
    margin-top: 0.1rem;
    font-size: var(--op-text-xs);
    color: var(--op-text-3);
}

    .choice-card .choice-meta > span {
        display: inline-flex;
        align-items: center;
        gap: 0.35rem;
    }

    .choice-card .choice-meta .tone-warning,
    .choice-card .choice-meta .tone-accent {
        color: var(--tone-fg);
    }

.choice-card:disabled {
    opacity: 0.7;
}

/* outcome of an action under the page header (StatusNotice) */
.status-notice {
    align-items: center;
}

    .status-notice .btn-close {
        width: 0.6rem;
        height: 0.6rem;
        background-size: 0.6rem;
        flex: 0 0 auto;
    }

/* counters of the conversion report: tone tiles */
.count-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.count-tile {
    --tone-fg: var(--op-text);
    --tone-dot: var(--op-border-strong);
    position: relative;
    padding: 0.5rem 0.75rem 0.55rem 0.9rem;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius);
    background: var(--op-surface);
    overflow: hidden;
}

    .count-tile::before {
        content: "";
        position: absolute;
        inset: 0 auto 0 0;
        width: 3px;
        background: var(--tone-dot);
    }

    .count-tile .count-label {
        font-size: var(--op-text-xs);
        color: var(--op-text-2);
        white-space: nowrap;
    }

    .count-tile .count-value {
        font-size: var(--op-text-lg);
        font-weight: 650;
        color: var(--tone-fg);
        font-variant-numeric: tabular-nums;
    }

/* validation groups */
.issue-groups {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin-bottom: 1rem;
}

.issue-group {
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    background: var(--op-surface);
    overflow: hidden;
}

    .issue-group.open {
        box-shadow: var(--op-shadow-sm);
    }

    .issue-group > .issue-head {
        display: flex;
        align-items: flex-start;
        gap: 0.6rem;
        width: 100%;
        padding: 0.6rem 0.85rem;
        border: 0;
        background: none;
        text-align: left;
        color: var(--op-text);
    }

        .issue-group > .issue-head:hover {
            background: var(--op-surface-2);
        }

        .issue-group > .issue-head:focus-visible {
            outline: 2px solid var(--op-focus);
            outline-offset: -2px;
        }

.issue-chevron {
    flex: 0 0 auto;
    margin-top: 0.3rem;
    width: 0.8rem;
    height: 0.8rem;
    color: var(--op-text-3);
    transition: transform var(--op-dur) var(--op-ease);
}

.issue-group.open .issue-chevron {
    transform: rotate(90deg);
}

.issue-title {
    font-weight: 600;
}

.issue-title + .origin-tag {
    margin-left: 0.45rem;
    vertical-align: 1px;
}

.issue-subject {
    margin-left: 0.4rem;
    font-family: var(--op-font-mono);
    font-size: var(--op-text-xs);
    color: var(--op-text-2);
    word-break: break-all;
}

.issue-explanation {
    display: block;
    margin-top: 0.1rem;
    font-size: var(--op-text-sm);
    color: var(--op-text-2);
}

.issue-body {
    padding: 0.25rem 0.85rem 0.85rem 2.25rem;
    border-top: 1px solid var(--op-border);
    background: color-mix(in srgb, var(--op-surface-2) 40%, var(--op-surface));
}

.severity-legend {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
    gap: 0.35rem 1.25rem;
    margin: 0 0 0.75rem;
    font-size: var(--op-text-xs);
    color: var(--op-text-2);
}

    .severity-legend > span {
        display: inline-flex;
        align-items: baseline;
        gap: 0.35rem;
    }

        .severity-legend > span .op-dot {
            transform: translateY(-0.05rem);
        }

/* federations list: one card per federation */
.fed-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
    gap: 0.75rem;
}

.fed-card {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    background: var(--op-surface);
    box-shadow: var(--op-shadow-sm);
    transition: border-color var(--op-dur) var(--op-ease), box-shadow var(--op-dur) var(--op-ease);
}

    .fed-card:hover {
        border-color: var(--op-border-strong);
        box-shadow: var(--op-shadow);
    }

.fed-card-head {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
}

    /* one line with an ellipsis (the full name in the tooltip), like the names of the tables */
    .fed-card-head .title {
        display: block;
        font-weight: 650;
        font-size: var(--op-text-base);
        text-decoration: none;
        color: var(--op-text);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

        .fed-card-head .title:hover {
            color: var(--op-accent);
        }

        /* the whole card is the link target */
        .fed-card-head .title::after {
            content: "";
            position: absolute;
            inset: 0;
        }

.fed-card {
    position: relative;
}

    .fed-card .fed-actions {
        position: relative;
        z-index: 1;
        margin-left: auto;
        display: flex;
        gap: 0.15rem;
    }

.fed-members {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    min-height: 1.4rem;
}

.fed-member {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    max-width: 100%;
    padding: 0.1rem 0.5rem 0.1rem 0.4rem;
    border-radius: var(--op-radius-pill);
    font-size: var(--op-text-xs);
    color: var(--op-text-2);
    background: var(--op-surface-2);
    box-shadow: inset 0 0 0 1px var(--op-border);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

    .fed-member .member-swatch {
        margin: 0;
        width: 0.55rem;
        height: 0.55rem;
    }

.fed-card-foot {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 0.75rem;
    margin-top: auto;
    padding-top: 0.5rem;
    border-top: 1px solid var(--op-border);
    font-size: var(--op-text-xs);
    color: var(--op-text-3);
}

    .fed-card-foot > span {
        display: inline-flex;
        align-items: center;
        gap: 0.3rem;
    }

    .fed-card-foot .op-icon {
        width: 0.8rem;
        height: 0.8rem;
    }

/* ── viewer windows (ViewerLayout .viewer-shell, light or dark as the theme) ── */

/* the 3D viewer takes its overlay colours from these variables (Opera.Viewer): its own near-opaque panel over the scene */
.viewer-shell {
    --opera-viewer-overlay-bg: var(--op-float-bg);
    --opera-viewer-overlay-fg: var(--op-float-fg);
    --opera-viewer-accent: var(--op-accent);
}

/* ghost buttons of the chrome (top bar, tree commands, banners): .op-btn-ghost on the tokens of both themes (in place of
   Bootstrap's btn-outline-light, made for a dark bar only) */
.btn.op-btn-ghost {
    --bs-btn-color: var(--op-text-2);
    --bs-btn-bg: transparent;
    --bs-btn-border-color: var(--op-border-strong);
    --bs-btn-hover-color: var(--op-text);
    --bs-btn-hover-bg: var(--op-hover);
    --bs-btn-hover-border-color: var(--op-border-hover);
    --bs-btn-active-color: var(--op-text);
    --bs-btn-active-bg: var(--op-surface-3);
    --bs-btn-active-border-color: var(--op-border-hover);
    --bs-btn-disabled-color: var(--op-text-3);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: var(--op-border);
}

/* pressed toggles (Statistiche on, a side panel open) and the main action of a banner: .op-btn-pressed (in place of
   Bootstrap's btn-light) */
.btn.op-btn-pressed {
    --bs-btn-color: var(--op-accent-fg);
    --bs-btn-bg: var(--op-accent-soft);
    --bs-btn-border-color: color-mix(in srgb, var(--op-accent) 55%, transparent);
    --bs-btn-hover-color: var(--op-active-fg);
    --bs-btn-hover-bg: color-mix(in srgb, var(--op-accent) 26%, transparent);
    --bs-btn-hover-border-color: var(--op-accent);
    --bs-btn-active-color: var(--op-active-fg);
    --bs-btn-active-bg: color-mix(in srgb, var(--op-accent) 30%, transparent);
    --bs-btn-active-border-color: var(--op-accent);
    --bs-btn-disabled-color: var(--op-accent-fg);
    --bs-btn-disabled-bg: var(--op-accent-soft);
    --bs-btn-disabled-border-color: color-mix(in srgb, var(--op-accent) 35%, transparent);
}

.viewer-shell .btn-outline-warning {
    --bs-btn-color: var(--op-warn);
    --bs-btn-border-color: color-mix(in srgb, var(--op-warn) 55%, transparent);
    --bs-btn-hover-color: var(--op-bg);
    --bs-btn-hover-bg: var(--op-warn);
    --bs-btn-hover-border-color: var(--op-warn);
}

.viewer-shell .form-control,
.viewer-shell .form-select {
    background-color: var(--op-surface-2);
    border-color: var(--op-border-strong);
    color: var(--op-text);
}

    .viewer-shell .form-control::placeholder {
        color: var(--op-text-3);
    }

    .viewer-shell .form-control:hover,
    .viewer-shell .form-select:hover {
        border-color: var(--op-border-hover);
    }

    .viewer-shell .form-control:focus,
    .viewer-shell .form-select:focus {
        background-color: var(--op-surface-2);
        border-color: var(--op-focus);
    }

.viewer-shell .text-warning {
    color: var(--op-warn) !important;
}

/* stroke icons of the viewer chrome (toolbar, tree commands): 16×16 grid, currentColor */
.op-icon {
    flex: 0 0 auto;
    width: 1rem;
    height: 1rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.35;
    stroke-linecap: round;
    stroke-linejoin: round;
    vertical-align: -0.15em;
}

/* dark trees of the viewer: rows end with [label ………][×n][count][⌖] */
.viewer-tree {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

    .viewer-tree .viewer-tree-list {
        flex: 1 1 0;
        min-height: 6rem;
        border-radius: var(--op-radius);
    }

    .viewer-tree .tree-label {
        margin-right: auto;
    }

    .viewer-tree .tree-row.match .tree-label {
        color: var(--op-text-strong);
    }

    .viewer-tree .tree-sources {
        order: 1;
    }

        /* "×n models" badge of the federated tree: tinted, not a saturated cyan block */
        .viewer-tree .tree-sources.text-bg-info {
            background-color: var(--op-teal-bg) !important;
            color: var(--op-teal-fg) !important;
            font-weight: 600;
        }

    .viewer-tree .tree-count {
        order: 2;
        margin-left: 0;
    }

    /* select-in-3D button of each row: the text glyph (an image or a mask here costs a raster per new row and drops frames
       while scrolling fast), quiet until the row is hovered or selected */
    .viewer-tree .tree-pick {
        order: 3;
        flex: 0 0 auto;
        width: 1.5rem;
        height: 1.3rem;
        margin: 0 0 0 0.1rem;
        padding: 0;
        border: 1px solid transparent;
        border-radius: var(--op-radius-sm);
        background: transparent;
        color: var(--op-text-3);
        font-size: 1rem;
        line-height: 1;
        cursor: pointer;
    }

    .viewer-tree .tree-row:hover .tree-pick,
    .viewer-tree .tree-row.selected .tree-pick,
    .viewer-tree .tree-pick:focus-visible {
        color: var(--op-accent-hover);
        border-color: var(--op-border-strong);
    }

        .viewer-tree .tree-row .tree-pick:hover:not(:disabled) {
            background: var(--op-accent-fill);
            border-color: var(--op-accent-fill);
            color: var(--op-on-accent);
        }

        .viewer-tree .tree-pick:focus-visible {
            outline: 2px solid var(--op-focus);
            outline-offset: 0;
        }

        .viewer-tree .tree-pick:disabled {
            opacity: 0.4;
            cursor: progress;
        }

/* status of "expand all" and of the benchmark, under the command row (live region: always rendered, hidden when empty) */
.tree-notes {
    margin: -0.2rem 0 0.45rem;
    line-height: 1.35;
    font-size: var(--op-text-xs);
    color: var(--op-text-2);
}

    .tree-notes:empty {
        display: none;
    }

    .tree-notes .spinner-border-sm {
        width: 0.75rem;
        height: 0.75rem;
        border-width: 0.15em;
    }

/* ───────────────────────── 4. IFC icons ─────────────────────────
   IfcIcon / IfcIcons, sprite wwwroot/icons/ifc-icons.svg. Outline in the family colour (currentColor), accent area
   tinted with the same colour (--ia), "type" badge drawn over the glyph with a knockout ring in the background colour
   (--ifc-knockout). Palette tuned for light pages and for the dark viewer ([data-bs-theme=dark]). */
:root {
    --ifc-context: #6f42c1;
    --ifc-spatial: #0b7c83;
    --ifc-arch: #b0570f;
    --ifc-struct: #2c62b0;
    --ifc-component: #52627a;
    --ifc-furnish: #b03a72;
    --ifc-feature: #6c757d;
    --ifc-civil: #7a661a;
    --ifc-dist: #337487;
    --ifc-hvac: #0873a3;
    --ifc-plumbing: #1b7d45;
    --ifc-electrical: #9f6f00;
    --ifc-control: #93318f;
    --ifc-group: #4453c2;
    --ifc-analysis: #bb3728;
    --ifc-annotation: #466879;
    --ifc-process: #87523a;
    --ifc-generic: #6c757d;
    --ifc-accent-mix: 20%;
    --ifc-knockout: var(--op-surface, #fff);
}

[data-bs-theme=dark] {
    --ifc-context: #b99cf2;
    --ifc-spatial: #52d0cb;
    --ifc-arch: #f3a45e;
    --ifc-struct: #86b2f2;
    --ifc-component: #b1bfd0;
    --ifc-furnish: #f297c3;
    --ifc-feature: #b3bac1;
    --ifc-civil: #d5c16b;
    --ifc-dist: #7fc3d6;
    --ifc-hvac: #5cc4f2;
    --ifc-plumbing: #6fd69c;
    --ifc-electrical: #f4c84a;
    --ifc-control: #e59ae2;
    --ifc-group: #a5aef7;
    --ifc-analysis: #f4897c;
    --ifc-annotation: #9ec0d1;
    --ifc-process: #dcaa90;
    --ifc-generic: #b3bac1;
    --ifc-accent-mix: 26%;
    --ifc-knockout: var(--op-surface);
}

.ifc-icon {
    flex: 0 0 auto;
    overflow: visible;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
    --ia: color-mix(in srgb, currentColor var(--ifc-accent-mix), transparent);
}

.ifc-f-context { color: var(--ifc-context); }
.ifc-f-spatial { color: var(--ifc-spatial); }
.ifc-f-arch { color: var(--ifc-arch); }
.ifc-f-struct { color: var(--ifc-struct); }
.ifc-f-component { color: var(--ifc-component); }
.ifc-f-furnish { color: var(--ifc-furnish); }
.ifc-f-feature { color: var(--ifc-feature); }
.ifc-f-civil { color: var(--ifc-civil); }
.ifc-f-dist { color: var(--ifc-dist); }
.ifc-f-hvac { color: var(--ifc-hvac); }
.ifc-f-plumbing { color: var(--ifc-plumbing); }
.ifc-f-electrical { color: var(--ifc-electrical); }
.ifc-f-control { color: var(--ifc-control); }
.ifc-f-group { color: var(--ifc-group); }
.ifc-f-analysis { color: var(--ifc-analysis); }
.ifc-f-annotation { color: var(--ifc-annotation); }
.ifc-f-process { color: var(--ifc-process); }
.ifc-f-generic { color: var(--ifc-generic); }

/* ───────────────────────── 5. viewer extras ───────────────────────── */

.viewer-subtitle {
    font-weight: 400;
    color: var(--op-text-2);
}

@media (prefers-reduced-motion: reduce) {
    .placeholder-glow .placeholder {
        animation: none;
    }
}

/* icons of the property sections (a mask coloured with currentColor: no extra DOM, same look in both themes) */
.sec-icon {
    flex: 0 0 auto;
    width: 14px;
    height: 14px;
    color: var(--op-text-3);
    background: currentColor;
    -webkit-mask: var(--sec-icon) center / 14px 14px no-repeat;
    mask: var(--sec-icon) center / 14px 14px no-repeat;
}

.sec-position { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 14.5s4.8-4.3 4.8-8a4.8 4.8 0 0 0-9.6 0c0 3.7 4.8 8 4.8 8z'/%3E%3Ccircle cx='8' cy='6.4' r='1.7'/%3E%3C/svg%3E"); }
.sec-element { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 1.8l5.6 3.1v6.2L8 14.2l-5.6-3.1V4.9z'/%3E%3Cpath d='M2.4 4.9 8 8l5.6-3.1M8 8v6.2'/%3E%3C/svg%3E"); }
.sec-type { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linejoin='round'%3E%3Cpath d='M8 1.8 14.2 8 8 14.2 1.8 8z'/%3E%3Cpath d='M8 5.2 10.8 8 8 10.8 5.2 8z'/%3E%3C/svg%3E"); }
.sec-children { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1.8' y='1.8' width='5' height='3.6' rx='.8'/%3E%3Crect x='9' y='6.4' width='5.2' height='3.4' rx='.8'/%3E%3Crect x='9' y='11' width='5.2' height='3.4' rx='.8'/%3E%3Cpath d='M4.3 5.4v7.3H9M4.3 8.1H9'/%3E%3C/svg%3E"); }
.sec-groups { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2 14 5 8 8 2 5z'/%3E%3Cpath d='M2 8.2l6 3 6-3M2 11.2l6 3 6-3'/%3E%3C/svg%3E"); }
.sec-connections { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.5 9.5l3-3'/%3E%3Cpath d='M7.2 4.6l1.3-1.3a2.7 2.7 0 0 1 3.9 3.8l-1.3 1.3M8.8 11.4l-1.3 1.3a2.7 2.7 0 0 1-3.9-3.8l1.3-1.3'/%3E%3C/svg%3E"); }
.sec-materials { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='2' width='12' height='12' rx='1.5'/%3E%3Cpath d='M2 7.5 7.5 2M2 12.5 12.5 2M6.5 14 14 6.5M11.5 14l2.5-2.5'/%3E%3C/svg%3E"); }
.sec-classifications { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 2h5.4l6.6 6.6-5.4 5.4L2 7.4z'/%3E%3Ccircle cx='5.3' cy='5.3' r='1.1'/%3E%3C/svg%3E"); }
.sec-other { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='black'%3E%3Ccircle cx='3.2' cy='8' r='1.4'/%3E%3Ccircle cx='8' cy='8' r='1.4'/%3E%3Ccircle cx='12.8' cy='8' r='1.4'/%3E%3C/svg%3E"); }
.sec-psets { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='2.5' width='12' height='11' rx='1.5'/%3E%3Cpath d='M2 6.2h12M6.2 6.2v7.3M2 9.8h12'/%3E%3C/svg%3E"); }
/* groups of the viewer settings (ViewerSettingsPanel) */
.sec-vs-style { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 1.8a6.2 6.2 0 1 0 0 12.4c1 0 1.5-.6 1.5-1.3 0-.9-.8-1.2-.8-2 0-.8.6-1.3 1.4-1.3h1.7a2.4 2.4 0 0 0 2.4-2.4C14.2 4.3 11.4 1.8 8 1.8z'/%3E%3Ccircle cx='4.8' cy='7.4' r='.9'/%3E%3Ccircle cx='7' cy='4.6' r='.9'/%3E%3Ccircle cx='10.4' cy='5' r='.9'/%3E%3C/svg%3E"); }
.sec-vs-sun { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='10.5' cy='5.5' r='2.2'/%3E%3Cpath d='M10.5 1.4v.9M14.6 5.5h-.9M13.4 2.6l-.6.6M7.6 2.6l.6.6'/%3E%3Cpath d='M2 14.2h12'/%3E%3Cpath d='M3 14.2 6 9.5h2.4L6.6 14.2'/%3E%3C/svg%3E"); }
.sec-vs-elements { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 1.8l5.6 3.1v6.2L8 14.2l-5.6-3.1V4.9z'/%3E%3Cpath d='M2.4 4.9 8 8l5.6-3.1M8 8v6.2'/%3E%3C/svg%3E"); }
.sec-vs-selection { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6V2.5H6M10 2.5h3.5V6M2.5 10v3.5H6'/%3E%3Cpath d='M8.5 8.5l5 1.8-2.2.8-.8 2.2z'/%3E%3C/svg%3E"); }
.sec-vs-section { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 1.8l5.6 3.1v6.2L8 14.2l-5.6-3.1V4.9z'/%3E%3Cpath d='M1 9.6l14-4'/%3E%3C/svg%3E"); }
.sec-vs-xray { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 1.8l5.5 3.1v6.2L8 14.2 2.5 11.1V4.9z' stroke-dasharray='1.7 1.5'/%3E%3Cpath d='M8 5.6l2.6 1.5v3L8 11.6 5.4 10.1v-3z'/%3E%3C/svg%3E"); }
.sec-vs-appearance { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1.6 8s2.4-4.6 6.4-4.6S14.4 8 14.4 8s-2.4 4.6-6.4 4.6S1.6 8 1.6 8z'/%3E%3Ccircle cx='8' cy='8' r='1.9'/%3E%3C/svg%3E"); }
.sec-vs-lights { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8' cy='8' r='2.8'/%3E%3Cpath d='M8 1.6v1.6M8 12.8v1.6M1.6 8h1.6M12.8 8h1.6M3.5 3.5l1.1 1.1M11.4 11.4l1.1 1.1M3.5 12.5l1.1-1.1M11.4 4.6l1.1-1.1'/%3E%3C/svg%3E"); }
.sec-vs-camera { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1.8' y='4.6' width='12.4' height='8.6' rx='1.6'/%3E%3Cpath d='M5.6 4.6l1-1.8h2.8l1 1.8'/%3E%3Ccircle cx='8' cy='8.9' r='2.3'/%3E%3C/svg%3E"); }
.sec-vs-navigation { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8' cy='8' r='6.2'/%3E%3Cpath d='M10.6 5.4 9.1 9.1 5.4 10.6 6.9 6.9z'/%3E%3C/svg%3E"); }
.sec-vs-measure { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.2 10.6l8.4-8.4 3.2 3.2-8.4 8.4z'/%3E%3Cpath d='M4.7 8.1l1.3 1.3M6.6 6.2l1.8 1.8M8.5 4.3l1.3 1.3'/%3E%3C/svg%3E"); }
.sec-vs-walk { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='2.6' r='1.3'/%3E%3Cpath d='M8.4 5.2l-1.6 4.1 2.6 2.1.9 3.3M7 7.2L4.6 8.6l-.6 2.4M8.6 5.6l2 2.4 2.3.6M6.8 9.6l-1.6 4.9'/%3E%3C/svg%3E"); }
.sec-vs-spaces { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 5.2L8 2.4l5.5 2.8v5.6L8 13.6l-5.5-2.8z'/%3E%3Cpath d='M2.5 5.2L8 8l5.5-2.8M8 8v5.6' stroke-dasharray='1.6 1.4'/%3E%3C/svg%3E"); }
.sec-vs-performance { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.4 11.6a5.8 5.8 0 1 1 11.2 0'/%3E%3Cpath d='M8 9.4l2.6-3'/%3E%3Ccircle cx='8' cy='9.6' r='.9'/%3E%3C/svg%3E"); }
.sec-vs-pointclouds { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='black'%3E%3Ccircle cx='4' cy='4.5' r='1.2'/%3E%3Ccircle cx='9' cy='3.5' r='1.2'/%3E%3Ccircle cx='12.5' cy='7' r='1.2'/%3E%3Ccircle cx='6.5' cy='8' r='1.2'/%3E%3Ccircle cx='3.5' cy='11.5' r='1.2'/%3E%3Ccircle cx='9.5' cy='11' r='1.2'/%3E%3Ccircle cx='13' cy='12.5' r='1.2'/%3E%3C/svg%3E"); }
.sec-vs-pointcloudDetail { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='black'%3E%3Ccircle cx='3.5' cy='3.5' r='.8'/%3E%3Ccircle cx='6.5' cy='3.5' r='.8'/%3E%3Ccircle cx='9.5' cy='3.5' r='.8'/%3E%3Ccircle cx='12.5' cy='3.5' r='.8'/%3E%3Ccircle cx='3.5' cy='6.5' r='.8'/%3E%3Ccircle cx='6.5' cy='6.5' r='.8'/%3E%3Ccircle cx='9.5' cy='6.5' r='.8'/%3E%3Ccircle cx='12.5' cy='6.5' r='.8'/%3E%3Ccircle cx='3.5' cy='9.5' r='.8'/%3E%3Ccircle cx='6.5' cy='9.5' r='.8'/%3E%3Ccircle cx='9.5' cy='9.5' r='.8'/%3E%3Ccircle cx='12.5' cy='9.5' r='.8'/%3E%3Ccircle cx='3.5' cy='12.5' r='.8'/%3E%3Ccircle cx='6.5' cy='12.5' r='.8'/%3E%3Ccircle cx='9.5' cy='12.5' r='.8'/%3E%3Ccircle cx='12.5' cy='12.5' r='.8'/%3E%3C/svg%3E"); }
.sec-qsets { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1.8 10.8 10.8 1.8l3.4 3.4-9 9z'/%3E%3Cpath d='M5.1 7.5l1.4 1.4M7.4 5.2l1.4 1.4M9.7 2.9l1.4 1.4'/%3E%3C/svg%3E"); }
.sec-attributes { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.5 3.5 1.8 8l3.7 4.5M10.5 3.5 14.2 8l-3.7 4.5M9 2.5 7 13.5'/%3E%3C/svg%3E"); }
.sec-owner { --sec-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8' cy='5.3' r='2.8'/%3E%3Cpath d='M2.6 14c.6-2.9 2.8-4.6 5.4-4.6s4.8 1.7 5.4 4.6'/%3E%3C/svg%3E"); }

.upload-targets {
    max-height: 50vh;
    overflow-y: auto;
}

.georef-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: var(--op-text-xs);
    font-weight: 600;
    color: var(--tone-fg);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.georef-number {
    min-width: 1.1rem;
    text-align: right;
}

/* highlighted rows follow the tones */
.op-table > tbody > tr.table-warning > * {
    --bs-table-bg: var(--op-warning-bg);
    --bs-table-color: var(--op-text);
    --bs-table-striped-bg: var(--op-warning-bg);
    --bs-table-hover-bg: color-mix(in srgb, var(--op-warning-bg) 70%, var(--op-warning-border));
    --bs-table-hover-color: var(--op-text);
    border-color: var(--op-border);
}

.op-table > tbody > tr.table-danger > * {
    --bs-table-bg: var(--op-danger-bg);
    --bs-table-color: var(--op-text);
    --bs-table-striped-bg: var(--op-danger-bg);
    border-color: var(--op-border);
}

.member-ordinal {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

    .member-ordinal .member-swatch {
        margin: 0;
    }

.member-model {
    min-width: 10rem;
}

.member-warning {
    display: flex;
    align-items: flex-start;
    gap: 0.3rem;
    margin-top: 0.15rem;
    color: var(--op-warning-fg);
}

    .member-warning .op-icon {
        width: 0.8rem;
        height: 0.8rem;
        margin-top: 0.15rem;
    }

.fed-description {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* tables inside dialogs stick to the top of the scrolling body */
.modal .op-table,
.op-table-scroll .op-table {
    --op-sticky-top: 0px;
}

.conversion-source {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem 0.8rem;
    padding: 0.7rem 0.85rem;
    margin-bottom: 0.85rem;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius-lg);
    background: var(--op-surface-2);
}

.conversion-flow {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    color: var(--op-text-3);
}

    .conversion-flow .schema-chip {
        font-size: var(--op-text-xs);
        padding: 0.15rem 0.5rem;
    }

.report-summary {
    padding: 0.35rem 0;
    cursor: pointer;
}

    .report-summary:hover {
        color: var(--op-accent);
    }

.upload-spinner {
    width: 0.45rem;
    height: 0.45rem;
    color: var(--tone-dot);
}

.hero-figure.is-danger strong,
.op-table .sub.is-danger {
    color: var(--op-danger-fg);
}

/* point clouds (docs/07 §Nuvole di punti): source format chip (FormatChip, same look as the schema chip), class histogram,
   attribute chips of the list */
.format-las { --schema: var(--op-accent-fg); }
.format-e57 { --schema: var(--op-success-fg); }
.format-ply { --schema: var(--op-warning-fg); }
.format-text { --schema: var(--op-info-fg); }

/* Revit (docs/07 §Revit, docs/11): format chip, thumbnail stored in the file, parameter tables */
.format-revit { --schema: var(--op-info-fg); }

/* AutoCAD (docs/07 §AutoCAD, docs/12): format chip (DWG, DXF), colour swatch of the layers */
.format-cad { --schema: var(--op-warning-fg); }

/* SketchUp (docs/07 §SketchUp, docs/13): format chip (SKP); thumbnails and swatches reuse .revit-preview / .revit-list-thumb / .cad-swatch */
.format-sketchup { --schema: var(--op-accent-fg); }

/* Navisworks (docs/07 §Navisworks, docs/14): format chip (NWD, NWC, NWF); thumbnails and swatches reuse .revit-preview / .revit-list-thumb / .cad-swatch */
.format-navisworks { --schema: var(--op-info-fg); }

/* 3D models (docs/07 §Modelli 3D, docs/15): format chips of the two sections; previews and swatches reuse .revit-preview / .revit-list-thumb / .cad-swatch */
.format-model3d { --schema: var(--op-success-fg); }
.format-3dsmax { --schema: var(--op-warning-fg); }

/* PDF drawings (docs/07 §PDF, docs/16): format chip; the converted page of the pages table; swatches reuse .cad-swatch */
.format-pdf { --schema: var(--op-danger-fg); }
.pdf-page-row.is-converted > * { background-color: var(--op-accent-bg, var(--bs-tertiary-bg)); }
.pdf-scale-input { width: 6.5rem; }
.scene-node-depth { display: inline-block; flex: 0 0 auto; }

.cad-swatch {
    display: inline-block;
    flex: 0 0 auto;
    width: 0.8rem;
    height: 0.8rem;
    border-radius: 0.2rem;
    border: 1px solid var(--op-border-strong, var(--op-border));
    vertical-align: -0.1em;
    margin-right: 0.4rem;
}

.revit-preview {
    display: block;
    width: 100%;
    max-width: 16rem;
    aspect-ratio: 1;
    object-fit: contain;
    border: 1px solid var(--op-border);
    border-radius: var(--op-radius);
    background: #fff;
}

.revit-preview-empty {
    display: grid;
    place-items: center;
    width: 100%;
    max-width: 16rem;
    aspect-ratio: 1;
    border: 1px dashed var(--op-border);
    border-radius: var(--op-radius);
    color: var(--op-text-3);
    font-size: 0.8rem;
    text-align: center;
    padding: 1rem;
}

.revit-list-thumb {
    width: 2rem;
    height: 2rem;
    object-fit: contain;
    border-radius: 0.25rem;
    background: #fff;
    border: 1px solid var(--op-border);
}

.pc-class-bar {
    height: 0.45rem;
    border-radius: var(--op-radius-pill);
    background: var(--op-surface-3);
    overflow: hidden;
}

    .pc-class-bar > span {
        display: block;
        height: 100%;
        min-width: 2px;
        border-radius: inherit;
        background: var(--tone-dot, var(--op-neutral-dot));
    }

.pc-classes td {
    padding-block: 0.3rem;
}

.pc-attributes {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    min-width: 11rem;
}

.pc-group-label {
    margin: 0.75rem 0 0.35rem;
    font-size: var(--op-text-2xs);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--op-text-3);
}

/* origin of a check (ValidationOrigins in Opera.Contracts): a small rounded tag beside the severity of a group of problems;
   its own hues, never those of the severities */
.op-badge.origin-tag {
    border-radius: var(--op-radius-pill);
    padding-inline: 0.45rem;
    font-weight: 600;
    cursor: default;
}
.origin-schema { --tone-fg: var(--op-neutral-fg); --tone-bg: var(--op-neutral-bg); --tone-border: var(--op-neutral-border); }
.origin-data { --tone-fg: var(--op-accent-fg); --tone-bg: var(--op-accent-bg); --tone-border: var(--op-accent-border); }
.origin-bsi { --tone-fg: var(--op-violet-fg); --tone-bg: var(--op-violet-bg); --tone-border: var(--op-violet-border); }
.origin-ids { --tone-fg: var(--op-teal-fg); --tone-bg: var(--op-teal-bg); --tone-border: var(--op-teal-border); }
.origin-plugin { --tone-fg: var(--op-neutral-fg); --tone-bg: transparent; --tone-border: var(--op-neutral-dot); }

/* tones: .tone-* sets the palette that .op-badge, .op-count, .op-dot, .op-callout, tiles and icon discs read. Kept at the
   end of the file on purpose: a tone class must win over the neutral defaults those components declare. */
.tone-success { --tone-fg: var(--op-success-fg); --tone-bg: var(--op-success-bg); --tone-border: var(--op-success-border); --tone-dot: var(--op-success-dot); }
.tone-warning { --tone-fg: var(--op-warning-fg); --tone-bg: var(--op-warning-bg); --tone-border: var(--op-warning-border); --tone-dot: var(--op-warning-dot); }
.tone-danger { --tone-fg: var(--op-danger-fg); --tone-bg: var(--op-danger-bg); --tone-border: var(--op-danger-border); --tone-dot: var(--op-danger-dot); }
.tone-info { --tone-fg: var(--op-info-fg); --tone-bg: var(--op-info-bg); --tone-border: var(--op-info-border); --tone-dot: var(--op-info-dot); }
.tone-neutral { --tone-fg: var(--op-neutral-fg); --tone-bg: var(--op-neutral-bg); --tone-border: var(--op-neutral-border); --tone-dot: var(--op-neutral-dot); }
.tone-accent { --tone-fg: var(--op-accent-fg); --tone-bg: var(--op-accent-bg); --tone-border: var(--op-accent-border); --tone-dot: var(--op-accent-dot); }

/* ───────────── Dashboard: figures and charts (docs/07 «Dashboard») ─────────────
   Categorical slots of the charts (light admin pages; validated palette: adjacent CVD ΔE ≥ 9.1, normal-vision ΔE ≥ 19.6;
   slots 3–5 are below 3:1 on white, so every chart has a legend, values in text and a table view). Fixed order, never by rank. */
.viz {
    --viz-1: #2a78d6;
    --viz-2: #eb6834;
    --viz-3: #1baf7a;
    --viz-4: #eda100;
    --viz-5: #e87ba4;
    --viz-6: #008300;
    --viz-grid: #e8ebef;
    --viz-axis: var(--op-text-3, #6b7487);
    --viz-track: #e4edfc;
}

/* the dark pages: the grid and the tracks recede on the dark surface (the categorical slots stay, they read on dark too) */
[data-bs-theme=dark] .viz {
    --viz-grid: #262d3a;
    --viz-track: #1b2638;
}

.viz-swatch {
    display: inline-block;
    flex: none;
    width: 0.65rem;
    height: 0.65rem;
    border-radius: 2px;
    background: var(--swatch);
}

.viz-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
    margin: 0 0 0.6rem;
    padding: 0;
    list-style: none;
    font-size: var(--op-text-xs);
    color: var(--op-text-2);
}

    .viz-legend li {
        display: inline-flex;
        align-items: center;
        gap: 0.35rem;
    }

.viz-chart {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}

    .viz-chart text {
        font-family: var(--op-font-sans);
        font-size: 11px;
        fill: var(--viz-axis);
    }

    .viz-chart .viz-gridline { stroke: var(--viz-grid); stroke-width: 1; shape-rendering: crispEdges; }
    .viz-chart .viz-baseline { stroke: var(--op-border-strong); stroke-width: 1; shape-rendering: crispEdges; }
    .viz-chart .viz-hit { fill: transparent; }
    .viz-chart .viz-col:hover .viz-hit { fill: var(--op-hover); }
    .viz-chart:has(.viz-col:hover) .viz-col:not(:hover) .viz-mark { opacity: 0.45; }

/* hero figures of the disk usage: uploaded, viewer data, total */
.usage-figures {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.75rem;
    margin-bottom: 0.9rem;
}

.usage-figure {
    min-width: 0;
}

    .usage-figure .label {
        display: flex;
        align-items: center;
        gap: 0.4rem;
        font-size: var(--op-text-xs);
        color: var(--op-text-2);
    }

    .usage-figure .value {
        font-size: 1.6rem;
        font-weight: 600;
        line-height: 1.2;
        color: var(--op-text);
        white-space: nowrap;
    }

    .usage-figure.is-total .value {
        font-size: 2rem;
    }

    .usage-figure .sub {
        font-size: var(--op-text-xs);
        color: var(--op-text-3, var(--op-text-2));
    }

/* part-to-whole bar: segments separated by a 2px surface gap */
.viz-stack {
    display: flex;
    gap: 2px;
    height: 0.75rem;
    margin: 0.25rem 0 0.35rem;
    border-radius: var(--op-radius-sm);
    overflow: hidden;
    background: var(--op-surface-3, #eef1f5);
}

    .viz-stack > span {
        min-width: 3px;
        background: var(--swatch);
    }

/* horizontal bars: label, bar, value at the tip */
.viz-bars {
    display: grid;
    grid-template-columns: minmax(7rem, 38%) minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.35rem 0.6rem;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: var(--op-text-sm);
}

    .viz-bars > li {
        display: contents;
    }

    .viz-bars .bar-label {
        display: inline-flex;
        align-items: center;
        gap: 0.4rem;
        min-width: 0;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        color: var(--op-text);
    }

    .viz-bars .bar-track {
        height: 0.6rem;
    }

    .viz-bars .bar-fill {
        display: block;
        height: 100%;
        min-width: 2px;
        border-radius: 0 4px 4px 0;
        background: var(--swatch, var(--viz-1));
    }

    .viz-bars .bar-value {
        font-variant-numeric: tabular-nums;
        color: var(--op-text-2);
        text-align: right;
        white-space: nowrap;
    }

.viz-subhead {
    margin: 1rem 0 0.5rem;
    font-size: var(--op-text-xs);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--op-text-2);
}

.viz-table summary {
    margin-top: 0.6rem;
    font-size: var(--op-text-xs);
    color: var(--op-accent);
    cursor: pointer;
}

.viz-table table {
    margin-top: 0.4rem;
    font-size: var(--op-text-xs);
}

/* the one import button of the dashboard */
.btn-import {
    padding: 0.55rem 1.1rem;
    font-size: var(--op-text-base);
    font-weight: 600;
    box-shadow: var(--op-shadow);
}

    .btn-import .op-icon {
        width: 1.1rem;
        height: 1.1rem;
    }

.dashboard-sections td.num,
.dashboard-sections th.num {
    font-variant-numeric: tabular-nums;
}

.dashboard-sections .share-bar {
    width: 6rem;
    margin-top: 0;
}

@media (max-width: 575.98px) {
    .usage-figures {
        grid-template-columns: minmax(0, 1fr);
    }

    .viz-bars {
        grid-template-columns: minmax(5rem, 40%) minmax(0, 1fr) auto;
    }
}


/* Ribbon of the viewer windows (ViewerFrame + ViewerToolBar, docs/07 «Barra multifunzione»): under the top bar, a strip
   of tabs with the collapse button on its right, then the groups of the active tab (large buttons with a label, the
   group name under them). Global because both components render into it. Desktop only: the narrow layout (≤720px) keeps
   the vertical tool menu on the stage. Collapsed, the body floats over the stage while the mouse is on the tabs or on it
   (or a drop-down of it is open, or the keyboard is in it). */
.viewer-ribbon {
    position: relative;
    z-index: 30; /* above the stage layers (tools 4, edge tabs 5, resizers 6) */
    flex: 0 0 auto;
    background: var(--op-bar-2);
    border-bottom: 1px solid var(--op-border);
    font-size: var(--op-text-sm);
}

.ribbon-tabs {
    display: flex;
    align-items: flex-end;
    gap: 0.5rem;
    min-height: 1.85rem;
    padding: 0.15rem 0.45rem 0 0.6rem;
    background: var(--op-bar);
    border-bottom: 1px solid var(--op-border);
}

.ribbon-tablist {
    flex: 1 1 auto;
    display: flex;
    align-items: flex-end;
    gap: 0.15rem;
    min-width: 0;
}

.ribbon-tab {
    margin-bottom: -1px;
    padding: 0.22rem 0.9rem 0.28rem;
    border: 1px solid transparent;
    border-bottom: 0;
    border-radius: var(--op-radius) var(--op-radius) 0 0;
    background: transparent;
    color: var(--op-text-2);
    font-size: var(--op-text-sm);
    font-weight: 600;
    cursor: default;
}

    .ribbon-tab:hover {
        color: var(--op-text);
    }

    .ribbon-tab.is-active {
        border-color: var(--op-border);
        background: var(--op-bar-2);
        color: var(--op-text-strong);
    }

    /* collapsed: the active tab is not joined to a body under it */
    .viewer-ribbon.is-collapsed .ribbon-tab.is-active {
        margin-bottom: 0;
        border-bottom: 1px solid var(--op-border);
        border-radius: var(--op-radius);
    }

.ribbon-collapse {
    align-self: center;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.5rem;
    padding: 0;
    border: 0;
    border-radius: var(--op-radius-sm, 4px);
    background: transparent;
    color: var(--op-text-2);
    cursor: pointer;
}

    .ribbon-collapse:hover {
        background: var(--op-bar-hover);
        color: var(--op-text);
    }

.ribbon-tab:focus-visible,
.ribbon-collapse:focus-visible,
.ribbon-btn:focus-visible {
    outline: 2px solid var(--op-focus);
    outline-offset: -2px;
}

.ribbon-body {
    display: flex;
    align-items: stretch;
    padding: 0.25rem 0.4rem 0.1rem;
    background: var(--op-bar-2);
}

.viewer-ribbon.is-collapsed .ribbon-body {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    border-bottom: 1px solid var(--op-border);
    box-shadow: var(--op-shadow-float);
    visibility: hidden;
    opacity: 0;
    transform: translateY(-0.3rem);
    /* hidden a moment after the mouse leaves, so a slip of the pointer does not close it */
    transition: opacity 0.12s ease 0.25s, transform 0.12s ease 0.25s, visibility 0s linear 0.37s;
}

.viewer-ribbon.is-collapsed:hover .ribbon-body,
.viewer-ribbon.is-collapsed:has(.viewer-flyout) .ribbon-body,
.viewer-ribbon.is-collapsed:has(:focus-visible) .ribbon-body {
    visibility: visible;
    opacity: 1;
    transform: none;
    transition: opacity 0.12s ease, transform 0.12s ease, visibility 0s;
}

.ribbon-tools {
    display: flex;
    align-items: stretch;
}

.ribbon-group {
    display: flex;
    flex-direction: column;
    padding: 0 0.4rem;
    border-right: 1px solid var(--op-border);
}

.ribbon-group-items {
    flex: 1 1 auto;
    display: flex;
    align-items: flex-start;
    gap: 0.1rem;
}

.ribbon-group-label {
    padding: 0.1rem 0 0.15rem;
    color: var(--op-text-3);
    font-size: var(--op-text-2xs);
    letter-spacing: 0.02em;
    text-align: center;
    white-space: nowrap;
}

/* a tool with options: the drop-down is placed under its button */
.ribbon-item {
    position: relative;
}

.ribbon-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    min-width: 3.5rem;
    max-width: 5.75rem;
    height: 3.6rem;
    padding: 0.35rem 0.35rem 0.2rem;
    border: 1px solid transparent;
    border-radius: var(--op-radius);
    background: transparent;
    color: var(--op-text);
    font-size: var(--op-text-xs);
    line-height: 1.15;
    text-align: center;
    cursor: pointer;
    transition: background-color var(--op-dur) var(--op-ease), color var(--op-dur) var(--op-ease);
}

    a.ribbon-btn {
        text-decoration: none; /* the download of the file is a link drawn as a button */
    }

    .ribbon-btn:hover:not(:disabled) {
        background: var(--op-bar-hover);
        color: var(--op-text-strong);
    }

    .ribbon-btn.is-open {
        background: var(--op-surface-3);
        color: var(--op-text-strong);
    }

    /* a tool that is on */
    .ribbon-btn.is-active {
        border-color: var(--op-active-border);
        background: var(--op-active-bg);
        color: var(--op-active-fg);
    }

    .ribbon-btn:disabled {
        opacity: 0.4;
        cursor: default;
    }

.ribbon-icon {
    flex: 0 0 auto;
    width: 1.35rem;
    height: 1.35rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

    .ribbon-icon .fill {
        fill: currentColor;
        fill-opacity: 0.55;
    }

    .ribbon-icon .cut {
        stroke: var(--op-accent, #5b97ff);
        stroke-width: 1.5;
    }

.ribbon-collapse .ribbon-icon {
    width: 1rem;
    height: 1rem;
    stroke-width: 1.5;
}

/* a tool with options: a chevron after the label, kept on its line */
.ribbon-btn.has-menu {
    max-width: none;
}

    .ribbon-btn.has-menu .ribbon-btn-label {
        white-space: nowrap;
    }

.ribbon-caret {
    width: 0.55rem;
    height: 0.55rem;
    margin-left: 0.15rem;
    vertical-align: 0.05rem;
    fill: none;
    stroke: var(--op-text-2);
    stroke-width: 1.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* the options of a tool (ViewerToolBar's flyout) as a drop-down under its button; from the fourth group on it opens
   towards the left, so the last groups do not run out of the window */
.viewer-ribbon .ribbon-item > .viewer-flyout {
    top: calc(100% + 0.3rem);
    left: 0;
    right: auto;
    transform: none;
    max-height: calc(100vh - 9rem);
    z-index: 1;
}

.viewer-ribbon .ribbon-group:nth-child(n+4) .ribbon-item > .viewer-flyout {
    left: auto;
    right: 0;
}

/* a desktop window not wide enough for the labels: icons only (the tooltips name them) */
@media (max-width: 1240px) {
    .ribbon-btn {
        min-width: 2.4rem;
        height: 2.4rem;
        padding: 0.5rem;
    }

    .ribbon-btn-label {
        display: none;
    }
}

@media (max-width: 720px) {
    .viewer-ribbon {
        display: none;
    }
}
