0% found this document useful (0 votes)
7 views60 pages

Index

The document is an HTML template for a web application called 'MineConv - Conversor Avançado', featuring advanced styling and layout using CSS variables for colors and effects. It includes various screens such as a loading screen, login screen, mode select screen, and main app screen, with interactive elements like buttons and input fields. The design emphasizes a modern aesthetic with animations, gradients, and responsive layouts to enhance user experience.

Uploaded by

karlioevanio666
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views60 pages

Index

The document is an HTML template for a web application called 'MineConv - Conversor Avançado', featuring advanced styling and layout using CSS variables for colors and effects. It includes various screens such as a loading screen, login screen, mode select screen, and main app screen, with interactive elements like buttons and input fields. The design emphasizes a modern aesthetic with animations, gradients, and responsive layouts to enhance user experience.

Uploaded by

karlioevanio666
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 60

<!

DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MineConv - Conversor Avançado</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-
awesome/6.4.0/css/all.min.css">
<style>
/* --- Base & Reset --- */
:root {
--primary-color: #00ffff; /* Cyan */
--secondary-color: #ff00ff; /* Magenta */
--background-color: #0d0d1a; /* Dark blue/purple */
--surface-color: #1a1a2e;
--text-color: #e0e0e0;
--text-darker: #a0a0a0;
--success-color: #00ff7f; /* Spring Green */
--error-color: #ff4d4d;
--warning-color: #ffcc00; /* Yellowish */
--glow-color-primary: rgba(0, 255, 255, 0.7);
--glow-color-secondary: rgba(255, 0, 255, 0.7);
--font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
--alt-font-family: 'Roboto', sans-serif; /* Alternative font */
--current-font-family: var(--font-family); /* Default font */
--border-radius: 8px; /* Slightly more rounded */
--transition-speed: 0.35s; /* Slightly slower for smoother feel */
--shadow-color-light: rgba(0, 255, 255, 0.3);
--shadow-color-dark: rgba(255, 0, 255, 0.3);
}

body {
font-family: var(--current-font-family); /* Use current font variable */
background:
url('https://i.imgur.com/YOUR_8K_ANIMATED_WALLPAPER_URL.gif'); /* Replace with your
8k animated wallpaper URL */
background-size: cover;
background-attachment: fixed; /* Optional: for fixed background */
color: var(--text-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden; /* Prevent scrollbars during transitions */
position: relative; /* For absolute positioning of elements */
}

/* Simulated Shader Effect */


body::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: radial-gradient(circle at top left, rgba(0, 255, 255, 0.05),
transparent 40%),
radial-gradient(circle at bottom right, rgba(255, 0, 255,
0.05), transparent 40%);
pointer-events: none;
z-index: 0;
animation: subtle-glow 15s ease-in-out infinite alternate;
}

@keyframes subtle-glow {
from { opacity: 0.6; }
to { opacity: 1; }
}

/* --- Utility Classes --- */


.hidden {
display: none !important;
}

.screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
opacity: 0;
visibility: hidden;
transition: opacity var(--transition-speed) ease-in-out, visibility
var(--transition-speed);
background-color: transparent; /* Allow body gradient */
z-index: 1;
}

.screen.active {
opacity: 1;
visibility: visible;
z-index: 10; /* Bring active screen to front */
}

.popup {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0.9);
background-color: rgba(26, 26, 46, 0.95); /* Slightly transparent surface
*/
backdrop-filter: blur(5px); /* Frosted glass effect */
border: 1px solid var(--primary-color);
box-shadow: 0 0 25px var(--glow-color-primary), 0 0 10px rgba(0,0,0,0.5);
padding: 30px 40px;
border-radius: var(--border-radius);
z-index: 100;
opacity: 0;
visibility: hidden;
transition: opacity var(--transition-speed) ease, transform var(--
transition-speed) ease, visibility var(--transition-speed);
min-width: 320px;
max-width: 90%;
text-align: center;
}
.popup.active {
opacity: 1;
visibility: visible;
transform: translate(-50%, -50%) scale(1);
}

.popup h2 {
color: var(--primary-color);
margin-bottom: 20px;
text-shadow: 0 0 8px var(--glow-color-primary);
font-weight: 600;
}

.popup p {
margin-bottom: 25px;
color: var(--text-darker);
line-height: 1.6;
}

.popup .button-group {
display: flex;
justify-content: center;
gap: 15px;
flex-wrap: wrap; /* Allow buttons to wrap on small screens */
}

.button {
background: linear-gradient(45deg, var(--primary-color), var(--secondary-
color));
color: var(--background-color);
border: none;
padding: 12px 28px; /* Slightly larger padding */
border-radius: var(--border-radius);
font-size: 1rem;
font-weight: bold;
cursor: pointer;
transition: transform var(--transition-speed) ease, box-shadow var(--
transition-speed) ease, background var(--transition-speed) ease;
text-align: center;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 10px; /* Increased gap */
text-decoration: none;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}

.button:hover {
transform: translateY(-4px) scale(1.03); /* Enhanced hover effect */
box-shadow: 0 8px 20px var(--shadow-color-light), 0 8px 20px var(--
shadow-color-dark);
}
.button:active {
transform: translateY(-1px) scale(0.98);
}

.button.secondary {
background: var(--surface-color);
color: var(--primary-color);
border: 1px solid var(--primary-color);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}

.button.secondary:hover {
background: rgba(0, 255, 255, 0.1); /* Subtle hover background */
box-shadow: 0 0 15px var(--glow-color-primary), 0 4px 10px rgba(0, 0, 0,
0.3);
transform: translateY(-4px) scale(1.03);
}

.button.danger {
background: linear-gradient(45deg, var(--error-color), #ff0055);
color: white;
}
.button.danger:hover {
box-shadow: 0 8px 20px rgba(255, 77, 77, 0.5);
}

.button i {
font-size: 1.1em;
line-height: 1; /* Prevent icon from affecting button height */
}

.icon-button {
background: none;
border: none;
color: var(--primary-color);
font-size: 1.6rem; /* Slightly larger */
cursor: pointer;
transition: color var(--transition-speed) ease, text-shadow var(--
transition-speed) ease, transform var(--transition-speed) ease;
padding: 8px; /* More clickable area */
position: relative; /* For badge positioning */
line-height: 1;
}

.icon-button:hover {
color: var(--secondary-color);
text-shadow: 0 0 12px var(--glow-color-secondary);
transform: scale(1.1);
}

.icon-button .badge {
position: absolute;
top: 0;
right: 0;
background-color: var(--error-color);
color: white;
border-radius: 50%;
padding: 2px 6px;
font-size: 0.7rem;
font-weight: bold;
line-height: 1;
transform: translate(40%, -40%);
pointer-events: none; /* Don't interfere with clicks */
}

.input-field {
background-color: rgba(26, 26, 46, 0.8); /* Slightly transparent surface
*/
border: 1px solid var(--primary-color);
border-radius: var(--border-radius);
padding: 12px 18px; /* Increased padding */
color: var(--text-color);
font-size: 1rem;
width: 100%;
margin-bottom: 18px; /* Increased margin */
transition: border-color var(--transition-speed) ease, box-shadow var(--
transition-speed) ease;
}

.input-field:focus {
outline: none;
border-color: var(--secondary-color);
box-shadow: 0 0 12px var(--glow-color-secondary);
}

.input-group {
position: relative;
margin-bottom: 18px;
}

.input-group .icon-button {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
font-size: 1.2rem;
padding: 5px; /* Smaller padding for inline icon */
}

/* --- Loading Screen --- */


#loading-screen {
text-align: center;
}

#loading-screen h1 {
font-size: 3rem; /* Larger title */
color: var(--primary-color);
text-shadow: 0 0 15px var(--glow-color-primary), 0 0 5px white; /*
Enhanced glow */
margin-bottom: 40px;
letter-spacing: 2px;
}

.loading-bar-container { /* Renamed for clarity */


width: 80%;
max-width: 500px;
height: 8px; /* Slimmer loading bar */
background-color: var(--surface-color);
border-radius: 4px; /* Rounded corners for loading bar */
overflow: hidden;
margin-bottom: 30px; /* Space below loading bar */
}

.loading-bar { /* Renamed for clarity */


width: 0%;
height: 100%;
background: linear-gradient(90deg, var(--primary-color), var(--secondary-
color));
border-radius: 4px; /* Match container radius */
transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1); /* Smoother, more
realistic ease */
box-shadow: 0 0 10px var(--glow-color-primary);
}

#loading-spinner {
border: 6px solid var(--surface-color);
border-top: 6px solid var(--primary-color);
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1.2s linear infinite;
margin-bottom: 20px; /* Space below spinner */
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

/* --- Login Screen --- */


#login-screen h1 {
font-size: 2.5rem;
margin-bottom: 30px;
color: var(--primary-color);
text-shadow: 0 0 10px var(--glow-color-primary);
}
#login-screen .login-options {
display: flex;
gap: 40px; /* Increased gap */
margin-top: 50px;
}

.login-option {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px; /* Increased gap */
}

.login-option i {
font-size: 3.5rem; /* Larger icons */
color: var(--primary-color);
text-shadow: 0 0 12px var(--glow-color-primary);
margin-bottom: 15px;
transition: transform 0.3s ease;
}
.login-option:hover i {
transform: scale(1.1);
}
#create-account-btn.button.secondary {
margin-top: 20px;
}
/* --- Mode Select Screen --- */
#mode-select-screen h1 {
font-size: 2.5rem;
margin-bottom: 30px;
color: var(--primary-color);
text-shadow: 0 0 10px var(--glow-color-primary);
}
#mode-select-screen .mode-options {
display: flex;
gap: 40px;
margin-top: 50px;
}

.mode-option {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}

.mode-option i {
font-size: 3.5rem;
color: var(--primary-color);
text-shadow: 0 0 12px var(--glow-color-primary);
margin-bottom: 15px;
transition: transform 0.3s ease;
}
.mode-option:hover i {
transform: scale(1.1);
}

/* --- Main App Screen --- */


#main-app-screen {
justify-content: flex-start; /* Align content to top */
padding-top: 80px; /* Increased padding for header */
}

.main-header {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 30px; /* Vertical padding */
position: absolute;
top: 0;
left: 0;
background-color: rgba(13, 13, 26, 0.6); /* Semi-transparent header */
backdrop-filter: blur(8px);
z-index: 50;
border-bottom: 1px solid rgba(0, 255, 255, 0.2);
}

.header-left {
display: flex;
align-items: center;
gap: 15px;
}
#clock-display {
font-size: 1.3rem;
font-weight: bold;
color: var(--primary-color);
text-shadow: 0 0 5px var(--glow-color-primary);
transition: color 0.5s ease, text-shadow 0.5s ease; /* Animation for
time change */
}
#clock-display.animated {
color: var(--secondary-color);
text-shadow: 0 0 8px var(--glow-color-secondary);
}

.header-right {
display: flex;
align-items: center;
gap: 15px; /* Space between icons */
}

.limits-display {
display: flex;
align-items: center;
gap: 8px;
font-size: 1.1rem; /* Slightly smaller */
cursor: pointer;
padding: 8px 12px;
border-radius: var(--border-radius);
transition: background-color var(--transition-speed) ease, color var(--
transition-speed) ease;
color: var(--text-darker);
}
.limits-display:hover {
background-color: rgba(255, 255, 255, 0.1);
color: var(--text-color);
}

.limits-display i {
color: var(--warning-color); /* Lightning color */
font-size: 1.2em;
}

#rules-btn.icon-button {
margin-right: 5px;
}

.account-menu {
position: relative;
}
#accounts-list-btn.icon-button {
margin-right: 5px;
}

#account-menu-popup {
position: absolute;
top: 55px; /* Position below the icon group */
right: 0;
background-color: var(--surface-color);
border: 1px solid var(--primary-color);
border-radius: var(--border-radius);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.5); /* Stronger shadow */
z-index: 110;
width: 220px; /* Wider menu */
overflow: hidden; /* Ensures buttons fit */
opacity: 0;
visibility: hidden;
transform: translateY(-10px) scale(0.95);
transform-origin: top right;
transition: opacity var(--transition-speed) ease, transform var(--
transition-speed) ease, visibility var(--transition-speed) ease;
}

#account-menu-popup.active {
opacity: 1;
visibility: visible;
transform: translateY(0) scale(1);
}

#account-menu-popup button {
display: flex; /* Use flex for alignment */
align-items: center; /* Align icon and text */
width: 100%;
padding: 14px 20px; /* More padding */
background: none;
border: none;
color: var(--text-color);
text-align: left;
cursor: pointer;
transition: background-color var(--transition-speed) ease, color var(--
transition-speed) ease;
font-size: 1rem; /* Standardize font size */
gap: 12px; /* Space between icon and text */
}
#account-menu-popup button i {
/* margin-right: 10px; */ /* Replaced by gap */
color: var(--primary-color);
font-size: 1.1rem; /* Adjust icon size */
width: 20px; /* Align icons */
text-align: center;
transition: color var(--transition-speed) ease;
}

#account-menu-popup button:hover {
background-color: rgba(0, 255, 255, 0.15); /* Primary color tint */
color: white;
}
#account-menu-popup button:hover i {
color: var(--secondary-color);
}

.main-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex-grow: 1; /* Take remaining space */
width: 100%;
max-width: 800px; /* Limit content width */
margin: 0 auto; /* Center content */
padding: 20px;
/* margin-top: 60px; */ /* Removed, padding-top on screen handles it */
}

.main-content h1 {
font-size: 2.8rem; /* Larger title */
color: var(--primary-color);
text-shadow: 0 0 12px var(--glow-color-primary);
margin-bottom: 50px; /* More space */
text-align: center;
}

.main-actions {
display: grid; /* Use grid for better layout */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); /*
Responsive columns */
gap: 25px; /* Increased gap */
width: 100%;
margin-top: 20px;
}
.main-actions .button {
width: 100%; /* Make buttons fill grid cells */
}
.main-actions .button.plus-feature {
opacity: 0.7; /* Indicate Plus feature */
cursor: not-allowed;
}
.main-actions .button.plus-feature i.fa-star {
margin-left: 5px;
}

