/* =============================================================================
 *  FELIS_CRYPTA — the gate.  Hacker / CTF decryption-terminal aesthetic.
 *  Mobile-first (360–414px), scales up. No framework. Phosphor-green console.
 * ===========================================================================*/

:root {
  --bg:      #05080a;
  --bg-term: rgba(6,11,9,.93);
  --green:   #4dff7c;
  --green-b: #9dffba;   /* bright */
  --green-d: #1c6b37;   /* dim */
  --amber:   #ffb340;
  --red:     #ff4d52;
  --cyan:    #46d7ff;
  --mute:    #3f6f52;
  --line:    rgba(77,255,124,.22);

  --glow:    0 0 6px rgba(77,255,124,.55);
  --glow-a:  0 0 8px rgba(255,179,64,.7);
  --glow-r:  0 0 8px rgba(255,77,82,.7);

  --mono: "JetBrains Mono", ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; }
html, body {
  margin: 0; height: 100%;
  background: var(--bg); color: var(--green);
  font-family: var(--mono);
  overflow: hidden; overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}

/* matrix rain canvas, far background */
#matrix { position: fixed; inset: 0; z-index: 0; opacity: .13; pointer-events: none; }

#stage {
  position: fixed; inset: 0; z-index: 1;
  display: flex; align-items: center; justify-content: center;
  padding: calc(var(--safe-t) + 10px) 10px calc(var(--safe-b) + 10px);
}

/* ===========================================================================
 *  Terminal window
 * ===========================================================================*/
