/* ================================================================
   auth.css  —  IngressGateway authentication pages
   Design system mirrors iop-app (Angular 20 / Tailwind dark theme)
   ================================================================ */

/* ── Design Tokens ─────────────────────────────────────────────── */
:root {
  --color-bg:               #081028;          /* dashboard-bg        */
  --color-card:             #08122E;          /* dashboard-sidebar   */
  --color-card-hover:       #0F1535;          /* dashboard-bg-light  */
  --color-primary:          #0251F1;          /* dashboard-primary   */
  --color-primary-glow:     rgba(2, 81, 241, 0.15);
  --color-primary-border:   rgba(2, 81, 241, 0.4);
  --color-primary-gradient: linear-gradient(90deg, rgba(2, 81, 241, 0.8), rgba(2, 81, 241, 0.4));
  --color-text-primary:     #FFFFFF;
  --color-text-secondary:   #CBD5E0;
  --color-text-muted:       #A0AEC0;
  --color-border:           rgba(255, 255, 255, 0.1);
  --color-border-strong:    rgba(255, 255, 255, 0.3);
  --color-field-bg:         rgba(15, 21, 53, 0.6);
  --color-field-bg-focused: rgba(15, 21, 53, 0.8);
  --color-field-label:      rgba(255, 255, 255, 0.4);
  --color-field-label-active: rgba(150, 180, 255, 0.85);
  --color-field-text:       rgba(255, 255, 255, 0.95);
  --color-error:            rgba(255, 100, 100, 1);
  --color-error-border:     rgba(241, 2,   2,   0.4);
  --color-error-glow:       rgba(241, 2,   2,   0.15);
  --color-warning-border:   rgba(255, 142, 0,   0.3);
  --color-warning-text:     rgba(255, 200, 100, 0.9);
  --color-warning-bg:       rgba(255, 142, 0,   0.08);
  --font-body:    'Geologica', -apple-system, Roboto, Helvetica, sans-serif;
  --font-display: 'Figtree',   -apple-system, Roboto, Helvetica, sans-serif;
  --radius-sm:   0.375rem;   /* 6px  */
  --radius-field: 0.5rem;   /* 8px  */
  --radius-card:  0.875rem; /* 14px */
  --transition-fast: 200ms ease-in-out;
  --transition-base: 300ms ease-in-out;
}

/* ── Reset & Base ──────────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  height: 100%;
}

body {
  font-family: var(--font-body);
  background-color: var(--color-bg);
  color: var(--color-text-primary);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* ── Auth Page — full-screen centred wrapper ───────────────────── */
/*
   The .auth-page div lives inside each view, not in the layout,
   so Privacy / Error pages can render without centering constraints.
*/
.auth-page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  /*
     Subtle radial glow replicates the feeling of the Angular SPA
     where the primary blue "breathes" in from the centre.
  */
  background-image: radial-gradient(
    ellipse at 50% 40%,
    rgba(2, 81, 241, 0.07) 0%,
    transparent 65%
  );
}

/* ── Sign-in Card ──────────────────────────────────────────────── */
.auth-card {
  width: 100%;
  max-width: 420px;
  background-color: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  padding: 2.5rem;
  /*
     Three-layer shadow: a tight inner ring for depth,
     a mid-range ambient, and a wide dark drop shadow.
     Matches the layered shadow system used in iop-app cards.
  */
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.04),
    0 8px 32px rgba(0, 0, 0, 0.35),
    0 24px 64px rgba(0, 0, 0, 0.25);
  animation: cardFadeIn var(--transition-base) ease-out both;
}

@keyframes cardFadeIn {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ── Brand / Logo row ──────────────────────────────────────────── */
/*
   Replicates the iop-app sidebar logo section:
   a white-bordered circle + bold display-font name.
*/
.auth-brand {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin-bottom: 2rem;
}

.auth-brand-icon {
  width: 1.75rem;        /* 28px — matches Tailwind w-7 h-7 */
  height: 1.75rem;
  border-radius: 50%;
  border: 3px solid #ffffff;
  background: transparent;
  flex-shrink: 0;
}

.auth-brand-name {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--color-text-primary);
  line-height: 1;
}

/* ── Card headings ─────────────────────────────────────────────── */
.auth-title {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--color-text-primary);
  margin-bottom: 0.375rem;
  line-height: 1.3;
}

.auth-subtitle {
  font-size: 0.875rem;
  color: var(--color-text-muted);
  line-height: 1.5;
  margin-bottom: 1.75rem;
}

/* ── Banners (error / reason) ──────────────────────────────────── */
/*
   Reason banner: amber tone — used for soft informational messages
   such as "session expired" or "you have been signed out".
*/
.auth-reason-banner {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  background-color: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
  border-radius: var(--radius-field);
  padding: 0.75rem 1rem;
  margin-bottom: 1.25rem;
  font-size: 0.8125rem;
  color: var(--color-warning-text);
  animation: bannerSlide var(--transition-fast) both;
}