/* --- Conversion Wizard --- */


.conversion-step {
text-align: center;
}
.conversion-step h2 {
margin-bottom: 30px; /* More space */
}
.conversion-step .button {
margin-top: 25px;
}
.skin-preview-container {
width: 220px; /* Larger preview */
height: 280px;
border: 2px dashed var(--primary-color); /* Thicker border */
margin: 25px auto;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0,0,0,0.3);
position: relative;
overflow: hidden; /* For grid effect */
border-radius: var(--border-radius);
box-shadow: inset 0 0 15px rgba(0,0,0,0.5);
}
.skin-preview-container::before,
.skin-preview-container::after {
content: '';
position: absolute;
background-size: 30px 30px;
opacity: 0.15; /* Slightly more visible grid */
pointer-events: none; /* Allow interaction with skin */
transition: background-position 0.1s linear; /* Smooth grid movement */
}
.skin-preview-container::before { /* Vertical lines */
width: 100%; height: 100%; top: 0; left: 0;
background-image: linear-gradient(to right, var(--primary-color) 1px,
transparent 1px);
}
.skin-preview-container::after { /* Horizontal lines */
width: 100%; height: 100%; top: 0; left: 0;
background-image: linear-gradient(to bottom, var(--primary-color) 1px,
transparent 1px);
}

#skin-preview {
width: 80px; /* Adjust as needed */
height: 160px; /* Adjust as needed */
background-color: grey; /* Default skin color */
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 0.8rem;
text-align: center;
z-index: 1; /* Above grid */
cursor: grab;
transform-style: preserve-3d; /* Needed for 3D rotation */
transition: background-image 0.5s ease;
}
#skin-preview.loaded {
background-color: transparent; /* Show actual skin if loaded */
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}

.wizard-back-button {
position: absolute;
top: 15px;
left: 15px;
font-size: 1.2rem; /* Smaller back button */
padding: 5px;
}

.delivery-time-inputs {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
gap: 10px;
margin-bottom: 20px;
}
.delivery-time-inputs label {
display: block;
font-size: 0.85rem;
color: var(--text-darker);
margin-bottom: 5px;
}
.delivery-time-inputs input {
padding: 8px 10px;
font-size: 0.9rem;
margin-bottom: 0; /* Remove default margin */
}

/* --- Settings & Profile Screens --- */


.settings-section, .profile-section {
margin-bottom: 35px; /* More space */
width: 100%;
max-width: 450px; /* Wider sections */
background-color: rgba(26, 26, 46, 0.5); /* Subtle background */
padding: 20px;
border-radius: var(--border-radius);
border: 1px solid rgba(0, 255, 255, 0.1);
}
.settings-section h2, .profile-section h2 {
color: var(--primary-color);
margin-bottom: 20px;
border-bottom: 1px solid var(--primary-color);
padding-bottom: 8px;
font-size: 1.3rem;
}
.setting-item, .profile-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px; /* More space */
padding: 5px 0;
}
.setting-item label, .profile-item label {
color: var(--text-darker);
flex-shrink: 0; /* Prevent label from shrinking */
margin-right: 15px;
}
select.input-field { /* Style select dropdowns */
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg
xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%2300ffff'%3E
%3Cpath d='M6 9l-6-6h12z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 18px center; /* Adjust arrow position */
padding-right: 45px; /* Space for arrow */
}
#profile-pic-preview {
width: 80px;
height: 80px;
border-radius: 50%;
background-color: var(--surface-color);
border: 2px solid var(--primary-color);
margin-left: 15px; /* Space from button */
background-size: cover;
background-position: center;
display: inline-block;
vertical-align: middle;
}
#profile-pic-input {
display: none; /* Hide actual file input */
}

/* --- Chatbot --- */


#chatbot-toggle {
position: fixed;
bottom: 25px;
right: 25px;
font-size: 2.8rem; /* Larger toggle */
z-index: 90;
animation: pulse 2s infinite;
filter: drop-shadow(0 0 10px var(--glow-color-primary));
}

@keyframes pulse {
0% { transform: scale(1); filter: drop-shadow(0 0 10px var(--glow-color-
primary)); }
50% { transform: scale(1.1); filter: drop-shadow(0 0 15px var(--glow-
color-secondary)); }
100% { transform: scale(1); filter: drop-shadow(0 0 10px var(--glow-
color-primary)); }
}

#chatbot-popup {
width: 380px; /* Wider chat */
height: 500px; /* Taller chat */
top: auto;
left: auto;
bottom: 90px; /* Position above toggle */
right: 25px;
transform: scale(0.9) translateY(20px); /* Adjust initial transform */
transform-origin: bottom right;
display: flex;
flex-direction: column;
padding: 0; /* Remove default padding */
border-radius: var(--border-radius); /* Ensure consistent radius */
overflow: hidden; /* Clip content */
}
#chatbot-popup.active {
transform: scale(1) translateY(0);
}

.chatbot-header {
background: linear-gradient(45deg, var(--primary-color), var(--secondary-
color));
color: var(--background-color);
padding: 12px 18px; /* Adjust padding */
/* border-top-left-radius: var(--border-radius); */ /* Removed due to
overflow:hidden */
/* border-top-right-radius: var(--border-radius); */
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}
.chatbot-header h2 {
font-size: 1.2rem; /* Larger header */
margin: 0;
color: var(--background-color);
text-shadow: none;
font-weight: 600;
}
#close-chatbot-btn {
background: none;
border: none;
color: var(--background-color);
font-size: 1.4rem; /* Larger close button */
cursor: pointer;
padding: 5px;
opacity: 0.8;
transition: opacity 0.3s ease;
}
#close-chatbot-btn:hover {
opacity: 1;
}

.chatbot-messages {
flex-grow: 1;
overflow-y: auto;
padding: 20px; /* More padding */
background-color: var(--surface-color); /* Match popup background */
display: flex;
flex-direction: column;
gap: 12px; /* Increased gap */
}
/* Scrollbar styling */
.chatbot-messages::-webkit-scrollbar {
width: 8px;
}
.chatbot-messages::-webkit-scrollbar-track {
background: rgba(0,0,0,0.2);
border-radius: 4px;
}
.chatbot-messages::-webkit-scrollbar-thumb {
background: linear-gradient(var(--primary-color), var(--secondary-
color));
border-radius: 4px;
}
.chatbot-messages::-webkit-scrollbar-thumb:hover {
background: linear-gradient(var(--secondary-color), var(--primary-
color));
}

.chat-message {
padding: 10px 15px; /* More padding */
border-radius: var(--border-radius);
max-width: 85%; /* Slightly wider max */
word-wrap: break-word;
line-height: 1.5;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.chat-message.user {
background: linear-gradient(45deg, var(--primary-color), #00c6ff); /*
User message gradient */
color: var(--background-color);
align-self: flex-end;
border-bottom-right-radius: 2px; /* Slightly sharper corner */
}
.chat-message.bot {
background-color: #2a2a3e; /* Slightly different background */
color: var(--text-color);
align-self: flex-start;
border-bottom-left-radius: 2px;
}

.chatbot-input {
display: flex;
border-top: 1px solid var(--primary-color);
padding: 12px; /* More padding */
background-color: var(--surface-color); /* Match popup background */
/* border-bottom-left-radius: var(--border-radius); */ /* Removed due to
overflow:hidden */
/* border-bottom-right-radius: var(--border-radius); */
}
#chatbot-input-field {
flex-grow: 1;
margin-bottom: 0; /* Override default margin */
border-radius: var(--border-radius) 0 0 var(--border-radius);
border-right: none;
padding: 12px 18px; /* Match button height */
}
#chatbot-send-btn {
border-radius: 0 var(--border-radius) var(--border-radius) 0;
padding: 12px 18px; /* Match input height */
font-size: 1.1rem; /* Larger send icon */
}

/* --- Notification Banner --- */


#notification-banner {
position: fixed;
top: 80px; /* Below header */
right: 30px;
padding: 18px 30px; /* More padding */
border-radius: var(--border-radius);
color: var(--background-color);
font-weight: bold;
z-index: 200;
opacity: 0;
transform: translateX(110%); /* Start further off-screen */
transition: opacity var(--transition-speed) ease, transform var(--
transition-speed) cubic-bezier(0.25, 1, 0.5, 1); /* Smoother cubic-bezier */
display: flex;
align-items: center;
gap: 15px; /* More gap */
min-width: 250px;
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}
#notification-banner.show {
opacity: 1;
transform: translateX(0);
}
#notification-banner.success {
background: linear-gradient(45deg, var(--success-color), #00e673);
box-shadow: 0 0 15px var(--success-color);
}
#notification-banner.error {
background: linear-gradient(45deg, var(--error-color), #ff3333);
box-shadow: 0 0 15px var(--error-color);
}
#notification-banner.warning {
background: linear-gradient(45deg, var(--warning-color), #ffdd33);
box-shadow: 0 0 15px var(--warning-color);
color: #333; /* Darker text for yellow */
}
#notification-banner i {
font-size: 1.4em; /* Larger icon */
}

/* --- Edit Mode --- */


.draggable {
cursor: grab;
position: relative; /* Needed for potential absolute positioning during
drag */
border: 1px dashed transparent; /* Placeholder for visual feedback */
transition: border-color 0.2s ease, box-shadow 0.2s ease;
border-radius: 4px; /* Slight rounding for hover effect */
}
.draggable.dragging {
cursor: grabbing;
opacity: 0.7;
border-color: var(--secondary-color);
box-shadow: 0 0 15px var(--glow-color-secondary);
z-index: 1000; /* Ensure dragged element is on top */
}
body.edit-mode .draggable:hover {
border-color: var(--primary-color);
box-shadow: 0 0 10px var(--glow-color-primary);
}

#edit-mode-controls {
position: fixed;
bottom: 25px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(26, 26, 46, 0.9); /* Surface color with
transparency */
padding: 12px 25px; /* More padding */
border-radius: var(--border-radius);
border: 1px solid var(--primary-color);
box-shadow: 0 0 20px var(--glow-color-primary);
z-index: 150;
display: flex;
gap: 20px; /* More gap */
}

/* --- Manage Accounts --- */


#manage-accounts-popup ul {
list-style: none;
padding: 0;
margin-top: 20px;
max-height: 250px; /* Taller list */
overflow-y: auto;
text-align: left;
}
#manage-accounts-popup li {
background-color: rgba(0, 255, 255, 0.08); /* Slightly more visible */
padding: 10px 15px; /* More padding */
margin-bottom: 8px; /* More space */
border-radius: 5px;
border-left: 4px solid var(--primary-color); /* Thicker border */
color: var(--text-darker);
transition: background-color 0.3s ease;
}
#manage-accounts-popup li:hover {
background-color: rgba(0, 255, 255, 0.15);
color: var(--text-color);
}

/* --- Email & Timer & Ban History Popups --- */


.list-popup ul {
list-style: none;
padding: 0;
margin-top: 15px;
max-height: 250px;
overflow-y: auto;
text-align: left;
}
.list-popup li {
background-color: rgba(255, 255, 255, 0.05);
padding: 12px 15px;
margin-bottom: 8px;
border-radius: 5px;
border-left: 3px solid var(--secondary-color);
color: var(--text-darker);
font-size: 0.95rem;
}
.list-popup li strong {
color: var(--text-color);
display: block;
margin-bottom: 3px;
}
.list-popup li span { /* For timestamp or details */
font-size: 0.8em;
opacity: 0.7;
}
.list-popup .empty-message {
color: var(--text-darker);
font-style: italic;
text-align: center;
margin-top: 20px;
}
#delivery-timer-popup h3 {
font-size: 1.5rem;
color: var(--warning-color);
margin-bottom: 15px;
}
#delivery-timer-popup p {
font-size: 1.1rem;
margin-bottom: 25px;
}

/* --- Ban Popup Enhancements --- */


#ban-popup h2 i {
margin-right: 10px;
vertical-align: middle;
}
#ban-popup p {
font-size: 1.1rem;
}
#ban-popup .ban-details {
background-color: rgba(0,0,0,0.2);
padding: 15px;
border-radius: var(--border-radius);
margin-bottom: 25px;
border: 1px solid var(--error-color);
}
#ban-popup .ban-actions {
margin-top: 30px;
display: flex;
flex-direction: column;
gap: 15px;
align-items: center;
}
#ban-popup .ban-actions .button {
width: 80%;
max-width: 300px;
}
#ban-popup .final-ban-message {
color: var(--error-color);
font-weight: bold;
margin-top: 20px;
}
#ban-popup .popup-content { /* Container for scrollable content */
max-height: 70vh; /* Limit height to viewport */
overflow-y: auto; /* Enable vertical scroll if needed */
padding-right: 10px; /* Add some padding for scrollbar */
}

/* --- Unban Simulation Popup --- */


#unban-sim-popup .video-placeholder {
width: 100%;
height: 150px;
background-color: #333;
margin: 10px 0;
display: flex;
justify-content: center;
align-items: center;
color: #777;
border-radius: 5px;
font-style: italic;
}
#unban-sim-popup .progress-bar-container {
height: 15px;
margin-top: 15px;
}
#unban-sim-popup .progress-bar {
height: 100%;
border-radius: 8px;
}

/* --- Rules Popup --- */


#rules-popup ul {
list-style-type: none; /* Remove default list bullets */
padding-left: 20px; /* Indent list items */
}

#rules-popup li {
margin-bottom: 10px; /* Space between rules */
line-height: 1.6;
position: relative; /* For custom bullet */
}

#rules-popup li::before {
content: '\f054'; /* Font Awesome 'angle-right' icon */
font-family: 'Font Awesome 6 Free';
font-weight: 900; /* Solid style */
position: absolute;
left: -20px; /* Position bullet to the left */
top: 4px; /* Adjust vertical alignment */
color: var(--primary-color); /* Bullet color */
}
#rules-popup h3 {
color: var(--secondary-color);
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 1px dashed var(--secondary-color);
padding-bottom: 5px;
}

