/* ============================================================
   DMIT Website — Stylesheet
   Department of Management & Information Technology
   South Eastern University of Sri Lanka
   ============================================================ */

/* ─── Variables ───────────────────────────────────── */
:root {
    --primary: #0a2463;
    --primary-rgb: 10, 36, 99;   /* the same colour as r, g, b, for its tints; a unit theme overrides both (header.php) */
    --primary-light: #1a3a7a;
    --primary-dark: #071a4a;
    --accent: #d4a843;
    --accent-light: #e8c46a;
    --white: #ffffff;
    --light: #f5f7fa;
    --gray-100: #eef1f5;
    --gray-200: #dde2ea;
    --gray-300: #bcc3cf;
    /* --gray-600 completes the Tailwind-derived half of this scale
       (--gray-500 #6b7280, --gray-700 #374151, --gray-900 #111827 are
       Tailwind's). It was MISSING while 30 inline styles already said
       `color:var(--gray-600)`, so that text silently inherited the full body
       colour instead of rendering muted. At #4b5563 it is 7.56:1 on white —
       comfortably past WCAG AA.

       >>> --gray-400 IS DELIBERATELY NOT DEFINED. Tailwind's value (#9ca3af)
       is 2.54:1 on white, which FAILS AA for normal text, and every single
       use of that token in this codebase is a `color:` — 34 of them. Defining
       it would have taken 20 text elements from 10.31:1 down to 2.54:1, one
       session after UX4 added focus rings for accessibility. Those uses were
       pointed at --gray-500 (4.83:1) instead. If a future need is a BORDER or
       a disabled icon rather than text, define it then. */
    --gray-500: #6b7280;
    --gray-600: #4b5563;
    --gray-700: #374151;
    --gray-900: #111827;
    --success: #16a34a;
    --warning: #f59e0b;
    --danger: #dc2626;
    --info: #2563eb;

    /* UX8 · tokens for colours that were bare literals inside inline
       style="" attributes. Each is defined at the EXACT value it replaced,
       so the substitution is pixel-identical by construction — verified by
       fingerprinting every computed colour on four pages before and after.
       Near-identical greys are kept separate on purpose: merging #888,
       #999 and #aaa is a design decision with visible consequences, not a
       mechanical cleanup. They exist so a theme can redefine them. */
    --ink-black:   #000;     /* pure black, used for high-contrast text */
    --grey-mid:    #999;     /* mid grey. NOT named --gray-400: that name is
                                already referenced 27 times in inline styles as an
                                UNDEFINED token, and defining it would silently
                                change what all of them render. See the Session 35
                                entry and the >>> NEXT item about that. */
    --gray-450:    #888;     /* mid grey */
    --grey-dark:   #666;     /* mid-dark grey. NOT --gray-600, for the same reason. */
    --gray-550:    #777;     /* mid grey */
    --line-200:    #ccc;     /* border grey */
    --line-100:    #eee;     /* light border / divider */
    --line-050:    #f5f5f5;  /* faintest fill */
    --surface-100: #f1f5f9;  /* tinted panel background */
    --surface-050: #f8fafc;  /* faintest panel background */
    --amber-dark:  #a07a20;  /* warning text on a light amber fill */
    --teal-dark:   #0f766e;  /* HDIT accent / success text */
    --danger-dark: #b91c1c;  /* error text on a light red fill */
    --hdit-green:  #0b6b3a;  /* HDIT's own accent, used in its admin shell */
    --focus-fill:  #fffbea;  /* soft highlight behind a focused grid cell */
    --radius: 8px;
    --radius-lg: 12px;
    --shadow: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.06);
    --shadow-md: 0 4px 6px rgba(0,0,0,0.07), 0 2px 4px rgba(0,0,0,0.06);
    --shadow-lg: 0 10px 15px rgba(0,0,0,0.1), 0 4px 6px rgba(0,0,0,0.05);
    --transition: all 0.3s ease;
    --font: 'Inter', -apple-system, sans-serif;
}

/* ─── Reset ───────────────────────────────────────── */
*, *::before, *::after { margin:0; padding:0; box-sizing:border-box; }
/* Visually hidden, still read by screen readers (headings that complete the outline). */
.sr-only { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
html { scroll-behavior: smooth; }
body { font-family: var(--font); color: var(--gray-700); background: var(--white); line-height: 1.6; }
a { text-decoration: none; color: inherit; }
ul { list-style: none; }
img { max-width: 100%; height: auto; }
button { cursor: pointer; border: none; background: none; font-family: inherit; }

/* ─── Container ───────────────────────────────────── */
.container { width: 100%; max-width: 1200px; margin: 0 auto; padding: 0 20px; }

/* ─── Top Bar ─────────────────────────────────────── */
.top-bar { background: var(--primary-dark); color: rgba(255,255,255,0.8); font-size: 13px; padding: 6px 0; }
.top-bar .container { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; }
.top-bar-left { display: flex; gap: 20px; }
.top-bar-left span i { margin-right: 5px; color: var(--accent); }
.top-bar-right { display: flex; align-items: center; gap: 18px; }
.top-bar-right a { color: rgba(255,255,255,0.85); transition: var(--transition); }
.top-bar-right a:hover { color: var(--accent); }
.top-bar-right a i { margin-right: 4px; }
.social-links { display: flex; gap: 10px; }
.social-links a { width: 26px; height: 26px; border-radius: 50%; background: rgba(255,255,255,0.1); display: flex; align-items: center; justify-content: center; font-size: 11px; color: rgba(255,255,255,0.8); }
.social-links a:hover { background: var(--accent); color: var(--white); }

/* ─── Navbar ──────────────────────────────────────── */
.navbar { background: var(--white); padding: 0; position: sticky; top: 0; z-index: 1000; box-shadow: var(--shadow); }
.navbar .container { display: flex; justify-content: space-between; align-items: center; }
.logo { display: flex; align-items: center; gap: 10px; padding: 10px 0; }
.logo-crest { height: 52px; width: auto; }
.logo-crest-white { filter: brightness(0) invert(1); }
.logo-text .name { font-size: 18px; font-weight: 700; color: var(--primary); letter-spacing: 1px; line-height: 1.2; }
.logo-text .sub { font-size: 11px; color: var(--gray-500); line-height: 1.3; }

.nav-menu { display: flex; align-items: center; gap: 0; }
.nav-menu > li > a { display: block; padding: 20px 14px; font-size: 14px; font-weight: 500; color: var(--gray-700); transition: var(--transition); position: relative; }
.nav-menu > li > a:hover, .nav-menu > li > a.active { color: var(--primary); }
.nav-menu > li > a.active::after { content: ''; position: absolute; bottom: 0; left: 14px; right: 14px; height: 3px; background: var(--accent); border-radius: 3px 3px 0 0; }
.nav-menu > li > a i { font-size: 10px; margin-left: 3px; }

/* Dropdown */
.has-dropdown { position: relative; }
.dropdown { position: absolute; top: 100%; left: 0; background: var(--white); min-width: 220px; border-radius: 0 0 var(--radius) var(--radius); box-shadow: var(--shadow-lg); opacity: 0; visibility: hidden; transform: translateY(10px); transition: var(--transition); z-index: 100; }
.has-dropdown:hover .dropdown,
.has-dropdown.open .dropdown,
.has-dropdown:focus-within .dropdown { opacity: 1; visibility: visible; transform: translateY(0); }
.dropdown li a { display: block; padding: 10px 18px; font-size: 13px; color: var(--gray-700); border-bottom: 1px solid var(--gray-100); transition: var(--transition); }
.dropdown li a:hover { background: var(--light); color: var(--primary); padding-left: 22px; }
.dropdown li:last-child a { border-bottom: none; }

/* Mobile Toggle */
.nav-toggle { display: none; flex-direction: column; gap: 5px; padding: 10px; }
.nav-toggle span { display: block; width: 24px; height: 2px; background: var(--gray-700); transition: var(--transition); }

/* ─── Hero Section ────────────────────────────────── */
.hero { position: relative; background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 50%, var(--primary-dark) 100%); color: var(--white); padding: 80px 0 100px; overflow: hidden; }
.hero::before { content: ''; position: absolute; top: 0; right: 0; bottom: 0; width: 55%; background: linear-gradient(100deg, rgba(var(--primary-rgb), 0.55), rgba(var(--primary-rgb), 0.15)); z-index: 1; pointer-events: none; }
.hero::after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 60px; background: linear-gradient(transparent, rgba(var(--primary-rgb), 0.8)); z-index: 3; pointer-events: none; }
.hero-content { position: relative; z-index: 4; max-width: 600px; }

/* Blended hero background image (South Eastern University + IT context).
   The photo sits behind a navy gradient overlay so the white hero text
   stays readable; the subtle blue→navy blend ties it to the brand. */
.hero-bg-img { position: absolute; top: 0; right: 0; width: 65%; height: 100%; object-fit: cover; object-position: center top; z-index: 0; }
@media (max-width: 768px) { .hero-bg-img { width: 100%; opacity: .8; } }
.hero-badge { display: inline-block; background: rgba(212,168,67,0.2); border: 1px solid var(--accent); color: var(--accent); padding: 5px 16px; border-radius: 20px; font-size: 13px; font-weight: 500; margin-bottom: 20px; }
.hero h1 { font-size: 42px; font-weight: 700; line-height: 1.2; margin-bottom: 10px; }
.hero h1 span { color: var(--accent); }
.hero-programme { font-size: 18px; opacity: 0.9; margin-bottom: 8px; }
.hero-tagline { font-size: 16px; opacity: 0.7; margin-bottom: 30px; }
.hero-buttons { display: flex; gap: 12px; flex-wrap: wrap; }

/* Hero messages — backend-managed, eye-catching banners shown under
   "Learn More". Light card on the dark hero so text stays readable; the
   urgent/warning themes gently pulse to draw attention. */
