/* =========================================================================
 * adminator-hrdd.css
 * -------------------------------------------------------------------------
 * HRDD's layer on top of the Adminator 2026 stylesheet. Loaded last.
 *
 * Deliberately small: the auth pages are built from the template's own
 * components (.auth-shell, .auth-card, .field, .input-icon, .check, .btn),
 * so this only covers the few things HRDD adds — a real logo in the brand
 * mark, a theme toggle in the slot where the demo had "Create account", a
 * password reveal button, and validation/flash message styling.
 *
 * All colours reference the template's own tokens (--primary, --danger,
 * --t-muted, …), which are defined for both light and dark themes, so
 * everything here follows the theme switch automatically.
 * ========================================================================= */

/* =========================================================================
 * MORESCO 1 head office photo in the aside
 * -------------------------------------------------------------------------
 * The old AdminLTE login used /images/bg.png — a photo of the MORESCO 1 head
 * office — as a full-page background behind a centred card, so most of the
 * building sat behind the form. The split layout gives it a better home: the
 * aside is a full-height panel that already expects white text over colour,
 * so the photo replaces the template's flat blue/purple gradient and the
 * gradient becomes a tint on top of it.
 *
 * Two layers sit over the photo, first-listed painting on top:
 *   1. a scrim, strongest at the bottom — .auth-aside-body has margin-top:auto,
 *      so the text lands over the white entrance steps, the brightest part of
 *      the frame, where white-on-white would otherwise be unreadable
 *   2. the brand tint, which keeps the panel recognisably blue
 *
 * The source PNG is 3.1 MB, which is a lot for the first screen anyone loads
 * on office wifi. It is re-encoded to WebP (127 KB) with a JPEG fallback
 * (238 KB); the original stays untouched in /images/.
 * ========================================================================= */
.auth-aside {
  /* Plain-url first for engines without image-set(); the second declaration
     overrides it wherever image-set() is understood. */
  background:
    linear-gradient(to top, rgba(8, 14, 30, .93) 0%, rgba(8, 14, 30, .58) 45%, rgba(8, 14, 30, .20) 100%),
    linear-gradient(135deg, rgba(37, 99, 235, .70), rgba(139, 92, 246, .48)),
    url("../img/login-bg.jpg") 50% 45% / cover no-repeat;
  background:
    linear-gradient(to top, rgba(8, 14, 30, .93) 0%, rgba(8, 14, 30, .58) 45%, rgba(8, 14, 30, .20) 100%),
    linear-gradient(135deg, rgba(37, 99, 235, .70), rgba(139, 92, 246, .48)),
    image-set(url("../img/login-bg.webp") type("image/webp"),
              url("../img/login-bg.jpg")  type("image/jpeg")) 50% 45% / cover no-repeat;
}

/* Dark theme: deepen the scrim and pull the tint back, so the panel sits with
   the darker page rather than glowing against it. */
[data-theme="dark"] .auth-aside {
  background:
    linear-gradient(to top, rgba(3, 7, 18, .95) 0%, rgba(3, 7, 18, .72) 45%, rgba(3, 7, 18, .42) 100%),
    linear-gradient(135deg, rgba(37, 99, 235, .45), rgba(88, 28, 135, .40)),
    url("../img/login-bg.jpg") 50% 45% / cover no-repeat;
  background:
    linear-gradient(to top, rgba(3, 7, 18, .95) 0%, rgba(3, 7, 18, .72) 45%, rgba(3, 7, 18, .42) 100%),
    linear-gradient(135deg, rgba(37, 99, 235, .45), rgba(88, 28, 135, .40)),
    image-set(url("../img/login-bg.webp") type("image/webp"),
              url("../img/login-bg.jpg")  type("image/jpeg")) 50% 45% / cover no-repeat;
}

/* The template's two radial glows are tuned for a flat gradient; over a photo
   they read as haze, so they are softened rather than removed — they still
   lift the top-right corner where the sky is. */
.auth-aside:before { opacity: .55; }
.auth-aside:after  { opacity: .40; }

/* Give the headline a little shadow: it now sits over cloud detail, which
   varies in brightness across the panel width. */
.auth-aside h1 { text-shadow: 0 1px 12px rgba(0, 0, 0, .35); }
.auth-aside p  { text-shadow: 0 1px 8px rgba(0, 0, 0, .30); }

/* The quote card is frosted glass (backdrop-filter), which was doing nothing
   over a flat gradient. Over the photo it finally does its job — nudge the
   contrast up so it stays readable against the bright steps. */
.auth-quote {
  background: rgba(255, 255, 255, .12);
  border-color: rgba(255, 255, 255, .22);
}

/* =========================================================================
 * Drifting sky
 * -------------------------------------------------------------------------
 * The clouds in the photograph are fixed pixels. Animating those specific
 * clouds would mean cutting the sky away from the building and the treeline
 * by hand, so instead two soft layers drift across the sky region on top of
 * the photo, at different speeds so they read as depth rather than one
 * sliding sheet.
 *
 * Each layer is a repeating tile moved by exactly one tile width, which makes
 * the loop seamless — no jump when the animation restarts. Both are masked to
 * fade out well above the roofline, so nothing ever slides across the
 * building or the steps.
 * ========================================================================= */
