/* Q-Gateway — one screen, no dependencies, no build step.
 *
 * Palette, type, radii and easing are lifted verbatim from the marketing
 * site's own token block (veyqon-website/src/app/globals.css, `@theme`) so
 * this page and veyqon.de are one design system rather than two similar dark
 * blues. Token names below are that file's names; values are its values. */

:root {
  /* -- Navy: the dominant surface ---------------------------- */
  --navy-950: #040f2a; /* deepest — full-bleed ground */
  --navy-900: #071b4a; /* BRAND — Deep Infrastructure Navy */
  --navy-850: #07204a;
  --navy-800: #0a2456; /* raised surface */
  --navy-700: #0e3a8a;
  --navy-600: #14306b; /* dividers on navy */

  /* -- Fog: text and structure on navy ----------------------- */
  --fog-50: #ffffff; /* 16.60:1 */
  --fog-100: #e8edf8; /* 14.15:1 */
  --fog-200: #c7d2e8; /* 10.92:1 */
  --fog-300: #aabbd8; /* 8.55:1 */
  --fog-400: #8a9bbd; /* 5.93:1 — muted, smallest text floor */
  --fog-600: #4a5c85; /* 2.50:1 — non-text only, so borders only */

  /* -- Electric Blue: action ---------------------------------
     #0e6bff is 3.61:1 on navy — a UI colour, not a text colour, so
     blue-200/300 carry any blue text here. */
  --blue-200: #86b5ff; /* 7.96:1 on navy */
  --blue-300: #4a90ff; /* 5.32:1 on navy */
  --blue-500: #0e6bff; /* BRAND — fills, rules, the mark */
  --blue-600: #0d5bdb;
  --blue-700: #0e3a8a;

  /* Failure states only. The palette has no success colour. */
  --danger: #ef5350;

  /* -- Type -------------------------------------------------- */
  --font-display: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;

  /* -- Radius: precision-engineered, structural -------------- */
  --radius-xs: 2px;
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 10px;

  /* -- Motion ------------------------------------------------ */
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --ease-exit: cubic-bezier(0.4, 0, 1, 1);
  --ease-settle: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-mechanical: cubic-bezier(0.83, 0, 0.17, 1);

  /* Dark-surface elevation, verbatim from the site's `elev-plane` utility. */
  --elev-plane: 0 0 0 1px rgb(255 255 255 / 0.1), 0 32px 64px -32px rgb(0 0 0 / 0.7);
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background: var(--navy-950);
  color: var(--fog-100);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

/* -- The field ------------------------------------------------
   The rotating icosahedron lattice, drawn by field.js. Sits behind
   everything and is never interactive. */

#field {
  position: fixed;
  inset: 0;
  z-index: 0;
  inline-size: 100%;
  block-size: 100%;
  display: block;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.6s var(--ease-standard);
}

#field.is-ready {
  opacity: 1;
}

/* The brand ground sits on top of the raw canvas so the lattice reads as
   embedded in the navy rather than floating on black. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(120% 85% at 50% 0%, rgb(7 27 74 / 0.34) 0%, rgb(4 15 42 / 0.62) 72%);
}

/* A structural hairline mesh — the same engineered metaphor the marketing
   site uses. Faint enough to read as texture, not decoration. */
.mesh {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgb(74 92 133 / 0.08) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(74 92 133 / 0.08) 1px, transparent 1px);
  background-size: 68px 68px;
  -webkit-mask-image: radial-gradient(78% 60% at 50% 42%, transparent 0%, #000 88%);
  mask-image: radial-gradient(78% 60% at 50% 42%, transparent 0%, #000 88%);
}

.vignette {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  /* Only enough to keep the edges from competing with the card. The field is
     meant to be seen — heavier vignetting is what made it read as barely there. */
  background: radial-gradient(80% 70% at 50% 46%, transparent 55%, rgb(4 15 42 / 0.58) 100%);
}

/* -- Layout ---------------------------------------------------- */

.shell {
  position: relative;
  z-index: 3;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding: 32px 20px;
  overflow-y: auto;
}

.card {
  position: relative;
  width: 100%;
  max-width: 424px;
  padding: 38px 34px 28px;
  border: 1px solid var(--navy-600);
  border-radius: var(--radius-lg);
  /* Alpha and blur are set against a deliberately busy background — the
     lattice passes behind this card, and body copy has to stay at its rated
     contrast while it does. */
  background:
    linear-gradient(180deg, rgb(10 36 86 / 0.94) 0%, rgb(7 32 74 / 0.95) 100%);
  box-shadow: var(--elev-plane);
  -webkit-backdrop-filter: blur(18px) saturate(1.1);
  backdrop-filter: blur(18px) saturate(1.1);
  overflow: hidden;
  animation: card-in 0.9s var(--ease-settle) both;
}

/* A blue rule along the top edge — blue-500 is explicitly "fills, rules,
   the mark". */
.card::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 1px;
  background: linear-gradient(
    to right,
    transparent,
    var(--blue-500) 30%,
    var(--blue-200) 50%,
    var(--blue-500) 70%,
    transparent
  );
  opacity: 0.85;
}

@keyframes card-in {
  from {
    opacity: 0;
    transform: translateY(18px) scale(0.985);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* Children arrive after the card, in order. */
.brand,
.card h1,
.lede,
#gateway-form,
.foot {
  animation: rise 0.7s var(--ease-settle) both;
}

.brand { animation-delay: 0.12s; }
.card h1 { animation-delay: 0.18s; }
.lede { animation-delay: 0.24s; }
#gateway-form { animation-delay: 0.3s; }
.foot { animation-delay: 0.38s; }

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* -- Brand ----------------------------------------------------- */

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-bottom: 30px;
}

.brand-mark {
  width: 28px;
  height: 28px;
  filter: drop-shadow(0 2px 10px rgb(14 107 255 / 0.5));
}

.brand-name {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--fog-100);
}

