/* ==========================================================================
   Unified modal header — one look for every dialog
   --------------------------------------------------------------------------
   The welcome modal (public/css/mascot-welcome.css) had the one header worth
   copying: a solid brand-blue bar carrying the school logo, the school name
   and a white title. Everything else had drifted — Bootstrap .modal-header was
   grey, .custom-modal-header was grey with a separate 4px gradient strip,
   .admin-modal was white. This file makes the welcome header the standard.

   Covered, deliberately:
     .modal-header              Bootstrap, ~28 views
     .custom-modal-header       customConfirm() / customAlert() in modal-system.js
     .admin-modal .modal-header the admin shape in admin-ui.css
     .create-admin-shell-header the one hand-rolled admin form dialog
     .mascot-welcome__head      the original, restyled at the foot of this file
                               to read from these same tokens

   The guided tour is NOT in this list, by request. .mascot-tour__card in
   mascot-tour.css keeps its own amber accent; it shares no class with anything
   above, so excluding it costs nothing and it stays visually distinct.

   Load order
   ----------
   Must load AFTER dashboard.css, modal-system.css and admin-ui.css, which all
   declare .modal-header rules with !important at the same specificity. Equal
   specificity + !important + later in document order = this file wins. Keep the
   <link> after them and before typography.css, which must stay last.
   ========================================================================== */

