/* Maintenance / "we'll be right back" page.
 *
 * Two distinct surfaces share this stylesheet:
 *
 *  1. The full-page maintenance template (.maintenance-body / .maintenance-page
 *     and friends) — design lifted from the Syncc design bundle's
 *     "CampuSync Maintenance.html". Standalone (no base.html chrome),
 *     teal accents, italic serif headline, soft pulsing wrench mark,
 *     ETA card, and a quiet pulsing "deploying" status pill.
 *
 *  2. The sticky admin banner (.maintenance-banner) shown across the
 *     in-app surfaces while maintenance mode is on so the maintainer
 *     never forgets they flipped the switch. Untouched by the redesign.
 *
 * Plus the small reusable .status-indicator primitive at the bottom of
 * this file (consumed elsewhere — see CLAUDE.md UI primitives section).
 */

:root {
  /* Brand tokens scoped to this surface — not in the global brand.css
     because they include hairline alpha values + paper-canvas neutrals
     that would be noise everywhere else. */
  --maint-teal:        #1AB994;
  --maint-teal-bright: #25D6AD;
  --maint-teal-dark:   #0F8A6B;
  --maint-teal-soft:   rgba(26, 185, 148, 0.10);
  --maint-teal-line:   rgba(26, 185, 148, 0.28);
  --maint-navy:        #0A1628;
  --maint-bg:          #FAFBFB;
  --maint-bg-2:        #F2F5F4;
  --maint-card:        #ffffff;
  --maint-border:      rgba(10, 22, 40, 0.10);
  --maint-text-p:      #0A1628;
  --maint-text-s:      #2C3D52;
  --maint-text-m:      #5C6B7E;
  --maint-text-t:      #8B98A8;
  --maint-sans:        'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  --maint-serif:       'Instrument Serif', 'Times New Roman', serif;
}

/* ── Standalone page surface ───────────────────────────────────── */

.maintenance-body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  background: var(--maint-bg-2);
  color: var(--maint-text-p);
  font-family: var(--maint-sans);
  -webkit-font-smoothing: antialiased;
}
.maintenance-body, .maintenance-body * { box-sizing: border-box; }

/* Page shell — subtle aurora gradient hint + faint grid texture.
 * Both layered onto the paper canvas so the card sits on a real
 * surface rather than a flat fill. The grid is masked by a radial
 * gradient so it fades out toward the edges. */
.maintenance-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(ellipse 60% 40% at 50% 12%, rgba(26, 185, 148, 0.10), transparent 70%),
    radial-gradient(ellipse 50% 35% at 80% 90%, rgba(26, 185, 148, 0.06), transparent 70%),
    var(--maint-bg-2);
}
.maintenance-page::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(10, 22, 40, 0.04) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(10, 22, 40, 0.04) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, #000 0%, transparent 80%);
  mask-image:         radial-gradient(ellipse 70% 60% at 50% 40%, #000 0%, transparent 80%);
  opacity: 0.55;
}

/* Topbar — wordmark left, status pill right. */
.maintenance-topbar {
  position: absolute;
  top: 28px;
  left: 32px;
  right: 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  z-index: 2;
}
.maintenance-wordmark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  line-height: 1;
  user-select: none;
  text-decoration: none;
}
.maintenance-wordmark img {
  height: 28px;
  width: auto;
  display: block;
}
.maintenance-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--maint-teal-soft);
  border: 1px solid var(--maint-teal-line);
  color: var(--maint-teal-dark);
  font: 500 12px/1 var(--maint-sans);
  letter-spacing: 0.04em;
}
.maintenance-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--maint-teal-bright);
  animation: maint-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes maint-pulse {
  0%, 100% { box-shadow: 0 0 0 0   rgba(37, 214, 173, 0.55); }
  50%      { box-shadow: 0 0 0 6px rgba(37, 214, 173, 0);    }
}

/* Card — the centerpiece. Soft hairline border + layered shadow
 * (one tight 1px for crispness + one loose 24px for elevation). */
.maintenance-card {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 560px;
  background: var(--maint-card);
  border: 1px solid var(--maint-border);
  border-radius: 22px;
  padding: 56px 48px 44px;
  box-shadow:
    0 1px  2px      rgba(10, 22, 40, 0.04),
    0 24px 48px -20px rgba(10, 22, 40, 0.14);
  text-align: center;
}

