/* ==========================================================================
   Tangaza University Student Portal - shared design system
   --------------------------------------------------------------------------
   Every page in the portal is built from the components in this file. Before
   adding a <style> block to a view, check whether the thing you need is
   already here - the point of this file is that a table on the Fee Statement
   looks like a table on the Results page without anybody having to remember
   the hex codes.

   Palette is the official Tangaza University website palette:

       Primary          #c52127   red      - primary actions, active nav, links
       Secondary        #d19c2c   gold     - accents, rails, icons on dark
       Secondary Purple #51506E            - card and table headers
       Secondary Black  #444444            - chrome, body text

   Prefix is tz- so nothing collides with Bootstrap 4 or the pcoded theme.
   Change a colour here and it changes everywhere; do not hard-code hex values
   in a view.
   ========================================================================== */

:root {
    /* Brand - primary red */
    --tz-crimson: #c52127;
    --tz-crimson-dark: #a41a1f;
    --tz-crimson-soft: #fbeaeb;

    /* Brand - secondary gold */
    --tz-gold: #d19c2c;
    --tz-gold-dark: #b08222;
    --tz-gold-soft: #fbf3e3;

    /* Brand - secondary purple, used for headers */
    --tz-purple: #51506E;
    --tz-purple-dark: #414058;
    --tz-purple-soft: #eeeef3;

    /* Brand - secondary black */
    --tz-ink: #444444;
    --tz-ink-deep: #333333;
    --tz-header: #444444;

    /* Neutrals */
    --tz-text: #2f3337;
    --tz-text-muted: #6b7280;
    --tz-text-faint: #98a0ab;
    --tz-border: #e3e6ec;
    --tz-border-soft: #edeff3;
    --tz-surface: #ffffff;
    --tz-surface-alt: #fafbfc;
    --tz-canvas: #f4f6f9;

    /* Semantic */
    --tz-success: #2e7d32;
    --tz-success-soft: #e8f5e9;
    --tz-warn: #9a6100;
    --tz-warn-soft: #fff3e0;
    --tz-danger: #c62828;
    --tz-danger-soft: #fdecea;
    --tz-info: #1565c0;
    --tz-info-soft: #e8f1fb;

    --tz-radius: 6px;
    --tz-radius-sm: 4px;
    --tz-shadow: 0 1px 3px rgba(16, 24, 40, .06), 0 1px 2px rgba(16, 24, 40, .04);
    --tz-shadow-lg: 0 4px 16px rgba(16, 24, 40, .10);

    /* Typeface. Linked from Google Fonts in SiteMaster and LoginMaster.
       The fallback stack is load-bearing, not decoration: if fonts.googleapis.com is
       blocked or slow the page renders in the platform UI face instead of dropping to
       an arbitrary serif. Do not add "feather" or "FontAwesome" here - those are icon
       fonts and the theme sets them per-element. */
    --tz-font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
}

/* ==========================================================================
   0b. Typography
   This portal runs the Skote theme, whose stack starts at "Poppins" - a face it does
   not ship and never loads, so everything fell back to the browser default. These
   rules put Inter on the body, the topbar and the sidebar.
   portal.css is loaded last, so it wins on equal specificity; !important is only used
   where the theme itself used a heavier hand.
   ========================================================================== */

body,
#page-topbar,
.vertical-menu {
    font-family: var(--tz-font);
    /* Inter ships contextual alternates that tighten spacing around punctuation. */
    -webkit-font-feature-settings: "cv05", "cv11";
    font-feature-settings: "cv05", "cv11";
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--tz-font);
    /* Inter runs optically larger than Quicksand at the same size, so headings need a
       tighter fit to keep the vertical rhythm the cards were spaced for. */
    letter-spacing: -.011em;
    text-wrap: balance;
}

/* Form controls do not inherit the document face on any browser. */
input, select, textarea, button, .form-control, .btn {
    font-family: inherit;
}

/* --- File-type icons -----------------------------------------------------
   Used by the Important Documents table. Font Awesome 4.7 glyphs, coloured by
   type so the list is scannable without reading the Type column. These replace
   img/pdf.png and img/word.png, which the markup referenced but which have
   never existed in the project. */

.tz-fileicon {
    font-size: 21px;
    line-height: 1;
    vertical-align: middle;
    color: var(--tz-text-muted);
}

.tz-fileicon-pdf {
    color: #c52127;
}

.tz-fileicon-word {
    color: #2b579a;
}

.tz-fileicon-excel {
    color: #217346;
}

.tz-fileicon-ppt {
    color: #c55a11;
}

.tz-fileicon-image {
    color: #51506e;
}

.tz-fileicon-archive {
    color: #b07d16;
}

.tz-fileicon-other {
    color: #6b7280;
}

/* The icon is the download control, so it needs a visible affordance. */
.tz-table a:hover .tz-fileicon,
.tz-table a:focus-visible .tz-fileicon {
    opacity: .72;
}

/* ==========================================================================
   1. Page shell
   ========================================================================== */

.tz-page {
    padding: 22px 26px 60px 26px;
    background: var(--tz-canvas);
    min-height: calc(100vh - 70px);
    color: var(--tz-text);
    font-size: 13.5px;
}