:root {
  /* The brand blue, lifted from --color-primary (#1e40af) so the header and
     the buttons in the footer are provably the same colour. */
  --modal-header-bg: #1e40af;
  --modal-header-bg-hover: #1e3a8a;
  --modal-header-fg: #ffffff;
  --modal-header-muted: rgba(255, 255, 255, 0.78);

  --modal-header-logo: 40px;   /* the welcome modal's own 46px still wins there */
  --modal-header-logo-gap: 0.7rem;
  --modal-header-pad-y: 1rem;
  --modal-header-pad-x: 1.25rem;
  --modal-header-radius: 12px;

  /* Semantic variants. Same geometry, different hue, so a destructive dialog
     still reads as destructive. A "Delete Student" confirm that looks identical
     to "Save" is an accessibility problem, not a branding win. */
  --modal-header-danger-bg: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);
  --modal-header-success-bg: linear-gradient(135deg, #059669 0%, #047857 100%);
  --modal-header-warning-bg: linear-gradient(135deg, #d97706 0%, #b45309 100%);

  /* Documented here, but NOT usable as a @container condition — see the note
     above the @container block. Kept for reference and for the @media
     fallback; the number of record is the literal 480px in the query. */
  --modal-header-brand-min: 480px;
}

/* The container the brand breakpoint is measured against. inline-size
   containment leaves block sizing — and therefore the dialog's height and its
   scrolling — untouched, which is what makes this safe on .modal-content. */
@supports (container-type: inline-size) {
  .modal-content,
  .custom-modal-container,
  .admin-modal,
  .create-admin-shell {
    container-type: inline-size;
    container-name: modal;
  }
}

/* ==========================================================================
   The shared header
   ========================================================================== */

/* One declaration list, four selectors. Keeping them together is the point of
   this file: the day someone adds a fifth modal system, they extend this list
   rather than invent a fifth colour. */
.modal-header,
.custom-modal-header,
.admin-modal .modal-header,
.create-admin-shell-header,
.mascot-welcome__head,
/* responsive.css:849 sets .dashboard-app .custom-modal-header padding with
   !important. That is one class deeper than .custom-modal-header, so on every
   width up to its own 768px breakpoint it wins on specificity regardless of
   this file loading later. Matching the selector here is what actually makes
   the token below stick on the dashboard; without it the mobile padding would
   silently stay 1.25rem. */
.dashboard-app .custom-modal-header,
.dashboard-app .modal-header {
  display: flex;
  align-items: center;
  gap: var(--modal-header-logo-gap);
  padding: var(--modal-header-pad-y) var(--modal-header-pad-x) !important;
  background: var(--modal-header-bg) !important;
  color: var(--modal-header-fg) !important;
  border: 0 !important;
  border-radius: var(--modal-header-radius) var(--modal-header-radius) 0 0 !important;
  margin-top: 0;
}

/* The logo, injected rather than templated into ~28 views.

   relative to this stylesheet (public/css/ -> public/), so it survives the
   /public base-path juggling in asset_helper.php without needing PHP. It is
   decorative: the title beside it is the real accessible label. */
.modal-header::before,
.custom-modal-header::before,
.admin-modal .modal-header::before,
.create-admin-shell-header::before,
.mascot-welcome__head::before {
  content: '';
  flex: 0 0 auto;
  width: var(--modal-header-logo);
  height: var(--modal-header-logo);
  background: url("../LPHS2.png") center / contain no-repeat;
}

/* The welcome modal already has a real <img class="mascot-welcome__logo"> in
   its markup. Two logos side by side would be exactly the visible bug this
   file exists to prevent, so its pseudo-element stands down. */
.mascot-welcome__head::before {
  content: none;
}

/* Titles. The colour is restated rather than inherited: Bootstrap's
   .modal-title, .custom-modal-title and admin-ui.css's --admin-heading each set
   their own dark colour, and none of them yield to inheritance. */
.modal-header .modal-title,
.custom-modal-header .custom-modal-title,
.admin-modal .modal-header .modal-title,
.admin-modal .modal-header .modal-title i,
.create-admin-shell-header .create-admin-shell-title,
.create-admin-shell-header .create-admin-modal-header-icon,
.mascot-welcome__head .mascot-welcome__school,
.modal-header h5,
.modal-header h4 {
  color: var(--modal-header-fg) !important;
  margin: 0;
}

/* Icons in a header used to inherit the title colour, which is fine on blue —
   but admin-ui.css pins .modal-title i to --color-primary, which would put a
   dark blue icon on a dark blue bar. */
.modal-header .bi,
.custom-modal-header .bi,
.mascot-welcome__head .bi {
  color: var(--modal-header-fg);
}

/* Bootstrap's own contextual text colours, neutralised on a coloured bar.
   backups.php:915 has <i class="bi bi-exclamation-triangle-fill text-danger">
   inside the restore header: red-on-red is invisible, which is the exact
   failure .modal-header-danger was added to prevent. On the brand blue a
   text-danger icon is merely hard to read. Strip the utility so the icon takes
   the header's own foreground. */
.modal-header .text-danger,
.modal-header .text-warning,
.modal-header .text-success,
.modal-header .text-primary,
.modal-header .text-body,
.modal-header .text-muted {
  color: var(--modal-header-fg) !important;
}

/* backups.php marks its two destructive dialogs with Bootstrap's
   .bg-danger-subtle. That is a *danger* signal, not a neutral one, so it maps to
   the red variant — the same geometry as every other header, different hue.
   Reading it as the brand blue (as an earlier draft of this file did) turned
   "Delete backup" into a reassuring blue bar, which is exactly the confusion the
   danger variant exists to prevent. */
.modal-header.bg-danger-subtle,
.modal-header.bg-danger {
  background: var(--modal-header-danger-bg) !important;
}

.modal-header.bg-warning-subtle {
  background: var(--modal-header-warning-bg) !important;
}

.modal-header.bg-success-subtle {
  background: var(--modal-header-success-bg) !important;
}

/* Bootstrap's close button is a near-black SVG. Left alone it is a black X on
   a blue bar. */
.modal-header .btn-close,
.custom-modal-header .btn-close,
.admin-modal .modal-header .btn-close {
  filter: invert(1) grayscale(1) brightness(2);
  opacity: 0.85;
}

.modal-header .btn-close:hover,
.custom-modal-header .btn-close:hover {
  filter: invert(1) grayscale(1) brightness(2);
  opacity: 1;
}

/* The eyebrow line ("CSCS Tap n Track", modal subtitles). */
.modal-header .modal-subtitle,
.create-admin-shell-header .create-admin-shell-subtitle,
.mascot-welcome__head .mascot-welcome__eyebrow {
  color: var(--modal-header-muted) !important;
}

/* Give the title room to breathe and keep the close button on the right edge
   without disturbing Bootstrap's space-between layout. */
.modal-header .modal-title,
.custom-modal-header .custom-modal-title {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 700;
}

/* ==========================================================================
   Branding: the school name, on wide dialogs only
   ========================================================================== */

/* The 480px is written as a literal, NOT as var(--modal-header-brand-min).
   Custom properties are not substituted inside a @container condition — the
   rule parses and then silently never matches, so the whole block looked like
   it worked while the brand lockup never appeared. A @media query would accept
   the var, but the dialog's width is what matters here, not the viewport's, and
   that is the whole reason this is a container query. If the breakpoint moves,
   this number and the --modal-header-brand-min token above it have to move
   together; that duplication is the price of the feature working.

   Below the breakpoint the logo alone carries the branding, which is the
   intended fallback rather than a degraded state. */
@supports (container-type: inline-size) {
  @container modal (min-width: 480px) {
    .modal-header::after,
    .custom-modal-header::after,
    .admin-modal .modal-header::after,
    .create-admin-shell-header::after {
      content: 'CSCS Tap n Track';
      flex: 0 0 auto;
      order: -1;                 /* beside the title, opposite the close */
      font-size: var(--fs-xs, 0.75rem);
      line-height: 1.2;
      letter-spacing: var(--letter-spacing-caps, 0.05em);
      text-transform: uppercase;
      color: var(--modal-header-muted);
      white-space: nowrap;
      padding-left: 0.6rem;
      border-left: 1px solid rgba(255, 255, 255, 0.28);
    }
  }
}

/* ==========================================================================
   Semantic variants
   ========================================================================== */

/* Danger. dashboard.css already has .modal-header-danger (a red banner added
   with !important for the same white-on-white reason); this keeps that name
   working and gives it the shared geometry, so it stops looking bolted on. */
.modal-header-danger,
.admin-modal .modal-header.modal-header-danger {
  background: var(--modal-header-danger-bg) !important;
}

.modal-header-success { background: var(--modal-header-success-bg) !important; }
.modal-header-warning { background: var(--modal-header-warning-bg) !important; }

/* Type-based variants, for callers that pass an intent rather than a class —
   the same vocabulary customConfirm() / customAlert() already use. */
.modal-header--danger,
.admin-modal .modal-header--danger { background: var(--modal-header-danger-bg) !important; }
.modal-header--success,
.admin-modal .modal-header--success { background: var(--modal-header-success-bg) !important; }
.modal-header--warning,
.admin-modal .modal-header--warning { background: var(--modal-header-warning-bg) !important; }

/* ==========================================================================
   Retired decoration
   ========================================================================== */

/* modal-system.css drew a 4px blue gradient strip across the top of every
   .custom-modal-container, plus one on .create-admin-shell. Both were half
   measures at the same idea this file now implements properly: once the header
   itself is a solid brand-blue bar, the strip is a second competing blue line
   across the top of the dialog. */
.custom-modal-container::before,
.create-admin-shell::before {
  content: none !important;
  display: none !important;
}

/* The 5px amber strip on the welcome dialog. The same amber survives on the
   tour card (mascot-tour.css), where it is the only accent and reads
   deliberately; above a solid blue header it read as a stray line. */
.mascot-welcome__dialog { border-top: 0 !important; }

/* The welcome dialog was 1.1rem while its header was 1.05rem, so the header's
   top corners sat 0.05rem inside the card's. One token for both now. */
.mascot-welcome__dialog,
.custom-modal-container,
.admin-modal,
.create-admin-shell,
.modal-content {
  border-radius: var(--modal-header-radius) !important;
}

/* The welcome modal keeps its 46px logo — it is the fullest branding on the
   page and can afford the larger mark. */
.mascot-welcome__head {
  --modal-header-logo: 46px;
}

/* ==========================================================================
   Narrow screens
   ========================================================================== */
@media (max-width: 575.98px) {
  :root {
    --modal-header-logo: 34px;
    --modal-header-pad-y: 0.85rem;
    --modal-header-pad-x: 1rem;
  }

  /* The brand lockup is the first thing to go: the title needs the room more. */
  .modal-header::after,
  .custom-modal-header::after,
  .admin-modal .modal-header::after,
  .create-admin-shell-header::after {
    display: none;
  }
}
