/**
 * base.css
 * ─────────────────────────────────────────────────────────────────
 * PRD Section 2: Design Language — Foundation Styles
 *
 * Contents:
 *   1. @font-face — self-hosted, font-display: swap (PRD 2.1)
 *   2. Modern CSS Reset
 *   3. Base Document Styles
 *   4. Typography Defaults
 *   5. Film Grain Overlay (PRD 2.4)
 *   6. Scanline Effect
 *   7. Skip-to-content (PRD 4.8, 6.1)
 *   8. Custom Cursor Shell (PRD 2.5)
 *   9. Scrollbar
 *  10. Selection
 *  11. Focus Ring (PRD 4.5)
 *  12. Reduced Motion
 *
 * ✅ No Bootstrap layout — Bootstrap utilities only
 * ✅ All font sizes use clamp() from variables.css
 */

/* ═══════════════════════════════════════════════
   1. @FONT-FACE — Self-hosted (PRD 2.1)
   No Google Fonts CDN. Files live in /assets/fonts/
   ═══════════════════════════════════════════════ */

/* Space Grotesk — Display / Hero / Section Titles */
@font-face {
  font-family: "Space Grotesk";
  src: url("/assets/fonts/SpaceGrotesk-Bold.woff2") format("woff2"),
       url("/assets/fonts/SpaceGrotesk-Bold.woff")  format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;     /* PRD 2.1: prevent invisible text flash */
}

@font-face {
  font-family: "Space Grotesk";
  src: url("/assets/fonts/SpaceGrotesk-Medium.woff2") format("woff2"),
       url("/assets/fonts/SpaceGrotesk-Medium.woff")  format("woff");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Space Grotesk";
  src: url("/assets/fonts/SpaceGrotesk-Regular.woff2") format("woff2"),
       url("/assets/fonts/SpaceGrotesk-Regular.woff")  format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* JetBrains Mono — Code / Terminal / Metadata / Data */
@font-face {
  font-family: "JetBrains Mono";
  src: url("/assets/fonts/JetBrainsMono-Regular.woff2") format("woff2"),
       url("/assets/fonts/JetBrainsMono-Regular.woff")  format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  font-feature-settings: "liga" 1, "calt" 1;  /* ligatures: -> !== === */
}

@font-face {
  font-family: "JetBrains Mono";
  src: url("/assets/fonts/JetBrainsMono-Medium.woff2") format("woff2"),
       url("/assets/fonts/JetBrainsMono-Medium.woff")  format("woff");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
  font-feature-settings: "liga" 1, "calt" 1;
}

/* DM Sans — Body text / Descriptions */
@font-face {
  font-family: "DM Sans";
  src: url("/assets/fonts/DMSans-Regular.woff2") format("woff2"),
       url("/assets/fonts/DMSans-Regular.woff")  format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "DM Sans";
  src: url("/assets/fonts/DMSans-Medium.woff2") format("woff2"),
       url("/assets/fonts/DMSans-Medium.woff")  format("woff");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}


/* ═══════════════════════════════════════════════
   2. MODERN CSS RESET
   Based on: Andy Bell / Josh Comeau methodology
   Opinionated — keeps box-sizing, removes defaults
   ═══════════════════════════════════════════════ */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* Remove default list styles only when inside [role="list"] */
ul[role="list"],
ol[role="list"] {
  list-style: none;
}

/* Set core root defaults */
html {
  scroll-behavior: smooth;           /* overridden by Lenis smooth scroll JS */
  text-size-adjust: 100%;            /* prevent iOS font-size inflation */
  -webkit-text-size-adjust: 100%;
  hanging-punctuation: first last;   /* better quotation mark placement */
}

/* Set core body defaults */
body {
  min-height: 100dvh;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Images default */
img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

/* Form elements inherit fonts */
input,
button,
textarea,
select {
  font: inherit;
}

/* Remove text decoration for links — controlled per-component */
a {
  text-decoration: none;
  color: inherit;
}

/* Avoid overflow from long words */
p,
h1, h2, h3, h4, h5, h6 {
  overflow-wrap: break-word;
}

/* Remove default button styles — always reset */
button {
  background: none;
  border: none;
  cursor: pointer;
  color: inherit;
}

/* Horizontal rule */
hr {
  border: none;
  border-top: 1px solid var(--text-tertiary);
  opacity: 0.4;
}

/* Tables */
table {
  border-collapse: collapse;
  border-spacing: 0;
}

/* ═══════════════════════════════════════════════
   3. BASE DOCUMENT STYLES
   ═══════════════════════════════════════════════ */

html {
  font-size: 16px;
  /* Theme applied via [data-theme] attribute set before paint by inline <head> script */
  /* Must match body bg — fills notch/Dynamic Island zone on iOS (viewport-fit=cover) */
  background-color: var(--bg-base);
}

body {
  background-color: var(--bg-base);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--text-body);
  position: relative;
  overflow-x: hidden;
}

/* Contain scrollbar width in layout calculations */
@supports (scrollbar-gutter: stable) {
  html {
    scrollbar-gutter: stable;
  }
}

/* ═══════════════════════════════════════════════
   4. TYPOGRAPHY DEFAULTS (PRD 2.1)
   ═══════════════════════════════════════════════ */

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: var(--tracking-tight);
  color: var(--text-primary);
  font-feature-settings: var(--font-features-display);
}

