/*
  cfsam.org game visual kit
  -------------------------
  The reference SVGs already contain their core appearance. This stylesheet
  adds host-page layout, interactive states, motion, focus treatment, and
  reduced-motion/forced-color safeguards.
*/

:root {
  --gv-bg: #08141c;
  --gv-surface: #10232d;
  --gv-surface-2: #17323e;
  --gv-text: #eef7f8;
  --gv-muted: #9fb4bc;
  --gv-line: #2c4c59;
  --gv-cyan: #58d5e5;
  --gv-blue: #69a7ff;
  --gv-green: #6fd39a;
  --gv-amber: #f2c45e;
  --gv-red: #ff7c78;
  --gv-radius-sm: 12px;
  --gv-radius-md: 18px;
  --gv-radius-lg: 28px;
  --gv-motion-quick: 160ms;
  --gv-motion-normal: 280ms;
  --gv-motion-route: 420ms;
  --gv-motion-landing: 520ms;
  --gv-motion-go-around: 720ms;
  --gv-focus-ring: 0 0 0 3px var(--gv-bg), 0 0 0 6px var(--gv-cyan);
}

[data-theme="light"],
.gv-theme-light {
  --gv-bg: #f5f2ea;
  --gv-surface: #ffffff;
  --gv-surface-2: #e8eef1;
  --gv-text: #17232b;
  --gv-muted: #5b6d78;
  --gv-line: #b8c8cf;
  --gv-cyan: #0b94a8;
  --gv-blue: #2d7dd2;
  --gv-green: #2f9e62;
  --gv-amber: #b97600;
  --gv-red: #c44545;
}

.gv-visual {
  position: relative;
  width: 100%;
  color: var(--gv-text);
  isolation: isolate;
}

.gv-visual > svg,
.gv-visual > img,
.gv-visual > object {
  display: block;
  width: 100%;
  height: auto;
}

.gv-visual[data-aspect="board"] {
  aspect-ratio: 4 / 3;
}

.gv-visual[data-aspect="thumbnail"] {
  aspect-ratio: 12 / 7;
}

.gv-completion-badge {
  display: block;
  width: min(240px, 100%);
  height: auto;
  border-radius: var(--gv-radius-md);
}

.gv-completion-badge[hidden] { display: none; }

/* Keep hit targets as native HTML buttons whenever possible. */
.gv-hit {
  appearance: none;
  -webkit-tap-highlight-color: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  touch-action: manipulation;
}

.gv-hit:focus-visible {
  outline: none;
  filter: drop-shadow(0 0 0 var(--gv-bg));
}

.gv-hit:focus-visible .gv-focus-shape,
.gv-hit[aria-pressed="true"] .gv-focus-shape {
  stroke: var(--gv-cyan);
  stroke-width: 5;
  stroke-dasharray: 8 7;
}

.gv-hit[disabled],
.gv-hit[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.48;
}

/* Color is reinforced with line style and iconography. */
[data-gv-state="safe"] .gv-state-ring {
  stroke: var(--gv-green);
  stroke-width: 5;
  stroke-dasharray: none;
}

[data-gv-state="caution"] .gv-state-ring {
  stroke: var(--gv-amber);
  stroke-width: 5;
  stroke-dasharray: 4 6;
}

[data-gv-state="blocked"] .gv-state-ring {
  stroke: var(--gv-red);
  stroke-width: 5;
  stroke-dasharray: 12 5 2 5;
}

[data-gv-state="ruled-out"] {
  opacity: 0.38;
}

[data-gv-state="possible"] {
  opacity: 1;
}

[data-gv-state="fix"] .gv-marker-ring {
  stroke: var(--gv-cyan);
  stroke-width: 5;
}

[data-gv-state="candidate"] .gv-marker-ring {
  stroke: var(--gv-green);
  stroke-width: 5;
}

/* Overview cards */
.gv-game-card-art {
  overflow: hidden;
  border-radius: var(--gv-radius-lg);
  background: var(--gv-bg);
  border: 1px solid color-mix(in srgb, var(--gv-line) 88%, transparent);
}

