/* ==========================================================================
   DAVIS BALLARD — GREEN PHOSPHOR v3
   The portfolio is a live terminal session. Black tube, green phosphor,
   one font (Perfect DOS VGA 437). Every section = a command + its output.
   ========================================================================== */

/* ---------- Font ---------- */
@font-face {
  font-family: 'DOS VGA';
  src: url('../fonts/Perfect-DOS-VGA-437.ttf') format('truetype');
  font-weight: 400;
  font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
  --bg: #030704;                  /* near-black, green-biased */
  --ph: #36f573;                  /* primary phosphor */
  --ph-bright: #a8ffc2;           /* highlights / glow cores */
  --ph-dim: #1c7a42;              /* secondary text */
  --ph-faint: rgba(54, 245, 115, 0.16);   /* rules, borders */
  --amber: #ffb000;
  --red: #ff4136;
  --dos: 'DOS VGA', 'Courier New', monospace;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; background: var(--bg); }
body {
  background: var(--bg);
  color: var(--ph);
  font-family: var(--dos);
  font-size: clamp(15px, 1.15vw, 19px);
  line-height: 1.6;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
pre { font-family: var(--dos); }
::selection { background: var(--ph); color: var(--bg); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---------- Voice ---------- */
.dim { color: var(--ph-dim); }
.amber { color: var(--amber); text-shadow: 0 0 8px rgba(255, 176, 0, 0.45); }
.ps1 { color: var(--ph-dim); }

/* Phosphor glow */
.glow-dos {
  text-shadow:
    0 0 1px rgba(200, 255, 215, 0.9),
    0 0 10px rgba(54, 245, 115, 0.45),
    0 0 26px rgba(54, 245, 115, 0.25);
}
.glow-strong {
  color: var(--ph-bright);
  text-shadow:
    0.5px 0 0 rgba(255, 60, 60, 0.25),
    -0.5px 0 0 rgba(60, 180, 255, 0.25),
    0 0 1px rgba(220, 255, 230, 0.95),
    0 0 14px rgba(54, 245, 115, 0.55),
    0 0 42px rgba(54, 245, 115, 0.3);
}

/* "Alive" phosphor breathing */
.alive { animation: breathe 7s linear infinite; }
.alive[data-pace="2"] { animation-duration: 9.5s; animation-delay: -3.2s; }
@keyframes breathe {
  0%, 100% { opacity: 1; }
  6%  { opacity: 0.98; }
  7%  { opacity: 0.93; }
  8%  { opacity: 0.99; }
  41% { opacity: 0.96; }
  58% { opacity: 1; }
  83% { opacity: 0.97; }
}
.blink { animation: blink 1s steps(1) infinite; }
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }

/* hover glitch: one short RGB-split jitter on link hover */
@keyframes hoverglitch {
  0%   { transform: translate(0, 0);
         text-shadow: 2px 0 rgba(255, 60, 60, 0.75), -2px 0 rgba(60, 180, 255, 0.75); }
  40%  { transform: translate(1px, -1px);
         text-shadow: -2px 0 rgba(255, 60, 60, 0.75), 2px 0 rgba(60, 180, 255, 0.75); }
  100% { transform: translate(0, 0); text-shadow: none; }
}
.topbar-nav a:hover, .statusbar a:hover,
.bin a:hover .bin-name, .cmd-links a:hover {
  animation: hoverglitch 0.28s steps(3) 1;
}

/* ==========================================================================
   FX — grain / scanlines / vignette / roll (validated recipes, retinted)
   ========================================================================== */
.fx-grain {
  position: fixed;
  inset: -50%;
  z-index: 9000;
  pointer-events: none;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256"><filter id="n"><feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="2" stitchTiles="stitch"/><feColorMatrix type="saturate" values="0"/></filter><rect width="100%25" height="100%25" filter="url(%23n)"/></svg>');
  background-size: 256px 256px;
  opacity: 0.13;
  animation: grain 0.8s steps(8) infinite;
  will-change: transform;
}
@keyframes grain {
  0%    { transform: translate3d(0, 0, 0); }
  12.5% { transform: translate3d(-6%, 4%, 0); }
  25%   { transform: translate3d(4%, -7%, 0); }
  37.5% { transform: translate3d(-3%, -5%, 0); }
  50%   { transform: translate3d(7%, 3%, 0); }
  62.5% { transform: translate3d(-5%, 7%, 0); }
  75%   { transform: translate3d(3%, -3%, 0); }
  87.5% { transform: translate3d(-7%, -6%, 0); }
  100%  { transform: translate3d(0, 0, 0); }
}
/* full-bleed scanlines + a soft edge vignette (no rounded bezel) */
.fx-crt {
  position: fixed;
  inset: 0;
  z-index: 8000;
  pointer-events: none;
  background:
    radial-gradient(ellipse 130% 110% at 50% 50%,
      transparent 70%, rgba(0, 6, 3, 0.16) 92%, rgba(0, 6, 3, 0.3) 100%),
    repeating-linear-gradient(to bottom,
      rgba(0, 0, 0, 0.09) 0px, rgba(0, 0, 0, 0.09) 1px,
      transparent 1px, transparent 3px);
}
.fx-roll {
  position: fixed;
  left: 0; right: 0; top: 0;
  height: 16vh;
  z-index: 8500;
  pointer-events: none;
  background: linear-gradient(to bottom,
    transparent,
    rgba(168, 255, 194, 0.045) 42%,
    rgba(0, 10, 4, 0.07) 58%,
    transparent);
  animation: roll 8s linear infinite;
  will-change: transform;
}
@keyframes roll {
  0%   { transform: translateY(-30vh); }
  100% { transform: translateY(115vh); }
}

/* ==========================================================================
   LOGIN BOOT
   ========================================================================== */
#boot { display: none; }
html.js #boot {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: var(--bg);
  padding: clamp(28px, 6vw, 90px);
  font-family: var(--dos);
  color: var(--ph);
  font-size: clamp(14px, 1.5vw, 21px);
  line-height: 1.7;
  text-shadow: 0 0 8px rgba(54, 245, 115, 0.4);
  transition: opacity 0.55s ease, visibility 0s linear 0.55s;
}
body.is-loaded #boot { opacity: 0; visibility: hidden; }
.boot-frame { width: 100%; }
.boot-lines { white-space: pre-wrap; min-height: 10em; }
.boot-progress { display: block; margin-top: 0.4em; letter-spacing: 1px; }
#boot-pct { margin-left: 1em; }
.boot-cursor { animation: blink 1s steps(1) infinite; }

