/* ============================================================================
   Howzit Buddy, staff pages: finishing touches
   Loaded after app.css by teacher.php, admin.php and the staff sign-in and
   sign-up pages; never by the learner app. The aim is a calm, well-made tool:
   surfaces lift a little under the pointer, buttons catch the light, focus is
   always easy to see, and open safeguarding alerts glow softly. Only
   transform, opacity and box-shadow ever move, so nothing reflows, and every
   movement sits inside prefers-reduced-motion: no-preference. Focus styles,
   and the steady alert glow, apply to everyone.
   ========================================================================== */

/* ---------- The staff skin: the home page's wall, calmer ----------
   app.css paints the learner app with the home page's lit petrol wall. People
   reading safeguarding alerts all day get the same colours a notch quieter: a
   less saturated wall with the light low and off to one side, firmer cards so
   tables and numbers sit on a steady surface, and a darker rail. */
:root {
  --card:    rgba(3, 26, 42, 0.6);
  --card-hi: rgba(4, 31, 49, 0.72);
  --card-lo: rgba(3, 27, 44, 0.64);
  --nav-bg:  rgba(5, 36, 56, 0.96);
}
body {
  background:
    radial-gradient(80% 55% at 62% -14%, rgba(10, 106, 152, 0.42) 0%, rgba(10, 106, 152, 0) 70%),
    linear-gradient(180deg, #0f4a68 0%, #0b3d59 46%, var(--deep) 100%);
  background-color: var(--deep);
  background-attachment: fixed;
}
/* The front door (sign-in, sign-up, a new code) is where a principal arrives
   from the home page's "School sign-in" button: the hero's own lit wall and
   the learner app's lighter glass, so the two read as one place. */
body:not(.has-sidebar) {
  --card-hi: rgba(4, 33, 53, 0.62);
  --card-lo: rgba(3, 29, 47, 0.56);
  background:
    radial-gradient(120% 60% at 50% -12%, var(--wall-light) 0%, rgba(10, 106, 152, 0) 72%),
    linear-gradient(180deg, var(--wall) 0%, var(--wall-edge) 58%, var(--deep) 100%);
  background-color: var(--deep);
  background-attachment: fixed;
}

/* The data field from fx-pro.js: behind everything, never in the way. */
.fxp-bg {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
}
.fxp-bg.is-on { opacity: 1; }
@media print { .fxp-bg { display: none; } }

::selection { background: rgba(6, 146, 249, 0.4); color: #fff; }

/* ---------- Focus: crisp, high contrast, for keyboard users ---------- */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--sun);
  outline-offset: 3px;
}
.btn:focus-visible { box-shadow: 0 0 0 6px rgba(255, 211, 102, 0.16); }
.input:focus-visible, select.input:focus-visible { outline-offset: 2px; }
.input:focus, select.input:focus, textarea.input:focus {
  box-shadow: 0 0 0 5px rgba(6, 146, 249, 0.18), inset 0 1px 2px rgba(0, 10, 20, 0.3);
}
.input:hover:not(:focus) { box-shadow: 0 0 0 3px rgba(156, 203, 255, 0.06); }
.nav-btn:focus-visible { outline-offset: -2px; }

/* ---------- Buttons: a sheen that passes once, a firm press ---------- */
.btn { position: relative; overflow: hidden; isolation: isolate; }
.btn::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 32%, rgba(255, 255, 255, 0.26) 48%, transparent 64%);
  transform: translateX(-115%);
  opacity: 0;
}
.btn-ghost::after { background: linear-gradient(105deg, transparent 32%, rgba(255, 255, 255, 0.09) 48%, transparent 64%); }
.btn-mint:hover   { box-shadow: inset 0 -3px 0 rgba(0, 70, 45, 0.22), 0 10px 26px -6px rgba(83, 188, 150, 0.55); }
.btn-yellow:hover { box-shadow: inset 0 -3px 0 rgba(120, 60, 0, 0.28), 0 10px 26px -6px rgba(253, 160, 2, 0.55); }
.btn-ghost:hover  { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 8px 20px -12px rgba(0, 12, 22, 0.8); }
.btn:disabled::after, .btn[aria-disabled="true"]::after { display: none; }

/* ---------- Surfaces ---------- */
.stat-card {
  position: relative;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 16px 34px -26px rgba(0, 12, 22, 0.9);
}
.stat-card:hover {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), inset 0 0 0 1px rgba(156, 203, 255, 0.08),
              0 24px 44px -24px rgba(0, 12, 22, 0.95);
}
.stat-num {
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 26px color-mix(in srgb, currentColor 30%, transparent);
}
.card:hover {
  box-shadow: 0 26px 54px -28px rgba(0, 12, 22, 0.95), inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

/* Table rows: a thin accent, the logo's blue, at the start of the row under the pointer. */
table.data tbody tr:hover > td:first-child { box-shadow: inset 2px 0 0 rgba(79, 179, 255, 0.85); }

/* Pills and counts: a hairline in their own colour makes them read crisply. */
.pill        { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07); }
.pill-green  { box-shadow: inset 0 0 0 1px rgba(98, 210, 169, 0.3); }
.pill-amber  { box-shadow: inset 0 0 0 1px rgba(255, 183, 77, 0.28); }
.pill-red    { box-shadow: inset 0 0 0 1px rgba(255, 138, 112, 0.34); }
.pill-blue   { box-shadow: inset 0 0 0 1px rgba(156, 203, 255, 0.32); }
.nav-badge       { box-shadow: 0 2px 8px -1px rgba(252, 83, 56, 0.55); }
.nav-badge-quiet { box-shadow: 0 2px 6px -1px rgba(156, 203, 255, 0.35); }

