/* Youmy ERP design system: deep navy, electric blue and turquoise. */

:root {
    --appcore-ink: #071a3d;
    --appcore-muted: #65738a;
    --appcore-line: #e3eaf3;
    --appcore-accent: #087cf0;
    --appcore-accent-strong: #0565d5;
    --appcore-teal: #10c8b5;
    --appcore-navy: #021a3e;
    --appcore-navy-soft: #082653;
    --appcore-surface: #ffffff;
    --appcore-canvas: #f4f7fb;
    --appcore-bg: #f4f7fb;
    --appcore-shadow: 0 0.65rem 2rem rgb(2 26 62 / 8%);
    --appcore-gradient: linear-gradient(135deg, var(--appcore-accent), var(--appcore-teal));
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: Inter, "Segoe UI", Tahoma, Arial, sans-serif;
    color: var(--appcore-ink);
    background: var(--appcore-canvas);
}

html[dir="rtl"] body {
    font-family: Tahoma, "Segoe UI", Arial, sans-serif;
}

code,
pre,
input[name="userName"] {
    direction: ltr;
    text-align: left;
}

/* Blazor focuses the page heading after navigation for screen readers. */
h1:focus {
    outline: none;
}

/* Off-screen for sight, present for a screen reader.
   `margin: -1px` matters: absolutely positioned boxes still contribute to their
   containing block's scrollable overflow, so this 1px span sitting at the far
   edge of a wide table was on its own enough to give the whole document a
   horizontal scrollbar on a phone. Pulling it back inside costs nothing and
   stops it being able to widen anything. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Shell -------------------------------------------------------------- */

.appcore-shell {
    display: grid;
    grid-template-columns: 16.5rem minmax(0, 1fr);
    min-height: 100vh;
}

