/* ============================================================
   AL MOKHTABAR — Page loader (curtain + heartbeat mark)
   ------------------------------------------------------------
   Loaded FIRST in <head>, before fonts/base/site. Every stylesheet
   in the head is render-blocking, so by the time the browser paints
   anything at all this file is already applied — which is the whole
   point: the overlay must be fully styled on the very first frame,
   otherwise the raw markup it is supposed to be hiding flashes past
   before the loader can cover it.

   Self-contained on purpose. It must not depend on base.css custom
   properties, because it has to render correctly even if a later
   stylesheet in the chain is slow or fails.

   All layout properties are logical (RTL-safe).
   ============================================================ */

:root {
  --mkl-red: #D8141C;
  --mkl-red-deep: #9E0D13;
  --mkl-gold: #F0B40D;
  --mkl-ink: #17181C;
  /* Curtain travel time. Overridden while the curtain is CLOSING for a
     navigation, where the point is to cover the old page fast. */
  --mkl-curtain: .62s;
  --mkl-ease: cubic-bezier(.76, 0, .24, 1);
}

/* ============================================================
   Overlay shell
   ============================================================ */

.mkl {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  overflow: hidden;
  /* Fail-safe. If loader.js never runs (404, blocked, parse error) the
     overlay would trap the page forever, so CSS alone dissolves it. The
     script cancels this the moment it is alive — see .mkl-js below. */
  animation: mkl-failsafe 8s linear forwards;
}

/* loader.js sets this on <html> as soon as it executes; from then on the
   script owns the overlay's lifetime and the CSS fail-safe must not fire. */
.mkl-js .mkl { animation: none; }

.mkl.is-done { pointer-events: none; }

/* Parked between navigations. [hidden] is declared here as well as in
   base.css so the overlay stays self-contained. */
.mkl[hidden], .mkl-top[hidden] { display: none !important; }

/* The curtain CLOSING again for an outgoing navigation. Faster than the
   opening sweep — every millisecond before it covers the old page is a
   millisecond of the white flash this whole file exists to hide. */
.mkl.is-entering { --mkl-curtain: .34s; }
.mkl.is-entering .mkl__half { transition-delay: 0s; }

/* ---- The two curtain halves ---------------------------------
   One continuous field split across two elements: each paints the same
   100vw x 100vh image, anchored to opposite edges, so the seam is
   invisible until they part. */
