/* ==========================================================================
   NelSMS — App Design System
   Light & Dark themes, SaaS-blue primary. Custom CSS, no frameworks.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */
:root {
  --bg: #f4f6fb;
  --surface: #ffffff;
  --surface-2: #f6f8fc;
  --surface-3: #eef1f8;
  --border: #e4e8f1;
  --border-strong: #d2d9e8;

  --text: #2f3b4f;
  --text-2: #566274;
  --text-3: #909bac;

  --brand: #2563eb;
  --brand-hover: #1d4ed8;
  --brand-active: #1e40af;
  --brand-soft: rgba(37, 99, 235, 0.1);
  --brand-softer: rgba(37, 99, 235, 0.06);
  --brand-ring: rgba(37, 99, 235, 0.28);

  --success: #12b76a;
  --success-soft: rgba(18, 183, 106, 0.12);
  --warning: #f79009;
  --warning-soft: rgba(247, 144, 9, 0.14);
  --danger: #f04438;
  --danger-soft: rgba(240, 68, 56, 0.12);
  --violet: #7a5af8;
  --violet-soft: rgba(122, 90, 248, 0.12);
  --cyan: #06aed4;
  --cyan-soft: rgba(6, 174, 212, 0.12);

  --shadow-xs: 0 1px 2px rgba(16, 24, 40, 0.04);
  --shadow-sm:
    0 1px 3px rgba(16, 24, 40, 0.06), 0 1px 2px rgba(16, 24, 40, 0.04);
  --shadow-md:
    0 6px 16px -4px rgba(16, 24, 40, 0.1), 0 2px 6px -2px rgba(16, 24, 40, 0.05);
  --shadow-lg:
    0 20px 40px -12px rgba(16, 24, 40, 0.18),
    0 8px 16px -6px rgba(16, 24, 40, 0.08);

  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 16px;
  --radius-full: 999px;

  --sidebar-w: 264px;
  --sidebar-w-collapsed: 82px;
  --topbar-h: 68px;

  --font:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
}

[data-theme="dark"] {
  --bg: #0a0f1e;
  --surface: #0f1729;
  --surface-2: #121d34;
  --surface-3: #182442;
  --border: #1e2a47;
  --border-strong: #2b3a5e;

  --text: #c8d1e2;
  --text-2: #96a3ba;
  --text-3: #6d7d96;

  --brand: #3b82f6;
  --brand-hover: #5b93f7;
  --brand-active: #2563eb;
  --brand-soft: rgba(59, 130, 246, 0.16);
  --brand-softer: rgba(59, 130, 246, 0.08);
  --brand-ring: rgba(59, 130, 246, 0.34);

  --success: #22c58b;
  --success-soft: rgba(34, 197, 139, 0.16);
  --warning: #fbbf24;
  --warning-soft: rgba(251, 191, 36, 0.16);
  --danger: #f87171;
  --danger-soft: rgba(248, 113, 113, 0.16);
  --violet: #9b84ff;
  --violet-soft: rgba(155, 132, 255, 0.16);
  --cyan: #22d3ee;
  --cyan-soft: rgba(34, 211, 238, 0.16);

  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 8px 20px -6px rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 24px 48px -12px rgba(0, 0, 0, 0.6);
}

/* --------------------------------------------------------------------------
   2. Reset / base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  transition:
    background 0.3s ease,
    color 0.3s ease;
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition:
    background 0.3s ease,
    color 0.3s ease;
}

h1,
h2,
h3,
h4,
h5,
h6,
p {
  margin: 0;
}
a {
  color: var(--brand);
  text-decoration: none;
}
a:hover {
  color: var(--brand-hover);
}
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
img {
  max-width: 100%;
  display: block;
}
button {
  font-family: inherit;
}

::selection {
  background: var(--brand-ring);
  color: var(--text);
}

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 6px;
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 8px;
  border: 2px solid var(--bg);
}
::-webkit-scrollbar-track {
  background: transparent;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

/* --------------------------------------------------------------------------
   3. App shell layout
   -------------------------------------------------------------------------- */
.app {
  display: flex;
  min-height: 100vh;
}

.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--sidebar-w);
  z-index: 60;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-right: 1px solid var(--border);
  transition:
    width 0.22s ease,
    transform 0.25s ease;
}

.main {
  flex: 1;
  min-width: 0;
  margin-left: var(--sidebar-w);
  display: flex;
  flex-direction: column;
  transition: margin-left 0.22s ease;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 24px;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}

.content {
  flex: 1;
  padding: 26px 26px 20px;
}

@media (min-width: 1280px) {
  .content {
    padding: 28px 34px 24px;
  }
}

/* --- Collapsed sidebar (desktop) --- */
body.sidebar-collapsed .sidebar {
  width: var(--sidebar-w-collapsed);
}
body.sidebar-collapsed .main {
  margin-left: var(--sidebar-w-collapsed);
}
body.sidebar-collapsed .sidebar .brand-text,
body.sidebar-collapsed .sidebar .nav-label,
body.sidebar-collapsed .sidebar .nav-badge,
body.sidebar-collapsed .sidebar .nav-caret,
body.sidebar-collapsed .sidebar .nav-group-title,
body.sidebar-collapsed .sidebar .sidebar-foot .foot-text,
body.sidebar-collapsed .sidebar .user-meta {
  display: none;
}
body.sidebar-collapsed .sidebar .nav-link {
  justify-content: center;
  padding: 10px;
}
body.sidebar-collapsed .sidebar .nav-link .nav-icon {
  margin: 0;
}
body.sidebar-collapsed .sidebar .sidebar-foot .user-chip {
  justify-content: center;
  padding: 10px;
}

.sidebar-backdrop {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: rgba(9, 13, 24, 0.55);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}

/* --- Mobile drawer --- */
@media (max-width: 1023px) {
  .sidebar {
    transform: translateX(-105%);
    box-shadow: var(--shadow-lg);
    border-right: 0;
  }
  body.sidebar-mobile-open .sidebar {
    transform: translateX(0);
  }
  body.sidebar-mobile-open .sidebar-backdrop {
    opacity: 1;
    pointer-events: auto;
  }
  .main {
    margin-left: 0;
  }
  .topbar {
    padding: 0 16px;
  }
  .content {
    padding: 20px 16px 20px;
  }
}

