/* ==========================================================================
   DEPTH DIGITAL — ENTRANCE
   The brand resolves at the centre of a lighter version of the site's ocean
   palette. Enter then carries that exact lock-up into the real header while
   the genuine home page gradually replaces the opening colour field.
   ========================================================================== */

/* First-paint cover. JavaScript replaces this with the interactive layer; if
   the module fails, the cover quietly clears and leaves the website usable. */
html.is-diving::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 400;
  background:
    radial-gradient(90% 58% at 50% -8%, rgba(229, 255, 251, .98) 0%, rgba(139, 237, 233, .74) 28%, transparent 62%),
    linear-gradient(
      180deg,
      #c8f8f3 0%,
      #8be6e4 25%,
      #5fd7dc 46%,
      #1882a2 67%,
      #0a526f 83%,
      #03111d 100%
    );
  animation: entrance-failsafe 3s linear forwards;
}

html.is-diving.entrance-live::before { display: none; }

html.is-diving,
html.is-diving body {
  overflow: hidden;
  overscroll-behavior: none;
}

@keyframes entrance-failsafe {
  0%, 84% { opacity: 1; visibility: visible; }
  100% { opacity: 0; visibility: hidden; }
}

@media (prefers-reduced-motion: reduce) {
  html.is-diving::before { display: none; }
}

/* --------------------------------------------------------------------------
   Gradual page handoff
   -------------------------------------------------------------------------- */
html.entrance-active .site-header,
html.entrance-active .depth-gauge,
html.entrance-active main,
html.entrance-active [data-whatsapp-contact] {
  opacity: 0;
  transition: opacity 1.35s cubic-bezier(.2, .65, .3, 1);
}

html.entrance-active.entrance-page-ready .site-header,
html.entrance-active.entrance-page-ready .depth-gauge,
html.entrance-active.entrance-page-ready main,
html.entrance-active.entrance-page-ready [data-whatsapp-contact] {
  opacity: 1;
}

/* Keep the destination logo clear until the travelling copy has reached it. */
html.entrance-active .site-header .brand__logo-stack {
  opacity: 0;
  transition:
    width .35s cubic-bezier(.2, .65, .3, 1),
    opacity .36s ease;
}

html.entrance-active.entrance-logo-landed .site-header .brand__logo-stack {
  opacity: 1;
}

/* --------------------------------------------------------------------------
   Interactive layer
   -------------------------------------------------------------------------- */
.entrance {
  --enter-y: calc(50% + clamp(120px, 17vh, 154px));
  position: fixed;
  inset: 0;
  z-index: 401;
  overflow: hidden;
  cursor: default;
  outline: none;
  touch-action: none;
}

.entrance__surface,
.entrance__site-colour {
  position: absolute;
  pointer-events: none;
}

/* A brighter opening interpretation of the homepage gradient. It is light at
   the surface and already resolves into the site's true abyss colour below. */
.entrance__surface {
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background:
    radial-gradient(90% 58% at 50% -8%, rgba(229, 255, 251, .98) 0%, rgba(139, 237, 233, .74) 28%, transparent 62%),
    linear-gradient(
      180deg,
      #c8f8f3 0%,
      #8be6e4 25%,
      #5fd7dc 46%,
      #1882a2 67%,
      #0a526f 83%,
      #03111d 100%
    );
}

/* This is the same colour recipe as .ocean__gradient. It briefly replaces the
   opening field, making the subsequent transparency reveal imperceptible. */
.entrance__site-colour {
  inset: -10%;
  z-index: 1;
  opacity: 0;
  transform: scale(1.08);
  background:
    radial-gradient(90% 55% at 50% -5%, rgba(196,255,249,.95) 0%, rgba(55,207,215,.62) 18%, transparent 48%),
    linear-gradient(
      180deg,
      #5fd7dc 0%,
      #1882a2 17%,
      #0a526f 36%,
      #07384f 54%,
      #061f31 72%,
      #03111d 100%
    );
}

/* --------------------------------------------------------------------------
   Centred brand lock-up
   -------------------------------------------------------------------------- */
.entrance__identity {
  position: fixed;
  top: 45%;
  left: 50%;
  z-index: 4;
  width: min(82vw, 570px);
  aspect-ratio: 1222 / 341;
  opacity: 1;
  transform: translate(-50%, -50%);
  transform-origin: center;
  will-change: transform, opacity;
}