/* -- Copy ------------------------------------------------------ */

h1 {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-size: 23px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--fog-50);
}

.lede {
  margin: 0 0 28px;
  color: var(--fog-400);
  font-size: 14px;
  line-height: 1.65;
}

/* -- Form ------------------------------------------------------ */

label {
  display: block;
  margin-bottom: 9px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--fog-300);
}

.field {
  display: flex;
  align-items: center;
  border: 1px solid var(--navy-600);
  border-radius: var(--radius-md);
  background: rgb(4 15 42 / 0.6);
  transition:
    border-color 0.2s var(--ease-standard),
    box-shadow 0.25s var(--ease-standard),
    background-color 0.2s var(--ease-standard);
}

.field:hover {
  border-color: var(--navy-700);
}

.field:focus-within {
  border-color: var(--blue-500);
  background: rgb(4 15 42 / 0.85);
  box-shadow: 0 0 0 3px rgb(14 107 255 / 0.18), 0 0 26px -6px rgb(14 107 255 / 0.5);
}

input {
  flex: 1;
  min-width: 0;
  padding: 13px 4px 13px 14px;
  border: 0;
  background: transparent;
  color: var(--fog-50);
  font: inherit;
  font-size: 15px;
  letter-spacing: 0.01em;
  outline: none;
}

input::placeholder {
  color: #6b7ea6; /* fog-500 — large text and UI only, correct for a placeholder */
}

input[aria-invalid="true"] {
  color: var(--danger);
}

.suffix {
  padding: 0 14px 0 2px;
  color: var(--fog-600);
  font-family: var(--font-display);
  font-size: 14px;
  white-space: nowrap;
  transition: color 0.2s var(--ease-standard);
}

.field:focus-within .suffix {
  color: var(--fog-400);
}

/* -- Destination preview --------------------------------------- */

.destination {
  margin: 11px 0 0;
  min-height: 20px;
  font-size: 12.5px;
  color: var(--fog-600);
  transition: opacity 0.2s var(--ease-standard);
}

.destination[data-empty] {
  opacity: 0.6;
}

.destination-url {
  color: var(--blue-300);
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 12.5px;
}

.destination[data-empty] .destination-url {
  color: var(--fog-400);
  font-weight: 400;
}

/* -- Error ------------------------------------------------------ */

.error {
  margin: 11px 0 0;
  color: var(--danger);
  font-size: 13px;
  animation: shake 0.4s var(--ease-standard);
}

.error[hidden] {
  display: none;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-2px); }
  80% { transform: translateX(2px); }
}

/* -- Button ----------------------------------------------------- */

button {
  position: relative;
  width: 100%;
  margin-top: 22px;
  padding: 13px 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 0;
  border-radius: var(--radius-md);
  background: linear-gradient(180deg, var(--blue-500), var(--blue-600));
  color: #fff;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  overflow: hidden;
  box-shadow: 0 6px 20px -8px rgb(14 107 255 / 0.9);
  transition:
    transform 0.35s var(--ease-settle),
    box-shadow 0.35s var(--ease-settle),
    filter 0.2s var(--ease-standard);
}

/* A light sweep across the face on hover. */
button::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: -60%;
  inline-size: 45%;
  background: linear-gradient(100deg, transparent, rgb(255 255 255 / 0.28), transparent);
  transform: skewX(-18deg);
  transition: inset-inline-start 0.65s var(--ease-standard);
}

button:hover:not(:disabled) {
  transform: translateY(-1px);
  filter: brightness(1.06);
  box-shadow: 0 12px 30px -10px rgb(14 107 255 / 1);
}

button:hover:not(:disabled)::after {
  inset-inline-start: 115%;
}

button:active:not(:disabled) {
  transform: translateY(0);
}

button:focus-visible {
  outline: 2px solid var(--blue-200);
  outline-offset: 3px;
}

button:disabled {
  filter: saturate(0.6);
  opacity: 0.75;
  cursor: default;
  box-shadow: none;
}

.btn-arrow {
  width: 16px;
  height: 16px;
  transition: transform 0.35s var(--ease-mechanical);
}

button:hover:not(:disabled) .btn-arrow {
  transform: translateX(3px);
}

/* -- Footer ------------------------------------------------------ */

.foot {
  margin: 26px 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--navy-600);
  color: var(--fog-600);
  font-size: 12.5px;
  line-height: 1.6;
}

.noscript {
  position: relative;
  z-index: 3;
  max-width: 424px;
  margin: 0;
  padding: 14px 16px;
  border: 1px solid var(--navy-600);
  border-radius: var(--radius-md);
  background: rgb(10 36 86 / 0.9);
  color: var(--fog-300);
  font-size: 13px;
}

@media (max-width: 460px) {
  .card {
    padding: 30px 24px 22px;
  }
}

/* Motion is decoration here; the page must be usable without it. */
@media (prefers-reduced-motion: reduce) {
  .card,
  .brand,
  .card h1,
  .lede,
  #gateway-form,
  .foot,
  .error {
    animation: none;
  }

  #field,
  .field,
  button,
  .btn-arrow,
  .suffix,
  .destination {
    transition: none;
  }

  button::after {
    display: none;
  }

  button:hover:not(:disabled) {
    transform: none;
  }
}
