* {
  box-sizing: border-box;
}

:root {
  --theme-primary: #57859d;
  --theme-secondary: #ff6e48;
  --theme-tertiary: #f2c94c;
  --theme-background: #070a0b;
  --theme-on-background: #f1f1f1;
  --loader-muted: rgba(241, 241, 241, 0.56);
  --loader-soft: rgba(241, 241, 241, 0.08);
  --loader-line: rgba(241, 241, 241, 0.12);
  --loader-deco: #c69a4a;
  --loader-deco-rgb: 198, 154, 74;
  --loader-deco-soft: rgba(198, 154, 74, 0.40);
}

html,
body {
  height: 100%;
  margin: 0;
  background: var(--theme-background);
  overflow: hidden;
}

body:not(.flutter-loaded) {
  overflow: hidden;
}

#loading-container {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  min-height: 100%;
  overflow: hidden;
  color: var(--theme-on-background);
  background:
    radial-gradient(ellipse 90% 60% at 50% 48%,
      color-mix(in srgb, var(--theme-primary) 8%, transparent),
      transparent 62%),
    var(--theme-background);
  isolation: isolate;
  z-index: 9999;
  opacity: 1;
  transition:
    opacity 700ms ease,
    filter 700ms ease;
}

.flutter-loaded #loading-container {
  opacity: 0;
  filter: blur(10px);
  pointer-events: none;
}

#intro-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

.intro-overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

/* ------------------------------------------------------------------
   Background ornaments
   ------------------------------------------------------------------ */

/* Contained sunburst halo. Fixed 380px box centered on the viewport
   so the rays never reach the screen edges. The radial mask keeps
   the rays entirely OUTSIDE the mark area — they appear only as a
   tight ring of gold rays around the central diamond, peaking ~80px
   beyond the mark's edge and fading to nothing at the box edge. */
.loader-beams {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 380px;
  height: 380px;
  transform: translate(-50%, -50%);
  background: repeating-conic-gradient(
    from -90deg at 50% 50%,
    transparent 0deg 8.4deg,
    color-mix(in srgb, var(--loader-deco) 32%, transparent) 8.4deg 9deg
  );
  -webkit-mask-image: radial-gradient(
    circle at 50% 50%,
    transparent 0%,
    transparent 30%,
    rgba(0, 0, 0, 0.72) 52%,
    rgba(0, 0, 0, 0.55) 72%,
    transparent 100%
  );
  mask-image: radial-gradient(
    circle at 50% 50%,
    transparent 0%,
    transparent 30%,
    rgba(0, 0, 0, 0.72) 52%,
    rgba(0, 0, 0, 0.55) 72%,
    transparent 100%
  );
  opacity: 0.7;
  animation: loader-sunburst-breathe 9s ease-in-out infinite;
}

/* Subtle vertical fluting at the left/right margins — keeps the eye
   anchored to the central column without screaming. */
.loader-grid {
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    90deg,
    transparent 0 26px,
    color-mix(in srgb, var(--theme-on-background) 6%, transparent) 26px 27px,
    transparent 27px 30px,
    color-mix(in srgb, var(--theme-on-background) 3%, transparent) 30px 31px,
    transparent 31px 34px
  );
  -webkit-mask-image: linear-gradient(
    90deg,
    rgba(0, 0, 0, 0.85) 0%,
    transparent 20%,
    transparent 80%,
    rgba(0, 0, 0, 0.85) 100%
  );
  mask-image: linear-gradient(
    90deg,
    rgba(0, 0, 0, 0.85) 0%,
    transparent 20%,
    transparent 80%,
    rgba(0, 0, 0, 0.85) 100%
  );
  opacity: 0.45;
}

.loader-noise {
  position: absolute;
  inset: 0;
  opacity: 0.06;
  background-image:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.04) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.03) 0 1px, transparent 1px 7px);
  mix-blend-mode: screen;
}

/* ------------------------------------------------------------------
   Architectural frame: thin gold perimeter rectangle with stepped
   double-L corner brackets at all four corners.
   ------------------------------------------------------------------ */