.hero-messages { margin-top: 18px; display: flex; flex-direction: column; gap: 10px; max-width: 640px; }
.hero-message { border-radius: var(--radius); padding: 12px 16px; border-left: 4px solid var(--info); background: rgba(255,255,255,0.94); box-shadow: var(--shadow); }
.hero-message .hm-title { font-weight: 700; font-size: 15px; margin-bottom: 4px; color: var(--info); }
.hero-message .hm-body { font-size: 13.5px; line-height: 1.55; color: var(--gray-700); }
.hero-message .hm-body a { color: var(--primary); font-weight: 600; text-decoration: underline; }
.hero-message-urgent { border-left-color: var(--danger); background: rgba(254,242,242,0.96); }
.hero-message-urgent .hm-title { color: var(--danger); }
.hero-message-warning { border-left-color: #d97706; background: rgba(254,252,242,0.96); }
.hero-message-warning .hm-title { color: #b45309; }
.hero-message-success { border-left-color: #16a34a; background: rgba(240,253,244,0.96); }
.hero-message-success .hm-title { color: #15803d; }
.hero-message-urgent, .hero-message-warning { animation: hmPulse 2s ease-in-out infinite; }
@keyframes hmPulse {
    0%, 100% { box-shadow: var(--shadow); }
    50% { box-shadow: 0 0 0 4px rgba(37,99,235,0.14), var(--shadow); }
}

/* ─── Self-contained rich text editor (admin) ─────── */
.rte-toolbar { display: flex; gap: 4px; padding: 6px 8px; border: 1px solid var(--gray-200); border-bottom: none; border-radius: var(--radius) var(--radius) 0 0; background: var(--light); }
.rte-toolbar button { width: 32px; height: 32px; border: 1px solid var(--gray-200); background: #fff; border-radius: 6px; cursor: pointer; color: var(--gray-700); display: flex; align-items: center; justify-content: center; font-size: 13px; transition: var(--transition); }
.rte-toolbar button:hover { background: var(--gray-100); color: var(--primary); }
.rte-editor { min-height: 150px; border: 1px solid var(--gray-200); border-radius: 0 0 var(--radius) var(--radius); padding: 12px 14px; font-size: 14px; line-height: 1.6; background: #fff; overflow: auto; color: var(--gray-900); }
.rte-editor:focus { outline: none; border-color: var(--primary); }
.rte-editor p { margin: 0 0 8px; }
.rte-editor a { color: var(--primary); }

/* ─── Buttons ─────────────────────────────────────── */
.btn { display: inline-flex; align-items: center; gap: 8px; padding: 12px 28px; border-radius: var(--radius); font-size: 14px; font-weight: 600; transition: var(--transition); border: 2px solid transparent; }
.btn-primary { background: var(--accent); color: var(--primary-dark); border-color: var(--accent); }
.btn-primary:hover { background: var(--accent-light); border-color: var(--accent-light); transform: translateY(-1px); }
.btn-outline { background: transparent; color: var(--white); border-color: rgba(255,255,255,0.4); }
.btn-outline:hover { background: rgba(255,255,255,0.1); border-color: var(--white); }
.btn-sm { padding: 8px 18px; font-size: 13px; }
.btn-blue { background: var(--primary); color: var(--white); }
.btn-blue:hover { background: var(--primary-light); }
.btn-success { background: var(--success); color: var(--white); }
.btn-danger { background: var(--danger); color: var(--white); }
.btn-icon { background: var(--light); color: var(--gray-700); padding: 8px 14px; border-radius: var(--radius); }
.btn-icon:hover { background: var(--gray-200); }

/* ─── Quick Access Panel ──────────────────────────── */
.quick-access { position: relative; z-index: 10; margin-top: -50px; margin-bottom: 40px; }
.qa-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; background: var(--white); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); overflow: hidden; }
.qa-item { display: flex; flex-direction: column; align-items: center; padding: 28px 16px; text-align: center; transition: var(--transition); border-right: 1px solid var(--gray-100); cursor: pointer; }
.qa-item:last-child { border-right: none; }
.qa-item:hover { background: var(--primary); color: var(--white); }
.qa-item .qa-icon { width: 50px; height: 50px; border-radius: 50%; background: var(--light); display: flex; align-items: center; justify-content: center; font-size: 20px; color: var(--primary); margin-bottom: 10px; transition: var(--transition); }
.qa-item:hover .qa-icon { background: rgba(255,255,255,0.2); color: var(--white); }
.qa-item .qa-title { font-size: 13px; font-weight: 600; margin-bottom: 3px; }
.qa-item .qa-sub { font-size: 11px; opacity: 0.7; }

/* ─── Section Styles ──────────────────────────────── */
.section { padding: 60px 0; }
.section-alt { background: var(--light); }
.section-header { text-align: center; margin-bottom: 40px; }
.section-header h1, .section-header h2 { font-size: 28px; font-weight: 700; color: var(--gray-900); margin-bottom: 8px; }
.section-header p { color: var(--gray-500); max-width: 600px; margin: 0 auto; }
.section-header .accent-bar { width: 50px; height: 4px; background: var(--accent); border-radius: 2px; margin: 12px auto 0; }
.section-title-flex { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; }
.section-title-flex h2 { font-size: 22px; font-weight: 700; color: var(--gray-900); }
.home-col .section-title-flex h2 { font-size: 16px; font-weight: 700; color: var(--gray-900); }
.view-all { font-size: 13px; font-weight: 600; color: var(--primary); }
.view-all:hover { color: var(--accent); }

/* ─── Home 3-Col Grid ─────────────────────────────── */
.home-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 24px; margin-bottom: 50px; }

/* Announcement Cards */
.announcement-card { display: flex; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--gray-100); }
.announcement-card:last-child { border-bottom: none; }
.ann-icon { width: 36px; height: 36px; border-radius: 50%; background: rgba(220,38,38,0.1); color: var(--danger); display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 14px; }
.ann-icon.academic { background: rgba(37,99,235,0.1); color: var(--info); }
.ann-icon.exam { background: rgba(245,158,11,0.1); color: var(--warning); }
.ann-content h4, .ann-content h3 { font-size: 13px; font-weight: 600; color: var(--gray-900); line-height: 1.4; }
.ann-content .date { font-size: 11px; color: var(--gray-500); margin-top: 2px; }

/* Event Cards */
.event-card { display: flex; gap: 14px; padding: 14px 0; border-bottom: 1px solid var(--gray-100); }
.event-card:last-child { border-bottom: none; }
.event-date { text-align: center; flex-shrink: 0; background: var(--light); border-radius: var(--radius); padding: 8px 12px; min-width: 56px; }
.event-date .day { font-size: 22px; font-weight: 700; color: var(--primary); line-height: 1; }
.event-date .month { font-size: 11px; font-weight: 600; color: var(--accent); text-transform: uppercase; }
.event-info h4, .event-info h3 { font-size: 13px; font-weight: 600; color: var(--gray-900); }
.event-info .time { font-size: 12px; color: var(--gray-500); margin-top: 2px; }
.event-info .venue { font-size: 12px; color: var(--gray-500); }
.event-info .venue i { color: var(--danger); margin-right: 3px; }

/* Programme Highlights */
.highlight-item { display: flex; align-items: flex-start; gap: 10px; padding: 10px 0; }
.highlight-item i { color: var(--success); margin-top: 3px; flex-shrink: 0; }
.highlight-item span { font-size: 13px; color: var(--gray-700); }

/* ─── Stats Bar ───────────────────────────────────── */
.stats-bar { background: var(--primary); padding: 30px 0; }
.stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; text-align: center; color: var(--white); }
.stat-item { display: flex; flex-direction: column; align-items: center; }
.stat-item .stat-icon { font-size: 28px; color: var(--accent); margin-bottom: 8px; }
.stat-item .stat-num { font-size: 32px; font-weight: 700; line-height: 1.1; }
.stat-item .stat-label { font-size: 13px; opacity: 0.8; margin-top: 4px; }

/* ─── Research Spotlight ──────────────────────────── */
.research-spotlight { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.research-card { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 24px; transition: var(--transition); }
.research-card:hover { border-color: var(--primary); box-shadow: var(--shadow-md); }
.research-card .r-type { display: inline-block; font-size: 11px; font-weight: 600; text-transform: uppercase; color: var(--primary); background: rgba(var(--primary-rgb), 0.08); padding: 3px 10px; border-radius: 4px; margin-bottom: 10px; }
.research-card h4, .research-card h3 { font-size: 15px; font-weight: 600; color: var(--gray-900); margin-bottom: 6px; line-height: 1.4; }
.research-card .r-authors { font-size: 13px; color: var(--gray-500); }
.research-card .r-journal { font-size: 12px; color: var(--accent); margin-top: 4px; font-style: italic; }
a.research-card-link { display: block; text-decoration: none; color: inherit; cursor: pointer; }
a.research-card-link:hover h4, a.research-card-link:hover h3 { color: var(--primary); }

/* ─── Cards (Generic) ─────────────────────────────── */
.card { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 24px; transition: var(--transition); }
.card:hover { box-shadow: var(--shadow-md); }
.card-header { border-bottom: 1px solid var(--gray-100); padding-bottom: 14px; margin-bottom: 16px; display: flex; justify-content: space-between; align-items: center; }
.card-header h3, .card-header h2 { font-size: 16px; font-weight: 600; color: var(--gray-900); }

/* ─── Page Banner ─────────────────────────────────── */
.page-banner { background: linear-gradient(135deg, var(--primary), var(--primary-light)); color: var(--white); padding: 50px 0 40px; }
.page-banner h1 { font-size: 32px; font-weight: 700; }
.page-banner .breadcrumb { display: flex; gap: 8px; font-size: 13px; margin-top: 8px; opacity: 0.8; }
.page-banner .breadcrumb a { color: var(--accent); }
.page-banner .breadcrumb span { opacity: 0.6; }

/* ─── About Page ──────────────────────────────────── */
.about-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: center; }
.about-text h3 { font-size: 22px; font-weight: 700; color: var(--gray-900); margin-bottom: 12px; }
.about-text h2 { font-size: 22px; font-weight: 700; color: var(--gray-900); margin-bottom: 12px; }
.about-text p { color: var(--gray-500); margin-bottom: 12px; }
.vision-mission { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.vm-card { background: var(--light); border-radius: var(--radius-lg); padding: 24px; border-left: 4px solid var(--accent); }
.vm-card h4, .vm-card h3 { font-size: 16px; font-weight: 600; color: var(--primary); margin-bottom: 8px; }
.vm-card p { font-size: 14px; color: var(--gray-500); }

/* Semester Tabs */
.semester-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }
.sem-tab { padding: 8px 18px; border-radius: var(--radius); font-size: 13px; font-weight: 500; border: 1px solid var(--gray-200); color: var(--gray-700); transition: var(--transition); cursor: pointer; }
.sem-tab.active, .sem-tab:hover { background: var(--primary); color: var(--white); border-color: var(--primary); }

/* Module Table */
.module-table { width: 100%; border-collapse: collapse; }
.module-table th { background: var(--primary); color: var(--white); padding: 12px 16px; font-size: 13px; font-weight: 600; text-align: left; }
.module-table td { padding: 12px 16px; font-size: 13px; border-bottom: 1px solid var(--gray-100); }
.module-table tr:hover { background: var(--light); }
/* Generic badges. ~30 `badge badge-*` labels (research publication types, admin statuses) had
   no rule outside the curriculum table and rendered as plain text (found 2026-10-22). */
.badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; line-height: 1.5; background: var(--gray-100); color: var(--gray-700, #374151); }
.badge-primary { background: rgba(var(--primary-rgb), 0.1); color: var(--primary); }
.badge-success { background: rgba(22,163,74,0.12); color: var(--success); }
.badge-warning { background: rgba(245,158,11,0.15); color: #92400e; }
.badge-danger { background: rgba(220,38,38,0.12); color: var(--danger); }
.badge-secondary { background: var(--gray-100); color: var(--gray-700, #374151); }
.module-table .badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; }
.module-table .badge-core { background: rgba(var(--primary-rgb), 0.1); color: var(--primary); }
.module-table .badge-elective { background: rgba(245,158,11,0.1); color: var(--warning); }

/* Staff Profile Cards */
.staff-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 20px; }
.staff-card { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); overflow: hidden; text-align: center; transition: var(--transition); }
.staff-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.staff-avatar { width: 100%; height: 200px; object-fit: cover; background: var(--gray-100); }
.staff-info { padding: 16px; }
.staff-info h4, .staff-info h3 { font-size: 15px; font-weight: 600; color: var(--gray-900); }
.staff-info .designation { font-size: 12px; color: var(--accent); font-weight: 500; margin-top: 2px; }
.staff-info .qualifications { font-size: 12px; color: var(--gray-500); margin-top: 4px; }

/* ─── Research Page ───────────────────────────────── */
.research-areas-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-bottom: 50px; }
.ra-card { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 24px; text-align: center; transition: var(--transition); }
.ra-card:hover { border-color: var(--primary); box-shadow: var(--shadow-md); }
.ra-card .ra-icon { width: 60px; height: 60px; border-radius: 50%; background: rgba(var(--primary-rgb), 0.08); color: var(--primary); display: flex; align-items: center; justify-content: center; font-size: 24px; margin: 0 auto 14px; }
.ra-card h4, .ra-card h3 { font-size: 15px; font-weight: 600; color: var(--gray-900); margin-bottom: 6px; }
.ra-card p { font-size: 13px; color: var(--gray-500); }

.pub-list { list-style: none; }
.pub-item { padding: 16px 0; border-bottom: 1px solid var(--gray-100); }
.pub-item:last-child { border-bottom: none; }
.pub-item .pub-type { display: inline-block; font-size: 10px; font-weight: 600; text-transform: uppercase; padding: 2px 8px; border-radius: 4px; margin-bottom: 6px; }
.pub-item .pub-type.journal { background: rgba(37,99,235,0.1); color: var(--info); }
.pub-item .pub-type.conference { background: rgba(22,163,74,0.1); color: var(--success); }
.pub-item .pub-type.book_chapter { background: rgba(245,158,11,0.1); color: var(--warning); }
.pub-item h4, .pub-item h3 { font-size: 14px; font-weight: 600; color: var(--gray-900); line-height: 1.4; }
.pub-item .pub-authors { font-size: 13px; color: var(--gray-500); margin-top: 3px; }
.pub-item .pub-journal { font-size: 12px; color: var(--accent); font-style: italic; margin-top: 2px; }

/* ─── Downloads Page ──────────────────────────────── */
.download-item { display: flex; align-items: center; gap: 16px; padding: 16px; border: 1px solid var(--gray-200); border-radius: var(--radius); margin-bottom: 10px; transition: var(--transition); }
.download-item:hover { border-color: var(--primary); background: var(--light); }
.download-icon { width: 44px; height: 44px; border-radius: var(--radius); background: rgba(220,38,38,0.1); color: var(--danger); display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0; }
.download-info { flex: 1; }
.download-info h4, .download-info h3 { font-size: 14px; font-weight: 600; color: var(--gray-900); }
.download-info p { font-size: 12px; color: var(--gray-500); margin-top: 2px; }
.download-meta { font-size: 12px; color: var(--gray-500); white-space: nowrap; }

/* Filter Tabs */
.filter-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }
.filter-tab { padding: 6px 16px; border-radius: 20px; font-size: 12px; font-weight: 500; border: 1px solid var(--gray-200); color: var(--gray-700); cursor: pointer; transition: var(--transition); }
.filter-tab.active, .filter-tab:hover { background: var(--primary); color: var(--white); border-color: var(--primary); }

