:root {
  /* surfaces */
  --color-bg:              #f0f2f5;
  --color-surface:         #ffffff;
  --color-border:          #e2e8f0;
  --color-border-input:    #cbd5e1;

  /* text */
  --color-text:            #1e293b;
  --color-text-muted:      #64748b;

  /* primary (indigo) */
  --color-primary:         #4f46e5;
  --color-primary-hover:   #4338ca;

  /* secondary */
  --color-secondary-bg:    #f1f5f9;
  --color-secondary-hover: #e2e8f0;
  --color-secondary-text:  #334155;

  /* danger */
  --color-danger:          #ef4444;
  --color-danger-hover:    #dc2626;

  /* cells */
  --color-cell-bg:         #f8fafc;
  --color-cell-wall:       #334155;
  --color-cell-wall-flash: #64748b;

  /* visited */
  --color-visited:         #a5b4fc;
  --color-visited-mid:     #818cf8;
  --color-visited-dark:    #6366f1;
  --color-visited-start:   #e0e7ff;

  /* path */
  --color-path:            #f59e0b;
  --color-path-wave:       #fde68a;
  --color-path-glow:       rgba(245, 158, 11, 0.45);

  /* sizing */
  --cell-size:             36px;
  --icon-size:             30px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: 'Segoe UI', sans-serif;
  background: var(--color-bg);
  color: var(--color-text);
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

header {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  padding: 10px 20px;
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}

header h1 {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--color-primary);
  white-space: nowrap;
}

.controls {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

select, button {
  padding: 6px 14px;
  border-radius: 6px;
  border: 1px solid var(--color-border-input);
  font-size: 0.85rem;
  cursor: pointer;
  transition: all 0.15s;
}

select {
  background: var(--color-cell-bg);
  color: var(--color-text);
}

select:focus { outline: none; border-color: var(--color-primary); }

button {
  background: var(--color-primary);
  color: var(--color-surface);
  border-color: var(--color-primary);
  font-weight: 600;
}

button:hover    { background: var(--color-primary-hover); }
button:disabled { opacity: 0.4; cursor: not-allowed; }

.btn-secondary {
  background: var(--color-secondary-bg);
  color: var(--color-secondary-text);
  border-color: var(--color-border-input);
}

.btn-secondary:hover { background: var(--color-secondary-hover); }

.btn-danger {
  background: var(--color-danger);
  border-color: var(--color-danger);
  color: var(--color-surface);
}

.btn-danger:hover { background: var(--color-danger-hover); }

.speed-label {
  font-size: 0.8rem;
  color: var(--color-text-muted);
}

input[type=range] {
  accent-color: var(--color-primary);
  width: 80px;
}

#status {
  font-size: 0.8rem;
  color: var(--color-text-muted);
  white-space: nowrap;
  display: inline-block;
}

/* void offsetWidth forces a reflow so re-adding the same class
 * still triggers the animation even if it was already set. */
#status.update {
  animation: status-in 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

#status.success {
  animation: status-success 1.8s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

#status.failure {
  animation: status-failure 0.55s ease forwards;
}

