/* ---------------------------------------------------------------------------
   ITaid Ticketsystem - design system
   Calm, Apple-inspired look: generous whitespace, clear typography, subtle
   depth, ~8px radii, frosted glass panels. Bootstrap is only the technical
   foundation underneath.
--------------------------------------------------------------------------- */

:root {
    --ia-bg: #f5f5f7;
    --ia-surface: rgba(255, 255, 255, 0.72);
    --ia-surface-strong: rgba(255, 255, 255, 0.86);
    --ia-text: #1d1d1f;
    --ia-text-secondary: #6e6e73;
    --ia-border: #d2d2d7;
    --ia-border-soft: rgba(60, 60, 67, 0.12);
    --ia-accent: #0071e3;
    --ia-accent-hover: #0077ed;
    --ia-accent-active: #006edb;
    /* Buttons are decoupled from the accent (icon) colour so both can be
       branded independently. Literal defaults, overridable via /branding.css. */
    --ia-button: #0071e3;
    --ia-button-hover: #0077ed;
    --ia-button-active: #006edb;
    /* Optional button gradient overlay (none = solid --ia-button). */
    --ia-button-image: none;
    /* Configurable logo widths (menu + login), default 15rem. */
    --brand-logo-width-menu: 15rem;
    --brand-logo-width-login: 15rem;
    --ia-danger: #d70015;
    --ia-success: #1d7a3a;
    --ia-radius: 8px;
    --ia-radius-large: 12px;
    /* Gradient top-border bar shown on every card (.glass_panel). Height 0
       removes it; both are overridable via /branding.css (Design settings). */
    --card-top-gradient: linear-gradient(90deg, #7A509E 0%, #68B9B9 100%);
    --card-top-height: 20px;
    --ia-shadow-soft: 0 1px 2px rgba(0, 0, 0, 0.04), 0 8px 24px rgba(0, 0, 0, 0.06);
    --ia-shadow-panel: 0 1px 1px rgba(0, 0, 0, 0.03), 0 12px 40px rgba(0, 0, 0, 0.08);
    --ia-font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
        Roboto, "Helvetica Neue", Arial, sans-serif;
}

html {
    height: 100%;
}

body {
    font-family: var(--ia-font);
    color: var(--ia-text);
    background-color: var(--ia-bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    min-height: 100%;
}

/* Frosted glass panel ---------------------------------------------------- */

.glass_panel {
    position: relative;
    /* The gradient bar is painted into the (transparent) top border, which
       also reserves the layout space so content is pushed below it and the
       rounded corners are preserved. */
    background-color: var(--ia-surface);
    background-image: var(--card-top-gradient, none);
    background-repeat: no-repeat;
    background-position: top center;
    background-size: 100% var(--card-top-height, 0px);
    background-origin: border-box;
    background-clip: border-box;
    -webkit-backdrop-filter: blur(5px) saturate(180%);
    backdrop-filter: blur(5px) saturate(180%);
    border: 1px solid var(--ia-border-soft);
    border-top: var(--card-top-height, 1px) solid transparent;
    border-radius: var(--ia-radius-large);
    box-shadow: var(--ia-shadow-panel);
}

/* Focus visibility (keyboard operation) ---------------------------------- */

:focus-visible {
    outline: 2px solid var(--ia-accent);
    outline-offset: 2px;
    border-radius: var(--ia-radius);
}

/* Auth pages -------------------------------------------------------------- */

.auth_body {
    background:
        radial-gradient(48rem 32rem at 12% -8%, rgba(0, 113, 227, 0.10), transparent 60%),
        radial-gradient(40rem 30rem at 105% 108%, rgba(88, 86, 214, 0.10), transparent 60%),
        var(--ia-bg);
}

.auth_wrap {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
}

.auth_card {
    width: 100%;
    max-width: 24.5rem;
    padding: 2.5rem 2.25rem 2rem;
}

.auth_card_header {
    text-align: center;
    margin-bottom: 1.75rem;
}

.auth_title {
    font-size: 1.45rem;
    font-weight: 600;
    letter-spacing: -0.015em;
    margin: 1rem 0 0.35rem;
}

.auth_subtitle {
    color: var(--ia-text-secondary);
    font-size: 0.95rem;
    margin: 0;
}

.auth_language_switch {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 1.75rem;
}

.auth_language_button {
    background: none;
    border: 0;
    padding: 0.25rem 0.4rem;
    color: var(--ia-text-secondary);
    font-size: 0.85rem;
    border-radius: var(--ia-radius);
    cursor: pointer;
}

.auth_language_button:hover {
    color: var(--ia-text);
}

.auth_language_button.is_active {
    color: var(--ia-accent);
    font-weight: 600;
}

.auth_language_divider {
    color: var(--ia-border);
}

/* Brand ------------------------------------------------------------------- */

.app_brand_mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--ia-radius);
    background: linear-gradient(135deg, #0a84ff, #0055b8);
    color: #ffffff;
    font-weight: 700;
    font-size: 0.85rem;
    letter-spacing: 0.02em;
}

.app_brand_mark_large {
    width: 3rem;
    height: 3rem;
    font-size: 1.2rem;
    border-radius: var(--ia-radius-large);
    box-shadow: var(--ia-shadow-soft);
}

/* Configurable branding assets (logo + background video) ------------------ */

.app_brand_logo {
    width: auto;
    height: auto;
    max-width: var(--brand-logo-width-menu, 15rem);
    max-height: 2.5rem;
    object-fit: contain;
    display: block;
}

.auth_brand_logo {
    width: auto;
    height: auto;
    max-width: var(--brand-logo-width-login, 15rem);
    max-height: 6rem;
    object-fit: contain;
    margin: 0 auto;
    display: block;
}

/* Full-screen background video, painted behind all page content. Same-origin
   only (enforced by the Content-Security-Policy). */
.app_bg_video {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: -1;
    pointer-events: none;
}

/* App shell --------------------------------------------------------------- */

.app_body {
    background:
        radial-gradient(60rem 24rem at 85% -12%, rgba(0, 113, 227, 0.07), transparent 60%),
        var(--ia-bg);
}

.app_header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: var(--ia-surface-strong);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    backdrop-filter: blur(20px) saturate(180%);
    border-bottom: 1px solid var(--ia-border-soft);
}

.app_nav {
    max-width: 95%;
    margin: 0 auto;
    padding: 0.55rem 1.25rem;
    display: flex;
    align-items: center;
    gap: 0.5rem 1.1rem;
    position: relative;
}

.app_brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    text-decoration: none;
    color: var(--ia-text);
    font-weight: 600;
    font-size: 0.98rem;
    letter-spacing: -0.01em;
    flex: 0 0 auto;
}

/* Header navigation ------------------------------------------------------- */

.app_nav_links {
    list-style: none;
    display: flex;
    align-items: center;
    gap: 0.2rem;
    margin: 0;
    padding: 0;
}

.app_nav_link {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.45rem 0.75rem;
    border-radius: var(--ia-radius);
    text-decoration: none;
    color: var(--ia-text-secondary);
    font-size: 0.92rem;
    font-weight: 500;
    white-space: nowrap;
}

.app_nav_link:hover {
    background: rgba(0, 0, 0, 0.045);
    color: var(--ia-text);
}

.app_nav_link .bi {
    font-size: 1.05rem;
    color: var(--ia-accent);
}

.app_nav_link.is_active {
    background: rgba(0, 0, 0, 0.05);
    color: var(--ia-text);
}

/* Search / profile / logout inside the menu overlay: mobile only — on desktop
   these live in the header bar. */
.app_nav_links_mobile {
    display: none;
}

.app_nav_logout_form {
    margin: 0;
    display: block;
}

/* The logout entry is a submit button styled exactly like the links. */
.app_nav_link_button {
    width: 100%;
    background: none;
    border: 0;
    text-align: left;
    font-family: inherit;
    cursor: pointer;
}

.app_nav_actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex: 0 0 auto;
}

.app_nav_new {
    white-space: nowrap;
    padding-top: 0.45rem;
    padding-bottom: 0.45rem;
}

.app_nav_toggle {
    display: none;
    background: none;
    border: 0;
    /* ~30% larger than the original 1.35rem/0.3rem-0.5rem so the burger is
       easier to hit on phones. */
    padding: 0.4rem 0.65rem;
    border-radius: var(--ia-radius);
    color: var(--ia-text);
    font-size: 1.75rem;
    line-height: 1;
    cursor: pointer;
}

.app_nav_toggle:hover {
    background: rgba(0, 0, 0, 0.045);
}

@media (max-width: 60rem) {
    .app_nav_toggle {
        display: inline-flex;
        order: 3;
        margin-left: 0.25rem;
        position: relative;
        z-index: 1060;
    }

    .app_nav_actions {
        order: 2;
    }

    /* Save space on mobile: the full search field becomes a magnifier icon
       (linking to /search) and "+ Ticket" collapses to just the plus icon.
       Scoped under .app_nav so these beat the base search rules declared later
       in this stylesheet (equal specificity would otherwise let source order win). */
    .app_nav .app_nav_search {
        display: none;
    }

    /* Header keeps only "+" and the hamburger on mobile: search, own profile
       and logout live inside the menu overlay instead (see
       .app_nav_links_mobile). */
    .app_nav .app_nav_search_link,
    .app_nav .app_user_box {
        display: none;
    }

    .app_nav .app_nav_links_mobile {
        display: flex;
    }

    /* Configurable mobile header-logo width (Design setting); falls back to the
       desktop menu width, so leaving it empty keeps the current size. */
    .app_brand_logo {
        max-width: var(--brand-logo-width-menu-mobile, var(--brand-logo-width-menu, 15rem));
    }

    .app_nav_new span {
        display: none;
    }

    /* Scoped under .app_nav: .app_button_primary sets the padding later in
       this stylesheet, so an unscoped .app_nav_new would lose on source order
       despite the media query. */
    .app_nav .app_nav_new {
        padding: 0.45rem 0.6rem;
    }

    /* Only the user icon is shown on mobile; the name is hidden. */
    .app_user_name {
        display: none;
    }

    /* Mobile navigation opens as a full-screen overlay with the items stacked
       vertically in an OPAQUE card, instead of expanding the header. */
    .app_nav_menu {
        display: none;
    }

    /* While the overlay is open the header must NOT have a backdrop-filter:
       a filtered ancestor becomes the containing block for position:fixed,
       which clamped the overlay to the header strip (tiny scrollable window)
       instead of the viewport. body.app_no_scroll is toggled together with
       is_open by the nav JS. */
    body.app_no_scroll .app_header {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }

    .app_nav_menu.is_open {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 1050;
        background: rgba(18, 18, 26, 0.5);
    }

    /* The opaque card holds both lists (main navigation + the mobile-only
       search/profile/logout entries), so the panel — not a single list — is
       the positioned element. */
    .app_nav_menu.is_open .app_nav_menu_panel {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        max-height: 100%;
        overflow-y: auto;
        padding: 4.5rem 1rem 1.25rem;
        background: var(--ia-bg);
        border-bottom: 1px solid var(--ia-border-soft);
        border-radius: 0 0 var(--ia-radius-large) var(--ia-radius-large);
        box-shadow: var(--ia-shadow-panel);
    }

    .app_nav_menu.is_open .app_nav_links {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 0.25rem;
        margin: 0;
        padding: 0;
    }

    /* Separated from the page navigation by a hairline. */
    .app_nav_menu.is_open .app_nav_links_mobile {
        margin-top: 0.5rem;
        padding-top: 0.5rem;
        border-top: 1px solid var(--ia-border-soft);
    }

    .app_nav_link {
        padding: 0.85rem 0.9rem;
        font-size: 1.05rem;
        border-radius: var(--ia-radius);
    }
}

body.app_no_scroll {
    overflow: hidden;
}

.app_user_button {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    background: none;
    border: 0;
    padding: 0.35rem 0.6rem;
    border-radius: var(--ia-radius);
    color: var(--ia-text);
    font-size: 0.92rem;
    cursor: pointer;
}

.app_user_button:hover {
    background: rgba(0, 0, 0, 0.045);
}

/* User area: name label plus a standalone logout icon button (no dropdown). */
.app_user_box {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    flex: 0 0 auto;
}

.app_user_label {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--ia-text);
    font-size: 0.92rem;
    padding: 0.35rem 0.5rem;
    border-radius: var(--ia-radius);
    white-space: nowrap;
    text-decoration: none;
}

/* Anchor variant (links to own profile): subtle hover feedback. */
a.app_user_label:hover {
    background: rgba(0, 0, 0, 0.045);
    color: var(--ia-text);
}

.app_user_label .bi {
    font-size: 1.15rem;
    color: var(--ia-accent);
}

.app_logout_form {
    margin: 0;
    display: inline-flex;
    align-items: center;
}

/* Remaining minutes until the idle logout, right of the logout icon. */
.app_idle_countdown {
    font-size: 0.78rem;
    color: var(--ia-text-secondary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    padding-right: 0.15rem;
}

.app_idle_countdown.is_soon {
    color: var(--ia-danger);
    font-weight: 600;
}

.app_logout_button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: 0;
    padding: 0.4rem 0.5rem;
    border-radius: var(--ia-radius);
    color: var(--ia-text-secondary);
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
}

.app_logout_button:hover {
    background: rgba(0, 0, 0, 0.045);
    color: var(--ia-danger);
}

.app_dropdown {
    border: 1px solid var(--ia-border-soft);
    border-radius: var(--ia-radius);
    box-shadow: var(--ia-shadow-soft);
    background: var(--ia-surface-strong);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    backdrop-filter: blur(20px) saturate(180%);
    min-width: 12rem;
    padding: 0.3rem;
}

.app_dropdown .dropdown-item {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    border-radius: calc(var(--ia-radius) - 2px);
    font-size: 0.92rem;
    padding: 0.5rem 0.7rem;
    color: var(--ia-text);
}

.app_dropdown .dropdown-item:hover {
    background: rgba(0, 0, 0, 0.05);
}

.app_main {
    max-width: 95%;
    margin: 0 auto;
    padding: 2.25rem 1.25rem 4rem;
}

.app_page_title {
    font-size: 1.7rem;
    font-weight: 600;
    letter-spacing: -0.02em;
    margin-bottom: 0.3rem;
}

.app_page_subtitle {
    color: var(--ia-text-secondary);
    font-size: 0.98rem;
    margin-bottom: 2rem;
}

/* Clickable entries inside a page subtitle (client, contact). */
.app_subtitle_link {
    color: inherit;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
    text-decoration-color: var(--ia-border);
}

.app_subtitle_link:hover,
.app_subtitle_link:focus-visible {
    color: var(--ia-accent);
    text-decoration-color: var(--ia-accent);
}

.app_page_header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.app_back_link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--ia-accent);
    text-decoration: none;
    font-size: 0.92rem;
    padding-top: 0.4rem;
    white-space: nowrap;
}

.app_back_link:hover {
    text-decoration: underline;
}

/* Tiles ------------------------------------------------------------------- */

.app_tile_grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
    gap: 1.1rem;
}