.loader-frame {
  position: absolute;
  inset: 28px;
  pointer-events: none;
  border: 1px solid color-mix(in srgb, var(--loader-deco) 18%, transparent);
}

.loader-frame::before {
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid color-mix(in srgb, var(--loader-deco) 11%, transparent);
  pointer-events: none;
}

.loader-corner {
  position: absolute;
  width: 78px;
  height: 78px;
  pointer-events: none;
}

.loader-corner::before,
.loader-corner::after {
  content: "";
  position: absolute;
  display: block;
  border-style: solid;
  border-width: 0;
}

/* Outer L (full corner bracket — overlays the perimeter at full strength) */
.loader-corner::before {
  inset: 0;
  border-color: var(--loader-deco);
}

/* Inner L (stepped inward, slightly softer) */
.loader-corner::after {
  inset: 11px;
  border-color: color-mix(in srgb, var(--loader-deco) 58%, transparent);
}

.loader-corner--tl {
  top: 0;
  left: 0;
}

.loader-corner--tl::before {
  border-top-width: 1px;
  border-left-width: 1px;
}

.loader-corner--tl::after {
  border-top-width: 1px;
  border-left-width: 1px;
}

.loader-corner--tr {
  top: 0;
  right: 0;
}

.loader-corner--tr::before {
  border-top-width: 1px;
  border-right-width: 1px;
}

.loader-corner--tr::after {
  border-top-width: 1px;
  border-right-width: 1px;
}

.loader-corner--br {
  right: 0;
  bottom: 0;
}

.loader-corner--br::before {
  border-bottom-width: 1px;
  border-right-width: 1px;
}

.loader-corner--br::after {
  border-bottom-width: 1px;
  border-right-width: 1px;
}

.loader-corner--bl {
  bottom: 0;
  left: 0;
}

.loader-corner--bl::before {
  border-bottom-width: 1px;
  border-left-width: 1px;
}

.loader-corner--bl::after {
  border-bottom-width: 1px;
  border-left-width: 1px;
}

/* ------------------------------------------------------------------
   Centerpiece
   ------------------------------------------------------------------ */
.loader {
  position: relative;
  z-index: 2;
  display: flex;
  width: min(620px, calc(100vw - 64px));
  min-height: 340px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 36px;
  padding: 24px 0;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  text-align: center;
}

.loader-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 30px;
}

/* The intro scripts for these apps bring a mark of their own. Keyed on the
   app rather than on a class the script adds, or the shared mark shows and
   then vanishes when the script lands. */
body:is([data-app-name="social_world"], [data-app-name="gus"], [data-app-name="fucking_fast_file_drive"]) .loader-brand {
  display: none;
}

/* Mark shell — the wrapping container that produces the circular gold
   halo behind the emblem. No more nested CSS diamonds, scan lines,
   or raster icon here. All geometry lives inside the SVG emblem
   so the lines stay crisp and a single visual system owns the mark. */
.loader-mark-shell {
  position: relative;
  display: grid;
  width: 148px;
  height: 148px;
  place-items: center;
  border-radius: 50%;
  box-shadow:
    0 0 100px rgba(var(--loader-deco-rgb), 0.22),
    0 0 36px rgba(var(--loader-deco-rgb), 0.16);
}

/* Single inline SVG holding the entire deco mark:
   outer diamond + middle hairline + inner stepped center
   + 4 cardinal lozenge finials + a tiny filled core diamond. */
.loader-mark-emblem {
  display: block;
  width: 100%;
  height: 100%;
  color: var(--loader-deco);
  filter:
    drop-shadow(0 0 10px rgba(var(--loader-deco-rgb), 0.35))
    drop-shadow(0 0 22px rgba(var(--loader-deco-rgb), 0.18));
}

/* ------------------------------------------------------------------
   Typography
   ------------------------------------------------------------------ */
.loader-copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

.loader-kicker-row {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}

.loader-kicker-row::before,
.loader-kicker-row::after {
  content: "";
  display: block;
  width: 38px;
  height: 1px;
  flex-shrink: 0;
}

