/* Giyan coming-soon page. Self-contained: fonts and images are local, no CDN. */

@font-face { font-family: "Estedad"; src: url("/fonts/estedad-arabic-400-normal.woff2") format("woff2"); font-weight: 400; font-display: swap; unicode-range: U+0600-06FF, U+0750-077F, U+0870-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FEFF; }
@font-face { font-family: "Estedad"; src: url("/fonts/estedad-arabic-500-normal.woff2") format("woff2"); font-weight: 500; font-display: swap; unicode-range: U+0600-06FF, U+0750-077F, U+0870-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FEFF; }
@font-face { font-family: "Estedad"; src: url("/fonts/estedad-arabic-700-normal.woff2") format("woff2"); font-weight: 700; font-display: swap; unicode-range: U+0600-06FF, U+0750-077F, U+0870-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FEFF; }
@font-face { font-family: "Geist"; src: url("/fonts/Geist-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Geist"; src: url("/fonts/Geist-Medium.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Geist"; src: url("/fonts/Geist-Bold.woff2") format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: "JetBrains Mono"; src: url("/fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2"); font-weight: 400; font-display: swap; }

:root {
  --emerald: #44d9a1;
  --fold: #1bb485;
  --forest: #087151;
  --black: #000000;
  --surface: #0a0a0a;
  --raised: #141414;
  --line: #222222;
  --line-strong: #363636;
  --text: #ededed;
  --muted: #8f8f8f;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  /* how long one feature stays on stage; app.js reads this */
  --cycle: 4200ms;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--black);
  color: var(--text);
  font-family: "Estedad", "Geist", system-ui, sans-serif;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  overflow-x: clip;
  line-height: 1.8;
}

.ltr {
  direction: ltr;
  unicode-bidi: isolate;
  font-family: "Geist", sans-serif;
}

/* ---- backdrop: drifting dots and one soft light behind the stack ------------- */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: radial-gradient(60vmax 60vmax at var(--light-x, 72%) 46%, rgb(68 217 161 / 0.13), transparent 62%), var(--black);
  -webkit-mask-image: radial-gradient(120% 90% at 50% 40%, #000 55%, transparent 100%);
  mask-image: radial-gradient(120% 90% at 50% 40%, #000 55%, transparent 100%);
}
/* only this layer moves, and only by transform, so nothing is repainted per frame */
.backdrop::before {
  content: "";
  position: absolute;
  inset: -22px;
  background: radial-gradient(var(--line-strong) 1px, transparent 1.4px) 0 0 / 22px 22px;
  animation: drift 14s linear infinite;
  will-change: transform;
}
[dir="rtl"] .backdrop {
  --light-x: 28%;
}

/*
 * Chamfered outline. A CSS border or shadow is cut off by clip-path at the two
 * chamfered corners, so the outline is the element's own background (--edge) and the
 * inside is a 1px-inset layer with the same shape (--fill).
 */
.cut {
  --cut: 8px;
  --edge: var(--line-strong);
  --fill: var(--black);
  position: relative;
  isolation: isolate;
  border: 0;
  background: var(--edge);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  transition:
    background-color 400ms,
    color 400ms,
    transform 400ms var(--ease);
}
.cut::before {
  content: "";
  position: absolute;
  inset: 1px;
  z-index: -1;
  background: var(--fill);
  clip-path: polygon(
    calc(var(--cut) - 0.4px) 0,
    100% 0,
    100% calc(100% - var(--cut) + 0.4px),
    calc(100% - var(--cut) + 0.4px) 100%,
    0 100%,
    0 calc(var(--cut) - 0.4px)
  );
  transition: background-color 400ms;
}

/* ---- frame --------------------------------------------------------------------- */

.top,
.foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: min(100%, 76rem);
  margin-inline: auto;
  padding: 1.25rem clamp(1.25rem, 4vw, 2.5rem);
}
.lockup {
  display: block;
  height: 2rem;
  width: auto;
}
.lang {
  font: inherit;
  font-family: "Geist", "Estedad", sans-serif;
  font-size: 0.8125rem;
  color: var(--muted);
  padding: 0.3rem 0.9rem;
  cursor: url("/cursor-link.svg") 4 3, pointer;
}
.lang:hover {
  color: var(--emerald);
  --edge: var(--emerald);
}
.lang:active {
  transform: scale(0.94);
}
.foot {
  font-size: 0.8125rem;
  color: var(--muted);
  flex-wrap: wrap;
  padding-block: 1.25rem calc(1.25rem + env(safe-area-inset-bottom));
}

.hero {
  display: grid;
  align-items: center;
  gap: clamp(1rem, 4vw, 3rem);
  width: min(100%, 76rem);
  margin-inline: auto;
  padding: 0 clamp(1.25rem, 4vw, 2.5rem);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 56rem) {
  .hero {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  }
}

/* ---- language switch: the words leave, change, and come back ---------------------- */

.copy,
.lockup,
.foot {
  transition:
    opacity 380ms var(--ease),
    transform 380ms var(--ease),
    filter 380ms var(--ease);
}
.lang-swap .copy,
.lang-swap .lockup,
.lang-swap .foot {
  opacity: 0;
  transform: translateY(10px);
  filter: blur(6px);
}

/* ---- copy ---------------------------------------------------------------------- */

.copy > * {
  animation: rise 900ms var(--ease) both;
}
.copy > *:nth-child(2) { animation-delay: 120ms; }
.copy > *:nth-child(3) { animation-delay: 240ms; }
.copy > *:nth-child(4) { animation-delay: 360ms; }
.copy > *:nth-child(5) { animation-delay: 440ms; }
.copy > *:nth-child(6) { animation-delay: 540ms; }

.soon {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0 0 1.25rem;
  padding: 0.2rem 0.9rem;
  font-size: 0.875rem;
  color: var(--emerald);
  --edge: color-mix(in srgb, var(--emerald) 55%, var(--black));
}
/* a diamond, like the dots in the Giyan icon set */
.soon-dot {
  position: relative;
  width: 7px;
  height: 7px;
  background: var(--emerald);
  transform: rotate(45deg);
}
.soon-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--emerald);
  animation: ping 2.6s var(--ease) infinite;
}

