/* LOCKED auth polish - Login + change password. Scope under body.auth-body / .auth-* */
/* @page-scope: auth - Perf: static blur layers + no live backdrop-filter (2026-08-06). Do not polish in prototype_parity.css. */
/* @page-scope: auth - Foreground GPU pass (2026-08-07):
   1. Ambient full-viewport layers sample on a ~50ms grid via steps(). Keyframes were re-cut at
      12.5% spacing along the original ease curve, so the motion path is unchanged; only the
      sampling rate drops. Per-step deltas are all sub-1.5px, so the drift reads as continuous.
   2. soft-light needs a destination read on desktop GPUs (no KHR_blend_equation_advanced), which
      costs a full-viewport render pass per frame. Removed from .auth-glass-sheen (a no-op: its
      backdrop inside .auth-glass is transparent) and from .auth-console-light (re-derived colour,
      matches to <1/255 by render diff). Fog keeps soft-light - it blends against the opaque
      atmosphere field, so no fixed normal-blend alpha matches across the luminance range. */
/* @page-scope: auth - Foreground GPU pass 3 (2026-08-07): the pass above throttled the CSS, but
   the pointer loop in login.html still wrote transforms once per displayed frame, so moving the
   mouse forced ~100 full-viewport soft-light re-blends/s (measured) and bypassed the whole 50ms
   grid. That loop now samples on the same grid. The only CSS part of the fix is cropping
   .auth-cursor-light and .auth-console-light to the extent where their gradients already reach
   zero alpha, which shrinks the region their movement invalidates. See the notes on each. */
/* @page-scope: auth - Foreground GPU pass 5 (2026-08-08): passes 1-4 all reduced how OFTEN the
   atmosphere re-rendered, and pass 4 went as far as freezing it after 2.5s of pointer stillness -
   which is what finally made video in another window playable, at the cost of the drift being
   stopped whenever anyone was actually reading the page. This pass attacks what a re-render COSTS
   instead, so the freeze could be deleted and the page animates continuously again.

   Attributed on the real target hardware (Intel UHD iGPU) with a query-string A/B, using a video
   seek as the detector - a seek is a burst of decode work, so it fails long before steady playback
   does. Three structural changes, in order of measured benefit:
     1. .auth-overlay - vignette/horizon/glass moved OUT of the isolated blend group. Their ticks
        were forcing the fog's full-screen soft-light passes to re-run. 0/255.
     2. Map split into consecutive static/moving SVG layers, so a dash tick re-rasters only the
        moving strokes rather than the whole map. 0 px above 16/255 at 1920x1080.
     3. .auth-fog-group - one soft-light pass for the three fog planes instead of three. 2/255.
   Things that were tried and measured WORSE, do not retry blindly: removing soft-light from the fog
   (30/255, plainly visible - soft-light raises backdrop contrast and no transparent layer can);
   removing isolation/contain from .auth-atmosphere; clip-path on the atmosphere to skip the region
   behind the opaque right-hand console (it forces an extra compositing pass costing more than the
   fifth of a screen it saves). */
/* Full-bleed ink navy floor. Looking through rain-glass into eThekwini. Credentials = edge console. */

:root {
  --auth-ink: #0D1A78;
  --auth-ink-deep: #07124f;
  --auth-night: #0D1A78;
  --auth-night-deep: #07124f;
  --auth-accent: #1088F8;
  --auth-accent-strong: #4f8df7;
  --auth-soft: #EEF2FB;
  --auth-line: #C5D0E8;
  --auth-muted: #4A5A7A;
  --auth-panel: #ffffff;
  --auth-critical: #9b1b6d;
  --auth-well: #EEF2FB;
  --auth-console: rgba(7, 18, 79, 0.82);
}

/* --- Login shell --- */

body.auth-body {
  min-height: 100vh;
  overflow: hidden !important;
  background: var(--auth-night) !important;
  color: #ffffff !important;
  -webkit-font-smoothing: antialiased;
  text-rendering: geometricPrecision;
}

body.auth-body .auth-shell {
  position: relative !important;
  min-height: 100vh !important;
  max-height: 100vh !important;
  overflow: hidden !important;
  padding: 0 !important;
  display: block !important;
  color: #ffffff !important;
  background: var(--auth-night) !important;
}

body.auth-body .auth-shell::before,
body.auth-body .auth-shell::after {
  content: none !important;
  display: none !important;
}

body.auth-body .auth-flash-wrap {
  position: absolute;
  z-index: 5;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  width: min(420px, calc(100% - 48px));
  margin: 0;
}

body.auth-body .auth-flash-wrap .alert {
  border-radius: 8px;
  border-color: rgba(197, 208, 232, 0.35);
  background: rgba(7, 18, 79, 0.94);
  color: #f5f9ff;
  backdrop-filter: blur(10px);
}

body.auth-body .auth-flash-wrap .btn-close {
  filter: invert(1) grayscale(1) brightness(1.8);
  opacity: 0.78;
}

/* --- Atmosphere: looking through rain-glass into eThekwini --- */

/* Keyframes below are the original ease-in-out curves resampled at 12.5% so that steps()
   can quantise the update rate without linearising the motion. */

@keyframes auth-aurora {
  0%, 100% { opacity: 0.55; }
  12.5% { opacity: 0.5926; }
  25% { opacity: 0.715; }
  37.5% { opacity: 0.8374; }
  50% { opacity: 0.88; }
  62.5% { opacity: 0.8374; }
  75% { opacity: 0.715; }
  87.5% { opacity: 0.5926; }
}

@keyframes auth-bloom {
  0%, 100% { opacity: 0.5; }
  12.5% { opacity: 0.5413; }
  25% { opacity: 0.66; }
  37.5% { opacity: 0.7787; }
  50% { opacity: 0.82; }
  62.5% { opacity: 0.7787; }
  75% { opacity: 0.66; }
  87.5% { opacity: 0.5413; }
}

@keyframes auth-horizon {
  0%, 100% { opacity: 0.88; }
  12.5% { opacity: 0.8955; }
  25% { opacity: 0.94; }
  37.5% { opacity: 0.9845; }
  50% { opacity: 1; }
  62.5% { opacity: 0.9845; }
  75% { opacity: 0.94; }
  87.5% { opacity: 0.8955; }
}

@keyframes auth-fog-a {
  0%, 100% { transform: translate3d(-4%, 2%, 0) scale(1.05); opacity: 0.42; }
  12.5% { transform: translate3d(-2.839%, 1.355%, 0) scale(1.059); opacity: 0.4535; }
  25% { transform: translate3d(0.5%, -0.5%, 0) scale(1.085); opacity: 0.55; }
  37.5% { transform: translate3d(3.839%, -2.355%, 0) scale(1.111); opacity: 0.6465; }
  50% { transform: translate3d(5%, -3%, 0) scale(1.12); opacity: 0.68; }
  62.5% { transform: translate3d(3.839%, -2.355%, 0) scale(1.111); opacity: 0.6465; }
  75% { transform: translate3d(0.5%, -0.5%, 0) scale(1.085); opacity: 0.55; }
  87.5% { transform: translate3d(-2.839%, 1.355%, 0) scale(1.059); opacity: 0.4535; }
}

@keyframes auth-fog-b {
  0%, 100% { transform: translate3d(6%, -2%, 0) scale(1.08); opacity: 0.35; }
  12.5% { transform: translate3d(4.323%, -1.226%, 0) scale(1.0929); opacity: 0.3848; }
  25% { transform: translate3d(-0.5%, 1%, 0) scale(1.13); opacity: 0.485; }
  37.5% { transform: translate3d(-5.323%, 3.226%, 0) scale(1.1671); opacity: 0.5852; }
  50% { transform: translate3d(-7%, 4%, 0) scale(1.18); opacity: 0.62; }
  62.5% { transform: translate3d(-5.323%, 3.226%, 0) scale(1.1671); opacity: 0.5852; }
  75% { transform: translate3d(-0.5%, 1%, 0) scale(1.13); opacity: 0.485; }
  87.5% { transform: translate3d(4.323%, -1.226%, 0) scale(1.0929); opacity: 0.3848; }
}

@keyframes auth-fog-c {
  0%, 100% { transform: translate3d(-2%, 6%, 0) scale(1.1); opacity: 0.28; }
  12.5% { transform: translate3d(-1.226%, 4.581%, 0) scale(1.1129); opacity: 0.3084; }
  25% { transform: translate3d(1%, 0.5%, 0) scale(1.15); opacity: 0.39; }
  37.5% { transform: translate3d(3.226%, -3.581%, 0) scale(1.1871); opacity: 0.4716; }
  50% { transform: translate3d(4%, -5%, 0) scale(1.2); opacity: 0.5; }
  62.5% { transform: translate3d(3.226%, -3.581%, 0) scale(1.1871); opacity: 0.4716; }
  75% { transform: translate3d(1%, 0.5%, 0) scale(1.15); opacity: 0.39; }
  87.5% { transform: translate3d(-1.226%, 4.581%, 0) scale(1.1129); opacity: 0.3084; }
}

