/* ====================================================================
 * Precepto admin — legacy app.css
 *
 * After the Fase 3 re-skin, this file is now scoped to:
 *   - Brand color tokens (--brand-*) consumed by leftover *.razor.css
 *   - Dark-mode overrides for Syncfusion components (theme switch is
 *     planned post-Fase 4; keep the rules ready)
 *   - Cross-cutting Syncfusion grid/dialog/pager polish
 *   - GlobalSearch result list classes (rendered via RenderTreeBuilder
 *     so they aren't scoped to a .razor.css)
 *   - Blazor framework hooks (.text-muted, .validation-*, error-boundary)
 *
 * Removed during Fase 4 cleanup: .page-header*, .skeleton/.skel-*,
 * .metric-card, .dash-*, .profile-card, .integration-*, .empty-state,
 * .grid-skeleton, .btn-primary (Bootstrap), .darker-border-checkbox,
 * .content (pages migrated to kt-card), .loading (covered by shim).
 * ==================================================================== */

/* ====================================================================
 * Active sidebar menu item — Precepto brand styling
 *
 * Blazor's <NavLink ActiveClass="kt-menu-item-active"> adds the class
 * to the rendered <a>. We fill the link with the brand colour so the
 * selected route is obvious at a glance.
 *
 * Light mode: navy fill, white text/icons (the classic "primary" look).
 * Dark mode: invert — warm parchment fill with navy text. Reads like
 * a hand-stamp on the dark surface and keeps the gold ochre as a focus
 * ring without overloading the menu with brand colour.
 * ==================================================================== */

.kt-menu-item-active .kt-menu-link {
    background: var(--primary);
    border-radius: var(--radius);
    /* Gold 3px stripe on the inline-start edge — same affordance as the
       collapsed-rail active marker, now visible in expanded mode too. */
    box-shadow: inset 3px 0 0 0 var(--ring);
}

.kt-menu-item-active .kt-menu-link .kt-menu-icon,
.kt-menu-item-active .kt-menu-link .kt-menu-title {
    color: var(--primary-foreground) !important;
}

/* Stronger active-state weight — label jumps from 500 to 600 when the
   route is current, matching the wordmark's CEPTO bold treatment. */
.kt-menu-item-active .kt-menu-link .kt-menu-title {
    font-weight: 600 !important;
}

.dark .kt-menu-item-active .kt-menu-link {
    background: #F4EFE3; /* parchment-500, hardcoded — Metronic's dark --secondary
                            is too cool a grey to read as "selected" against ink-900 */
}

.dark .kt-menu-item-active .kt-menu-link .kt-menu-icon,
.dark .kt-menu-item-active .kt-menu-link .kt-menu-title {
    color: #1B4F7A !important; /* kit: Azul Marinho on parchment */
}

/* ====================================================================
 * Sidebar menu icons — outline ↔ filled swap
 *
 * <NavIcon Name="..."> renders both glyph variants side by side; this
 * rule hides whichever doesn't match the parent state. Two parents
 * flip the swap:
 *   · NavLink active route  → .kt-menu-item-active on the <a>
 *   · Accordion expanded    → .show on the wrapper
 *     (used by the "Administração" group)
 *
 * Default is outline (.nav-icon-default visible, .nav-icon-active
 * hidden). Active/expanded state swaps them.
 * ==================================================================== */

.nav-icon-active {
    display: none;
}

.kt-menu-item-active .nav-icon-default,
.kt-menu-item.show > .kt-menu-link .nav-icon-default {
    display: none;
}

.kt-menu-item-active .nav-icon-active,
.kt-menu-item.show > .kt-menu-link .nav-icon-active {
    display: inline-block;
}

/* ====================================================================
 * Accordion group whose current route is among its children (e.g. "Admin")
 *
 * The parent is a <div>, not a NavLink, so NavMenu applies `.nav-group-active`
 * when IsAdminSectionActive. We do NOT reuse `.kt-menu-item-active` here: the
 * global active styling uses DESCENDANT selectors
 * (`.kt-menu-item-active .kt-menu-link`), which would paint EVERY accordion
 * sub-item as active. Targeting the direct child (`>`) keeps the highlight on
 * the group's own link only; the sub-items keep their normal state.
 * ==================================================================== */

/* Keep the parent visible as context without competing with the active child.
   The child owns the solid primary selection; the parent uses a soft tint and
   a slim primary marker in both themes. */
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .nav-group-active > .kt-menu-link {
    background: color-mix(in oklab, var(--primary) 10%, transparent);
    border-radius: var(--radius);
    box-shadow: inset 2px 0 0 0 var(--primary);
}
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .nav-group-active > .kt-menu-link .kt-menu-icon,
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .nav-group-active > .kt-menu-link .kt-menu-title,
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .nav-group-active > .kt-menu-link .kt-menu-arrow {
    color: var(--primary) !important;
}
/* Filled variant of the group icon (both modes) */
.nav-group-active > .kt-menu-link .nav-icon-default { display: none; }
.nav-group-active > .kt-menu-link .nav-icon-active { display: inline-block; }

/* Collapsed — soft navy pill + navy outline icon (same as the collapsed active state) */
.demo1.kt-sidebar-collapse .kt-sidebar .nav-group-active > .kt-menu-link {
    background: color-mix(in oklab, var(--primary) 16%, transparent) !important;
    color: var(--primary) !important;
    box-shadow: none !important;
}
.demo1.kt-sidebar-collapse .kt-sidebar .nav-group-active > .kt-menu-link .nav-icon-default {
    display: inline-block !important;
    color: var(--primary);
}
.demo1.kt-sidebar-collapse .kt-sidebar .nav-group-active > .kt-menu-link .nav-icon-active {
    display: none !important;
}

/* ====================================================================
 * Sidebar information hierarchy
 *
 * Section labels use the existing muted token and collapse into neutral
 * dividers in rail mode. Top-level destinations keep a consistent 40px hit
 * target; all geometry remains inside the Metronic sidebar width variables.
 * ==================================================================== */

.demo1:not(.kt-sidebar-collapse) .kt-sidebar .sidebar-menu-heading-slot {
    margin-top: 14px;
}

.demo1:not(.kt-sidebar-collapse) .kt-sidebar .sidebar-menu-heading-slot:first-child {
    margin-top: 0;
}

.demo1:not(.kt-sidebar-collapse) .kt-sidebar .sidebar-menu-heading {
    min-height: 22px;
    padding: 3px 10px 5px;
    color: var(--muted-foreground);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    line-height: 0.875rem;
    text-transform: uppercase;
    white-space: nowrap;
}

.demo1:not(.kt-sidebar-collapse) .kt-sidebar .sidebar-menu > .kt-menu-item > .kt-menu-link {
    min-height: 40px;
    border-radius: var(--radius);
    transition: background-color 140ms ease, color 140ms ease, box-shadow 140ms ease;
}

.sidebar-menu-group > .kt-menu-link {
    width: 100%;
    appearance: none;
    font: inherit;
    text-align: inherit;
}

/* ====================================================================
 * Sidebar — collapsed-mode overrides
 *
 * Out-of-the-box Metronic does three odd things when the sidebar
 * minimises (.kt-sidebar-collapse on body):
 *   1. Replaces every group heading text ("ADMINISTRAÇÃO") with the
 *      pseudo-content "..." — looks broken, not minimal.
 *   2. Keeps the active item's `.kt-menu-link` background but with the
 *      full menu-link padding, so the highlight stretches off the
 *      visible 80px rail and the icon ends up uncentered with no
 *      visible pill.
 *   3. Has no tooltip for collapsed icons — users can't see what an
 *      icon means without expanding.
 *
 * This block fixes all three without forking the Metronic theme.
 * ==================================================================== */

.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu > .kt-menu-item > .kt-menu-heading::before {
    content: "" !important;
}
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu > .kt-menu-item:has(> .kt-menu-heading) {
    /* Heading slot becomes a 1px divider */
    border-top: 1px solid var(--border);
    margin: 8px 12px;
    padding: 0 !important;
    height: 0;
}
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu > .sidebar-menu-heading-slot:first-child {
    display: none !important;
}
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu > .kt-menu-item > .kt-menu-heading {
    display: none !important;
}

