/* vvr.web — design system. Tokens + shared components; pages compose these classes
   instead of carrying their own copies. See CLAUDE.md → "Color & UI style". */

@font-face {
    font-family: "Pretendard Variable";
    font-weight: 45 920;
    font-style: normal;
    font-display: swap;
    src: url("fonts/PretendardVariable.woff2") format("woff2-variations");
}

:root {
    color-scheme: dark;

    /* surfaces */
    --bg: #000000;
    --surface: #0c0c0c;          /* panels, cards */
    --surface-2: #151515;        /* inputs, table header, nested blocks */
    --surface-hover: #1b1b1b;    /* hovered rows / controls */
    --line: #232323;             /* default borders & dividers */
    --line-strong: #353535;      /* secondary button borders, focused rows */

    /* text — 3 tiers */
    --fg: #fafafa;
    --muted: #a3a3a3;            /* labels, descriptions, table headers */
    --faint: #6e6e6e;            /* placeholders, footnotes, disabled */

    /* primary action = inverted (white fill, black text) */
    --accent: #fafafa;
    --accent-fg: #0a0a0a;
    --accent-hover: #e2e2e2;
    --focus-ring: 0 0 0 3px rgba(250, 250, 250, 0.12);

    /* status */
    --success: #3ecf8e;
    --success-soft: rgba(62, 207, 142, 0.12);
    --warning: #f5a524;
    --warning-soft: rgba(245, 165, 36, 0.12);
    --danger: #f25555;
    --danger-soft: rgba(242, 85, 85, 0.12);
    --info: #6ea8fe;
    --info-soft: rgba(110, 168, 254, 0.12);

    --font: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo",
            "Malgun Gothic", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    --mono: "JetBrains Mono", "Geist Mono", "SF Mono", Menlo, Consolas, ui-monospace, monospace;

    --radius-sm: 6px;
    --radius: 8px;
    --radius-lg: 12px;

    --topbar-h: 56px;
    --container: 1200px;
    --ease: 0.15s ease;

    /* legacy aliases — kept so any stray page style still resolves */
    --bg-sidebar: var(--surface);
    --bg-elev: var(--surface-2);
    --bg-elev-hover: var(--surface-hover);
    --border: var(--line);
    --border-strong: var(--line-strong);
    --fg-mid: var(--muted);
    --fg-dim: var(--faint);
    --accent-dim: #bdbdbd;
}

/* ------------------------------------------------------------------ base */

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

/* Component classes set display:flex/grid — the hidden attribute (used by page JS) must still win. */
[hidden] { display: none !important; }

/* FocusOnNavigate (Routes.razor) focuses the page h1; don't paint a ring for that programmatic focus. */
h1:focus { outline: none; }

/* Reserve the scrollbar's column on every page. The scrollbar is styled (::-webkit-scrollbar below), so it
   takes layout space even on macOS; without this, going from a short page to a long one narrows the
   viewport and the centred top bar — tabs and all — jumps sideways. The track is transparent. */
html { overflow-y: scroll; }

html, body {
    margin: 0;
    background: var(--bg);
    color: var(--fg);
    font-family: var(--font);
    font-size: 14px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
    margin: 0;
    color: var(--fg);
    font-weight: 600;
    letter-spacing: -0.015em;
    line-height: 1.3;
}

p { margin: 0; }

a { color: var(--fg); text-decoration: none; transition: color var(--ease), opacity var(--ease); }
a:hover { color: var(--accent-hover); }
a.link { text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 3px; }
a.link:hover { text-decoration-color: var(--fg); }

code, kbd, samp, .mono { font-family: var(--mono); font-size: 0.92em; }
code {
    color: var(--fg);
    background: var(--surface-2);
    border: 1px solid var(--line);
    padding: 0.05rem 0.35rem;
    border-radius: 4px;
    word-break: break-word;
}
pre, .code-block {
    margin: 0;
    font-family: var(--mono);
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--fg);
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 0.85rem 1rem;
    overflow: auto;
    white-space: pre;
}

hr { border: none; border-top: 1px solid var(--line); margin: 1.25rem 0; }

::selection { background: var(--fg); color: var(--bg); }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(250, 250, 250, 0.16); border-radius: 999px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: rgba(250, 250, 250, 0.3); }

/* ------------------------------------------------------------ app shell */

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

.topbar {
    position: sticky;
    top: 0;
    z-index: 50;
    /* Solid, no backdrop-filter: a filter makes the bar the containing block for position:fixed
       descendants, which would pin the bell's toasts and click-away scrim inside the 56px bar. */
    background: var(--bg);
    border-bottom: 1px solid var(--line);
}
.topbar-inner {
    max-width: var(--container);
    margin: 0 auto;
    padding: 0 24px;
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: 28px;
}
.brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 700;
    font-size: 15px;
    letter-spacing: -0.02em;
    color: var(--fg);
    white-space: nowrap;
}
/* Logo ▌vvr▐ — the desktop app icon's white square (8% corners), drawn as two halves. On a full page load
   the halves sit together as one square that turns in at its centre; then they part and "vvr" comes out of
   the gap (the middle grid track grows 0fr → 1fr, the word unclips from its centre). --logo-mark is the
   square's side; everything else scales from it. The top bar is static SSR, so enhanced navigation keeps
   these nodes and the intro plays once per full load. Component: Layout/Logo.razor.
   .logo holds the finished ▌vvr▐'s width from the first frame (an invisible "vvr" in ::before, padded by
   the halves) and .logo-body animates centred inside it — the split never changes the box, so the top
   bar's tabs next to it don't slide while it plays. The body spans that full width and centres its tracks
   (so the halves part at the same speed — a shrink-to-fit body grew with the gap and the right half lagged),
   and the word stays centred in its track while the gap opens. */
