/* Qviple web splash — shown until Flutter paints its first frame.
   Sizing is fluid (one --q-tile unit derived from the small viewport) so the
   stage fits phones, foldables, landscape and 4K alike. Every looping
   animation touches only transform/opacity so it runs on the compositor and
   stays smooth while dart2js / CanvasKit block the main thread. The particle
   canvas is driven from a worker by loader.js. */

:root {
  --q-primary: #2A5C82;
  --q-blue: #3484C8;
  --q-cyan: #26B9EA;
  --q-indigo: #233F93;

  --q-text: #0f1b2d;
  --q-muted: #5b6b7d;
  --q-bg: #f4f8fc;
  --q-bg-hi: #ffffff;
  --q-blob-1: rgba(38, 185, 234, 0.30);
  --q-blob-2: rgba(35, 63, 147, 0.20);
  --q-blob-3: rgba(52, 132, 200, 0.22);
  --q-grid: rgba(42, 92, 130, 0.10);
  --q-noise-opacity: 0.035;

  /* Opaque so the border beam behind the face never shows through it. */
  --q-face-top: #ffffff;
  --q-face-bottom: #eaf2f9;
  --q-face-inset:
    0 1px 0 rgba(255, 255, 255, 1) inset,
    0 -10px 24px -12px rgba(52, 132, 200, 0.18) inset;
  --q-rim: rgba(42, 92, 130, 0.14);
  --q-card-shadow:
    0 30px 60px -22px rgba(35, 63, 147, 0.38),
    0 10px 20px -10px rgba(42, 92, 130, 0.22);
  --q-halo: rgba(38, 185, 234, 0.34);
  --q-ring: rgba(42, 92, 130, 0.14);
  --q-ring-dot: #26B9EA;
  --q-word-grad: linear-gradient(100deg, #1b2f5e 0%, #233F93 30%, #3484C8 60%, #26B9EA 80%, #1b2f5e 100%);
  --q-track: rgba(42, 92, 130, 0.12);
  --q-sheen: rgba(255, 255, 255, 0.85);

  --q-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --q-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --q-text: #eef4fb;
    --q-muted: #8fa2b8;
    --q-bg: #050912;
    --q-bg-hi: #0d1729;
    --q-blob-1: rgba(38, 185, 234, 0.22);
    --q-blob-2: rgba(91, 84, 230, 0.20);
    --q-blob-3: rgba(52, 132, 200, 0.20);
    --q-grid: rgba(148, 196, 240, 0.08);
    --q-noise-opacity: 0.06;

    --q-face-top: #1a2840;
    --q-face-bottom: #0b121f;
    --q-face-inset:
      0 1px 0 rgba(255, 255, 255, 0.10) inset,
      0 -12px 28px -14px rgba(38, 185, 234, 0.30) inset;
    --q-rim: rgba(148, 196, 240, 0.16);
    --q-card-shadow:
      0 30px 70px -20px rgba(0, 0, 0, 0.75),
      0 0 60px -10px rgba(38, 185, 234, 0.30);
    --q-halo: rgba(38, 185, 234, 0.45);
    --q-ring: rgba(148, 196, 240, 0.14);
    --q-ring-dot: #6fdcff;
    --q-word-grad: linear-gradient(100deg, #ffffff 0%, #cfe9ff 30%, #6fdcff 55%, #8f9bff 75%, #ffffff 100%);
    --q-track: rgba(148, 196, 240, 0.14);
    --q-sheen: rgba(255, 255, 255, 0.22);
  }
}

/* Paint the splash colour before the first byte of Flutter arrives, so dark
   mode never flashes white. Flutter's view covers this once it renders. */
html {
  background-color: var(--q-bg);
}

.loading {
  /* One unit drives the whole stage: 26% of the small-viewport short side,
     clamped for tiny phones and huge monitors. */
  --q-vmin: 1vmin;
  --q-tile: clamp(84px, calc(var(--q-vmin) * 26), 140px);
  --q-gap: calc(var(--q-tile) * 0.26);

  position: fixed;
  inset: 0;
  z-index: 1000;
  box-sizing: border-box;
  display: grid;
  place-items: center;
  padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px)
           env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
  overflow: hidden;
  background: radial-gradient(ellipse 80% 70% at 50% 40%, var(--q-bg-hi) 0%, var(--q-bg) 70%);
  font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}