h1 {
  margin: 0;
  font-size: clamp(2.5rem, 7.2vw, 4.75rem);
  font-weight: 700;
  line-height: 1.25;
  text-wrap: balance;
}
[dir="ltr"] h1 {
  font-family: "Geist", sans-serif;
  line-height: 1.08;
  letter-spacing: -0.03em;
}

.lead {
  margin: 1.25rem 0 0;
  max-width: 34rem;
  font-size: clamp(1rem, 1.6vw, 1.1875rem);
  color: var(--muted);
  text-wrap: pretty;
}

.features {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.6rem;
  max-width: 30rem;
  margin: 2rem 0 0;
}
@media (min-width: 30rem) {
  .features {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    max-width: 34rem;
  }
}
.feature {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 0.45rem;
  padding: 0.85rem 0.4rem 0.75rem;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--muted);
  cursor: url("/cursor-link.svg") 4 3, pointer;
  --cut: 10px;
  --edge: var(--line-strong);
  --fill: var(--surface);
}
.feature svg {
  width: 22px;
  height: 22px;
  transition: transform 500ms var(--ease);
}
.feature:hover {
  color: var(--text);
  transform: translateY(-2px);
}
.feature:hover svg {
  transform: scale(1.12) rotate(-6deg);
}
.feature:active {
  transform: scale(0.97);
}
.feature.is-on {
  color: var(--emerald);
  --edge: var(--emerald);
  --fill: var(--raised);
}
/* time left before the next one takes the stage */
.feature::after {
  content: "";
  position: absolute;
  /* the cut corner is always bottom right, in both directions */
  left: 1px;
  right: 11px;
  bottom: 1px;
  height: 2px;
  background: var(--emerald);
  transform: scaleX(0);
  transform-origin: left;
}
[dir="rtl"] .feature::after {
  transform-origin: right;
}
.feature.is-on::after {
  animation: fill var(--cycle) linear both;
}

svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: butt;
  stroke-linejoin: miter;
}
svg .fill {
  fill: currentColor;
  stroke: none;
}

.note {
  min-height: 3.6em;
  max-width: 34rem;
  margin: 1rem 0 0;
  font-size: 0.9375rem;
  color: var(--text);
}
.note.swap {
  animation: rise 600ms var(--ease) both;
}

.cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.5rem;
  margin-top: 0.75rem;
}
.btn {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 3rem;
  padding: 0 1.6rem;
  font-weight: 500;
  color: #00140d;
  background: var(--emerald);
  text-decoration: none;
  clip-path: polygon(9px 0, 100% 0, 100% calc(100% - 9px), calc(100% - 9px) 100%, 0 100%, 0 9px);
  transition:
    transform 300ms var(--ease),
    filter 300ms;
}
.btn svg {
  width: 18px;
  height: 18px;
  transform-origin: 50% 20%;
}
.btn::after {
  content: "";
  position: absolute;
  inset-block: 0;
  left: -60%;
  width: 40%;
  background: linear-gradient(100deg, transparent, rgb(255 255 255 / 0.45), transparent);
  transform: skewX(-20deg);
}
.btn:hover {
  transform: translateY(-2px);
  filter: brightness(1.06);
}
.btn:hover::after {
  animation: sheen 1100ms var(--ease);
}
.btn:hover svg {
  animation: ring 900ms var(--ease);
}
.btn:active {
  transform: scale(0.97);
}
.mail {
  direction: ltr;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.875rem;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--line-strong);
  transition:
    color 300ms,
    border-color 300ms;
}
.mail:hover {
  color: var(--emerald);
  border-color: var(--emerald);
}

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

/* ---- the 3D scene -------------------------------------------------------------- */

.scene {
  position: relative;
  /* app.js scales the stage to fit this box */
  height: clamp(17rem, 46vh, 26rem);
  margin-bottom: 1.75rem;
  order: -1;
}
@media (min-width: 56rem) {
  .scene {
    height: min(72vh, 40rem);
    margin-bottom: 0;
    order: 0;
  }
}

/* designed at 440 x 520, then scaled as one piece */
.stage {
  /* out of the flow: its layout box must not widen the page before it is scaled */
  position: absolute;
  left: 50%;
  top: 50%;
  margin: -260px 0 0 -220px;
  width: 440px;
  height: 520px;
  transform: scale(var(--k, 1));
  perspective: 1400px;
}

.glow {
  position: absolute;
  left: 44%;
  top: 418px;
  width: 340px;
  height: 120px;
  translate: -50% -50%;
  background: radial-gradient(closest-side, rgb(68 217 161 / 0.35), transparent);
  filter: blur(12px);
  animation: breathe 5s ease-in-out infinite;
}

.stack {
  --a: 200px; /* slab side */
  --t: 30px; /* slab thickness */
  --gap: 44px; /* distance between slabs */
  position: absolute;
  left: 40%;
  top: 318px;
  width: var(--a);
  height: var(--a);
  margin-inline-start: calc(var(--a) / -2);
  transform-style: preserve-3d;
  /* --rx / --rz follow the pointer, set by app.js */
  transform: rotateX(calc(60deg + var(--rx, 0deg))) rotateZ(calc(45deg + var(--rz, 0deg)));
}
[dir="rtl"] .stack {
  margin-inline-start: 0;
  margin-left: calc(var(--a) / -2);
}

.slab {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  /* --out slides a slab along its own plane, like a drawer */
  transform: translate3d(var(--out, 0px), 0, calc(var(--level) * var(--gap) + var(--lift, 0px)));
  transition: transform 900ms var(--ease);
  animation:
    slab-in 1100ms var(--ease) both,
    slab-bob 6s ease-in-out infinite;
  animation-delay: calc(var(--level) * 160ms + 300ms), calc(var(--level) * -900ms + 2s);
}
.slab[data-level="0"] { --level: 0; }
.slab[data-level="1"] { --level: 1; }
.slab[data-level="2"] { --level: 2; }
.slab[data-level="3"] { --level: 3; }
.slab[data-level="4"] { --level: 4; }

.face {
  position: absolute;
  background: var(--surface);
  border: 1.5px solid #4a4a4a;
  transition:
    background-color 700ms var(--ease),
    border-color 700ms var(--ease),
    color 700ms var(--ease);
  animation: face-in 900ms var(--ease) both;
  animation-delay: calc(var(--level) * 160ms + 300ms);
}
.face.top {
  inset: 0;
  display: grid;
  place-items: center;
  color: #8a8a8a;
  background:
    linear-gradient(135deg, rgb(255 255 255 / 0.1), transparent 60%),
    #1e1e1e;
  /* the far corner is cut, like every Giyan shape */
  clip-path: polygon(34px 0, 100% 0, 100% 100%, 0 100%, 0 34px);
}
.face.top svg {
  width: 44%;
  height: 44%;
  stroke-width: 1.6;
}
/* the two faces towards the viewer hang from the slab's near edges */
.face.side-a {
  left: 0;
  top: 100%;
  width: 100%;
  height: var(--t);
  transform-origin: top;
  transform: rotateX(-90deg);
  display: grid;
  place-items: center;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.08em;
  color: var(--muted);
  direction: ltr;
  background: #111111;
}
.face.side-b {
  left: 100%;
  top: 0;
  width: var(--t);
  height: 100%;
  transform-origin: left;
  transform: rotateY(90deg);
  background: #050505;
}