.app_tile {
    /* Icon and title share one row (description spans below) — saves height. */
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    column-gap: 0.6rem;
    row-gap: 0.35rem;
    padding: 1.1rem 1.4rem 1rem;
    text-decoration: none;
    color: var(--ia-text);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.app_tile_description {
    grid-column: 1 / -1;
}

.app_tile:hover {
    transform: translateY(-2px);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04), 0 16px 48px rgba(0, 0, 0, 0.10);
    color: var(--ia-text);
}

.app_tile_icon {
    font-size: 1.5rem;
    color: var(--ia-accent);
}

/* Alert state (e.g. backup overdue): red-tinted tile, red icon/title.
   Only the background is tinted so the gradient top bar stays intact. */
.app_tile_alert {
    background-color: rgba(215, 0, 21, 0.07);
}

.app_tile_alert .app_tile_icon,
.app_tile_alert .app_tile_title {
    color: var(--ia-danger);
}

.app_tile_title {
    font-weight: 600;
    font-size: 1.02rem;
    letter-spacing: -0.01em;
}

.app_tile_description {
    color: var(--ia-text-secondary);
    font-size: 0.88rem;
    line-height: 1.45;
}

/* Admin-added quick-access tile (Schnellzugriff-Kacheln): free HTML content
   rendered below the title. Spans the tile and keeps long words/images tame. */
.app_tile_custom_content {
    grid-column: 1 / -1;
    color: var(--ia-text-secondary);
    font-size: 0.88rem;
    line-height: 1.5;
    overflow-wrap: anywhere;
}

.app_tile_custom_content :where(p, ul, ol) {
    margin: 0 0 0.4rem;
}

.app_tile_custom_content :where(p, ul, ol):last-child {
    margin-bottom: 0;
}

.app_tile_custom_content img {
    max-width: 100%;
    height: auto;
}

/* Live figure on a tile (e.g. open tickets), between title and description. */
.app_tile_stat {
    grid-column: 1 / -1;
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--ia-accent);
}

/* Tile variant with direct module links (settings hub): the head stays a
   link, the module links render as a wrapping text-link row below. */
.app_tile_head_link {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    column-gap: 0.6rem;
    text-decoration: none;
    color: var(--ia-text);
}

.app_tile_head_link:hover .app_tile_title {
    color: var(--ia-accent);
}

.app_tile_links {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem 0.9rem;
    margin-top: 0.1rem;
}

.app_tile_links a {
    font-size: 0.85rem;
    color: var(--ia-accent);
    text-decoration: none;
}

.app_tile_links a:hover {
    text-decoration: underline;
}

/* Forms ------------------------------------------------------------------- */

.app_field {
    margin-bottom: 1.1rem;
}

.form-label {
    font-size: 0.88rem;
    font-weight: 500;
    color: var(--ia-text);
    margin-bottom: 0.35rem;
}

.form-control,
.form-select {
    border-radius: var(--ia-radius);
    border: 1px solid var(--ia-border);
    background-color: rgba(255, 255, 255, 0.85);
    padding: 0.55rem 0.8rem;
    font-size: 0.95rem;
    color: var(--ia-text);
    box-shadow: none;
}

.form-control:focus,
.form-select:focus {
    border-color: var(--ia-accent);
    box-shadow: 0 0 0 3px rgba(0, 113, 227, 0.18);
    background-color: #ffffff;
}

.app_password_wrap {
    position: relative;
}

.app_password_wrap .form-control {
    padding-right: 2.7rem;
}

.app_password_toggle {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 2.6rem;
    background: none;
    border: 0;
    color: var(--ia-text-secondary);
    cursor: pointer;
    border-radius: 0 var(--ia-radius) var(--ia-radius) 0;
}

.app_password_toggle:hover {
    color: var(--ia-text);
}

.app_button_primary {
    background-color: var(--ia-button);
    background-image: var(--ia-button-image, none);
    color: #ffffff;
    border: 0;
    border-radius: var(--ia-radius);
    padding: 0.6rem 1.3rem;
    font-size: 0.95rem;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
}

.app_button_primary:hover {
    background-color: var(--ia-button-hover);
    color: #ffffff;
}

.app_button_primary:active {
    background-color: var(--ia-button-active);
}

/* Submit buttons locked during submission (double-submit prevention). */
.is_submitting {
    opacity: 0.65;
    cursor: progress;
    pointer-events: none;
}

.app_button_secondary {
    border: 1px solid var(--ia-border);
    border-radius: var(--ia-radius);
    background: rgba(255, 255, 255, 0.8);
    color: var(--ia-text);
    padding: 0.6rem 1.3rem;
    font-size: 0.95rem;
}

.app_button_secondary:hover {
    background: #ffffff;
    color: var(--ia-text);
}

.app_form {
    padding: 1.75rem;
    max-width: 44rem;
}

/* A form standing on its own carries the padding above. Inside a card the card
   already provides it, and adding it twice indents the fields against
   everything else in the same card — visible wherever a tile holds more than
   just the form (the background tile shows its thumbnails right beside it). */
.app_detail_section > .app_form {
    padding: 0;
    max-width: none;
}

.app_form_actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.7rem;
    margin-top: 1.5rem;
}

/* Alerts ------------------------------------------------------------------ */

.app_alert {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    border-radius: var(--ia-radius);
    border: 1px solid transparent;
    font-size: 0.92rem;
    padding: 0.7rem 0.95rem;
    margin-bottom: 1.25rem;
}

.alert-danger.app_alert {
    background: rgba(215, 0, 21, 0.07);
    border-color: rgba(215, 0, 21, 0.22);
    color: var(--ia-danger);
}

.alert-success.app_alert {
    background: rgba(29, 122, 58, 0.08);
    border-color: rgba(29, 122, 58, 0.22);
    color: var(--ia-success);
}

/* Filter bar + tables ----------------------------------------------------- */

.app_filter_bar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.9rem;
    padding: 1.1rem 1.25rem;
    margin-bottom: 1rem;
    /* Sit above the following result card so the autocomplete dropdown (inside
       this bar) is not hidden behind it — each .glass_panel has backdrop-filter
       and thus its own stacking context. */
    position: relative;
    z-index: 20;
}

.app_filter_field {
    min-width: 8.5rem;
}

.app_filter_field_grow {
    flex: 1 1 14rem;
}

/* Date pickers stay narrow so they do not push the other filters around. */
.app_filter_field_date {
    min-width: 9.5rem;
    flex: 0 0 auto;
}

.app_filter_actions {
    display: flex;
    align-items: flex-end;
    gap: 0.6rem;
}

.app_result_count {
    color: var(--ia-text-secondary);
    font-size: 0.88rem;
    margin: 0.25rem 0 0.9rem;
}

.app_table_wrap {
    overflow-x: auto;
    padding: 0.4rem 0.4rem 0;
}

/* Client access column (user list): several client names must wrap instead
   of stretching the table. */
.app_users_clients_cell {
    max-width: 22rem;
    overflow-wrap: anywhere;
}

/* A panel directly after a table panel (e.g. file area: list + upload form)
   needs the same vertical gap that paginated lists get from the pager. */
.app_table_wrap + .app_detail_section {
    margin-top: 1.1rem;
}

.app_table {
    margin-bottom: 0.4rem;
    font-size: 0.92rem;
}

.app_table > :not(caption) > * > * {
    background: transparent;
    padding: 0.7rem 0.85rem;
    border-bottom-color: var(--ia-border-soft);
}

.app_table thead th {
    color: var(--ia-text-secondary);
    font-weight: 500;
    font-size: 0.82rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

/* Highlight the hovered body row so it stays easy to follow across wide
   tables (the cell backgrounds are otherwise transparent). */
.app_table tbody tr:hover > * {
    background: rgba(0, 0, 0, 0.04);
}

.app_table_key code {
    color: var(--ia-text);
    background: rgba(0, 0, 0, 0.045);
    border-radius: 5px;
    padding: 0.15rem 0.4rem;
    font-size: 0.82rem;
}

.app_table_text {
    max-width: 22rem;
}

.app_table_actions_col {
    text-align: right;
    white-space: nowrap;
}

.app_icon_link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--ia-radius);
    color: var(--ia-accent);
    text-decoration: none;
}

.app_icon_link:hover {
    background: rgba(0, 113, 227, 0.10);
}

/* Badges ------------------------------------------------------------------ */

.app_badge {
    display: inline-block;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.05);
    color: var(--ia-text-secondary);
    font-size: 0.75rem;
    font-weight: 600;
    padding: 0.2rem 0.6rem;
    letter-spacing: 0.02em;
}

/* Clickable badge (e.g. assignee bubble in the dashboard ticket feed). */
a.app_badge {
    text-decoration: none;
}

a.app_badge:hover {
    background: rgba(0, 0, 0, 0.09);
    color: var(--ia-text);
}

.app_assignee_badge {
    white-space: nowrap;
}

/* Person bubble behind a feed title: who raised the ticket or wrote last. */
.app_person_badge {
    white-space: nowrap;
    max-width: 12rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app_person_badge .bi,
.app_update_badge .bi,
.app_assignee_badge .bi {
    margin-right: 0.3rem;
}

/* How the ticket arrived — mail or system. Sits between the two bubbles. */
.app_source_icon {
    flex: 0 0 auto;
    color: var(--ia-text-secondary);
    font-size: 0.95rem;
}

/* Leading ticket icon in front of the number, and the client icon at the end. */
.app_feed_ticket_icon,
.app_client_icon {
    margin-right: 0.35rem;
}

/* ---------------------------------------------------------------------------
   Bottom of the dashboard: activity and the team links side by side, half the
   width each. One column stacks them on a narrow screen.
   --------------------------------------------------------------------------- */
.app_bottom_columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
    gap: 1.2rem;
    align-items: start;
}

.app_bottom_column {
    min-width: 0;
}

.app_links_panel {
    margin-bottom: 0;
}

.app_links_topic {
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--ia-text-secondary);
    margin: 1rem 0 0.4rem;
}

.app_links_topic:first-child {
    margin-top: 0;
}

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

.app_links_item {
    display: block;
    padding: 0.45rem 0.6rem;
    border-radius: var(--ia-radius);
    text-decoration: none;
    color: var(--ia-text);
}

.app_links_item:hover,
.app_links_item:focus-visible {
    background: rgba(0, 0, 0, 0.045);
    color: var(--ia-text);
}

.app_links_title {
    display: block;
    font-weight: 500;
}

/* The "opens elsewhere" arrow stays quiet next to the title. */
.app_links_title .bi {
    margin-left: 0.35rem;
    font-size: 0.75em;
    color: var(--ia-text-secondary);
}

.app_links_description {
    display: block;
    font-size: 0.85rem;
    color: var(--ia-text-secondary);
}

/* Staggered dashboard tiles. The keyframes live here, the per-tile delays come
   from the dynamic branding sheet — they depend on a setting. Without a
   configured step no .app_fade rule exists and the tiles simply appear. */
@keyframes app_fade_in {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: none; }
}

/* Same timing, no travel. "Reduce motion" is about things moving across the
   screen, not about a gentle change in opacity — switching the effect off
   entirely would rob those users of the staggering they asked for. */
@keyframes app_fade_in_soft {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* ---------------------------------------------------------------------------
   Background thumbnails on the own profile plus the lightbox they open.
   --------------------------------------------------------------------------- */
/* Last tile on the profile, across every column of the detail grid. */
.app_background_section {
    grid-column: 1 / -1;
}

/* The dropdown must not stretch across that full width — a list of names
   needs no more room than the other fields on the page. */
.app_background_select {
    max-width: 26rem;
}

.app_background_previews {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
    gap: 0.6rem;
    margin: 0.4rem 0 1rem;
}

.app_background_preview {
    display: block;
    padding: 0;
    border: 1px solid var(--ia-border);
    border-radius: var(--ia-radius);
    background: none;
    overflow: hidden;
    cursor: zoom-in;
    text-align: left;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.app_background_preview:hover,
.app_background_preview:focus-visible {
    transform: translateY(-2px);
    box-shadow: var(--ia-shadow-soft);
}

.app_background_preview img {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
}

.app_background_preview_name {
    display: block;
    padding: 0.3rem 0.5rem;
    font-size: 0.8rem;
    color: var(--ia-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app_lightbox {
    position: fixed;
    inset: 0;
    z-index: 1080;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: rgba(0, 0, 0, 0.72);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
}

.app_lightbox[hidden] {
    display: none;
}

.app_lightbox_frame {
    position: relative;
    max-width: min(92vw, 70rem);
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.app_lightbox_image {
    max-width: 100%;
    /* Room for the caption and the close button above it. */
    max-height: calc(90vh - 4rem);
    object-fit: contain;
    border-radius: var(--ia-radius-large);
    background: #000;
}

.app_lightbox_caption {
    margin: 0;
    text-align: center;
    color: #ffffff;
    font-size: 0.9rem;
}

.app_lightbox_close {
    position: absolute;
    top: -0.75rem;
    right: -0.75rem;
    width: 2.25rem;
    height: 2.25rem;
    border: 0;
    border-radius: 999px;
    background: #ffffff;
    color: #1d1d1f;
    cursor: pointer;
    box-shadow: var(--ia-shadow-soft);
}

@media (max-width: 40rem) {
    /* On a phone the button would hang off the screen edge. */
    .app_lightbox_close {
        top: 0.4rem;
        right: 0.4rem;
    }
}

/* ---------------------------------------------------------------------------
   Stopwatch tile: three rows, each topic — time — buttons. Sized so the tile
   stays as tall as its neighbours instead of stretching the dashboard row.
   --------------------------------------------------------------------------- */
/* Inside the quick access grid: same box as its neighbours, but worked in
   rather than clicked through — so no hover lift and no pointer cursor.
   Two columns wide, because three rows of field-time-buttons need the room. */
.app_tile_stopwatch {
    cursor: default;
    grid-column: span 2;
}

/* The grid fills itself with 15rem columns, so below roughly 34rem there is
   only one — spanning two would invent a second column and push the tile out
   of the page. There it simply takes the single column it has. */
@media (max-width: 34rem) {
    .app_tile_stopwatch {
        grid-column: auto;
    }
}

.app_tile_stopwatch:hover {
    transform: none;
}

/* The tile is a two-column grid (icon | title). Without this the list would
   land in the narrow first column, blow it up and push the title far to the
   right — exactly like the description does, it has to span both columns. */
.app_stopwatch_list {
    grid-column: 1 / -1;
    list-style: none;
    margin: 0.6rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    width: 100%;
}

.app_stopwatch_row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* The topic takes half the row, as asked; time and buttons share the rest. */
.app_stopwatch_label {
    flex: 1 1 50%;
    min-width: 0;
}

.app_stopwatch_time {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--ia-text-secondary);
    min-width: 5.5rem;
    text-align: right;
}

/* A running watch reads as active without shouting. */
.app_stopwatch_row.is_running .app_stopwatch_time {
    color: var(--ia-success);
}

.app_stopwatch_actions {
    flex: 0 0 auto;
    display: flex;
    gap: 0.25rem;
}

.app_stopwatch_button {
    padding: 0.25rem 0.5rem;
    line-height: 1;
}

@media (max-width: 40rem) {
    /* Phone: topic on its own line, time and buttons underneath. */
    .app_stopwatch_row {
        flex-wrap: wrap;
    }

    .app_stopwatch_label {
        flex: 1 1 100%;
    }

    .app_stopwatch_time {
        flex: 1 1 auto;
        text-align: left;
    }
}

/* ---------------------------------------------------------------------------
   Background administration: one card per entry. Wide screens put them next to
   each other, a phone stacks them — every field keeps its full width either
   way, which a table of inputs could never do.
   --------------------------------------------------------------------------- */
.app_background_grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
    gap: 1rem;
    margin-bottom: 1rem;
}

.app_background_card {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    /* The grid gap already separates the cards; the section's own bottom
       margin would double it and leave the last row hanging. */
    margin-bottom: 0;
}

/* Order number and the active switch share one line — both are short. */
.app_background_meta {
    display: flex;
    align-items: flex-end;
    gap: 1.25rem;
    flex-wrap: wrap;
}

.app_field_narrow {
    flex: 0 0 7rem;
}

.app_background_check {
    padding-bottom: 0.5rem;
}

/* Due date / "do not touch before" markers inside the status bubble. */
.app_status_icon {
    margin-left: 0.35rem;
    opacity: 0.75;
}

/* Still asleep — the date has not passed yet. */
.app_status_icon.is_waiting {
    opacity: 1;
}

/* ---------------------------------------------------------------------------
   Live tile: the ticket feed refreshes itself, and a very quiet heartbeat in
   the background says so without ever demanding attention.
   Only opacity is animated (compositor-only, no repaint), and browsers stop
   animations in hidden tabs on their own.
   --------------------------------------------------------------------------- */
.app_live_block::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background: radial-gradient(120% 80% at 50% 0%,
        rgba(122, 80, 158, 0.11), rgba(122, 80, 158, 0) 70%);
    opacity: 0;
    animation: app_live_pulse 3.4s ease-in-out infinite;
}

/* Keeps the pulse strictly behind the rows instead of over their text. */
.app_live_block > * {
    position: relative;
    z-index: 1;
}

@keyframes app_live_pulse {
    0%, 100% { opacity: 0; }
    50% { opacity: 1; }
}

/* Short confirmation the moment new rows arrive. */
[data-live-feed].is_updated {
    animation: app_live_swap 0.9s ease-out;
}

@keyframes app_live_swap {
    from { background-color: rgba(122, 80, 158, 0.10); }
    to { background-color: transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .app_live_block::after,
    [data-live-feed].is_updated {
        animation: none;
    }
}

/* The customer wrote last and we have not answered yet. The badge breathes
   softly (opacity only — no travel, so it stays on even when the system
   asks for reduced motion, same reasoning as the tile fade). */
.app_update_badge {
    white-space: nowrap;
    background: rgba(197, 122, 0, 0.12);
    color: #a86400;
    animation: app_update_pulse 2.4s ease-in-out infinite;
}

@keyframes app_update_pulse {
    0%, 100% { opacity: 0.7; }
    50% { opacity: 1; }
}

/* Waiting on an answer for more than 24 hours: amber becomes red. */
.app_update_badge.is_overdue {
    background: rgba(215, 0, 21, 0.10);
    color: var(--ia-danger);
}

/* No assignee: same pill, reddish label (stays red on hover too). */
.app_assignee_badge.is_unassigned,
a.app_badge.is_unassigned:hover {
    color: var(--ia-danger);
}

.app_badge_success {
    background: rgba(29, 122, 58, 0.10);
    color: var(--ia-success);
}

.app_badge_muted {
    background: rgba(0, 0, 0, 0.05);
    color: var(--ia-text-secondary);
}

/* Pagination -------------------------------------------------------------- */

.app_pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.9rem;
    margin-top: 1.4rem;
}

.app_pagination_link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.2rem;
    height: 2.2rem;
    border-radius: var(--ia-radius);
    border: 1px solid var(--ia-border);
    background: rgba(255, 255, 255, 0.8);
    color: var(--ia-text);
    text-decoration: none;
}

.app_pagination_link:hover {
    border-color: var(--ia-accent);
    color: var(--ia-accent);
}

.app_pagination_status {
    color: var(--ia-text-secondary);
    font-size: 0.9rem;
}

/* Empty states, misc ------------------------------------------------------ */

.app_empty_state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
    padding: 3rem 1.5rem;
    color: var(--ia-text-secondary);
    text-align: center;
}