@keyframes auth-coast-dash {
  to { stroke-dashoffset: -220; }
}

@keyframes auth-node-pulse {
  0%, 100% { opacity: 0.85; transform: scale(1); }
  12.5% { opacity: 0.8694; transform: scale(1.0452); }
  25% { opacity: 0.925; transform: scale(1.175); }
  37.5% { opacity: 0.9807; transform: scale(1.3049); }
  50% { opacity: 1; transform: scale(1.35); }
  62.5% { opacity: 0.9807; transform: scale(1.3049); }
  75% { opacity: 0.925; transform: scale(1.175); }
  87.5% { opacity: 0.8694; transform: scale(1.0452); }
}

@keyframes auth-ring-pulse {
  0% { opacity: 0.45; transform: scale(0.85); }
  17.5% { opacity: 0.2795; transform: scale(1.229); }
  35% { opacity: 0.1422; transform: scale(1.534); }
  52.5% { opacity: 0.0423; transform: scale(1.756); }
  70%, 100% { opacity: 0; transform: scale(1.85); }
}

@keyframes auth-droplet-drip {
  0% { transform: translate3d(0, 0, 0); }
  /* Only the long fall is quantised. The 0-12% swell and the implicit opacity ramp keep the
     animation-level linear easing, so the fade stays smooth. */
  12% { transform: translate3d(0, 2px, 0); animation-timing-function: steps(440); }
  100% { transform: translate3d(0, 52vh, 0); opacity: 0.15; }
}

@keyframes auth-duty-pulse {
  0%, 100% { text-shadow: 0 0 8px rgba(52, 211, 153, 0.35), 0 0 18px rgba(52, 211, 153, 0.18); }
  50% { text-shadow: 0 0 12px rgba(52, 211, 153, 0.55), 0 0 28px rgba(52, 211, 153, 0.28); }
}

@keyframes auth-place-glow {
  0%, 100% { text-shadow: 0 0 8px rgba(251, 191, 36, 0.22), 0 4px 12px rgba(7, 18, 79, 0.35); }
  50% { text-shadow: 0 0 14px rgba(251, 191, 36, 0.4), 0 4px 14px rgba(7, 18, 79, 0.35); }
}

@keyframes auth-rule-core {
  /* Quiet hold, then a load pulse every cycle */
  0%, 68% {
    transform: scaleX(1);
    opacity: 0.88;
    filter: brightness(1);
    box-shadow: 0 0 14px rgba(16, 136, 248, 0.45);
  }
  74% {
    transform: scaleX(0.18);
    opacity: 0.35;
    filter: brightness(0.85);
    box-shadow: 0 0 6px rgba(16, 136, 248, 0.2);
  }
  76% {
    transform: scaleX(0.18);
    opacity: 0.4;
  }
  88% {
    transform: scaleX(1.06);
    opacity: 1;
    filter: brightness(1.35);
    box-shadow: 0 0 22px rgba(56, 189, 248, 0.75);
  }
  100% {
    transform: scaleX(1);
    opacity: 0.88;
    filter: brightness(1);
    box-shadow: 0 0 14px rgba(16, 136, 248, 0.45);
  }
}

@keyframes auth-rule-node {
  0%, 68% {
    transform: scale(1);
    box-shadow: 0 0 8px rgba(16, 136, 248, 0.45), 0 0 0 0 rgba(16, 136, 248, 0.15);
  }
  74%, 76% {
    transform: scale(0.7);
    box-shadow: 0 0 4px rgba(16, 136, 248, 0.25);
  }
  88% {
    transform: scale(1.25);
    box-shadow: 0 0 16px rgba(56, 189, 248, 0.85), 0 0 0 5px rgba(16, 136, 248, 0.18);
  }
  100% {
    transform: scale(1);
    box-shadow: 0 0 8px rgba(16, 136, 248, 0.45), 0 0 0 0 rgba(16, 136, 248, 0.15);
  }
}

@keyframes auth-rule-ticks {
  0%, 68% { opacity: 0.55; }
  74%, 76% { opacity: 0.2; }
  88% { opacity: 1; }
  100% { opacity: 0.55; }
}

@keyframes auth-rule-scan {
  0%, 72% {
    transform: translate3d(-30%, 0, 0);
    opacity: 0;
  }
  76% {
    opacity: 0.9;
  }
  90% {
    transform: translate3d(160%, 0, 0);
    opacity: 0;
  }
  100% {
    transform: translate3d(160%, 0, 0);
    opacity: 0;
  }
}

@keyframes auth-glass-sheen {
  0%, 100% { opacity: 0.22; transform: translate3d(-2%, 0, 0); }
  12.5% { opacity: 0.2406; transform: translate3d(-1.355%, 0, 0); }
  25% { opacity: 0.3; transform: translate3d(0.5%, 0, 0); }
  37.5% { opacity: 0.3594; transform: translate3d(2.355%, 0, 0); }
  50% { opacity: 0.38; transform: translate3d(3%, 0, 0); }
  62.5% { opacity: 0.3594; transform: translate3d(2.355%, 0, 0); }
  75% { opacity: 0.3; transform: translate3d(0.5%, 0, 0); }
  87.5% { opacity: 0.2406; transform: translate3d(-1.355%, 0, 0); }
}

@keyframes auth-brand-in {
  from { opacity: 0; transform: translate3d(-12px, 10px, 0); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes auth-console-in {
  from { opacity: 0; transform: translate3d(18px, 0, 0); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes auth-spine {
  0%, 100% { opacity: 0.55; }
  12.5% { opacity: 0.6081; }
  25% { opacity: 0.775; }
  37.5% { opacity: 0.942; }
  50% { opacity: 1; }
  62.5% { opacity: 0.942; }
  75% { opacity: 0.775; }
  87.5% { opacity: 0.6081; }
}

body.auth-body .auth-atmosphere {
  --auth-mx: 38%;
  --auth-my: 48%;
  position: absolute !important;
  inset: 0 !important;
  z-index: 0 !important;
  pointer-events: none !important;
  overflow: hidden !important;
  isolation: isolate;
  contain: paint;
}

body.auth-body .auth-atmosphere-field {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 70% 55% at 42% 40%, rgba(16, 136, 248, 0.34), transparent 62%),
    radial-gradient(ellipse 48% 40% at 72% 55%, rgba(10, 61, 158, 0.35), transparent 70%),
    linear-gradient(155deg, #0a3d9e 0%, #0D1A78 34%, #0a1568 68%, #050d38 100%);
}

/* Artistic municipal map ? coast east, hinterland west */
body.auth-body .auth-map-plane {
  position: absolute;
  inset: -4%;
  /* Both of these used to sit on the single .auth-map SVG. The map is now several stacked layers
     (see login.html), and applying either one per layer is not the same picture as applying it
     once to the whole thing, so they live on the shared parent. */
  opacity: 0.92;
  filter: contrast(1.05) saturate(1.08);
}

body.auth-body .auth-map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* stroke-dashoffset can never be composited, so a dash tick always re-rasters on the CPU. It used
   to re-raster the entire full-viewport SVG - ocean, land gradient, ward lattice and all - because
   everything shared one element. The artwork is now split into consecutive static and moving
   layers in the original paint order, so a tick only redraws these strokes. The dash also travels
   ~11px/s on a 1080p viewport, so sampling at 50ms moves it 0.6px per step - below the
   antialiasing threshold. */
/* login.html re-rolls the duration, step count and dash pattern of this and .auth-map-river on
   every load, so these values are the fallback rather than what usually renders. Anything changing
   them must keep duration/steps at ~0.05s per step - that grid is what makes the atmosphere
   affordable, and it is easy to undo by accident when picking a new duration. */
body.auth-body .auth-map-coast {
  stroke-dasharray: 14 10;
  animation: auth-coast-dash 28s steps(560) infinite;
}

body.auth-body .auth-map-coast-soft {
  filter: blur(3px);
  opacity: 0.55;
}

body.auth-body .auth-map-river {
  stroke-dasharray: 6 14;
  animation: auth-coast-dash 40s steps(800) infinite reverse;
}

body.auth-body .auth-map-node-pulse {
  transform-box: fill-box;
  transform-origin: center;
  animation: auth-node-pulse 3.6s steps(9) infinite;
}

body.auth-body .auth-map-ring {
  transform-box: fill-box;
  transform-origin: center;
  animation: auth-ring-pulse 3.6s steps(13) infinite;
}

body.auth-body .auth-atmosphere-aurora {
  position: absolute;
  left: -10%;
  right: 10%;
  top: 18%;
  height: 55%;
  /* Blur lives on ::before so opacity animation does not re-filter each frame */
  background: none;
  filter: none;
  mix-blend-mode: screen;
  animation: auth-aurora 16s steps(40) infinite;
}

body.auth-body .auth-atmosphere-aurora::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 65% 50% at 40% 48%, rgba(16, 136, 248, 0.32), transparent 70%),
    radial-gradient(ellipse 40% 36% at 62% 58%, rgba(238, 242, 251, 0.1), transparent 72%);
  filter: blur(8px);
}

body.auth-body .auth-atmosphere-bloom {
  position: absolute;
  left: 22%;
  top: 28%;
  width: 46%;
  height: 44%;
  background: none;
  filter: none;
  animation: auth-bloom 14s steps(35) infinite;
}

body.auth-body .auth-atmosphere-bloom::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center, rgba(16, 136, 248, 0.3), transparent 68%);
  filter: blur(40px);
}