/* Page title bar. Sits at the top of every page, above the first card. */
.tz-page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 20px;
}

    .tz-page-head h1 {
        margin: 0;
        font-size: 21px;
        font-weight: 600;
        letter-spacing: .2px;
        color: var(--tz-ink);
        line-height: 1.25;
    }

        .tz-page-head h1 i {
            color: var(--tz-crimson);
            margin-right: 9px;
            vertical-align: -2px;
        }

    .tz-page-head .tz-sub {
        margin: 5px 0 0 0;
        font-size: 13px;
        color: var(--tz-text-muted);
    }

    .tz-page-head .tz-page-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        align-items: center;
    }

/* Dark identity banner - student number, name, programme, semester. */
.tz-banner {
    background: linear-gradient(135deg, var(--tz-purple) 0%, var(--tz-purple-dark) 100%);
    border-left: 4px solid var(--tz-gold);
    color: #fff;
    border-radius: var(--tz-radius);
    padding: 18px 22px;
    margin-bottom: 22px;
    box-shadow: var(--tz-shadow);
}

.tz-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 30px;
}

.tz-fact .k {
    display: block;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .9px;
    text-transform: uppercase;
    color: var(--tz-gold);
    margin-bottom: 3px;
}

.tz-fact .v {
    display: block;
    font-size: 13.5px;
    font-weight: 600;
    color: #fff;
    word-break: break-word;
}

/* ==========================================================================
   2. Cards
   ========================================================================== */

.tz-card {
    background: var(--tz-surface);
    border: 1px solid var(--tz-border);
    border-radius: var(--tz-radius);
    margin-bottom: 22px;
    box-shadow: var(--tz-shadow);
    overflow: hidden;
}

.tz-card-head {
    background: var(--tz-purple);
    color: #fff;
    padding: 12px 18px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;
}

    .tz-card-head h2,
    .tz-card-head .tz-card-title {
        margin: 0;
        font-size: 13px;
        font-weight: 600;
        letter-spacing: .5px;
        text-transform: uppercase;
        color: #fff;
        display: flex;
        align-items: center;
    }

        .tz-card-head h2 i,
        .tz-card-head .tz-card-title i {
            color: var(--tz-gold);
            margin-right: 8px;
        }

.tz-card-body {
    padding: 18px;
}

    .tz-card-body > :last-child {
        margin-bottom: 0;
    }

/* Numbered step marker used on multi-stage pages (course registration). */
.tz-step {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--tz-gold);
    color: var(--tz-ink);
    font-weight: 700;
    font-size: 11.5px;
    margin-right: 10px;
    flex: 0 0 auto;
}

/* Small count chip that follows a card title. */
.tz-count {
    display: inline-block;
    background: var(--tz-crimson);
    color: #fff;
    border-radius: 20px;
    padding: 1px 10px;
    font-size: 11px;
    font-weight: 700;
    margin-left: 9px;
}

.tz-count-zero {
    background: #6d6d6d;
}

/* Chip in a dark card header, e.g. the current semester. */
.tz-chip {
    background: rgba(255,255,255,.10);
    border: 1px solid rgba(229,169,59,.45);
    border-radius: 20px;
    padding: 3px 14px;
    font-size: 11.5px;
    font-weight: 600;
    color: #fff;
    white-space: nowrap;
}

    .tz-chip i {
        color: var(--tz-gold);
        margin-right: 5px;
    }

/* ==========================================================================
   3. Tables
   ========================================================================== */

.tz-scroll {
    max-height: 420px;
    overflow: auto;
    border: 1px solid var(--tz-border);
    border-radius: var(--tz-radius-sm);
    background: var(--tz-surface);
}

.tz-scroll-tall {
    max-height: 620px;
}

.tz-scroll-auto {
    max-height: none;
    overflow-x: auto;
}

.tz-table {
    width: 100%;
    margin: 0;
    font-size: 12.5px;
    border-collapse: separate;
    border-spacing: 0;
    background: var(--tz-surface);
}

    .tz-table thead th {
        position: sticky;
        top: 0;
        z-index: 2;
        background: var(--tz-purple);
        color: #fff;
        font-size: 10.5px;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .6px;
        padding: 10px 12px;
        border: 0;
        white-space: nowrap;
        text-align: left;
    }

    /* A header carrying .tz-num or .tz-center has to beat ".tz-table thead th" above,
       which is more specific than the bare .tz-num / .tz-center utilities. Without these
       the heading sat left while its numbers sat right, so every numeric column looked
       shifted against its own title. */
    .tz-table thead th.tz-num {
        text-align: right;
    }

    .tz-table thead th.tz-center {
        text-align: center;
    }

    .tz-table tbody td {
        padding: 9px 12px;
        border-top: 1px solid var(--tz-border-soft);
        vertical-align: middle;
        color: var(--tz-text);
    }

    .tz-table tbody tr:nth-child(even) {
        background: var(--tz-surface-alt);
    }

    .tz-table tbody tr:hover {
        background: var(--tz-gold-soft);
    }

    .tz-table tfoot td {
        background: var(--tz-purple-dark);
        color: var(--tz-gold);
        font-weight: 700;
        padding: 10px 12px;
        border: 0;
    }

    /* Row emphasis */
    .tz-table tr.tz-row-fail td {
        background: var(--tz-danger-soft);
    }

    .tz-table tr.tz-row-total td {
        font-weight: 700;
        background: #f1f3f7;
    }

.tz-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.tz-code {
    font-weight: 600;
    color: var(--tz-ink);
    white-space: nowrap;
}

