/* ── Outfit, self-hosted ──
   Variable font: one file covers 300-900, so the weight range is a span,
   not six separate @font-face blocks. Served from our own origin, so no
   request reaches Google and no visitor IP leaves the site. */
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('/assets/fonts/outfit-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Outfit';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('/assets/fonts/outfit-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ============================================================
   base.css — chrome shared by every top-level page.
   Loaded first; each page's own stylesheet loads after and
   overrides what it needs (the home page restyles the brand,
   the footer icons and the body layout).
   ============================================================ */

/* ── Reset ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── Page ── */
body {
  min-height: 100vh;
  font-family: 'Outfit', sans-serif;
  background: #0a0a0c;
  color: #fff;
  overflow-x: hidden;
}

/* ── Animated background orbs ── */
.bg-orbs {
  position: fixed;
  inset: 0;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
}

.orb-1, .orb-2, .orb-3 {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: .6;
}

.orb-1 { width: 45vw; height: 45vw; background: #79bc68; top: -10%; left: -10%; animation: drift-1 25s infinite alternate ease-in-out; }
.orb-2 { width: 55vw; height: 55vw; background: #9a42f1; bottom: -20%; right: -10%; animation: drift-2 30s infinite alternate ease-in-out; }
.orb-3 { width: 30vw; height: 30vw; background: #3b82f6; top: 40%; left: 40%; animation: drift-3 35s infinite alternate ease-in-out; }

@keyframes drift-1 {
  0%   { transform: translate(0, 0) scale(1); }
  33%  { transform: translate(35vw, 25vh) scale(1.2); }
  66%  { transform: translate(15vw, 60vh) scale(.9); }
  100% { transform: translate(60vw, 10vh) scale(1.1); }
}

@keyframes drift-2 {
  0%   { transform: translate(0, 0) scale(1); }
  33%  { transform: translate(-30vw, -40vh) scale(1.3); }
  66%  { transform: translate(-50vw, 10vh) scale(.8); }
  100% { transform: translate(-20vw, -50vh) scale(1.2); }
}

@keyframes drift-3 {
  0%   { transform: translate(0, 0) scale(1); }
  33%  { transform: translate(-40vw, -30vh) scale(1.1); }
  66%  { transform: translate(30vw, -20vh) scale(1.4); }
  100% { transform: translate(-20vw, -10vh) scale(.9); }
}

/* ── Noise overlay ── */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
  opacity: .04;
  pointer-events: none;
  z-index: 2;
}

/* ── Brand (home page enlarges this in home.css) ── */
.brand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  font-size: clamp(16px, 2vw, 20px);
  font-weight: 700;
  letter-spacing: 3px;
  text-transform: uppercase;
  background: linear-gradient(135deg, #fff, #a0a0b0);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.logo-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #79bc68;
  box-shadow: 0 0 12px #79bc68;
  animation: pulse-dot 3s infinite ease-in-out;
  flex-shrink: 0;
}

@keyframes pulse-dot {
  0%, 100% { opacity: .5; box-shadow: 0 0 6px #79bc68; }
  50%      { opacity: 1;  box-shadow: 0 0 16px #79bc68; }
}

/* ── Back link ── */
.back-link:hover { color: #fff; }

/* ── Social footer ──
   One minimal row: bare icons, soft divider, generous breathing room.
   Pages needing a wider measure just set --footer-max. */
.social-footer {
  position: relative;
  z-index: 5;
  width: 100%;
  max-width: var(--footer-max, 900px);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 26px 24px;
  border-top: 1px solid rgba(255,255,255,.06);
}

/* Negative margin pulls the first icon flush with the page edge,
   cancelling its own tap-target padding. */
.footer-icons  { display: flex; align-items: center; gap: 4px; margin-left: -10px; }
.footer-right  { display: flex; align-items: center; gap: 14px; }
.footer-credit { font-size: 12px; color: rgba(255,255,255,.25); font-weight: 300; letter-spacing: .3px; }

.social-footer a {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;              /* keeps a 40px tap target without a visible box */
  color: rgba(255,255,255,.4);
  font-size: 19px;
  text-decoration: none;
  transition: color .3s ease, transform .3s ease;
}

.social-footer a:hover { color: #79bc68; transform: translateY(-2px); }

/* ── Language toggle ── */
.lang-toggle {
  position: static;
  background: transparent;
  border: 1px solid rgba(255,255,255,.14);
  color: rgba(255,255,255,.5);
  font-family: 'Outfit', sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1.4px;
  padding: 7px 16px;
  border-radius: 999px;
  cursor: pointer;
  transition: border-color .3s ease, color .3s ease;
}

.lang-toggle:hover { border-color: #79bc68; color: #79bc68; }

@media (max-width: 900px) {
  .lang-toggle { padding: 6px 14px; font-size: 11px; letter-spacing: 1px; }
}

/* ── Cursor-tracking glow on cards (JS sets --mouse-x / --mouse-y) ── */
.nav-card, .project-card, .post-card, .form-card, .bio-card, .skills-card, .interests-card {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.nav-card::before, .project-card::before, .post-card::before, .form-card::before,
.bio-card::before, .skills-card::before, .interests-card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(600px circle at var(--mouse-x, 0) var(--mouse-y, 0), rgba(255,255,255,.06), transparent 40%);
  z-index: -1;
  opacity: 0;
  transition: opacity .5s;
  pointer-events: none;
}

.nav-card:hover::before, .project-card:hover::before, .post-card:hover::before, .form-card:hover::before,
.bio-card:hover::before, .skills-card:hover::before, .interests-card:hover::before { opacity: 1; }

/* ── Scroll reveal ────────────────────────────────────────────
   Elements marked data-reveal start offset and fade into place
   as they scroll into view (base.js adds .is-visible). The
   hiding is scoped to html[data-js], which base.js sets, so
   without JavaScript the content simply renders normally.     */

html[data-js] [data-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .34s cubic-bezier(.16,.84,.44,1),
              transform .34s cubic-bezier(.16,.84,.44,1);
  transition-delay: var(--reveal-delay, 0s);
}

html[data-js] [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* ── Keyboard focus ── */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid #79bc68;
  outline-offset: 3px;
  border-radius: 4px;
}

/* ── Reduced motion ──────────────────────────────────────────
   Honours the OS "reduce motion" setting for the interface.
   The background orbs are deliberately left running.          */

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

  html[data-js] [data-reveal] { opacity: 1; transform: none; }
}

/* Inline SVG icons (assets/icons.svg sprite) — sized by the parent font-size. */
.icon { width:1em; height:1em; vertical-align:-.125em; flex:none }
