/* =====================================================================
   ASVM School - Components (app.css)
   Restyles Bootstrap 5 primitives to a premium SaaS look and adds the app
   shell (topbar + sidebar), KPI cards, tables, floating-label forms,
   badges, toasts, skeletons and empty states. Loaded after theme.css.
   ===================================================================== */

/* =============================================================== SHELL */
.app { display: flex; min-height: 100vh; }

.brand-badge {
    width: 27px; height: 27px; border-radius: 8px;
    display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 12px;
    background: linear-gradient(135deg, var(--brand-500), var(--brand-700));
    box-shadow: var(--sh-sm); flex: 0 0 auto;
}
.icon-btn {
    width: 33px; height: 33px; border-radius: var(--r-sm);
    display: inline-grid; place-items: center;
    background: transparent; border: 1px solid transparent; color: var(--text-soft);
    cursor: pointer; position: relative; transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.icon-btn .dot {
    position: absolute; top: 7px; right: 8px; width: 8px; height: 8px; border-radius: 50%;
    background: #f43f5e; border: 2px solid var(--topbar-bg);
}

/* ---- colored full-height sidebar ---- */
.sidebar {
    width: var(--sidebar-w); flex: 0 0 var(--sidebar-w);
    background: linear-gradient(185deg, var(--side-1) 0%, var(--side-2) 52%, var(--side-3) 100%);
    color: #fff; display: flex; flex-direction: column;
    position: sticky; top: 0; height: 100vh; overflow: hidden; z-index: 30;
    transition: transform var(--dur) var(--ease), width var(--dur) var(--ease);
}
.brand-block { display: flex; align-items: center; gap: 10px; padding: 11px 13px 8px; color: #fff; }
.brand-block:hover { text-decoration: none; color: #fff; }
.brand-badge-lg { width: 34px; height: 34px; border-radius: 10px; background: #fff; color: var(--brand-700);
    display: grid; place-items: center; font-weight: 800; font-size: 13px; box-shadow: var(--sh); flex: 0 0 auto; }
.bb-title { display: block; font-weight: 750; font-size: 13.5px; letter-spacing: -.01em; line-height: 1.15; }
.bb-sub { display: block; font-size: 9px; opacity: .72; letter-spacing: .03em; text-transform: uppercase; }

.side-search { margin: 2px 10px 7px; position: relative; }
.side-search i { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 11px; }
.side-search input { width: 100%; border: none; border-radius: 8px; padding: 6px 10px 6px 29px; font-size: 12px; background: #fff; color: var(--text); }
.side-search input::placeholder { color: var(--muted); }
.side-search input:focus { outline: none; box-shadow: 0 0 0 3px rgba(255,255,255,.35); }

.side-nav { flex: 1 1 auto; overflow-y: auto; padding: 2px 8px 8px; }
.side-nav::-webkit-scrollbar { width: 6px; }
.side-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.22); }
.side-group { margin: 1px 0; }
.side-section { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%;
    text-align: left; background: transparent; border: 0; cursor: pointer; border-radius: 8px;
    font-size: 12.5px; font-weight: 700; letter-spacing: .01em;
    color: rgba(255,255,255,.92); padding: 7px 10px; }
.side-section:hover { color: #fff; background: rgba(255,255,255,.12); }
.side-sec-label { flex: 1 1 auto; text-transform: uppercase; letter-spacing: .05em; font-size: 11.5px; font-weight: 700;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.side-section .grp-chev { font-size: 11px; opacity: .8; transition: transform .18s var(--ease); }
.side-group.open > .side-section { color: #fff; background: rgba(255,255,255,.10); }
.side-group.open > .side-section .grp-chev { transform: rotate(180deg); }
.side-group-items { overflow: hidden; max-height: 0; transition: max-height .22s var(--ease); }
.side-group.open > .side-group-items { max-height: 1200px; }
#sideNav.searching .side-group-items { max-height: none; }
#sideNav.searching .side-section { display: none; }
.side-link {
    display: flex; align-items: center; gap: 10px; padding: 7px 10px; margin-bottom: 1px;
    border-radius: 8px; color: rgba(255,255,255,.88); font-weight: 550; font-size: 12.5px;
    transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.side-link:hover { background: rgba(255,255,255,.13); color: #fff; text-decoration: none; }
.side-link > i:first-child { width: 18px; text-align: center; font-size: 13.5px; opacity: .95; }
.side-label { flex: 1 1 auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.side-badge { background: rgba(255,255,255,.22); color: #fff; font-size: 10px; font-weight: 700;
    min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; display: inline-grid; place-items: center; }
.side-chev { font-size: 9px; opacity: .5; }
.side-link.active { background: #fff; color: var(--brand-700); font-weight: 700; box-shadow: var(--sh-sm); }
.side-link.active > i:first-child { color: var(--brand-600); opacity: 1; }
.side-link.active .side-badge { background: var(--brand-50); color: var(--brand-700); }
.side-link.active .side-chev { color: var(--brand-600); opacity: .8; }

.side-foot { padding: 9px 10px; border-top: 1px solid rgba(255,255,255,.14); display: flex; align-items: center; gap: 9px; }
.side-user { display: flex; align-items: center; gap: 9px; flex: 1 1 auto; min-width: 0; }
.side-user .brand-badge { background: rgba(255,255,255,.2); }
.su-name { font-weight: 650; font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.15; }
.su-role { font-size: 9px; opacity: .72; text-transform: uppercase; letter-spacing: .04em; }
.btn-logout { width: 32px; height: 32px; border-radius: 8px; border: 1px solid rgba(255,255,255,.25);
    background: rgba(255,255,255,.08); color: #fff; display: grid; place-items: center; transition: background var(--dur) var(--ease); }
.btn-logout:hover { background: rgba(255,255,255,.2); color: #fff; }

/* ---- app main (topbar + content over the rail) ---- */
.app-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.topbar {
    position: sticky; top: 0; z-index: 1020; height: var(--topbar-h);
    display: flex; align-items: center; gap: 10px; padding: 0 clamp(11px, 1.6vw, 20px);
    background: var(--topbar-bg); backdrop-filter: saturate(1.4) blur(12px); -webkit-backdrop-filter: saturate(1.4) blur(12px);
    border-bottom: 1px solid var(--border);
}
.tb-title { font-weight: 700; font-size: 14px; letter-spacing: -.01em; }
.topbar-spacer { flex: 1 1 auto; }
.tb-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; color: var(--muted);
    background: var(--surface-2); border: 1px solid var(--border); padding: 4px 9px; border-radius: 999px; }
.tb-avatar { width: 30px; height: 30px; }

.content { flex: 1 1 auto; min-width: 0; padding: 13px clamp(11px, 1.6vw, 20px) 24px; animation: fadeIn .3s var(--ease) both; }

/* collapsed rail (desktop) */
body.sidebar-collapsed .sidebar { width: var(--sidebar-w-collapsed); flex-basis: var(--sidebar-w-collapsed); }
body.sidebar-collapsed .side-label, body.sidebar-collapsed .side-badge, body.sidebar-collapsed .side-chev,
body.sidebar-collapsed .side-sec-label, body.sidebar-collapsed .grp-chev,
body.sidebar-collapsed .bb-title, body.sidebar-collapsed .bb-sub, body.sidebar-collapsed .side-search,
body.sidebar-collapsed .su-name, body.sidebar-collapsed .su-role { display: none; }
body.sidebar-collapsed .side-link, body.sidebar-collapsed .side-foot, body.sidebar-collapsed .brand-block { justify-content: center; }

/* mobile off-canvas */
.sidebar-backdrop { position: fixed; inset: 0; background: rgba(2,6,23,.5); z-index: 25; opacity: 0; visibility: hidden; transition: opacity var(--dur) var(--ease); }
@media (max-width: 991.98px) {
    .sidebar { position: fixed; top: 0; left: 0; z-index: 1040; transform: translateX(-102%); box-shadow: var(--sh-lg); }
    body.sidebar-open .sidebar { transform: none; }
    body.sidebar-open .sidebar-backdrop { opacity: 1; visibility: visible; }
}
@media (min-width: 992px) { .topbar .hamburger { display: none; } }

/* page header */
.page-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 11px; }
.page-head h1 { font-size: 16.5px; margin: 0; }
.page-head .sub { color: var(--muted); font-size: 11.5px; }
.breadcrumb-mini { font-size: 11px; color: var(--muted); margin-bottom: 2px; }
.breadcrumb-mini a { color: var(--muted); }

/* =========================================================== DASHBOARD */
.welcome {
    border-radius: var(--r-lg); padding: 12px 15px; margin-bottom: 12px;
    background: linear-gradient(100deg, var(--accent-tint), transparent 68%);
    border: 1px solid var(--border);
}
.welcome h2 { font-size: 16px; margin: 0; }
.welcome .meta { display: flex; gap: 14px; flex-wrap: wrap; color: var(--muted); font-size: 11.5px; margin-top: 5px; }
.welcome .meta b { color: var(--text-soft); font-weight: 650; }

.section-label { display: flex; align-items: center; gap: 7px; font-size: 10.5px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .09em; color: var(--muted); margin: 13px 2px 7px; }
.section-label i { color: var(--accent); }

/* module quick-stat card */
.mod-card { position: relative; padding: 10px 11px; height: 100%; }
.mod-arrow { position: absolute; top: 9px; right: 9px; width: 24px; height: 24px; border-radius: 50%;
    border: 1px solid var(--border); color: var(--muted); display: grid; place-items: center; font-size: 10px;
    transition: all var(--dur) var(--ease); }
.mod-card:hover .mod-arrow { background: var(--accent); color: #fff; border-color: var(--accent); transform: translateX(2px); }
.mod-ico { width: 30px; height: 30px; border-radius: 8px; display: grid; place-items: center; font-size: 13px; margin-bottom: 6px; }
.mod-title { font-weight: 650; font-size: 12px; }
.mod-num { font-size: 1.25rem; font-weight: 750; letter-spacing: -.02em; line-height: 1.1; margin-top: 1px; }
.mod-label { text-transform: uppercase; letter-spacing: .06em; font-size: 9px; font-weight: 700; color: var(--muted); }
.mod-foot { display: flex; justify-content: space-between; gap: 8px; margin-top: 7px; padding-top: 6px; border-top: 1px solid var(--border); font-size: 11px; color: var(--muted); }

/* soft icon tints */
.tint-indigo { background: var(--accent-tint); color: var(--accent); }   /* content = teal, not red */
.tint-green  { background: var(--success-soft); color: var(--success); }
.tint-amber  { background: var(--warning-soft); color: var(--warning); }
.tint-sky    { background: var(--info-soft); color: var(--info); }
.tint-purple { background: var(--purple-soft); color: var(--purple); }
.tint-red    { background: var(--danger-soft); color: var(--danger); }

/* top-accent stat card (TODAY row) */
.stat-card { position: relative; text-align: center; padding: 9px 9px 9px; overflow: hidden; height: 100%; }
.stat-card::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--sc-accent, var(--brand-600)); }
.stat-card .sc-ico { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; margin: 1px auto 5px; font-size: 13px; }
.stat-card .sc-num { font-size: 1.3rem; font-weight: 750; letter-spacing: -.02em; line-height: 1.05; }
.stat-card .sc-label { text-transform: uppercase; letter-spacing: .06em; font-size: 9.5px; font-weight: 700; color: var(--muted); margin-top: 1px; }
.stat-card .sc-sub { font-size: 10.5px; color: var(--muted); margin-top: 1px; }

/* =============================================================== CARDS */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-sm);
    transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.card.hover-lift:hover { box-shadow: var(--sh-lg); transform: translateY(-3px); border-color: var(--border-strong); }
.card-header, .card-footer { background: transparent; border-color: var(--border); }
.card-body { padding: 12px; }   /* compact default (Bootstrap ships 16px) */
.glass { background: var(--surface-glass); backdrop-filter: blur(14px) saturate(1.3); -webkit-backdrop-filter: blur(14px) saturate(1.3); }

/* KPI */
.kpi { padding: 12px; border-radius: var(--r-lg); position: relative; overflow: hidden; }
.kpi .kpi-icon {
    width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center;
    font-size: 14px; color: var(--accent); background: var(--accent-tint); margin-bottom: 9px;
}
.kpi .kpi-icon.green { color: var(--success); background: var(--success-soft); }
.kpi .kpi-icon.amber { color: var(--warning); background: var(--warning-soft); }
.kpi .kpi-icon.sky   { color: var(--info);    background: var(--info-soft); }
.kpi .kpi-label { text-transform: uppercase; letter-spacing: .08em; font-size: 10px; font-weight: 700; color: var(--muted); }
.kpi .kpi-value { font-size: 1.4rem; font-weight: 750; letter-spacing: -.02em; line-height: 1.1; margin-top: 1px; }
.kpi .kpi-trend { font-size: 11.5px; font-weight: 600; margin-top: 4px; display: inline-flex; align-items: center; gap: 5px; }
.kpi .trend-up { color: var(--success); }
.kpi .trend-down { color: var(--danger); }

/* thin progress bar */
.bar { height: 6px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.bar > span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--accent), var(--navy)); transition: width .6s var(--ease); }

/* ============================================================= BUTTONS */
.btn {
    border-radius: var(--r-sm); font-weight: 600; font-size: 13px;
    padding: .42rem .8rem; border: 1px solid transparent;
    position: relative; overflow: hidden; transition: transform .12s var(--ease), box-shadow var(--dur) var(--ease), background var(--dur) var(--ease), color var(--dur) var(--ease);
    display: inline-flex; align-items: center; gap: 6px;
}
.btn:active { transform: translateY(1px); }
.btn-sm { padding: .3rem .62rem; font-size: 12px; border-radius: var(--r-xs); }
.btn-lg { padding: .7rem 1.2rem; font-size: 15px; }
.btn-primary { background: var(--brand-600); border-color: var(--brand-600); color: #fff; box-shadow: 0 6px 16px -6px rgba(79,70,229,.6); }
.btn-primary:hover { background: var(--brand-700); border-color: var(--brand-700); color: #fff; box-shadow: 0 10px 22px -8px rgba(79,70,229,.7); }
.btn-secondary { background: var(--surface-2); border-color: var(--border-strong); color: var(--text); }
.btn-secondary:hover { background: var(--border); color: var(--text); }
.btn-outline-secondary { border-color: var(--border-strong); color: var(--text-soft); background: transparent; }
.btn-outline-secondary:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-strong); }
.btn-outline-light { border-color: rgba(255,255,255,.5); color: #fff; }
.btn-danger { background: var(--danger); border-color: var(--danger); }
.btn-success { background: var(--success); border-color: var(--success); }
.btn-link { color: var(--brand-600); font-weight: 600; }

/* ripple (added by app.js) */
.ripple-ink { position: absolute; border-radius: 50%; background: rgba(255,255,255,.5); transform: scale(0); pointer-events: none; animation: ripple .6s var(--ease); }
.btn-secondary .ripple-ink, .btn-outline-secondary .ripple-ink, .btn-link .ripple-ink { background: rgba(99,102,241,.28); }

/* =============================================================== FORMS */
.form-control, .form-select {
    border-radius: var(--r-sm); border: 1px solid var(--border-strong);
    background: var(--surface); color: var(--text); font-size: 13px;
    padding: .4rem .65rem; transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background var(--dur) var(--ease);
}
.form-control::placeholder { color: var(--muted); }
.form-control:focus, .form-select:focus { border-color: var(--brand-500); box-shadow: var(--ring); background: var(--surface); color: var(--text); }
.form-control.form-control-sm, .form-select.form-select-sm { padding: .3rem .55rem; font-size: 12px; border-radius: var(--r-xs); }
.form-label { font-size: 11.5px; font-weight: 600; color: var(--text-soft); margin-bottom: 3px; }
textarea.form-control { resize: vertical; }

/* toggle switches - compact RED pill. High specificity (element+class) so it always
   beats Bootstrap's .form-switch .form-check-input regardless of stylesheet load order. */
.form-switch { padding-left: 0; min-height: 20px; display: inline-flex; align-items: center; gap: 8px; margin: 0; }
.form-switch input.form-check-input {
    -webkit-appearance: none; appearance: none;
    flex: 0 0 36px; width: 36px; height: 20px; margin: 0; padding: 0;
    border-radius: 999px; border: 1px solid var(--border-strong); box-shadow: none;
    background-color: var(--surface-2); vertical-align: middle; cursor: pointer;
    background-repeat: no-repeat; background-position: left 2px center; background-size: 16px 16px;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3e%3ccircle cx='8' cy='8' r='7' fill='%2394a3b8'/%3e%3c/svg%3e");
    transition: background-color .2s ease, background-position .2s cubic-bezier(.4,0,.2,1), border-color .2s ease; }
.form-switch input.form-check-input:checked {
    background-color: var(--brand); border-color: var(--brand); background-position: right 2px center;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3e%3ccircle cx='8' cy='8' r='7' fill='%23ffffff'/%3e%3c/svg%3e"); }
.form-switch input.form-check-input:hover { border-color: var(--brand); }
.form-switch input.form-check-input:checked:hover { background-color: var(--brand-700); border-color: var(--brand-700); }
.form-switch input.form-check-input:focus { border-color: var(--brand); box-shadow: 0 0 0 .18rem var(--brand-100); outline: none; }
.form-switch .form-check-label { cursor: pointer; margin: 0; font-size: 12px; font-weight: 500; color: var(--text-soft); user-select: none; }

/* required indicator */
.req > .form-label::after, label.req::after { content: " *"; color: var(--danger); font-weight: 700; }

/* floating labels */
.field { position: relative; margin-bottom: 2px; }
.field > .form-control, .field > .form-select { height: 50px; padding: 1.25rem .85rem .4rem; }
.field > textarea.form-control { height: auto; padding-top: 1.4rem; }
.field > label {
    position: absolute; left: .9rem; top: 50%; transform: translateY(-50%);
    color: var(--muted); font-size: 13.5px; pointer-events: none;
    transition: all .16s var(--ease); background: transparent; padding: 0 2px;
}
.field > textarea.form-control ~ label { top: 1.15rem; transform: none; }
.field > .form-control:focus ~ label,
.field > .form-control:not(:placeholder-shown) ~ label,
.field > .form-select:focus ~ label,
.field > .form-select.has-value ~ label,
.field.filled > label {
    top: 8px; transform: none; font-size: 10px; font-weight: 600; letter-spacing: .03em;
    text-transform: uppercase; color: var(--text-soft);
}
/* accent the label only on the field currently being edited (resting labels stay calm) */
.field > .form-control:focus ~ label,
.field > .form-select:focus ~ label { color: var(--brand-600); font-weight: 700; }

/* neutralise the browser autofill wash so filled fields match the theme (no blue/yellow box) */
.form-control:-webkit-autofill,
.form-control:-webkit-autofill:hover,
.form-control:-webkit-autofill:focus,
.form-control:-webkit-autofill:active {
    -webkit-text-fill-color: var(--text);
    caret-color: var(--text);
    -webkit-box-shadow: inset 0 0 0 1000px var(--surface);
    box-shadow: inset 0 0 0 1000px var(--surface);
    transition: background-color 6000s ease-in-out 0s;
}
.form-control:-webkit-autofill:focus {
    -webkit-box-shadow: inset 0 0 0 1000px var(--surface), var(--ring);
    box-shadow: inset 0 0 0 1000px var(--surface), var(--ring);
}

.field.invalid > .form-control, .field.invalid > .form-select { border-color: var(--danger); }
.field.invalid > label { color: var(--danger); }
.field-msg { font-size: 11.5px; margin-top: 4px; min-height: 1em; }
.field-msg.err { color: var(--danger); }
.field-msg.ok { color: var(--success); }

/* ---- global floating labels (applied by app.js toFloatingForms across all forms) ---- */
.fld-float { position: relative; }
.fld-float > .form-control, .fld-float > .form-select { width: 100%; }
.fld-float > label.form-label {
    position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
    margin: 0; padding: 0 5px; font-size: 13px; font-weight: 500; color: var(--muted);
    background: transparent; pointer-events: none; z-index: 2; white-space: nowrap; overflow: hidden;
    text-overflow: ellipsis; max-width: calc(100% - 26px);
    transition: top .14s var(--ease), font-size .14s var(--ease), color .14s var(--ease);
}
.fld-float.ff-area > label.form-label { top: 16px; transform: none; }
.fld-float.ff-up > label.form-label {
    top: 0; transform: translateY(-50%); font-size: 11px; font-weight: 600; letter-spacing: 0;
    text-transform: none; color: var(--text-soft); background: var(--surface); padding: 0 6px;
}
.fld-float.ff-up.ff-focus > label.form-label { color: var(--brand-600); }

/* validation error state (app.js validateSave) */
.form-control.inv, .form-select.inv { border-color: var(--danger); box-shadow: 0 0 0 .16rem var(--danger-soft); }
.fld-err { color: var(--danger); font-size: 11.5px; font-weight: 600; margin-top: 4px; }

/* validators from asp.net */
.text-danger { color: var(--danger) !important; }

/* =============================================================== TABLE */
.table-wrap { border-radius: var(--r-lg); overflow: hidden; border: 1px solid var(--border); background: var(--surface); }
.table-scroll { overflow: auto; max-height: 62vh; }
table.table { margin: 0; color: var(--text); border-color: var(--border); }
table.table thead th {
    position: sticky; top: 0; z-index: 2;
    background: linear-gradient(180deg, var(--navy), var(--navy-2)); color: #E5EDF7;
    text-transform: uppercase; letter-spacing: .06em; font-size: 10px; font-weight: 700;
    border-bottom: 1px solid var(--accent); white-space: nowrap; padding: 4px 9px;
}
table.table tbody td { padding: 3px 9px; border-color: var(--border); vertical-align: middle; font-size: 12px; line-height: 1.4; }
table.table tbody tr { transition: background var(--dur) var(--ease); }
table.table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--surface-2) 55%, transparent); }
table.table tbody tr:hover { background: var(--surface-2); }
table.table.sortable thead th[data-sort] { cursor: pointer; user-select: none; }
table.table.sortable thead th[data-sort]:hover { color: #fff; }
table.table thead th .sort-ind { opacity: .4; margin-left: 4px; font-size: 9px; }

.num { text-align: right; font-variant-numeric: tabular-nums; }
.table-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 14px; border-bottom: 1px solid var(--border); }
.table-search { position: relative; flex: 1 1 240px; max-width: 340px; }
.table-search i { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 12px; pointer-events: none; }
/* higher specificity so it beats .form-control.form-control-sm padding shorthand */
.table-search input.form-control { padding-left: 30px; }

/* ============================================================== BADGES */
.badge-soft {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 11px; font-weight: 650; padding: 3px 9px; border-radius: var(--r-pill);
    background: var(--surface-2); color: var(--muted);
}
.badge-soft::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge-soft.green { color: var(--success); background: var(--success-soft); }
.badge-soft.amber { color: var(--warning); background: var(--warning-soft); }
.badge-soft.red   { color: var(--danger);  background: var(--danger-soft); }
.badge-soft.sky   { color: var(--info);    background: var(--info-soft); }
.badge-soft.indigo{ color: var(--accent); background: var(--accent-tint); }

/* status as coloured text (pro, non-loud) */
.status { font-weight: 650; font-size: 12.5px; }
.status.green { color: var(--success); } .status.red { color: var(--danger); } .status.muted { color: var(--muted); } .status.amber { color: var(--warning); }

/* =============================================================== TOASTS */
#toast-host { position: fixed; top: calc(var(--topbar-h) + 14px); right: 18px; z-index: 1080; display: flex; flex-direction: column; gap: 10px; max-width: 360px; }
.toast-item {
    display: flex; align-items: flex-start; gap: 11px;
    background: var(--surface); border: 1px solid var(--border); border-left: 4px solid var(--brand-600);
    border-radius: var(--r); box-shadow: var(--sh-lg); padding: 12px 14px;
    animation: slideInRight .3s var(--ease) both;
}
.toast-item.ok { border-left-color: var(--success); }
.toast-item.err { border-left-color: var(--danger); }
.toast-item.warn { border-left-color: var(--warning); }
.toast-item .t-ico { font-size: 15px; margin-top: 1px; }
.toast-item.ok .t-ico { color: var(--success); } .toast-item.err .t-ico { color: var(--danger); } .toast-item.warn .t-ico { color: var(--warning); } .toast-item .t-ico { color: var(--brand-600); }
.toast-item .t-title { font-weight: 650; font-size: 13px; }
.toast-item .t-body { font-size: 12px; color: var(--muted); }
.toast-item.hide { animation: slideInRight .25s var(--ease) reverse forwards; }

/* ============================================================ SKELETON */
.skeleton { position: relative; overflow: hidden; background: var(--surface-2); border-radius: var(--r-sm); }
.skeleton::after { content: ""; position: absolute; inset: 0;
    background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--border) 60%, transparent), transparent);
    background-size: 200% 100%; animation: shimmer 1.3s infinite; }
.skel-line { height: 12px; margin: 8px 0; }

/* top loading bar (page transition / postback) */
#load-bar { position: fixed; top: 0; left: 0; height: 3px; width: 0; z-index: 2000;
    background: linear-gradient(90deg, var(--brand-500), var(--info)); box-shadow: 0 0 10px var(--brand-500);
    transition: width .3s var(--ease), opacity .3s var(--ease); opacity: 0; }