.tz-nowrap {
    white-space: nowrap;
}

/* ==========================================================================
   4. Pills / status badges
   ========================================================================== */

.tz-pill {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 20px;
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .4px;
    white-space: nowrap;
    line-height: 1.6;
}

    .tz-pill i {
        font-size: 11px;
        margin-right: 4px;
        vertical-align: -1px;
    }

.tz-pill-neutral {
    background: #eceff3;
    color: #4a5158;
}

.tz-pill-info {
    background: var(--tz-info-soft);
    color: var(--tz-info);
}

.tz-pill-success {
    background: var(--tz-success-soft);
    color: var(--tz-success);
}

.tz-pill-warn {
    background: var(--tz-warn-soft);
    color: var(--tz-warn);
}

.tz-pill-danger {
    background: var(--tz-danger-soft);
    color: var(--tz-danger);
}

.tz-pill-gold {
    background: var(--tz-gold-soft);
    color: var(--tz-gold-dark);
}

/* ==========================================================================
   5. Buttons
   ========================================================================== */

.tz-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    border: 1px solid transparent;
    border-radius: var(--tz-radius-sm);
    padding: 9px 17px;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    text-decoration: none;
    transition: background .15s ease, border-color .15s ease, color .15s ease;
    white-space: nowrap;
}

    .tz-btn:focus {
        outline: 2px solid var(--tz-gold);
        outline-offset: 2px;
    }

    .tz-btn:disabled,
    .tz-btn.tz-btn-disabled {
        opacity: .45;
        cursor: not-allowed;
    }

    .tz-btn i {
        font-size: 14px;
    }

.tz-btn-primary {
    background: var(--tz-crimson);
    color: #fff;
}

    .tz-btn-primary:hover:not(:disabled) {
        background: var(--tz-crimson-dark);
        color: #fff;
        text-decoration: none;
    }

.tz-btn-gold {
    background: var(--tz-gold);
    color: var(--tz-ink);
}

    .tz-btn-gold:hover:not(:disabled) {
        background: var(--tz-gold-dark);
        color: var(--tz-ink);
        text-decoration: none;
    }

.tz-btn-dark {
    background: var(--tz-ink);
    color: #fff;
}

    .tz-btn-dark:hover:not(:disabled) {
        background: #333;
        color: #fff;
        text-decoration: none;
    }

.tz-btn-ghost {
    background: var(--tz-surface);
    color: var(--tz-ink);
    border-color: #c9cfd9;
}

    .tz-btn-ghost:hover:not(:disabled) {
        background: #f1f3f7;
        color: var(--tz-ink);
        text-decoration: none;
    }

.tz-btn-sm {
    padding: 5px 11px;
    font-size: 11.5px;
}

.tz-btn-block {
    width: 100%;
    justify-content: center;
}

.tz-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 9px;
    align-items: center;
}

/* Inline table links */
.tz-link {
    color: var(--tz-crimson);
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

    .tz-link:hover {
        color: var(--tz-crimson-dark);
        text-decoration: underline;
    }

.tz-link-muted {
    color: var(--tz-text-muted);
    font-weight: 600;
    text-decoration: none;
}

    .tz-link-muted:hover {
        color: var(--tz-ink);
        text-decoration: underline;
    }

/* ==========================================================================
   6. Callouts and empty states
   ========================================================================== */

.tz-hint {
    background: var(--tz-gold-soft);
    border-left: 3px solid var(--tz-gold);
    border-radius: var(--tz-radius-sm);
    padding: 12px 16px;
    margin-bottom: 18px;
    font-size: 12.5px;
    color: #5c4a1e;
}

    .tz-hint ol,
    .tz-hint ul {
        margin: 0;
        padding-left: 18px;
    }

    .tz-hint li {
        margin-bottom: 3px;
    }

        .tz-hint li:last-child {
            margin-bottom: 0;
        }

.tz-note {
    background: var(--tz-info-soft);
    border-left: 3px solid var(--tz-info);
    color: #14406e;
}

.tz-warning {
    background: var(--tz-warn-soft);
    border-left: 3px solid #ef9a00;
    color: #6d4500;
}

.tz-alert {
    background: var(--tz-danger-soft);
    border-left: 3px solid var(--tz-danger);
    color: #8c1d18;
}

.tz-empty {
    text-align: center;
    padding: 38px 18px;
    color: var(--tz-text-faint);
    font-size: 13px;
}

    .tz-empty i {
        font-size: 32px;
        display: block;
        margin-bottom: 10px;
        opacity: .45;
    }

    .tz-empty strong {
        color: var(--tz-text-muted);
    }

/* ==========================================================================
   7. Stat tiles (dashboard)
   ========================================================================== */

.tz-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 16px;
    margin-bottom: 22px;
}

.tz-stat {
    background: var(--tz-surface);
    border: 1px solid var(--tz-border);
    border-left: 4px solid var(--tz-crimson);
    border-radius: var(--tz-radius);
    padding: 16px 18px;
    box-shadow: var(--tz-shadow);
}

.tz-stat-gold {
    border-left-color: var(--tz-gold);
}

.tz-stat-success {
    border-left-color: var(--tz-success);
}

.tz-stat-info {
    border-left-color: var(--tz-info);
}

.tz-stat .tz-stat-label {
    display: block;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: var(--tz-text-muted);
    margin-bottom: 6px;
}