/* entrance gating */
html.js .reveal {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
html.js body.is-loaded .reveal { opacity: 1; transform: none; }
html.js body:not(.is-loaded) .alive { animation-play-state: paused; }
html.js body.is-loaded .topbar      { transition-delay: 0.05s; }
html.js body.is-loaded .hero .prompt { transition-delay: 0.1s; }
html.js body.is-loaded .hero-head   { transition-delay: 0.2s; }
html.js body.is-loaded .badgebox    { transition-delay: 0.4s; }
html.js body.is-loaded .binbox      { transition-delay: 0.55s; }

/* ==========================================================================
   TERMINAL CHROME
   ========================================================================== */
.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px clamp(16px, 3vw, 44px);
  background: rgba(3, 7, 4, 0.88);
  border-bottom: 1px solid var(--ph-faint);
  font-size: clamp(12px, 0.95vw, 15px);
  letter-spacing: 1px;
}
/* faint bowed glass line under the chrome */
.topbar::after {
  content: '';
  position: absolute;
  left: -6vw; right: -6vw;
  top: 100%;
  height: 12px;
  border-top: 1px solid rgba(54, 245, 115, 0.12);
  border-radius: 50% 50% 0 0 / 12px 12px 0 0;
  pointer-events: none;
}
.topbar-title { color: var(--ph-dim); }
.topbar-nav { display: flex; gap: clamp(8px, 1.6vw, 22px); }
.topbar-nav a { padding: 3px 6px; color: var(--ph); }
.topbar-nav a:hover, .topbar-nav a:focus-visible {
  background: var(--ph);
  color: var(--bg);
  text-shadow: none;
}

.statusbar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 7px clamp(16px, 3vw, 44px);
  background: rgba(3, 7, 4, 0.92);
  border-top: 1px solid var(--ph-faint);
  color: var(--ph-dim);
  font-size: clamp(11px, 0.85vw, 13px);
  letter-spacing: 1px;
  text-transform: lowercase;
}
.statusbar a { color: var(--ph); }
.statusbar a:hover, .statusbar a:focus-visible { background: var(--ph); color: var(--bg); }