/* ─── Gallery Page ────────────────────────────────── */
.gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
.gallery-item { position: relative; border-radius: var(--radius-lg); overflow: hidden; aspect-ratio: 4/3; cursor: pointer; }
.gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: var(--transition); }
.gallery-item:hover img { transform: scale(1.05); }
.gallery-overlay { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(transparent, rgba(0,0,0,0.7)); padding: 16px; color: var(--white); opacity: 0; transition: var(--transition); }
.gallery-item:hover .gallery-overlay { opacity: 1; }
.gallery-overlay h4, .gallery-overlay h2 { font-size: 14px; font-weight: 600; }
.gallery-overlay p { font-size: 12px; opacity: 0.8; }

/* Lightbox */
.lightbox { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.9); z-index: 9999; display: none; align-items: center; justify-content: center; }
.lightbox.active { display: flex; }
.lightbox img { max-width: 90%; max-height: 85vh; border-radius: var(--radius); }
.lightbox-close { position: absolute; top: 20px; right: 30px; color: var(--white); font-size: 30px; cursor: pointer; background: transparent; border: 2px solid transparent; border-radius: 6px; }
.lightbox-close:focus-visible { outline: none; border-color: var(--white); }

/* ─── Contact Page ────────────────────────────────── */
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; }
.contact-info-card { display: flex; gap: 14px; margin-bottom: 20px; }
.contact-info-card .ci-icon { width: 48px; height: 48px; border-radius: 50%; background: rgba(var(--primary-rgb), 0.08); color: var(--primary); display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0; }
.contact-info-card h4, .contact-info-card h3 { font-size: 14px; font-weight: 600; color: var(--gray-900); }
.contact-info-card p { font-size: 13px; color: var(--gray-500); }

/* Forms */
.form-group { margin-bottom: 16px; }
.form-group label { display: block; font-size: 13px; font-weight: 500; color: var(--gray-700); margin-bottom: 6px; }
.form-control { width: 100%; padding: 10px 14px; border: 1px solid var(--gray-200); border-radius: var(--radius); font-size: 14px; font-family: var(--font); color: var(--gray-700); transition: var(--transition); background: var(--white); }
.form-control:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.1); }
textarea.form-control { resize: vertical; min-height: 120px; }
select.form-control { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M6 8L1 3h10z' fill='%236b7280'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; padding-right: 36px; }

/* ─── News Page ───────────────────────────────────── */
.news-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 30px; }
.news-item { padding: 20px 0; border-bottom: 1px solid var(--gray-100); }
.news-item:last-child { border-bottom: none; }
.news-item .news-category { display: inline-block; font-size: 10px; font-weight: 600; text-transform: uppercase; padding: 2px 8px; border-radius: 4px; margin-bottom: 6px; background: rgba(var(--primary-rgb), 0.1); color: var(--primary); }
.news-item .news-category.urgent { background: rgba(220,38,38,0.1); color: var(--danger); }
.news-item .news-category.exam { background: rgba(245,158,11,0.1); color: var(--warning); }
.news-item h3 { font-size: 16px; font-weight: 600; color: var(--gray-900); margin-bottom: 6px; }
.news-item p { font-size: 13px; color: var(--gray-500); line-height: 1.5; }
.news-item .news-date { font-size: 12px; color: var(--gray-500); margin-top: 6px; }
.news-item .news-date i { color: var(--accent); margin-right: 4px; }

/* Events Sidebar */
.event-sidebar .event-card-full { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 18px; margin-bottom: 14px; transition: var(--transition); }
.event-sidebar .event-card-full:hover { border-color: var(--primary); }
.event-sidebar .event-card-full .ev-cat { display: inline-block; font-size: 10px; font-weight: 600; text-transform: uppercase; padding: 2px 8px; border-radius: 4px; background: rgba(var(--primary-rgb), 0.1); color: var(--primary); margin-bottom: 8px; }
.event-sidebar .event-card-full h4 { font-size: 14px; font-weight: 600; color: var(--gray-900); }
.event-sidebar .event-card-full .ev-meta { font-size: 12px; color: var(--gray-500); margin-top: 6px; }
.event-sidebar .event-card-full .ev-meta i { margin-right: 4px; color: var(--accent); }

/* ─── Alerts ──────────────────────────────────────── */
.alert { padding: 12px 18px; border-radius: var(--radius); font-size: 13px; margin-bottom: 16px; }
.alert-success { background: rgba(22,163,74,0.1); color: var(--success); border: 1px solid rgba(22,163,74,0.2); }
.alert-danger { background: rgba(220,38,38,0.1); color: var(--danger); border: 1px solid rgba(220,38,38,0.2); }
.alert-warning { background: rgba(245,158,11,0.1); color: var(--warning); border: 1px solid rgba(245,158,11,0.2); }
.alert-info { background: rgba(37,99,235,0.1); color: var(--info); border: 1px solid rgba(37,99,235,0.2); }

/* ─── Student Portal ──────────────────────────────── */
/* Login Page */
.login-page { min-height: 100vh; display: flex; }
.login-left { flex: 1; background: linear-gradient(135deg, var(--primary), var(--primary-light)); display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--white); padding: 40px; }
.login-left .logo-crest { height: 80px; margin-bottom: 20px; }
.login-left h1, .login-left h2 { font-size: 24px; font-weight: 700; margin-bottom: 8px; }
.login-left p { opacity: 0.7; font-size: 14px; }
.login-right { flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px; }
.login-box { width: 100%; max-width: 400px; }
.login-box h1, .login-box h2 { font-size: 24px; font-weight: 700; color: var(--gray-900); margin-bottom: 6px; }
.login-box p { font-size: 14px; color: var(--gray-500); margin-bottom: 24px; }
.login-box .login-btn { width: 100%; padding: 12px; background: var(--primary); color: var(--white); border: none; border-radius: var(--radius); font-size: 14px; font-weight: 600; cursor: pointer; transition: var(--transition); }
.login-box .login-btn:hover { background: var(--primary-light); }
.login-footer { text-align: center; margin-top: 16px; font-size: 13px; color: var(--gray-500); }
.login-footer a { color: var(--primary); font-weight: 500; }

