styles & new model

This commit is contained in:
T-A-H-prog
2026-09-12 20:45:20 +02:00
parent e33c509856
commit 1459fd3d2f
7 changed files with 1269 additions and 243 deletions

View File

@@ -0,0 +1,376 @@
<script setup lang="js">
import { nextTick, onMounted, onUnmounted, ref } from "vue";
const code = ref("");
const loggedIn = ref(false);
const error = ref("");
const inputRef = ref(null);
function cleanCode(event) {
code.value = event.target.value.replace(/\D/g, "").slice(0, 4);
error.value = "";
}
function login() {
if (code.value === "1337") {
loggedIn.value = true;
error.value = "";
return;
}
code.value = "";
error.value = "ACCESS DENIED";
nextTick(() => inputRef.value?.focus());
}
function logout() {
loggedIn.value = false;
code.value = "";
error.value = "";
nextTick(() => inputRef.value?.focus());
}
function leaveComputer() {
if (window.parent === window) return;
window.parent.postMessage({ type: "leave-computer" }, window.location.origin);
}
function onKeydown(event) {
if (event.key === "Escape") leaveComputer();
}
onMounted(() => {
window.addEventListener("keydown", onKeydown);
document.documentElement.addEventListener("mouseleave", leaveComputer);
inputRef.value?.focus();
});
onUnmounted(() => {
window.removeEventListener("keydown", onKeydown);
document.documentElement.removeEventListener("mouseleave", leaveComputer);
});
</script>
<template>
<main class="page">
<header>
<b>FEDERAL RECORDS SYSTEM</b>
<span>SECURE SERVER 04</span>
</header>
<section v-if="!loggedIn" class="login-box">
<h1>Restricted Access</h1>
<p>This system is for authorized personnel only.</p>
<form @submit.prevent="login">
<label for="code">Access Code:</label>
<input
id="code"
ref="inputRef"
:value="code"
type="password"
inputmode="numeric"
maxlength="4"
autocomplete="off"
@input="cleanCode"
/>
<button type="submit">LOGIN</button>
</form>
<p v-if="error" class="error" role="alert">{{ error }}</p>
<p class="help">Press ESC to leave terminal.</p>
</section>
<section v-else class="records">
<nav>
<b>RECORD DATABASE</b>
<button type="button" @click="logout">LOG OUT</button>
</nav>
<h1>Case File 04-1337</h1>
<table>
<tbody>
<tr>
<th>Status</th>
<td>OPEN</td>
</tr>
<tr>
<th>Classification</th>
<td>RESTRICTED</td>
</tr>
<tr>
<th>Subject</th>
<td>UNKNOWN</td>
</tr>
<tr>
<th>Last activity</th>
<td>03:17 / SECTOR 12</td>
</tr>
</tbody>
</table>
<div class="note">
<b>REPORT</b>
<p>
An unidentified signal was recorded near the archive terminal.
Investigation remains active. No further action authorized.
</p>
</div>
<footer>FICTIONAL ARCHIVE SYSTEM // LOCAL TERMINAL</footer>
</section>
</main>
</template>
<style scoped>
:global(*) {
box-sizing: border-box;
}
:global(html),
:global(body),
:global(#app) {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
background: #000;
}
:global(body) {
font-family: Verdana, Arial, sans-serif;
}
.page {
width: 100%;
height: 100dvh;
overflow: hidden;
color: #b7c2b9;
background: #000;
font-size: clamp(12px, 1.4vw, 16px);
}
header {
display: flex;
align-items: center;
justify-content: space-between;
height: 54px;
padding: 0 22px;
border-bottom: 1px solid #526056;
color: #d4ddd6;
background: #111;
font-family: "Courier New", monospace;
}
header span {
color: #718076;
font-size: 0.75em;
}
.login-box {
width: min(430px, calc(100% - 36px));
margin: clamp(40px, 14vh, 110px) auto 0;
padding: 22px;
border: 1px solid #58635b;
background: #080a08;
}
h1 {
margin: 0 0 18px;
color: #d6ddd7;
font:
bold 1.25em "Courier New",
monospace;
}
p {
line-height: 1.5;
}
form {
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 8px;
margin-top: 24px;
}
label {
white-space: nowrap;
}
input,
button {
border: 1px solid #5c685e;
border-radius: 0;
font: inherit;
}
input {
min-width: 0;
padding: 7px;
outline: none;
color: #9ee6ad;
background: #000;
}
input:focus {
border-color: #9ee6ad;
}
button {
padding: 7px 12px;
color: #d1d8d2;
background: #242924;
cursor: pointer;
}
button:hover,
button:focus-visible {
color: #fff;
background: #343b35;
}
.error {
margin: 15px 0 0;
color: #d76b62;
font-family: "Courier New", monospace;
}
.help {
margin: 22px 0 0;
color: #667068;
font-size: 0.75em;
}
.records {
width: min(760px, calc(100% - 36px));
height: calc(100dvh - 82px);
margin: 18px auto 0;
overflow: hidden;
border: 1px solid #4d574f;
background: #060706;
}
nav {
display: flex;
align-items: center;
justify-content: space-between;
height: 42px;
padding: 0 14px;
border-bottom: 1px solid #4d574f;
color: #9ee6ad;
background: #121512;
font-family: "Courier New", monospace;
}
nav button {
padding: 4px 9px;
font-size: 0.75em;
}
.records > h1,
.records > table,
.records > .note {
margin-right: 20px;
margin-left: 20px;
}
.records > h1 {
margin-top: 20px;
}
table {
width: calc(100% - 40px);
border-collapse: collapse;
}
th,
td {
padding: 8px 10px;
border: 1px solid #3e473f;
text-align: left;
}
th {
width: 34%;
color: #78847a;
background: #0c0f0c;
font-weight: normal;
}
td {
color: #a7d9b0;
font-family: "Courier New", monospace;
}
.note {
margin-top: 20px;
padding: 14px;
border: 1px solid #3e473f;
}
.note b {
color: #78847a;
font-size: 0.8em;
}
.note p {
margin: 8px 0 0;
}
footer {
margin: 22px 20px 0;
color: #566058;
font:
0.7em "Courier New",
monospace;
text-align: right;
}
@media (max-width: 500px), (max-height: 500px) {
header {
height: 44px;
padding: 0 12px;
}
.login-box {
margin-top: 24px;
padding: 16px;
}
form {
grid-template-columns: 1fr auto;
}
form label {
grid-column: 1 / -1;
}
.records {
height: calc(100dvh - 58px);
margin-top: 7px;
}
.records > h1 {
margin-top: 12px;
margin-bottom: 10px;
}
th,
td {
padding: 5px 7px;
}
.note {
margin-top: 10px;
padding: 8px;
}
footer {
display: none;
}
}
</style>