/* Machine-directions. Marker art stays 1:1: no rotation, no redraw, no stretch. */

:root {
  --bg: #050806;
  --ink: #e7f3ec;
  --dim: rgba(231, 243, 236, 0.66);
  --faint: rgba(231, 243, 236, 0.4);
  --line: rgba(214, 232, 220, 0.22);
  --rec: #d24b42;
  --grade: grayscale(0.8) sepia(0.1) hue-rotate(75deg) saturate(0.5) contrast(1.24) brightness(0.9);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.92);
  --mono: "Cascadia Mono", "JetBrains Mono", "DejaVu Sans Mono", "WenQuanYi Micro Hei Mono", ui-monospace, monospace;
}

* { box-sizing: border-box; }

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
}

body {
  font-family: var(--mono);
  text-rendering: geometricPrecision;
  -webkit-font-smoothing: antialiased;
  touch-action: manipulation;
}

button,
p,
ul,
h2,
time { margin: 0; }

button {
  font: inherit;
  color: inherit;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

button:focus { outline: none; }

button:focus-visible {
  outline: 1px solid var(--ink);
  outline-offset: 3px;
}

img { -webkit-user-drag: none; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

main { width: 100%; height: 100%; }

.camera-feed {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  filter: var(--grade);
  opacity: 0;
  animation: feed-signal 13s steps(1) infinite;
}

.camera-feed::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(8, 19, 12, 0.1);
  mix-blend-mode: multiply;
}

.feed-a { z-index: 0; background-image: url("./assets/cctv-intersection.png"); }
.feed-b { z-index: 1; }
.camera-feed.visible { opacity: 1; }

.analysis-grid {
  position: absolute;
  z-index: 2;
  inset: 0;
  opacity: 0.045;
  background-image:
    linear-gradient(rgba(195, 211, 201, 0.28) 1px, transparent 1px),
    linear-gradient(90deg, rgba(195, 211, 201, 0.28) 1px, transparent 1px);
  background-size: 12.5% 16.666%;
  pointer-events: none;
}

.shade {
  position: absolute;
  z-index: 4;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0) 16%),
    linear-gradient(to top, rgba(0, 0, 0, 0.58), rgba(0, 0, 0, 0) 20%);
}

.photo-mat {
  position: absolute;
  z-index: 5;
  pointer-events: none;
  box-shadow: 0 0 0 1px rgba(214, 232, 220, 0.2);
}

.photo-mat[hidden] { display: none; }

.marker {
  position: absolute;
  z-index: 6;
  height: auto;
  object-fit: contain;
  image-rendering: crisp-edges;
  image-rendering: pixelated;
  filter: none;
  opacity: 0;
  translate: -50% -50%;
  pointer-events: auto;
  cursor: pointer;
  will-change: left, top, opacity;
}

.marker.is-visible { opacity: 0.96; }
.marker.reacquire { animation: reacquire 0.26s steps(3); }
.marker[hidden] { display: none; }

.signal-switch,
.video-dropout,
.overscan-frame { position: fixed; inset: 0; pointer-events: none; }

.signal-switch {
  z-index: 12;
  visibility: hidden;
  opacity: 0;
  background: #010201;
}

.signal-switch::before {
  content: "";
  position: absolute;
  inset: -15%;
  opacity: 0.42;
  mix-blend-mode: screen;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 160 160' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='s'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.92' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23s)'/%3E%3C/svg%3E");
  animation: switch-noise 0.07s steps(2) infinite;
}

.signal-switch::after {
  content: "";
  position: absolute;
  left: -4%;
  right: -4%;
  top: 42%;
  height: 10%;
  background: rgba(229, 242, 232, 0.22);
  box-shadow: 0 -4px 0 rgba(0, 0, 0, 0.92), 0 7px 0 rgba(0, 0, 0, 0.8);
  filter: blur(0.6px);
  animation: sync-tear 0.18s steps(3) infinite;
}

.signal-switch.active {
  visibility: visible;
  animation: channel-switch 0.62s steps(1) both;
}

.video-dropout {
  z-index: 11;
  opacity: 0;
  background: linear-gradient(
    180deg,
    transparent 0 46%,
    rgba(226, 238, 229, 0.28) 47%,
    rgba(0, 0, 0, 0.8) 48% 51%,
    transparent 52%
  );
  animation: dropout-band 12.7s steps(1) infinite;
}

.osd {
  position: fixed;
  z-index: 18;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding:
    max(22px, env(safe-area-inset-top))
    max(28px, env(safe-area-inset-right))
    max(16px, env(safe-area-inset-bottom))
    max(28px, env(safe-area-inset-left));
  pointer-events: none;
  user-select: none;
  text-shadow: var(--shadow);
}

.osd-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
}

.camera-label {
  font-size: clamp(22px, 2.5vw, 36px);
  line-height: 0.9;
  letter-spacing: 0.16em;
  font-weight: 400;
}