.entrance__emblem {
  position: absolute;
  top: 0;
  left: 50%;
  display: block;
  width: 27.905%;
  height: 100%;
  overflow: hidden;
  border-radius: 50%;
  clip-path: circle(45% at 49.7% 50%);
  opacity: 0;
  transform: translate(-50%, 18px) scale(.99);
  transform-origin: center;
  mix-blend-mode: multiply;
  animation:
    entrance-emblem-emerge 2.4s .12s cubic-bezier(.22, .61, .36, 1) forwards,
    entrance-emblem-align .68s 2.55s cubic-bezier(.2, .65, .3, 1) forwards;
  will-change: left, opacity, transform;
}

.entrance__emblem-source {
  display: block;
  width: auto;
  max-width: none;
  height: 100%;
}

.entrance__wordmark {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  clip-path: inset(0 65.5% 0 34.5%);
  mix-blend-mode: multiply;
  animation: entrance-wordmark-form 1.5s 3.65s linear forwards;
}

/* The depth reveal is one uninterrupted opacity/transform interpolation.
   Keeping it separate from the later horizontal alignment prevents easing
   from restarting at intermediate checkpoints and removes visible stepping. */
@keyframes entrance-emblem-emerge {
  from {
    opacity: 0;
    transform: translate(-50%, 18px) scale(.99);
  }
  to {
    opacity: 1;
    transform: translate(-50%, 0) scale(1);
  }
}

@keyframes entrance-emblem-align {
  from { left: 50%; }
  to { left: 13.9525%; }
}

@keyframes entrance-wordmark-form {
  from {
    opacity: 0;
    clip-path: inset(0 65.5% 0 34.5%);
  }
  to {
    opacity: 1;
    clip-path: inset(0 0 0 34.5%);
  }
}

/* A single soft aqua reflection crosses the completed mark. The original logo
   alpha is the mask, so no highlight or rectangular edge can leave the D or
   lettering. */
.entrance__glint {
  position: absolute;
  inset: 0;
  z-index: 3;
  overflow: hidden;
  pointer-events: none;
  -webkit-mask-image: url('/assets/logo-depth-digital-top.webp');
  -webkit-mask-position: center;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-size: contain;
  mask-image: url('/assets/logo-depth-digital-top.webp');
  mask-mode: alpha;
  mask-position: center;
  mask-repeat: no-repeat;
  mask-size: contain;
}

.entrance__glint::before {
  content: '';
  position: absolute;
  top: -22%;
  left: -31%;
  width: 24%;
  height: 144%;
  border-radius: 48% 52% 46% 54%;
  background:
    linear-gradient(
      104deg,
      transparent 8%,
      rgba(205, 255, 250, .08) 27%,
      rgba(238, 255, 253, .62) 49%,
      rgba(123, 233, 231, .24) 66%,
      transparent 86%
    );
  opacity: 0;
  filter: blur(2px);
  mix-blend-mode: screen;
  transform: translateX(0) skewX(-9deg) rotate(2deg);
  transform-origin: center;
  animation: entrance-logo-glint 1.55s 4.94s cubic-bezier(.32, 0, .28, 1) forwards;
  will-change: opacity, transform;
}

@keyframes entrance-logo-glint {
  0% {
    opacity: 0;
    transform: translateX(0) skewX(-9deg) rotate(2deg);
  }
  15% { opacity: .16; }
  42% { opacity: .42; }
  74% { opacity: .28; }
  100% {
    opacity: 0;
    transform: translateX(610%) skewX(-9deg) rotate(2deg);
  }
}

.entrance.has-started .entrance__identity {
  opacity: 1;
  transform: translate(-50%, -50%);
  filter: none;
}

.entrance.has-started .entrance__emblem {
  animation: none;
  left: 13.9525%;
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
}

.entrance.has-started .entrance__wordmark {
  animation: none;
  opacity: 1;
  clip-path: inset(0 0 0 28%);
}

.entrance.has-started .entrance__glint::before {
  animation: none;
  opacity: 0;
}

/* --------------------------------------------------------------------------
   Circular Enter control
   -------------------------------------------------------------------------- */
.entrance__prompt {
  position: absolute;
  top: var(--enter-y);
  left: 50%;
  z-index: 5;
  opacity: 0;
  transform: translate(-50%, -50%) translateY(12px);
  animation: entrance-prompt-arrive .72s 6.52s cubic-bezier(.2, .65, .3, 1) forwards;
  pointer-events: none;
}