/* Center the icon on the narrow rail and give every link a 40x40 hit
   target so active/hover pills can wrap around the icon evenly. The
   markup carries Tailwind's `grow` (flex-grow: 1) so width and height
   need !important to win against the utility class. */
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu .kt-menu-link {
    justify-content: center !important;
    align-items: center !important;
    padding-inline: 0 !important;
    padding-block: 0 !important;
    margin-inline: auto !important;
    margin-block: 2px !important;
    height: 40px !important;
    width: 40px !important;
    min-width: 40px !important;
    flex: 0 0 40px !important;
    border-radius: 10px !important;
    border-color: transparent !important;
    transition: background-color 140ms ease, color 140ms ease;
}
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu .kt-menu-icon {
    width: auto !important;
    margin: 0 !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Active in collapsed mode: soft primary-tinted pill + primary-coloured
   icon. Keep the OUTLINE variant (not filled) — filled keenicons read
   as a heavy navy block on the white rail and visually overwhelm the
   neighbour items. The pill carries the active signal, the icon stroke
   carries the brand colour. */
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu-item-active .kt-menu-link,
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu-item.show > .kt-menu-link {
    background: color-mix(in oklab, var(--primary) 16%, transparent) !important;
    color: var(--primary) !important;
    box-shadow: none !important;
}
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu-item-active .kt-menu-link .nav-icon-default,
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu-item.show > .kt-menu-link .nav-icon-default {
    display: inline-block !important;
    color: var(--primary);
}
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu-item-active .kt-menu-link .nav-icon-active,
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu-item.show > .kt-menu-link .nav-icon-active {
    display: none !important;
}

/* Hover in collapsed mode: same shape, lighter fill. */
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu .kt-menu-link:hover {
    background: color-mix(in oklab, var(--primary) 9%, transparent) !important;
    color: var(--primary) !important;
}

/* Center the badge dot over the icon centre — the link is 40x40 so we
   need explicit positioning rather than relying on the expanded-mode
   icon-corner anchor. */
.demo1.kt-sidebar-collapse .kt-sidebar .menu-badge-dot {
    top: -2px;
    right: -2px;
}

/* ====================================================================
 * Sidebar — submenu accordion spacing
 *
 * The accordion wrapper draws a vertical guide line via a `::before`
 * pseudo-element positioned at `start-[20px]`. Inner NavLinks have
 * `ps-[10px]` on their `.kt-menu-link` span, which lands the icon at
 * roughly the same x-coordinate as the line — the icon visually sits
 * ON the line. Pushing the inner items a few pixels to the right gives
 * them breathing room.
 * ==================================================================== */

.demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item > .kt-menu-link {
    /* `ps` positions the icon; the negative margin extends the pill (active/
       hover background) left to the sidebar's content edge, so a selected
       sub-item reads the same ~245px width as a top-level item. The accordion
       wrapper insets its children by 10px, so -10px cancels that exactly
       (the 30px ps still indents the icon/label for the nested look). */
    padding-inline-start: calc(30px + var(--pill-bleed, 0px));
    margin-inline-start: calc(-10px - var(--pill-bleed, 0px));
    /* Match the top-level pill's outward bleed on the right too, so a
       selected sub-item stays the same width as a top-level item (see the
       --pill-bleed block below). */
    padding-inline-end: calc(10px + var(--pill-bleed, 0px));
    margin-inline-end: calc(-1 * var(--pill-bleed, 0px));
    /* Sit ABOVE the accordion's vertical guide line (a `::before` pseudo
       element on the wrapper). Without this z-index, the line draws on
       top of the active item's background pill, cutting through it. */
    position: relative;
    z-index: 1;
}

/* ====================================================================
 * Sidebar — wider hover/active pill (expanded mode)   [--pill-bleed knob]
 *
 * The pill IS the .kt-menu-link background; because the link is `grow`,
 * its border-box always fills the item and its outer edge is pinned to
 * the scroll wrapper's content box (MainLayout: ps-5 / pe-3 + pe-2). So
 * bumping the link's OWN padding never moves the pill edge. To widen the
 * pill without shifting the icon/label, pull the link outward with a
 * negative inline margin and add the same amount back as padding — the
 * exact trick the accordion sub-items above use.
 *
 * `--pill-bleed` is the single knob: raise/lower to taste (7px ≈ 14px
 * wider overall). Defined here on .kt-sidebar so it inherits into the
 * accordion rule above as well. Kept in app.css — loaded AFTER the
 * Tailwind-generated styles.css and never regenerated — so a Tailwind
 * rebuild can't overwrite it (the usual cause of "my change vanished").
 * ==================================================================== */
.demo1:not(.kt-sidebar-collapse) .kt-sidebar {
    --pill-bleed: 7px;
}
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu > .kt-menu-item > .kt-menu-link {
    margin-inline: calc(-1 * var(--pill-bleed));
    padding-inline: calc(10px + var(--pill-bleed));
}

/* Group-header links (Financeiro / Contratos / Administração) carry a chevron at the
   trailing edge and have `width: 100%` from the native-button reset above.
   Unlike flex-growing NavLinks, a fixed 100% width does not absorb negative
   margins, so explicitly add both bleed values to match every other pill
   without pushing content beyond the sidebar's scroll viewport. */
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu > .kt-menu-item:has(> .kt-menu-accordion) > .kt-menu-link {
    width: calc(100% + var(--pill-bleed) + var(--pill-bleed));
    padding-inline-end: 22px;
}

/* Keep the active accordion item's pill visible on hover. Metronic's
   default hover styles apply a muted background that visually overrides
   the navy active state. We force the active state to win when the user
   hovers — same navy fill, slightly darker for a subtle hover hint. */
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item-active > .kt-menu-link,
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item-active > .kt-menu-link:hover {
    background: var(--primary) !important;
    color: var(--primary-foreground) !important;
}
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item-active > .kt-menu-link:hover {
    background: color-mix(in oklab, var(--primary) 92%, black) !important;
}
/* Dark mode — the active child follows the dark active style (parchment +
   navy), NOT var(--primary): in dark that resolves to the brighter #2B7CB5
   (Azul Médio), which clashes with the parchment-filled group header above
   it. Mirrors `.dark .kt-menu-item-active` so parent and child match. */
.dark .demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item-active > .kt-menu-link,
.dark .demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item-active > .kt-menu-link:hover {
    background: #F4EFE3 !important;
    color: #1B4F7A !important;
}
.dark .demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item-active > .kt-menu-link:hover {
    background: color-mix(in oklab, #F4EFE3 92%, black) !important;
}
/* Keep the active item's text/icon WHITE on hover. The utility class
   `kt-menu-link-hover:!text-primary` on .kt-menu-title would paint it navy —
   navy over the active item's navy fill = invisible (the item became a solid
   blue block with no text).
   Must live INSIDE `@layer utilities`: per the cascade, `!important` in a
   layer beats `!important` outside any layer, so a plain rule (even a more
   specific one) would lose to the utility. In the same layer, specificity
   decides again and ours (far more specific) wins. */
@layer utilities {
    .demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item-active > .kt-menu-link:hover .kt-menu-title,
    .demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item-active > .kt-menu-link:hover .kt-menu-icon {
        color: var(--primary-foreground) !important;
    }
    /* Dark mode: text/icon stay NAVY on the parchment fill (not white). */
    .dark .demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item-active > .kt-menu-link:hover .kt-menu-title,
    .dark .demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item-active > .kt-menu-link:hover .kt-menu-icon {
        color: #1B4F7A !important;
    }

    /* Group header hover keeps title, icon and chevron on the same primary
       foreground. The active group is intentionally a soft contextual state,
       so it uses primary text rather than the selected route's white text. */
    .demo1:not(.kt-sidebar-collapse) .kt-sidebar .nav-group-active > .kt-menu-link:hover .kt-menu-title,
    .demo1:not(.kt-sidebar-collapse) .kt-sidebar .nav-group-active > .kt-menu-link:hover .kt-menu-icon,
    .demo1:not(.kt-sidebar-collapse) .kt-sidebar .nav-group-active > .kt-menu-link:hover .kt-menu-arrow {
        color: var(--primary) !important;
    }
    .demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-item:not(.nav-group-active):has(> .kt-menu-accordion) > .kt-menu-link:hover .kt-menu-title,
    .demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-item:not(.nav-group-active):has(> .kt-menu-accordion) > .kt-menu-link:hover .kt-menu-icon,
    .demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-item:not(.nav-group-active):has(> .kt-menu-accordion) > .kt-menu-link:hover .kt-menu-arrow {
        color: var(--primary) !important;
    }
}

/* Hover on a non-active accordion item — soft primary tint so the
   interaction reads but doesn't compete with the active pill. */
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion .kt-menu-item:not(.kt-menu-item-active) > .kt-menu-link:hover {
    background: color-mix(in oklab, var(--primary) 8%, transparent) !important;
    color: var(--primary) !important;
}

/* Group header hover backgrounds (see the @layer block above for text colour). */
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-item:not(.nav-group-active):has(> .kt-menu-accordion) > .kt-menu-link:hover {
    background: color-mix(in oklab, var(--primary) 8%, transparent) !important;
}
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .nav-group-active > .kt-menu-link:hover {
    background: color-mix(in oklab, var(--primary) 14%, transparent) !important;
}

/* Breathing room between the group header and its first sub-item. The
   accordion is display:none when collapsed, so this only spaces the
   expanded submenu. The guide line (before:top-0) starts after the margin,
   staying aligned with the first child. */
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu-accordion {
    margin-top: 5px;
}

/* ====================================================================
 * Sidebar — tooltip on collapsed icons
 *
 * In collapsed mode the labels are hidden, so users can't tell what an
 * icon means until they click. A `title` attribute is already on every
 * NavLink for screen readers, but the native browser tooltip only fires
 * after ~700ms and looks generic. This pseudo-element tooltip uses the
 * same `title` value, pops immediately on hover, and is styled to match
 * the brand chrome (ink-on-card with a soft shadow).
 *
 * `::after` is hidden by default (opacity:0 + pointer-events:none) and
 * fades in on `:hover`. Positioned absolutely to the right of the icon,
 * vertically centred, with a small gap.
 * ==================================================================== */

.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu-link[title] {
    position: relative;
}
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu-link[title]::after {
    content: attr(title);
    position: absolute;
    inset-inline-start: calc(100% + 10px);
    top: 50%;
    transform: translateY(-50%);
    background: var(--foreground);
    color: var(--background);
    padding: 6px 10px;
    border-radius: 6px;
    font-size: 12px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 120ms ease, transform 120ms ease;
    z-index: 50;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
}
.demo1.kt-sidebar-collapse .kt-sidebar .kt-menu-link[title]:hover::after {
    opacity: 1;
    transform: translateY(-50%) translateX(2px);
}

/* demo1.css forces `overflow: hidden` on .kt-sidebar-content in collapsed
   mode to clip overflowing label text — but in our setup the labels are
   already `display: none` (so nothing actually overflows horizontally),
   and the hidden overflow clips our pseudo-element tooltip. Override to
   visible so the tooltip can escape the sidebar's right edge. Vertical
   scroll is still handled by the inner `kt-scrollable-y` container,
   which has its own overflow rules — so this doesn't break long menus. */
.demo1.kt-sidebar-collapse .kt-sidebar .kt-sidebar-content {
    overflow: visible !important;
}

/* ====================================================================
 * Sidebar badges — pending counters on Tarefas, Prazos, Comunicações
 *
 * Two display modes driven by sidebar collapse state:
 *   - Expanded: right-aligned numeric pill next to the label
 *   - Collapsed: small status dot on the icon (no number)
 *
 * Pending work stays danger-red. Unread communications use a soft primary
 * treatment so "new" does not look as urgent as a deadline.
 * ==================================================================== */

.menu-badge {
    margin-inline-start: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--danger);
    color: var(--primary-foreground);
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.02em;
    flex-shrink: 0;
}

.menu-badge-unread {
    background: color-mix(in oklab, var(--primary) 12%, transparent);
    color: var(--primary);
}

.kt-menu-item-active .menu-badge-unread {
    background: var(--primary-foreground);
    color: var(--primary);
}

/* Dot variant is the icon-overlay rendered alongside the numeric badge
   in the markup. Hidden by default; shown only when the sidebar is
   collapsed, so the number disappears with the label and the dot picks
   up the slack. */
.menu-badge-dot {
    display: none;
    position: absolute;
    top: -2px;
    right: -4px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--danger);
    border: 2px solid var(--background);
    box-sizing: content-box;
}

.menu-badge-dot-unread {
    background: var(--primary);
}

.demo1.kt-sidebar-collapse .menu-badge { display: none; }
.demo1.kt-sidebar-collapse .menu-badge-dot { display: inline-block; }

/* ====================================================================
 * Required field markers — universal across all editors.
 *
 * Add the `required` class to any label whose field is mandatory; the
 * `::after` rule appends a red asterisk that screen readers ignore
 * (purely decorative — the actual aria-required is on the input).
 *
 * Pair with a top-of-form `.required-hint` note explaining what `*` means.
 * ==================================================================== */

.editor-label.required::after,
label.required::after {
    content: " *";
    color: var(--danger);
    font-weight: 600;
    margin-inline-start: 2px;
}

.required-hint {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.72rem;
    color: var(--text-muted);
    margin-bottom: 0.5rem;
}
.required-hint::before {
    content: "*";
    color: var(--danger);
    font-weight: 600;
}

/* ====================================================================
 * Accessibility — skip link + focus-visible audit
 *
 * Skip link is the first focusable element in MainLayout. It stays
 * offscreen until Tab focuses it, then jumps to `#content`. Standard
 * pattern documented in WCAG 2.4.1 (Bypass Blocks).
 *
 * Focus-visible adds a 2px gold ring around any keyboard-focused
 * interactive element where the browser/component theme didn't already
 * provide one. We don't override Syncfusion's internal focus rings —
 * just fill in the gaps for raw <button>/<a>/<input>.
 * ==================================================================== */