.appcore-shell__nav {
    position: sticky;
    top: 0;
    display: flex;
    flex-direction: column;
    height: 100vh;
    box-sizing: border-box;
    overflow-y: auto;
    background:
        radial-gradient(circle at 20% 0%, rgb(8 124 240 / 22%), transparent 32%),
        linear-gradient(180deg, var(--appcore-navy), #01142f);
    border-inline-end: 1px solid rgb(255 255 255 / 8%);
    padding: 1.5rem 1rem;
    color: #fff;
}

.appcore-shell__nav-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.appcore-shell__nav-close,
.appcore-shell__menu-toggle,
.appcore-shell__nav-backdrop {
    display: none;
}

.appcore-shell__brand {
    margin: 0 0 1.75rem;
    color: #fff;
    text-decoration: none;
}

.youmy-brand-mark {
    position: relative;
    display: inline-block;
    width: 2.5rem;
    height: 2.75rem;
    flex: none;
}

.youmy-brand-mark::before,
.youmy-brand-mark::after {
    position: absolute;
    top: 0.8rem;
    width: 0.72rem;
    height: 2rem;
    border-radius: 999px;
    content: "";
    transform-origin: 50% 85%;
}

.youmy-brand-mark::before {
    left: 0.55rem;
    background: linear-gradient(180deg, #168ff7, #075ad8);
    transform: rotate(-43deg);
}

.youmy-brand-mark::after {
    right: 0.55rem;
    background: linear-gradient(180deg, #1dd8c3, #069bad);
    transform: rotate(43deg);
}

.youmy-brand-mark > span {
    position: absolute;
    top: 0.05rem;
    left: 50%;
    width: 0.78rem;
    height: 0.78rem;
    border-radius: 50%;
    background: #0a7df0;
    box-shadow: 0 0 1.2rem rgb(10 125 240 / 55%);
    transform: translateX(-50%);
}

.youmy-wordmark {
    display: grid;
    line-height: 1;
}

.youmy-wordmark strong {
    color: inherit;
    font-size: 1.65rem;
    font-weight: 650;
    letter-spacing: 0.015em;
}

.youmy-wordmark small {
    margin-top: 0.28rem;
    color: var(--appcore-teal);
    font-size: 0.67rem;
    font-weight: 800;
    letter-spacing: 0.45em;
    text-align: center;
}

.appcore-shell__product-label {
    margin: auto 0 0;
    padding: 1rem 0.65rem 0;
    border-top: 1px solid rgb(255 255 255 / 10%);
    color: rgb(255 255 255 / 48%);
    font-size: 0.72rem;
}

.appcore-shell__workspace {
    min-width: 0;
}

.appcore-shell__topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 4.5rem;
    box-sizing: border-box;
    padding: 0.75rem clamp(1rem, 3vw, 2.5rem);
    border-bottom: 1px solid var(--appcore-line);
    background: rgb(255 255 255 / 92%);
    backdrop-filter: blur(0.8rem);
}

.appcore-shell__identity {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
}

.appcore-shell__identity-copy {
    display: grid;
    gap: 0.1rem;
}

.appcore-shell__eyebrow {
    color: var(--appcore-teal);
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.16em;
}

.appcore-shell__workspace-name {
    color: var(--appcore-ink);
    font-size: 1rem;
    font-weight: 700;
}

.appcore-shell__main {
    width: 100%;
    min-width: 0;
    padding: clamp(1rem, 3vw, 2.5rem);
}

/* Prose gets a reading width; data does not.

   The workspace used to cap at 96rem and centre itself, which is right for a
   paragraph and wrong for everything this product actually shows: on a 1080p
   screen it left a dead margin either side and then squeezed the tables into
   what was left. The cap now applies to running text only, so a directory can
   use the monitor and a sentence still does not run 1600px wide. */
.appcore-shell__main > p,
.appcore-shell__main > section > p {
    max-width: 60rem;
}

.appcore-shell__main > h1,
.appcore-shell__main section > h1 {
    margin-top: 0;
    color: var(--appcore-ink);
    font-size: clamp(1.7rem, 3vw, 2.15rem);
    letter-spacing: -0.035em;
}

/* Collapsing the rail on a wide screen ---------------------------------
   Separate control from the mobile drawer button, and deliberately so: one
   button whose meaning changed with the viewport could not say what it would
   do, and CSS cannot tell the component which breakpoint is active without
   JavaScript. Below 64rem this button is hidden and the drawer takes over. */

.appcore-shell__nav-collapse {
    display: none;
}

@media (min-width: 64.01rem) {
    .appcore-shell__nav-collapse {
        display: inline-grid;
        place-items: center;
        width: 2rem;
        height: 2rem;
        flex: 0 0 auto;
        padding: 0;
        border: 1px solid rgb(255 255 255 / 18%);
        border-radius: 0.5rem;
        background: rgb(255 255 255 / 8%);
        color: #fff;
        cursor: pointer;
    }

    .appcore-shell--collapsed {
        grid-template-columns: 4.5rem 1fr;
    }

    .appcore-shell--collapsed .appcore-shell__nav {
        padding-inline: 0.6rem;
        align-items: center;
    }

    /* Everything that is words rather than an icon. The rail keeps its icons so
       the menu stays usable collapsed, rather than becoming a blank strip. */
    .appcore-shell--collapsed .appcore-shell__nav .youmy-wordmark,
    .appcore-shell--collapsed .appcore-shell__nav .appcore-shell__brand span:not([aria-hidden]),
    .appcore-shell--collapsed .appcore-shell__product-label,
    .appcore-shell--collapsed .appcore-menu__group-title,
    .appcore-shell--collapsed .appcore-menu__label,
    .appcore-shell--collapsed .appcore-menu__twisty,
    .appcore-shell--collapsed .appcore-menu__list--nested {
        display: none;
    }

    .appcore-shell--collapsed .appcore-menu__link {
        justify-content: center;
        padding-inline: 0.5rem;
    }
}

@media (max-width: 64rem) {
    .appcore-shell {
        grid-template-columns: 1fr;
    }

    .appcore-shell__nav {
        position: fixed;
        inset-block: 0;
        inset-inline-start: 0;
        z-index: 110;
        width: min(19rem, calc(100vw - 3.5rem));
        height: 100dvh;
        border: 0;
        box-shadow: 1.25rem 0 3rem rgb(0 10 30 / 28%);
        transform: translateX(-105%);
        transition: transform 180ms ease;
    }

    html[dir="rtl"] .appcore-shell__nav {
        transform: translateX(105%);
    }

    .appcore-shell__nav--open,
    html[dir="rtl"] .appcore-shell__nav--open {
        transform: translateX(0);
    }

    .appcore-shell__nav-close,
    .appcore-shell__menu-toggle {
        display: inline-grid;
        place-items: center;
        width: 2.5rem;
        height: 2.5rem;
        flex: 0 0 auto;
        padding: 0;
    }

    .appcore-shell__nav-close {
        border-color: rgb(255 255 255 / 18%);
        background: rgb(255 255 255 / 8%);
        color: #fff;
        font-size: 1.5rem;
    }

    .appcore-shell__menu-toggle .appcore-icon {
        width: 1.25rem;
        height: 1.25rem;
    }

    .appcore-shell__nav-backdrop {
        position: fixed;
        inset: 0;
        z-index: 100;
        display: block;
        width: 100%;
        height: 100%;
        padding: 0;
        border: 0;
        border-radius: 0;
        background: rgb(2 12 30 / 58%);
    }

    .appcore-shell__product-label {
        display: none;
    }

    .appcore-shell__topbar {
        padding-inline: clamp(0.75rem, 3vw, 1.5rem);
    }
}

@media (max-width: 34rem) {
    /* Full width on a phone: a 19rem drawer over a 20rem screen leaves a strip of
       page that is too narrow to read and wide enough to tap by accident. */
    .appcore-shell__nav {
        width: 100vw;
        max-width: 100vw;
    }
}

@media (max-width: 34rem) {
    .appcore-shell__topbar {
        min-height: 4rem;
        gap: 0.5rem;
        padding-block: 0.55rem;
    }

    .appcore-shell__identity-copy {
        display: none;
    }

    .appcore-shell__main {
        padding: 1rem 0.75rem;
    }
}

/* Password reveal ----------------------------------------------------

   The button is positioned over the field rather than beside it, so the input
   stays an ordinary input in whatever form it lands in - the login card, a
   modal, the account page - and none of those layouts have to know it exists.

   Selectors are doubled up on purpose. `.appcore-login__card button` is a type
   selector inside a class (0,1,1) and would otherwise beat a bare
   `.appcore-password__reveal` (0,1,0), turning the reveal into a full-width
   primary button in the middle of the sign-in form. */

.appcore-password__control {
    position: relative;
    display: block;
}

.appcore-password .appcore-password__input {
    /* Room for the button, on whichever side the writing direction puts it. */
    width: 100%;
    box-sizing: border-box;
    padding-inline-end: 2.5rem;
}

/* Edge draws a reveal control of its own inside every password box. Left alone the
   reader gets two eyes side by side, and only one of them is ours: the native one
   decides for itself when to put the password back, so the field can stay legible
   after everything below has masked it. */
.appcore-password .appcore-password__input::-ms-reveal,
.appcore-password .appcore-password__input::-ms-clear {
    display: none;
}

.appcore-password .appcore-password__reveal {
    display: none;
}

/* Only once the script that makes it work has run: a button that does nothing
   is worse than no button. */
[data-appcore-enhanced] .appcore-password .appcore-password__reveal {
    position: absolute;
    inset-inline-end: 0.25rem;
    inset-block-start: 50%;
    transform: translateY(-50%);
    display: inline-grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0.35rem;
    background: transparent;
    color: var(--appcore-muted);
    cursor: pointer;
}

[data-appcore-enhanced] .appcore-password .appcore-password__reveal:hover,
[data-appcore-enhanced] .appcore-password .appcore-password__reveal:focus-visible {
    background: color-mix(in srgb, var(--appcore-ink) 8%, transparent);
    color: var(--appcore-ink);
}

.appcore-password__icon {
    width: 1.05rem;
    height: 1.05rem;
}

/* One icon at a time: the eye offers the reveal, the struck-through eye offers
   to take it back. Both render, so the swap needs nothing but a class. */
.appcore-password__icon--hide,
.appcore-password--revealed .appcore-password__icon--show {
    display: none;
}

.appcore-password--revealed .appcore-password__icon--hide {
    display: block;
}

/* The product and the build, stacked in the rail's foot. Two lines because a
   product name and a version number read as one meaningless string when run
   together, and the name is the half that identifies the app. */
.appcore-shell__version-product {
    display: block;
    font-weight: 600;
    color: rgb(255 255 255 / 62%);
}

.appcore-shell__version-number {
    display: block;
    font-variant-numeric: tabular-nums;
}

/* Menu --------------------------------------------------------------- */

.appcore-menu__group-title {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgb(255 255 255 / 47%);
    margin: 1.25rem 0 0.4rem;
}

.appcore-menu__list {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* A row is the link plus its twisty. They are separate controls because a parent
   in this menu is itself a page: one control that both navigated and expanded
   would leave no way to do the other. */
.appcore-menu__row {
    display: flex;
    align-items: center;
    gap: 0.15rem;
}

.appcore-menu__link {
    position: relative;
    display: flex;
    flex: 1 1 auto;
    min-width: 0;
    align-items: center;
    gap: 0.6rem;
    min-height: 2.65rem;
    box-sizing: border-box;
    padding: 0.55rem 0.75rem;
    border-radius: 0.55rem;
    color: rgb(255 255 255 / 76%);
    text-decoration: none;
    transition: background 160ms ease, color 160ms ease, transform 160ms ease;
}

.appcore-menu__icon {
    flex: 0 0 auto;
    width: 1.15rem;
    height: 1.15rem;
}

/* Truncated rather than wrapped: a long page name pushing the twisty out of the
   rail is how a parent becomes impossible to expand. */
.appcore-menu__label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.appcore-menu__twisty {
    flex: 0 0 auto;
    display: inline-grid;
    place-items: center;
    width: 1.9rem;
    height: 1.9rem;
    padding: 0;
    border: 0;
    border-radius: 0.45rem;
    background: transparent;
    color: rgb(255 255 255 / 62%);
    cursor: pointer;
}

.appcore-menu__twisty:hover,
.appcore-menu__twisty:focus-visible {
    background: rgb(255 255 255 / 10%);
    color: #fff;
}

.appcore-menu__chevron {
    width: 1rem;
    height: 1rem;
    transition: transform 160ms ease;
}

.appcore-menu__chevron--open {
    transform: rotate(90deg);
}

html[dir="rtl"] .appcore-menu__chevron {
    transform: rotate(180deg);
}

html[dir="rtl"] .appcore-menu__chevron--open {
    transform: rotate(90deg);
}

/* The rule that makes the nesting readable at a glance. Indentation alone reads
   as a rendering accident; the line says the entries belong to the one above. */
.appcore-menu__list--nested {
    margin-inline-start: 1.4rem;
    border-inline-start: 1px solid rgb(255 255 255 / 14%);
}

.appcore-menu__link:hover,
.appcore-menu__link:focus-visible {
    background: rgb(255 255 255 / 8%);
    color: #fff;
    transform: translateX(0.12rem);
}

.appcore-menu__link.active {
    background: var(--appcore-gradient);
    color: #fff;
    box-shadow: 0 0.45rem 1.2rem rgb(7 124 240 / 23%);
    font-weight: 650;
}

/* Collections -------------------------------------------------------- */

.appcore-page__grid {
    display: grid;
    gap: 1.25rem;
    /* min(20rem, 100%), not 20rem: a bare floor is kept even when the container
       is narrower than it, so on a 320px phone this 320px track pushed the whole
       page wider than the viewport and the cards sat over the border. */
    grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
}

.appcore-collection,
.appcore-role-assignment,
.appcore-permission-grant {
    background: var(--appcore-surface);
    border: 1px solid var(--appcore-line);
    border-radius: 0.9rem;
    padding: 1rem 1.25rem;
    margin-block: 1rem;
    box-shadow: var(--appcore-shadow);
}

.appcore-collection__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.appcore-collection__header h2 {
    font-size: 1rem;
    margin: 0;
}

.appcore-collection__viewport {
    position: relative;
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    -webkit-overflow-scrolling: touch;
}

/* Opened action menus have to escape the scroll box, or the panel is clipped by
   the very thing that stops the table overflowing. Same escape the newer grid
   uses; without it the fix for one problem creates another. */
.appcore-collection__viewport:has(.appcore-action-menu__panel) {
    overflow: visible;
}

.appcore-collection__table {
    width: 100%;
    /* Content-sized rather than squeezed: with the viewport above, a wide table
       scrolls instead of crushing every column into unreadable slivers. */
    min-width: max-content;
    border-collapse: collapse;
    margin-top: 0.75rem;
}

.appcore-collection__table th,
.appcore-collection__table td {
    text-align: left;
    padding: 0.45rem 0.5rem;
    border-bottom: 1px solid var(--appcore-line);
    font-size: 0.9rem;
}

.appcore-collection__status {
    color: var(--appcore-muted);
    font-size: 0.9rem;
}

.appcore-collection__status--error {
    color: #a3242c;
}

/* Reusable grid view ------------------------------------------------ */

.appcore-grid {
    display: grid;
    gap: 0.75rem;
    min-width: 0;
}

.appcore-grid__toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    justify-content: space-between;
    gap: 0.75rem;
}

.appcore-type-definitions__search {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.appcore-type-definitions__search label {
    color: var(--appcore-muted);
    font-size: 0.85rem;
}

.appcore-type-definitions__search input {
    min-width: min(20rem, 70vw);
    border: 1px solid var(--appcore-line);
    border-radius: 0.35rem;
    background: var(--appcore-surface);
    color: var(--appcore-ink);
    font: inherit;
    padding: 0.4rem 0.55rem;
}

.appcore-type-definitions__action {
    white-space: nowrap;
}

.appcore-catalog-items,
.appcore-catalog-units {
    min-width: 0;
}

.appcore-catalog-items .appcore-grid__toolbar,
.appcore-catalog-units .appcore-grid__toolbar,
.appcore-variant-directory .appcore-grid__toolbar,
.appcore-variant-unit-directory .appcore-grid__toolbar,
.appcore-variant-unit-barcode-directory .appcore-grid__toolbar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
    gap: 1rem;
}

.appcore-filter-panel {
    min-width: 0;
    border: 1px solid var(--appcore-line);
    border-radius: 0.9rem;
    background: var(--appcore-surface);
    box-shadow: 0 0.35rem 1.25rem rgb(2 26 62 / 5%);
    overflow: hidden;
}

.appcore-filter-panel__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    width: 100%;
    min-height: 3rem;
    padding: 0.7rem 1rem;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: var(--appcore-ink);
    font: inherit;
    text-align: start;
    cursor: pointer;
}

.appcore-filter-panel__toggle:hover {
    background: color-mix(in srgb, var(--appcore-accent) 5%, var(--appcore-surface));
}

.appcore-filter-panel__toggle:focus-visible {
    outline: 2px solid var(--appcore-accent);
    outline-offset: -3px;
}

.appcore-filter-panel__title {
    font-size: 0.9rem;
    font-weight: 750;
}

.appcore-filter-panel__toggle-state {
    display: inline-flex;
    align-items: center;
    gap: 0.65rem;
    flex: 0 0 auto;
}

.appcore-filter-panel__count {
    display: inline-grid;
    place-items: center;
    min-width: 1.6rem;
    min-height: 1.6rem;
    padding-inline: 0.4rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--appcore-accent) 14%, var(--appcore-surface));
    color: var(--appcore-accent-strong);
    font-size: 0.78rem;
    font-weight: 750;
}

