/* ============================================================================
   SOPHIA COLLEGE - UNIFIED LOGGING SYSTEM
   Design System for: Out of Class, Infringements, Positive Affirmations
   Version: 2.0 - October 2025
   
   This stylesheet provides consistent layout, typography, spacing, and
   components across all three staff logging pages.
   ============================================================================ */

/* ============================================================================
   1. DESIGN TOKENS (CSS Custom Properties)
   ============================================================================ */

:root {
  /* === BRAND COLORS === */
  --brand-primary: #00488d;           /* Sophia College Blue */
  --brand-secondary: #004a73;         /* Deep Blue */
  --brand-accent-default: #660000;    /* Maroon (general use) */
  
  /* === CONTEXTUAL ACCENT COLORS (per page) === */
  --accent-infringement: #8B0000;     /* Dark Red/Maroon for Infringements */
  --accent-outofclass: #F59E0B;       /* Amber/Orange for Out of Class */
  --accent-affirmation: #059669;      /* Green/Teal for Positive Affirmations */
  
  /* === SEMANTIC COLORS === */
  --success: #10b981;
  --success-dark: #059669;
  --warning: #f59e0b;
  --warning-dark: #d97706;
  --error: #ef4444;
  --error-dark: #dc2626;
  --info: #3b82f6;
  --info-dark: #2563eb;
  
  /* === NEUTRAL PALETTE === */
  --neutral-50: #f8fafc;
  --neutral-100: #f1f5f9;
  --neutral-200: #e2e8f0;
  --neutral-300: #cbd5e1;
  --neutral-400: #94a3b8;
  --neutral-500: #64748b;
  --neutral-600: #475569;
  --neutral-700: #334155;
  --neutral-800: #1e293b;
  --neutral-900: #0f172a;
  
  /* === TEXT COLORS === */
  --text-primary: var(--neutral-900);
  --text-secondary: var(--neutral-700);
  --text-tertiary: var(--neutral-500);
  --text-muted: var(--neutral-400);
  --text-inverse: #ffffff;
  --text-link: var(--brand-primary);
  --text-link-hover: var(--brand-secondary);
  
  /* === BACKGROUND COLORS === */
  --bg-page: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 50%, #f1f5f9 100%);
  --bg-card: #ffffff;
  --bg-card-hover: var(--neutral-50);
  --bg-input: #ffffff;
  --bg-input-focus: #ffffff;
  --bg-overlay: rgba(15, 23, 42, 0.5);
  
  /* === BORDER COLORS === */
  --border-light: var(--neutral-200);
  --border-medium: var(--neutral-300);
  --border-dark: var(--neutral-400);
  --border-focus: var(--brand-primary);
  
  /* === SHADOW SYSTEM === */
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.06);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
  --shadow-lg: 0 8px 20px rgba(0, 0, 0, 0.12);
  --shadow-xl: 0 12px 32px rgba(0, 0, 0, 0.15);
  --shadow-2xl: 0 20px 48px rgba(0, 0, 0, 0.2);
  --shadow-focus: 0 0 0 3px rgba(0, 72, 141, 0.15);
  
  /* === SPACING SCALE (8px base grid) === */
  --space-0: 0;
  --space-1: 4px;    /* 0.5 unit */
  --space-2: 8px;    /* 1 unit */
  --space-3: 12px;   /* 1.5 units */
  --space-4: 16px;   /* 2 units */
  --space-5: 20px;   /* 2.5 units */
  --space-6: 24px;   /* 3 units */
  --space-8: 32px;   /* 4 units */
  --space-10: 40px;  /* 5 units */
  --space-12: 48px;  /* 6 units */
  --space-16: 64px;  /* 8 units */
  --space-20: 80px;  /* 10 units */
  
  /* === BORDER RADIUS === */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 16px;
  --radius-2xl: 20px;
  --radius-full: 9999px;
  
  /* === TYPOGRAPHY === */
  --font-family: 'Inter', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif;
  --font-mono: 'SF Mono', 'Monaco', 'Consolas', monospace;
  
  /* Font Sizes */
  --text-xs: 0.75rem;     /* 12px */
  --text-sm: 0.875rem;    /* 14px */
  --text-base: 1rem;      /* 16px */
  --text-lg: 1.125rem;    /* 18px */
  --text-xl: 1.25rem;     /* 20px */
  --text-2xl: 1.5rem;     /* 24px */
  --text-3xl: 1.875rem;   /* 30px */
  --text-4xl: 2.25rem;    /* 36px */
  
  /* Font Weights */
  --font-normal: 400;
  --font-medium: 500;
  --font-semibold: 600;
  --font-bold: 700;
  
  /* Line Heights */
  --leading-tight: 1.25;
  --leading-normal: 1.5;
  --leading-relaxed: 1.75;
  
  /* === TRANSITIONS & ANIMATIONS === */
  --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-base: 300ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-slow: 500ms cubic-bezier(0.4, 0, 0.2, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 1);
  --ease-out: cubic-bezier(0, 0, 0.2, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  
  /* === Z-INDEX SCALE === */
  --z-base: 0;
  --z-dropdown: 100;
  --z-sticky: 200;
  --z-overlay: 300;
  --z-modal: 400;
  --z-toast: 1080; /* matches design-tokens.css --z-notification; toast's real on-page
                       stacking is actually set by toast-manager.js's #unified-toast-container
                       (z-index:10000), this token only orders toasts relative to each other */
  --z-tooltip: 600;
  
  /* === LAYOUT === */
  --max-width-content: 1000px;
  --nav-height: 64px;
  --header-height: auto;
}