.app_empty_state .bi {
    font-size: 1.8rem;
    color: var(--ia-border);
}

.app_empty_state p {
    margin: 0;
    font-size: 0.95rem;
}

.app_error_code {
    color: var(--ia-text-secondary);
    font-size: 0.85rem;
    letter-spacing: 0.24em;
    margin: 0;
}

.app_page_wide {
    max-width: none;
}

/* Auth extensions (registration, reset, results) -------------------------- */

.auth_card_wide {
    max-width: 32rem;
}

.auth_card_text {
    max-width: 46rem;
}

.auth_links {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 1.4rem;
    font-size: 0.88rem;
}

.auth_links a {
    color: var(--ia-accent);
    text-decoration: none;
}

.auth_links a:hover {
    text-decoration: underline;
}

.app_field_row {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 0 1rem;
}

/* A field label with a small helper link on the right (e.g. "browse icons"). */
.app_field_label_row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    flex-wrap: wrap;
}

.app_field_label_link {
    font-size: 0.82rem;
    white-space: nowrap;
    text-decoration: none;
    color: var(--ia-accent, #2c6ecb);
}

.app_field_label_link:hover {
    text-decoration: underline;
}

/* Public safe-create + admin-open + "our data"/link tiles: input-with-buttons rows. */
.app_safe_pw_row,
.app_safe_inline_form {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
}

.app_safe_pw_row > .form-control,
.app_safe_inline_form > .form-control {
    flex: 1 1 12rem;
    min-width: 0;
}

.app_safe_public_link {
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    white-space: nowrap;
    font-size: 0.85rem;
    padding: 0.35rem 0.5rem;
    background: rgba(0, 0, 0, 0.05);
    border-radius: 6px;
}

/* Ticket approval (Ticketgenehmigungs-Modus): a held ticket reads greyed-out
   and locked; the approver panel above it carries the decision dropdown. */
.app_row_pending > td {
    opacity: 0.5;
}

.app_ticket_pending {
    opacity: 0.55;
}

.app_approval_panel {
    padding: 1rem 1.25rem;
    margin-bottom: 1rem;
}

.app_approval_row {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 0.35rem;
}

.app_approval_row > .form-select {
    flex: 0 1 20rem;
}

@media (max-width: 40rem) {
    .app_field_row {
        grid-auto-flow: row;
        grid-auto-columns: auto;
        grid-template-columns: 1fr;
    }
}

.app_field_error {
    color: var(--ia-danger);
    font-size: 0.82rem;
    margin: 0.3rem 0 0;
}

.app_field_hint {
    color: var(--ia-text-secondary);
    font-size: 0.82rem;
    margin: 0.3rem 0 0;
}

.auth_result_icon {
    display: inline-flex;
    font-size: 2.4rem;
    line-height: 1;
}

/* Only when a logo sits right above it — the other result pages start with
   the icon and need no extra gap. */
.auth_brand_logo + .auth_result_icon {
    margin-top: 1.1rem;
}

.auth_result_icon.is_success {
    color: var(--ia-success);
}

.auth_result_icon.is_error {
    color: var(--ia-danger);
}

/* Toolbar (list header with filters + primary action) --------------------- */

.app_toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.app_toolbar_filters {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.app_toolbar_actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.app_form_wide {
    max-width: 60rem;
}

.app_textarea_code {
    font-family: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, monospace;
    font-size: 0.85rem;
    line-height: 1.5;
}

/* Rich text (sanitized admin HTML) ---------------------------------------- */

.app_rich_text {
    font-size: 0.95rem;
    line-height: 1.6;
    color: var(--ia-text);
    text-align: left;
    /* Long URLs / unbroken strings wrap instead of widening the page. */
    overflow-wrap: anywhere;
}

/* Embedded images (descriptions, comments, chat bubbles) never exceed their
   container — a big pasted image must not push the page wider on mobile. */
.app_rich_text img,
.app_chat_bubble img {
    max-width: 100%;
    height: auto;
}

.app_rich_text_panel {
    padding: 1.75rem 2rem;
    max-width: 60rem;
}

.app_rich_text h1,
.app_rich_text h2,
.app_rich_text h3,
.app_rich_text h4 {
    font-weight: 600;
    letter-spacing: -0.01em;
    margin: 1.4em 0 0.5em;
}

.app_rich_text h1 { font-size: 1.35rem; }
.app_rich_text h2 { font-size: 1.15rem; }
.app_rich_text h3 { font-size: 1.02rem; }

.app_rich_text p,
.app_rich_text ul,
.app_rich_text ol {
    margin-bottom: 0.8em;
}

.app_rich_text a {
    color: var(--ia-accent);
}

/* Consent text inside the registration checkbox label: it sits in a <label>,
   so block elements from the admin HTML must not add outer spacing. */
.app_consent_text {
    display: inline;
}

.app_consent_text p:last-child,
.app_consent_text ul:last-child,
.app_consent_text ol:last-child {
    margin-bottom: 0;
}

.app_rich_text table {
    width: 100%;
    border-collapse: collapse;
    margin: 1em 0;
    font-size: 0.9rem;
}

.app_rich_text th,
.app_rich_text td {
    border: 1px solid var(--ia-border-soft);
    padding: 0.5rem 0.7rem;
    text-align: left;
}

/* Detail pages, sections, matrices ---------------------------------------- */

.app_detail_grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
    gap: 1.1rem;
    margin-bottom: 1.1rem;
}

/* Compact stat list (e.g. client ticket overview) ------------------------ */

.app_stat_list {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
}

.app_stat_list li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--ia-border-soft);
}

.app_stat_list li:last-child {
    border-bottom: 0;
}

.app_stat_label {
    color: var(--ia-text-secondary);
    font-size: 0.9rem;
}

.app_stat_value {
    font-size: 1.15rem;
    font-weight: 600;
}

.app_stat_value.app_stat_urgent {
    color: var(--ia-danger);
}

.app_detail_actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
}

.app_page_website {
    margin: 0.2rem 0 0.35rem;
    font-size: 0.92rem;
}

.app_page_website a {
    color: var(--ia-accent);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.app_page_website a:hover {
    text-decoration: underline;
}

.app_detail_section {
    padding: 1.4rem 1.6rem;
    margin-bottom: 1.1rem;
}

.app_section_title {
    font-size: 1.02rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.9rem;
}

.app_section_title .bi {
    color: var(--ia-accent);
}

/* Small icon-only action next to a section title (e.g. edit description). */
.app_icon_button {
    background: none;
    border: 0;
    color: var(--ia-text-secondary);
    cursor: pointer;
    font-size: 0.9rem;
    line-height: 1;
    padding: 0.15rem 0.3rem;
}

.app_icon_button:hover,
.app_icon_button:focus-visible {
    color: var(--ia-accent);
}

.app_icon_button .bi {
    color: inherit;
}

.app_description_input {
    min-height: 9rem;
}

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

.app_entity_list li {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0;
    border-bottom: 1px solid var(--ia-border-soft);
    font-size: 0.92rem;
    flex-wrap: wrap;
}

.app_entity_list li:last-child {
    border-bottom: 0;
}

.app_entity_list form.app_inline_form {
    margin-left: auto;
}

.app_muted {
    color: var(--ia-text-secondary);
    font-size: 0.88rem;
}

.app_row_link {
    color: var(--ia-text);
    font-weight: 500;
    text-decoration: none;
}

.app_row_link:hover {
    color: var(--ia-accent);
}

.app_id_link {
    text-decoration: underline;
    text-underline-offset: 0.15em;
}

.app_inline_form {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
}

.app_icon_link_danger {
    color: var(--ia-danger);
    background: none;
    border: 0;
}

.app_icon_link_danger:hover {
    background: rgba(215, 0, 21, 0.08);
}

button.app_icon_link {
    background: none;
    border: 0;
}

/* "Jetzt erstellen" icon (recurring list): a spinning arrow while the ticket
   is created, then a green check or a red warning triangle. */
@keyframes app_spin {
    to { transform: rotate(360deg); }
}

.app_spin {
    display: inline-block;
    animation: app_spin 0.7s linear infinite;
}

.app_recurring_run_now.is_created {
    color: var(--ia-success);
}

.app_recurring_run_now.is_error {
    color: var(--ia-danger);
}

.app_recurring_run_now:disabled {
    cursor: default;
    opacity: 1;
}

.app_details summary {
    cursor: pointer;
    color: var(--ia-accent);
    font-size: 0.92rem;
    font-weight: 500;
    padding: 0.6rem 0;
}

/* "Relevante Themen" tile: the summary reads as the tile heading, the
   categories unfold as a simple vertical checkbox list. */
.app_topics_summary {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--ia-text-primary);
}

.app_topics_summary .bi {
    color: var(--ia-accent);
    margin-right: 0.4rem;
}

.app_topics_hint {
    margin: 0.4rem 0 0.8rem;
}

.app_topics_list {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-bottom: 1rem;
}

.app_topics_list .form-check {
    margin: 0;
}

/* Reverse mapping page (category → relevant clients). */
.app_topics_clients_panel {
    padding: 1.25rem;
}

.app_topics_toggle_all {
    margin-bottom: 0.9rem;
}

/* A long client list stays scrollable inside the panel instead of pushing
   the save button off-screen. */
.app_topics_clients_list {
    max-height: 60vh;
    overflow-y: auto;
    padding-right: 0.4rem;
}

/* Live filter box above the client list. */
.app_topics_filter_wrap {
    position: relative;
    margin-bottom: 0.9rem;
}

.app_topics_filter_wrap .bi {
    position: absolute;
    left: 0.7rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--ia-text-secondary);
    pointer-events: none;
}

.app_topics_filter {
    padding-left: 2rem;
}

.app_topics_no_match {
    padding: 0.6rem 0.2rem;
}

/* Boundary between the bundled selection and the remaining clients. */
.app_topics_divider {
    margin: 0.55rem 0 0.1rem;
    padding-top: 0.5rem;
    border-top: 1px solid rgba(128, 128, 128, 0.25);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ia-text-secondary);
}

/* The sublink under a product name in the products list. */
.app_option_sublink {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    margin-top: 0.4rem;
    font-size: 0.85rem;
    color: var(--ia-accent);
    text-decoration: none;
}

.app_option_sublink:hover {
    text-decoration: underline;
}

/* Ticket "Schritte" (Steps) checklist. */
.app_steps_field > .form-label {
    font-size: 1rem;
    font-weight: 600;
}

.app_steps_field > .form-label .bi {
    color: var(--ia-accent);
    margin-right: 0.35rem;
}

.app_steps_list {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.app_step_row {
    display: flex;
    align-items: center;
    gap: 0.55rem;
}

.app_step_toggle {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--ia-text-secondary);
    font-size: 1.2rem;
    line-height: 1;
    flex: 0 0 auto;
}

.app_step_toggle.is_done {
    color: #2e9e5b;
}

.app_step_input {
    flex: 1 1 auto;
}

