<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Hello, world</title>
</head>
<body>
<main>
<h1>Hello, world.</h1>
<p>Every good idea starts somewhere.</p>
</main>
</body>
</html>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Formulario de Staff Sergioland</title>
<style>
:root {
--gold: #d9a629;
--gold-light: #ffe19a;
--black: #090909;
--panel: #141414;
--muted: #aaa;
--danger: #ff6464;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: #080808;
color: #f5f5f5;
font-family: Arial, Helvetica, sans-serif;
min-height: 100vh;
}
body::before {
content: "";
display: block;
height: 9px;
background: repeating-linear-gradient(
135deg, var(--gold) 0 18px, #111 18px 36px
);
}
.container {
width: min(850px, 94%);
margin: 30px auto;
border: 1px solid #8b681b;
background: var(--panel);
box-shadow: 0 0 28px #000;
}
header {
text-align: center;
padding: 32px 20px 25px;
border-bottom: 2px solid var(--gold);
background: linear-gradient(180deg, #242017, #111);
}
.logo {
display: inline-block;
border: 2px solid var(--gold);
padding: 7px 13px;
color: var(--gold-light);
letter-spacing: 4px;
font-size: 12px;
font-weight: bold;
margin-bottom: 14px;
}
h1 {
color: var(--gold);
margin: 0;
font-size: clamp(25px, 5vw, 39px);
text-transform: uppercase;
letter-spacing: 1px;
}
.subtitle {
color: #ccc;
line-height: 1.6;
margin: 15px auto 0;
max-width: 650px;
}
.content { padding: 25px; }
.section-title {
color: var(--gold);
text-transform: uppercase;
letter-spacing: 1.5px;
border-bottom: 1px solid #51401b;
padding-bottom: 10px;
margin: 0 0 18px;
}
.rules {
list-style: none;
padding: 0;
margin: 0 0 25px;
counter-reset: rules;
}
.rules li {
counter-increment: rules;
display: flex;
align-items: flex-start;
gap: 13px;
background: #0d0d0d;
border: 1px solid #292929;
padding: 14px;
margin-bottom: 9px;
line-height: 1.5;
}
.rules li::before {
content: counter(rules, decimal-leading-zero);
color: var(--gold);
font-weight: bold;
border: 1px solid #80601c;
padding: 4px 7px;
flex-shrink: 0;
}
.notice {
border-left: 3px solid var(--gold);
background: #211c10;
color: #e8d9b3;
padding: 13px 15px;
line-height: 1.6;
margin-bottom: 22px;
}
.question {
padding: 18px;
margin-bottom: 15px;
border: 1px solid #333;
background: #0e0e0e;
}
.question-heading {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
margin-bottom: 14px;
}
.question-title {
font-weight: bold;
line-height: 1.5;
}
.number {
color: var(--gold);
border: 1px solid #8c681c;
padding: 4px 9px;
font-weight: bold;
flex-shrink: 0;
}
.points {
display: inline-block;
font-size: 11px;
color: var(--gold-light);
border: 1px solid #6f531a;
padding: 5px 8px;
margin-top: 8px;
letter-spacing: .5px;
}
input[type="text"], textarea, select {
width: 100%;
background: #181818;
color: white;
border: 1px solid #494949;
padding: 12px;
font: inherit;
border-radius: 2px;
}
textarea { min-height: 115px; resize: vertical; }
input:focus, textarea:focus, select:focus {
outline: 1px solid var(--gold);
border-color: var(--gold);
}
.hint {
color: var(--muted);
font-size: 13px;
line-height: 1.5;
margin-top: 9px;
}
.radio-option {
display: flex;
align-items: center;
gap: 10px;
padding: 12px;
background: #181818;
border: 1px solid #333;
margin-bottom: 8px;
cursor: pointer;
}
input[type="radio"] { accent-color: var(--gold); }
button {
background: var(--gold);
color: #111;
font-weight: bold;
text-transform: uppercase;
letter-spacing: .5px;
border: 1px solid var(--gold-light);
padding: 15px 18px;
cursor: pointer;
font-size: 13px;
transition: .2s;
}
button:hover { background: var(--gold-light); }
button:disabled {
cursor: not-allowed;
opacity: .45;
}
.secondary {
background: transparent;
color: var(--gold);
border: 1px solid #86631d;
}
.secondary:hover { background: #251e10; }
.actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 24px;
}
.actions button { flex: 1; min-width: 180px; }
.progress-wrap {
margin: 0 0 22px;
color: #bbb;
font-size: 13px;
}
.progress-track {
height: 6px;
background: #333;
margin-top: 9px;
}
.progress-bar {
height: 100%;
width: 0;
background: var(--gold);
transition: width .2s;
}
.status {
color: var(--gold-light);
font-size: 13px;
line-height: 1.5;
margin-top: 12px;
}
.error { color: var(--danger); }
.success-screen {
text-align: center;
padding: 42px 24px;
}
.success-icon {
width: 78px;
height: 78px;
margin: 0 auto 22px;
display: grid;
place-items: center;
border: 2px solid var(--gold);
border-radius: 50%;
color: var(--gold);
font-size: 42px;
}
.success-screen h2 {
color: var(--gold);
font-size: clamp(24px, 5vw, 34px);
line-height: 1.3;
}
.success-screen p {
line-height: 1.7;
color: #ddd;
}
.cooldown {
border: 1px solid #6d531d;
background: #1a170f;
padding: 15px;
margin: 20px 0;
color: var(--gold-light);
}
footer {
border-top: 1px solid #4b3917;
padding: 18px;
color: #888;
text-align: center;
font-size: 11px;
letter-spacing: 2px;
}
.hidden { display: none !important; }
@media (max-width: 550px) {
.container { width: 100%; margin: 0; border-left: 0; border-right: 0; }
.content { padding: 16px; }
header { padding: 26px 14px; }
.question { padding: 14px; }
.question-heading { flex-wrap: wrap; }
.actions { flex-direction: column; }
.actions button { width: 100%; }
}
</style>
</head>
<body>
<div class="container">
<header>
<div class="logo">SERGIOLAND · STAFF</div>
<h1>Formulario de Staff Sergioland</h1>
<p class="subtitle">
Cada pregunta puntuable vale 1 punto, excepto la pregunta 9,
que vale 2 puntos. Las respuestas parcialmente correctas podrán
recibir 0,5 puntos. ¡MUCHA SUERTE!
</p>
</header>
<main class="content">
<section id="welcome">
<h2 class="section-title">Antes de comenzar</h2>
<p class="subtitle" style="margin:0 0 18px">
Lee todas las normas antes de presentar tu candidatura al equipo.
</p>
<ol class="rules">
<li>No puedes tener ninguna sanción, ni dentro del juego ni dentro de la comunidad de Discord.</li>
<li>Debes tener 13 o más años para ser administrador.</li>
<li>Responde TÚ mismo, no uses ningún tipo de IA.</li>
<li>Debes estar en el servidor de Discord o tener contacto con el creador.</li>
<li>Ten paciencia: el cuestionario será revisado de vez en cuando.</li>
</ol>
<div class="notice">
La pregunta 1 solo solicita tus datos de usuario y no vale puntos.
La pregunta 9 vale 2 puntos y será valorada por el equipo de Moderación.
</div>
<div id="welcomeCooldown" class="cooldown hidden"></div>
<button id="startButton" type="button" onclick="startQuiz()">
Comenzar cuestionario
</button>
</section>
<section id="quizSection" class="hidden">
<div class="progress-wrap">
<span id="progressText">0 de 9 preguntas respondidas</span>
<div class="progress-track"><div id="progressBar" class="progress-bar"></div></div>
</div>
<form id="staffForm">
<div class="question">
<div class="question-heading">
<div class="question-title">1. Usuario de Discord y Fortnite</div>
<span class="number">01</span>
</div>
<input name="usuario" type="text" placeholder="Discord y Fortnite" required>
<div class="points">DATOS · 0 PUNTOS</div>
</div>
<div class="question">
<div class="question-heading">
<div class="question-title">2. ¿Tienes experiencia de staff?</div>
<span class="number">02</span>
</div>
<textarea name="experiencia" placeholder="Explica tu experiencia..." required></textarea>
<div class="points">1 PUNTO</div>
</div>
<div class="question">
<div class="question-heading">
<div class="question-title">3. ¿Sabes cómo se conecta un dispositivo a otro para crear un sistema?</div>
<span class="number">03</span>
</div>
<textarea name="conectar" placeholder="Escribe tu respuesta..." required></textarea>
<div class="points">1 PUNTO</div>
</div>
<div class="question">
<div class="question-heading">
<div class="question-title">4. ¿Sabes lo que es un dispositivo de mensajes HUD?</div>
<span class="number">04</span>
</div>
<textarea name="hud" placeholder="Explica qué es..." required></textarea>
<div class="hint">Si explicas correctamente para qué se utiliza, podrás recibir 0,5 puntos aunque tu respuesta esté incompleta.</div>
<div class="points">1 PUNTO</div>
</div>
<div class="question">
<div class="question-heading">
<div class="question-title">5. Para conectar un dispositivo a otro, ¿qué debes hacer?</div>
<span class="number">05</span>
</div>
<textarea name="conexion" placeholder="Describe los pasos..." required></textarea>
<div class="points">1 PUNTO</div>
</div>
<div class="question">
<div class="question-heading">
<div class="question-title">6. ¿Es verdad que necesitas un dispositivo de selector de clases para hacer un rol?</div>
<span class="number">06</span>
</div>
<label class="radio-option">
<input type="radio" name="selector" value="Sí" required> Sí
</label>
<label class="radio-option">
<input type="radio" name="selector" value="No" required> No
</label>
<div class="points">1 PUNTO</div>
</div>
<div class="question">
<div class="question-heading">
<div class="question-title">7. ¿Qué harías si dos usuarios estuvieran haciendo anti y luego te insultan?</div>
<span class="number">07</span>
</div>
<textarea name="anti" placeholder="Explica cómo actuarías como staff..." required></textarea>
<div class="points">1 PUNTO</div>
</div>
<div class="question">
<div class="question-heading">
<div class="question-title">8. ¿Qué harías si un usuario quiere reportar a otro usuario?</div>
<span class="number">08</span>
</div>
<textarea name="reporte" placeholder="Explica cómo gestionarías el reporte..." required></textarea>
<div class="points">1 PUNTO</div>
</div>
<div class="question">
<div class="question-heading">
<div class="question-title">9. ¿Por qué quieres ser admin?</div>
<span class="number">09</span>
</div>
<textarea name="motivo" placeholder="Cuéntanos tus motivos..." required></textarea>
<div class="hint">Esta respuesta será evaluada por el equipo de Moderación.</div>
<div class="points">2 PUNTOS · VALORACIÓN DEL EQUIPO DE MODERACIÓN</div>
</div>
<div class="actions">
<button type="submit">Enviar formulario</button>
<button type="button" class="secondary" onclick="backToWelcome()">Volver</button>
</div>
<p class="hint">
Al enviar, tus respuestas se guardarán en este dispositivo.
Este formulario no envía los datos automáticamente a Discord.
</p>
</form>
</section>
<section id="successSection" class="success-screen hidden">
<div class="success-icon">✓</div>
<h2>FORMULARIO ENVIADO CON EXITO</h2>
<p>Se te contactara por discord si apruebas o no</p>
<p id="savedMessage"></p>
<div id="successCooldown" class="cooldown"></div>
<button id="newQuizButton" type="button" onclick="startNewQuiz()">
Comenzar nuevo cuestionario
</button>
<p class="hint">Tu candidatura queda guardada en este dispositivo y navegador.</p>
</section>
</main>
<footer>FORMULARIO DE STAFF · SERGIOLAND</footer>
</div>
<script>
const STORAGE_KEY = "sergioland_staff_forms_v1";
const COOLDOWN_KEY = "sergioland_staff_last_submission_v1";
const COOLDOWN_MS = 10 * 24 * 60 * 60 * 1000;
let cooldownInterval = null;
function getSavedForms() {
try {
const data = JSON.parse(localStorage.getItem(STORAGE_KEY) || "[]");
return Array.isArray(data) ? data : [];
} catch (error) {
return [];
}
}
function getLastSubmission() {
const value = Number(localStorage.getItem(COOLDOWN_KEY) || 0);
return Number.isFinite(value) ? value : 0;
}
function getRemainingTime() {
return Math.max(0, getLastSubmission() + COOLDOWN_MS - Date.now());
}
function formatRemaining(ms) {
const totalSeconds = Math.ceil(ms / 1000);
const days = Math.floor(totalSeconds / 86400);
const hours = Math.floor((totalSeconds % 86400) / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
return `${days} días, ${hours} horas, ${minutes} minutos y ${seconds} segundos`;
}
function showScreen(screenId) {
["welcome", "quizSection", "successSection"].forEach(id => {
document.getElementById(id).classList.toggle("hidden", id !== screenId);
});
}
function refreshCooldownUI() {
const remaining = getRemainingTime();
const startButton = document.getElementById("startButton");
const newQuizButton = document.getElementById("newQuizButton");
const welcomeCooldown = document.getElementById("welcomeCooldown");
const successCooldown = document.getElementById("successCooldown");
if (remaining > 0) {
startButton.disabled = true;
startButton.textContent = "Cuestionario bloqueado temporalmente";
welcomeCooldown.classList.remove("hidden");
welcomeCooldown.textContent =
"Ya has enviado un formulario. Podrás volver a presentarte dentro de: " +
formatRemaining(remaining) + ".";
newQuizButton.disabled = true;
successCooldown.textContent =
"Podrás comenzar un nuevo cuestionario dentro de: " +
formatRemaining(remaining) + ".";
} else {
startButton.disabled = false;
startButton.textContent = "Comenzar cuestionario";
welcomeCooldown.classList.add("hidden");
newQuizButton.disabled = false;
successCooldown.textContent =
"Ya puedes volver a presentarte cuando quieras.";
}
}
function startCooldownTimer() {
if (cooldownInterval) clearInterval(cooldownInterval);
refreshCooldownUI();
cooldownInterval = setInterval(() => {
refreshCooldownUI();
if (getRemainingTime() <= 0) {
clearInterval(cooldownInterval);
cooldownInterval = null;
}
}, 1000);
}
function startQuiz() {
if (getRemainingTime() > 0) {
refreshCooldownUI();
return;
}
document.getElementById("staffForm").reset();
updateProgress();
showScreen("quizSection");
window.scrollTo({ top: 0, behavior: "smooth" });
}
function backToWelcome() {
showScreen("welcome");
refreshCooldownUI();
window.scrollTo({ top: 0, behavior: "smooth" });
}
function startNewQuiz() {
if (getRemainingTime() > 0) {
refreshCooldownUI();
return;
}
startQuiz();
}
function updateProgress() {
const form = document.getElementById("staffForm");
const names = [...new Set(
[...form.querySelectorAll("[name]")].map(el => el.name)
)];
let answered = 0;
names.forEach(name => {
const fields = [...form.querySelectorAll(`[name="${name}"]`)];
const first = fields[0];
let hasAnswer = false;
if (first.type === "radio") {
hasAnswer = fields.some(field => field.checked);
} else {
hasAnswer = fields.some(field => field.value.trim() !== "");
}
if (hasAnswer) answered++;
});
document.getElementById("progressText").textContent =
`${answered} de ${names.length} preguntas respondidas`;
document.getElementById("progressBar").style.width =
`${(answered / names.length) * 100}%`;
}
document.getElementById("staffForm").addEventListener("input", updateProgress);
document.getElementById("staffForm").addEventListener("change", updateProgress);
document.getElementById("staffForm").addEventListener("submit", function(event) {
event.preventDefault();
if (getRemainingTime() > 0) {
alert("Todavía no puedes enviar otro cuestionario. Espera a que termine el plazo de 10 días.");
backToWelcome();
return;
}
const formData = new FormData(this);
const answers = {};
for (const [key, value] of formData.entries()) {
answers[key] = String(value).trim();
}
const submittedAt = Date.now();
const record = {
id: (window.crypto && crypto.randomUUID)
? crypto.randomUUID()
: String(submittedAt) + "-" + Math.random().toString(36).slice(2),
submittedAt: new Date(submittedAt).toISOString(),
answers: answers
};
try {
const saved = getSavedForms();
saved.push(record);
localStorage.setItem(STORAGE_KEY, JSON.stringify(saved));
localStorage.setItem(COOLDOWN_KEY, String(submittedAt));
} catch (error) {
alert("No se pudo guardar el formulario en este dispositivo. Comprueba que el navegador permita guardar datos y vuelve a intentarlo.");
return;
}
document.getElementById("savedMessage").textContent =
"Fecha de envío: " + new Date(submittedAt).toLocaleString("es-ES") +
". Tus respuestas se han guardado localmente.";
showScreen("successSection");
startCooldownTimer();
window.scrollTo({ top: 0, behavior: "smooth" });
});
// Si se recarga la página, se conserva el estado y se vuelve a mostrar
// la pantalla de confirmación si ya se había enviado una candidatura.
function init() {
const saved = getSavedForms();
const lastSubmission = getLastSubmission();
if (lastSubmission > 0 && saved.some(item =>
new Date(item.submittedAt).getTime() === lastSubmission
)) {
document.getElementById("savedMessage").textContent =
"Fecha de envío: " + new Date(lastSubmission).toLocaleString("es-ES") +
". Tu candidatura sigue guardada en este dispositivo.";
showScreen("successSection");
} else {
showScreen("welcome");
}
startCooldownTimer();
}
init();
</script>
</body>
</html>