/* ============================================================
   Leaderboard-only additions on top of main.css (copied as-is from
   the course site). Colours, type and spacing come from main.css's
   tokens only — add a token there rather than a literal here.
   ============================================================ */

/* ============================================================
   Header, page shell and footer from the student blog
   (cs2680-blog/assets/css/blog.css, copied as-is), so the
   leaderboard wears the blog's bar: the MadSys mark and the site's
   own name instead of the SEAS lockup, which moves to the footer.
   ============================================================ */

/* ------------------------------------------------------------
   Page shell
   course.css lays the page out as ordinary blocks, which leaves
   the footer floating in the middle of the window on a short page
   -- the author index and the tag index are both one screen with
   a dozen pills on it. The body becomes a column tall enough to
   fill the viewport and the content between header and footer
   takes up the slack, so the footer is always on the bottom edge
   and never above it.
   ------------------------------------------------------------ */

body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    /* dvh follows the mobile browser's collapsing address bar; vh above is
       the fallback for anything that does not know the unit. */
    min-height: 100dvh;
}

.container.page {
    flex: 1 0 auto;
}

.site-footer {
    flex-shrink: 0;
}

/* ------------------------------------------------------------
   Header brand
   The course site's header is the SEAS lockup and nothing else,
   which is exactly why this one cannot be. The blog leads with the
   MadSys mark -- the same drawing both sites use as their favicon --
   and its own name, with the course code and term as the small line
   underneath. Same white bar, same crimson rule, different thing
   standing on it.

   It is also the one element that has to hold together from a
   1200px desktop bar down to a 320px phone, beside a hamburger.
   Nothing here is hidden on the way down; the mark and the two
   lines of type step down together.
   ------------------------------------------------------------ */

.site-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
    margin-right: auto;
    padding: 11px 0;
    color: inherit;
    text-decoration: none;
}

.site-brand:hover,
.site-brand:focus {
    color: inherit;
    text-decoration: none;
}

/* The mark is a hexagon, not a tile, so the corner radius and the box-shadow
   that framed the old square are gone; a drop-shadow filter follows the real
   silhouette instead. */
/* The lab mark is an outline, not a solid shape, so it carries no shadow --
   a drop-shadow on a 19/585 stroke reads as a printing error. It lifts on
   hover and nothing more. */
.brand-mark {
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    transition: transform 0.2s ease;
}

.site-brand:hover .brand-mark {
    transform: translateY(-1px);
}

.brand-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.brand-name {
    font-family: 'Open Sans', sans-serif;
    font-size: 1.3rem;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -0.005em;
    color: var(--crimson);
    white-space: nowrap;
    transition: color 0.15s ease;
}

.site-brand:hover .brand-name {
    color: var(--crimson-bright);
}

.brand-sub {
    font-family: 'Open Sans', sans-serif;
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.site-brand:focus-visible {
    outline: 2px solid var(--crimson);
    outline-offset: 3px;
    border-radius: var(--r-sm);
}

/* The brand and the toggler share one row on a phone; neither may push the
   other off it, so the brand shrinks and the toggler does not. */
.site-header .navbar-toggler {
    flex-shrink: 0;
}

@media (max-width: 575px) {
    .site-brand {
        gap: 9px;
        padding: 9px 0;
    }

    .brand-mark {
        width: 38px;
        height: 38px;
    }

    .brand-name {
        font-size: 1.12rem;
    }

    .brand-sub {
        font-size: 0.64rem;
        letter-spacing: 0.08em;
    }
}

@media (max-width: 380px) {
    .brand-mark {
        width: 34px;
        height: 34px;
    }

    .brand-name {
        font-size: 1.02rem;
    }

    .navbar-toggler {
        padding: 6px 8px;
    }

    .navbar-toggler-icon {
        width: 1.2em;
        height: 1.2em;
    }
}

.navbar-nav .nav-link {
    white-space: nowrap;
}

/* ------------------------------------------------------------
   Collapsed menu
   Below 992px the links become a drop-down panel. Bootstrap leaves
   them as bare inline text; these rules give the panel one row per
   link and the same crimson current-page fill the bar uses.
   ------------------------------------------------------------ */

@media (max-width: 991.98px) {
    .navbar-collapse {
        margin: 0 calc(-1 * var(--s3)) var(--s2);
        padding: var(--s2) var(--s3) var(--s3);
        border-top: 1px solid var(--border-soft);
    }

    .navbar-nav {
        margin-left: 0;
        gap: 2px;
    }

    .navbar-nav .nav-item {
        width: 100%;
    }

    .navbar-nav .nav-link {
        padding: 11px 12px !important;
        border-radius: var(--r-sm);
    }
}

/* ------------------------------------------------------------
   Footer additions
   The SEAS lockup moved here when the header took the blog's own
   brand, and the pages the four-item menu leaves out are listed
   beside the menu's own, so the navigation bar is a shortcut and
   never the only way in.
   ------------------------------------------------------------ */

.footer-seas {
    display: inline-block;
    border-bottom: none !important;
    margin-bottom: var(--s4);
}

.footer-seas img {
    height: 54px;
    width: auto;
    opacity: 0.85;
    transition: opacity 0.15s ease;
}

.footer-seas:hover img {
    opacity: 1;
}

.footer-nav {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--s2) var(--s4);
    margin-bottom: var(--s4);
    padding-bottom: var(--s4);
    border-bottom: 1px solid var(--border-soft);
}

