/* Design System Variables */
:root {
    --font-primary: 'Inter', sans-serif;
    
    /* Color Palette — extracted from the Vistas/VELS logo: royal blue
       wordmark (primary), lighter royal blue (secondary, gradient partner),
       UGC-shield gold (accent, payment CTAs only). */
    --color-primary: #2b3990;
    --color-primary-dark: #1e2a6a;
    --color-secondary: #4053b8;
    --color-accent: #f0b429;
    
    /* Text Colors */
    --text-primary: #1f2937;
    --text-secondary: #6b7280;
    --text-light: #9ca3af;
    
    /* Status Colors */
    --success-bg: #dcfce7;
    --success-text: #16a34a;
    --success-border: #10b981;
    
    --error-bg: #fef2f2;
    --error-text: #dc2626;
    --error-border: #ef4444;
    
    --warning-bg: #fef3c7;
    --warning-text: #d97706;
    --warning-border: #f59e0b;
    
    --info-bg: #dbeafe;
    --info-text: #2563eb;
    --info-border: #3b82f6;

    /* Z-Index Scale: raised content < loader < sticky CTA < modal < toast.
       Tailwind utilities in the views top out at z-50 (mobile menu button). */
    --z-raised: 10;
    --z-loader: 50;
    --z-sticky-pay: 60;
    --z-modal: 70;
    --z-toast: 80;
}

body {
    font-family: var(--font-primary);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Toast Notification Styles */
.toast-container {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: var(--z-toast);
    max-width: 400px;
}

.toast {
    /* Anchors .toast-progress; previously this only worked because the
       transform below created a containing block as a side effect. */
    position: relative;
    background: white;
    border-radius: 12px;
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1), 0 4px 6px rgba(0, 0, 0, 0.05);
    margin-bottom: 12px;
    padding: 16px 20px;
    transform: translateX(400px);
    opacity: 0;
    transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 60px;
}

.toast.show {
    transform: translateX(0);
    opacity: 1;
}

.toast-icon {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 14px;
    font-weight: 600;
}

.toast.success .toast-icon {
    background: var(--success-bg);
    color: var(--success-text);
}

.toast.error .toast-icon {
    background: var(--error-bg);
    color: var(--error-text);
}

.toast.warning .toast-icon {
    background: var(--warning-bg);
    color: var(--warning-text);
}

.toast.info .toast-icon {
    background: var(--info-bg);
    color: var(--info-text);
}

.toast-content {
    flex: 1;
}

.toast-title {
    font-weight: 600;
    font-size: 14px;
    color: var(--text-primary);
    margin-bottom: 2px;
}

.toast-message {
    font-size: 13px;
    color: var(--text-secondary);
    line-height: 1.4;
}

.toast-close {
    background: none;
    border: none;
    color: var(--text-light);
    cursor: pointer;
    /* 44px touch target without inflating the toast's visual footprint. */
    min-width: 44px;
    min-height: 44px;
    margin: -12px -16px -12px -8px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    transition: all 0.2s ease;
    flex-shrink: 0;
}

.toast-close:hover {
    background: #f3f4f6;
    color: var(--text-secondary);
}

.toast-progress {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 3px;
    background: linear-gradient(90deg, currentColor, currentColor);
    border-radius: 0 0 12px 12px;
    transition: width linear;
}

.toast.success .toast-progress {
    color: var(--success-border);
}

.toast.error .toast-progress {
    color: var(--error-border);
}

.toast.warning .toast-progress {
    color: var(--warning-border);
}

.toast.info .toast-progress {
    color: var(--info-border);
}

/* Mobile Toast Styles */
@media (max-width: 640px) {
    .toast-container {
        top: 10px;
        right: 10px;
        left: 10px;
        max-width: none;
    }
    
    .toast {
        margin-bottom: 8px;
        padding: 12px 16px;
        min-height: 50px;
    }
    
    .toast-title {
        font-size: 13px;
    }
    
    .toast-message {
        font-size: 12px;
    }
    
    .toast-icon {
        width: 20px;
        height: 20px;
        font-size: 12px;
    }
}

.step-indicator {
    transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    position: relative;
    z-index: var(--z-raised);
}