/* ============================================================================
   2. PAGE-SPECIFIC ACCENT OVERRIDES

   2026-06-30: infringements/outofclass's --accent-color now draws from
   css/design-tokens.css's real maroon/info scales (the design system's
   actual brand/semantic colours), not this file's own parallel
   --accent-infringement/--accent-outofclass tokens below - those are left
   in place since other, untouched rules in this file may still reference
   them, but nothing new is written against them per the design-plan
   confirmation. --accent-affirmation is unchanged (positiveaffirmations.html
   doesn't load this stylesheet, so it's unused dead weight either way, not
   touched here).
   ============================================================================ */

/* Infringements Page - maroon (the design system's accent/brand colour) */
body[data-page="infringements"] {
  --accent-color: var(--maroon-700);
  --accent-light: var(--maroon-50);
  --accent-gradient: linear-gradient(135deg, var(--maroon-700) 0%, var(--maroon-500) 100%);
}

/* Out of Class Page - info/navy (operational, lighter-weight register) */
body[data-page="outofclass"] {
  --accent-color: var(--info-600);
  --accent-light: var(--info-50);
  --accent-gradient: linear-gradient(135deg, var(--info-600) 0%, var(--navy-500) 100%);
}

/* Positive Affirmations Page */
body[data-page="affirmations"] {
  --accent-color: var(--accent-affirmation);
  --accent-light: rgba(5, 150, 105, 0.1);
  --accent-gradient: linear-gradient(135deg, #059669 0%, #10B981 100%);
}

/* ============================================================================
   3. RESET & BASE STYLES
   ============================================================================ */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-family);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--text-primary);
  background: var(--bg-page);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ============================================================================
   4. UNIFIED PAGE LAYOUT
   ============================================================================ */

.unified-logging-container {
  max-width: var(--max-width-content);
  margin: 0 auto;
  padding: var(--space-6);
  animation: fadeInUp 0.6s var(--ease-out);
}

@media (max-width: 768px) {
  .unified-logging-container {
    padding: var(--space-4);
  }
}

/* ============================================================================
   5. PAGE HEADER COMPONENT
   Rebuilt 2026-06-30: the previous version (centred, logo-above-title,
   accent-gradient underline) was never actually rendering - infringements.html
   and outofclass.html overrode nearly all of it with inline styles (a tinted
   gradient banner, emoji icon, action buttons). This is the real component
   now. Per the design plan: the school crest already lives in the real top
   chrome (js/enhanced-ui-components.js's SidebarNavigation, which removes and
   re-injects .page-header on every load - the static #stars-header markup in
   these two pages is never actually shown). This header's only job is
   orientation, not decoration - no banner background, no logo repeat, no
   emoji. Tokens come from css/design-tokens.css (--navy-*/--maroon-*/--space-*),
   not this file's own parallel token set, per the design-plan confirmation.
   ============================================================================ */