@keyframes entrance-prompt-arrive {
  to {
    opacity: 1;
    transform: translate(-50%, -50%) translateY(0);
  }
}

.entrance.can-enter .entrance__prompt { pointer-events: auto; }

.entrance.has-started .entrance__prompt {
  animation: none;
  opacity: 1;
  transform: translate(-50%, -50%);
  pointer-events: none;
}

.entrance__enter {
  position: relative;
  display: grid;
  width: 100px;
  height: 100px;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(4, 59, 70, .42);
  border-radius: 50%;
  background: rgba(231, 255, 253, .2);
  box-shadow:
    0 18px 44px rgba(4, 54, 65, .13),
    inset 0 1px 0 rgba(255, 255, 255, .58);
  color: #073d49;
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: .7rem;
  font-weight: 500;
  letter-spacing: .2em;
  line-height: 1;
  text-indent: .2em;
  text-transform: uppercase;
  cursor: pointer;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition:
    color .3s ease,
    background-color .3s ease,
    border-color .3s ease,
    box-shadow .3s ease,
    transform .35s cubic-bezier(.2, .65, .3, 1);
}

.entrance__enter::before {
  content: '';
  position: absolute;
  inset: 8px;
  border: 1px solid rgba(255, 255, 255, .48);
  border-radius: 50%;
  pointer-events: none;
}

.entrance__enter::after {
  content: '';
  position: absolute;
  inset: -7px;
  border: 1px solid rgba(7, 61, 73, .17);
  border-radius: 50%;
  opacity: .7;
  pointer-events: none;
  animation: entrance-enter-breathe 2.8s 7.2s ease-in-out infinite;
}

@keyframes entrance-enter-breathe {
  0%, 100% { opacity: .28; transform: scale(.96); }
  50% { opacity: .72; transform: scale(1.055); }
}

.entrance__enter:hover {
  transform: translateY(-3px) scale(1.025);
  border-color: rgba(4, 59, 70, .62);
  background: rgba(239, 255, 254, .4);
  box-shadow:
    0 22px 48px rgba(4, 54, 65, .18),
    inset 0 1px 0 rgba(255, 255, 255, .72);
}

.entrance__enter:active { transform: translateY(0) scale(.96); }
.entrance__enter:disabled { cursor: default; }

.entrance__enter:focus-visible,
.entrance__skip:focus-visible {
  outline: 2px solid rgba(190, 255, 248, .92);
  outline-offset: 4px;
}

.entrance__enter:focus:not(:focus-visible),
.entrance__skip:focus:not(:focus-visible) { outline: none; }

/* Skip is intentionally available only after Enter. */
.entrance__skip {
  position: absolute;
  right: clamp(16px, 3vw, 34px);
  bottom: clamp(16px, 4vh, 38px);
  z-index: 6;
  padding: 10px 18px;
  border: 1px solid rgba(210, 244, 246, .28);
  border-radius: 999px;
  background: rgba(3, 16, 26, .32);
  color: rgba(225, 245, 247, .75);
  font-family: 'IBM Plex Mono', ui-monospace, monospace;
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  cursor: pointer;
  opacity: 0;
  transition: opacity .4s cubic-bezier(.2, .65, .3, 1), color .25s ease;
  pointer-events: none;
}

.entrance.can-skip .entrance__skip {
  opacity: 1;
  pointer-events: auto;
}