.footer-nav a {
    font-family: 'Open Sans', sans-serif;
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-2);
    border-bottom: none;
}

.footer-nav a:hover {
    color: var(--crimson-bright);
    border-bottom: none;
}

@media (max-width: 575px) {
    .footer-seas img {
        height: 44px;
    }
}

/* --- navbar: login / logout -------------------------------- */

.nav-auth {
    display: flex;
    align-items: center;
    margin-left: var(--s3);
}

.nav-user {
    display: inline-flex;
    align-items: center;
    gap: var(--s3);
    font-family: 'Open Sans', sans-serif;
    color: var(--ink-3);
}

.nav-user[hidden],
.btn-auth[hidden],
.nav-item[hidden] {
    display: none !important;
}

.btn-auth {
    font-family: 'Open Sans', sans-serif;
    font-size: 1rem;
    color: var(--crimson);
    background: var(--bg);
    border: 1px solid var(--crimson);
    border-radius: var(--r-sm);
    padding: 6px 16px;
    text-decoration: none;
    cursor: pointer;
    transition: all 0.2s ease;
}

.btn-auth:hover {
    color: var(--on-crimson);
    background: var(--crimson);
    text-decoration: none;
}

@media (max-width: 991.98px) {
    .nav-auth {
        margin: var(--s2) 0 var(--s3);
        padding: 0 12px;          /* in line with the menu links above (11px 12px) */
    }
}

/* --- buttons and forms ------------------------------------- */

.btn-crimson {
    font-size: 1rem;
    font-weight: 600;
    color: var(--on-crimson);
    background: var(--crimson);
    border: 1px solid var(--crimson);
    border-radius: var(--r-sm);
    padding: 8px 22px;
    cursor: pointer;
    transition: background 0.2s ease;
}

.btn-crimson:hover:not(:disabled) {
    background: var(--crimson-dark);
}

.btn-crimson:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* the same size as .btn-crimson, outlined: crimson border and text on white */
.btn-outline-crimson {
    display: inline-block;
    font-size: 1rem;
    font-weight: 600;
    color: var(--crimson);
    background: var(--bg);
    border: 1px solid var(--crimson);
    border-radius: var(--r-sm);
    padding: 8px 22px;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.2s ease;
}

.btn-outline-crimson:hover {
    color: var(--crimson-dark);
    background: var(--crimson-050);
    text-decoration: none;
}

.form-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s3);
}

.form-alt-link {
    color: var(--crimson);
}

.form-card {
    max-width: 560px;
    margin: var(--s5) auto 0;
    padding: var(--s6);
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-1);
}

.form-card.narrow {
    max-width: 400px;
}

.form-field {
    margin-bottom: var(--s5);
}

.form-field label {
    display: block;
    font-weight: 600;
    color: var(--ink-2);
    margin-bottom: var(--s2);
}