.skip-link {
    position: fixed;
    top: 0;
    inset-inline-start: 0;
    z-index: 9999;
    padding: 0.6rem 1rem;
    background: var(--primary);
    color: var(--primary-foreground);
    font-size: 0.85rem;
    font-weight: 500;
    text-decoration: none;
    border-radius: 0 0 8px 0;
    /* Hidden but not display:none — keep it in the accessibility tree.
       Transform off-screen so screen readers still announce it as the
       first link on the page. */
    transform: translateY(-120%);
    transition: transform 0.15s ease-out;
}
.skip-link:focus,
.skip-link:focus-visible {
    transform: translateY(0);
    outline: 2px solid var(--ring);
    outline-offset: 2px;
}

/* Universal focus ring fallback. The `:focus-visible` pseudo-class only
   fires for keyboard navigation, so mouse users don't see it on click. */
button:focus-visible,
a:focus-visible,
[role="button"]:focus-visible,
input:not(.e-input):focus-visible,
textarea:not(.e-input):focus-visible,
select:focus-visible {
    outline: 2px solid var(--ring);
    outline-offset: 2px;
    border-radius: 4px;
}

/* Tooltips on collapsed-mode icons. The NavLink carries `title="..."`,
   which browsers show on hover after ~700ms. We don't want it to show
   when the sidebar is expanded (label is already visible), so disable
   pointer-events on the label trigger when not collapsed. (No JS.) */
.demo1:not(.kt-sidebar-collapse) .kt-sidebar .kt-menu .kt-menu-link[title] {
    /* Keep the title attribute in DOM for screen readers, but visually
       the inline label is redundant — no action needed; this rule is
       a placeholder for future styling. */
}

/* ====================================================================
 * Sidebar toggle button — anchor inside the header
 *
 * The default Metronic layout positions the toggle absolutely on the
 * sidebar's right edge with -50% translate, which makes it "float" in
 * a vertical rail between sidebar and main content and creates a
 * jittery rendering during the width transition.
 *
 * Pin it inside the kt-sidebar-header so it travels with the sidebar
 * during minimise/expand and never appears detached.
 * ==================================================================== */

#sidebar_toggle {
    position: relative !important;
    inset: auto !important;
    transform: none !important;
    margin-inline-start: auto;
}
.demo1.kt-sidebar-collapse #sidebar_toggle {
    /* Centered when the header collapses */
    margin: 0 auto;
}

/* Collapsed header — the rail is 80px and the default `px-3 lg:px-6`
   padding (24px each side) leaves only ~32px for the small-logo +
   toggle button, which pushes them visually together with no gap.
   Tighten the side padding and add a real flex gap so the "P" logo
   has breathing room from the toggle button. */
.demo1.kt-sidebar-collapse .kt-sidebar .kt-sidebar-header {
    padding-inline: 8px !important;
    gap: 6px;
    justify-content: center;
}

/* --- Brand tokens — Precepto media kit (Backups/Media/precepto-media-kit.tsx) ---
 *
 * Light mode anchors the four kit colours:
 *   #1B4F7A  Azul Marinho (primário, brand-700)
 *   #2B7CB5  Azul Médio   (brand-500, hover/accent)
 *   #5A8BA8  Azul Claro   (brand-400, tagline/captions)
 *   #F7F9FB  Background   (kt-card surface / parchment)
 *
 * The 50/100/900 stops are derived to keep the existing CSS surfaces
 * (badges, hovers, dark ink-900) consistent — generated by tinting/
 * shading the primary, not picked separately.
 */

:root,
[data-theme="light"] {
    --brand-50: #e9f1f7;   /* very light wash of #1B4F7A — used on hovers + badges */
    --brand-100: #cfdfe9;
    --brand-400: #5A8BA8;  /* kit: Azul Claro */
    --brand-500: #2B7CB5;  /* kit: Azul Médio */
    --brand-700: #1B4F7A;  /* kit: Azul Marinho — primário */
    --brand-900: #103352;
    --brand-accent: #2B7CB5;
    --surface: #ffffff;
    --surface-alt: #F7F9FB;  /* kit: Background */
    --brand-border: #e0e6ed;
    --text: #1B4F7A;
    --text-muted: #5A8BA8;
    --text-subtle: #94a3b8;
    --danger: #c0392b;
    --success: #16a34a;
    --warning: #f59e0b;
    --shadow-sm: 0 1px 2px rgba(27, 79, 122, 0.08);
    --shadow-md: 0 4px 16px rgba(27, 79, 122, 0.10);
    --brand-radius: 10px;
    --brand-radius-sm: 6px;
}

[data-theme="dark"] {
    /* Dark surface intentionally keeps the same Azul Marinho hue family
       so the brand reads the same; just shift to a darker bracket. */
    --brand-50: #1a2740;    /* near-primary hover bg in dark */
    --brand-100: #233453;
    --brand-400: #8aaecb;
    --brand-500: #5A8BA8;
    --brand-700: #b8d0e3;   /* inverted: light blue for body text on dark */
    --brand-900: #e3edf5;
    --brand-accent: #2B7CB5;
    --surface: #0F2336;     /* darker shade of kit #1B4F7A */
    --surface-alt: #081421;
    --brand-border: #1f3a55;
    --text: #e3edf5;
    --text-muted: #8aaecb;
    --text-subtle: #5A8BA8;
    --danger: #f87171;
    --success: #34d399;
    --warning: #fbbf24;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
    --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.40);
}

/* ====================================================================
 * Syncfusion grid — Precepto polish
 *
 * Wraps Syncfusion's default tailwind theme with our token system so the
 * grid feels like part of the app, not a third-party drop-in.
 *
 * Light mode:
 *   - Card surface for the grid body (clean reading surface)
 *   - Page bg (parchment) for the header — separates header from body
 *     without needing a heavy border
 *   - Muted-foreground uppercase for column titles (overline treatment)
 *   - Rows breathe: 14px vertical padding (Syncfusion default ~6px)
 *   - Hover = subtle parchment tint, not a colour flash
 *
 * Dark mode:
 *   - Card surface (ink-800) for body, ink-900 (page bg) for header
 *   - Borders use ink-700 token, not the legacy --brand-border
 * ==================================================================== */

[data-theme="dark"] body { background: var(--background); color: var(--foreground); }

/* --- Container + outer border --- */
.e-grid {
    background: var(--card) !important;
    border-color: var(--border) !important;
    border-radius: var(--radius);
}
.e-grid .e-headercontent,
.e-grid .e-gridcontent {
    background: var(--card) !important;
}

/* --- Header row: parchment in light, ink-900 in dark --- */
.e-grid .e-gridheader {
    background: var(--background) !important;
    border-bottom: 1px solid var(--border) !important;
}
.e-grid .e-headercell {
    background: var(--background) !important;
    color: var(--muted-foreground) !important;
    font-size: 11px !important;
    font-weight: 600 !important;
    letter-spacing: 0.06em !important;
    text-transform: uppercase !important;
    border-color: var(--border) !important;
    padding-top: 10px !important;
    padding-bottom: 10px !important;
}
.e-grid .e-headercell .e-headercelldiv,
.e-grid .e-headercell .e-headertext {
    color: var(--muted-foreground) !important;
}

/* --- Body cells: relaxed padding, token colours --- */
.e-grid .e-rowcell {
    color: var(--foreground) !important;
    background: var(--card) !important;
    border-bottom: 1px solid var(--border) !important;
    border-top: none !important;
    padding-top: 14px !important;
    padding-bottom: 14px !important;
    font-size: 14px !important;
}

/* --- Zebra: alternate rows get a 3% mix with primary so the eye can scan
       columns without losing horizontal alignment. Falls back to muted on
       browsers without color-mix support.

       Dark mode bumps the mix to 6% — at 3% the stripe was nearly invisible
       against the deep-navy card surface (#102236). The extra tint reads
       as "row group" without becoming a heavy banded look. --- */
.e-grid .e-row:nth-child(even) .e-rowcell {
    background: var(--muted) !important;
}
@supports (background: color-mix(in oklab, red, blue)) {
    .e-grid .e-row:nth-child(even) .e-rowcell {
        background: color-mix(in oklab, var(--primary) 3%, var(--card)) !important;
    }
    [data-theme="dark"] .e-grid .e-row:nth-child(even) .e-rowcell {
        background: color-mix(in oklab, var(--primary) 6%, var(--card)) !important;
    }
}

/* --- Row hover: navy tint strong enough to read on top of zebra stripe. --- */
.e-grid .e-row:hover .e-rowcell,
.e-grid .e-row:nth-child(even):hover .e-rowcell {
    background: color-mix(in oklab, var(--primary) 8%, var(--card)) !important;
}

/* --- Selected row: navy tint (light) / parchment tint (dark) --- */
.e-grid .e-row.e-rowselect .e-rowcell,
.e-grid .e-row.e-rowselect:hover .e-rowcell {
    background: color-mix(in oklab, var(--primary) 8%, var(--card)) !important;
    color: var(--foreground) !important;
}

/* ====================================================================
 * Density: compact rows
 *
 * Add `kt-grid-compact` to any grid's wrapper (`.kt-card`, the parent
 * `<div>` around <SfGrid>, or `<body>` for app-wide opt-in) to drop
 * row padding ~30% — useful on data-heavy pages where the user wants
 * to see more rows per viewport.
 *
 * Density is a per-grid choice, not a global theme switch — toggle it
 * with a button placed near the grid header. Persisting per-grid in
 * localStorage is left to each page.
 * ==================================================================== */
.kt-grid-compact .e-grid .e-rowcell {
    padding-top: 6px !important;
    padding-bottom: 6px !important;
    line-height: 1.3 !important;
}
.kt-grid-compact .e-grid .e-headercell {
    padding-top: 7px !important;
    padding-bottom: 7px !important;
}
.kt-grid-compact .e-grid .e-row { height: auto !important; }

/* ====================================================================
 * Row action menu (⋮)
 *
 * Built on <details>/<summary> for zero-JS open/close. The summary is
 * the 28×28 trigger, the menu is absolutely positioned just below.
 * Click-outside-closes handled in precepto-ktui.js.
 *
 * Lives inside SfGrid row templates so the dropdown must escape the
 * grid's overflow:hidden via z-index + position:absolute (parent grid
 * cells do allow this — the kt-rowcell doesn't clip overflow).
 * ==================================================================== */
