/* ---------- design tokens ---------- */
:root {
  --bg-deep: #06070b;
  --bg-panel: rgba(6, 7, 12, 0.82);
  --bg-panel-solid: #08090d;
  --border-soft: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.16);

  --fg: #e8eaf2;
  --fg-dim: #8b90a8;
  --fg-faint: #565b73;

  --accent: #7dd3fc;
  --accent-2: #c4b5fd;
  --accent-3: #86efac;
  --accent-warn: #fcd34d;
  --accent-bad: #fb7185;

  --mono: "SF Mono", "Fira Code", "JetBrains Mono", "Cascadia Code", Menlo, Consolas, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --radius-lg: 18px;
  --radius-md: 10px;
  --radius-sm: 6px;
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--sans);
  color: var(--fg);
  background: var(--bg-deep);
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
  /* This reads as an app/game, not a document — no drag-to-select
     smears across the terminal/task tiles. Inputs opt back in below so
     typing/selecting what you typed still works normally. */
  -webkit-user-select: none;
  user-select: none;
}

input,
textarea,
[contenteditable] {
  -webkit-user-select: text;
  user-select: text;
}

/* ---------- animated background ---------- */
.bg-scene {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: radial-gradient(ellipse at top, #131829 0%, #0b0e17 60%);
}

.bg-glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.65;
  animation: drift 22s ease-in-out infinite alternate;
}

.bg-glow-1 {
  width: 46vw;
  height: 46vw;
  top: -12%;
  left: -10%;
  background: radial-gradient(circle, #6366f1, transparent 72%);
}

.bg-glow-2 {
  width: 42vw;
  height: 42vw;
  bottom: -16%;
  right: -8%;
  background: radial-gradient(circle, #06b6d4, transparent 72%);
  animation-duration: 26s;
  animation-delay: -6s;
}

.bg-glow-3 {
  width: 34vw;
  height: 34vw;
  top: 26%;
  right: 18%;
  background: radial-gradient(circle, #a855f7, transparent 72%);
  animation-duration: 30s;
  animation-delay: -12s;
}

@keyframes drift {
  from {
    transform: translate(0, 0) scale(1);
  }
  to {
    transform: translate(4%, 6%) scale(1.08);
  }
}

.bg-grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0.035) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: radial-gradient(ellipse at center, black 0%, transparent 75%);
}

/* ---------- header / footer ---------- */
.site-header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 22px clamp(16px, 4vw, 48px) 6px;
}

.logo {
  font-family: var(--mono);
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.logo-accent {
  color: var(--accent);
}

.tagline {
  color: var(--fg-dim);
  font-size: 0.9rem;
}

.site-footer {
  padding: 10px clamp(16px, 4vw, 48px) 22px;
  color: var(--fg-faint);
  font-size: 0.82rem;
  text-align: center;
}

.site-footer code {
  color: var(--fg-dim);
}

/* ---------- workspace layout ---------- */
/* Terminal pane is sized to feel like a default macOS Terminal.app
   window (roughly its 80x24 starting profile) rather than stretching to
   fill the viewport — everything below just centers around that. */
.workspace {
  flex: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: center;
  gap: 22px;
  padding: 16px clamp(16px, 4vw, 48px) 28px;
}

@media (max-width: 880px) {
  .workspace {
    flex-direction: column;
    align-items: center;
  }
}

/* ---------- terminal window ---------- */
.terminal-column {
  display: flex;
  flex-direction: column;
  flex: none;
  width: 640px;
  max-width: 100%;
  gap: 14px;
}

@property --angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

@keyframes fx-border-spin {
  to {
    --angle: 360deg;
  }
}

@keyframes fx-panel-in {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.terminal-pane {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 500px;
  margin-bottom: 12px; /* extra breathing room below the terminal specifically */
  background: var(--bg-panel);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  box-shadow:
    0 30px 60px -20px rgba(0, 0, 0, 0.75),
    0 0 0 1px rgba(255, 255, 255, 0.02) inset;
  overflow: hidden;
  transition: transform 0.05s linear;
  animation: fx-panel-in 0.5s ease-out both;
}

/* Slow, subtle animated glow chasing the terminal's border — decorative
   only, painted just on the ring (mask-composite excludes the interior)
   so it never interferes with the terminal content itself. Degrades to
   nothing (a static border) in browsers without @property support. */
.terminal-pane::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--angle), transparent 0%, var(--accent) 8%, transparent 18%, transparent 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0.5;
  animation: fx-border-spin 7s linear infinite;
  pointer-events: none;
}

