/* <Modal /> — default styling, lm-modal-* convention.
 *
 * COEXISTENCE: rules are guarded with :where(.lm-modal-root) — v6 markup
 * always wraps the panel in the root, v5 (and jspreadsheet's embedded v5
 * widgets) never does, so v6 styles can no longer clobber a v5 modal on
 * the same page (unscoped .lm-modal rules pulled jss's context menu into
 * the layout flow). :where() adds ZERO specificity, so consumer overrides
 * (.lm-contextmenu .lm-modal, .lm-dropdown .lm-modal-content, ...) keep
 * their existing cascade weight. Against v5 leakage on SHARED class names
 * (.lm-modal-title header-bar styles, .lm-modal min-height/transition)
 * the panel/title rules reset those properties explicitly and win by
 * load order (v6 css links come after the jspreadsheet/jsuites css); the
 * one v5 selector that outguns that (`.lm-modal > div:last-child`) is
 * beaten by a dedicated higher-specificity content reset below. */
.lm-modal-root {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    z-index: 50;
}

.lm-modal-root[data-position='left'] {
    justify-content: flex-start;
}

.lm-modal-root[data-position='right'] {
    justify-content: flex-end;
}

/* left/right are the side PANEL modes: full viewport height, square
   corners; any width/height props keep controlling the panel width */
.lm-modal-root[data-position='left'] .lm-modal:not(.lm-modal-minimized),
.lm-modal-root[data-position='right'] .lm-modal:not(.lm-modal-minimized) {
    height: 100% !important;
    max-height: 100%;
    border-radius: 0;
}

.lm-modal-root[data-position='bottom'] {
    align-items: flex-end;
}

.lm-modal-root[data-position='bottom'] .lm-modal:not(.lm-modal-minimized) {
    border-radius: 8px 8px 0 0;
}

/* radius=false: square panel (anchored panels — a dropdown under a
   4px-radius input reads wrong with 8px corners). The second selector
   outweighs the position variants above; minimized chips keep theirs. */
:where(.lm-modal-root) .lm-modal[data-radius='false'],
.lm-modal-root[data-position] .lm-modal[data-radius='false']:not(.lm-modal-minimized) {
    border-radius: 0;
}

/* absolute: CSS-anchored panel — the HOST's positioned ancestor places it
   (a dropdown panel under its input) and scrolling follows natively */
.lm-modal-root[data-position='absolute'] {
    position: absolute;
    inset: auto;
    display: block;
}

:where(.lm-modal-root) .lm-modal-backdrop {
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    background: rgba(0, 0, 0, 0.35);
    pointer-events: auto;
    animation: lm-modal-backdrop-in 0.2s ease;
}