.gv-game-card-art img,
.gv-game-card-art svg {
  transition: transform var(--gv-motion-normal) ease,
              filter var(--gv-motion-normal) ease;
  transform-origin: 50% 50%;
}

.gv-game-card:where(:hover, :focus-within) .gv-game-card-art img,
.gv-game-card:where(:hover, :focus-within) .gv-game-card-art svg,
.gv-game-card[data-in-view="true"] .gv-game-card-art img,
.gv-game-card[data-in-view="true"] .gv-game-card-art svg {
  transform: scale(1.018);
  filter: saturate(1.06);
}

/* Motion hooks. The JS helper adds these classes for one-shot feedback. */
.gv-route-draw {
  animation: gv-route-draw var(--gv-motion-route) ease-out both;
}

.gv-radar-sweep {
  transform-box: fill-box;
  transform-origin: center;
  animation: gv-radar-sweep 12s linear infinite;
}

.gv-ripple {
  transform-box: fill-box;
  transform-origin: center;
  animation: gv-ripple 560ms ease-out both;
}

.gv-wake-add {
  transform-box: fill-box;
  transform-origin: center;
  animation: gv-wake-add 360ms cubic-bezier(.2,.9,.25,1.25) both;
}

.gv-wake-fade {
  transform-box: fill-box;
  transform-origin: center;
  animation: gv-wake-fade 360ms ease-in both;
}

.gv-land {
  animation: gv-land var(--gv-motion-landing) cubic-bezier(.2,.8,.2,1) both;
}

.gv-go-around {
  animation: gv-go-around var(--gv-motion-go-around) cubic-bezier(.4,0,.2,1) both;
}

.gv-completion-stamp {
  transform-box: fill-box;
  transform-origin: center;
  animation: gv-stamp 480ms cubic-bezier(.18,.9,.28,1.25) both;
}

.gv-selected-preview {
  stroke-dasharray: 12 10;
  animation: gv-dash-flow 1.35s linear infinite;
}

@keyframes gv-route-draw {
  from { stroke-dashoffset: var(--gv-route-length, 1000); }
  to { stroke-dashoffset: 0; }
}

@keyframes gv-radar-sweep {
  to { transform: rotate(360deg); }
}

@keyframes gv-ripple {
  0% { opacity: 0.7; transform: scale(.55); }
  100% { opacity: 0; transform: scale(1.55); }
}

@keyframes gv-wake-add {
  0% { opacity: 0; transform: translateY(10px) scale(.72); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes gv-wake-fade {
  0% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: translateY(-6px) scale(.72); }
}

@keyframes gv-land {
  0% { opacity: 1; }
  82% { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes gv-go-around {
  0% { opacity: 1; }
  65% { opacity: 1; }
  100% { opacity: .55; }
}

@keyframes gv-stamp {
  0% { opacity: 0; transform: scale(1.18) rotate(-3deg); }
  65% { opacity: 1; transform: scale(.97) rotate(1deg); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}

@keyframes gv-dash-flow {
  to { stroke-dashoffset: -44; }
}

/* Screen-reader-only live region used by the examples. */
.gv-sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    scroll-behavior: auto !important;
  }

  .gv-game-card-art img,
  .gv-game-card-art svg,
  .gv-route-draw,
  .gv-radar-sweep,
  .gv-ripple,
  .gv-wake-add,
  .gv-wake-fade,
  .gv-land,
  .gv-go-around,
  .gv-completion-stamp,
  .gv-selected-preview {
    animation: none !important;
    transition: none !important;
    transform: none !important;
  }
}

@media (forced-colors: active) {
  .gv-visual,
  .gv-hit,
  .gv-game-card-art {
    forced-color-adjust: auto;
  }

  [data-gv-state="safe"] .gv-state-ring,
  [data-gv-state="caution"] .gv-state-ring,
  [data-gv-state="blocked"] .gv-state-ring {
    stroke: CanvasText;
  }
}