.appcore-filter-panel__chevron {
    width: 0.55rem;
    height: 0.55rem;
    border-inline-end: 2px solid currentColor;
    border-block-end: 2px solid currentColor;
    transform: rotate(45deg) translate(-0.1rem, -0.1rem);
    transition: transform 160ms ease;
}

.appcore-filter-panel--expanded .appcore-filter-panel__chevron {
    transform: rotate(225deg) translate(-0.1rem, -0.1rem);
}

.appcore-filter-panel__content {
    padding: 1rem;
    border-top: 1px solid var(--appcore-line);
}

.appcore-catalog-filter {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
    align-items: start;
    gap: 0.85rem;
    min-width: 0;
}

.appcore-catalog-filter__dates {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.85rem;
    min-width: 0;
}

.appcore-catalog-filter__actions,
.appcore-catalog-units__filter-actions,
.appcore-catalog-items__filter-actions {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 0.45rem;
    padding-block-start: 0.75rem;
    border-top: 1px solid var(--appcore-line);
}

.appcore-catalog-filter__actions button {
    min-height: 2.5rem;
}

.appcore-catalog__create {
    min-width: max-content;
}

.appcore-catalog__primary-action {
    min-height: 2.5rem;
    white-space: nowrap;
}

.appcore-status {
    display: inline-flex;
    align-items: center;
    min-height: 1.6rem;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
}