.auth-reason-banner::before {
  content: 'ℹ';
  flex-shrink: 0;
  font-size: 0.875rem;
  margin-top: 0.05em;
}

/*
   Error banner: red tone — used for authentication failures,
   user-not-found, and server errors.
*/
.auth-error-banner {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  background-color: rgba(241, 2, 2, 0.07);
  border: 1px solid var(--color-error-border);
  border-radius: var(--radius-field);
  padding: 0.75rem 1rem;
  margin-bottom: 1.25rem;
  font-size: 0.875rem;
  color: var(--color-error);
  animation: bannerSlide var(--transition-fast) both;
}

.auth-error-banner::before {
  content: '⚠';
  flex-shrink: 0;
  font-size: 0.875rem;
  margin-top: 0.05em;
}

.auth-error-banner > div + div {
  margin-top: 0.25rem;
}

@keyframes bannerSlide {
  from {
    opacity: 0;
    transform: translateX(-6px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* ── Floating-label Form Field ─────────────────────────────────── */
/*
   Mirrors form-field.component.scss from iop-app exactly:
   - Dark translucent container
   - Label positioned absolutely in the vertical centre
   - On :focus-within (focus) or :not(:placeholder-shown) (has value):
       label slides to the top border edge, shrinks, turns blue
   - Animated top gradient bar expands on focus (scaleX 0 → 1)
   - Blue glow shadow on focus
   - Red border + shadow on error state

   HTML structure required:
     <div class="field-container">
       <input class="field-input" placeholder=" " />   ← input FIRST
       <label class="field-label">...</label>          ← label AFTER (for + selector)
     </div>

   The placeholder=" " (single space) makes :not(:placeholder-shown)
   resolve to "input has a value" — the standard CSS floating-label trick.
*/
.form-field {
  width: 100%;
  position: relative;
  margin-bottom: 1.25rem;
}

.field-container {
  position: relative;
  width: 100%;
  background-color: var(--color-field-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-field);
  /* Top padding leaves room for the floating label */
  padding: 1.375rem 1rem 0.625rem;
  transition:
    background-color var(--transition-fast),
    border-color     var(--transition-fast),
    box-shadow       var(--transition-fast);
}

/* Top gradient line — animated on focus (replicates the ::before in form-field.component.scss) */
.field-container::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--color-primary-gradient);
  transform: scaleX(0);
  transition: transform var(--transition-fast);
  border-radius: var(--radius-field) var(--radius-field) 0 0;
  pointer-events: none;
}

/* ── Input element ── */
.field-input {
  width: 100%;
  background: transparent;
  border: none;
  outline: none;
  color: var(--color-field-text);
  font-size: 0.875rem;
  font-weight: 400;
  font-family: var(--font-body);
  line-height: 1.5;
  position: relative;
  z-index: 2;
  /* Native placeholder hidden — the floating label acts as the placeholder */
  caret-color: var(--color-primary);
}

.field-input::placeholder {
  color: transparent;
}

.field-input:-webkit-autofill,
.field-input:-webkit-autofill:focus {
  /* Override browser autofill yellow background */
  -webkit-box-shadow: 0 0 0 1000px rgba(15, 21, 53, 0.95) inset;
  -webkit-text-fill-color: var(--color-field-text);
  transition: background-color 5000s;
}

/* ── Floating label ── */
.field-label {
  position: absolute;
  /* Normal (placeholder) position — centred vertically */
  top: 50%;
  left: 1rem;
  transform: translateY(-50%);
  color: var(--color-field-label);
  font-size: 0.875rem;
  font-weight: 400;
  pointer-events: none;
  transition:
    top              var(--transition-fast),
    left             var(--transition-fast),
    transform        var(--transition-fast),
    font-size        var(--transition-fast),
    font-weight      var(--transition-fast),
    color            var(--transition-fast),
    background-color var(--transition-fast),
    padding          var(--transition-fast);
  background-color: transparent;
  z-index: 3;
  line-height: 1;
  white-space: nowrap;
  user-select: none;
}

.required-marker {
  color: rgba(241, 2, 2, 1);
  margin-left: 0.1rem;
}

/* ── Float the label up — FOCUS STATE ── */
.field-container:focus-within::before {
  transform: scaleX(1);
}

.field-container:focus-within {
  background-color: var(--color-field-bg-focused);
  border-color: var(--color-primary-border);
  box-shadow:
    0 4px 16px var(--color-primary-glow),
    0 0 0 1px rgba(2, 81, 241, 0.2);
}

.field-container:focus-within .field-label {
  top: 0;
  left: 0.75rem;
  transform: translateY(-50%);
  font-size: 0.6875rem; /* 11px */
  font-weight: 500;
  letter-spacing: 0.3px;
  color: var(--color-field-label-active);
  background-color: #08122E; /* Must match .auth-card background */
  padding: 0 0.25rem;
}

/* ── Float the label up — HAS VALUE STATE ── */
/*
   Uses the :not(:placeholder-shown) trick with placeholder=" ".
   The + combinator requires label to immediately follow input in the DOM.
*/
.field-input:not(:placeholder-shown) + .field-label {
  top: 0;
  left: 0.75rem;
  transform: translateY(-50%);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.3px;
  color: rgba(150, 180, 255, 0.85);
  background-color: #08122E;
  padding: 0 0.25rem;
}

/* ── Error state on the field container ── */
.form-field.is-error .field-container {
  border-color: var(--color-error-border);
  box-shadow: 0 0 0 1px rgba(241, 2, 2, 0.2);
}

.form-field.is-error .field-container:focus-within {
  box-shadow:
    0 4px 16px var(--color-error-glow),
    0 0 0 1px rgba(241, 2, 2, 0.2);
}

.form-field.is-error .field-label {
  color: rgba(255, 120, 120, 0.9);
}

/* ── Inline field error message ── */
.field-error-container {
  min-height: 1.125rem; /* Reserve space to prevent layout shift */
  margin-top: 0.25rem;
}

.field-error {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  color: var(--color-error);
  font-size: 0.75rem;
  padding-left: 0.25rem;
  line-height: 1.4;
  animation: bannerSlide var(--transition-fast) both;
}

.field-error::before {
  content: '⚠';
  font-size: 0.875rem;
  flex-shrink: 0;
}

/* ── Submit Button ─────────────────────────────────────────────── */
/*
   Full-width, primary blue, Geologica semi-bold.
   Hover: slightly darker + elevated shadow.
   Active: pressed down (no translateY).
   Focus-visible: 2px outline ring.
   Matches the button pattern used throughout iop-app.
*/
.btn-auth {
  display: block;
  width: 100%;
  padding: 0.8125rem 1rem;
  background-color: var(--color-primary);
  color: #ffffff;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  border: none;
  border-radius: var(--radius-field);
  cursor: pointer;
  margin-top: 1.5rem;
  transition:
    background-color var(--transition-fast),
    box-shadow       var(--transition-fast),
    transform        var(--transition-fast),
    opacity          var(--transition-fast);
  box-shadow: 0 4px 14px rgba(2, 81, 241, 0.35);
  text-align: center;
  line-height: 1;
}

.btn-auth:hover:not(:disabled) {
  background-color: #0244cc;
  box-shadow: 0 6px 22px rgba(2, 81, 241, 0.45);
  transform: translateY(-1px);
}

.btn-auth:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: 0 2px 8px rgba(2, 81, 241, 0.3);
}

