/* ============================================================
   PromptDB · design system
   Tokens, typography, layout, components — single file.
   ============================================================ */

:root {
    --bg-0:        #0b0c0f;
    --bg-1:        #111317;
    --bg-2:        #181a1f;
    --bg-3:        #20232a;
    --bg-elev:     #1c1f25;
    --border:      #2a2d35;
    --border-soft: #1f2128;
    --text-1:      #f5f5f7;
    --text-2:      #c7cad1;
    --text-3:      #8b8f99;
    --text-muted:  #6b6f78;
    --accent:      #10a37f;
    --accent-2:    #0e8e6e;
    --accent-soft: rgba(16,163,127,0.16);
    --success:     #22c55e;
    --warn:        #f59e0b;
    --danger:      #ef4444;
    --danger-soft: rgba(239, 68, 68, 0.16);
    --var-ok-bg:    rgba(34, 197, 94, 0.20);
    --var-ok-fg:    #4ade80;
    --var-bad-bg:   rgba(239, 68, 68, 0.18);
    --var-bad-fg:   #fca5a5;
    /* "empty" — variable IS defined in the drawer, the value just hasn't been
       provided yet. Distinct from "missing" (not in the drawer at all). */
    --var-empty-bg: rgba(245, 158, 11, 0.22);
    --var-empty-fg: #fcd34d;

    --radius-sm: 6px;
    --radius:    10px;
    --radius-lg: 16px;
    --radius-xl: 22px;

    --shadow-sm: 0 1px 2px rgba(0,0,0,0.3);
    --shadow:    0 8px 24px rgba(0,0,0,0.35);
    --shadow-lg: 0 24px 60px rgba(0,0,0,0.45);

    --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, "SF Pro Text",
                 Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
    --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    --side-w: 264px;
    --top-h:  56px;
    --drawer-w: 360px;

    color-scheme: dark;
}