.logo {
    --logo-mark: 22px;
    --logo-half: calc(var(--logo-mark) / 2);
    --logo-r: calc(var(--logo-mark) * 0.08);
    --logo-pad: calc(var(--logo-mark) * 0.2);
    display: inline-grid;
    align-items: center;
    justify-items: center;
    height: var(--logo-mark);
    vertical-align: middle;
}
.logo-lg { --logo-mark: 64px; }
.logo::before {
    content: "vvr";
    grid-area: 1 / 1;
    visibility: hidden;
    padding: 0 calc(var(--logo-half) + var(--logo-pad));
}
.logo-body {
    grid-area: 1 / 1;
    display: grid;
    justify-self: stretch;
    justify-content: center;
    grid-template-columns: var(--logo-half) minmax(0, 1fr) var(--logo-half);
    align-items: center;
    height: 100%;
    animation:
        logo-turn 0.8s cubic-bezier(0.65, 0, 0.35, 1) both,
        logo-split 0.55s cubic-bezier(0.65, 0, 0.35, 1) 0.8s both;
}
.logo-half { height: 100%; background: var(--fg); }
.logo-half.l { border-radius: var(--logo-r) 0 0 var(--logo-r); }
.logo-half.r { border-radius: 0 var(--logo-r) var(--logo-r) 0; }
.logo-word { min-width: 0; overflow: hidden; display: flex; justify-content: center; }
.logo-word > span {
    display: block;
    padding: 0 var(--logo-pad);
    /* optical centring: lowercase "vvr" is all x-height, so centre that, not the em box */
    transform: translateY(-0.04em);
    animation: logo-word 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) 0.95s both;
}
.logo::before, .logo-word > span {
    font-family: var(--font);
    font-size: calc(var(--logo-mark) * 0.82);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.05em;
    white-space: nowrap;
    color: var(--fg);
}
@keyframes logo-turn {
    from { transform: rotate(-180deg) scale(0.55); opacity: 0; }
    30% { opacity: 1; }
    to { transform: rotate(0) scale(1); opacity: 1; }
}
@keyframes logo-split {
    from { grid-template-columns: var(--logo-half) minmax(0, 0fr) var(--logo-half); }
    to { grid-template-columns: var(--logo-half) minmax(0, 1fr) var(--logo-half); }
}
@keyframes logo-word {
    from { opacity: 0; clip-path: inset(0 50% 0 50%); }
    to { opacity: 1; clip-path: inset(0 0 0 0); }
}
@media (prefers-reduced-motion: reduce) {
    .logo-body, .logo-word > span { animation: none; }
}
.nav-tabs {
    display: flex;
    align-items: stretch;
    gap: 2px;
    height: 100%;
    overflow-x: auto;
    overflow-y: hidden; /* x-scroll alone makes y "auto" too; the active tab's -1px underline then scrolls vertically */
    scrollbar-width: none;
    flex: 1;
    min-width: 0;
}
.nav-tabs::-webkit-scrollbar { display: none; }
.nav-tab {
    display: inline-flex;
    align-items: center;
    padding: 0 12px;
    color: var(--muted);
    font-size: 13px;
    font-weight: 500;
    white-space: nowrap;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color var(--ease), border-color var(--ease);
}
.nav-tab:hover { color: var(--fg); }
.nav-tab.active { color: var(--fg); border-bottom-color: var(--fg); }

/* 밑줄 하나가 탭 사이를 미끄러져 다닌다(wwwroot/js/nav-transitions.js). 밑줄은 TopBar.razor 의 .nav-rail
   (data-permanent) 안에 스크립트가 만든다 — 페이지를 옮겨도 지워지지 않고 제자리에서 출발한다.
   스크립트가 자리를 잡기 전에는 위의 탭별 밑줄이 보이고, 잡은 뒤(.is-on)에는 이것으로 바뀐다.
   탭을 누르면 페이지가 오기 전에 밑줄과 글자색이 먼저 옮겨 간다(.is-pending · .is-target) — 서버가 새
   페이지를 주면 enhanced navigation 이 이 두 클래스를 지운다. */