.auth-sky {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  /* Above the panel's photo/scrim background, below the text. */
  z-index: 0;
}

.auth-sky-far,
.auth-sky-near {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background-repeat: repeat-x;
  /* Confine the drift to the sky. The stops are measured, not guessed: the
     aside is always taller than it is wide and the photo is landscape 1.85:1,
     so background-size:cover always fills the height exactly and crops
     horizontally — which means panel % maps 1:1 onto image %. Sampling the
     visible slice puts the roofline at 18.8% down, with the row already ~46%
     building by 20%. So the clouds are solid to 13% and fully gone by 24%,
     and never touch the building. Two prefixes: Safari still needs -webkit-. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 13%, transparent 24%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 13%, transparent 24%);
  will-change: transform;
}

/* The softness is built into the gradient stops rather than added with
   filter: blur(). A blur filter on two full-panel layers that animate forever
   is a real cost on the modest hardware this runs on; a radial gradient that
   fades from its centre is already soft and costs nothing to composite.
   Vertical positions are percentages so the clouds stay inside the masked
   band on any panel height. */

/* Far layer — broad, slower. 1100px tile over 55s = 20px/s. */
.auth-sky-far {
  background-image:
    radial-gradient(170px 58px at 150px 6%,  rgba(255,255,255,.30), rgba(255,255,255,.12) 45%, transparent 72%),
    radial-gradient(215px 68px at 400px 12%, rgba(255,255,255,.25), rgba(255,255,255,.09) 45%, transparent 74%),
    radial-gradient(180px 58px at 680px 4%,  rgba(255,255,255,.22), rgba(255,255,255,.08) 45%, transparent 72%),
    radial-gradient(235px 74px at 930px 10%, rgba(255,255,255,.27), rgba(255,255,255,.10) 45%, transparent 74%);
  background-size: 1100px 100%;
  /* One tile wider than the panel, so translating a full tile never exposes
     a bare edge on the right. */
  width: calc(100% + 1100px);
  animation: auth-sky-drift 55s linear infinite;
}

/* Near layer — tighter and quicker. 760px over 27s = 28px/s. The difference
   in speed against the far layer is what reads as depth. */
.auth-sky-near {
  background-image:
    radial-gradient(135px 44px at 110px 9%,  rgba(255,255,255,.24), rgba(255,255,255,.09) 45%, transparent 72%),
    radial-gradient(160px 50px at 360px 3%,  rgba(255,255,255,.19), rgba(255,255,255,.07) 45%, transparent 74%),
    radial-gradient(145px 46px at 590px 14%, rgba(255,255,255,.21), rgba(255,255,255,.08) 45%, transparent 72%);
  background-size: 760px 100%;
  width: calc(100% + 760px);
  animation: auth-sky-drift-near 27s linear infinite;
}

/* Travel is exactly one tile width, so the repeat lines up and the loop has
   no seam. Driven by transform, not background-position: transform runs on
   the compositor, so the drift stays smooth and does not repaint the layer
   on every frame. */
@keyframes auth-sky-drift      { from { transform: translate3d(0, 0, 0); }
                                 to   { transform: translate3d(-1100px, 0, 0); } }
@keyframes auth-sky-drift-near { from { transform: translate3d(0, 0, 0); }
                                 to   { transform: translate3d(-760px, 0, 0); } }

/* Keep the panel's own content above the drifting layers. */
.auth-aside > .auth-brand,
.auth-aside > .auth-aside-body,
.auth-aside > .auth-aside-footer { position: relative; z-index: 1; }


/* =========================================================================
 * Sign-in splash
 * -------------------------------------------------------------------------
 * The login POST succeeds, then the page waits ~1.5s before redirecting. That
 * gap used to be a dead screen; it now carries the MORESCO 1 mark fading up.
 * Hidden and non-interactive until a page adds .is-visible.
 * ========================================================================= */
.auth-splash {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  background: var(--bg-body);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .45s ease, visibility 0s linear .45s;
}
.auth-splash.is-visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;      /* swallow clicks while the redirect is pending */
  transition: opacity .45s ease, visibility 0s;
}

.auth-splash-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
}
.auth-splash-inner img {
  width: 96px;
  height: 96px;
  object-fit: contain;
  opacity: 0;
  transform: scale(.9);
}
.auth-splash.is-visible .auth-splash-inner img {
  animation: auth-splash-in .9s cubic-bezier(.22, 1, .36, 1) forwards;
}