.loader-kicker-row::before {
  background: linear-gradient(
    90deg,
    transparent,
    color-mix(in srgb, var(--loader-deco) 55%, transparent)
  );
}

.loader-kicker-row::after {
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--loader-deco) 55%, transparent),
    transparent
  );
}

.loader-kicker-pip {
  width: 5px;
  height: 5px;
  background: var(--loader-deco);
  transform: rotate(45deg);
  flex-shrink: 0;
  box-shadow: 0 0 6px rgba(var(--loader-deco-rgb), 0.55);
}

.loader-kicker,
.intro-text {
  font-size: 11px;
  font-weight: 600;
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: 0.34em;
  color: color-mix(in srgb, var(--loader-deco) 88%, var(--theme-on-background));
}

.app-title {
  margin: 0;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 46px;
  font-weight: 300;
  line-height: 1;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: var(--theme-on-background);
  text-wrap: balance;
  text-shadow: 0 10px 36px color-mix(in srgb, var(--theme-primary) 22%, transparent);
  animation: loader-title-in 800ms ease-out both;
  padding-left: 0.20em;
}

.loader-subtitle {
  max-width: 420px;
  margin: 0;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--loader-muted);
}

/* ------------------------------------------------------------------
   Progress
   ------------------------------------------------------------------ */
.loader-status {
  display: grid;
  width: min(340px, 72vw);
  gap: 14px;
}

.loader-track {
  position: relative;
  height: 6px;
}

.loader-track::before,
.loader-track::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    color-mix(in srgb, var(--loader-deco) 60%, transparent) 18%,
    color-mix(in srgb, var(--loader-deco) 60%, transparent) 82%,
    transparent
  );
}

.loader-track::before {
  top: 0;
}

.loader-track::after {
  bottom: 0;
}

/* Opt-in: only the Social World shell draws a filling rail. FFFD's track is a
   sweeping capsule and has no use for it. */
.loader-track-fill {
  display: none;
}

.loader-track-marker {
  position: absolute;
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -3.5px;
  margin-left: -3.5px;
  background: var(--loader-deco);
  transform: rotate(45deg);
  box-shadow: 0 0 10px rgba(var(--loader-deco-rgb), 0.75);
  animation: loader-track-march 2800ms ease-in-out infinite;
}

.loader-status-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 10px;
  font-weight: 700;
  line-height: 1.3;
  color: color-mix(in srgb, var(--theme-on-background) 50%, transparent);
  text-transform: uppercase;
  letter-spacing: 0.34em;
}

.loading-dots {
  display: flex;
  gap: 8px;
  align-items: center;
}

.dot {
  width: 4px;
  height: 4px;
  background: var(--loader-deco);
  transform: rotate(45deg);
  animation: loader-dot 1600ms ease-in-out infinite;
  opacity: 0.5;
}

.dot:nth-child(2) {
  animation-delay: 160ms;
}

.dot:nth-child(3) {
  animation-delay: 320ms;
}

/* ------------------------------------------------------------------
   Footer wordmark
   ------------------------------------------------------------------ */
.intro-text-container {
  position: absolute;
  right: 0;
  bottom: 24px;
  left: 0;
  z-index: 2;
  display: flex;
  justify-content: center;
  pointer-events: none;
}

.intro-text {
  padding: 0 24px;
  letter-spacing: 0.44em;
  color: color-mix(in srgb, var(--loader-deco) 78%, var(--loader-muted));
  /* Override the inline <style> in index.html which forces a
     magenta-to-indigo gradient fill plus a blurFade animation that
     ends at opacity 0. None of those belong on the deco footer. */
  background: none;
  background-clip: initial;
  -webkit-background-clip: initial;
  -webkit-text-fill-color: currentColor;
  animation: none;
  filter: none;
  opacity: 1;
}

/* ------------------------------------------------------------------
   Intro-screen (FFFD / SOWO) overrides — preserved for the post-loader
   overlay copy. Kept structurally intact but cleaned up for consistency.
   ------------------------------------------------------------------ */