/* ==========================================================================
   SESSION LAYOUT
   ========================================================================== */
.session {
  max-width: 1560px;
  margin: 0 auto;
  padding: clamp(70px, 9vh, 110px) clamp(18px, 3.5vw, 56px) 90px;
}
.block { margin-bottom: clamp(56px, 8vh, 110px); }
.prompt {
  margin-bottom: clamp(14px, 1.8vh, 24px);
  color: var(--ph-bright);
  text-shadow: 0 0 8px rgba(54, 245, 115, 0.35);
}
.out { margin-left: clamp(0px, 1.5vw, 22px); }

/* scroll-triggered reveal — the page's scroll "motion": each section
   slides up + fades + sharpens into focus as it enters the viewport */
html.js .block:not(.hero) {
  opacity: 0;
  transform: translateY(46px);
  filter: blur(3px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1), filter 0.7s ease;
}
html.js .block.on { opacity: 1; transform: none; filter: none; }

/* ==========================================================================
   HERO — whoami
   ========================================================================== */
.hero {
  min-height: calc(100svh - 120px);
  container-type: inline-size;
}
/* BALLARD row is 82 chars x ~0.5625em advance = ~46em wide:
   size the banner to the hero so it can never clip */
.banner {
  font-size: clamp(6px, 1.5vw, 30px);   /* fallback */
  font-size: clamp(6px, 2.05cqw, 30px);
  line-height: 1.05;
  white-space: pre;
  overflow: hidden;
}
.banner--2 { margin-top: 0.4em; }
.scroll-hint {
  margin-top: clamp(18px, 3vh, 36px);
  letter-spacing: 3px;
  font-size: clamp(11px, 0.9vw, 14px);
}

/* ---------- badge + bin row ---------- */
.hero-lower {
  display: grid;
  grid-template-columns: 1fr 1fr;     /* 50 / 50 */
  gap: clamp(28px, 4vw, 80px);
  align-items: start;
  margin-top: clamp(26px, 4vh, 52px);
}
.hero-lower > * { min-width: 0; }
/* the card sizes ITSELF to its column via container units —
   the 50/50 split holds at every viewport width */
.badgebox { container-type: inline-size; }
.badge-card {
  display: flex;
  gap: 40px;                    /* breathing room to the right of the portrait */
  align-items: flex-start;
  width: 100%;
  border: 1px solid var(--ph-faint);
  background: rgba(54, 245, 115, 0.035);
  padding: clamp(16px, 2.4cqw, 26px) clamp(16px, 2.4cqw, 26px) clamp(16px, 2.4cqw, 26px) 40px;
}
.badge-info { flex: 1 1 auto; }   /* stats stretch across the rest of the card */
.badge-face {
  font-size: clamp(6px, 1.7cqw, 15px);
  line-height: 1.05;
  align-self: center;
  color: var(--ph);
  text-shadow: 0 0 6px rgba(54, 245, 115, 0.35);
  white-space: pre;
  user-select: none;
}
.badge-info { font-size: clamp(10px, 2.25cqw, 18px); min-width: 0; }
.badge-row { white-space: nowrap; font-size: 1em; }
.badge-row .dim { display: inline-block; min-width: 10ch; }
.badge-info .stats { margin-top: clamp(14px, 1.6vh, 22px); }
.badge-info .stat-label, .badge-info .stat-val { font-size: 1em; }
.badge-info .stat { gap: 1em; }

/* ---------- stats ---------- */
.stats-head {
  display: flex;
  justify-content: space-between;
  color: var(--ph-dim);
  letter-spacing: 3px;
  font-size: 0.8em;
  border-bottom: 1px solid var(--ph-faint);
  padding-bottom: 6px;
  margin-bottom: 14px;
}
.stat {
  display: flex;
  align-items: center;
  gap: 1.2em;
}
.stat + .stat { margin-top: 11px; }
.stat-label { flex: 0 0 auto; min-width: 9.5ch; }
/* flexible segmented LED meter — fills the full card width */
.meter {
  --n: 20;
  position: relative;
  flex: 1 1 auto;
  height: 1.1em;
  background: rgba(54, 245, 115, 0.16);
}
.meter-fill {
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: var(--pct);
  background: var(--ph);
  box-shadow: 0 0 7px rgba(54, 245, 115, 0.5);
  transition: width 1s steps(12, end);
}
/* the gap strips, painted in the card colour over both track and fill,
   slice the bar into evenly aligned cells regardless of width */