.nav-tabs { position: relative; }
.nav-tabs:has(> .nav-rail > .nav-indicator.is-on) .nav-tab.active { border-bottom-color: transparent; }
.nav-tabs.is-pending .nav-tab.active { color: var(--muted); }
.nav-tabs.is-pending .nav-tab.is-target { color: var(--fg); }
.nav-rail { position: absolute; left: 0; bottom: 0; width: 0; height: 2px; pointer-events: none; }
.nav-indicator {
    position: absolute;
    left: 0;
    top: 0;
    width: 0;
    height: 2px;
    border-radius: 2px;
    background: var(--fg);
    opacity: 0;
    pointer-events: none;
    transition:
        transform 0.38s cubic-bezier(0.22, 1, 0.36, 1),
        width 0.38s cubic-bezier(0.22, 1, 0.36, 1),
        opacity 0.2s ease;
}

/* 탭을 옮기면 본문이 그 방향에서 스며든다. 끝나면 transform 이 none 이라 안쪽의 fixed 요소
   (카드 판·토스트)의 기준을 바꾸지 않는다. */
.page-enter { animation: page-in 0.3s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.page-enter.from-right { --page-dx: 16px; }
.page-enter.from-left { --page-dx: -16px; }
@keyframes page-in {
    from { opacity: 0; transform: translateX(var(--page-dx, 16px)); }
    to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .nav-indicator { transition: none; }
    .page-enter { animation: none; }
}

.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.user-menu { position: relative; }

/* notification bell (Layout/NotificationBell.razor) */
.bell { position: relative; }
.bell-btn {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 34px; height: 34px;
    border-radius: 999px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--muted);
    cursor: pointer;
    transition: color var(--ease), background var(--ease), border-color var(--ease);
}
.bell-btn:hover, .bell-btn.open { color: var(--fg); background: var(--surface); border-color: var(--line); }
.bell-btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.bell-count {
    position: absolute;
    top: 1px; right: -2px;
    min-width: 17px; height: 17px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--danger);
    color: #fff;
    font-size: 10.5px;
    font-weight: 700;
    line-height: 17px;
    text-align: center;
    font-variant-numeric: tabular-nums;
    box-shadow: 0 0 0 2px var(--bg);
}
.bell-scrim { position: fixed; inset: 0; z-index: 55; }
.bell-panel { width: min(380px, calc(100vw - 24px)); padding: 0; right: -4px; }
.bell-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 10px 10px 14px; border-bottom: 1px solid var(--line); min-height: 48px; }
.bell-head strong { font-size: 14px; }
.bell-list { max-height: min(60vh, 460px); overflow-y: auto; }
.bell-item { display: flex; flex-direction: column; gap: 4px; padding: 11px 14px; border-bottom: 1px solid var(--line); color: var(--fg); position: relative; }
.bell-item:hover { background: var(--surface-2); color: var(--fg); }
.bell-item.unread::before { content: ""; position: absolute; left: 5px; top: 17px; width: 5px; height: 5px; border-radius: 999px; background: var(--info); }
.bell-item-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
.bell-title { font-weight: 600; font-size: 13px; min-width: 0; flex: 1; }
.bell-body { font-size: 13px; color: var(--muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.bell-foot { display: flex; justify-content: flex-end; padding: 8px 10px; }
.bell-count.needs { background: var(--warning); color: #111; }
.bell-section { display: flex; align-items: center; gap: 8px; padding: 10px 14px 6px; font-size: 11.5px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; border-bottom: 1px solid var(--line); }
.bell-item.needs { background: rgba(245, 165, 36, 0.05); }
.bell-item.needs:hover { background: var(--warning-soft); }

/* toasts (NotificationBell) — bottom-right, at most three, newest last */
.toasts { position: fixed; right: 16px; bottom: 16px; z-index: 80; display: flex; flex-direction: column; gap: 8px; width: min(360px, calc(100vw - 32px)); }
.toast {
    display: flex; flex-direction: column; gap: 4px;
    padding: 11px 12px 12px 14px;
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);
    color: var(--fg);
    animation: toast-in 0.18s ease;
}
.toast:hover { color: var(--fg); border-color: #4a4a4a; }
.toast.needs { border-color: rgba(245, 165, 36, 0.55); }
.toast-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.toast-title { font-weight: 600; font-size: 13px; flex: 1; min-width: 0; }
.toast-body { font-size: 13px; color: var(--muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.toast-x { border: none; background: none; color: var(--faint); font-size: 16px; line-height: 1; cursor: pointer; padding: 0 2px; }
.toast-x:hover { color: var(--fg); }
@keyframes toast-in { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
.user-menu > summary {
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 4px 8px 4px 4px;
    border-radius: 999px;
    border: 1px solid transparent;
    cursor: pointer;
    color: var(--muted);
    font-size: 13px;
    transition: border-color var(--ease), color var(--ease), background var(--ease);
}
.user-menu > summary::-webkit-details-marker { display: none; }
.user-menu > summary:hover, .user-menu[open] > summary { color: var(--fg); border-color: var(--line); background: var(--surface); }
.avatar {
    width: 26px; height: 26px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--line-strong);
    color: var(--fg);
    display: inline-grid;
    place-items: center;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
}
.menu {
    position: absolute;
    right: 0;
    top: calc(100% + 8px);
    min-width: 200px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.6);
    padding: 6px;
    z-index: 60;
}
.menu-head { padding: 8px 10px 10px; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
.menu-head strong { display: block; font-size: 13px; }
.menu-head span { font-size: 12px; color: var(--faint); }
.menu-item {
    display: flex;
    width: 100%;
    align-items: center;
    gap: 8px;
    padding: 7px 10px;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}
.menu-item:hover { background: var(--surface-2); color: var(--fg); }
.menu-item.danger:hover { color: var(--danger); }
.menu form { margin: 0; }

/* ------------------------------------------------------------ modal */

/* A centred dialog over a dimmed page: .modal-scrim (click = cancel) + .modal > .modal-head · .modal-body · .modal-foot
   (cancel left of the primary action, bottom-right). Interactive pages render both only while open; Esc closes. */
.modal-scrim { position: fixed; inset: 0; z-index: 90; background: rgba(0, 0, 0, 0.62); }
.modal {
    position: fixed;
    z-index: 91;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(480px, calc(100vw - 32px));
    max-height: calc(100dvh - 48px);
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-lg);
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.7);
}
.modal-head { padding: 20px 22px 4px; }
.modal-title { margin: 0; font-size: 16px; font-weight: 650; letter-spacing: -0.01em; }
.modal-desc { margin: 6px 0 0; font-size: 13px; color: var(--muted); line-height: 1.6; }
.modal-body { padding: 16px 22px; }
.modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 14px 22px 18px; border-top: 1px solid var(--line); }

.main { flex: 1; }
.container { max-width: var(--container); margin: 0 auto; padding: 32px 24px 64px; }
.container-narrow { max-width: 760px; margin-inline: auto; }

/* ----------------------------------------------------------- page head */

.page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 24px;
}
.page-head .titles { min-width: 0; }
.page-title { font-size: 24px; font-weight: 650; letter-spacing: -0.025em; }
.page-desc { margin-top: 4px; color: var(--muted); font-size: 14px; max-width: 72ch; }
.page-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

.crumbs {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 8px;
    font-size: 13px;
    color: var(--faint);
    flex-wrap: wrap;
}
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--fg); }
.crumbs .sep { color: var(--line-strong); }

