/* Terminal theme — green phosphor on black, monospace everywhere. */
:root{
  --bg:#070b08;
  --panel:#0b120d;
  --panel2:#0e1810;
  --line:#1c3a26;
  --line2:#2b5c3a;
  --txt:#7cffb2;
  --dim:#3f8f61;
  --acc:#00ff9c;
  --ok:#00ff9c;
  --bad:#ff5f56;
  --mono:"JetBrains Mono","SF Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}
*{box-sizing:border-box}
html{background:var(--bg)}
body{
  margin:0;background:var(--bg);color:var(--txt);
  font:13.5px/1.55 var(--mono);
  text-shadow:0 0 6px rgba(0,255,156,.18);
}
/* faint scanlines + crt vignette */
body::before{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:9;
  background:repeating-linear-gradient(0deg,rgba(0,0,0,.22) 0 1px,transparent 1px 3px);
  mix-blend-mode:multiply;
}
body::after{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:8;
  background:radial-gradient(120% 90% at 50% 45%,transparent 55%,rgba(0,0,0,.55) 100%);
}
.wrap{max-width:1180px;margin:0 auto;padding:22px 20px 70px;position:relative;z-index:1}

h1{margin:0;font-size:19px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--acc)}
h1::before{content:"root@decode:~$ ";color:var(--dim);font-weight:400;letter-spacing:0}
h1::after{content:"_";animation:blink 1.1s step-end infinite;color:var(--acc)}
@keyframes blink{50%{opacity:0}}
.sub{color:var(--dim);font-size:12px;margin:6px 0 20px;max-width:80ch}
.sub b{color:var(--ok);font-weight:600}

.grid{display:grid;grid-template-columns:1fr 1.15fr 1fr;gap:14px;align-items:start}
@media (max-width:1000px){.grid{grid-template-columns:1fr}}

.card{background:var(--panel);border:1px solid var(--line);border-radius:0;padding:0 12px 12px}
.card h2{
  margin:0 -12px 11px;padding:7px 12px;font-size:10.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.18em;color:var(--acc);
  background:var(--panel2);border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:8px;
}
.card h2::before{content:"▎"}
.card h2 > *:last-child{margin-left:auto}