/* --------------------------------------------------------------------------
   4. Brand
   -------------------------------------------------------------------------- */
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px 18px 16px;
  min-height: calc(var(--topbar-h) - 2px);
  border-bottom: 1px solid var(--border);
}
.brand-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: #fff;
  border-radius: var(--radius);
  background: linear-gradient(
    135deg,
    var(--mark-accent, #2563eb),
    color-mix(in srgb, var(--mark-accent, #2563eb) 62%, #6d28d9)
  );
  box-shadow: 0 6px 14px -6px
    color-mix(in srgb, var(--mark-accent, #2563eb) 70%, transparent);
}
.brand-mark--md {
  width: 42px;
  height: 42px;
  font-size: 15px;
  border-radius: var(--radius);
}
.brand-mark--lg {
  width: 56px;
  height: 56px;
  font-size: 20px;
  border-radius: var(--radius-lg);
}
.brand-mark--xs {
  width: 36px;
  height: 36px;
  font-size: 13px;
  border-radius: 10px;
}
.brand-logo {
  object-fit: contain;
}
.brand-logo--md {
  width: 42px;
  height: 42px;
}
.brand-logo--lg {
  width: 56px;
  height: 56px;
}
.brand-logo--xs {
  width: 36px;
  height: 36px;
}

.brand-text {
  min-width: 0;
}
.brand-name {
  display: block;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.25;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.brand-sub {
  display: block;
  font-size: 12px;
  color: var(--text-3);
  margin-top: 1px;
}

/* --------------------------------------------------------------------------
   5. Sidebar navigation
   -------------------------------------------------------------------------- */
.sidebar-nav {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 14px 12px 20px;
}
.nav-group + .nav-group {
  margin-top: 18px;
}
.nav-group-title {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-3);
  padding: 0 10px;
  margin-bottom: 6px;
}
.nav-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  margin-bottom: 2px;
  border-radius: 10px;
  color: var(--text-2);
  font-weight: 500;
  font-size: 14px;
  transition:
    background 0.15s ease,
    color 0.15s ease;
}
.nav-link:hover {
  background: var(--surface-2);
  color: var(--text);
}
.nav-link.is-active {
  background: var(--brand-soft);
  color: var(--brand);
  font-weight: 600;
}
.nav-icon {
  width: 20px;
  text-align: center;
  font-size: 15px;
  flex: none;
}
.nav-label {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.nav-badge {
  font-size: 11px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: var(--radius-full);
}
.nav-badge--blue {
  background: var(--brand-soft);
  color: var(--brand);
}
.nav-badge--green {
  background: var(--success-soft);
  color: var(--success);
}
.nav-badge--violet {
  background: var(--violet-soft);
  color: var(--violet);
}
.nav-badge--amber {
  background: var(--warning-soft);
  color: var(--warning);
}
.nav-badge--red {
  background: var(--danger-soft);
  color: var(--danger);
}

/* Sidebar footer */
.sidebar-foot {
  padding: 14px 12px 16px;
  border-top: 1px solid var(--border);
}
.sidebar-upgrade {
  padding: 14px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface-2);
  margin-bottom: 12px;
}
.sidebar-upgrade h4 {
  font-size: 13px;
  margin-bottom: 4px;
}
.sidebar-upgrade p {
  font-size: 12px;
  color: var(--text-2);
  margin-bottom: 10px;
}
.sidebar-upgrade .btn {
  width: 100%;
}
.user-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border-radius: 10px;
}
.user-chip:hover {
  background: var(--surface-2);
}
.user-meta {
  flex: 1;
  min-width: 0;
}
.user-meta strong {
  display: block;
  font-size: 13px;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.user-meta span {
  display: block;
  font-size: 12px;
  color: var(--text-3);
}

/* --------------------------------------------------------------------------
   6. Topbar
   -------------------------------------------------------------------------- */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-2);
  font-size: 15px;
  cursor: pointer;
  transition:
    background 0.15s ease,
    color 0.15s ease,
    border-color 0.15s ease;
  position: relative;
}
.icon-btn:hover {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--border-strong);
}

.icon-btn .dot {
  position: absolute;
  top: 8px;
  right: 9px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--danger);
  border: 2px solid var(--surface);
}

.topbar-breadcrumb small {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-3);
  font-weight: 500;
}
.topbar-breadcrumb small i {
  font-size: 10px;
  color: var(--text-3);
}
.topbar-search {
  flex: 1;
  max-width: 380px;
}
.topbar-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}
/* The account avatar uses the large avatar size, which reads heavier than the
   icon buttons beside it. Match them in the top bar (scoped, so the large
   avatar on the student profile is untouched). */
.topbar-actions .avatar--lg {
  width: 40px;
  height: 40px;
  font-size: 14px;
}

/* --------------------------------------------------------------------------
   7. Search
   -------------------------------------------------------------------------- */
.search {
  position: relative;
}
.search > i {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-3);
  font-size: 14px;
  pointer-events: none;
}
.search .input {
  padding-left: 40px;
}

/* --------------------------------------------------------------------------
   8. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
  padding: 11px 16px;
  border-radius: 10px;
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
  transition:
    background 0.15s ease,
    border-color 0.15s ease,
    box-shadow 0.15s ease,
    color 0.15s ease,
    transform 0.05s ease;
}
.btn:active {
  transform: translateY(1px);
}
.btn i {
  font-size: 14px;
}
.btn-sm {
  padding: 8px 12px;
  font-size: 13px;
  border-radius: 8px;
}
.btn-sm i {
  font-size: 13px;
}
.btn-lg {
  padding: 13px 20px;
  font-size: 15px;
  border-radius: 12px;
}
.btn-block {
  width: 100%;
  display: flex;
}
.btn-icon {
  width: 40px;
  height: 40px;
  padding: 0;
}

.btn-primary {
  background: var(--brand);
  color: #fff;
  box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--brand) 60%, transparent);
}
.btn-primary:hover {
  background: var(--brand-hover);
  color: #fff;
}
.btn-primary:active {
  background: var(--brand-active);
  color: #fff;
}

.btn-outline {
  background: var(--surface);
  color: var(--text-2);
  border-color: var(--border-strong);
}
.btn-outline:hover {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--text-3);
}

.btn-ghost {
  background: transparent;
  color: var(--text-2);
}
.btn-ghost:hover {
  background: var(--surface-2);
  color: var(--text);
}

.btn-danger {
  background: var(--danger);
  color: #fff;
}
.btn-danger:hover {
  filter: brightness(0.94);
  color: #fff;
}
.btn-danger-outline {
  background: transparent;
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
}
.btn-danger-outline:hover {
  background: var(--danger-soft);
  color: var(--danger);
}

.btn-success {
  background: var(--success);
  color: #fff;
}
.btn-success:hover {
  filter: brightness(0.94);
  color: #fff;
}

/* --------------------------------------------------------------------------
   9. Cards
   -------------------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}
.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--border);
}
.card-head h3 {
  font-size: 15px;
  font-weight: 700;
}
.card-head p {
  font-size: 13px;
  color: var(--text-2);
  margin-top: 2px;
}
.card-body {
  padding: 20px;
}
.card-body--flush {
  padding: 0;
}
.card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 20px;
  border-top: 1px solid var(--border);
  font-size: 13px;
  color: var(--text-2);
}

/* --------------------------------------------------------------------------
   10. Stats / metric tiles
   -------------------------------------------------------------------------- */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 16px;
  margin-bottom: 22px;
}
.stat {
  position: relative;
  overflow: hidden;
  padding: 18px 18px 16px;
}
/* The text column is always the first <div>; the icon is a <span> and is parked
   top-right. min-width: 0 keeps flex from spilling, and padding-right keeps the
   text clear of the icon. Values stay on one line (fitStatValues() in app.js
   shrinks long figures to fit) so a tile never grows taller than its content. */