/* ---------------------------------------------------------------- panel */

.stack { display: flex; flex-direction: column; gap: 20px; }
.stack-sm { display: flex; flex-direction: column; gap: 10px; }

.panel {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    min-width: 0;
}
.panel-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--line);
}
.panel-head:last-child { border-bottom: none; }
.panel-title { font-size: 15px; font-weight: 600; display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.panel-desc { margin-top: 2px; color: var(--muted); font-size: 13px; }
.panel-body { padding: 20px; }
.panel-body.tight { padding: 0; }
.panel-foot {
    padding: 12px 20px;
    border-top: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    color: var(--faint);
    font-size: 12.5px;
}
.panel.danger-zone { border-color: rgba(242, 85, 85, 0.35); }

.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-sidebar { grid-template-columns: minmax(0, 1fr) 320px; align-items: start; }

/* stat tiles */
.stat { padding: 16px 20px; }
.stat-label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    font-weight: 500;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.stat-value { margin-top: 6px; font-size: 26px; font-weight: 650; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.stat-sub { margin-top: 2px; font-size: 12.5px; color: var(--faint); }

/* key / value list */
.kv {
    display: grid;
    grid-template-columns: minmax(120px, max-content) minmax(0, 1fr);
    column-gap: 24px;
    row-gap: 10px;
    margin: 0;
    font-size: 13.5px;
}
.kv dt { color: var(--muted); font-weight: 500; }
.kv dd { margin: 0; color: var(--fg); min-width: 0; overflow-wrap: anywhere; }

/* ---------------------------------------------------------------- table */

.table-wrap { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.table th {
    text-align: left;
    font-size: 12px;
    font-weight: 500;
    color: var(--muted);
    padding: 10px 16px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}
.table td {
    padding: 11px 16px;
    border-bottom: 1px solid var(--line);
    color: var(--fg);
    vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr { transition: background var(--ease); }
.table tbody tr:hover td { background: rgba(255, 255, 255, 0.025); }
.table tr.clickable { cursor: pointer; }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table .actions { text-align: right; white-space: nowrap; width: 1%; }
.table .actions > * + * { margin-left: 6px; }
.table .muted { color: var(--muted); }
.table tr.is-dim td { opacity: 0.55; }
.panel > .table-wrap > .table th, .panel > .table th { background: transparent; }
.table-wrap > .table.min-600 { min-width: 600px; } /* scroll sideways on phones instead of wrapping cells */

/* -------------------------------------------------------------- buttons */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 34px;
    padding: 0 14px;
    border-radius: var(--radius);
    border: 1px solid var(--line-strong);
    background: var(--surface-2);
    color: var(--fg);
    font-family: var(--font);
    font-size: 13px;
    font-weight: 550;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition: background var(--ease), border-color var(--ease), color var(--ease), box-shadow var(--ease), opacity var(--ease);
}
.btn:hover:not(:disabled) { background: var(--surface-hover); border-color: #4a4a4a; color: var(--fg); }
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }

.btn-primary { background: var(--accent); color: var(--accent-fg); border-color: var(--accent); }
.btn-primary:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-fg); }

.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn-ghost:hover:not(:disabled) { background: var(--surface-2); border-color: transparent; color: var(--fg); }

.btn-outline { background: transparent; }

.btn-danger { background: transparent; border-color: rgba(242, 85, 85, 0.45); color: var(--danger); }
.btn-danger:hover:not(:disabled) { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn-danger.solid { background: var(--danger); border-color: var(--danger); color: #fff; }

.btn-sm { height: 28px; padding: 0 10px; font-size: 12.5px; border-radius: var(--radius-sm); }
.btn-lg { height: 40px; padding: 0 18px; font-size: 14px; }
.btn-block { width: 100%; }
.btn-group { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; }

/* ---------------------------------------------------------------- forms */

.input, .select, .textarea,
.form-control {
    width: 100%;
    height: 36px;
    padding: 0 12px;
    background: var(--bg);
    color: var(--fg);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    font-family: var(--font);
    font-size: 13.5px;
    transition: border-color var(--ease), box-shadow var(--ease), background var(--ease);
}
.textarea, textarea.form-control { height: auto; min-height: 96px; padding: 10px 12px; line-height: 1.55; resize: vertical; }
.input.mono, .textarea.mono { font-family: var(--mono); font-size: 12.5px; }
.select {
    appearance: none;
    padding-right: 32px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23a3a3a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
}
.input::placeholder, .textarea::placeholder, .form-control::placeholder { color: var(--faint); }
.input:hover, .select:hover, .textarea:hover { border-color: #4a4a4a; }
.input:focus, .select:focus, .textarea:focus, .form-control:focus {
    outline: none;
    border-color: var(--fg);
    box-shadow: var(--focus-ring);
}
.input:disabled, .select:disabled, .textarea:disabled { opacity: 0.5; cursor: not-allowed; }
.input[readonly] { background: var(--surface-2); }
.input-sm { height: 30px; font-size: 12.5px; padding: 0 10px; }

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > label, .label { font-size: 13px; font-weight: 550; color: var(--fg); }
.field .hint, .hint { font-size: 12.5px; color: var(--faint); }
.field .error, .field-error { font-size: 12.5px; color: var(--danger); }
.field > .segmented { align-self: flex-start; }
.form-grid { display: grid; gap: 16px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.form-grid .span-2 { grid-column: 1 / -1; }
.form-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.form-row > .field { flex: 1 1 200px; }
.form-actions { display: flex; gap: 8px; justify-content: flex-end; align-items: center; flex-wrap: wrap; }

.input-group { display: flex; gap: 8px; align-items: center; }
.input-group > .input { flex: 1; min-width: 0; }

.check { display: inline-flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--fg); cursor: pointer; user-select: none; }
.check input { width: 16px; height: 16px; accent-color: var(--fg); margin: 0; }

.switch { position: relative; display: inline-flex; width: 36px; height: 20px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; position: absolute; }
.switch .track {
    position: absolute; inset: 0;
    border-radius: 999px;
    background: var(--surface-hover);
    border: 1px solid var(--line-strong);
    cursor: pointer;
    transition: background var(--ease), border-color var(--ease);
}
.switch .track::after {
    content: "";
    position: absolute;
    top: 2px; left: 2px;
    width: 14px; height: 14px;
    border-radius: 999px;
    background: var(--muted);
    transition: transform var(--ease), background var(--ease);
}
.switch input:checked + .track { background: var(--fg); border-color: var(--fg); }
.switch input:checked + .track::after { transform: translateX(16px); background: var(--bg); }
.switch input:focus-visible + .track { box-shadow: var(--focus-ring); }

.search {
    position: relative;
    flex: 1 1 240px;
    max-width: 360px;
}
.search .input { padding-left: 32px; }
.search::before {
    content: "";
    position: absolute;
    left: 11px; top: 50%;
    width: 13px; height: 13px;
    transform: translateY(-50%);
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 24 24' fill='none' stroke='%236e6e6e' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") no-repeat center;
    pointer-events: none;
}
.toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }
.toolbar .spacer { flex: 1; }

/* ------------------------------------------------------ badges & status */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 22px;
    padding: 0 8px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 550;
    line-height: 1;
    white-space: nowrap;
    color: var(--muted);
    background: var(--surface-2);
    border: 1px solid var(--line);
}
.badge-success { color: var(--success); background: var(--success-soft); border-color: transparent; }
.badge-warning { color: var(--warning); background: var(--warning-soft); border-color: transparent; }
.badge-danger { color: var(--danger); background: var(--danger-soft); border-color: transparent; }
.badge-info { color: var(--info); background: var(--info-soft); border-color: transparent; }
.badge-solid { color: var(--accent-fg); background: var(--accent); border-color: transparent; }
.badge.mono { font-family: var(--mono); font-weight: 500; }
button.badge { cursor: pointer; font-family: inherit; transition: color var(--ease), border-color var(--ease); }
button.badge.mono { font-family: var(--mono); }
button.badge:hover { color: var(--fg); border-color: var(--line-strong); }

.count {
    display: inline-grid;
    place-items: center;
    min-width: 20px;
    height: 18px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--surface-hover);
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.dot { width: 8px; height: 8px; border-radius: 999px; background: var(--faint); display: inline-block; flex-shrink: 0; }
.dot.ok, .dot-success { background: var(--success); box-shadow: 0 0 0 3px var(--success-soft); }
.dot.warn, .dot-warning { background: var(--warning); box-shadow: 0 0 0 3px var(--warning-soft); }
.dot.fail, .dot-danger { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-soft); }

/* ----------------------------------------------------------------- tabs */

.tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--line);
    overflow-x: auto;
    scrollbar-width: none;
}
.tabs .tab {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    margin-bottom: -1px;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--muted);
    font: inherit;
    font-size: 13.5px;
    font-weight: 550;
    cursor: pointer;
    white-space: nowrap;
    transition: color var(--ease), border-color var(--ease);
}
.tabs .tab:hover { color: var(--fg); }
.tabs .tab.active { color: var(--fg); border-bottom-color: var(--fg); }
.tabs .tab.active .count { background: var(--fg); color: var(--bg); }