.unified-page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-8);
  padding-bottom: 0;
  border-bottom: none;
}

.unified-page-eyebrow {
  display: block;
  font-size: var(--text-xs, 0.75rem);
  font-weight: var(--font-bold, 700);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--gray-500, #6b7280);
  margin-bottom: var(--space-2);
}

.unified-page-title-block {
  min-width: 0;
}

.unified-page-title {
  font-size: var(--text-3xl, 2.369rem);
  font-weight: var(--font-extrabold, 800);
  color: var(--gray-900, #111827);
  margin-bottom: var(--space-2);
  letter-spacing: -0.02em;
  line-height: var(--leading-tight, 1.25);
  position: relative;
  display: inline-block;
  padding-bottom: var(--space-3);
}

/* The maroon/accent underline - the header's one deliberate decorative
   element, already an established pattern elsewhere (h2::after in these
   pages' own inline styles) rather than a new device. Colour comes from
   each page's --accent-color (set via body[data-page] below, itself
   pointing at design-tokens.css's maroon/navy scales). */
.unified-page-title::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 64px;
  height: 4px;
  border-radius: 2px;
  background: var(--accent-color);
}

.unified-page-subtitle {
  font-size: var(--text-base);
  color: var(--text-tertiary);
  max-width: 560px;
  margin: 0;
  line-height: var(--leading-relaxed);
}

.unified-page-header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* Flat icon buttons replacing the old inline-styled, emoji-labelled
   Export/Print/notification buttons. */
.unified-icon-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--bg-card);
  color: var(--text-secondary);
  border: 1px solid var(--border-medium);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  font-family: var(--font-family);
  cursor: pointer;
  transition: all var(--transition-fast);
}

.unified-icon-btn svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.unified-icon-btn:hover {
  background: var(--bg-card-hover);
  border-color: var(--accent-color);
  color: var(--accent-color);
}

.unified-icon-btn--icon-only {
  padding: var(--space-2);
}

.unified-stats-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding: var(--space-2) var(--space-4);
  background: var(--accent-light);
  border: 1px solid var(--accent-color);
  border-radius: var(--radius-full);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--accent-color);
}

@media (max-width: 640px) {
  .unified-page-header {
    flex-direction: column;
  }

  .unified-page-header-actions {
    width: 100%;
  }

  .unified-icon-btn:not(.unified-icon-btn--icon-only) {
    flex: 1;
    justify-content: center;
  }
}

/* Below 480px the three labelled buttons are too wide to lay out comfortably
   side-by-side. Drop to icon-only — the title attrs already carry accessibility. */
@media (max-width: 480px) {
  .unified-page-header-actions .unified-icon-btn span:not([aria-hidden]) {
    display: none;
  }
  .unified-page-header-actions .unified-icon-btn:not(.unified-icon-btn--icon-only) {
    padding: var(--space-2);
  }
}

/* ============================================================================
   6. SECTION COMPONENTS
   ============================================================================ */

.unified-section {
  background: var(--bg-card);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  margin-bottom: var(--space-6);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-base);
}

.unified-section:hover {
  box-shadow: var(--shadow-md);
}

.unified-section-header {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--border-light);
}

.unified-section-icon {
  font-size: var(--text-2xl);
  line-height: 1;
}

.unified-section-title {
  font-size: var(--text-xl);
  font-weight: var(--font-semibold);
  color: var(--text-primary);
  flex: 1;
}

.unified-section-subtitle {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  margin-top: var(--space-1);
}

/* ============================================================================
   7. STUDENT SEARCH COMPONENT

   The 🔍 emoji in .search-icon was replaced with an inline SVG in
   js/unified-student-search.js's render() method during the broader icon
   sweep pass (unified-student-search.js line 85). The SVG uses
   width="1.25em" height="1.25em" so it scales with the font-size already
   applied here and in the mobile override below.
   ============================================================================ */

.unified-student-search {
  position: relative;
}

/* The Find Student section gets more visual weight than the sections below
   it (task before reference data) - bigger padding and a stronger shadow
   than the default .unified-form-section/.unified-section card. Targets the
   existing .unified-form-section.unified-student-section combination already
   present in both pages' markup, so the category-selection and
   selection/details sections (which only carry .unified-form-section alone)
   are unaffected. */