.place-label {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-top: 8px;
  font-size: clamp(11px, 1.05vw, 14px);
  letter-spacing: 0.16em;
  color: var(--dim);
}

.place-label .zh { letter-spacing: 0.08em; }

.tech-line {
  margin-top: 6px;
  font-size: clamp(10px, 0.9vw, 12px);
  letter-spacing: 0.18em;
  color: var(--faint);
}

.osd-rec { text-align: right; flex: none; }

.record-state {
  font-size: clamp(13px, 1.2vw, 16px);
  letter-spacing: 0.18em;
}

.record-dot {
  display: inline-block;
  width: 0.62em;
  height: 0.62em;
  margin-right: 0.45em;
  background: var(--rec);
  vertical-align: 0.02em;
  animation: record-blink 1.06s steps(1) infinite;
}

.osd-rec time {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 3px;
  margin-top: 8px;
  font-size: clamp(12px, 1.1vw, 15px);
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  color: var(--dim);
}

.readout {
  position: absolute;
  left: max(28px, env(safe-area-inset-left));
  bottom: calc(78px + env(safe-area-inset-bottom));
  text-align: left;
  pointer-events: none;
  max-width: calc(100vw - 36px);
}

.status-line {
  font-size: clamp(10px, 0.95vw, 12px);
  letter-spacing: 0.28em;
  color: var(--dim);
}

.direction-line {
  display: block;
  margin: 5px 0 0;
  pointer-events: auto;
  text-shadow: var(--shadow);
  font-size: clamp(16px, 1.9vw, 28px);
  letter-spacing: 0.08em;
  line-height: 1.15;
  white-space: nowrap;
}

.direction-line[aria-disabled="true"] { cursor: default; }

.transport {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 12px;
  pointer-events: none;
}

.channels,
.transport-actions {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  pointer-events: auto;
}

.ch,
.act {
  min-width: 48px;
  min-height: 44px;
  padding: 6px 8px 2px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  opacity: 0.4;
}

.ch[aria-pressed="true"],
.act[aria-pressed="true"],
.act[aria-expanded="true"] { opacity: 1; }

.ch:hover,
.act:hover,
.key-row:hover { opacity: 0.82; }

.ch[aria-pressed="true"] .ch-no {
  text-decoration: underline;
  text-underline-offset: 5px;
  text-decoration-thickness: 1px;
}

.ch-no,
.cmd {
  font-size: clamp(12px, 1.15vw, 15px);
  letter-spacing: 0.14em;
  line-height: 1;
}

.ch-name,
.cmd-zh {
  font-size: 10px;
  letter-spacing: 0.06em;
  line-height: 1;
  color: var(--dim);
}

.legend {
  position: absolute;
  top: 118px;
  left: max(28px, env(safe-area-inset-left));
  width: min(292px, calc(100vw - 36px));
  max-height: min(68vh, 540px);
  overflow: auto;
  padding: 12px 12px 14px;
  pointer-events: auto;
  background: rgba(3, 8, 5, 0.78);
  border: 1px solid var(--line);
  text-shadow: none;
  animation: legend-in 0.16s linear;
}

.legend h2 {
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.2em;
  color: var(--dim);
}

.legend-sub { margin-top: 14px; }

.key-list { margin-top: 4px; }

.key-row {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  width: 100%;
  min-height: 40px;
  padding: 5px 2px;
  text-align: left;
  opacity: 0.72;
  border-bottom: 1px solid rgba(214, 232, 220, 0.12);
}

.key-row[aria-pressed="true"] { opacity: 1; }

.key-row img {
  width: 28px;
  height: 28px;
  object-fit: contain;
  image-rendering: crisp-edges;
  image-rendering: pixelated;
}

.key-en {
  font-size: 12px;
  letter-spacing: 0.12em;
}

.key-zh {
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--dim);
}

.keys {
  list-style: none;
  padding: 8px 0 0;
  display: grid;
  gap: 5px;
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--dim);
}

kbd { letter-spacing: 0.08em; color: var(--ink); }

.legend-note {
  margin-top: 12px;
  font-size: 11px;
  line-height: 1.45;
  letter-spacing: 0.02em;
  color: var(--faint);
}

.cycle {
  position: fixed;
  z-index: 22;
  left: 0;
  right: 0;
  bottom: env(safe-area-inset-bottom);
  height: 2px;
  pointer-events: none;
  background: rgba(255, 255, 255, 0.05);
}

.cycle > span {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: rgba(214, 232, 220, 0.78);
}

body.is-held .cycle > span { opacity: 0.35; }

.overscan-frame {
  z-index: 19;
  box-shadow: inset 0 0 0 1px rgba(214, 232, 220, 0.08);
}

.crt-noise,
.crt-lines,
.crt-vignette {
  position: fixed;
  z-index: 20;
  inset: 0;
  pointer-events: none;
}