/* --- Accounts List Popup --- */


#accounts-list-popup ul {
list-style: none;
padding: 0;
margin-top: 20px;
max-height: 250px;
overflow-y: auto;
text-align: left;
}
#accounts-list-popup li {
background-color: rgba(0, 255, 255, 0.08);
padding: 10px 15px;
margin-bottom: 8px;
border-radius: 5px;
border-left: 4px solid var(--primary-color);
color: var(--text-darker);
transition: background-color 0.3s ease;
}
#accounts-list-popup li:hover {
background-color: rgba(0, 255, 255, 0.15);
color: var(--text-color);
}

/* --- Responsive Adjustments --- */


@media (max-width: 768px) {
.main-header {
padding: 10px 15px;
}
.header-right {
gap: 5px; /* Reduce gap on smaller screens */
}
.icon-button {
font-size: 1.4rem;
padding: 6px;
}
.limits-display {
font-size: 1rem;
padding: 6px 10px;
}
#clock-display {
font-size: 1.1rem;
}
.main-content h1 {
font-size: 2.2rem;
margin-bottom: 40px;
}
.main-actions {
grid-template-columns: 1fr; /* Stack buttons */
gap: 15px;
}
#account-menu-popup {
width: 200px;
}
#account-menu-popup button {
padding: 12px 15px;
font-size: 0.95rem;
gap: 10px;
}
#account-menu-popup button i {
font-size: 1rem;
width: 18px;
}
}

@media (max-width: 600px) {


.login-options, .mode-options {
flex-direction: column;
gap: 25px;
}
.popup {
width: 90%;
padding: 25px 20px; /* Adjust padding */
}
.main-header {
padding: 10px 15px;
position: relative; /* Allow content to flow below */
}
#main-app-screen {
padding-top: 20px; /* Reduce top padding */
}
.main-content h1 {
font-size: 1.8rem;
margin-bottom: 30px;
}
#chatbot-popup {
width: 90%;
bottom: 75px; /* Adjust position */
right: 5%;
height: calc(100% - 100px); /* Adjust height */
max-height: 450px;
}
#chatbot-toggle {
bottom: 20px;
right: 20px;
font-size: 2.2rem;
}
#notification-banner {
width: calc(100% - 40px);
left: 20px;
right: 20px;
top: 15px; /* Position near top */
transform: translateY(-150%); /* Animate from top */
}
#notification-banner.show {
transform: translateY(0);
}
.delivery-time-inputs {
grid-template-columns: repeat(auto-fit, minmax(60px, 1fr)); /* Adjust
for smaller inputs */
gap: 8px;
}
.header-left, .header-right {
gap: 8px;
}
#clock-display { display: none; } /* Hide clock on very small screens */
}

</style>
</head>
<body>

<!-- Loading Screen -->


<div id="loading-screen" class="screen active">
<div id="loading-spinner"></div>
<h1>MineConv</h1>
<div class="loading-bar-container">
<div id="loading-bar" class="loading-bar"></div>
</div>
</div>

<!-- Login Screen -->


<div id="login-screen" class="screen">
<h1>Bem-vindo ao MineConv</h1>
<div class="login-options">
<div class="login-option">
<i class="fab fa-google"></i>
<button id="google-login-btn" class="button">Login com Google</button>
</div>
<div class="login-option">
<i class="fas fa-user-secret"></i>
<button id="guest-login-btn" class="button secondary">Entrar como
Convidado</button>
</div>
</div>
<button id="create-account-btn" class="button secondary" style="margin-top:
20px;"><i class="fas fa-user-plus"></i> Criar outra conta</button>
</div>
<!-- Guest Confirmation Popup -->
<div id="guest-confirm-popup" class="popup">
<h2>Modo Convidado</h2>
<p>Este modo somente mostra como é o site, você não conseguirá fazer
nenhuma ação significativa (como converter contas, editar perfil ou usar recursos
Plus).</p>
<div class="button-group">
<button id="guest-confirm-ok" class="button">Ok</button>
<button id="guest-confirm-cancel" class="button
secondary">Cancelar</button>
</div>
</div>

<!-- Mode Selection Screen -->


<div id="mode-select-screen" class="screen">
<h1>Selecionar Modo</h1>
<div class="mode-options">
<div class="mode-option">
<i class="fas fa-file-alt"></i>
<button id="normal-mode-btn" class="button">Modo Normal</button>
</div>
<div class="mode-option">
<i class="fas fa-arrows-alt"></i>
<button id="edit-mode-btn" class="button secondary">Modo
Edição</button>
</div>
</div>
</div>

<!-- Main App Screen (Conversion Page) -->


<div id="main-app-screen" class="screen">
<header class="main-header">
<div class="header-left">
<span id="clock-display">--:--</span>
</div>
<div class="header-right">
<button id="rules-btn" class="icon-button">
<i class="fas fa-book"></i>
</button>
<div id="limits-display" class="limits-display">
<i class="fas fa-bolt"></i>
<span id="limits-count">?</span>
</div>
<button id="ban-history-btn" class="icon-button hidden">
<i class="fas fa-exclamation-triangle"></i>
<span id="ban-history-badge" class="badge hidden">0</span>
</button>
<button id="delivery-timer-btn" class="icon-button hidden">
<i class="fas fa-clock"></i>
</button>
<button id="email-btn" class="icon-button hidden">
<i class="fas fa-envelope"></i>
<span id="email-badge" class="badge hidden">0</span>
</button>
<button id="accounts-list-btn" class="icon-button hidden">
<i class="fas fa-list-ul"></i>
<span id="accounts-list-badge" class="badge hidden">0</span>
</button>
<div class="account-menu">
<button id="account-menu-btn" class="icon-button">
<i class="fas fa-user-cog"></i>
</button>
<div id="account-menu-popup">
<button id="profile-btn"><i class="fas fa-user-edit"></i>Alterar
Perfil</button>
<button id="settings-btn"><i class="fas
fa-cog"></i>Configurações</button>
<button id="logout-btn"><i class="fas
fa-sign-out-alt"></i>Sair</button>
</div>
</div>
</div>
</header>

<main class="main-content">
<h1 id="main-title" class="draggable">Converter Minecraft Pirata para
Original</h1>
<div class="main-actions">
<button id="convert-btn" class="button draggable">
<i class="fas fa-exchange-alt"></i>Converter Pirata &rarr; Original
</button>
<button id="convert-reverse-btn" class="button secondary draggable
plus-feature">
<i class="fas fa-exchange-alt fa-flip-horizontal"></i>Converter
Original &rarr; Pirata <i class="fas fa-star" style="color: gold; font-size:
0.8em;"></i>
</button>
<button id="manage-accounts-btn" class="button secondary draggable">
<i class="fas fa-users-cog"></i>Gerenciar Contas
</button>
<button id="free-capes-btn" class="button secondary draggable plus-
feature">
<i class="fas fa-scroll"></i>Capas Grátis <i class="fas fa-star"
style="color: gold; font-size: 0.8em;"></i>
</button>
<button id="hypixel-tags-btn" class="button secondary draggable plus-
feature">
<i class="fas fa-tags"></i>Tags Hypixel <i class="fas fa-star"
style="color: gold; font-size: 0.8em;"></i>
</button>
<button id="mushmc-tags-btn" class="button secondary draggable plus-
feature">
<i class="fas fa-tags"></i>Tags MushMC <i class="fas fa-star"
style="color: gold; font-size: 0.8em;"></i>
</button>
<button id="hylex-tags-btn" class="button secondary draggable plus-
feature">
<i class="fas fa-crown"></i>Tags Hylex <i class="fas fa-star"
style="color: gold; font-size: 0.8em;"></i>
</button>
<button id="flamemc-tags-btn" class="button secondary draggable plus-
feature">
<i class="fas fa-fire"></i>Tags FlameMC <i class="fas fa-star"
style="color: gold; font-size: 0.8em;"></i>
</button>
<button id="stardix-tags-btn" class="button secondary draggable plus-
feature">
<i class="fas fa-star-of-life"></i>Tags Stardix <i class="fas fa-
star" style="color: gold; font-size: 0.8em;"></i>
</button>
</div>
</main>

<button id="chatbot-toggle" class="icon-button">


<i class="fas fa-robot"></i>
</button>
</div>

<!-- Conversion Wizard Step 1: Email -->


<div id="conversion-wizard-step-1" class="popup conversion-step">
<button class="icon-button wizard-back-button"
onclick="hideConversionWizard()"><i class="fas fa-times"></i></button>
<h2>Passo 1: Email Microsoft</h2>
<input type="email" id="conversion-email" class="input-field"
placeholder="[email protected]">
<button id="wizard-next-1" class="button">Próximo <i class="fas fa-arrow-
right"></i></button>
</div>

<!-- Conversion Wizard Step 2: Password -->


<div id="conversion-wizard-step-2" class="popup conversion-step">
<button class="icon-button wizard-back-button"
onclick="hideConversionWizard()"><i class="fas fa-times"></i></button>
<h2>Passo 2: Senha</h2>
<input type="password" id="conversion-password" class="input-field"
placeholder="Mínimo 8 caracteres">
<button id="wizard-next-2" class="button">Próximo <i class="fas fa-arrow-
right"></i></button>
</div>

<!-- Conversion Wizard Step 3: Nickname -->


<div id="conversion-wizard-step-3" class="popup conversion-step">
<button class="icon-button wizard-back-button"
onclick="hideConversionWizard()"><i class="fas fa-times"></i></button>
<h2>Passo 3: Nick do Jogo</h2>
<input type="text" id="conversion-nick" class="input-field"
placeholder="SeuNickNoJogo">
<button id="wizard-next-3" class="button">Próximo <i class="fas fa-arrow-
right"></i></button>
</div>

<!-- Conversion Wizard Step 4: Skin -->


<div id="conversion-wizard-step-4" class="popup conversion-step">
<button class="icon-button wizard-back-button"
onclick="hideConversionWizard()"><i class="fas fa-times"></i></button>
<h2>Passo 4: Adicionar Skin</h2>
<div class="skin-preview-container">
<div id="skin-preview">Gire-me!</div>
</div>
<div class="input-group">
<input type="text" id="skin-search-nick" class="input-field"
placeholder="Nick do jogador original">
<button id="skin-search-btn" class="icon-button"><i class="fas fa-
search"></i></button>
</div>
<button id="wizard-next-4" class="button">Próximo <i class="fas fa-arrow-
right"></i></button>
</div>

<!-- Conversion Wizard Step 5: Delivery Time -->


<div id="conversion-wizard-step-5" class="popup conversion-step">
<button class="icon-button wizard-back-button"
onclick="hideConversionWizard()"><i class="fas fa-times"></i></button>
<h2>Passo 5: Tempo de Entrega (Opcional)</h2>
<p>Defina um atraso para a entrega da conta. Deixe em branco para entrega
imediata.</p>
<div class="delivery-time-inputs">
<div><label for="delivery-years">Anos</label><input type="number"
id="delivery-years" class="input-field" min="0" placeholder="0"></div>
<div><label for="delivery-months">Meses</label><input type="number"
id="delivery-months" class="input-field" min="0" max="11" placeholder="0"></div>
<div><label for="delivery-days">Dias</label><input type="number"
id="delivery-days" class="input-field" min="0" max="30" placeholder="0"></div>
<div><label for="delivery-hours">Horas</label><input type="number"
id="delivery-hours" class="input-field" min="0" max="23" placeholder="0"></div>
<div><label for="delivery-minutes">Minutos</label><input type="number"
id="delivery-minutes" class="input-field" min="0" max="59" placeholder="0"></div>
<div><label for="delivery-seconds">Segundos</label><input type="number"
id="delivery-seconds" class="input-field" min="0" max="59" placeholder="0"></div>
</div>
<div class="button-group">
<button id="wizard-confirm-delivery" class="button">Confirmar Atraso <i
class="fas fa-clock"></i></button>
<button id="wizard-finish-now" class="button secondary">Converter Agora
<i class="fas fa-check"></i></button>
</div>
</div>

<!-- Delivery Confirmation Popup -->


<div id="delivery-confirm-popup" class="popup">
<h2><i class="fas fa-check-circle" style="color:
var(--success-color);"></i> Atraso Definido!</h2>
<p id="delivery-confirm-message">Sua conta será entregue em X tempo.</p>
<button class="button" onclick="hidePopup('delivery-confirm-popup');
showScreen('main-app-screen');">Ok</button>
</div>

<!-- Profile Edit Screen -->


<div id="profile-edit-screen" class="screen">
<h1>Editar Perfil</h1>
<div class="profile-section">
<h2>Informações da Conta</h2>
<div class="profile-item">
<label for="profile-name">Nome:</label>
<input type="text" id="profile-name" class="input-field"
style="max-width: 250px;" value="Usuário Google">
</div>
<div class="profile-item">
<label for="profile-pic-input">Foto:</label>
<div>
<img id="profile-pic-preview" src="" alt="Preview">
<input type="file" id="profile-pic-input" accept="image/*">
<button class="button secondary small"
onclick="document.getElementById('profile-pic-input').click();">
<i class="fas fa-upload"></i> Alterar Foto
</button>
</div>
</div>
</div>
<div class="profile-section">
<h2>Configurações Adicionais</h2>
<p style="color: var(--text-darker); margin-bottom: 15px;">Mais opções
de personalização aqui.</p>
{/* Add more profile settings as needed */}
</div>
<button class="button" onclick="showScreen('main-app-screen')"><i
class="fas fa-arrow-left"></i> Voltar</button>
</div>

<!-- Settings Screen -->


