/* Jailbreak Store UI — fluid, viewport-relative.
 *
 * No hardcoded pixel size is assumed. The root font scales with clamp()/vmin,
 * every dimension below is in rem, and the log grows into whatever vertical
 * space is left over. So the same markup fits a small modal popup or a 4K
 * desktop browser without a separate layout.
 */

* { margin:0; padding:0; box-sizing:border-box; }

:root {
  --bg:      #0a0a0a;
  --bg2:     #0e0e0e;
  --line:    #1e1e1e;
  --line2:   #2a2a2a;
  --txt:     #b9b9b9;
  --hi:      #e8e8e8;
  --dim:     #6a6a6a;
  --dim2:    #474747;
  --grn:     #33ff77;
  --grn-dim: #1d7a42;
  --amb:     #ffb02e;
  --red:     #ff4d4d;
  --cyan:    #35d0d0;

  /* single knob for the whole UI density */
  --fs: clamp(10px, 0.5vmin + 9.2px, 14px);
  --gut: clamp(5px, 1.1vmin, 12px);
  --maxw: 44rem;
}

html {
  font-size: var(--fs);
  -webkit-text-size-adjust:100%;
}

html, body { height:100%; }

/* Self-hosted rather than relying on the system stack. The PS5's WebView has
   none of the usual console names (ui-monospace, Menlo, Consolas) installed and
   falls through to its own default, which is not a monospace face and does not
   line up in a log. Shipping the font makes the console, a desktop and the
   local preview all render identically. */
@font-face {
  font-family:"JB Mono";
  src:url("fonts/DejaVuSansMono.ttf") format("truetype");
  font-weight:400;
  font-style:normal;
  font-display:swap;
}
@font-face {
  font-family:"JB Mono";
  src:url("fonts/DejaVuSansMono-Bold.ttf") format("truetype");
  font-weight:700;
  font-style:normal;
  font-display:swap;
}

body {
  background:var(--bg);
  color:var(--txt);
  font-family:"JB Mono",ui-monospace,monospace;
  font-size:1rem;
  line-height:1.5;
  -webkit-font-smoothing:none;
  display:flex;
  flex-direction:column;
  overflow-x:hidden;
}

.hidden { display:none !important; }

.cur { animation:blink 1s steps(1) infinite; color:var(--grn); }
@keyframes blink { 0%,50%{opacity:1} 51%,100%{opacity:0} }

.lnk {
  background:none; border:0; padding:0; cursor:pointer;
  color:var(--dim); font:inherit; font-size:.85rem;
  letter-spacing:.04em;
}
.lnk:hover, .lnk:focus-visible { color:var(--grn); outline:none; }

/* the start gate and the store installer share one treatment: this is the only
   control on the site that starts something irreversible, so it reads as solid
   rather than as a text link */
.go {
  background:transparent; color:var(--grn); cursor:pointer;
  border:1px solid var(--grn); border-radius:2px;
  font:inherit; font-size:1.05rem; font-weight:700; letter-spacing:.22em;
  padding:.7rem 1.9rem; margin:.3rem 0;
}
.go:hover, .go:focus-visible { background:var(--grn); color:var(--bg); outline:none; }
.go:disabled { border-color:var(--dim); color:var(--dim); cursor:default; background:transparent; }

/* ---------- post-run offer ---------- */
.offer {
  margin:1.4rem auto 0; max-width:34rem; text-align:left;
  border:1px solid var(--dim); border-radius:2px; padding:1rem 1.1rem;
}
.offerhead {
  color:var(--amb); font-size:.8rem; letter-spacing:.16em; margin:0 0 .55rem;
}
.offerbody { color:var(--dim); font-size:.88rem; line-height:1.5; margin:0 0 .3rem; }
.offerbody b { color:var(--grn); font-weight:400; }
.bootline.note { font-size:.8rem; opacity:.8; }

/* ---------- screens ---------- */
/* min-height first for old parsers, dvh so mobile-style viewports behave */
.screen { min-height:100vh; min-height:100dvh; width:100%; }

.screen.center {
  display:flex; align-items:center; justify-content:center; text-align:center;
}

.boot-inner { padding:var(--gut) calc(var(--gut) * 1.5); max-width:100%; }

.ascii {
  color:var(--grn);
  font-size:1.5rem;
  line-height:1.1;
  font-weight:700;
  text-shadow:0 0 6px rgba(51,255,119,.35);
  overflow-x:auto;
  max-width:100%;
}

.bootline { color:var(--dim); font-size:.92rem; margin-top:.7rem; }

.verdict {
  font-size:1.3rem; font-weight:700; letter-spacing:.1em; color:var(--grn);
  text-shadow:0 0 8px rgba(51,255,119,.4);
}
#done.error .verdict { color:var(--red); text-shadow:0 0 8px rgba(255,77,77,.4); }

