/* ==========================================================================
   Freelance PM - theme
   Plain CSS on top of Bootstrap 5. No build step required.
   ========================================================================== */

:root {
    --brand:        #6366f1;
    --brand-dark:   #4f46e5;
    --brand-light:  #a5b4fc;
    --brand-soft:   #eef2ff;
    --accent:       #ec4899;
    --success:      #10b981;
    --warning:      #f59e0b;
    --danger:       #ef4444;
    --info:         #0ea5e9;
    --purple:       #8b5cf6;

    --ink:          #0f172a;
    --ink-soft:     #475569;
    --muted:        #94a3b8;
    --line:         #e2e8f0;
    --surface:      #ffffff;
    --canvas:       #f1f5f9;

    --sidebar-w:    272px;
    --topbar-h:     68px;

    --radius:       16px;
    --radius-sm:    10px;
    --shadow-sm:    0 1px 2px rgba(15, 23, 42, .06), 0 1px 3px rgba(15, 23, 42, .05);
    --shadow:       0 10px 30px -12px rgba(15, 23, 42, .18);
    --shadow-lg:    0 24px 55px -18px rgba(15, 23, 42, .28);

    --gradient:     linear-gradient(135deg, #6366f1 0%, #8b5cf6 55%, #ec4899 100%);
    --gradient-2:   linear-gradient(135deg, #0ea5e9 0%, #6366f1 100%);
    --gradient-3:   linear-gradient(135deg, #10b981 0%, #0ea5e9 100%);
}

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

* { -webkit-font-smoothing: antialiased; }

body {
    font-family: 'Plus Jakarta Sans', 'Segoe UI', system-ui, -apple-system, sans-serif;
    background: var(--canvas);
    color: var(--ink);
    font-size: .935rem;
    overflow-x: hidden;
}

a { text-decoration: none; }

h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5 { font-weight: 700; letter-spacing: -.02em; }

::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 20px; }
::-webkit-scrollbar-thumb:hover { background: var(--brand-light); }

.text-muted-2 { color: var(--muted) !important; }
.fw-600 { font-weight: 600; }
.fs-13 { font-size: .8125rem; }
.fs-12 { font-size: .75rem; }
.letter-tight { letter-spacing: -.02em; }

/* ------------------------------------------------------------ sidebar */

.app-sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    width: var(--sidebar-w);
    background: #ffffff;
    border-right: 1px solid var(--line);
    z-index: 1045;
    display: flex;
    flex-direction: column;
    transition: transform .32s cubic-bezier(.4, 0, .2, 1);
}

.app-sidebar .brand {
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: .7rem;
    padding: 0 1.25rem;
    border-bottom: 1px solid var(--line);
    flex-shrink: 0;
}

.app-sidebar .brand-mark {
    width: 38px; height: 38px;
    border-radius: 12px;
    background: var(--gradient);
    color: #fff;
    display: grid; place-items: center;
    font-size: 1.1rem;
    box-shadow: 0 8px 18px -6px rgba(99, 102, 241, .7);
    animation: floaty 5s ease-in-out infinite;
}

.app-sidebar .brand-text { font-weight: 800; font-size: 1.03rem; line-height: 1.1; letter-spacing: -.03em; }
.app-sidebar .brand-text small { display: block; font-size: .66rem; font-weight: 600; color: var(--muted); letter-spacing: .08em; text-transform: uppercase; }

.sidebar-scroll { overflow-y: auto; flex: 1; padding: 1rem .85rem 2rem; }

.nav-label {
    font-size: .66rem;
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--muted);
    padding: 1.1rem .8rem .45rem;
}

.nav-link-app {
    display: flex;
    align-items: center;
    gap: .8rem;
    padding: .62rem .8rem;
    border-radius: 11px;
    color: var(--ink-soft);
    font-weight: 600;
    font-size: .875rem;
    margin-bottom: 2px;
    position: relative;
    transition: all .18s ease;
}