.stat > div:first-child {
  flex: 1 1 auto;
  min-width: 0;
  padding-right: 60px;
}
.stat-icon {
  position: absolute;
  top: 18px;
  right: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 50px;
  height: 50px;
  border-radius: var(--radius);
  font-size: 19px;
  flex: none;
  box-shadow: var(--shadow-xs);
}
.stat-icon--blue {
  background: var(--brand-soft);
  color: var(--brand);
}
.stat-icon--green {
  background: var(--success-soft);
  color: var(--success);
}
.stat-icon--violet {
  background: var(--violet-soft);
  color: var(--violet);
}
.stat-icon--amber {
  background: var(--warning-soft);
  color: var(--warning);
}
.stat-icon--cyan {
  background: var(--cyan-soft);
  color: var(--cyan);
}
.stat-icon--red {
  background: var(--danger-soft);
  color: var(--danger);
}
.stat .stat-label {
  font-size: 11px;
  color: var(--text-3);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.stat-value {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.stat-delta {
  position: relative;
  display: inline-flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 4px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.3;
  margin-top: 8px;
  padding: 4px 9px;
  border-radius: var(--radius-full);
  background: var(--surface-2);
  max-width: 100%;
  cursor: help;
}
/* The trailing text truncates inside the pill (… by CSS); the icon stays put.
   enhanceStatDeltas() in app.js wraps the text and stores the full value in
   data-full, which this tooltip pops open on hover. */
.stat-delta > i {
  flex: none;
}
.stat-delta-text {
  flex: 1 1 auto;
  min-width: 0;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.stat-delta::after {
  content: attr(data-full);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  z-index: 40;
  max-width: 300px;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  background: var(--text);
  color: var(--surface);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  white-space: normal;
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition:
    opacity 0.12s ease,
    transform 0.12s ease,
    visibility 0.12s;
  pointer-events: none;
  box-shadow: var(--shadow-md);
}
.stat-delta:hover::after,
.stat-delta:focus-visible::after {
  opacity: 1;
  visibility: visible;
  transform: none;
}
.stat-delta--up {
  color: var(--success);
  background: var(--success-soft);
}
.stat-delta--down {
  color: var(--danger);
  background: var(--danger-soft);
}
.stat-spark {
  margin-top: 10px;
}

/* A thin accent bar ties each tile to the colour of its icon. :has() is a
   progressive enhancement: browsers that support it get the bar, everything
   else simply renders without it. */
@supports (selector(:has(a))) {
  .stat::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    height: 3px;
    border-radius: 2px;
  }
  .stat:has(.stat-icon--blue)::before {
    background: var(--brand);
  }
  .stat:has(.stat-icon--green)::before {
    background: var(--success);
  }
  .stat:has(.stat-icon--violet)::before {
    background: var(--violet);
  }
  .stat:has(.stat-icon--amber)::before {
    background: var(--warning);
  }
  .stat:has(.stat-icon--cyan)::before {
    background: var(--cyan);
  }
  .stat:has(.stat-icon--red)::before {
    background: var(--danger);
  }
}

/* --------------------------------------------------------------------------
   11. Grid helpers
   -------------------------------------------------------------------------- */
/* Sections toggled by the tab strips in app.js. */
[hidden] {
  display: none !important;
}

.grid {
  display: grid;
  gap: 18px;
}
.grid-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.grid-4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.grid-main {
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}
@media (max-width: 1100px) {
  .grid-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 820px) {
  .grid-2,
  .grid-3,
  .grid-4,
  .grid-main {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* On desktop, the Recent activity card matches the height of its sibling
   (the attendance-bars card) and scrolls its own inner content. */
@media (min-width: 821px) {
  .activity-card {
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  .activity-card .card-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
  }
}

/* Finance main grid: the sidebar sets the row height and the invoice ledger
   fills that row -- its records scroll inside the row (the column header
   stays sticky) instead of the ledger stretching the grid taller and taller.
   Desktop only -- grid-main stacks below 821px. */
@media (min-width: 821px) {
  .ledger-card {
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  .ledger-card > .table-wrap {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
  }
  .ledger-card .table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
  }
}

/* --------------------------------------------------------------------------
   12. Page header
   -------------------------------------------------------------------------- */
.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}
.page-head h1 {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.02em;
}
.page-head p {
  color: var(--text-2);
  font-size: 14px;
  margin-top: 4px;
}
.page-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   13. Tables
   -------------------------------------------------------------------------- */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.table th {
  text-align: left;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-3);
  padding: 12px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
  white-space: nowrap;
}
.table th:first-child {
  border-radius: 0;
}
.table td {
  padding: 13px 20px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  color: var(--text-2);
}
.table tbody tr {
  transition: background 0.12s ease;
}
.table tbody tr:hover {
  background: var(--surface-2);
}
.table tbody tr:last-child td {
  border-bottom: 0;
}
.table td strong {
  color: var(--text);
  font-weight: 600;
}
.table .cell-main {
  display: flex;
  align-items: center;
  gap: 12px;
}
.table .cell-title {
  font-weight: 600;
  color: var(--text);
  font-size: 14px;
}
.table .cell-sub {
  font-size: 12px;
  color: var(--text-3);
  margin-top: 1px;
}
.table .cell-end {
  text-align: right;
}
.table .row-actions {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  flex-wrap: wrap;
}

/* Tables mounted flush in a card get a gutter so row rules, hover
   backgrounds and the header bar stop short of the card border (and its
   rounded corners) at every scroll position. Margins, not padding: inline-end
   padding is not reliably part of a scroll container's scrollable area, so a
   margin guarantees the gap at both ends of a horizontal scroll. */
.card > .table-wrap {
  margin-left: 12px;
  margin-right: 12px;
  margin-bottom: 14px;
}

/* Compensate the first cell so column text keeps lining up with the card-head
   title (12 + 8 = 20px). Desktop table only -- below 768px rows stack into
   cards that keep their own 14px cell padding. */
@media (min-width: 768px) {
  .card > .table-wrap .table th:first-child,
  .card > .table-wrap .table td:first-child {
    padding-left: 8px;
  }
}

/* Invoice ledger: let columns keep their natural (unwrapped) length instead
   of squeezing cells to min-content, which wrapped invoice numbers, student
   names and descriptions into 3-line rows. The horizontal scroll container
   takes up the slack. Desktop only -- stacked rows below 768px are untouched,
   and min-width keeps the table filling the card when it fits naturally. */
@media (min-width: 768px) {
  .ledger-card .table {
    width: max-content;
    min-width: 100%;
  }
}

/* Mobile: stack tables into cards */
@media (max-width: 767px) {
  .table-wrap {
    overflow: visible;
  }
  .table-stack thead {
    display: none;
  }
  .table-stack,
  .table-stack tbody,
  .table-stack tr,
  .table-stack td {
    display: block;
    width: 100%;
  }
  .table-stack tr {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 12px;
    box-shadow: var(--shadow-xs);
    overflow: hidden;
  }
  .table-stack tr:first-child {
    border-top: 1px solid var(--border);
  }
  .table-stack td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
  }
  .table-stack td:last-child {
    border-bottom: 0;
  }
  .table-stack td::before {
    content: attr(data-label);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-3);
    flex: none;
  }
  .table-stack .cell-main {
    flex: 1;
    justify-content: flex-end;
    text-align: right;
    flex-direction: row-reverse;
  }
}

/* --------------------------------------------------------------------------
   14. Badges / chips / avatars
   -------------------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: var(--radius-full);
  white-space: nowrap;
}
.badge--green {
  background: var(--success-soft);
  color: var(--success);
}
.badge--amber {
  background: var(--warning-soft);
  color: var(--warning);
}
.badge--red {
  background: var(--danger-soft);
  color: var(--danger);
}
.badge--blue {
  background: var(--brand-soft);
  color: var(--brand);
}
.badge--violet {
  background: var(--violet-soft);
  color: var(--violet);
}
.badge--cyan {
  background: var(--cyan-soft);
  color: var(--cyan);
}
.badge--grey {
  background: var(--surface-3);
  color: var(--text-2);
}
.badge i {
  font-size: 10px;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: var(--radius-full);
  background: var(--surface-3);
  color: var(--text-2);
}

.avatar {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  background: linear-gradient(135deg, var(--brand), var(--violet));
}

.icon-btn.avatar:hover{
  background: linear-gradient(135deg, var(--brand), var(--violet));
  color: #dadada;
}

.avatar--sm {
  width: 30px;
  height: 30px;
  font-size: 11px;
}
.avatar--lg {
  width: 48px;
  height: 48px;
  font-size: 16px;
}
.avatar--green {
  background: linear-gradient(135deg, #12b76a, #0d9488);
}
.avatar--amber {
  background: linear-gradient(135deg, #f79009, #ea580c);
}
.avatar--cyan {
  background: linear-gradient(135deg, #06aed4, #0284c7);
}
.avatar--violet {
  background: linear-gradient(135deg, #7a5af8, #6d28d9);
}
.avatar .status-dot {
  position: absolute;
  bottom: 1px;
  right: 1px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--surface);
}
.status-dot--online {
  background: var(--success);
}
.status-dot--busy {
  background: var(--warning);
}
.status-dot--offline {
  background: var(--text-3);
}

/* --------------------------------------------------------------------------
   15. Forms
   -------------------------------------------------------------------------- */