/* Portal Layout */
.portal-layout { display: flex; min-height: 100vh; }
.portal-sidebar { width: 260px; background: var(--primary); color: var(--white); padding: 0; position: fixed; top: 0; left: 0; bottom: 0; overflow-y: auto; z-index: 100; }
.portal-sidebar .sidebar-header { padding: 20px; border-bottom: 1px solid rgba(255,255,255,0.1); display: flex; align-items: center; gap: 12px; }
.portal-sidebar .sidebar-header .logo-crest { height: 40px; filter: brightness(0) invert(1); }
.portal-sidebar .sidebar-header .sidebar-title { font-size: 14px; font-weight: 600; }
.portal-sidebar .sidebar-header .sidebar-sub { font-size: 11px; opacity: 0.6; }
.sidebar-nav { padding: 12px 0; }
.sidebar-nav a { display: flex; align-items: center; gap: 12px; padding: 11px 20px; font-size: 13px; color: rgba(255,255,255,0.75); transition: var(--transition); }
.sidebar-nav a:hover, .sidebar-nav a.active { background: rgba(255,255,255,0.1); color: var(--white); }
.sidebar-nav a.active { border-left: 3px solid var(--accent); }
.sidebar-nav a i { width: 18px; text-align: center; font-size: 14px; }
.sidebar-nav .nav-divider { height: 1px; background: rgba(255,255,255,0.1); margin: 10px 20px; }

/* min-width:0 is load-bearing, not tidying. .portal-content is a flex item, and
   a flex item defaults to min-width:auto, which refuses to shrink below its
   content's min-content width. A wide admin table therefore forced this column
   to the table's full width (measured: 1065px against a 500px viewport), so the
   WHOLE PAGE scrolled sideways and UX2's .table-scroll wrapper could never be
   narrower than its parent — the wrapper existed but never scrolled. That is
   exactly the symptom UX2 was built to fix, and it was silently inert until
   this was added. Verified by measuring document.scrollWidth before and after. */
.portal-content { flex: 1; min-width: 0; margin-left: 260px; background: var(--light); min-height: 100vh; }
.portal-topbar { background: var(--white); padding: 14px 24px; display: flex; justify-content: space-between; align-items: center; box-shadow: var(--shadow); position: sticky; top: 0; z-index: 50; }
/* The page title is the page's one h1 (was an h2, so no portal page had an h1 — accessibility scan 2026-10-22). */
.portal-topbar h1, .portal-topbar h2 { font-size: 18px; font-weight: 600; color: var(--gray-900); margin-right: auto; }
.portal-topbar .user-info { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.portal-topbar .user-avatar { width: 34px; height: 34px; border-radius: 50%; background: var(--primary); color: var(--white); display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 13px; position: relative; overflow: hidden; }
.portal-topbar .user-avatar img, .staff-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
/* admin/staff.php list: photo (or initials) beside each name */
.staff-name-cell { display: flex; align-items: center; gap: 10px; }
.staff-thumb { position: relative; flex: none; width: 36px; height: 36px; border-radius: 50%; overflow: hidden; background: var(--primary); color: var(--white); display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; }
.portal-main { padding: 24px; }

/* Portal mobile nav.
   The sidebar is position:fixed 260px on desktop. Its ONLY mobile rule used to
   be `width:100%; position:relative`, which stacked the whole navigation above
   the content — so on a phone every portal page opened with the brand header,
   Dashboard, nine group headers, the expanded group and three footer links, all
   of which had to be scrolled past to reach the page just requested, on every
   single navigation. Below 768px the sidebar is now off-canvas and opens from a
   toggle in the topbar. Styles live here; the behaviour is in assets/js/portal-ui.js,
   shared with the HDIT admin shell, which uses different class names. */
.sidebar-toggle {
    display: none; align-items: center; justify-content: center;
    width: 38px; height: 38px; margin-right: 12px; flex-shrink: 0;
    border: 1px solid var(--gray-200); border-radius: var(--radius);
    background: var(--white); color: var(--gray-700);
    font-size: 16px; cursor: pointer;
}
.sidebar-toggle:hover { background: var(--light); }
.sidebar-scrim {
    display: none; position: fixed; inset: 0; z-index: 99;
    background: rgba(var(--primary-rgb), 0.45); border: 0; padding: 0; cursor: pointer;
}
body.nav-locked { overflow: hidden; }

/* Dashboard Stats */
.dash-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-bottom: 24px; }
.dash-stat { background: var(--white); border-radius: var(--radius-lg); padding: 20px; border: 1px solid var(--gray-200); }
.dash-stat .ds-label { font-size: 12px; color: var(--gray-500); font-weight: 500; }
.dash-stat .ds-value { font-size: 28px; font-weight: 700; color: var(--gray-900); margin-top: 4px; }
.dash-stat .ds-icon { float: right; width: 44px; height: 44px; border-radius: var(--radius); display: flex; align-items: center; justify-content: center; font-size: 20px; }
.dash-stat .ds-icon.blue { background: rgba(37,99,235,0.1); color: var(--info); }
.dash-stat .ds-icon.amber { background: rgba(245,158,11,0.1); color: var(--warning); }
.dash-stat .ds-icon.red { background: rgba(220,38,38,0.1); color: var(--danger); }
.dash-stat .ds-icon.green { background: rgba(22,163,74,0.1); color: var(--success); }

/* Timetable */
.timetable { width: 100%; border-collapse: collapse; background: var(--white); border-radius: var(--radius-lg); overflow: hidden; }
.timetable th { background: var(--primary); color: var(--white); padding: 12px; font-size: 12px; font-weight: 600; text-transform: uppercase; }
.timetable td { padding: 12px; font-size: 13px; border-bottom: 1px solid var(--gray-100); vertical-align: top; }
.timetable tr:hover { background: var(--light); }
.tt-subject { font-weight: 600; color: var(--primary); }
.tt-venue { font-size: 11px; color: var(--gray-500); margin-top: 2px; }

/* Results Table */
.results-table { width: 100%; border-collapse: collapse; }
.results-table th { background: var(--primary); color: var(--white); padding: 10px 14px; font-size: 12px; font-weight: 600; text-align: left; }
.results-table td { padding: 10px 14px; font-size: 13px; border-bottom: 1px solid var(--gray-100); }
.results-table tr:hover { background: var(--light); }
.grade-badge { display: inline-block; padding: 2px 10px; border-radius: 4px; font-size: 12px; font-weight: 700; }
.grade-a { background: rgba(22,163,74,0.15); color: var(--success); }
.grade-b { background: rgba(37,99,235,0.15); color: var(--info); }
.grade-c { background: rgba(245,158,11,0.15); color: var(--warning); }
.grade-d { background: rgba(220,38,38,0.15); color: var(--danger); }

/* Attendance Display */
.attendance-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; }
.att-card { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 20px; }
.att-card .att-subject { font-size: 14px; font-weight: 600; color: var(--gray-900); margin-bottom: 4px; }
.att-card .att-code { font-size: 12px; color: var(--gray-500); margin-bottom: 12px; }
.att-bar { height: 8px; background: var(--gray-100); border-radius: 4px; overflow: hidden; margin-bottom: 8px; }
.att-bar-fill { height: 100%; border-radius: 4px; transition: width 0.8s ease; }
.att-bar-fill.green { background: var(--success); }
.att-bar-fill.amber { background: var(--warning); }
.att-bar-fill.red { background: var(--danger); }
.att-percent { font-size: 22px; font-weight: 700; }
.att-percent.green { color: var(--success); }
.att-percent.amber { color: var(--warning); }
.att-percent.red { color: var(--danger); }
.att-detail { font-size: 12px; color: var(--gray-500); margin-top: 4px; }
.att-status { display: inline-block; padding: 3px 10px; border-radius: 4px; font-size: 11px; font-weight: 600; margin-top: 8px; }
.att-status.eligible { background: rgba(22,163,74,0.1); color: var(--success); }
.att-status.warning { background: rgba(245,158,11,0.1); color: var(--warning); }
.att-status.ineligible { background: rgba(220,38,38,0.1); color: var(--danger); }

/* Registration Steps */
.reg-steps { display: flex; align-items: center; gap: 0; margin-bottom: 30px; }
.reg-step { display: flex; align-items: center; gap: 8px; padding: 10px 20px; font-size: 13px; font-weight: 500; color: var(--gray-500); }
.reg-step.active { color: var(--primary); font-weight: 600; }
.reg-step .step-num { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; border: 2px solid var(--gray-300); }
.reg-step.active .step-num { background: var(--primary); color: var(--white); border-color: var(--primary); }
.reg-step-line { flex: 1; height: 2px; background: var(--gray-200); }

/* Checkbox Table */
.check-table { width: 100%; border-collapse: collapse; }
.check-table th { text-align: left; padding: 10px 14px; font-size: 12px; font-weight: 600; background: var(--light); color: var(--gray-700); }
.check-table td { padding: 10px 14px; font-size: 13px; border-bottom: 1px solid var(--gray-100); }
.check-table input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--primary); cursor: pointer; }

/* ─── Admin Panel ─────────────────────────────────── */
.admin-table { width: 100%; border-collapse: collapse; background: var(--white); border-radius: var(--radius-lg); overflow: hidden; }
.admin-table th { background: var(--light); padding: 12px 16px; font-size: 12px; font-weight: 600; text-align: left; color: var(--gray-700); text-transform: uppercase; letter-spacing: 0.5px; }
.admin-table td { padding: 12px 16px; font-size: 13px; border-bottom: 1px solid var(--gray-100); }
.admin-table tr:hover { background: var(--light); }
.status-badge { display: inline-block; padding: 3px 10px; border-radius: 20px; font-size: 11px; font-weight: 600; }
.status-badge.pending { background: rgba(245,158,11,0.15); color: var(--warning); }
.status-badge.approved { background: rgba(22,163,74,0.15); color: var(--success); }
.status-badge.rejected { background: rgba(220,38,38,0.15); color: var(--danger); }
.status-badge.new { background: rgba(37,99,235,0.15); color: var(--info); }
.status-badge.published { background: rgba(22,163,74,0.15); color: var(--success); }

.action-btns { display: flex; gap: 6px; }
/* 55 cells on 32 pages put the class on the <td> itself. A flex <td> stops being a table cell: its
   border no longer lines up with the row and its buttons can spill past the card (seen on
   students.php, Session 53). Keep the cell a cell and lay the buttons out inline instead. */
td.action-btns { display: table-cell; white-space: nowrap; vertical-align: middle; }
td.action-btns > * { vertical-align: middle; }
td.action-btns > form { display: inline-block; margin: 0; }
td.action-btns > * + * { margin-left: 2px; }
td.action-btns .action-btn { display: inline-flex; }   /* block-level flex would stack them */
.action-btn { width: 30px; height: 30px; border-radius: var(--radius); display: flex; align-items: center; justify-content: center; font-size: 12px; transition: var(--transition); }
.action-btn.edit { background: rgba(37,99,235,0.1); color: var(--info); }
.action-btn.delete { background: rgba(220,38,38,0.1); color: var(--danger); }
.action-btn.approve { background: rgba(22,163,74,0.1); color: var(--success); }
.action-btn:hover { opacity: 0.8; }