.appcore-status--active {
    background: color-mix(in srgb, #0f9f78 14%, var(--appcore-surface));
    color: #087457;
}

.appcore-status--warning {
    background: color-mix(in srgb, #e6a700 17%, var(--appcore-surface));
    color: #8a6200;
}

.appcore-status--inactive {
    background: color-mix(in srgb, var(--appcore-muted) 14%, var(--appcore-surface));
    color: var(--appcore-muted);
}

.appcore-catalog-units__conversion-result {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.85rem;
    padding: 1rem;
    border: 1px solid color-mix(in srgb, var(--appcore-accent) 35%, var(--appcore-line));
    border-radius: 0.65rem;
    background: color-mix(in srgb, var(--appcore-accent) 7%, var(--appcore-surface));
    color: var(--appcore-ink);
    font-size: 1.05rem;
}

@media (max-width: 48rem) {
    .appcore-catalog-items .appcore-grid__toolbar,
    .appcore-catalog-units .appcore-grid__toolbar,
    .appcore-variant-directory .appcore-grid__toolbar,
    .appcore-variant-unit-directory .appcore-grid__toolbar,
    .appcore-variant-unit-barcode-directory .appcore-grid__toolbar {
        grid-template-columns: 1fr;
    }

    .appcore-catalog__create {
        grid-row: 1;
        min-width: 0;
    }

    .appcore-catalog__primary-action,
    .appcore-catalog__create > .appcore-gate,
    .appcore-catalog__create > .appcore-gate > button {
        width: 100%;
    }

    .appcore-filter-panel {
        grid-row: 2;
    }

    .appcore-filter-panel__content {
        padding: 0.85rem;
    }

    .appcore-catalog-filter {
        grid-template-columns: 1fr;
    }

    .appcore-catalog-filter__dates {
        grid-template-columns: 1fr;
    }

    .appcore-catalog-filter__actions {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .appcore-catalog-filter__actions button:only-child {
        grid-column: 1 / -1;
    }
}

.appcore-type-definitions__row-actions {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    white-space: nowrap;
}

/* Reusable row action dropdown ------------------------------------- */

.appcore-action-menu {
    position: relative;
    display: inline-flex;
    justify-content: flex-end;
    white-space: nowrap;
}

.appcore-action-menu__trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 2.5rem;
}

.appcore-action-menu__trigger .appcore-icon {
    color: var(--appcore-muted);
}

.appcore-action-menu__chevron {
    color: var(--appcore-muted);
    font-size: 0.75rem;
}

.appcore-action-menu__dismiss {
    position: fixed;
    inset: 0;
    z-index: 40;
    width: 100vw;
    height: 100vh;
    cursor: default;
    border: 0;
    border-radius: 0;
    background: transparent;
    padding: 0;
}

.appcore-action-menu__dismiss:hover {
    border: 0;
    background: transparent;
}

.appcore-action-menu__panel {
    position: absolute;
    z-index: 41;
    inset-block-start: calc(100% + 0.35rem);
    inset-inline-end: 0;
    display: grid;
    min-width: 14rem;
    overflow: hidden;
    border: 1px solid var(--appcore-line);
    border-radius: 0.7rem;
    background: var(--appcore-surface);
    box-shadow: 0 1rem 2.5rem rgb(15 23 42 / 18%);
    padding: 0.35rem;
}

.appcore-action-menu__panel > .appcore-gate {
    display: block;
}

.appcore-action-menu__item {
    display: flex;
    width: 100%;
    align-items: center;
    gap: 0.65rem;
    justify-content: flex-start;
    border: 0;
    border-radius: 0.45rem;
    background: transparent;
    color: var(--appcore-ink);
    padding: 0.55rem 0.65rem;
    text-align: start;
}

.appcore-action-menu__item:hover,
.appcore-action-menu__item:focus-visible {
    border: 0;
    background: color-mix(in srgb, var(--appcore-accent) 8%, var(--appcore-surface));
    color: var(--appcore-accent);
}

.appcore-action-menu__item--danger {
    color: #a3242c;
}

.appcore-action-menu__item--danger:hover,
.appcore-action-menu__item--danger:focus-visible {
    background: color-mix(in srgb, #c0392b 8%, var(--appcore-surface));
    color: #a3242c;
}

.appcore-icon {
    width: 1.1rem;
    height: 1.1rem;
    flex: 0 0 auto;
}

/* The grid normally scrolls horizontally. While a row menu is open its panel must
   be allowed to extend outside the viewport instead of being clipped. */
.appcore-grid__viewport:has(.appcore-action-menu__panel) {
    overflow: visible;
}

.appcore-type-definitions__danger {
    border-color: #c0392b;
    color: #a3242c;
}

.appcore-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: grid;
    place-items: center;
    overflow-y: auto;
    padding: 1rem;
    background: rgb(15 23 42 / 55%);
}

.appcore-modal {
    width: min(42rem, 100%);
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    border: 1px solid var(--appcore-line);
    border-radius: 1rem;
    background: var(--appcore-surface);
    box-shadow: 0 1.5rem 4rem rgb(15 23 42 / 28%);
}

.appcore-modal--confirmation {
    width: min(32rem, 100%);
}

.appcore-modal--wide {
    width: min(64rem, 100%);
}

.appcore-modal-backdrop--nested {
    z-index: 1010;
}

.appcore-type-capabilities__heading {
    display: grid;
    gap: 0.15rem;
}

.appcore-type-capabilities__heading span {
    color: var(--appcore-muted);
    font-size: 0.82rem;
}

.appcore-type-details {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
    margin: 0;
}

.appcore-type-details > div {
    min-width: 0;
}

.appcore-type-details dt {
    margin-bottom: 0.25rem;
    color: var(--appcore-muted);
    font-size: 0.8rem;
    font-weight: 600;
}

.appcore-type-details dd {
    margin: 0;
    overflow-wrap: anywhere;
}

.appcore-type-details__wide {
    grid-column: 1 / -1;
}

.appcore-type-details pre {
    max-height: 14rem;
    overflow: auto;
    margin: 0;
    padding: 0.75rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.35rem;
    background: var(--appcore-bg);
    white-space: pre-wrap;
}

.appcore-type-details ul {
    margin: 0;
    padding-inline-start: 1.25rem;
}

@media (max-width: 40rem) {
    .appcore-type-details {
        grid-template-columns: 1fr;
    }
}

.appcore-modal__header {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--appcore-line);
    background: var(--appcore-surface);
}

.appcore-modal__header h2 {
    margin: 0;
    font-size: 1.1rem;
}

.appcore-modal__subtitle {
    margin: 0.25rem 0 0;
    color: var(--appcore-muted);
    font-size: 0.82rem;
}

.appcore-modal__subtitle code {
    margin-inline-start: 0.35rem;
}

.appcore-modal__close {
    border: 0;
    background: transparent;
    color: var(--appcore-muted);
    font-size: 1.5rem;
    line-height: 1;
}

.appcore-modal__form {
    display: grid;
    gap: 0.9rem;
    padding: 1.25rem;
}

.appcore-modal__actions {
    justify-content: flex-end;
}

.appcore-button--danger {
    border-color: color-mix(in srgb, #a3242c 45%, var(--appcore-line));
    color: #a3242c;
}

.appcore-button--danger:hover:not(:disabled) {
    border-color: #a3242c;
    background: color-mix(in srgb, #a3242c 7%, var(--appcore-surface));
}

.appcore-attribute-values__summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 1rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.75rem;
    background: color-mix(in srgb, var(--appcore-accent) 4%, var(--appcore-surface));
}

.appcore-attribute-values__summary > div {
    display: grid;
    gap: 0.15rem;
}

.appcore-attribute-values__summary span:not(.appcore-status),
.appcore-attribute-values__empty {
    color: var(--appcore-muted);
    font-size: 0.85rem;
}

.appcore-attribute-values__empty {
    margin: 0;
    padding: 1.5rem;
    border: 1px dashed var(--appcore-line);
    border-radius: 0.75rem;
    text-align: center;
}

.appcore-attribute-values__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.85rem;
}

.appcore-attribute-value {
    display: grid;
    align-content: start;
    gap: 0.85rem;
    min-width: 0;
    padding: 1rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.8rem;
    background: var(--appcore-surface);
}

.appcore-attribute-value__heading,
.appcore-attribute-value__state,
.appcore-attribute-value__actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.appcore-attribute-value__heading > div:first-child {
    display: grid;
    gap: 0.15rem;
}

.appcore-attribute-value__heading code,
.appcore-attribute-value__state {
    color: var(--appcore-muted);
    font-size: 0.78rem;
}

.appcore-attribute-value__badges {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.3rem;
}

.appcore-attribute-value__badge {
    padding: 0.2rem 0.45rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--appcore-muted) 11%, var(--appcore-surface));
    color: var(--appcore-muted);
    font-size: 0.7rem;
    font-weight: 650;
}