.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-top: 16px;
}

.field label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
}
.field label .req {
  color: var(--danger);
}
.field .hint {
  font-size: 12px;
  color: var(--text-3);
}

.input,
.select,
.textarea {
  width: 100%;
  font-family: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  padding: 11px 14px;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}
.input::placeholder,
.textarea::placeholder {
  color: var(--text-3);
}
.input:focus,
.select:focus,
.textarea:focus {
  outline: 0;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-ring);
}
.select {
  appearance: none;
  -webkit-appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text-3) 50%),
    linear-gradient(135deg, var(--text-3) 50%, transparent 50%);
  background-position:
    calc(100% - 18px) 50%,
    calc(100% - 13px) 50%;
  background-size: 5px 5px;
  background-repeat: no-repeat;
  padding-right: 38px;
  cursor: pointer;
}
.textarea {
  min-height: 100px;
  resize: vertical;
}
.input-group {
  display: flex;
  gap: 10px;
}
.form-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 16px;
}

.checkbox,
.radio {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--text-2);
  cursor: pointer;
  user-select: none;
}
.checkbox input,
.radio input {
  width: 18px;
  height: 18px;
  accent-color: var(--brand);
  cursor: pointer;
}

.switch {
  position: relative;
  display: inline-block;
  width: 44px;
  height: 24px;
  flex: none;
}
.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}
.switch .track {
  position: absolute;
  inset: 0;
  background: var(--border-strong);
  border-radius: var(--radius-full);
  transition: background 0.15s ease;
  cursor: pointer;
}
.switch .track::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.18s ease;
  box-shadow: var(--shadow-sm);
}
.switch input:checked + .track {
  background: var(--brand);
}
.switch input:checked + .track::before {
  transform: translateX(20px);
}

/* Toggle field rows */
.toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}
.toggle-row:last-child {
  border-bottom: 0;
}
.toggle-row h4 {
  font-size: 14px;
  font-weight: 600;
}
.toggle-row p {
  font-size: 12.5px;
  color: var(--text-2);
  margin-top: 2px;
}

/* --------------------------------------------------------------------------
   16. Dropdowns / menus
   -------------------------------------------------------------------------- */
.dropdown {
  position: relative;
}
.dropdown-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 230px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 6px;
  z-index: 70;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition:
    opacity 0.16s ease,
    transform 0.16s ease,
    visibility 0.16s;
}
.dropdown.open .dropdown-menu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.menu-head {
  padding: 10px 12px 8px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.menu-head h4 {
  font-size: 13px;
  font-weight: 700;
}
.menu-head p {
  font-size: 12px;
  color: var(--text-3);
}
.menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 12px;
  border-radius: 8px;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 14px;
  color: var(--text-2);
  cursor: pointer;
  text-align: left;
  transition:
    background 0.12s ease,
    color 0.12s ease;
}
.menu-item i {
  width: 16px;
  text-align: center;
  color: var(--text-3);
}
.menu-item:hover {
  background: var(--surface-2);
  color: var(--text);
}
.menu-item:hover i {
  color: var(--text-2);
}
.menu-item--danger,
.menu-item--danger i {
  color: var(--danger);
}
.menu-item--danger:hover {
  background: var(--danger-soft);
  color: var(--danger);
}
.menu-item--danger:hover i {
  color: var(--danger);
}
.menu-divider {
  height: 1px;
  background: var(--border);
  margin: 6px;
}

.notif-item {
  display: flex;
  gap: 12px;
  padding: 12px;
  border-radius: 10px;
}
.notif-item:hover {
  background: var(--surface-2);
}
.notif-item .notif-body {
  min-width: 0;
}
.notif-item .notif-body p {
  font-size: 13.5px;
  color: var(--text-2);
}
.notif-item .notif-body strong {
  color: var(--text);
  font-weight: 600;
}
.notif-item .notif-time {
  font-size: 12px;
  color: var(--text-3);
  margin-top: 2px;
}
.dropdown-menu--wide {
  min-width: 320px;
}
.dropdown-menu--wide .card-foot {
  border: 0;
  padding: 8px 12px 4px;
  justify-content: center;
}

/* --------------------------------------------------------------------------
   17. Charts (pure CSS / SVG)
   -------------------------------------------------------------------------- */
.bars {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  height: 190px;
  padding-top: 10px;
}
.bar-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  height: 100%;
  justify-content: flex-end;
  min-width: 0;
}
.bar-track {
  flex: 1;
  width: 100%;
  max-width: 44px;
  display: flex;
  align-items: flex-end;
  border-radius: 8px 8px 4px 4px;
  background: var(--surface-3);
  overflow: hidden;
}
.bar-fill {
  width: 100%;
  border-radius: 8px 8px 4px 4px;
  background: linear-gradient(
    180deg,
    var(--brand),
    color-mix(in srgb, var(--brand) 55%, transparent)
  );
  animation: grow-bar 0.8s ease;
  min-height: 2px;
}
.bar-fill--violet {
  background: linear-gradient(
    180deg,
    var(--violet),
    color-mix(in srgb, var(--violet) 55%, transparent)
  );
}
.bar-fill--green {
  background: linear-gradient(
    180deg,
    var(--success),
    color-mix(in srgb, var(--success) 55%, transparent)
  );
}
.bar-fill--amber {
  background: linear-gradient(
    180deg,
    var(--warning),
    color-mix(in srgb, var(--warning) 55%, transparent)
  );
}
.bar-label {
  font-size: 12px;
  color: var(--text-3);
  font-weight: 600;
  white-space: nowrap;
}
.bar-value {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-2);
}
@keyframes grow-bar {
  from {
    transform: scaleY(0);
    transform-origin: bottom;
  }
  to {
    transform: scaleY(1);
  }
}