.intro-headline {
  max-width: 760px;
  margin: 0;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 38px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: 0;
  color: var(--theme-on-background);
  text-align: center;
  opacity: 0;
  animation: loader-title-in 800ms ease-out 260ms forwards;
}

.intro-body {
  max-width: 520px;
  margin: 0;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.55;
  letter-spacing: 0;
  color: var(--loader-muted);
  text-align: center;
  opacity: 0;
  animation: loader-title-in 650ms ease-out 520ms forwards;
}

.intro-headline.mono,
.intro-coord,
.intro-counter {
  font-family: "Fira Code", ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0;
}

.intro-headline.shimmer,
.intro-body .gradient-text,
.intro-body .shimmer-word {
  background: linear-gradient(90deg, var(--theme-primary), var(--theme-secondary), var(--theme-tertiary));
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: loader-title-in 800ms ease-out 260ms forwards, loader-text-flow 2600ms linear infinite;
}

.intro-body .color-indigo,
.intro-body .color-purple {
  color: var(--theme-primary);
  -webkit-text-fill-color: var(--theme-primary);
}

.intro-body .color-emerald,
.intro-body .color-gold {
  color: var(--theme-secondary);
  -webkit-text-fill-color: var(--theme-secondary);
}

.intro-coord,
.intro-counter-label {
  font-size: 11px;
  font-weight: 700;
  color: color-mix(in srgb, var(--theme-on-background) 42%, transparent);
  text-transform: uppercase;
}

.intro-counter {
  font-size: 68px;
  font-weight: 800;
  line-height: 0.95;
  color: var(--theme-secondary);
}

/* ------------------------------------------------------------------
   Animations
   ------------------------------------------------------------------ */
@keyframes loader-title-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes loader-sunburst-breathe {
  0%,
  100% {
    opacity: 0.50;
  }

  50% {
    opacity: 0.72;
  }
}

@keyframes loader-track-march {
  0%,
  100% {
    left: 4%;
    opacity: 0.85;
  }

  50% {
    left: 96%;
    opacity: 1;
  }
}

@keyframes loader-dot {
  0%,
  100% {
    opacity: 0.28;
    transform: rotate(45deg) scale(0.78);
  }

  45% {
    opacity: 0.92;
    transform: rotate(45deg) scale(1);
  }
}

@keyframes loader-text-flow {
  from {
    background-position: 0 center;
  }

  to {
    background-position: 220% center;
  }
}

/* ------------------------------------------------------------------
   Responsive
   ------------------------------------------------------------------ */
@media (max-width: 700px) {
  .loader {
    width: min(420px, calc(100vw - 36px));
    min-height: 300px;
    gap: 28px;
  }

  .loader-mark-shell {
    width: 118px;
    height: 118px;
  }

  .app-title {
    font-size: 32px;
    letter-spacing: 0.18em;
  }

  .loader-subtitle,
  .intro-body {
    font-size: 11px;
    letter-spacing: 0.24em;
  }

  .loader-frame {
    inset: 16px;
  }

  .loader-corner {
    width: 44px;
    height: 44px;
  }

  .loader-corner::after {
    inset: 7px;
  }

  .intro-text-container {
    bottom: 16px;
  }

  .intro-text {
    letter-spacing: 0.34em;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
  }
}

/* ------------------------------------------------------------------
   Social World - cosmic loader
   Logo-forward and copy-light. Keep the loading bar treatment, but
   drop the full-screen frame, beams, grid, noise, and footer wordmark.
   ------------------------------------------------------------------ */

/* The shared deco gold is an antique #c69a4a, which sits a long way from the
   gold in the mark. Everything drawn beside the logo should be the same gold
   as the smile. */
body[data-app-name="social_world"],
body[data-app-name="gus"] {
  /* APP_COLORS in index.html, held here too so the first paint is not the
     default loader's colours. */
  --theme-primary: #7c3aed;
  --theme-secondary: #f6c343;
  --theme-tertiary: #14b8a6;
  --theme-background: #07030c;
  --theme-on-background: #f1f1f1;
  --loader-deco: #f6c343;
  --loader-deco-rgb: 246, 195, 67;
  --loader-deco-soft: rgba(246, 195, 67, 0.38);
}