.unified-form-section.unified-student-section {
  padding: var(--space-8, 2rem);
  box-shadow: var(--shadow-lg);
}

.unified-find-student-heading {
  font-size: var(--text-xl, 1.333rem);
  font-weight: var(--font-bold, 700);
  color: var(--gray-900, #111827);
  margin: 0 0 var(--space-2) 0;
}

.unified-find-student-hint {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  margin: 0 0 var(--space-4) 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.unified-find-student-hint svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: var(--text-muted);
}

.unified-search-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--text-secondary);
  margin-bottom: var(--space-2);
}

.unified-search-input {
  width: 100%;
  padding: var(--space-4);
  font-size: var(--text-base);
  font-family: var(--font-family);
  color: var(--text-primary);
  background: var(--bg-input);
  border: 2px solid var(--border-light);
  border-radius: var(--radius-md);
  transition: all var(--transition-base);
}

.unified-search-input:hover {
  border-color: var(--border-medium);
}

.unified-search-input:focus {
  outline: none;
  border-color: var(--border-focus);
  box-shadow: var(--shadow-focus);
  background: var(--bg-input-focus);
}

.unified-search-input::placeholder {
  color: var(--text-muted);
  font-style: italic;
}

/* Search Dropdown Results */
.unified-search-dropdown {
  position: absolute;
  top: calc(100% + var(--space-2));
  left: 0;
  right: 0;
  max-height: 400px;
  overflow-y: auto;
  background: var(--bg-card);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  z-index: var(--z-dropdown);
  display: none;
  animation: fadeInDown 0.2s var(--ease-out);
}

.unified-search-dropdown.active {
  display: block;
}

.unified-search-result {
  padding: var(--space-4);
  border-bottom: 1px solid var(--border-light);
  cursor: pointer;
  transition: background var(--transition-fast);
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.unified-search-result:last-child {
  border-bottom: none;
}

.unified-search-result:hover {
  background: var(--bg-card-hover);
}

.unified-search-result-name {
  font-weight: var(--font-semibold);
  color: var(--text-primary);
  font-size: var(--text-base);
}

.unified-search-result-meta {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-1);
}

.unified-search-no-results {
  padding: var(--space-6);
  text-align: center;
  color: var(--text-muted);
  font-style: italic;
}

/* ============================================================================
   8. STUDENT PREVIEW CARD
   ============================================================================ */

.unified-student-preview {
  background: linear-gradient(135deg, var(--neutral-50) 0%, #ffffff 100%);
  border: 2px solid var(--accent-color);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  margin-top: var(--space-6);
  display: none;
  animation: scaleIn 0.4s var(--ease-out);
  box-shadow: var(--shadow-md);
}

.unified-student-preview.active {
  display: block;
}

.unified-student-preview-grid {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-4);
  align-items: center;
}

/* Student Photo */
.unified-student-photo {
  width: 80px;
  height: 80px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--neutral-200);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--accent-color);
  box-shadow: var(--shadow-sm);
}

.unified-student-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.unified-student-photo-fallback {
  font-size: 2.5rem;
  color: var(--text-muted);
}

/* Student Info */
.unified-student-info {
  flex: 1;
}

.unified-student-name {
  font-size: var(--text-xl);
  font-weight: var(--font-bold);
  color: var(--text-primary);
  margin-bottom: var(--space-2);
}