.appcore-attribute-value__badge--required {
    background: color-mix(in srgb, #e6a700 14%, var(--appcore-surface));
    color: #8a6200;
}

.appcore-attribute-value__unsaved {
    color: #8a6200;
    font-weight: 650;
}

.appcore-attribute-value__actions {
    justify-content: flex-end;
    margin-block-start: auto;
    padding-block-start: 0.75rem;
    border-top: 1px solid var(--appcore-line);
}

@media (max-width: 48rem) {
    .appcore-attribute-values__grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 40rem) {
    .appcore-attribute-values__summary {
        align-items: flex-start;
    }

    .appcore-attribute-value__actions,
    .appcore-attribute-value__actions > .appcore-gate,
    .appcore-attribute-value__actions button {
        width: 100%;
    }
}

.appcore-grid__viewport {
    position: relative;
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    -webkit-overflow-scrolling: touch;
    border: 1px solid var(--appcore-line);
    border-radius: 0.9rem;
    background: var(--appcore-surface);
    box-shadow: var(--appcore-shadow);
}

.appcore-grid__table {
    width: 100%;
    min-width: max-content;
    border-collapse: collapse;
}

.appcore-grid__table caption:not(.visually-hidden) {
    padding: 0.75rem;
    color: var(--appcore-ink);
    font-weight: 600;
    text-align: start;
}

.appcore-grid__table th,
.appcore-grid__table td {
    padding: 0.65rem 0.75rem;
    border-bottom: 1px solid var(--appcore-line);
    font-size: 0.9rem;
    text-align: start;
    vertical-align: middle;
}

.appcore-grid__table th {
    background: #f7faff;
    color: var(--appcore-muted);
    font-size: 0.8rem;
    font-weight: 650;
    letter-spacing: 0.015em;
    white-space: nowrap;
}

.appcore-grid__table tbody tr:last-child > td {
    border-bottom: 0;
}

.appcore-grid--dense .appcore-grid__table th,
.appcore-grid--dense .appcore-grid__table td {
    padding: 0.4rem 0.55rem;
}

.appcore-grid--striped .appcore-grid__table tbody tr:nth-child(even) {
    background: color-mix(in srgb, var(--appcore-canvas) 60%, transparent);
}

.appcore-grid--selectable .appcore-grid__table tbody tr:not(:has(.appcore-grid__state)) {
    cursor: pointer;
}

.appcore-grid--selectable .appcore-grid__table tbody tr:not(:has(.appcore-grid__state)):hover,
.appcore-grid--selectable .appcore-grid__table tbody tr:not(:has(.appcore-grid__state)):focus-visible {
    background: color-mix(in srgb, var(--appcore-accent) 7%, var(--appcore-surface));
    outline: none;
}

.appcore-grid__row--selected {
    background: color-mix(in srgb, var(--appcore-accent) 12%, var(--appcore-surface)) !important;
    box-shadow: inset 0.2rem 0 var(--appcore-accent);
}

.appcore-grid__sort {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    padding: 0;
}

.appcore-grid__sort:hover {
    color: var(--appcore-accent);
}

.appcore-grid__state {
    min-width: min(30rem, 80vw);
    padding: 1.25rem !important;
    color: var(--appcore-muted);
    text-align: center !important;
}

.appcore-grid__state--error {
    color: #a3242c;
}

.appcore-grid__pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem 1rem;
    color: var(--appcore-muted);
    font-size: 0.82rem;
}

.appcore-grid__page-size,
.appcore-grid__pager-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.appcore-grid__page-size select {
    border: 1px solid var(--appcore-line);
    border-radius: 0.35rem;
    background: var(--appcore-surface);
    color: var(--appcore-ink);
    font: inherit;
    padding: 0.3rem 0.45rem;
}

.appcore-grid__pager-actions button {
    min-width: 2rem;
    padding-inline: 0.45rem;
}

@media (max-width: 40rem) {
    .appcore-modal-backdrop {
        align-items: end;
        padding: 0;
    }

    .appcore-modal,
    .appcore-modal--confirmation,
    .appcore-modal--wide {
        width: 100%;
        max-height: 94dvh;
        border-width: 1px 0 0;
        border-radius: 1rem 1rem 0 0;
    }

    .appcore-modal__header,
    .appcore-modal__form {
        padding-inline: 1rem;
    }

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

    .appcore-modal__actions button {
        width: 100%;
    }

    .appcore-grid__viewport {
        border-radius: 0.75rem;
    }

    .appcore-grid__pager {
        align-items: stretch;
        flex-direction: column;
    }

    .appcore-grid__pager-actions {
        justify-content: space-between;
    }
}

.appcore-permission-grant__warning {
    color: var(--appcore-muted);
    font-size: 0.85rem;
}

/* Gates -------------------------------------------------------------- */

/* A disabled gate keeps the affordance visible but inert, so the caller can see
   that the action exists and infer that they lack permission for it. */
.appcore-gate--disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.appcore-gate--disabled > * {
    pointer-events: none;
}

button {
    font: inherit;
    padding: 0.35rem 0.75rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.5rem;
    background: var(--appcore-surface);
    cursor: pointer;
    transition: border-color 150ms ease, color 150ms ease, box-shadow 150ms ease, transform 150ms ease;
}

button:hover {
    border-color: var(--appcore-accent);
    color: var(--appcore-accent);
}

button:active:not(:disabled) {
    transform: translateY(1px);
}

button:focus-visible,
a:focus-visible {
    outline: 0.18rem solid color-mix(in srgb, var(--appcore-teal) 45%, transparent);
    outline-offset: 0.12rem;
}

.appcore-type-definitions__action,
.appcore-editor__actions button[type="submit"] {
    border-color: transparent;
    background: var(--appcore-gradient);
    color: #fff;
    box-shadow: 0 0.4rem 1rem rgb(7 124 240 / 18%);
}

.appcore-type-definitions__action:hover,
.appcore-editor__actions button[type="submit"]:hover {
    border-color: transparent;
    color: #fff;
    box-shadow: 0 0.55rem 1.25rem rgb(7 124 240 / 28%);
}

/* Reusable form fields ---------------------------------------------- */

.appcore-field {
    display: grid;
    gap: 0.35rem;
    min-width: 0;
}

.appcore-form-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.9rem;
}

.appcore-form-grid--checks {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
}

@media (max-width: 42rem) {
    .appcore-form-grid,
    .appcore-form-grid--checks {
        grid-template-columns: 1fr;
    }
}

.appcore-field__label,
.appcore-multirow__label {
    color: var(--appcore-ink);
    font-size: 0.875rem;
    font-weight: 600;
}

.appcore-field__required {
    color: #a3242c;
    margin-inline-start: 0.15rem;
}

.appcore-field__control input:not([type="checkbox"]):not([type="radio"]),
.appcore-field__control select,
.appcore-field__control textarea {
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    max-width: 100%;
    min-height: 2.5rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.55rem;
    background: var(--appcore-surface);
    color: var(--appcore-ink);
    font: inherit;
    padding: 0.5rem 0.65rem;
}

.appcore-field__control {
    min-width: 0;
    max-width: 100%;
}