.auth-splash-word {
  font-family: "Inter Tight", Inter, sans-serif;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--t-base);
  opacity: 0;
}
.auth-splash-msg {
  font-size: 13px;
  color: var(--t-muted);
  opacity: 0;
}
.auth-splash.is-visible .auth-splash-word { animation: auth-splash-in .9s cubic-bezier(.22,1,.36,1) .12s forwards; }
.auth-splash.is-visible .auth-splash-msg  { animation: auth-splash-in .9s cubic-bezier(.22,1,.36,1) .24s forwards; }

@keyframes auth-splash-in {
  from { opacity: 0; transform: translateY(8px) scale(.94); }
  to   { opacity: 1; transform: none; }
}

/* =========================================================================
 * Reduced motion
 * Anyone who has asked the OS for less animation gets the same design with
 * the movement removed — the sky holds still and the splash simply appears.
 * ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .auth-sky-far,
  .auth-sky-near { animation: none; }

  .auth-splash,
  .auth-splash.is-visible { transition: opacity .01s linear; }

  .auth-splash.is-visible .auth-splash-inner img,
  .auth-splash.is-visible .auth-splash-word,
  .auth-splash.is-visible .auth-splash-msg {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* ---- brand mark ----
   The demo used an inline SVG wordmark; HRDD uses the MORESCO 1 logo, which
   needs to sit inside the same rounded tile without being cropped. */
.auth-brand .logo {
  overflow: hidden;
  display: grid;
  place-items: center;
}
.auth-brand .logo img {
  width: 24px;
  height: 24px;
  object-fit: contain;
}

/* ---- top bar ---- */
.auth-back-link {
  font-size: 12.5px;
  color: var(--t-muted);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  text-decoration: none;
}
.auth-back-link:hover { color: var(--t-base); }

.auth-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-card);
  color: var(--t-muted);
  cursor: pointer;
  transition: color .18s, border-color .18s, background .18s;
}
.auth-theme-toggle:hover { color: var(--t-base); border-color: var(--t-light); }
/* Show whichever icon represents the theme you would switch TO. */
[data-theme="light"] .auth-theme-toggle .ico-sun  { display: none; }
[data-theme="dark"]  .auth-theme-toggle .ico-moon { display: none; }

/* ---- password reveal ----
   Sits inside .input-icon, opposite the leading icon. The template's .input
   has no trailing padding reserved, so it is added here. */
.input-icon .reveal {
  position: absolute;
  top: 50%;
  right: 8px;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--t-light);
  cursor: pointer;
}
.input-icon .reveal:hover { color: var(--t-base); }
.input-icon .reveal svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; }
.input-icon:has(.reveal) .input { padding-right: 38px; }
/* :has() is unsupported in older engines; this class is set on the wrapper
   as a fallback so the text never runs under the button. */
.input-icon.has-reveal .input { padding-right: 38px; }

/* ---- validation + flash messages ---- */
.auth-alert {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 12.5px;
  line-height: 1.5;
  margin-bottom: 16px;
  border: 1px solid transparent;
}
.auth-alert svg { flex-shrink: 0; width: 15px; height: 15px; margin-top: 1px; fill: none; stroke: currentColor; stroke-width: 2; }
.auth-alert--error   { background: var(--danger-soft);  border-color: var(--danger);  color: var(--danger); }
.auth-alert--success { background: var(--success-soft); border-color: var(--success); color: var(--success); }
.auth-alert ul { margin: 0; padding-left: 16px; }

/* A field-level message, under the input it belongs to. */
.field-error {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--danger);
}
.input.is-invalid { border-color: var(--danger); }

/* ---- submit button ----
   .auth-submit is full width in the template; keep the arrow from wandering
   when the label is swapped for "Signing in…". */
.auth-submit { justify-content: center; }
.auth-submit[disabled] { opacity: .65; cursor: not-allowed; }
.auth-submit svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; }

/* ---- password rules note ---- */
.auth-note {
  font-size: 11.5px;
  line-height: 1.6;
  color: var(--t-muted);
  background: var(--bg-muted);
  border-radius: 8px;
  padding: 10px 12px;
}
.auth-note strong { color: var(--t-base); }
.auth-note ul { margin: 6px 0 0; padding-left: 16px; }

/* ---- helper link row under the card ---- */
.auth-alt-action {
  margin-top: 18px;
  text-align: center;
  font-size: 12.5px;
  color: var(--t-muted);
}
.auth-alt-action a { color: var(--primary); font-weight: 600; text-decoration: none; }
.auth-alt-action a:hover { text-decoration: underline; }

/* ---- toastr, retinted to the template's tokens ----
   The AdminLTE build ships its own green/red; on this palette they read as
   foreign, and they are unreadable against the dark theme. */
#toast-container > div {
  border-radius: 8px;
  box-shadow: var(--shadow-lg);
  opacity: 1;
  font-family: inherit;
  font-size: 13px;
}
#toast-container > .toast-success { background-color: var(--success); }
#toast-container > .toast-error   { background-color: var(--danger); }
#toast-container > .toast-info    { background-color: var(--info); }
#toast-container > .toast-warning { background-color: var(--warning); }