@keyframes status-in {
  0%   { opacity: 0; transform: translateY(6px) scale(0.95); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes status-success {
  0%   { opacity: 0; transform: scale(0.8);  color: #16a34a; }
  25%  { opacity: 1; transform: scale(1.25); color: #16a34a; }
  55%  { transform: scale(1.1);  color: #16a34a; }
  100% { transform: scale(1);    color: var(--color-text-muted); }
}

@keyframes status-failure {
  0%   { transform: translateX(0);    color: var(--color-danger); }
  20%  { transform: translateX(-7px); }
  40%  { transform: translateX(7px);  }
  60%  { transform: translateX(-4px); }
  80%  { transform: translateX(4px);  }
  100% { transform: translateX(0);    color: var(--color-danger); }
}

#tip {
  text-align: center;
  padding: 10px;
  font-size: 0.78rem;
  color: var(--color-text-muted);
  background: var(--color-cell-bg);
  border-bottom: 1px solid var(--color-border);
}

#grid-container {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
  overflow: hidden;
}

#grid {
  display: grid;
  gap: 1px;
  background: var(--color-border-input);
  border: 1px solid var(--color-border-input);
  border-radius: 8px;
  overflow: hidden;
  user-select: none;
  cursor: crosshair;
  box-shadow: 0 4px 16px rgba(0,0,0,0.08);
}

.cell {
  width: var(--cell-size);
  height: var(--cell-size);
  background: var(--color-cell-bg);
  position: relative;
}

/* icons are rendered via ::before/::after pseudo-elements so animations on
 * the icon don't affect the cell background, and vice versa. */
.cell.start { z-index: 1; }

.cell.start::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url('assets/triangle-right.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: var(--icon-size) var(--icon-size);
  animation: node-breathe 2s ease-in-out infinite;
}

.cell.end { z-index: 1; }

.cell.end.found {
  animation: end-found 1.4s ease forwards;
}

/* wave on the end node overrides end-found so the ripple still plays */
.cell.end.found.wave {
  animation: path-wave 0.4s ease forwards;
  animation-delay: var(--wave-delay, 0ms);
}

@keyframes end-found {
  0%   { background: var(--color-cell-bg); }
  100% { background: var(--color-path); }
}

.cell.end.found::after {
  animation: node-pop 1.4s cubic-bezier(0.36, 0.07, 0.19, 0.97) forwards;
}

@keyframes node-pop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.3); filter: brightness(1.3); }
  70%  { transform: scale(0.9); }
  100% { transform: scale(1); }
}

.cell.end::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url('assets/circle.svg');
  background-repeat: no-repeat;
  background-position: center;
  background-size: var(--icon-size) var(--icon-size);
  animation: node-breathe 2s ease-in-out infinite 1s;
}

@keyframes node-breathe {
  0%, 100% { transform: scale(1);    filter: brightness(1); }
  50%       { transform: scale(1.12); filter: brightness(1.15); }
}

.legend {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: auto;
  flex-wrap: wrap;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.legend-dot {
  width: 14px;
  height: 14px;
  border-radius: 3px;
}
.cell.wall {
  background: var(--color-cell-wall);
  animation: wall-thud 0.18s cubic-bezier(0.36, 0.07, 0.19, 0.97) forwards;
}

@keyframes wall-thud {
  0%   { transform: scale(0.6); background: var(--color-cell-wall-flash); }
  55%  { transform: scale(1.08); }
  80%  { transform: scale(0.96); }
  100% { transform: scale(1);    background: var(--color-cell-wall); }
}
.cell.visited {
  animation: visited-anim 0.45s cubic-bezier(0.34, 1.3, 0.64, 1) forwards;
}

.cell.path {
  background: var(--color-path);
  box-shadow: 0 0 6px 2px var(--color-path-glow);
}

/* wave is added after the path is fully drawn to create a ripple effect.
 * --wave-delay is set inline per cell so the animation staggers along the path. */
.cell.path.wave {
  animation: path-wave 0.4s ease forwards;
  animation-delay: var(--wave-delay, 0ms);
}

@keyframes path-wave {
  0%   { transform: scale(1);    filter: brightness(1); }
  40%  { transform: scale(1.25); filter: brightness(1.4); background: var(--color-path-wave); }
  100% { transform: scale(1);    filter: brightness(1);  background: var(--color-path); }
}

@keyframes visited-anim {
  0% {
    transform: scale(0) rotate(-180deg);
    background: var(--color-visited-start);
    border-radius: 50%;
    opacity: 0.6;
  }
  35% {
    transform: scale(1.25) rotate(15deg);
    background: var(--color-visited-mid);
    border-radius: 30%;
    opacity: 1;
  }
  65% {
    transform: scale(0.92) rotate(-5deg);
    background: var(--color-visited-dark);
    border-radius: 10%;
  }
  100% {
    transform: scale(1) rotate(0deg);
    background: var(--color-visited);
    border-radius: 3px;
  }
}