.segmented {
    display: inline-flex;
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
    padding: 3px;
    gap: 2px;
    background: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}
.segmented button {
    flex-shrink: 0;
    white-space: nowrap;
    height: 26px;
    padding: 0 10px;
    border: none;
    border-radius: 5px;
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: 12.5px;
    font-weight: 550;
    cursor: pointer;
}
.segmented button.active { background: var(--surface-hover); color: var(--fg); box-shadow: 0 1px 0 rgba(255, 255, 255, 0.04) inset; }

/* ------------------------------------------------ empty, notice, callout */

.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 6px;
    padding: 40px 20px;
    color: var(--muted);
}
.empty-title { color: var(--fg); font-weight: 600; font-size: 14px; }
.empty-desc { font-size: 13px; color: var(--faint); max-width: 48ch; }
.empty-personal { display: block; margin-top: 8px; }
.empty .btn { margin-top: 10px; }

.notice {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 14px;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: var(--surface-2);
    font-size: 13px;
    color: var(--fg);
}
.notice::before { content: ""; width: 8px; height: 8px; margin-top: 6px; border-radius: 999px; background: var(--muted); flex-shrink: 0; }
.notice-success { border-color: rgba(62, 207, 142, 0.3); background: var(--success-soft); }
.notice-success::before { background: var(--success); }
.notice-error { border-color: rgba(242, 85, 85, 0.35); background: var(--danger-soft); }
.notice-error::before { background: var(--danger); }
.notice-warning { border-color: rgba(245, 165, 36, 0.3); background: var(--warning-soft); }
.notice-warning::before { background: var(--warning); }
.notice ul { margin: 0; padding-left: 1rem; }