/* Admin Attendance Entry */
.att-entry-grid { display: grid; grid-template-columns: auto 1fr; gap: 16px; align-items: center; }
.att-entry-table { width: 100%; border-collapse: collapse; }
.att-entry-table th { padding: 10px 14px; font-size: 12px; font-weight: 600; background: var(--light); text-align: left; }
.att-entry-table td { padding: 10px 14px; font-size: 13px; border-bottom: 1px solid var(--gray-100); }
.att-entry-table .att-radio { display: flex; gap: 12px; }
.att-entry-table .att-radio label { display: flex; align-items: center; gap: 4px; font-size: 12px; cursor: pointer; }

/* ─── Footer ──────────────────────────────────────── */
.footer { background: var(--primary-dark); color: rgba(255,255,255,0.8); padding: 50px 0 0; }
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: 30px; }
.footer-about { }
.footer-about .logo { margin-bottom: 14px; }
.footer-about .logo .logo-text .name { color: var(--white); }
.footer-about .logo .logo-text .sub { color: rgba(255,255,255,0.5); }
.footer-about p { font-size: 13px; line-height: 1.7; opacity: 0.7; }
.footer-col h4, .footer-col h2 { font-size: 15px; font-weight: 600; color: var(--white); margin-bottom: 16px; position: relative; padding-bottom: 10px; }
.footer-col h4::after, .footer-col h2::after { content: ''; position: absolute; bottom: 0; left: 0; width: 30px; height: 2px; background: var(--accent); }
.footer-col ul li { margin-bottom: 8px; }
.footer-col ul li a { font-size: 13px; opacity: 0.7; transition: var(--transition); }
.footer-col ul li a:hover { opacity: 1; color: var(--accent); padding-left: 4px; }
.contact-list li { display: flex; gap: 10px; font-size: 13px; opacity: 0.7; }
.contact-list li i { color: var(--accent); margin-top: 3px; }
.footer-social { display: flex; gap: 10px; margin-bottom: 20px; }
.footer-social a { width: 36px; height: 36px; border-radius: 50%; border: 1px solid rgba(255,255,255,0.2); display: flex; align-items: center; justify-content: center; font-size: 14px; color: rgba(255,255,255,0.7); transition: var(--transition); }
.footer-social a:hover { background: var(--accent); border-color: var(--accent); color: var(--white); }
.footer-uni-names { margin-top: 10px; }
.footer-uni-names small { font-size: 12px; line-height: 1.7; opacity: 0.5; }
.footer-bottom { text-align: center; padding: 18px 0; margin-top: 30px; border-top: 1px solid rgba(255,255,255,0.1); }
.footer-bottom p { font-size: 12px; opacity: 0.5; }

/* ─── Utility ─────────────────────────────────────── */
.text-center { text-align: center; }
.text-muted { color: var(--gray-500); }
.text-success { color: var(--success); }
.text-danger { color: var(--danger); }
.text-warning { color: var(--warning); }
.text-primary { color: var(--primary); }
.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: 8px; }
.mb-2 { margin-bottom: 16px; }
.mb-3 { margin-bottom: 24px; }
.mt-2 { margin-top: 16px; }
.mt-3 { margin-top: 24px; }
.d-flex { display: flex; }
.gap-2 { gap: 16px; }
.flex-1 { flex: 1; }
.empty-state { text-align: center; padding: 40px; color: var(--gray-500); }
.empty-state i { font-size: 40px; margin-bottom: 12px; display: block; opacity: 0.3; }

/* ─── Responsive ──────────────────────────────────── */
@media (max-width: 992px) {
    .home-grid { grid-template-columns: 1fr; }
    .qa-grid { grid-template-columns: repeat(3, 1fr); }
    .about-grid { grid-template-columns: 1fr; }
    .contact-grid { grid-template-columns: 1fr; }
    .news-grid { grid-template-columns: 1fr; }
    .research-areas-grid { grid-template-columns: repeat(2, 1fr); }
    .footer-grid { grid-template-columns: 1fr 1fr; }
    .stats-grid { grid-template-columns: repeat(2, 1fr); }
    .research-spotlight { grid-template-columns: 1fr; }
}

/* Portal / VLE links duplicated into the phone menu (the top bar is hidden there). */
.nav-mobile-only { display: none; }

@media (max-width: 768px) {
    .top-bar { display: none; }
    .nav-mobile-only { display: block; }
    .nav-mobile-first { border-top: 1px solid var(--gray-200); margin-top: 8px; padding-top: 8px; }
    .nav-toggle { display: flex; }
    .nav-menu { position: fixed; top: 0; right: -100%; width: 280px; height: 100vh; overflow-y: auto; background: var(--white); flex-direction: column; padding: 60px 0 20px; box-shadow: var(--shadow-lg); transition: var(--transition); z-index: 1000; }
    .nav-menu.active { right: 0; }
    .nav-menu > li > a { padding: 14px 24px; }
    .nav-menu > li > a.active::after { display: none; }
    .dropdown { position: static; box-shadow: none; opacity: 1; visibility: visible; transform: none; background: var(--light); }
    .dropdown li a { padding-left: 36px; }
    .hero h1 { font-size: 28px; }
    .hero { padding: 50px 0 80px; }
    .qa-grid { grid-template-columns: repeat(2, 1fr); }
    .qa-item:nth-child(5) { grid-column: span 2; }
    .vision-mission { grid-template-columns: 1fr; }
    .research-areas-grid { grid-template-columns: 1fr; }
    .semester-tabs { overflow-x: auto; flex-wrap: nowrap; }
    .footer-grid { grid-template-columns: 1fr; }

    /* Portal Mobile */
    .login-page { flex-direction: column; }
    .login-left { padding: 30px; min-height: auto; }

    /* Off-canvas sidebar — see the note by .sidebar-toggle above. */
    .portal-sidebar {
        width: 264px; height: auto;
        position: fixed; top: 0; left: 0; bottom: 0;
        transform: translateX(-100%);
        transition: transform 0.24s ease;
        box-shadow: 4px 0 24px rgba(0, 0, 0, 0.18);
    }
    .portal-layout.sidebar-open .portal-sidebar { transform: translateX(0); }
    .portal-layout.sidebar-open .sidebar-scrim { display: block; }
    .portal-content { margin-left: 0; }
    .sidebar-toggle { display: inline-flex; }
    .portal-topbar { padding: 12px 16px; }
    .portal-main { padding: 16px; }
}

@media (prefers-reduced-motion: reduce) {
    .portal-sidebar { transition: none; }
}

@media (max-width: 480px) {
    .hero h1 { font-size: 24px; }
    .hero-buttons { flex-direction: column; }
    .qa-grid { grid-template-columns: 1fr 1fr; }
    .qa-item:nth-child(5) { grid-column: span 2; }
    .stats-grid { grid-template-columns: 1fr 1fr; }
    .page-banner h1 { font-size: 24px; }
    .dash-stats { grid-template-columns: 1fr 1fr; }
}

/* ============================================================
   DMIT REDESIGN v2 — Enhanced Styles
   ============================================================ */

/* ─── Hero v2 ─────────────────────────────────────── */
.hero { padding: 90px 0 120px; background: linear-gradient(140deg, var(--primary-dark) 0%, var(--primary) 40%, var(--primary-light) 100%); }
.hero::before { width: 55%; opacity: 1; }
.hero-content { max-width: 640px; }
.hero h1 { font-size: 46px; letter-spacing: -0.5px; }
.hero h1 span { display: inline-block; position: relative; }
.hero h1 span::after { content: ''; position: absolute; bottom: 2px; left: 0; right: 0; height: 4px; background: var(--accent); border-radius: 2px; }
.hero-badge { backdrop-filter: blur(8px); }
.hero-buttons .btn { padding: 14px 32px; border-radius: var(--radius-lg); font-size: 15px; }

/* ─── Quick Access v2 ─────────────────────────────── */
.qa-grid { border-radius: var(--radius-lg); }
.qa-item { padding: 30px 16px; }
.qa-item .qa-icon { width: 56px; height: 56px; border-radius: var(--radius-lg); font-size: 22px; background: linear-gradient(135deg, rgba(var(--primary-rgb), 0.08), rgba(var(--primary-rgb), 0.04)); }
.qa-item:hover .qa-icon { background: rgba(255,255,255,0.25); transform: scale(1.08); transition: var(--transition); }
.qa-item .qa-title { font-size: 14px; }

/* ─── Programme Highlights v2 (icon card grid) ────── */
.highlights-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.highlight-card { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 24px 20px; text-align: center; transition: var(--transition); position: relative; overflow: hidden; }
.highlight-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--accent); transform: scaleX(0); transition: transform 0.3s ease; }
.highlight-card:hover::before { transform: scaleX(1); }
.highlight-card:hover { box-shadow: var(--shadow-md); transform: translateY(-3px); }
.highlight-card .hc-icon { width: 52px; height: 52px; border-radius: 50%; background: linear-gradient(135deg, rgba(var(--primary-rgb), 0.1), rgba(var(--primary-rgb), 0.04)); color: var(--primary); display: flex; align-items: center; justify-content: center; font-size: 22px; margin: 0 auto 12px; }
.highlight-card h4, .highlight-card h3 { font-size: 14px; font-weight: 600; color: var(--gray-900); margin-bottom: 4px; }
.highlight-card p { font-size: 12px; color: var(--gray-500); line-height: 1.5; }

/* ─── Announcements v2 (card style) ───────────────── */
.ann-card-v2 { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 18px; margin-bottom: 12px; transition: var(--transition); position: relative; }
.ann-card-v2:hover { border-color: var(--primary); box-shadow: var(--shadow); }
.ann-card-v2.pinned { border-left: 4px solid var(--accent); }
.ann-card-v2 .ann-cat { display: inline-block; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; padding: 3px 10px; border-radius: 4px; margin-bottom: 8px; }
.ann-cat.general { background: rgba(var(--primary-rgb), 0.08); color: var(--primary); }
.ann-cat.academic { background: rgba(37,99,235,0.1); color: var(--info); }
.ann-cat.exam { background: rgba(245,158,11,0.1); color: var(--warning); }
.ann-cat.urgent { background: rgba(220,38,38,0.1); color: var(--danger); }
.ann-card-v2 h4, .ann-card-v2 h3 { font-size: 14px; font-weight: 600; color: var(--gray-900); margin-bottom: 6px; line-height: 1.4; }
.ann-card-v2 p { font-size: 12px; color: var(--gray-500); line-height: 1.5; margin-bottom: 8px; }
.ann-card-v2 .ann-meta { display: flex; align-items: center; gap: 14px; font-size: 11px; color: var(--gray-500); }
.ann-card-v2 .ann-meta i { color: var(--accent); margin-right: 3px; }