.tz-stat .tz-stat-value {
    display: block;
    font-size: 23px;
    font-weight: 700;
    color: var(--tz-ink);
    font-variant-numeric: tabular-nums;
    line-height: 1.15;
}

.tz-stat .tz-stat-foot {
    display: block;
    font-size: 11.5px;
    color: var(--tz-text-faint);
    margin-top: 5px;
}

/* ==========================================================================
   7b. Profile photo
   ========================================================================== */

.tz-avatar-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding-bottom: 16px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--tz-border-soft);
}

.tz-avatar {
    width: 78px;
    height: 78px;
    border-radius: 50%;
    object-fit: cover;
    border: 3px solid var(--tz-gold);
    background: var(--tz-surface-alt);
    flex: 0 0 auto;
}

.tz-avatar-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--tz-text-faint);
    font-size: 30px;
}

.tz-avatar-actions {
    min-width: 0;
}

    .tz-avatar-actions .tz-file {
        display: none;
    }

    .tz-avatar-actions label.tz-btn {
        margin: 0;
    }

/* ==========================================================================
   7c. Dashboard: hero tiles, quick actions, identity grid
   ========================================================================== */

/* Greeting strip above the page title. */
.tz-greeting {
    font-size: 13px;
    color: var(--tz-text-muted);
    margin: 0 0 2px 0;
}

    .tz-greeting strong {
        color: var(--tz-ink);
    }

    .tz-greeting i {
        margin-right: 5px;
        color: var(--tz-gold-dark);
    }

/* Dismissible banner. */
.tz-hint {
    position: relative;
}

.tz-dismiss {
    position: absolute;
    top: 8px;
    right: 10px;
    background: none;
    border: 0;
    padding: 2px 6px;
    line-height: 1;
    font-size: 18px;
    color: inherit;
    opacity: .45;
    cursor: pointer;
}

    .tz-dismiss:hover {
        opacity: 1;
    }

/* Filled headline tiles for the two unit counts. */
.tz-hero {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 16px;
    margin-bottom: 22px;
    align-items: stretch;
}

.tz-hero-tile {
    border-radius: var(--tz-radius);
    padding: 18px 20px;
    color: #fff;
    box-shadow: var(--tz-shadow);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 104px;
}

.tz-hero-red {
    background: linear-gradient(135deg, var(--tz-crimson) 0%, var(--tz-crimson-dark) 100%);
}

.tz-hero-gold {
    background: linear-gradient(135deg, var(--tz-gold) 0%, var(--tz-gold-dark) 100%);
}

.tz-hero-tile .tz-hero-label {
    display: block;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .9px;
    text-transform: uppercase;
    opacity: .92;
    margin-bottom: 6px;
}