.progress {
  display: flex;
  align-items: center;
  gap: 10px;
}
.progress-track {
  flex: 1;
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--surface-3);
  overflow: hidden;
}
.progress-fill {
  height: 100%;
  border-radius: var(--radius-full);
  background: linear-gradient(
    90deg,
    var(--brand),
    color-mix(in srgb, var(--brand) 65%, #a5f3fc)
  );
}
.progress-fill--green {
  background: linear-gradient(
    90deg,
    var(--success),
    color-mix(in srgb, var(--success) 60%, #d1fae5)
  );
}
.progress-fill--amber {
  background: linear-gradient(
    90deg,
    var(--warning),
    color-mix(in srgb, var(--warning) 60%, #fef3c7)
  );
}
.progress-fill--red {
  background: linear-gradient(
    90deg,
    var(--danger),
    color-mix(in srgb, var(--danger) 60%, #fee2e2)
  );
}
.progress-fill--violet {
  background: linear-gradient(
    90deg,
    var(--violet),
    color-mix(in srgb, var(--violet) 60%, #ede9fe)
  );
}
.progress-num {
  font-size: 13px;
  font-weight: 700;
  color: var(--text-2);
  min-width: 38px;
  text-align: right;
}

.donut-wrap {
  display: flex;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
}
.donut {
  position: relative;
  width: 170px;
  height: 170px;
  border-radius: 50%;
  flex: none;
}
.donut::after {
  content: "";
  position: absolute;
  inset: 26px;
  border-radius: 50%;
  background: var(--surface);
}
.donut-center {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.donut-center strong {
  display: block;
  max-width: 110px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 24px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.donut-center span {
  display: block;
  max-width: 104px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 12px;
  color: var(--text-3);
}
.legend {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.legend-item {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13.5px;
  color: var(--text-2);
}
.legend-swatch {
  width: 12px;
  height: 12px;
  border-radius: 4px;
  flex: none;
}
.legend-item strong {
  margin-left: auto;
  color: var(--text);
}

.spark-title {
  font-size: 12px;
  color: var(--text-3);
  font-weight: 600;
  margin-bottom: 2px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* --------------------------------------------------------------------------
   18. Tabs
   -------------------------------------------------------------------------- */
.tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  margin-bottom: 22px;
}
.tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-2);
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition:
    color 0.15s ease,
    border-color 0.15s ease;
  font-family: inherit;
}
.tab:hover {
  color: var(--text);
}
.tab.is-active {
  color: var(--brand);
  border-bottom-color: var(--brand);
}

/* --------------------------------------------------------------------------
   19. Misc components
   -------------------------------------------------------------------------- */
.avatar-stack {
  display: flex;
}
.avatar-stack .avatar {
  border: 2px solid var(--surface);
  margin-left: -10px;
}
.avatar-stack .avatar:first-child {
  margin-left: 0;
}

.empty-state {
  text-align: center;
  padding: 44px 20px;
  color: var(--text-2);
}
.empty-state i {
  font-size: 40px;
  color: var(--text-3);
  background: var(--surface-2);
  width: 84px;
  height: 84px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  margin-bottom: 16px;
}
.empty-state h3 {
  font-size: 16px;
  color: var(--text);
  margin-bottom: 6px;
}
.empty-state p {
  font-size: 14px;
  max-width: 320px;
  margin: 0 auto 18px;
}

.ktl {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.ktl + .ktl {
  margin-top: 10px;
}
.ktl:hover {
  border-color: var(--border-strong);
  background: var(--surface-2);
}
.ktl-left {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.ktl-icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  flex: none;
}
.ktl-body {
  min-width: 0;
}
.ktl-body strong {
  display: block;
  font-size: 14px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ktl-body span {
  font-size: 12.5px;
  color: var(--text-3);
}

.timeline {
  position: relative;
}
.timeline::before {
  content: "";
  position: absolute;
  left: 19px;
  top: 6px;
  bottom: 6px;
  width: 2px;
  background: var(--border);
}
.timeline-item {
  position: relative;
  display: flex;
  gap: 14px;
  padding-bottom: 18px;
}
.timeline-item:last-child {
  padding-bottom: 0;
}
.timeline-dot {
  position: relative;
  z-index: 1;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  flex: none;
  color: var(--brand);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-xs);
}
.timeline-item strong {
  font-size: 14px;
  color: var(--text);
  display: block;
}
.timeline-item p {
  font-size: 13px;
  color: var(--text-2);
  margin-top: 2px;
}
.timeline-item time {
  font-size: 12px;
  color: var(--text-3);
  margin-top: 4px;
  display: block;
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.toolbar .search {
  flex: 1;
  min-width: 220px;
}
.toolbar .spacer {
  flex: 1;
}

.pagination {
  display: flex;
  align-items: center;
  gap: 6px;
}
.pagination .icon-btn {
  width: 36px;
  height: 36px;
  font-size: 13px;
}
.pagination .pg {
  min-width: 36px;
  height: 36px;
  padding: 0 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-2);
}
.pagination .pg:hover {
  background: var(--surface-2);
}

/* --- Dashboard app footer --- */
.app-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 16px 0 0;
  margin-top: 28px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  color: var(--text-3);
}
.app-footer-left,
.app-footer-right {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.app-footer strong {
  font-weight: 600;
}
.app-footer a {
  color: var(--text-3);
  text-decoration: none;
  padding: 4px 6px;
  border-radius: 8px;
  transition:
    color 0.15s ease,
    background 0.15s ease;
}
.app-footer a:hover {
  color: var(--brand);
  background: var(--brand-soft);
}
.app-footer .dot-sep {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--border-strong);
}
.footer-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.footer-top {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  color: var(--text-2);
  cursor: pointer;
  font-size: 13px;
  transition:
    background 0.15s ease,
    color 0.15s ease,
    border-color 0.15s ease;
}
.footer-top:hover {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}

@media (max-width: 767px) {
  .app-footer {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 8px;
    padding-top: 18px;
    margin-top: 24px;
  }
  .app-footer-left,
  .app-footer-right {
    justify-content: center;
    width: 100%;
  }
  .app-footer-right {
    gap: 2px;
  }
  .app-footer a {
    padding: 8px 10px;
  }
  .footer-top {
    margin-inline-start: 4px;
  }
}

[data-sidebar-collapse] i {
  transition: transform 0.25s ease;
}
body.sidebar-collapsed [data-sidebar-collapse] i {
  transform: rotate(180deg);
}

.sidebar,
.topbar,
.main,
.card,
.surface,
.btn,
.icon-btn,
.input,
.select,
.nav-link,
.dropdown-menu {
  transition:
    background-color 0.3s ease,
    color 0.3s ease,
    border-color 0.25s ease,
    box-shadow 0.25s ease;
}
.pagination .pg.is-active {
  background: var(--brand);
  color: #fff;
}

/* Toast */
.toast-wrap {
  position: fixed;
  bottom: 22px;
  right: 22px;
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.toast {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--text);
  color: var(--bg);
  font-size: 14px;
  font-weight: 500;
  padding: 12px 16px;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  transform: translateY(14px);
  opacity: 0;
  transition:
    transform 0.25s ease,
    opacity 0.25s ease;
  max-width: 340px;
}

.toast-error{
  background: #dc2626;
  color: #fff;
}

.toast-success{
  background: #16a34a;
  color: #fff;
}

.toast.show {
  transform: translateY(0);
  opacity: 1;
}
.toast i {
  color: var(--success);
}

.toast-error i{
  color: #ccc;
}

.loading i{
  transition: all 1s ease-in-out;
  animation: rotate 3s forwards infinite;
}

@keyframes rotate {
  0%{
    transform: rotate(90deg);
  } 
  25%{
    transform: rotate(180deg);
  } 
  75%{
    transform: rotate(270deg);
  }
  100%{
    transform: rotate(360deg);
  }
}


.toast-success i{
   color: #fff;
}

/* Modal (non-functional stub) */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(9, 13, 24, 0.6);
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding: 24px;
  overflow-y: auto;
}
.modal-backdrop.open {
  display: flex;
}
.modal {
  width: 100%;
  max-width: 560px;
  margin-top: 6vh;
  background: var(--surface);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  animation: modal-in 0.22s ease;
}
@keyframes modal-in {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 20px;
  border-bottom: 1px solid var(--border);
}
.modal-head h3 {
  font-size: 16px;
  font-weight: 700;
}
.modal-body {
  padding: 20px;
}
.modal-foot {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 16px 20px;
  border-top: 1px solid var(--border);
}

/* --------------------------------------------------------------------------
   20. Auth (login / register) page
   -------------------------------------------------------------------------- */
.auth-page {
  --auth-surface: var(--surface);
  min-height: 100vh;
  display: flex;
  align-items: stretch;
  background: var(--bg);
  color: var(--text);
}

/* ---- Left: fixed brand showcase ----------------------------------------- */
.auth-brand {
  position: sticky;
  top: 0;
  align-self: flex-start;
  height: 100vh;
  flex: 1.05;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 28px;
  padding: 48px 56px;
  color: #fff;
  overflow: hidden;
  isolation: isolate;
  background:
    radial-gradient(
      920px 620px at 116% -12%,
      color-mix(in srgb, var(--mark-accent, #2563eb) 68%, transparent),
      transparent 58%
    ),
    radial-gradient(
      760px 540px at -16% 114%,
      color-mix(in srgb, var(--brand, #2563eb) 52%, transparent),
      transparent 60%
    ),
    linear-gradient(
      157deg,
      #0a1430 0%,
      #122250 48%,
      color-mix(in srgb, var(--mark-accent, #2563eb) 90%, #0a1430) 132%
    );
}
.auth-brand::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.055) 1px, transparent 1px);
  background-size: 44px 44px;
  -webkit-mask-image: radial-gradient(125% 95% at 50% 0%, #000 30%, transparent 82%);
  mask-image: radial-gradient(125% 95% at 50% 0%, #000 30%, transparent 82%);
  pointer-events: none;
}
.auth-brand::after {
  content: "";
  position: absolute;
  z-index: -1;
  right: -170px;
  bottom: -190px;
  width: 540px;
  height: 540px;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 32%, rgba(255, 255, 255, 0.2), transparent 62%);
  filter: blur(6px);
  pointer-events: none;
  animation: auth-orb 16s ease-in-out infinite;
}
@keyframes auth-orb {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(-28px, -36px, 0) scale(1.07); }
}
@media (prefers-reduced-motion: reduce) {
  .auth-brand::after { animation: none; }
}
.auth-brand * {
  position: relative;
  z-index: 1;
}
.auth-brand .brand {
  border: 0;
  padding: 0;
  min-height: 0;
}
.auth-brand .brand-name {
  color: #fff;
  font-size: 18px;
  letter-spacing: -0.01em;
}
.auth-brand .brand-sub {
  color: rgba(255, 255, 255, 0.7);
  letter-spacing: 0.01em;
}
.auth-brand-body {
  display: flex;
  flex-direction: column;
  gap: 22px;
  max-width: 470px;
}
.auth-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: fit-content;
  padding: 7px 14px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: #e8f1ff;
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.auth-eyebrow i {
  color: #ffd873;
  font-size: 11px;
}
.auth-brand-body h1 {
  margin: 0;
  font-size: clamp(30px, 3vw, 44px);
  line-height: 1.1;
  font-weight: 800;
  letter-spacing: -0.025em;
  text-wrap: balance;
}
.auth-brand-lead {
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.82);
  max-width: 430px;
}
.auth-features {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 8px;
}
.auth-features li {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px 16px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: transform 0.18s ease, background 0.18s ease, border-color 0.18s ease;
}
.auth-features li:hover {
  transform: translateY(-2px);
  background: rgba(255, 255, 255, 0.11);
  border-color: rgba(255, 255, 255, 0.22);
}
.auth-feature-ico {
  flex: none;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  font-size: 14px;
  color: #fff;
  background: linear-gradient(140deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.08));
  border: 1px solid rgba(255, 255, 255, 0.2);
}
.auth-features li div {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.auth-features li strong {
  font-size: 14px;
  font-weight: 600;
  color: #fff;
}
.auth-features li div span {
  font-size: 13px;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.72);
}
.auth-brand-foot p {
  margin: 0;
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.6);
}

/* ---- Right: form panel --------------------------------------------------- */
.auth-panel {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
}
.auth-card {
  width: 100%;
  max-width: 430px;
}
.auth-card .brand {
  border: 0;
  padding: 0 0 20px;
  min-height: 0;
}
.auth-logo-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 26px;
}
.auth-logo-row .brand-name {
  font-size: 17px;
}
.auth-card h2 {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.025em;
}
.auth-card .lead {
  color: var(--text-2);
  font-size: 14px;
  margin: 6px 0 24px;
}
.auth-alt {
  text-align: center;
  font-size: 14px;
  color: var(--text-2);
  margin-top: 20px;
}
.auth-alt a {
  font-weight: 600;
}

@media (max-width: 920px) {
  .auth-brand {
    display: none;
  }
  .auth-panel {
    padding: 32px 18px;
  }
}

/* --------------------------------------------------------------------------
   21. Landing page
   -------------------------------------------------------------------------- */
.landing-page {
  background: var(--bg);
}
.landing-nav {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 26px;
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
.landing-nav .spacer {
  flex: 1;
}
.landing-nav .nav-link-2 {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-2);
  padding: 8px 10px;
  border-radius: 8px;
}
.landing-nav .nav-link-2:hover {
  color: var(--text);
  background: var(--surface-2);
}
.landing-hero {
  text-align: center;
  padding: 90px 24px 70px;
  position: relative;
  overflow: hidden;
}
.landing-hero::before {
  content: "";
  position: absolute;
  inset: -20% -10% auto;
  height: 60%;
  background:
    radial-gradient(600px 260px at 20% 0, var(--brand-soft), transparent 60%),
    radial-gradient(600px 260px at 80% 10%, var(--violet-soft), transparent 60%);
  pointer-events: none;
}
.landing-hero h1 {
  font-size: clamp(32px, 5vw, 52px);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
  max-width: 720px;
  margin: 0 auto 18px;
}
.landing-hero h1 span {
  color: var(--brand);
}
.landing-hero p {
  font-size: 17px;
  color: var(--text-2);
  max-width: 560px;
  margin: 0 auto 30px;
}
.landing-hero .hero-cta {
  display: flex;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}
.landing-features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px;
  padding: 30px 26px 70px;
  max-width: 1200px;
  margin: 0 auto;
}
.landing-features .card {
  padding: 26px;
}
.landing-features .ktl-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  font-size: 18px;
  margin-bottom: 14px;
}
.landing-features h3 {
  font-size: 16px;
  margin-bottom: 8px;
}
.landing-features p {
  font-size: 14px;
  color: var(--text-2);
}
.landing-cta {
  text-align: center;
  padding: 60px 24px;
  background: var(--surface);
  border-top: 1px solid var(--border);
}
.landing-cta h2 {
  font-size: 28px;
  font-weight: 800;
  margin-bottom: 10px;
}
.landing-cta p {
  color: var(--text-2);
  margin-bottom: 22px;
}
.landing-footer {
  border-top: 1px solid var(--border);
  padding: 22px 26px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  color: var(--text-3);
  font-size: 13px;
}

/* --------------------------------------------------------------------------
   22. Utilities
   -------------------------------------------------------------------------- */
.flex {
  display: flex;
  align-items: center;
  gap: 10px;
}
.flex-between {
  justify-content: space-between;
}
.wrap {
  flex-wrap: wrap;
}
.shrink-0 {
  flex: none;
}
.grow {
  flex: 1;
  min-width: 0;
}
.mt-0 {
  margin-top: 0;
}
.mt-1 {
  margin-top: 6px;
}
.mt-2 {
  margin-top: 12px;
}
.mt-3 {
  margin-top: 18px;
}
.mt-4 {
  margin-top: 26px;
}
.mb-0 {
  margin-bottom: 0;
}
.mb-1 {
  margin-bottom: 6px;
}
.mb-2 {
  margin-bottom: 12px;
}
.mb-3 {
  margin-bottom: 18px;
}
.mb-4 {
  margin-bottom: 26px;
}
.text-2 {
  color: var(--text-2);
}
.text-3 {
  color: var(--text-3);
}
.text-brand {
  color: var(--brand);
}
.text-success {
  color: var(--success);
}
.text-danger {
  color: var(--danger);
}
.text-warning {
  color: var(--warning);
}
.fw-6 {
  font-weight: 600;
}
.fw-7 {
  font-weight: 700;
}
.fs-2 {
  font-size: 12px;
}
.fs-3 {
  font-size: 13px;
}
.fs-4 {
  font-size: 14px;
}
.select-inline {
  width: auto;
  min-width: 150px;
}
.truncate {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hide-lg {
  display: none;
}

/* Responsive visibility helpers */
@media (max-width: 1023px) {
  .hide-mobile {
    display: none !important;
  }
  .topbar-search {
    display: none;
  }
}
@media (min-width: 1024px) {
  .hide-desktop {
    display: none !important;
  }
}

/* --------------------------------------------------------------------------
   23. Sidebar — professional polish (overrides)
   -------------------------------------------------------------------------- */
.sidebar {
  background:
    radial-gradient(280px 170px at 0% 0%, var(--brand-softer), transparent 60%),
    linear-gradient(180deg, var(--surface) 0%, var(--surface-2) 100%);
}

.sidebar .brand {
  min-height: calc(var(--topbar-h) - 1px);
  padding: 16px 20px;
}

.sidebar .brand-name {
  font-size: 15px;
}

.brand-pill {
  display: inline-block;
  margin-top: 3px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--brand);
  background: var(--brand-soft);
  padding: 2px 8px;
  border-radius: var(--radius-full);
}

.sidebar-nav {
  padding: 18px 14px 26px;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}

.nav-group + .nav-group {
  margin-top: 24px;
}

.nav-group-title {
  margin: 0 10px 9px;
  font-size: 10.5px;
  letter-spacing: 0.1em;
}

.nav-link {
  position: relative;
  min-height: 44px;
  gap: 12px;
  padding: 9px 10px;
  margin-bottom: 3px;
  border-radius: 12px;
  font-size: 13.5px;
  font-weight: 500;
}

.nav-link::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 3px;
  height: 18px;
  border-radius: 0 6px 6px 0;
  background: var(--brand);
  opacity: 0;
  transform: translateY(-50%) scaleY(0.4);
  transition:
    opacity 0.18s ease,
    transform 0.18s ease;
}

.nav-link:hover {
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  color: var(--text);
}

.nav-link:hover::before {
  opacity: 0.4;
}

.nav-icon {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9px;
  background: var(--surface-3);
  color: var(--text-2);
  font-size: 14px;
  flex: none;
  transition:
    background 0.16s ease,
    color 0.16s ease,
    box-shadow 0.16s ease;
}

.nav-link:hover .nav-icon {
  background: var(--surface);
  color: var(--text);
}

.nav-link.is-active {
  background: linear-gradient(
    90deg,
    var(--brand-soft),
    color-mix(in srgb, var(--brand-soft) 30%, transparent) 85%,
    transparent
  );
  color: var(--brand);
  font-weight: 600;
}

.nav-link.is-active::before {
  opacity: 1;
  transform: translateY(-50%) scaleY(1);
}

.nav-link.is-active .nav-icon {
  background: var(--brand);
  color: #fff;
  box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--brand) 75%, transparent);
}

