:root{--bg:#101a14;--card:#16241c;--line:#24382c;--ink:#eef4ef;--dim:#93ac9c;--good:#2f9e6b;--bad:#c8202e;--warn:#d9a441;--in:#2f9e6b;--out:#c8202e;--break:#3d7fd6;--accent:#c8202e;--go:#2f9e6b;--on:#2f9e6b;--off:#24382c;--red:#c8202e;--gold:#d9a441;--tftred:#ed1a2c;--sunk:#0b120e}

body { position:relative; padding-bottom:64px; }

/* Snow, near layer. Bigger flakes, moving faster. */
body::before {
  content:"";
  position:fixed; inset:0; z-index:-1; pointer-events:none;
  background:
    radial-gradient(circle 3px at 12% 14%, rgba(255,255,255,.55) 99%, transparent 100%),
    radial-gradient(circle 2px at 31% 41%, rgba(255,255,255,.45) 99%, transparent 100%),
    radial-gradient(circle 3px at 67% 11%, rgba(255,255,255,.50) 99%, transparent 100%),
    radial-gradient(circle 2px at 88% 47%, rgba(255,255,255,.42) 99%, transparent 100%),
    radial-gradient(circle 3px at 48% 73%, rgba(255,255,255,.48) 99%, transparent 100%),
    radial-gradient(circle 2px at 19% 90%, rgba(255,255,255,.44) 99%, transparent 100%),
    radial-gradient(circle 3px at 76% 84%, rgba(255,255,255,.46) 99%, transparent 100%),
    radial-gradient(circle 2px at 57% 28%, rgba(255,255,255,.40) 99%, transparent 100%);
  background-repeat: repeat;
  background-size: 300px 420px;
  animation: snow-near 26s linear infinite;
}

/* Snow, far layer. Smaller, fainter, slower, drifting the other way, which is
   what gives it depth instead of one sheet sliding down the glass. */
.wrap::after {
  content:"";
  position:fixed; inset:0; z-index:-1; pointer-events:none;
  background:
    radial-gradient(circle 1px at 22% 8%,  rgba(255,255,255,.34) 99%, transparent 100%),
    radial-gradient(circle 1px at 44% 52%, rgba(255,255,255,.30) 99%, transparent 100%),
    radial-gradient(circle 1px at 72% 23%, rgba(255,255,255,.32) 99%, transparent 100%),
    radial-gradient(circle 1px at 8%  64%, rgba(255,255,255,.28) 99%, transparent 100%),
    radial-gradient(circle 1px at 91% 77%, rgba(255,255,255,.30) 99%, transparent 100%),
    radial-gradient(circle 1px at 36% 93%, rgba(255,255,255,.26) 99%, transparent 100%),
    radial-gradient(ellipse 900px 460px at 50% -12%, rgba(0,0,0,.42), transparent 60%),
    radial-gradient(ellipse 700px 420px at 50% 112%, rgba(0,0,0,.36), transparent 60%);
  background-repeat: repeat;
  background-size: 190px 260px;
  animation: snow-far 58s linear infinite;
}

@keyframes snow-near {
  from { background-position: 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0; }
  to   { background-position: 30px 420px, 30px 420px, 30px 420px, 30px 420px,
                              30px 420px, 30px 420px, 30px 420px, 30px 420px; }
}
@keyframes snow-far {
  from { background-position: 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0; }
  to   { background-position: -22px 260px, -22px 260px, -22px 260px, -22px 260px,
                              -22px 260px, -22px 260px, 0 0, 0 0; }
}

/* Candy stripe at the top, in the dead strip above the header, and a matching
   one pinned to the foot of the window. Neither crosses a character. */
body::after {
  content:"";
  position:fixed; top:0; left:0; right:0; height:10px; z-index:6;
  pointer-events:none;
  background: repeating-linear-gradient(-45deg,
    var(--tftred) 0 12px, #ffffff 12px 24px, var(--good) 24px 36px);
  box-shadow: 0 1px 6px rgba(0,0,0,.5);
}
.wrap::before {
  content:"";
  position:fixed; bottom:0; left:0; right:0; height:6px; z-index:6;
  pointer-events:none;
  background: repeating-linear-gradient(-45deg,
    var(--good) 0 12px, #ffffff 12px 24px, var(--tftred) 24px 36px);
  opacity:.85;
}

/* String lights under the header. One gradient that breathes, rather than a
   row of elements each blinking on its own timer. */
header {
  position:relative;
  padding-bottom:16px;
}
header::after {
  content:"";
  position:absolute; left:0; right:0; bottom:2px; height:9px;
  pointer-events:none;
  background:
    radial-gradient(circle 4px at 10px 4px, #ff6b6b 99%, transparent 100%),
    radial-gradient(circle 4px at 40px 4px, #ffd98a 99%, transparent 100%),
    radial-gradient(circle 4px at 70px 4px, #7fe3a4 99%, transparent 100%),
    radial-gradient(circle 4px at 100px 4px, #9fd4ff 99%, transparent 100%),
    linear-gradient(to bottom, transparent 3px, rgba(255,255,255,.16) 3px,
                    rgba(255,255,255,.16) 4px, transparent 4px);
  background-repeat: repeat-x, repeat-x, repeat-x, repeat-x, repeat-x;
  background-size: 120px 9px, 120px 9px, 120px 9px, 120px 9px, 120px 9px;
  animation: lights-breathe 4.5s ease-in-out infinite;
}
@keyframes lights-breathe {
  0%, 100% { opacity:.55; }
  50%      { opacity:1; }
}

/* Snow settled along the top of every card, over the garland. */
.card, .tile, .whpanel, .setup, .sug-form, .calc, .msgbox {
  box-shadow: inset 0 3px 0 0 var(--tftred),
              inset 0 7px 6px -4px rgba(255,255,255,.22);
}

/* The button people press all day gets to look like a present. */
.submitbtn, button.go, .saverow button, .acts button.in {
  background-image: linear-gradient(135deg,
    var(--good) 0%, var(--good) 46%,
    rgba(255,255,255,.22) 50%,
    var(--good) 54%, var(--good) 100%);
}

@media (prefers-reduced-motion: reduce) {
  body::before, .wrap::after { animation: none; background-position: 0 0; }
  header::after { animation: none; opacity:.8; }
}