.tz-hero-tile .tz-hero-value {
    display: block;
    font-size: 34px;
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.tz-hero-tile .tz-hero-foot {
    display: block;
    font-size: 11.5px;
    opacity: .9;
    margin-top: 5px;
}

.tz-hero-tile > i {
    font-size: 30px;
    opacity: .35;
    flex: 0 0 auto;
}

/* Fee summary tile: three figures side by side on a white card. */
.tz-fee-tile {
    grid-column: span 2;
    background: var(--tz-surface);
    border: 1px solid var(--tz-border);
    border-left: 4px solid var(--tz-gold);
    border-radius: var(--tz-radius);
    padding: 16px 20px;
    box-shadow: var(--tz-shadow);
    min-height: 104px;
}

    .tz-fee-tile h3 {
        margin: 0 0 12px 0;
        font-size: 10.5px;
        font-weight: 700;
        letter-spacing: .9px;
        text-transform: uppercase;
        color: var(--tz-crimson);
        text-align: center;
    }

.tz-fee-split {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

    .tz-fee-split > div {
        flex: 1 1 110px;
        text-align: center;
    }

    .tz-fee-split .k {
        display: block;
        font-size: 11px;
        color: var(--tz-text-muted);
        margin-bottom: 3px;
    }

    .tz-fee-split .v {
        display: block;
        font-size: 18px;
        font-weight: 700;
        font-variant-numeric: tabular-nums;
        color: var(--tz-ink);
    }

    .tz-fee-split .v.paid {
        color: var(--tz-success);
    }

    .tz-fee-split .v.owing {
        color: var(--tz-crimson);
    }

    .tz-fee-split .v.credit {
        color: var(--tz-success);
    }

@media (max-width: 700px) {
    .tz-fee-tile {
        grid-column: span 1;
    }
}

/* Two-column dashboard body: content left, quick actions right. */
.tz-dash-split {
    display: grid;
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
    gap: 20px;
    align-items: start;
}

@media (max-width: 1100px) {
    .tz-dash-split {
        grid-template-columns: 1fr;
    }
}

/* Identity grid: labelled value tiles with an icon. */
.tz-info-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 12px;
}

.tz-info-item {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    border: 1px solid var(--tz-border);
    border-radius: var(--tz-radius-sm);
    padding: 11px 13px;
    background: var(--tz-surface);
    min-width: 0;
}

    .tz-info-item > i {
        color: var(--tz-crimson);
        font-size: 16px;
        margin-top: 2px;
        flex: 0 0 auto;
    }

    .tz-info-item .k {
        display: block;
        font-size: 10px;
        font-weight: 700;
        letter-spacing: .7px;
        text-transform: uppercase;
        color: var(--tz-text-muted);
        margin-bottom: 3px;
    }

    .tz-info-item .v {
        display: block;
        font-size: 13px;
        font-weight: 600;
        color: var(--tz-ink);
        word-break: break-word;
    }

        .tz-info-item .v.ok {
            color: var(--tz-success);
        }

/* Quick actions: a stack of tappable rows. */
.tz-quick {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.tz-quick-item {
    display: flex;
    align-items: center;
    gap: 12px;
    border: 1px solid var(--tz-border);
    border-left: 3px solid var(--tz-crimson);
    border-radius: var(--tz-radius-sm);
    padding: 12px 14px;
    background: var(--tz-surface);
    color: var(--tz-ink);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    transition: background .15s ease, border-color .15s ease, transform .15s ease;
}

    .tz-quick-item:hover {
        background: var(--tz-gold-soft);
        border-left-color: var(--tz-gold);
        color: var(--tz-ink);
        text-decoration: none;
        transform: translateX(2px);
    }

    .tz-quick-item > i:first-child {
        color: var(--tz-crimson);
        font-size: 17px;
        flex: 0 0 auto;
    }

    .tz-quick-item .tz-quick-label {
        flex: 1 1 auto;
        min-width: 0;
    }

    .tz-quick-item .tz-quick-go {
        color: var(--tz-text-faint);
        font-size: 15px;
        flex: 0 0 auto;
    }

/* Reg-no chip under the student's name. */
.tz-regchip {
    display: inline-block;
    background: var(--tz-ink);
    color: #fff;
    border-radius: var(--tz-radius-sm);
    padding: 3px 11px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .3px;
}

/* ==========================================================================
   8. Forms
   ========================================================================== */

.tz-label {
    display: block;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .5px;
    color: var(--tz-text-muted);
    margin-bottom: 5px;
}

    .tz-label .tz-req {
        color: var(--tz-crimson);
        margin-left: 3px;
    }

.tz-field {
    margin-bottom: 16px;
}

.tz-input,
.tz-select,
.tz-textarea {
    width: 100%;
    border: 1px solid #c9cfd9;
    border-radius: var(--tz-radius-sm);
    padding: 9px 12px;
    font-size: 13px;
    color: var(--tz-text);
    background: var(--tz-surface);
}

    .tz-input:focus,
    .tz-select:focus,
    .tz-textarea:focus {
        border-color: var(--tz-gold);
        outline: none;
        box-shadow: 0 0 0 3px rgba(229,169,59,.18);
    }

    .tz-input:disabled,
    .tz-input[readonly] {
        background: #f4f5f7;
        color: var(--tz-text-muted);
    }

.tz-help {
    font-size: 11.5px;
    color: var(--tz-text-faint);
    margin-top: 4px;
}

.tz-error-text {
    font-size: 11.5px;
    color: var(--tz-danger);
    margin-top: 4px;
}

/* ==========================================================================
   9. Utilities
   ========================================================================== */

.tz-grid-2 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 18px;
}

.tz-grid-3 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 18px;
}

.tz-mt-0 {
    margin-top: 0;
}

.tz-mb-0 {
    margin-bottom: 0 !important;
}

.tz-mb-16 {
    margin-bottom: 16px;
}

.tz-mt-16 {
    margin-top: 16px;
}

.tz-muted {
    color: var(--tz-text-muted);
}

.tz-faint {
    color: var(--tz-text-faint);
}

.tz-strong {
    font-weight: 700;
}

.tz-center {
    text-align: center;
}

.tz-right {
    text-align: right;
}

/* Embedded PDF viewer body used by the document modals. */
.tz-pdf {
    width: 100%;
    height: 460px;
    background: #f4f5f7;
    border-radius: var(--tz-radius-sm);
}

/* ==========================================================================
   9b. Classes the existing markup still references
   --------------------------------------------------------------------------
   These were each redefined in a per-view <style> block. Their definitions were
   identical everywhere they appeared, so they live here once instead. Prefer the
   tz- components above for anything new.
   ========================================================================== */

/* Larger tick target for unit-selection tables. */
.checkboxClass {
    width: 18px;
    height: 18px;
    padding: 0;
    cursor: pointer;
    accent-color: var(--tz-crimson);
    vertical-align: middle;
}

/* Compact in-table buttons. Note .BtnPadding and .btnPadding are two different
   classes - CSS is case-sensitive and both spellings are used in the views. */
.BtnPadding,
.btnPadding,
.btnClass {
    padding: 5px 11px;
    font-size: 11.5px;
    line-height: 1.2;
    border-radius: var(--tz-radius-sm);
}

/* Section heading inside partials loaded into a modal. */
.spanClass {
    font-size: 15px;
    font-weight: 600;
    color: var(--tz-ink);
}

/* Row the user has clicked in a pick-list. */
.selectedTableRow,
.tz-table tbody tr.selectedTableRow,
.tz-table tbody tr.selectedTableRow:hover {
    background: var(--tz-purple) !important;
    color: #fff !important;
}

    .selectedTableRow td {
        color: #fff !important;
    }

/* ==========================================================================
   10. Modals - align the Bootstrap modal with the card look
   ========================================================================== */