.appcore-field__control input[type="datetime-local"] {
    inline-size: 100%;
    min-inline-size: 0;
    max-inline-size: 100%;
}

.appcore-field__control textarea {
    min-height: 6rem;
    resize: vertical;
}

.appcore-field__control input:focus-visible,
.appcore-field__control select:focus-visible,
.appcore-field__control textarea:focus-visible {
    border-color: var(--appcore-accent);
    box-shadow: 0 0 0 0.18rem color-mix(in srgb, var(--appcore-accent) 18%, transparent);
    outline: none;
}

.appcore-field__control .modified.invalid {
    border-color: #a3242c;
}

.appcore-field__control :disabled,
.appcore-field__control [readonly] {
    background: #f3f4f6;
    color: var(--appcore-muted);
    cursor: not-allowed;
}

.appcore-field__help,
.appcore-field__state {
    color: var(--appcore-muted);
    font-size: 0.8rem;
}

.appcore-field__validation {
    color: #a3242c;
    font-size: 0.8rem;
}

.appcore-field__validation:empty {
    display: none;
}

.appcore-field__input-group {
    display: flex;
    align-items: stretch;
}

.appcore-field__input-group > input {
    flex: 1 1 auto;
    min-width: 0;
}

.appcore-field__input-group > :first-child:not(:last-child) {
    border-start-end-radius: 0;
    border-end-end-radius: 0;
}

.appcore-field__input-group > :last-child:not(:first-child) {
    border-start-start-radius: 0;
    border-end-start-radius: 0;
}

.appcore-field__affix {
    display: grid;
    place-items: center;
    border: 1px solid var(--appcore-line);
    background: #f7f8fa;
    color: var(--appcore-muted);
    padding-inline: 0.65rem;
    white-space: nowrap;
}

.appcore-choice-list {
    display: grid;
    gap: 0.5rem;
}

.appcore-choice-list--radio {
    /* Same floor problem as .appcore-page__grid, one screen further in. */
    grid-template-columns: repeat(auto-fit, minmax(min(10rem, 100%), 1fr));
}

.appcore-choice {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    color: var(--appcore-ink);
    cursor: pointer;
}

.appcore-choice input {
    accent-color: var(--appcore-accent);
}

.appcore-choice--single {
    font-weight: 600;
}

.appcore-json-editor {
    display: grid;
    gap: 0.5rem;
}

.appcore-json-editor textarea {
    font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", monospace;
    tab-size: 2;
}

.appcore-json-editor__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.appcore-multirow {
    display: grid;
    gap: 0.65rem;
    min-width: 0;
}

.appcore-multirow__header,
.appcore-multirow__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.75rem;
    align-items: start;
}

.appcore-multirow__header {
    color: var(--appcore-muted);
    font-size: 0.8rem;
    font-weight: 600;
}

.appcore-multirow__rows {
    display: grid;
    gap: 0.6rem;
}

.appcore-multirow__row {
    border: 1px solid var(--appcore-line);
    border-radius: 0.5rem;
    background: var(--appcore-surface);
    padding: 0.75rem;
}

.appcore-multirow__content {
    min-width: 0;
}

.appcore-multirow__row-actions,
.appcore-multirow__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.appcore-multirow__remove {
    color: #a3242c;
}

.appcore-multirow__add {
    justify-self: start;
}

.appcore-multirow__empty {
    border: 1px dashed var(--appcore-line);
    border-radius: 0.5rem;
    color: var(--appcore-muted);
    padding: 1rem;
    text-align: center;
}

@media (max-width: 40rem) {
    .appcore-multirow__row {
        grid-template-columns: 1fr;
    }
}

/* Inline editor ------------------------------------------------------ */

.appcore-editor {
    background: var(--appcore-surface);
    border: 1px solid var(--appcore-line);
    border-radius: 0.6rem;
    padding: 1rem 1.25rem;
    margin-block: 1rem;
    display: grid;
    gap: 0.75rem;
    max-width: 26rem;
}

.appcore-editor h3 {
    margin: 0;
    font-size: 1rem;
}

.appcore-editor label {
    display: grid;
    gap: 0.25rem;
    font-size: 0.85rem;
    color: var(--appcore-muted);
}

.appcore-editor input[type="text"],
.appcore-editor input[type="password"],
.appcore-editor input:not([type]) {
    font: inherit;
    padding: 0.4rem 0.5rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.35rem;
    color: var(--appcore-ink);
}

.appcore-editor__check {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--appcore-ink);
}

.appcore-editor__actions {
    display: flex;
    gap: 0.5rem;
}

.appcore-collection__row-actions {
    display: flex;
    gap: 0.4rem;
}

/* ---------------------------------------------------------------------------
   Sign-in
   --------------------------------------------------------------------------- */

.appcore-login {
    display: grid;
    place-items: center;
    min-height: 100vh;
    box-sizing: border-box;
    padding: 1rem;
    /* The product's own palette, not the platform's default one.

       These three colours were literals, so every product's sign-in page - the
       first screen anybody sees, and for most users the only one they see before
       deciding which application they are looking at - carried the same teal and
       blue whatever the theme said. Same defect as a theme overriding three of
       sixteen tokens, one screen earlier. */
    background:
        radial-gradient(circle at 10% 15%, color-mix(in srgb, var(--appcore-teal) 22%, transparent), transparent 26%),
        radial-gradient(circle at 90% 90%, color-mix(in srgb, var(--appcore-accent) 26%, transparent), transparent 34%),
        linear-gradient(135deg, var(--appcore-navy), var(--appcore-navy-soft));
}

.appcore-login__card {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    width: min(24rem, 100%);
    padding: 2rem;
    border: 1px solid var(--appcore-line);
    border-radius: 1rem;
    background: #fff;
    box-shadow: 0 1.5rem 4rem rgb(0 10 30 / 35%);
}

.appcore-login__brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    margin-bottom: 0.4rem;
    color: var(--appcore-navy);
}

.appcore-login__card h1 {
    margin: 0;
    font-size: 1.4rem;
}

.appcore-login__hint {
    margin: 0;
    color: var(--appcore-muted);
    font-size: 0.9rem;
}

.appcore-login__error {
    margin: 0;
    padding: 0.55rem 0.7rem;
    border-radius: 0.35rem;
    background: #fdecea;
    color: #8a1c12;
    font-size: 0.9rem;
}

.appcore-login__card label {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.85rem;
    color: var(--appcore-muted);
}

.appcore-login__card input {
    font: inherit;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.35rem;
    color: var(--appcore-ink);
}

.appcore-login__card button {
    font: inherit;
    margin-top: 0.4rem;
    padding: 0.55rem 0.8rem;
    border: 0;
    border-radius: 0.35rem;
    background: var(--appcore-gradient);
    color: #fff;
    cursor: pointer;
}

/* The permissions half of the role dialog: separated from the fields above so
   the dialog reads as two decisions rather than one long form. */
.appcore-role-permissions {
    display: grid;
    gap: 0.7rem;
    margin-top: 1.1rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--appcore-line);
}

.appcore-role-permissions h3 {
    margin: 0;
    font-size: 0.95rem;
    color: var(--appcore-ink);
}

.appcore-shell__version {
    margin: auto 0 0;
    padding-top: 0.75rem;
    color: rgb(255 255 255 / 38%);
    font-size: 0.68rem;
    letter-spacing: 0.04em;
}