@supports (width: 1svmin) {
  .loading { --q-vmin: 1svmin; }
}

.loading.is-leaving {
  pointer-events: none;
  animation: q-leave 0.6s var(--q-ease-out) 0.12s forwards;
}

.loading.is-leaving .q-stage {
  animation: q-stage-out 0.55s var(--q-ease-out) forwards;
}

@keyframes q-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes q-leave {
  to { opacity: 0; }
}

@keyframes q-stage-out {
  to { opacity: 0; transform: scale(1.08); }
}

/* --- Background layers ------------------------------------------------- */

.q-aurora {
  position: absolute;
  inset: -20%;
  pointer-events: none;
}

.q-blob {
  position: absolute;
  width: 60vmax;
  height: 60vmax;
  border-radius: 50%;
  will-change: transform;
}

.q-blob.b1 {
  top: 0;
  left: 5%;
  background: radial-gradient(circle, var(--q-blob-1) 0%, transparent 62%);
  animation: q-drift-1 16s ease-in-out infinite alternate;
}

.q-blob.b2 {
  right: 0;
  bottom: 0;
  background: radial-gradient(circle, var(--q-blob-2) 0%, transparent 62%);
  animation: q-drift-2 19s ease-in-out infinite alternate;
}

.q-blob.b3 {
  top: 25%;
  left: 30%;
  width: 45vmax;
  height: 45vmax;
  background: radial-gradient(circle, var(--q-blob-3) 0%, transparent 62%);
  animation: q-drift-3 13s ease-in-out infinite alternate;
}

@keyframes q-drift-1 {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(12vmax, 8vmax, 0) scale(1.15); }
}

@keyframes q-drift-2 {
  from { transform: translate3d(0, 0, 0) scale(1.1); }
  to   { transform: translate3d(-14vmax, -6vmax, 0) scale(0.9); }
}

@keyframes q-drift-3 {
  from { transform: translate3d(-6vmax, 4vmax, 0) scale(0.9); }
  to   { transform: translate3d(6vmax, -6vmax, 0) scale(1.1); }
}