.tz-modal .modal-header {
    background: var(--tz-purple);
    color: #fff;
    border-bottom: 3px solid var(--tz-gold);
    padding: 13px 18px;
    align-items: center;
}

    .tz-modal .modal-header .modal-title {
        font-size: 14px;
        font-weight: 600;
        letter-spacing: .4px;
        text-transform: uppercase;
        color: #fff;
        margin: 0;
    }

    .tz-modal .modal-header .close {
        color: #fff;
        opacity: .8;
        text-shadow: none;
        font-size: 26px;
        line-height: 1;
    }

        .tz-modal .modal-header .close:hover {
            opacity: 1;
            color: var(--tz-gold);
        }

.tz-modal .modal-body {
    padding: 18px;
}

.tz-modal .modal-footer {
    border-top: 1px solid var(--tz-border);
    padding: 12px 18px;
}

/* ==========================================================================
   10b. Sign-in pages (Login, Forgot Password, Reset Password)
   ========================================================================== */

.tz-auth-body {
    background: #2b2b33 url('../img/login-bg2.jpg') center / cover no-repeat fixed;
    min-height: 100vh;
    margin: 0;
}

    /* Darken the photo so white text on it stays readable whatever the image is. */
    .tz-auth-body::before {
        content: "";
        position: fixed;
        inset: 0;
        background: linear-gradient(135deg, rgba(30,30,36,.82) 0%, rgba(30,30,36,.62) 100%);
        z-index: 0;
    }

.tz-auth-wrap {
    position: relative;
    z-index: 1;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 30px 16px;
}

.tz-auth-card {
    width: 100%;
    max-width: 410px;
    background: #fff;
    border-radius: 10px;
    box-shadow: 0 18px 50px rgba(0,0,0,.35);
    overflow: hidden;
}

.tz-auth-head {
    /*  Crimson is held through the top half - where the crest sits - before the
        ramp to gold. Same two brand colours and the same warmth as before; it
        just no longer puts a pale crest on a pale ground. */
    background: linear-gradient(160deg, var(--tz-crimson) 0%, var(--tz-crimson) 52%, var(--tz-gold) 100%);
    padding: 26px 26px 22px 26px;
    text-align: center;
}

    /*  No white plate behind the crest. Logo2.png is a transparent PNG, so the
        plate was turning it into a sticker plaqued onto the header.

        It does mean the crest has to sit on a ground it can be seen against, and
        it cannot sit on the gold end of the ramp: 52% of its opaque pixels are
        near-white (it averages #bdac9b) and light-on-gold measures 1.12:1, so
        half the crest would simply vanish. That is why .tz-auth-head below holds
        crimson for the top portion and only turns to gold underneath. */
    .tz-auth-head img {
        max-height: 74px;
        width: auto;
        background: none;
        padding: 0;
        filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .35));
    }

    .tz-auth-head h1 {
        margin: 14px 0 0 0;
        font-size: 16px;
        font-weight: 700;
        letter-spacing: 1.4px;
        text-transform: uppercase;
        color: #fff;
    }

    .tz-auth-head p {
        margin: 5px 0 0 0;
        font-size: 12.5px;
        color: rgba(255,255,255,.9);
    }

.tz-auth-body-inner {
    padding: 26px;
}

.tz-auth-foot {
    padding: 14px 26px 22px 26px;
    text-align: center;
    font-size: 12px;
    color: var(--tz-text-faint);
}

/* Separated from the sign-in options above by a rule, so an external destination does not read
   as another way of getting into the portal. */
.tz-auth-alt {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--tz-border);
}

.tz-auth-alt-label {
    display: block;
    margin-bottom: 8px;
    font-size: 11.5px;
    color: var(--tz-text-faint);
}

    .tz-auth-foot a {
        color: var(--tz-crimson);
        font-weight: 600;
        text-decoration: none;
    }

        .tz-auth-foot a:hover {
            text-decoration: underline;
        }

/* "or" separator between the password and magic-link sign-in options */
.tz-auth-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 18px 0 14px 0;
    color: var(--tz-text-faint);
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: .8px;
}

    .tz-auth-divider::before,
    .tz-auth-divider::after {
        content: "";
        flex: 1 1 auto;
        height: 1px;
        background: var(--tz-border);
    }

/* Password field with a reveal toggle */
.tz-password-wrap {
    position: relative;
}

    .tz-password-wrap .tz-input {
        padding-right: 40px;
    }

.tz-toggle-password {
    position: absolute;
    right: 12px;
    bottom: 9px;
    cursor: pointer;
    color: var(--tz-text-faint);
    z-index: 5;
    background: none;
    border: 0;
    padding: 0;
    line-height: 1;
}

    .tz-toggle-password:hover {
        color: var(--tz-ink);
    }

/* Live password-rule checklist on the reset page. The .valid / .invalid class
   names are set by that page's script, so they are kept as-is. */
.tz-pwrules {
    background: var(--tz-surface-alt);
    border: 1px solid var(--tz-border);
    border-radius: var(--tz-radius-sm);
    padding: 12px 14px;
    margin-bottom: 16px;
    font-size: 12px;
}

    .tz-pwrules div {
        padding: 2px 0;
    }

    .tz-pwrules i {
        margin-right: 8px;
        width: 13px;
        display: inline-block;
        text-align: center;
    }

    .tz-pwrules .valid {
        color: var(--tz-success) !important;
        font-weight: 600;
    }

    .tz-pwrules .invalid {
        color: var(--tz-text-faint);
    }