:where(.lm-modal-root) .lm-modal {
    /* Elevation lives in a custom prop so the focus/dark variants swap the
       VALUE and every rule that must repaint the shadow reads one source */
    --lm-modal-shadow: 0 8px 24px rgba(0, 0, 0, 0.11);
    position: relative;
    pointer-events: auto;
    background: var(--lm-background-color, #fff);
    /* hairline carries the edge definition (shadow stays subtle); also
       explicitly overrides v5/jsuites' 1px #ccc border on this class */
    border: 1px solid var(--lm-border-color, #e4e4e7);
    border-radius: 8px;
    box-shadow: var(--lm-modal-shadow);
    box-sizing: border-box;
    min-width: 280px;
    min-height: 0;
    max-width: calc(100vw - 32px);
    max-height: calc(100vh - 32px);
    margin: 0;
    display: flex;
    flex-direction: column;
    outline: none;
    font: 14px/1.5 system-ui, sans-serif;
    transition: none;
    animation: lm-modal-in 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}

@keyframes lm-modal-in {
    from {
        opacity: 0;
        transform: scale(0.96) translateY(8px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes lm-modal-backdrop-in {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@media (prefers-reduced-motion: reduce) {
    :where(.lm-modal-root) .lm-modal,
    :where(.lm-modal-root) .lm-modal-backdrop {
        animation: none;
    }
}

:where(.lm-modal-root) .lm-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--lm-border-color, #e4e4e7);
    user-select: none;
}

/* explicit width/padding/border resets: v5's .lm-modal-title styles the
   whole HEADER BAR (full width, bottom border) on this same class name */
:where(.lm-modal-root) .lm-modal-title {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    width: auto;
    padding: 0;
    border: 0;
    border-radius: 0;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.4;
}

/* optional leading icon (`icon` prop — material icon name) */
:where(.lm-modal-root) .lm-modal-icon {
    font-size: 20px;
    line-height: 1;
    color: var(--lm-icon-color, #5f6368);
}

:where(.lm-modal-root) .lm-modal-controls {
    display: flex;
    align-items: center;
    gap: 4px;
    /* header pads 12px top / 16px right — pull the buttons 4px right so
       the close button sits at the same distance from top and right */
    margin-right: -4px;
}

/* classed selectors, not `button` — a host page's element resets must not
   find our controls through a bare tag, and vice versa */
:where(.lm-modal-root) .lm-modal-close,
:where(.lm-modal-root) .lm-modal-minimize {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    appearance: none;
    background: transparent;
    width: 32px;
    height: 32px;
    padding: 0;
    margin: 0;
    border-radius: var(--lm-radius, 6px);
    cursor: pointer;
    color: var(--lm-font-grayout, #52525b);
    font: inherit;
}

/* the chip background is the HOVER highlight only — not a rest state */
:where(.lm-modal-root) .lm-modal-close:hover,
:where(.lm-modal-root) .lm-modal-minimize:hover {
    background: var(--lm-background-color-highlight, #f4f4f5);
    color: var(--lm-font-color, #18181b);
}

/* inline SVG icons (no icon-font dependency): crisp 2px strokes */
:where(.lm-modal-root) .lm-modal-close svg,
:where(.lm-modal-root) .lm-modal-minimize svg {
    width: 20px;
    height: 20px;
    display: block;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

:where(.lm-modal-root) .lm-modal-content {
    padding: 16px;
    flex: 1;
}

/* v5 defense, deliberately ABOVE consumer weight for these three props
   only: v5's `.lm-modal > div:last-child` (0-2-1) forces width/height
   100% onto the content box and nothing lighter can undo it */
.lm-modal-root .lm-modal > .lm-modal-content {
    width: auto;
    height: auto;
    box-sizing: border-box;
}

:where(.lm-modal-root) .lm-modal-overflow .lm-modal-content {
    overflow: auto;
}

/* Minimized: docked to the bottom taskbar row (positions set by the dock) */
:where(.lm-modal-root) .lm-modal-minimized {
    width: 195px !important;
    height: 40px !important;
    min-width: 0;
    transition: top 0.3s ease, left 0.3s ease, box-shadow 0.15s ease;
    overflow: hidden;
}

:where(.lm-modal-root) .lm-modal-minimized .lm-modal-content {
    display: none;
}

:where(.lm-modal-root) .lm-modal-minimized .lm-modal-header {
    border-bottom: 0;
    cursor: pointer;
    box-sizing: border-box;
    height: 40px;
    padding: 0 6px 0 14px;
}

:where(.lm-modal-root) .lm-modal-minimized .lm-modal-title {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

:where(.lm-modal-root) .lm-modal-minimized:hover {
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
}

:where(.lm-modal-root) .lm-modal-minimized:hover .lm-modal-header {
    background: var(--lm-background-color-highlight, #f4f4f5);
}

/* During drag/resize: no transitions, no accidental selection */
:where(.lm-modal-root) .lm-modal-action {
    transition: none !important;
    user-select: none;
}

/* front/focused modal: same elevation as at rest — deliberately NO shadow
   bump and NO ring/outline (an extra shadow on focus read as flicker);
   the class stays as a marker for the layering logic */

/* Dark mode: a black shadow barely reads on a dark page, so deepen the
   alpha AND add a hairline for separation. Forced-class and OS-driven
   paths share the values (CSS can't share the block). */
.lm-dark-mode :where(.lm-modal-root) .lm-modal {
    --lm-modal-shadow: 0 6px 18px rgba(0, 0, 0, 0.55);
}

@media (prefers-color-scheme: dark) {
    :root:not(.lm-light-mode) :where(.lm-modal-root) .lm-modal {
        --lm-modal-shadow: 0 6px 18px rgba(0, 0, 0, 0.55);
    }
}

/* Keyboard focus stays visible (WCAG 2.4.7): the base rule's outline:none
   only silences pointer/programmatic focus — :focus-visible paints a ring
   whenever the panel is reached through the keyboard. The `outline` prop
   keeps its stronger always-on catalog ring below. */
:where(.lm-modal-root) .lm-modal:focus-visible {
    outline: 2px solid var(--lm-border-outline, #000);
    outline-offset: -1px;
}

.lm-modal-root .lm-modal[data-outline='true']:focus-visible {
    outline: 2px solid var(--lm-border-outline, #000);
    outline-offset: -1px;
}

:where(.lm-modal-root) .lm-modal-fullscreen {
    position: fixed !important;
    inset: 0;
    width: 100% !important;
    height: 100% !important;
    max-width: none;
    max-height: none;
    border-radius: 0;
    margin: 0;
}

/* Resize is edge-based (8 directions, 10px zones) — no handle element */