/* ─── Events v2 (timeline style) ──────────────────── */
.event-card-v2 { display: flex; gap: 16px; background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 20px; margin-bottom: 14px; transition: var(--transition); }
.event-card-v2:hover { border-color: var(--primary); box-shadow: var(--shadow); transform: translateX(4px); }
.event-date-v2 { text-align: center; flex-shrink: 0; background: linear-gradient(135deg, var(--primary), var(--primary-light)); border-radius: var(--radius); padding: 12px 16px; min-width: 64px; color: var(--white); }
.event-date-v2 .day { font-size: 26px; font-weight: 700; line-height: 1; }
.event-date-v2 .month { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 1px; opacity: 0.9; }
.event-info-v2 h4, .event-info-v2 h3 { font-size: 15px; font-weight: 600; color: var(--gray-900); margin-bottom: 4px; }
.event-info-v2 p { font-size: 12px; color: var(--gray-500); margin-bottom: 8px; line-height: 1.5; }
.event-info-v2 .ev-details { display: flex; gap: 16px; flex-wrap: wrap; }
.event-info-v2 .ev-detail { font-size: 12px; color: var(--gray-500); display: flex; align-items: center; gap: 4px; }
.event-info-v2 .ev-detail i { color: var(--accent); font-size: 11px; }
.event-info-v2 .ev-cat-badge, .detail-facts .ev-cat-badge { display: inline-block; font-size: 10px; font-weight: 600; text-transform: uppercase; padding: 2px 8px; border-radius: 4px; background: rgba(var(--primary-rgb), 0.08); color: var(--primary); margin-bottom: 6px; }

/* ─── Stats Bar v2 (counter cards) ────────────────── */
.stats-bar { background: linear-gradient(135deg, var(--primary-dark), var(--primary)); padding: 40px 0; }
.stat-item { position: relative; }
.stat-item::after { content: ''; position: absolute; right: 0; top: 50%; transform: translateY(-50%); height: 40px; width: 1px; background: rgba(255,255,255,0.15); }
.stats-grid > .stat-item:last-child::after { display: none; }
.stat-item .stat-icon { width: 50px; height: 50px; border-radius: 50%; background: rgba(212,168,67,0.2); display: flex; align-items: center; justify-content: center; margin-bottom: 10px; }

/* ─── Staff Profiles v2 ──────────────────────────── */
.staff-tabs { display: flex; gap: 0; margin-bottom: 30px; border-bottom: 2px solid var(--gray-200); }
.staff-tab { padding: 12px 28px; font-size: 14px; font-weight: 600; color: var(--gray-500); cursor: pointer; border-bottom: 3px solid transparent; margin-bottom: -2px; transition: var(--transition); }
.staff-tab.active, .staff-tab:hover { color: var(--primary); border-bottom-color: var(--accent); }
.staff-content { display: none; }
.staff-content.active { display: block; }

.staff-card-v2 { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); overflow: hidden; transition: var(--transition); }
.staff-card-v2:hover { box-shadow: var(--shadow-lg); transform: translateY(-4px); }
.staff-card-v2 .staff-photo { width: 100%; height: 220px; object-fit: cover; background: var(--gray-100); }
/* Staff photo area — initials sit centered behind an overlaid photo;
   the <img> removes itself on error, revealing the initials fallback.
   This keeps the markup valid (no unclosed divs) so the grid stays intact. */