body:is([data-app-name="social_world"], [data-app-name="gus"]) .intro-overlay,
body:is([data-app-name="social_world"], [data-app-name="gus"]) .intro-text-container {
  display: none;
}

/* The SoWo mark carries the screen without promo copy. */
body:is([data-app-name="social_world"], [data-app-name="gus"]) .intro-headline,
body:is([data-app-name="social_world"], [data-app-name="gus"]) .intro-body,
body:is([data-app-name="social_world"], [data-app-name="gus"]) .intro-counter,
body:is([data-app-name="social_world"], [data-app-name="gus"]) .intro-counter-label,
body:is([data-app-name="social_world"], [data-app-name="gus"]) .intro-coord {
  display: none;
}

/* The mark and the bar are one object, so they hold together rather than
   drifting apart down the middle of an empty field. One width drives both:
   two clamps that happen to land near each other agree on wide screens and
   invert on narrow ones. */
body:is([data-app-name="social_world"], [data-app-name="gus"]) {
  --sowo-block: clamp(208px, 34vw, 320px);
}

body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader {
  min-height: 0;
  gap: 40px;
}

/* ---- Progress ---------------------------------------------------- */
body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader-status {
  width: var(--sowo-block);
  gap: 16px;
  opacity: 0;
  animation: loader-status-in 800ms cubic-bezier(0.2, 0.7, 0.2, 1) 620ms forwards;
}

/* A capsule with an unfilled remainder, drawn out from the middle on entry.
   The shared track is a pair of fading hairlines — at this width the empty
   part vanishes, so a part-full bar reads as a gold smear rather than
   progress against a known distance. */
body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader-track {
  height: 2px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--theme-on-background) 19%, transparent);
  transform: scaleX(0);
  transform-origin: center;
  animation: loader-rail-draw 900ms cubic-bezier(0.2, 0.7, 0.2, 1) 660ms forwards;
}

body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader-track::before,
body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader-track::after {
  display: none;
}

body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader-track-fill {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  border-radius: 999px;
  width: calc(var(--loader-progress, 0) * 100%);
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--loader-deco) 45%, transparent),
    var(--loader-deco)
  );
  box-shadow: 0 0 12px rgba(var(--loader-deco-rgb), 0.5);
}

/* The marker rides the head of the fill instead of marching back and forth
   on a loop that means nothing. */
body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader-track-marker {
  left: calc(var(--loader-progress, 0) * 100%);
  width: 5px;
  height: 5px;
  margin-top: -2.5px;
  margin-left: -2.5px;
  animation: none;
  box-shadow: 0 0 12px rgba(var(--loader-deco-rgb), 0.85);
}