.meter::after {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(90deg,
    transparent 0 calc(100% / var(--n) - 2px),
    var(--bg) calc(100% / var(--n) - 2px) calc(100% / var(--n)));
}
.stat-val { flex: 0 0 auto; min-width: 3.5ch; text-align: right; color: var(--ph-bright); }
.stat-note { margin-top: 12px; font-size: 0.85em; }

/* meters fill on hero reveal, staggered */
html.js body:not(.is-loaded) .meter-fill { width: 0; }
html.js body.is-loaded .stat:nth-child(2) .meter-fill { transition-delay: 0.55s; }
html.js body.is-loaded .stat:nth-child(3) .meter-fill { transition-delay: 0.72s; }
html.js body.is-loaded .stat:nth-child(4) .meter-fill { transition-delay: 0.89s; }
html.js body.is-loaded .stat:nth-child(5) .meter-fill { transition-delay: 1.06s; }

/* ---------- bin/ links ---------- */
/* block flow + uniform margin = gaps that physically cannot be uneven */
.bin { display: block; max-width: 34em; }
.bin a {
  display: flex;
  align-items: baseline;
  gap: 2ch;
  padding: 6px 10px;
  margin: 0 -10px clamp(12px, 1.6vh, 22px);
  font-size: clamp(16px, 1.3vw, 21px);
}
.bin a:last-child { margin-bottom: 0; }
.bin .perms { flex: 0 0 auto; font-size: 0.78em; }
.bin .bin-name { flex: 1 1 auto; letter-spacing: 1px; }
.bin .run { opacity: 0; font-size: 0.78em; color: var(--ph-bright); }
.bin a:hover, .bin a:focus-visible { background: var(--ph); }
.bin a:hover .bin-name, .bin a:focus-visible .bin-name,
.bin a:hover .perms, .bin a:focus-visible .perms { color: var(--bg); }
.bin a:hover .run, .bin a:focus-visible .run { opacity: 1; color: var(--bg); }

/* ---------- bin row: links left, portfolio cover right ---------- */
.bin-row {
  display: flex;
  align-items: flex-start;
  gap: clamp(16px, 2.5vw, 44px);
}
.bin-row .bin { flex: 1 1 auto; min-width: 0; }
.feature {
  display: block;
  flex: 0 1 50%;       /* half the column */
  min-width: 0;
  margin: 0;
  container-type: inline-size;
}
/* a little CRT screen showing the portfolio, no photo */
.feature-screen {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--ph-faint);
  background:
    radial-gradient(ellipse at 50% 40%, rgba(24, 92, 48, 0.35), rgba(3, 13, 7, 0.95) 75%),
    var(--well);
  aspect-ratio: 16 / 10;
  padding: clamp(14px, 4cqw, 30px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.35em;
}
.feature-screen::after {     /* scanlines + a soft glass corner */
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: 6px;
  background: repeating-linear-gradient(to bottom,
    rgba(0, 0, 0, 0.16) 0 1px, transparent 1px 3px);
  box-shadow: inset 0 0 30px rgba(0, 8, 3, 0.6);
}
.feature-tag {
  font-size: clamp(9px, 2.6cqw, 13px);
  letter-spacing: 3px;
  color: var(--ph-dim);
}
.feature-title {
  font-size: clamp(20px, 9cqw, 50px);
  line-height: 1.02;
  letter-spacing: 2px;
}
.feature-cta {
  margin-top: 0.3em;
  font-size: clamp(11px, 3.4cqw, 17px);
}
.feature:hover .feature-screen,
.feature:focus-visible .feature-screen {
  border-color: var(--ph);
  box-shadow: 0 0 22px rgba(54, 245, 115, 0.35);
}
.feature:hover .feature-title { animation: hoverglitch 0.28s steps(3) 1; }

/* ==========================================================================
   CLIENTS
   ========================================================================== */