textarea{
  width:100%;min-height:230px;resize:vertical;background:#050805;color:var(--txt);
  border:1px solid var(--line);border-radius:0;padding:9px;font-family:var(--mono);font-size:12.5px;
  caret-color:var(--acc);
}
textarea::placeholder{color:#2b6a45}
textarea:focus,select:focus,input:focus{outline:1px solid var(--acc);outline-offset:0;box-shadow:0 0 12px rgba(0,255,156,.25)}
select,input[type=text],input[type=number]{
  background:#050805;color:var(--txt);border:1px solid var(--line);border-radius:0;
  padding:5px 7px;font-size:12px;font-family:var(--mono);max-width:100%;
}

button{
  background:transparent;color:var(--acc);border:1px solid var(--line2);border-radius:0;
  padding:5px 11px;font-size:11.5px;font-family:var(--mono);font-weight:700;
  text-transform:uppercase;letter-spacing:.08em;cursor:pointer;transition:background .12s,box-shadow .12s;
}
button:hover:not(:disabled){background:rgba(0,255,156,.12);box-shadow:0 0 10px rgba(0,255,156,.25)}
button:disabled{opacity:.28;cursor:default}
button.ghost{color:var(--dim);border-color:var(--line)}
button.ghost:hover:not(:disabled){color:var(--acc);border-color:var(--line2)}
button.mini{padding:2px 6px;font-size:10.5px;letter-spacing:.04em}
#suggest{background:rgba(0,255,156,.14);border-color:var(--acc)}

.row{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
.mt{margin-top:9px}
.meta{font-size:11px;color:var(--dim);margin-top:7px}
.meta.err{color:var(--bad);text-shadow:0 0 6px rgba(255,95,86,.3)}

.drop{border:1px dashed var(--line2);border-radius:0;padding:8px;text-align:center;
  color:var(--dim);font-size:11.5px;margin-top:9px}
.drop.over{border-color:var(--acc);color:var(--acc);background:rgba(0,255,156,.06)}

/* pipeline */
.step{background:var(--panel2);border:1px solid var(--line);border-left:2px solid var(--line2);
  border-radius:0;padding:7px 8px;margin-bottom:8px}
.step.off{opacity:.4}
.step.bad{border-left-color:var(--bad)}
.step .hd{display:flex;gap:5px;align-items:center;flex-wrap:wrap}
.step .hd select{flex:1 1 92px;min-width:92px;max-width:150px}
.idx{width:18px;height:18px;flex:none;border:1px solid var(--acc);color:var(--acc);
  font-size:10.5px;font-weight:700;display:grid;place-items:center}
.spacer{flex:1}
.step .opts{display:flex;gap:6px;flex-wrap:wrap;margin-top:7px}
.step .opts label{font-size:9.5px;color:var(--dim);text-transform:uppercase;letter-spacing:.12em;
  display:flex;flex-direction:column;gap:3px}
.peek{margin:7px 0 0;font-family:var(--mono);font-size:11.5px;color:var(--dim);white-space:pre-wrap;
  word-break:break-word;max-height:44px;overflow:hidden;border-top:1px dashed var(--line);padding-top:6px}
.peek::before{content:"> ";color:var(--line2)}
.peek.err{color:var(--bad)}

.seg{display:inline-flex;border:1px solid var(--line);border-radius:0;overflow:hidden}
.seg button{border:0;padding:4px 8px;color:var(--dim);font-weight:600}
.seg button.on{background:var(--acc);color:#04140c;text-shadow:none}

.empty{color:var(--dim);font-size:11.5px;text-align:center;padding:16px 8px;border:1px dashed var(--line)}

/* candidates */
.cand{background:var(--panel2);border:1px solid var(--line);border-radius:0;padding:7px 8px;
  margin-bottom:7px;cursor:pointer;transition:border-color .12s,background .12s}
.cand:hover{border-color:var(--acc);background:rgba(0,255,156,.06)}
.cand .n{font-size:11px;font-weight:700;color:var(--acc);letter-spacing:.06em;text-transform:uppercase}
.cand .s{float:right;font-size:10.5px;color:var(--dim)}
.cand pre{margin:5px 0 0;font-family:var(--mono);font-size:11.5px;white-space:pre-wrap;
  word-break:break-word;max-height:54px;overflow:hidden;color:var(--txt)}
.bar{height:2px;background:var(--acc);margin-top:6px;box-shadow:0 0 8px rgba(0,255,156,.5)}

.toast{position:fixed;bottom:18px;left:50%;transform:translateX(-50%) translateY(20px);opacity:0;
  background:#04140c;color:var(--acc);border:1px solid var(--acc);padding:7px 14px;border-radius:0;
  font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;
  transition:.18s;pointer-events:none;z-index:20;box-shadow:0 0 18px rgba(0,255,156,.3)}
.toast.on{opacity:1;transform:translateX(-50%)}

kbd{font-size:10.5px;border:1px solid var(--line2);padding:0 4px;color:var(--acc)}

::selection{background:var(--acc);color:#04140c;text-shadow:none}
::-webkit-scrollbar{width:9px;height:9px}
::-webkit-scrollbar-track{background:#050805}
::-webkit-scrollbar-thumb{background:var(--line2)}
::-webkit-scrollbar-thumb:hover{background:var(--acc)}

/* --- top bar / auth --- */
.topbar{display:flex;align-items:flex-end;gap:14px;flex-wrap:wrap;justify-content:space-between}
.auth{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.auth input{width:110px}
.auth .meta{color:var(--dim)}
.auth .meta b{color:var(--acc)}

/* --- saved / history --- */
.grid.two{grid-template-columns:1fr 1fr;margin-top:14px}
@media (max-width:1000px){.grid.two{grid-template-columns:1fr}}
#saves .cand,#history .cand{padding:8px}
#saves .cand .s,#history .cand .s{float:right;font-size:10px;letter-spacing:.02em}
#saves .cand .meta,#history .cand .meta{border-top:1px dashed var(--line);padding-top:5px}
/* the layout rules above set display, which would otherwise beat [hidden] */
[hidden]{display:none !important}

/* link styled as a button (nav between the decoder and /history) */
.btnlink{display:inline-block;text-decoration:none;color:var(--dim);border:1px solid var(--line);
  padding:2px 6px;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em}
.btnlink:hover{color:var(--acc);border-color:var(--line2);background:rgba(0,255,156,.12)}
#list .cand .src{color:var(--dim);word-break:break-all}

/* ==========================================================================
   Half-broken CRT
   The whole structure is lit; the right half of the tube is failing — it
   flickers, dims, and a bright band rolls down it. Everything here is
   decoration: no layout, no colour meaning, nothing you need to read.
   ========================================================================== */

/* --- the structure glows --- */
.card{
  box-shadow:0 0 0 1px rgba(0,255,156,.05),
             inset 0 0 22px rgba(0,255,156,.05),
             0 0 26px rgba(0,255,156,.05);
}
.card h2{text-shadow:0 0 9px rgba(0,255,156,.45)}
.step,.cand,.sym,.rule,.empty,.drop{
  box-shadow:inset 0 0 14px rgba(0,255,156,.045), 0 0 10px rgba(0,255,156,.03);
}
textarea,select,input[type=text],input[type=number],input[type=password]{
  box-shadow:inset 0 0 16px rgba(0,255,156,.06);
}
h1{text-shadow:0 0 12px rgba(0,255,156,.55)}
.idx,.btnlink,button{box-shadow:0 0 8px rgba(0,255,156,.06)}

/* --- random faults ---
   glitch.js picks the elements; these are the three ways one can misbehave.
   --g-ms is set per element so no two flickers run at the same speed. */
/* A flickering element is also a dead one: no clicks, no typing, for as long
   as the fault lasts. glitch.js sets `inert` too, which also removes it from
   the tab order; this rule is the fallback where inert isn't supported. */
.glitch{animation-duration:var(--g-ms,300ms);animation-timing-function:steps(1,end);
  animation-iteration-count:infinite;will-change:opacity,filter;
  pointer-events:none;user-select:none;cursor:default}

@keyframes g-dim{        /* losing power */
  0%,100%{opacity:1}
  20%{opacity:.35}
  40%{opacity:.85}
  55%{opacity:.18}
  70%{opacity:.7}
  85%{opacity:.42}
}
@keyframes g-surge{      /* burning too bright */
  0%,100%{filter:brightness(1)}
  25%{filter:brightness(1.9) saturate(1.4)}
  45%{filter:brightness(.75)}
  65%{filter:brightness(1.6)}
  80%{filter:brightness(.9)}
}
@keyframes g-jitter{     /* slipping sideways */
  0%,100%{transform:translate(0,0);opacity:1}
  20%{transform:translate(-1px,0);opacity:.72}
  40%{transform:translate(2px,-1px)}
  60%{transform:translate(-2px,1px);opacity:.9}
  80%{transform:translate(1px,0);opacity:.6}
}
.glitch.g-dim{animation-name:g-dim}
.glitch.g-surge{animation-name:g-surge}
.glitch.g-jitter{animation-name:g-jitter}

/* --- respect people who don't want motion ---
   glitch.js also bails out on its own; this covers anything already applied. */
@media (prefers-reduced-motion: reduce){
  .glitch{animation:none}
}

/* file pickers — the browser default is a white button that fights the theme */
input[type=file]{background:transparent;border:0;color:var(--dim);font-size:11px;font-family:var(--mono)}
input[type=file]::file-selector-button{
  background:transparent;color:var(--acc);border:1px solid var(--line2);border-radius:0;
  padding:4px 9px;margin-right:8px;font:700 11px/1 var(--mono);
  text-transform:uppercase;letter-spacing:.08em;cursor:pointer}
input[type=file]::file-selector-button:hover{background:rgba(0,255,156,.12)}
/* a candidate is a submit button now, so strip the button chrome back off */
button.cand{background:var(--panel2);font-family:var(--mono)}
button.cand:hover{background:rgba(0,255,156,.06);box-shadow:none}