.q-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: radial-gradient(var(--q-grid) 1px, transparent 1px);
  background-size: 24px 24px;
  background-position: center;
  -webkit-mask-image: radial-gradient(ellipse 50% 45% at 50% 50%, #000 0%, transparent 100%);
          mask-image: radial-gradient(ellipse 50% 45% at 50% 50%, #000 0%, transparent 100%);
  animation: q-fade-in 1.4s ease-out 0.2s both;
}

/* Film grain — static, tiled, cheap */
.q-noise {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--q-noise-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.q-fx {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  animation: q-fade-in 0.9s ease-out both;
}

/* --- Center stage ------------------------------------------------------ */

.q-stage {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 100%;
  padding: 0 20px;
  box-sizing: border-box;
  text-align: center;
}

/* Wrapper follows the pointer with a subtle 3D tilt (vars set in loader.js) */
.q-mark-wrap {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--q-tile);
  height: var(--q-tile);
  transform: perspective(700px) rotateX(var(--q-tilt-x, 0deg)) rotateY(var(--q-tilt-y, 0deg));
  transition: transform 0.5s var(--q-ease-out);
}

.q-halo {
  position: absolute;
  inset: calc(var(--q-tile) * -0.28);
  border-radius: 50%;
  background: radial-gradient(circle, var(--q-halo), transparent 68%);
  animation: q-pop 1s var(--q-ease-out) 0.2s both,
             q-halo 3s ease-in-out 1.2s infinite;
}

@keyframes q-halo {
  0%, 100% { opacity: 0.55; scale: 0.94; }
  50%      { opacity: 1;    scale: 1.08; }
}

/* Orbit rings with a glowing satellite */
.q-orbit {
  position: absolute;
  left: 50%;
  top: 50%;
  border-radius: 50%;
  border: 1px solid var(--q-ring);
  pointer-events: none;
  -webkit-mask-image: linear-gradient(180deg, #000 15%, transparent 68%);
          mask-image: linear-gradient(180deg, #000 15%, transparent 68%);
}

.q-orbit.o1 {
  --d: calc(var(--q-tile) * 1.56);
  width: var(--d);
  height: var(--d);
  margin: calc(var(--d) / -2) 0 0 calc(var(--d) / -2);
  animation: q-orbit-in 1s var(--q-ease-out) 1s both,
             q-orbit-spin 9s linear infinite;
}

.q-orbit.o2 {
  --d: calc(var(--q-tile) * 2.19);
  width: var(--d);
  height: var(--d);
  margin: calc(var(--d) / -2) 0 0 calc(var(--d) / -2);
  border-style: dashed;
  animation: q-orbit-in 1.1s var(--q-ease-out) 1.15s both,
             q-orbit-spin 16s linear infinite reverse;
}

.q-orbit i {
  position: absolute;
  top: -3px;
  left: 50%;
  width: 6px;
  height: 6px;
  margin-left: -3px;
  border-radius: 50%;
  background: var(--q-ring-dot);
  box-shadow: 0 0 10px 2px var(--q-ring-dot), 0 0 22px 6px rgba(38, 185, 234, 0.35);
}

.q-orbit.o2 i {
  width: 4px;
  height: 4px;
  margin-left: -2px;
  top: -2px;
}

@keyframes q-orbit-in {
  from { opacity: 0; scale: 0.55; }
  to   { opacity: 1; scale: 1; }
}

@keyframes q-orbit-spin {
  to { rotate: 360deg; }
}

/* Tile: a rim layer with a rotating "border beam", an opaque face inset by
   the rim width on top of it, then the logo. Rotating a transformed child
   (instead of animating a conic-gradient angle) keeps the beam on the GPU. */
.q-mark {
  --q-rim-w: 1.5px;
  position: relative;
  width: var(--q-tile);
  height: var(--q-tile);
  border-radius: calc(var(--q-tile) * 0.28);
  display: grid;
  place-items: center;
  box-shadow: var(--q-card-shadow);
  animation: q-pop 0.95s var(--q-ease-spring) 0.1s both,
             q-float 5s ease-in-out 1.6s infinite;
}

.q-beam,
.q-face {
  position: absolute;
  border-radius: inherit;
  pointer-events: none;
}

.q-beam {
  inset: 0;
  overflow: hidden;
  background: var(--q-rim);
}

.q-beam::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 150%;
  height: 150%;
  translate: -50% -50%;
  background: conic-gradient(
    transparent 0deg,
    transparent 220deg,
    var(--q-cyan) 300deg,
    #ffffff 330deg,
    var(--q-indigo) 360deg
  );
  animation: q-spin 2.6s linear infinite;
}

.q-face {
  inset: var(--q-rim-w);
  border-radius: calc(var(--q-tile) * 0.28 - var(--q-rim-w));
  background: linear-gradient(150deg, var(--q-face-top), var(--q-face-bottom));
  box-shadow: var(--q-face-inset);
}

@keyframes q-spin {
  to { rotate: 360deg; }
}

@keyframes q-pop {
  from { opacity: 0; transform: scale(0.55) translateY(14px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

@keyframes q-float {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -6px; }
}

/* Logo pieces assemble in sequence, then a light sweep passes over */
.q-logo {
  position: relative;
  width: 50%;
  height: auto;
  overflow: visible;
  filter: drop-shadow(0 6px 10px rgba(35, 63, 147, 0.22));
}

.q-logo .pc {
  transform-box: fill-box;
  transform-origin: center;
  animation: q-piece 0.7s var(--q-ease-spring) both;
}

.q-logo .pc-1 { animation-delay: 0.35s; --dx: -14px; --dy: 14px; }
.q-logo .pc-2 { animation-delay: 0.45s; --dx: -16px; --dy: -12px; }
.q-logo .pc-3 { animation-delay: 0.55s; --dx: 16px;  --dy: -12px; }
.q-logo .pc-4 { animation-delay: 0.65s; --dx: 14px;  --dy: 14px; }

@keyframes q-piece {
  from { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(0.5) rotate(-10deg); }
  /* No opacity here so pieces keep their SVG opacity attribute */
  to   { transform: none; }
}

.q-sheen,
.q-flash {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
}

.q-sheen::before {
  content: '';
  position: absolute;
  top: -50%;
  left: 0;
  width: 40%;
  height: 200%;
  background: linear-gradient(90deg, transparent, var(--q-sheen), transparent);
  transform: translateX(-160%) rotate(20deg);
  animation: q-sheen 3.6s ease-in-out 1.6s infinite;
}

@keyframes q-sheen {
  0%        { transform: translateX(-160%) rotate(20deg); }
  45%, 100% { transform: translateX(330%) rotate(20deg); }
}

/* Bright flash on the tile the moment the particle blast fires (~1s).
   loader.js reads this animation's clock to sync the canvas burst. */
.q-flash {
  background: radial-gradient(circle, rgba(255, 255, 255, 0.95), rgba(111, 220, 255, 0.4) 45%, transparent 75%);
  opacity: 0;
  animation: q-flash 0.7s ease-out 0.95s both;
}

@keyframes q-flash {
  0%   { opacity: 0; }
  20%  { opacity: 1; }
  100% { opacity: 0; }
}

/* --- Wordmark ---------------------------------------------------------- */

.q-word {
  margin-top: var(--q-gap);
  display: flex;
  font-size: clamp(26px, calc(var(--q-tile) * 0.265), 38px);
  font-weight: 800;
  letter-spacing: -0.024em;
  line-height: 1.1;
  color: var(--q-text);
}

.q-word span {
  display: inline-block;
  background: var(--q-word-grad);
  background-size: 600% 100%;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: q-letter 0.8s var(--q-ease-out) both;
  animation-delay: calc(1.05s + var(--i) * 0.055s);
}

/* Each letter samples its own slice so the gradient reads continuous */
.q-word span:nth-child(1) { background-position: 0% 0; }
.q-word span:nth-child(2) { background-position: 20% 0; }
.q-word span:nth-child(3) { background-position: 40% 0; }
.q-word span:nth-child(4) { background-position: 60% 0; }
.q-word span:nth-child(5) { background-position: 80% 0; }
.q-word span:nth-child(6) { background-position: 100% 0; }

@keyframes q-letter {
  from { opacity: 0; transform: translateY(0.5em) scale(0.92); }
  to   { opacity: 1; transform: none; }
}

.q-tagline {
  margin-top: 0.6em;
  font-size: clamp(12.5px, calc(var(--q-tile) * 0.105), 15px);
  font-weight: 500;
  letter-spacing: 0.01em;
  line-height: 1.35;
  color: var(--q-muted);
  animation: q-rise 0.7s var(--q-ease-out) 1.4s both;
}

@keyframes q-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* --- Progress ---------------------------------------------------------- */

.q-progress {
  position: relative;
  width: clamp(150px, calc(var(--q-tile) * 1.6), 220px);
  height: 4px;
  margin-top: var(--q-gap);
  border-radius: 999px;
  overflow: hidden;
  background: var(--q-track);
  animation: q-rise 0.7s var(--q-ease-out) 1.5s both;
}

.q-progress::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 45%;
  border-radius: inherit;
  background: linear-gradient(90deg, transparent, var(--q-cyan), var(--q-blue), var(--q-indigo));
  box-shadow: 0 0 12px rgba(38, 185, 234, 0.7);
  animation: q-comet 1.5s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}

@keyframes q-comet {
  from { transform: translateX(-110%); }
  to   { transform: translateX(260%); }
}

.q-status {
  position: relative;
  height: 1.6em;
  margin-top: 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  line-height: 1.6;
  white-space: nowrap;
  text-transform: uppercase;
  color: var(--q-muted);
  animation: q-rise 0.7s var(--q-ease-out) 1.6s both;
}

.q-status-text {
  display: inline-block;
  transition: opacity 0.3s ease, transform 0.3s var(--q-ease-out);
}

.q-status-text.is-swapping {
  opacity: 0;
  transform: translateY(-5px);
}

.q-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Narrow phones: the outer orbit would crowd the edges. */
@media (max-width: 480px) {
  .q-orbit.o2 { display: none; }
}

/* Short landscape phones: tighten vertical rhythm so the stack fits. */
@media (max-height: 480px) and (orientation: landscape) {
  .loading { --q-gap: calc(var(--q-tile) * 0.2); }
  .q-orbit.o2 { display: none; }
  .q-tagline { margin-top: 0.35em; }
  .q-status { margin-top: 8px; }
}

/* --- Reduced motion ---------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .loading *,
  .loading *::before,
  .loading *::after {
    animation: none !important;
    transition: none !important;
  }
  .loading.is-leaving { animation: q-leave 0.3s ease forwards; }
  .q-fx, .q-sheen, .q-flash { display: none; }
  .q-progress::before { transform: translateX(60%); }
  .q-mark-wrap { transform: none; }
}