/* Drifting fog ? depth between map and glass.

   soft-light has no advanced-blend extension on desktop GL, so each soft-light layer is a
   backdrop readback - a full-screen render pass. With one such layer per fog plane, a single
   invalidation of the atmosphere cost three of them. The three planes now alpha-composite
   together inside this isolated group and the group blends with the backdrop once, so an
   invalidation costs one pass instead of three.

   Sequential soft-light is NOT algebraically the same as one pass over the union, so this is
   justified by measurement rather than by argument: worst case 2/255 across the animation cycle
   at 1920x1080, nothing on the page above 2/255, against a control that measured 0/255. For
   comparison, simply dropping soft-light was 30/255 and plainly visible. */
body.auth-body .auth-fog-group {
  position: absolute;
  inset: 0;
  pointer-events: none;
  isolation: isolate;
  mix-blend-mode: soft-light;
}

body.auth-body .auth-fog {
  position: absolute;
  inset: -20%;
  pointer-events: none;
  background: none;
  filter: none;
}

body.auth-body .auth-fog::before {
  content: "";
  position: absolute;
  inset: 0;
}

/* The three fog planes keep soft-light (see header note), so each one is a full-viewport
   destination-read pass. Sampling at 50ms cuts those passes from 180/s to 60/s; the blobs are
   blurred 48-64px and drift ~1.4px per step, so the motion still reads as continuous. */
body.auth-body .auth-fog-a {
  animation: auth-fog-a 22s steps(55) infinite;
}

body.auth-body .auth-fog-a::before {
  background:
    radial-gradient(ellipse 50% 36% at 28% 42%, rgba(238, 242, 251, 0.38), transparent 70%),
    radial-gradient(ellipse 42% 30% at 62% 58%, rgba(197, 208, 232, 0.22), transparent 72%);
  filter: blur(48px);
}

body.auth-body .auth-fog-b {
  animation: auth-fog-b 31s steps(78) infinite;
}

body.auth-body .auth-fog-b::before {
  background:
    radial-gradient(ellipse 55% 40% at 70% 35%, rgba(16, 136, 248, 0.2), transparent 68%),
    radial-gradient(ellipse 48% 34% at 35% 70%, rgba(238, 242, 251, 0.28), transparent 74%);
  filter: blur(56px);
}

body.auth-body .auth-fog-c {
  animation: auth-fog-c 26s steps(65) infinite;
}

body.auth-body .auth-fog-c::before {
  background:
    radial-gradient(ellipse 60% 28% at 48% 78%, rgba(197, 208, 232, 0.24), transparent 70%),
    radial-gradient(ellipse 36% 42% at 18% 28%, rgba(79, 141, 247, 0.16), transparent 68%);
  filter: blur(64px);
}

/* Cursor light through the pane ? brand side (window bloom)
   Position via transform (GPU) instead of re-painting a full-viewport gradient each frame.
   The box is cropped to where the gradient actually ends: the last stop is transparent at 68% of
   a 520x420 ending shape, i.e. 353.6 x 285.6 from the centre, so everything outside 708x572 was
   already alpha 0. Moving this element forces the fog's soft-light passes to re-run inside its
   box, and cropping to the painted extent drops that box from 0.61 to 0.28 of a 1600x900
   viewport. Gradient geometry is absolute px, so the rendering is unchanged. */
body.auth-body .auth-cursor-light {
  position: absolute;
  width: 708px;
  height: 572px;
  left: 0;
  top: 0;
  margin-left: -354px;
  margin-top: -286px;
  transform: translate3d(38vw, 48vh, 0);
  background:
    radial-gradient(
      520px 420px at 50% 50%,
      rgba(238, 242, 251, 0.22) 0%,
      rgba(16, 136, 248, 0.16) 22%,
      rgba(16, 136, 248, 0.05) 42%,
      transparent 68%
    );
  mix-blend-mode: screen;
  opacity: 1;
  transition: opacity 280ms ease;
  pointer-events: none;
}

body.auth-body.auth-pointer-console .auth-cursor-light {
  opacity: 0.12;
}

/* Sibling of .auth-atmosphere rather than a child of it, holding the vignette, horizon and glass.
   Same z-index and later in the DOM, so it paints straight after the atmosphere and still below
   .auth-stage at z-index 1 - which is exactly where .auth-glass used to sit. Everything inside
   blends normally, so the output is identical (verified 0/255).

   The point is what it does NOT have: no isolation, no contain. Inside the atmosphere's blend
   group, the sheen and the ~11 drifting droplets each forced the fog's full-screen soft-light
   pass to re-run on every one of their ticks, which was roughly half of all the invalidations
   this page produced. */
body.auth-body .auth-overlay {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

/* Glass pane + lens droplets */
body.auth-body .auth-glass {
  position: absolute;
  inset: 0;
  z-index: 2;
}

body.auth-body .auth-glass-film {
  position: absolute;
  inset: 0;
  /* No live backdrop-filter: it re-samples every animated layer underneath each frame. */
  background:
    linear-gradient(125deg, rgba(238, 242, 251, 0.08) 0%, transparent 28%, transparent 62%, rgba(16, 136, 248, 0.07) 100%),
    radial-gradient(ellipse 90% 70% at 50% 40%, rgba(255, 255, 255, 0.05), transparent 60%);
}

body.auth-body .auth-droplets {
  position: absolute;
  inset: 0;
  overflow: hidden;
  contain: layout style paint;
}

body.auth-body .auth-droplet {
  position: absolute;
  border-radius: 50% 50% 50% 50% / 52% 52% 48% 48%;
  background:
    radial-gradient(ellipse 55% 45% at 32% 28%, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.35) 35%, rgba(16, 136, 248, 0.12) 62%, rgba(7, 18, 79, 0.15) 100%);
  box-shadow:
    inset 0 -2px 4px rgba(7, 18, 79, 0.25),
    inset 1px 1px 2px rgba(255, 255, 255, 0.55),
    0 1px 2px rgba(7, 18, 79, 0.2);
}

body.auth-body .auth-droplet-lg {
  border-radius: 46% 54% 48% 52% / 42% 58% 42% 58%;
  box-shadow:
    inset 0 -3px 6px rgba(7, 18, 79, 0.28),
    inset 2px 2px 3px rgba(255, 255, 255, 0.65),
    0 2px 6px rgba(7, 18, 79, 0.22),
    0 0 12px rgba(16, 136, 248, 0.12);
}

body.auth-body .auth-droplet-drip {
  animation: auth-droplet-drip var(--drip-dur, 18s) linear var(--drip-delay, 0s) infinite;
}

/* Dropped mix-blend-mode: soft-light. .auth-glass is its own stacking context, so the sheen's
   backdrop was only .auth-glass-film and the droplets - almost fully transparent - and over a
   transparent backdrop soft-light degenerates to normal blending. The colours below are
   therefore unchanged; only the full-viewport destination-read pass goes away. Verified
   identical by render diff. */
body.auth-body .auth-glass-sheen {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(105deg, transparent 18%, rgba(255, 255, 255, 0.07) 42%, transparent 58%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.05) 0%, transparent 18%);
  animation: auth-glass-sheen 18s steps(45) infinite;
}

body.auth-body .auth-window-rim {
  position: absolute;
  inset: 0;
  box-shadow:
    inset 0 0 80px rgba(5, 13, 56, 0.55),
    inset 0 0 0 1px rgba(197, 208, 232, 0.08);
  background:
    linear-gradient(90deg, rgba(5, 13, 56, 0.35) 0%, transparent 8%, transparent 92%, rgba(5, 13, 56, 0.45) 100%),
    linear-gradient(180deg, rgba(5, 13, 56, 0.28) 0%, transparent 10%, transparent 88%, rgba(5, 13, 56, 0.4) 100%);
}