.logo-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(26px, 3vw, 54px) clamp(18px, 2.4vw, 44px);
  align-items: center;
  justify-items: center;
  border: 1px solid var(--ph-faint);
  padding: clamp(26px, 3vw, 52px);
}
.logo-grid a { display: flex; align-items: center; justify-content: center; width: 100%; }
.logo-grid img {
  width: 78%;
  max-width: 150px;
  max-height: clamp(36px, 3.6vw, 62px);
  object-fit: contain;
  /* white svg -> bright phosphor green (calibrated against --ph) */
  filter: sepia(1) saturate(12) hue-rotate(48deg) brightness(1.2);
  opacity: 0.95;
}
.logo-grid a:hover img, .logo-grid a:focus-visible img {
  filter: sepia(1) saturate(12) hue-rotate(48deg) brightness(1.5)
          drop-shadow(0 0 12px rgba(54, 245, 115, 0.8));
  opacity: 1;
}

/* ==========================================================================
   BIOGRAPHY
   ========================================================================== */
.bio-row {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: clamp(28px, 4vw, 80px);
  align-items: center;
}
.bio { max-width: 68ch; }
.bio p {
  color: #63fc92;
  text-shadow: 0 0 6px rgba(54, 245, 115, 0.3);
  text-transform: none;
  margin-bottom: 1.1em;
}
.bio p:last-child { margin-bottom: 0; }
/* featured portfolio card in the biography section */
.feature--bio {
  flex: none;
  width: 100%;
  max-width: 480px;
  justify-self: end;
  container-type: inline-size;
}
@media screen and (max-width: 767px) {
  .bio-row { grid-template-columns: 1fr; }
  .feature--bio { justify-self: stretch; max-width: none; }
}

/* ==========================================================================
   GALLERY
   ========================================================================== */
.art-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(14px, 1.8vw, 28px);
}
.art-grid figure {
  border: 1px solid var(--ph-faint);
  padding: 6px;
}
.art-grid img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) sepia(1) saturate(5) hue-rotate(48deg) brightness(1.0);
}
.art-grid figure:hover img { filter: none; }
.art-grid figure:hover { border-color: rgba(54, 245, 115, 0.5); }
.cmd-links { display: flex; flex-direction: column; margin-top: clamp(18px, 2.4vh, 30px); }
.cmd-links a { padding: 6px 10px; margin: 0 -10px; }
.cmd-links a:hover, .cmd-links a:focus-visible { background: var(--ph); color: var(--bg); }
.cmd-links a:hover .ps1, .cmd-links a:hover .dim,
.cmd-links a:focus-visible .ps1, .cmd-links a:focus-visible .dim { color: var(--bg); }

/* ==========================================================================
   LIVE TERMINAL
   ========================================================================== */
#term-out { white-space: pre-wrap; overflow-wrap: anywhere; }
#term-out .line { margin: 2px 0; }
#term-out .err { color: var(--red); }
#term-out .ok { color: var(--ph-bright); }
.term-line {
  display: flex;
  align-items: baseline;
  gap: 1ch;
  margin-top: 8px;
  margin-left: clamp(0px, 1.5vw, 22px);
}
#term-in {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--ph-bright);
  font-family: var(--dos);
  font-size: inherit;
  caret-color: var(--ph-bright);
  text-shadow: 0 0 8px rgba(54, 245, 115, 0.4);
}

/* meltdown easter egg */
body.meltdown { animation: shake 0.45s linear infinite; }
@keyframes shake {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(-3px, 2px); }
  50% { transform: translate(2px, -2px); }
  75% { transform: translate(-2px, -3px); }
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media screen and (max-width: 991px) {
  .hero-lower { grid-template-columns: 1fr; }
  .statusbar-mid { display: none; }
}
@media screen and (max-width: 767px) {
  .logo-grid { grid-template-columns: repeat(4, 1fr); }
  .art-grid { grid-template-columns: 1fr; }
  .topbar-title { display: none; }
  .badge-card { flex-direction: column; }
}
@media screen and (max-width: 479px) {
  .logo-grid { grid-template-columns: repeat(3, 1fr); }
  .stat { gap: 0.7em; }
  .stat-label { min-width: 9ch; }
  .bin a { gap: 1ch; }
}

/* ==========================================================================
   REDUCED MOTION
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .fx-grain, .alive, .blink, .boot-cursor { animation: none !important; }
  .fx-roll { display: none; }
  html.js .reveal, html.js .block:not(.hero) { transition: none; }
  html.js .meter-fill { transition: none; }
  body.meltdown { animation: none; }
  .topbar-nav a:hover, .statusbar a:hover,
  .bin a:hover .bin-name, .cmd-links a:hover { animation: none; }
}