.form-field .hint {
    font-size: 0.9rem;
    color: var(--ink-3);
    margin-top: var(--s1);
}

.form-field input[type="text"],
.form-field input[type="email"],
.form-field input[type="password"] {
    width: 100%;
    padding: 8px var(--s3);
    font-size: 1rem;
    color: var(--ink);
    border: 1px solid var(--border-strong);
    border-radius: var(--r-sm);
}

.form-field input:focus {
    outline: none;
    border-color: var(--crimson);
    box-shadow: 0 0 0 3px var(--crimson-100);
}

/* --- zip drop zone ----------------------------------------- */

.dropzone {
    display: block;
    padding: var(--s6) var(--s4);
    text-align: center;
    color: var(--ink-3);
    background: var(--surface);
    border: 2px dashed var(--border-strong);
    border-radius: var(--r);
    cursor: pointer;
    transition: all 0.15s ease;
}

.dropzone:hover,
.dropzone.dragover {
    color: var(--crimson);
    background: var(--crimson-050);
    border-color: var(--crimson);
}

.dropzone .dropzone-main {
    font-size: 1.05rem;
    font-weight: 600;
}

.dropzone .dropzone-file {
    margin-top: var(--s2);
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 0.95rem;
    word-break: break-all;
}

.dropzone input[type="file"] {
    display: none;
}

/* --- status messages --------------------------------------- */

.status {
    margin-top: var(--s4);
    padding: var(--s3) var(--s4);
    border-radius: var(--r-sm);
    border: 1px solid transparent;
}

.status:empty {
    display: none;
}

.status.error {
    color: var(--crimson-dark);
    background: var(--crimson-050);
    border-color: var(--crimson-200);
}

.status.ok {
    color: var(--green);
    background: var(--green-050);
    border-color: var(--green-200);
}

.status.info {
    color: var(--ink-2);
    background: var(--surface);
    border-color: var(--border);
}

/* submit page: how many submissions a new upload would wait behind */
.queue-banner {
    max-width: 560px;
    margin: var(--s5) auto 0;
    padding: var(--s3) var(--s4);
    color: var(--ink-2);
    background: var(--blue-050);
    border: 1px solid var(--blue-200);
    border-radius: var(--r-sm);
}

.queue-banner b {
    color: var(--blue);
}

.queue-banner + .form-card {
    margin-top: var(--s4);
}

/* submit page: today's grading budget, above the Submit button */
.budget-line {
    margin-bottom: var(--s4);
    color: var(--ink-2);
}

.budget-line.out b {
    color: var(--crimson-dark);
}

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

.board-table td.rank,
.board-table th.rank {
    width: 4.5em;
    text-align: center;
}

.board-table td.num,
.board-table th.num {
    text-align: right;
}

.board-table td.empty {
    text-align: center;
    color: var(--ink-3);
    padding: var(--s6) var(--s3);
}

.badge-pending {
    display: inline-block;
    font-size: 0.85rem;
    color: var(--amber);
    background: var(--amber-050);
    border: 1px solid var(--amber-200);
    border-radius: 999px;
    padding: 1px 10px;
}

.board-note {
    text-align: center;
    color: var(--ink-3);
    margin-top: var(--s3);
}

/* --- leaderboard card (layout after cachecompetition.com/leaderboard) --- */

:root {
    /* medal colours for ranks 1-3 */
    --gold: #C7932E;
    --silver: #7C7C82;
    --bronze: #AD6B45;
}

.board-card {
    margin-top: var(--s6);
    padding: 28px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: 0 12px 38px rgba(20, 22, 26, 0.10);
}

.board-card .board-title {
    font-size: 32px;
    font-weight: 700;
    color: var(--ink);
    margin: 0 0 var(--s4);
}

.board-card .board-refreshed {
    color: var(--ink-3);
    margin: 0 0 var(--s5);
}