.unified-student-metadata {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.unified-student-meta-item {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.unified-student-meta-icon {
  font-size: var(--text-base);
}

/* Student Stats */
.unified-student-stats {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.unified-student-stat {
  text-align: right;
}

.unified-student-stat-value {
  display: block;
  font-size: var(--text-2xl);
  font-weight: var(--font-bold);
  color: var(--accent-color);
  line-height: 1;
}

.unified-student-stat-label {
  display: block;
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  margin-top: var(--space-1);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Responsive Student Preview */
@media (max-width: 640px) {
  .unified-student-preview-grid {
    grid-template-columns: 1fr;
    text-align: center;
  }
  
  .unified-student-photo {
    margin: 0 auto;
  }
  
  .unified-student-metadata {
    justify-content: center;
  }
  
  .unified-student-stats {
    flex-direction: row;
    justify-content: center;
    gap: var(--space-6);
  }
  
  .unified-student-stat {
    text-align: center;
  }
}

/* ============================================================================
   8.5. "AT A GLANCE" STAT CARDS (rebuilt 2026-06-30)
   Was previously defined per-page (each of infringements.html/outofclass.html
   had its own near-identical copy with glassmorphism, gradient text-fill, and
   emoji icons at font-size: 2.5rem). One shared definition now - both pages
   use identical markup/classes; only the --card-color value per card differs
   (set inline per card, pointing at a design-tokens.css maroon/info/gold
   token, not a hardcoded hex).
   ============================================================================ */

.analytics-dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4);
  margin: var(--space-2) 0 0;
}

@media (max-width: 1024px) {
  .analytics-dashboard {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .analytics-dashboard {
    grid-template-columns: 1fr;
  }
}

.analytics-card {
  background: var(--bg-card);
  border: 1px solid var(--border-light);
  border-left: 3px solid var(--card-color, var(--border-medium));
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-sm);
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  transition: box-shadow var(--transition-fast);
  min-height: 92px;
}

.analytics-card:hover {
  box-shadow: var(--shadow-md);
}

.analytics-card-icon {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  color: var(--card-color, var(--text-tertiary));
}

.analytics-card-icon svg {
  width: 100%;
  height: 100%;
}

.analytics-card-content {
  flex: 1;
  min-width: 0;
}

.analytics-card-label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-tertiary);
  font-weight: var(--font-bold);
  display: block;
  margin-bottom: var(--space-1);
}

/* Value-first hierarchy: the number is what the user reads first, so it's
   the largest text in the card - no gradient text-fill trick, just colour
   and weight. */
.analytics-card-value {
  font-size: var(--text-3xl);
  font-weight: var(--font-bold);
  color: var(--text-primary);
  line-height: 1;
  margin-bottom: var(--space-1);
}

/* A failed fetch must look different from a genuine zero (existing
   pattern, unchanged - only the JS that toggles this class is untouched). */
.analytics-card-value.stat-error {
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--warning-dark, #d97706);
}

.analytics-card-subtitle {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  font-weight: var(--font-medium);
}

.analytics-card-trend {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  padding: 2px var(--space-2);
  border-radius: var(--radius-full);
  font-weight: var(--font-semibold);
  margin-top: var(--space-1);
}

.analytics-card-trend svg {
  width: 12px;
  height: 12px;
}

.analytics-card-trend.up {
  background: var(--danger-50, #fef2f2);
  color: var(--error-dark);
}

.analytics-card-trend.down {
  background: var(--success-50, #ecfdf5);
  color: var(--success-dark);
}

.analytics-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.analytics-list-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-1) 0;
}

.analytics-list-item:not(:last-child) {
  border-bottom: 1px solid var(--border-light);
}

.analytics-list-name {
  font-size: var(--text-sm);
  font-weight: var(--font-medium);
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.analytics-list-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 24px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  background: var(--card-color, var(--accent-color));
  color: var(--text-inverse);
  font-weight: var(--font-bold);
  font-size: var(--text-xs);
  flex-shrink: 0;
}

/* ============================================================================
   9. FORM ELEMENTS
   ============================================================================ */

.unified-form-group {
  margin-bottom: var(--space-6);
}

.unified-form-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--font-semibold);
  color: var(--text-secondary);
  margin-bottom: var(--space-2);
}

.unified-form-label-required::after {
  content: '*';
  color: var(--error);
  margin-left: var(--space-1);
}

.unified-form-input,
.unified-form-select,
.unified-form-textarea {
  width: 100%;
  padding: var(--space-4);
  font-size: var(--text-base);
  font-family: var(--font-family);
  color: var(--text-primary);
  background: var(--bg-input);
  border: 2px solid var(--border-light);
  border-radius: var(--radius-md);
  transition: all var(--transition-base);
}

.unified-form-input:hover,
.unified-form-select:hover,
.unified-form-textarea:hover {
  border-color: var(--border-medium);
}