.step-indicator.active {
    background: linear-gradient(135deg, var(--color-primary), var(--color-secondary)) !important;
    transform: scale(1.1);
    box-shadow: 0 8px 25px rgba(43, 57, 144, 0.3);
    color: white !important;
}

.step-indicator.completed {
    background: linear-gradient(135deg, var(--success-border), #059669) !important;
    transform: scale(1.05);
    color: white !important;
    box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
}

.step-indicator.completed i {
    animation: checkmark 0.5s ease-in-out;
}

@keyframes checkmark {
    0% { transform: scale(0); }
    50% { transform: scale(1.2); }
    100% { transform: scale(1); }
}

.step-line {
    transition: all 0.6s ease;
    z-index: 1;
}

.step-line.completed {
    background: linear-gradient(to bottom, var(--success-border), #059669);
}

.step-item {
    cursor: pointer;
    transition: all 0.3s ease;
}

.step-item:hover .step-indicator {
    transform: scale(1.05);
}

.form-section {
    display: none;
    opacity: 0;
    transform: translateX(20px);
    position: relative;
}

.form-section.active {
    display: block;
    animation: slideInFade 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

.form-fields {
    display: none;
    opacity: 0;
}

.form-fields.show {
    display: block;
    opacity: 1;
    animation: fadeInFields 0.4s ease forwards;
}

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

.form-section.exit {
    animation: slideOutFade 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes slideInFade {
    from { 
        opacity: 0; 
        transform: translateX(20px);
    }
    to { 
        opacity: 1; 
        transform: translateX(0);
    }
}

@keyframes slideOutFade {
    from { 
        opacity: 1; 
        transform: translateX(0);
    }
    to { 
        opacity: 0; 
        transform: translateX(-20px);
    }
}

.input-group {
    position: relative;
}

.input-icon {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-secondary);
    z-index: var(--z-raised);
    pointer-events: none;
    transition: color 0.2s ease;
}

.input-with-icon {
    padding-left: 40px;
}

.input-with-icon:focus + .input-icon,
.input-with-icon:focus ~ .input-icon {
    color: var(--color-primary);
}

.compact-input {
    height: 40px;
    padding: 8px 12px;
    font-size: 14px;
}

.compact-input.input-with-icon {
    padding-left: 40px;
}

.compact-label {
    font-size: 13px;
    margin-bottom: 4px;
    font-weight: 500;
}

/* A <select> locked after the Application Fee is paid. Selects can't use the
   native readonly attribute, so we block pointer/keyboard interaction while
   keeping the value readable; it reads visually like the readonly text inputs. */
.select-readonly {
    background-color: #f3f4f6;
    cursor: not-allowed;
    pointer-events: none;
}

.education-tab {
    background: transparent;
    color: var(--text-secondary);
    border: none;
    cursor: pointer;
}

.education-tab.active {
    background: white;
    color: var(--color-primary);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.education-tab:hover:not(.active) {
    background: rgba(255, 255, 255, 0.5);
    color: var(--text-primary);
}

.education-tab.tab-error {
    background: var(--error-bg);
    color: var(--error-text);
    border: 1px solid #fca5a5;
    animation: shake 0.5s ease-in-out;
}

.education-tab.tab-error.active {
    background: var(--error-text);
    color: white;
    border: 1px solid var(--error-text);
}

@keyframes shake {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-2px); }
    75% { transform: translateX(2px); }
}

.field-error {
    border-color: var(--error-text) !important;
    box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1) !important;
    animation: pulse-error 1s ease-in-out;
}

@keyframes pulse-error {
    0% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.4); }
    50% { box-shadow: 0 0 0 6px rgba(220, 38, 38, 0.1); }
    100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0); }
}

.education-content {
    display: none;
    opacity: 0;
    transform: translateY(10px);
}

.education-content.active {
    display: block;
    opacity: 1;
    transform: translateY(0);
    animation: fadeInUp 0.3s ease-out;
}

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

/* Mobile Stepper Optimizations */
@media (max-width: 1024px) {
    .lg\:w-72 {
        width: 100%;
        margin-bottom: 1rem;
    }
    .sticky {
        position: relative !important;
        top: auto !important;
    }
}