/* the feature on stage slides out so its top face and icon can be seen */
.slab.is-on {
  --lift: 6px;
  --out: 150px;
}
.slab.cap .face {
  border-color: color-mix(in srgb, var(--emerald) 55%, var(--line-strong));
}
.slab.cap .top {
  background:
    linear-gradient(135deg, rgb(68 217 161 / 0.22), transparent 70%),
    #121212;
}
.slab.is-on .face {
  border-color: var(--emerald);
}
.slab.is-on .top {
  color: #00140d;
  background:
    linear-gradient(135deg, rgb(255 255 255 / 0.35), transparent 60%),
    var(--emerald);
}
.slab.is-on .side-a {
  color: #00140d;
  background: var(--fold);
}
.slab.is-on .side-b {
  background: var(--forest);
}

/* the caracal is flat artwork standing on the top slab */
.mascot {
  position: absolute;
  left: 40%;
  top: 40px;
  width: 236px;
  height: 218px;
  margin-left: -118px;
  /* --mx / --my follow the pointer; app.js eases them, so no CSS transition here */
  transform: translate3d(var(--mx, 0px), var(--my, 0px), 0);
  animation: mascot-in 900ms var(--ease) 1150ms both;
}
.mascot-bob {
  position: absolute;
  inset: 0;
  animation: mascot-bob 6s ease-in-out 2.2s infinite;
  will-change: transform;
}
.pose {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transform: scale(0.94) translateY(6px);
  transition:
    opacity 600ms var(--ease),
    transform 700ms var(--ease);
}
.pose.is-on {
  opacity: 1;
  transform: none;
}

/* ---- the pointer ---------------------------------------------------------------- */

/*
 * Giyan's own arrow, as a real CSS cursor: the browser draws it, so it never lags
 * behind the mouse. The numbers are the hot spot (the arrow's tip). Browsers that
 * cannot use an SVG cursor fall back to the system one.
 */
html {
  cursor: url("/cursor.svg") 4 3, auto;
}
a,
button {
  cursor: url("/cursor-link.svg") 4 3, pointer;
}

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

@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}
@keyframes drift {
  to { transform: translate3d(22px, 22px, 0); }
}
@keyframes ping {
  0% { transform: scale(1); opacity: 0.7; }
  80%, 100% { transform: scale(3); opacity: 0; }
}
@keyframes fill {
  to { transform: scaleX(1); }
}
@keyframes sheen {
  to { left: 130%; }
}
@keyframes ring {
  0%, 100% { transform: rotate(0); }
  25% { transform: rotate(14deg); }
  55% { transform: rotate(-10deg); }
  80% { transform: rotate(5deg); }
}
@keyframes breathe {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}
/* slabs fall into place from above, one after the other */
@keyframes slab-in {
  from { translate: 0 0 260px; }
  to { translate: 0 0 0; }
}
/* opacity lives on the faces: animating it on the slab itself would flatten its 3D children */
@keyframes face-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes slab-bob {
  0%, 100% { translate: 0 0 0; }
  50% { translate: 0 0 7px; }
}
@keyframes mascot-in {
  from { opacity: 0; scale: 0.7; }
  to { opacity: 1; scale: 1; }
}
@keyframes mascot-bob {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50% { transform: translate3d(0, -7px, 0); }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ---- scrollbar: thin, square, emerald on hover ---------------------------------- */

html {
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}
*::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
*::-webkit-scrollbar-track {
  background: transparent;
}
*::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  /* a transparent border makes the bar look slimmer than its hit area */
  border: 3px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover,
*::-webkit-scrollbar-thumb:active {
  background: var(--emerald);
  background-clip: content-box;
}
*::-webkit-scrollbar-corner {
  background: transparent;
}
