﻿/* 3dnegar — design tokens
   Ported verbatim from design_handoff_3dnegar/README.md's "Visual system" table
   and cross-checked against every page's own renderVals() theme block (identical
   values computed independently per page in the source — kept as static CSS here
   since there is no cross-page live sync in the source either, only persistence). */

:root {
  --ink: 255,255,255;
  --fg: #f2f3f6;
  --bg-rgb: 18,18,24;
  --accent1: #4f7dfb;
  --accent2: #8b5cf6;
  --accent1-rgb: 79,124,255;
  --accent2-rgb: 139,92,246;
  --accent3-rgb: 56,189,248;
  --accent3: #ff5340;
  --accent-soft: #8fa4ff;
  --accent-tint: #c9c3ff;
  --page-bg: #07070a;
  --heading-weight: 800;
}

:root[data-theme="light"] {
  --ink: 20,20,34;
  --fg: #12121c;
  --bg-rgb: 255,255,255;
  --accent1: #3358e6;
  --accent2: #7c3aed;
  --accent1-rgb: 51,88,230;
  --accent2-rgb: 124,58,237;
  --accent3-rgb: 14,165,233;
  --accent3: #d6301f;
  --accent-soft: #3355dd;
  --accent-tint: #5b3fd6;
  --page-bg: #eef0f7;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: 'Vazirmatn', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  text-wrap: pretty;
  background: var(--page-bg);
  color: var(--fg);
  transition: background .4s, color .4s;
}
::selection { background: rgba(var(--accent2-rgb), 0.35); }

/* NOTE on the fixed side rail (site-rail, right:0): earlier attempts at
   reserving space for it via body padding (first with a logical property
   that resolved to the wrong side on this RTL page, then corrected to the
   physical side) technically stopped the overlap, but padding on only one
   side of body makes margin:auto centering skew the whole content block
   toward the OTHER edge -- trading "touches the rail" for "hugs the left
   edge instead," not actually fixing the complaint (too little margin,
   content reading as too wide/full-bleed). The real fix is on the content
   side: every section's own max-width is now narrow enough (1160px, see
   index.html) that even the widest realistic viewport leaves comfortable,
   SYMMETRIC margin on both true edges before it would ever reach the
   rail's 56-210px zone -- no body padding needed at all. */

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

a { color: var(--accent-tint); text-decoration: none; }
a:hover { color: var(--fg); }

::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: var(--page-bg); }
::-webkit-scrollbar-thumb { background: rgba(var(--ink), 0.15); border-radius: 6px; }

/* Background treatment -- present on every page */
.bg-dotgrid {
  position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden;
  background-image: radial-gradient(rgba(var(--ink), 0.14) 1px, transparent 1px);
  background-size: 28px 28px;
  opacity: 0.35;
}
.bg-vignette {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(ellipse 80% 60% at 50% 0%, rgba(var(--accent1-rgb), 0.10), transparent 65%);
}

/* Scroll progress bar */
.scroll-progress-track {
  position: fixed; top: 0; inset-inline: 0; height: 2.5px; z-index: 51;
  background: rgba(var(--ink), 0.06);
}
.scroll-progress-bar {
  height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--accent1), var(--accent2));
}

/* Keyframes used across pages */
@keyframes fadeUp { from { opacity: 0; transform: translateY(36px); filter: blur(6px); } to { opacity: 1; transform: translateY(0); filter: blur(0); } }
@keyframes fadeUpSmall { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
[data-reveal] { animation: fadeUp .9s cubic-bezier(.16,.8,.24,1) both; animation-timeline: view(); animation-range: entry 0% cover 28%; }
[data-reveal-small] { animation: fadeUpSmall .9s cubic-bezier(.16,.8,.24,1) both; animation-timeline: view(); animation-range: entry 0% cover 30%; }
/* Browsers without scroll-driven animations (Firefox, Safari <17.4) never advance the
   view() timeline, which would otherwise leave every [data-reveal] section stuck at the
   fadeUp "from" state (opacity:0) forever. Force the visible end state instead. */
@supports not (animation-timeline: view()) {
  [data-reveal], [data-reveal-small] { animation: none !important; opacity: 1 !important; transform: none !important; filter: none !important; }
}
@keyframes drift1 { 0%,100% { transform: translate(-6%,-4%) scale(1); } 50% { transform: translate(4%,6%) scale(1.15); } }
@keyframes drift2 { 0%,100% { transform: translate(6%,4%) scale(1.1); } 50% { transform: translate(-4%,-6%) scale(1); } }
@keyframes floatObj { 0%,100% { transform: translateY(0) rotateY(-6deg) rotateX(2deg); } 50% { transform: translateY(-18px) rotateY(6deg) rotateX(-2deg); } }
@keyframes shine { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
@keyframes popIn { from { opacity: 0; transform: scale(.85) translateY(30px); } to { opacity: 1; transform: scale(1) translateY(0); } }
@keyframes typing { from { width: 0; } to { width: 100%; } }
@keyframes blinkCaret { 50% { border-color: transparent; } }
@keyframes fadeInLeft { from { opacity: 0; transform: translateX(-46px); } to { opacity: 1; transform: translateX(0); } }
@keyframes fadeInRight { from { opacity: 0; transform: translateX(46px); } to { opacity: 1; transform: translateX(0); } }
@keyframes dotPulse { 0%,100% { box-shadow: 0 0 0 0 rgba(var(--accent1-rgb), 0.5); } 50% { box-shadow: 0 0 0 6px rgba(var(--accent1-rgb), 0); } }


h1, h2, h3, h4, h5, h6 { line-height: 1.5 !important; letter-spacing: 0 !important; font-family: 'Archivo', 'Vazirmatn', sans-serif !important; }