/* Only on completion, so the bar visibly closes as the screen leaves. */
body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader-status.is-complete .loader-track-fill,
body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader-status.is-complete .loader-track-marker {
  transition: width 520ms cubic-bezier(0.2, 0.8, 0.2, 1), left 520ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* ---- Status line ------------------------------------------------- */

/* The bar carries the motion now, so the pulsing dots are a second thing
   saying the same nothing — and they hung off the right of a centred line,
   pushing the words a dot-width out of true. */
body:is([data-app-name="social_world"], [data-app-name="gus"]) .loading-dots {
  display: none;
}

body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader-status-line {
  justify-content: center;
  font-size: 9px;
  letter-spacing: 0.4em;
  color: color-mix(in srgb, var(--theme-on-background) 62%, transparent);
}

body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader-status-text {
  /* Tracking hangs off the last letter; nudge back by half of it. */
  padding-left: 0.4em;
  transition: opacity 240ms ease, transform 240ms ease;
}

body:is([data-app-name="social_world"], [data-app-name="gus"]) .loader-status-text.is-swapping {
  opacity: 0;
  transform: translateY(-4px);
}

/* ---- Mark -------------------------------------------------------- */

/* The SoWo mark floats with a soft violet aura. */
body:is([data-app-name="social_world"], [data-app-name="gus"]) .intro-logo {
  width: var(--sowo-block);
  margin: 0;
  opacity: 0;
  transform: translateY(12px) scale(0.94);
  animation:
    loader-logo-in 1000ms cubic-bezier(0.2, 0.7, 0.2, 1) 140ms forwards,
    loader-logo-float 6s ease-in-out 1140ms infinite;
}

/* Two violet passes, tight then wide, plus a low warm one so the smile keeps
   its own colour instead of being swallowed by the purple bloom. */
body:is([data-app-name="social_world"], [data-app-name="gus"]) .intro-logo img {
  display: block;
  width: 100%;
  height: auto;
  filter:
    drop-shadow(0 0 16px color-mix(in srgb, var(--theme-primary) 40%, transparent))
    drop-shadow(0 0 56px color-mix(in srgb, var(--theme-primary) 22%, transparent))
    drop-shadow(0 8px 24px color-mix(in srgb, var(--theme-secondary) 15%, transparent));
}

@keyframes loader-status-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes loader-rail-draw {
  to {
    transform: scaleX(1);
  }
}

/* ------------------------------------------------------------------
   FFFD

   The showcase hero's opening, held for the second the app takes to
   boot: the wordmark, one honest progress line and one status, over a
   sparse rain that fffd-intro-screens.js draws around them.
   ------------------------------------------------------------------ */
.fffd-intro-content {
  display: none;
}

/* Colours are here as well as in APP_COLORS so the first paint is already
   the app's own ground rather than the shared default. */
body[data-app-name="fucking_fast_file_drive"] {
  --theme-primary: #57859d;
  --theme-secondary: #ff6e48;
  --theme-background: #11171a;
  --theme-on-background: #f1f1f1;
  /* The signal cyan and its text tone (FffdTerminalTheme) and the
     secondary grey (onSurfaceVariant), matched so nothing shifts at the
     handoff. */
  --fffd-signal: #2ee6ff;
  --fffd-signal-text: #7af0ff;
  --fffd-muted: #cacaca;
}

body[data-app-name="fucking_fast_file_drive"] #loading-container {
  background: var(--theme-background);
}

body[data-app-name="fucking_fast_file_drive"] .intro-overlay,
body[data-app-name="fucking_fast_file_drive"] .intro-text-container,
body[data-app-name="fucking_fast_file_drive"] .loading-dots {
  display: none;
}

body[data-app-name="fucking_fast_file_drive"] .loader {
  min-height: 0;
  gap: 28px;
}