table.board {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

table.board th,
table.board td {
    padding: var(--s4);
    text-align: left;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

table.board td:nth-child(2) {
    white-space: normal;   /* long names wrap; everything else stays on one line */
}

table.board th {
    background: var(--crimson-050);
    color: var(--ink);
    font-size: 0.85rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

table.board tbody tr:hover td {
    background: var(--surface);
}

table.board td.empty {
    text-align: center;
    color: var(--ink-3);
    padding: var(--s6) var(--s4);
}

.board-rank {
    font-weight: 700;
    color: var(--crimson);
}

.board-rank.rank-1 { color: var(--gold); }
.board-rank.rank-2 { color: var(--silver); }
.board-rank.rank-3 { color: var(--bronze); }
.board-rank.pending { color: var(--ink-4); }

.board-score {
    font-weight: 700;
    font-size: 1.05rem;
}

.board-card .board-note {
    text-align: left;
    margin: var(--s4) 0 0;
}

@media (max-width: 575px) {
    .board-card {
        padding: var(--s4);
    }

    .board-card .board-title {
        font-size: 24px;
    }
}

/* main.css frames every .table-responsive; inside the card the card is the frame */
.board-card .table-responsive {
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

/* the logged-in person's own best, below the top 10 */
table.board tr.board-me-label td {
    padding: var(--s5) var(--s4) var(--s2);
    font-size: 0.85rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--crimson);
    border-bottom: 2px solid var(--crimson-200);
    background: var(--bg) !important;
}

table.board tr.board-me td {
    background: var(--crimson-050);
}

table.board tr.board-me:hover td {
    background: var(--crimson-100);
}

/* --- grading results --------------------------------------- */

.of {
    color: var(--ink-3);
    font-weight: 400;
}

.muted {
    color: var(--ink-4);
}

.badge-status {
    display: inline-block;
    font-size: 0.85rem;
    border-radius: 999px;
    padding: 1px 10px;
    border: 1px solid;
}

.badge-queued,
.badge-canceled { color: var(--ink-3); background: var(--surface); border-color: var(--border); }
/* stopped at the budget: the most one run may cost, or the student's budget left today */
.badge-budget { color: var(--amber); background: var(--amber-050); border-color: var(--amber-200); }
.badge-running { color: var(--blue); background: var(--blue-050); border-color: var(--blue-200); }
.badge-best { color: var(--green); background: var(--green-050); border-color: var(--green-200); }
.badge-error,
.badge-failed,
.badge-timeout { color: var(--crimson-dark); background: var(--crimson-050); border-color: var(--crimson-200); }

.btn-tasks {
    font-size: 0.9rem;
    color: var(--crimson);
    background: var(--bg);
    border: 1px solid var(--crimson-200);
    border-radius: var(--r-sm);
    padding: 2px 10px;
    white-space: nowrap;
    cursor: pointer;
}

.btn-tasks:hover {
    background: var(--crimson-050);
}

.history-table tr.detail-row > td {
    background: var(--surface);
    padding: var(--s3) var(--s4);
}

/* under a submission being graded: how far it has got (updated every 2 minutes), one line on
   the right, a little smaller than the rows of finished ones */
.history-table tr.progress-row > td {
    font-size: 0.92rem;
    color: var(--ink-2);
    padding-top: 6px;
    padding-bottom: 6px;
}

.history-table .progress-line {
    text-align: right;
}

.history-table .copy-total {
    font-size: 0.85rem;
    color: var(--ink-3);
}

.grade-error {
    margin: 0;
    white-space: pre-wrap;
    font-family: var(--font-mono);
    font-size: 0.85rem;
}

table.task-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--bg);
    font-variant-numeric: tabular-nums;
}

table.task-table th,
table.task-table td {
    padding: 6px var(--s3);
    border-bottom: 1px solid var(--border);
    text-align: left;
}

table.task-table th {
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-3);
}

table.task-table .num {
    text-align: right;
}

.ok-mark { color: var(--green); font-weight: 700; }
.no-mark { color: var(--ink-4); }
.task-table .reason { color: var(--ink-3); font-size: 0.92em; }

.form-field input[type="number"] {
    width: 10em;
    padding: 8px var(--s3);
    font-size: 1rem;
    color: var(--ink);
    border: 1px solid var(--border-strong);
    border-radius: var(--r-sm);
}

.form-field label .optional {
    font-weight: 400;
    color: var(--ink-3);
}