/* collapsed-run recap on the verdict screen */
.summary {
  margin-top:.8rem; padding:.5rem .6rem;
  font-size:.75rem; line-height:1.6; color:var(--dim);
  text-align:left;
  border:1px solid var(--line); background:var(--bg2);
  max-width:26rem; margin-left:auto; margin-right:auto;
  white-space:pre-wrap; overflow-wrap:anywhere; word-break:break-word;
  max-height:40vh; overflow-y:auto;
}
.summary b { color:var(--grn); font-weight:400; }
.summary i { color:var(--amb); font-style:normal; }
#done.error .summary b { color:var(--red); }

/* ---------- main: single flex column that fills the window ---------- */
/* full-bleed on purpose: a max-width + auto margins column reads as a narrow
   strip floating in the middle of a large window. */
#main {
  display:flex;
  flex-direction:column;
  width:100%;
  max-width:100%;
}

.bar {
  flex:0 0 auto;
  display:flex; justify-content:space-between; align-items:center; gap:var(--gut);
  padding:.55rem var(--gut);
  border-bottom:1px solid var(--line);
  background:var(--bg2);
}
.tag { color:var(--hi); font-weight:700; letter-spacing:.1em; }
.fw { color:var(--grn-dim); white-space:nowrap; margin-left:auto; }

/* ---------- steps ---------- */
.steps { flex:0 0 auto; }
.step {
  display:flex; align-items:center; gap:.6rem;
  padding:.3rem var(--gut);
  font-size:.95rem;
  border-bottom:1px solid #141414;
}
.step:last-child { border-bottom:0; }
.step i { color:var(--dim2); font-style:normal; width:.7rem; flex:0 0 auto; }
.step .what { flex:1 1 auto; color:var(--dim); letter-spacing:.04em; }
.step .stat { color:var(--dim2); font-size:.82rem; white-space:nowrap; }

.step.active i, .step.active .what, .step.active .stat { color:var(--cyan); }
.step.done i, .step.done .what, .step.done .stat { color:var(--grn); }
.step.fail i, .step.fail .what, .step.fail .stat { color:var(--red); }

/* ---------- progress ---------- */
.prog {
  flex:0 0 auto; height:3px; background:#131313;
  border-bottom:1px solid var(--line);
  position:relative; overflow:hidden;
}
/* segmented ticks so the bar reads as a track, not a blob */
.prog::after {
  content:""; position:absolute; inset:0; pointer-events:none;
  background:repeating-linear-gradient(90deg,
    transparent 0, transparent calc(10% - 1px),
    rgba(0,0,0,.55) calc(10% - 1px), rgba(0,0,0,.55) 10%);
}
.prog i { display:block; height:100%; width:0%; background:var(--cyan); transition:width .35s linear; }
.prog i.ok { background:var(--grn); }
.prog i.err { background:var(--red); }

/* ---------- progress caption ---------- */
.rowhead {
  flex:0 0 auto;
  display:flex; justify-content:space-between; align-items:baseline; gap:var(--gut);
  padding:.3rem var(--gut);
  font-size:.78rem; color:var(--dim2);
  border-bottom:1px solid var(--line);
  background:var(--bg2);
}
.rowhead .pct { color:var(--txt); }
.rowhead .now { color:var(--cyan); text-align:right; overflow-wrap:anywhere; word-break:break-word; }

/* ---------- collapsible sections ---------- */
.sec { flex:0 0 auto; border-bottom:1px solid var(--line); overflow:hidden; }
.sec h2 { border-bottom:0; }

.sec .body {
  overflow:hidden;
  max-height:60rem;
  transition:max-height .28s ease, opacity .2s ease;
  opacity:1;
}
.sec.collapsed > .body,
.sec.collapsed #log { max-height:0 !important; opacity:0; }
.sec.collapsed h2 { color:var(--dim2); }

.sum { color:var(--grn-dim); }

.tg {
  min-width:1.4em; text-align:center;
  border:1px solid var(--line2); line-height:1.3;
  margin-left:.35em;
}
.tg:hover { border-color:var(--grn-dim); }


/* ---------- key/value ---------- */
.kv {
  flex:0 0 auto;
  display:grid; grid-template-columns:auto minmax(0,1fr);
  gap:.1rem .7rem;
  padding:.5rem var(--gut);
  font-size:.85rem;
  border-bottom:1px solid var(--line);
}
.kv > span:nth-child(odd) { color:var(--dim2); }
.kv > span:nth-child(even) { color:var(--txt); text-align:right; overflow-wrap:anywhere; word-break:break-word; }
.kv #kPort, .kv #kSource { color:var(--dim); }
.kv #kPort.ok { color:var(--grn); }