:root[data-theme="light"] {
    --bg-0:        #ffffff;
    --bg-1:        #fafafa;
    --bg-2:        #f3f4f6;
    --bg-3:        #eceef2;
    --bg-elev:     #ffffff;
    --border:      #e4e6eb;
    --border-soft: #eef0f3;
    --text-1:      #0e1116;
    --text-2:      #3c4250;
    --text-3:      #6b7280;
    --text-muted:  #8a8f99;
    --accent:      #10a37f;
    --accent-2:    #0c8a6a;
    --accent-soft: rgba(16,163,127,0.10);
    --var-ok-bg:    rgba(16, 163, 127, 0.14);
    --var-ok-fg:    #047857;
    --var-bad-bg:   rgba(239, 68, 68, 0.10);
    --var-bad-fg:   #b91c1c;
    --var-empty-bg: rgba(245, 158, 11, 0.15);
    --var-empty-fg: #b45309;
    --shadow:    0 8px 24px rgba(15,22,36,0.08);
    --shadow-lg: 0 24px 60px rgba(15,22,36,0.12);
    color-scheme: light;
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
body {
    margin: 0;
    font-family: var(--font-sans);
    font-size: 15px;
    line-height: 1.55;
    color: var(--text-1);
    background: var(--bg-0);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 { margin: 0 0 0.5em; line-height: 1.2; letter-spacing: -0.01em; }
/* Dark Theme toggling and antdesign overwriting color of heading */
:root[data-theme="dark"] h1, 
:root[data-theme="dark"] h2, 
:root[data-theme="dark"] h3, 
:root[data-theme="dark"] h4, 
:root[data-theme="dark"] h5, 
:root[data-theme="dark"] h6 {
    color:white !important
}

h1 {
    font-size: clamp(1.6rem, 2.4vw, 2.2rem);
    font-weight: 650;
    letter-spacing: -0.02em;
}
h2 { font-size: 1.35rem; font-weight: 650; }
h3 { font-size: 1.05rem; font-weight: 600; }

p { margin: 0 0 0.5em; color: var(--text-2); }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
code, pre, kbd { font-family: var(--font-mono); font-size: 0.92em; }
kbd {
    background: var(--bg-3); padding: 2px 6px; border-radius: 4px;
    border: 1px solid var(--border); font-size: 0.85em;
}
.muted { color: var(--text-3); }
.small { font-size: 0.85rem; }

/* ---------- App shell ---------- */
.app-shell {
    display: grid;
    grid-template-columns: var(--side-w) 1fr;
    grid-template-rows: var(--top-h) 1fr;
    grid-template-areas: "side top" "side main";
    min-height: 100vh;
}
.app-sidebar { grid-area: side; }
.app-topbar  { grid-area: top; }
.app-main    { grid-area: main; padding: 24px clamp(16px, 3vw, 32px) 64px; max-width: 1280px; width: 100%; min-width: 0; }

/* On the prompt editor, drop the 1280px cap on the main column so the
   Template + Compiled Output panes can stretch across the full width of
   the viewport between the sidebar and the variables drawer. Without this,
   on a wide monitor an enormous empty gutter shows up between the output
   pane and the drawer. */
.app-main:has(.editor-page) {
    max-width: none;
}

.app-sidebar {
    background: var(--bg-1);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    position: sticky; top: 0; height: 100vh;
    padding: 18px 14px 14px;
}

.brand { display: flex; align-items: center; gap: 10px; padding: 6px 8px 18px; }
.brand-mark {
    width: 34px; height: 34px;
    color: var(--accent);
    background: var(--accent-soft);
    border-radius: 9px;
    display: grid; place-items: center;
}
.brand-mark.large { width: 44px; height: 44px; border-radius: 12px; }
.brand-text strong { font-size: 16px; letter-spacing: -0.01em; }
.brand-text span { display:block; font-size: 11px; color: var(--text-3); }

.app-nav { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; }
.nav-item {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px;
    border-radius: var(--radius);
    color: var(--text-2);
    font-size: 14px;
    transition: background 120ms ease, color 120ms ease;
}
.nav-item:hover { background: var(--bg-2); color: var(--text-1); text-decoration: none; }
.nav-item.active { background: var(--bg-3); color: var(--text-1); }
.nav-item.sub { padding-left: 32px; font-size: 13px; color: var(--text-3); }
.nav-item .ico { width: 18px; text-align: center; color: var(--text-3); }
.nav-item .ico.dot::before { content: "●"; }

.sidebar-foot { margin-top: auto; display: flex; flex-direction: column; gap: 10px; padding-top: 12px; border-top: 1px solid var(--border-soft); }

/* ---------- Theme switch (sidebar) ----------
   A two-cell segmented control. The "active" cell is selected purely from the
   <html data-theme="..."> attribute, so it stays in sync without any Blazor or
   JS state to manage on re-render. */
.theme-switch {
    display: inline-flex;
    width: 100%;
    background: var(--bg-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 3px;
}
.theme-option {
    flex: 1;
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text-3);
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    padding: 6px 8px;
    border-radius: 7px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    transition: background 120ms ease, color 120ms ease;
}
.theme-option:hover { color: var(--text-1); }
.theme-option svg { flex-shrink: 0; }

/* The actually-applied theme lights up its corresponding cell. */
:root[data-theme="dark"]  .theme-option[data-theme-value="dark"],
:root[data-theme="light"] .theme-option[data-theme-value="light"] {
    background: var(--bg-0);
    color: var(--text-1);
    box-shadow: var(--shadow-sm);
}
.user-pill { display: flex; align-items: center; gap: 10px; padding: 6px 8px; }
.user-pill .info { min-width: 0; overflow: hidden; }
.user-pill .info strong { font-size: 13px; display:block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-pill .info span { font-size: 11px; color: var(--text-3); display:block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.logout-form { padding: 0 4px; }
.logout-form button { width: 100%; }

.avatar {
    width: 34px; height: 34px; border-radius: 50%;
    background: linear-gradient(135deg, var(--accent), #6366f1);
    color: #fff; font-weight: 600; font-size: 13px;
    display: grid; place-items: center; flex-shrink: 0;
}
.avatar.large { width: 44px; height: 44px; font-size: 15px; }

/* ---------- Topbar ---------- */
.app-topbar {
    background: color-mix(in oklab, var(--bg-0) 80%, transparent);
    backdrop-filter: saturate(140%) blur(10px);
    -webkit-backdrop-filter: saturate(140%) blur(10px);
    border-bottom: 1px solid var(--border-soft);
    display: flex; align-items: center; gap: 12px;
    padding: 0 16px;
    position: sticky; top: 0; z-index: 30;
}
.topbar-title { display: flex; align-items: center; gap: 8px; font-weight: 600; }
.topbar-title .dot { width: 10px; height: 10px; border-radius: 50%; }
.topbar-actions { margin-left: auto; display: flex; gap: 6px; }
.sidebar-toggle { display: none; }

.icon-btn {
    height: 36px; min-width: 36px;
    border-radius: 8px;
    background: transparent; color: var(--text-2);
    border: 1px solid transparent;
    cursor: pointer;
    display: inline-grid; place-items: center;
    transition: background 120ms ease, color 120ms ease;
}
.icon-btn:hover { background: var(--bg-2); color: var(--text-1); }
.icon-btn.small { height: 28px; min-width: 28px; }
.icon-btn.danger { color: var(--text-3); }
.icon-btn.danger:hover { background: var(--danger-soft); color: var(--danger); }
.icon-btn.xs {
    height: 16px; min-width: 22px;
    font-size: 9px;
    line-height: 1;
    padding: 0;
    border-radius: 4px;
}
.icon-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.icon-btn:disabled:hover { background: transparent; color: var(--text-2); }

/* Reorder column inside each variable row — two stacked xs buttons. */
.var-reorder {
    display: flex;
    flex-direction: column;
    gap: 1px;
    margin-right: 4px;
    flex-shrink: 0;
}

/* ──────────────────────────────────────────────────────────────────
   Expand-variable overlay — full-screen on mobile, floating panel on
   tablet and desktop. Mobile-first: the BASE rules target a small
   touch screen and the @media (min-width: …) blocks layer on the
   larger-screen treatment.
   ──────────────────────────────────────────────────────────────────  */

/* Backdrop. On mobile we hand the whole viewport to the panel and skip
   any padding so it goes truly full-bleed. */
.var-expand-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 110;
    display: flex;
    align-items: stretch;       /* mobile: panel fills full height */
    justify-content: stretch;   /* mobile: panel fills full width */
    padding: 0;
    animation: fadeIn 120ms ease;
}

/* Panel. Mobile-first: 100% × 100dvh (dynamic viewport — accounts for
   iOS URL bar collapse/expand), no border, no rounding. */
.var-expand-panel {
    width: 100%;
    height: 100vh;          /* fallback */
    height: 100dvh;         /* iOS Safari, Chrome ≥108, etc. */
    max-height: 100dvh;
    background: var(--bg-1);
    border: none;
    border-radius: 0;
    box-shadow: none;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: pop 160ms ease;
}

/* Head bar — uses safe-area insets so it clears the iOS status bar /
   notch. The hint text is hidden by default and re-shown on tablet+. */
.var-expand-head {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    padding: 10px 12px;
    padding-top: max(10px, env(safe-area-inset-top));
    padding-left: max(12px, env(safe-area-inset-left));
    padding-right: max(12px, env(safe-area-inset-right));
    border-bottom: 1px solid var(--border-soft);
    min-height: 48px;
    background: var(--bg-1);
}
.var-expand-head code.var {
    font-size: 13px;
    max-width: 60vw;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.var-expand-head .muted { display: none; }
.var-expand-head .icon-btn {
    margin-left: auto;
    /* Comfortable thumb target on touch */
    height: 40px;
    min-width: 40px;
}

/* Textarea fills the remaining height. 16px font is critical: anything
   smaller and iOS Safari auto-zooms when the user taps in, which jacks
   up the layout and won't always restore on blur. */
.var-expand-textarea {
    flex: 1;
    width: 100%;
    min-height: 0;
    border: none;
    outline: none;
    resize: none;
    background: var(--bg-1);
    color: var(--text-1);
    font-family: var(--font-mono);
    font-size: 16px;
    line-height: 1.55;
    padding: 14px 16px;
    /* Safe-area aware so the home indicator / notch don't eat content. */
    padding-bottom: max(14px, env(safe-area-inset-bottom));
    padding-left: max(16px, env(safe-area-inset-left));
    padding-right: max(16px, env(safe-area-inset-right));
}
.var-expand-textarea:focus { outline: none; box-shadow: none; }

/* ── Tablet (≥ 640px): floating panel with breathing room ─────────── */
@media (min-width: 640px) {
    .var-expand-overlay {
        align-items: center;
        justify-content: center;
        padding: clamp(16px, 3vw, 32px);
    }
    .var-expand-panel {
        width: min(94vw, 820px);
        height: min(88dvh, 720px);
        max-height: min(88dvh, 720px);
        border: 1px solid var(--border);
        border-radius: var(--radius-lg);
        box-shadow: var(--shadow-lg);
    }
    .var-expand-head {
        padding: 12px 16px;
        min-height: 0;
    }
    .var-expand-head code.var { font-size: 14px; max-width: none; }
    .var-expand-head .muted { display: inline; flex: 1; }
    .var-expand-head .icon-btn { height: 36px; min-width: 36px; }
    .var-expand-textarea {
        font-size: 14px;
        padding: 18px;
    }
}

/* ── Large desktop (≥ 1200px): roomier panel ──────────────────────── */
@media (min-width: 1200px) {
    .var-expand-panel {
        width: min(96vw, 1200px);
        height: min(92dvh, 900px);
        max-height: min(92dvh, 900px);
    }
    .var-expand-textarea {
        padding: 22px clamp(18px, 2.4vw, 28px);
    }
}

/* iOS-friendly hidden source for the clipboard helper.
   `display: none` and `visibility: hidden` both kill text selection on iOS,
   so we keep the textarea laid out but pushed off-screen at 1×1px. */
.clipboard-source {
    position: fixed !important;
    top: 0;
    left: 0;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: 0;
    border: 0;
    outline: none;
    opacity: 0;
    pointer-events: none;
    /* 16px keeps iOS from auto-zooming if it ever steals focus. */
    font-size: 16px;
    overflow: hidden;
    z-index: -1;
}

/* ---------- Buttons ---------- */
.btn {
    --pad-y: 8px; --pad-x: 14px;
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    padding: var(--pad-y) var(--pad-x);
    border-radius: 10px; border: 1px solid var(--border);
    background: var(--bg-2); color: var(--text-1);
    font: inherit; font-weight: 550; cursor: pointer; line-height: 1.1;
    transition: transform 80ms ease, background 120ms ease, border-color 120ms ease, opacity 120ms ease;
    text-decoration: none;
}
.btn:hover { background: var(--bg-3); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }

.btn-primary {
    background: var(--accent);
    border-color: transparent;
    color: #001b14;
}
.btn-primary:hover { background: var(--accent-2); color: #ffffff; }

.btn-ghost { background: transparent; border-color: transparent; color: var(--text-2); }
.btn-ghost:hover { background: var(--bg-2); color: var(--text-1); }

.btn-danger {
    background: var(--danger);
    border-color: transparent;
    color: #ffffff;
}
.btn-danger:hover { background: #dc2626; color: #ffffff; }

.btn-sm { --pad-y: 5px; --pad-x: 10px; font-size: 13px; }
.btn-block { width: 100%; }

/* ---------- Form ---------- */
.form-stack { display: flex; flex-direction: column; gap: 12px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field > span { font-size: 13px; color: var(--text-2); font-weight: 550; }
.field input, .field textarea, .field select, .select {
    background: var(--bg-2);
    border: 1px solid var(--border);
    border-radius: 9px;
    color: var(--text-1);
    padding: 10px 12px;
    font: inherit;
    transition: border-color 120ms ease, background 120ms ease, box-shadow 120ms ease;
    outline: none;
}
.field input:focus, .field textarea:focus, .field select:focus, .select:focus {
    border-color: var(--accent);
    background: var(--bg-1);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.field small { color: var(--text-3); }
.form-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }

/* ---------- Alerts ---------- */
.alert {
    border-radius: 10px;
    padding: 10px 12px;
    font-size: 14px;
    border: 1px solid;
}
.alert-error { background: var(--danger-soft); color: var(--danger); border-color: rgba(239,68,68,0.4); }
.alert-success { background: var(--accent-soft); color: var(--accent); border-color: rgba(16,163,127,0.4); }
.resend-form { margin-top: 10px; }

/* ---------- Auth shell ---------- */
.auth-shell {
    display: grid;
    grid-template-columns: 1fr 1fr;
    min-height: 100vh;
}
.auth-aside {
    padding: 56px;
    background: radial-gradient(ellipse at top left, rgba(16,163,127,0.15), transparent 60%),
                radial-gradient(ellipse at bottom right, rgba(99,102,241,0.10), transparent 60%),
                var(--bg-1);
    display: flex; flex-direction: column; gap: 18px;
    border-right: 1px solid var(--border-soft);
}
.auth-brand { display: flex; align-items: center; gap: 10px; }
.auth-brand strong { font-size: 18px; }
.auth-headline { font-size: clamp(1.8rem, 3.2vw, 2.6rem); margin-top: auto; max-width: 32ch; }
.auth-sub { max-width: 42ch; color: var(--text-2); font-size: 15px; }
.auth-bullets { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 8px; margin: 6px 0 30px; }
.auth-bullets li { display: flex; align-items: center; gap: 8px; color: var(--text-2); }
.b-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-3); display: inline-block; }
.b-dot.ok { background: var(--success); }

.auth-main { display: grid; place-items: center; padding: 32px; }
.auth-card {
    width: 100%; max-width: 420px;
    background: var(--bg-1);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 28px;
    box-shadow: var(--shadow);
}
.auth-card h2 { margin-bottom: 4px; }
.auth-card .muted { margin-bottom: 16px; }
.auth-foot { margin-top: 16px; font-size: 14px; color: var(--text-3); text-align: center; }
.auth-loading { padding: 40px; text-align: center; color: var(--text-3); }

/* ---------- Hero / Cards ---------- */
.page-hero {
    padding: 24px 0 36px;
    border-bottom: 1px solid var(--border-soft);
    margin-bottom: 24px;
}
.hero-eyebrow {
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    font-size: 11px;
    font-weight: 700;
    margin-bottom: 8px;
}
.hero-sub { color: var(--text-2); font-size: 17px; max-width: 60ch; }
.hero-actions { margin-top: 16px; display: flex; gap: 8px; }

.page-head {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 16px;
    margin-bottom: 18px;
    flex-wrap: wrap;
}
.page-head h1 { margin-bottom: 2px; }
.head-actions { display: flex; gap: 8px; }

.ws-title { display: flex; align-items: center; gap: 12px; }
.ws-title .dot { width: 12px; height: 12px; border-radius: 4px; }

.card-grid {
    display: grid; gap: 14px;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.ws-card {
    --ws-color: var(--accent);
    background: var(--bg-1);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 16px;
    color: var(--text-1);
    text-decoration: none;
    display: flex; flex-direction: column; gap: 6px;
    transition: transform 120ms ease, border-color 120ms ease, background 120ms ease;
    position: relative; overflow: hidden;
}
.ws-card::before {
    content: ""; position: absolute; inset: 0;
    background: radial-gradient(circle at top right, color-mix(in oklab, var(--ws-color) 18%, transparent), transparent 60%);
    pointer-events: none;
}
.ws-card:hover { transform: translateY(-1px); border-color: color-mix(in oklab, var(--ws-color) 50%, var(--border)); text-decoration: none; }
.ws-card .ws-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--ws-color); }
.ws-card h3 { margin: 4px 0 0; }
.ws-card p { color: var(--text-2); font-size: 14px; flex: 1; }

.empty-card {
    grid-column: 1 / -1;
    border: 1px dashed var(--border);
    border-radius: var(--radius-lg);
    padding: 32px;
    text-align: center;
    background: var(--bg-1);
}

.skeleton-card, .skeleton-row {
    background: linear-gradient(90deg, var(--bg-2) 0%, var(--bg-3) 50%, var(--bg-2) 100%);
    background-size: 200% 100%;
    animation: shimmer 1.4s linear infinite;
    border-radius: var(--radius-lg);
    height: 120px;
}
.skeleton-row { height: 56px; margin-bottom: 12px; }
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* Search */
.search-bar {
    display: flex; align-items: center; gap: 12px;
    background: var(--bg-1); border: 1px solid var(--border);
    border-radius: 12px; padding: 6px 12px; margin-bottom: 16px;
}
.search-bar input {
    flex: 1; background: transparent; border: none; outline: none;
    color: var(--text-1); padding: 8px 0; font: inherit;
}

/* Prompts list */
.prompt-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
/* The whole card is the link. The delete button (owners only) overlays
   absolutely on top of the right edge of the link — that way the entire
   visible card surface is the clickable navigation target, and the
   delete button isn't carved out of it. */
.prompt-row {
    background: var(--bg-1); border: 1px solid var(--border);
    border-radius: 12px;
    position: relative;
    transition: border-color 120ms ease, background 120ms ease, transform 80ms ease;
}
.prompt-row-link {
    display: flex; justify-content: space-between; align-items: center; gap: 16px;
    padding: 14px 16px;
    color: inherit;
    text-decoration: none;
    min-width: 0;
    cursor: pointer;
    border-radius: 12px;
}
.prompt-row-link:hover { text-decoration: none; }
.prompt-row-link:active { transform: translateY(1px); }
/* Reserve room on the right so meta text never sits under the trash icon.
   The .has-actions class is set server-side (owners only) instead of relying
   on :has(), so alignment is identical in every browser. */
.prompt-row.has-actions .prompt-row-link { padding-right: 52px; }
.prompt-row-delete {
    position: absolute;
    top: 50%;
    right: 12px;
    transform: translateY(-50%);
    z-index: 1;
}
.prompt-row:hover { border-color: var(--accent); background: var(--bg-2); }
.prompt-row:active { transform: translateY(1px); }
.pr-title { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; flex: 1; min-width: 0; }
.pr-title h3 { margin: 0; }
.pr-meta { display: flex; flex-direction: column; gap: 2px; font-size: 12px; color: var(--text-3); text-align: right; flex-shrink: 0; }
.pr-meta .vars { color: var(--accent); font-weight: 600; }
.pr-right { display: flex; align-items: center; gap: 10px; }

/* Chips */
.chip {
    background: var(--bg-3); border: 1px solid var(--border);
    color: var(--text-2); border-radius: 999px;
    padding: 2px 8px; font-size: 11px; font-weight: 500;
}
.chip-action { cursor: pointer; }
.chip-action:hover { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }

/* Members */
.members-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.member-row {
    display: flex; align-items: center; gap: 12px;
    background: var(--bg-1); border: 1px solid var(--border);
    border-radius: 12px; padding: 10px 12px;
}
.m-info { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.m-info strong { font-size: 14px; }
.m-info span { font-size: 12px; }
.m-actions { display: flex; gap: 6px; align-items: center; }
.role-pill {
    border-radius: 999px; padding: 3px 10px; font-size: 11px; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.04em;
}
.role-owner  { background: rgba(245,158,11,0.18); color: var(--warn); }
.role-editor { background: var(--accent-soft); color: var(--accent); }
.role-viewer { background: var(--bg-3); color: var(--text-3); }

/* ---------- Modal ---------- */
.modal-backdrop {
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    display: grid; place-items: center;
    z-index: 100;
    animation: fadeIn 120ms ease;
}
.modal {
    background: var(--bg-1);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    width: min(520px, calc(100vw - 32px));
    box-shadow: var(--shadow-lg);
    animation: pop 160ms ease;
}
.modal-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 18px; border-bottom: 1px solid var(--border-soft);
}
.modal-head h3 { margin: 0; }
.modal-body { padding: 18px; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop   { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }

/* ---------- Share modal (Versioned / Fixed link picker) ---------- */
.share-choice { display: flex; flex-direction: column; gap: 10px; }
.share-option {
    appearance: none;
    display: flex; align-items: flex-start; gap: 12px;
    width: 100%;
    background: var(--bg-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
    cursor: pointer;
    text-align: left;
    font: inherit;
    color: var(--text-1);
    transition: border-color 120ms ease, background 120ms ease;
}
.share-option:hover { border-color: var(--accent); }
.share-option.is-selected {
    border-color: var(--accent);
    background: var(--accent-soft);
}
.share-option-radio {
    flex: 0 0 auto;
    width: 16px; height: 16px;
    margin-top: 2px;
    border-radius: 50%;
    border: 2px solid var(--border);
    position: relative;
    transition: border-color 120ms ease;
}
.share-option.is-selected .share-option-radio { border-color: var(--accent); }
.share-option.is-selected .share-option-radio::after {
    content: "";
    position: absolute; inset: 2px;
    border-radius: 50%;
    background: var(--accent);
}
.share-option-main { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.share-fixed-pick {
    display: flex; align-items: center; gap: 10px;
    margin: -2px 0 2px;
    padding: 0 14px 0 42px; /* aligns with the card text, past the radio dot */
}
.share-fixed-pick .select { flex: 1; min-width: 0; }
.share-option-title { font-weight: 600; display: flex; align-items: center; gap: 8px; }
.share-option-desc { line-height: 1.45; }
.share-dirty-note { margin: 12px 0 0; }
.share-link-row { display: flex; gap: 8px; margin-top: 14px; }
.share-link-input {
    flex: 1; min-width: 0;
    font-family: var(--font-mono);
    font-size: 12px;
    background: var(--bg-2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 8px 10px;
    color: var(--text-2);
}
.share-link-row .btn { flex: 0 0 auto; white-space: nowrap; }

.color-row { display: flex; gap: 8px; flex-wrap: wrap; }
.swatch {
    width: 28px; height: 28px; border-radius: 50%; border: 2px solid transparent;
    cursor: pointer; transition: transform 80ms ease, box-shadow 120ms ease;
}
.swatch:hover { transform: scale(1.06); }
.swatch.is-active { border-color: var(--text-1); box-shadow: 0 0 0 2px var(--bg-1) inset; }

/* ---------- Prompt editor ---------- */
.editor-page {
    display: grid;
    grid-template-rows: auto 1fr;
    height: calc(100vh - var(--top-h) - 1px);
    margin: -24px clamp(-16px, -3vw, -32px) -64px;
    padding: 0;
    /* Lock the editor page to the viewport on desktop. Each pane handles its
       own scrolling internally — without this, oversized output would push
       editor-page past 100vh and the whole window would scroll instead. */
    overflow: hidden;
    min-height: 0;
    /* Let the shell define the usable width. With the negative margins above,
       an auto-width block fills the padded main column without adding viewport
       units that can overflow beside scrollbars or the drawer. */
    width: auto;
    max-width: none;
}
.editor-header {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 16px;
    align-items: center;
    padding: 14px clamp(16px, 3vw, 32px);
    border-bottom: 1px solid var(--border-soft);
    background: var(--bg-0);
}
.back-link { font-size: 13px; color: var(--text-3); }
.back-link:hover { color: var(--text-1); text-decoration: none; }
.title-block { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.title-input {
    background: transparent; border: none; outline: none; color: var(--text-1);
    font-size: 18px; font-weight: 650; padding: 0;
    border-bottom: 1px solid transparent;
}
.title-input:focus { border-bottom-color: var(--accent); }
.tag-input {
    background: transparent; border: none; outline: none; color: var(--text-3);
    font-size: 12px; padding: 0;
}
.editor-actions { display: flex; gap: 6px; align-items: center; }
.dirty-pill {
    font-size: 11px; color: var(--warn);
    background: rgba(245,158,11,0.16);
    padding: 2px 8px; border-radius: 999px;
}

.editor-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* Single explicit row so the grid takes the full available height from
       editor-page's 1fr row instead of shrinking to content. */
    grid-template-rows: minmax(0, 1fr);
    gap: 0;
    overflow: hidden;
    min-height: 0;
    /* Defensive: no inherited cap should constrain how wide the grid is —
       it must fill its parent (editor-page) entirely so each 1fr pane gets
       half of every available pixel. */
    width: 100%;
    max-width: none;
}
.editor-pane {
    display: flex; flex-direction: column;
    border-right: 1px solid var(--border-soft);
    min-width: 0;
    /* Critical for nested scroll: without min-height: 0 a flex/grid item
       refuses to shrink past its intrinsic content size, and flex:1 children
       can't resolve a height — overflow:auto inside them then never triggers. */
    min-height: 0;
    overflow: hidden;
    /* Explicitly drop any max-width that might be coming from inheritance or
       a stale UA stylesheet — each pane must claim its entire 1fr column. */
    max-width: none;
    width: auto;
}
.editor-pane:last-child { border-right: none; }
.pane-head {
    display: flex; justify-content: space-between; align-items: center;
    padding: 10px 16px;
    border-bottom: 1px solid var(--border-soft);
    font-size: 12px; color: var(--text-3); font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.06em;
}

/* The editor uses a textarea overlaid on a <pre> that paints syntax-highlighted spans.
   Both share font/padding/line-height so characters line up exactly. */
.editor-wrap {
    position: relative;
    flex: 1 1 0;
    min-height: 0;
    overflow: hidden;
    background: var(--bg-1);
    /* Match the pane: no inherited width cap. */
    width: 100%;
    max-width: none;
}
.editor-input, .editor-highlight {
    margin: 0;
    padding: 18px clamp(16px, 3vw, 28px);
    font-family: var(--font-mono);
    font-size: 14px;
    line-height: 1.55;
    tab-size: 4;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: break-word;
}
.editor-highlight {
    position: absolute; inset: 0;
    color: var(--text-1);
    pointer-events: none;
    overflow: auto;
}
.editor-input {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    background: transparent;
    color: transparent;
    caret-color: var(--text-1);
    border: none; outline: none; resize: none;
    overflow: auto;
}
.editor-input::selection { background: rgba(16,163,127,0.40); }
.hl-placeholder { color: var(--text-muted); font-style: italic; }

.var {
    border-radius: 4px;
    padding: 0 3px;
    font-family: var(--font-mono);
    font-weight: 600;
}
.var.ok      { background: var(--var-ok-bg);    color: var(--var-ok-fg); }
.var.empty   { background: var(--var-empty-bg); color: var(--var-empty-fg); }
.var.missing { background: var(--var-bad-bg);   color: var(--var-bad-fg); }

/* Inside the editor's highlight overlay the span MUST NOT change character
   positions, otherwise the textarea's caret (sitting behind transparent text
   with the unstyled font) ends up offset from where each character appears
   to be drawn. Strip padding and bold here, and use box-shadow to keep a
   "padded background" look that doesn't affect layout. */
.editor-highlight .var {
    padding: 0;
    font-weight: inherit;
}
.editor-highlight .var.ok      { box-shadow: 0 0 0 2px var(--var-ok-bg); }
.editor-highlight .var.empty   { box-shadow: 0 0 0 2px var(--var-empty-bg); }
.editor-highlight .var.missing { box-shadow: 0 0 0 2px var(--var-bad-bg); }

.legend {
    font-size: 11px; color: var(--text-3);
    padding: 8px 16px; border-top: 1px solid var(--border-soft);
    display: flex; gap: 14px; align-items: center;
}
.leg-dot { width: 8px; height: 8px; border-radius: 2px; display: inline-block; margin-right: 4px; vertical-align: middle; }
.leg-dot.ok { background: var(--var-ok-fg); }
.leg-dot.missing { background: var(--var-bad-fg); }

/* Output pane */
.output-wrap {
    flex: 1 1 0;
    min-height: 0;
    overflow: auto;
    padding: 18px clamp(16px, 3vw, 28px);
    /* No inherited width cap — fill the pane edge to edge. */
    width: 100%;
    max-width: none;
}
.output-empty { padding: 32px; text-align: center; }
.output-text {
    white-space: pre-wrap; word-break: break-word;
    font-family: var(--font-mono); font-size: 14px; line-height: 1.55;
    margin: 0; color: var(--text-1);
    background: var(--bg-1);
    padding: 16px;
    border-radius: 10px;
    border: 1px solid var(--border-soft);
}
.output-actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 12px; align-items: center; }
.missing-warn { font-size: 12px; color: var(--text-3); display: inline-flex; flex-wrap: wrap; gap: 4px; align-items: center; }

/* ----- Circular dependency banner ----- */
.cycle-error {
    background: var(--danger-soft);
    border: 1px solid rgba(239, 68, 68, 0.45);
    border-radius: var(--radius);
    padding: 16px 18px;
    color: var(--var-bad-fg);
}
.cycle-error h4 {
    margin: 0 0 6px;
    color: var(--danger);
    font-size: 15px;
    font-weight: 650;
}
.cycle-error p { margin: 0 0 10px; color: var(--text-2); font-size: 13.5px; }
.cycle-path {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    padding: 6px 0;
}
.cycle-arrow {
    color: var(--var-bad-fg);
    font-weight: 700;
    opacity: 0.7;
}

/* Drawer/variable row when a variable is part of a cycle */
.var-row.is-cycle,
.share-var-row.is-cycle {
    border-color: rgba(239, 68, 68, 0.55);
    background: color-mix(in oklab, var(--danger-soft) 60%, var(--bg-2));
}
.cycle-pill {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--var-bad-fg);
    background: var(--var-bad-bg);
    padding: 2px 6px;
    border-radius: 999px;
}

.pane-head-right { display: flex; align-items: center; gap: 12px; }

/* Segmented toggle inside the pane head */
.seg-toggle {
    display: inline-flex;
    background: var(--bg-2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 2px;
    text-transform: none;
    letter-spacing: 0;
}
.seg-toggle button {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text-3);
    font: inherit;
    font-size: 11px;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 6px;
    cursor: pointer;
    transition: background 120ms ease, color 120ms ease;
}
.seg-toggle button:hover { color: var(--text-1); }
.seg-toggle button.is-active {
    background: var(--bg-0);
    color: var(--text-1);
    box-shadow: var(--shadow-sm);
}

/* Markdown rendered output (Markdig) */
.output-text.markdown, .share-output-text.markdown {
    font-family: var(--font-sans);
    font-size: 14.5px;
    line-height: 1.65;
    white-space: normal;
    word-break: normal;
}
.output-text.markdown > :first-child,
.share-output-text.markdown > :first-child { margin-top: 0; }
.output-text.markdown > :last-child,
.share-output-text.markdown > :last-child  { margin-bottom: 0; }
.output-text.markdown h1, .share-output-text.markdown h1,
.output-text.markdown h2, .share-output-text.markdown h2,
.output-text.markdown h3, .share-output-text.markdown h3,
.output-text.markdown h4, .share-output-text.markdown h4,
.output-text.markdown h5, .share-output-text.markdown h5,
.output-text.markdown h6, .share-output-text.markdown h6 {
    margin: 1.4em 0 0.5em;
    line-height: 1.25;
    color: var(--text-1);
    font-weight: 650;
}
.output-text.markdown h1, .share-output-text.markdown h1 { font-size: 1.55em; }
.output-text.markdown h2, .share-output-text.markdown h2 { font-size: 1.32em; }
.output-text.markdown h3, .share-output-text.markdown h3 { font-size: 1.14em; }
.output-text.markdown h4, .share-output-text.markdown h4 { font-size: 1.02em; }
.output-text.markdown p,  .share-output-text.markdown p  { margin: 0 0 0.85em; color: var(--text-2); }
.output-text.markdown a,  .share-output-text.markdown a  { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.output-text.markdown ul, .share-output-text.markdown ul,
.output-text.markdown ol, .share-output-text.markdown ol { margin: 0 0 0.85em; padding-left: 1.4em; }
.output-text.markdown li, .share-output-text.markdown li { margin: 0.15em 0; }
.output-text.markdown li > p, .share-output-text.markdown li > p { margin: 0; }
.output-text.markdown blockquote, .share-output-text.markdown blockquote {
    margin: 0.6em 0; padding: 0.4em 0.9em;
    border-left: 3px solid var(--accent);
    background: var(--bg-2);
    color: var(--text-2);
    border-radius: 0 8px 8px 0;
}
.output-text.markdown hr, .share-output-text.markdown hr {
    border: none;
    border-top: 1px solid var(--border-soft);
    margin: 1.5em 0;
}
.output-text.markdown code, .share-output-text.markdown code {
    font-family: var(--font-mono);
    background: var(--bg-2);
    border: 1px solid var(--border-soft);
    border-radius: 4px;
    padding: 1px 5px;
    font-size: 0.9em;
}
.output-text.markdown pre, .share-output-text.markdown pre {
    background: var(--bg-0);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 12px 14px;
    overflow: auto;
    margin: 0.6em 0;
    line-height: 1.5;
}
.output-text.markdown pre code, .share-output-text.markdown pre code {
    background: transparent;
    border: none;
    padding: 0;
    font-size: 13px;
}
.output-text.markdown table, .share-output-text.markdown table {
    border-collapse: collapse;
    width: 100%;
    margin: 0.8em 0;
    font-size: 0.95em;
}
.output-text.markdown th, .share-output-text.markdown th,
.output-text.markdown td, .share-output-text.markdown td {
    border: 1px solid var(--border);
    padding: 6px 10px;
    text-align: left;
}
.output-text.markdown th, .share-output-text.markdown th { background: var(--bg-2); font-weight: 650; color: var(--text-1); }
.output-text.markdown tr:nth-child(even) td, .share-output-text.markdown tr:nth-child(even) td { background: color-mix(in oklab, var(--bg-2) 50%, transparent); }
.output-text.markdown img, .share-output-text.markdown img { max-width: 100%; border-radius: 6px; }
.output-text.markdown input[type="checkbox"], .share-output-text.markdown input[type="checkbox"] { margin-right: 6px; }

/* ---------- Drawer ---------- */
.drawer {
    position: fixed; top: var(--top-h); right: 0; bottom: 0;
    width: var(--drawer-w); max-width: 100vw;
    background: var(--bg-1);
    border-left: 1px solid var(--border);
    transform: translateX(100%);
    transition: transform 220ms cubic-bezier(.2,.7,.2,1);
    z-index: 40;
    display: flex; flex-direction: column;
    box-shadow: var(--shadow-lg);
}
.is-drawer-open .drawer { transform: translateX(0); }
.is-drawer-open .editor-grid { margin-right: 0; }
@media (min-width: 1280px) {
    .is-drawer-open .editor-grid {
        width: calc(100% - var(--drawer-w));
        margin-right: var(--drawer-w);
    }
    .drawer { box-shadow: none; }
}
.drawer-head {
    display: flex; justify-content: space-between; align-items: center;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border-soft);
}
.drawer-body { padding: 14px 16px 24px; overflow: auto; flex: 1; display: flex; flex-direction: column; gap: 10px; }
.var-row { background: var(--bg-2); border: 1px solid var(--border-soft); border-radius: 10px; padding: 10px; display: flex; flex-direction: column; gap: 6px; }
.var-row.unused { opacity: 0.7; }
.var-row-head { display: flex; justify-content: space-between; align-items: center; }
.var-row code.var { font-size: 12px; }
.var-value {
    background: var(--bg-1); border: 1px solid var(--border); border-radius: 8px;
    color: var(--text-1); font-family: var(--font-mono); font-size: 13px;
    padding: 8px 10px; min-height: 40px; resize: vertical;
    outline: none; transition: border-color 120ms ease, box-shadow 120ms ease;
}
.var-value:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

.add-var { display: flex; gap: 6px; margin-top: 4px; }
.add-var-input {
    flex: 1; background: var(--bg-2); border: 1px solid var(--border);
    border-radius: 8px; padding: 8px 10px; color: var(--text-1);
    font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.04em;
    outline: none;
}
.add-var-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.quick-add { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; padding-top: 6px; border-top: 1px dashed var(--border-soft); }

.select {
    appearance: none; -webkit-appearance: none;
    padding-right: 28px;
    background-image: linear-gradient(45deg, transparent 50%, var(--text-3) 50%),
                      linear-gradient(135deg, var(--text-3) 50%, transparent 50%);
    background-position: calc(100% - 14px) 14px, calc(100% - 9px) 14px;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
}

/* ---------- Sidebar close button & backdrop ---------- */
/* Both are hidden on desktop; the mobile breakpoint promotes them. */
.sidebar-close { display: none; margin-left: auto; }
.sidebar-backdrop { display: none; }

/* ---------- Responsive ---------- */
@media (max-width: 1024px) {
    /* Editor is no longer a fixed-height viewport on tablet/mobile — let the page
       scroll naturally so a long compiled output can be read end-to-end. */
    .editor-page {
        height: auto;
        min-height: calc(100vh - var(--top-h));
        margin: -24px clamp(-16px, -3vw, -32px) 0;
        overflow: visible;
    }
    .editor-grid {
        grid-template-columns: 1fr;
        grid-template-rows: auto auto;
        overflow: visible;
    }
    .editor-pane {
        border-right: none; border-bottom: 1px solid var(--border-soft);
        overflow: visible;
    }
    .editor-pane:last-child { border-bottom: none; }
    /* Editor side gets a sensible textarea height; output side grows with content. */
    .editor-pane:first-child .editor-wrap { min-height: min(56vh, 460px); }
    .output-wrap { overflow: visible; }

    .auth-shell { grid-template-columns: 1fr; }
    .auth-aside { display: none; }
}

@media (max-width: 768px) {
    .app-shell {
        grid-template-columns: 1fr;
        grid-template-areas: "top" "main";
    }
    .app-sidebar {
        position: fixed; inset: 0 auto 0 0;
        width: 80vw; max-width: 320px;
        z-index: 60;
        transform: translateX(-100%);
        transition: transform 200ms ease;
        box-shadow: var(--shadow-lg);
    }
    .app-shell.is-sidebar-open .app-sidebar { transform: translateX(0); }
    .sidebar-toggle { display: inline-grid; }

    /* Close button inside sidebar, only meaningful when it's an overlay. */
    .sidebar-close { display: inline-grid; }

    /* Dimmed click-to-dismiss layer behind the sidebar overlay. */
    .sidebar-backdrop {
        display: block;
        position: fixed; inset: 0;
        background: rgba(0,0,0,0.5);
        z-index: 55;
        opacity: 0;
        pointer-events: none;
        transition: opacity 200ms ease;
    }
    .app-shell.is-sidebar-open .sidebar-backdrop {
        opacity: 1;
        pointer-events: auto;
    }

    .editor-page { margin: -24px -16px 0; }
    .editor-header { grid-template-columns: 1fr; gap: 8px; }
    .editor-actions { flex-wrap: wrap; }
    .drawer { top: 0; width: 100vw; }
    .modal { width: calc(100vw - 24px); }
    .auth-main { padding: 16px; }
}

/* ---------- Public share page ---------- */
.share-shell {
    min-height: 100vh;
    background:
        radial-gradient(ellipse at top, rgba(16,163,127,0.10), transparent 50%),
        var(--bg-0);
    padding: 32px clamp(16px, 4vw, 64px);
}
.share-empty {
    max-width: 480px; margin: 12vh auto; text-align: center;
}
.share-page {
    max-width: 1100px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 24px;
}
.share-header {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border-soft);
    flex-wrap: wrap;
}
.share-header-right {
    display: flex; align-items: center; gap: 12px;
    flex-wrap: wrap;
}
/* The share-scope theme switch is a touch more compact than the sidebar one
   (the share header has limited room). */
.share-header-right .theme-switch { width: auto; }
.share-title-block h1 { margin: 4px 0 8px; }
.share-tags { display: flex; flex-wrap: wrap; gap: 6px; }

.share-body {
    display: grid;
    grid-template-columns: 320px minmax(0, 1fr);
    gap: 20px;
    align-items: start;
}
.share-section-head {
    display: flex; justify-content: space-between; align-items: center;
    gap: 12px; margin-bottom: 12px;
    flex-wrap: wrap;
}
.share-section-head h3 { margin: 0; }
.share-section-head-right {
    display: flex; align-items: center; gap: 12px;
    flex-wrap: wrap;
}

.share-vars {
    display: flex; flex-direction: column; gap: 10px;
    background: var(--bg-1);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 16px;
    position: sticky; top: 24px;
    max-height: calc(100vh - 48px);
    overflow: auto;
}
.share-var-row {
    background: var(--bg-2);
    border: 1px solid var(--border-soft);
    border-radius: 10px;
    padding: 10px;
    display: flex; flex-direction: column; gap: 6px;
    transition: border-color 120ms ease;
}
.share-var-row.is-missing { border-color: rgba(239, 68, 68, 0.45); }
.share-var-row.is-empty   { border-color: rgba(245, 158, 11, 0.45); }
.share-var-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }

.share-output {
    background: var(--bg-1);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 18px clamp(16px, 2vw, 22px);
    min-height: 320px;
}
.share-output-text {
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: break-word;
    font-family: var(--font-mono);
    font-size: 14px;
    line-height: 1.6;
    color: var(--text-1);
    user-select: text;
    /* this looks/behaves like an unmodifiable textarea, without actually being a <textarea> */
}

/* Any $VAR that survived the compile (i.e. no value was provided) — bright red
   so it's impossible to miss. */
.missing-var {
    color: var(--var-bad-fg);
    background: var(--var-bad-bg);
    border-radius: 3px;
    box-shadow: 0 0 0 2px var(--var-bad-bg);
    font-weight: 600;
}

.share-foot { padding: 12px 0; text-align: center; }

@media (max-width: 860px) {
    .share-body {
        grid-template-columns: 1fr;
    }
    .share-vars {
        position: static;
        max-height: none;
    }
}

/* prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

.btn-primary { color:white !important; }

/* ---------- Version history ----------
   Scroll chain: the height cap lives on the modal and is handed down
   modal (flex, max-height) → .history-body (flex item, min-height:0)
   → .history-layout (flex item, min-height:0) → grid row minmax(0,1fr)
   → panes (overflow-y: auto). Break any link — e.g. a content-sized grid
   row — and the panes never shrink, so they clip instead of scrolling. */
.modal.history-modal {
    width: min(980px, calc(100vw - 32px));
    max-height: min(85vh, 800px);
    display: flex; flex-direction: column;
    overflow: hidden;
}
/* The title bar keeps its size; only the body shrinks and scrolls. */
.modal.history-modal .modal-head { flex: 0 0 auto; }

.history-body {
    padding: 0;
    /* Shrinkable flex item — passes the modal's cap down instead of
       letting the layout size itself to its content. */
    flex: 1 1 auto;
    min-height: 0;
    display: flex; flex-direction: column;
}

.history-layout {
    display: grid;
    grid-template-columns: 230px 1fr;
    /* THE fix: a plain grid row sizes to content no matter what the
       container says, so overflow-y on the panes never engaged. minmax(0,1fr)
       lets the row shrink to the capped container instead. */
    grid-template-rows: minmax(0, 1fr);
    flex: 1 1 auto;
    min-height: 320px;
    overflow: hidden;
}

.history-list {
    display: flex; flex-direction: column; gap: 2px;
    padding: 10px;
    border-right: 1px solid var(--border-soft);
    overflow-y: auto;
    /* Grid items default to min-height:auto — without this the pane refuses to
       shrink below its content and overlaps the modal instead of scrolling. */
    min-height: 0;
    min-width: 0;
}
.history-item {
    display: flex; flex-direction: column; gap: 3px;
    align-items: flex-start;
    padding: 8px 10px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    cursor: pointer;
    text-align: left;
    color: var(--text-2);
    font: inherit;
}
.history-item:hover { background: var(--bg-2); }
.history-item.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--text-1);
}
.history-item-head { display: flex; align-items: center; gap: 8px; }
.history-item-meta { line-height: 1.3; min-width: 0; overflow-wrap: anywhere; }

.ver-badge {
    font-family: var(--font-mono);
    font-size: 12px; font-weight: 700;
    color: var(--accent);
    background: var(--accent-soft);
    border-radius: 999px;
    padding: 2px 9px;
}
.ver-current {
    font-size: 10px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.05em;
    color: var(--text-3);
    background: var(--bg-3);
    border-radius: 999px;
    padding: 2px 8px;
}

.history-detail {
    display: flex; flex-direction: column; gap: 10px;
    padding: 14px 16px;
    overflow-y: auto;
    min-width: 0;
    /* Same grid-item shrink fix as .history-list — this is what makes the
       detail pane scroll instead of growing past the modal. */
    min-height: 0;
}
.history-detail-head {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    flex-wrap: wrap;
}
.history-detail-head > div { display: flex; align-items: center; gap: 10px; }

.history-warn {
    margin: 0;
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    background: var(--var-empty-bg);
    color: var(--var-empty-fg);
}
.history-diff-caption { margin: 0; }
.history-field-change {
    display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
    min-width: 0; overflow-wrap: anywhere;
}
.history-field-change .diff-old { color: var(--var-bad-fg); text-decoration: line-through; }
.history-field-change .diff-new { color: var(--var-ok-fg); }

/* Variable value history */
.history-vars-block {
    display: flex; flex-direction: column; gap: 8px;
    min-width: 0;
}
.history-var-row {
    display: flex; flex-direction: column; gap: 5px;
    padding: 8px 10px;
    background: var(--bg-2);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    min-width: 0;
}
.history-var-row-head {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    min-width: 0;
}
.history-var-row-head .diff-sign {
    font-family: var(--font-mono);
    color: var(--text-3);
    user-select: none;
}
.history-var-value {
    margin: 0;
    padding: 6px 9px;
    background: var(--bg-3);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 12px;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
    /* Long values scroll inside their own box instead of swallowing the pane. */
    max-height: 140px;
    overflow-y: auto;
}
.history-var-value.added { background: var(--var-ok-bg); color: var(--var-ok-fg); }
.history-var-value.removed { background: var(--var-bad-bg); color: var(--var-bad-fg); }
.history-var-value.is-empty { color: var(--text-muted); font-style: italic; }
.history-var-desc { overflow-wrap: anywhere; }
.history-vars-details summary {
    cursor: pointer;
    user-select: none;
}
.history-vars-details summary:hover { color: var(--text-1); }
.history-vars-details[open] summary { margin-bottom: 8px; }

.history-snapshot-body {
    margin: 0;
    padding: 12px;
    background: var(--bg-2);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 12.5px;
    line-height: 1.55;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
    overflow-y: auto;
    /* Don't let the flex parent squash it to nothing; the pane scrolls. */
    flex-shrink: 0;
}

/* Unified inline diff */
.diff-view {
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    background: var(--bg-2);
    font-family: var(--font-mono);
    font-size: 12.5px;
    line-height: 1.55;
    overflow: auto;
}
.diff-line {
    display: grid;
    grid-template-columns: 38px 38px 18px 1fr;
    align-items: baseline;
}
.diff-line .diff-gutter {
    text-align: right;
    padding: 0 6px;
    color: var(--text-muted);
    user-select: none;
    font-size: 11px;
}
.diff-line .diff-sign {
    text-align: center;
    user-select: none;
    color: var(--text-3);
}
.diff-line .diff-text {
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
    padding-right: 10px;
    min-width: 0;
}
/* Keep blank lines from collapsing the row to zero height. */
.diff-line .diff-text:empty::before { content: "\00a0"; }
.diff-line.added { background: var(--var-ok-bg); }
.diff-line.added .diff-sign, .diff-line.added .diff-text { color: var(--var-ok-fg); }
.diff-line.removed { background: var(--var-bad-bg); }
.diff-line.removed .diff-sign, .diff-line.removed .diff-text { color: var(--var-bad-fg); }

@media (max-width: 720px) {
    .history-layout {
        grid-template-columns: 1fr;
        /* Two rows in single-column mode: version strip (content-sized),
           then the detail pane takes whatever height is left and scrolls. */
        grid-template-rows: auto minmax(0, 1fr);
    }
    .history-list {
        flex-direction: row; overflow-x: auto; overflow-y: hidden;
        border-right: none; border-bottom: 1px solid var(--border-soft);
    }
    .history-item { min-width: 150px; }
}

/* Pinned-version badge on the public share page */
.share-ver-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ---------- Pending invitations (members page) ---------- */
.invites-head { margin-top: 28px; }
.invites-head h2 { margin: 0; font-size: 18px; }
.avatar.pending {
    background: transparent;
    border: 1.5px dashed var(--border);
    color: var(--text-3);
}

/* ---------- $VARIABLE autocomplete (editor body) ---------- */
.var-autocomplete {
    position: absolute;
    z-index: 30; /* above the highlight overlay and textarea */
    min-width: 180px;
    max-width: 320px;
    max-height: 220px;
    overflow-y: auto;
    background: var(--bg-elev);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow);
    padding: 4px;
}
.var-ac-item {
    padding: 5px 9px;
    border-radius: 5px;
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--var-ok-fg);
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.var-ac-item.is-active {
    background: var(--accent-soft);
    color: var(--text-1);
}