body[data-app-name="fucking_fast_file_drive"] .fffd-intro-content {
  display: flex;
  align-items: center;
  gap: 14px;
  animation: fffd-lockup-in 560ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.fffd-lockup-mark {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  border-radius: 10px;
  object-fit: cover;
}

.fffd-lockup-mark svg {
  display: block;
  width: 100%;
  height: 100%;
}

.fffd-lockup-name {
  font-family: "Schibsted Grotesk", Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 34px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.fffd-lockup-name .first {
  color: var(--fffd-signal-text);
}

.fffd-lockup-name .rest {
  color: var(--theme-secondary);
}

/* Set a size down from the name: at display size the monospace would outweigh it. */
.fffd-lockup-drive {
  font-family: "Fira Code", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78em;
  font-weight: 400;
  letter-spacing: 0;
  color: color-mix(in srgb, var(--fffd-muted) 72%, transparent);
}

body[data-app-name="fucking_fast_file_drive"] .loader-status {
  width: 180px;
  gap: 14px;
  animation: fffd-status-in 560ms cubic-bezier(0.16, 1, 0.3, 1) 180ms both;
}

body[data-app-name="fucking_fast_file_drive"] .loader-track {
  height: 2px;
  overflow: hidden;
  border-radius: 999px;
  background: color-mix(in srgb, var(--theme-on-background) 10%, transparent);
}

body[data-app-name="fucking_fast_file_drive"] .loader-track::before,
body[data-app-name="fucking_fast_file_drive"] .loader-track::after,
body[data-app-name="fucking_fast_file_drive"] .loader-track-marker {
  display: none;
}

body[data-app-name="fucking_fast_file_drive"] .loader-track-fill {
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: calc(var(--loader-progress, 0) * 100%);
  border-radius: inherit;
  background: var(--fffd-signal);
}

/* Only on completion, so the line visibly closes as the screen leaves. */
body[data-app-name="fucking_fast_file_drive"] .loader-status.is-complete .loader-track-fill {
  transition: width 520ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

body[data-app-name="fucking_fast_file_drive"] .loader-status-line {
  justify-content: center;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
  color: var(--fffd-muted);
}

body[data-app-name="fucking_fast_file_drive"] .loader-status-text {
  transition: opacity 240ms ease;
}

body[data-app-name="fucking_fast_file_drive"] .loader-status-text.is-swapping {
  opacity: 0;
}

@keyframes fffd-lockup-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fffd-status-in {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

@media (max-width: 700px) {
  .fffd-lockup-mark {
    width: 36px;
    height: 36px;
    border-radius: 8px;
  }

  .fffd-lockup-name {
    font-size: 26px;
  }
}

@keyframes loader-logo-in {
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes loader-logo-float {
  0%,
  100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-9px);
  }
}

/* =====================================================================
   The Witching Hour
   ---------------------------------------------------------------------
   Not the Absurd loader in gold. Every piece of shared chrome is off —
   the deco frame, the corner rules, the kicker, the system header and
   footer, the progress rail. What is left is one object: a clock in a
   dark room with its maker's name printed on the case.
   ===================================================================== */

/* Keyed on the attribute the first script in <body> sets, not on a class
   the intro script adds later: the intro scripts load after the loader
   markup, and the shared chrome was painting for a frame in between. The
   colours are here for the same reason — APP_CONFIG sets them, but only
   once it runs. */
body[data-app-name="the_witching_hour"] {
  --theme-primary: #ffd93d;
  --theme-secondary: #6366f1;
  --theme-tertiary: #4a4a6a;
  --theme-background: #0f0f1a;
  --theme-on-background: #f0e6d3;
}

body[data-app-name="the_witching_hour"] .intro-overlay,
body[data-app-name="the_witching_hour"] .intro-text-container,
body[data-app-name="the_witching_hour"] .loader-mark-shell,
body[data-app-name="the_witching_hour"] .loader-kicker-row,
body[data-app-name="the_witching_hour"] .loader-subtitle,
body[data-app-name="the_witching_hour"] .loader-status {
  display: none;
}

body[data-app-name="the_witching_hour"] .loader {
  min-height: 0;
  width: min(560px, calc(100vw - 48px));
  margin-top: clamp(104px, 21vh, 252px);
  gap: 22px;
}

body[data-app-name="the_witching_hour"] .loader-brand {
  gap: 0;
}

/* Silkscreen on the case, not a headline: the readout above it is the
   loud thing, and this only has to say whose clock it is. */
body[data-app-name="the_witching_hour"] .app-title {
  margin: 0;
  font-size: clamp(11px, 1.5vw, 14px);
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: 0.52em;
  text-indent: 0.52em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--theme-on-background) 52%, transparent);
}

@media (max-width: 560px) {
  body[data-app-name="the_witching_hour"] .loader {
    margin-top: clamp(48px, 11vh, 110px);
    gap: 18px;
  }

  body[data-app-name="the_witching_hour"] .app-title {
    letter-spacing: 0.38em;
    text-indent: 0.38em;
  }
}

/* ------------------------------------------------------------------
   Napalm admin and console: the session's mark in the emblem's place
   (napalm-intro-screens.js). Napalm's heat is flat, so the emblem's
   halo and glow come off.
   ------------------------------------------------------------------ */
body[data-app-name="admin"] .loader-mark-shell,
body[data-app-name="console"] .loader-mark-shell {
  width: 112px;
  height: 112px;
  box-shadow: none;
}

body[data-app-name="admin"] .loader-mark-emblem,
body[data-app-name="console"] .loader-mark-emblem {
  filter: none;
}
