/* CRT look for the TV screen in the Game Collection box. Loaded after style.css.
   The screen is the .game-link element; its two pseudo-elements and the TV's ::before carry the effects.
   Tweak the numbers in the .tv block below: 0 turns an effect off, bigger is stronger.

   Layers, bottom to top:
     game box, towers, caption      (the picture)
     .game-link::after              scanlines, RGB phosphor stripes, curved-glass highlight, vignette
     .game-link::before             dark rounded corners, film grain, dark edge of the tube
     .tv::before                    slow rolling refresh bar
     tv.png                         the TV body, on top of everything */

.tv {
  --crt-scanlines: 0.22;    /* dark horizontal lines */
  --crt-rgb: 0.06;          /* red/green/blue phosphor stripes */
  --crt-vignette: 0.55;     /* darkening toward the edges */
  --crt-glare: 0.16;        /* curved-glass highlight, top left */
  --crt-roll: 0.07;         /* brightness of the rolling refresh bar */
  --crt-roll-time: 7s;      /* how long the bar takes to cross the screen */
  --crt-flicker: 0.025;     /* tiny brightness flicker */
  --crt-fringe: 1px;        /* red/cyan colour fringing on the text */
  --crt-corner: 7% / 9%;    /* how rounded the tube's corners are */
  --crt-tube: #0c0e0c;      /* colour outside the rounded tube (behind the TV's bezel) */
}

/* Solid black behind the screen (same rectangle as .game-link) */
.crt-backing {
  position: absolute;
  left: 5.7692%;
  top: 6.1224%;
  width: 88.4615%;
  height: 65.3061%;
  background: #000;
  z-index: 0;
}

/* The picture: a little extra contrast and colour, like a bright tube */
.game-link {
  filter: contrast(1.08) saturate(1.15) brightness(1.04);
  animation: crtFlicker 0.18s steps(1) infinite;
}

/* Colour fringing on the caption text, and a soft glow */
.game-title,
.game-meta {
  text-shadow:
    calc(var(--crt-fringe) * -1) 0 rgba(255, 60, 60, 0.55),
    var(--crt-fringe) 0 rgba(60, 255, 255, 0.55),
    0 0 6px rgba(255, 255, 255, 0.25);
}

/* Scanlines, phosphor stripes, curved glass highlight and vignette */
.game-link::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  background:
    radial-gradient(ellipse 60% 40% at 18% 10%, rgba(255, 255, 255, var(--crt-glare)), transparent 70%),
    radial-gradient(ellipse at center, transparent 55%, rgba(0, 0, 0, var(--crt-vignette)) 100%),
    repeating-linear-gradient(0deg, rgba(0, 0, 0, var(--crt-scanlines)) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg,
      rgba(255, 0, 0, var(--crt-rgb)) 0 1px,
      rgba(0, 255, 0, var(--crt-rgb)) 1px 2px,
      rgba(0, 0, 255, var(--crt-rgb)) 2px 3px);
}

/* Rounded tube corners (the huge shadow paints everything outside the rounded rectangle),
   the dark edge of the glass, and moving film grain */
.game-link::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--crt-corner);
  box-shadow:
    inset 0 0 18px 4px rgba(0, 0, 0, 0.7),
    0 0 0 80px var(--crt-tube);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.13'/%3E%3C/svg%3E");
  animation: crtGrain 0.5s steps(1) infinite;
  pointer-events: none;
  z-index: 3;
}

/* Rolling refresh bar, sitting over the same area as the screen */
.tv::before {
  content: "";
  position: absolute;
  left: 5.7692%;    /* same rectangle as .game-link: 12 / 208 */
  top: 6.1224%;     /* 12 / 196 */
  width: 88.4615%;  /* 184 / 208 */
  height: 65.3061%; /* 128 / 196 */
  border-radius: var(--crt-corner);
  background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, var(--crt-roll)) 50%, transparent) 0 -30% / 100% 30% no-repeat;
  animation: crtRoll var(--crt-roll-time) linear infinite;
  pointer-events: none;
  z-index: 2;
}

@keyframes crtRoll {
  from { background-position-y: -30%; }
  to { background-position-y: 130%; }
}

/* The grain jumps to a new spot a few times a second, like static */
@keyframes crtGrain {
  0%   { background-position: 0 0; }
  20%  { background-position: -47px 31px; }
  40%  { background-position: 22px -63px; }
  60%  { background-position: -81px -12px; }
  80%  { background-position: 58px 74px; }
}

@keyframes crtFlicker {
  0%   { filter: contrast(1.08) saturate(1.15) brightness(calc(1.04 + var(--crt-flicker))); }
  25%  { filter: contrast(1.08) saturate(1.15) brightness(calc(1.04 - var(--crt-flicker))); }
  50%  { filter: contrast(1.08) saturate(1.15) brightness(1.04); }
  75%  { filter: contrast(1.08) saturate(1.15) brightness(calc(1.04 + var(--crt-flicker) * 0.5)); }
}

/* Channel change: the picture collapses to a bright line and snaps back open.
   indexGames.js adds .crt-switch to the TV for a moment on load and on every reroll. */
.tv.crt-switch .game-link {
  animation: crtSwitch 0.42s ease-out;
}

@keyframes crtSwitch {
  0%   { transform: scale(1, 1);       filter: brightness(1)   contrast(1.08); }
  30%  { transform: scale(1.03, 0.03); filter: brightness(4)   contrast(1.4); }
  50%  { transform: scale(1.01, 0.05); filter: brightness(3)   contrast(1.4); }
  75%  { transform: scale(1, 1.05);    filter: brightness(1.8) contrast(1.3); }
  100% { transform: scale(1, 1);       filter: contrast(1.08) saturate(1.15) brightness(1.04); }
}

@media (prefers-reduced-motion: reduce) {
  .game-link,
  .tv.crt-switch .game-link,
  .game-link::before,
  .tv::before {
    animation: none;
  }
}