.app_steps_readonly {
    list-style: none;
    margin: 0.3rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.app_step_readonly {
    display: flex;
    align-items: center;
    gap: 0.55rem;
}

.app_step_readonly .bi {
    color: var(--ia-text-secondary);
    flex: 0 0 auto;
}

.app_step_readonly.is_done .bi {
    color: #2e9e5b;
}

.app_step_readonly.is_done span {
    text-decoration: line-through;
    color: var(--ia-text-secondary);
}

/* Ticket conversation as a chat (WhatsApp-style): admin messages on the right,
   customers on the left, system events centered and compact. */
.app_chat {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}

.app_chat_msg {
    display: flex;
    flex-direction: column;
    max-width: 80%;
}

.app_chat_admin {
    align-self: flex-end;
    align-items: flex-end;
}

.app_chat_customer {
    align-self: flex-start;
    align-items: flex-start;
}

.app_chat_system {
    align-self: flex-end;
    max-width: 80%;
}

/* Bubble + avatar in a row; the avatar sits at the bubble's bottom corner
   (right for our messages, left for the customer's). The meta caption is
   below, spanning the full width. */
.app_chat_row {
    display: flex;
    align-items: flex-end;
    gap: 0.5rem;
    min-width: 0;
    max-width: 100%;
}

.app_chat_customer .app_chat_row {
    flex-direction: row-reverse;
}

/* Initials avatar circle next to each bubble. */
.app_chat_avatar {
    flex: 0 0 auto;
    width: 2.2rem;
    height: 2.2rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--ia-chat-text, #fff);
    text-decoration: none;
}

.app_chat_admin .app_chat_avatar {
    background: linear-gradient(to right, var(--ia-chat-admin-from, #68b9b9), var(--ia-chat-admin-to, #6e92af));
}

.app_chat_customer .app_chat_avatar {
    background: linear-gradient(to right, var(--ia-chat-customer-from, #79509e), var(--ia-chat-customer-to, #7378a9));
}

.app_chat_bubble {
    padding: 0.55rem 0.8rem;
    border-radius: 14px;
    background: rgba(130, 130, 130, 0.16);
    overflow-wrap: anywhere;
    /* Bubble text colour — configurable in Settings → Design. */
    color: var(--ia-chat-text, #fff);
}

.app_chat_admin .app_chat_bubble {
    background: linear-gradient(to right, var(--ia-chat-admin-from, #68b9b9), var(--ia-chat-admin-to, #6e92af));
    border-bottom-right-radius: 4px;
}

.app_chat_customer .app_chat_bubble {
    background: linear-gradient(to right, var(--ia-chat-customer-from, #79509e), var(--ia-chat-customer-to, #7378a9));
    border-bottom-left-radius: 4px;
}

.app_chat_admin .app_chat_bubble a,
.app_chat_customer .app_chat_bubble a {
    color: inherit;
    text-decoration: underline;
}

/* Internal comments: same "our" bubble, set apart by an amber outline + tag. */
.app_chat_msg.is_internal .app_chat_bubble {
    outline: 2px solid rgba(212, 167, 44, 0.7);
    outline-offset: -2px;
}

.app_chat_bubble .app_rich_text {
    margin: 0;
    /* Inherit the bubble text colour (white) instead of the default dark text. */
    color: inherit;
}

/* Attachments uploaded with a message: download links under its bubble. */
.app_chat_files {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    margin-top: 0.3rem;
    padding: 0 0.3rem;
}

.app_chat_file {
    font-size: 0.8rem;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.app_chat_file:hover {
    text-decoration: underline;
}

.app_chat_tag {
    display: inline-block;
    margin-bottom: 0.3rem;
}

/* Opening bubble that previews the description; links up to the full text. */
.app_chat_desc {
    text-decoration: none;
}

/* The "Name, 20.08.26, 12:23 Uhr" caption under each bubble. */
.app_chat_meta {
    margin-top: 0.25rem;
    padding: 0 0.3rem;
    font-size: 0.72rem;
    color: var(--ia-text-secondary);
}

/* System entries stay grey, compact and on a single line. */
.app_chat_system_inner {
    font-size: 0.76rem;
    color: var(--ia-text-secondary);
    background: rgba(130, 130, 130, 0.12);
    border-radius: 8px;
    padding: 0.25rem 0.6rem;
}

.app_chat_sysline {
    display: block;
}

.app_chat_ts {
    white-space: nowrap;
    opacity: 0.85;
}

.app_chat_mail {
    text-align: left;
}

.app_chat_mail > summary {
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app_chat_mail_subject {
    margin: 0.35rem 0 0.2rem;
    white-space: normal;
}

/* Composer integrated into the chat (no own tile). */
.app_chat_composer {
    margin-top: 1rem;
    border-top: 1px solid var(--ia-border-soft, rgba(128, 128, 128, 0.25));
    padding-top: 0.8rem;
}

.app_chat_composer_bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
    margin-bottom: 0.5rem;
}

.app_chat_canned {
    width: auto;
    max-width: 100%;
    margin-left: auto;
}

.app_chat_composer_row {
    display: flex;
    align-items: flex-end;
    gap: 0.5rem;
}

.app_chat_input {
    flex: 1 1 auto;
    min-width: 0;
}

.app_chat_attach {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 50%;
    border: 1px solid var(--ia-border-soft, rgba(128, 128, 128, 0.3));
    cursor: pointer;
    font-size: 1.1rem;
    color: var(--ia-text-secondary);
}

.app_chat_attach:hover {
    color: var(--ia-accent);
    border-color: var(--ia-accent);
}

.app_chat_attach_names {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.78rem;
}

/* Auto-grow textareas (internal note + composer input). */
.app_autogrow {
    resize: none;
    overflow: hidden;
    min-height: 2.6rem;
    max-height: 40vh;
}

/* Section title with actions pushed to the right (description tile). */
.app_section_title_row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.app_section_title_actions {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
}

.app_steps_add_link {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--ia-accent);
}

/* Internal note as a compact field under the description. */
.app_internal_field {
    margin-top: 0.9rem;
}

.app_internal_field_label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* Attachments in the description tile: image thumbnails + name links. */
.app_attach_field {
    margin-top: 0.9rem;
}

.app_attach_grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.3rem 0 0.5rem;
}

.app_attach_item {
    text-decoration: none;
    color: var(--ia-text);
    max-width: 100%;
}

.app_attach_image {
    position: relative;
    display: inline-block;
    line-height: 0;
}

/* Thumbnails: fixed 8rem, never the full image size. */
.app_attach_image img {
    width: 8rem;
    height: 8rem;
    object-fit: cover;
    border-radius: var(--ia-radius, 8px);
    border: 1px solid var(--ia-border-soft, rgba(128, 128, 128, 0.25));
}

.app_attach_badge {
    position: absolute;
    top: 0.25rem;
    left: 0.25rem;
}

.app_attach_file {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.85rem;
    padding: 0.3rem 0.55rem;
    border-radius: var(--ia-radius, 8px);
    background: rgba(130, 130, 130, 0.1);
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.app_attach_file:hover {
    text-decoration: underline;
}

.app_attach_add_row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* Internal note collapsed row: label + reveal pencil in one line. */
.app_internal_toggle_row {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* "Sonstiges" collapsible items in the sidebar. */
.app_misc_details {
    border-top: 1px solid var(--ia-border-soft, rgba(128, 128, 128, 0.2));
}

.app_misc_details > summary {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 500;
    color: var(--ia-text);
}

/* Leads app: per-row action buttons + the "versendet" info count. */
.app_lead_actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.app_stat_sent {
    color: #2e9e5b;
}

/* Generic "hide it" helper toggled by JS (checks editor, website check). */
.is_hidden {
    display: none !important;
}

/* Leads → Checks editor + the check columns on the leads table. */
.app_checks_table th,
.app_checks_table td {
    vertical-align: top;
}

.app_check_order_cell {
    width: 8rem;
}

.app_check_active_cell {
    width: 5rem;
    text-align: center;
}

.app_check_meta_cell {
    width: 9rem;
    white-space: nowrap;
}

.app_check_status {
    font-size: 0.8rem;
    margin-right: 0.4rem;
}

.app_check_template {
    min-height: 2.6rem;
}

.app_checks_hint {
    margin: 0.6rem 0 0;
}

/* Check columns on the leads table. Width is configurable (Layout → rem); the
   header wraps within it so long titles don't stretch the column. In an auto
   table `width` is only a hint, so min-/max-width pin the column for real. */
.app_check_col {
    text-align: center;
    padding: 0.35rem 0.6rem;
    width: var(--lead-check-col-w, 8rem);
    min-width: var(--lead-check-col-w, 8rem);
    max-width: var(--lead-check-col-w, 8rem);
}

/* Outranks `.app_table thead th { white-space: nowrap }` so long check titles
   wrap inside the (narrow) column instead of forcing it wide. */
.app_table thead th.app_check_col {
    white-space: normal;
    overflow-wrap: anywhere;
    vertical-align: bottom;
}

td.app_check_col {
    white-space: nowrap;
}

/* Bigger, easier-to-hit check checkboxes on the leads table. */
.app_check_col input[type="checkbox"] {
    width: 1.35rem;
    height: 1.35rem;
    cursor: pointer;
    accent-color: var(--ia-accent, #68b9b9);
}

/* Archived leads: greyed out but kept (actions stay fully usable). */
.app_lead_archived td:not(.app_table_actions_col) {
    opacity: 0.45;
}

/* Kundengeschenke inline-editor table. */
.app_presents_table th,
.app_presents_table td {
    vertical-align: top;
}

.app_present_num {
    width: 8rem;
}

.app_present_meta {
    width: 12rem;
    white-space: nowrap;
}

.app_present_text {
    min-height: 2.6rem;
}

.app_present_active {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-right: 0.4rem;
}

.app_present_active input[type="checkbox"] {
    width: 1.2rem;
    height: 1.2rem;
    cursor: pointer;
    accent-color: var(--ia-accent, #68b9b9);
}

.app_presents_empty {
    margin: 0.6rem 0 0;
}

/* Per-present quantity inputs on the client create form. */
.app_present_qty_list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: 0.5rem 1.2rem;
    margin-top: 0.35rem;
}

.app_present_qty_row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.app_present_qty_label {
    flex: 1;
    margin: 0;
}

.app_present_qty_input {
    width: 5.5rem;
}

/* "Unternehmen" quick-access tile: standard icon+title row like the other tiles;
   the company list spans the full width below, left-aligned. */
.app_tile_company_list {
    grid-column: 1 / -1;
    list-style: disc;
    margin: 0.1rem 0 0;
    padding-left: 1.25rem;
    text-align: left;
}

.app_tile_company_list li {
    margin: 0.15rem 0;
}

/* Consistent gap under the page header on these pages (1.75rem), whether or not
   they carry a subtitle — so /clients/detail, /clients/people and /tickets/create
   line up. The subtitle's own 2rem margin is neutralised here. */
.app_portal_page .app_page_header {
    margin-bottom: 1.75rem;
}

.app_portal_page .app_page_subtitle {
    margin-bottom: 0;
}

/* A detail tile that is itself a link (e.g. "Verbundene Personen"). */
.app_detail_link {
    display: block;
    text-decoration: none;
    color: inherit;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.app_detail_link:hover {
    color: inherit;
    transform: translateY(-2px);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04), 0 16px 48px rgba(0, 0, 0, 0.10);
}

/* Verbundene-Personen list: name left, badges right. */
.app_people_list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.app_people_row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 0.65rem 0.5rem;
    border-bottom: 1px solid var(--ia-border-soft);
    transition: background 0.12s ease;
}

.app_people_row:last-child {
    border-bottom: none;
}

.app_people_row:hover {
    background: rgba(0, 0, 0, 0.04);
}

.app_people_main {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    min-width: 0;
}

.app_people_email {
    font-size: 0.85rem;
    overflow-wrap: anywhere;
}

.app_people_badges {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.app_badge_role {
    background: rgba(104, 185, 185, 0.18);
    color: var(--ia-text);
}

/* ---- Angebote (offers) ------------------------------------------------- */
.app_offer_thumb {
    width: 44px;
    height: 44px;
    object-fit: cover;
    border-radius: 6px;
    display: block;
}

/* Admin form: existing images with a remove checkbox. */
.app_offer_image_grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.8rem;
}

.app_offer_image_item {
    margin: 0;
    width: 130px;
}

.app_offer_image_item img {
    width: 130px;
    height: 100px;
    object-fit: cover;
    border-radius: 8px;
    display: block;
}

.app_offer_preview_tag {
    font-size: 0.72rem;
    color: var(--ia-accent);
    font-weight: 600;
    margin: 0.2rem 0 0;
}

.app_offer_remove {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.8rem;
    margin-top: 0.25rem;
}

/* Detail page gallery + body. */
.app_offer_detail {
    padding: 1.4rem 1.6rem;
}

.app_offer_gallery {
    display: flex;
    flex-wrap: wrap;
    gap: 0.8rem;
    margin-bottom: 1.2rem;
}

.app_offer_image {
    max-height: 20em;
    max-width: 100%;
    width: auto;
    border-radius: 10px;
    cursor: zoom-in;
    object-fit: cover;
}


.app_offer_subtitle {
    font-size: 1.05rem;
    color: var(--ia-text-secondary);
    margin: 0 0 0.5rem;
}

.app_offer_price {
    font-size: 1.2rem;
    font-weight: 600;
    margin: 0 0 1rem;
}

.app_offer_description {
    margin-bottom: 1.2rem;
    line-height: 1.6;
}

/* Dashboard offers slider: ~4 tiles wide, one slide at a time. The section
   heading sits above the panel (like the other dashboard sections). */
.app_section_heading.app_offer_slider_head {
    margin: 2.75rem 0 0.9rem;
}

.app_offer_slider {
    position: relative;
    width: 100%;
    padding: 1.1rem 3.4rem 1.3rem;
    margin-bottom: 1.5rem;
}

.app_offer_view_btn {
    display: inline-block;
    margin-top: 0.7rem;
    padding: 0.4rem 1rem;
    border-radius: 8px;
    background: var(--ia-accent, #68b9b9);
    color: #ffffff;
    font-size: 0.85rem;
    font-weight: 600;
}

.app_offer_slide {
    display: none;
    gap: 1.1rem;
    align-items: center;
    text-decoration: none;
    color: inherit;
}

.app_offer_slide.is_active {
    display: flex;
}

.app_offer_slide_media {
    flex: 0 0 40%;
    max-width: 40%;
}

.app_offer_slide_media img {
    width: 100%;
    height: 374px;
    object-fit: cover;
    border-radius: 10px;
    display: block;
}

.app_offer_slide_body {
    flex: 1 1 auto;
    min-width: 0;
}

.app_offer_slide_title {
    font-size: 1.1rem;
    font-weight: 600;
    margin: 0 0 0.3rem;
}

.app_offer_slide_price {
    font-weight: 600;
    color: var(--ia-accent);
    margin-bottom: 0.4rem;
}

.app_offer_slide_desc {
    color: var(--ia-text-secondary);
    margin: 0;
}

.app_offer_arrow {
    position: absolute;
    top: 55%;
    transform: translateY(-50%);
    width: 2.2rem;
    height: 2.2rem;
    border-radius: 50%;
    border: none;
    background: rgba(0, 0, 0, 0.06);
    color: var(--ia-text);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}

.app_offer_prev {
    left: 0.4rem;
}

.app_offer_next {
    right: 0.4rem;
}

.app_offer_arrow:hover {
    background: rgba(0, 0, 0, 0.12);
}

/* Progress "comet": a soft dot runs along the bottom over the 15s auto-advance,
   its trail fading out behind it; reaching the right shows the next offer. */
.app_offer_progress {
    position: absolute;
    left: 3.4rem;
    right: 3.4rem;
    bottom: 0.55rem;
    height: 4px;
    overflow: hidden;
    border-radius: 3px;
    pointer-events: none;
}

.app_offer_progress_dot {
    position: absolute;
    top: 0;
    left: -70px;
    width: 70px;
    height: 100%;
    border-radius: 3px;
    background: linear-gradient(to right, rgba(104, 185, 185, 0), var(--ia-accent, #68b9b9));
    animation: app_offer_progress_run 15s linear infinite;
}

@keyframes app_offer_progress_run {
    from {
        left: -70px;
    }

    to {
        left: calc(100% - 70px);
    }
}

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

@media (max-width: 60rem) {
    .app_offer_slider {
        width: 100%;
    }

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

    .app_offer_slide_media {
        flex: none;
        max-width: 100%;
    }

    .app_offer_slide_media img {
        height: 420px;
    }
}

/* Client detail: reserved empty tile for an upcoming section. */
.app_detail_placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 8rem;
    text-align: center;
}

/* Native colour swatch inputs (e.g. the chat bubble colours in Design). */
.app_color_input {
    width: 3.6rem;
    height: 2.5rem;
    padding: 0.15rem;
    border: 1px solid var(--ia-border-soft, rgba(128, 128, 128, 0.3));
    border-radius: var(--ia-radius, 8px);
    background: none;
    cursor: pointer;
}

@media (max-width: 720px) {
    .app_chat_msg {
        max-width: 94%;
    }
}

/* "Neues Produkt anlegen" form inside its top tile. */
.app_products_add_form .app_field {
    margin-bottom: 0.7rem;
}

.app_products_add_form .app_form_actions {
    margin-top: 0.2rem;
}

.app_sort_link {
    color: inherit;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
}

.app_sort_link:hover {
    color: var(--ia-accent);
}

.app_sort_icon {
    font-size: 0.65rem;
}

.app_badge_warning {
    background: rgba(255, 149, 0, 0.14);
    color: #b25f00;
}

.app_badge_danger {
    background: rgba(215, 0, 21, 0.10);
    color: var(--ia-danger);
}

.app_button_danger {
    border: 1px solid rgba(215, 0, 21, 0.35);
    border-radius: var(--ia-radius);
    background: rgba(255, 255, 255, 0.8);
    color: var(--ia-danger);
    padding: 0.6rem 1.3rem;
    font-size: 0.95rem;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}

.app_button_danger:hover {
    background: rgba(215, 0, 21, 0.06);
    color: var(--ia-danger);
}

.app_alert_block {
    align-items: flex-start;
}

.app_alert_title {
    font-weight: 600;
    margin: 0 0 0.4rem;
}

.app_code_block {
    display: block;
    background: rgba(0, 0, 0, 0.05);
    border-radius: var(--ia-radius);
    padding: 0.55rem 0.75rem;
    font-size: 0.82rem;
    word-break: break-all;
    color: var(--ia-text);
    user-select: all;
}

.app_action_bar {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.app_add_row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.9rem;
    flex-wrap: wrap;
}

.app_add_row .form-select {
    max-width: 16rem;
}

/* Autocomplete inside an add-row: the wrapper holds the dropdown, so it needs
   its own width instead of collapsing to the input's intrinsic size. */
.app_add_row_grow {
    flex: 1 1 16rem;
    max-width: 22rem;
}

.app_registration_meta {
    margin: 0.9rem 0 0;
}

.app_toolbar_filters .form-control,
.app_toolbar_filters .form-select {
    max-width: 13rem;
}

/* Autocomplete inside a toolbar: the wrapper carries the dropdown, so it must
   not stretch across the remaining space. */
.app_toolbar_autocomplete {
    flex: 0 0 auto;
}

/* The free-text search gets clearly more room than the narrow selects. */
.app_toolbar_filters {
    flex: 1 1 auto;
    flex-wrap: wrap;
}

.app_toolbar_filters .form-control[type="search"] {
    flex: 1 1 18rem;
    max-width: 32rem;
}

.app_matrix_table th[scope="row"] {
    font-weight: 500;
}

.app_matrix_action {
    text-align: center;
    font-size: 0.72rem;
}

.app_matrix_cell {
    text-align: center;
}

.app_matrix_none {
    color: var(--ia-border);
}

/* Tickets: queue chips, layout, timeline, autocomplete --------------------- */

.app_queue_bar {
    display: flex;
    gap: 0.45rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.app_queue_chip {
    display: inline-flex;
    align-items: center;
    padding: 0.32rem 0.85rem;
    border-radius: 999px;
    border: 1px solid var(--ia-border);
    background: rgba(255, 255, 255, 0.72);
    color: var(--ia-text-secondary);
    font-size: 0.85rem;
    text-decoration: none;
}

.app_queue_chip:hover {
    color: var(--ia-text);
    border-color: var(--ia-text-secondary);
}

.app_queue_chip.is_active {
    background: var(--ia-accent);
    border-color: var(--ia-accent);
    color: #ffffff;
    font-weight: 500;
}

.app_ticket_layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 21rem;
    gap: 1.1rem;
    align-items: start;
}

@media (max-width: 991.98px) {
    /* minmax(0, 1fr) — NOT 1fr — so the single column may shrink below the
       intrinsic width of its widest child; otherwise a wide element (chat,
       composer, long word) pushes the whole page wider than the phone screen
       and it scrolls sideways. */
    .app_ticket_layout {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Grid children default to min-width:auto and would refuse to shrink; force 0
   so long content wraps or scrolls inside instead of overflowing the page. */
.app_ticket_main,
.app_ticket_sidebar {
    min-width: 0;
}

.app_ticket_sidebar .app_detail_section {
    padding: 1.1rem 1.25rem;
}

/* When there is no properties sidebar (e.g. customers), the main column
   spans the full width. */
.app_ticket_layout.is_single {
    grid-template-columns: minmax(0, 1fr);
}

/* Tool cards (time, attachments, relations, approvals, actions) as a
   responsive full-width grid below the reply, above the history. */
.app_ticket_tools_grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
    gap: 1.1rem;
    /* Default stretch: every card in a row gets the height of the tallest. */
    margin-top: 1.1rem;
}

.app_ticket_tools_grid .app_detail_section {
    margin-bottom: 0;
}

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

.app_timeline_item {
    padding: 0.8rem 0;
    border-bottom: 1px solid var(--ia-border-soft);
}

.app_timeline_item:last-child {
    border-bottom: 0;
}

.app_timeline_item.is_internal {
    background: rgba(255, 149, 0, 0.05);
    border-radius: var(--ia-radius);
    padding-left: 0.7rem;
    padding-right: 0.7rem;
}

.app_timeline_meta {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin-bottom: 0.35rem;
    flex-wrap: wrap;
}

.app_timeline_author {
    font-weight: 600;
    font-size: 0.9rem;
}

.app_timeline_history {
    color: var(--ia-text-secondary);
    font-size: 0.88rem;
    margin: 0;
    display: flex;
    align-items: baseline;
    gap: 0.45rem;
}

/* Sent notification mails (timeline + activity log) ----------------------- */

.app_timeline_mail_subject {
    font-size: 0.85rem;
    margin: 0.2rem 0 0 1.35rem;
}

.app_mail_meta {
    font-size: 0.85rem;
    margin-top: 0.2rem;
}

.app_mail_details {
    margin-top: 0.35rem;
    margin-left: 1.35rem;
}

.app_mail_details > summary {
    cursor: pointer;
    color: var(--ia-text-secondary);
    font-size: 0.85rem;
}

.app_mail_details > summary:hover {
    color: var(--ia-accent);
}

.app_mail_body {
    background: var(--ia-surface-muted, rgba(0, 0, 0, 0.03));
    border: 1px solid var(--ia-border-soft);
    border-radius: var(--ia-radius);
    color: var(--ia-text-secondary);
    font-size: 0.82rem;
    line-height: 1.5;
    margin: 0.4rem 0 0;
    max-height: 22rem;
    overflow: auto;
    padding: 0.7rem 0.85rem;
    white-space: pre-wrap;
    word-break: break-word;
}

.app_mail_no_text {
    font-size: 0.82rem;
    margin: 0.25rem 0 0 1.35rem;
}

.app_table .app_mail_details,
.app_table .app_mail_no_text {
    margin-left: 0;
}

.app_radio_row {
    display: flex;
    gap: 0.75rem;
}

.app_toggle_block {
    margin-top: -0.4rem;
}

.app_autocomplete_wrap {
    position: relative;
}

.app_autocomplete_list {
    position: absolute;
    z-index: 60;
    left: 0;
    right: 0;
    top: 100%;
    margin: 0.25rem 0 0;
    padding: 0.3rem;
    list-style: none;
    background: var(--ia-surface-strong);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    backdrop-filter: blur(20px) saturate(180%);
    border: 1px solid var(--ia-border-soft);
    border-radius: var(--ia-radius);
    box-shadow: var(--ia-shadow-soft);
    max-height: 14rem;
    overflow-y: auto;
}

.app_autocomplete_list button {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: 0;
    border-radius: calc(var(--ia-radius) - 2px);
    padding: 0.45rem 0.6rem;
    font-size: 0.9rem;
    color: var(--ia-text);
    cursor: pointer;
    /* Long labels (e.g. name + e-mail) wrap instead of being clipped in a
       narrow field like the ticket-list "Bearbeiter" filter. */
    white-space: normal;
    overflow-wrap: anywhere;
    line-height: 1.3;
}

.app_autocomplete_list button:hover,
.app_autocomplete_list button:focus-visible {
    background: rgba(0, 113, 227, 0.10);
}

/* Statistics, notices, charts, honeypot ----------------------------------- */

.app_stat_grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
    gap: 0.9rem;
    margin-bottom: 1.3rem;
}

.app_stat_card {
    padding: 1rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.app_stat_value {
    font-size: 1.5rem;
    font-weight: 600;
    letter-spacing: -0.02em;
}

.app_stat_label {
    color: var(--ia-text-secondary);
    font-size: 0.8rem;
}

.app_chart {
    width: 100%;
    height: auto;
    /* Never upscale far beyond the 400-unit viewBox (keeps text crisp). */
    max-width: 34rem;
}

/* Full-width daily trend chart (Chart.js): fixed height, canvas fills it. */
.app_day_chart_wrap {
    position: relative;
    height: 320px;
    width: 100%;
}

/* Safety net: the chart canvas must never exceed its container, whatever
   size Chart.js writes into the inline style. */
.app_day_chart_wrap canvas {
    max-width: 100%;
}

/* Chart tiles need more minimum width than generic detail tiles, so the
   400-unit SVG viewBox renders at roughly 1:1 and text stays readable. */
.app_chart_grid {
    /* min() keeps the 26rem minimum on desktop but lets the column shrink to
       the viewport on phones (a fixed 26rem overflowed a 390px screen). */
    grid-template-columns: repeat(auto-fit, minmax(min(26rem, 100%), 1fr));
}

.app_chart_bar {
    fill: var(--ia-accent);
    opacity: 0.85;
}

.app_chart_label {
    font-size: 13px;
    fill: var(--ia-text-secondary);
}

.app_chart_value {
    font-size: 13px;
    fill: var(--ia-text);
    font-weight: 600;
}

.app_notice {
    background: rgba(0, 113, 227, 0.06);
    border-color: rgba(0, 113, 227, 0.2);
    color: var(--ia-text);
    justify-content: space-between;
}

.app_notice_body {
    flex: 1;
}

.app_popup {
    border-radius: var(--ia-radius-large);
}

.app_honeypot {
    position: absolute;
    left: -9999px;
    top: -9999px;
    height: 1px;
    overflow: hidden;
}

/* Calendar + CSAT --------------------------------------------------------- */

.app_calendar {
    padding: 1rem;
}

.app_calendar_head,
.app_calendar_grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 4px;
}

.app_calendar_weekday {
    text-align: center;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--ia-text-secondary);
    padding: 0.3rem 0;
}

.app_calendar_cell {
    min-height: 5rem;
    border: 1px solid var(--ia-border-soft);
    border-radius: var(--ia-radius);
    padding: 0.3rem;
    background: rgba(255, 255, 255, 0.5);
}

.app_calendar_empty {
    background: transparent;
    border: 0;
}

.app_calendar_day {
    font-size: 0.78rem;
    color: var(--ia-text-secondary);
    margin-bottom: 0.2rem;
}

.app_calendar_event {
    display: block;
    font-size: 0.72rem;
    padding: 0.12rem 0.3rem;
    border-radius: 4px;
    margin-bottom: 2px;
    text-decoration: none;
    color: #ffffff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.app_calendar_event_due { background: #d70015; }
.app_calendar_event_not_before { background: #b25f00; }
.app_calendar_event_recurring { background: #0071e3; }
.app_calendar_event_asset { background: #1d7a3a; }

.app_csat_scale {
    display: flex;
    gap: 0.6rem;
    border: 0;
    padding: 0;
}

.app_csat_option {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    cursor: pointer;
    padding: 0.6rem 0.9rem;
    border: 1px solid var(--ia-border);
    border-radius: var(--ia-radius);
    font-weight: 600;
}

.app_csat_option:has(input:checked) {
    border-color: var(--ia-accent);
    background: rgba(0, 113, 227, 0.1);
    color: var(--ia-accent);
}

/* Reduced motion ---------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .app_tile {
        transition: none;
    }
}

/* Responsive tweaks ------------------------------------------------------- */

@media (max-width: 575.98px) {
    .auth_card {
        padding: 1.9rem 1.4rem 1.6rem;
    }

    .app_main {
        padding: 1.5rem 1rem 3rem;
    }

    .app_filter_bar {
        align-items: stretch;
    }

    .app_filter_field,
    .app_filter_field_grow {
        flex: 1 1 100%;
    }
}

/* Settings hub: collapsible topic cards --------------------------------- */

.app_section_heading {
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ia-text-secondary);
    margin: 1.75rem 0 0.85rem;
}

.app_section_heading:first-of-type {
    margin-top: 0.5rem;
}

/* Dashboard "quick access" heading: match the breathing room above the
   activity section below it (.app_activity_head margin-top). */
/* Second and further sections on one page (e.g. trash: tickets/users/contacts).
   Both classes in the selector so this beats .app_section_heading:first-of-type —
   a heading can be the page's first h2 in the DOM and still start a LATER
   section when the first heading sits inside a wrapper (checklist overview). */
.app_section_heading.app_section_heading_spaced {
    margin-top: 2.5rem;
}

.app_section_heading.app_quick_heading {
    margin-top: 2.75rem;
}

/* Second heading inside one detail card (e.g. sessions below language). */
.app_section_title_spaced {
    margin-top: 1.75rem;
}

.app_subsection_title {
    font-size: 0.95rem;
    font-weight: 600;
    margin: 1.25rem 0 0.6rem;
    color: var(--ia-text);
}

.settings_card {
    margin-bottom: 0.9rem;
    padding: 0;
    overflow: hidden;
}

.settings_card_summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 1.05rem 1.35rem;
    font-weight: 600;
    font-size: 1.03rem;
    user-select: none;
}

.settings_card_summary::-webkit-details-marker {
    display: none;
}

.settings_card_summary::marker {
    content: '';
}

.settings_card_toggle {
    display: inline-flex;
    color: var(--ia-accent);
    font-size: 1.05rem;
}

.settings_card_head_icon {
    color: var(--ia-accent);
    font-size: 1.15rem;
}

.settings_card_icon_open {
    display: none;
}

.settings_card[open] .settings_card_icon_open {
    display: inline-block;
}

.settings_card[open] .settings_card_icon_closed {
    display: none;
}

.settings_card_body {
    padding: 0.25rem 1.35rem 1.35rem;
}

.settings_nav_list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr));
    gap: 0.4rem;
}

.settings_nav_link {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.7rem 0.85rem;
    border-radius: var(--ia-radius);
    text-decoration: none;
    color: var(--ia-text);
    transition: background 0.15s ease;
}

.settings_nav_link:hover {
    background: var(--ia-surface-strong);
    color: var(--ia-text);
}

.settings_nav_link > .bi {
    font-size: 1.25rem;
    color: var(--ia-accent);
    flex: 0 0 auto;
}

.settings_nav_link_text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.settings_nav_link_title {
    font-weight: 500;
}

.settings_nav_link_desc {
    font-size: 0.8rem;
    color: var(--ia-text-secondary);
    line-height: 1.35;
}

/* Dashboard work surface ------------------------------------------------- */

/* Feed left, then "Was eilig ist" and "Meine nächsten Tickets" sharing the
   right side — each half of what the urgent block alone used to have. */
.app_dashboard_columns {
    display: grid;
    grid-template-columns: 1.4fr 0.5fr 0.5fr;
    gap: 1.1rem;
    margin-bottom: 1.5rem;
}

/* The two half-width blocks: without min-width the grid would hand the
   column with the longest unwrappable row the bigger share — the halves
   only stay halves when the content may shrink. Rows wrap like on mobile. */
.app_dashboard_columns > .app_dashboard_block {
    min-width: 0;
}

.app_dashboard_block_narrow .app_ticket_feed_item {
    flex-wrap: wrap;
    align-items: baseline;
    row-gap: 0.3rem;
}

.app_dashboard_block_narrow .app_ticket_feed_meta {
    flex: 0 1 auto;
    flex-wrap: wrap;
    min-width: 0;
}

/* "Meine nächsten Tickets" rows are only id + title: never wrap — the
   title's own ellipsis absorbs whatever does not fit on the line. */
.app_next_block .app_ticket_feed_item {
    flex-wrap: nowrap;
}

/* The block title doubles as the link to "all my tickets". */
.app_next_title_link {
    color: inherit;
    text-decoration: none;
}

.app_next_title_link:hover {
    color: var(--ia-accent);
    text-decoration: underline;
}

.app_dashboard_block {
    padding: 1.25rem 1.35rem 1.35rem;
}

/* Customer users only see the newest-tickets block ("Was eilig ist" is staff
   only) — a lone block spans the full row instead of leaving a gap. */
.app_dashboard_columns > .app_dashboard_block:only-child {
    grid-column: 1 / -1;
}

.app_dashboard_block_head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}

.app_dashboard_block_title {
    font-size: 1.05rem;
    font-weight: 600;
    margin: 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.app_dashboard_block_title .bi {
    color: var(--ia-accent);
}

.app_dashboard_block_link {
    font-size: 0.85rem;
    text-decoration: none;
    color: var(--ia-accent);
    white-space: nowrap;
}

/* Quick assignment: agent bubbles next to the heading, 2em away from it.
   Desktop only — dragging is pointless on touch devices (hidden below). */
.app_assign_targets {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-left: 2em;
    margin-right: auto;
}

.app_assign_target {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.25rem 0.7rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.05);
    border: 1px dashed transparent;
    color: var(--ia-text-secondary);
    font-size: 0.8rem;
    font-weight: 500;
    white-space: nowrap;
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.app_assign_target .bi {
    font-size: 0.9rem;
}

/* While a ticket is being dragged the targets show they accept a drop. */
.app_assign_targets.is_dragging .app_assign_target {
    border-color: var(--ia-border);
}

.app_assign_target.is_over {
    background: var(--ia-accent);
    border-color: var(--ia-accent);
    color: #ffffff;
}

.app_assign_target.is_busy {
    opacity: 0.6;
}

.app_assign_target.is_done {
    background: rgba(29, 122, 58, 0.16);
    color: var(--ia-success);
}

.app_assign_target.is_error {
    background: rgba(215, 0, 21, 0.12);
    color: var(--ia-danger);
}

/* Filter fields directly under the column headers ------------------------ */

/* Column titles and the filter row read as one block: no divider between
   them (the row below the filters still separates head from data). */
.app_column_title_row th {
    border-bottom-width: 0;
}

.app_column_filter_row td {
    padding: 0 0.6rem 0.55rem;
    border-bottom: 1px solid var(--ia-border);
    background: transparent;
}

.app_column_filter {
    width: 100%;
    min-width: 4.5rem;
    padding: 0.2rem 0.5rem;
    font-size: 0.8rem;
    font-weight: 400;
}

/* Warning line inside a dashboard block (e.g. users without client access). */
.app_dashboard_warning {
    align-items: baseline;
    color: var(--ia-danger);
    display: flex;
    font-size: 0.9rem;
    gap: 0.45rem;
    margin: 0 0 0.9rem;
}

.app_dashboard_warning a {
    color: inherit;
    font-weight: 600;
}

/* "No entries" line inside a table that stays visible because of filters. */
.app_table_empty {
    text-align: center;
    padding: 1.4rem 0.75rem;
}

/* The bin closes the row of targets and answers in red, not in accent. */
.app_assign_trash {
    margin-left: 0.35rem;
}

.app_assign_trash.is_over {
    background: var(--ia-danger);
    border-color: var(--ia-danger);
    color: #ffffff;
}

/* Ticket numbers become drag handles when targets are present. */
.app_assign_source {
    cursor: grab;
}

.app_assign_source:active {
    cursor: grabbing;
}

.app_dashboard_empty {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.5rem 0 0;
}

.app_ticket_feed {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.app_ticket_feed_item {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.6rem 0.4rem;
    border-top: 1px solid var(--ia-border-soft);
    border-radius: calc(var(--ia-radius) - 2px);
}

/* Match the table-row hover so the hovered entry is easy to follow. */
.app_ticket_feed_item:hover {
    background: rgba(0, 0, 0, 0.04);
}

.app_ticket_feed_item:first-child {
    border-top: 0;
}

.app_ticket_feed_id {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--ia-text);
}

.app_ticket_feed_title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-decoration: none;
    color: var(--ia-text);
}

.app_ticket_feed_title:hover {
    color: var(--ia-accent);
}

.app_ticket_feed_meta {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.82rem;
}

@media (max-width: 60rem) {
    .app_dashboard_columns {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 40rem) {
    /* Phones: feed rows wrap — id + full (wrapping) title first, the
       assignee bubble, status badge and client on the following line(s). */
    .app_ticket_feed_item {
        flex-wrap: wrap;
        align-items: baseline;
        row-gap: 0.4rem;
        padding: 0.7rem 0.4rem;
    }

    .app_ticket_feed_title {
        flex: 1 1 60%;
        white-space: normal;
        overflow: visible;
        overflow-wrap: anywhere;
    }

    .app_ticket_feed_meta {
        flex: 0 1 auto;
        flex-wrap: wrap;
        min-width: 0;
    }

    .app_ticket_feed_meta > * {
        min-width: 0;
        overflow-wrap: anywhere;
    }

    .app_dashboard_block_head {
        flex-wrap: wrap;
    }
}

/* Site footer (configurable HTML) --------------------------------------- */

.app_footer {
    margin-top: auto;
    padding: 1.5rem 1.25rem;
    color: var(--ia-text-secondary);
    font-size: 0.85rem;
}

/* The footer content floats in its own milky bubble: same surface, blur,
   border and shadow as the tiles (without their gradient top bar), hugging
   the content instead of spanning the page. */
.app_footer_inner {
    width: fit-content;
    max-width: 95%;
    margin: 0 auto;
    text-align: center;
    padding: 0.7rem 1.5rem;
    background-color: var(--ia-surface);
    -webkit-backdrop-filter: blur(5px) saturate(180%);
    backdrop-filter: blur(5px) saturate(180%);
    border: 1px solid var(--ia-border-soft);
    border-radius: var(--ia-radius-large);
    box-shadow: var(--ia-shadow-panel);
}

.app_footer_inner a {
    color: var(--ia-text-secondary);
}

.auth_footer {
    position: relative;
    z-index: 1;
    background: transparent;
}

.auth_body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.auth_body .auth_wrap {
    flex: 1 1 auto;
}

/* Dashboard welcome box (first session only, admin HTML). */
.app_welcome_box {
    padding: 1.25rem 1.5rem;
    margin-bottom: 1.25rem;
}

.app_activity_head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    /* More breathing room above the activity section (below quick access). */
    margin-top: 2.75rem;
}

/* Ticket option administration ------------------------------------------- */

.app_options_list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin-bottom: 1.5rem;
}

.app_option_row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.6rem 0.9rem;
    padding: 0.85rem 1.1rem;
}

.app_option_row.is_inactive {
    opacity: 0.6;
}

.app_option_field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.app_option_field_grow {
    flex: 1 1 14rem;
    min-width: 10rem;
}

.app_option_field_small {
    flex: 0 0 5.5rem;
}

.app_option_label {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ia-text-secondary);
}

.app_option_check {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.85rem;
    white-space: nowrap;
    padding-bottom: 0.5rem;
}

.app_option_actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
    padding-bottom: 0.15rem;
}

/* Dashboard admin note (auto-saving scratchpad) -------------------------- */

.app_admin_note_block {
    margin-top: 1.1rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--ia-border-soft);
}

.app_admin_note_head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.45rem;
}

.app_admin_note_label {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--ia-text-secondary);
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.app_admin_note_status {
    font-size: 0.78rem;
}

.app_admin_note {
    width: 100%;
    border: 1px solid var(--ia-border);
    border-radius: var(--ia-radius);
    background: rgba(255, 255, 255, 0.85);
    padding: 0.6rem 0.7rem;
    font-size: 0.9rem;
    line-height: 1.5;
    color: var(--ia-text);
    font-family: var(--ia-font);
    resize: vertical;
}

.app_admin_note:focus {
    outline: none;
    border-color: var(--ia-accent);
}

/* Recently changed (last edit within the configured window): a gradient
   frame (the card-top Design colours) gently pulses around the note. */
.app_admin_note_frame {
    border-radius: var(--ia-radius);
}

.app_admin_note_frame.is_recent {
    position: relative;
    padding: 3px;
    border-radius: calc(var(--ia-radius) + 3px);
    isolation: isolate;
}

.app_admin_note_frame.is_recent::before {
    content: "";
    position: absolute;
    z-index: 0;
    inset: 0;
    border-radius: inherit;
    background: var(--card-top-gradient, linear-gradient(90deg, #7A509E 0%, #68B9B9 100%));
    animation: app_note_pulse 1.8s ease-in-out infinite;
}

@keyframes app_note_pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.3; }
}

.app_admin_note_frame.is_recent .app_admin_note {
    position: relative;
    z-index: 1;
    border: 0;
    display: block;
    width: 100%;
}

@media (prefers-reduced-motion: reduce) {
    .app_admin_note_frame.is_recent::before {
        animation: none;
    }
}

/* Copy-to-clipboard controls (recoverable links / passwords) ------------- */

.app_copy_row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.75rem;
    margin-top: 0.4rem;
    flex-basis: 100%;
}

.app_copy_btn {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    border: 1px solid var(--ia-border-soft);
    background: rgba(255, 255, 255, 0.7);
    color: var(--ia-text);
    border-radius: var(--ia-radius);
    padding: 0.2rem 0.55rem;
    font-size: 0.78rem;
    cursor: pointer;
}

.app_copy_btn:hover {
    border-color: var(--ia-border);
}

.app_copy_btn.is_copied {
    color: var(--ia-success);
    border-color: var(--ia-success);
}

.app_copy_btn_icon {
    padding: 0.2rem 0.4rem;
}

.app_copy_secret {
    font-size: 0.8rem;
    color: var(--ia-text-secondary);
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.app_copy_secret code {
    background: rgba(60, 60, 67, 0.08);
    padding: 0.1rem 0.4rem;
    border-radius: 6px;
    color: var(--ia-text);
    font-size: 0.82rem;
}

.app_copy_legacy {
    font-size: 0.78rem;
}

/* Inline "view public" link next to a label ------------------------------ */

.app_inline_link {
    font-size: 0.85rem;
    font-weight: 400;
    margin-left: 0.4rem;
    white-space: nowrap;
}

/* Breadcrumbs (subtle, above the page content) --------------------------- */

.app_breadcrumbs {
    margin: 0 0 1rem;
}

.app_breadcrumb_list {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
    margin: 0;
    padding: 0;
    font-size: 0.8rem;
    color: var(--ia-text-secondary);
}

.app_breadcrumb_item {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.app_breadcrumb_item + .app_breadcrumb_item::before {
    content: "\203A";
    color: var(--ia-border);
}

.app_breadcrumb_item a {
    color: var(--ia-text-secondary);
    text-decoration: none;
}

.app_breadcrumb_item a:hover {
    color: var(--ia-accent);
    text-decoration: underline;
}

.app_breadcrumb_item span[aria-current] {
    color: var(--ia-text);
    font-weight: 500;
}

/* Header search box ------------------------------------------------------ */

.app_nav_search {
    display: flex;
    align-items: stretch;
    flex: 1 1 16rem;
    max-width: 22rem;
    min-width: 0;
    margin: 0 0.5rem;
    border: 1px solid var(--ia-border-soft);
    border-radius: var(--ia-radius);
    background: rgba(255, 255, 255, 0.7);
    overflow: hidden;
}

/* Scope select as a button-styled chip: uses the configurable button
   gradient (Design → Button-Farbverlauf), solid button colour as fallback. */
.app_nav_search_scope {
    border: 0;
    background-color: var(--ia-button);
    background-image: var(--ia-button-image, none);
    color: #ffffff;
    font-size: 0.8rem;
    font-weight: 500;
    padding: 0 0.6rem;
    max-width: 8rem;
    border-radius: calc(var(--ia-radius) - 1px) 0 0 calc(var(--ia-radius) - 1px);
    cursor: pointer;
}

/* The global focus ring sits OUTSIDE the element, and the search box clips
   anything overflowing — so of that ring only the right-hand sliver survived,
   which read as a stray violet line next to the green button. A ring drawn
   inside the button cannot be clipped and keeps keyboard focus visible. */
.app_nav_search_scope:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.85);
}

/* Native dropdown list stays readable (dark text on white). */
.app_nav_search_scope option {
    color: var(--ia-text);
    background: #ffffff;
}

.app_nav_search_input {
    border: 0;
    background: transparent;
    padding: 0.4rem 0.5rem;
    font-size: 0.9rem;
    flex: 1 1 auto;
    min-width: 0;
    color: var(--ia-text);
}

.app_nav_search_input:focus {
    outline: none;
}

.app_nav_search_button {
    border: 0;
    background: transparent;
    color: var(--ia-accent);
    padding: 0 0.7rem;
    cursor: pointer;
}

/* Compact magnifier that replaces the full search field on mobile; it links
   straight to the search page. Hidden on desktop (the full field is shown). */
.app_nav_search_link {
    display: none;
    align-items: center;
    justify-content: center;
    padding: 0.4rem 0.5rem;
    border-radius: var(--ia-radius);
    color: var(--ia-text-secondary);
    font-size: 1.2rem;
    line-height: 1;
    text-decoration: none;
}

.app_nav_search_link:hover {
    background: rgba(0, 0, 0, 0.045);
    color: var(--ia-accent);
}

/* Search: dashboard hero + results-page form + grouped results ----------- */

.app_search_form {
    display: flex;
    gap: 0.6rem;
    align-items: stretch;
    flex-wrap: wrap;
    padding: 0.65rem;
    margin-bottom: 1.5rem;
}

.app_search_scope {
    flex: 0 0 auto;
    max-width: 12rem;
}

.app_search_input {
    flex: 1 1 18rem;
    min-width: 10rem;
}

.app_search_section {
    margin-bottom: 1.5rem;
}

.app_search_results {
    list-style: none;
    margin: 0;
    padding: 0.3rem 0;
}

.app_search_result {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.6rem 1rem;
    border-top: 1px solid var(--ia-border-soft);
}

.app_search_result:first-child {
    border-top: 0;
}

.app_search_link {
    display: inline-flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.5rem;
    text-decoration: none;
    color: var(--ia-text);
}

.app_search_link:hover .app_search_title {
    text-decoration: underline;
}

.app_search_title {
    font-weight: 500;
}

.app_search_meta {
    margin-left: auto;
    font-size: 0.85rem;
}

.app_search_empty {
    padding: 0.3rem 0.2rem;
}

/* Ticket detail: full-width history at the bottom of the page ------------ */

.app_timeline_section {
    margin-top: 1.25rem;
}

/* Ticket detail: single sticky save bar for the combined form ------------ */

.app_save_bar {
    position: sticky;
    bottom: 0.75rem;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 1.25rem;
    padding: 0.75rem 1.1rem;
    background: var(--ia-surface-strong);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    backdrop-filter: blur(20px) saturate(180%);
    border: 1px solid var(--ia-border-soft);
    border-radius: var(--ia-radius-large);
    box-shadow: var(--ia-shadow-panel);
}

.app_save_bar_hint {
    margin-right: auto;
    font-size: 0.85rem;
}

/* Time entry inside the save bar: label, "hh:mm" field, booked total. */
.app_save_bar_field {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.app_save_bar_field .form-label {
    margin: 0;
    font-size: 0.85rem;
    white-space: nowrap;
}

.app_save_bar_time {
    width: 5.5rem;
    text-align: center;
}

.app_save_bar_total {
    white-space: nowrap;
}

.app_save_bar_check {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    padding: 0;
    white-space: nowrap;
}

.app_save_bar_check .form-check-input {
    margin: 0;
    float: none;
}

.app_save_bar_check .form-check-label {
    font-size: 0.85rem;
}

@media (max-width: 40rem) {
    .app_save_bar_hint {
        display: none;
    }
    .app_save_bar .app_button_primary {
        width: 100%;
    }
    .app_save_bar_field {
        width: 100%;
    }
    .app_save_bar_time {
        flex: 1;
    }
}

/* Mobile breathing room ---------------------------------------------------
   On phones the page header used to squeeze title, primary action and the
   back link into a single row (leaving ~10px between the buttons), and the
   queue chips sat 7px apart. Declared last so these win over the base rules
   regardless of source order. */
@media (max-width: 40rem) {
    /* Title on its own line, actions below it. */
    .app_page_header {
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
    }

    .app_toolbar_actions,
    .app_page_header .app_action_bar {
        flex-wrap: wrap;
        gap: 0.6rem 0.85rem;
    }

    /* Everything below the page header used to touch it. On a wide screen the
       header's buttons sit NEXT to the title, so whatever follows lands under
       the heading and its spacing carries them. Stacked on a phone the button
       row drops straight onto the next element — the chip bar on the ticket
       list, the toolbar on the client list, the filter card on the statistics
       page. One rule instead of patching each of them. */
    .app_page_header {
        margin-bottom: 1rem;
    }

    /* Toolbar filters on a phone: a two-column grid instead of a wrapping row.
       The search spans the full width, the two selects share the next line,
       the buttons the one after. The desktop max-width of 13rem left every
       control stranded at some arbitrary fraction of the screen. */
    .app_toolbar_filters {
        display: grid;
        /* The status select carries long labels, the page size only "100". */
        grid-template-columns: 2fr 1fr;
        gap: 0.6rem;
        align-items: stretch;
    }

    .app_toolbar_filters > .form-control,
    .app_toolbar_filters > .form-select,
    .app_toolbar_filters > .btn,
    .app_toolbar_filters > .app_autocomplete_wrap {
        max-width: none;
        width: 100%;
        margin: 0;
    }

    /* Free text, autocompletes and buttons get a line of their own: the first
       two hold the longest values, and a button label like "Suche
       zurücksetzen" simply does not fit into a half column. */
    .app_toolbar_filters > .form-control[type="search"],
    .app_toolbar_filters > .app_autocomplete_wrap,
    .app_toolbar_filters > .btn {
        grid-column: 1 / -1;
    }

    /* Filter chips: more room between rows and columns. */
    .app_queue_bar {
        gap: 0.55rem 0.75rem;
    }

    /* Button rows inside cards and forms. */
    .app_action_bar,
    .app_detail_actions,
    .app_form_actions,
    .app_add_row,
    .app_filter_actions {
        gap: 0.6rem 0.85rem;
    }

    /* Row of small icon buttons in table cells (edit/delete). */
    .app_table_actions_col .app_inline_form,
    .app_table_actions_col .app_icon_link {
        margin-left: 0.15rem;
    }
}

/* Quick assignment is a desktop-only affordance: hide the drop targets on
   phones/tablets where dragging a ticket number is not practical. */
@media (max-width: 60rem) {
    .app_assign_targets {
        display: none;
    }

    .app_assign_source {
        cursor: pointer;
    }
}

/* "Was eilig ist": the ticket number and the assignee bubble scream red —
   both selectors doubled with :hover so the badge/link hover rules that sit
   earlier in the file cannot fade the urgency away. */
.app_urgent_id,
.app_urgent_id:hover {
    color: var(--ia-danger);
}

.app_urgent_assignee,
.app_urgent_assignee:hover {
    background: var(--ia-danger);
    border-color: var(--ia-danger);
    color: #fff;
}

/* Inline title editor on the ticket detail (pencil next to the headline). */
.app_title_edit {
    margin: 0.35rem 0 0.5rem;
    max-width: 46rem;
}

.app_title_edit .form-control {
    font-size: 1.15rem;
    font-weight: 600;
}

/* Favourite star in the priority column: greyed outline until clicked,
   then solid gold. One shared flag per ticket. */
.app_fav_star {
    background: none;
    border: none;
    padding: 0 0 0 0.45rem;
    cursor: pointer;
    color: var(--ia-text-secondary);
    opacity: 0.55;
    font-size: 0.95rem;
    vertical-align: middle;
    line-height: 1;
}

.app_fav_star:hover {
    opacity: 1;
    color: #d4a72c;
}

.app_fav_star.is_active {
    opacity: 1;
    color: #f2b90d;
}

/* Small solid star behind the id in "Meine nächsten Tickets". */
.app_fav_mini {
    color: #f2b90d;
    font-size: 0.8rem;
    flex: 0 0 auto;
}

/* Initials chips behind the "Bearbeiter" label (ticket forms): one click
   assigns that colleague. Deliberately tiny — a hint, not a toolbar. */
.app_assign_label_row {
    display: flex;
    align-items: baseline;
    gap: 0.45rem;
    flex-wrap: wrap;
}

.app_assign_shortcuts {
    display: inline-flex;
    gap: 0.25rem;
    flex-wrap: wrap;
}

.app_assign_shortcut {
    font-size: 0.62rem;
    font-weight: 600;
    line-height: 1;
    padding: 0.22rem 0.4rem;
    border-radius: 999px;
    border: 1px solid var(--ia-border-soft);
    background: var(--ia-surface-strong);
    color: var(--ia-text-secondary);
    cursor: pointer;
}

.app_assign_shortcut:hover {
    color: #fff;
    background: var(--ia-accent);
    border-color: var(--ia-accent);
}

/* Background column in the user list: the name opens the picture in the
   lightbox — styled as a quiet text button, not a big control. */
.app_background_name_button {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: inherit;
    cursor: zoom-in;
    white-space: nowrap;
}

.app_background_name_button:hover {
    color: var(--ia-accent);
    text-decoration: underline;
}

/* ============================================================ Checklists
   Settings → Checklists: template editor rows and the tick-off view. */

/* Section heading with the add button beside it. The row owns the spacing
   (above the row, below towards the table); the heading's own margins are
   zeroed so the button centers cleanly against the text. */
.app_checklist_section_head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin: 0.75rem 0 1rem;
}

.app_checklist_section_head .app_section_heading {
    margin: 0;
}

/* One editor row: group, short text, long text, order, assignee. The long
   description gets the widest column — it carries the actual instructions. */
.app_checklist_editor {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
}

.app_checklist_row {
    display: grid;
    grid-template-columns: 0.7fr 1fr 1.4fr 5.5rem 1fr;
    gap: 0.6rem 0.85rem;
    align-items: start;
    border: 1px solid var(--ia-border-soft);
    border-radius: var(--ia-radius);
    padding: 0.75rem;
    margin: 0;
}

.app_checklist_row .app_field {
    margin: 0;
}

.app_checklist_grow_hint {
    margin: 0 0 1rem;
    font-size: 0.85rem;
}

/* General notes from the template, shown above the tick-off list. */
.app_checklist_notes {
    margin: 0 0 1.1rem;
    padding: 0.6rem 0.9rem;
    border-left: 3px solid var(--ia-accent);
    background: rgba(0, 0, 0, 0.03);
    border-radius: 0 var(--ia-radius) var(--ia-radius) 0;
}

/* Progress + actions above the tick-off list. */
.app_checklist_toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.app_checklist_toolbar_actions {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.app_checklist_progress_line {
    margin: 0;
    font-weight: 600;
    color: var(--ia-accent);
}

/* Progress cell in the overview table; green once everything is ticked. */
.app_checklist_progress {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-variant-numeric: tabular-nums;
}

.app_checklist_progress.is_complete {
    color: var(--ia-success);
    font-weight: 600;
}

/* The tick-off list itself. */
.app_check_list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.app_check_item {
    border: 1px solid var(--ia-border-soft);
    border-radius: var(--ia-radius);
    padding: 0.75rem 0.9rem;
}

.app_check_item.is_done {
    background: rgba(29, 122, 58, 0.06);
    border-color: rgba(29, 122, 58, 0.25);
}

.app_check_main {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    cursor: pointer;
    margin: 0;
}

.app_check_main .form-check-input {
    margin-top: 0.2rem;
    flex-shrink: 0;
}

.app_check_short {
    font-weight: 600;
}

.app_check_item.is_done .app_check_short {
    text-decoration: line-through;
    color: var(--ia-text-secondary);
}

.app_check_long {
    margin: 0.4rem 0 0 2rem;
    color: var(--ia-text-secondary);
    white-space: pre-line;
}

.app_check_meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1.25rem;
    margin: 0.4rem 0 0 2rem;
    font-size: 0.85rem;
    color: var(--ia-text-secondary);
}

.app_check_meta:empty {
    display: none;
}

.app_check_done {
    color: var(--ia-success);
    font-weight: 600;
}

.app_check_assignee {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

/* Group heading inside the tick-off list. */
.app_check_group {
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ia-text-secondary);
    margin-top: 0.9rem;
}

.app_check_group:first-child {
    margin-top: 0;
}

/* Comparison matrix: items as rows, projects as columns. The first column
   sticks while the project columns scroll on a narrow screen. */
.app_compare_table th:first-child,
.app_compare_table td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--ia-surface-strong);
    min-width: 11rem;
}

.app_compare_col {
    min-width: 8rem;
}

.app_compare_client {
    display: block;
    font-weight: 400;
    font-size: 0.8rem;
    color: var(--ia-text-secondary);
}

.app_compare_cell {
    text-align: center;
}

.app_compare_done {
    color: var(--ia-success);
    font-size: 1.1rem;
}

.app_compare_open {
    color: var(--ia-text-secondary);
    font-size: 1.05rem;
}

.app_compare_group_row td {
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ia-text-secondary);
    background: rgba(0, 0, 0, 0.03);
}