/* In-card brand wordmark — large and centered. Doubles the
 * topbar wordmark on purpose: the topbar version anchors the page
 * (small, corner) while this one anchors the message (large,
 * centered). For a parent who lands here without context, this is
 * what tells them they're on a Syncc page. */
.maintenance-card-brand {
  display: flex;
  justify-content: center;
  margin: 0 auto 24px;
}
.maintenance-card-brand img {
  height: 36px;
  width: auto;
  display: block;
}
@media (max-width: 560px) {
  .maintenance-card-brand img { height: 30px; }
}

/* Wrench mark — adapted from the existing icon, now in a soft
 * teal-tinted disc with a concentric expanding ring behind it.
 * The ring quietly suggests "something's happening" without being
 * a spinner that demands attention. */
.maintenance-mark-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: 999px;
  background: var(--maint-teal-soft);
  border: 1px solid var(--maint-teal-line);
  color: var(--maint-teal-dark);
  margin: 0 auto 28px;
  position: relative;
}
.maintenance-mark-wrap::after {
  content: '';
  position: absolute;
  inset: -10px;
  border-radius: 999px;
  border: 1px solid var(--maint-teal-line);
  opacity: 0.5;
  animation: maint-ring 2.6s ease-out infinite;
}
@keyframes maint-ring {
  0%   { transform: scale(0.92); opacity: 0.55; }
  100% { transform: scale(1.20); opacity: 0;    }
}

.maintenance-eyebrow-row {
  display: flex;
  justify-content: center;
}
.maintenance-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font: 500 11px/1 var(--maint-sans);
  color: var(--maint-teal-dark);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-bottom: 18px;
}
.maintenance-eyebrow-tick {
  width: 22px;
  height: 1px;
  background: var(--maint-teal-dark);
}

.maintenance-title {
  font: 400 48px/1.05 var(--maint-serif);
  color: var(--maint-text-p);
  letter-spacing: -0.012em;
  margin: 0 0 16px;
}
.maintenance-title em {
  font-style: italic;
  color: var(--maint-teal-dark);
}

.maintenance-body-text {
  font: 400 16px/1.6 var(--maint-sans);
  color: var(--maint-text-m);
  margin: 0 auto 28px;
  max-width: 420px;
  text-wrap: pretty;
}

/* Meta strip — Started / Estimated back / Status. The italic serif
 * ETA value is the design's signature touch; it leans on the
 * brand's display font for a moment of warmth in an otherwise
 * data-rich row. */
.maintenance-meta {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 22px;
  background: var(--maint-bg-2);
  border: 1px solid var(--maint-border);
  border-radius: 14px;
  font: 400 13.5px/1.4 var(--maint-sans);
  color: var(--maint-text-m);
  margin: 0 0 28px;
  width: 100%;
  text-align: left;
}
.maintenance-meta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.maintenance-meta-label {
  color: var(--maint-text-t);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 11px;
  font-weight: 500;
  flex-shrink: 0;
}
.maintenance-meta-value {
  color: var(--maint-text-p);
  font-weight: 500;
  white-space: nowrap;
  flex-shrink: 0;
}
.maintenance-meta-value.italic {
  font: italic 400 16px/1 var(--maint-serif);
  color: var(--maint-teal-dark);
}
.maintenance-meta-value.wrap {
  white-space: normal;
  text-align: right;
  color: var(--maint-teal-dark);
}

/* Buttons — primary uses the brand teal with navy text (matches
 * the design's high-contrast call). Secondary is a quiet outline. */
.maintenance-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
}
.maintenance-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 20px;
  border-radius: 10px;
  cursor: pointer;
  font: 600 14px/1 var(--maint-sans);
  letter-spacing: -0.005em;
  text-decoration: none;
  transition: transform 0.15s, box-shadow 0.15s, background 0.15s;
  border: 1px solid transparent;
}
.maintenance-btn-primary {
  background: var(--maint-teal);
  color: var(--maint-navy);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.30) inset,
    0 8px 24px -8px rgba(26, 185, 148, 0.55);
}
.maintenance-btn-primary:hover {
  transform: translateY(-1px);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.30) inset,
    0 12px 28px -8px rgba(26, 185, 148, 0.65);
}
.maintenance-btn-secondary {
  background: transparent;
  color: var(--maint-text-s);
  border-color: var(--maint-border);
}
.maintenance-btn-secondary:hover {
  background: var(--maint-bg-2);
}

