/* ============================================================
   KAY SCIENCE — Student Dashboard (new, isolated redesign)
   Self-contained stylesheet. Does NOT depend on any existing
   dashboard / Metronic / Bootstrap CSS.
   ============================================================ */

/* ---------- Self-hosted Poppins (guarantees the typeface loads) ---------- */
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/poppins-400.woff2') format('woff2');
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/poppins-500.woff2') format('woff2');
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('../fonts/poppins-600.woff2') format('woff2');
}
@font-face {
    font-family: 'Poppins';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('../fonts/poppins-700.woff2') format('woff2');
}

/* ---------- Design tokens ---------- */
:root {
    --ks-font: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

    /* text — sampled from the PDF: one saturated blue-violet family, no neutral grey */
    --ks-heading: #4848ae;   /* headings, card titles, numbers, due values */
    --ks-indigo:  #4848ae;   /* primary text */
    --ks-indigo-soft: #5b5bb6;  /* teacher names / dates */
    --ks-muted:   #7c7cc2;   /* secondary labels (Due In / Progress / stat labels) */

    /* brand — official Kay Science palette */
    --ks-purple:   #a48dee;   /* CONTINUE HOMEWORK  */
    --ks-purple-2: #b9a6f2;   /* lighter purple (gradient end) */
    --ks-teal:     #66c2cc;   /* REDO HOMEWORK */
    --ks-mint:     #90ecda;   /* FINISH HOMEWORK */
    --ks-cyan:     #74d2e2;   /* DASHBOARD HIGHLIGHT */
    --mod-green:   #ecf8f5;   /* MODULE HIGHLIGHT - GREEN */
    --mod-blue:    #dff0f2;   /* MODULE HIGHLIGHT - BLUE  */

    /* surfaces */
    --ks-bg:      #fbfbfd;
    --ks-card:    #ffffff;
    --ks-track:   #e7e7f0;
    --ks-divider: #eef0f4;

    /* gradients (built from the official palette) */
    --grad-purple-teal: linear-gradient(90deg, #a48dee 0%, #90ecda 100%);
    --grad-purple-btn:  linear-gradient(135deg, #a48dee 0%, #b9a6f2 100%);
    --grad-keepgoing:   linear-gradient(90deg, #90ecda 0%, #ecf8f5 52%, #9fe9dd 100%);

    /* badge tints */
    --grad-badge-green:  linear-gradient(135deg, #b6f0df 0%, #90ecda 100%);
    --grad-badge-blue:   linear-gradient(135deg, #8fdcea 0%, #74d2e2 100%);
    --grad-badge-purple: linear-gradient(135deg, #bda7f3 0%, #a48dee 100%);

    --ks-radius:   18px;
    --ks-radius-lg: 24px;
    --ks-radius-pill: 999px;
    --ks-shadow:    0 12px 30px rgba(78, 66, 150, .07);
    --ks-shadow-sm: 0 6px 18px rgba(78, 66, 150, .06);
    /* Rail width. 212px cut the right end off the longest menu labels
       ("Upgrade to Full Access", "LIVE Tuition! Click") — the items are nowrap
       and .ks-sidebar is overflow:hidden, so they were clipped at the edge.
       260px leaves the longest label ~8px of slack at its 14px/600 size.
       .ks-main's margin-left reads the same variable, so the content area
       follows automatically. */
    --ks-sidebar-w: 260px;
}

/* ---------- Reset (scoped to dashboard) ---------- */
/* The browser's default 8px body margin made the document ~16px taller than
   the viewport even though .ks-main already has its own height:100vh +
   overflow:auto scroll — that stray 16px triggered a second, page-level
   scrollbar alongside .ks-main's intentional one. */
body:has(> .ks-app) { margin: 0; }

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

.ks-app {
    margin: 0;
    font-family: var(--ks-font);
    color: var(--ks-indigo);
    background: var(--ks-bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    display: block;
    min-height: 100vh;
    font-size: 15px;
    line-height: 1.4;
}
.ks-app a { text-decoration: none; color: inherit; }
.ks-app ul { list-style: none; margin: 0; padding: 0; }
.ks-app button { font-family: inherit; cursor: pointer; border: none; background: none; }

/* ============================================================
   SIDEBAR
   ============================================================ */
.ks-sidebar {
    width: var(--ks-sidebar-w);
    /* Brand gradient, sampled straight off the brand sheet: pure vertical,
       #9D88E5 -> #87CFD7 at the halfway point -> #A8F0D2. */
    background: linear-gradient(180deg, #9D88E5 0%, #87CFD7 50%, #A8F0D2 100%);
    border-radius: 0 36px 36px 0;
    padding: 30px 0 24px;
    display: flex;
    flex-direction: column;
    position: fixed;        /* stays fixed on the left during horizontal/vertical scroll */
    left: 0;
    top: 0;
    height: 100vh;
    overflow: hidden;
    z-index: 20;
}

.ks-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 4px 26px 72px;   /* breathing room between the logo and "My Homework" */
    color: #fff;
}
.ks-brand__logo { width: 100%; max-width: 160px; height: auto; display: block; }
.ks-brand__logo svg { width: 100%; height: 100%; }
.ks-brand__text { line-height: 1; }
.ks-brand__text .t1 { font-weight: 400; font-size: 17px; letter-spacing: 3px; display: block; }
.ks-brand__text .t2 { font-weight: 700; font-size: 19px; letter-spacing: 2px; display: block; }

/* "Upgrade to Full Access" — purple gradient pill above the nav.
   Shown only for Private students without an active plan (same gate as the
   old top-menu-bar "Get Full Access" button). */
.ks-upgrade {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin: 0 22px 20px;
    padding: 13px 18px;
    background: linear-gradient(135deg, #7b61e6, #6d5ae0);
    color: #fff;
    border-radius: var(--ks-radius-pill, 999px);
    font-weight: 600;
    font-size: 14px;
    text-decoration: none;
    box-shadow: 0 12px 24px rgba(95, 80, 175, .28);
    transition: transform .18s ease, box-shadow .18s ease, filter .18s ease;
}
.ks-upgrade:hover { transform: translateY(-1px); box-shadow: 0 16px 30px rgba(95, 80, 175, .36); filter: brightness(1.04); }
.ks-upgrade .ks-ico { width: 18px; height: 18px; flex-shrink: 0; color: #fff; }

.ks-nav {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding-right: 0;
    padding-bottom: 8px;
    /* Take the free vertical space and scroll internally when the menu is tall
       (e.g. Upgrade + Return to Admin present) so the user block below stays visible. */
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, .7) transparent;
}
.ks-nav::-webkit-scrollbar { width: 6px; }
.ks-nav::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .7); border-radius: 999px; }
.ks-nav::-webkit-scrollbar-track { background: transparent; }
.ks-nav__item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 16px;
    margin-left: 18px;
    padding: 10px 20px;
    min-height: 52px;   /* every menu item (Upgrade, My Homework, …) is the same height */
    /* Diagonal white sheen sampled off the design: solid white at the bottom-left
       cap, thinning to ~13% two-thirds along the axis, then lifting back to ~75%
       at the top-right. The 60deg tilt is measured — the thin band sits ~18px
       further right at the pill's bottom edge than at its top. */
    background: linear-gradient(60deg,
        rgba(255, 255, 255, 1) 0%,
        rgba(255, 255, 255, .13) 67%,
        rgba(255, 255, 255, .75) 100%);
    color: var(--ks-indigo);
    border-radius: var(--ks-radius-pill) 0 0 var(--ks-radius-pill);
    font-weight: 600;
    font-size: 14px;
    box-shadow: 0 8px 18px rgba(95, 80, 175, .08);
    transition: background .18s ease, transform .18s ease;
}
/* Every nav icon occupies the SAME square box, whatever the artwork's aspect
   (nav-homework is 0.73:1, the rest are ~0.95:1). Without the fixed box the
   icons rendered at different widths, so they sat off-centre against each
   other and each label started at a different x. object-fit keeps the artwork
   undistorted and fully inside the box. */
.ks-nav__item .ks-ico { width: 28px; height: 28px; flex-shrink: 0; color: var(--ks-indigo); }
.ks-nav__icon { width: 28px; height: 28px; flex-shrink: 0; display: block; object-fit: contain; }
.ks-nav__item > span { white-space: nowrap; }   /* keep every menu label on one line */
.ks-nav__item:hover {
    background: linear-gradient(60deg,
        rgba(255, 255, 255, 1) 0%,
        rgba(255, 255, 255, .34) 67%,
        rgba(255, 255, 255, .9) 100%);
}

/* "Upgrade to Full Access" — standard menu-item shape, fitted onto one line
   (smaller gap/type than a normal label since the copy is longer). Purple fill
   so the white label + crown stay readable and the action stands out. */
.ks-nav__upgrade {
    gap: 12px;   /* font-size/weight inherit from .ks-nav__item — same as every menu label */
    color: #fff;
    background: linear-gradient(135deg, #7b61e6, #6d5ae0);
    box-shadow: 0 8px 18px rgba(95, 80, 175, .22);
}
.ks-nav__upgrade > span { color: #fff; }
.ks-nav__upgrade .ks-ico { width: 27px; height: 27px; color: #fff; }   /* match the menu icon size */
.ks-nav__upgrade:hover { background: linear-gradient(135deg, #8670ea, #7666e4); }

/* "LIVE Tuition! Click" — the legacy menu's live-tuition button, kept in the same
   green (.btn-live-tuition, #00b050) so students recognise it, shaped as a normal
   menu item. Rendered inside `.live_tuition`, which the legacy live-tuition script
   shows in place of the "Live Lessons" item while a lesson is on air. */
.ks-nav__live {
    gap: 12px;
    color: #fff;
    background: #00b050;
    box-shadow: 0 8px 18px rgba(0, 176, 80, .22);
}
.ks-nav__live > span { color: #fff; }
.ks-nav__live .ks-ico { width: 16px; height: 16px; color: #fff; }
.ks-nav__live:hover { background: #009d48; }
/* The active item carries the SAME sheen as the rest (that is how the design
   draws it) — only the cyan cap and the deeper shadow set it apart. */
.ks-nav__item.is-active {
    box-shadow: 0 12px 24px rgba(95, 80, 175, .16);
}
/* The accent is the pill's own left cap painted cyan: it runs the FULL height of
   the item and its outer edge follows the pill's round end. Hence inset:0 +
   border-radius:inherit (exact pill silhouette) with a hard-stop gradient that
   colours only the leftmost 17px — matching the design, where the bar measures
   ~0.32 x the item height. */
.ks-nav__item.is-active::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(180deg, #43DBE8, #28D3E5) left / 13px 100% no-repeat;
    pointer-events: none;
}

/* Emitted by the private-student menu-lock condition ($ksDisableMenu, from
   StudentDashboardController::privateMenuState()), exactly as on the legacy top
   menu bar. Same rule as frontend/css/main.css, which this shell does not load. */
.disabledMenu {
    cursor: not-allowed;
    pointer-events: none;
    opacity: .55;
}

/* …except in the sidebar, where a locked item stays clickable ON PURPOSE: it
   keeps the greyed-out look but leads to the "Upgrade to Full Access" page
   rather than its own paywalled destination. */
.ks-nav__item.disabledMenu {
    pointer-events: auto;
    cursor: pointer;
}

/* "Return to Admin" — nav-item look (inherits .ks-nav__item) reset for a
   <button>, tinted red so the admin action stands out from the menu links. */
/* Two classes so this beats the global `.ks-app button { background: none }`
   reset and shows the SAME pill background as the menu links (e.g. Leaderboard). */
.ks-nav__item.ks-return-admin {
    border: 0;
    cursor: pointer;
    font-family: inherit;
    text-align: left;
    color: var(--ks-indigo);   /* same text colour as the menu links (e.g. Leaderboard) */
    background: linear-gradient(60deg,
        rgba(255, 255, 255, 1) 0%,
        rgba(255, 255, 255, .13) 67%,
        rgba(255, 255, 255, .75) 100%);
}
.ks-return-admin .ks-ico { width: 22px; height: 22px; flex-shrink: 0; color: var(--ks-indigo); }
.ks-return-admin:hover {
    background: linear-gradient(60deg,
        rgba(255, 255, 255, 1) 0%,
        rgba(255, 255, 255, .34) 67%,
        rgba(255, 255, 255, .9) 100%);
}
.ks-return-admin:disabled { opacity: .6; cursor: default; }

.ks-sidebar__spacer { flex: 0 0 0; }   /* .ks-nav now takes the free space (see above) */

.ks-user {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 26px 4px;
    color: #fff;
}
.ks-user__avatar {
    width: 64px; height: 64px; border-radius: 50%;
    /* White brand mark on the sidebar's own colour — no pale disc or ring
       behind it, which a white icon would disappear into. */
    object-fit: contain; flex-shrink: 0; background: transparent;
}
.ks-user__meta { line-height: 1.2; display: flex; flex-direction: column; align-items: flex-start; }
.ks-user__name { font-weight: 600; font-size: 16px; display: inline-flex; align-items: center; gap: 6px; }
.ks-user__name .ks-ico { width: 16px; height: 16px; }
.ks-user__role { display: block; font-size: 13px; opacity: .85; font-weight: 400; }

/* ---- User-menu flyout: hover (or click) the name/avatar -> My Profile /
   Manage Plan / Logout panel opens to the right of the sidebar. Same pattern
   as the teacher dashboard's flyout (teacher-dashboard/css/teacher-common.css). ---- */
.ks-sidebar:has(.ks-user-menu) { overflow: visible; }   /* let the flyout escape the sidebar box */
.ks-user-menu { position: relative; }
.ks-user-menu .ks-user { cursor: pointer; }
.ks-user-menu::before {
    content: "";
    position: fixed;
    inset: 0;
    background: rgba(27, 27, 43, .32);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .16s ease, visibility .16s;
    z-index: 4;
}
.ks-user-menu:hover::before,
.ks-user-menu:focus-within::before {
    opacity: 1;
    visibility: visible;
}
.ks-user-menu__panel {
    position: absolute;
    left: calc(100% + 16px);
    bottom: -6px;
    min-width: 210px;
    /* same brand gradient as the sidebar itself, so the flyout reads as an
       extension of the sidebar rather than a plain white popup */
    background: linear-gradient(180deg, #9D88E5 0%, #87CFD7 50%, #A8F0D2 100%);
    border-radius: 18px;
    box-shadow: 0 20px 46px rgba(20, 20, 40, .28);
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateX(-6px);
    transition: opacity .16s ease, transform .16s ease, visibility .16s;
    z-index: 5;
}
/* invisible hover-bridge over the gap so moving the cursor from the avatar
   into the panel doesn't cross a dead zone and close it early */
.ks-user-menu__panel::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: -16px;
    width: 16px;
}
/* caret connecting the panel back to the avatar it belongs to */
.ks-user-menu__panel::after {
    content: "";
    position: absolute;
    left: -6px;
    bottom: 22px;
    width: 12px;
    height: 12px;
    background: #A2EAD3;   /* gradient colour at the caret's height */
    transform: rotate(45deg);
    border-radius: 2px;
}
.ks-user-menu:hover .ks-user-menu__panel,
.ks-user-menu:focus-within .ks-user-menu__panel {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateX(0);
}
.ks-user-menu__item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 8px 14px;
    /* same translucent-white pill as .ks-nav__item, so the flyout entries look
       like the sidebar menu buttons */
    min-height: 42px;
    background: linear-gradient(60deg,
        rgba(255, 255, 255, 1) 0%,
        rgba(255, 255, 255, .13) 67%,
        rgba(255, 255, 255, .75) 100%);
    border-radius: var(--ks-radius-pill);
    box-shadow: 0 8px 18px rgba(95, 80, 175, .08);
    font-size: 14.5px;
    font-weight: 600;
    color: var(--ks-indigo);
    white-space: nowrap;
    transition: background .12s ease;
}
.ks-user-menu__icon {
    width: 26px; height: 26px; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    background: transparent;
    color: var(--ks-indigo);
}
.ks-user-menu__icon svg { width: 16px; height: 16px; }
.ks-user-menu__item:hover {
    background: linear-gradient(60deg,
        rgba(255, 255, 255, 1) 0%,
        rgba(255, 255, 255, .34) 67%,
        rgba(255, 255, 255, .9) 100%);
}
/* Logout is a different kind of action — red tint on hover */
.ks-user-menu__item--danger:hover { background: #fdeceb; color: #d64545; }
.ks-user-menu__item--danger:hover .ks-user-menu__icon { color: #d64545; }

/* right-arrow hint that hovering the name/avatar opens a popup */
.ks-user-menu__caret {
    margin-left: auto;
    flex-shrink: 0;
    opacity: .75;
    transition: opacity .15s ease, transform .15s ease;
}
.ks-user-menu__caret svg { width: 16px; height: 16px; display: block; }
.ks-user-menu:hover .ks-user-menu__caret,
.ks-user-menu:focus-within .ks-user-menu__caret {
    opacity: 1;
    transform: translateX(2px);
}

/* ---- Fit the whole menu without the nav needing its own scrollbar ----
   The menu can hold up to 8 items (Upgrade + 6 links + Return to Admin). At the
   roomy default spacing that overflows on shorter screens, so .ks-nav scrolls.
   These height-based tiers progressively tighten the vertical rhythm as the
   viewport gets shorter — tall screens keep the generous look, short laptops fit
   every item. (.ks-nav keeps overflow-y:auto as a last-resort fallback.) */
@media (max-height: 820px) {
    .ks-brand { padding-bottom: 50px; }
    .ks-nav { gap: 10px; }
    .ks-nav__item { padding: 9px 20px; min-height: 48px; }
}
@media (max-height: 720px) {
    .ks-sidebar { padding: 20px 0 16px; }
    .ks-brand { padding-bottom: 32px; }
    .ks-nav { gap: 7px; }
    .ks-nav__item { padding: 8px 20px; min-height: 44px; font-size: 14px; gap: 12px; }
    .ks-nav__icon { width: 22px; height: 22px; }
    .ks-nav__item .ks-ico { width: 22px; height: 22px; }
    .ks-nav__upgrade .ks-ico { width: 19px; height: 19px; }
    .ks-user { padding-top: 6px; }
    .ks-user__avatar { width: 54px; height: 54px; }
}

/* ============================================================
   MAIN
   ============================================================ */
.ks-main {
    margin-left: var(--ks-sidebar-w);   /* room for the fixed sidebar */
    height: 100vh;
    overflow: auto;                      /* content scrolls here; sidebar stays fixed */
    padding: 34px 34px 40px;
    /* same styled scrollbar as the Past Papers page's own scroll boxes
       (.pp-filters/.pp-results in past-papers.css) */
    scrollbar-width: thin;
    scrollbar-color: #cdc6ec transparent;
}
.ks-main::-webkit-scrollbar { width: 9px; }
.ks-main::-webkit-scrollbar-track { background: transparent; }
.ks-main::-webkit-scrollbar-thumb {
    background: #d3cdec;
    border-radius: 9px;
    border: 2px solid transparent;
    background-clip: padding-box;
}
.ks-main::-webkit-scrollbar-thumb:hover { background: #b9afe6; }

/* topbar (greeting) */
.ks-topbar { margin-bottom: 26px; }
.ks-topbar__title {
    margin: 0 0 6px;
    font-size: 34px;
    font-weight: 600;
    color: var(--ks-heading);
    display: flex;
    align-items: center;
    gap: 10px;
    letter-spacing: .2px;
}
.ks-topbar__title .ks-wave { width: 36px; height: 36px; margin-left: 2px; }
.ks-topbar__subtitle { margin: 0; color: var(--ks-indigo); font-weight: 500; font-size: 14px; }

.ks-hamburger {
    display: none;
    width: 44px; height: 44px;
    border-radius: 12px;
    background: #fff;
    box-shadow: var(--ks-shadow-sm);
    color: var(--ks-indigo);
    align-items: center;
    justify-content: center;
}
.ks-hamburger .ks-ico { width: 22px; height: 22px; }

/* Standalone drawer trigger rendered by layouts/student-dashboard.blade.php on
   pages that hide the greeting top-bar (video lesson, quizzes, checkout…).
   Those pages have no .ks-topbar in the DOM, so without this button the mobile
   off-canvas sidebar has no way to be opened. Desktop keeps it hidden via the
   base .ks-hamburger rule above; the <=860px block below shows it. */
/* .ks-app prefix outranks the ".ks-app button { background: none }" reset. */
.ks-app .ks-hamburger--float {
    flex: 0 0 auto;
    align-self: flex-start;
    margin: 0 0 12px;
    position: relative;
    z-index: 10;
    background: #fff;
    box-shadow: var(--ks-shadow-sm);
}

/* ---------- Stats strip ---------- */
.ks-stats {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    background: var(--ks-card);
    border-radius: var(--ks-radius);
    box-shadow: var(--ks-shadow);
    padding: 22px 10px;
    margin-bottom: 26px;
}
.ks-stat {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 4px 24px;
    position: relative;
}
.ks-stat + .ks-stat::before {
    content: "";
    position: absolute;
    left: 0; top: 50%;
    transform: translateY(-50%);
    height: 46px;
    width: 1px;
    background: var(--ks-divider);
}
/* The component wraps icon + copy in .ks-stat__inner so pages that need it can
   size the icon off the copy block. Here it just reproduces the old flat
   icon+copy row, so the dashboard/league-table strips are unchanged. */
.ks-stat__inner { display: flex; align-items: center; gap: inherit; width: 100%; }
.ks-stat__icon { height: 64px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.ks-stat__icon svg { width: 60px; height: 60px; }
.ks-stat__icon img { height: 64px; width: auto; display: block; }
.ks-stat__value { font-size: 24px; font-weight: 600; color: var(--ks-indigo); line-height: 1.1; }
.ks-stat__label { font-size: 13.5px; color: var(--ks-muted); font-weight: 500; margin-top: 2px; }

/* ---------- Two column area ---------- */
.ks-columns {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 450px;
    gap: 30px;
    align-items: start;
}
.ks-col-left { display: flex; flex-direction: column; gap: 26px; min-width: 0; }

/* ---------- Section header ---------- */
.ks-section__head {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
}
.ks-section__head h2 {
    margin: 0;
    font-size: 19px;
    font-weight: 600;
    color: var(--ks-heading);
}
.ks-section__count {
    margin-left: auto;
    width: 30px; height: 30px;
    border-radius: 50%;
    background: var(--grad-purple-teal);
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    display: flex; align-items: center; justify-content: center;
}
.ks-section__info {
    margin-left: auto;
    width: 26px; height: 26px;
    color: var(--ks-purple);
}

/* exact badge images extracted from the design */
.ks-section-badge { width: 44px; height: 44px; flex-shrink: 0; display: block; }
.ks-pstat-badge { width: 52px; height: 52px; flex-shrink: 0; display: block; }

/* round tinted badge used in section heads & progress stats */
.ks-badge {
    width: 44px; height: 44px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.ks-badge .ks-ico { width: 24px; height: 24px; }
.ks-badge--green  { background: var(--grad-badge-green);  color: #3bbd9b; }
.ks-badge--blue   { background: var(--grad-badge-blue);   color: #1f86ad; }
.ks-badge--purple { background: var(--grad-badge-purple); color: #ffffff; }
.ks-badge--green-soft  { background: var(--mod-green); color: #54c7b3; }
.ks-badge--blue-soft   { background: var(--mod-blue);  color: #5bbfd2; }
.ks-badge--purple-soft { background: #ece4fb;          color: #a48dee; }

/* ---------- Cards (homework) ---------- */
.ks-card {
    background: var(--ks-card);
    border-radius: var(--ks-radius);
    box-shadow: var(--ks-shadow);
}

.ks-hw-row {
    display: grid;
    grid-template-columns: minmax(0, 1.9fr) minmax(76px, 0.85fr) minmax(110px, 1.05fr) auto;
    align-items: center;
    gap: 14px;
    padding: 22px 26px;
}
.ks-hw-list .ks-hw-row + .ks-hw-row { border-top: 1px solid var(--ks-divider); }
.ks-hw-empty { padding: 26px; text-align: center; font-size: 14.5px; color: var(--ks-indigo-soft); font-weight: 500; }

/* Dashboard homework rows: fixed-fraction title column so the "Due In" column
   starts at the SAME left position in every row (and across the Continue
   Learning + Start Homework cards) — the flexible 1.9fr title otherwise resized
   per-row to fit different progress/button/date content. (Task page has its own
   rule under .ks-columns--task.) */
.ks-columns:not(.ks-columns--task) .ks-hw-row {
    grid-template-columns: 42% minmax(76px, 0.85fr) minmax(110px, 1.05fr) auto;
    align-items: start;
}

.ks-hw__title { font-size: 21px; font-weight: 600; color: var(--ks-heading); margin: 0 0 7px; }
.ks-hw__teacher { font-size: 14.5px; color: var(--ks-indigo-soft); font-weight: 500; }

.ks-hw__col-label { font-size: 14px; color: var(--ks-muted); font-weight: 500; margin-bottom: 8px; }
.ks-hw__due { font-size: 19px; font-weight: 600; color: var(--ks-heading); margin-bottom: 6px; white-space: nowrap; }
.ks-hw__due.is-soon { color: var(--ks-cyan); }
.ks-hw__date { font-size: 14px; color: var(--ks-indigo-soft); font-weight: 500; white-space: nowrap; }

.ks-progress__value { font-size: 19px; font-weight: 600; color: var(--ks-heading); margin-bottom: 12px; }
.ks-progress__bar { height: 9px; border-radius: 999px; background: var(--ks-track); overflow: hidden; max-width: 170px; }
.ks-progress__fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, #74d2e2, #90ecda); }

.ks-hw__actions { display: flex; align-items: center; gap: 12px; }

/* ---------- Buttons ---------- */
.ks-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: inherit;
    font-weight: 600;
    font-size: 11px;
    letter-spacing: 1px;
    text-transform: uppercase;
    border-radius: var(--ks-radius-pill);
    padding: 11px 16px;
    white-space: nowrap;
    transition: transform .15s ease, box-shadow .15s ease, opacity .15s ease;
}
.ks-btn:hover { transform: translateY(-1px); }
/* NOTE: selectors are doubled (.ks-btn.ks-btn--x) so their specificity beats
   the global `.ks-app a { color: inherit }` rule — otherwise white button
   labels would inherit the dark indigo text colour. */
.ks-btn.ks-btn--outline {
    background: #fff;
    color: var(--ks-indigo);
    border: 1.5px solid #d8d2f3;
}
.ks-btn.ks-btn--outline:hover { border-color: var(--ks-purple); }
.ks-btn.ks-btn--primary {
    background: var(--grad-purple-btn);
    color: #fff;
    box-shadow: 0 10px 20px rgba(160, 130, 240, .35);
}
.ks-btn.ks-btn--gradient {
    background: var(--grad-purple-teal);
    color: #fff;
    box-shadow: 0 10px 20px rgba(130, 170, 220, .3);
}
.ks-btn--sm { padding: 9px 18px; font-size: 11px; }

/* ---------- Homework resource download (solid dark icon tile) ---------- */
.ks-hw__download-cell { display: flex; align-items: center; justify-content: center; }
.ks-app a.ks-hw__download {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 7px;
    background: #2b2b45;
    color: #fff;
    flex: 0 0 auto;
    transition: background .15s ease, transform .15s ease;
}
.ks-app a.ks-hw__download:hover { background: #1e1e33; transform: translateY(-1px); }
.ks-hw__download .ks-ico { width: 15px; height: 15px; }

/* No resource files on the task -> no cell at all (no empty column, no gap).
   Also covers the dashboard rows, which never carry a download. */
.ks-hw__download-cell:not(:has(a)) { display: none; }

/* ---------- History card ---------- */
.ks-history-section { margin-top: 26px; }   /* space above the full-width history bar */
.ks-history { padding: 24px 28px; }
.ks-history__head { display: flex; align-items: center; gap: 12px; }
.ks-history__head h2 { margin: 0; font-size: 19px; font-weight: 600; color: var(--ks-heading); }
.ks-history__body {
    display: flex; align-items: center; gap: 18px;
    border-top: 1px solid var(--ks-divider);
    margin-top: 20px; padding-top: 20px;
}
.ks-history__count { font-size: 15px; font-weight: 600; color: var(--ks-indigo); }

/* ============================================================
   RIGHT COLUMN — progress panel
   ============================================================ */
.ks-progress-panel {
    background: var(--ks-card);
    border-radius: var(--ks-radius-lg);
    box-shadow: var(--ks-shadow);
    padding: 28px 26px;
}
.ks-progress-panel__head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 14px;
}
.ks-progress-panel__head .ks-spinner { width: 28px; height: 28px; flex-shrink: 0; }
.ks-progress-panel__head h2 {
    margin: 0; font-size: 18px; font-weight: 600; color: var(--ks-heading);
    flex: 1 1 auto; min-width: 0; line-height: 1.25;
}
.ks-progress-panel__head .ks-btn { margin-left: auto; flex-shrink: 0; padding: 9px 15px; font-size: 10.5px; letter-spacing: .7px; }

/* ring (left) + stats (right) — matches the PDF: large ring on the left, the
   stats column fills the remaining width so its text reaches the right edge. */
.ks-progress-main {
    display: flex; flex-wrap: nowrap; align-items: center;
    gap: 14px; padding: 12px 0 22px;
}
.ks-ring-wrap { flex-shrink: 0; display: flex; justify-content: center; }
.ks-ring { position: relative; width: 225px; height: 225px; }
.ks-ring svg { transform: rotate(-90deg); width: 100%; height: 100%; }
.ks-ring__center {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.ks-ring__value { font-size: 46px; font-weight: 600; color: var(--ks-heading); line-height: 1; }
.ks-ring__label { font-size: 16px; color: var(--ks-indigo); font-weight: 500; margin-top: 6px; }

/* progress stat rows (right column beside the ring) */
.ks-pstats { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 22px; }
.ks-pstat { display: flex; align-items: center; gap: 14px; }
.ks-pstat__text { line-height: 1.25; min-width: 0; }
.ks-pstat__value { font-size: 24px; font-weight: 600; color: var(--ks-indigo); }
.ks-pstat__label { font-size: 15px; color: var(--ks-indigo); font-weight: 500; line-height: 1.3; }
.ks-pstat .ks-badge { width: 50px; height: 50px; }
.ks-pstat .ks-badge .ks-ico { width: 27px; height: 27px; }

/* keep going banner */
.ks-cheer {
    margin-top: 26px;
    background: var(--grad-keepgoing);
    border-radius: var(--ks-radius);
    padding: 20px 20px;
    display: flex;
    align-items: center;
    gap: 14px;
}
.ks-cheer .ks-ico { width: 34px; height: 34px; color: #2f9c93; flex-shrink: 0; }
.ks-cheer__text { font-size: 18px; font-weight: 600; color: var(--ks-heading); }

/* gradient stroke helper for inline svgs */
.ks-grad-ico { color: var(--ks-purple); }

/* ============================================================
   COMPACT DESKTOP LAYOUT
   Keep the original two-column format (homework on the left, the progress
   panel on the right) and simply REDUCE the sizes so the whole design fits
   the screen — fills the full width (no left/right gaps), no scaling.
     - >= 1400px : two columns (left column stretches to fill the width)
     - 861-1399  : columns stack (too narrow for two side by side)
     - <= 860    : full mobile layout (handled further below)
   ============================================================ */
.ks-backdrop { display: none; }   /* off-canvas drawer is only used on mobile */

/* ---- Reduced ("compact") sizing on desktop: same layout, smaller ---- */
@media (min-width: 861px) {
    .ks-main { padding: 8px 24px 10px; }

    .ks-topbar { margin-bottom: 6px; }
    .ks-topbar__title { font-size: 22px; }
    .ks-topbar__title .ks-wave { width: 28px; height: 28px; }

    .ks-stats { padding: 14px 8px; margin-bottom: 12px; }
    .ks-stat { padding: 6px 16px; gap: 12px; }
    .ks-stat__icon, .ks-stat__icon img { height: 30px; }
    .ks-stat__icon svg { width: 28px; height: 28px; }
    .ks-stat__value { font-size: 18px; }
    .ks-stat__label { font-size: 12.5px; }

    .ks-col-left { gap: 8px; }
    .ks-columns { gap: 20px; }

    .ks-section__head { margin-bottom: 5px; }
    .ks-section__head h2 { font-size: 15px; }
    .ks-section-badge { width: 32px; height: 32px; }

    .ks-hw-row { padding: 6px 20px; gap: 12px; }
    .ks-hw__title { font-size: 16px; margin-bottom: 2px; }
    .ks-hw__teacher { font-size: 12.5px; }
    .ks-hw__col-label { font-size: 12px; margin-bottom: 2px; }
    .ks-hw__due { font-size: 15px; margin-bottom: 2px; }
    .ks-hw__date { font-size: 13px; }
    .ks-progress__value { font-size: 16px; margin-bottom: 8px; }
    .ks-btn { padding: 9px 13px; font-size: 10px; }
    .ks-btn--sm { padding: 8px 14px; }

    .ks-history-section { margin-top: 8px; }
    .ks-history { padding: 10px 22px; }
    .ks-history__head h2 { font-size: 15px; }
    .ks-history__body { margin-top: 8px; padding-top: 8px; }

    .ks-progress-panel { padding: 18px; }
    .ks-progress-panel__head { margin-bottom: 10px; }
    .ks-progress-panel__head h2 { font-size: 15px; }
    .ks-progress-main { gap: 12px; padding: 6px 0 10px; }
    .ks-ring { width: 165px; height: 165px; }
    .ks-ring__value { font-size: 34px; }
    .ks-ring__label { font-size: 13px; }
    .ks-pstats { gap: 14px; }
    .ks-pstat-badge { width: 42px; height: 42px; }
    .ks-pstat__value { font-size: 19px; }
    .ks-pstat__label { font-size: 13px; }
    .ks-cheer { margin-top: 10px; padding: 12px 16px; }
    .ks-cheer .ks-ico { width: 28px; height: 28px; }
    .ks-cheer__text { font-size: 15px; }
}

/* Keep two columns once there is room for them; narrower desktops stack. */
@media (min-width: 1400px) {
    /* Stretch the progress panel so its bottom is LEVEL with the bottom of the
       Start Homework card (the left column), matching the reference design. */
    .ks-columns { grid-template-columns: minmax(0, 1fr) 360px; align-items: stretch; }
    .ks-progress-panel { display: flex; flex-direction: column; }
    .ks-progress-panel .ks-cheer { margin-top: auto; }   /* pin cheer to the bottom */
}
@media (min-width: 861px) and (max-width: 1399px) {
    .ks-columns { grid-template-columns: 1fr; }
}

/* ============================================================
   MOBILE / SMALL SCREENS (<= 860px)
   Below this width the locked desktop layout is released: every block
   reflows into a single column (one box under another) and the sidebar
   becomes an off-canvas drawer that is hidden by default and slides in
   from the hamburger button. Larger screens are untouched.
   ============================================================ */
@media (max-width: 860px) {
    /* release the desktop min-width so blocks reflow instead of side-scrolling */
    .ks-topbar,
    .ks-stats,
    .ks-columns,
    .ks-history { min-width: 0; }

    /* ---- Sidebar -> off-canvas drawer (hidden by default) ----
       Wider than the desktop rail: as a drawer it no longer has to share the
       screen with the content, and the desktop rail was too narrow for the longest menu
       labels ("Upgrade to Full Access", "LIVE Tuition! Click"), whose right end
       was clipped by .ks-nav's scroll box. Capped at 86vw so it never covers
       the whole screen on the smallest phones. */
    .ks-sidebar {
        width: min(280px, 86vw);
        transform: translateX(-100%);
        transition: transform .25s ease;
        border-radius: 0 24px 24px 0;
        box-shadow: 0 0 40px rgba(78, 66, 150, .18);
    }
    .ks-app.is-sidebar-open .ks-sidebar { transform: translateX(0); }

    /* Belt and braces for the long labels: let them wrap to a second line
       instead of being cut off if the drawer is narrower than the text. The
       short labels are unaffected — they still fit on one line. */
    .ks-nav__item { min-width: 0; }
    .ks-nav__item > span { white-space: normal; line-height: 1.25; min-width: 0; }

    /* ---- User flyout (My Profile / Manage Plan / Logout) ----
       It opens to the RIGHT of the rail (left: 100% + 16px, min-width 210px),
       which lands past the edge of a phone screen — the panel was cut off. On
       mobile flip it to sit ABOVE the avatar, inside the viewport. */
    .ks-user-menu__panel {
        left: 12px;
        right: auto;
        bottom: calc(100% + 10px);
        min-width: 0;
        width: min(260px, calc(100vw - 40px));
        transform: translateY(6px);
    }
    /* the hover-bridge now spans the gap BELOW the panel, not to its left */
    .ks-user-menu__panel::before {
        left: 0; right: 0; width: auto;
        top: auto; bottom: -10px; height: 10px;
    }
    /* the caret pointed sideways at the avatar — meaningless once stacked */
    .ks-user-menu__panel::after { display: none; }
    .ks-user-menu:hover .ks-user-menu__panel,
    .ks-user-menu:focus-within .ks-user-menu__panel { transform: translateY(0); }

    /* dimmed backdrop shown only while the drawer is open */
    .ks-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(40, 32, 90, .35);
        opacity: 0;
        visibility: hidden;
        transition: opacity .25s ease, visibility .25s ease;
        z-index: 15;
    }
    .ks-app.is-sidebar-open .ks-backdrop { opacity: 1; visibility: visible; }

    /* ---- Main fills the full width (no fixed sidebar to reserve room for) ---- */
    .ks-main {
        margin-left: 0;
        height: auto;
        overflow: visible;
        padding: 20px 16px 32px;
    }

    /* ---- Top bar: hamburger beside the greeting ---- */
    .ks-hamburger { display: inline-flex; }
    .ks-topbar {
        display: flex;
        align-items: flex-start;
        gap: 14px;
        margin-bottom: 20px;
    }
    .ks-topbar__title { font-size: 24px; }
    .ks-topbar__title .ks-wave { width: 26px; height: 26px; }

    /* ---- Stats: one box per row ---- */
    .ks-stats {
        grid-template-columns: 1fr;
        padding: 6px 12px;
    }
    .ks-stat { padding: 16px 14px; }
    /* turn the vertical separators into horizontal ones between stacked boxes */
    .ks-stat + .ks-stat::before {
        left: 14px;
        right: 14px;
        top: 0;
        transform: none;
        width: auto;
        height: 1px;
    }

    /* ---- Two-column area stacks ---- */
    .ks-columns {
        grid-template-columns: 1fr;
        gap: 22px;
    }

    /* ---- Homework rows stack their cells ---- */
    .ks-hw-row {
        grid-template-columns: 1fr;
        gap: 12px;
        padding: 18px 20px;
    }
    .ks-hw__title { white-space: normal; }
    .ks-hw__due,
    .ks-hw__date { white-space: normal; }
    .ks-hw__actions { flex-wrap: wrap; }
    .ks-progress__bar { max-width: none; }

    /* ---- History card stacks count + button ---- */
    .ks-history__body {
        flex-direction: column;
        align-items: flex-start;
    }

    /* ---- Progress panel: ring above the stats ---- */
    .ks-progress-panel { padding: 24px 18px; }
    .ks-progress-main {
        flex-direction: column;
        align-items: center;
        gap: 22px;
    }
    .ks-pstats { width: 100%; }
}