.unified-form-input:focus,
.unified-form-select:focus,
.unified-form-textarea:focus {
  outline: none;
  border-color: var(--border-focus);
  box-shadow: var(--shadow-focus);
  background: var(--bg-input-focus);
}

.unified-form-textarea {
  resize: vertical;
  min-height: 100px;
  line-height: var(--leading-relaxed);
}

.unified-form-help {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  margin-top: var(--space-2);
}

/* ============================================================================
   10. DATE/TIME SELECTION
   ============================================================================ */

.unified-datetime-section {
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px dashed var(--border-medium);
}

.unified-datetime-options {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.unified-datetime-option {
  display: flex;
  align-items: flex-start;
  padding: var(--space-4);
  border: 2px solid var(--border-light);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all var(--transition-base);
  background: var(--bg-card);
}

.unified-datetime-option:hover {
  border-color: var(--border-medium);
  background: var(--bg-card-hover);
}

.unified-datetime-option input[type="radio"] {
  margin-top: 2px;
  margin-right: var(--space-3);
  accent-color: var(--accent-color);
  transform: scale(1.2);
  cursor: pointer;
}

.unified-datetime-option input[type="radio"]:checked ~ .unified-datetime-label {
  color: var(--accent-color);
  font-weight: var(--font-semibold);
}

.unified-datetime-option:has(input[type="radio"]:checked) {
  border-color: var(--accent-color);
  background: var(--accent-light);
}

.unified-datetime-label {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.unified-datetime-label-text {
  font-size: var(--text-base);
  font-weight: var(--font-medium);
  color: var(--text-primary);
}

.unified-datetime-preview {
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  font-style: italic;
}

.unified-datetime-custom-inputs {
  display: none;
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-light);
  animation: fadeInUp 0.3s var(--ease-out);
}

.unified-datetime-custom-inputs.active {
  display: block;
}

.unified-datetime-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

@media (max-width: 640px) {
  .unified-datetime-grid {
    grid-template-columns: 1fr;
  }
}

/* ============================================================================
   11. BUTTONS
   ============================================================================ */

.unified-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  font-size: var(--text-base);
  font-weight: var(--font-semibold);
  font-family: var(--font-family);
  line-height: 1;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all var(--transition-base);
  text-decoration: none;
  white-space: nowrap;
  user-select: none;
}

/* Primary Button (Submit) */
.unified-btn-primary {
  background: var(--accent-gradient);
  color: var(--text-inverse);
  box-shadow: var(--shadow-md);
  position: relative;
  overflow: hidden;
}

.unified-btn-primary::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
  transition: left var(--transition-base);
}

.unified-btn-primary:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

.unified-btn-primary:hover:not(:disabled)::before {
  left: 100%;
}

.unified-btn-primary:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: var(--shadow-sm);
}

.unified-btn-primary:disabled {
  background: var(--neutral-300);
  color: var(--neutral-500);
  cursor: not-allowed;
  box-shadow: none;
  opacity: 0.6;
}

/* Secondary Button */
.unified-btn-secondary {
  background: var(--bg-card);
  color: var(--text-primary);
  border: 2px solid var(--border-medium);
}

.unified-btn-secondary:hover:not(:disabled) {
  background: var(--bg-card-hover);
  border-color: var(--border-dark);
}

.unified-btn-secondary:disabled {
  color: var(--text-muted);
  border-color: var(--border-light);
  cursor: not-allowed;
  opacity: 0.6;
}

/* Button Sizes */
.unified-btn-sm {
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
}

.unified-btn-lg {
  padding: var(--space-5) var(--space-8);
  font-size: var(--text-lg);
}

/* Full Width Button */
.unified-btn-block {
  width: 100%;
}

/* ============================================================================
   12. SEGMENTED CONTROL (for Infringements: Uniform vs Learning)
   ============================================================================ */

.unified-segmented-control {
  display: inline-flex;
  background: var(--neutral-100);
  border: 2px solid var(--border-light);
  border-radius: var(--radius-lg);
  padding: var(--space-1);
  margin-bottom: var(--space-6);
}

.unified-segment-btn {
  padding: var(--space-3) var(--space-6);
  font-size: var(--text-base);
  font-weight: var(--font-semibold);
  font-family: var(--font-family);
  color: var(--text-secondary);
  background: transparent;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all var(--transition-fast);
  white-space: nowrap;
}