.app_compare_footer td {
    font-weight: 600;
    border-top: 2px solid var(--ia-border-soft);
}

/* On a phone the editor row stacks; the order field keeps a narrow lane
   and the assignee takes the rest of that line. */
@media (max-width: 48rem) {
    .app_checklist_row {
        grid-template-columns: 6rem 1fr;
    }

    .app_checklist_cell_group,
    .app_checklist_cell_short,
    .app_checklist_cell_long {
        grid-column: 1 / -1;
    }

    .app_checklist_cell_sort {
        grid-column: 1;
    }

    .app_checklist_cell_assignee {
        grid-column: 2;
    }

    .app_check_long,
    .app_check_meta {
        margin-left: 0;
    }
}

/* ===== Safe: end-to-end encrypted data hand-over ===================== */

/* Admin list: expired safes show a red date + badge. */
.app_safe_expired {
    color: var(--ia-danger);
    font-weight: 600;
}

/* Create form: password field with the generator button beside it. The
   row wraps, so on narrow screens the button drops to its own line
   instead of squeezing (and never breaks inside itself). */
.app_safe_password_row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
}

.app_safe_password_row .form-control {
    font-family: var(--bs-font-monospace, monospace);
    flex: 1 1 14rem;
    width: auto;
}

/* Colours come from the primary-button branding (gradient like the other
   buttons); this class only keeps the label on one line. */