.window-titlebar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 13px 16px;
  background: rgba(255, 255, 255, 0.03);
  border-bottom: 1px solid var(--border-soft);
}

.dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
}

.dot-red {
  background: #ff5f57;
}

.dot-yellow {
  background: #febc2e;
}

.dot-green {
  background: #28c840;
}

.window-title {
  margin: 0 auto;
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--fg-dim);
  transform: translateX(-16px);
}

.window-body {
  position: relative;
  flex: 1;
  display: flex;
  min-height: 0;
}

/* ---------- shell ---------- */
.shell-view {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 12px 16px;
  font-family: var(--mono);
  font-size: 0.8rem;
  line-height: 1.5;
}

.terminal-output {
  flex: 1;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--fg);
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}

.terminal-output::-webkit-scrollbar {
  width: 8px;
}

.terminal-output::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 4px;
}

.line {
  min-height: 1.55em;
}

.line-cmd .cmd-prompt {
  color: var(--accent-3);
  margin-right: 6px;
}

.line-error {
  color: var(--accent-bad);
}

.line-dir {
  color: var(--accent);
}

.line-hint {
  color: var(--fg-dim);
}

.terminal-inputline {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
  flex-shrink: 0;
}

.prompt {
  color: var(--accent-3);
  white-space: nowrap;
}

.shell-input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--fg);
  font-family: var(--mono);
  font-size: 0.92rem;
  caret-color: var(--accent);
}

/* ---------- vim view ---------- */
.vim-view {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  font-family: var(--mono);
  font-size: 0.8rem;
  outline: none;
}

.vim-view.hidden,
.shell-view.hidden {
  display: none;
}

.vim-buffer {
  flex: 1;
  overflow-y: auto;
  padding: 14px 0;
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}

.vim-line {
  display: flex;
  padding: 0 18px;
  min-height: 1.5em;
  line-height: 1.5;
}

.vim-line.vim-line-active {
  background: rgba(255, 255, 255, 0.04);
}

.vim-lnum {
  width: 3.4em;
  flex-shrink: 0;
  text-align: right;
  margin-right: 14px;
  color: var(--fg-faint);
  user-select: none;
}

.vim-line.vim-line-active .vim-lnum {
  color: var(--accent-warn);
}

.vim-text {
  white-space: pre;
  position: relative;
}

.vim-text.browser-dir {
  color: var(--accent);
  font-weight: 600;
}

.vim-view.mode-browse .vim-mode-indicator {
  background: rgba(196, 181, 253, 0.2);
  color: var(--accent-2);
}

.vim-char {
  position: relative;
}

.vim-char.vim-cursor {
  background: var(--accent);
  color: var(--bg-deep);
  border-radius: 2px;
}

.vim-view.mode-insert .vim-char.vim-cursor {
  background: transparent;
  color: inherit;
  box-shadow: -1px 0 0 var(--accent-3) inset;
}

.vim-char.vim-selected {
  background: rgba(196, 181, 253, 0.32);
}

.vim-cmdline {
  padding: 5px 18px;
  font-family: var(--mono);
  border-top: 1px solid var(--border-soft);
  color: var(--fg);
}

.vim-cmdline.hidden {
  display: none;
}

/* ---------- in-terminal contextual hint popup ---------- */
.vim-hint-popup {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  max-width: min(90%, 480px);
  padding: 10px 12px;
  border-radius: var(--radius-md);
  background: rgba(23, 22, 12, 0.92);
  border: 1px solid rgba(252, 211, 77, 0.4);
  box-shadow: 0 12px 30px -10px rgba(0, 0, 0, 0.6);
  font-family: var(--sans);
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--fg);
  animation: fx-hint-in 0.25s ease-out;
}

.vim-hint-popup.hidden {
  display: none;
}

.vim-hint-icon {
  flex-shrink: 0;
}

#vim-hint-text {
  flex: 1;
}

#vim-hint-text code {
  background: rgba(255, 255, 255, 0.08);
  border-radius: 4px;
  padding: 1px 5px;
  font-family: var(--mono);
  color: var(--accent-warn);
}