/* one-time secret / token reveal */
.secret {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 6px 6px 12px;
    background: var(--bg);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
}
.secret .value {
    flex: 1;
    min-width: 0;
    font-family: var(--mono);
    font-size: 12.5px;
    overflow-x: auto;
    white-space: nowrap;
    scrollbar-width: none;
}

/* inline confirm (destructive actions) */
.confirm {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 3px 3px 10px;
    border-radius: var(--radius);
    background: var(--danger-soft);
    border: 1px solid rgba(242, 85, 85, 0.35);
    font-size: 12.5px;
    color: var(--danger);
    white-space: nowrap;
}

/* ------------------------------------------------------------- utilities */

.muted { color: var(--muted); }
.faint { color: var(--faint); }
.strong { color: var(--fg); font-weight: 600; }
.danger-text { color: var(--danger); }
.success-text { color: var(--success); }
.small { font-size: 12.5px; }
.nowrap { white-space: nowrap; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row { display: flex; align-items: center; gap: 10px; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.wrap { flex-wrap: wrap; }
.spacer { flex: 1; }
.mt-0 { margin-top: 0; }
.tabular { font-variant-numeric: tabular-nums; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; }

/* ------------------------------------------------------ blazor plumbing */

.valid.modified:not([type=checkbox]) { outline: none; }
.invalid { border-color: var(--danger) !important; }
.validation-message { color: var(--danger); font-size: 12.5px; }

.blazor-error-boundary {
    background: var(--danger-soft);
    border: 1px solid rgba(242, 85, 85, 0.35);
    color: var(--danger);
    padding: 1rem;
    border-radius: var(--radius);
}
.blazor-error-boundary::after { content: "An error has occurred."; }

#blazor-error-ui {
    color-scheme: dark only;
    background: var(--danger);
    color: #fff;
    bottom: 0;
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
    font-size: 13px;
}
#blazor-error-ui .reload { color: #fff; text-decoration: underline; margin-left: 0.5rem; }
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 0.9rem; top: 0.45rem; font-size: 1.1rem; }