/* Collapsed rail polish */
body.sidebar-collapsed .sidebar-nav {
  padding: 18px 14px;
}
body.sidebar-collapsed .nav-group + .nav-group {
  margin-top: 26px;
}

/* Collapsed footer: pro-card tucks down to an icon-only bolt */
body.sidebar-collapsed .sidebar-foot {
  padding: 12px 14px 16px;
}
body.sidebar-collapsed .pro-card {
  display: flex;
  justify-content: center;
  padding: 0;
  background: none;
  box-shadow: none;
  margin-bottom: 8px;
}
body.sidebar-collapsed .pro-card::after,
body.sidebar-collapsed .pro-card h4,
body.sidebar-collapsed .pro-card p,
body.sidebar-collapsed .pro-card-cta {
  display: none;
}
body.sidebar-collapsed .pro-card-bolt {
  position: static;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--brand);
  color: #fff;
  font-size: 15px;
  box-shadow: 0 6px 14px -6px color-mix(in srgb, var(--brand) 75%, transparent);
}

/* Footer */
.sidebar-foot {
  padding: 12px 14px 16px;
  border-top: 1px solid var(--border);
  background: color-mix(in srgb, var(--surface) 55%, transparent);
}

.pro-card {
  position: relative;
  overflow: hidden;
  border-radius: 14px;
  padding: 14px 14px 13px;
  margin-bottom: 12px;
  color: #fff;
  background: linear-gradient(
    135deg,
    var(--brand) 0%,
    color-mix(in srgb, var(--brand) 52%, var(--violet)) 130%
  );
  box-shadow: 0 10px 22px -10px
    color-mix(in srgb, var(--brand) 65%, transparent);
}
.pro-card::after {
  content: "";
  position: absolute;
  right: -34px;
  top: -34px;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
}
.pro-card-bolt {
  position: absolute;
  right: 14px;
  top: 14px;
  font-size: 15px;
  opacity: 0.9;
}
.pro-card h4 {
  position: relative;
  font-size: 13px;
  font-weight: 800;
  margin-bottom: 3px;
}
.pro-card p {
  position: relative;
  font-size: 11.5px;
  opacity: 0.85;
  line-height: 1.45;
  margin-bottom: 11px;
}
.pro-card-cta {
  position: relative;
  background: #fff;
  color: var(--brand);
  box-shadow: none;
  font-size: 12.5px;
}
.pro-card-cta:hover {
  background: #f0f5ff;
  color: var(--brand);
}