.entrance__skip:hover { color: #f3fbfc; }
.entrance__skip:focus-visible { outline-color: #a5fff4; }

@media (max-width: 700px) {
  .entrance {
    --enter-y: calc(50% + 116px);
  }

  .entrance__identity {
    top: 44.5%;
    width: min(91vw, 440px);
  }

  .entrance__enter {
    width: 94px;
    height: 94px;
  }
}

@media (max-height: 650px) {
  .entrance {
    --enter-y: calc(50% + 101px);
  }

  .entrance__identity { top: 43%; }

  .entrance__enter {
    width: 86px;
    height: 86px;
  }
}

/* The wordmark's own refraction — the field is animated by entrance.js, which
   is affordable because the element is small. */
.entrance__wordmark.is-refracting {
  filter: url('#dd-mark-water');
}

@media (prefers-reduced-motion: reduce) {

  .entrance__rule { display: none; }
  .entrance__wordmark.is-refracting { filter: none; }
}

/* ==========================================================================
   THE RULE
   One line, four beats. It appears beside the D only after the D has finished
   moving, sweeps right with the wordmark revealing in its wake, then curves
   back down through the water and settles at 33.15% — exactly where the
   artwork's own divider sits. The wordmark's clip now starts at 34.5%, past
   that divider, so the painted one is never uncovered and this is the only
   line the visitor ever sees.

   Motion is split across three nested elements on purpose: the wrapper travels
   horizontally, the arc dips and rotates, the <i> grows in. Composing all of
   that into one transform makes the curve impossible to tune and lets one
   animation overwrite another's work.

     4.53s  D finishes moving (nothing visible yet)
     4.55s  appear, growing from a sliver
     4.85s  sweep right, 28% -> 100%
     5.95s  arc back down, 100% -> 33.15%
     6.95s  settle: rotation and dip resolve to zero
     7.20s  at rest as the divider
   ========================================================================== */

.entrance__rule {
  position: absolute;
  top: 5.9%;
  left: 28%;
  width: 72%;
  height: 87.7%;
  opacity: 0;
  pointer-events: none;
  transform: translateX(0);
  animation:
    entrance-rule-appear .3s 3.25s cubic-bezier(.2, .65, .3, 1) forwards,
    entrance-rule-travel 1.5s 3.55s cubic-bezier(.4, 0, .3, 1) forwards,
    entrance-rule-handover .01s 5.15s linear forwards,
    entrance-rule-settle .01s 8.05s linear forwards,
    entrance-rule-return .01s 8.05s linear forwards;
  will-change: transform, opacity;
}

/* The dip. Vertical only, so it composes cleanly with the travel above. */
.entrance__rule-arc {
  position: absolute;
  inset: 0;
  display: block;
  transform: none;
  will-change: transform;
}

/* The line itself, matched to the divider baked into the logo artwork. */
.entrance__rule-arc > i {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 2px;
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(180deg,
    rgba(24, 37, 55, .28) 0%,
    rgba(24, 37, 55, .92) 22%,
    rgba(24, 37, 55, .92) 78%,
    rgba(24, 37, 55, .28) 100%);
  transform: scaleY(.14);
  transform-origin: 50% 50%;
  animation: entrance-rule-grow .3s 3.25s cubic-bezier(.2, .65, .3, 1) forwards;
}

@keyframes entrance-rule-appear {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes entrance-rule-grow {
  from { transform: scaleY(.14); }
  to   { transform: scaleY(1); }
}

/* Horizontal travel. 0% of the wrapper is 28% of the logo, 100% is the right
   edge, and 7.15% lands the line on the divider position at 33.15%. */
@keyframes entrance-rule-travel {
  from { transform: translateX(0); }
  to   { transform: translateX(100%); }
}

/* Jump to the divider position while invisible, ready to be handed back. */
@keyframes entrance-rule-settle {
  from { transform: translateX(7.15%); }
  to   { transform: translateX(7.15%); }
}

/* The instant the SVG segment takes over at the right-hand end, this element
   steps aside and reappears at rest once the journey is done. Both are 2px,
   the same ink, in the same place on the swap frame, so neither swap shows. */
@keyframes entrance-rule-handover {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* Back at rest as the divider, the moment the travelling segment arrives. */
@keyframes entrance-rule-return {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Once the dive begins the line is part of the lockup, not an animation — hold
   it at rest so it stays put through the flight to the header. */
.entrance.has-started .entrance__emblem,
.entrance.has-started .entrance__wordmark {
  mix-blend-mode: normal;
}

.entrance.has-started .entrance__rule {
  animation: none;
  opacity: 1;
  transform: translateX(7.15%);
  will-change: auto;
}

.entrance.has-started .entrance__rule-arc {
  animation: none;
  transform: none;
  will-change: auto;
}

.entrance.has-started .entrance__rule-arc > i {
  animation: none;
  transform: scaleY(1);
}

/* The line's return journey, drawn as a dash travelling along a path so it
   bends around the corners instead of pivoting. Scales with the identity
   because the viewBox matches the artwork; non-scaling-stroke keeps it 2px. */
.entrance__journey {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

/* Base state: nothing drawn. The dash animation takes over at 5.05s; until it
   does, this is what holds, so the path cannot appear before its turn. */
.entrance__journey path {
  stroke-dasharray: 0 9999;
}

/* Once the journey is over the DOM line takes the divider back, so the path
   steps aside — and neither is animating during the flight to the header. */
.entrance.has-started .entrance__journey { display: none; }

@media (prefers-reduced-motion: reduce) {
  .entrance__journey { display: none; }
}
