/* ============================================================================
   VolTrack polish layer — app-wide micro-interactions & motion.

   Additive only. Loaded after app.css + ui.css on authenticated app pages
   (via partials/head.ejs). Adds the "alive / premium" feel: gentle content
   entrance, hover lift on cards, row hover on tables, animated nav + buttons,
   a styled file input, and stronger keyboard focus. Every animation is
   guarded by prefers-reduced-motion and NEVER hides content by default
   (elements are fully visible; the animation only plays FROM a start state),
   so a JS-off or reduced-motion user loses nothing.
   ============================================================================ */

:root {
  --pl-ease: cubic-bezier(.2, .7, .3, 1);
  --pl-ease-out: cubic-bezier(.16, 1, .3, 1);
}

/* ── Page content entrance ────────────────────────────────────────────────
   One soft rise+fade on the main content when a page loads. Content is
   visible regardless; the keyframe just plays in from a 10px offset. */
@keyframes pl-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
main > .container,
main > .container-fluid,
.app-main > .container,
main .page-header {
  animation: pl-rise .42s var(--pl-ease-out) both;
}

/* ── Cards: responsive-to-cursor hover ────────────────────────────────────
   Static cards get a soft shadow deepen on hover (no movement, so grids of
   cards never jiggle). Only cards that are actually clickable (links, or
   opted-in) get the small lift. Layout and click targets are unchanged. */