/* Tree ------------------------------------------------------------------
   Uses the same tokens as the rest of the shell, so it inherits the theme and
   both text directions without a second definition. Indentation is inline-start
   padding rather than a left margin, which is what makes it mirror in Arabic. */

.appcore-tree {
    max-height: min(26rem, 60vh);
    overflow-y: auto;
    padding: 0.35rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.6rem;
    background: var(--appcore-canvas);
}

.appcore-tree__list {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Only nested lists indent; the root sits flush. */
.appcore-tree__list .appcore-tree__list {
    padding-inline-start: 1.15rem;
    border-inline-start: 1px solid var(--appcore-line);
    margin-inline-start: 0.55rem;
}

.appcore-tree__row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.22rem 0.3rem;
    border-radius: 0.4rem;
}

.appcore-tree__row:hover {
    background: var(--appcore-surface);
}

.appcore-tree__twist {
    font: inherit;
    flex: 0 0 auto;
    width: 1.1rem;
    height: 1.1rem;
    padding: 0;
    border: 0;
    border-radius: 0.25rem;
    background: transparent;
    color: var(--appcore-muted);
    line-height: 1;
    cursor: pointer;
}

/* Kept in the layout so labels stay aligned down a level instead of stepping
   in and out depending on whether a row happens to have children. */
.appcore-tree__twist--leaf {
    visibility: hidden;
    cursor: default;
}

.appcore-tree__label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    min-width: 0;
}

.appcore-tree__label input {
    width: auto;
    margin: 0;
    flex: 0 0 auto;
}

.appcore-tree__text {
    font-size: 0.85rem;
    color: var(--appcore-ink);
}

/* A row that exists to hold others rather than to be chosen. */
.appcore-tree__text--group {
    color: var(--appcore-muted);
    font-weight: 650;
}

.appcore-tree__detail {
    font-size: 0.72rem;
    color: var(--appcore-muted);
    white-space: nowrap;
}

@media (max-width: 34rem) {
    /* The code is the first thing to go: it is the least useful half on a phone
       and the part that forces the row to scroll sideways. */
    .appcore-tree__detail {
        display: none;
    }
}

/* Profile menu ---------------------------------------------------------
   The signed-in person in the header of both frontends. Collapsed to a name
   and an avatar; everything else is inside the panel, because the header had
   been accumulating one control per feature until it ran out of room on a
   laptop. */

.appcore-profile {
    position: relative;
}

.appcore-profile__trigger {
    font: inherit;
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.3rem 0.5rem;
    border: 1px solid transparent;
    border-radius: 999px;
    background: transparent;
    color: var(--appcore-ink);
    cursor: pointer;
}

.appcore-profile__trigger:hover,
.appcore-profile__trigger:focus-visible,
.appcore-profile--open .appcore-profile__trigger {
    border-color: var(--appcore-line);
    background: var(--appcore-canvas);
}

.appcore-profile__identity {
    display: grid;
    /* Start, not left: the name sits against the reading edge in both directions. */
    text-align: start;
    line-height: 1.2;
}

.appcore-profile__name {
    font-size: 0.85rem;
    font-weight: 650;
    color: var(--appcore-ink);
}

.appcore-profile__tenant,
.appcore-profile__login {
    font-size: 0.72rem;
    color: var(--appcore-muted);
}

.appcore-profile__chevron {
    font-size: 0.7rem;
    color: var(--appcore-muted);
}

.appcore-profile__avatar,
.appcore-account__avatar {
    display: grid;
    place-items: center;
    flex: none;
    width: 2.15rem;
    height: 2.15rem;
    border-radius: 50%;
    background: var(--appcore-gradient);
    color: #fff;
    font-size: 0.8rem;
    font-weight: 800;
}

.appcore-profile__avatar--large,
.appcore-account__avatar {
    width: 2.75rem;
    height: 2.75rem;
    font-size: 1rem;
}

/* Covers the page so a click anywhere dismisses the panel, with no script and
   no document-level listener to leave behind. */
.appcore-profile__dismiss {
    position: fixed;
    inset: 0;
    z-index: 30;
    border: 0;
    padding: 0;
    background: transparent;
    cursor: default;
}

.appcore-profile__panel {
    position: absolute;
    top: calc(100% + 0.5rem);
    /* Anchored to the inline end, so it opens inwards from the header's edge in
       both directions rather than off the side of the page in Arabic. */
    inset-inline-end: 0;
    z-index: 31;
    display: grid;
    gap: 0.85rem;
    min-width: 17rem;
    max-width: min(22rem, calc(100vw - 2rem));
    padding: 1rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.85rem;
    background: var(--appcore-surface);
    box-shadow: 0 1.4rem 2.6rem rgb(2 26 62 / 16%);
}

.appcore-profile__header {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding-bottom: 0.85rem;
    border-bottom: 1px solid var(--appcore-line);
}

.appcore-profile__label {
    display: block;
    margin-bottom: 0.35rem;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--appcore-muted);
}

.appcore-profile__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.appcore-profile__chip {
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: var(--appcore-canvas);
    border: 1px solid var(--appcore-line);
    font-size: 0.72rem;
    color: var(--appcore-ink);
}

.appcore-profile__actions {
    display: grid;
    gap: 0.25rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--appcore-line);
}

.appcore-profile__action {
    font: inherit;
    display: block;
    width: 100%;
    padding: 0.5rem 0.6rem;
    border: 0;
    border-radius: 0.45rem;
    background: transparent;
    color: var(--appcore-ink);
    text-align: start;
    text-decoration: none;
    cursor: pointer;
}

.appcore-profile__action:hover,
.appcore-profile__action:focus-visible {
    background: var(--appcore-canvas);
}

.appcore-profile__action--signout {
    color: var(--appcore-muted);
}

@media (max-width: 30rem) {
    /* The avatar alone below this width. The name is in the panel, one tap away,
       and keeping it here pushed the chevron off the screen. */
    .appcore-profile__identity,
    .appcore-profile__chevron {
        display: none;
    }
}

/* The account page ------------------------------------------------------ */

.appcore-account {
    max-width: 42rem;
    margin-bottom: 1.75rem;
    padding: 1.35rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.85rem;
    background: var(--appcore-surface);
}

.appcore-account__identity {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    margin-bottom: 1.1rem;
}

.appcore-account__name,
.appcore-account h2 {
    margin: 0;
    font-size: 1.2rem;
}

.appcore-account h2 {
    margin-bottom: 1rem;
}

.appcore-account__login,
.appcore-account__empty {
    margin: 0;
    color: var(--appcore-muted);
    font-size: 0.85rem;
}

.appcore-account__facts {
    display: grid;
    gap: 0.75rem;
    margin: 0;
}

.appcore-account__facts > div {
    display: grid;
    /* The label column may shrink; the value column may not be pushed out of the
       card by a long login name or a role chip that will not wrap. */
    grid-template-columns: minmax(min(7rem, 35%), 12rem) minmax(0, 1fr);
    gap: 0.5rem 1rem;
    align-items: baseline;
}

.appcore-account__facts dt {
    color: var(--appcore-muted);
    font-size: 0.8rem;
}

.appcore-account__facts dd {
    margin: 0;
    color: var(--appcore-ink);
}

.appcore-account__form {
    display: grid;
    gap: 0.85rem;
    max-width: 24rem;
}

.appcore-account__form label {
    display: grid;
    gap: 0.3rem;
    font-size: 0.85rem;
    color: var(--appcore-muted);
}