.btn-auth:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
}

.btn-auth:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* Loading spinner inside button */
.btn-auth .btn-spinner {
  display: inline-block;
  width: 0.875rem;
  height: 0.875rem;
  border: 2px solid rgba(255, 255, 255, 0.3);
  border-top-color: #ffffff;
  border-radius: 50%;
  animation: spin 600ms linear infinite;
  margin-right: 0.5rem;
  vertical-align: middle;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ── Card footer ───────────────────────────────────────────────── */
.auth-footer {
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--color-border);
  text-align: center;
}

.auth-footer-text {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
}

.auth-footer-text::before {
  content: '';
  display: inline-block;
  width: 0.75rem;
  height: 0.875rem;
  /* Padlock SVG encoded inline — same technique as iop-app icon approach */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A0AEC0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'/%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: contain;
  flex-shrink: 0;
}

/* ── Below-card area ───────────────────────────────────────────── */
.auth-below-card {
  margin-top: 1rem;
  text-align: center;
}

/* ── Links ─────────────────────────────────────────────────────── */
.auth-link {
  color: var(--color-text-muted);
  font-size: 0.8125rem;
  text-decoration: none;
  transition: color var(--transition-fast);
}

.auth-link:hover {
  color: var(--color-text-secondary);
}

.auth-link:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ── Generic page styles (Privacy, Error) ──────────────────────── */
.prose-page {
  max-width: 680px;
  margin: 3rem auto;
  padding: 0 1.5rem;
  color: var(--color-text-secondary);
  line-height: 1.7;
}

.prose-page h1 {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--color-text-primary);
  margin-bottom: 1rem;
}

.prose-page p {
  font-size: 0.9375rem;
  margin-bottom: 1rem;
}

.prose-page a {
  color: var(--color-primary);
  text-decoration: none;
}

.prose-page a:hover {
  text-decoration: underline;
}

/* ── Responsive ────────────────────────────────────────────────── */
@media (max-width: 480px) {
  .auth-card {
    padding: 1.75rem 1.25rem;
    border-radius: 0.75rem;
  }

  .auth-title {
    font-size: 1.25rem;
  }
}