/* ------------------------------------------------------- board-ui host */

/* /board · /flow 는 앱의 「작업」·「플로우」 화면을 통째로 얹는다(Pages/Board.razor · js/board-ui.js).
   페이지 폭 제한과 여백을 풀고, 상단 바(높이 + 아래 테두리 1px) 아래 남은 자리를 전부 준다 — 안쪽
   스크롤은 앱과 같이 그 화면이 스스로 돈다. */
.container:has(> .board-ui-host) { max-width: none; padding: 0; }
.board-ui-host { height: calc(100dvh - var(--topbar-h) - 1px); min-height: 360px; }

/* -------------------------------------------------------- project shell */

/* /admin/projects/{code}/… (Layout/ProjectShell.razor): the project's feature pages in a sidebar next to the
   page body. The only sidebar in the web — everything else is top-bar tabs. It stays inside the 1200px column
   so its left edge lines up with the top bar's logo. */
.project-shell {
    display: grid;
    grid-template-columns: 196px minmax(0, 1fr);
    gap: 24px;
    align-items: start;
}
.project-body { min-width: 0; }
/* The slot holds the rail's place in the grid; the nav inside it can float over the page when collapsed. */
.side-nav-slot {
    position: sticky;
    top: calc(var(--topbar-h) + 24px);
    z-index: 5;
}
.side-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.side-nav-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
    padding: 4px 4px 14px 10px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--line);
}
.side-nav-head {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    min-width: 0;
}
.side-nav-title { max-width: 100%; font-size: 14px; font-weight: 600; }
.side-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    color: var(--muted);
    font-size: 13.5px;
    font-weight: 550;
    white-space: nowrap;
    transition: background var(--ease), color var(--ease);
}
.side-nav-item:hover { background: var(--surface-2); color: var(--fg); }
.side-nav-item.active { background: var(--surface-hover); color: var(--fg); }
.side-nav-icon, .side-nav-toggle svg {
    flex-shrink: 0;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.3;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.side-nav-icon { color: var(--faint); transition: color var(--ease); }
.side-nav-item:hover .side-nav-icon, .side-nav-item.active .side-nav-icon { color: var(--fg); }
/* Collapse button (wwwroot/js/project-shell.js). Collapsed styles live in that script (adoptedStyleSheets). */
.side-nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--faint);
    cursor: pointer;
    transition: color var(--ease), background var(--ease);
}
.side-nav-toggle:hover { color: var(--fg); background: var(--surface-2); }
.side-nav-toggle:focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* Project discovery and the operations overview compose the shared panels and controls. */
.project-toolbar { display: flex; justify-content: space-between; align-items: end; gap: 20px; flex-wrap: wrap; }
.project-filters { display: flex; gap: 12px; flex-wrap: wrap; }
.project-filters .field:first-child { flex: 1; min-width: min(280px, 100%); }
.project-card { display: flex; flex-direction: column; }
.project-card > .panel-body:first-child { flex: 1; }
.project-card-title { font-size: 22px; font-weight: 600; letter-spacing: -0.025em; overflow-wrap: anywhere; }
.project-card-description { font-size: 13.5px; line-height: 1.65; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.project-card-resources { display: flex; align-items: baseline; flex-wrap: wrap; gap: 12px 24px; padding-top: 12px; font-size: 13px; }
.project-card-resources strong { font-size: 20px; font-weight: 600; }
.project-delete { border-top: 1px solid var(--line); }
.project-delete .input { width: 150px; max-width: 100%; }
.project-name { overflow-wrap: anywhere; }
.project-snapshot { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.project-snapshot > * + * { border-left: 1px solid var(--line); }
.project-snapshot .stat-label { text-transform: none; letter-spacing: normal; }
.project-snapshot .stat-sub { color: var(--muted); }
.project-snapshot .project-date { font-size: 20px; margin-top: 12px; }
.project-overview-grid { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); align-items: start; }
.project-service { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 20px; }
.project-service + .project-service { border-top: 1px solid var(--line); }
.project-service:hover, .project-snapshot a:hover { background: var(--surface-hover); }
.project-service > span:first-child { min-width: 0; display: grid; gap: 4px; }
.project-service strong { font-size: 14px; font-weight: 600; }
.project-service .muted { font-size: 12.5px; line-height: 1.6; }
.project-service .badge { flex-shrink: 0; }
.project-setup { margin: 0; padding-left: 40px; display: grid; gap: 18px; font-size: 13px; }
.project-setup li { padding-left: 4px; }
.project-setup li::marker { color: var(--muted); }
.project-setup a { font-weight: 550; }
.project-setup .muted { display: block; margin-top: 4px; font-size: 12.5px; }
.project-card a:focus-visible, .project-service:focus-visible, .project-snapshot a:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--radius-sm); }

/* ------------------------------------------------------------ responsive */