.maintenance-footer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 28px;
  text-align: center;
  font: 400 12.5px/1.4 var(--maint-sans);
  color: var(--maint-text-t);
  z-index: 2;
}
.maintenance-footer a {
  color: var(--maint-teal-dark);
  text-decoration: none;
  border-bottom: 1px solid var(--maint-teal-dark);
}

@media (max-width: 560px) {
  .maintenance-card {
    padding: 40px 28px 32px;
    border-radius: 18px;
  }
  .maintenance-title { font-size: 36px; }
  .maintenance-topbar { top: 20px; left: 20px; right: 20px; }
  .maintenance-footer { bottom: 20px; }
}

/* Reduced-motion: kill the looping ring + dot pulses. The
 * surface still reads as fresh; users with vestibular sensitivities
 * shouldn't pay for the subtle vibe. */
@media (prefers-reduced-motion: reduce) {
  .maintenance-status-dot,
  .maintenance-mark-wrap::after {
    animation: none;
  }
}

/* ── Dark mode ─────────────────────────────────────────────────── */

html.dark .maintenance-body {
  background: #0A1220;
  color: #E2E8F0;
}
html.dark .maintenance-page {
  background:
    radial-gradient(ellipse 60% 40% at 50% 12%, rgba(37, 214, 173, 0.14), transparent 70%),
    radial-gradient(ellipse 50% 35% at 80% 90%, rgba(37, 214, 173, 0.08), transparent 70%),
    #0A1220;
}
html.dark .maintenance-page::before {
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0.04) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.04) 1px, transparent 1px);
}
html.dark .maintenance-card {
  background: #131F33;
  border-color: rgba(255, 255, 255, 0.08);
  box-shadow:
    0 1px  2px       rgba(0, 0, 0, 0.30),
    0 24px 48px -20px rgba(0, 0, 0, 0.55);
}
html.dark .maintenance-title { color: #F1F5F9; }
html.dark .maintenance-body-text { color: #94A3B8; }
html.dark .maintenance-meta {
  background: rgba(255, 255, 255, 0.03);
  border-color: rgba(255, 255, 255, 0.08);
  color: #94A3B8;
}
html.dark .maintenance-meta-label { color: #64748B; }
html.dark .maintenance-meta-value { color: #E2E8F0; }
html.dark .maintenance-btn-secondary {
  color: #CBD5E1;
  border-color: rgba(255, 255, 255, 0.12);
}
html.dark .maintenance-btn-secondary:hover {
  background: rgba(255, 255, 255, 0.04);
}

/* ── Sticky admin banner (in-app surfaces) ─────────────────────── *
 * Apple-style: near-white background with a hairline tinted
 * border + a subtle accent dot. No saturated pill blocks. Untouched
 * by the maintenance redesign — different surface, different needs.
 */
.maintenance-banner {
  position: sticky;
  top: 0;
  /* z-index 30 — BELOW the navbar (z-50). The navbar carries
   * the notification bell + avatar dropdown, both of which the
   * user needs to reach mid-session even when the banner is
   * visible. Stacking the banner under the navbar means the
   * navbar wins the paint order on mobile where the two strips
   * overlap; the navbar's `top` is bumped below to reserve
   * vertical space for the banner so they don't visually
   * overlap when both are sticky.
   *
   * Earlier versions used z-index: 60 which painted the banner
   * over the navbar on phone widths and blocked the bell +
   * avatar tap targets — bug filed by maintainer. */
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  background: rgba(255, 251, 235, 0.85);
  backdrop-filter: saturate(180%) blur(10px);
  -webkit-backdrop-filter: saturate(180%) blur(10px);
  color: rgb(71, 85, 105);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  border-bottom: 0.5px solid rgba(180, 83, 9, 0.18);
}
/* When the maintenance banner is rendered, push the sticky
 * navbar down by its height so they stack vertically instead
 * of overlapping. ``:has()`` checks for the banner once at the
 * body level; the navbar's existing ``top: 0`` shifts to the
 * banner height. */
body:has(.maintenance-banner) .navbar {
  top: 36px;  /* matches the banner's rendered height */
}
.maintenance-banner-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgb(217, 119, 6);
  box-shadow: 0 0 0 3px rgba(217, 119, 6, 0.18);
  flex-shrink: 0;
}
.maintenance-banner strong {
  color: rgb(15, 23, 42);
  font-weight: 600;
}
.maintenance-banner a {
  color: rgb(15, 23, 42);
  text-decoration: none;
  border-bottom: 0.5px solid rgba(15, 23, 42, 0.35);
  font-weight: 500;
  transition: border-color 0.15s ease;
}
.maintenance-banner a:hover { border-bottom-color: rgb(15, 23, 42); }

html.dark .maintenance-banner {
  background: rgba(30, 41, 59, 0.85);
  color: rgb(203, 213, 225);
  border-bottom-color: rgba(217, 119, 6, 0.4);
}
html.dark .maintenance-banner strong { color: rgb(241, 245, 249); }
html.dark .maintenance-banner a {
  color: rgb(241, 245, 249);
  border-bottom-color: rgba(241, 245, 249, 0.4);
}
html.dark .maintenance-banner a:hover { border-bottom-color: rgb(241, 245, 249); }

/* ── Emergency banner ─────────────────────────────────────────── *
 * Same chrome as the maintenance banner but coral instead of
 * amber, and visible to every authenticated user (not just
 * admins). Stacks above the maintenance banner when both are
 * active — emergencies beat maintenance.
 *
 * Subtle pulsing dot draws the eye without becoming a strobe;
 * the animation respects ``prefers-reduced-motion``. */
.emergency-banner {
  position: sticky;
  top: 0;
  z-index: 31;  /* one above the maintenance banner */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  background: rgba(254, 226, 226, 0.92);
  backdrop-filter: saturate(180%) blur(10px);
  -webkit-backdrop-filter: saturate(180%) blur(10px);
  color: rgb(127, 29, 29);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: -0.005em;
  border-bottom: 0.5px solid rgba(127, 29, 29, 0.28);
}
body:has(.emergency-banner) .navbar {
  top: 36px;
}
body:has(.emergency-banner):has(.maintenance-banner) .navbar {
  top: 72px;  /* both banners stacked */
}
.emergency-banner-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgb(220, 38, 38);
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.22);
  flex-shrink: 0;
  animation: emergency-pulse 1.6s ease-in-out infinite;
}
@keyframes emergency-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.22); }
  50%      { box-shadow: 0 0 0 5px rgba(220, 38, 38, 0.10); }
}
@media (prefers-reduced-motion: reduce) {
  .emergency-banner-dot { animation: none; }
}
.emergency-banner a {
  color: rgb(127, 29, 29);
  text-decoration: none;
  border-bottom: 0.5px solid rgba(127, 29, 29, 0.45);
  font-weight: 600;
  transition: border-color 0.15s ease;
}
.emergency-banner a:hover { border-bottom-color: rgb(127, 29, 29); }
html.dark .emergency-banner {
  background: rgba(127, 29, 29, 0.78);
  color: rgb(254, 226, 226);
  border-bottom-color: rgba(254, 226, 226, 0.32);
}
html.dark .emergency-banner a {
  color: rgb(254, 226, 226);
  border-bottom-color: rgba(254, 226, 226, 0.50);
}
html.dark .emergency-banner a:hover { border-bottom-color: rgb(254, 226, 226); }

/* ── Reusable status indicator primitive ──────────────────────── *
 * Pattern: <span class="status-indicator status-on">
 *            <span class="status-indicator-dot"></span>On
 *          </span>
 * Used by maintenance.html and other surfaces (CLAUDE.md UI
 * primitives section calls it out as the canonical pattern).
 */
.status-indicator {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.125rem 0.5rem 0.125rem 0.4rem;
  border-radius: 999px;
  background: rgb(248, 250, 252);
  border: 0.5px solid rgb(226, 232, 240);
  color: rgb(51, 65, 85);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.status-indicator-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgb(148, 163, 184);
  flex-shrink: 0;
}
.status-on  .status-indicator-dot {
  background: rgb(217, 119, 6);
  box-shadow: 0 0 0 3px rgba(217, 119, 6, 0.15);
}
.status-off .status-indicator-dot {
  background: rgb(5, 150, 105);
  box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.12);
}

html.dark .status-indicator {
  background: rgb(30, 41, 59);
  border-color: rgb(71, 85, 105);
  color: rgb(203, 213, 225);
}
html.dark .status-indicator-dot { background: rgb(100, 116, 139); }