.vim-hint-close {
  flex-shrink: 0;
  background: none;
  border: none;
  color: var(--fg-faint);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 2px;
}

.vim-hint-close:hover {
  color: var(--fg);
}

@keyframes fx-hint-in {
  from {
    opacity: 0;
    transform: translate(-50%, -8px);
  }
  to {
    opacity: 1;
    transform: translate(-50%, 0);
  }
}

.vim-caret {
  display: inline-block;
  width: 0.5em;
  height: 1em;
  vertical-align: -2px;
  background: var(--accent);
  animation: blink 1s steps(1) infinite;
}

@keyframes blink {
  50% {
    opacity: 0;
  }
}

.vim-statusline {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 6px 18px;
  font-family: var(--mono);
  font-size: 0.78rem;
  background: rgba(255, 255, 255, 0.04);
  border-top: 1px solid var(--border-soft);
  color: var(--fg-dim);
}

.vim-mode-indicator {
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 1px 8px;
  border-radius: var(--radius-sm);
  background: rgba(125, 211, 252, 0.18);
  color: var(--accent);
}

.vim-view.mode-insert .vim-mode-indicator {
  background: rgba(134, 239, 172, 0.18);
  color: var(--accent-3);
}

.vim-view.mode-visual .vim-mode-indicator,
.vim-view.mode-visualline .vim-mode-indicator {
  background: rgba(196, 181, 253, 0.2);
  color: var(--accent-2);
}

.vim-view.mode-command .vim-mode-indicator {
  background: rgba(252, 211, 77, 0.2);
  color: var(--accent-warn);
}

.vim-status-spacer {
  flex: 1;
}

.vim-keycount {
  color: var(--fg-faint);
}

/* ---------- tasks pane ---------- */
/* No internal scrolling by design — the whole pane grows to fit every
   task tile + the open detail panel, and the page scrolls as a whole
   if it needs to, rather than cropping content inside this box. */
.tasks-pane {
  display: flex;
  flex-direction: column;
  flex: none;
  width: 360px;
  max-width: 100%;
  background: var(--bg-panel);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.75);
  animation: fx-panel-in 0.5s ease-out 0.08s both;
}

.tasks-header {
  padding: 16px 18px 12px;
  border-bottom: 1px solid var(--border-soft);
}

.tasks-header h2 {
  margin: 0 0 4px;
  font-size: 1rem;
}

.progress-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.progress-summary {
  font-size: 0.78rem;
  color: var(--fg-dim);
}

.tasks-list {
  padding: 8px;
}

.task-category {
  padding: 10px 8px 4px;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-faint);
}

.task-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
  gap: 6px;
  padding: 2px 8px 10px;
}

.task-tile {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.03);
  color: var(--fg-dim);
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
}

.task-tile:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-1px);
}

.task-tile.active {
  border-color: var(--accent);
  background: rgba(125, 211, 252, 0.16);
  color: var(--accent);
  animation: fx-tile-glow 1.8s ease-in-out infinite;
}

@keyframes fx-tile-glow {
  0%,
  100% {
    box-shadow: 0 0 0 2px rgba(125, 211, 252, 0.2);
  }
  50% {
    box-shadow: 0 0 0 4px rgba(125, 211, 252, 0.4);
  }
}

.task-tile.done {
  border-color: var(--accent-3);
  background: rgba(134, 239, 172, 0.16);
  color: var(--accent-3);
}

.task-tile.done.active {
  box-shadow: 0 0 0 2px rgba(134, 239, 172, 0.3);
}

.task-tile-check {
  font-size: 0.9rem;
}

.task-detail {
  padding: 16px 18px 18px;
  border-top: 1px solid var(--border-soft);
}

.task-detail-empty {
  color: var(--fg-dim);
  font-size: 0.85rem;
  line-height: 1.6;
}

.task-detail-empty code {
  color: var(--accent);
}

.task-detail h3 {
  margin: 0 0 8px;
  font-size: 1rem;
}

.task-detail .task-meta {
  font-size: 0.72rem;
  color: var(--fg-faint);
  margin-bottom: 10px;
}

.task-detail .task-desc {
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--fg);
  margin-bottom: 14px;
}