<div id="settings-screen" class="screen">
<h1>Configurações</h1>
<div class="settings-section">
<h2>Aparência</h2>
<div class="setting-item">
<label for="font-select">Fonte:</label>
<select id="font-select" class="input-field" style="max-width:
200px;">
<option value="default">Padrão (Segoe UI)</option>
<option value="alt">Alternativa (Roboto)</option>
</select>
</div>
</div>
<div class="settings-section">
<h2>Idioma</h2>
<div class="setting-item">
<label for="language-select">Idioma:</label>
<select id="language-select" class="input-field" style="max-width:
200px;">
<option value="pt-BR">Português (BR)</option>
<option value="en">English</option>
<option value="es">Español</option>
<option value="fr">Français</option>
<option value="de">Deutsch</option>
<option value="ja">日本語</option>
<option value="zh">中文</option>
<option value="ru">Русский</option>
</select>
</div>
</div>
<div class="settings-section">
<h2>Outras Configurações</h2>
<p style="color: var(--text-darker); margin-bottom: 15px;">Opções de
notificação, conta, etc.</p>
{/* Add more settings as needed */}
</div>
<button class="button" onclick="showScreen('main-app-screen')"><i
class="fas fa-arrow-left"></i> Voltar</button>
</div>

<!-- Manage Accounts Popup -->


<div id="manage-accounts-popup" class="popup list-popup">
<h2><i class="fas fa-users-cog"></i> Contas Criadas</h2>
<ul id="created-accounts-list">
<!-- Accounts will be listed here -->
<li class="empty-message">Nenhuma conta criada ainda.</li>
</ul>
<button class="button secondary" style="margin-top: 20px;"
onclick="hidePopup('manage-accounts-popup')">Fechar</button>
</div>

<!-- Email Popup -->


<div id="email-popup" class="popup list-popup">
<h2><i class="fas fa-envelope-open-text"></i> Caixa de Entrada</h2>
<ul id="email-list">
<li class="empty-message">Você não recebeu nenhum email.</li>
</ul>
<button class="button secondary" style="margin-top: 20px;"
onclick="hidePopup('email-popup')">Fechar</button>
</div>

<!-- Delivery Timer Popup -->


<div id="delivery-timer-popup" class="popup">
<h2><i class="fas fa-hourglass-half"></i> Entrega Agendada</h2>
<h3>Tempo Restante:</h3>
<p id="delivery-countdown">Calculando...</p>
<div class="button-group">
<button id="cancel-delivery-btn" class="button danger"><i class="fas
fa-times"></i> Cancelar Entrega</button>
<button class="button secondary" onclick="hidePopup('delivery-timer-
popup')">Fechar</button>
</div>
</div>

<!-- Ban History Popup -->


<div id="ban-history-popup" class="popup list-popup">
<h2><i class="fas fa-history"></i> Histórico de Banimentos</h2>
<ul id="ban-history-list">
<li class="empty-message">Nenhum banimento registrado.</li>
</ul>
<button class="button secondary" style="margin-top: 20px;"
onclick="hidePopup('ban-history-popup')">Fechar</button>
</div>

<!-- Chatbot Popup -->


<div id="chatbot-popup" class="popup">
<div class="chatbot-header">
<h2>Chatbot Assistente</h2>
<button id="close-chatbot-btn" class="icon-button"><i class="fas fa-
times"></i></button>
</div>
<div id="chatbot-messages" class="chatbot-messages">
<div class="chat-message bot">Olá! Sou o assistente MineConv. Como
posso ajudar você hoje?</div>
</div>
<div class="chatbot-input">
<input type="text" id="chatbot-input-field" class="input-field"
placeholder="Digite sua pergunta...">
<button id="chatbot-send-btn" class="button"><i class="fas fa-paper-
plane"></i></button>
</div>
</div>

<!-- Generic Info/Error Popup -->


<div id="info-popup" class="popup">
<h2 id="info-popup-title">Informação</h2>
<p id="info-popup-message">Mensagem aqui.</p>
<button class="button" onclick="hidePopup('info-popup')">Ok</button>
</div>

<!-- Plus Required Popup -->


<div id="plus-required-popup" class="popup">
<h2><i class="fas fa-star" style="color: gold;"></i> Recurso MineConv+</h2>
<p>Esta funcionalidade é exclusiva para assinantes do plano MineConv+
Plus.</p>
<p style="font-size: 0.9em; color: var(--text-darker);">(Simulação:
Assinatura não implementada)</p>
<button class="button" onclick="hidePopup('plus-required-
popup')">Entendido</button>
</div>

<!-- Ban Popup -->


<div id="ban-popup" class="popup">
<div class="popup-content">
<h2 id="ban-popup-title"><i class="fas fa-ban"></i> Banido!</h2>
<div class="ban-details">
<p id="ban-popup-reason">Motivo: Violação dos termos.</p>
<p id="ban-popup-duration">Tempo restante: Calculando...</p>
</div>
<p id="ban-popup-advice" style="font-size: 0.9em; color: var(--text-
darker);">Recarregar a página não removerá o banimento.</p>

<div id="ban-actions" class="ban-actions">


<!-- Buttons will be added dynamically by JS -->
</div>
<p id="final-ban-message" class="final-ban-message hidden">Você
atingiu o limite de banimentos permanentes e não pode mais usar esta conta ou criar
novas.</p>
</div>
</div>

<!-- Unban Simulation Popup -->


<div id="unban-sim-popup" class="popup">
<h2><i class="fas fa-video"></i> Adquirir Unban</h2>
<p>Assista aos vídeos abaixo para remover seu banimento permanente.</p>
<div class="video-placeholder">Simulação de Vídeo 1</div>
<div class="video-placeholder">Simulação de Vídeo 2</div>
<div class="video-placeholder">Simulação de Vídeo 3</div>
<div class="progress-bar-container">
<div id="unban-progress-bar" class="progress-bar" style="width: 0%;
background: var(--success-color);"></div>
</div>
<p id="unban-status-text" style="margin-top: 15px; font-size:
0.9em;">Progresso: 0%</p>
<button id="finish-unban-btn" class="button hidden" style="margin-top:
20px; background: var(--success-color);"><i class="fas fa-check"></i> Finalizar
Unban</button>
</div>

<!-- Rules Popup -->


<div id="rules-popup" class="popup list-popup">
<h2><i class="fas fa-book"></i> Regras e Punições</h2>
<ul>
<li><strong>Linguagem Imprópria no Chatbot:</strong>
<ul>
<li>Primeira vez: Banimento temporário de 5 minutos.</li>
<li>Reincidência: Banimentos progressivamente mais longos.</li>
</ul>
</li>
<li><strong>Envio Excessivo de Mensagens no Chatbot (Spam):</strong>
<ul>
<li>Banimento temporário de 10 minutos.</li>
</ul>
</li>
<li><strong>Uso de Nickname Suspeito (com termos proibidos):</strong>
<ul>
<li>Banimento temporário de 1 dia.</li>
</ul>
</li>
<li><strong>Uso de Email Suspeito (temporário/descartável):</strong>
<ul>
<li>Banimento temporário de 1 dia.</li>
</ul>
</li>
<li><strong>Atividade Suspeita Durante Login/Logout:</strong>
<ul>
<li>Banimento temporário de 1 dia (para investigação).</li>
</ul>
</li>
<li><strong>Tentativa de Definir Tempo de Entrega Excessivo:</strong>
<ul>
<li>Banimento temporário de 1 dia.</li>
</ul>
</li>
<li><strong>Abuso da Função "Criar Nova Conta" para obter vantagens
injustas:</strong>
<ul>
<li>Primeira vez: Banimento temporário de 30 dias.</li>
<li>Reincidência: Banimento permanente.</li>
</ul>
</li>
</ul>
<h3>Política de Banimentos Permanentes</h3>
<p>Após atingir um certo número de banimentos temporários ou cometer
infrações graves, sua conta poderá ser banida permanentemente. Banimentos
permanentes são irreversíveis, a menos que você adquira um 'Unban' através de meios
específicos (quando disponíveis).</p>

<button class="button secondary" style="margin-top: 20px;"


onclick="hidePopup('rules-popup')">Fechar</button>
</div>

<!-- Accounts List Popup -->


<div id="accounts-list-popup" class="popup list-popup">
<h2><i class="fas fa-list-ul"></i> Contas Existentes</h2>
<ul id="existing-accounts-list">
<!-- Accounts will be listed here -->
<li class="empty-message">Nenhuma conta criada ainda.</li>
</ul>
<button class="button secondary" style="margin-top: 20px;"
onclick="hidePopup('accounts-list-popup')">Fechar</button>
</div>
<!-- Notification Banner -->
<div id="notification-banner">
<i id="notification-icon" class="fas fa-check-circle"></i>
<span id="notification-message">Ação realizada com sucesso!</span>
</div>

<!-- Edit Mode Controls -->


<div id="edit-mode-controls" class="hidden">
<button id="save-layout-btn" class="button"><i class="fas fa-save"></i>
Salvar Layout</button>
<button id="cancel-layout-btn" class="button secondary"><i class="fas fa-
times"></i> Cancelar</button>
</div>

<script>
// --- Constants and State ---
const LOADING_TIME = 3000; // 3 seconds loading
const DAILY_LIMIT = 3;
const BANNED_KEYWORDS_NICK = ['hack', 'cheat', 'crack', 'bot', 'exploit',
'script', 'auto', 'burla', 'roubar']; // Nickname keywords
const BANNED_KEYWORDS_CHAT = ['xingamento_aqui', 'palavrão_aqui',
'insulto_aqui']; // Chatbot keywords
const MAX_TEMP_BANS = 3; // 3 temp bans before permanent
const MAX_PERMANENT_BANS = 3; // 3 permanent bans before final block
const MAX_NEW_ACCOUNT_CREATIONS = 5; // Limit for creating new accounts
after perm ban
const CHATBOT_BAN_DURATION_FAST_MESSAGES = 5 * 60 * 1000; // 5 minutes for
fast messages
const CHATBOT_BAN_DURATION_SWEARING = 5 * 60 * 1000; // 5 minutes for
swearing
const ACCOUNT_ABUSE_BAN_DURATION = 30 * 24 * 60 * 60 * 1000; // 30 days for
account abuse

let currentState = {
loggedInAs: null, // 'google' or 'guest'
currentScreen: 'loading-screen',
conversionLimits: DAILY_LIMIT,
lastLimitReset: null, // Store date string YYYY-MM-DD
isBanned: false,
banType: null, // 'temporary' or 'permanent'
banReason: '',
banExpiry: null, // Store timestamp for temporary bans
banHistory: [], // Store { reason: '...', type: '...', timestamp: ... }
permanentBanCount: 0, // Count how many permanent bans occurred
newAccountCreations: 0, // Count how many times 'Create New Account' was
used
createdAccounts: [], // Store { nick: '...', email: '...', skin: '...' }
elementPositions: {}, // Store { elementId: { top: '...', left: '...' } }
isEditMode: false,
originalPositions: {}, // Store original positions before dragging
unreadEmails: 0,
emails: [], // Store { id: ..., subject: '...', body: '...',
timestamp: ..., read: false }
deliveryTimerEnd: null, // Timestamp when delivery finishes
deliveryTimerInterval: null, // Interval ID for the countdown
deliveryData: null, // Store conversion data during timer
profilePic: null, // Store data URL of profile picture
language: 'pt-BR', // Default language
fontFamily: 'default', // 'default' or 'alt'
lastChatMessagesTimestamps: [], // For rate limiting chatbot messages
};

let clockInterval = null;


let unbanProgressInterval = null;
let unbanTimeout = null;
let lastTimeUpdate = null; // For clock animation

// --- DOM Elements ---