.term-window {
  width: 100%; max-width: 680px;
  height: min(88vh, 760px);
  display: flex; flex-direction: column;
  background: var(--bg-term);
  border: 1px solid rgba(77,255,124,.35);
  border-radius: 10px; overflow: hidden;
  box-shadow: 0 0 0 1px rgba(0,0,0,.5), 0 24px 70px rgba(0,0,0,.7),
              0 0 60px rgba(77,255,124,.10), inset 0 0 60px rgba(0,0,0,.5);
  backdrop-filter: blur(2px);
}
.titlebar {
  flex: 0 0 auto; display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; background: rgba(10,16,12,.9);
  border-bottom: 1px solid var(--line);
}
.dots { display: inline-flex; gap: 6px; }
.dots i { width: 11px; height: 11px; border-radius: 50%; background: #2a3a30; }
.dots i:nth-child(1){ background:#ff5f56; } .dots i:nth-child(2){ background:#ffbd2e; } .dots i:nth-child(3){ background:#27c93f; }
.ttl {
  flex: 1; min-width: 0; font-size: 11.5px; color: var(--mute);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: center;
}
.ttl-status { font-size: 11px; color: var(--red); text-shadow: var(--glow-r); white-space: nowrap; }
.ttl-status.ok { color: var(--green); text-shadow: var(--glow); }

/* the scrollback */
.term-body {
  flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding: 14px 14px calc(var(--safe-b) + 18px);
  font-size: clamp(12.5px, 3.6vw, 14.5px); line-height: 1.55;
  outline: none;
  text-shadow: 0 0 1px rgba(77,255,124,.3);
}
.term-body::-webkit-scrollbar { width: 8px; }
.term-body::-webkit-scrollbar-thumb { background: rgba(77,255,124,.25); border-radius: 4px; }
.term-body::-webkit-scrollbar-track { background: transparent; }

/* ---- line types ----------------------------------------------------------- */
.ln { white-space: pre-wrap; word-break: break-word; margin: 1px 0; }
.ln.dim   { color: var(--mute); }
.ln.ok    { color: var(--green); }
.ln.okb   { color: var(--green-b); text-shadow: var(--glow); }
.ln.info  { color: var(--cyan); text-shadow: 0 0 6px rgba(70,215,255,.5); }
.ln.warn  { color: var(--amber); text-shadow: var(--glow-a); }
.ln.fail  { color: var(--red); text-shadow: var(--glow-r); }
.ln.hint  { color: var(--amber); text-shadow: var(--glow-a); }
.ln.cmd   { color: var(--green-b); }
.ln.cmd::before { content: "$ "; color: var(--green-d); }
.ln.story { color: var(--green-b); font-weight: 700; font-size: 1.16em; text-shadow: var(--glow); margin: 8px 0; }
.ln.brief { color: #d6ffe2; }
.ln.banner { color: var(--green-d); font-weight: 500; line-height: 1.15; }
.ln.tag   { color: var(--green-d); }

.tok-ok   { color: var(--green); } .tok-fail { color: var(--red); }
.tok-warn { color: var(--amber); } .tok-info { color: var(--cyan); }

.cur { display: inline-block; width: .62em; height: 1.05em; vertical-align: -2px;
       background: var(--green); box-shadow: var(--glow); animation: blink 1.05s steps(1) infinite; }
.ln.prompt { color: var(--amber); text-shadow: var(--glow-a); }
@keyframes blink { 0%,49%{opacity:1} 50%,100%{opacity:.05} }

/* progress bar line */
.bar { color: var(--green); letter-spacing: -1px; }

/* ===========================================================================
 *  Key-input widget
 * ===========================================================================*/
.keypad { margin: 12px 0 6px; }
.keypad.retired { opacity: .38; filter: grayscale(.5); pointer-events: none; }
.keyhead { color: var(--green-d); font-size: .92em; margin-bottom: 8px; }
.kp-meta { color: var(--mute); }
.keyrow { display: flex; gap: clamp(7px, 2.6vw, 12px); flex-wrap: nowrap; }

.kbyte {
  --c: var(--green);
  flex: 1 1 0; min-width: 0;
  height: clamp(50px, 15vw, 62px);
  font-family: var(--mono); font-weight: 700;
  font-size: clamp(20px, 6.4vw, 28px); text-align: center; text-transform: uppercase;
  color: #eafff0; caret-color: var(--c);
  background: rgba(3,7,5,.92);
  border: 1.5px solid var(--c); border-radius: 7px;
  box-shadow: 0 0 8px color-mix(in srgb, var(--c) 45%, transparent),
              inset 0 0 10px color-mix(in srgb, var(--c) 16%, transparent);
  outline: none; padding: 0; transition: transform .07s, box-shadow .18s;
  text-shadow: 0 0 8px var(--c);
}
.kbyte:focus { transform: translateY(-2px); box-shadow: 0 0 16px var(--c), inset 0 0 14px color-mix(in srgb, var(--c) 30%, transparent); }
.kbyte.filled { background: color-mix(in srgb, var(--c) 12%, rgba(3,7,5,.92)); }
.kbyte.bad { animation: badflash .42s ease; }
@keyframes badflash { 0%,100%{} 45%{ background: rgba(255,77,82,.35); border-color: var(--red); box-shadow: 0 0 16px var(--red); } }

.keyactions { margin-top: 12px; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.btn-run, .btn-enter {
  font-family: var(--mono); font-weight: 700; font-size: 14px; cursor: pointer;
  color: #04140a; background: var(--green); border: none;
  border-radius: 6px; padding: 11px 18px; letter-spacing: .5px;
  box-shadow: var(--glow); transition: transform .07s, filter .2s, box-shadow .2s;
}
.btn-run:active, .btn-enter:active { transform: scale(.95); }
.btn-run:disabled { background: #20402c; color: var(--mute); box-shadow: none; cursor: default; }
.btn-run::before { content: "▸ "; }
.runline { font-size: .92em; color: var(--mute); }

.btn-enter {
  display: block; margin: 18px auto 6px; font-size: 16px; padding: 14px 30px;
  background: linear-gradient(180deg, #9dffba, var(--green));
  animation: enterpulse 1.3s ease-in-out infinite;
}
.btn-enter::before { content: "▶ "; }
@keyframes enterpulse { 0%,100%{ box-shadow: 0 0 8px var(--green); } 50%{ box-shadow: 0 0 24px var(--green), 0 0 50px rgba(77,255,124,.5); } }

.shake { animation: shake .4s cubic-bezier(.36,.07,.19,.97); }
@keyframes shake { 10%,90%{transform:translateX(-2px)} 30%,50%,70%{transform:translateX(-6px)} 40%,60%{transform:translateX(6px)} }

/* success: wipe the whole scrollback, then a big triumphant reveal */
.term-body.wipe { animation: wipe .44s ease forwards; }
@keyframes wipe {
  0%{ opacity:1; filter:none; transform:translateY(0); }
  35%{ opacity:1; filter:brightness(2.2); }
  65%{ opacity:.2; filter:blur(2px) brightness(3); transform:translateY(-6px); }
  100%{ opacity:0; transform:translateY(-14px); }
}

.granted-big {
  display:block; text-align:center; margin: 22px 0 10px;
  font-weight:700; font-size: clamp(28px, 10vw, 60px); line-height:1.1; letter-spacing:2px;
  color: var(--green-b);
  text-shadow: 0 0 14px var(--green), 0 0 50px rgba(77,255,124,.6);
  animation: grantbig .85s cubic-bezier(.2,.85,.2,1) both, grantglow 1.8s ease-in-out infinite .85s;
}
@keyframes grantbig { 0%{ opacity:0; transform:scale(.35); filter:blur(12px);} 60%{ opacity:1; transform:scale(1.08);} 100%{ transform:scale(1); filter:blur(0);} }
@keyframes grantglow { 0%,100%{ text-shadow:0 0 14px var(--green),0 0 40px rgba(77,255,124,.5);} 50%{ text-shadow:0 0 24px var(--green),0 0 74px rgba(77,255,124,.85);} }

/* pixel confetti */
#confetti { position: fixed; inset: 0; z-index: 46; pointer-events: none; overflow: hidden; }
.pixel { position: absolute; top: -16px; width: 8px; height: 8px; animation: fall linear forwards; }
@keyframes fall { to { transform: translateY(112vh) rotate(560deg); opacity: .12; } }

/* sweeping light on win */
#winsweep { position: fixed; inset: 0; z-index: 45; pointer-events: none; overflow: hidden; }
#winsweep::before {
  content: ""; position: absolute; top: -20%; left: -60%; width: 42%; height: 140%;
  background: linear-gradient(90deg, transparent, rgba(77,255,124,.30), transparent);
  transform: skewX(-18deg); opacity: 0;
}
#winsweep.go::before { animation: wsweep 1.0s ease 1; }
@keyframes wsweep { 0%{ opacity:0; left:-60%; } 20%{ opacity:1; } 100%{ opacity:0; left:120%; } }

/* ===========================================================================
 *  Caesar reveal
 * ===========================================================================*/
#caesar {
  position: fixed; inset: 0; z-index: 20; pointer-events: none;
  display: grid; place-items: center; color: var(--green);
  opacity: 0; transition: opacity 4.2s ease-in; mix-blend-mode: screen;
}
#caesar.show { opacity: var(--caesar-opacity, .42); }
#caesar img { width: min(70vw, 340px); height: auto; filter: drop-shadow(0 0 26px rgba(77,255,124,.5)); }

/* system-crash takeover (on the wrvfd trap) */
#crash {
  position: fixed; inset: 0; z-index: 48; pointer-events: none;
  display: grid; place-items: center; text-align: center;
  background: radial-gradient(120% 120% at 50% 50%, rgba(3,9,5,.95), rgba(1,3,2,.995));
  opacity: 0; visibility: hidden; transition: opacity .45s ease;
}
#crash.show { opacity: 1; visibility: visible; pointer-events: auto; cursor: pointer; }
.crash-inner { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 18px; max-width: 100vw; }
.crash-continue {
  display: none; margin-top: 4px;
  font-family: var(--mono); font-size: clamp(12px,3.6vw,15px);
  color: var(--cyan); text-shadow: 0 0 8px rgba(70,215,255,.6);
}
.crash-continue.show { display: block; animation: blink 1.1s steps(1) infinite; }
.crash-noise { font-size: clamp(9px,3vw,14px); color: var(--green-d); letter-spacing: 1px;
  opacity: .65; white-space: pre; overflow: hidden; max-width: 96vw; }
.crash-art {
  margin: 0; white-space: pre; display: inline-block; text-align: left;
  font-family: var(--mono); font-weight: 700; line-height: 1.02;
  font-size: min(3.05vw, 15px); color: var(--green);
  text-shadow: 0 0 12px var(--green), 0 0 34px rgba(77,255,124,.5);
  animation: bigglitch .5s steps(2) infinite;
}
/* full ASCII portrait — fit to BOTH viewport width and height */
.crash-art.portrait {
  font-weight: 400; line-height: 1.0; letter-spacing: 0;
  font-size: min(1.22vw, 0.9vh, 12px);
  text-shadow: 0 0 5px rgba(77,255,124,.55);
  animation: portjit .42s steps(2) infinite;
}
@keyframes portjit {
  0%{ transform: translate(0,0); } 25%{ transform: translate(-2px,0); }
  50%{ transform: translate(1px,1px) skewX(-.5deg); } 75%{ transform: translate(2px,-1px); }
  100%{ transform: translate(0,0); }
}
.crash-numeral {
  font-family: var(--mono); font-weight: 700; line-height: 1;
  font-size: clamp(26px, 8vw, 54px); letter-spacing: 12px; padding-left: 12px;
  color: var(--amber); text-shadow: 0 0 14px var(--amber), 0 0 42px rgba(255,179,64,.6);
  animation: numpulse 1.8s ease-in-out infinite;
}
@keyframes numpulse { 0%,100%{ opacity: .85; filter: brightness(1); } 50%{ opacity: 1; filter: brightness(1.55); } }
.crash-cap { font-size: clamp(12px,4vw,18px); letter-spacing: 5px; color: var(--amber);
  text-shadow: var(--glow-a); animation: blink 1.1s steps(1) infinite; }
@keyframes bigglitch {
  0%   { transform: translate(0,0);     text-shadow: 2px 0 #ff2d55,-2px 0 #46d7ff,0 0 14px var(--green); }
  25%  { transform: translate(-2px,1px); }
  50%  { transform: translate(2px,-1px); text-shadow: -3px 0 #ff2d55,3px 0 #46d7ff,0 0 14px var(--green); }
  75%  { transform: translate(-1px,0); }
  100% { transform: translate(1px,1px);  text-shadow: 2px 0 #ff2d55,-2px 0 #46d7ff,0 0 18px var(--green); }
}
/* hard glitch on the window during the panic cascade */
.term-window.crashing { animation: hardglitch .26s steps(2) infinite; }
@keyframes hardglitch {
  0%   { transform: translate(0,0); filter: none; }
  20%  { transform: translate(-3px,1px) skewX(-1deg); filter: hue-rotate(25deg); }
  40%  { transform: translate(3px,-2px); filter: invert(.12); }
  60%  { transform: translate(-2px,2px) skewX(1deg); }
  80%  { transform: translate(2px,-1px); filter: invert(.05); }
  100% { transform: translate(0,0); }
}

/* ---- FX ------------------------------------------------------------------- */
#flash { position: fixed; inset: 0; z-index: 50; pointer-events: none; opacity: 0; }
#flash.green { background: var(--green); animation: flash .55s ease; }
#flash.red   { background: var(--red);   animation: flash .32s ease; }
@keyframes flash { 0%{opacity:.8} 100%{opacity:0} }

.glitch { animation: glitch .45s steps(2) 3; }
@keyframes glitch { 0%{transform:translate(0,0)} 25%{transform:translate(-2px,1px)} 50%{transform:translate(2px,-1px)} 75%{transform:translate(-1px,-1px)} 100%{transform:translate(0,0)} }

.scan {
  position: fixed; inset: 0; z-index: 30; pointer-events: none;
  background: repeating-linear-gradient(to bottom, transparent 0 2px, rgba(0,0,0,.18) 2px 3px);
  mix-blend-mode: multiply; opacity: .5;
}

/* ===========================================================================
 *  Reduced motion
 * ===========================================================================*/
@media (prefers-reduced-motion: reduce) {
  #matrix, .scan { display: none; }
  *, *::before, *::after { animation-duration: .001s !important; animation-iteration-count: 1 !important; transition-duration: .12s !important; }
  .cur { animation: none; }
  #caesar { transition: opacity .3s ease-in; }
}

/* Bigger screens: give the window a touch of CRT curvature */
@media (min-width: 720px) { .term-window { box-shadow: 0 0 0 1px rgba(0,0,0,.5), 0 30px 90px rgba(0,0,0,.75), 0 0 80px rgba(77,255,124,.12), inset 0 0 80px rgba(0,0,0,.55); } }