.user-chip {
  gap: 11px;
  padding: 9px;
  border-radius: 12px;
}
.user-chip:hover {
  background: var(--surface);
  box-shadow: var(--shadow-xs);
}
.user-meta strong {
  font-size: 13px;
}
.user-meta span {
  font-size: 11.5px;
}

@media (max-width: 1023px) {
  .sidebar .brand {
    padding: 16px 20px;
  }
}

/* Screen-reader-only text. Used where a control needs an accessible name but
   the visual design has no room for a visible label, such as the timetable
   class picker and the icon-only action column header. */
.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;
}

/* Display a span on its own line inside a table cell. */
.d-block {
  display: block;
}

/* Red variant for the room-utilisation bars. The amber variant was already
   used for "getting full", so an over-booked room needed its own tone rather
   than reusing amber for two different meanings. */
.bar-fill--red {
  background: linear-gradient(
    180deg,
    var(--danger),
    color-mix(in srgb, var(--danger) 55%, transparent)
  );
}

/* Timetable grid. Each lesson cell is a button filling the whole cell so the
   click target matches the visual cell, which is what makes the grid editable
   without a separate edit icon on every lesson. */
.tt-cell {
  display: block;
  width: 100%;
  min-height: 54px;
  text-align: left;
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface-2);
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.tt-cell:hover {
  border-color: var(--brand);
  background: var(--brand-soft);
}
.tt-cell:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
.tt-cell--empty {
  border-style: dashed;
  background: transparent;
}
.tt-cell-add {
  font-size: 12px;
  color: var(--text-3);
  font-weight: 600;
}
.tt-cell-meta {
  display: block;
  margin-top: 4px;
  font-size: 11px;
  color: var(--text-3);
  line-height: 1.35;
}
.tt-cell-meta i {
  font-size: 9px;
}

/* A break spans the week: the label repeats in every day cell rather than
   leaving a confusing empty box. */
.tt-break {
  display: block;
  padding: 8px;
  border-radius: 6px;
  background: var(--surface-3);
  color: var(--text-3);
  font-size: 11px;
  font-weight: 600;
  text-align: center;
}
.tt-break-row td {
  background: var(--surface-3);
}

/* The teacher's own day above the grid. */
.tt-daylist {
  display: grid;
  gap: 8px;
}
.tt-daylist-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
}

/* Printing a timetable: drop the controls, keep the grid, and let the sheet
   use the full width instead of the dashboard's max-width. */
@media print {
  .no-print,
  .sidebar,
  .topbar,
  .toolbar,
  .page-actions,
  .card-foot,
  .toast-wrap,
  .modal-backdrop {
    display: none !important;
  }
  .tt-grid {
    min-width: 0 !important;
    font-size: 11px;
  }
  .tt-cell {
    border-color: #999;
    min-height: 40px;
  }
  .tt-cell-add,
  .tt-cell-meta,
  .tt-break {
    color: #444;
  }
}