@media (max-width: 960px) {
    .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .grid-sidebar { grid-template-columns: minmax(0, 1fr); }
    /* the rail becomes a row of pills above the page, scrolling sideways like .tabs */
    .project-shell { grid-template-columns: minmax(0, 1fr); gap: 16px; }
    .side-nav-slot { position: static; }
    .side-nav { flex-direction: row; overflow-x: auto; scrollbar-width: none; }
    .side-nav-top { display: none; }
    .side-nav-icon { display: none; }
}
@media (max-width: 640px) {
    .project-filters { width: 100%; }
    .project-filters .field { min-width: 0; }
    .project-overview-grid { grid-template-columns: minmax(0, 1fr); }
    .project-snapshot { grid-template-columns: minmax(0, 1fr); }
    .project-snapshot > * + * { border-left: 0; border-top: 1px solid var(--line); }
    .project-service { padding: 16px; gap: 10px; }
    .topbar-inner { padding: 0 16px; gap: 16px; }
    /* tabs scroll sideways on phones — fade the edge so the hidden tabs read as "more" */
    .nav-tabs { -webkit-mask-image: linear-gradient(to right, #000 82%, transparent); mask-image: linear-gradient(to right, #000 82%, transparent); padding-right: 24px; }
    .user-name-label { display: none; }
    .container { padding: 24px 16px 48px; }
    .grid-2, .grid-3, .form-grid { grid-template-columns: minmax(0, 1fr); }
    .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
    .stat { padding: 14px 16px; }
    .stat-value { font-size: 21px; }
    .page-title { font-size: 21px; }
    .panel-head { flex-wrap: wrap; }
    .panel-head, .panel-body, .panel-foot { padding-left: 16px; padding-right: 16px; }
    .search { max-width: none; }
}

/* ------------------------------------------------------------------------
   Sign-in flow — /login and the desktop app's /desktop-auth hand-off (bare layout, no top bar) and the
   forced first-login /account/change-password. One centered column: the logo (large, animated), then the
   form (/login has no title — the logo is the title). */

/* The bare layout: MainLayout's signed-out branch and BareLayout (pages that must look like /login even
   when signed in). */
.bare {
    display: flex;
    min-height: 100vh;
    background: #0a0a0a; /* login keeps its original ground */
}
.bare main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.bare-content { flex: 1; padding: 1.5rem 2rem; }

.auth {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 48px 16px;
}
/* inside the signed-in layout (top bar above) the column doesn't need the full viewport */
.container .auth { min-height: calc(100vh - 180px); padding: 24px 0; }
.auth-card {
    width: 100%;
    max-width: 360px;
    display: flex;
    flex-direction: column;
    gap: 36px;
}
.auth-brand { display: flex; justify-content: center; }
.auth-body {
    display: flex;
    flex-direction: column;
    gap: 20px;
}
/* After the logo lands, the screen's parts fade in one by one in reading order — each carries its
   place as --i (title 0, fields next, the button last). */
.auth-body > :not(.auth-form),
.auth-form > .field,
.auth-form > .btn {
    animation: auth-in 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) both;
    animation-delay: calc(1.3s + var(--i, 0) * 0.12s);
}
.auth-head { text-align: center; }
.auth-title { margin: 0; font-size: 20px; font-weight: 650; letter-spacing: -0.02em; }
.auth-sub { margin: 6px 0 0; color: var(--muted); font-size: 13.5px; line-height: 1.6; }
.auth-sub strong { color: var(--fg); font-weight: 600; }
.auth-form { display: flex; flex-direction: column; gap: 14px; margin: 0; }
.auth-form .btn-primary { margin-top: 6px; }
.auth-foot { text-align: center; color: var(--faint); font-size: 12.5px; margin: 0; }
.auth-link {
    background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
    color: var(--muted); text-decoration: underline; text-underline-offset: 3px;
}
.auth-link:hover { color: var(--fg); }
@keyframes auth-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .auth-body > *, .auth-form > * { animation: none; } }

/* ── 보안 모드 (admin/security) */
.row.wrap { flex-wrap: wrap; gap: 6px; }
.btn-x { background: none; border: 0; padding: 0 0 0 4px; color: var(--fg-dim); cursor: pointer; font: inherit; line-height: 1; }
.btn-x:hover { color: var(--danger); }
.sealed-text { color: var(--fg-dim); font-style: italic; }

/* Right-click menu (Components/DataEditor/GridMenu.razor): data grids, the research tree. */
.gm-backdrop { position: fixed; inset: 0; z-index: 50; }
.gm {
    position: fixed; z-index: 51; min-width: 180px; padding: 4px;
    background: var(--surface-2); border: 1px solid var(--line-strong); border-radius: var(--radius);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); display: flex; flex-direction: column;
}
.gm-item {
    border: none; background: transparent; color: var(--fg); font: inherit; font-size: 13px; text-align: left;
    padding: 7px 10px; border-radius: var(--radius-sm); cursor: pointer;
}
.gm-item:hover:not(:disabled) { background: var(--surface-hover); }
.gm-item:disabled { color: var(--faint); cursor: default; }
.gm-danger:not(:disabled) { color: var(--danger); }
.gm-sep { height: 1px; margin: 4px 2px; background: var(--line); }