.task-detail code {
  background: rgba(255, 255, 255, 0.06);
  border-radius: 4px;
  padding: 1px 5px;
  font-family: var(--mono);
  font-size: 0.85em;
  color: var(--accent);
}

.hint-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-strong);
  background: rgba(255, 255, 255, 0.04);
  color: var(--fg);
  font-family: var(--sans);
  font-size: 0.82rem;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.hint-btn:hover {
  background: rgba(252, 211, 77, 0.12);
  border-color: var(--accent-warn);
  color: var(--accent-warn);
}

.hint-box {
  margin-top: 10px;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  background: rgba(252, 211, 77, 0.09);
  border: 1px solid rgba(252, 211, 77, 0.25);
  color: var(--fg);
  font-size: 0.84rem;
  line-height: 1.55;
}

.hint-box.hidden {
  display: none;
}

.task-status {
  margin-top: 14px;
  padding: 8px 12px;
  border-radius: var(--radius-md);
  font-size: 0.84rem;
  font-weight: 600;
}

.task-status.status-pending {
  color: var(--fg-dim);
  background: rgba(255, 255, 255, 0.04);
}

.task-status.status-done {
  color: var(--accent-3);
  background: rgba(134, 239, 172, 0.12);
}

.reopen-btn {
  margin-top: 10px;
  display: inline-flex;
  padding: 7px 14px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-strong);
  background: rgba(255, 255, 255, 0.04);
  color: var(--fg);
  font-family: var(--sans);
  font-size: 0.82rem;
  cursor: pointer;
}

.reopen-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.hidden {
  display: none !important;
}

.rmrf-warning {
  text-align: center;
  font-family: var(--mono);
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--accent-bad);
  padding: 8px 14px;
  border: 1.5px solid var(--accent-bad);
  border-radius: var(--radius-md);
  background: rgba(251, 113, 133, 0.1);
}

/* ---------- basic commands cheat sheet ---------- */
.cmds-pane {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px 18px;
  background: var(--bg-panel);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.6);
  animation: fx-panel-in 0.5s ease-out 0.16s both;
}

.cmds-title {
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--fg-dim);
}

.cmds-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 6px 18px;
}

.cmds-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 0.78rem;
}

.cmds-item code {
  flex-shrink: 0;
  min-width: 4.2em;
  font-family: var(--mono);
  color: var(--accent);
}

.cmds-item span {
  color: var(--fg-dim);
}

/* ---------- promo card (nvim-config quickstart) — deliberately its own
   black, minimal look, distinct from the rest of the glass UI ---------- */
.promo-pane {
  /* Plain block-level element (see index.html) — width/centering here
     don't interact with .workspace's flex layout at all. */
  width: calc(100% - 2 * clamp(16px, 4vw, 48px));
  max-width: 820px;
  margin: 4px auto 0;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 22px 28px;
  background: #000;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--radius-lg);
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.8);
  animation: fx-panel-in 0.5s ease-out 0.24s both;
}

.promo-title {
  font-weight: 600;
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.82);
  letter-spacing: -0.01em;
}

.promo-install-line {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  background: #0a0a0a;
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: #e8eaf2;
  font-family: var(--sans);
  cursor: pointer;
  text-align: left;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.promo-install-line:hover {
  border-color: rgba(255, 255, 255, 0.32);
  background: #131313;
}

.promo-install-line.copied {
  border-color: var(--accent-3);
}

.promo-install-line code {
  flex: 1;
  min-width: 0;
  font-family: var(--mono);
  font-size: 0.74rem;
  font-weight: 400;
  color: rgba(255, 255, 255, 0.55);
  letter-spacing: 0.01em;
  white-space: normal;
  overflow-wrap: anywhere;
}

.promo-copy-icon {
  flex-shrink: 0;
  color: var(--fg-faint);
  font-size: 0.85rem;
}

.promo-install-line.copied .promo-copy-icon {
  color: var(--accent-3);
}

.promo-repo-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: center;
  padding: 9px 18px;
  border-radius: var(--radius-md);
  background: #0a0a0a;
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: rgba(255, 255, 255, 0.8);
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.82rem;
  text-decoration: none;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease, color 0.15s ease;
}

.promo-repo-btn:hover {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.4);
  background: #131313;
  transform: translateY(-1px);
}