/* Permission matrix: a permission-per-row grid with one column per role.
   The matrix is long and wider than the viewport, so .table-wrap scrolls on
   both axes; the header pins to the top of that scrollport (as the finance
   ledger does) so the role labels stay visible while the rows scroll. */
.table .cell-center {
  text-align: center;
}
.perm-matrix {
  min-width: 640px;
}
@media (min-width: 768px) {
  .table-wrap:has(> .perm-matrix) {
    max-height: calc(100vh - 240px);
    overflow-y: auto;
  }
}
.perm-matrix thead th {
  vertical-align: top;
  position: sticky;
  top: 0;
  z-index: 2;
  /* border-collapse strips the collapsed border off a sticky cell */
  box-shadow: inset 0 -1px 0 var(--border);
}
.perm-group-row td {
  background: var(--surface-2);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding-top: 8px;
  padding-bottom: 8px;
}
.perm-group-row strong {
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-2);
}
.perm-label {
  font-weight: 600;
}
.perm-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.perm-check input {
  width: 17px;
  height: 17px;
  accent-color: var(--brand, #2563eb);
  cursor: pointer;
}
@media (max-width: 720px) {
  .perm-matrix.table-stack {
    min-width: 0;
  }
  .perm-matrix.table-stack thead {
    display: none;
  }
  .perm-matrix.table-stack .perm-group-row td {
    display: block;
  }
}

/* --------------------------------------------------------------------------
   Report card sheet
   -------------------------------------------------------------------------- */
.report-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 28px clamp(18px, 4vw, 40px);
  max-width: 980px;
  margin-inline: auto;
}
.report-card-head {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  justify-content: space-between;
  border-bottom: 2px solid var(--line);
  padding-bottom: 16px;
}
.report-card-brand {
  display: flex;
  align-items: center;
  gap: 14px;
}
.report-card-brand h2 {
  margin: 0;
  font-size: 20px;
}
.report-card-brand p {
  margin: 2px 0 0;
  color: var(--text-3);
  font-size: 13px;
}
.report-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.report-card-details {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin: 18px 0;
}
.report-card-details div {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  background: var(--surface-2);
  border-radius: 10px;
}
.report-card-details span {
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-3);
}
.report-card-comments {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
  margin-top: 20px;
}
.report-comment h4 {
  margin: 0 0 6px;
  font-size: 13px;
  color: var(--text-2);
}
.report-comment p {
  margin: 0;
  padding: 12px;
  min-height: 64px;
  background: var(--surface-2);
  border-radius: 10px;
  font-size: 13px;
}
.report-card-sign {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: space-between;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--text-3);
}
@media print {
  .app-footer,
  .report-card-sign,
  .breadcrumb,
  .topbar-breadcrumb,
  .sub-banner {
    display: none !important;
  }
  .report-card {
    border: none;
    padding: 0;
    max-width: none;
  }
}

/* Subscription banner: shown in place of the old forced logout when a school's
   plan lapses (expired / cancelled / past due). */
.sub-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 18px;
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface-2);
}
.sub-banner-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  font-size: 15px;
}
.sub-banner-body {
  flex: 1 1 auto;
  min-width: 0;
}
.sub-banner-body strong {
  display: block;
  font-size: 13px;
}
.sub-banner-body p {
  margin: 2px 0 0;
  font-size: 12.5px;
  color: var(--text-3);
}
.sub-banner-cta {
  flex: 0 0 auto;
  white-space: nowrap;
}
.sub-banner--danger {
  border-color: color-mix(in srgb, var(--danger) 35%, transparent);
  background: var(--danger-soft);
}
.sub-banner--danger .sub-banner-icon {
  background: color-mix(in srgb, var(--danger) 22%, transparent);
  color: var(--danger);
}
.sub-banner--amber {
  border-color: color-mix(in srgb, var(--warning) 40%, transparent);
  background: var(--warning-soft);
}
.sub-banner--amber .sub-banner-icon {
  background: color-mix(in srgb, var(--warning) 24%, transparent);
  color: var(--warning);
}
@media (max-width: 640px) {
  .sub-banner {
    flex-wrap: wrap;
  }
  .sub-banner-cta {
    width: 100%;
    justify-content: center;
  }
}

/* --------------------------------------------------------------------------
   24. Phones / touch
   --------------------------------------------------------------------------
   Additive overrides for narrow viewports only. The shell is already
   responsive (off-canvas drawer, `.table-stack` cards, collapsing grids);
   this section closes the remaining phone gaps: iOS zoom-on-focus, small tap
   targets, a topbar that can push the page wider than the screen, dropdown
   menus that clip off the left edge, and a modal that crowds the edges. */

/* Form controls stay at 16px on phones — anything smaller makes iOS Safari
   zoom the whole page the moment a field is focused. The coarse-pointer branch
   also covers phones held in landscape, which are wider than 767px. */
@media (max-width: 767px), (hover: none) and (pointer: coarse) {
  .input,
  .select,
  .textarea {
    font-size: 16px;
  }
}

/* Comfortable touch targets — the accepted ~44px minimum. */
@media (max-width: 767px), (hover: none) and (pointer: coarse) {
  .btn {
    min-height: 44px;
  }
  .btn-icon,
  .icon-btn {
    width: 44px;
    height: 44px;
  }
  .topbar .icon-btn {
    flex: none;
  }
  .btn-sm {
    min-height: 44px;
  }
  .menu-item {
    min-height: 44px;
  }
  .pagination .icon-btn,
  .pagination .pg {
    min-width: 44px;
    height: 44px;
  }
  .footer-top {
    width: 44px;
    height: 44px;
  }
}

/* The topbar breadcrumb must be allowed to shrink, otherwise its min-content
   width plus the action cluster pushes the whole page into horizontal scroll
   on the narrowest phones. The page title truncates with an ellipsis. */
@media (max-width: 767px) {
  .topbar {
    gap: 10px;
  }
  .topbar-breadcrumb {
    min-width: 0;
    overflow: hidden;
  }
  .topbar-breadcrumb small {
    min-width: 0;
    white-space: nowrap;
  }
  .topbar-breadcrumb small span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

@media (max-width: 480px) {
  .topbar {
    padding-left: 12px;
    padding-right: 12px;
  }
  .topbar-actions {
    gap: 6px;
  }
  .card-head {
    flex-wrap: wrap;
  }
}

/* Topbar menus drop as a full-width sheet below the bar. The notifications
   menu alone is 320px wide, which otherwise clips off the left edge of a
   360px phone. */
@media (max-width: 600px) {
  .topbar .dropdown-menu {
    position: fixed;
    left: 12px;
    right: 12px;
    top: calc(var(--topbar-h) + 6px);
    width: auto;
    min-width: 0;
    max-width: none;
    max-height: calc(100vh - var(--topbar-h) - 20px);
    overflow-y: auto;
  }
}

/* Modals: less inset, and stack their actions so both buttons are easy hits. */
@media (max-width: 600px) {
  .modal-backdrop {
    padding: 12px;
  }
  .modal {
    margin-top: 3vh;
  }
  .modal-foot {
    flex-wrap: wrap;
  }
  .modal-foot .btn {
    flex: 1 1 auto;
  }
}

/* The public landing page shares app.css. Tighten its generous desktop
   spacing on phones so the school name stays visible in the nav and the hero
   copy is not pushed below a large empty band. */
@media (max-width: 640px) {
  .landing-nav {
    padding: 12px 14px;
    gap: 10px;
  }
  .landing-hero {
    padding: 56px 20px 48px;
  }
  .landing-features {
    padding: 24px 20px 56px;
  }
  .landing-cta {
    padding: 48px 20px;
  }
  .landing-footer {
    padding: 20px;
  }
}