.nav-link-app i:first-child { font-size: 1.05rem; width: 20px; text-align: center; transition: transform .2s ease; }

.nav-link-app:hover { background: var(--brand-soft); color: var(--brand-dark); transform: translateX(3px); }
.nav-link-app:hover i:first-child { transform: scale(1.15); }

.nav-link-app.active {
    background: var(--gradient);
    color: #fff;
    box-shadow: 0 10px 22px -12px rgba(99, 102, 241, .95);
}

.nav-link-app.active::before {
    content: '';
    position: absolute;
    left: -.85rem; top: 50%;
    transform: translateY(-50%);
    width: 4px; height: 22px;
    border-radius: 0 4px 4px 0;
    background: var(--brand);
}

.nav-link-app .badge { margin-left: auto; font-size: .66rem; }

/* ------------------------------------------------------------- topbar */

.app-topbar {
    position: fixed;
    top: 0; right: 0;
    left: var(--sidebar-w);
    height: var(--topbar-h);
    background: rgba(255, 255, 255, .86);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1.4rem;
    z-index: 1040;
    transition: left .32s cubic-bezier(.4, 0, .2, 1);
}

.app-main {
    margin-left: var(--sidebar-w);
    padding: calc(var(--topbar-h) + 1.6rem) 1.6rem 3rem;
    min-height: 100vh;
    transition: margin-left .32s cubic-bezier(.4, 0, .2, 1);
}

.sidebar-backdrop {
    position: fixed; inset: 0;
    background: rgba(15, 23, 42, .45);
    backdrop-filter: blur(2px);
    z-index: 1044;
    opacity: 0; visibility: hidden;
    transition: all .3s ease;
}

body.sidebar-open .sidebar-backdrop { opacity: 1; visibility: visible; }

@media (max-width: 991.98px) {
    .app-sidebar { transform: translateX(-100%); }
    body.sidebar-open .app-sidebar { transform: translateX(0); box-shadow: var(--shadow-lg); }
    .app-topbar { left: 0; }
    .app-main { margin-left: 0; padding-left: 1rem; padding-right: 1rem; }
}

/* --------------------------------------------------------- global search */

.global-search { position: relative; max-width: 430px; width: 100%; }

.global-search input {
    border-radius: 12px;
    border: 1px solid var(--line);
    background: #f8fafc;
    padding: .58rem .9rem .58rem 2.4rem;
    font-size: .86rem;
    width: 100%;
    transition: all .2s ease;
}

.global-search input:focus {
    outline: none;
    background: #fff;
    border-color: var(--brand-light);
    box-shadow: 0 0 0 4px rgba(99, 102, 241, .12);
}

.global-search .bi-search { position: absolute; left: .85rem; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: .95rem; }

.search-results {
    position: absolute;
    top: calc(100% + .5rem); left: 0; right: 0;
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-lg);
    max-height: 380px; overflow-y: auto;
    z-index: 1060;
    display: none;
    animation: dropIn .18s ease;
}

.search-results.show { display: block; }

.search-results a {
    display: flex; align-items: center; gap: .75rem;
    padding: .6rem .85rem;
    color: var(--ink);
    border-bottom: 1px solid #f1f5f9;
    transition: background .15s ease;
}

.search-results a:last-child { border-bottom: 0; }
.search-results a:hover { background: var(--brand-soft); }

/* ---------------------------------------------------------------- cards */

.card {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
    transition: transform .25s cubic-bezier(.4, 0, .2, 1), box-shadow .25s ease;
}

.card-header {
    background: transparent;
    border-bottom: 1px solid var(--line);
    padding: 1rem 1.25rem;
    font-weight: 700;
}

.card-body { padding: 1.25rem; }

.card-hover:hover { transform: translateY(-4px); box-shadow: var(--shadow); }

/* stat card */

.stat-card {
    position: relative;
    overflow: hidden;
    border-radius: var(--radius);
    padding: 1.15rem 1.25rem;
    background: #fff;
    border: 1px solid var(--line);
    box-shadow: var(--shadow-sm);
    transition: transform .25s cubic-bezier(.34, 1.56, .64, 1), box-shadow .25s ease;
    height: 100%;
}