.app_safe_genpw {
    white-space: nowrap;
    flex: 0 0 auto;
}

/* Shared status line on the create page and the public retrieval page. */
.app_safe_status {
    margin: 0.75rem 0 0;
    font-weight: 600;
}

.app_safe_status.is_error {
    color: var(--ia-danger);
}

/* Public retrieval page. */
.app_safe_step_info {
    margin-bottom: 1rem;
}

.app_safe_pin_input {
    font-size: 1.4rem;
    letter-spacing: 0.4rem;
    text-align: center;
    font-family: var(--bs-font-monospace, monospace);
}

.app_safe_restart {
    margin: 0.75rem 0 0;
    text-align: center;
    font-size: 0.85rem;
}

.app_safe_result {
    margin-top: 1rem;
}

.app_safe_result_heading {
    font-size: 1rem;
    font-weight: 600;
    margin: 1rem 0 0.5rem;
}

/* Decrypted text: preserve line breaks, never overflow the card. */
.app_safe_secret {
    white-space: pre-wrap;
    word-break: break-word;
    background: rgba(0, 0, 0, 0.06);
    border-radius: var(--ia-radius-small, 0.5rem);
    padding: 0.75rem;
    max-height: 40vh;
    overflow: auto;
}

.app_safe_files {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.4rem;
}

