/* ============================================================
   Gauransh Portfolio — enhancement layer (additive only)
   PRUNE click ripple · loki easter egg · variant stamp ·
   polish pack · mobile nav · deep links
   © 2026 Gauransh Ahuja
   ============================================================ */

/* ---- global 90% comfortable scale (like browser zoom at 90%) ------- */
/* The whole design is rem-based, so scaling the root font scales text,
   cards, paddings and panels together. Canvas backdrops stay full-bleed.
   Kept uniform across sections: a per-section root font-size (the old
   html:has(#about) rule) reflows the entire page on every transition. */
@media (min-width: 768px) {
  html { font-size: 90%; }
}

/* ---- polish pack -------------------------------------------------- */
::selection { background: rgba(214, 169, 74, 0.85); color: #020503; }
::-moz-selection { background: rgba(214, 169, 74, 0.85); color: #020503; }
html { scrollbar-width: thin; scrollbar-color: rgba(0, 255, 156, 0.2) #030305; }

/* ---- PRUNE click ripple ------------------------------------------- */
.gp-ring {
  position: fixed; z-index: 99; pointer-events: none;
  border-radius: 50%; transform: translate(-50%, -50%);
  animation: gp-ring-grow 0.62s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.gp-ring-gold { border: 2px solid rgba(255, 149, 45, 0.85); box-shadow: 0 0 14px rgba(255, 149, 45, 0.4); }
.gp-ring-green { border: 1px solid rgba(0, 255, 156, 0.7); animation-duration: 0.5s; }
@keyframes gp-ring-grow {
  0%   { width: 6px; height: 6px; opacity: 0.95; }
  100% { width: 76px; height: 76px; opacity: 0; }
}

/* ---- VARIANT FILE stamp ------------------------------------------- */
.gp-stamp {
  position: fixed; inset: 0; z-index: 120; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
}
.gp-stamp-box {
  border: 4px double rgba(255, 95, 31, 0.9); border-radius: 6px;
  padding: 18px 34px; text-align: center; transform: rotate(-7deg);
  color: #ff7a3d; font-family: "JetBrains Mono", Overpass, monospace;
  background: rgba(20, 8, 2, 0.35); backdrop-filter: blur(1px);
  box-shadow: 0 0 34px rgba(255, 95, 31, 0.25), inset 0 0 22px rgba(255, 95, 31, 0.12);
  animation: gp-stamp-slam 0.42s cubic-bezier(0.22, 1.4, 0.36, 1) forwards,
             gp-stamp-fade 0.55s ease 2.1s forwards;
}
.gp-stamp-box .gp-stamp-top { font-size: 21px; font-weight: 700; letter-spacing: 6px; }
.gp-stamp-box .gp-stamp-sub { font-size: 12px; letter-spacing: 4px; margin-top: 7px; color: rgba(255, 173, 122, 0.9); }
@keyframes gp-stamp-slam {
  0%   { opacity: 0; transform: rotate(-7deg) scale(2.6); }
  60%  { opacity: 1; transform: rotate(-7deg) scale(0.94); }
  100% { opacity: 1; transform: rotate(-7deg) scale(1); }
}
@keyframes gp-stamp-fade { to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .gp-stamp-box { animation: gp-stamp-fade 0.4s ease 1.8s forwards; }
}

/* ---- loki easter egg: TVA time slip through a 3D timedoor ------------ */
.gp-loki #root {
  animation: glitch 0.14s steps(2) infinite;
  filter: hue-rotate(35deg) saturate(1.6) contrast(1.2) brightness(1.06);
}
/* the page gets pulled through the door */
.gp-suck #root {
  animation: gp-root-suck 0.75s cubic-bezier(0.6, -0.1, 0.85, 0.4) forwards;
  transform-origin: 50% 46%;
}
@keyframes gp-root-suck {
  0%   { transform: none; filter: none; opacity: 1; }
  45%  { transform: scale(0.55) rotate(-1deg); filter: blur(1px) saturate(1.4) sepia(0.25); }
  100% { transform: scale(0.04) rotate(3deg); filter: blur(6px) saturate(2) sepia(0.5); opacity: 0.12; }
}

/* portal overlay scene */
.gp-loki-flash {
  position: fixed; inset: 0; z-index: 130; pointer-events: none;
  display: grid; place-items: center; perspective: 1400px;
  background: radial-gradient(circle at center, rgba(24, 18, 4, 0.18), rgba(2, 5, 3, 0.78));
  animation: gp-flash-in 0.25s ease forwards;
  transition: opacity 0.45s ease;
}
.gp-portal {
  position: relative;
  width: min(330px, 60vw); height: min(600px, 76vh);
  transform-style: preserve-3d;
  transform: rotateY(-18deg) rotateX(2deg) scaleX(0.04) scaleY(0.12);
  opacity: 0;
}
.gp-open .gp-portal { animation: gp-p-open 0.85s cubic-bezier(0.22, 0.61, 0.36, 1) forwards; }
@keyframes gp-p-open {
  0%   { opacity: 0; transform: rotateY(-18deg) rotateX(2deg) scaleX(0.04) scaleY(0.12); }
  30%  { opacity: 1; transform: rotateY(-18deg) rotateX(2deg) scaleX(0.08) scaleY(0.55); }
  70%  { opacity: 1; transform: rotateY(-17deg) rotateX(2deg) scaleX(1.06) scaleY(1.01); }
  100% { opacity: 1; transform: rotateY(-18deg) rotateX(2deg) scale(1); }
}
/* slipping through: door flies past the camera */
.gp-zoom .gp-portal { animation: gp-p-zoom 0.8s cubic-bezier(0.7, 0, 0.9, 0.6) forwards; }
@keyframes gp-p-zoom {
  0%   { transform: rotateY(-18deg) rotateX(2deg) scale(1); }
  100% { transform: rotateY(-3deg) rotateX(0deg) scale(8.5); }
}
.gp-p-front {
  position: absolute; inset: 0; overflow: hidden;
  border: 4px solid rgba(255, 255, 238, 0.96);
  transform: translateZ(34px);
  background: linear-gradient(90deg, rgba(255, 222, 105, 0.16), rgba(205, 170, 70, 0.42), rgba(88, 73, 28, 0.56));
  box-shadow: 0 0 20px rgba(255, 230, 140, 0.45), inset 0 0 25px rgba(255, 218, 92, 0.35), inset 0 0 90px rgba(100, 110, 40, 0.28);
}
.gp-p-side {
  position: absolute; top: 0; right: -68px; width: 68px; height: 100%;
  background: linear-gradient(90deg, rgba(145, 118, 44, 0.95), rgba(70, 56, 20, 0.98));
  border: 4px solid rgba(255, 255, 238, 0.96); border-left: none;
  transform-origin: left center; transform: rotateY(90deg);
  box-shadow: inset 18px 0 28px rgba(255, 223, 116, 0.14);
}
.gp-p-top {
  position: absolute; left: 0; top: -68px; width: 100%; height: 68px;
  background: linear-gradient(180deg, rgba(130, 104, 38, 0.95), rgba(190, 154, 56, 0.88), rgba(82, 66, 24, 0.96));
  border: 4px solid rgba(255, 255, 238, 0.96); border-bottom: none;
  transform-origin: center bottom; transform: rotateX(90deg);
  box-shadow: inset 0 -16px 26px rgba(255, 223, 116, 0.16);
}
.gp-p-frame {
  position: absolute; inset: 25px 21px; z-index: 7; pointer-events: none;
  border: 2px solid rgba(255, 184, 45, 0.72);
  box-shadow: 0 0 12px rgba(255, 176, 40, 0.85), inset 0 0 14px rgba(255, 176, 40, 0.42);
}
.gp-p-core {
  position: absolute; inset: 20px; overflow: hidden;
  clip-path: inset(0 49% 0 49%); opacity: 0.35;
  background:
    radial-gradient(circle at 50% 74%, rgba(255, 236, 153, 0.72), transparent 26%),
    radial-gradient(circle at 48% 50%, rgba(182, 207, 110, 0.26), transparent 32%),
    linear-gradient(90deg, rgba(243, 221, 134, 0.16), rgba(205, 180, 89, 0.24), rgba(131, 132, 63, 0.24));
}
.gp-open .gp-p-core { animation: gp-p-core-open 0.7s cubic-bezier(0.22, 0.61, 0.36, 1) 0.3s forwards; }
@keyframes gp-p-core-open {
  0%   { clip-path: inset(0 49% 0 49%); opacity: 0.35; }
  100% { clip-path: inset(0 0% 0 0%); opacity: 1; }
}
.gp-p-core::before {
  content: ""; position: absolute; inset: 0; mix-blend-mode: screen;
  background: repeating-linear-gradient(90deg, rgba(255, 241, 167, 0.22) 0 1px, transparent 2px 6px);
  animation: gp-p-scan 1s linear infinite;
}
@keyframes gp-p-scan { from { background-position-x: 0; } to { background-position-x: 18px; } }
.gp-p-core::after {
  content: ""; position: absolute; left: 8px; right: 8px; bottom: 16px; height: 26%;
  background:
    radial-gradient(ellipse at center, rgba(255, 241, 150, 0.95), transparent 62%),
    radial-gradient(ellipse at 72% 50%, rgba(255, 125, 70, 0.32), transparent 36%);
  filter: blur(12px);
  animation: gp-p-pulse 1.5s ease-in-out infinite;
}
@keyframes gp-p-pulse { 0%, 100% { opacity: 0.65; transform: scaleX(0.92); } 50% { opacity: 1; transform: scaleX(1.08); } }
.gp-p-spark {
  position: absolute; width: 2px; height: 44px; top: -56px;
  background: linear-gradient(to bottom, transparent, #ffe983, transparent);
  opacity: 0; filter: drop-shadow(0 0 8px rgba(255, 220, 100, 0.9));
  animation: gp-p-spark 1.4s linear infinite;
}
@keyframes gp-p-spark {
  0% { top: -56px; opacity: 0; } 12% { opacity: 1; } 78% { opacity: 0.8; } 100% { top: 102%; opacity: 0; }
}
.gp-p-ground {
  position: absolute; left: 50%; bottom: 9vh; width: min(520px, 80vw); height: 130px;
  border-radius: 50%; transform: translateX(-50%);
  background: radial-gradient(ellipse at center, rgba(255, 218, 100, 0.26), rgba(255, 218, 100, 0.08) 40%, transparent 70%);
  filter: blur(24px); opacity: 0;
}
.gp-open .gp-p-ground { animation: gp-flash-in 0.8s ease 0.3s forwards; }
.gp-p-white {
  position: absolute; inset: 0; opacity: 0; z-index: 5;
  background: radial-gradient(circle at center, rgba(255, 248, 214, 0.98), rgba(255, 224, 118, 0.9) 40%, rgba(60, 48, 12, 0.92));
}
.gp-zoom .gp-p-white { animation: gp-p-white 0.8s ease-in forwards; }
@keyframes gp-p-white { 0% { opacity: 0; } 55% { opacity: 0.22; } 100% { opacity: 1; } }
.gp-p-label {
  position: absolute; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 6;
  font-family: "JetBrains Mono", Overpass, monospace; font-size: 12px; letter-spacing: 5px;
  color: rgba(255, 235, 160, 0.85); text-shadow: 0 0 12px rgba(255, 210, 88, 0.7); white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .gp-suck #root { animation: none; }
  .gp-open .gp-portal { animation: none; opacity: 1; transform: rotateY(-18deg) rotateX(2deg); }
  .gp-open .gp-p-core { animation: none; clip-path: inset(0); opacity: 1; }
}
@keyframes gp-flash-in { from { opacity: 0; } to { opacity: 1; } }

/* ---- keyboard hint chip (desktop) ---------------------------------- */
.gp-hint {
  position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%) translateY(24px);
  z-index: 60; display: none; align-items: center; gap: 10px; opacity: 0;
  font-family: "JetBrains Mono", Overpass, monospace; font-size: 11px; letter-spacing: 3px;
  color: rgba(255, 244, 194, 0.75); background: rgba(10, 14, 8, 0.72);
  border: 1px solid rgba(214, 169, 74, 0.35); border-radius: 999px; padding: 8px 16px;
  backdrop-filter: blur(6px); transition: opacity 0.6s ease, transform 0.6s ease;
}
.gp-hint.gp-show { opacity: 1; transform: translateX(-50%) translateY(0); }
.gp-hint b { color: #00ff9c; font-weight: 700; text-shadow: 0 0 8px rgba(0, 255, 156, 0.6); }
.gp-hint button {
  background: none; border: none; color: rgba(255, 255, 255, 0.62);
  cursor: pointer; font-size: 12px; padding: 0 0 0 4px; line-height: 1;
}
.gp-hint button:hover { color: rgba(255, 255, 255, 0.8); }
@media (min-width: 768px) and (pointer: fine) { .gp-hint { display: flex; } }

/* ---- contrast floor (WCAG 2.2 AA) ----------------------------------
   Measured against the page background (#030305): full-strength gold is
   9.4:1 and green 15.4:1, so the palette itself is fine — only the very
   low-alpha text utilities fell below 4.5:1. Raise those to the measured
   minimum (white 0.46, gold 0.67) rather than recolouring anything, so
   the visual hierarchy is preserved and only unreadable text moves.
   The bundle's stylesheet loads first, so these win on cascade order. */
.text-white\/15 { color: rgba(255, 255, 255, 0.46); }
.text-white\/20 { color: rgba(255, 255, 255, 0.46); }
.text-white\/30 { color: rgba(255, 255, 255, 0.48); }
.text-white\/35 { color: rgba(255, 255, 255, 0.5); }
.text-white\/40 { color: rgba(255, 255, 255, 0.52); }
.text-timeline-gold\/60 { color: rgba(214, 169, 74, 0.7); }
/* The section rail and coordinate labels get their colour from React
   inline styles, which outrank any stylesheet rule — so these are matched
   on the style attribute itself and need !important. Values are the
   measured 4.5:1 minimums, not guesses. */
[style*="color: rgba(255, 255, 255, 0.3)"] { color: rgba(255, 255, 255, 0.48) !important; }
[style*="color: rgba(255, 255, 255, 0.4)"] { color: rgba(255, 255, 255, 0.52) !important; }
.coord-label { color: rgba(214, 169, 74, 0.72) !important; }
/* CRT monitor brand plate: rgb(94,79,54) measured 2.4:1 — scaled to the
   same hue at the 4.5:1 threshold. */
.crt-brand { color: rgb(137, 115, 79) !important; }
/* Phosphor green at 0.5 alpha measures 4.2:1; 0.62 clears the bar. */
.text-phosphor\/50 { color: rgba(0, 255, 156, 0.62); }
[style*="color: rgba(0, 255, 156, 0.5)"] { color: rgba(0, 255, 156, 0.62) !important; }
/* Decorative-only marks keep their faintness: they carry no information
   and are hidden from assistive tech, so the floor does not apply. */
[aria-hidden="true"].text-white\/15,
[aria-hidden="true"].text-white\/20 { color: rgba(255, 255, 255, 0.2); }

/* ---- screen-reader utilities + skip link ---------------------------- */
.gp-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.gp-skip {
  position: fixed; top: 0; left: 50%; transform: translate(-50%, -120%);
  z-index: 200; padding: 10px 22px; border-radius: 0 0 8px 8px;
  font-family: "JetBrains Mono", Overpass, monospace; font-size: 12px; letter-spacing: 2px;
  color: #020503; background: #00ff9c; text-decoration: none; font-weight: 700;
  transition: transform 0.18s ease;
}
.gp-skip:focus { transform: translate(-50%, 0); outline: none; }

/* ---- Citadel (demo CMS) honesty note -------------------------------- */
.gp-citadel-note {
  position: fixed; left: 50%; bottom: 14px; transform: translateX(-50%);
  z-index: 100; max-width: min(92vw, 640px); margin: 0; padding: 10px 16px;
  font-family: "JetBrains Mono", Overpass, monospace; font-size: 11px; line-height: 1.6;
  letter-spacing: 0.5px; text-align: center; color: rgba(255, 244, 194, 0.62);
  background: rgba(10, 14, 8, 0.82); border: 1px solid rgba(214, 169, 74, 0.3);
  border-radius: 8px; backdrop-filter: blur(6px);
}

/* ---- third-party stat widgets: loading + archival fallback ---------- */
.gp-stat-loading {
  min-height: 90px;
  background:
    linear-gradient(90deg, rgba(214, 169, 74, 0.05), rgba(214, 169, 74, 0.12), rgba(214, 169, 74, 0.05));
  background-size: 200% 100%;
  animation: gp-stat-shimmer 1.5s ease-in-out infinite;
  border-radius: 8px;
}
@keyframes gp-stat-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.gp-stat-archive {
  display: flex; flex-direction: column; gap: 6px; align-items: center; justify-content: center;
  min-height: 96px; padding: 18px 22px; text-decoration: none; text-align: center;
  border: 1px dashed rgba(214, 169, 74, 0.45); border-radius: 8px;
  background: rgba(20, 14, 4, 0.35);
  font-family: "JetBrains Mono", Overpass, monospace;
}
.gp-stat-archive b { color: rgba(245, 201, 122, 0.92); font-size: 12px; letter-spacing: 3px; font-weight: 700; }
.gp-stat-archive span { color: rgba(255, 244, 194, 0.5); font-size: 11px; letter-spacing: 1px; }
.gp-stat-archive:hover b { color: #00ff9c; }
.gp-stat-archive:focus-visible { outline: 2px solid #00ff9c; outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .gp-stat-loading { animation: none; }
}

/* ---- focus visibility (keyboard users) ------------------------------ */
.gp-mnav-btn:focus-visible,
.gp-mnav-item:focus-visible,
.gp-mnav-close:focus-visible,
.gp-hint button:focus-visible {
  outline: 2px solid #00ff9c;
  outline-offset: 3px;
}

/* ---- mobile nav ----------------------------------------------------- */
.gp-mnav-btn {
  position: fixed; left: 50%; bottom: 16px; transform: translateX(-50%);
  z-index: 105; display: none; align-items: center; gap: 8px;
  font-family: "JetBrains Mono", Overpass, monospace; font-size: 11px; letter-spacing: 3px;
  color: #f5c97a; background: rgba(20, 14, 4, 0.8); border: 1px solid rgba(214, 169, 74, 0.5);
  border-radius: 999px; padding: 9px 18px; cursor: pointer;
  backdrop-filter: blur(6px); box-shadow: 0 2px 18px rgba(0, 0, 0, 0.5);
}
@media (max-width: 767px) { .gp-mnav-btn { display: flex; } }
.gp-mnav {
  position: fixed; inset: 0; z-index: 108; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px;
  background: rgba(2, 5, 3, 0.93); backdrop-filter: blur(10px);
  animation: gp-flash-in 0.22s ease forwards;
}
.gp-mnav-title {
  font-family: "JetBrains Mono", Overpass, monospace; font-size: 10px; letter-spacing: 5px;
  color: rgba(214, 169, 74, 0.8); margin-bottom: 14px;
}
.gp-mnav-item {
  font-family: "JetBrains Mono", Overpass, monospace; font-size: 17px; letter-spacing: 6px;
  background: none; border: none; border-left: 2px solid transparent; cursor: pointer;
  color: rgba(255, 255, 255, 0.55); padding: 11px 26px; width: min(76vw, 320px); text-align: left;
}
.gp-mnav-item.gp-active {
  color: #00ff9c; text-shadow: 0 0 10px rgba(0, 255, 156, 0.7);
  border-left-color: #00ff9c;
}
.gp-mnav-item .gp-mnav-idx { color: rgba(214, 169, 74, 0.6); font-size: 11px; margin-right: 12px; }
.gp-mnav-close {
  margin-top: 20px; font-family: "JetBrains Mono", Overpass, monospace; font-size: 11px;
  letter-spacing: 3px; color: rgba(255, 255, 255, 0.4); background: none;
  border: 1px solid rgba(255, 255, 255, 0.18); border-radius: 999px; padding: 8px 20px; cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
  .gp-ring { animation-duration: 0.01ms; }
  .gp-loki #root, .gp-loki-flash span { animation: none; }
  /* The portal's decorative loops (scanline, pulse, sparks) were still
     running for reduced-motion users even though the big transforms were
     correctly skipped. Stop everything inside the overlay. */
  .gp-p-core::before, .gp-p-core::after, .gp-p-spark { animation: none; }
  .gp-p-spark { opacity: 0; }
  .gp-p-ground { animation: none; opacity: 1; }
  .gp-p-white { transition: none; }
  .gp-skip { transition: none; }
  .gp-hint { transition: none; }
}