/* ---------- Navigation: where you are, at a glance ---------- */
.nav-btn { position: relative; }
.nav-btn.active { box-shadow: inset 0 0 0 1px rgba(79, 179, 255, 0.24); }
.nav-btn.active::before {             /* phone: a short bar on the top edge */
  content: '';
  position: absolute;
  top: -8px; left: 50%;
  width: 24px; height: 2px; margin-left: -12px;
  border-radius: 0 0 3px 3px;
  background: #4fb3ff;
  box-shadow: 0 0 10px rgba(1, 138, 254, 0.75);
}
@media (min-width: 1024px) {
  body.has-sidebar .nav-bar { box-shadow: 1px 0 0 rgba(255, 255, 255, 0.02), 28px 0 60px -48px rgba(0, 12, 22, 0.9); }
  body.has-sidebar .nav-btn.active::before {   /* rail: a bar on the left edge */
    top: 50%; left: -14px;
    width: 3px; height: 22px; margin: -11px 0 0;
    border-radius: 0 3px 3px 0;
  }
  body.has-sidebar .nav-btn:not(.active):hover { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05); }
}

/* ---------- Safeguarding: open alerts are easy to find ----------
   fx-pro.js marks each open alert card (Alerts tab) and each urgent pill in
   the admin's open-alerts table. The glow is a separate layer so only its
   opacity changes. At rest it stays as a steady, soft outline. */
.fxp-attn { position: relative; --fxp-rest: 0.5; }
.fxp-attn::after {
  content: '';
  position: absolute; inset: -1px;
  border-radius: inherit;
  pointer-events: none;
  box-shadow: 0 0 0 1px rgba(252, 83, 56, 0.6), 0 0 0 5px rgba(252, 83, 56, 0.08),
              0 0 34px 0 rgba(252, 83, 56, 0.22);
  opacity: var(--fxp-rest);
}
.fxp-attn-watch { --fxp-rest: 0.4; }
.fxp-attn-watch::after {
  box-shadow: 0 0 0 1px rgba(255, 183, 77, 0.45), 0 0 0 5px rgba(255, 183, 77, 0.05),
              0 0 30px 0 rgba(255, 183, 77, 0.15);
}
.fxp-ping { position: relative; }
.fxp-ping::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
  box-shadow: 0 0 0 1.5px rgba(252, 83, 56, 0.65);
  opacity: 0;
}

/* ============================ Motion ============================ */
@media (prefers-reduced-motion: no-preference) {
  .fxp-bg { transition: opacity 1.6s ease; }

  .btn {
    transition: transform 0.18s cubic-bezier(.2, .8, .2, 1), box-shadow 0.22s ease, filter 0.15s ease;
  }
  .btn::after { transition: transform 0.75s cubic-bezier(.2, .8, .2, 1), opacity 0.25s ease; }
  .btn:active { transform: translateY(1px) scale(0.985); transition-duration: 0.06s; }
  .btn:disabled, .btn[disabled] { transform: none; }

  .input, select.input, textarea.input { transition: box-shadow 0.2s ease, border-color 0.2s ease; }
  .stat-card { transition: transform 0.28s cubic-bezier(.2, .8, .2, 1), box-shadow 0.28s ease; }
  .card { transition: box-shadow 0.3s ease; }
  .wide-shell .card > a.flex { transition: transform 0.22s cubic-bezier(.2, .8, .2, 1); }
  table.data tbody tr > td:first-child { transition: box-shadow 0.18s ease; }
  .nav-btn { transition: box-shadow 0.2s ease, background-color 0.2s ease; }
  .nav-icon { transition: transform 0.22s cubic-bezier(.2, .8, .2, 1); }
  .nav-btn.active::before { animation: fxp-mark 0.55s cubic-bezier(.2, .8, .2, 1) 0.15s both; }

  /* Breathes about eight times (half a minute), then rests; never while the
     person is typing into that alert's form. Under 0.3 Hz: a glow, not a flash. */
  .fxp-attn::after { animation: fxp-breathe 3.6s ease-in-out 0.9s 8 both; }
  .fxp-attn-watch::after { animation-duration: 4.4s; }
  .fxp-attn:focus-within::after { animation: none; }
  .fxp-ping::after { animation: fxp-ping 3s cubic-bezier(.2, .6, .3, 1) 1s 10; }
}

/* Movement under the pointer only where there is a pointer: on a touch screen
   a tap would otherwise leave a card or button stuck half-lifted. */
@media (prefers-reduced-motion: no-preference) and (hover: hover) {
  .btn:hover { transform: translateY(-1px); }
  .btn:hover::after { transform: translateX(115%); opacity: 1; }
  .btn:hover:active { transform: translateY(1px) scale(0.985); }
  .btn:disabled:hover, .btn[disabled]:hover { transform: none; }
  .stat-card:hover { transform: translateY(-2px); }
  .wide-shell .card > a.flex:hover { transform: translateX(3px); }
  body.has-sidebar .nav-btn:hover .nav-icon { transform: translateX(2px); }
}

@keyframes fxp-mark    { from { opacity: 0; transform: scale(0.2); } }
@keyframes fxp-breathe { 0%, 100% { opacity: var(--fxp-rest); } 50% { opacity: 1; } }
@keyframes fxp-ping    { 0% { opacity: 0.9; transform: scale(1); } 70%, 100% { opacity: 0; transform: scale(1.16, 1.7); } }