.mkl__half {
  position: absolute;
  inset-inline: 0;
  height: 50.4%;
  background-color: #FFFFFF;
  background-image:
    repeating-linear-gradient(0deg, rgba(23, 24, 28, .030) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(90deg, rgba(23, 24, 28, .030) 0 1px, transparent 1px 34px),
    radial-gradient(700px 440px at 50% 42%, rgba(216, 20, 28, .13), transparent 64%),
    radial-gradient(680px 420px at 84% 108%, rgba(240, 180, 13, .16), transparent 66%),
    radial-gradient(600px 360px at 8% -8%, rgba(216, 20, 28, .09), transparent 62%),
    radial-gradient(120% 90% at 50% 50%, transparent 52%, rgba(23, 24, 28, .05) 100%),
    linear-gradient(180deg, #FFFFFF 0%, #FBFAF7 100%);
  background-repeat: no-repeat;
  background-size: 100vw 100vh;
  will-change: transform;
  transition: transform var(--mkl-curtain) var(--mkl-ease) .05s;
}

.mkl__half--top { inset-block-start: 0; background-position: center top; }
.mkl__half--bottom { inset-block-end: 0; background-position: center bottom; }

.mkl.is-done .mkl__half--top { transform: translateY(-101%); }
.mkl.is-done .mkl__half--bottom { transform: translateY(101%); }

/* The seam that lights up along the split as the curtain opens. */
.mkl__seam {
  position: absolute;
  inset-block-start: 50%;
  inset-inline: 0;
  height: 1px;
  transform: scaleX(.18);
  opacity: 0;
  background: linear-gradient(90deg, transparent, var(--mkl-red) 35%, var(--mkl-gold) 65%, transparent);
  box-shadow: 0 0 14px rgba(216, 20, 28, .5);
}

.mkl.is-done .mkl__seam { animation: mkl-seam .66s var(--mkl-ease) forwards; }

/* ============================================================
   Core — mark, wordmark, pulse trace
   ============================================================ */

/* Centred by flex rather than a 50%/translate pair: translate() is not a
   logical property, so the usual -50% correction would have to be flipped
   by hand on the Arabic pages. Flex centring is direction-agnostic, which
   also leaves `transform` free for the exit animation alone. */
.mkl__core {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 26px;
  transition: opacity .26s ease, transform .3s ease;
}

.mkl.is-done .mkl__core { opacity: 0; transform: translateY(-12px) scale(.94); }

/* The only thing in the overlay a screen reader should reach. */
.mkl__sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- Mark: heart logo, ripples, counter-rotating arcs ---- */
/* One knob for the mark: the logo, the ripple rings and the ripple's own
   centring offset all read --mkl-dot, so a breakpoint resizes the whole
   assembly by overriding two values. */
.mkl__mark {
  --mkl-dot: 72px;
  position: relative;
  width: 150px;
  height: 150px;
  display: grid;
  place-items: center;
}

.mkl__logo {
  position: relative;
  z-index: 2;
  width: var(--mkl-dot);
  height: var(--mkl-dot);
  filter: drop-shadow(0 10px 26px rgba(216, 20, 28, .34));
  animation: mkl-beat 2.2s cubic-bezier(.4, 0, .2, 1) infinite;
}

/* Two rings pushed out of the mark on the beat — the visual echo of a pulse. */
.mkl__ripple {
  position: absolute;
  /* Offset in the inset itself, not a negative margin: `margin-left` would
     have to flip with the inline-start anchor under RTL, calc() does not. */
  inset-block-start: calc(50% - var(--mkl-dot) / 2);
  inset-inline-start: calc(50% - var(--mkl-dot) / 2);
  width: var(--mkl-dot);
  height: var(--mkl-dot);
  border-radius: 50%;
  border: 1.5px solid rgba(216, 20, 28, .5);
  opacity: 0;
  animation: mkl-ripple 2.2s cubic-bezier(.2, .6, .3, 1) infinite;
}

.mkl__ripple--2 { animation-delay: .32s; border-color: rgba(240, 180, 13, .55); }

/* Sized by the inset alone so it tracks .mkl__mark at every breakpoint; the
   viewBox keeps the geometry below in fixed user units either way. */
.mkl__orbit {
  position: absolute;
  inset: 0;
  overflow: visible;
}

.mkl__orbit circle {
  fill: none;
  stroke-linecap: round;
  transform-origin: 60px 60px;
}

.mkl__track { stroke: rgba(23, 24, 28, .08); stroke-width: 1.5; }

.mkl__arc {
  stroke-width: 3;
  /* r=52 -> circumference ~326.7. A 62-unit dash is a ~68deg sweep. */
  stroke-dasharray: 62 265;
}

.mkl__arc--red {
  stroke: var(--mkl-red);
  filter: drop-shadow(0 0 6px rgba(216, 20, 28, .45));
  animation: mkl-spin 1.45s linear infinite;
}

.mkl__arc--gold {
  stroke: var(--mkl-gold);
  stroke-dasharray: 34 293;
  animation: mkl-spin 2.3s linear infinite reverse;
}

/* ---- Wordmark with a light sweep across it ---- */
.mkl__word {
  font: 600 13px/1 "Instrument Sans", "Helvetica Neue", Arial, sans-serif;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--mkl-ink);
  background: linear-gradient(100deg,
      rgba(23, 24, 28, .45) 34%,
      var(--mkl-red) 46%,
      var(--mkl-gold) 54%,
      rgba(23, 24, 28, .45) 66%) 0 0 / 260% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: mkl-sweep 2.8s ease-in-out infinite;
}

[lang="ar"] .mkl__word {
  font-family: "IBM Plex Sans Arabic", "Segoe UI", Tahoma, sans-serif;
  font-size: 16px;
  letter-spacing: .08em;
  text-transform: none;
}

/* ---- ECG trace: a pulse travelling across a faint full trace ---- */
.mkl__ecg { width: 260px; height: 50px; }
.mkl__ecg svg { width: 100%; height: 100%; display: block; overflow: visible; }

.mkl__ecg path {
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mkl__ecg-ghost { stroke: rgba(23, 24, 28, .12); }

.mkl__ecg-live {
  stroke: var(--mkl-red);
  /* The trace is ~303 user units long. A 72-unit dash with a 303-unit gap
     means exactly one visible segment at a time, sweeping the full path as
     the offset runs through one 375-unit period. */
  stroke-dasharray: 72 303;
  filter: drop-shadow(0 0 5px rgba(216, 20, 28, .55));
  animation: mkl-trace 1.9s linear infinite;
}

/* ============================================================
   Top progress bar — shown on its own during a navigation
   ============================================================ */

.mkl-top {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  height: 3px;
  z-index: 2147483001;
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s ease .1s;
}

.mkl-top.is-on { opacity: 1; transition-delay: 0s; }

.mkl-top span {
  display: block;
  width: 0;
  height: 100%;
  background: linear-gradient(90deg, var(--mkl-red-deep), var(--mkl-red) 55%, var(--mkl-gold));
  box-shadow: 0 0 12px rgba(216, 20, 28, .65), 0 0 4px rgba(216, 20, 28, .9);
  transition: width .42s cubic-bezier(.22, .8, .3, 1);
}

/* ============================================================
   Keyframes
   ============================================================ */

/* Two beats then rest — a cardiac rhythm, not a generic throb. */
@keyframes mkl-beat {
  0%, 100% { transform: scale(1); }
  8% { transform: scale(1.11); }
  16% { transform: scale(1); }
  24% { transform: scale(1.07); }
  34% { transform: scale(1); }
}

@keyframes mkl-ripple {
  0% { transform: scale(1); opacity: 0; }
  10% { opacity: .75; }
  70%, 100% { transform: scale(2.05); opacity: 0; }
}

@keyframes mkl-spin {
  to { transform: rotate(360deg); }
}

@keyframes mkl-sweep {
  0%, 100% { background-position: 130% 0; }
  50% { background-position: -30% 0; }
}

@keyframes mkl-trace {
  from { stroke-dashoffset: 375; }
  to { stroke-dashoffset: 0; }
}

@keyframes mkl-seam {
  0% { transform: scaleX(.18); opacity: 0; }
  30% { opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}

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

/* ============================================================
   Reduced motion — keep the cover, drop the choreography
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  .mkl__logo,
  .mkl__ripple,
  .mkl__arc,
  .mkl__word,
  .mkl__ecg-live,
  .mkl__seam { animation: none; }

  .mkl__ripple { opacity: 0; }
  .mkl__arc--red { stroke-dasharray: 62 265; }
  .mkl__word { -webkit-text-fill-color: var(--mkl-ink); background: none; }
  .mkl__ecg-live { stroke-dasharray: none; opacity: .8; }

  /* No curtain: the whole overlay just fades. */
  .mkl { transition: opacity .25s linear; }
  .mkl__half { transition: none; }
  .mkl.is-done { opacity: 0; }
  .mkl.is-done .mkl__half--top,
  .mkl.is-done .mkl__half--bottom { transform: none; }
  .mkl-top span { transition: none; }
}

/* ============================================================
   Small screens
   ============================================================ */

@media (max-width: 520px) {
  .mkl__core { gap: 20px; }
  .mkl__mark { --mkl-dot: 56px; width: 116px; height: 116px; }
  .mkl__word { font-size: 12px; letter-spacing: .28em; }
  .mkl__ecg { width: 200px; height: 42px; }
}