h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); }
h3 { font-size: var(--text-h3); }

/* Display — hero title scale (PRD: "must dominate the screen") */
.text-display {
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: 700;
  line-height: 0.95;                   /* tight for large display type */
  letter-spacing: var(--tracking-tight);
  font-feature-settings: var(--font-features-display);
}

.text-display-sm {
  font-family: var(--font-display);
  font-size: var(--text-display-sm);
  font-weight: 700;
  line-height: 1.0;
  letter-spacing: var(--tracking-tight);
  font-feature-settings: var(--font-features-display);
}

p {
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: 1.7;
  color: var(--text-secondary);
  max-width: 68ch;                     /* optimal reading line length */
}

/* Monospace — code, terminal, data values (PRD 2.1) */
code,
kbd,
samp,
pre,
.mono {
  font-family: var(--font-mono);
  font-feature-settings: var(--font-features-mono);
}

code {
  font-size: 0.875em;
  color: var(--accent);
  background: var(--accent-glow-bg, rgba(0, 212, 255, 0.08));
  padding: 0.15em 0.4em;
  border-radius: var(--radius-sm);
}

/* Metadata text — "11px beside 120px title" (PRD Section 0) */
.text-meta {
  font-family: var(--font-mono);
  font-size: var(--text-meta);
  color: var(--text-tertiary);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

/* Section code-comment headers (PRD 6.1: /* AI/ML */ */
.section-comment {
  font-family: var(--font-mono);
  font-size: var(--text-small);
  color: var(--text-tertiary);
  letter-spacing: var(--tracking-wide);
  opacity: 0.7;
}

.section-comment::before { content: "/* "; }
.section-comment::after  { content: " */"; }

/* Accent label — uppercase monospace labels (PRD 2.1) */
.label {
  font-family: var(--font-display);
  font-size: var(--text-label);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  color: var(--text-secondary);
}

/* Strong / Em defaults */
strong, b {
  font-weight: 700;
  color: var(--text-primary);
}

em, i {
  font-style: italic;
}

/* ═══════════════════════════════════════════════
   5. FILM GRAIN OVERLAY (PRD 2.4)
   Fixed on body::after — always on top.
   SVG feTurbulence generates the stochastic noise.
   mix-blend-mode: overlay applies it non-destructively.
   ═══════════════════════════════════════════════ */

body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: var(--z-grain);
  opacity: var(--grain-opacity);
  mix-blend-mode: overlay;

  /* SVG feTurbulence grain — no external file, no bandwidth cost */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='grain'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23grain)'/%3E%3C/svg%3E");

  /* Tile the 300×300 grain across the full viewport */
  background-repeat: repeat;
  background-size: 300px 300px;

  /* Subtle animation — barely perceptible grain "breathing" */
  animation: grain-shift 8s steps(2) infinite;
}

@keyframes grain-shift {
  0%   { background-position: 0 0; }
  25%  { background-position: -60px 40px; }
  50%  { background-position: 50px -30px; }
  75%  { background-position: -40px -50px; }
  100% { background-position: 0 0; }
}

/* Freeze grain for reduced-motion users */
@media (prefers-reduced-motion: reduce) {
  body::after {
    animation: none;
  }
}