.row-action {
    position: relative;
    display: inline-block;
}
.row-action[open] .row-action-trigger {
    background: var(--brand-50);
    color: var(--primary);
    border-color: var(--primary);
}
.row-action-trigger {
    list-style: none; /* drop the default ▶ marker on <summary> */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 6px;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.row-action-trigger::-webkit-details-marker { display: none; }
.row-action-trigger::marker { content: ""; }
.row-action-trigger:hover {
    background: var(--brand-50);
    color: var(--primary);
    border-color: var(--primary);
}

.row-action-menu {
    position: absolute;
    top: calc(100% + 4px);
    inset-inline-end: 0;
    z-index: 30;
    min-width: 160px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    padding: 4px 0;
    display: flex;
    flex-direction: column;
}
[data-theme="dark"] .row-action-menu {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}

.row-action-item {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    background: transparent;
    border: 0;
    padding: 0.5rem 0.85rem;
    font-size: 0.85rem;
    color: var(--text);
    text-align: start;
    cursor: pointer;
    transition: background 0.1s;
    white-space: nowrap;
}
.row-action-item:hover,
.row-action-item:focus-visible {
    background: var(--brand-50);
    color: var(--primary);
}
.row-action-item i { width: 16px; text-align: center; }

.row-action-item.row-action-danger { color: var(--destructive); }
.row-action-item.row-action-danger:hover,
.row-action-item.row-action-danger:focus-visible {
    background: color-mix(in oklab, var(--destructive) 10%, transparent);
    color: var(--destructive);
}

/* The menu's `position`, `top`, `right`, `z-index` are all managed
   live by precepto-ktui.js (positionRowMenu): it switches the menu to
   `position: fixed` anchored to the trigger's getBoundingClientRect()
   when the <details> toggles open, so the popup escapes the SfGrid's
   `.e-content` overflow:auto and the `.e-rowcell` overflow:hidden
   wrappers without needing per-ancestor CSS overrides. The static
   `position: absolute` rule above is the fallback for the brief frame
   between click and the JS toggle handler running. */

/* --- Pager: align with grid surface --- */
.e-grid .e-gridpager {
    background: var(--card) !important;
    border-top: 1px solid var(--border) !important;
    color: var(--muted-foreground) !important;
}
.e-grid .e-gridpager .e-pagercontainer,
.e-grid .e-gridpager .e-numericcontainer .e-numericitem {
    background: transparent !important;
    color: var(--muted-foreground) !important;
    border-color: var(--border) !important;
}
.e-grid .e-gridpager .e-numericcontainer .e-numericitem.e-currentitem {
    background: var(--primary) !important;
    color: var(--primary-foreground) !important;
    border-color: var(--primary) !important;
}
.e-grid .e-gridpager .e-numericcontainer .e-numericitem:hover:not(.e-currentitem) {
    background: var(--muted) !important;
    color: var(--foreground) !important;
}

/* ====================================================================
 * Mobile (< 768px): grids switch to Syncfusion's adaptive vertical row
 * mode (EnableAdaptiveUI + RowRenderingMode.Vertical → grid gets the
 * `.e-row-responsive` class; each column stacks as a "label: value" line
 * via `.e-rowcell::before { content: attr(data-cell) }`). Two fixes:
 *
 *  1. Hide the injected "Mostrando de X até Y de N" pager summary — there
 *     is no room for it beside the page-size dropdown + nav on a phone.
 *  2. Column TextAlign flows through to the stacked cell: center/right
 *     columns (e.g. "Processos" TextAlign.Center, "Total" right, the ⋮
 *     action column) render their label+value centred/right, misaligned
 *     against the left-aligned rows. Force left-align on stacked cells so
 *     every line reads uniformly. SCOPED to `.e-row-responsive` so it
 *     NEVER touches the desktop horizontal table (which keeps its own
 *     column alignment). Verified live via Chrome DevTools at 500px.
 *  3. No horizontal page scroll: even in vertical mode the grid renders a
 *     `table-layout: fixed` table that keeps the SUM of the desktop column
 *     widths (e.g. Documents ≈ 526px). That exceeds a phone viewport, and
 *     because the app-shell flex items (`.flex.grow`, `.kt-wrapper`,
 *     `#content`) default to `min-width: auto` they refuse to shrink below
 *     that width — pushing the WHOLE page into horizontal scroll. Fix in
 *     two parts: (a) let those shell items shrink (`min-width: 0`); (b)
 *     force the vertical-mode table to `width: 100%` so it fills/fits the
 *     card and its values truncate via the existing cell ellipsis. Grids
 *     whose columns already fit (Clients ≈ 433px) are unaffected. Both
 *     parts are needed — the circular width dependency only breaks with
 *     both. Verified live via Chrome DevTools.
 *  4. Empty cells no longer collapse under their label. The stacked label
 *     is drawn by an ABSOLUTELY-positioned `::before` (24px line-height)
 *     inside a `position: relative; overflow: hidden` cell. A cell whose
 *     value is blank (e.g. a client with no document/phone) shrinks to
 *     just its vertical padding (~19px), so the 24px label overflows the
 *     cell and is clipped — visually colliding with the next stacked line
 *     ("encavalado"). Give every stacked cell a `min-height` that fits the
 *     label + padding (matches the ~42px of a filled cell), so blank rows
 *     stay full-height and uniform. SCOPED to `.e-row-responsive` — never
 *     touches the desktop table. Verified live via Chrome DevTools at 400px.
 * ==================================================================== */
@media (max-width: 767px) {
    .precepto-pager-info { display: none !important; }

    /* Fixes #2 + #4 — left-align stacked cells and keep blank ones
       full-height so the absolutely-positioned label never clips. */
    .e-grid.e-row-responsive .e-rowcell {
        text-align: left !important;
        min-height: 42px;
    }

    /* Fix #3a — allow the app-shell flex items to shrink below their
       content's min-content (the sidebar is hidden on mobile, so the
       outer `.flex.grow` row holds only `.kt-wrapper`). */
    body > .flex.grow,
    .kt-wrapper,
    #content {
        min-width: 0;
    }

    /* Fix #3b — the fixed-layout table fills the card instead of keeping
       its desktop column-width sum. SCOPED to `.e-row-responsive`. */
    .e-grid.e-row-responsive .e-content table {
        width: 100% !important;
    }
}

/* ====================================================================
 * Action icon buttons (Edit/Delete in table rows)
 *
 * The Tailwind composition `kt-btn kt-btn-outline kt-btn-icon size-8`
 * with `hover:text-primary hover:border-primary` already swaps text
 * + border colour, but feels static without a bg change. Add a faint
 * muted fill on hover and a smooth transition so the affordance reads
 * as "pressable", not just "highlightable".
 * ==================================================================== */
.kt-btn.kt-btn-outline.kt-btn-icon {
    transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
.kt-btn.kt-btn-outline.kt-btn-icon:hover {
    background-color: var(--muted);
}

/* ====================================================================
 * Filter chip group label — the small "STATUS" / "LINK" overline that
 * precedes the chip row. Pages today repeat:
 *   <span class="text-xs font-medium text-secondary-foreground
 *                uppercase tracking-wider me-1">STATUS</span>
 *
 * This bumps the letter-spacing so the label reads as an editorial
 * overline and adds a tiny ochre dot that ties the filter group to
 * the brand without colouring the chips themselves.
 * ==================================================================== */
.kt-filter-label,
.text-secondary-foreground.uppercase.tracking-wider {
    letter-spacing: 0.08em;
    font-size: 11px;
}

/* ====================================================================
 * Empty state icon container — `bg-primary/10` is barely visible in
 * dark mode against ink-800. Bump the mix so the icon circle reads
 * cleanly without changing the markup in every listing.
 * ==================================================================== */
.dark .bg-primary\/10 {
    background-color: color-mix(in oklab, var(--primary) 22%, transparent) !important;
}

/* --- Dark mode: Syncfusion dialog --- */

[data-theme="dark"] .e-dlg-overlay { background: rgba(0, 0, 0, 0.55) !important; }

[data-theme="dark"] .e-dialog {
    background: var(--surface) !important;
    color: var(--text) !important;
    border: 1px solid var(--brand-border) !important;
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.55) !important;
}
[data-theme="dark"] .e-dialog .e-dlg-header-content {
    background: var(--surface) !important;
    border-bottom: 1px solid var(--brand-border) !important;
    color: var(--text) !important;
}
[data-theme="dark"] .e-dialog .e-dlg-header,
[data-theme="dark"] .e-dialog .e-dlg-header * { color: var(--text) !important; }

/* Body slot — the area between header and footer was missing from the
   dark theme, so it rendered on the default light Syncfusion surface. */
[data-theme="dark"] .e-dialog .e-dlg-content {
    background: var(--surface) !important;
    color: var(--text) !important;
}
[data-theme="dark"] .e-dialog .e-dlg-content hr,
[data-theme="dark"] .e-dialog .e-dlg-content .border-b,
[data-theme="dark"] .e-dialog .e-dlg-content .border-t { border-color: var(--brand-border) !important; }

[data-theme="dark"] .e-dialog .e-footer-content {
    background: var(--surface) !important;
    border-top: 1px solid var(--brand-border) !important;
}

/* Close icon button — the default has a transparent bg + dark icon
   that disappears against a dark header. Force a visible icon + a soft
   hover affordance, and override Syncfusion's nested icon spans whose
   inherited colour wins over the parent .color rule.

   IMPORTANT: the close button is also `.e-btn`, so the generic .e-btn
   dark theme rule above gives it `background: var(--surface-alt)` which
   rendered as a visible dark oval next to the header. We re-spec the
   selector with `.e-btn.e-dlg-closeicon-btn` to win the cascade. */
[data-theme="dark"] .e-dialog .e-btn.e-dlg-closeicon-btn,
[data-theme="dark"] .e-dialog .e-btn.e-flat.e-dlg-closeicon-btn,
[data-theme="dark"] .e-dialog .e-dlg-closeicon-btn {
    background: transparent !important;
    background-color: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    color: var(--text) !important;
    opacity: 1 !important;
    width: 32px !important;
    height: 32px !important;
    min-width: 32px !important;
    padding: 0 !important;
    border-radius: 6px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}