body.auth-body .auth-atmosphere-horizon {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 42%;
  z-index: 1;
  background:
    linear-gradient(180deg, transparent 0%, rgba(13, 26, 120, 0.18) 30%, rgba(5, 13, 56, 0.72) 100%);
  animation: auth-horizon 12s steps(30) infinite;
}

body.auth-body .auth-atmosphere-vignette {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(ellipse 72% 68% at 36% 44%, transparent 20%, rgba(5, 13, 56, 0.5) 100%),
    linear-gradient(90deg, transparent 0%, transparent 55%, rgba(5, 13, 56, 0.42) 100%);
}

/* Legacy atmosphere nodes (hidden) */
body.auth-body .auth-atmosphere-grid,
body.auth-body .auth-atmosphere-topo,
body.auth-body .auth-atmosphere-sky,
body.auth-body .auth-atmosphere-sea,
body.auth-body .auth-atmosphere-contours,
body.auth-body .auth-atmosphere-skyline,
body.auth-body .auth-atmosphere-haze,
body.auth-body .auth-atmosphere-mesh,
body.auth-body .auth-atmosphere-lightplane,
body.auth-body .auth-atmosphere-mist,
body.auth-body .auth-atmosphere-sheen,
body.auth-body .auth-atmosphere-coast,
body.auth-body .auth-atmosphere-scan,
body.auth-body .auth-atmosphere-sweep {
  display: none !important;
}

/* --- Floor Threshold stage: brand in environment + edge console --- */

body.auth-body .auth-stage.auth-stage-floor,
body.auth-body .auth-stage.auth-stage-duty,
body.auth-body .auth-stage.auth-stage-nightwatch,
body.auth-body .auth-stage.auth-stage-threshold,
body.auth-body .auth-stage.auth-stage-gate,
body.auth-body .auth-stage.auth-stage-login {
  position: relative !important;
  z-index: 1 !important;
  box-sizing: border-box !important;
  min-height: 100vh !important;
  height: 100vh !important;
  margin: 0 !important;
  padding: 0 !important;
  display: grid !important;
  grid-template-columns: minmax(0, 1fr) minmax(340px, 420px) !important;
  gap: 0 !important;
  align-items: stretch !important;
}

/* Kill legacy floating instrument card if present */
body.auth-body .auth-instrument {
  display: contents !important;
  width: auto !important;
  border: 0 !important;
  background: none !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  backdrop-filter: none !important;
  animation: none !important;
  overflow: visible !important;
}

body.auth-body .auth-instrument::before {
  display: none !important;
}

body.auth-body .auth-cluster {
  display: contents !important;
}

/* --- Brand floor (open night ? not a panel) --- */