h2 {
  font-size:.8rem; font-weight:400; letter-spacing:.14em; text-transform:uppercase;
  color:var(--dim2); padding:.45rem var(--gut);
  border-bottom:1px solid var(--line);
  display:flex; justify-content:space-between; align-items:center; gap:var(--gut);
}
h2 em { font-style:normal; letter-spacing:.04em; text-transform:none; }

/* ---------- payload queue ---------- */
.pay { flex:0 0 auto; }
.plist { list-style:none; }
.plist li {
  display:flex; align-items:center; gap:.6rem;
  padding:.22rem var(--gut);
  font-size:.95rem;
}
.plist li i {
  width:.42rem; height:.42rem; border-radius:50%;
  background:var(--dim2); flex:0 0 auto;
}
.plist .pname { flex:1 1 auto; overflow-wrap:anywhere; word-break:break-word; }
.plist em { font-style:normal; color:var(--dim2); font-size:.82rem; white-space:nowrap; }
.plist li.sent i { background:var(--grn); }
.plist li.sent .pname, .plist li.sent em { color:var(--grn); }
.plist li.warming i { background:var(--amb); }
.plist li.warming em { color:var(--amb); }

/* ---------- log: takes all leftover height, but never gets crushed ---------- */
#secLog {
  flex:1 1 auto;
  display:flex;
  flex-direction:column;
  min-height:8rem;
}
#secLog h2 { flex:0 0 auto; }
/* The container carries both class "log" and id "log". Key all log layout and
 * colour off the id so a "line log" message can never inherit the box. */
#log {
  flex:1 1 auto;
  min-height:5rem;
  overflow-y:auto;
  overflow-x:hidden;
  -webkit-overflow-scrolling:touch;
  padding:.25rem var(--gut);
  font-size:.82rem;
  line-height:1.45;
  scrollbar-width:thin;
  scrollbar-color:var(--line2) transparent;
}
#log .line {
  display:block;
  overflow-wrap:anywhere; word-break:break-word;
  white-space:normal;
}
#log .line.log { color:var(--dim); }
#log .line.info { color:var(--txt); }
#log .line.success { color:var(--grn); }
#log .line.warning { color:var(--amb); }
#log .line.error { color:var(--red); }
#log .line.sys { color:var(--cyan); }
#log::-webkit-scrollbar, .summary::-webkit-scrollbar { width:8px; height:8px; }
#log::-webkit-scrollbar-track, .summary::-webkit-scrollbar-track { background:var(--bg2); }
#log::-webkit-scrollbar-thumb, .summary::-webkit-scrollbar-thumb { background:var(--line2); border-radius:4px; }
#log::-webkit-scrollbar-thumb:hover, .summary::-webkit-scrollbar-thumb:hover { background:#3a3a3a; }

.note {
  flex:0 0 auto;
  padding:.5rem var(--gut);
  font-size:.72rem; line-height:1.5; color:var(--dim2);
  border-top:1px solid var(--line);
}

#exploit { display:none; }

/* per-deploy build tag, fixed bottom-left corner. Shown on the boot screen
   only (app.js hides it once a run starts). */
#bver {
  position:fixed; left:.6rem; bottom:.5rem; z-index:50;
  font:600 .75rem/1 "JB Mono",ui-monospace,monospace; color:var(--grn-dim);
  letter-spacing:.08em; pointer-events:none; user-select:none;
}

/* ---------- viewport probe ---------- */
#measure { padding:var(--gut); }
#measure .boot-inner { max-width:var(--maxw); margin:0 auto; }
#measure .mhead {
  font-size:.85rem; font-weight:700; letter-spacing:.14em;
  color:var(--grn); border:0; padding:0 0 .5rem; display:block;
}
#measure .mout {
  font-size:.88rem; line-height:1.7; color:var(--cyan);
  white-space:pre; overflow-x:auto; padding-bottom:.5rem;
}

/* ---------- narrow windows: shave the optional chrome ---------- */
@media (max-width:22rem) {
  .note { display:none; }
  .ascii { font-size:1.15rem; }
}

/* ---------- short windows: buy back vertical space for the log ---------- */
@media (max-height:26rem) {
  body { line-height:1.35; }
  .bar { padding:.35rem var(--gut); }
  .step { padding:.1rem var(--gut); }
  .kv { padding:.25rem var(--gut); gap:0 .7rem; }
  .plist li { padding:.05rem var(--gut); }
  h2 { padding:.25rem var(--gut); }
  #log { font-size:.78rem; line-height:1.45; padding:.2rem var(--gut); }
  #secLog { min-height:6.5rem; }
  #log { min-height:4.5rem; }
}

@media (max-height:20rem) {
  .ascii { font-size:.95rem; }
  .note { display:none; }
}