const screens = document.querySelectorAll('.screen');
const popups = document.querySelectorAll('.popup');
const loadingBar = document.getElementById('loading-bar'); // Renamed
const limitsCount = document.getElementById('limits-count');
const limitsDisplay = document.getElementById('limits-display');
const accountMenuBtn = document.getElementById('account-menu-btn');
const accountMenuPopup = document.getElementById('account-menu-popup');
const chatbotToggle = document.getElementById('chatbot-toggle');
const chatbotPopup = document.getElementById('chatbot-popup');
const closeChatbotBtn = document.getElementById('close-chatbot-btn');
const chatbotMessages = document.getElementById('chatbot-messages');
const chatbotInputField = document.getElementById('chatbot-input-field');
const chatbotSendBtn = document.getElementById('chatbot-send-btn');
const notificationBanner = document.getElementById('notification-banner');
const notificationIcon = document.getElementById('notification-icon');
const notificationMessage = document.getElementById('notification-
message');
const editModeControls = document.getElementById('edit-mode-controls');
const createdAccountsList = document.getElementById('created-accounts-
list');
const clockDisplay = document.getElementById('clock-display');
const emailBtn = document.getElementById('email-btn');
const emailBadge = document.getElementById('email-badge');
const emailPopup = document.getElementById('email-popup');
const emailList = document.getElementById('email-list');
const deliveryTimerBtn = document.getElementById('delivery-timer-btn');
const deliveryTimerPopup = document.getElementById('delivery-timer-popup');
const deliveryCountdown = document.getElementById('delivery-countdown');
const banHistoryBtn = document.getElementById('ban-history-btn');
const banHistoryBadge = document.getElementById('ban-history-badge');
const banHistoryPopup = document.getElementById('ban-history-popup');
const banHistoryList = document.getElementById('ban-history-list');
const profilePicPreview = document.getElementById('profile-pic-preview');
const profilePicInput = document.getElementById('profile-pic-input');
const languageSelect = document.getElementById('language-select');
const fontSelect = document.getElementById('font-select');
const rulesBtn = document.getElementById('rules-btn');
const rulesPopup = document.getElementById('rules-popup');
const accountsListBtn = document.getElementById('accounts-list-btn');
const accountsListPopup = document.getElementById('accounts-list-popup');
const existingAccountsListEl = document.getElementById('existing-accounts-
list');
const createAccountBtn = document.getElementById('create-account-btn');

// --- Initialization ---


function initializeApp() {
loadState();
updateClock(); // Initial clock update
if (clockInterval) clearInterval(clockInterval);
clockInterval = setInterval(updateClock, 1000); // Update clock every
second

applyLanguage(); // Apply saved language


applyFont(); // Apply saved font
applyProfilePic(); // Apply saved profile pic

checkBanStatus(); // Check ban first

if (currentState.isBanned) {
showBanScreen();
return; // Stop further initialization if banned
}

// Start loading animation


let progress = 0;
const interval = setInterval(() => {
progress += 100 / (LOADING_TIME / 100); // Update every 100ms for
smoother bar
loadingBar.style.width = Math.min(progress, 100) + '%';
if (progress >= 100) {
clearInterval(interval);
setTimeout(() => {
// Decide initial screen after loading based on saved state
if (currentState.loggedInAs) {
checkDailyLimitReset(); // Check limits if logged in
updateHeaderUI(); // Update all header icons/badges
startDeliveryTimerIfNeeded(); // Resume timer if active
showScreen('mode-select-screen'); // Or main-app if preferred
} else {
showScreen('login-screen');
}
}, 300); // Short delay after loading bar full
}
}, 100); // Faster interval for smoother bar
}

// --- Clock ---


function updateClock() {
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const currentTime = `${hours}:${minutes}`;

if (clockDisplay.textContent !== currentTime) {


clockDisplay.classList.add('animated'); // Trigger animation
setTimeout(() => {
clockDisplay.classList.remove('animated'); // Remove class
after animation
}, 500); // Match CSS animation duration
}
clockDisplay.textContent = currentTime;
}

// --- State Management (LocalStorage) ---


function saveState() {
try {
// Basic anti-tamper (very weak, just for demonstration)
const stateString = JSON.stringify(currentState);
const checksum = btoa(stateString).substring(0, 10); // Simple checksum
const dataToSave = { state: currentState, chk: checksum };
localStorage.setItem('mineConvState_v2', JSON.stringify(dataToSave));
// console.log("State saved.");
} catch (e) {
console.error("Failed to save state:", e);
showNotification("Erro ao salvar progresso localmente.", "error");
}
}

function loadState() {
try {
const savedData = localStorage.getItem('mineConvState_v2');
if (savedData) {
const parsedData = JSON.parse(savedData);
const stateString = JSON.stringify(parsedData.state);
const checksum = btoa(stateString).substring(0, 10);

if (parsedData.chk === checksum) {


// Merge carefully, don't overwrite functions etc.
currentState = { ...currentState, ...parsedData.state };
// Ensure nested objects/arrays are handled
currentState.elementPositions = parsedData.state.elementPositions
|| {};
currentState.createdAccounts = parsedData.state.createdAccounts
|| [];
currentState.emails = parsedData.state.emails || [];
currentState.banHistory = parsedData.state.banHistory || [];
currentState.lastChatMessagesTimestamps =
parsedData.state.lastChatMessagesTimestamps || [];
// console.log("State loaded successfully.");
} else {
console.warn("State checksum mismatch. Resetting state.");
localStorage.removeItem('mineConvState_v2');
// Optionally notify user about potential data loss/reset
// showNotification("Dados locais corrompidos, resetando.",
"warning");
}
}
} catch (e) {
console.error("Failed to load state:", e);
localStorage.removeItem('mineConvState_v2'); // Clear corrupted state
}
}

// --- Navigation ---


function showScreen(screenId) {
if (currentState.isBanned && screenId !== 'ban-screen') { // Redirect to
ban screen if banned
showBanScreen();
return;
}
screens.forEach(screen => {
screen.id === screenId ? screen.classList.add('active') :
screen.classList.remove('active');
});
currentState.currentScreen = screenId;
hideAllPopups();
accountMenuPopup.classList.remove('active');
editModeControls.classList.toggle('hidden', screenId !== 'main-app-
screen' || !currentState.isEditMode);
document.body.classList.toggle('edit-mode', currentState.isEditMode &&
screenId === 'main-app-screen');

// Apply element positions when showing main screen in normal mode


if (screenId === 'main-app-screen' && !currentState.isEditMode) {
applyElementPositions();
}

console.log("Showing screen:", screenId);


}

function showPopup(popupId) {
if (currentState.isBanned && !['ban-popup', 'unban-sim-popup', 'rules-
popup'].includes(popupId)) return; // Prevent most popups if banned
hideAllPopups(); // Hide others before showing new one
const popup = document.getElementById(popupId);
if (popup) {
popup.classList.add('active');
}
}

function hidePopup(popupId) {
const popup = document.getElementById(popupId);
if (popup) {
popup.classList.remove('active');
}
}

function hideAllPopups() {
popups.forEach(popup => popup.classList.remove('active'));
accountMenuPopup.classList.remove('active'); // Also hide account menu
}

// --- Notifications ---


function showNotification(message, type = 'success', duration = 4000) {
notificationMessage.textContent = message;
notificationBanner.className = ''; // Reset classes
notificationBanner.classList.add(type); // 'success', 'error', or
'warning'
let iconClass = 'fa-check-circle';
if (type === 'error') iconClass = 'fa-exclamation-triangle';
if (type === 'warning') iconClass = 'fa-exclamation-circle';
notificationIcon.className = `fas ${iconClass}`;

notificationBanner.classList.add('show');

// Auto-hide after specified duration


setTimeout(() => {
notificationBanner.classList.remove('show');
}, duration);
}

// --- Login/Logout Logic ---


document.getElementById('google-login-btn').addEventListener('click', () =>
{
console.log("Simulating Google Login...");
// Simulate anti-cheat check
if (Math.random() < 0.05) { // 5% chance of simulated detection
applyBan('login-suspicion', 'Atividade suspeita durante o login.',
1);
return;
}

currentState.loggedInAs = 'google';
checkDailyLimitReset();
updateHeaderUI();
updateAccountsListBadge();
saveState();
showScreen('mode-select-screen');
showNotification('Login com Google bem-sucedido!', 'success');
});

document.getElementById('guest-login-btn').addEventListener('click', () =>
{
showPopup('guest-confirm-popup');
});

document.getElementById('guest-confirm-ok').addEventListener('click', () =>
{
console.log("Entering as Guest...");
currentState.loggedInAs = 'guest';
updateHeaderUI(); // Hide relevant icons for guest
updateAccountsListBadge();
saveState();
hidePopup('guest-confirm-popup');
showScreen('mode-select-screen');
});

document.getElementById('guest-confirm-cancel').addEventListener('click',
() => {
hidePopup('guest-confirm-popup');
});

document.getElementById('logout-btn').addEventListener('click', () => {
console.log("Logging out...");
// Simulate anti-cheat check
if (Math.random() < 0.02) { // 2% chance
applyBan('logout-suspicion', 'Atividade suspeita durante o logout.',
1);
// Don't proceed with logout if banned during the process
return;
}

currentState.loggedInAs = null;
currentState.isEditMode = false;
// Clear sensitive session data, but keep limits, bans, history etc.
currentState.elementPositions = {};
currentState.originalPositions = {};
// Stop timers
if (currentState.deliveryTimerInterval)
clearInterval(currentState.deliveryTimerInterval);
currentState.deliveryTimerInterval = null;
saveState();
updateHeaderUI(); // Hide icons
updateAccountsListBadge();
showScreen('login-screen');
showNotification('Você saiu da sua conta.', 'success');
});

document.getElementById('create-account-btn').addEventListener('click',
createNewAccountAfterBan);

// --- Mode Selection ---


document.getElementById('normal-mode-btn').addEventListener('click', () =>
{
currentState.isEditMode = false;
saveState();
applyElementPositions(); // Apply saved positions if any
showScreen('main-app-screen');
});

document.getElementById('edit-mode-btn').addEventListener('click', () => {
if (currentState.loggedInAs === 'guest') {
showInfoPopup("Acesso Negado", "O Modo Edição não está disponível para
convidados.");
return;
}
currentState.isEditMode = true;
saveState();
enableDragAndDrop();
showScreen('main-app-screen');
editModeControls.classList.remove('hidden');
showNotification("Modo Edição Ativado. Arraste os elementos.",
"success");
});

// --- Header UI Management ---


function updateHeaderUI() {
const isGuest = currentState.loggedInAs === 'guest';
const isLoggedIn = currentState.loggedInAs === 'google';

// Limits Display
limitsDisplay.classList.toggle('hidden', isGuest);
if (isLoggedIn) {
limitsCount.textContent = currentState.conversionLimits;
}

// Email Button & Badge


emailBtn.classList.toggle('hidden', !isLoggedIn);
if (isLoggedIn) {
emailBadge.textContent = currentState.unreadEmails;
emailBadge.classList.toggle('hidden', currentState.unreadEmails ===
0);
} else {
emailBadge.classList.add('hidden');
}

// Delivery Timer Button


deliveryTimerBtn.classList.toggle('hidden', !isLoggedIn || !
currentState.deliveryTimerEnd);
// Ban History Button & Badge
banHistoryBtn.classList.toggle('hidden', !isLoggedIn);
if (isLoggedIn) {
const banCount = currentState.banHistory.length;
banHistoryBadge.textContent = banCount;
banHistoryBadge.classList.toggle('hidden', banCount === 0);
} else {
banHistoryBadge.classList.add('hidden');
}

// Accounts List Button & Badge


accountsListBtn.classList.toggle('hidden', !isLoggedIn);
updateAccountsListBadge();

// Chatbot Toggle
chatbotToggle.classList.toggle('hidden', !isLoggedIn);

// Account Menu Button (always visible if logged in or guest, but


functionality differs)
accountMenuBtn.classList.toggle('hidden', !currentState.loggedInAs);
}

function updateAccountsListBadge() {
const isLoggedIn = currentState.loggedInAs === 'google';
accountsListBtn.classList.toggle('hidden', !isLoggedIn);
if (isLoggedIn) {
const accountsCount = currentState.createdAccounts.length;
document.getElementById('accounts-list-badge').textContent =
accountsCount;
document.getElementById('accounts-list-
badge').classList.toggle('hidden', accountsCount === 0);
} else {
document.getElementById('accounts-list-
badge').classList.add('hidden');
}
}

// --- Account Menu ---


accountMenuBtn.addEventListener('click', (e) => {
e.stopPropagation(); // Prevent body click from closing immediately
accountMenuPopup.classList.toggle('active');
});

document.body.addEventListener('click', (e) => {


if (!accountMenuPopup.contains(e.target) && !
accountMenuBtn.contains(e.target)) {
accountMenuPopup.classList.remove('active');
}
});

document.getElementById('profile-btn').addEventListener('click', () => {
if (currentState.loggedInAs === 'guest') {
showInfoPopup("Acesso Negado", "Não é possível editar o perfil no Modo
Convidado.");
return;
}
// Load current profile data into fields
document.getElementById('profile-name').value = "Usuário Google"; //
Replace with actual name if stored
applyProfilePic(); // Ensure preview is updated
showScreen('profile-edit-screen');
});

document.getElementById('settings-btn').addEventListener('click', () => {
languageSelect.value = currentState.language; // Set current language
fontSelect.value = currentState.fontFamily; // Set current font
showScreen('settings-screen');
});

// --- Profile Picture Handling ---


profilePicInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (file && file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
currentState.profilePic = e.target.result; // Store as data URL
profilePicPreview.style.backgroundImage = `url($
{currentState.profilePic})`;
saveState();
showNotification("Foto de perfil atualizada (simulado).",
"success");
}
reader.readAsDataURL(file);
} else if (file) {
showNotification("Por favor, selecione um arquivo de imagem.",
"error");
}
});

function applyProfilePic() {
if (currentState.profilePic) {
profilePicPreview.style.backgroundImage = `url($
{currentState.profilePic})`;
} else {
profilePicPreview.style.backgroundImage = 'none'; // Or a default
image
}
}

// --- Language Handling ---


languageSelect.addEventListener('change', (event) => {
currentState.language = event.target.value;
saveState();
applyLanguage();
showNotification(`Idioma alterado para $
{languageSelect.options[languageSelect.selectedIndex].text} (simulado).`,
"success");
});

function applyLanguage() {
// In a real app, this would involve loading translation files
// Here, we just simulate by changing a few key texts if needed
console.log(`Applying language: ${currentState.language}`);
// Example: document.getElementById('main-title').textContent =
getTranslation('main_title');
document.documentElement.lang = currentState.language.split('-')[0]; //
Set lang attribute
}

// --- Font Handling ---


fontSelect.addEventListener('change', (event) => {
currentState.fontFamily = event.target.value;
saveState();
applyFont();
showNotification(`Fonte alterada para $
{fontSelect.options[fontSelect.selectedIndex].text} (simulado).`, "success");
});

function applyFont() {
if (currentState.fontFamily === 'alt') {
document.documentElement.style.setProperty('--current-font-family',
'var(--alt-font-family)');
} else {
document.documentElement.style.setProperty('--current-font-family',
'var(--font-family)');
}
}

// --- Conversion Limits ---


function checkDailyLimitReset() {
const today = new Date().toLocaleDateString('sv-SE'); // YYYY-MM-DD
format
if (currentState.lastLimitReset !== today) {
console.log("Resetting daily limits for", today);
currentState.conversionLimits = DAILY_LIMIT;
currentState.lastLimitReset = today;
saveState();
}
}

limitsDisplay.addEventListener('click', () => {
if (currentState.loggedInAs === 'google') {
showInfoPopup("Limite de Conversão", `Você tem $
{currentState.conversionLimits} conversões restantes hoje. Assine o MineConv+ Plus
para ter vidas ilimitadas (Simulado).`);
}
});

// --- Conversion Wizard ---


let conversionData = {}; // Temporary storage during wizard

document.getElementById('convert-btn').addEventListener('click', () => {
if (currentState.loggedInAs === 'guest') {
showInfoPopup("Acesso Negado", "A conversão de contas não está
disponível para convidados.");
return;
}
if (currentState.conversionLimits <= 0) {
showInfoPopup("Limite Atingido", "Você usou todas as suas conversões
gratuitas por hoje. Volte amanhã ou assine o MineConv+.");
return;
}
// Reset previous data and start wizard
conversionData = {};
document.getElementById('conversion-email').value = '';
document.getElementById('conversion-password').value = '';
document.getElementById('conversion-nick').value = '';
document.getElementById('skin-search-nick').value = '';
document.getElementById('skin-preview').style.backgroundImage = 'none';
document.getElementById('skin-preview').classList.remove('loaded');
document.getElementById('skin-preview').textContent = 'Gire-me!';
document.getElementById('skin-preview').style.transform = 'rotateX(0deg)
rotateY(0deg)'; // Reset rotation
// Reset delivery time inputs
['years', 'months', 'days', 'hours', 'minutes', 'seconds'].forEach(unit
=> {
document.getElementById(`delivery-${unit}`).value = '';
});

showPopup('conversion-wizard-step-1');
});

function hideConversionWizard() {
hidePopup('conversion-wizard-step-1');
hidePopup('conversion-wizard-step-2');
hidePopup('conversion-wizard-step-3');
hidePopup('conversion-wizard-step-4');
hidePopup('conversion-wizard-step-5');
}

// Step 1 -> Step 2 (Email)


document.getElementById('wizard-next-1').addEventListener('click', () => {
const email = document.getElementById('conversion-email').value.trim();
// Basic validation, allow more domains if needed
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
showNotification("Formato de email inválido.", "error");
return;
}
// Simulate anti-cheat check
if (email.includes('temp') || email.includes('disposable')) {
applyBan('suspicious-email', 'Uso de email suspeito
(temporário/descartável).', 1);
hideConversionWizard();
return;
}
conversionData.email = email;
hidePopup('conversion-wizard-step-1');
showPopup('conversion-wizard-step-2');
});

// Step 2 -> Step 3 (Password)


document.getElementById('wizard-next-2').addEventListener('click', () => {
const password = document.getElementById('conversion-password').value;
if (password.length < 8) {
showNotification("A senha deve ter pelo menos 8 caracteres.", "error");
return;
}
conversionData.password = password; // NOTE: Storing password client-side
is insecure!
hidePopup('conversion-wizard-step-2');
showPopup('conversion-wizard-step-3');
});

// Step 3 -> Step 4 (Nickname)


document.getElementById('wizard-next-3').addEventListener('click', () => {
const nick = document.getElementById('conversion-nick').value.trim();
const nickRegex = /^[a-zA-Z0-9_]{3,16}$/; // Common Minecraft nick
constraints
if (!nickRegex.test(nick)) {
showNotification("Nickname inválido (3-16 caracteres, letras, números,
_).", "error");
return;
}
// Simulate anti-cheat check
if (BANNED_KEYWORDS_NICK.some(keyword =>
nick.toLowerCase().includes(keyword))) {
applyBan('suspicious-nickname', 'Nickname contém termos proibidos.',
1);
hideConversionWizard();
return;
}
conversionData.nick = nick;
hidePopup('conversion-wizard-step-3');
showPopup('conversion-wizard-step-4');
});

// Step 4 - Skin Search


document.getElementById('skin-search-btn').addEventListener('click', () =>
{
const nick = document.getElementById('skin-search-nick').value.trim();
if (!nick) {
showNotification("Digite um nick para pesquisar a skin.", "error");
return;
}
showNotification(`Pesquisando skin para ${nick}...`, 'success');
setTimeout(() => {
const skinUrl = `https://crafatar.com/renders/body/${nick}?
overlay&default=MHF_Steve&scale=10`; // Use Steve as default
const skinPreview = document.getElementById('skin-preview');
// Check if image loaded successfully (basic check)
const img = new Image();
img.onload = () => {
skinPreview.style.backgroundImage = `url(${skinUrl})`;
skinPreview.textContent = ''; // Clear placeholder text
skinPreview.classList.add('loaded');
conversionData.skinNick = nick; // Store the nick used for the skin
showNotification(`Skin de ${nick} carregada!`, 'success');
};
img.onerror = () => {
skinPreview.style.backgroundImage =
`url(https://crafatar.com/renders/body/MHF_Steve?overlay&scale=10)`; // Fallback to
Steve
skinPreview.textContent = '';
skinPreview.classList.add('loaded');
conversionData.skinNick = 'MHF_Steve'; // Store fallback
showNotification(`Skin de ${nick} não encontrada. Usando skin
padrão.`, 'warning');
};
img.src = skinUrl;
}, 1000); // Simulate network delay
});

// Step 4 -> Step 5 (Skin Confirmation)


document.getElementById('wizard-next-4').addEventListener('click', () => {
if (!conversionData.skinNick) { // Check if skin was searched/loaded
showNotification("Por favor, pesquise e carregue uma skin antes de
continuar.", "error");
return;
}
hidePopup('conversion-wizard-step-4');
showPopup('conversion-wizard-step-5');
});

// Step 5 - Finish Conversion (Immediate)


document.getElementById('wizard-finish-now').addEventListener('click', ()
=> {
finishConversion(0); // 0 delay means immediate
});

// Step 5 - Confirm Delivery Delay


document.getElementById('wizard-confirm-
delivery').addEventListener('click', () => {
let totalDelaySeconds = 0;
try {
const years = parseInt(document.getElementById('delivery-
years').value || '0');
const months = parseInt(document.getElementById('delivery-
months').value || '0');
const days = parseInt(document.getElementById('delivery-
days').value || '0');
const hours = parseInt(document.getElementById('delivery-
hours').value || '0');
const minutes = parseInt(document.getElementById('delivery-
minutes').value || '0');
const seconds = parseInt(document.getElementById('delivery-
seconds').value || '0');

if (isNaN(years) || isNaN(months) || isNaN(days) || isNaN(hours) ||


isNaN(minutes) || isNaN(seconds) ||
years < 0 || months < 0 || days < 0 || hours < 0 || minutes < 0
|| seconds < 0 ||
months > 11 || days > 30 || hours > 23 || minutes > 59 ||
seconds > 59) {
showNotification("Valores de tempo inválidos.", "error");
return;
}

totalDelaySeconds = seconds +
minutes * 60 +
hours * 3600 +
days * 86400 +
months * 30 * 86400 + // Approximation
years * 365 * 86400; // Approximation

} catch (e) {
showNotification("Erro ao processar o tempo.", "error");
return;
}
if (totalDelaySeconds <= 0) {
showNotification("O tempo de atraso deve ser maior que zero.",
"error");
return;
}
// Simulate anti-cheat check for excessive delay
if (totalDelaySeconds > 30 * 86400) { // More than 30 days
applyBan('excessive-delay', 'Tentativa de definir tempo de entrega
excessivo.', 1);
hideConversionWizard();
return;
}

finishConversion(totalDelaySeconds);
});

function finishConversion(delaySeconds) {
// Final validation
if (!conversionData.email || !conversionData.password || !
conversionData.nick || !conversionData.skinNick) {
showNotification("Erro interno: Dados de conversão incompletos.",
"error");
hideConversionWizard();
return;
}
if (currentState.conversionLimits <= 0) {
showNotification("Limite de conversão diário atingido.", "error");
hideConversionWizard();
return;
}

// Consume limit
currentState.conversionLimits--;
updateHeaderUI();

const finalData = { ...conversionData }; // Copy data

if (delaySeconds > 0) {
// Schedule delayed delivery
currentState.deliveryTimerEnd = Date.now() + delaySeconds * 1000;
currentState.deliveryData = finalData; // Store data for later
startDeliveryTimerIfNeeded();
updateHeaderUI(); // Show clock icon
saveState();
hideConversionWizard();
// Show confirmation popup
document.getElementById('delivery-confirm-message').textContent =
`Sua conta para ${finalData.nick} será entregue em $
{formatTimeDuration(delaySeconds)}.`;
showPopup('delivery-confirm-popup');
console.log(`Conversion scheduled for ${finalData.nick} in $
{delaySeconds}s`);

} else {
// Process immediate conversion
console.log("Simulating immediate conversion for:", finalData);
// Add to managed accounts
currentState.createdAccounts.push({ nick: finalData.nick, email:
finalData.email, skin: finalData.skinNick });
updateManageAccountsList();
updateAccountsListBadge();
saveState();
hideConversionWizard();
showNotification(`Conta para ${finalData.nick} convertida com
sucesso!`, 'success');
// Send immediate email notification
addEmail("Conversão Concluída", `Sua conta Minecraft para o nick $
{finalData.nick} foi convertida com sucesso.`);
}
}

// --- Delivery Timer ---


function startDeliveryTimerIfNeeded() {
if (currentState.deliveryTimerEnd && !
currentState.deliveryTimerInterval) {
const now = Date.now();
if (currentState.deliveryTimerEnd > now) {
// Timer is active and hasn't finished
updateHeaderUI(); // Ensure clock icon is visible
currentState.deliveryTimerInterval =
setInterval(checkDeliveryTimer, 1000);
console.log("Delivery timer resumed.");
} else {
// Timer finished while offline
console.log("Delivery timer finished while offline.
Processing...");
processScheduledDelivery();
}
}
}

function checkDeliveryTimer() {
if (!currentState.deliveryTimerEnd) {
clearInterval(currentState.deliveryTimerInterval);
currentState.deliveryTimerInterval = null;
return;
}

const now = Date.now();


const timeLeft = Math.max(0, Math.round((currentState.deliveryTimerEnd
- now) / 1000));

if (deliveryTimerPopup.classList.contains('active')) {
deliveryCountdown.textContent = formatTimeDuration(timeLeft);
}

if (timeLeft <= 0) {
console.log("Delivery timer finished.");
processScheduledDelivery();
}
}

function processScheduledDelivery() {
if (currentState.deliveryTimerInterval)
clearInterval(currentState.deliveryTimerInterval);
currentState.deliveryTimerInterval = null;
if (currentState.deliveryData) {
const finalData = currentState.deliveryData;
console.log("Processing scheduled conversion for:", finalData);
// Add to managed accounts
currentState.createdAccounts.push({ nick: finalData.nick, email:
finalData.email, skin: finalData.skinNick });
updateManageAccountsList();
updateAccountsListBadge();
// Send email notification
addEmail("Entrega Concluída", `Sua conta Minecraft agendada para o
nick ${finalData.nick} foi entregue com sucesso.`);
showNotification(`Entrega da conta para ${finalData.nick}
concluída!`, 'success');
} else {
console.warn("Scheduled delivery processed but no data found.");
}

// Clear timer state


currentState.deliveryTimerEnd = null;
currentState.deliveryData = null;
updateHeaderUI(); // Hide clock icon
hidePopup('delivery-timer-popup'); // Hide popup if open
saveState();
}

function formatTimeDuration(totalSeconds) {
if (totalSeconds <= 0) return "0 segundos";
const years = Math.floor(totalSeconds / (365 * 86400));
totalSeconds %= (365 * 86400);
const months = Math.floor(totalSeconds / (30 * 86400));
totalSeconds %= (30 * 86400);
const days = Math.floor(totalSeconds / 86400);
totalSeconds %= 86400;
const hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
const minutes = Math.floor(totalSeconds / 60);
totalSeconds %= 60;
const seconds = totalSeconds;

let result = "";


if (years > 0) result += `${years}a `;
if (months > 0) result += `${months}m `;
if (days > 0) result += `${days}d `;
if (hours > 0) result += `${hours}h `;
if (minutes > 0) result += `${minutes}min `;
if (seconds > 0 || result === "") result += `${seconds}s`; // Show
seconds if it's the only unit or > 0

return result.trim();
}

// Delivery Timer Popup Button


deliveryTimerBtn.addEventListener('click', () => {
if (currentState.deliveryTimerEnd) {
const timeLeft = Math.max(0,
Math.round((currentState.deliveryTimerEnd - Date.now()) / 1000));
deliveryCountdown.textContent = formatTimeDuration(timeLeft);
showPopup('delivery-timer-popup');
}
});

// Cancel Delivery Button


document.getElementById('cancel-delivery-btn').addEventListener('click', ()
=> {
if (currentState.deliveryTimerInterval)
clearInterval(currentState.deliveryTimerInterval);
currentState.deliveryTimerInterval = null;
currentState.deliveryTimerEnd = null;
const cancelledData = currentState.deliveryData;
currentState.deliveryData = null;
updateHeaderUI(); // Hide clock icon
hidePopup('delivery-timer-popup');
saveState();
showNotification(`Entrega agendada para ${cancelledData?.nick ||
'conta'} cancelada.`, 'warning');
addEmail("Entrega Cancelada", `A entrega agendada para a conta $
{cancelledData?.nick || ''} foi cancelada.`);
});

// --- Manage Accounts ---


document.getElementById('manage-accounts-btn').addEventListener('click', ()
=> {
if (currentState.loggedInAs === 'guest') {
showInfoPopup("Acesso Negado", "Gerenciamento de contas não
disponível para convidados.");
return;
}
updateManageAccountsList(); // Ensure list is up-to-date
showPopup('manage-accounts-popup');
});

function updateManageAccountsList() {
createdAccountsList.innerHTML = ''; // Clear previous list
if (currentState.createdAccounts.length === 0) {
createdAccountsList.innerHTML = '<li class="empty-message">Nenhuma
conta criada ainda.</li>';
} else {
currentState.createdAccounts.forEach(acc => {
const li = document.createElement('li');
li.innerHTML = `<strong>Nick:</strong> ${acc.nick}<br>
<span style="opacity:
0.8;"><strong>Email:</strong> ${acc.email} | <strong>Skin:</strong> ${acc.skin ||
'Padrão'}</span>`;
createdAccountsList.appendChild(li);
});
}
}

// --- Email System ---


function addEmail(subject, body) {
if (currentState.loggedInAs !== 'google') return; // Only for logged-in
users

const newEmail = {
id: Date.now(), // Simple unique ID
subject: subject,
body: body,
timestamp: Date.now(),
read: false
};
currentState.emails.unshift(newEmail); // Add to the beginning
currentState.unreadEmails++;
updateHeaderUI(); // Update badge
saveState();
}

emailBtn.addEventListener('click', () => {
updateEmailList();
showPopup('email-popup');
// Mark all as read when opened
currentState.unreadEmails = 0;
currentState.emails.forEach(email => email.read = true);
updateHeaderUI(); // Update badge immediately
saveState();
});

function updateEmailList() {
emailList.innerHTML = ''; // Clear previous list
if (currentState.emails.length === 0) {
emailList.innerHTML = '<li class="empty-message">Você não recebeu
nenhum email.</li>';
} else {
currentState.emails.forEach(email => {
const li = document.createElement('li');
const date = new Date(email.timestamp).toLocaleString();
li.innerHTML = `<strong>${email.subject}</strong>
${email.body}<br>
<span>${date}</span>`;
// Optionally add a style for unread emails if needed visually
in the list
// if (!email.read) li.style.fontWeight = 'bold';
emailList.appendChild(li);
});
}
}

// --- Chatbot ---


chatbotToggle.addEventListener('click', () => {
chatbotPopup.classList.add('active');
// Optionally scroll to bottom when opening
chatbotMessages.scrollTop = chatbotMessages.scrollHeight;
});

closeChatbotBtn.addEventListener('click', () => {
chatbotPopup.classList.remove('active');
});

chatbotSendBtn.addEventListener('click', sendChatMessage);
chatbotInputField.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && !e.shiftKey) { // Send on Enter, allow
Shift+Enter for newline
e.preventDefault(); // Prevent default newline insertion
sendChatMessage();
}
});
function sendChatMessage() {
const messageText = chatbotInputField.value.trim();
if (!messageText) return;

// Rate Limiting - Check for fast messages


const now = Date.now();
currentState.lastChatMessagesTimestamps.push(now);
currentState.lastChatMessagesTimestamps =
currentState.lastChatMessagesTimestamps.filter(ts => now - ts < 10000); // Keep
last 10s
if (currentState.lastChatMessagesTimestamps.length > 5) { // 5 messages
in 10 seconds is too fast
applyBan('chatbot-spam-fast', 'Envio rápido de mensagens no chat
(spam).', CHATBOT_BAN_DURATION_FAST_MESSAGES / (24 * 60 * 60 * 1000)); // 5 min ban
appendChatMessage("Detectei spam no chat. Sua conta foi banida
temporariamente por 5 minutos.", 'bot');
chatbotInputField.value = ''; // Clear input
return; // Stop processing further
}

appendChatMessage(messageText, 'user');
chatbotInputField.value = '';

// Enhanced Anti-Cheat/Ban Check


const lowerCaseMessage = messageText.toLowerCase();
if (BANNED_KEYWORDS_CHAT.some(keyword =>
lowerCaseMessage.includes(keyword))) {
applyBan('chatbot-abuse-swearing', 'Uso de linguagem imprópria no
chatbot.', CHATBOT_BAN_DURATION_SWEARING / (24 * 60 * 60 * 1000)); // 5 min ban
appendChatMessage("Linguagem imprópria detectada. Sua conta foi
banida temporariamente por 5 minutos.", 'bot');
return; // Stop processing further
}
if (messageText.length > 500) { // Prevent extremely long messages
applyBan('chatbot-spam-long', 'Envio de mensagem excessivamente
longa no chat.', 1);
appendChatMessage("Mensagem muito longa. Sua conta foi banida
temporariamente.", 'bot');
return;
}

// Simulate bot response


setTimeout(() => {
let botResponse = "Desculpe, não entendi. Pode reformular sua pergunta
sobre o MineConv?";
// Add more sophisticated responses based on keywords or simple NLP
if (lowerCaseMessage.includes('ajuda') ||
lowerCaseMessage.includes('como usar')) {
botResponse = "Use 'Converter Pirata -> Original' para iniciar. O
menu <i class='fas fa-user-cog'></i> tem perfil/configurações. Limites <i
class='fas fa-bolt'></i> mostram conversões restantes. Emails <i class='fas fa-
envelope'></i> e timer <i class='fas fa-clock'></i> aparecem quando ativos. Precisa
de mais detalhes?";
} else if (lowerCaseMessage.includes('limites') ||
lowerCaseMessage.includes('vidas')) {
botResponse = `Você tem ${currentState.conversionLimits} conversões
gratuitas restantes hoje. Elas reiniciam à meia-noite. Assine o Plus para
ilimitadas!`;
} else if (lowerCaseMessage.includes('editar') &&
lowerCaseMessage.includes('modo')) {
botResponse = "O Modo Edição (acessível pelo Google Login) permite
arrastar elementos como o título e os botões na tela principal. Use os controles
Salvar/Cancelar na parte inferior.";
} else if (lowerCaseMessage.includes('gerenciar') &&
lowerCaseMessage.includes('contas')) {
botResponse = "O botão 'Gerenciar Contas' lista as contas que você
converteu com sucesso usando o MineConv.";
} else if (lowerCaseMessage.includes('tempo') &&
lowerCaseMessage.includes('entrega')) {
botResponse = "No último passo da conversão, você pode definir um
atraso opcional para a entrega da conta. Se definir, um ícone de relógio <i
class='fas fa-clock'></i> aparecerá no topo.";
} else if (lowerCaseMessage.includes('banido') ||
lowerCaseMessage.includes('ban')) {
botResponse = "Banimentos ocorrem por violar as regras (ex:
linguagem imprópria, tentativas de abuso, spam). Banimentos temporários expiram.
Após 3 temporários, o banimento se torna permanente. Você pode ver seu histórico no
ícone <i class='fas fa-exclamation-triangle'></i>.";
} else if (lowerCaseMessage.includes('plus') ||
lowerCaseMessage.includes('premium')) {
botResponse = "O MineConv+ (simulado) oferece recursos extras como
conversão Original -> Pirata, capas grátis, tags e limites ilimitados. Clique nos
botões com <i class='fas fa-star' style='color: gold;'></i> para ver.";
} else if (lowerCaseMessage.match(/\b(oi|olá|bom dia|boa tarde|boa
noite)\b/)) {
botResponse = "Olá! Como posso te ajudar com o MineConv hoje?";
}
appendChatMessage(botResponse, 'bot');
}, 200 + Math.random() * 300); // Simulate thinking time, faster now
}

function appendChatMessage(text, sender) { // sender is 'user' or 'bot'


const messageDiv = document.createElement('div');
messageDiv.classList.add('chat-message', sender);
// Sanitize text before setting innerHTML if needed, but textContent is
safer
// For allowing basic HTML like the icons in bot responses:
if (sender === 'bot') {
messageDiv.innerHTML = text; // Use innerHTML carefully for bot
responses
} else {
messageDiv.textContent = text; // Use textContent for user messages
(safer)
}
chatbotMessages.appendChild(messageDiv);
// Scroll to bottom smoothly
chatbotMessages.scrollTo({ top: chatbotMessages.scrollHeight, behavior:
'smooth' });
}

// --- Ban System ---


function applyBan(source, reason, durationDays = null) {
// Check if already finally banned
if (currentState.permanentBanCount >= MAX_PERMANENT_BANS) {
console.warn(`Attempted to apply ban (${reason}) but user is
already finally blocked.`);
showBanScreen(); // Ensure the final ban screen is shown
return;
}

console.warn(`Applying ban. Source: ${source}, Reason: ${reason},


Duration: ${durationDays ? durationDays + ' days' : 'Permanent'}`);
const now = Date.now();
let banType = 'temporary';
let expiryTimestamp = null;

// Determine ban type and duration


const tempBanCount = currentState.banHistory.filter(b => b.type ===
'temporary').length;

if (durationDays === null || (tempBanCount + 1 >= MAX_TEMP_BANS &&


currentState.permanentBanCount < MAX_PERMANENT_BANS)) {
// Apply permanent ban if duration is null OR if temp ban limit
reached
banType = 'permanent';
currentState.permanentBanCount++;
console.log(`Permanent ban count incremented to: $
{currentState.permanentBanCount}`);
} else {
// Apply temporary ban
expiryTimestamp = now + (durationDays * 24 * 60 * 60 * 1000 ||
durationDays * 1000); // Default to days, but allow seconds for chatbot bans
}

// Add to history
currentState.banHistory.push({ reason: reason, type: banType,
timestamp: now, source: source });

// Update state
currentState.isBanned = true;
currentState.banType = banType;
currentState.banReason = reason;
currentState.banExpiry = expiryTimestamp; // Will be null for permanent

// Stop delivery timer if running


if (currentState.deliveryTimerInterval) {
clearInterval(currentState.deliveryTimerInterval);
currentState.deliveryTimerInterval = null;
// Optionally cancel the delivery entirely or just pause it
// currentState.deliveryTimerEnd = null;
// currentState.deliveryData = null;
console.log("Delivery timer paused due to ban.");
}

saveState();
updateHeaderUI(); // Update ban history badge
showBanScreen(); // Display the ban screen/popup
}

function checkBanStatus() {
if (currentState.isBanned) {
if (currentState.banType === 'temporary' && currentState.banExpiry)
{
const now = Date.now();
if (now >= currentState.banExpiry) {
// Temporary ban expired
console.log("Temporary ban expired. Lifting ban.");
liftBan("Seu banimento temporário expirou.");
} else {
// Ban still active
showBanScreen(); // Ensure ban screen is shown
}
} else if (currentState.banType === 'permanent') {
// Permanent ban, stays until unbanned or final block
showBanScreen();
} else {
// Inconsistent state, lift ban
console.warn("Inconsistent ban state found. Lifting ban.");
liftBan("Erro no estado de banimento, removendo.");
}
} else {
// Ensure consistency if not banned
currentState.banType = null;
currentState.banReason = '';
currentState.banExpiry = null;
}
}

function liftBan(notificationMessageText) {
currentState.isBanned = false;
currentState.banType = null;
currentState.banReason = '';
currentState.banExpiry = null;
// Don't clear history or permanent counts here
saveState();
showNotification(notificationMessageText, "success");
// Decide where to go after ban lifts
if (currentState.loggedInAs) {
startDeliveryTimerIfNeeded(); // Resume timer if needed
updateHeaderUI();
showScreen('main-app-screen'); // Or mode-select
} else {
showScreen('login-screen');
}
}

function showBanScreen() {
const banPopup = document.getElementById('ban-popup');
const titleEl = document.getElementById('ban-popup-title');
const reasonEl = document.getElementById('ban-popup-reason');
const durationEl = document.getElementById('ban-popup-duration');
const adviceEl = document.getElementById('ban-popup-advice');
const actionsEl = document.getElementById('ban-actions');
const finalBanMsgEl = document.getElementById('final-ban-message');

actionsEl.innerHTML = ''; // Clear previous actions


finalBanMsgEl.classList.add('hidden');

reasonEl.textContent = `Motivo: ${currentState.banReason || 'Violação


dos termos.'}`;

if (currentState.permanentBanCount >= MAX_PERMANENT_BANS) {


// Final, irreversible ban
titleEl.innerHTML = `<i class="fas fa-skull-crossbones"></i> Banido
Permanentemente!`;
durationEl.textContent = "Duração: Para Sempre";
adviceEl.textContent = "Você excedeu o limite de banimentos
permanentes.";
finalBanMsgEl.classList.remove('hidden');
} else if (currentState.banType === 'permanent') {
// Permanent ban (can be unbanned)
titleEl.innerHTML = `<i class="fas fa-gavel"></i> Banido
Permanentemente!`;
durationEl.textContent = "Duração: Permanente (Requer Ação)";
adviceEl.textContent = "Você pode tentar adquirir um unban ou criar
uma nova conta (com limites).";
// Add Unban Button
const unbanBtn = document.createElement('button');
unbanBtn.id = 'acquire-unban-btn';
unbanBtn.className = 'button success'; // Use a different style
maybe
unbanBtn.innerHTML = '<i class="fas fa-video"></i> Adquirir Unban
(Simulado)';
unbanBtn.onclick = showUnbanSimulation;
actionsEl.appendChild(unbanBtn);
// Add Create New Account Button
const newAccBtn = document.createElement('button');
newAccBtn.id = 'create-new-account-btn';
newAccBtn.className = 'button secondary';
newAccBtn.innerHTML = '<i class="fas fa-user-plus"></i> Criar Nova
Conta';
newAccBtn.onclick = createNewAccountAfterBan;
actionsEl.appendChild(newAccBtn);

} else if (currentState.banType === 'temporary' &&


currentState.banExpiry) {
// Temporary ban
titleEl.innerHTML = `<i class="fas fa-clock"></i> Banido
Temporariamente!`;
adviceEl.textContent = "Recarregar a página não removerá o
banimento.";
const updateTimer = () => {
if (!currentState.isBanned || currentState.banType !==
'temporary') return; // Stop if ban lifted or changed
const now = Date.now();
const timeLeft = currentState.banExpiry - now;
if (timeLeft <= 0) {
durationEl.textContent = "Tempo restante: Expirado!";
checkBanStatus(); // Re-check should lift the ban
} else {
durationEl.textContent = `Tempo restante: $
{formatTimeDuration(Math.round(timeLeft / 1000))}`;
// Update timer every second only if the popup is visible
if (banPopup.classList.contains('active')) {
requestAnimationFrame(updateTimer);
}
}
};
updateTimer(); // Start the timer
} else {
// Fallback for inconsistent state
titleEl.innerHTML = `<i class="fas fa-question-circle"></i> Erro
no Banimento`;
reasonEl.textContent = "Estado de banimento inconsistente.";
durationEl.textContent = "Duração: Desconhecida";
liftBan("Erro no estado de banimento, removendo."); // Attempt to
fix
return; // Don't show the popup in this case
}

// Hide everything else and show only the ban popup


screens.forEach(s => s.classList.remove('active'));
popups.forEach(p => p.classList.remove('active')); // Hide other popups
banPopup.classList.add('active'); // Show ban popup
currentState.currentScreen = 'ban-screen'; // Special state
}

// --- Unban Simulation ---


function showUnbanSimulation() {
hidePopup('ban-popup');
showPopup('unban-sim-popup');

const progressBar = document.getElementById('unban-progress-bar');


const statusText = document.getElementById('unban-status-text');
const finishBtn = document.getElementById('finish-unban-btn');

progressBar.style.width = '0%';
statusText.textContent = 'Progresso: 0%';
finishBtn.classList.add('hidden');

let progress = 0;
const totalTime = 10000; // 10 seconds simulation
const intervalTime = 100;

if (unbanProgressInterval) clearInterval(unbanProgressInterval);
if (unbanTimeout) clearTimeout(unbanTimeout);

unbanProgressInterval = setInterval(() => {


progress += (intervalTime / totalTime) * 100;
progressBar.style.width = Math.min(progress, 100) + '%';
statusText.textContent = `Progresso: $
{Math.round(Math.min(progress, 100))}%`;
if (progress >= 100) {
clearInterval(unbanProgressInterval);
}
}, intervalTime);

unbanTimeout = setTimeout(() => {


finishBtn.classList.remove('hidden');
statusText.textContent = "Vídeos assistidos! Clique para
finalizar.";
}, totalTime);
}

document.getElementById('finish-unban-btn').addEventListener('click', () =>
{
if (unbanProgressInterval) clearInterval(unbanProgressInterval);
if (unbanTimeout) clearTimeout(unbanTimeout);
hidePopup('unban-sim-popup');
// Lift the ban, but keep the history and permanent count
currentState.isBanned = false;
currentState.banType = null;
currentState.banReason = '';
currentState.banExpiry = null;
// DO NOT reset currentState.permanentBanCount here
saveState();
showNotification("Unban adquirido com sucesso!", "success");
// Go to login screen after unban
showScreen('login-screen');
});

// --- Create New Account After Ban ---


function createNewAccountAfterBan() {
// Anti-abuse check
if (currentState.newAccountCreations >= MAX_NEW_ACCOUNT_CREATIONS) {
applyBan('new-account-abuse', 'Abuso da função "Criar Nova
Conta".', null); // Apply final permanent ban
return;
}

console.log("Creating new account state after ban...");


const oldBanHistory = [...currentState.banHistory]; // Preserve history
const oldPermanentBanCount = currentState.permanentBanCount;
const oldNewAccountCreations = currentState.newAccountCreations + 1;
const oldCreatedAccounts = [...currentState.createdAccounts]; //
Preserve created accounts

// Reset most of the state, similar to a fresh start but keeping ban
info
currentState = {
// Keep ban-related info
banHistory: oldBanHistory,
permanentBanCount: oldPermanentBanCount,
newAccountCreations: oldNewAccountCreations,
// Keep created accounts list
createdAccounts: oldCreatedAccounts,
// Reset user-specific data
loggedInAs: null,
currentScreen: 'login-screen', // Start at login
conversionLimits: DAILY_LIMIT,
lastLimitReset: null,
isBanned: false, // Not banned on the new "account" yet
banType: null,
banReason: '',
banExpiry: null,
elementPositions: {},
isEditMode: false,
originalPositions: {},
unreadEmails: 0,
emails: [],
deliveryTimerEnd: null,
deliveryTimerInterval: null,
deliveryData: null,
profilePic: null,
language: 'pt-BR', // Reset language
fontFamily: 'default', // Reset font
lastChatMessagesTimestamps: [], // Reset chat timestamps
};

saveState(); // Save the new reset state


hidePopup('ban-popup');
showNotification("Nova 'conta' criada. Faça o login.", "success");
showScreen('login-screen'); // Go to login
updateAccountsListBadge(); // Update badge count
}

// --- Ban History ---


banHistoryBtn.addEventListener('click', () => {
updateBanHistoryList();
showPopup('ban-history-popup');
});

function updateBanHistoryList() {
banHistoryList.innerHTML = ''; // Clear previous list
if (currentState.banHistory.length === 0) {
banHistoryList.innerHTML = '<li class="empty-message">Nenhum
banimento registrado.</li>';
} else {
// Show newest first
[...currentState.banHistory].reverse().forEach(ban => {
const li = document.createElement('li');
const date = new Date(ban.timestamp).toLocaleString();
const typeText = ban.type === 'permanent' ? 'Permanente' :
'Temporário';
const typeColor = ban.type === 'permanent' ? 'var(--error-
color)' : 'var(--warning-color)';
li.innerHTML = `<strong style="color: ${typeColor};">[$
{typeText}]</strong> ${ban.reason}<br>
<span>${date} (Fonte: ${ban.source ||
'Desconhecida'})</span>`;
li.style.borderLeftColor = typeColor; // Match border color
banHistoryList.appendChild(li);
});
}
}

// --- Rules Popup ---


rulesBtn.addEventListener('click', () => {
showPopup('rules-popup');
});

// --- Accounts List Popup ---


accountsListBtn.addEventListener('click', () => {
updateExistingAccountsList();
showPopup('accounts-list-popup');
});

function updateExistingAccountsList() {
existingAccountsListEl.innerHTML = ''; // Clear previous list
if (currentState.createdAccounts.length === 0) {
existingAccountsListEl.innerHTML = '<li class="empty-
message">Nenhuma conta criada ainda.</li>';
} else {
currentState.createdAccounts.forEach((acc, index) => {
const li = document.createElement('li');
li.innerHTML = `<strong>Conta #${index + 1}:</strong> $
{acc.nick || 'N/A'} (${acc.email || 'N/A'})`;
existingAccountsListEl.appendChild(li);
});
}
}

// --- Generic Info Popup ---


function showInfoPopup(title, message) {
document.getElementById('info-popup-title').textContent = title;
document.getElementById('info-popup-message').textContent = message;
showPopup('info-popup');
}

// --- "Plus Required" Buttons ---


['convert-reverse-btn', 'free-capes-btn', 'hypixel-tags-btn', 'mushmc-tags-
btn', 'hylex-tags-btn', 'flamemc-tags-btn', 'stardix-tags-btn'].forEach(id => {
document.getElementById(id)?.addEventListener('click', () => {
if (currentState.loggedInAs === 'guest') {
showInfoPopup("Acesso Negado", "Recursos Plus não estão
disponíveis para convidados.");
return;
}
showPopup('plus-required-popup');
});
});

// --- Edit Mode Drag & Drop (Improved) ---


let draggedElement = null;
let offsetX, offsetY;
let startX, startY; // Original position before drag starts

function enableDragAndDrop() {
document.querySelectorAll('.draggable').forEach(el => {
el.addEventListener('mousedown', startDrag);
el.style.position = 'absolute'; // Required for positioning

// Store original position if not already stored for cancellation


if (!currentState.originalPositions[el.id]) {
const computedStyle = getComputedStyle(el);
currentState.originalPositions[el.id] = {
top: computedStyle.top,
left: computedStyle.left,
position: computedStyle.position // Store original position
type too
};
}
// Apply saved position if exists, otherwise use computed style
if (currentState.elementPositions[el.id]) {
el.style.top = currentState.elementPositions[el.id].top;
el.style.left = currentState.elementPositions[el.id].left;
} else {
// If no saved position, ensure top/left are set based on
current rendering
// This prevents elements jumping on first drag if they were
auto-positioned
const rect = el.getBoundingClientRect();
const parentRect = el.parentElement.getBoundingClientRect();
el.style.top = `${rect.top - parentRect.top}px`;
el.style.left = `${rect.left - parentRect.left}px`;
}
});
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', endDrag);
document.body.classList.add('edit-mode'); // Add class for potential
styling
editModeControls.classList.remove('hidden');
}

function disableDragAndDrop(revert = false) {


document.querySelectorAll('.draggable').forEach(el => {
el.removeEventListener('mousedown', startDrag);
el.style.cursor = 'default'; // Reset cursor
if (revert && el.id && currentState.originalPositions[el.id]) {
// Revert to original position and style
el.style.top = currentState.originalPositions[el.id].top;
el.style.left = currentState.originalPositions[el.id].left;
el.style.position =
currentState.originalPositions[el.id].position;
} else if (!revert && el.id && !
currentState.elementPositions[el.id]) {
// If not reverting and no position saved, reset styles
el.style.position =
currentState.originalPositions[el.id]?.position || 'relative';
el.style.top = 'auto';
el.style.left = 'auto';
} else if (!revert && el.id &&
currentState.elementPositions[el.id]) {
// Ensure position is absolute if saved
el.style.position = 'absolute';
}
});
document.removeEventListener('mousemove', drag);
document.removeEventListener('mouseup', endDrag);
document.body.classList.remove('edit-mode');
editModeControls.classList.add('hidden');
if (draggedElement) { // Ensure cleanup if disabled mid-drag
draggedElement.classList.remove('dragging');
draggedElement = null;
}
if (revert) {
currentState.originalPositions = {}; // Clear stored originals
after reverting
}
}

function startDrag(e) {
// Allow dragging only with left mouse button
if (e.button !== 0 || !currentState.isEditMode || !
e.target.closest('.draggable')) return;

draggedElement = e.target.closest('.draggable');
draggedElement.classList.add('dragging');

// Calculate offset from the element's top-left corner relative to the


viewport
const rect = draggedElement.getBoundingClientRect();
offsetX = e.clientX - rect.left;
offsetY = e.clientY - rect.top;
// Store the starting position for smooth dragging relative to parent
startX = parseFloat(draggedElement.style.left || '0');
startY = parseFloat(draggedElement.style.top || '0');

// Prevent default browser drag behavior


e.preventDefault();
}

function drag(e) {
if (!draggedElement) return;
e.preventDefault(); // Prevent text selection during drag

// Calculate new position based on mouse movement relative to the


parent
// We use clientX/Y and the initial offset relative to the viewport,
// then convert it to be relative to the parent offset container.
const parentRect = draggedElement.offsetParent.getBoundingClientRect();
let newX = e.clientX - parentRect.left - offsetX;
let newY = e.clientY - parentRect.top - offsetY;

// Optional: Constrain movement within the parent element


(offsetParent)
const parentWidth = draggedElement.offsetParent.clientWidth;
const parentHeight = draggedElement.offsetParent.clientHeight;
const elementWidth = draggedElement.offsetWidth;
const elementHeight = draggedElement.offsetHeight;

newX = Math.max(0, Math.min(newX, parentWidth - elementWidth));


newY = Math.max(0, Math.min(newY, parentHeight - elementHeight));

draggedElement.style.left = `${newX}px`;
draggedElement.style.top = `${newY}px`;
}

function endDrag(e) {
if (!draggedElement) return;
draggedElement.classList.remove('dragging');
// Position is already set by the drag function
draggedElement = null;
}

// Edit Mode Controls


document.getElementById('save-layout-btn').addEventListener('click', () =>
{
currentState.elementPositions = {}; // Clear previous saved positions
document.querySelectorAll('.draggable').forEach(el => {
if (el.id) { // Only save elements with IDs
currentState.elementPositions[el.id] = { top: el.style.top,
left: el.style.left };
}
});
saveState();
disableDragAndDrop(false); // Disable but don't revert
currentState.isEditMode = false; // Exit edit mode after saving
currentState.originalPositions = {}; // Clear stored originals
saveState(); // Save the mode change
showNotification("Layout salvo com sucesso!", "success");
showScreen('main-app-screen'); // Stay on main screen to see result
});

document.getElementById('cancel-layout-btn').addEventListener('click', ()
=> {
disableDragAndDrop(true); // Disable and revert positions
currentState.isEditMode = false; // Exit edit mode
// Positions already reverted by disableDragAndDrop(true)
saveState(); // Save the mode change
showNotification("Alterações de layout canceladas.", "success");
showScreen('main-app-screen'); // Stay on main screen
});

// Apply saved positions on load/mode change


function applyElementPositions() {
if (currentState.isEditMode) return; // Don't apply if entering edit
mode

document.querySelectorAll('.draggable').forEach(el => {
if (el.id && currentState.elementPositions[el.id]) {
el.style.position = 'absolute'; // Ensure it can be positioned
el.style.top = currentState.elementPositions[el.id].top;
el.style.left = currentState.elementPositions[el.id].left;
} else {
// Reset if no saved position or element has no ID
const originalStyle = currentState.originalPositions[el.id];
el.style.position = originalStyle?.position || 'relative'; //
Reset to original or default
el.style.top = originalStyle?.top || 'auto';
el.style.left = originalStyle?.left || 'auto';
}
});
}

// --- Skin Preview Interaction (Improved Rotation) ---


const skinPreview = document.getElementById('skin-preview');
const skinContainer = document.querySelector('.skin-preview-container');
let isDraggingSkin = false;
let skinPrevX, skinPrevY;
let skinRotationY = 0;
let skinRotationX = 0;

skinPreview.addEventListener('mousedown', (e) => {


if (!skinPreview.classList.contains('loaded') || e.button !== 0)
return; // Only drag loaded skin with left button
isDraggingSkin = true;
skinPrevX = e.clientX;
skinPrevY = e.clientY;
skinPreview.style.cursor = 'grabbing';
skinContainer.style.cursor = 'grabbing'; // Change container cursor too
});

document.addEventListener('mousemove', (e) => {


if (!isDraggingSkin) return;
const deltaX = e.clientX - skinPrevX;
const deltaY = e.clientY - skinPrevY;

skinRotationY += deltaX * 0.6; // Adjust sensitivity


skinRotationX -= deltaY * 0.6; // Adjust sensitivity
skinRotationX = Math.max(-60, Math.min(60, skinRotationX)); // Limit
vertical rotation slightly

skinPreview.style.transform = `rotateX(${skinRotationX}deg) rotateY($


{skinRotationY}deg)`;

skinPrevX = e.clientX;
skinPrevY = e.clientY;

// Move grid effect smoothly


if (skinContainer) {
skinContainer.style.backgroundPosition = `${-skinRotationY * 0.3}px
${skinRotationX * 0.3}px`;
}
});

document.addEventListener('mouseup', (e) => {


if (isDraggingSkin && e.button === 0) {
isDraggingSkin = false;
skinPreview.style.cursor = 'grab';
skinContainer.style.cursor = 'default';
}
});
// Prevent dragging image behavior in some browsers
skinPreview.addEventListener('dragstart', (e) => e.preventDefault());

// --- Run ---


initializeApp();

</script>
</body>
</html>

You might also like