.unified-segment-btn:hover:not(.active) {
  background: var(--bg-card-hover);
  color: var(--text-primary);
}

.unified-segment-btn.active {
  background: var(--bg-card);
  color: var(--accent-color);
  box-shadow: var(--shadow-sm);
}

/* ============================================================================
   13. ANIMATIONS
   ============================================================================ */

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeInDown {
  from {
    opacity: 0;
    transform: translateY(-20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes slideInLeft {
  from {
    opacity: 0;
    transform: translateX(-30px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes slideInRight {
  from {
    opacity: 0;
    transform: translateX(30px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.7;
  }
}

/* ============================================================================
   14. UTILITY CLASSES
   ============================================================================ */

.unified-hidden {
  display: none !important;
}

.unified-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

.unified-text-center {
  text-align: center;
}

.unified-text-right {
  text-align: right;
}

.unified-mt-0 { margin-top: var(--space-0); }
.unified-mt-2 { margin-top: var(--space-2); }
.unified-mt-4 { margin-top: var(--space-4); }
.unified-mt-6 { margin-top: var(--space-6); }
.unified-mt-8 { margin-top: var(--space-8); }

.unified-mb-0 { margin-bottom: var(--space-0); }
.unified-mb-2 { margin-bottom: var(--space-2); }
.unified-mb-4 { margin-bottom: var(--space-4); }
.unified-mb-6 { margin-bottom: var(--space-6); }
.unified-mb-8 { margin-bottom: var(--space-8); }

/* ============================================================================
   15. TOAST NOTIFICATIONS
   ============================================================================ */

.unified-toast {
  position: fixed;
  top: var(--space-6);
  right: var(--space-6);
  min-width: 300px;
  max-width: 500px;
  padding: var(--space-4);
  background: var(--bg-card);
  border: 1px solid var(--border-light);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  z-index: var(--z-toast);
  display: none;
  animation: slideInRight 0.3s var(--ease-out);
}

.unified-toast.active {
  display: block;
}

.unified-toast-success {
  border-left: 4px solid var(--success);
}

.unified-toast-error {
  border-left: 4px solid var(--error);
}

.unified-toast-warning {
  border-left: 4px solid var(--warning);
}

.unified-toast-info {
  border-left: 4px solid var(--info);
}

/* ============================================================================
   16. LOADING STATES
   ============================================================================ */

.unified-loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid var(--border-light);
  border-top-color: var(--accent-color);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  margin: var(--space-6) auto;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.unified-skeleton {
  background: linear-gradient(
    90deg,
    var(--neutral-200) 0%,
    var(--neutral-100) 50%,
    var(--neutral-200) 100%
  );
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: var(--radius-md);
}

@keyframes shimmer {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

/* ============================================================================
   17. SIDEBAR DOUBLE-OFFSET FIX

   css/sidebar-navigation.css has a broad rule:
     body.sidebar-layout .main-content, body.sidebar-layout .main-container {
       margin-left: var(--sidebar-effective-width) !important; ... }
   which applies the sidebar offset to BOTH elements simultaneously with
   !important. On most pages .main-container is a top-level sibling of the
   sidebar (so the offset is correct), but on these logging pages it is a
   descendant of .main-content — which already received the offset — making
   it double-offset (220px gap between sidebar edge and content on desktop).

   The old gradient-banner header masked this because the banner card visually
   anchored the left edge of the 1000px container. The clean replacement
   header (no background card) made the gap obvious.

   Fixing here rather than in sidebar-navigation.css to avoid unintended
   effects on pages where .main-container IS top-level.
   ============================================================================ */

body.sidebar-layout .main-content .main-container {
  margin-left: 0 !important;
  max-width: 100% !important;
  width: 100% !important;
}

/* ============================================================================
   18. CONFIRMATION MODAL REDESIGN (2026-06-30)
   Applied to the dynamically-inserted .confirmationModalOverlay in both
   infringements.html and outofclass.html. These classes override the
   gradient-header and 3-card summary patterns built into those JS templates
   with the same clean, token-based visual language now used on the page
   headers themselves. form-workflow-polish.css keeps .modal-overlay /
   .modal-container animation rules — these classes only affect the internal
   visual structure that was previously inline-styled.
   ============================================================================ */

/* Clean white header — replaces the gradient banner. Uses --accent-color
   which is already set per page (maroon for infringements, info-blue for
   outofclass) to tint the title underline and icon. */
.modal-header--clean {
  background: var(--color-bg, #ffffff);
  border-bottom: 1px solid var(--color-border, #e2e8f0);
  padding: var(--space-6, 24px);
  border-radius: 12px 12px 0 0;
}

.modal-header--clean h2 {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--gray-900, #111827);
  font-family: var(--font-heading, 'Poppins', sans-serif);
  letter-spacing: -0.01em;
  position: relative;
  display: inline-block;
  padding-bottom: var(--space-3, 12px);
}

.modal-header--clean h2::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 40px;
  height: 3px;
  border-radius: 2px;
  background: var(--accent-color, var(--maroon-700, #be123c));
}

.modal-header--clean p {
  margin: var(--space-3, 12px) 0 0 0;
  color: var(--gray-500, #6b7280);
  font-size: 0.875rem;
  line-height: 1.4;
}

/* Summary chip-row: replaces the 3-card grid. A single flex row of
   icon+text chips for count / type / timing — proportional to content,
   mobile-friendly (wraps naturally), reads like a receipt. */
.modal-summary-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2, 8px);
  padding: var(--space-4, 16px) var(--space-5, 20px);
  background: var(--gray-50, #f9fafb);
  border: 1px solid var(--color-border, #e2e8f0);
  border-radius: var(--radius-lg, 12px);
  margin-bottom: var(--space-6, 24px);
}

.modal-summary-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2, 8px);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--gray-700, #374151);
}

.modal-summary-chip svg {
  width: 14px;
  height: 14px;
  color: var(--accent-color, var(--maroon-700, #be123c));
  flex-shrink: 0;
}

.modal-summary-divider {
  color: var(--gray-300, #d1d5db);
  font-size: 1rem;
  user-select: none;
}

/* Small meta-line below summary (infringements only — shows category name
   that isn't part of the chip row). */
.modal-meta-line {
  font-size: 0.75rem;
  color: var(--gray-500, #6b7280);
  margin: calc(var(--space-2, 8px) * -1) 0 var(--space-5, 20px) 0;
  display: flex;
  align-items: center;
  gap: var(--space-2, 8px);
}

/* Students section heading replaces the emoji "📚 Students" label. */
.modal-students-heading {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--gray-500, #6b7280);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  display: flex;
  align-items: center;
  gap: var(--space-2, 8px);
  margin: 0 0 var(--space-3, 12px) 0;
}

.modal-students-heading svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* Confirm & Log button — uses --accent-color so it automatically matches
   the page's brand colour (maroon on infringements, info-blue on outofclass)
   without needing a separate colour per page. */
.unified-action-btn-confirm {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2, 8px);
  padding: var(--space-3, 12px) var(--space-5, 20px);
  background: var(--accent-color, var(--maroon-700, #be123c));
  color: #ffffff;
  border: none;
  border-radius: var(--radius-md, 8px);
  font-size: 0.875rem;
  font-weight: 600;
  font-family: var(--font-body, 'Inter', sans-serif);
  cursor: pointer;
  transition: filter var(--transition-fast, 150ms), transform var(--transition-fast, 150ms);
  box-shadow: 0 2px 6px rgba(0,0,0,0.15);
}

.unified-action-btn-confirm:hover {
  filter: brightness(0.9);
  transform: translateY(-1px);
}

.unified-action-btn-confirm svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* ============================================================================
   19. SVG ICON SIZING CORRECTIONS
   ============================================================================ */

/* The .empty-icon in .empty-state-polished (css/common-styles.css) uses
   font-size: 2.5rem to size an emoji. SVG replacements need an explicit
   width/height since font-size has no effect on them. */
.empty-state-polished .empty-icon svg {
  width: 40px;
  height: 40px;
  color: var(--text-tertiary);
}

/* ============================================================================
   END OF UNIFIED LOGGING SYSTEM STYLESHEET
   ============================================================================ */