/* ═══════════════════════════════════════════════
   6. SCANLINE EFFECT
   Applied via <div class="scanlines"> in HTML.
   Subtle CRT aesthetic — reinforces technical identity.
   ═══════════════════════════════════════════════ */

.scanlines {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: calc(var(--z-grain) - 1);   /* just below grain */
  background: repeating-linear-gradient(
    to bottom,
    transparent 0px,
    transparent 3px,
    rgba(0, 0, 0, 0.015) 3px,
    rgba(0, 0, 0, 0.015) 4px
  );
  opacity: 0;
  transition: opacity var(--dur-normal) var(--ease-out-expo);
}

/* Scanlines visible only in dark themes */
[data-theme="dark-cyber"] .scanlines,
[data-theme="terminal-green"] .scanlines,
[data-theme="midnight-purple"] .scanlines {
  opacity: 1;
}

/* ═══════════════════════════════════════════════
   7. SKIP-TO-CONTENT (PRD 4.8, 6.1)
   First focusable element in <body>.
   Visually hidden until focused via keyboard.
   ═══════════════════════════════════════════════ */

.skip-link {
  position: absolute;
  top: var(--sp-4);
  left: var(--sp-4);
  z-index: calc(var(--z-nav) + 10);

  /* Visually hidden by default */
  transform: translateY(-200%);
  opacity: 0;

  /* Styled for fast recognition when revealed */
  font-family: var(--font-mono);
  font-size: var(--text-small);
  font-weight: 500;
  color: var(--bg-base);
  background: var(--accent);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--radius-md);
  white-space: nowrap;

  transition:
    transform var(--dur-fast)  var(--ease-out-expo),
    opacity   var(--dur-fast)  var(--ease-out-expo);
}

.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  opacity: 1;
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* ───────────────────────────────────────────────
   ACCESSIBILITY UTILITY — Visually Hidden
   Hides element visually while keeping it accessible
   to screen readers and aria-labelledby references.
   ─────────────────────────────────────────────── */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ═══════════════════════════════════════════════
   8. CUSTOM CURSOR SHELL (PRD 2.5)
   The cursor DOM elements are created by cursor.js.
   CSS handles the visual definition.
   JS tracks mouse position and sets data-cursor on body.
   ═══════════════════════════════════════════════ */

/* Hide custom cursor on touch devices (CSS safety net) */
@media (pointer: coarse) {
  .cursor-dot,
  .cursor-ring,
  .cursor-ghost {
    display: none !important;
  }
}

/* Hide custom cursor on narrow screens (definitely touch/mobile) */
@media (max-width: 1023px) {
  .cursor-dot,
  .cursor-ring,
  .cursor-ghost {
    display: none !important;
  }
}

/* Hide system cursor on non-touch desktop when cursor.js is active */
@media (pointer: fine) {
  body.cursor-active,
  body.cursor-active * {
    cursor: none !important;
  }
}

/* Cursor dot — 8px filled circle */
.cursor-dot {
  position: fixed;
  top: 0; left: 0;
  width: 8px;
  height: 8px;
  background: var(--accent);
  border-radius: 50%;
  pointer-events: none;
  z-index: var(--z-cursor);
  transform: translate(-50%, -50%);
  will-change: transform;
  transition:
    width     var(--dur-fast) var(--ease-out-expo),
    height    var(--dur-fast) var(--ease-out-expo),
    opacity   var(--dur-fast) var(--ease-out-expo),
    background var(--dur-fast) var(--ease-out-expo);
}

/* Cursor ring — 40px dashed ring (lags 100ms behind via JS) */
.cursor-ring {
  position: fixed;
  top: 0; left: 0;
  width: 40px;
  height: 40px;
  border: 1px solid var(--accent);
  border-radius: 50%;
  pointer-events: none;
  z-index: calc(var(--z-cursor) - 1);
  transform: translate(-50%, -50%);
  will-change: transform;
  opacity: 0.6;
  transition:
    width      var(--dur-normal) var(--ease-out-expo),
    height     var(--dur-normal) var(--ease-out-expo),
    border-color var(--dur-normal) var(--ease-out-expo),
    opacity    var(--dur-normal) var(--ease-out-expo);
}

/* Cursor label — shown inside ring on hover states */
.cursor-label {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: var(--font-mono);
  font-size: 8px;
  font-weight: 500;
  color: var(--accent);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out-expo);
}