body.auth-body .auth-floor-brand,
body.auth-body .auth-instrument-identity,
body.auth-body .auth-identity,
body.auth-body .auth-stage-floor .auth-hero,
body.auth-body .auth-stage-duty .auth-hero {
  position: relative !important;
  z-index: 1 !important;
  max-width: none !important;
  min-height: 100vh !important;
  padding: 48px 56px 40px 64px !important;
  display: flex !important;
  flex-direction: column !important;
  justify-content: space-between !important;
  align-items: flex-start !important;
  gap: 0 !important;
  background: transparent !important;
  border: 0 !important;
  animation: auth-brand-in 900ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

body.auth-body .auth-floor-brand-core {
  display: grid;
  justify-items: start;
  align-content: center;
  flex: 1 1 auto;
  padding-top: 4vh;
  max-width: 34rem;
}

body.auth-body .auth-brand-logo,
body.auth-body .auth-brand-seal {
  /* Official crest asset is 190?230 ? box matches that ratio exactly */
  --auth-seal-w: 100px;
  width: var(--auth-seal-w) !important;
  height: calc(var(--auth-seal-w) * 230 / 190) !important;
  min-width: var(--auth-seal-w) !important;
  min-height: calc(var(--auth-seal-w) * 230 / 190) !important;
  margin: 0 0 28px !important;
  padding: 0 !important;
  border-radius: 14px !important;
  background: #0a1a6e !important;
  border: 2px solid rgba(255, 255, 255, 0.95) !important;
  box-shadow:
    0 0 0 5px rgba(16, 136, 248, 0.22),
    0 0 36px rgba(16, 136, 248, 0.28),
    0 16px 36px rgba(7, 18, 79, 0.45) !important;
  display: grid !important;
  place-items: center !important;
  overflow: hidden !important;
  color: transparent !important;
  box-sizing: border-box !important;
  aspect-ratio: 190 / 230;
}

body.auth-body .auth-brand-logo img,
body.auth-body .auth-brand-seal img {
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
  max-height: none !important;
  object-fit: cover !important;
  object-position: center center !important;
  transform: none !important;
  display: block !important;
  border-radius: 12px;
}

body.auth-body .auth-civic,
body.auth-body .auth-brand-title,
body.auth-body .auth-stage-threshold h1.auth-brand-title,
body.auth-body .auth-stage-gate h1.auth-brand-title {
  margin: 0 0 12px !important;
  max-width: none !important;
  color: #f4f8ff !important;
  -webkit-text-fill-color: #f4f8ff !important;
  font-size: clamp(13px, 1.05vw, 15px) !important;
  line-height: 1.25 !important;
  letter-spacing: 0.18em !important;
  font-weight: 700 !important;
  text-transform: uppercase !important;
  text-shadow:
    0 1px 0 rgba(255, 255, 255, 0.12),
    0 8px 22px rgba(7, 18, 79, 0.5) !important;
}

body.auth-body .auth-ops-title,
body.auth-body .auth-product {
  margin: 0 !important;
  max-width: 11ch !important;
  color: #ffffff !important;
  -webkit-text-fill-color: #ffffff !important;
  font-size: clamp(52px, 6.2vw, 76px) !important;
  line-height: 0.90 !important;
  letter-spacing: -0.055em !important;
  font-weight: 850 !important;
  text-transform: none !important;
  text-shadow:
    0 18px 48px rgba(7, 18, 79, 0.55),
    0 0 40px rgba(16, 136, 248, 0.18) !important;
}

/* Legacy thin rule ? replaced by .auth-title-rule */
body.auth-body .auth-ops-title::after,
body.auth-body .auth-product::after {
  content: none !important;
  display: none !important;
}

/* Developed title rule ? instrument underline with periodic load pulse */
body.auth-body .auth-title-rule {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 10px;
  width: min(220px, 58%);
  margin: 20px 0 18px;
  height: 18px;
  overflow: hidden;
}

body.auth-body .auth-title-rule-core {
  width: 72px;
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(90deg, #1088F8 0%, #38bdf8 55%, rgba(56, 189, 248, 0.15) 100%);
  box-shadow: 0 0 16px rgba(16, 136, 248, 0.55);
  transform-origin: left center;
  animation: auth-rule-core 32.5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

body.auth-body .auth-title-rule-ticks {
  height: 10px;
  background:
    repeating-linear-gradient(
      90deg,
      rgba(197, 208, 232, 0.55) 0 1px,
      transparent 1px 7px
    );
  mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0.85), transparent 92%);
  -webkit-mask-image: linear-gradient(90deg, rgba(0, 0, 0, 0.85), transparent 92%);
  opacity: 0.7;
  animation: auth-rule-ticks 32.5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

body.auth-body .auth-title-rule-node {
  position: absolute;
  left: 68px;
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -3.5px;
  border-radius: 50%;
  background: #38bdf8;
  border: 1px solid rgba(244, 248, 255, 0.85);
  transform-origin: center;
  animation: auth-rule-node 32.5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

body.auth-body .auth-title-rule-fade {
  position: absolute;
  left: 0;
  top: 50%;
  width: 42px;
  height: 12px;
  margin-top: -6px;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, rgba(238, 242, 251, 0.55), transparent);
  filter: blur(1px);
  pointer-events: none;
  animation: auth-rule-scan 32.5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

body.auth-body .auth-threshold-copy {
  margin: 0 !important;
  max-width: 28rem;
  color: rgba(244, 248, 255, 0.78) !important;
  -webkit-text-fill-color: rgba(244, 248, 255, 0.78) !important;
  font-size: 16px !important;
  line-height: 1.5 !important;
  font-weight: 450 !important;
  text-shadow: 0 8px 20px rgba(7, 18, 79, 0.35);
}

body.auth-body .auth-lead,
body.auth-body .auth-status,
body.auth-body .auth-brand-hero,
body.auth-body .auth-brand-stack,
body.auth-body .auth-value-grid,
body.auth-body .auth-copy,
body.auth-body .auth-help-note,
body.auth-body .auth-posture,
body.auth-body .auth-posture-rail {
  display: none !important;
}

@keyframes auth-meta-tap {
  0% { filter: brightness(1); }
  40% { filter: brightness(1.18); }
  100% { filter: brightness(1); }
}

@keyframes auth-meta-tip-in {
  from { opacity: 0; transform: translate3d(0, 4px, 0); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* Duty strip: tight spacing; hover = glow only; click = quiet tip */
body.auth-body .auth-floor-meta-wrap {
  position: relative;
  display: block;
  max-width: min(420px, 100%);
}

body.auth-body .auth-floor-meta {
  display: inline-flex !important;
  align-items: center !important;
  flex-wrap: wrap !important;
  gap: 8px !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  background: transparent !important;
  color: #fbbf24 !important;
  -webkit-text-fill-color: #fbbf24 !important;
  font-size: 12px !important;
  font-weight: 650 !important;
  letter-spacing: 0.10em !important;
  text-transform: uppercase !important;
}

body.auth-body .auth-floor-meta-zone,
body.auth-body .auth-floor-meta-tz,
body.auth-body .auth-floor-meta-clock-wrap {
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
  padding: 2px 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
  transition: color 160ms ease, text-shadow 160ms ease, opacity 160ms ease;
}

body.auth-body .auth-floor-meta-zone,
body.auth-body .auth-floor-meta-tz {
  color: #fbbf24 !important;
  -webkit-text-fill-color: #fbbf24 !important;
  /* text-shadow is a paint property: this repainted the chips on the main thread every frame. */
  animation: auth-place-glow 4.2s steps(42) infinite;
}

body.auth-body .auth-floor-meta-clock-wrap {
  color: #34d399 !important;
  -webkit-text-fill-color: #34d399 !important;
}

body.auth-body .auth-floor-meta time {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.12em;
  color: #34d399 !important;
  -webkit-text-fill-color: #34d399 !important;
  font-weight: 750 !important;
  animation: auth-duty-pulse 2.8s steps(28) infinite;
}

body.auth-body .auth-floor-meta-zone:hover,
body.auth-body .auth-floor-meta-zone:focus-visible,
body.auth-body .auth-floor-meta-tz:hover,
body.auth-body .auth-floor-meta-tz:focus-visible {
  color: #fde68a !important;
  -webkit-text-fill-color: #fde68a !important;
  text-shadow: 0 0 14px rgba(251, 191, 36, 0.55);
  outline: none;
  animation: none;
}

body.auth-body .auth-floor-meta-clock-wrap:hover,
body.auth-body .auth-floor-meta-clock-wrap:focus-visible {
  outline: none;
}

body.auth-body .auth-floor-meta-clock-wrap:hover time,
body.auth-body .auth-floor-meta-clock-wrap:focus-visible time {
  color: #6ee7b7 !important;
  -webkit-text-fill-color: #6ee7b7 !important;
  text-shadow: 0 0 14px rgba(52, 211, 153, 0.55);
  animation: none;
}

body.auth-body .auth-floor-meta-zone.is-active,
body.auth-body .auth-floor-meta-tz.is-active {
  color: #fde68a !important;
  -webkit-text-fill-color: #fde68a !important;
  text-shadow: 0 0 14px rgba(251, 191, 36, 0.45);
  animation: none;
  box-shadow: inset 0 -2px 0 rgba(251, 191, 36, 0.85);
}

body.auth-body .auth-floor-meta-clock-wrap.is-active time {
  color: #6ee7b7 !important;
  -webkit-text-fill-color: #6ee7b7 !important;
  text-shadow: 0 0 14px rgba(52, 211, 153, 0.45);
  animation: none;
}

body.auth-body .auth-floor-meta-clock-wrap.is-active {
  box-shadow: inset 0 -2px 0 rgba(52, 211, 153, 0.85);
}

body.auth-body .auth-floor-meta-zone.is-tapped,
body.auth-body .auth-floor-meta-tz.is-tapped,
body.auth-body .auth-floor-meta-clock-wrap.is-tapped {
  animation: auth-meta-tap 420ms ease;
}

body.auth-body .auth-floor-meta-sep {
  opacity: 0.45;
  color: rgba(244, 248, 255, 0.45) !important;
  -webkit-text-fill-color: rgba(244, 248, 255, 0.45) !important;
}

/* Quiet tip ? absolute so it never shoves the strip */
body.auth-body .auth-floor-meta-tip {
  position: absolute;
  left: 0;
  bottom: calc(100% + 10px);
  display: none;
  width: max-content;
  max-width: min(320px, 70vw);
  margin: 0;
  padding: 8px 12px 8px 11px;
  border: 0;
  border-radius: 8px;
  border-left: 3px solid #fbbf24;
  background: rgba(7, 18, 79, 0.92);
  box-shadow: 0 10px 24px rgba(5, 13, 56, 0.4);
  color: #f4f8ff;
  text-transform: none;
  letter-spacing: 0;
  pointer-events: none;
}

body.auth-body .auth-floor-meta-tip.is-visible {
  display: block;
  animation: auth-meta-tip-in 220ms ease both;
}

body.auth-body .auth-floor-meta-tip[data-kind="time"] {
  border-left-color: #34d399;
}

body.auth-body .auth-floor-meta-tip-pip {
  display: none !important;
}

body.auth-body .auth-floor-meta-tip-copy {
  display: grid;
  gap: 2px;
}

body.auth-body .auth-floor-meta-tip-kicker {
  color: rgba(251, 191, 36, 0.9);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

body.auth-body .auth-floor-meta-tip[data-kind="time"] .auth-floor-meta-tip-kicker {
  color: rgba(52, 211, 153, 0.95);
}

body.auth-body .auth-floor-meta-tip-body {
  color: rgba(244, 248, 255, 0.88);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: 0.01em;
}

body.auth-body .auth-floor-meta-note {
  display: none !important;
}

/* --- Edge console strip (subordinate, docked ? not a card) --- */

body.auth-body .auth-floor-console,
body.auth-body .auth-instrument-console,
body.auth-body .auth-console,
body.auth-body .auth-card {
  --auth-cx: 50%;
  --auth-cy: 28%;
  position: relative !important;
  z-index: 2 !important;
  width: 100% !important;
  max-width: none !important;
  min-height: 100vh !important;
  height: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
  border-radius: 0 !important;
  border: 0 !important;
  border-left: 1px solid rgba(197, 208, 232, 0.28) !important;
  background:
    linear-gradient(180deg, rgba(16, 136, 248, 0.14) 0%, transparent 26%),
    linear-gradient(270deg, #07124f 0%, rgba(13, 26, 120, 0.94) 100%) !important;
  box-shadow:
    -20px 0 48px rgba(7, 18, 79, 0.28),
    inset 1px 0 0 rgba(16, 136, 248, 0.16) !important;
  /* Console fill is already near-opaque; live backdrop-filter only taxed the animated map behind it. */
  overflow: hidden;
  display: flex !important;
  flex-direction: column !important;
  color: var(--auth-soft) !important;
  animation: auth-console-in 820ms cubic-bezier(0.16, 1, 0.3, 1) 80ms both;
}

/* Console cursor highlight ? quiet instrument wash, not a second spotlight */
/* Cropped to the painted extent for the same reason as .auth-cursor-light: transparent at 68% of
   a 200x160 ending shape = 136 x 108.8 from the centre. The pre-script transform was 50%/28% of
   the old 400x320 box, restated in px so it resolves to the same place. */
body.auth-body .auth-console-light {
  position: absolute;
  width: 272px;
  height: 218px;
  left: 0;
  top: 0;
  z-index: 0;
  margin-left: -136px;
  margin-top: -109px;
  pointer-events: none;
  opacity: 0;
  transform: translate3d(200px, 89.6px, 0);
  /* soft-light over the console fill lifted blue strongly, green barely and red slightly
     negative. A deeper blue at a lower alpha reproduces that per-channel response under normal
     blending (error < 1/255 across the console gradient), and drops both the destination read
     and the isolated render surface the blend mode forced around the sign-in form. */
  background:
    radial-gradient(
      200px 160px at 50% 50%,
      rgba(0, 25, 250, 0.0353) 0%,
      rgba(0, 25, 250, 0.0141) 38%,
      transparent 68%
    );
  transition: opacity 260ms ease;
}

body.auth-body.auth-pointer-console .auth-console-light {
  opacity: 0.85;
}

body.auth-body .auth-floor-console > *:not(.auth-console-light) {
  position: relative;
  z-index: 1;
}

body.auth-body .auth-floor-console-spine {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: linear-gradient(180deg, transparent 8%, var(--auth-accent) 42%, var(--auth-accent) 58%, transparent 92%);
  box-shadow: 0 0 18px rgba(16, 136, 248, 0.35);
  animation: auth-spine 3.8s steps(10) infinite;
  pointer-events: none;
}

body.auth-body .auth-console-head,
body.auth-body .auth-instrument-head {
  flex: 0 0 auto;
  padding: 48px 36px 22px;
  border-bottom: 1px solid rgba(197, 208, 232, 0.14);
  background: linear-gradient(180deg, rgba(238, 242, 251, 0.05) 0%, transparent 100%);
}

body.auth-body .auth-console-kicker,
body.auth-body .auth-instrument-kicker,
body.auth-body .auth-card .auth-kicker {
  margin: 0 0 8px !important;
  color: #d7e6ff !important;
  -webkit-text-fill-color: #d7e6ff !important;
  font-size: 11px !important;
  font-weight: 800 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
}

body.auth-body .auth-console h2,
body.auth-body .auth-card h2,
body.auth-body .auth-instrument-head h2,
body.auth-body .auth-instrument-console h2,
body.auth-body .auth-floor-console h2 {
  margin: 0 0 8px !important;
  color: #ffffff !important;
  -webkit-text-fill-color: #ffffff !important;
  font-size: 26px !important;
  line-height: 1.1 !important;
  letter-spacing: -0.03em !important;
  font-weight: 850 !important;
  text-shadow: none !important;
}

body.auth-body .auth-console-lede {
  display: none !important;
}

body.auth-body .auth-console .auth-form,
body.auth-body .auth-card .auth-form,
body.auth-body .auth-instrument .auth-form,
body.auth-body .auth-instrument-console .auth-form,
body.auth-body .auth-floor-console .auth-form {
  display: grid !important;
  gap: 12px !important;
  padding: 28px 36px 12px !important;
  flex: 1 1 auto;
  align-content: start;
}

body.auth-body .auth-form label {
  margin: 0 !important;
  color: #EEF2FB !important;
  -webkit-text-fill-color: #EEF2FB !important;
  font-size: 11px !important;
  font-weight: 800 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
}

body.auth-body .auth-form input,
body.auth-body .auth-card input,
body.auth-body .auth-console input,
body.auth-body .auth-instrument-console input,
body.auth-body .auth-floor-console input {
  width: 100%;
  min-height: 50px !important;
  padding: 0 14px !important;
  border-radius: 6px !important;
  border: 1px solid #C5D0E8 !important;
  background: #EEF2FB !important;
  color: #0D1A78 !important;
  -webkit-text-fill-color: #0D1A78 !important;
  caret-color: #1088F8 !important;
  font-size: 15px !important;
  font-weight: 600 !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.65) !important;
}

body.auth-body .auth-form input::placeholder,
body.auth-body .auth-card input::placeholder,
body.auth-body .auth-console input::placeholder,
body.auth-body .auth-instrument-console input::placeholder,
body.auth-body .auth-floor-console input::placeholder {
  color: #4A5A7A !important;
  -webkit-text-fill-color: #4A5A7A !important;
  opacity: 1 !important;
}

body.auth-body .auth-form input:focus,
body.auth-body .auth-form input:focus-visible,
body.auth-body .auth-card input:focus,
body.auth-body .auth-card input:focus-visible,
body.auth-body .auth-console input:focus,
body.auth-body .auth-console input:focus-visible,
body.auth-body .auth-instrument-console input:focus,
body.auth-body .auth-instrument-console input:focus-visible,
body.auth-body .auth-floor-console input:focus,
body.auth-body .auth-floor-console input:focus-visible {
  outline: none;
  border-color: #1088F8 !important;
  box-shadow:
    0 0 0 3px rgba(16, 136, 248, 0.35),
    inset 0 1px 0 rgba(255, 255, 255, 0.75) !important;
  background: #ffffff !important;
  color: #0D1A78 !important;
  -webkit-text-fill-color: #0D1A78 !important;
}

body.auth-body .auth-form input[aria-invalid="true"] {
  border-color: rgba(155, 27, 109, 0.85) !important;
  box-shadow: 0 0 0 3px rgba(155, 27, 109, 0.22) !important;
}

body.auth-body .auth-form input:-webkit-autofill,
body.auth-body .auth-form input:-webkit-autofill:hover,
body.auth-body .auth-form input:-webkit-autofill:focus,
body.auth-body .auth-card input:-webkit-autofill,
body.auth-body .auth-console input:-webkit-autofill,
body.auth-body .auth-instrument-console input:-webkit-autofill,
body.auth-body .auth-floor-console input:-webkit-autofill {
  -webkit-text-fill-color: #0D1A78 !important;
  color: #0D1A78 !important;
  caret-color: #1088F8 !important;
  border: 1px solid #C5D0E8 !important;
  box-shadow: 0 0 0 1000px #EEF2FB inset !important;
  -webkit-box-shadow: 0 0 0 1000px #EEF2FB inset !important;
  transition: background-color 99999s ease-out 0s !important;
}

body.auth-body .auth-password-wrap {
  position: relative !important;
  display: grid !important;
}

body.auth-body .auth-password-wrap input {
  padding-right: 78px !important;
}

body.auth-body .auth-password-toggle {
  position: absolute !important;
  top: 50% !important;
  right: 8px !important;
  transform: translateY(-50%) !important;
  border: 0 !important;
  background: transparent !important;
  color: #0D1A78 !important;
  font-size: 11px !important;
  font-weight: 800 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  padding: 8px 10px !important;
  border-radius: 4px !important;
  cursor: pointer !important;
}

body.auth-body .auth-password-toggle:hover,
body.auth-body .auth-password-toggle:focus-visible {
  background: rgba(16, 136, 248, 0.16) !important;
  color: #0D1A78 !important;
  outline: none !important;
}

body.auth-body .auth-caps-hint {
  margin: -2px 0 0 !important;
  color: #f0c674 !important;
  font-size: 12px !important;
  font-weight: 650 !important;
}

body.auth-body .auth-form-error {
  margin: 18px 36px 0 !important;
  padding: 11px 12px !important;
  border-radius: 6px !important;
  border: 1px solid rgba(155, 27, 109, 0.45) !important;
  background: rgba(155, 27, 109, 0.16) !important;
  color: #f5c6de !important;
  font-size: 13px !important;
  line-height: 1.4 !important;
  font-weight: 650 !important;
}

body.auth-body .auth-submit,
body.auth-body .auth-card .auth-submit,
body.auth-body .auth-console .auth-submit,
body.auth-body .auth-instrument-console .auth-submit,
body.auth-body .auth-floor-console .auth-submit {
  width: 100%;
  margin-top: 10px !important;
  min-height: 52px !important;
  border: 0 !important;
  border-radius: 6px !important;
  color: #ffffff !important;
  -webkit-text-fill-color: #ffffff !important;
  font-size: 13px !important;
  font-weight: 850 !important;
  letter-spacing: 0.10em !important;
  text-transform: uppercase !important;
  background: #1088F8 !important;
  box-shadow: 0 12px 28px rgba(16, 136, 248, 0.40) !important;
  transition: filter 160ms ease, box-shadow 160ms ease, transform 160ms ease;
}

body.auth-body .auth-submit:hover {
  filter: brightness(1.08);
  transform: translateY(-1px);
  box-shadow: 0 16px 36px rgba(16, 136, 248, 0.48) !important;
}

body.auth-body .auth-submit:active {
  transform: translateY(0);
}

body.auth-body .auth-submit.is-busy,
body.auth-body .auth-submit:disabled {
  opacity: 0.82 !important;
  cursor: wait !important;
  transform: none !important;
  filter: none !important;
}

body.auth-body .auth-console-help,
body.auth-body .auth-card-help {
  margin: auto 0 0 !important;
  padding: 16px 36px 28px !important;
  color: rgba(215, 230, 255, 0.72) !important;
  -webkit-text-fill-color: rgba(215, 230, 255, 0.72) !important;
  font-size: 12px !important;
  line-height: 1.45 !important;
  font-weight: 500 !important;
  border-top: 1px solid rgba(197, 208, 232, 0.22);
  background: rgba(7, 18, 79, 0.35);
  flex: 0 0 auto;
}

body.auth-body .auth-card-lede,
body.auth-body .auth-card > p:not(.auth-card-help):not(.auth-console-help):not(.auth-caps-hint):not(.auth-form-error):not(.auth-console-lede) {
  display: none !important;
}

/* --- Responsive --- */

@media (max-width: 1100px) {
  body.auth-body .auth-stage.auth-stage-floor,
  body.auth-body .auth-stage.auth-stage-duty,
  body.auth-body .auth-stage.auth-stage-nightwatch,
  body.auth-body .auth-stage.auth-stage-threshold,
  body.auth-body .auth-stage.auth-stage-gate,
  body.auth-body .auth-stage.auth-stage-login {
    grid-template-columns: minmax(0, 1fr) minmax(320px, 380px) !important;
  }

  body.auth-body .auth-floor-brand,
  body.auth-body .auth-instrument-identity {
    padding: 40px 40px 32px 44px !important;
  }

  body.auth-body .auth-ops-title,
  body.auth-body .auth-product {
    font-size: clamp(46px, 5.5vw, 64px) !important;
  }
}

@media (max-width: 820px) {
  body.auth-body {
    overflow: auto !important;
  }

  body.auth-body .auth-shell {
    max-height: none !important;
    overflow: auto !important;
  }

  body.auth-body .auth-stage.auth-stage-floor,
  body.auth-body .auth-stage.auth-stage-duty,
  body.auth-body .auth-stage.auth-stage-nightwatch,
  body.auth-body .auth-stage.auth-stage-threshold,
  body.auth-body .auth-stage.auth-stage-gate,
  body.auth-body .auth-stage.auth-stage-login {
    height: auto !important;
    min-height: 100vh !important;
    grid-template-columns: 1fr !important;
    grid-template-rows: auto auto !important;
  }

  body.auth-body .auth-floor-brand,
  body.auth-body .auth-instrument-identity {
    min-height: auto !important;
    padding: 36px 24px 28px !important;
    gap: 36px !important;
  }

  body.auth-body .auth-floor-brand-core {
    padding-top: 8px;
    max-width: none;
  }

  body.auth-body .auth-floor-console,
  body.auth-body .auth-instrument-console {
    min-height: auto !important;
    border-left: 0 !important;
    border-top: 1px solid rgba(197, 208, 232, 0.22) !important;
    box-shadow: 0 -18px 48px rgba(7, 18, 79, 0.35) !important;
  }

  body.auth-body .auth-floor-console-spine {
    top: 0;
    left: 0;
    right: 0;
    bottom: auto;
    width: auto;
    height: 3px;
    background: linear-gradient(90deg, transparent 8%, var(--auth-accent) 42%, var(--auth-accent) 58%, transparent 92%);
  }

  body.auth-body .auth-console-head {
    padding: 28px 24px 18px !important;
  }

  body.auth-body .auth-floor-console .auth-form,
  body.auth-body .auth-instrument-console .auth-form {
    padding: 22px 24px 10px !important;
  }

  body.auth-body .auth-console-help,
  body.auth-body .auth-form-error {
    padding-left: 24px !important;
    padding-right: 24px !important;
  }

  body.auth-body .auth-form-error {
    margin-left: 24px !important;
    margin-right: 24px !important;
  }

  body.auth-body .auth-flash-wrap {
    left: 16px;
    transform: none;
    width: calc(100% - 32px);
  }

  body.auth-body .auth-brand-logo {
    --auth-seal-w: 86px;
    width: var(--auth-seal-w) !important;
    height: calc(var(--auth-seal-w) * 230 / 190) !important;
    min-width: var(--auth-seal-w) !important;
    min-height: calc(var(--auth-seal-w) * 230 / 190) !important;
    margin-bottom: 20px !important;
    padding: 0 !important;
  }

  body.auth-body .auth-ops-title,
  body.auth-body .auth-product {
    font-size: clamp(40px, 11vw, 56px) !important;
  }
}

@media (max-width: 720px) {
  body.auth-body .auth-console-head,
  body.auth-body .auth-floor-console .auth-form,
  body.auth-body .auth-console-help,
  body.auth-body .auth-form-error {
    padding-left: 18px !important;
    padding-right: 18px !important;
  }

  body.auth-body .auth-form-error {
    margin-left: 18px !important;
    margin-right: 18px !important;
  }

  body.auth-body .auth-floor-brand,
  body.auth-body .auth-instrument-identity {
    padding: 28px 18px 24px !important;
  }

  body.auth-body .auth-threshold-copy {
    font-size: 15px !important;
  }
}

@media (max-height: 700px) and (min-width: 821px) {
  body.auth-body .auth-floor-brand,
  body.auth-body .auth-instrument-identity {
    padding: 28px 40px 24px 48px !important;
  }

  body.auth-body .auth-floor-brand-core {
    padding-top: 0;
  }

  body.auth-body .auth-brand-logo {
    --auth-seal-w: 74px;
    width: var(--auth-seal-w) !important;
    height: calc(var(--auth-seal-w) * 230 / 190) !important;
    min-width: var(--auth-seal-w) !important;
    min-height: calc(var(--auth-seal-w) * 230 / 190) !important;
    margin-bottom: 16px !important;
    padding: 0 !important;
  }

  body.auth-body .auth-ops-title,
  body.auth-body .auth-product {
    font-size: clamp(40px, 4.8vw, 56px) !important;
  }

  body.auth-body .auth-title-rule {
    margin: 14px 0 14px;
  }

  body.auth-body .auth-threshold-copy {
    font-size: 14px !important;
  }

  body.auth-body .auth-console-head {
    padding-top: 28px !important;
    padding-bottom: 16px !important;
  }

  body.auth-body .auth-floor-console .auth-form {
    padding-top: 18px !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  body.auth-body .auth-atmosphere-aurora,
  body.auth-body .auth-atmosphere-bloom,
  body.auth-body .auth-atmosphere-horizon,
  body.auth-body .auth-fog,
  body.auth-body .auth-map-coast,
  body.auth-body .auth-map-river,
  body.auth-body .auth-map-node-pulse,
  body.auth-body .auth-map-ring,
  body.auth-body .auth-droplet-drip,
  body.auth-body .auth-glass-sheen,
  body.auth-body .auth-floor-brand,
  body.auth-body .auth-floor-console,
  body.auth-body .auth-floor-console-spine,
  body.auth-body .auth-floor-meta time,
  body.auth-body .auth-floor-meta-zone,
  body.auth-body .auth-floor-meta-tz,
  body.auth-body .auth-title-rule-core,
  body.auth-body .auth-title-rule-node,
  body.auth-body .auth-title-rule-ticks,
  body.auth-body .auth-title-rule-fade,
  body.auth-body .auth-floor-meta-zone.is-tapped,
  body.auth-body .auth-floor-meta-tz.is-tapped,
  body.auth-body .auth-floor-meta-clock-wrap.is-tapped,
  body.auth-body .auth-floor-meta-note.is-visible,
  body.auth-body .auth-floor-meta-tip.is-visible {
    animation: none !important;
  }

  body.auth-body .auth-floor-meta time {
    text-shadow: 0 0 10px rgba(52, 211, 153, 0.4);
  }

  body.auth-body .auth-floor-meta-zone,
  body.auth-body .auth-floor-meta-tz {
    text-shadow: 0 0 8px rgba(251, 191, 36, 0.28);
  }

  body.auth-body .auth-cursor-light,
  body.auth-body .auth-console-light {
    opacity: 0 !important;
    transition: none !important;
  }
}

/* Pause continuous atmosphere work when the tab is hidden. The page is not on display then, so
   this is invisible; animation-play-state holds the exact current frame and resuming picks up from
   the same point with no jump.

   The pointer-idle variant of this (.auth-idle-frozen) has been removed. It froze the atmosphere
   2.5s after the last mouse movement, which is most of the time anyone is actually reading the
   page, so the drift was almost never running when it was meant to be. What it was compensating
   for is now fixed structurally: the glass sits outside the blend group, the map re-rasters only
   its moving strokes, and the fog blends once instead of three times. */
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-atmosphere-aurora,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-atmosphere-bloom,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-atmosphere-horizon,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-fog,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-map-coast,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-map-river,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-map-node-pulse,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-map-ring,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-droplet-drip,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-glass-sheen,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-floor-console-spine,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-floor-meta time,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-floor-meta-zone,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-floor-meta-tz,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-title-rule-core,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-title-rule-node,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-title-rule-ticks,
body.auth-body:is(.auth-tab-paused, .auth-away) .auth-title-rule-fade {
  animation-play-state: paused !important;
}

/* Adaptive load shedding - see the note in login.html for when the page enters and leaves this
   state. Applied live while something else on the machine needs the GPU, and lifted again when it
   does not, so it is transient rather than a verdict about the computer.

   Gives up only the two genuinely expensive things. The fog is one soft-light backdrop readback
   plus 48/56/64px blur intermediates, and the coast and rivers are a CPU re-raster on every dash
   tick because stroke-dashoffset can never be composited. Everything that stays is compositable and
   outside the blend group: the field, the glow, the aurora, the glass, its droplets and the sheen.
   The node keeps pulsing too - it is a handful of pixels - so the page still reads as live.

   Two classes, not one: .auth-shedding fades the fog, .auth-shed then stops painting it. Going
   straight to display:none would snap, and leaving it at opacity 0 would keep paying for the blend.
   The dashes are paused rather than cancelled, so they resume from the same phase with no jump. */
body.auth-body .auth-fog-group {
  transition: opacity 280ms linear;
}

body.auth-body.auth-shedding .auth-fog-group {
  opacity: 0;
}

body.auth-body.auth-shed .auth-fog-group {
  display: none !important;
}

body.auth-body.auth-shed .auth-map-coast,
body.auth-body.auth-shed .auth-map-river {
  animation-play-state: paused !important;
}

/* ?diag readout. Inert unless login.html creates the element, which only happens with the flag. */
.auth-diag {
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 99999;
  padding: 6px 10px;
  border: 1px solid rgba(238, 242, 251, 0.3);
  border-radius: 4px;
  background: rgba(5, 13, 56, 0.92);
  color: #EEF2FB;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.35;
  letter-spacing: 0.02em;
  white-space: pre;
  pointer-events: none;
}

/* --- Change password (authenticated shell) ? brand-aligned --- */

.auth-account-page {
  display: flex !important;
  align-items: stretch !important;
  justify-content: center !important;
  min-height: calc(100vh - 88px) !important;
  padding: 20px 18px 28px !important;
  box-sizing: border-box !important;
  background: transparent !important;
  color: var(--auth-ink) !important;
}

.auth-account-panel {
  display: grid !important;
  grid-template-columns: minmax(240px, 0.9fr) minmax(320px, 1.2fr) !important;
  width: min(920px, 100%) !important;
  margin: 0 auto !important;
  overflow: hidden !important;
  border: 1px solid var(--auth-line) !important;
  border-radius: 12px !important;
  background: var(--auth-panel) !important;
  box-shadow: 0 16px 40px rgba(13, 26, 120, 0.10) !important;
}

.auth-account-aside {
  display: flex !important;
  flex-direction: column !important;
  justify-content: center !important;
  gap: 12px !important;
  padding: 36px 32px !important;
  background:
    radial-gradient(ellipse 80% 60% at 20% 20%, rgba(16, 136, 248, 0.28), transparent 55%),
    linear-gradient(165deg, #0D1A78 0%, #081878 55%, #06145f 100%) !important;
  color: #ffffff !important;
}

.auth-account-kicker {
  margin: 0 !important;
  font-size: 11px !important;
  font-weight: 800 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  color: rgba(238, 242, 251, 0.72) !important;
}

.auth-account-aside h1 {
  margin: 0 !important;
  font-size: 28px !important;
  line-height: 1.15 !important;
  letter-spacing: -0.03em !important;
  font-weight: 850 !important;
  color: #ffffff !important;
}

.auth-account-lede {
  margin: 0 !important;
  font-size: 14px !important;
  line-height: 1.45 !important;
  color: rgba(238, 242, 251, 0.78) !important;
}

.auth-account-form-wrap {
  padding: 32px 28px !important;
  background: #ffffff !important;
}

.auth-account-form {
  display: grid !important;
  gap: 10px !important;
}

.auth-account-form label {
  margin: 0 !important;
  font-size: 11px !important;
  font-weight: 800 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  color: var(--auth-ink) !important;
}

.auth-account-form input {
  width: 100%;
  min-height: 46px !important;
  padding: 0 12px !important;
  border-radius: 6px !important;
  border: 1px solid #8fa0c0 !important;
  background: #ffffff !important;
  color: var(--auth-ink) !important;
  font-size: 15px !important;
}

.auth-account-form input:focus,
.auth-account-form input:focus-visible {
  outline: none;
  border-color: var(--auth-accent) !important;
  box-shadow: 0 0 0 3px rgba(16, 136, 248, 0.18) !important;
}

.auth-account-submit {
  margin-top: 8px !important;
  min-height: 48px !important;
  border-radius: 6px !important;
  font-weight: 800 !important;
  letter-spacing: 0.06em !important;
  text-transform: uppercase !important;
}

@media (max-width: 760px) {
  .auth-account-panel {
    grid-template-columns: 1fr !important;
  }

  .auth-account-aside {
    padding: 24px 22px !important;
  }

  .auth-account-form-wrap {
    padding: 22px 18px !important;
  }
}

/* @page-scope: auth - Focus visibility in Windows High Contrast.
   Every focus indicator on these pages is drawn with box-shadow, a colour change or a text-shadow,
   and each of those rules turns the real outline off. Forced-colours mode discards all three, so
   the indicator disappears entirely: measured in Chrome's forced-colours emulation, focusing the
   username field changed 20 pixels of the field and its surroundings - the text caret, and nothing
   else. A keyboard user in High Contrast therefore has no way to see where they are on a login
   form, which is a plain WCAG 2.4.7 failure and the sort of thing a municipality gets asked about.

   Outline is the one indicator forced-colours honours, and the Highlight system colour matches
   whichever High Contrast theme the person has chosen rather than fighting it. The override has to
   be !important because several of the base rules set outline: none !important. All of this lives
   inside the media query, so normal rendering is byte-for-byte unchanged. */
@media (forced-colors: active) {
  body.auth-body .auth-form input:focus-visible,
  body.auth-body .auth-card input:focus-visible,
  body.auth-body .auth-console input:focus-visible,
  body.auth-body .auth-instrument-console input:focus-visible,
  body.auth-body .auth-floor-console input:focus-visible,
  body.auth-body .auth-password-toggle:focus-visible,
  body.auth-body button:focus-visible,
  body.auth-body a:focus-visible,
  body.auth-body [tabindex]:focus-visible,
  .auth-account-form input:focus-visible,
  .auth-account-form button:focus-visible,
  .auth-account-submit:focus-visible {
    outline: 3px solid Highlight !important;
    outline-offset: 2px !important;
  }
}

/* === SHARED LIGHT PRIMITIVES v1 ===
   prototype_parity.css is the original dark theme. These shared
   components kept dark backgrounds while this family forces text to
   dark navy, which rendered them dark-on-dark. Values are the family
   palette declared above, so all pages describe them identically.
   Scope: .auth-login-page, .auth-account-page */
body:has(.auth-login-page) .empty-state,
body:has(.auth-account-page) .empty-state {
  background:#F5F9FF !important;border:1px dashed #C5D0E8 !important;color:#4A5A7A !important;
}
body:has(.auth-login-page) .empty-state b, body:has(.auth-login-page) .empty-state strong,
body:has(.auth-account-page) .empty-state b, body:has(.auth-account-page) .empty-state strong {
  color:#0D1A78 !important;
}
body:has(.auth-login-page) .attention,
body:has(.auth-account-page) .attention {
  background:#FFFFFF !important;border-color:#C5D0E8 !important;color:#0D1A78 !important;
}
body:has(.auth-login-page) .alert,
body:has(.auth-account-page) .alert {
  background:#FFFFFF !important;border:1px solid #C5D0E8 !important;color:#0D1A78 !important;box-shadow:0 8px 22px rgba(13,26,120,.06) !important;
}
body:has(.auth-login-page) .alert-success,
body:has(.auth-account-page) .alert-success {
  background:#EEF9F1 !important;border-color:#B7DFC4 !important;color:#1B6B39 !important;
}
body:has(.auth-login-page) .alert-danger,
body:has(.auth-account-page) .alert-danger {
  background:#FDECEC !important;border-color:#E3B0B0 !important;color:#A62121 !important;
}
body:has(.auth-login-page) .alert-warning,
body:has(.auth-account-page) .alert-warning {
  background:#FFF6E8 !important;border-color:#E8CE9C !important;color:#8A5300 !important;
}
body:has(.auth-login-page) .alert-info,
body:has(.auth-account-page) .alert-info {
  background:#EEF2FB !important;border-color:#C5D0E8 !important;color:#0D1A78 !important;
}

/* Light-theme flash dismiss on Change Password (login dark flashes already invert via .auth-body) */
body:has(.auth-account-page) .alert .btn-close {
  filter:none!important;
  opacity:.65!important;
  background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230D1A78'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat!important;
}
/* === SUNDAY MATURITY PUSH: auth sign-in trust cues === */
body.auth-body .auth-login-page h1,
body:has(.auth-login-page) h1 {
  letter-spacing: -0.03em !important;
}
body.auth-body .auth-login-page .lede,
body:has(.auth-login-page) .lede {
  color: rgba(247, 251, 255, 0.82) !important;
}