.staff-photo-wrap { position: relative; height: 220px; background: var(--gray-100); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.staff-photo-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.staff-initials { width: 90px; height: 90px; border-radius: 50%; background: var(--primary); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 32px; font-weight: 700; }
.staff-photo-wrap.support .staff-initials { background: var(--accent); }
.staff-card-v2 .staff-body { padding: 18px; }
.staff-card-v2 h4, .staff-card-v2 h3 { font-size: 16px; font-weight: 600; color: var(--gray-900); margin-bottom: 2px; }
.staff-card-v2 .staff-desig { font-size: 13px; font-weight: 500; color: var(--accent); margin-bottom: 4px; }
.staff-card-v2 .staff-qual { font-size: 12px; color: var(--gray-500); margin-bottom: 10px; line-height: 1.5; }
.staff-card-v2 .staff-email { font-size: 12px; color: var(--primary); display: flex; align-items: center; gap: 4px; margin-bottom: 12px; }
.staff-social-links { display: flex; gap: 8px; border-top: 1px solid var(--gray-100); padding-top: 12px; }
.staff-social-links a { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 14px; transition: var(--transition); }
.staff-social-links a.linkedin { background: rgba(0,119,181,0.1); color: #0077b5; }
.staff-social-links a.linkedin:hover { background: #0077b5; color: var(--white); }
.staff-social-links a.scholar { background: rgba(66,133,244,0.1); color: #4285F4; }
.staff-social-links a.scholar:hover { background: #4285F4; color: var(--white); }
.staff-social-links a.rgate { background: rgba(0,204,187,0.1); color: #00CCBB; }
.staff-social-links a.rgate:hover { background: #00CCBB; color: var(--white); }
.staff-social-links a.cv-link { background: rgba(220,38,38,0.1); color: var(--danger); }
.staff-social-links a.cv-link:hover { background: var(--danger); color: var(--white); }

/* ─── IT Lab Page ─────────────────────────────────── */
.lab-hero { background: linear-gradient(135deg, var(--primary-dark) 0%, #1a2a5e 100%); padding: 60px 0; color: var(--white); }
.lab-hero-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: center; }
.lab-hero h2 { font-size: 32px; font-weight: 700; margin-bottom: 12px; }
.lab-hero p { opacity: 0.8; margin-bottom: 20px; }
.lab-features { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 40px 0; }
.lab-feature { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 24px; text-align: center; transition: var(--transition); }
.lab-feature:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.lab-feature .lf-icon { width: 56px; height: 56px; border-radius: 50%; background: rgba(var(--primary-rgb), 0.08); color: var(--primary); display: flex; align-items: center; justify-content: center; font-size: 24px; margin: 0 auto 12px; }
.lab-feature h4, .lab-feature h3 { font-size: 14px; font-weight: 600; color: var(--gray-900); margin-bottom: 4px; }
.lab-feature p { font-size: 12px; color: var(--gray-500); }
.lab-booking { background: var(--light); border: 2px dashed var(--accent); border-radius: var(--radius-lg); padding: 30px; text-align: center; }
.lab-booking h3 { font-size: 20px; color: var(--primary); margin-bottom: 8px; }
.lab-booking p { color: var(--gray-500); margin-bottom: 16px; }

/* ─── News Page v2 ────────────────────────────────── */
.news-featured { background: linear-gradient(135deg, var(--primary), var(--primary-light)); border-radius: var(--radius-lg); padding: 30px; color: var(--white); margin-bottom: 30px; }
.news-featured .nf-badge { display: inline-block; background: rgba(255,255,255,0.2); padding: 4px 14px; border-radius: 20px; font-size: 11px; font-weight: 600; margin-bottom: 12px; }
.news-featured h2 { font-size: 24px; margin-bottom: 8px; }
.news-featured p { opacity: 0.85; font-size: 14px; line-height: 1.6; }

/* ─── Home 2-col layout for ann + events ──────────── */
.home-ann-events { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; margin-bottom: 50px; }

/* ─── Research cards animated border ──────────────── */
.research-card { position: relative; }
.research-card::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 3px; background: linear-gradient(90deg, var(--primary), var(--accent)); transform: scaleX(0); transform-origin: left; transition: transform 0.4s ease; }
.research-card:hover::before { transform: scaleX(1); }

/* ─── Responsive additions ────────────────────────── */
@media (max-width: 992px) {
    .highlights-grid { grid-template-columns: repeat(2, 1fr); }
    .home-ann-events { grid-template-columns: 1fr; }
    .lab-hero-grid { grid-template-columns: 1fr; }
    .lab-features { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
    .hero h1 { font-size: 30px; }
    .highlights-grid { grid-template-columns: 1fr 1fr; }
    .lab-features { grid-template-columns: 1fr; }
    .staff-tabs { overflow-x: auto; }
}
@media (max-width: 480px) {
    .highlights-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   v3 — HDIT-style compact homepage + real photos
   ============================================================ */

/* ─── Hero with real photo ────────────────────────── */
.hero { position: relative; overflow: hidden; padding: 80px 0 110px; background: var(--primary-dark); }
.hero::before, .hero::after { display: none; }
.hero-bg-wrap { position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 0; }
.hero-bg-gradient { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(100deg, rgba(var(--primary-rgb), 0.88) 0%, rgba(var(--primary-rgb), 0.60) 40%, rgba(var(--primary-rgb), 0.18) 70%, rgba(var(--primary-rgb), 0.05) 100%); z-index: 1; }
/* Home hero photo (2026-10-23): the image itself fades to dark navy on its left, so it spans the whole
   hero, anchored right where the people are; the gradient above keeps the white text readable. */
.hero-bg-photo { width: 100%; object-position: right center; }
@media (max-width: 768px) {
    /* On a phone the text sits over the photo: a stronger, even tint instead of the left-only fade. */
    .hero-bg-photo { opacity: 1; object-position: 70% center; }
    .hero-bg-wrap:has(.hero-bg-photo) .hero-bg-gradient { background: linear-gradient(180deg, rgba(var(--primary-rgb), 0.82) 0%, rgba(var(--primary-rgb), 0.72) 100%); }
}

/* ─── 3-Column Home Grid (HDIT style) ─────────────── */
.home-grid-3col { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 24px; }
.home-col { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 20px; }
.home-col .section-title-flex { margin-bottom: 14px; padding-bottom: 10px; border-bottom: 2px solid var(--gray-100); }
.home-col .section-title-flex h3 { font-size: 16px; font-weight: 700; color: var(--gray-900); }

/* Home announcement items */
.home-ann-item { display: flex; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--gray-100); }
.home-ann-item:last-child { border-bottom: none; }
.home-ann-item .hai-icon { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; flex-shrink: 0; }
.home-ann-item .hai-icon.general { background: rgba(var(--primary-rgb), 0.1); color: var(--primary); }
.home-ann-item .hai-icon.academic { background: rgba(37,99,235,0.1); color: var(--info); }
.home-ann-item .hai-icon.exam { background: rgba(245,158,11,0.1); color: var(--warning); }
.home-ann-item .hai-icon.urgent { background: rgba(220,38,38,0.1); color: var(--danger); }
.home-ann-item h4, .home-ann-item h3 { font-size: 13px; font-weight: 600; color: var(--gray-900); line-height: 1.35; }
.home-ann-item .hai-date { font-size: 11px; color: var(--gray-500); }

/* Home event items */
.home-event-item { display: flex; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--gray-100); }
.home-event-item:last-child { border-bottom: none; }
.hei-date { text-align: center; flex-shrink: 0; background: var(--light); border-radius: var(--radius); padding: 6px 10px; min-width: 50px; }
.hei-day { display: block; font-size: 20px; font-weight: 700; color: var(--primary); line-height: 1; }
.hei-month { display: block; font-size: 10px; font-weight: 600; color: var(--accent); text-transform: uppercase; margin-top: 2px; }
.home-event-item h4, .home-event-item h3 { font-size: 13px; font-weight: 600; color: var(--gray-900); line-height: 1.35; }
.hei-meta { display: block; font-size: 11px; color: var(--gray-500); margin-top: 2px; }
.hei-meta i { color: var(--accent); margin-right: 3px; font-size: 10px; }

/* Home highlight items */
.home-hl-item { display: flex; align-items: center; gap: 8px; padding: 8px 0; }
.home-hl-item i { color: var(--success); font-size: 14px; flex-shrink: 0; }
.home-hl-item span { font-size: 13px; color: var(--gray-700); }

/* ─── Image Feature Strip ─────────────────────────── */
.img-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.img-strip-item { position: relative; border-radius: var(--radius-lg); overflow: hidden; aspect-ratio: 16/10; }
.img-strip-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s ease; }
.img-strip-item:hover img { transform: scale(1.08); }
.img-strip-label { position: absolute; bottom: 0; left: 0; right: 0; background: linear-gradient(transparent, rgba(0,0,0,0.75)); color: var(--white); padding: 20px 14px 12px; font-size: 13px; font-weight: 600; }

/* ─── Responsive for 3-col ────────────────────────── */
@media (max-width: 992px) { .home-grid-3col { grid-template-columns: 1fr; } .img-strip { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .img-strip { grid-template-columns: 1fr; } }

/* ============================================================
   v4 — HOD sidebar + layout refinements
   ============================================================ */

/* Main layout with HOD sidebar */
.home-main-layout { display: grid; grid-template-columns: 1fr 280px; gap: 24px; align-items: start; }

/* HOD Card */
.hod-sidebar { position: sticky; top: 80px; }
.hod-card { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow); }
.hod-card-header { background: var(--primary); color: var(--white); text-align: center; padding: 12px 16px; font-size: 14px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; border-bottom: 3px solid var(--accent); }
.hod-photo-wrap { text-align: center; padding: 20px 20px 0; }
.hod-photo { width: 140px; height: 160px; object-fit: cover; border-radius: var(--radius); border: 3px solid var(--gray-200); background: var(--gray-100); }
.hod-info { padding: 16px 20px 20px; text-align: center; }
.hod-info h3 { font-size: 16px; font-weight: 700; color: var(--gray-900); margin-bottom: 2px; }
.hod-desig { font-size: 12px; font-weight: 600; color: var(--accent); margin-bottom: 4px; }
.hod-qual { font-size: 11px; color: var(--gray-500); margin-bottom: 14px; }
.hod-contacts { text-align: left; border-top: 1px solid var(--gray-100); padding-top: 12px; }
.hod-contact { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--gray-700); margin-bottom: 8px; }
.hod-contact i { width: 16px; text-align: center; color: var(--primary); font-size: 12px; }
.hod-contact span { word-break: break-all; }
.hod-links { display: flex; justify-content: center; gap: 8px; border-top: 1px solid var(--gray-100); padding-top: 12px; margin-top: 4px; }
.hod-links a { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 14px; transition: var(--transition); background: var(--light); color: var(--primary); }
.hod-links a:hover { background: var(--primary); color: var(--white); }

/* Responsive */
@media (max-width: 1100px) {
    .home-main-layout { grid-template-columns: 1fr 240px; gap: 16px; }
}
@media (max-width: 992px) {
    .home-main-layout { grid-template-columns: 1fr; }
    .hod-sidebar { position: static; }
    .hod-card { max-width: 320px; margin: 0 auto; }
    .home-grid-3col { grid-template-columns: 1fr; }
}

/* ── Shared list-page search bar + result summary ────────────────────────────
   Used by includes/list_filter.php. Replaces the per-page inline-styled search
   forms so every admin list reads the same way. Sticky table headers are here
   too: they apply to every long admin list and were the cheapest fix in the UI
   audit. */
.list-filter {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    align-items: flex-end;
    margin: 0 0 14px;
}
.list-filter-field { flex: 1; min-width: 220px; }
.list-filter-field label {
    display: block;
    font-size: 12px;
    font-weight: 600;
    color: var(--gray-700);
    margin-bottom: 4px;
}
.list-summary {
    font-size: 12px;
    color: var(--gray-500);
    margin: 0 0 12px;
}
.list-summary strong { color: var(--gray-700); }
/* The capped-list note is the whole point of the summary — a page showing the
   newest 50 of 1,284 must not look like a page with only 50 records. */
.list-summary-note { color: var(--warning); font-weight: 600; }

/* Pager rendered by listPager(). Classes rather than the inline styles the two
   hand-rolled pagers used, so the look is changed in one place (UX8). */
.list-pager {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 8px;
    margin-top: 20px;
    flex-wrap: wrap;
}
.list-pager-status {
    font-size: 13px;
    color: var(--gray-500);
    padding: 0 8px;
}
.list-pager-status strong { color: var(--gray-700); }

.admin-table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--light);
}
/* Pinned first column for wide data-entry grids (marks, CA marks — Session 53): when the grid
   scrolls sideways the student stays in view. Needs an opaque background or cells slide under it. */
.admin-table .col-pin { position: sticky; left: 0; z-index: 1; background: var(--white); box-shadow: 1px 0 0 var(--gray-200); min-width: 150px; max-width: 220px; }
.admin-table thead th.col-pin { z-index: 3; background: var(--light); }
/* Crowded list tables (students, staff): a little less cell padding (16 → 10px a side). */
.admin-table.table-dense th, .admin-table.table-dense td { padding-left: 10px; padding-right: 10px; }
/* Marks grids: one column per question/component, mostly cell padding — halve it. */
.admin-table.grid-compact th, .admin-table.grid-compact td { padding: 8px 8px; }
/* .admin-table clips (overflow:hidden, for its rounded corners), which made the TABLE the sticky
   column's scroll frame — so .col-pin never pinned. These grids give up the clip instead. */
.admin-table.grid-compact { overflow: visible; }
.admin-table.grid-compact .form-control { padding-left: 6px; padding-right: 4px; }

/* ── Wide-table scroll containers (UX2) ──────────────────────────────────────
   assets/js/portal-ui.js wraps every unwrapped table in .portal-main / .h-body
   at runtime, so these rules have no markup to edit — they apply everywhere at
   once. ~84 of the 127 portal tables had no overflow container and dragged the
   whole page sideways on a phone, which breaks the sticky topbar and reads as a
   broken layout rather than a cramped one. */
.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* Give the sticky thead something to stick to without clipping it. */
    overflow-y: visible;
}
/* .admin-table is width:100%, which inside a scroll container means the table
   compresses to fit and NEVER scrolls — an 11-column table just squashes. So on
   phone widths the table is allowed to size to its content and overflow; the
   container scrolls instead. Desktop keeps width:100% so nothing about the
   existing layout changes. */
.table-scroll > table { min-width: 100%; }
@media (max-width: 768px) {
    .table-scroll > table { width: auto; }
}
/* The wrapper is tabindex="0" so it can be scrolled from the keyboard, which
   means it must show focus. Only the second :focus-visible rule in this
   stylesheet — see UX4 in docs/IMPROVEMENT_REVIEW.md. */
.table-scroll:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* ── Busy state on submit (UX3 + F2) ─────────────────────────────────────────
   A disabled button IS the loading state, so one mechanism covers both "no
   feedback during long operations" and double-submit protection. See the
   comment in portal-ui.js for why the control is disabled on a deferred tick
   rather than immediately. */
.is-busy {
    position: relative;
    color: transparent !important;
    pointer-events: none;
}
.is-busy::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 14px;
    height: 14px;
    margin: -7px 0 0 -7px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    color: var(--white);
    animation: busy-spin 0.6s linear infinite;
}
@keyframes busy-spin { to { transform: rotate(360deg); } }
/* Every other control in the form is disabled too, so it must look it. */
.portal-main button:disabled,
.portal-main input[type="submit"]:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

@media (prefers-reduced-motion: reduce) {
    .is-busy::after { animation-duration: 2.4s; }
}


/* ─── UX4 · Visible keyboard focus ──────────────────────────────────────────
   Before this there were exactly two :focus-visible rules in the whole
   stylesheet, both narrow (.lightbox-close, .table-scroll) — so tabbing through
   a form or the nav showed nothing at all in browsers that suppress the default
   ring once a stylesheet touches outline.

   It matters most on the marks grids, which are keyboard-driven by design: an
   operator tabs across question columns and types. With no ring, glancing away
   loses your place in a 10-column row, which is exactly how a mark gets typed
   into the wrong cell.

   :where() keeps specificity at 0, so any component rule still overrides this
   without needing !important — the two existing rules above continue to win.
   :focus-visible (not :focus) means a mouse click does not draw a ring. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
    border-radius: 3px;
}

/* .form-control:focus and .rte-editor:focus both set `outline: none` and have
   specificity (0,2,0), so they beat the :where() rule above — which is the
   trap in using :where() for an accessibility baseline. Measured in Chrome:
   every input and select on every admin page reported outline-style:none while
   :focus-visible genuinely matched. These restore the ring for KEYBOARD focus
   only, so the soft box-shadow look on a mouse click is unchanged. */
.form-control:focus-visible,
.rte-editor:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* On the dark sidebar the navy ring is invisible against navy. */
:where(.portal-sidebar, .sidebar-nav) :where(a, button, summary):focus-visible {
    outline-color: var(--accent);
}

/* The marks grid gets more than a ring: the whole cell lifts, so the current
   position is findable from across a desk rather than by hunting for a 2px
   outline in a dense table. */
.marks-grid input:focus-visible,
table input[type="number"]:focus-visible,
table input[type="text"]:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 0;
    background: #fffbea;
    box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.12);
}

/* ─── UX6 · Reduced motion ──────────────────────────────────────────────────
   var(--transition) is applied to 35 selectors and `transition:` appears 42
   times, but only two narrow reduced-motion rules existed (the sidebar drawer
   and the busy spinner). For someone with vestibular sensitivity the setting is
   an accessibility need, not a preference, so this covers everything in one
   place instead of per-component.

   Durations are near-zero rather than `none` so that transitionend/animationend
   listeners still fire — setting them to none can leave JS waiting forever for
   an event that never arrives. */
@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;
    }
}