#load-bar.active { opacity: 1; }

/* spinner */
.spin { width: 16px; height: 16px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin .7s linear infinite; display: inline-block; }

/* =========================================================== EMPTY / MISC */
.empty-state { text-align: center; padding: 46px 20px; color: var(--muted); }
.empty-state .ico { font-size: 34px; color: var(--border-strong); margin-bottom: 12px; }
.empty-state h6 { color: var(--text-soft); margin-bottom: 4px; }

/* dropdown menu (bootstrap) */
.dropdown-menu { border-radius: var(--r); border: 1px solid var(--border); box-shadow: var(--sh-lg); background: var(--surface); padding: 6px; animation: pop .16s var(--ease) both; }
.dropdown-item { border-radius: var(--r-xs); font-size: 13px; color: var(--text-soft); padding: 8px 10px; }
.dropdown-item:hover { background: var(--surface-2); color: var(--text); }
.dropdown-divider { border-color: var(--border); }

/* alerts */
.alert { border-radius: var(--r); border: 1px solid var(--border); font-size: 13px; }
.alert-success { background: var(--success-soft); border-color: transparent; color: var(--success); }
.alert-danger { background: var(--danger-soft); border-color: transparent; color: var(--danger); }

/* =============================================================== AUTH */
.auth-body { min-height: 100vh; }
.auth-theme { position: fixed; top: 16px; right: 18px; z-index: 20; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--sh-sm); }
.auth-wrap { display: grid; grid-template-columns: 1.22fr .9fr; min-height: 100vh; }
.auth-visual {
    position: relative; overflow: hidden; color: #fff;
    /* The TOP 20 logo artwork is built on black, so the sign-in panel now uses a deep
       maroon -> near-black ground (a soft red brand glow top-left, a fainter one bottom-right)
       instead of the old flat Coke-red. The logo's own black background then blends seamlessly
       into the panel - no visible rectangle seam - while the gold/red artwork stays the hero. */
    background:
        /* a dark matte behind the logo (fades to the base colour) so the logo's own black
           rectangle melts into the panel with no visible seam, while the red glow still warms
           the rest of the panel around it */
        radial-gradient(700px 470px at 22% 46%, #070406 0%, rgba(7,4,6,.60) 54%, rgba(7,4,6,0) 74%),
        radial-gradient(1000px 560px at 12% 0%, rgba(214,0,8,.38) 0%, rgba(150,0,8,.12) 42%, transparent 70%),
        radial-gradient(820px 820px at 94% 108%, rgba(120,0,6,.26) 0%, transparent 58%),
        linear-gradient(150deg, #24070A 0%, #140609 46%, #070406 100%);
    display: flex; align-items: center; justify-content: center; padding: 6vh 5vw;
}
/* the TOP 20 logo lock-up - the loudest thing on the panel */
.auth-logo {
    display: block; width: min(440px, 84%); height: auto; margin: 0 auto 26px;
    filter: drop-shadow(0 10px 34px rgba(0,0,0,.55));
}
/* A faint wireframe floor, echoing the artwork's grid. It is drawn in CSS so the panel still
   looks designed on a build where Content/img/login-hero.jpg has not been dropped in yet, and it
   is quiet enough (.05) to sit under the photograph once it is there. */
.auth-visual::after {
    content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .05;
    background-image:
        repeating-linear-gradient(64deg, rgba(255,255,255,.9) 0 1px, transparent 1px 62px),
        repeating-linear-gradient(-64deg, rgba(255,255,255,.9) 0 1px, transparent 1px 62px);
    mask-image: linear-gradient(to top, #000 0%, transparent 70%);
    -webkit-mask-image: linear-gradient(to top, #000 0%, transparent 70%);
}
.auth-visual-inner { position: relative; z-index: 1; max-width: 560px; text-align: center; animation: riseIn .5s var(--ease) both; }

/* --- the programme badge: big short label over the descriptive line --- */
.auth-badge {
    display: inline-flex; align-items: center; gap: 14px;
    border: 1px solid rgba(255,255,255,.5); border-radius: 14px;
    padding: 11px 20px 11px 13px; margin-bottom: 30px;
    background: rgba(255,255,255,.08); backdrop-filter: blur(2px);
}
.auth-badge-ico {
    width: 40px; height: 40px; flex: 0 0 auto; border-radius: 11px; background: #fff;
    display: grid; place-items: center; padding: 7px;
}
.auth-badge-ico img { width: 100%; height: auto; display: block; }
.auth-badge-top { font-size: 25px; font-weight: 800; line-height: 1; letter-spacing: .01em; }
.auth-badge-sub { font-size: 11px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
                  color: rgba(255,255,255,.92); margin-top: 5px; }

/* --- the tagline, the loudest thing on the page --- */
.auth-headline {
    color: #fff; font-weight: 900; text-transform: uppercase;
    font-size: clamp(1.9rem, .6rem + 3.2vw, 3.6rem); line-height: 1.04; letter-spacing: -.015em;
    margin: 0; text-shadow: 0 2px 18px rgba(0,0,0,.28);
}
/* The tagline is authored as two lines and must READ as two lines. Wide enough to hold them,
   nothing wraps; below that it is allowed to fold rather than overflow the panel. */
@media (min-width: 1100px) { .auth-headline { white-space: nowrap; } }
/* the closing word of each line carries the accent - dark on the first, gold on the second */
.auth-headline .hl-dark { color: #1A1A1A; }
.auth-headline .hl-gold {
    background: linear-gradient(180deg, #FFE79A 0%, #F5B12B 55%, #D98A00 100%);
    -webkit-background-clip: text; background-clip: text; color: transparent;
}
.auth-sub { color: rgba(255,255,255,.92); font-size: 15px; line-height: 1.65; margin: 22px auto 34px; max-width: 430px; }

/* --- the four stages of the programme --- */
.auth-steps {
    display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap;
    border: 1px solid rgba(255,255,255,.28); border-radius: 16px;
    padding: 14px 10px; background: rgba(0,0,0,.16); backdrop-filter: blur(2px);
}
.auth-step { display: flex; flex-direction: column; align-items: center; gap: 7px; padding: 0 16px; }
.auth-step i { font-size: 17px; color: #fff; }
.auth-step span { font-size: 10.5px; font-weight: 700; letter-spacing: .12em; color: rgba(255,255,255,.95); }
.auth-step-dot { width: 5px; height: 5px; border-radius: 50%; background: #FF5A5F; box-shadow: 0 0 8px #FF3B3B; }
@media (max-width: 1200px) {
    .auth-step { padding: 0 10px; }
    .auth-badge-top { font-size: 21px; }
}

.auth-form { display: flex; align-items: center; justify-content: center; padding: 5vh 6vw; background: var(--bg); background-image: var(--bg-tint); }
.auth-card { width: 100%; max-width: 400px; padding: 34px 30px; border-radius: var(--r-xl); border: 1px solid var(--border); box-shadow: var(--sh-lg); }
.auth-title { font-size: 24px; font-weight: 750; letter-spacing: -.02em; margin: 6px 0 2px; }

/* login form: clean placeholder inputs, evenly aligned (no floating labels) */
.auth-card .fld { margin-top: 13px; }
.auth-card .form-control { height: 46px; padding: 0 .95rem; font-size: 14px; border-radius: var(--r-sm); }
.auth-card .form-control::placeholder { color: var(--muted); opacity: 1; }
.auth-card .btn-lg { padding: .72rem 1rem; font-size: 14px; border-radius: var(--r-sm); }
.otp-input { letter-spacing: 5px; font-family: var(--num); font-weight: 700; text-align: center; }
.otp-input::placeholder { letter-spacing: normal; font-weight: 500; font-family: inherit; }
.auth-error {
    display: flex; align-items: center; gap: 9px; margin-bottom: 16px;
    background: var(--danger-soft); color: var(--danger); border-radius: var(--r);
    padding: 10px 13px; font-size: 12.5px; font-weight: 600; animation: pop .18s var(--ease) both;
}
@media (max-width: 860px) {
    .auth-wrap { grid-template-columns: 1fr; }
    .auth-visual { display: none; }
    .auth-form { min-height: 100vh; }
}

/* utilities */
.divider { height: 1px; background: var(--border); margin: 14px 0; }
.chip { display:inline-flex; align-items:center; gap:6px; font-size:12px; font-weight:600; padding:5px 10px; border-radius: var(--r-pill); background: var(--surface-2); color: var(--text-soft); border:1px solid var(--border); }
.soft-tile { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r); }

/* ===================== ERP Connect kit components ===================== */
/* status pills (soft-tint, semantic) */
.pill { display: inline-flex; align-items: center; gap: .3rem; border-radius: var(--r-pill);
    padding: .1rem .5rem; font-size: 10.5px; font-weight: 700; line-height: 1.5;
    white-space: nowrap; }   /* a status label never breaks across two lines */
.pill-good { background: var(--success-soft); color: var(--success); }
.pill-warn { background: #FEF3C7; color: #92400E; }
.pill-bad  { background: var(--danger-soft); color: var(--danger); }
.pill-info { background: var(--accent-tint); color: var(--accent-700); }
.pill-mut  { background: var(--surface-2); color: var(--muted); }

/* green Excel / export button */
.btn-excel { display: inline-flex; align-items: center; gap: .4rem; border: 1px solid rgba(21,128,61,.28);
    background: var(--success-soft); color: var(--success); font-weight: 700; border-radius: var(--r-sm);
    padding: .3rem .7rem; font-size: 12px; transition: background var(--dur) var(--ease), color var(--dur) var(--ease); }
.btn-excel:hover { background: var(--success); color: #fff; border-color: var(--success); }

/* right-aligned tabular numbers (statements) */
.num-pos { color: var(--success); } .num-neg { color: var(--danger); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--num); white-space: nowrap; }
/* short cells that read better on ONE line (a competency name, a status, a code). The table
   scroller handles the extra width; the mobile card layout gives the value its own row, where
   wrapping is correct, so the rule is lifted there. */
.nowrap { white-space: nowrap; }
/* a read-only field is not disabled (it still submits and still reads clearly) but it must
   never look editable - flat surface, muted text, no caret */
.form-control[readonly], .form-select[readonly] {
    background: var(--surface-2); color: var(--text-soft); cursor: default; box-shadow: none; }
/* app.js wraps every labelled field in .fld-float, and `.fld-float > .form-control:focus`
   further down this file has the SAME specificity - so a plain `.form-control[readonly]:focus`
   loses on source order and a locked box still lights up brand-red. These selectors outrank it. */
.form-control[readonly]:focus,
.fld-float > .form-control[readonly]:focus,
.fld-float > .form-select[readonly]:focus { border-color: var(--border); box-shadow: none; }
/* and the floating label must stay muted too (progressive - ignored where :has is missing) */
.fld-float.ff-focus:has(> .form-control[readonly]) > label.form-label { color: var(--text-soft); }

/* dark formula-style tooltip (Title -> Formula -> Source -> Meaning; code turns gold) */
[data-bs-toggle="tooltip"], th[title] { cursor: help; }
.tooltip { --bs-tooltip-bg: #0F172A; --bs-tooltip-color: #F1F5F9; --bs-tooltip-max-width: 320px; font-size: 12px; }
.tooltip-inner { text-align: left; line-height: 1.4; padding: .5rem .7rem; border-radius: 8px; box-shadow: var(--sh-lg); }
.tooltip-inner code, .tooltip-inner strong { color: #FCD34D; font-weight: 700; }

/* context data-source banner above a report */
.data-banner { display: flex; align-items: flex-start; gap: .55rem; border: 1px solid var(--border);
    background: linear-gradient(90deg, rgba(14,116,144,.06), rgba(15,42,82,.03));
    border-left: 3px solid var(--accent); border-radius: var(--r-sm); padding: .55rem .8rem;
    margin-bottom: .9rem; font-size: 12.5px; color: var(--text-soft); }
.data-banner i { color: var(--accent); margin-top: .1rem; flex: 0 0 auto; }
.data-banner b { color: var(--text); }

/* ============ assessment kit (shared by Online Quiz + Take Case Study) ============ */
.qz-bar { position: sticky; top: 0; z-index: 6; background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r); padding: 12px 14px; margin-bottom: 14px; box-shadow: var(--sh-sm); }
.qz-bar-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.qz-title { font-weight: 700; font-size: 13.5px; color: var(--text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qz-title i { color: var(--brand); }
.qz-count { font-family: var(--num); font-weight: 700; font-size: 13px; color: var(--text-soft); white-space: nowrap; }
.qz-count b { color: var(--brand); }
.qz-headtools { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.qz-progress { height: 6px; border-radius: 999px; background: var(--surface-2); margin-top: 9px; overflow: hidden; }
.qz-progress span { display: block; height: 100%; width: 0; border-radius: 999px;
    background: linear-gradient(90deg, var(--brand), var(--brand-600)); transition: width .3s var(--ease); }

.qz-list { display: flex; flex-direction: column; gap: 12px; }
.q-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); padding: 16px; box-shadow: var(--sh-sm); }
.q-head { display: flex; gap: 10px; align-items: flex-start; }
.q-no { flex: 0 0 26px; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
    background: var(--brand); color: #fff; font-weight: 700; font-size: 12.5px; font-family: var(--num); margin-top: 1px; }
.q-text { font-weight: 600; font-size: 14.5px; line-height: 1.4; color: var(--text); }
.q-marks { font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); margin: 6px 0 0 36px; }

.quiz-opts { display: flex; flex-direction: column; gap: 9px; margin: 12px 0 0 36px; }
.quiz-opts input[type=radio] { display: none; }
.quiz-opts label { display: block; padding: 13px 15px; border: 1.5px solid var(--border-strong); border-radius: 12px;
    cursor: pointer; font-size: 14px; line-height: 1.35; color: var(--text); background: var(--surface);
    transition: border-color .15s var(--ease), background .15s var(--ease), color .15s var(--ease); -webkit-tap-highlight-color: transparent; }
.quiz-opts label:hover { border-color: var(--brand); }
.quiz-opts input[type=radio]:checked + label { border-color: var(--brand); background: var(--brand-100);
    color: var(--brand-700); font-weight: 650; box-shadow: 0 0 0 1px var(--brand) inset; }

.qz-submit { position: sticky; bottom: 0; z-index: 6; margin-top: 16px; padding: 12px 0 4px;
    background: linear-gradient(180deg, transparent, var(--bg) 40%); }

.qz-score .card-body { text-align: center; padding: 30px 20px; }
.score-ring { --pct: 0; width: 150px; height: 150px; border-radius: 50%; margin: 14px auto 6px;
    background: conic-gradient(var(--brand) calc(var(--pct) * 1%), var(--surface-2) 0); display: grid; place-items: center; }
.score-ring-in { width: 118px; height: 118px; border-radius: 50%; background: var(--surface); display: grid; place-items: center; box-shadow: var(--sh-sm); }
.score-pct { font-family: var(--num); font-weight: 800; font-size: 2rem; color: var(--text); letter-spacing: -.02em; }
.score-marks { font-family: var(--num); font-weight: 700; color: var(--text-soft); font-size: 15px; }
.score-msg { font-size: 13px; font-weight: 600; margin-top: 8px; }
.score-msg.ok { color: var(--success); } .score-msg.wait { color: var(--accent-700); }
.score-msg i { margin-right: 5px; }

/* open-text answer + reading gate (case study) */
.cs-answer { margin: 12px 0 0 36px; }
.cs-answer textarea.form-control { width: 100%; }
.cs-gate { opacity: .55; pointer-events: none; filter: grayscale(.2); }
.cs-gatehint { font-size: 12px; color: var(--muted); margin-top: 6px; }
/* the same hint turned into a caution - used when a quiz is submitted part-answered */
.cs-gatehint.warn { color: var(--warning); font-weight: 600; }

@media (max-width: 640px) {
    .q-marks, .quiz-opts, .cs-answer { margin-left: 0; }
    .q-card { padding: 14px; }
}

/* case study PDF reader */
.cs-reader-wrap { border: 1px solid var(--border); border-radius: var(--r); background: var(--surface); box-shadow: var(--sh-sm); overflow: hidden; margin-bottom: 14px; }
.cs-reader { max-height: 62vh; overflow-y: auto; overflow-x: hidden; background: var(--surface-2); padding: 12px;
             overscroll-behavior: contain; scroll-behavior: auto; }
             /* the reader scrolls freely - nothing clamps it; JS only gates SUBMIT on reading time */
/* reading-time indicator in the reader header: seconds still owed on the current page */
.cs-lock { display: inline-flex; align-items: center; gap: 6px; font-family: var(--num);
           font-size: 12px; font-weight: 700; color: var(--warning); white-space: nowrap; }
.cs-lock i { font-size: 11px; }
.cs-readhint.done .cs-lock { color: var(--success); }
.cs-play { border: 1px solid var(--border-strong); background: var(--surface); color: var(--brand-600);
    font-weight: 600; font-size: 12px; border-radius: 999px; padding: 5px 14px; cursor: pointer;
    display: inline-flex; align-items: center; gap: 6px; transition: border-color .15s var(--ease), color .15s var(--ease); }
.cs-play:hover { border-color: var(--brand); }
.cs-readhint.done .cs-play { display: none; }
.cs-page { display: block; margin: 0 auto 12px; max-width: 100%; height: auto; background: #fff; box-shadow: var(--sh-sm); border-radius: 4px; }
.cs-page:last-child { margin-bottom: 0; }
.cs-readhint { padding: 10px 14px; border-top: 1px solid var(--border); font-size: 12px; color: var(--text-soft);
    display: flex; align-items: center; gap: 8px; background: var(--surface); line-height: 1.45; }
/* the hint is a flex item, so it needs min-width:0 or the sentence overflows instead of wrapping */
.cs-readhint > span { flex: 1 1 auto; min-width: 0; }
.cs-readhint.done { color: var(--success); }
/* speak-to-write on the written case-study answers */
.cs-dictate { display: flex; align-items: center; gap: 9px; margin-top: 7px; flex-wrap: wrap; }
.cs-mic { display: inline-flex; align-items: center; gap: 7px; min-height: 44px; padding: 8px 16px;
          border: 1px solid var(--border-strong); border-radius: 999px; background: var(--surface);
          color: var(--brand-600); font-size: 12.5px; font-weight: 600; cursor: pointer;
          transition: border-color .15s, background .15s, color .15s; }
.cs-mic:hover { border-color: var(--brand); }
.cs-mic:active { transform: translateY(1px); }
.cs-dictate.on .cs-mic { background: var(--brand); border-color: var(--brand); color: #fff; }
.cs-dictate.on .cs-mic i { animation: cs-mic-pulse 1.1s ease-in-out infinite; }
@keyframes cs-mic-pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
.cs-mic-hint { font-size: 11.5px; color: var(--text-soft); }
.cs-dictate.on .cs-mic-hint { color: var(--brand-600); }
@media (prefers-reduced-motion: reduce) { .cs-dictate.on .cs-mic i { animation: none; } }
.cs-readhint i { flex: 0 0 auto; }
.cs-loading { padding: 30px; text-align: center; color: var(--muted); font-size: 13px; }

/* the sticky topbar already shows the page title, so the in-page header (breadcrumb + big title + sub)
   is redundant - hide it everywhere to reclaim vertical space (desktop + mobile). */
.page-head { display: none; }

/* ============ responsive table -> stacked cards on phones (opt-in: table.resp-cards) ============ */
.jbar { display: flex; align-items: center; gap: 8px; }
@media (max-width: 760px) {
    .resp-scroll, .table-scroll { overflow-x: visible; }
    table.resp-cards { border: 0; background: transparent; }
    table.resp-cards thead { display: none; }
    table.resp-cards tbody, table.resp-cards tr, table.resp-cards td { display: block; width: 100%; }
    table.resp-cards tr {
        background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
        box-shadow: var(--sh-sm); margin-bottom: 14px; overflow: hidden;
        transition: box-shadow .18s var(--ease), transform .12s var(--ease);
    }
    table.resp-cards tr:active { transform: scale(.995); }
    /* key/value rows */
    table.resp-cards td {
        border: 0; padding: 11px 16px; display: flex; align-items: center; justify-content: space-between;
        gap: 16px; text-align: right; font-size: 13.5px; line-height: 1.35;
    }
    table.resp-cards td[data-label] + td[data-label] { border-top: 1px solid var(--surface-2); }
    table.resp-cards td[data-label]::before {
        content: attr(data-label); color: var(--muted); font-weight: 600; font-size: 10.5px;
        text-transform: uppercase; letter-spacing: .05em; text-align: left; flex: 0 0 auto;
    }
    table.resp-cards td.num { font-family: var(--num); font-weight: 600; color: var(--text); }
    /* the first column = a card header band (title) */
    table.resp-cards td:first-child {
        display: block; text-align: left; font-weight: 700; font-size: 15px; color: var(--text);
        padding: 13px 16px; background: linear-gradient(180deg, var(--surface-2), transparent);
        border-bottom: 1px solid var(--border);
    }
    table.resp-cards td:first-child::before { display: none; }
    /* action / unlabelled cells (e.g. the edit button) = a right-aligned footer strip */
    table.resp-cards td:not([data-label]):not(:first-child) {
        justify-content: flex-end; background: var(--surface-2); padding: 10px 14px;
        border-top: 1px solid var(--border);
    }
    table.resp-cards .jbar { flex: 1 1 auto; max-width: 62%; }
    /* roomier action buttons on the card footer */
    table.resp-cards td .btn-sm { padding: .35rem .7rem; }
    table.resp-cards td.nowrap, table.resp-cards th.nowrap { white-space: normal; }
}

/* roomier, softer form fields everywhere (desktop + mobile) - premium feel */
.fld-float > .form-control, .fld-float > .form-select {
    min-height: 44px; border-radius: 10px;
    transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.fld-float > textarea.form-control { min-height: 80px; }
.fld-float > .form-control:focus, .fld-float > .form-select:focus { border-color: var(--brand-500); box-shadow: var(--ring); }

/* quick login (testing) buttons on the sign-in card */
.quick-login { margin-top: 16px; border-top: 1px dashed var(--border); padding-top: 14px; }
.ql-title { font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); text-align: center; margin-bottom: 9px; }
.ql-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; }
.ql-grid .btn { width: 100%; font-size: 12px; padding: .4rem .3rem; }
@media (max-width: 760px) {
    .card-body .row.g-2 { --bs-gutter-y: .75rem; }         /* a touch more breathing room in dense forms */
    .fld-float > .form-control, .fld-float > .form-select { min-height: 46px; font-size: 14px; }
}

/* ============ custom confirm/alert modal (replaces native confirm/alert app-wide) ============ */
.cmp-modal-ov { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center;
    padding: 20px; background: rgba(15,23,42,.5); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
    animation: fadeIn .15s var(--ease) both; }
.cmp-modal { width: 100%; max-width: 420px; background: var(--surface); color: var(--text); border: 1px solid var(--border);
    border-radius: var(--r-xl); box-shadow: var(--sh-lg); padding: 22px 22px 18px; animation: pop .16s var(--ease) both; }
.cmp-modal-ico { width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center; font-size: 18px; margin-bottom: 12px; }
.cmp-modal-ico.ask { background: var(--brand-100); color: var(--brand-700); }
.cmp-modal-ico.danger { background: var(--danger-soft); color: var(--danger); }
.cmp-modal-ico.info { background: var(--accent-tint); color: var(--accent-700); }
.cmp-modal h3 { font-size: 17px; font-weight: 750; margin: 0 0 6px; letter-spacing: -.01em; color: var(--text); }
.cmp-modal p { font-size: 13.5px; color: var(--text-soft); line-height: 1.5; margin: 0 0 18px; white-space: pre-line; }
.cmp-modal-actions { display: flex; justify-content: flex-end; gap: 8px; }
.cmp-modal-actions .btn { min-width: 96px; }
@media (max-width: 480px) { .cmp-modal-actions { flex-direction: column-reverse; } .cmp-modal-actions .btn { width: 100%; } }
@media (prefers-reduced-motion: reduce) { .cmp-modal-ov, .cmp-modal { animation: none; } }

/* ===================== print ===================== */
@media print {
    .sidebar, .topbar, .no-print, #load-bar, #toast-host, .breadcrumb-mini, .page-head .d-flex { display: none !important; }
    .app, .app-main { display: block; }
    .content { padding: 0 !important; }
    .card, .table-wrap { box-shadow: none !important; border-color: #999 !important; }
    table.table thead th { background: #0F2A52 !important; color: #fff !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
    .pill { border: 1px solid #999; }
    a[href]:after { content: ""; }
    /* profile: print every tab stacked */
    #stTabs { display: none !important; }
    .tab-content .tab-pane { display: block !important; opacity: 1 !important; page-break-inside: avoid; margin-bottom: 6px; }
}

/* =====================================================================
   PREMIUM REFINEMENTS (2026-09-03) - additive polish applied app-wide
   through the shared components, so every page lifts at once. Conservative
   on purpose: shadows / hover / accents only, no layout or logic change.
   ===================================================================== */

/* (1) subtle depth on the page background instead of flat grey (light only;
       dark already has its own bg-tint at higher specificity, untouched) */
:root {
    --bg-tint:
        radial-gradient(1200px 560px at 100% -12%, rgba(14,116,144,.055), transparent 58%),
        radial-gradient(900px 520px at -10% 112%, rgba(15,42,82,.045), transparent 55%);
}

/* (2) on-brand primary button: a soft red gradient with red depth (the old
       shadow + ripple were an off-brand indigo left over from a past theme) */
.btn-primary { background: linear-gradient(180deg, #FF1B26 0%, var(--brand-600) 60%);
    box-shadow: 0 6px 15px -7px rgba(244,0,9,.55); }
.btn-primary:hover { background: linear-gradient(180deg, var(--brand-600) 0%, var(--brand-700) 100%);
    box-shadow: 0 12px 24px -9px rgba(244,0,9,.62); }
.btn-primary:active { box-shadow: 0 4px 11px -6px rgba(244,0,9,.5); }
.btn-secondary .ripple-ink, .btn-outline-secondary .ripple-ink, .btn-link .ripple-ink { background: rgba(244,0,9,.16); }

/* (3) dashboard tiles feel alive: a gentle lift on hover (KPI / stat / module) */
.stat-card, .kpi, .mod-card { transition: transform .16s var(--ease), box-shadow .16s var(--ease), border-color .16s var(--ease); }
.stat-card:hover, .kpi:hover, .mod-card:hover { transform: translateY(-3px); box-shadow: var(--sh); border-color: var(--border-strong); }

/* (4) section labels read as designed section dividers, not just tiny caps */
.section-label::before { content: ""; width: 3px; height: 13px; border-radius: 2px; flex: 0 0 auto;
    background: linear-gradient(180deg, var(--accent), var(--navy)); }

/* (5) the welcome banner gets quiet depth + a brand-adjacent accent edge */
.welcome { box-shadow: var(--sh-sm); border-left: 3px solid var(--accent); }

/* (6) every empty state's icon becomes a soft gradient tile (premium, friendly) */
.empty-state .ico { display: inline-grid; place-items: center; width: 64px; height: 64px; border-radius: 18px;
    font-size: 26px; color: var(--accent); margin: 0 auto 14px;
    background: linear-gradient(135deg, var(--accent-tint), var(--surface-2)); }

/* (7) list/card toolbars get a whisper-soft header wash so a plain table card
       reads as a titled panel rather than a naked grid */
.table-toolbar { background: linear-gradient(180deg, color-mix(in srgb, var(--surface-2) 55%, transparent), transparent); }

/* (8) primary action links / .hover-lift cards: a slightly richer lift */
.card.hover-lift { transition: transform .16s var(--ease), box-shadow .16s var(--ease), border-color .16s var(--ease); }
.card.hover-lift:hover { transform: translateY(-4px); box-shadow: var(--sh-lg); }

/* (9) pills get a hairline for crisper definition on soft backgrounds */
.pill { border: 1px solid color-mix(in srgb, currentColor 22%, transparent); }

/* =====================================================================
   MOTION LAYER (2026-09-03) - a subtle entrance + micro-animation on EVERY
   page, applied through the shared shell so nothing per-page is needed.
   The global prefers-reduced-motion guard in theme.css neutralises all of it.
   ===================================================================== */

/* top-level page blocks rise + fade in, lightly staggered, on each load */
.content > * { animation: riseIn .5s var(--ease) both; }
.content > *:nth-child(1) { animation-delay: .03s; }
.content > *:nth-child(2) { animation-delay: .09s; }
.content > *:nth-child(3) { animation-delay: .15s; }
.content > *:nth-child(4) { animation-delay: .20s; }
.content > *:nth-child(5) { animation-delay: .25s; }
.content > *:nth-child(6) { animation-delay: .29s; }
.content > *:nth-child(n+7) { animation-delay: .33s; }

/* KPI / stat numbers + score ring pop in a beat later, so the value lands */
.sc-num, .mod-num, .kpi-value, .hero-num, .score-pct { animation: pop .55s var(--ease) both; animation-delay: .18s; }

/* the coloured icon tiles + journey nodes assemble with a gentle pop */
.sc-ico, .mod-ico, .kpi-icon, .jny-node, .lh-empty-ico, .empty-state .ico { animation: pop .5s var(--ease) both; animation-delay: .12s; }

/* list rows fade in in sequence - capped to the first 14 so a 500-row report
   never animates hundreds of elements at once */
table.table tbody tr:nth-child(-n+14) { animation: fadeIn .45s var(--ease) both; }
table.table tbody tr:nth-child(1) { animation-delay: .04s; }
table.table tbody tr:nth-child(2) { animation-delay: .07s; }
table.table tbody tr:nth-child(3) { animation-delay: .10s; }
table.table tbody tr:nth-child(4) { animation-delay: .13s; }
table.table tbody tr:nth-child(5) { animation-delay: .16s; }
table.table tbody tr:nth-child(6) { animation-delay: .19s; }
table.table tbody tr:nth-child(7) { animation-delay: .22s; }
table.table tbody tr:nth-child(8) { animation-delay: .25s; }
table.table tbody tr:nth-child(n+9):nth-child(-n+14) { animation-delay: .28s; }