@media (max-width: 640px) {
    .compact-input {
        height: 44px;
        font-size: 16px;
    }
    
    /* Mobile Stepper Layout */
    .space-y-4 {
        gap: 1rem;
    }
    
    .step-item {
        padding: 0.5rem;
        background: rgba(249, 250, 251, 0.3);
        border-radius: 0.5rem;
        transition: all 0.3s ease;
    }
    
    .step-item:hover {
        background: rgba(249, 250, 251, 0.6);
    }
    
    .step-item.active-step {
        background: rgba(43, 57, 144, 0.05);
        border: 1px solid rgba(43, 57, 144, 0.2);
    }
    
    .step-line {
        height: 12px !important;
        top: 48px !important;
    }
}

/* Step Transition Loader */
.step-loader {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(255, 255, 255, 0.95);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: var(--z-loader);
    backdrop-filter: blur(2px);
}

.step-loader.show {
    display: flex;
}

.loader-spinner {
    width: 40px;
    height: 40px;
    border: 3px solid #f3f4f6;
    border-top: 3px solid var(--color-primary);
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* Form Container Improvements */
.form-container {
    min-height: 600px;
    position: relative;
    overflow: hidden;
}

.form-section {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    opacity: 0;
    transform: translateX(30px);
    transition: none;
    pointer-events: none;
}

.form-section.active {
    position: relative;
    opacity: 1;
    transform: translateX(0);
    pointer-events: auto;
    animation: smoothSlideIn 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

.form-section.exiting {
    position: absolute;
    opacity: 1;
    transform: translateX(0);
    pointer-events: none;
    animation: smoothSlideOut 0.3s cubic-bezier(0.55, 0.06, 0.68, 0.19) forwards;
}

@keyframes smoothSlideIn {
    0% {
        opacity: 0;
        transform: translateX(30px);
    }
    100% {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes smoothSlideOut {
    0% {
        opacity: 1;
        transform: translateX(0);
    }
    100% {
        opacity: 0;
        transform: translateX(-30px);
    }
}

/* Login Page Styles */

/* Campus photography backdrop. The indigo scrim keeps the white card crisp
   over the bright photo; the solid color is the fallback while the image
   loads (or if it fails). Media queries ensure only the matching banner is
   ever downloaded. */
.login-bg {
    background-color: #1e2a6a;
}

@media (min-width: 768px) {
    .login-bg {
        background-image:
            linear-gradient(rgba(22, 31, 79, 0.45), rgba(22, 31, 79, 0.45)),
            url('../img/login-banner-desktop.webp');
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
    }
}

@media (max-width: 767px) {
    .login-bg {
        background-image:
            linear-gradient(rgba(22, 31, 79, 0.45), rgba(22, 31, 79, 0.45)),
            url('../img/login-banner-mobile.webp');
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
    }
}

/* Card entrance: one short, subtle rise. Stilled by the reduced-motion guard. */
.login-card {
    animation: cardIn 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

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

/* Floating-label Input Fields */
.input-field {
    width: 100%;
    padding: 16px 20px 16px 50px;
    border: 2px solid #e5e7eb;
    border-radius: 8px;
    font-size: 16px;
    background: #ffffff;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.input-field:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 4px rgba(43, 57, 144, 0.1);
}

/* Login inputs have no label above the field: the group is exactly the input's
   height, so the base .input-icon (top: 50%) centres the icon on the field. */

.input-label {
    position: absolute;
    left: 50px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-secondary);
    font-size: 16px;
    pointer-events: none;
    transition: all 0.2s ease;
    background: transparent;
    padding: 0 4px;
}

.input-field:focus + .input-icon + .input-label,
.input-field:not(:placeholder-shown) + .input-icon + .input-label {
    top: 0;
    left: 46px;
    font-size: 12px;
    color: var(--text-secondary);
    background: #ffffff;
    font-weight: 500;
}

/* Indigo means "interactive": the floated label only takes the accent while
   the field is actually focused, and stays gray at rest. */
.input-field:focus + .input-icon + .input-label {
    color: var(--color-primary);
}

/* Inline field error message (toggled with the Tailwind .hidden utility) */
.field-message {
    margin-top: 6px;
    font-size: 13px;
    line-height: 1.4;
    color: var(--error-text);
}

/* Login Button */
.login-btn {
    background: linear-gradient(135deg, var(--color-primary), var(--color-secondary));
    transition: opacity 0.2s ease, box-shadow 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.login-btn:hover:not(:disabled) {
    opacity: 0.92;
}

.login-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px #ffffff, 0 0 0 5px var(--color-primary);
}

.login-btn:disabled {
    cursor: not-allowed;
}

/* Login Loading Spinner */
.loading-spinner {
    width: 20px;
    height: 20px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-top: 2px solid white;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    display: none;
}

/* While loading, the spinner joins the label; the label never disappears,
   so the button keeps its accessible name during the lookup. */
.login-btn.loading .loading-spinner {
    display: inline-block;
}

/* Login Responsive Design */
@media (max-width: 640px) {
    .login-card {
        padding: 2rem 1.5rem;
    }

    .input-field {
        padding: 14px 18px 14px 45px;
        font-size: 16px; /* Prevent zoom on iOS */
    }

    .login-card .input-icon {
        left: 14px;
        font-size: 16px;
    }

    .input-label {
        left: 45px;
        font-size: 15px;
    }

    .input-field:focus + .input-icon + .input-label,
    .input-field:not(:placeholder-shown) + .input-icon + .input-label {
        left: 41px;
        font-size: 11px;
    }
}

/* Documents Page Styles */

/* Sidebar Styles */
.sidebar {
    transition: transform 0.3s ease;
}

.sidebar-hidden {
    transform: translateX(-100%);
}

/* Upload Area Styles */
.upload-area {
    border: 2px dashed #d1d5db;
    transition: all 0.3s ease;
}

.upload-area:hover {
    border-color: var(--color-primary);
    background-color: #f8fafc;
}

.upload-area.dragover {
    border-color: var(--color-primary);
    background-color: #eef2ff;
}

/* File Preview Styles */
.file-preview {
    max-width: 150px;
    max-height: 150px;
    object-fit: cover;
    border-radius: 8px;
}

/* Action Button Styles */
.action-btn {
    width: 32px;
    height: 32px;
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s ease;
    cursor: pointer;
}

.action-btn:hover {
    transform: scale(1.1);
}

.action-btn.upload {
    background: var(--info-bg);
    color: var(--info-text);
}

.action-btn.upload:hover {
    background: #bfdbfe;
}

.action-btn.download {
    background: var(--success-bg);
    color: var(--success-text);
}

.action-btn.download:hover {
    background: #bbf7d0;
}

.action-btn.view {
    background: var(--warning-bg);
    color: var(--warning-text);
}

.action-btn.view:hover {
    background: #fde68a;
}

.action-btn.delete {
    background: var(--error-bg);
    color: var(--error-text);
}

.action-btn.delete:hover {
    background: #fecaca;
}

.action-btn.disabled {
    background: #f3f4f6;
    color: var(--text-light);
    cursor: not-allowed;
}

.action-btn.disabled:hover {
    transform: none;
}

/* Fees Page Styles */

/* Fee Card Animations */
.fee-card {
    transition: all 0.3s ease;
}

.fee-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
}

/* Progress Bar Animations: scaleX instead of width so the fill animation
   composites on the GPU instead of triggering layout. */
.progress-bar {
    transform-origin: left;
    animation: fillProgress 1.5s ease-out;
}

@keyframes fillProgress {
    from { transform: scaleX(0); }
}

/* Sticky Pay Button on Mobile */
.sticky-pay-button {
    position: fixed;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--z-sticky-pay);
    display: none;
}

/* CSS owns the show/hide; no JS resize listener needed. */
@media (max-width: 768px) {
    .sticky-pay-button {
        display: block;
    }
}

/* Reduced Motion: collapse every animation and transition to an instant
   state change. Required companion to all the keyframes above. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Application-form fields carry a label above a fixed-height input, and an
   inline error message may be appended below. Lay the group out as rows and
   drop the icon into the input's own row, vertically centred there — so it is
   never shifted by a label that wraps above it or an error appended below.
   (Login fields use .input-field, not .input-with-icon, so they keep the
   absolute, group-centred icon above.) */
.input-group:has(.input-with-icon) {
    display: grid;
    grid-template-columns: 1fr;
    align-content: start;    /* if the outer grid stretches the group taller
                                than its content (a taller field beside it),
                                keep the rows at natural size so the input row
                                stays 40px and the centred icon tracks it. */
}
.input-group:has(.input-with-icon) > .compact-label { grid-row: 1; }
.input-group:has(.input-with-icon) > .input-with-icon { grid-row: 2; grid-column: 1; }
.input-group:has(.input-with-icon) > .input-icon {
    grid-row: 2;
    grid-column: 1;          /* same cell as the field, so it overlays it */
    position: static;        /* placed by the grid, not absolutely */
    transform: none;         /* the grid centres it; drop the base translate */
    align-self: center;      /* vertical centre of the 40px input row */
    justify-self: start;
    margin-left: 12px;
}
.input-group:has(.input-with-icon) > .field-message { grid-row: 3; grid-column: 1; }

/* Stepper items are role="button" divs; keyboard focus needs a visible ring. */
.step-item:focus-visible {
    outline: none;
    border-radius: 0.5rem;
    box-shadow: 0 0 0 3px rgba(43, 57, 144, 0.35);
}

/* ---------------------------------------------------------------------------
   Modal system (opt-in). One centered, animated, accessible dialog pattern
   shared by every pop-up (file viewer, remark, confirm). Visibility is driven
   by a single `.is-open` class — no hidden/flex juggling — so a panel is always
   correctly centred. The overlay owns the backdrop + the --z-modal layer; the
   global prefers-reduced-motion block above collapses these transitions to an
   instant state change. JS adds .modal-open to <body> to lock background scroll.
--------------------------------------------------------------------------- */
.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(0, 0, 0, 0.6);
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, visibility 0.2s ease;
}

.modal-overlay.is-open {
    opacity: 1;
    visibility: visible;
}

/* The dialog itself: a column that can scroll its own body while the header /
   footer stay put, capped to the viewport so it never overflows the screen. */
.modal-panel {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-height: calc(100vh - 2rem);
    background: #ffffff;
    border-radius: 1rem;             /* 16px — modal radius per design system */
    overflow: hidden;                /* clip header/body to the rounded corners */
    box-shadow: 0 24px 48px -16px rgba(15, 23, 42, 0.40), 0 8px 20px -12px rgba(15, 23, 42, 0.25);
    transform: translateY(10px) scale(0.98);
    opacity: 0;
    transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.18s ease;
}

.modal-overlay.is-open .modal-panel {
    transform: translateY(0) scale(1);
    opacity: 1;
}

/* Subtle, square icon-button for modal close (and similar 40px controls).
   Replaces the low-contrast bare text-gray-400 'x'. */
.modal-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 0.5rem;
    color: #6b7280;            /* slate-voice; AA on white */
    transition: background-color 0.15s ease, color 0.15s ease;
}

.modal-icon-btn:hover {
    background-color: #f3f4f6;
    color: #1f2937;            /* ink */
}

.modal-icon-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(43, 57, 144, 0.30);
}

body.modal-open {
    overflow: hidden;
}

/* Modal action buttons. Defined here (not as Tailwind utilities) because the
   prebuilt tailwind.min.css does not include bg-red-600 / hover:bg-red-700, and
   these are swapped in via JS class strings for the confirm dialog's variants. */
.modal-btn-danger,
.modal-btn-primary {
    padding: 0.5rem 1rem;
    border-radius: 0.5rem;
    font-size: 0.875rem;
    font-weight: 600;
    color: #ffffff;
    transition: background-color 0.15s ease, opacity 0.15s ease;
}

.modal-btn-danger {
    background-color: #dc2626;       /* error-red */
}

.modal-btn-danger:hover {
    background-color: #b91c1c;
}

.modal-btn-primary {
    background-image: linear-gradient(135deg, #2b3990, #4053b8);   /* royal-blue gradient */
}

.modal-btn-primary:hover {
    opacity: 0.9;
}