/* Text inputs must stay selectable - a previous rule elsewhere disabled it. */
.tz-auth-card input {
    -webkit-user-select: text !important;
    -moz-user-select: text !important;
    -ms-user-select: text !important;
    user-select: text !important;
    pointer-events: auto !important;
}

/* ==========================================================================
   10c. Motion and polish
   --------------------------------------------------------------------------
   Everything here hangs off class names the views already use, so no view needs
   editing to pick it up. Keep it restrained - this is a records system students
   use under deadline pressure, not a marketing site. Movement should tell them
   something arrived or responded, never decorate.

   The whole section is switched off under prefers-reduced-motion at the end.
   ========================================================================== */

@keyframes tz-fade-up {
    from {
        opacity: 0;
        transform: translateY(10px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes tz-fade-in {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes tz-slide-down {
    from {
        opacity: 0;
        transform: translateY(-8px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@keyframes tz-shimmer {
    from {
        background-position: -420px 0;
    }

    to {
        background-position: 420px 0;
    }
}

@keyframes tz-pop {
    0% {
        transform: scale(.94);
        opacity: 0;
    }

    60% {
        transform: scale(1.02);
    }

    100% {
        transform: scale(1);
        opacity: 1;
    }
}

/* --- Page entrance ------------------------------------------------------- */

.tz-page-head {
    animation: tz-slide-down .32s ease-out both;
}

.tz-banner {
    animation: tz-fade-up .38s ease-out both;
}

/* Cards arrive in sequence rather than all at once. Capped at six so a long
   page never leaves the reader waiting on the last one. */
.tz-card {
    animation: tz-fade-up .38s ease-out both;
}

    .tz-card:nth-of-type(1) {
        animation-delay: .02s;
    }

    .tz-card:nth-of-type(2) {
        animation-delay: .07s;
    }

    .tz-card:nth-of-type(3) {
        animation-delay: .12s;
    }

    .tz-card:nth-of-type(4) {
        animation-delay: .17s;
    }

    .tz-card:nth-of-type(5) {
        animation-delay: .22s;
    }

    .tz-card:nth-of-type(n+6) {
        animation-delay: .26s;
    }

.tz-stat,
.tz-hero-tile,
.tz-fee-tile {
    animation: tz-fade-up .34s ease-out both;
}

.tz-stats .tz-stat:nth-child(2),
.tz-hero > *:nth-child(2) {
    animation-delay: .06s;
}

.tz-stats .tz-stat:nth-child(3),
.tz-hero > *:nth-child(3) {
    animation-delay: .12s;
}

.tz-stats .tz-stat:nth-child(4) {
    animation-delay: .18s;
}

.tz-stats .tz-stat:nth-child(5) {
    animation-delay: .24s;
}

/* Callouts slide in - they usually appear in response to something. */
.tz-hint {
    animation: tz-slide-down .3s ease-out both;
}

/* Quick-action rows cascade down the panel. */
.tz-quick-item {
    animation: tz-fade-up .3s ease-out both;
}

    .tz-quick-item:nth-child(1) {
        animation-delay: .04s;
    }

    .tz-quick-item:nth-child(2) {
        animation-delay: .08s;
    }

    .tz-quick-item:nth-child(3) {
        animation-delay: .12s;
    }

    .tz-quick-item:nth-child(4) {
        animation-delay: .16s;
    }

    .tz-quick-item:nth-child(5) {
        animation-delay: .20s;
    }

    .tz-quick-item:nth-child(6) {
        animation-delay: .24s;
    }

    .tz-quick-item:nth-child(7) {
        animation-delay: .28s;
    }

    .tz-quick-item:nth-child(n+8) {
        animation-delay: .32s;
    }

/* Empty states and the sign-in card get a gentler treatment. */
.tz-empty {
    animation: tz-fade-in .4s ease-out both;
}

.tz-auth-card {
    animation: tz-pop .34s cubic-bezier(.2, .8, .3, 1) both;
}

/* --- Response to touch --------------------------------------------------- */

.tz-card {
    transition: box-shadow .2s ease, transform .2s ease;
}

.tz-stat,
.tz-info-item {
    transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
}

    .tz-stat:hover,
    .tz-info-item:hover {
        transform: translateY(-2px);
        box-shadow: var(--tz-shadow-lg);
    }

.tz-hero-tile {
    transition: transform .18s ease, box-shadow .18s ease;
}

    .tz-hero-tile:hover {
        transform: translateY(-3px);
        box-shadow: 0 10px 24px rgba(16, 24, 40, .18);
    }

.tz-btn {
    transform: translateZ(0);
}

    .tz-btn:hover:not(:disabled) {
        box-shadow: 0 4px 10px rgba(16, 24, 40, .12);
    }

    .tz-btn:active:not(:disabled) {
        transform: translateY(1px);
        box-shadow: none;
    }

/* Table rows settle rather than snap. */
.tz-table tbody tr {
    transition: background .15s ease;
}

/* Pills pop when they first render - they are the thing the eye should find.
   Not inside tables: a results table can hold hundreds of them, and animating
   every one at once stutters badly on the low-end machines students use. */
.tz-pill {
    animation: tz-pop .26s ease-out both;
}

.tz-table .tz-pill {
    animation: none;
}

/* Photo: hint that it can be replaced. */
.tz-avatar {
    transition: transform .2s ease, border-color .2s ease;
}

.tz-avatar-row:hover .tz-avatar {
    transform: scale(1.04);
    border-color: var(--tz-crimson);
}

/* --- Keyboard focus ------------------------------------------------------
   Visible focus is not decoration. Anyone navigating by keyboard needs to see
   where they are, and the browser default is nearly invisible on dark chrome. */

.tz-btn:focus-visible,
.tz-quick-item:focus-visible,
.tz-link:focus-visible,
.tz-input:focus-visible,
.tz-select:focus-visible,
.tz-nav-link:focus-visible {
    outline: 2px solid var(--tz-gold);
    outline-offset: 2px;
    border-radius: var(--tz-radius-sm);
}

/* --- Loading placeholder -------------------------------------------------
   Add class="tz-skeleton" to a block being filled by AJAX so the space is
   visibly reserved instead of collapsing and then jumping. */

.tz-skeleton {
    min-height: 90px;
    border-radius: var(--tz-radius-sm);
    background: linear-gradient(90deg, #f2f4f7 25%, #e9ecf2 37%, #f2f4f7 63%);
    background-size: 840px 100%;
    animation: tz-shimmer 1.3s linear infinite;
}

/* --- Loading overlay -----------------------------------------------------
   Overrides CSS/Loader.css, which is loaded before this file. The original was
   a black 80% sheet behind a 300x100 white box with a 5px light-blue border and
   an animated GIF, positioned by JavaScript arithmetic on every show. This is
   the same two elements, restyled and centred by CSS. */

.modalLoader {
    background: rgba(28, 28, 34, .55) !important;
    opacity: 1 !important;
    filter: none !important;
    backdrop-filter: blur(2px);
    animation: tz-fade-in .15s ease-out both;
}

.loading {
    width: auto !important;
    height: auto !important;
    min-width: 168px;
    border: 0 !important;
    border-top: 3px solid var(--tz-gold) !important;
    border-radius: var(--tz-radius) !important;
    background: #fff !important;
    box-shadow: 0 12px 34px rgba(0,0,0,.28) !important;
    padding: 22px 26px !important;
    font-family: inherit !important;
    font-size: 12.5px !important;
    color: var(--tz-text-muted);
    text-align: center;
    /* Centred here rather than by the inline top/left the script used to set. */
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%);
}

.tz-spinner {
    width: 34px;
    height: 34px;
    margin: 0 auto 10px auto;
    border: 3px solid var(--tz-border);
    border-top-color: var(--tz-crimson);
    border-right-color: var(--tz-gold);
    border-radius: 50%;
    animation: tz-spin .7s linear infinite;
}

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

/* --- Reduced motion ------------------------------------------------------
   Honour the operating-system setting. Some people get motion sickness or
   migraines from movement on screen; for them everything below simply appears. */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }

        .tz-card,
        .tz-stat,
        .tz-hero-tile,
        .tz-fee-tile,
        .tz-hint,
        .tz-quick-item,
        .tz-pill,
        .tz-auth-card,
        .tz-page-head,
        .tz-banner,
        .tz-empty {
            animation: none !important;
            opacity: 1 !important;
            transform: none !important;
        }

        .tz-stat:hover,
        .tz-info-item:hover,
        .tz-hero-tile:hover,
        .tz-btn:active:not(:disabled) {
            transform: none;
        }
}

/* ==========================================================================
   11. Print
   ========================================================================== */

@media print {
    .vertical-menu,
    #page-topbar,
    .navbar-header,
    .tz-page-actions,
    .tz-btn,
    #styleSelector {
        display: none !important;
    }

    /* Skote offsets the content to clear the fixed sidebar; on paper there is no
       sidebar to clear, and the offset would push everything off the right edge. */
    .main-content,
    .page-content {
        margin-left: 0 !important;
        padding: 0 !important;
    }

    .tz-page {
        background: #fff;
        padding: 0;
    }

    .tz-card {
        box-shadow: none;
        border: 1px solid #999;
        break-inside: avoid;
    }

    .tz-scroll {
        max-height: none;
        overflow: visible;
        border: 0;
    }

    .tz-card-head {
        background: #fff !important;
        color: #000 !important;
        border-bottom: 2px solid #000;
    }

        .tz-card-head h2,
        .tz-card-head .tz-card-title {
            color: #000 !important;
        }

    .tz-table thead th {
        background: #ddd !important;
        color: #000 !important;
        position: static;
    }
}

/* ==========================================================================
   12. Small screens
   ========================================================================== */

@media (max-width: 768px) {
    /*  Containment guard. The theme puts overflow-x: hidden on <body>, which suppresses the
        sideways scrollbar but does not stop content being laid out wider than the screen - it
        just clips it, so cards lose their right-hand edge with no way to scroll to it. These
        caps stop the layout exceeding the viewport in the first place. */
    .main-content,
    .page-content,
    #layout-wrapper,
    .tz-page {
        max-width: 100%;
    }

    .tz-page {
        padding: 16px 14px 50px 14px;
    }

    .tz-page-head h1 {
        font-size: 18px;
    }

    .tz-facts {
        gap: 10px 18px;
    }

    .tz-card-body {
        padding: 14px;
    }

    .tz-btn {
        padding: 8px 13px;
        font-size: 12px;
    }

    .tz-stat .tz-stat-value {
        font-size: 20px;
    }
}