.app_safe_files a {
    word-break: break-word;
}

/* Save-now reminder after a successful decryption. */
.app_safe_success_note {
    font-weight: 600;
}

/* Eye toggle beside the text heading; the blur hides the secret from
   onlookers without collapsing the layout. */
.app_safe_blur_btn {
    border: 0;
    background: none;
    padding: 0 0.25rem;
    margin-left: 0.35rem;
    color: inherit;
    cursor: pointer;
    vertical-align: middle;
}

.app_safe_blur_btn:hover {
    color: var(--ia-accent);
}

.app_safe_secret.is_blurred {
    filter: blur(7px);
    user-select: none;
}

/* Copy feedback on the safe heading buttons (same flash as app_copy_btn). */
.app_safe_blur_btn.is_copied {
    color: var(--ia-success);
}

/* ===== Checks: website monitoring ==================================== */

/* Red row while a check failed within 48h (until the reset button). */
.app_check_row_alert > * {
    background: rgba(215, 0, 21, 0.07);
}

.app_check_domain_alert {
    color: var(--ia-danger);
    font-weight: 600;
}

.app_check_row_paused > * {
    opacity: 0.55;
}

.app_check_paused_badge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.1rem 0.5rem;
    border-radius: 20px;
    background: rgba(0, 0, 0, 0.08);
    font-size: 0.75rem;
    color: var(--ia-text-muted, #6e6e73);
}