/* ---------- free mode ---------- */
.freeplay-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: calc(100% - 16px);
  margin: 8px;
  padding: 10px;
  border-radius: var(--radius-md);
  border: 1px dashed var(--border-strong);
  background: linear-gradient(135deg, rgba(125, 211, 252, 0.1), rgba(196, 181, 253, 0.1));
  color: var(--fg);
  font-family: var(--sans);
  font-size: 0.84rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.1s ease;
}

.freeplay-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-1px);
}

.freeplay-btn.active {
  border-style: solid;
  border-color: var(--accent-3);
  color: var(--accent-3);
}

.freeplay-banner {
  margin-bottom: 14px;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  background: rgba(134, 239, 172, 0.1);
  border: 1px solid rgba(134, 239, 172, 0.25);
  color: var(--fg);
  font-size: 0.84rem;
  line-height: 1.55;
}

/* ---------- stars ---------- */
.stars {
  display: inline-flex;
  gap: 1px;
  color: var(--accent-warn);
  font-size: 0.78rem;
  letter-spacing: -1px;
}

.stars .star-off {
  color: var(--border-strong);
}

.progress-stars {
  color: var(--accent-warn);
}

/* ---------- completion celebration ---------- */
#fx-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 999;
  overflow: hidden;
}

.fx-star {
  position: absolute;
  transform: translate(-50%, -50%);
  font-size: calc(14px * var(--scale, 1));
  color: hsl(var(--hue, 45) 90% 65%);
  text-shadow: 0 0 8px hsl(var(--hue, 45) 90% 60% / 0.8);
  animation: fx-burst 0.9s cubic-bezier(0.15, 0.6, 0.35, 1) forwards;
  will-change: transform, opacity;
}

@keyframes fx-burst {
  0% {
    transform: translate(-50%, -50%) translate(0, 0) rotate(0deg) scale(0.3);
    opacity: 1;
  }
  70% {
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) translate(var(--dx), var(--dy)) rotate(var(--rot)) scale(var(--scale));
    opacity: 0;
  }
}

@keyframes fx-pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(134, 239, 172, 0.55);
  }
  70% {
    box-shadow: 0 0 0 14px rgba(134, 239, 172, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(134, 239, 172, 0);
  }
}

.fx-pulse {
  animation: fx-pulse 0.7s ease-out;
}

@keyframes fx-pop {
  0% {
    transform: scale(0.4) rotate(-10deg);
  }
  60% {
    transform: scale(1.25) rotate(4deg);
  }
  100% {
    transform: scale(1) rotate(0deg);
  }
}

.fx-pop {
  animation: fx-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ---------- rm -rf / meltdown easter egg ---------- */
.terminal-pane.meltdown {
  animation: fx-shake 0.4s infinite;
  border-color: rgba(251, 113, 133, 0.6);
  box-shadow:
    0 0 40px rgba(251, 113, 133, 0.35),
    0 30px 60px -20px rgba(0, 0, 0, 0.6);
}

@keyframes fx-shake {
  0%,
  100% {
    transform: translate(0, 0);
  }
  20% {
    transform: translate(-2px, 1px);
  }
  40% {
    transform: translate(2px, -1px);
  }
  60% {
    transform: translate(-1px, -2px);
  }
  80% {
    transform: translate(1px, 2px);
  }
}

.line-meltdown {
  color: var(--accent-bad);
}

/* CS:GO-style flashbang: hold pure white just long enough to register as
   a blind-out, then fade to black while the picture fades in underneath
   — a viewer's eyes are "recovering" as it settles. Timed to roughly
   match img/flashbang.mp3's own length (~2.5s) so the visual doesn't
   finish while the sound is still playing. */
.meltdown-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: fx-flashbang 2.5s ease-out forwards;
}

.meltdown-overlay.hidden {
  display: none;
}

.meltdown-overlay img {
  max-width: min(90vw, 560px);
  max-height: 80vh;
  border-radius: var(--radius-lg);
  box-shadow: 0 0 120px rgba(251, 113, 133, 0.55);
  opacity: 0;
  animation: fx-shake 0.4s infinite, fx-img-reveal 0.3s ease-out forwards;
}

@keyframes fx-flashbang {
  0% {
    background: #fff;
  }
  12% {
    background: #fff;
  }
  100% {
    background: #000;
  }
}

@keyframes fx-img-reveal {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