.card,
.ui-card {
  transition: transform .2s var(--pl-ease), box-shadow .2s var(--pl-ease),
              border-color .2s var(--pl-ease);
}
.card:hover,
.ui-card:hover {
  box-shadow: 0 10px 24px rgba(15, 23, 42, .09), 0 2px 6px rgba(15, 23, 42, .05);
}
/* Lift only clickable cards. */
a.card:hover,
.card--clickable:hover,
.ui-card--interactive:hover {
  transform: translateY(-3px);
  border-color: var(--ui-border-strong, #CBD2E0);
}

/* ── Tables: row hover + calmer separators ────────────────────────────────
   Makes long rosters/tables easier to scan across. */
table tbody tr {
  transition: background-color .14s var(--pl-ease), box-shadow .14s var(--pl-ease);
}
table tbody tr:hover {
  background-color: color-mix(in srgb, var(--ui-primary, #4F46E5) 5%, transparent);
}
/* Tabular figures so hours/counts line up column-to-column. Only affects
   digit glyphs, so it's safe on mixed text cells too. */
table td,
table th,
.stat-value, .stat-number, [class*="stat"] strong, [class*="metric"] {
  font-variant-numeric: tabular-nums;
}

/* ── Buttons: springier press + hover elevation ───────────────────────────
   Covers Bootstrap .btn and the .ui-btn system without changing sizes. */
.btn {
  transition: transform .12s var(--pl-ease), box-shadow .18s var(--pl-ease),
              background-color .18s var(--pl-ease), filter .18s var(--pl-ease);
}
.btn:not(:disabled):hover { transform: translateY(-1px); }
.btn:not(:disabled):active { transform: translateY(0); }
.btn-primary:not(:disabled):hover,
.ui-btn:not([disabled]):not([aria-disabled="true"]):hover {
  box-shadow: 0 6px 16px color-mix(in srgb, var(--ui-primary, #4F46E5) 30%, transparent);
}

/* ── Nav links: animated underline reveal ─────────────────────────────────
   Targets the app top-nav links (anchors inside the primary nav). */
nav a.nav-link,
nav .nav-link,
.app-nav a {
  position: relative;
}
nav a.nav-link::after,
.app-nav a:not(.btn)::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -2px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: left;
  opacity: .0;
  transition: transform .22s var(--pl-ease-out), opacity .22s var(--pl-ease-out);
}
nav a.nav-link:hover::after,
.app-nav a:not(.btn):hover::after {
  transform: scaleX(1);
  opacity: .5;
}

/* ── Progress bars: animate the fill ──────────────────────────────────────
   The roster/dashboard progress fills grow in instead of snapping. */
.progress-bar,
[class*="progress"] > [style*="width"] {
  transition: width .8s var(--pl-ease-out);
}

/* ── File input: match the design system ──────────────────────────────────
   The native "Choose File" control is the one off-brand element in the
   submit-hours form. Style the button portion to look like a secondary btn. */
input[type="file"] {
  font-size: var(--ui-fs-md, .875rem);
  color: var(--ui-text-2, #51607A);
}
input[type="file"]::file-selector-button {
  margin-right: 12px;
  padding: 8px 14px;
  font-family: inherit;
  font-size: var(--ui-fs-sm, .8125rem);
  font-weight: 600;
  color: var(--ui-text, #0F172A);
  background: var(--ui-surface, #fff);
  border: 1px solid var(--ui-border-strong, #CBD2E0);
  border-radius: var(--ui-radius, 10px);
  cursor: pointer;
  transition: background-color .15s var(--pl-ease), border-color .15s var(--pl-ease);
}
input[type="file"]::file-selector-button:hover {
  background: var(--ui-surface-2, #F6F7FB);
  border-color: var(--ui-primary, #4F46E5);
}

/* ── Keyboard focus: consistent, visible ring app-wide ────────────────────
   Bootstrap removes/varies focus styling; unify it for accessibility. */
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ui-primary, #4F46E5) 38%, transparent);
  border-radius: var(--ui-radius-sm, 6px);
}

/* ── Modal / dropdown entrance ────────────────────────────────────────────
   Soften Bootstrap dropdown menu appearance. */
.dropdown-menu.show {
  animation: pl-pop .16s var(--pl-ease-out) both;
}
@keyframes pl-pop {
  from { opacity: 0; transform: translateY(-6px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ── Mobile nav menu (the hamburger drawer) ───────────────────────────────
   The top nav is navbar-expand-lg, so below 992px it collapses. The stacked
   links inherited a horizontal-nav "pill" active state (a short floating band)
   and tight 6px padding (sub-44px touch targets), which read as unfinished.
   Give the open menu a real panel: full-width rows, 44px targets, dividers,
   and a clean left-accent active state instead of the floating pill. */
@media (max-width: 991.98px) {
  /* Keep the top bar on ONE row. The brand (a possibly long school name) plus
     the bell + avatar were filling the row, pushing the hamburger to wrap to a
     second line. Cap the brand and let it ellipsize so the toggler always fits. */
  .navbar-brand {
    min-width: 0;
    max-width: calc(100vw - 210px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .navbar-toggler { flex: 0 0 auto; }

  .navbar .navbar-collapse {
    margin-top: .6rem;
    padding-top: .35rem;
    border-top: 1px solid var(--ui-border, #E6E9F0);
  }
  .navbar .navbar-nav { gap: 2px; width: 100%; }
  .navbar .navbar-nav .nav-link {
    display: flex;
    align-items: center;
    gap: .1rem;
    min-height: 44px;                 /* comfortable touch target */
    padding: .6rem .8rem;
    border-radius: var(--ui-radius, 10px);
    font-weight: 500;
  }
  .navbar .navbar-nav .nav-link i { width: 1.4em; text-align: center; }
  .navbar .navbar-nav .nav-link:hover {
    background: var(--ui-surface-2, #F6F7FB);
  }
  /* Active row: full-width tint + a left accent bar (not a short pill). */
  .navbar .navbar-nav .nav-link.active {
    position: relative;
    background: var(--ui-primary-weak, #EEF2FF);
    font-weight: 600;
  }
  .navbar .navbar-nav .nav-link.active::before {
    content: "";
    position: absolute;
    left: 0; top: 8px; bottom: 8px;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--ui-primary, #4F46E5);
  }
}

/* ── Respect the user's motion preference ─────────────────────────────────
   Turn OFF all movement; keep the (instant) end states. */
@media (prefers-reduced-motion: reduce) {
  main > .container,
  main > .container-fluid,
  .app-main > .container,
  main .page-header,
  .dropdown-menu.show {
    animation: none;
  }
  .card, .ui-card, .btn, table tbody tr,
  .progress-bar, [class*="progress"] > [style*="width"],
  nav a.nav-link::after, .app-nav a:not(.btn)::after {
    transition: none;
  }
  .card:hover, .ui-card:hover,
  .btn:not(:disabled):hover, .btn:not(:disabled):active {
    transform: none;
  }
}
