/* ============================================================
   game.css — the office, the camera feeds, the HUD
   ============================================================ */

#game-screen{
  width:100%; height:100%;
  align-items:stretch; justify-content:flex-start;
  background:var(--bg);
}

.cam-area{
  position:relative;
  flex:1; min-height:0;
  overflow:hidden;
  background:#000;
  cursor:default;
}
.cam-area.pannable{ cursor:ew-resize; }

.room{ position:absolute; inset:0; display:none; }
.room.showing{ display:block; }

/* ============================================================
   THE OFFICE
   The doorway hotspots were measured against the 760x760 photo,
   so the photo gets its own square "stage" that is letterboxed to
   fit. Overlay percentages then line up with the picture on every
   aspect ratio instead of drifting into the black bars.
   ============================================================ */
.office-view{ background:#040302; }

.office-backdrop{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover;
  filter:blur(24px) brightness(0.5) saturate(0.85);
  transform:scale(1.25);
  pointer-events:none;
}

.office-view{ overflow:hidden; }

.office-stage{
  position:absolute; inset:0; margin:auto;
  aspect-ratio:1 / 1;
  width:auto; height:100%;
  max-width:100%; max-height:100%;
}
/* very tall / narrow viewports: let width lead instead of height */
@media (max-aspect-ratio: 1/1){
  .office-stage{ width:100%; height:auto; }
}
/* Wide and short — a phone held sideways. Containing a square picture in a
   3:1 frame leaves the room as a small tile floating in blur. Overscale it
   and let the crop come off the top, where there is only ceiling: the
   doorways, both figures and the whole desk stay in shot. */
@media (min-aspect-ratio: 5/3){
  .office-stage{
    inset:auto auto 0 50%;
    margin:0;
    height:126%; width:auto;
    max-height:none;
    transform:translateX(-50%);
  }
}

.office-photo{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover;
  display:block;
  background:#000;
  filter:brightness(0.78) contrast(1.06);
  transition:filter 0.14s ease;
}
.office-view.lit-left .office-photo,
.office-view.lit-right .office-photo{ filter:brightness(1.42) contrast(1.02) saturate(1.04); }

.office-vignette{
  position:absolute; inset:0; pointer-events:none; z-index:6;
  box-shadow:inset 0 0 160px 60px rgba(0,0,0,0.78);
}

/* ---------------- doors ---------------- */
.office-stage{ perspective:1100px; perspective-origin:50% 45%; }

.door-panel{
  position:absolute; z-index:4;
  background-repeat:no-repeat;
  background-size:100% 100%;
  background-position:center;
  filter:drop-shadow(0 6px 20px rgba(0,0,0,0.8));
  backface-visibility:hidden;
  opacity:0; visibility:hidden;
  transition:transform 0.34s cubic-bezier(.25,.75,.35,1),
             filter 0.34s ease,
             opacity 0.1s ease 0.24s,
             visibility 0s linear 0.34s;
}
.door-panel.left{
  left:5.26%; width:15.53%; top:11.58%; height:80.79%;
  background-image:url('../../assets/img/door-left.png');
  transform-origin:left center;
  transform:rotateY(-104deg);
}
.door-panel.right{
  left:80.53%; width:14.47%; top:11.58%; height:80.79%;
  background-image:url('../../assets/img/door-right.png');
  transform-origin:right center;
  transform:rotateY(104deg);
}
.door-panel.closed{
  opacity:1; visibility:visible;
  filter:drop-shadow(0 6px 20px rgba(0,0,0,0.8)) brightness(0.82);
  transform:rotateY(0deg);
  transition:transform 0.34s cubic-bezier(.25,.75,.35,1),
             filter 0.34s ease,
             opacity 0.08s ease,
             visibility 0s linear 0s;
}
@media (prefers-reduced-motion: reduce){
  .door-panel,
  .door-panel.closed{
    transform:none !important;
    transition:opacity 0.12s ease, visibility 0s linear 0s;
  }
}

/* ---------------- doorway lights ---------------- */
.light-beam{
  position:absolute; inset:0; z-index:3;
  pointer-events:none; opacity:0;
  transition:opacity 0.09s ease;
  mix-blend-mode:screen;
}
.light-beam.left{
  background:
    radial-gradient(ellipse 24% 60% at 13% 52%,
      rgba(255,248,214,0.88) 0%, rgba(255,248,214,0.44) 45%, transparent 78%),
    radial-gradient(ellipse 46% 52% at 30% 55%,
      rgba(255,246,205,0.30) 0%, transparent 76%);
}
.light-beam.right{
  background:
    radial-gradient(ellipse 24% 60% at 87% 52%,
      rgba(255,248,214,0.88) 0%, rgba(255,248,214,0.44) 45%, transparent 78%),
    radial-gradient(ellipse 46% 52% at 70% 55%,
      rgba(255,246,205,0.30) 0%, transparent 76%);
}
.light-beam.on{ opacity:1; }
/* a light that is flickering out reads as failing hardware, not as a bug */
.light-beam.flicker{ animation:lightFlicker 0.32s steps(2) infinite; }
@keyframes lightFlicker{ 0%,100%{ opacity:1; } 50%{ opacity:0.28; } }

/* ---------------- someone standing in a doorway ---------------- */
.doorway-figure{
  position:absolute; z-index:5;
  bottom:8%; width:14%;
  opacity:0; pointer-events:none;
  transition:opacity 0.16s ease;
  filter:brightness(0.28) saturate(0.45) drop-shadow(0 8px 14px rgba(0,0,0,0.9));
}
.doorway-figure.left{ left:6.4%; }
.doorway-figure.right{ left:81%; }
.doorway-figure img{ display:block; width:100%; height:auto; }
.doorway-figure.visible{ opacity:1; }
/* he only truly reads as "there" once the light actually reaches him */
.office-view.lit-left  .doorway-figure.left,
.office-view.lit-right .doorway-figure.right{
  filter:brightness(1.08) contrast(1.1) saturate(1) drop-shadow(0 8px 18px rgba(0,0,0,0.95));
}

/* Entity identity.
   One silhouette has to read as three different things, and hue alone
   cannot do it: the camera feed runs at saturate(0.4), and a colour-blind
   player has nothing to go on either way. Each one gets a distinct
   *value* and outline as well as a distinct hue:
     GUNNER  — as photographed, warm, normal contrast
     SHADE   — crushed to a flat black cut-out with a violet rim
     HOLLOW  — blown out, high contrast, hard amber rim */
.ent-gunner img{
  filter:contrast(1.05) drop-shadow(0 0 3px rgba(93,255,143,0.5));
}
.ent-shade img{
  filter:grayscale(1) brightness(0.18) contrast(2.4)
         drop-shadow(0 0 2px rgba(185,140,255,0.95))
         drop-shadow(0 0 9px rgba(185,140,255,0.65));
}
.ent-hollow img{
  filter:grayscale(1) brightness(1.9) contrast(2.2)
         drop-shadow(0 0 2px rgba(255,138,61,0.95))
         drop-shadow(0 0 9px rgba(255,138,61,0.6));
}

/* ---------------- power-out sequence ---------------- */
.power-out-eyes{
  position:absolute; inset:0; z-index:7;
  display:none; pointer-events:none;
  background:#000;
}
.power-out-eyes.on{ display:block; }
.power-out-eyes::before,
.power-out-eyes::after{
  content:"";
  position:absolute; top:46%;
  width:2.6vmin; height:1.5vmin;
  border-radius:50% 50% 45% 45%;
  background:radial-gradient(ellipse at 50% 40%, #ffffff 0%, var(--nv) 45%, #0d5b2c 100%);
  box-shadow:0 0 22px 7px rgba(93,255,143,0.45);
  animation:eyeBlink 1.7s steps(1) infinite;
}
.power-out-eyes::before{ left:calc(50% - 3.4vmin); transform:rotate(-4deg); }
.power-out-eyes::after{ left:calc(50% + 0.8vmin); transform:rotate(4deg); }
@keyframes eyeBlink{ 0%,72%{ opacity:1; } 74%,80%{ opacity:0; } 82%,100%{ opacity:1; } }

/* ============================================================
   CAMERA FEEDS
   ============================================================ */
.cam-feeds{ position:absolute; inset:0; }

.cam-frame{ position:absolute; inset:0; overflow:hidden; background:#000; }
/* the plate carries the pan so the photo and anyone standing in it move together */
.cam-plate{
  position:absolute; inset:0;
  transform:scale(1.16) translateX(var(--pan, 0%));
  transition:transform 0.28s ease;
  will-change:transform;
}
.cam-plate.dragging{ transition:none; }

.cam-photo{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover; display:block;
  background:#000;
}
.cam-plate svg{ position:absolute; inset:0; width:100%; height:100%; display:block; }

/* night-vision grade */
.nv-filter{ filter:brightness(0.44) contrast(1.35) saturate(0.4) sepia(0.25) hue-rotate(70deg); }

.cam-figure{
  position:absolute;
  opacity:0; z-index:2;
  transition:opacity 0.4s ease;
  filter:drop-shadow(0 8px 14px rgba(0,0,0,0.8));
}
.cam-figure.visible{ opacity:1; }
.cam-figure img{ display:block; width:100%; height:auto; }

.nv-tint{
  position:absolute; inset:0; pointer-events:none; z-index:3;
  background:radial-gradient(ellipse at 50% 45%,
    rgba(93,255,143,0.16) 0%, rgba(0,0,0,0.55) 78%);
  mix-blend-mode:screen;
}
.nv-noise{
  position:absolute; inset:0; pointer-events:none; z-index:3;
  opacity:0.10; mix-blend-mode:overlay;
  background-image:
    repeating-radial-gradient(circle at 20% 30%, rgba(255,255,255,0.5) 0px, transparent 1px),
    repeating-radial-gradient(circle at 70% 60%, rgba(255,255,255,0.4) 0px, transparent 1px);
  background-size:3px 3px, 4px 4px;
  animation:noiseshift 0.4s steps(2) infinite;
}
@keyframes noiseshift{
  from{ background-position:0 0, 0 0; }
  to{ background-position:4px 3px, -3px 4px; }
}
.scanlines{
  position:absolute; inset:0; pointer-events:none; z-index:3;
  background-image:repeating-linear-gradient(0deg,
    rgba(0,0,0,0.28) 0px, rgba(0,0,0,0.28) 1px, transparent 2px, transparent 4px);
  mix-blend-mode:multiply;
}
.cam-vignette{
  position:absolute; inset:0; pointer-events:none; z-index:3;
  box-shadow:inset 0 0 130px 50px rgba(0,0,0,0.92);
}

.cam-label{
  position:absolute; top:calc(12px + var(--safe-t)); left:calc(54px + var(--safe-l));
  z-index:4; font-size:0.74rem; letter-spacing:0.08em;
  color:var(--nv); text-shadow:0 0 6px rgba(0,0,0,0.9);
}
.cam-label::before{ content:"● REC "; color:var(--red); }
.cam-timestamp{
  position:absolute; top:calc(29px + var(--safe-t)); left:calc(54px + var(--safe-l));
  z-index:4; font-size:0.68rem; color:var(--nv); opacity:0.75;
}

/* dropout: the feed loses signal for a beat */
.cam-static{
  position:absolute; inset:0; z-index:5;
  opacity:0; pointer-events:none;
  background:
    repeating-linear-gradient(0deg,
      rgba(255,255,255,0.10) 0px, rgba(255,255,255,0.10) 2px,
      rgba(0,0,0,0.55) 2px, rgba(0,0,0,0.55) 4px),
    #0a0d0a;
  transition:opacity 0.1s ease;
}
.cam-frame.dropout .cam-static{ opacity:1; animation:staticRoll 0.18s steps(3) infinite; }
@keyframes staticRoll{
  from{ background-position:0 0, 0 0; }
  to{ background-position:0 7px, 0 0; }
}
.cam-frame.dropout .cam-label::after{
  content:" — SIGNAL LOST"; color:var(--red);
}

.glitch{ animation:glitchflick 0.12s steps(2) 1; }
@keyframes glitchflick{
  0%,100%{ opacity:1; }
  50%{ opacity:0.2; filter:invert(0.1); }
}

/* ============================================================
   HUD
   ============================================================ */
.hud-time{
  position:absolute; z-index:11;
  top:calc(10px + var(--safe-t)); right:calc(14px + var(--safe-r));
  font-family:var(--font-pixel); text-align:right; line-height:1.05;
  color:#fff; text-shadow:0 2px 6px rgba(0,0,0,0.95);
  pointer-events:none;
}
.hud-time .clock{ display:block; font-size:clamp(1.5rem, 4.4vw, 2.2rem); }
.hud-time .night{ display:block; font-size:clamp(0.95rem, 2.6vw, 1.3rem); opacity:0.92; }

.hud-power{
  position:absolute; z-index:11;
  bottom:calc(12px + var(--safe-b)); left:calc(14px + var(--safe-l));
  font-family:var(--font-pixel);
  color:#fff; text-shadow:0 2px 6px rgba(0,0,0,0.95);
  pointer-events:none;
}
.hud-power .plabel{ font-size:clamp(0.95rem, 2.5vw, 1.25rem); }
.hud-power .pnum{ font-size:clamp(1.25rem, 3.4vw, 1.7rem); }
.hud-power.critical .pnum{ color:var(--red); animation:powerPulse 1s ease-in-out infinite; }
@keyframes powerPulse{ 0%,100%{ opacity:1; } 50%{ opacity:0.42; } }

.usage-row{ display:block; margin-top:2px; }
.usage-row .ulabel{ font-size:clamp(0.85rem, 2.2vw, 1.05rem); opacity:0.9; }
.usage-bars{ display:inline-flex; gap:3px; vertical-align:middle; margin-left:6px; }
.usage-bars i{
  display:block; width:9px; height:15px;
  background:#2a2f26; border:1px solid #000;
  transition:background 0.2s ease;
}
.usage-bars i.on{ background:#39d13a; }
.usage-bars i.on.warm{ background:#e0c020; }
.usage-bars i.on.hot{ background:#e0392b; }

#power-bar-outer{
  display:block; margin-top:5px;
  width:120px; height:12px;
  border:1px solid rgba(0,0,0,0.8);
  background:#141610;
}
#power-bar-inner{
  display:block; height:100%; width:100%;
  background:#39d13a;
  transition:width 0.4s linear, background 0.4s linear;
}

.cam-hint{
  position:absolute; z-index:8;
  left:50%; bottom:calc(8% + var(--safe-b));
  transform:translateX(-50%);
  margin:0; padding:0 16px;
  max-width:min(380px, 84vw);
  text-align:center; line-height:1.6;
  font-size:0.8rem; color:var(--paper-dim);
  text-shadow:0 2px 6px rgba(0,0,0,0.95);
  pointer-events:none;
  opacity:0; transition:opacity 0.3s ease;
}
.cam-hint.show{ opacity:1; }

/* screen shake, used sparingly */
.shake{ animation:shake 0.4s cubic-bezier(.36,.07,.19,.97) both; }
@keyframes shake{
  10%,90%{ transform:translate3d(-2px,0,0); }
  20%,80%{ transform:translate3d(4px,0,0); }
  30%,50%,70%{ transform:translate3d(-7px,0,0); }
  40%,60%{ transform:translate3d(7px,0,0); }
}

/* ============================================================
   Threat pulse.

   The only tell that something had reached a doorway used to be an audio
   cue, which made the game unplayable with the sound off — and phones are
   muted by default. This says that something is at *a* doorway. It
   deliberately does not say which one, or which of the three it is:
   finding that out is what the doorway lights are for, and that is the
   decision the whole power economy rests on.
   ============================================================ */
.cam-area::after{
  content:"";
  position:absolute; inset:0;
  z-index:7; pointer-events:none;
  opacity:0;
  box-shadow:inset 0 0 90px 18px rgba(224,57,43,0.42);
  transition:opacity 0.5s ease;
}
.cam-area.threat::after{ opacity:1; animation:threatPulse 1.9s ease-in-out infinite; }
@keyframes threatPulse{ 0%,100%{ opacity:0.35; } 50%{ opacity:1; } }
body.safe-mode .cam-area.threat::after{ animation:none; opacity:0.7; }

/* The tablet covers the lower half of the frame; a hint pinned near the
   bottom would sit behind it. */
body.cams-up .cam-hint{ opacity:0 !important; }