@media (max-width: 34rem) {
    .appcore-account__facts > div {
        grid-template-columns: 1fr;
        gap: 0.15rem;
    }
}

.appcore-culture-switcher {
    display: inline-flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.18rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.55rem;
    background: var(--appcore-canvas);
}

.appcore-culture-switcher a {
    padding: 0.3rem 0.5rem;
    border-radius: 0.38rem;
    color: var(--appcore-muted);
    font-size: 0.73rem;
    font-weight: 650;
    text-decoration: none;
}

.appcore-culture-switcher a.active {
    background: var(--appcore-surface);
    color: var(--appcore-accent-strong);
    box-shadow: 0 0.15rem 0.45rem rgb(2 26 62 / 10%);
}

.appcore-login__remember {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.85rem;
    color: var(--appcore-muted);
    cursor: pointer;
}

.appcore-login__remember input {
    width: auto;
    margin: 0;
}

.appcore-login__toolbar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: -0.25rem;
}

html[dir="rtl"] .appcore-menu__link:hover,
html[dir="rtl"] .appcore-menu__link:focus-visible {
    transform: translateX(-0.12rem);
}

html[dir="rtl"] .appcore-grid__row--selected {
    box-shadow: inset -0.2rem 0 var(--appcore-accent);
}

/* ---------------------------------------------------------------------------
   Branding hooks.

   A product supplies a logo and a palette; it must not have to restyle the
   shell. Everything below sizes and positions those two things, so a profile
   stylesheet only ever redefines the custom properties at the top of this file.
   --------------------------------------------------------------------------- */

.appcore-shell__brand {
    display: flex;
    align-items: center;
    gap: 0.65rem;
}

.appcore-shell__logo {
    /* Fixed box so a tall or wide logo cannot resize the navigation column. */
    width: 1.75rem;
    height: 1.75rem;
    object-fit: contain;
    flex: none;
}

.appcore-shell__tenant {
    margin: 0.125rem 0 0.5rem;
    font-size: 0.8125rem;
    color: var(--appcore-muted);
}

.appcore-login__logo {
    display: block;
    width: 3rem;
    height: 3rem;
    object-fit: contain;
    margin: 0 auto 0.75rem;
}

/* Routed catalog workspaces ------------------------------------------ */

.appcore-workspace {
    display: grid;
    min-width: 0;
    gap: 1.25rem;
}

.appcore-workspace__breadcrumbs {
    display: flex;
    align-items: center;
    min-width: 0;
    gap: 0.5rem;
    color: var(--appcore-muted);
    font-size: 0.82rem;
    overflow-x: auto;
    white-space: nowrap;
    scrollbar-width: thin;
}

.appcore-workspace__breadcrumbs a {
    color: var(--appcore-accent-strong);
    text-decoration: none;
}

.appcore-workspace__breadcrumbs a:hover,
.appcore-workspace__breadcrumbs a:focus-visible {
    text-decoration: underline;
}

.appcore-workspace__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    min-width: 0;
    gap: 1rem;
}

.appcore-workspace__header h1 {
    margin: 0.1rem 0 0.55rem;
}

.appcore-workspace__eyebrow {
    margin: 0;
    color: var(--appcore-teal);
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.appcore-workspace__meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.55rem;
}

.appcore-workspace__meta code {
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.4rem;
    background: var(--appcore-surface);
}

.appcore-workspace__back {
    flex: 0 0 auto;
    padding: 0.55rem 0.8rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.5rem;
    background: var(--appcore-surface);
    color: var(--appcore-ink);
    font-size: 0.85rem;
    text-decoration: none;
    box-shadow: 0 0.2rem 0.6rem rgb(2 26 62 / 4%);
}

.appcore-workspace__back:hover,
.appcore-workspace__back:focus-visible {
    border-color: var(--appcore-accent);
    color: var(--appcore-accent-strong);
}

.appcore-workspace__tabs {
    display: flex;
    min-width: 0;
    gap: 0.25rem;
    padding: 0.3rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.75rem;
    background: var(--appcore-surface);
    overflow-x: auto;
    box-shadow: var(--appcore-shadow);
    scrollbar-width: thin;
}

.appcore-workspace__tabs a {
    flex: 0 0 auto;
    padding: 0.65rem 0.9rem;
    border-radius: 0.55rem;
    color: var(--appcore-muted);
    font-size: 0.88rem;
    font-weight: 650;
    text-decoration: none;
    white-space: nowrap;
}

.appcore-workspace__tabs a:hover,
.appcore-workspace__tabs a:focus-visible {
    color: var(--appcore-accent-strong);
    background: rgb(8 124 240 / 6%);
}

.appcore-workspace__tabs a.active {
    color: #fff;
    background: var(--appcore-gradient);
    box-shadow: 0 0.25rem 0.65rem rgb(8 124 240 / 20%);
}

/* Buttons in a tab strip. The anchors above already carry the look; these only
   need the resets a <button> comes with and the anchors do not. */
.appcore-tabs button {
    font: inherit;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.65rem 0.9rem;
    border: 0;
    border-radius: 0.55rem;
    background: transparent;
    color: var(--appcore-muted);
    font-size: 0.88rem;
    font-weight: 650;
    white-space: nowrap;
    cursor: pointer;
}

.appcore-tabs button:hover:not(:disabled),
.appcore-tabs button:focus-visible {
    color: var(--appcore-accent-strong);
    background: rgb(8 124 240 / 6%);
}

.appcore-tabs button.active {
    color: #fff;
    background: var(--appcore-gradient);
    box-shadow: 0 0.25rem 0.65rem rgb(8 124 240 / 20%);
}

.appcore-tabs button:disabled {
    cursor: default;
    opacity: 0.6;
}

/* How many of this section's permissions are granted. Inherits the tab's colour
   so it stays legible on the active tab's gradient as well as off it. */
.appcore-tabs__badge {
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    background: rgb(127 127 127 / 22%);
    font-size: 0.72rem;
    font-weight: 700;
}

.appcore-workspace__content,
.appcore-workspace-section {
    min-width: 0;
}

.appcore-workspace-section__surface {
    min-width: 0;
    border: 1px solid var(--appcore-line);
    border-radius: 0.85rem;
    background: var(--appcore-surface);
    box-shadow: var(--appcore-shadow);
}

.appcore-workspace-section__surface > h2 {
    margin: 0;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--appcore-line);
    font-size: 1.05rem;
}

.appcore-workspace-section__surface > .appcore-type-details {
    padding: 1.25rem;
}

.appcore-workspace__state {
    display: grid;
    justify-items: start;
    gap: 0.75rem;
    padding: 1.25rem;
    border: 1px solid var(--appcore-line);
    border-radius: 0.85rem;
    background: var(--appcore-surface);
    box-shadow: var(--appcore-shadow);
}

.appcore-workspace__state p {
    margin: 0;
}

.appcore-workspace__state--error {
    color: #9b1c1c;
}

@media (max-width: 40rem) {
    .appcore-workspace {
        gap: 1rem;
    }

    .appcore-workspace__header {
        flex-direction: column;
    }

    .appcore-workspace__back {
        width: 100%;
        text-align: center;
    }

    .appcore-workspace__tabs a {
        flex: 1 0 auto;
        text-align: center;
    }

    .appcore-workspace-section__surface > .appcore-type-details,
    .appcore-workspace-section__surface > .appcore-modal__form {
        padding: 1rem;
    }
}