/* The [hidden] attribute is only `display:none` in the UA stylesheet, so ANY
   author rule with a class selector beats it — `.sidebar-nav a { display:flex }`
   silently did exactly that, and the nav filter below set a.hidden on every
   non-matching link while all of them stayed on screen. Eleven passing tests
   missed it because they asserted the .hidden PROPERTY; a screenshot caught it
   in one look. With 74 `display:` declarations in this file, make the attribute
   mean what it says rather than fixing it per component. */
/* UX9 · runtime empty state for data tables. See portal-ui.js section 5:
   28 of 109 table pages rendered a bare <thead> with nothing beneath it, which
   reads as a broken page rather than an empty one. */
.table-empty {
    padding: 22px 16px;
    text-align: center;
    color: var(--gray-500);
    font-size: 13px;
    font-style: italic;
}

[hidden] { display: none !important; }

/* ─── F8 · Nav quick-jump filter ────────────────────────────────────────────
   One input at the top of the sidebar that filters the nav labels live. The
   groups fixed scanning; this fixes depth — nine collapsible groups over ~35
   destinations still means open-the-group-then-find without it. */
.nav-filter-wrap { padding: 10px 16px 6px; }
.nav-filter {
    width: 100%;
    box-sizing: border-box;
    padding: 7px 10px;
    font-size: 12.5px;
    color: var(--white);
    background: rgba(255, 255, 255, 0.10);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 6px;
}
.nav-filter::placeholder { color: rgba(255, 255, 255, 0.55); }
.nav-filter:focus { background: rgba(255, 255, 255, 0.16); border-color: var(--accent); }
/* The sidebar is dark, so the global navy ring would vanish here. */
.nav-filter:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nav-filter-empty {
    padding: 8px 20px;
    font-size: 12px;
    color: rgba(255, 255, 255, 0.55);
    font-style: italic;
}

/* ── Print ───────────────────────────────────────────────────────────────────
   REQUIRED, not cosmetic. This system prints heavily — result sheets,
   transcripts, admission cards, allocation letters — and a table inside an
   overflow container prints clipped, silently losing the columns that are
   scrolled out of view. Must stay in step with the same rule in
   public/hdit/auth.php's inline <style>. */
@media print {
    .table-scroll {
        overflow: visible !important;
    }
    .table-scroll > table { width: 100% !important; min-width: 0 !important; }
    /* Sticky headers repeat oddly or float over rows when paginated on paper. */
    .admin-table thead th { position: static; }
    .admin-table .col-pin { position: static; box-shadow: none; }
    .sidebar-toggle, .sidebar-scrim, .portal-sidebar { display: none !important; }

    /* Hiding the sidebar is not enough on its own: .portal-content carries
       margin-left:260px to clear it, so without this every page printed with a
       dead 26%-wide strip down the left and lost its right-hand columns off the
       page. Seen by rendering the print stylesheet on screen, not inferred.
       Pages with their own print CSS (staff/my_allocation.php,
       admin/subjects.php letters) already do this with !important and are
       unaffected — this only rescues the pages that have no print rules at all. */
    .portal-content { margin-left: 0 !important; }
    .portal-main { padding: 12px !important; }

    /* Interactive chrome is noise on paper and costs vertical space. */
    .portal-topbar, .list-filter, .list-pager { display: none !important; }
}


/* ── Tabs (Session 42; behaviour in portal-ui.js §6) ─────────────────────────
   Before the script runs (.ptabs-on absent) the nav is hidden and every panel
   shows in sequence, so the content is never lost behind a tab that cannot open. */
.ptabs-nav { display: none; }
.ptabs-on > .ptabs-nav {
    display: flex; gap: 4px; flex-wrap: wrap;
    border-bottom: 2px solid var(--gray-200); margin-bottom: 16px;
}
.ptabs-nav [role="tab"] {
    background: none; border: 0; border-bottom: 3px solid transparent; margin-bottom: -2px;
    padding: 10px 14px; font: inherit; font-size: 14px; font-weight: 600;
    color: var(--gray-600); cursor: pointer; border-radius: var(--radius) var(--radius) 0 0;
}
.ptabs-nav [role="tab"]:hover { color: var(--primary); background: var(--gray-100); }
.ptabs-nav [role="tab"][aria-selected="true"] { color: var(--primary); border-bottom-color: var(--accent); }
.ptabs-nav [role="tab"]:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.ptabs-nav .tab-count {
    display: inline-block; min-width: 20px; padding: 0 6px; margin-left: 4px;
    border-radius: 10px; background: var(--gray-100); font-size: 12px; text-align: center;
}

/* Row of labelled shortcuts (student profile hub). */
.quick-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 16px; }
.quick-actions .btn { display: inline-flex; align-items: center; gap: 6px; }
@media print {
    .ptabs-nav, .quick-actions { display: none !important; }
    .ptabs-panel[hidden] { display: block !important; }   /* print the whole record, not one tab */
}

/* ── Event / announcement detail pages + clickable cards (Session 42) ─────── */
.detail-layout { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 32px; align-items: start; }
.detail-image { width: 100%; max-height: 420px; object-fit: cover; border-radius: var(--radius-lg); margin-bottom: 20px; }
.detail-body { font-size: 15px; line-height: 1.75; color: var(--gray-700, #374151); }
.rich-content h1, .rich-content h2, .rich-content h3, .rich-content h4 { margin: 1.2em 0 .5em; line-height: 1.3; color: var(--gray-900); }
.rich-content p, .rich-content ul, .rich-content ol, .rich-content table { margin: 0 0 1em; }
.rich-content ul, .rich-content ol { padding-left: 1.4em; }
.rich-content ul { list-style: disc; }
.rich-content ol { list-style: decimal; }
.rich-content img { max-width: 100%; height: auto; border-radius: var(--radius); }
.rich-content a { color: var(--info); text-decoration: underline; }
.rich-content table { border-collapse: collapse; width: 100%; display: block; overflow-x: auto; }
.rich-content td, .rich-content th { border: 1px solid var(--gray-200); padding: 6px 10px; }
.detail-side { position: sticky; top: 90px; }
.detail-facts { background: var(--white); border: 1px solid var(--gray-200); border-radius: var(--radius-lg); padding: 18px; display: flex; flex-direction: column; gap: 12px; }
.detail-facts .ann-cat, .detail-facts .ev-cat-badge { align-self: flex-start; margin-bottom: 0; }
.detail-facts .ann-cat { display: inline-block; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; padding: 3px 10px; border-radius: 4px; }
.detail-fact { display: flex; gap: 10px; align-items: flex-start; font-size: 14px; color: var(--gray-700, #374151); }
.detail-fact i { color: var(--accent); width: 16px; margin-top: 3px; }
.detail-past { font-size: 13px; color: var(--gray-500); font-style: italic; }
.detail-back { display: inline-block; margin-top: 14px; font-size: 14px; font-weight: 600; }
@media (max-width: 860px) {
    .detail-layout { grid-template-columns: 1fr; }
    .detail-side { position: static; order: -1; }
}

/* Whole card clickable: the title is the real link; its ::after covers the card. */
.ann-card-v2, .event-card-v2, .home-ann-item, .home-event-item, .news-featured { position: relative; }
.card-link { color: inherit; text-decoration: none; }
.card-link::after { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.card-link:hover, .card-link:focus-visible { color: var(--primary); text-decoration: underline; }
.card-link:focus-visible { outline: none; }
.card-link:focus-visible::after { outline: 2px solid var(--primary); outline-offset: 2px; }
.home-ann-item:hover h4, .home-event-item:hover h4, .event-card-v2:hover h4, .home-ann-item:hover h3, .home-event-item:hover h3, .event-card-v2:hover h3 { color: var(--primary); }
.read-more { display: inline-block; margin-top: 6px; font-size: 13px; font-weight: 600; color: var(--accent); }
/* Staff cards open staff_profile.php; the email and social links stay clickable above the card link. */
.staff-card-v2 { position: relative; }
.staff-card-v2 .staff-email a, .staff-card-v2 .staff-social-links a { position: relative; z-index: 2; }
.staff-card-v2:hover h4, .staff-card-v2:hover h3 { color: var(--primary); }

/* ── Staff profile page (Session 42) ─────────────────────────────────────── */
.profile-head { display: flex; gap: 20px; align-items: center; margin-bottom: 24px; }
.profile-photo { width: 120px; height: 120px; flex: none; border-radius: 50%; overflow: hidden; background: var(--primary); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 40px; font-weight: 700; position: relative; }
.profile-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
.profile-head .staff-desig { font-size: 15px; font-weight: 600; color: var(--accent); }
.profile-head .profile-quals { font-size: 13px; color: var(--gray-500); margin-top: 4px; line-height: 1.5; }
.profile-section { margin-top: 28px; }
.profile-section h3 { font-size: 17px; color: var(--gray-900); margin-bottom: 12px; padding-bottom: 6px; border-bottom: 2px solid var(--gray-100); }
.profile-item { padding: 12px 0; border-bottom: 1px solid var(--gray-100); }
.profile-item:last-child { border-bottom: 0; }
.profile-item .pi-title { font-weight: 600; color: var(--gray-900); }
.profile-item .pi-meta { font-size: 13px; color: var(--gray-500); margin-top: 3px; }
.profile-links { display: flex; flex-wrap: wrap; gap: 8px; }
.profile-links a { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; padding: 6px 12px; border: 1px solid var(--gray-200); border-radius: var(--radius); color: var(--gray-700, #374151); }
.profile-links a:hover { border-color: var(--primary); color: var(--primary); }
@media (max-width: 860px) { .profile-layout .detail-side { order: 0; } }   /* the person first, then contact (event pages put facts first) */
@media (max-width: 560px) { .profile-head { flex-direction: column; text-align: center; } }
.news-featured .read-more { color: var(--accent); }

/* ─── Install-the-app chip (Session 55, assets/js/pwa.js) ─────────────────────
   Shown only when the browser offers installation; dismissible and remembered per device. */
.pwa-chip { position: fixed; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 1200; display: flex; align-items: center; gap: 4px; background: var(--primary); color: var(--white); border-radius: 999px; box-shadow: 0 6px 24px rgba(0,0,0,.25); padding: 4px 4px 4px 6px; max-width: calc(100vw - 32px); }
.pwa-chip button { background: none; border: 0; color: inherit; font: inherit; cursor: pointer; border-radius: 999px; }
.pwa-chip-go { padding: 9px 14px; font-weight: 600; font-size: 14px; white-space: nowrap; }
.pwa-chip-go:hover { background: rgba(255,255,255,.12); }
.pwa-chip-x { width: 34px; height: 34px; font-size: 20px; line-height: 1; }
.pwa-chip-x:hover { background: rgba(255,255,255,.12); }
.pwa-chip button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media print { .pwa-chip { display: none !important; } }