.stat-card::after {
    content: '';
    position: absolute;
    right: -30px; top: -30px;
    width: 110px; height: 110px;
    border-radius: 50%;
    background: var(--tone, var(--brand));
    opacity: .08;
    transition: transform .35s ease;
    z-index: 0;          /* stays behind the figure */
    pointer-events: none;
}

.stat-card:hover { transform: translateY(-6px); box-shadow: var(--shadow); }
.stat-card:hover::after { transform: scale(1.45); }

.stat-card .stat-icon {
    width: 44px; height: 44px;
    border-radius: 13px;
    display: grid; place-items: center;
    font-size: 1.2rem;
    color: #fff;
    background: var(--tone, var(--brand));
    box-shadow: 0 10px 20px -10px var(--tone, var(--brand));
    margin-bottom: .85rem;
}

/* Amounts can get long (e.g. "Rs. 1,85,00,000.00"), so the value shrinks to
   fit rather than being clipped by the card. */
.stat-card .stat-value {
    font-size: clamp(1.05rem, 1.9vw + .35rem, 1.7rem);
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -.03em;
    word-break: break-word;
    overflow-wrap: anywhere;
    position: relative;
    z-index: 1;
}

.stat-card .stat-label { font-size: .78rem; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }

/* Money never wraps mid-number in tables, and the column grows to fit. */
.amount, td.amount, .table td.amount { white-space: nowrap; }

.money-value { white-space: nowrap; overflow-wrap: normal; }

/* ---------------------------------------------------------- page header */

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

.page-head h1 { font-size: 1.5rem; margin: 0; }
.page-head .subtitle { color: var(--muted); font-size: .86rem; margin-top: .15rem; }

.breadcrumb { font-size: .8rem; margin-bottom: .3rem; }
.breadcrumb a { color: var(--muted); }
.breadcrumb a:hover { color: var(--brand); }

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

.btn { border-radius: 11px; font-weight: 600; font-size: .86rem; padding: .55rem 1.1rem; transition: all .2s ease; }
.btn:active { transform: scale(.97); }

.btn-brand {
    background: var(--gradient);
    color: #fff;
    border: none;
    box-shadow: 0 10px 22px -12px rgba(99, 102, 241, .95);
}