[data-theme="dark"] .e-dialog .e-btn.e-dlg-closeicon-btn:hover,
[data-theme="dark"] .e-dialog .e-btn.e-dlg-closeicon-btn:focus,
[data-theme="dark"] .e-dialog .e-dlg-closeicon-btn:hover,
[data-theme="dark"] .e-dialog .e-dlg-closeicon-btn:focus {
    background: rgba(255, 255, 255, 0.08) !important;
    background-color: rgba(255, 255, 255, 0.08) !important;
    color: #fff !important;
}
[data-theme="dark"] .e-dialog .e-dlg-closeicon-btn .e-icon-dlg-close,
[data-theme="dark"] .e-dialog .e-dlg-closeicon-btn .e-btn-icon,
[data-theme="dark"] .e-dialog .e-dlg-closeicon-btn span,
[data-theme="dark"] .e-dialog .e-dlg-closeicon-btn::before {
    color: var(--text) !important;
    opacity: 1 !important;
    font-size: 14px !important;
}
[data-theme="dark"] .e-dialog .e-dlg-closeicon-btn:hover .e-icon-dlg-close,
[data-theme="dark"] .e-dialog .e-dlg-closeicon-btn:hover .e-btn-icon,
[data-theme="dark"] .e-dialog .e-dlg-closeicon-btn:hover span { color: #fff !important; }

/* --- Dark mode: Syncfusion inputs --- */

[data-theme="dark"] .e-input-group,
[data-theme="dark"] .e-input-group.e-control-wrapper,
[data-theme="dark"] .e-input,
[data-theme="dark"] .e-ddl,
[data-theme="dark"] .e-dropdownlist,
[data-theme="dark"] .e-numerictextbox,
[data-theme="dark"] .e-textbox,
[data-theme="dark"] .e-multiselect,
[data-theme="dark"] input.e-input,
[data-theme="dark"] textarea.e-input { background: var(--surface-alt) !important; color: var(--text) !important; border-color: var(--brand-border) !important; }

/* The input value text inside Syncfusion wrappers is a nested span/input;
   force it to inherit so placeholder/value colours both adapt. */
[data-theme="dark"] .e-input-group .e-input,
[data-theme="dark"] .e-input-group input,
[data-theme="dark"] .e-input-group .e-ddl-icon,
[data-theme="dark"] .e-input-group .e-clear-icon { color: var(--text) !important; background: transparent !important; }
[data-theme="dark"] .e-input::placeholder,
[data-theme="dark"] .e-input-group input::placeholder { color: var(--text-subtle) !important; }

[data-theme="dark"] .e-popup { background: var(--surface) !important; color: var(--text) !important; border-color: var(--brand-border) !important; }
[data-theme="dark"] .e-list-item { color: var(--text) !important; background: var(--surface) !important; }
[data-theme="dark"] .e-list-item.e-hover,
[data-theme="dark"] .e-list-item:hover,
[data-theme="dark"] .e-list-item.e-active { background: var(--brand-50) !important; color: var(--text) !important; }

/* --- Dark mode: Syncfusion buttons --- */

[data-theme="dark"] .e-btn,
[data-theme="dark"] .e-btn.e-small,
[data-theme="dark"] .e-btn.e-flat {
    background: var(--surface-alt) !important;
    border-color: var(--brand-border) !important;
    color: var(--text) !important;
}
[data-theme="dark"] .e-btn:hover,
[data-theme="dark"] .e-btn.e-small:hover,
[data-theme="dark"] .e-btn.e-flat:hover {
    background: var(--brand-50) !important;
    border-color: var(--brand-accent) !important;
    color: var(--text) !important;
}
[data-theme="dark"] .e-btn.e-primary,
[data-theme="dark"] .e-btn.e-primary.e-small {
    background: var(--brand-500) !important;
    border-color: var(--brand-500) !important;
    color: #fff !important;
}
[data-theme="dark"] .e-btn.e-primary:hover {
    background: var(--brand-accent) !important;
    border-color: var(--brand-accent) !important;
}
[data-theme="dark"] .e-btn.e-danger,
[data-theme="dark"] .e-btn.e-small.e-danger {
    background: transparent !important;
    border-color: var(--danger) !important;
    color: var(--danger) !important;
}
[data-theme="dark"] .e-btn.e-danger:hover,
[data-theme="dark"] .e-btn.e-small.e-danger:hover {
    background: var(--danger) !important;
    color: #fff !important;
}

/* --- Dark mode: Syncfusion schedule --- */

[data-theme="dark"] .e-schedule,
[data-theme="dark"] .e-schedule .e-schedule-table,
[data-theme="dark"] .e-schedule .e-content-wrap,
[data-theme="dark"] .e-schedule .e-date-header-wrap,
[data-theme="dark"] .e-schedule .e-time-cells-wrap,
[data-theme="dark"] .e-schedule .e-month-header-wrap { background: var(--surface) !important; color: var(--text) !important; }
[data-theme="dark"] .e-schedule .e-header-cells,
[data-theme="dark"] .e-schedule .e-date-header-container .e-header-cells,
[data-theme="dark"] .e-schedule .e-all-day-cells { background: var(--surface-alt) !important; color: var(--text) !important; border-color: var(--brand-border) !important; }
[data-theme="dark"] .e-schedule .e-work-cells,
[data-theme="dark"] .e-schedule .e-time-slots,
[data-theme="dark"] .e-schedule .e-time-cells { background: var(--surface) !important; color: var(--text-muted) !important; border-color: var(--brand-border) !important; }
[data-theme="dark"] .e-schedule .e-work-cells.e-alternate-cells { background: var(--surface-alt) !important; }
[data-theme="dark"] .e-schedule .e-work-hours { background: var(--brand-50) !important; }
[data-theme="dark"] .e-schedule .e-current-time { color: var(--danger) !important; }
[data-theme="dark"] .e-schedule .e-current-timeline { border-color: var(--danger) !important; }
[data-theme="dark"] .e-schedule .e-toolbar,
[data-theme="dark"] .e-schedule .e-toolbar-wrapper { background: var(--surface) !important; border-color: var(--brand-border) !important; }
[data-theme="dark"] .e-schedule .e-toolbar .e-tbar-btn,
[data-theme="dark"] .e-schedule .e-tbar-btn-text { color: var(--text) !important; background: transparent !important; }
[data-theme="dark"] .e-schedule .e-tbar-btn:hover { background: var(--brand-50) !important; }
[data-theme="dark"] .e-schedule .e-active-view .e-tbar-btn,
[data-theme="dark"] .e-schedule .e-toolbar .e-tbar-btn.e-active-view { background: var(--brand-500) !important; color: #fff !important; }
[data-theme="dark"] .e-schedule td.e-selected-cell,
[data-theme="dark"] .e-schedule td.e-selected-cell.e-work-cells { background: var(--brand-100) !important; }

/* --- Syncfusion schedule: restore the view-toggle button icons ---
 *
 * Syncfusion's `tailwind.css` hides the view icons
 * (`.e-toolbar-item.e-week .e-icon-week`, etc.) with `display:none` because
 * it was built to show the view *text* ("Week", "Month"…) instead. In this
 * build (v33.1.49) the component renders the buttons in icon mode
 * (`e-icon-btn`) WITHOUT the `.e-tbar-btn-text`, so the button ends up empty
 * (icon hidden + no text) and the view selector disappears entirely. We
 * re-show the icons (they exist in the `e-icons` font) so the buttons come
 * back. Verified via Playwright: the icon goes from width 0 → 18px. Applies
 * to light + dark. NB: the disappearance was NOT caused by the colour rules
 * below. */
.e-schedule .e-schedule-toolbar .e-toolbar-items .e-toolbar-item.e-day .e-icon-day,
.e-schedule .e-schedule-toolbar .e-toolbar-items .e-toolbar-item.e-week .e-icon-week,
.e-schedule .e-schedule-toolbar .e-toolbar-items .e-toolbar-item.e-work-week .e-icon-workweek,
.e-schedule .e-schedule-toolbar .e-toolbar-items .e-toolbar-item.e-month .e-icon-month,
.e-schedule .e-schedule-toolbar .e-toolbar-items .e-toolbar-item.e-year .e-icon-year,
.e-schedule .e-schedule-toolbar .e-toolbar-items .e-toolbar-item.e-agenda .e-icon-agenda,
.e-schedule .e-schedule-toolbar .e-toolbar-items .e-toolbar-item.e-month-agenda .e-icon-month-agenda,
.e-schedule .e-schedule-toolbar .e-toolbar-items .e-toolbar-item.e-today .e-icon-today {
    display: inline-flex !important;
}

/* --- Syncfusion schedule: show view labels next to bigger icons ---
 *
 * Demo-style header (blazor.syncfusion.com/demos/scheduler/overview): each view
 * tab shows its name ("Dia", "Semana", "Mês", "Agenda") beside an enlarged
 * icon. The names come from each <ScheduleView DisplayName="…"> (localised);
 * here we just un-hide the text node the theme suppresses, enlarge the glyphs,
 * and space the two apart. The active-view recolour block below paints the
 * selected tab navy. Applies to light + dark. */
.e-schedule .e-schedule-toolbar .e-toolbar-items .e-toolbar-item .e-tbar-btn-text {
    display: inline-block !important;
    font-size: 0.8125rem;
    font-weight: 500;
    padding-inline-start: 0.375rem;
}
.e-schedule .e-schedule-toolbar .e-toolbar-items .e-toolbar-item .e-tbar-btn .e-icons {
    font-size: 1.125rem;
}
.e-schedule .e-schedule-toolbar .e-toolbar-items .e-toolbar-item .e-tbar-btn {
    padding-block: 0.4375rem;
}

/* --- Agenda event colours by type ---
 *
 * Applied through each appointment's built-in `CssClass` field (set in
 * Calendar.razor.cs → MapToScheduleEvent), NOT the EventRendered event: that
 * callback's per-event interop crashes the Agenda view's layout pass on an
 * all-day/multi-day event ("Cannot read properties of null (reading
 * 'offsetHeight')"). A data-bound CssClass is painted by Syncfusion's own
 * render, so the colours show in every view, Agenda included. The appointment
 * text is forced white below so it stays legible on every fill (the Tailwind
 * theme otherwise leaves agenda-view subjects dark). */
.e-schedule .e-appointment.evt-hearing,
.e-schedule .evt-hearing { background-color: #7c3aed !important; }
.e-schedule .e-appointment.evt-consultation,
.e-schedule .evt-consultation { background-color: #0891b2 !important; }
.e-schedule .e-appointment.evt-meeting,
.e-schedule .evt-meeting { background-color: #2563eb !important; }
.e-schedule .e-appointment.evt-reminder,
.e-schedule .evt-reminder { background-color: #d97706 !important; }
.e-schedule .e-appointment.evt-deadline-fatal,
.e-schedule .evt-deadline-fatal { background-color: #dc2626 !important; }
.e-schedule .e-appointment.evt-deadline,
.e-schedule .evt-deadline { background-color: #ea580c !important; }
.e-schedule .e-appointment.evt-task,
.e-schedule .evt-task { background-color: #0d9488 !important; }
.e-schedule .e-appointment.evt-other,
.e-schedule .evt-other { background-color: #475569 !important; }

/* Keep appointment text white on every coloured block, in every view.
 * The Tailwind theme leaves agenda-view (list) subjects/times dark, which is
 * illegible on the saturated fills above. Every event element carries an
 * `evt-*` CssClass in all views, so target it and its descendants directly. */
.e-schedule [class*="evt-"],
.e-schedule [class*="evt-"] * { color: #fff !important; }

/* --- Light mode: Syncfusion schedule — Precepto navy accent ---
 *
 * The stock Syncfusion `tailwind.css` theme ships an indigo/blue accent
 * that reads as "off-brand" purple-ish against the rest of the app. These
 * rules repaint the /calendar scheduler's brand-bearing affordances
 * (active view, selected cell, today's date, current-time line, toolbar
 * hovers) in the primary navy (#1B4F7A). Light-mode only — the dark block
 * above already handles `[data-theme="dark"]`. Any selector that doesn't
 * match the shipped markup is simply inert, so the set is intentionally
 * broad to cover view variants (day/week/month). */

/* Active view in the header toolbar.
 *
 * The Tailwind Syncfusion theme marks the selected view with an accent
 * *text* colour, NOT a solid fill — so we only swap that accent to navy.
 * (An earlier version forced a navy background + white text; the white
 * text landed on the theme's white button surface because the fill applied
 * to a different node, hiding the label as an empty bordered square.
 * Recolouring the text/icons — and every descendant — is structure-proof:
 * it can never hide the button regardless of the internal markup.) */
[data-theme="light"] .e-schedule .e-schedule-toolbar .e-active-view,
[data-theme="light"] .e-schedule .e-schedule-toolbar .e-active-view *,
[data-theme="light"] .e-schedule .e-toolbar .e-active-view,
[data-theme="light"] .e-schedule .e-toolbar .e-active-view * {
    color: var(--primary) !important;
}
/* The selected view is marked with a 4px navy underline (demo-style), not a
 * boxed border. `box-shadow: inset` paints the line inside the button, so it
 * never shifts the toolbar layout; the border stays transparent (its width is
 * unchanged, so neighbouring tabs keep the same height). */
[data-theme="light"] .e-schedule .e-schedule-toolbar .e-active-view,
[data-theme="light"] .e-schedule .e-toolbar .e-active-view {
    border-color: transparent !important;
    box-shadow: inset 0 -4px 0 0 var(--primary) !important;
}

/* Selected cell(s) — faint navy wash instead of the stock blue */
[data-theme="light"] .e-schedule td.e-selected-cell,
[data-theme="light"] .e-schedule td.e-selected-cell.e-work-cells,
[data-theme="light"] .e-schedule .e-month-view td.e-selected-cell {
    background: color-mix(in oklab, var(--primary) 12%, transparent) !important;
}

/* Today — column header (day/week) and the month-view date badge that
   Syncfusion paints in its accent (the "roxo/azul" the brief mentions) */
[data-theme="light"] .e-schedule .e-date-header-wrap .e-current-day,
[data-theme="light"] .e-schedule .e-header-cells.e-current-day {
    color: var(--primary) !important;
}
[data-theme="light"] .e-schedule .e-month-view .e-current-date .e-date-header,
[data-theme="light"] .e-schedule .e-current-date .e-navigate {
    background: var(--primary) !important;
    color: #fff !important;
    border-radius: 9999px !important;
}

/* Current-time indicator (line + label) */
[data-theme="light"] .e-schedule .e-current-time { color: var(--primary) !important; }
[data-theme="light"] .e-schedule .e-current-timeline { border-top-color: var(--primary) !important; }
[data-theme="light"] .e-schedule .e-previous-timeline { border-top-color: color-mix(in oklab, var(--primary) 35%, transparent) !important; }

/* Navigation/today toolbar buttons — Metronic-style navy ghost on hover */
[data-theme="light"] .e-schedule .e-toolbar .e-tbar-btn:not(.e-active-view):hover {
    background: color-mix(in oklab, var(--primary) 8%, transparent) !important;
}
[data-theme="light"] .e-schedule .e-toolbar .e-tbar-btn:not(.e-active-view):hover .e-tbar-btn-text,
[data-theme="light"] .e-schedule .e-toolbar .e-tbar-btn:not(.e-active-view):hover .e-icons {
    color: var(--primary) !important;
}

/* Work-hours band — faint navy wash so the business day stands out */
[data-theme="light"] .e-schedule .e-work-hours {
    background: color-mix(in oklab, var(--primary) 4%, transparent) !important;
}

/* --- Dark mode: Syncfusion calendar/timepicker --- */

[data-theme="dark"] .e-calendar,
[data-theme="dark"] .e-calendar .e-content { background: var(--surface) !important; color: var(--text) !important; }
[data-theme="dark"] .e-calendar .e-content td,
[data-theme="dark"] .e-calendar .e-header,
[data-theme="dark"] .e-calendar .e-header .e-title { color: var(--text) !important; }
[data-theme="dark"] .e-calendar .e-content td.e-today span { border-color: var(--brand-accent) !important; color: var(--brand-accent) !important; }
[data-theme="dark"] .e-calendar .e-content td.e-selected span { background: var(--brand-500) !important; color: #fff !important; }
[data-theme="dark"] .e-timepicker-popup { background: var(--surface) !important; border-color: var(--brand-border) !important; }
[data-theme="dark"] .e-timepicker-popup .e-list-item { color: var(--text) !important; }

/* --- Dark mode: Syncfusion checkbox --- */

[data-theme="dark"] .e-checkbox-wrapper .e-frame { background: var(--surface-alt) !important; border-color: var(--brand-border) !important; }
[data-theme="dark"] .e-checkbox-wrapper .e-frame.e-check { background: var(--brand-500) !important; border-color: var(--brand-500) !important; }

/* --- Dark mode: editor custom widgets still alive (event recurrence + uploader) --- */

[data-theme="dark"] .file-trigger { background: var(--surface-alt); border-color: var(--brand-border); color: var(--text); }
[data-theme="dark"] .file-trigger:hover { border-color: var(--brand-accent); }
[data-theme="dark"] .scope-option { background: var(--surface); border-color: var(--brand-border); }
[data-theme="dark"] .scope-option:hover { background: var(--surface-alt); border-color: var(--brand-500); }
[data-theme="dark"] .scope-option.active { background: var(--brand-50); border-color: var(--brand-accent); }
[data-theme="dark"] .day-chip { border-color: var(--brand-border); color: var(--text); }
[data-theme="dark"] .day-chip.active { background: var(--brand-500); border-color: var(--brand-500); color: #fff; }

/* --- HTML/body global typography --- */

html, body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
    color: var(--text);
    background: var(--surface-alt);
    -webkit-font-smoothing: antialiased;
}

/* Cascade-layers gotcha: unlayered `a { color }` beats KTUI's
   `.kt-btn { color: var(--primary-foreground) }` because layered
   rules always lose to unlayered ones — turning every anchor with
   `.kt-btn kt-btn-primary` into navy text on a navy background.
   Exclude buttons explicitly so anchors keep the blue link tint
   only when they aren't rendered as buttons. */
a:not(.kt-btn) { color: var(--brand-500); }

h1:focus { outline: none; }
h1, h2, h3, h4 { color: var(--text); }

.text-muted { color: var(--text-muted) !important; }

/* --- Blazor form validation --- */

.valid.modified:not([type=checkbox]) { outline: 1px solid var(--success); }
.invalid { outline: 1px solid var(--danger); }
.validation-message { color: var(--danger); }

/* --- Syncfusion grid: visual polish (light) --- */

.e-grid {
    border-radius: var(--brand-radius) !important;
    border: 1px solid var(--brand-border) !important;
    box-shadow: var(--shadow-sm);
}
.e-grid .e-gridheader {
    background: var(--surface-alt) !important;
    border-top-left-radius: var(--brand-radius);
    border-top-right-radius: var(--brand-radius);
}
.e-grid .e-gridpager {
    border-bottom-left-radius: var(--brand-radius);
    border-bottom-right-radius: var(--brand-radius);
    display: flex !important;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0.9rem !important;
}
.e-grid .e-gridpager .e-pagerdropdown,
.e-grid .e-gridpager .e-pagerconstant { order: 1; }
.e-grid .e-gridpager .e-parentmsgbar {
    order: 2;
    margin-left: auto;
    margin-right: auto;
    float: none !important;
    text-align: center;
}
.e-grid .e-gridpager .e-pagercontainer {
    order: 3;
    margin-left: auto;
    float: none !important;
}
.e-grid .e-headercell {
    font-weight: 600 !important;
    color: var(--text-muted) !important;
    font-size: 0.72rem !important;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding-top: 0.6rem !important;
    padding-bottom: 0.6rem !important;
}
.e-grid .e-rowcell {
    color: var(--text);
    padding-top: 0.55rem !important;
    padding-bottom: 0.55rem !important;
    font-size: 0.85rem !important;
}
.e-grid tr.e-row:hover .e-rowcell { background: var(--brand-50) !important; }
.e-grid tr.e-row:nth-child(even) .e-rowcell { background: var(--surface-alt); }
.e-grid tr.e-row:nth-child(even):hover .e-rowcell { background: var(--brand-50) !important; }

.e-pagerdropdown { margin-top: 6px !important; }

/* --- Syncfusion dialog: visual polish --- */

.e-dialog .e-dlg-header-content { background: var(--surface) !important; border-bottom: 1px solid var(--brand-border); }
.e-dialog .e-dlg-header { color: var(--text) !important; font-weight: 600; }

/* Wide modal (e.g. the discover-processes "assign clients" picker).
 * Syncfusion centres the box by setting an inline `left` computed from
 * its `Width`. A percentage Width plus a Tailwind `max-w-[…]` clamp made
 * the two disagree (left was computed for ~92% of the viewport while the
 * box was clamped to 1080px), so the box hugged the left edge. Give it a
 * fixed px Width (so Syncfusion's own maths is correct on roomy screens)
 * and centre it ourselves with margin:auto — that way the responsive cap
 * below can never knock it off-centre on smaller viewports. No transform,
 * so the open/close fade animation is untouched. */
.e-dialog.precep-dialog-wide {
    max-width: calc(100vw - 2rem);
    left: 0 !important;
    right: 0 !important;
    margin-inline: auto !important;
}

/* --- Blazor framework error boundary --- */

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

.blazor-error-boundary::after { content: "An error has occurred." }

/* --- Global search results (rendered via RenderTreeBuilder, not scoped) --- */

.result-group { padding: 0.35rem 0; }
.result-group + .result-group { border-top: 1px solid var(--brand-border); padding-top: 0.5rem; }

.group-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.35rem 1.15rem 0.25rem;
}
.group-label {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}
.group-count {
    background: var(--surface-alt);
    color: var(--text-muted);
    font-size: 0.68rem;
    font-weight: 500;
    padding: 0.05rem 0.4rem;
    border-radius: 8px;
}

.result-item {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    width: 100%;
    padding: 0.55rem 1.15rem;
    background: transparent;
    border: 0;
    text-align: left;
    cursor: pointer;
    transition: background 0.08s;
}
.result-item:hover, .result-item.selected { background: var(--brand-50); }

.result-icon {
    width: 32px; height: 32px;
    border-radius: 7px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.result-icon svg { width: 15px; height: 15px; }

.result-icon.icon-cases { background: #e0e7ff; color: #3730a3; }
.result-icon.icon-clients { background: #ffe4e6; color: #9f1239; }
.result-icon.icon-assignments { background: #d1fae5; color: #065f46; }
.result-icon.icon-deadlines { background: #fef3c7; color: #92400e; }
.result-icon.icon-communications { background: #dbeafe; color: #1e40af; }
.result-icon.icon-page { background: var(--brand-50); color: var(--brand-700); }

.result-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}
.result-title {
    font-size: 0.88rem;
    color: var(--text);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.result-subtitle {
    font-size: 0.76rem;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.result-subtitle.result-path {
    font-family: "SF Mono", ui-monospace, "Menlo", monospace;
    font-size: 0.72rem;
    color: var(--text-subtle);
}

/* Right-aligned type chip — keeps the result-row legible after scroll
   and makes the entity kind obvious without re-reading the group header. */
.result-chip {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    padding: 0.1rem 0.45rem;
    border-radius: 4px;
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    background: var(--surface-alt);
    color: var(--text-muted);
    border: 1px solid var(--brand-border);
}
.result-chip.chip-cases { background: #e0e7ff; color: #3730a3; border-color: transparent; }
.result-chip.chip-clients { background: #ffe4e6; color: #9f1239; border-color: transparent; }
.result-chip.chip-assignments { background: #d1fae5; color: #065f46; border-color: transparent; }
.result-chip.chip-deadlines { background: #fef3c7; color: #92400e; border-color: transparent; }
.result-chip.chip-communications { background: #dbeafe; color: #1e40af; border-color: transparent; }
.result-chip.chip-page { background: var(--brand-50); color: var(--brand-700); border-color: transparent; }

/* The "Ir para…" pages group is always rendered first; soft-divide it
   from the entity groups so users can visually skip past it. */
.result-group-pages { padding-bottom: 0.5rem; }

/* ====================================================================
 * Boot shell — static skeleton shown while WASM downloads + boots
 *
 * Lives at top of <body> in App.razor. Initially covers the viewport so
 * the user never sees a blank screen during Blazor's startup gap.
 * Faded out and removed by the inline script in App.razor once
 * MainLayout or a login card appears in the DOM (or after a 5s
 * safety timeout).
 *
 * Visual shapes mimic the actual layout — narrow sidebar with nav rows,
 * header with search + actions, content area with title + table — so
 * the perceived transition to the real UI feels like cells filling in
 * rather than a screen replacement.
 *
 * Respects the persisted `kt-sidebar-collapse` state via the same body
 * class the real sidebar listens to: when collapsed, the shell sidebar
 * shrinks to ~80px and only shows icon-sized pills.
 * ==================================================================== */

#precepto-boot-shell {
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: var(--background, #fff);
    display: flex;
    pointer-events: none;
    opacity: 1;
    transition: opacity 280ms ease;
}
body.precepto-ready #precepto-boot-shell {
    opacity: 0;
}

.boot-sidebar {
    width: 280px;
    border-inline-end: 1px solid color-mix(in oklab, currentColor 10%, transparent);
    padding: 18px 16px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex-shrink: 0;
}
.kt-sidebar-collapse .boot-sidebar {
    width: 80px;
    padding: 18px 10px;
}

.boot-logo {
    height: 28px;
    margin-bottom: 18px;
    border-radius: 6px;
    background: color-mix(in oklab, currentColor 12%, transparent);
    animation: boot-pulse 1.6s ease-in-out infinite;
}
.kt-sidebar-collapse .boot-logo {
    height: 36px;
    width: 36px;
    margin: 0 auto 18px;
}

.boot-nav-item {
    display: flex;
    align-items: center;
    gap: 12px;
    height: 38px;
    padding: 0 8px;
}
.kt-sidebar-collapse .boot-nav-item {
    justify-content: center;
    padding: 0;
}
.kt-sidebar-collapse .boot-nav-item .boot-pill-label { display: none; }

.boot-main {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.boot-header {
    height: 64px;
    border-block-end: 1px solid color-mix(in oklab, currentColor 10%, transparent);
    padding: 0 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}
.boot-header-actions {
    display: flex;
    align-items: center;
    gap: 12px;
}

.boot-content {
    padding: 28px 28px 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: 1280px;
    margin: 0 auto;
    width: 100%;
}

.boot-card {
    margin-top: 18px;
    border: 1px solid color-mix(in oklab, currentColor 10%, transparent);
    border-radius: 12px;
    overflow: hidden;
}
.boot-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 18px;
    border-block-end: 1px solid color-mix(in oklab, currentColor 8%, transparent);
}
.boot-row:last-child { border-block-end: none; }

.boot-pill {
    background: color-mix(in oklab, currentColor 12%, transparent);
    border-radius: 6px;
    animation: boot-pulse 1.6s ease-in-out infinite;
    display: inline-block;
}
.boot-pill-icon { width: 20px; height: 20px; border-radius: 6px; flex-shrink: 0; }
.boot-pill-label { height: 12px; width: 60%; }
.boot-pill-search { width: 320px; height: 36px; border-radius: 8px; }
.boot-pill-avatar { width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0; }
.boot-pill-title { width: 38%; height: 18px; }
.boot-pill-subtitle { width: 60%; height: 12px; }
.boot-pill-line { flex: 1; height: 12px; }
.boot-pill-tag { width: 80px; height: 22px; border-radius: 11px; flex-shrink: 0; }

@keyframes boot-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

@media (max-width: 1023px) {
    .boot-sidebar { display: none; }
    .boot-pill-search { width: 100%; max-width: 240px; }
    .boot-content { padding: 20px 16px 0; }
}

/* ====================================================================
 * Brand splash — the "loading geral": a full-screen logo + spinner shown
 * on the very first paint of any route, layered above the boot skeleton
 * (z-index 10000 > 9999). app-boot.js adds `precepto-splash-done` to fade
 * it out after a short minimum (revealing the route skeleton underneath),
 * or immediately once Blazor mounts. Background + currentColor inherit the
 * pre-painted light/dark theme so there's no flash; the wordmark swaps via
 * the same `.dark` class.
 * ==================================================================== */
#precepto-splash {
    position: fixed;
    inset: 0;
    z-index: 10000;
    background: var(--background, #fff);
    color: var(--foreground, #1B4F7A);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 28px;
    opacity: 1;
    transition: opacity 320ms ease;
}
body.precepto-splash-done #precepto-splash {
    opacity: 0;
    pointer-events: none;
}

.splash-logo { height: 40px; width: auto; }
.splash-logo-dark { display: none; }
.dark .splash-logo-light { display: none; }
.dark .splash-logo-dark { display: block; }

.splash-spinner {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 3px solid color-mix(in oklab, currentColor 16%, transparent);
    border-top-color: var(--primary, #1B4F7A);
    animation: precepto-spin 0.7s linear infinite;
}
.dark .splash-spinner {
    border-top-color: var(--ring, #B8893E);
}
@keyframes precepto-spin {
    to { transform: rotate(360deg); }
}

/* Auth-route boot skeleton — a centered card mirroring EmptyLayout's
 * max-w-[400px] login card, instead of the sidebar+content frame. Reuses
 * the shared #precepto-boot-shell fade + .boot-pill pulse. */
#precepto-boot-shell.boot-auth {
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.boot-auth-card {
    width: 100%;
    max-width: 400px;
    border: 1px solid color-mix(in oklab, currentColor 10%, transparent);
    border-radius: 12px;
    padding: 40px;
    display: flex;
    flex-direction: column;
    gap: 18px;
}
.boot-auth-logo { height: 34px; width: 150px; align-self: center; margin-bottom: 6px; }
.boot-auth-title { height: 22px; width: 55%; }
.boot-auth-subtitle { height: 12px; width: 80%; margin-bottom: 10px; }
.boot-auth-input { height: 44px; width: 100%; border-radius: 8px; }
.boot-auth-button { height: 44px; width: 100%; border-radius: 8px; margin-top: 6px; }

/* ====================================================================
 * Scrollbar — brand-aligned, cross-browser
 *
 * Replaces the default fat OS scrollbar with a 10px slim track that
 * matches the chrome's neutral palette. Thumb darkens on hover so the
 * interaction reads. Firefox uses the standard `scrollbar-color` +
 * `scrollbar-width` (no pseudo-element support); WebKit/Blink uses
 * `::-webkit-scrollbar`.
 *
 * Applied to the document and any scrollable element inside it.
 * `html` is the global root for page-level scrolling; the `*` rule
 * picks up inner scrollers (kt-card content, grid bodies, dialogs).
 *
 * Note: we deliberately don't touch Syncfusion-internal scrollers
 * (their wrappers have their own e-* classes and styling) — these
 * generic rules cascade but Syncfusion's specific selectors win.
 * ==================================================================== */

html {
    scrollbar-width: thin;
    scrollbar-color: color-mix(in oklab, currentColor 22%, transparent) transparent;
}

*::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}
*::-webkit-scrollbar-track {
    background: transparent;
}
*::-webkit-scrollbar-thumb {
    background: color-mix(in oklab, currentColor 18%, transparent);
    border-radius: 8px;
    transition: background-color 120ms ease;
}
*::-webkit-scrollbar-thumb:hover {
    background: color-mix(in oklab, currentColor 32%, transparent);
}
*::-webkit-scrollbar-corner {
    background: transparent;
}

/* Dark-mode tweak — currentColor inheritance handles most cases, but
   explicitly bumping the alpha helps the thumb stay legible against
   the darker surfaces. */
html.dark {
    scrollbar-color: color-mix(in oklab, currentColor 30%, transparent) transparent;
}
html.dark *::-webkit-scrollbar-thumb {
    background: color-mix(in oklab, currentColor 26%, transparent);
}
html.dark *::-webkit-scrollbar-thumb:hover {
    background: color-mix(in oklab, currentColor 42%, transparent);
}

/* ====================================================================
 * Page transition — subtle fade-in on route change
 *
 * MainLayout + the Router are static SSR; only the page islands are
 * interactive WASM, so navigation between routes is an *enhanced*
 * navigation that patches (rather than recreates) the `#page-content`
 * wrapper. A plain CSS animation on that element therefore wouldn't
 * replay on its own — precepto-ktui.js re-triggers it by toggling the
 * `.page-fade-in` class on each `blazor:enhancedload` (same hook it uses
 * to re-init KT components). Kept short (200ms) so navigation still
 * feels instant. Honours reduced-motion.
 * ==================================================================== */
@keyframes preceptoPageFade {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}
.page-fade-in {
    animation: preceptoPageFade 0.2s ease-out;
}
@media (prefers-reduced-motion: reduce) {
    .page-fade-in { animation: none; }
}

/* ====================================================================
 * Collapsed-sidebar tooltips
 *
 * When the sidebar is minimised the `.kt-menu-title` labels are hidden,
 * leaving only icons. precepto-ktui.js shows this tooltip (its text taken
 * from the hovered item's label) on hover, but ONLY while collapsed —
 * expanded items already show their label inline. The element is appended
 * to <body> and positioned with `position: fixed` so the sidebar's
 * scroll-overflow never clips it (a plain `::after` would be cut off).
 * Native browser tooltips are suppressed by using `aria-label` instead of
 * `title` on the menu items (see NavMenu.razor), so there's no duplicate.
 * ==================================================================== */
.sidebar-tip {
    position: fixed;
    z-index: 100;
    transform: translateY(-50%);
    padding: 0.3rem 0.6rem;
    border-radius: 0.375rem;
    background: var(--primary);
    color: var(--primary-foreground);
    font-size: 0.8125rem;
    font-weight: 500;
    line-height: 1.1;
    white-space: nowrap;
    pointer-events: none;
    box-shadow: 0 4px 14px color-mix(in oklab, var(--primary) 35%, transparent);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.12s ease-out;
}
.sidebar-tip.show {
    opacity: 1;
    visibility: visible;
}
/* Little arrow pointing back at the icon */
.sidebar-tip::before {
    content: "";
    position: absolute;
    top: 50%;
    inset-inline-start: -4px;
    width: 8px;
    height: 8px;
    transform: translateY(-50%) rotate(45deg);
    background: var(--primary);
}

/* ====================================================================
 * Collapsed-sidebar submenu flyout
 *
 * Panel positioned via JS (precepto-ktui.js), appended to <body> so it
 * escapes the sidebar's overflow clip. It holds the sub-items cloned from
 * `.kt-menu-accordion` — they carry the kt-menu-* classes but NOT the
 * sidebar styling (which is scoped to #sidebar), so we style them here.
 * Replaces the inline accordion (which flickered) while the sidebar is
 * collapsed. See the "submenu flyout" IIFE in precepto-ktui.js.
 * ==================================================================== */
.sidebar-flyout {
    position: fixed;
    z-index: 90;
    min-width: 210px;
    max-width: 260px;
    padding: 0.375rem;
    border-radius: 0.5rem;
    background: var(--card);
    border: 1px solid var(--border);
    box-shadow: 0 12px 32px color-mix(in oklab, var(--primary) 18%, transparent);
    opacity: 0;
    visibility: hidden;
    transform: translateX(-4px);
    transition: opacity 0.12s ease-out, transform 0.12s ease-out;
}
.sidebar-flyout.show {
    opacity: 1;
    visibility: visible;
    transform: none;
}
.sidebar-flyout-head {
    padding: 0.25rem 0.5rem 0.4rem;
    margin-bottom: 0.25rem;
    border-bottom: 1px solid var(--border);
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--primary);
}
.sidebar-flyout-items {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}
.sidebar-flyout .kt-menu-item { display: block; }
.sidebar-flyout .kt-menu-link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.5rem;
    border-radius: 0.375rem;
    color: var(--foreground);
    font-size: 0.8125rem;
    text-decoration: none;
    cursor: pointer;
}
.sidebar-flyout .kt-menu-item:hover .kt-menu-link {
    background: color-mix(in oklab, var(--primary) 9%, transparent);
    color: var(--primary);
}
/* Current-route item inside the flyout. Overrides the sidebar's "active"
   styling — which paints a solid navy fill + white text + ochre bar
   (inset box-shadow) — with a version legible on the light panel: soft navy
   fill, navy text, thin navy mark on the leading edge. !important because the
   global active rules (.kt-menu-item-active …) use it too. */
.sidebar-flyout .kt-menu-item-active .kt-menu-link {
    background: color-mix(in oklab, var(--primary) 12%, transparent) !important;
    box-shadow: inset 2px 0 0 0 var(--primary) !important;
    color: var(--primary) !important;
}
.sidebar-flyout .kt-menu-item-active .kt-menu-link .kt-menu-title,
.sidebar-flyout .kt-menu-item-active .kt-menu-link .kt-menu-icon {
    color: var(--primary) !important;
}
.sidebar-flyout .kt-menu-title {
    display: inline !important;
    font-weight: 500;
}
.sidebar-flyout .kt-menu-icon {
    display: inline-flex;
    align-items: center;
    width: 18px;
    flex-shrink: 0;
    color: var(--muted-foreground);
}
.sidebar-flyout .kt-menu-item:hover .kt-menu-icon,
.sidebar-flyout .kt-menu-item-active .kt-menu-icon {
    color: var(--primary);
}
/* Show only the outline icon; hide the filled (active-state) one and badges */
.sidebar-flyout .nav-icon-default { display: inline-flex; }
.sidebar-flyout .nav-icon-active,
.sidebar-flyout .kt-menu-badge,
.sidebar-flyout .kt-menu-badge-dot,
.sidebar-flyout .kt-menu-arrow { display: none; }

/* ====================================================================
 * Sidebar width — a touch wider so the selected menu item reads larger.
 * Overrides Metronic's `.demo1 { --sidebar-width: 280px }` (defined inside
 * @layer components, so this unlayered rule wins regardless of order). The
 * same var drives the content's inline-start offset, so everything stays
 * aligned to the sidebar edge — only the rail (and its items) grow ~16px.
 * ==================================================================== */
.demo1 {
    --sidebar-width: 286px;
    --sidebar-default-width: 286px;
}

/* The base rule above is UNLAYERED, so it also beats Metronic's layered
 * collapse reassignment (`.demo1.kt-sidebar-collapse { --sidebar-width:
 * var(--sidebar-width-collapse) }`, inside @layer components). Without this,
 * `--sidebar-width` stays 286px when collapsed → the rail never shrinks and
 * the icons sit centred in a 286px-wide band with a big empty gap. Re-assert
 * the collapse width unlayered: `.kt-sidebar-collapse` is more specific than
 * the base `.demo1`, so it wins ONLY when the sidebar is collapsed. */
.demo1.kt-sidebar-collapse {
    --sidebar-width: var(--sidebar-width-collapse);
}

/* A single chevron communicates hierarchy more clearly than +/- and follows
 * KTMenu's canonical `.show` state. */
.nav-group-chevron {
    transform-origin: center;
    transition: transform 160ms ease;
}

.sidebar-menu-group.show > .kt-menu-link .nav-group-chevron {
    transform: rotate(90deg);
}

/* ====================================================================
 * UX-05 — hide the grid pager while there are no rows.
 *
 * Our list grids use a CustomAdaptor (server-side paging), so the
 * component never holds the row collection to gate the pager from C#.
 * Instead key off the DOM: Syncfusion renders `.e-emptyrow` both for
 * the empty state and during the initial skeleton load — in either case
 * a lone "1 · 10 ▾ · ‹ ›" pager bar reads as broken. `:has()` is
 * supported by every browser the WASM runtime targets.
 * ==================================================================== */
.e-grid:has(.e-emptyrow) .e-gridpager {
    /* Beats the unconditional `.e-grid .e-gridpager { display: flex !important }`
       above — without !important here the pager stays visible on empty grids. */
    display: none !important;
}

/* ====================================================================
 * Syncfusion tailwind3 theme — recolor the primary palette to the
 * Precepto brand.
 *
 * The stock tailwind3 theme ships an indigo primary (#4f46e5 family) that
 * clashes with our navy + ochre identity. Rather than swap the component,
 * we remap the theme's `--color-sf-primary-*` custom properties onto the
 * brand tokens: fills follow `var(--primary)` (Azul Marinho #1B4F7A light /
 * Azul Médio #2B7CB5 dark), darker shades via color-mix, the focus ring
 * uses `var(--ring)` (ochre #B8893E), and text-on-primary uses
 * `var(--primary-foreground)`. Because those tokens already flip between
 * light and dark in css/styles.css, this ONE block covers both modes.
 *
 * `!important` is required: app.css is linked BEFORE tailwind3.css, so the
 * theme's own `:root` would otherwise win on source order. These vars feed
 * colour only (no layout/collapse math), so forcing them is safe.
 * ==================================================================== */
:root {
    --color-sf-primary: var(--primary) !important;

    /* Solid fills (buttons, selected cells, active view button) */
    --color-sf-primary-bg-color: var(--primary) !important;
    --color-sf-primary-bg-color-hover: color-mix(in oklab, var(--primary) 86%, black) !important;
    --color-sf-primary-bg-color-focus: color-mix(in oklab, var(--primary) 86%, black) !important;
    --color-sf-primary-bg-color-pressed: color-mix(in oklab, var(--primary) 74%, black) !important;
    --color-sf-primary-bg-color-disabled: color-mix(in oklab, var(--primary) 42%, white) !important;

    /* Borders mirror the fills */
    --color-sf-primary-border-color: var(--primary) !important;
    --color-sf-primary-border-color-hover: color-mix(in oklab, var(--primary) 86%, black) !important;
    --color-sf-primary-border-color-focus: color-mix(in oklab, var(--primary) 86%, black) !important;
    --color-sf-primary-border-color-pressed: color-mix(in oklab, var(--primary) 74%, black) !important;
    --color-sf-primary-border-color-disabled: color-mix(in oklab, var(--primary) 42%, white) !important;

    /* Accent shades used for tints, hovers and subtle highlights */
    --color-sf-primary-dark: color-mix(in oklab, var(--primary) 86%, black) !important;
    --color-sf-primary-darker: color-mix(in oklab, var(--primary) 74%, black) !important;
    --color-sf-primary-light: color-mix(in oklab, var(--primary) 55%, white) !important;
    --color-sf-primary-lighter: color-mix(in oklab, var(--primary) 12%, white) !important;

    /* Focus ring → brand ochre, matching our native inputs' --ring */
    --color-sf-primary-outline: var(--ring) !important;

    /* Text sitting on a primary fill stays white in both modes */
    --color-sf-primary-text: var(--primary-foreground) !important;
    --color-sf-primary-text-color: var(--primary-foreground) !important;
    --color-sf-primary-text-hover: var(--primary-foreground) !important;
    --color-sf-primary-text-focus: var(--primary-foreground) !important;
    --color-sf-primary-text-pressed: var(--primary-foreground) !important;
    --color-sf-primary-text-disabled: rgba(255, 255, 255, .45) !important;
}

/* ────────────────────────────────────────────────────────────────────────
   AI inline case linker (embedded in AiSuggestionPanel when the lawyer
   confirms accept on a suggestion for an unlinked communication).
   ──────────────────────────────────────────────────────────────────────── */
.ai-inline-case-linker {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding-top: 0.75rem;
    margin-top: 0.75rem;
    border-top: 1px solid var(--kt-border-color, #e5e7eb);
}

.ai-inline-case-linker .linker-mode-tabs {
    display: flex;
    flex-direction: row;
    gap: 1rem;
    font-size: 0.8125rem;
}

.ai-inline-case-linker .linker-mode-tabs label {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    cursor: pointer;
    user-select: none;
}

.ai-inline-case-linker .linker-actions {
    display: flex;
    flex-direction: row;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 0.25rem;
}

/* Privacy mode ("olhinho") — masked money/stat values render as larger-font
   asterisks so the masked state reads clearly, password-field style. Global
   (not scoped) because <Money>/<Private> render inside Base WASM pages whose
   scoped CSS this file cannot reach. Sizes are tunable in visual spot-check. */
.privacy-mask {
    font-size: 1.25em;
    letter-spacing: 0.12em;
    line-height: 1;
    vertical-align: -0.05em;
}

/* ────────────────────────────────────────────────────────────────────────
   Two-line dropdown option — the record on top, its qualifier beneath
   (a case number over its client, a deadline type over its catalog group).
   Used by the deadline-type pickers and by the case pickers in the
   assignment, deadline and event editors, so the collapsed box reads
   exactly like the row it was picked from.

   Global rather than scoped for two reasons: Syncfusion renders its popup
   at body level, and its input DOM is out of reach of a .razor.css scope
   without ::deep. Mark any ancestor of the select with `dd-two-line`; in
   the editors that is a bare wrapper around the select alone, so the
   label keeps the spacing its full-width siblings have.
   ──────────────────────────────────────────────────────────────────────── */
.dd-two-line { width: 100%; }

.dd-two-line-option { display: flex; flex-direction: column; gap: 0.05rem; line-height: 1.25; min-width: 0; }
.dd-two-line-option__name { font-size: 0.85rem; color: var(--text); white-space: normal; }
/* Not plain --text-muted: at 0.7rem on Syncfusion's white flyout that is 3.7:1, and
   2.98:1 on the row under the cursor. Before these templates existed the second line
   inherited the list item's own #111827, so shipping --text-muted here would have made
   the client name markedly harder to read than it was. Mixing toward --text moves away
   from the background in BOTH themes — 6.1:1 on white, 4.9:1 on the active row, and
   lighter (not darker) against the dark popup — while staying clearly subordinate to
   the name line. */
.dd-two-line-option__meta { font-size: 0.7rem; color: color-mix(in srgb, var(--text-muted) 40%, var(--text)); }

/* Syncfusion sizes the input group for one line of text. The ValueTemplate
   renders inside it, so the second line is clipped unless the box may grow;
   the icons then need centring against a box that is no longer one line tall. */
.dd-two-line .e-ddl.e-input-group { height: auto; min-height: 2.5rem; }
/* `input` belongs here too: with nothing selected Syncfusion shows its own input
   carrying the placeholder, not the ValueTemplate, and a 30px input left to stretch
   inside a 40px box puts that placeholder above the line the other fields sit on. */
.dd-two-line .e-ddl .e-input-value,
.dd-two-line .e-ddl input,
.dd-two-line .e-ddl .e-input-group-icon,
.dd-two-line .e-ddl .e-clear-icon { align-self: center; }
/* The ValueTemplate replaces Syncfusion's own input, and with it the
   horizontal padding that kept text off the border — put it back. */
.dd-two-line .e-ddl .e-input-value { padding-block: 0.3rem; padding-inline-start: 12px; width: 100%; }
