/* T4b: the in-game chat, drawn at a fixed 1280×830 and mapped onto the laptop screen
   with a matrix3d homography (see homography.js). Style 2 "shooter" from tools/mock-chat.html?v=2. */
.chat {
  position: fixed; left: 0; top: 0; width: 1280px; height: 830px; box-sizing: border-box;
  transform-origin: 0 0; background: #0a0c0a; color: #d4d4d4; overflow: hidden;
  font: 16px Consolas, "DejaVu Sans Mono", Menlo, "Liberation Mono", monospace;
  -webkit-font-smoothing: antialiased; font-variant-ligatures: none;
  --bar-h: 48px;
  opacity: 0; visibility: hidden; transition: opacity 200ms ease-out, visibility 0s linear 200ms;
}
.chat.on { opacity: 1; visibility: visible; transition: opacity 200ms ease-out, visibility 0s; }
.chat .vid {
  position: absolute; top: 18px; right: 18px; width: 330px; height: 190px; box-sizing: border-box;
  border: 1px solid #9bd35a; border-radius: 4px; overflow: hidden;
  background: radial-gradient(ellipse at 40% 45%, #172014, #0d110c 70%), #0a0c0a;
  /* C11: the log runs full width under the box. The box sits on top with an opaque 14 px
     #0a0c0a margin, so a line that scrolls up passes under it and is hidden, like a game HUD. */
  z-index: 2; box-shadow: 0 0 0 14px #0a0c0a, -14px 14px 0 0 #0a0c0a; /* 2nd shadow squares the bottom-left corner */
}
/* Improve 06:41: the empty box reads as a dead camera feed, not a missing element, until T6
   puts the gameplay video in. Everything moves with transform/opacity only (compositor, no
   repaint): static noise jumps at 10 Hz, one faint bar rolls down in 3.4 s, the LIVE dot pulses. */
.chat .vid::before { /* scanlines, over the noise */
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: repeating-linear-gradient(to bottom, rgba(0,0,0,0) 0 2px, rgba(0,0,0,0.32) 2px 3px);
}
.chat .vid .noise {
  position: absolute; inset: -64px; opacity: 0.14;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='128' height='128'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .62 0 0 0 0 .83 0 0 0 0 .36 0 0 0 2.2 -.75'/%3E%3C/filter%3E%3Crect width='128' height='128' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: vid-noise 400ms steps(1) infinite;
}
@keyframes vid-noise {
  0% { transform: translate(0, 0); } 25% { transform: translate(-37px, 21px); }
  50% { transform: translate(18px, -44px); } 75% { transform: translate(-52px, -9px); }
}
.chat .vid .roll {
  position: absolute; left: 0; right: 0; top: 0; height: 46px; z-index: 1;
  background: linear-gradient(to bottom, transparent, rgba(155, 211, 90, 0.07) 60%, transparent);
  animation: vid-roll 3400ms linear infinite;
}
@keyframes vid-roll { from { transform: translateY(-46px); } to { transform: translateY(190px); } }
/* viewfinder corners: 12 px L marks, 10 px in from each corner */
.chat .vid .fr {
  position: absolute; inset: 10px; z-index: 2; pointer-events: none; --c: rgba(155, 211, 90, 0.45);
  background:
    linear-gradient(var(--c), var(--c)) left top / 12px 1px, linear-gradient(var(--c), var(--c)) left top / 1px 12px,
    linear-gradient(var(--c), var(--c)) right top / 12px 1px, linear-gradient(var(--c), var(--c)) right top / 1px 12px,
    linear-gradient(var(--c), var(--c)) left bottom / 12px 1px, linear-gradient(var(--c), var(--c)) left bottom / 1px 12px,
    linear-gradient(var(--c), var(--c)) right bottom / 12px 1px, linear-gradient(var(--c), var(--c)) right bottom / 1px 12px;
  background-repeat: no-repeat;
}
.chat .vid .live {
  position: absolute; top: 8px; left: 10px; z-index: 3; display: flex; align-items: center; gap: 5px;
  padding: 1px 6px 1px 5px; border-radius: 2px;
  font: 700 10px/1.5 "DejaVu Sans", Arial, sans-serif; letter-spacing: 0.08em; color: #fff; background: #e0262b;
}
.chat .vid .live .dot { width: 5px; height: 5px; border-radius: 50%; background: #fff; animation: vid-dot 1200ms ease-in-out infinite; }
@keyframes vid-dot { 50% { opacity: 0.25; } }
.chat .vid .nosig {
  position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
}
.chat .vid .nosig b {
  font-weight: 700; font-size: 15px; letter-spacing: 0.32em; margin-right: -0.32em; color: #7d9a62;
  padding: 3px 10px; background: rgba(10, 12, 10, 0.78); text-shadow: 0 0 8px rgba(155, 211, 90, 0.35);
}
.chat .vid .nosig small { font-size: 11px; letter-spacing: 0.14em; color: #4f6145; text-shadow: 0 0 3px #0a0c0a, 0 0 6px #0a0c0a; }
.chat .vid .cam { position: absolute; left: 28px; bottom: 12px; z-index: 3; font-size: 10px; letter-spacing: 0.16em; color: #4b5c42; }
@media (prefers-reduced-motion: reduce) { .chat .vid .noise, .chat .vid .roll, .chat .vid .live .dot { animation: none; } }
/* Glass: a faint sheen from the top left and a soft dark edge, so the screen reads as a lit
   panel and not a flat black box. pointer-events off, drawn over the log and under nothing. */
.chat::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 3;
  background: linear-gradient(128deg, rgba(255,255,255,0.045) 0%, rgba(255,255,255,0.012) 28%, transparent 46%);
  box-shadow: inset 0 0 90px rgba(0,0,0,0.55), inset 0 0 0 1px rgba(255,255,255,0.03);
}
.chat .log {
  position: absolute; left: 28px; right: 28px; top: 24px; bottom: calc(var(--bar-h) + 42px);
  transition: bottom 120ms ease-out;
  display: flex; flex-direction: column; justify-content: flex-end; overflow: hidden;
  line-height: 1.4;
  /* old lines fade out at the top edge instead of being cut by it */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 56px);
          mask-image: linear-gradient(to bottom, transparent 0, #000 56px);
}
/* One line = a grid row (0fr → 1fr opens it, so the lines above glide up) holding .x. */
.chat .l { display: grid; grid-template-rows: 1fr; flex: none; }
.chat .l > .x {
  min-height: 0; overflow: hidden; padding: 3px 8px 3px calc(6ch + 8px); margin: 0 -8px;
  text-indent: -6ch; /* hanging indent: a wrapped line starts under the [All] tag, not under the time */
  overflow-wrap: anywhere; white-space: pre-wrap; border-radius: 2px;
}
.chat .l.in { animation: line-open 150ms cubic-bezier(.2, .8, .2, 1); }
.chat .l.in > .x { animation: line-flash 900ms cubic-bezier(.3, 0, .2, 1); }
.chat .l.in.k-me > .x { --flash: rgba(232, 232, 74, 0.13); }
.chat .l.in.k-foe > .x { --flash: rgba(255, 107, 61, 0.16); }
.chat .l.in.k-sys > .x { --flash: rgba(127, 211, 255, 0.12); }
@keyframes line-open { from { grid-template-rows: 0fr; opacity: 0; } to { grid-template-rows: 1fr; opacity: 1; } }
@keyframes line-flash { from { background: var(--flash, transparent); } to { background: transparent; } }
@media (prefers-reduced-motion: reduce) { .chat .l.in, .chat .l.in > .x { animation: none; } }
.chat .t { color: #6a6a6a; margin-right: 1ch; }
.chat .all { color: #9bd35a; }
.chat .me { color: #e8e84a; }
.chat .foe { color: #ff6b3d; }
.chat .sys { color: #7fd3ff; }
.chat .l.dim .sys { color: #555; }
.chat .inp {
  position: absolute; left: 28px; right: 28px; bottom: 26px; height: var(--bar-h); box-sizing: border-box;
  display: flex; align-items: center; gap: 14px; padding: 0 14px;
  background: #111; border: 1px solid #3a3a3a;
}
/* The bar is bottom-anchored, so a taller bar grows upward. */
.chat .inp { transition: height 120ms ease-out, border-color 120ms, box-shadow 120ms; }
.chat .inp.focus { border-color: #6b8f45; box-shadow: 0 0 0 1px rgba(155, 211, 90, 0.18), 0 0 18px rgba(155, 211, 90, 0.07); }
/* [All] and the counter sit on the first text line; wrapped text hangs under the text start. */
.chat .inp .to, .chat .inp .count { align-self: flex-start; line-height: 24px; margin-top: 11px; }
.chat .inp .to { color: #9bd35a; flex: none; }
.chat .inp textarea {
  flex: 1; min-width: 0; height: 24px; background: transparent; border: 0; outline: 0; padding: 0; margin: 0;
  font: inherit; line-height: 24px; color: #d4d4d4; caret-color: #e8e84a;
  resize: none; overflow: hidden; white-space: pre-wrap; overflow-wrap: anywhere; display: block;
}
.chat .inp textarea::placeholder { color: #666; }
.chat .inp .count { flex: none; color: #6a6a6a; font-size: 14px; min-width: 64px; text-align: right; }
.chat .inp .count.hot { color: #ff6b3d; }
/* C15: a 30+ char token breaks mid-row (see textHtml in chat.js). */
.chat .brk { word-break: break-all; }
/* C15: the 160 cap. Border flashes #ff6b3d (150 ms in, 450 ms out), counter bold #ff6b3d 600 ms. */
.chat .inp.cap { animation: cap-flash 600ms linear; }
.chat .inp.cap .count { color: #ff6b3d; font-weight: 700; }
@keyframes cap-flash {
  /* only the peak: start and end come from the bar's own (focus) style */
  25% { border-color: #ff6b3d; box-shadow: 0 0 0 1px rgba(255, 107, 61, 0.35), 0 0 18px rgba(255, 107, 61, 0.12); animation-timing-function: ease-out; }
}
/* T7b1: waiting caret, a 1-char block after the last system line, 530 ms on / 530 ms off. */
.chat .caret {
  display: inline-block; width: 1ch; height: 1.05em; margin-left: 1ch; vertical-align: -0.15em;
  background: #7fd3ff; animation: caret-blink 1060ms steps(1) infinite;
}
@keyframes caret-blink { 50% { opacity: 0; } }
/* T7b2: the "New room" link after Room is full / Room not found; the input greys out. */
.chat .newroom { color: #9bd35a; text-decoration: underline; text-underline-offset: 3px; margin-left: 1ch; }
.chat .newroom:hover { color: #0a0c0a; background: #9bd35a; text-decoration: none; }
.chat .inp.off { opacity: 0.45; }
.chat .inp.off textarea::placeholder { color: #444; }
/* Improve 05:41: the waiting queue panel. Centred in the empty screen above the log, opaque,
   so after a foe leaves it also reads over old lines. 250 ms fade + 6 px rise in, 200 ms out. */
.chat .lobby {
  position: absolute; left: 50%; top: 250px; width: 600px; margin-left: -300px; box-sizing: border-box;
  padding: 30px 36px 26px; text-align: center; z-index: 1; pointer-events: none;
  background: #0a0c0a; border: 1px solid #243220; border-radius: 2px;
  box-shadow: 0 0 0 6px #0a0c0a, 0 0 60px rgba(155, 211, 90, 0.05);
  opacity: 0; transform: translateY(6px);
  transition: opacity 200ms ease-in, transform 200ms ease-in;
}
.chat .lobby.on { opacity: 1; transform: none; transition: opacity 250ms cubic-bezier(.2,.8,.2,1) 150ms, transform 250ms cubic-bezier(.2,.8,.2,1) 150ms; }
.chat .lobby .q-title { color: #9bd35a; font-size: 20px; font-weight: 700; letter-spacing: 0.32em; margin-right: -0.32em; }
.chat .lobby .q-time { color: #e6e6e6; font-size: 64px; line-height: 1; margin: 18px 0 20px; letter-spacing: 0.06em; font-variant-numeric: tabular-nums; }
/* 16 cells; a lit cell sweeps left to right (1.6 s), each cell fades 480 ms behind it. */
.chat .lobby .q-scan { display: flex; gap: 5px; justify-content: center; margin-bottom: 22px; }
.chat .lobby .q-scan i { width: 22px; height: 5px; background: #1c2618; animation: q-scan 1600ms linear infinite; }
.chat .lobby .q-scan i:nth-child(1) { animation-delay: 0ms; }
.chat .lobby .q-scan i:nth-child(2) { animation-delay: 100ms; }
.chat .lobby .q-scan i:nth-child(3) { animation-delay: 200ms; }
.chat .lobby .q-scan i:nth-child(4) { animation-delay: 300ms; }
.chat .lobby .q-scan i:nth-child(5) { animation-delay: 400ms; }
.chat .lobby .q-scan i:nth-child(6) { animation-delay: 500ms; }
.chat .lobby .q-scan i:nth-child(7) { animation-delay: 600ms; }
.chat .lobby .q-scan i:nth-child(8) { animation-delay: 700ms; }
.chat .lobby .q-scan i:nth-child(9) { animation-delay: 800ms; }
.chat .lobby .q-scan i:nth-child(10) { animation-delay: 900ms; }
.chat .lobby .q-scan i:nth-child(11) { animation-delay: 1000ms; }
.chat .lobby .q-scan i:nth-child(12) { animation-delay: 1100ms; }
.chat .lobby .q-scan i:nth-child(13) { animation-delay: 1200ms; }
.chat .lobby .q-scan i:nth-child(14) { animation-delay: 1300ms; }
.chat .lobby .q-scan i:nth-child(15) { animation-delay: 1400ms; }
.chat .lobby .q-scan i:nth-child(16) { animation-delay: 1500ms; }
@keyframes q-scan { 0% { background: #9bd35a; box-shadow: 0 0 8px rgba(155,211,90,.55); } 30% { background: #1c2618; box-shadow: none; } 100% { background: #1c2618; } }
.chat .lobby .q-link { color: #7fd3ff; font-size: 18px; overflow-wrap: anywhere; }
.chat .lobby .q-hint { color: #6a6a6a; font-size: 14px; margin-top: 8px; }
@media (prefers-reduced-motion: reduce) { .chat .lobby .q-scan i { animation: none; } }
.chat .l > .x { transition: opacity 250ms ease-out; }
.chat .l.past > .x { opacity: 0.3; }