.btn-brand:hover { color: #fff; transform: translateY(-2px); box-shadow: 0 16px 30px -14px rgba(99, 102, 241, 1); }

.btn-soft {
    background: var(--brand-soft);
    color: var(--brand-dark);
    border: 1px solid transparent;
}

.btn-soft:hover { background: var(--brand); color: #fff; }

.btn-icon { width: 34px; height: 34px; padding: 0; display: inline-grid; place-items: center; border-radius: 9px; }

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

.form-label { font-weight: 600; font-size: .82rem; color: var(--ink-soft); margin-bottom: .35rem; }

.form-control, .form-select {
    border-radius: 11px;
    border: 1px solid var(--line);
    padding: .58rem .85rem;
    font-size: .875rem;
    transition: all .18s ease;
}

.form-control:focus, .form-select:focus {
    border-color: var(--brand-light);
    box-shadow: 0 0 0 4px rgba(99, 102, 241, .12);
}

.form-check-input:checked { background-color: var(--brand); border-color: var(--brand); }
.form-check-input:focus { box-shadow: 0 0 0 4px rgba(99, 102, 241, .15); }

.input-group-text { border-radius: 11px; background: #f8fafc; border-color: var(--line); font-size: .85rem; }

/* file drop zone */

.dropzone {
    border: 2px dashed var(--line);
    border-radius: var(--radius-sm);
    padding: 1.5rem;
    text-align: center;
    background: #f8fafc;
    cursor: pointer;
    transition: all .2s ease;
}

.dropzone:hover, .dropzone.dragover { border-color: var(--brand); background: var(--brand-soft); }
.dropzone i { font-size: 1.8rem; color: var(--brand); }

/* --------------------------------------------------------------- tables */

.table { font-size: .865rem; margin-bottom: 0; }

.table > thead > tr > th {
    background: #f8fafc;
    font-size: .7rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--muted);
    border-bottom: 1px solid var(--line);
    padding: .75rem 1rem;
    white-space: nowrap;
}

.table > tbody > tr > td { padding: .8rem 1rem; vertical-align: middle; border-color: #f1f5f9; }
.table > tbody > tr { transition: background .15s ease; }
.table-hover > tbody > tr:hover > * { background: var(--brand-soft); }

.table-card { border-radius: var(--radius); border: 1px solid var(--line); background: #fff; box-shadow: var(--shadow-sm); }
.table-card > .table-responsive { border-radius: var(--radius); }

/* A dropdown inside a horizontally scrolling table would normally be cut off.
   app.js positions those menus with Popper's "fixed" strategy; this keeps the
   scroll container from clipping them while one is open. */
.table-responsive { overflow-x: auto; }
.table-responsive.dropdown-open { overflow: visible; }

/* --------------------------------------------------------------- badges */

.badge { font-weight: 700; font-size: .68rem; padding: .38em .7em; border-radius: 7px; letter-spacing: .02em; }

.badge-soft-primary   { background: #eef2ff; color: #4338ca; }
.badge-soft-success   { background: #dcfce7; color: #15803d; }
.badge-soft-danger    { background: #fee2e2; color: #b91c1c; }
.badge-soft-warning   { background: #fef3c7; color: #b45309; }
.badge-soft-info      { background: #e0f2fe; color: #0369a1; }
.badge-soft-secondary { background: #f1f5f9; color: #475569; }
.badge-soft-dark      { background: #e2e8f0; color: #1e293b; }
.badge-soft-purple    { background: #f3e8ff; color: #7e22ce; }

.dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }

/* ------------------------------------------------------------- avatars */

.avatar { border-radius: 50%; object-fit: cover; background: #e2e8f0; }
.avatar-xs { width: 24px; height: 24px; }
.avatar-sm { width: 32px; height: 32px; }
.avatar-md { width: 42px; height: 42px; }
.avatar-lg { width: 64px; height: 64px; }
.avatar-xl { width: 104px; height: 104px; }

.avatar-stack { display: flex; }
.avatar-stack .avatar { border: 2px solid #fff; margin-left: -9px; }
.avatar-stack .avatar:first-child { margin-left: 0; }

/* ------------------------------------------------------------ progress */

.progress { height: 7px; border-radius: 20px; background: #eef2f7; overflow: hidden; }
.progress-bar { border-radius: 20px; background: var(--gradient); transition: width 1s cubic-bezier(.4, 0, .2, 1); }

.progress-ring { transform: rotate(-90deg); }
.progress-ring circle { transition: stroke-dashoffset 1.1s cubic-bezier(.4, 0, .2, 1); }

/* ------------------------------------------------------------- kanban */

.kanban { display: flex; gap: 1rem; overflow-x: auto; padding-bottom: 1rem; align-items: flex-start; }

.kanban-col {
    flex: 0 0 305px;
    background: #f8fafc;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: .85rem;
    max-height: calc(100vh - 220px);
    display: flex; flex-direction: column;
}

.kanban-col-head { display: flex; align-items: center; gap: .5rem; padding: .1rem .3rem .75rem; font-weight: 700; font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; }
.kanban-body { overflow-y: auto; flex: 1; display: flex; flex-direction: column; gap: .6rem; }

.kanban-card {
    background: #fff;
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: .8rem;
    box-shadow: var(--shadow-sm);
    transition: all .2s ease;
    cursor: grab;
}

.kanban-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--brand-light); }
.kanban-card.dragging { opacity: .45; transform: rotate(2deg); }
.kanban-col.drop-target { background: var(--brand-soft); border-color: var(--brand-light); }

/* ------------------------------------------------------------ timeline */

.timeline { position: relative; padding-left: 2.1rem; }

.timeline::before {
    content: ''; position: absolute;
    left: 13px; top: 6px; bottom: 6px;
    width: 2px; background: linear-gradient(180deg, var(--brand-light), transparent);
}

.timeline-item { position: relative; padding-bottom: 1.25rem; }

.timeline-item .timeline-dot {
    position: absolute; left: -2.1rem; top: 0;
    width: 28px; height: 28px;
    border-radius: 50%;
    display: grid; place-items: center;
    font-size: .75rem;
    color: #fff;
    box-shadow: 0 0 0 4px #fff;
}

/* -------------------------------------------------------------- comments */

.comment { display: flex; gap: .8rem; padding: .9rem 0; border-bottom: 1px solid #f1f5f9; }
.comment:last-child { border-bottom: 0; }
.comment-body { flex: 1; min-width: 0; }
.comment-bubble { background: #f8fafc; border: 1px solid var(--line); border-radius: 4px 14px 14px 14px; padding: .7rem .9rem; font-size: .875rem; }
.comment-bubble p:last-child { margin-bottom: 0; }
.comment .replies { margin-top: .75rem; padding-left: 1.1rem; border-left: 2px solid var(--line); }

.mention { background: var(--brand-soft); color: var(--brand-dark); padding: .05em .35em; border-radius: 5px; font-weight: 600; }

/* --------------------------------------------------------- notifications */

.notif-item { display: flex; gap: .75rem; padding: .75rem .95rem; border-bottom: 1px solid #f1f5f9; transition: background .15s ease; }
.notif-item:hover { background: #f8fafc; }
.notif-item.unread { background: var(--brand-soft); }
.notif-icon { width: 36px; height: 36px; border-radius: 10px; display: grid; place-items: center; flex-shrink: 0; }

.bell-dot {
    position: absolute; top: 5px; right: 5px;
    min-width: 17px; height: 17px; padding: 0 4px;
    border-radius: 9px;
    background: var(--danger);
    color: #fff;
    font-size: .6rem; font-weight: 800;
    display: grid; place-items: center;
    border: 2px solid #fff;
    animation: pulse 2s infinite;
}

.dropdown-menu {
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-lg);
    padding: .4rem;
    animation: dropIn .18s ease;
}

.dropdown-item { border-radius: 8px; font-size: .865rem; padding: .5rem .75rem; font-weight: 500; }
.dropdown-item:hover { background: var(--brand-soft); color: var(--brand-dark); }
.dropdown-item.text-danger:hover { background: #fee2e2; color: #b91c1c; }

/* ---------------------------------------------------------------- misc */

.empty-state { text-align: center; padding: 3rem 1rem; }
.empty-state .icon { width: 84px; height: 84px; border-radius: 26px; background: var(--brand-soft); color: var(--brand); display: grid; place-items: center; font-size: 2.1rem; margin: 0 auto 1.1rem; animation: floaty 4s ease-in-out infinite; }
.empty-state h5 { margin-bottom: .35rem; }
.empty-state p { color: var(--muted); font-size: .875rem; max-width: 380px; margin: 0 auto 1.2rem; }

.hover-lift { transition: transform .22s ease, box-shadow .22s ease; }
.hover-lift:hover { transform: translateY(-4px); box-shadow: var(--shadow); }

.glass {
    background: rgba(255, 255, 255, .72);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid rgba(255, 255, 255, .5);
}

.gradient-text {
    background: var(--gradient);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

.divider-text { display: flex; align-items: center; gap: .8rem; color: var(--muted); font-size: .78rem; }
.divider-text::before, .divider-text::after { content: ''; flex: 1; height: 1px; background: var(--line); }

.nav-tabs { border-bottom: 1px solid var(--line); gap: .2rem; }
.nav-tabs .nav-link {
    border: 0; border-bottom: 2px solid transparent;
    color: var(--ink-soft); font-weight: 600; font-size: .875rem;
    padding: .6rem 1rem; border-radius: 8px 8px 0 0;
    transition: all .18s ease;
}
.nav-tabs .nav-link:hover { background: var(--brand-soft); color: var(--brand-dark); }
.nav-tabs .nav-link.active { color: var(--brand-dark); border-bottom-color: var(--brand); background: transparent; }

.modal-content { border: 0; border-radius: var(--radius); box-shadow: var(--shadow-lg); }
.modal-header { border-bottom: 1px solid var(--line); padding: 1.1rem 1.35rem; }
.modal-body { padding: 1.35rem; }
.modal-footer { border-top: 1px solid var(--line); padding: 1rem 1.35rem; }

.offcanvas { border-left: 1px solid var(--line); }

.alert { border: 0; border-radius: var(--radius-sm); font-size: .875rem; font-weight: 500; border-left: 4px solid; }
.alert-success { background: #dcfce7; color: #14532d; border-color: var(--success); }
.alert-danger  { background: #fee2e2; color: #7f1d1d; border-color: var(--danger); }
.alert-warning { background: #fef3c7; color: #78350f; border-color: var(--warning); }
.alert-info    { background: #e0f2fe; color: #0c4a6e; border-color: var(--info); }

.pagination { gap: .25rem; }
.page-link { border-radius: 9px !important; border: 1px solid var(--line); color: var(--ink-soft); font-size: .84rem; font-weight: 600; }
.page-link:hover { background: var(--brand-soft); color: var(--brand-dark); border-color: var(--brand-light); }
.page-item.active .page-link { background: var(--gradient); border-color: transparent; }

.filter-bar {
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1rem 1.15rem;
    box-shadow: var(--shadow-sm);
    margin-bottom: 1.25rem;
    /* Nothing inside a filter bar may spill outside the card. */
    overflow: hidden;
}

.filter-bar .row { margin-left: 0; margin-right: 0; }
.filter-bar .form-control,
.filter-bar .form-select { min-width: 0; max-width: 100%; }

/* Native date pickers have a fixed minimum width in Chrome; let them shrink. */
.filter-bar input[type="date"] { padding-left: .6rem; padding-right: .4rem; }

.chart-wrap { position: relative; height: 280px; }
.chart-wrap.sm { height: 220px; }

.file-chip {
    display: flex; align-items: center; gap: .7rem;
    padding: .6rem .8rem;
    border: 1px solid var(--line);
    border-radius: 11px;
    background: #fff;
    transition: all .2s ease;
}
.file-chip:hover { border-color: var(--brand-light); background: var(--brand-soft); }
.file-chip .file-icon { width: 36px; height: 36px; border-radius: 9px; display: grid; place-items: center; font-size: 1.05rem; flex-shrink: 0; }

/* -------------------------------------------------------------- auth */

.auth-wrap { min-height: 100vh; display: grid; grid-template-columns: 1fr 1fr; }

.auth-visual {
    position: relative;
    background: var(--gradient);
    color: #fff;
    display: flex; flex-direction: column; justify-content: center;
    padding: 3.5rem;
    overflow: hidden;
}

.auth-visual::before,
.auth-visual::after {
    content: '';
    position: absolute;
    border-radius: 50%;
    background: rgba(255, 255, 255, .12);
}

.auth-visual::before { width: 420px; height: 420px; top: -140px; right: -110px; animation: floaty 9s ease-in-out infinite; }
.auth-visual::after  { width: 300px; height: 300px; bottom: -110px; left: -80px; animation: floaty 7s ease-in-out infinite reverse; }

.auth-visual .content { position: relative; z-index: 2; max-width: 460px; }

.auth-form-side { display: flex; align-items: center; justify-content: center; padding: 2.5rem 1.5rem; background: #fff; }
.auth-card { width: 100%; max-width: 420px; }

@media (max-width: 991.98px) {
    .auth-wrap { grid-template-columns: 1fr; }
    .auth-visual { display: none; }
}

.feature-row { display: flex; gap: .85rem; align-items: flex-start; margin-bottom: 1.1rem; }
.feature-row .ico { width: 38px; height: 38px; border-radius: 11px; background: rgba(255, 255, 255, .2); display: grid; place-items: center; flex-shrink: 0; }

/* ------------------------------------------------------------ animations */

@keyframes floaty {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-11px); }
}

@keyframes pulse {
    0%   { box-shadow: 0 0 0 0 rgba(239, 68, 68, .55); }
    70%  { box-shadow: 0 0 0 9px rgba(239, 68, 68, 0); }
    100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
}

@keyframes dropIn {
    from { opacity: 0; transform: translateY(-7px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes fadeUp {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

@keyframes shimmer {
    0%   { background-position: -450px 0; }
    100% { background-position: 450px 0; }
}

@keyframes spinSlow { to { transform: rotate(360deg); } }

/* reveal on scroll (see app.js)
   IMPORTANT: once the animation has finished we drop the transform entirely.
   A transformed ancestor becomes the containing block for position:fixed
   children, which would trap modals inside the card instead of the viewport. */
.reveal { opacity: 0; transform: translateY(18px); }
.reveal.in { animation: fadeUp .55s cubic-bezier(.22, 1, .36, 1) forwards; }
.reveal.done { animation: none !important; opacity: 1 !important; transform: none !important; }

/* Users who prefer less motion get no transforms at all. */
@media (prefers-reduced-motion: reduce) {
    .reveal { opacity: 1; transform: none; }
    .reveal.in { animation: none; }
}

.animate-fade   { animation: fadeIn .45s ease both; }
.animate-up     { animation: fadeUp .5s cubic-bezier(.22, 1, .36, 1) both; }
.spin-slow      { animation: spinSlow 9s linear infinite; }

.d-1 { animation-delay: .05s; }
.d-2 { animation-delay: .1s; }
.d-3 { animation-delay: .15s; }
.d-4 { animation-delay: .2s; }
.d-5 { animation-delay: .25s; }
.d-6 { animation-delay: .3s; }

/* page transition */
.page-enter { animation: fadeUp .4s cubic-bezier(.22, 1, .36, 1) both; }

/* top loading bar */
#page-loader {
    position: fixed; top: 0; left: 0;
    height: 3px; width: 0;
    background: var(--gradient);
    z-index: 2000;
    transition: width .3s ease, opacity .3s ease;
    box-shadow: 0 0 12px rgba(99, 102, 241, .8);
}

/* -------------------------------------------------------------- loaders */

/* Full page veil used for slow navigations (reports, exports, checkout). */
#app-loader {
    position: fixed;
    inset: 0;
    z-index: 2050;
    display: none;
    place-items: center;
    background: rgba(248, 250, 252, .72);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

#app-loader.show { display: grid; animation: fadeIn .15s ease; }

#app-loader .loader-box {
    background: #fff;
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 1.6rem 2.2rem;
    text-align: center;
    animation: fadeUp .25s cubic-bezier(.22, 1, .36, 1);
}

#app-loader .loader-text { font-size: .82rem; font-weight: 600; color: var(--ink-soft); margin-top: .8rem; }

/* Brand spinner */
.spinner-brand {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 3px solid var(--brand-soft);
    border-top-color: var(--brand);
    margin: 0 auto;
    animation: spin .7s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* A button that is mid-submit */
.btn.is-loading { position: relative; color: transparent !important; pointer-events: none; }

.btn.is-loading::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 15px; height: 15px;
    margin: -7.5px 0 0 -7.5px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, .45);
    border-top-color: #fff;
    animation: spin .6s linear infinite;
}

.btn-soft.is-loading::after,
.btn-outline-secondary.is-loading::after { border-color: rgba(99, 102, 241, .35); border-top-color: var(--brand); }

/* Skeleton shimmer for content that loads in */
.skeleton {
    background: linear-gradient(90deg, #eef2f7 25%, #f8fafc 37%, #eef2f7 63%);
    background-size: 450px 100%;
    animation: shimmer 1.2s infinite linear;
    border-radius: 8px;
}

/* toast */
.toast-stack { position: fixed; top: calc(var(--topbar-h) + 12px); right: 18px; z-index: 1090; display: flex; flex-direction: column; gap: .6rem; }

.app-toast {
    min-width: 290px;
    background: #fff;
    border-radius: 12px;
    border-left: 4px solid var(--brand);
    box-shadow: var(--shadow-lg);
    padding: .8rem 1rem;
    display: flex; gap: .7rem; align-items: flex-start;
    animation: dropIn .3s cubic-bezier(.22, 1, .36, 1);
}

/* print */
@media print {
    .app-sidebar, .app-topbar, .no-print, .btn { display: none !important; }
    .app-main { margin: 0; padding: 0; }
    .card { box-shadow: none; border: 1px solid #ddd; }
}

/* ------------------------------------------------------------------
   Dashboard list cards

   Left to themselves these cards grow to whatever their content needs,
   so a column with six projects sits next to one with twenty rows of
   activity and the page turns ragged. Fixing the height and scrolling
   the body keeps every row aligned, and the page short enough to scan.
   ------------------------------------------------------------------ */
.dash-card {
    display: flex;
    flex-direction: column;
    height: 420px;
    max-height: 420px;
}

.dash-card > .card-header { flex: 0 0 auto; }

.dash-card-body {
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;              /* without this flex refuses to shrink */
    -webkit-overflow-scrolling: touch;
}

/* A quiet scrollbar - visible enough to hint at more, not loud enough
   to compete with the content. */
.dash-card-body::-webkit-scrollbar { width: 8px; }
.dash-card-body::-webkit-scrollbar-track { background: transparent; }
.dash-card-body::-webkit-scrollbar-thumb {
    background: rgba(100, 116, 139, .25);
    border-radius: 8px;
}
.dash-card-body::-webkit-scrollbar-thumb:hover { background: rgba(100, 116, 139, .45); }
.dash-card-body { scrollbar-width: thin; scrollbar-color: rgba(100, 116, 139, .3) transparent; }

/* A table inside a fixed card keeps its header in view while scrolling. */
.dash-card-body .table > thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--surface, #fff);
}

/* On a phone the cards stack, so a shorter box shows more of the page. */
@media (max-width: 767.98px) {
    .dash-card { height: 340px; max-height: 340px; }
}

/* Wide screens have the room, so show a few more rows before scrolling. */
@media (min-width: 1400px) {
    .dash-card { height: 460px; max-height: 460px; }
}

/* Leads: long e-mails and messages must never widen the table. */
.table td .text-break { word-break: break-word; overflow-wrap: anywhere; }

/* ------------------------------------------------------------------
   Quick-filter chip row

   Wrapping made the bar one line tall sometimes and two others, which
   shifted everything below it. Keeping it on a single line and letting
   it scroll sideways when it has to means the page never jumps.
   ------------------------------------------------------------------ */
.chip-row {
    display: flex;
    flex-wrap: nowrap;
    gap: .5rem;
    overflow-x: auto;
    overflow-y: hidden;
    padding-bottom: 2px;            /* room for the focus ring */
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}

.chip-row::-webkit-scrollbar { height: 6px; }
.chip-row::-webkit-scrollbar-track { background: transparent; }
.chip-row::-webkit-scrollbar-thumb { background: rgba(100, 116, 139, .25); border-radius: 8px; }

/* On desktop there is room for every chip, so hide the scrollbar entirely. */
@media (min-width: 992px) {
    .chip-row { overflow-x: visible; }
    .chip-row::-webkit-scrollbar { display: none; }
}

/* The denominator in a "0 / 1" stat sits back so the number that matters
   still reads first. */
.stat-total {
    font-size: .62em;
    font-weight: 700;
    opacity: .5;
    margin-left: .05em;
}