.app_check_ok_count {
    font-weight: 600;
}

.app_check_ok_count.is_all_ok {
    color: var(--ia-success);
}

.app_check_ok_count.is_alert {
    color: var(--ia-danger);
}

/* Domain form: one grid row per URL check. */
.app_check_rows {
    display: grid;
    gap: 0.75rem;
}

.app_check_row {
    display: grid;
    /* path | check type | detail | remove (tight) | state value (roomy) */
    grid-template-columns: 1fr 1fr 1fr 2.25rem minmax(6.5rem, 11rem);
    gap: 0.5rem 1rem;
    align-items: end;
    border: 0;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--ia-border-soft, rgba(0, 0, 0, 0.08));
    margin: 0;
}

.app_check_row [data-check-detail][hidden] {
    display: none;
}

.app_check_cell_state {
    padding-bottom: 0.55rem;
    font-size: 0.85rem;
    line-height: 1.3;
    word-break: break-word;
}

.app_check_state {
    display: inline-flex;
    align-items: baseline;
    gap: 0.3rem;
}

.app_check_state.is_warn {
    color: #b8730a;
}

.app_check_state.is_ok {
    color: var(--ia-success);
}

.app_check_state.is_fail {
    color: var(--ia-danger);
}

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

    .app_check_cell_path {
        grid-column: 1 / -1;
    }
}

/* ===== Settings sub-menu (self-service header dropdown) ============== */

.app_nav_links li {
    position: relative;
}

.app_nav_caret {
    font-size: 0.65rem;
    margin-left: 0.15rem;
}

/* Desktop: opaque card below the settings entry, opened by hover/focus. */
.app_nav .app_nav_dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 15rem;
    background: var(--ia-bg);
    border: 1px solid var(--ia-border-soft, rgba(0, 0, 0, 0.12));
    border-radius: var(--ia-radius, 12px);
    box-shadow: 0 14px 34px rgba(0, 0, 0, 0.16);
    padding: 0.4rem;
    z-index: 220;
}

.app_nav .app_nav_links li:hover > .app_nav_dropdown,
.app_nav .app_nav_links li:focus-within > .app_nav_dropdown {
    display: block;
}

.app_nav_child {
    display: flex;
    width: 100%;
}

/* Mobile overlay: no hover — the sub-entries are always visible,
   indented under the settings entry. Scoped selector so it beats the
   desktop base rule regardless of source order. */
@media (max-width: 60rem) {
    .app_nav .app_nav_dropdown {
        display: block;
        position: static;
        min-width: 0;
        background: none;
        border: 0;
        box-shadow: none;
        padding: 0 0 0 1.6rem;
    }

    .app_nav_caret {
        display: none;
    }
}

/* Settings → menu items editor. */
.app_menu_rows {
    display: grid;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.app_menu_row {
    display: grid;
    grid-template-columns: 4rem 1fr 10rem 1.4fr 6rem 6rem;
    gap: 0.5rem 0.75rem;
    align-items: end;
    border: 0;
    margin: 0;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--ia-border-soft, rgba(0, 0, 0, 0.08));
}

.app_menu_cell_active,
.app_menu_cell_newtab {
    text-align: center;
}

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

    .app_menu_cell_link {
        grid-column: 1 / -1;
    }
}

/* Grid hygiene for the row editors (fr columns need a shrink floor). */
.app_check_cell_type,
.app_check_cell_detail,
.app_menu_cell_sort {
    min-width: 0;
}

.app_nav_has_children {
    position: relative;
}

/* Monitor stat tiles above the domain table. */
.app_monitor_stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.app_monitor_stat_tile {
    padding: 1.1rem 1.35rem;
    min-width: 0;
}

.app_monitor_percent {
    font-size: 2.1rem;
    font-weight: 700;
    line-height: 1.1;
    margin: 0.5rem 0 0.25rem;
}

.app_monitor_percent.is_good {
    color: var(--ia-success);
}

.app_monitor_percent.is_bad {
    color: var(--ia-danger);
}

.app_monitor_stat_detail {
    margin: 0;
    font-size: 0.85rem;
}

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

/* Small external-link icon behind the domain in the monitor list. */
.app_check_open_link {
    margin-left: 0.35rem;
    font-size: 0.85rem;
    vertical-align: baseline;
}

/* Monitor stats grew a fourth tile (customer domain import). */
.app_monitor_stats {
    grid-template-columns: repeat(4, 1fr);
}

.app_monitor_import_tile {
    display: block;
    color: inherit;
    text-decoration: none;
}

.app_monitor_import_tile:hover {
    color: inherit;
    transform: translateY(-2px);
}

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

/* Importer: one row per candidate domain. */
.app_import_list {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: grid;
    gap: 0.35rem;
}

.app_import_row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0.6rem;
    border-radius: var(--ia-radius, 12px);
    cursor: pointer;
}

.app_import_row:hover {
    background: rgba(0, 0, 0, 0.04);
}

.app_import_domain {
    font-weight: 600;
}

.app_import_clients {
    font-size: 0.85rem;
}

.app_import_actions {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}

/* Failing check types in the monitor list, kept short and red. */
.app_check_fail_types {
    color: var(--ia-danger);
    font-weight: 600;
    font-size: 0.85rem;
}

/* https check row: static hint instead of an input field. */
.app_check_https_hint {
    margin: 0;
    font-size: 0.85rem;
    padding-bottom: 0.55rem;
}

/* Quick-ticket icon below the failing check labels. */
.app_check_ticket_row {
    margin-top: 0.3rem;
}

.app_check_ticket_link {
    font-size: 0.95rem;
}

/* Explicit add button + per-row remove in the check editor. */
.app_check_add_button {
    margin-top: 0.75rem;
}

.app_check_cell_remove {
    padding-bottom: 0.45rem;
    text-align: right;
}

/* Five tiles now — let the grid distribute them itself. */
.app_monitor_stats {
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}

.app_monitor_whitelist_area {
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.85rem;
}

.app_monitor_whitelist_save {
    margin-top: 0.5rem;
}

/* Page-size check: warning (orange) is a third state next to ok/fail. */
.app_check_row_warn > * {
    background: rgba(184, 115, 10, 0.08);
}

.app_check_warn_types {
    margin-top: 0.3rem;
    color: #b8730a;
    font-weight: 600;
    font-size: 0.85rem;
}

.app_check_state.is_warn {
    color: #b8730a;
}

/* Two KB inputs (min – max) inside the page-size detail cell. */
.app_check_size_inputs {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.app_check_size_inputs .form-control {
    min-width: 0;
}

.app_check_size_sep {
    color: var(--ia-text-muted, #6e6e73);
}

/* Inline comment field in the monitor list. */
.app_check_comment_cell {
    min-width: 12rem;
}

.app_check_comment {
    font-size: 0.85rem;
    padding: 0.25rem 0.5rem;
    resize: vertical;
}

.app_check_comment.is_saved {
    border-color: var(--ia-success);
    box-shadow: 0 0 0 2px rgba(29, 122, 58, 0.18);
}

.app_check_comment.is_error {
    border-color: var(--ia-danger);
}

/* Resolved IP under the domain in the monitor list. */
.app_check_ip {
    font-size: 0.75rem;
    color: var(--ia-text-muted, #6e6e73);
    margin-top: 0.15rem;
}

.app_check_ip.is_kas {
    color: var(--ia-success);
    font-weight: 600;
}

/* Inline check-frequency dropdown in the monitor list. */
.app_check_frequency {
    font-size: 0.85rem;
    padding: 0.2rem 1.6rem 0.2rem 0.5rem;
    width: auto;
    min-width: 6.5rem;
}

.app_check_frequency.is_saved {
    border-color: var(--ia-success);
    box-shadow: 0 0 0 2px rgba(29, 122, 58, 0.18);
}

.app_check_frequency.is_error {
    border-color: var(--ia-danger);
}

/* Public read-only monitor status page (customer token link). */
.app_monitor_public {
    max-width: 760px;
}

.app_monitor_public_domain {
    font-weight: 600;
    font-size: 1.05rem;
    margin: 0.25rem 0 0;
    word-break: break-all;
}

.app_monitor_public_warn {
    background: rgba(184, 115, 10, 0.12);
    color: #8a5600;
    border: 1px solid rgba(184, 115, 10, 0.35);
}

.app_monitor_public_badge_warn {
    background: rgba(184, 115, 10, 0.14);
    color: #b8730a;
}

.app_monitor_public_table th,
.app_monitor_public_table td {
    vertical-align: middle;
}

.app_monitor_public_result {
    word-break: break-word;
    font-size: 0.9rem;
}

.app_monitor_public_stamp {
    margin-top: 0.75rem;
    text-align: center;
    font-size: 0.85rem;
}

/* Reset button hidden when there is no active alert (or after reset). */
.app_check_reset_btn.is_hidden {
    display: none;
}

/* Signatures ("Unterschriften") ------------------------------------------- */

.app_form_padded {
    padding: 1.5rem;
}

.app_code_area {
    font-family: ui-monospace, "SFMono-Regular", "Consolas", monospace;
    font-size: 0.85rem;
    line-height: 1.45;
}

.app_field_check {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.app_check_inline {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
}

.app_check_inline input {
    width: 1.05rem;
    height: 1.05rem;
}

/* Drawing pad for a signature (admin "our data" + public sign page). */
.app_sign_pad {
    max-width: 560px;
}

.app_sign_canvas {
    width: 100%;
    height: auto;
    aspect-ratio: 560 / 180;
    background: #ffffff;
    border: 1px solid var(--ia-border);
    border-radius: var(--ia-radius);
    touch-action: none;
    cursor: crosshair;
    display: block;
}

.app_sign_pad_actions {
    margin-top: 0.5rem;
}

/* One signatory block on the public sign page: name + drawn signature. */
.app_sign_signer {
    border: 1px solid var(--ia-border);
    border-radius: var(--ia-radius);
    padding: 0.9rem 1rem 1rem;
    margin: 0 0 1.1rem;
}

.app_sign_signer_title {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--ia-text-secondary, #444);
    width: auto;
    padding: 0;
    margin-bottom: 0.7rem;
}

/* Mandatory notice the signer must acknowledge before signing. */
.app_sign_notice {
    border: 1px solid rgba(199, 127, 10, 0.55);
    background: rgba(211, 139, 0, 0.09);
    border-radius: var(--ia-radius);
    padding: 0.9rem 1rem;
    margin: 0 0 1.3rem;
}

.app_sign_notice_head {
    font-weight: 600;
    color: #b5730a;
    margin-bottom: 0.4rem;
}

.app_sign_notice_body {
    white-space: pre-wrap;
    margin-bottom: 0.75rem;
}

.app_sign_notice_ack {
    font-weight: 500;
}

/* Feedbacks: "already invited" warning under the recipient picker. Amber by
   default; red once the two-year cool-off blocks a fresh invitation. */
.app_feedback_warning {
    margin: 0.8rem 0 0;
    color: #b5730a;
    font-weight: 500;
    white-space: pre-wrap;
}

.app_feedback_warning_blocked {
    border-color: rgba(200, 46, 46, 0.55);
    background: rgba(200, 46, 46, 0.09);
    color: #b02a2a;
    font-weight: 600;
}

/* Public signing page: wider than the default auth card, but tighter padding
   so the content is not lost in whitespace. */
.app_sign_public {
    max-width: 660px;
    padding: 1.6rem 1.7rem 1.5rem;
    text-align: left;
}

/* On this page the signature pad fills the card width (no big right gap). */
.app_sign_public .app_sign_pad {
    max-width: 100%;
}

/* Custom fields on the create page (add/remove). */
.app_sig_fields {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.app_sig_field_num {
    font-family: ui-monospace, "SFMono-Regular", "Consolas", monospace;
    font-size: 0.78rem;
    color: var(--ia-text-muted, #6e6e73);
    margin-bottom: 0.2rem;
}

.app_sig_field_row {
    display: flex;
    gap: 0.5rem;
    align-items: flex-start;
}

.app_sig_field_row textarea {
    flex: 1;
    min-width: 8rem;
}

.app_sig_field_type {
    flex: 0 0 auto;
    width: auto;
    min-width: 9.5rem;
    align-self: flex-start;
}

@media (max-width: 560px) {
    .app_sig_field_row {
        flex-wrap: wrap;
    }
    .app_sig_field_type {
        min-width: 8rem;
    }
}

.app_sig_field_add {
    margin-top: 0.6rem;
}

/* Read-only answers shown on a signed contract. */
.app_sign_answers {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin: 1rem 0 0.5rem;
}

.app_sign_answer {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.app_sign_answer_label {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--ia-text-secondary, #444);
}

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

.app_sign_contract {
    max-height: 46vh;
    overflow-y: auto;
    padding: 1rem 1.15rem;
    margin: 1rem 0 1.35rem;
    background: rgba(255, 255, 255, 0.55);
    border: 1px solid var(--ia-border);
    border-radius: var(--ia-radius);
}

@media (prefers-color-scheme: dark) {
    .app_sign_contract {
        background: rgba(0, 0, 0, 0.2);
    }
}

.app_sign_blank {
    display: inline-block;
    min-width: 8rem;
    border-bottom: 1px solid var(--ia-text-muted, #6e6e73);
}

.app_sign_done {
    margin-top: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    align-items: flex-start;
}