/* State: hovering a link */
body[data-cursor="link"] .cursor-ring {
  width: 64px;
  height: 64px;
  opacity: 1;
}

body[data-cursor="link"] .cursor-label {
  opacity: 1;
}

/* State: hovering a project card */
body[data-cursor="project"] .cursor-ring {
  width: 80px;
  height: 80px;
  opacity: 1;
  border-style: solid;
}

/* State: terminal overlay */
body[data-cursor="terminal"] .cursor-dot {
  width: 2px;
  height: 1.2em;
  border-radius: 0;
  background: var(--accent);
  animation: cursor-blink 1s step-end infinite;
}

body[data-cursor="terminal"] .cursor-ring {
  opacity: 0;
}

@keyframes cursor-blink {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0; }
}

/* ═══════════════════════════════════════════════
   9. SCROLLBAR (Webkit + Firefox)
   ═══════════════════════════════════════════════ */

/* Firefox */
html {
  scrollbar-width: thin;
  scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
}

/* Webkit */
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

::-webkit-scrollbar-track {
  background: var(--scrollbar-track);
}

::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
  border-radius: var(--radius-pill);
  transition: background var(--dur-fast) var(--ease-out-expo);
}

::-webkit-scrollbar-thumb:hover {
  background: var(--scrollbar-hover);
}

/* ═══════════════════════════════════════════════
   10. TEXT SELECTION
   ═══════════════════════════════════════════════ */

::selection {
  background-color: var(--selection-bg);
  color: var(--selection-text);
  text-shadow: none;
}

::-moz-selection {
  background-color: var(--selection-bg);
  color: var(--selection-text);
  text-shadow: none;
}

/* ═══════════════════════════════════════════════
   11. FOCUS RING (PRD 4.5)
   2px solid accent, 3px offset.
   Applied globally — never remove, only restyle.
   ═══════════════════════════════════════════════ */

/* Remove browser default for mouse users, keep for keyboard */
:focus:not(:focus-visible) {
  outline: none;
}

:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--radius-sm);
}

/* ═══════════════════════════════════════════════
   12. REDUCED MOTION (PRD 4.8, 5.3)
   Disable ALL non-essential motion.
   JS reads matchMedia and disables GSAP / Three.js.
   ═══════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }

  /* Freeze grain */
  body::after {
    animation: none;
  }

  /* Hide scanlines entirely (raster lines are motion-adjacent) */
  .scanlines {
    display: none;
  }

  /* Hide custom cursor (replaced by system cursor) */
  .cursor-dot,
  .cursor-ring {
    display: none;
  }
}

/* ═══════════════════════════════════════════════
   13. TOUCH RIPPLE + PARTICLE (cursor.js touch feedback)
   Modern touch interaction: ripple ring + scatter particles
   Uses --accent colour from active theme.
   ═══════════════════════════════════════════════ */

.touch-ripple {
  position: fixed;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1.5px solid var(--accent, #00c8ff);
  pointer-events: none;
  z-index: var(--z-cursor, 9999);
  transform: translate(-50%, -50%) scale(1);
  opacity: 0.7;
  transition: none;
}

.touch-ripple--active {
  transform: translate(-50%, -50%) scale(6);
  opacity: 0;
  transition:
    transform 0.55s cubic-bezier(0.16, 1, 0.3, 1),
    opacity   0.55s cubic-bezier(0.16, 1, 0.3, 1);
}

.touch-particle {
  position: fixed;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent, #00c8ff);
  pointer-events: none;
  z-index: var(--z-cursor, 9999);
  transform: translate(-50%, -50%) translate(0, 0) scale(1);
  opacity: 0.8;
  transition: none;
}

.touch-particle--active {
  transform: translate(-50%, -50%) translate(var(--tx, 0), var(--ty, 0)) scale(0);
  opacity: 0;
  transition:
    transform 0.45s cubic-bezier(0.16, 1, 0.3, 1),
    opacity   0.45s cubic-bezier(0.16, 1, 0.3, 1);
}

/* ═══════════════════════════════════════════════
   14. PRINT (PRD 5.9)
   Hide non-essential UI. Clean single-column output.
   Full stylesheet in print.css — this is the emergency
   fallback for elements not covered there.
   ═══════════════════════════════════════════════ */

@media print {
  .scanlines,
  .cursor-dot,
  .cursor-ring,
  body::after {
    display: none !important;
  }
}