.crt-noise {
  opacity: 0.07;
  mix-blend-mode: screen;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.76' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: noise-shift 0.28s steps(2) infinite;
}

.crt-lines {
  opacity: 0.16;
  background:
    repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0 1px, transparent 1px 3px),
    linear-gradient(90deg, rgba(255, 0, 0, 0.025), transparent 32%, transparent 68%, rgba(40, 90, 255, 0.03));
  animation: line-roll 9s linear infinite;
}

.crt-vignette {
  box-shadow: inset 0 0 90px 16px rgba(0, 0, 0, 0.48);
}

body.legend-open .readout { visibility: hidden; }

.is-switching .osd { animation: osd-drop 0.62s steps(1); }

.noscript {
  position: fixed;
  z-index: 30;
  left: 16px;
  bottom: 16px;
  max-width: 280px;
  padding: 8px 10px;
  background: rgba(0, 0, 0, 0.78);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12px;
}

@keyframes feed-signal {
  0%, 94%, 100% { filter: var(--grade); }
  95% { filter: grayscale(0.74) sepia(0.08) hue-rotate(75deg) saturate(0.56) contrast(1.32) brightness(0.96); }
  96% { filter: grayscale(0.84) sepia(0.12) hue-rotate(75deg) saturate(0.44) contrast(1.18) brightness(0.84); }
}

@keyframes channel-switch {
  0% { opacity: 0.98; }
  12% { opacity: 0.38; }
  20% { opacity: 1; }
  35% { opacity: 0.18; }
  46% { opacity: 0.86; }
  61% { opacity: 0.24; }
  74% { opacity: 0.68; }
  88% { opacity: 0.12; }
  100% { opacity: 0; }
}

@keyframes switch-noise {
  0% { transform: translate(0) scale(1); }
  50% { transform: translate(-3%, 2%) scale(1.04); }
  100% { transform: translate(2%, -2%) scale(1.02); }
}

@keyframes sync-tear {
  0% { top: 12%; translate: 0 0; }
  33% { top: 63%; translate: 3% 0; }
  66% { top: 38%; translate: -2% 0; }
  100% { top: 81%; translate: 1% 0; }
}

@keyframes dropout-band {
  0%, 91%, 93%, 100% { opacity: 0; transform: translateY(-45%); }
  91.5% { opacity: 0.48; transform: translateY(-16%); }
  92% { opacity: 0.22; transform: translateY(27%); }
  92.5% { opacity: 0.38; transform: translateY(49%); }
}

@keyframes osd-drop {
  0%, 18%, 49%, 100% { opacity: 1; }
  19%, 31%, 50%, 58% { opacity: 0.12; }
  32%, 48%, 59%, 72% { opacity: 0.7; }
}

@keyframes record-blink {
  0%, 69% { opacity: 1; }
  70%, 100% { opacity: 0.28; }
}

@keyframes noise-shift {
  0% { transform: translate(0); }
  50% { transform: translate(-1px, 1px); }
  100% { transform: translate(1px, -1px); }
}

@keyframes line-roll {
  from { transform: translateY(-3px); }
  to { transform: translateY(3px); }
}

@keyframes reacquire {
  0% { opacity: 0; scale: 1.08; }
  42% { opacity: 1; scale: 0.97; }
  72% { opacity: 0.52; scale: 1.01; }
  100% { opacity: 0.96; scale: 1; }
}

@keyframes legend-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (max-width: 700px) {
  .osd {
    padding:
      max(14px, env(safe-area-inset-top))
      max(12px, env(safe-area-inset-right))
      max(12px, env(safe-area-inset-bottom))
      max(12px, env(safe-area-inset-left));
  }

  .camera-label { letter-spacing: 0.12em; }
  .place-label { letter-spacing: 0.08em; margin-top: 6px; }
  .tech-line { letter-spacing: 0.1em; }
  .readout {
    left: max(12px, env(safe-area-inset-left));
    bottom: calc(72px + env(safe-area-inset-bottom));
  }
  .direction-line { letter-spacing: 0.04em; }
  .ch, .act { min-width: 44px; padding: 6px 4px 2px; }
  .legend {
    top: auto;
    bottom: calc(84px + env(safe-area-inset-bottom));
    left: 12px;
    width: auto;
    right: 12px;
  }
  .crt-vignette { box-shadow: inset 0 0 56px 12px rgba(0, 0, 0, 0.5); }
}

@media (max-width: 380px) {
  .ch-name { display: none; }
  .osd-rec time { font-size: 11px; }
}

@media (max-height: 520px) {
  .camera-label { font-size: 18px; }
  .place-label,
  .tech-line { margin-top: 3px; }
  .readout { bottom: 62px; }
  .direction-line { font-size: 15px; }
  .legend { top: 72px; max-height: calc(100vh - 150px); }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }

  .signal-switch,
  .signal-switch.active {
    opacity: 0 !important;
    visibility: hidden !important;
  }

  .video-dropout { opacity: 0 !important; }
}
