This commit is contained in:
Renan Bernordi 2025-01-28 00:10:23 -03:00
parent 1e205b6b2e
commit 90bcbd97fd
53 changed files with 783 additions and 1298 deletions

View file

@ -9,7 +9,10 @@ const sourcemaps = require('gulp-sourcemaps');
const imagemin = require('gulp-imagemin');
const webp = require('gulp-webp');
const newer = require('gulp-newer');
const fontmin = require('gulp-fontmin');
const rename = require('gulp-rename');
const ttf2woff = require('gulp-ttf2woff');
const ttf2woff2 = require('gulp-ttf2woff2');
const ttf2eot = require('gulp-ttf2eot');
const svgmin = require('gulp-svgmin');
const paths = {
@ -52,7 +55,7 @@ function styles() {
function scripts() {
return gulp.src(paths.scripts.src)
.pipe(sourcemaps.init())
.pipe(concat('script.js'))
.pipe(concat('scripts.js'))
.pipe(uglify())
.pipe(gulp.dest(paths.scripts.dest))
.pipe(sourcemaps.write('.'))
@ -78,8 +81,23 @@ function icons() {
function fonts() {
return gulp.src(paths.fonts.src)
.pipe(newer(paths.fonts.dest))
.pipe(fontmin())
.pipe(ttf2woff())
.pipe(rename({ extname: '.woff' }))
.pipe(gulp.dest(paths.fonts.dest))
.pipe(gulp.src(paths.fonts.src))
.pipe(ttf2woff2())
.pipe(rename({ extname: '.woff2' }))
.pipe(gulp.dest(paths.fonts.dest))
.pipe(gulp.src(paths.fonts.src))
.pipe(ttf2eot())
.pipe(rename({ extname: '.eot' }))
.pipe(gulp.dest(paths.fonts.dest))
.pipe(gulp.src(paths.fonts.src))
.pipe(gulp.dest(paths.fonts.dest));
}
function watch() {

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="black" d="M32 32l448 0c17.7 0 32 14.3 32 32l0 32c0 17.7-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96L0 64C0 46.3 14.3 32 32 32zm0 128l448 0 0 256c0 35.3-28.7 64-64 64L96 480c-35.3 0-64-28.7-64-64l0-256zm128 80c0 8.8 7.2 16 16 16l160 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-160 0c-8.8 0-16 7.2-16 16z"/></svg>

Before

Width:  |  Height:  |  Size: 376 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="black" d="M240 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM192 48a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm-32 80c17.7 0 32 14.3 32 32l8 0c13.3 0 24 10.7 24 24l0 16c0 1.7-.2 3.4-.5 5.1C280.3 229.6 320 286.2 320 352c0 88.4-71.6 160-160 160S0 440.4 0 352c0-65.8 39.7-122.4 96.5-146.9c-.4-1.6-.5-3.3-.5-5.1l0-16c0-13.3 10.7-24 24-24l8 0c0-17.7 14.3-32 32-32zm0 320a96 96 0 1 0 0-192 96 96 0 1 0 0 192zm192-96c0-25.9-5.1-50.5-14.4-73.1c16.9-32.9 44.8-59.1 78.9-73.9c-.4-1.6-.5-3.3-.5-5.1l0-16c0-13.3 10.7-24 24-24l8 0c0-17.7 14.3-32 32-32s32 14.3 32 32l8 0c13.3 0 24 10.7 24 24l0 16c0 1.7-.2 3.4-.5 5.1C600.3 229.6 640 286.2 640 352c0 88.4-71.6 160-160 160c-62 0-115.8-35.3-142.4-86.9c9.3-22.5 14.4-47.2 14.4-73.1zm224 0a96 96 0 1 0 -192 0 96 96 0 1 0 192 0zM368 0a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm80 48a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>

Before

Width:  |  Height:  |  Size: 908 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="black" d="M392.8 1.2c-17-4.9-34.7 5-39.6 22l-128 448c-4.9 17 5 34.7 22 39.6s34.7-5 39.6-22l128-448c4.9-17-5-34.7-22-39.6zm80.6 120.1c-12.5 12.5-12.5 32.8 0 45.3L562.7 256l-89.4 89.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l112-112c12.5-12.5 12.5-32.8 0-45.3l-112-112c-12.5-12.5-32.8-12.5-45.3 0zm-306.7 0c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3l112 112c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256l89.4-89.4c12.5-12.5 12.5-32.8 0-45.3z"/></svg>

Before

Width:  |  Height:  |  Size: 556 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="black" d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"/></svg>

Before

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View file

@ -1,130 +1,67 @@
/**
* JavaScript functions for form validation and error handling
* Funções JavaScript para validação de formulário e manipulação de erros
*/
/**
* Validates the form before submission
*
* Checks:
* - If URL is not empty
* - If URL starts with http:// or https://
* - If URL has a valid format
*
* @returns {boolean} True if URL is valid, False otherwise
*
* Valida o formulário antes do envio
*
* Verifica:
* - Se a URL não está vazia
* - Se a URL começa com http:// ou https://
* - Se a URL tem um formato válido
*
* @returns {boolean} True se a URL for válida, False caso contrário
*/
function validateForm() {
const urlInput = document.getElementById('url');
const submitButton = document.querySelector('button[type="submit"]');
const url = urlInput.value.trim();
// Check if URL is not empty
// Verifica se a URL não está vazia
if (!url) {
showError('Por favor, insira uma URL');
return false;
}
// Check if URL starts with http:// or https://
// Verifica se a URL começa com http:// ou https://
if (!/^https?:\/\//i.test(url)) {
showError('A URL deve começar com http:// ou https://');
return false;
}
// Try to create a URL object to validate format
// Tenta criar um objeto URL para validar o formato
try {
new URL(url);
} catch (e) {
showError('Formato de URL inválido');
return false;
}
// Disable input and button
// Desabilita o input e o botão
urlInput.readonly = true;
submitButton.disabled = true;
// Add Tailwind disabled classes
// Adiciona classes de disabled do Tailwind
submitButton.classList.add('cursor-wait', 'disabled:bg-blue-400');
submitButton.classList.remove('hover:bg-blue-700');
urlInput.classList.add('cursor-wait', 'disabled:bg-gray-50', 'focus:outline-none');
// Add loading state to button
// Adiciona estado de loading ao botão
submitButton.innerHTML = `
<img src="assets/svg/search.svg" class="w-6 h-6 mr-3" alt="Search">
Analisando...
`;
return true;
}
/**
* Displays an error message below the form
*
* Removes any existing error message before displaying the new one.
* The message is displayed with an error icon and red formatting.
*
* @param {string} message Error message to be displayed
*
* Exibe uma mensagem de erro abaixo do formulário
*
* Remove qualquer mensagem de erro existente antes de exibir a nova.
* A mensagem é exibida com um ícone de erro e formatação em vermelho.
*
* @param {string} message Mensagem de erro a ser exibida
*/
function showError(message) {
const form = document.getElementById('urlForm');
const existingError = form.querySelector('.error-message');
// Remove previous error message if it exists
// Remove mensagem de erro anterior se existir
if (existingError) {
existingError.remove();
}
// Create and add new error message
// Cria e adiciona nova mensagem de erro
const errorDiv = document.createElement('div');
errorDiv.className = 'error-message mt-4 text-base text-red-600';
errorDiv.innerHTML = `
<img src="assets/svgs/error.svg" class="inline-block w-5 h-5 mr-2" alt="Error icon">
${message}`;
form.appendChild(errorDiv);
}
/**
* Service Worker registration for PWA functionality
* Registers a service worker to enable offline capabilities and PWA features
*
* Registro do Service Worker para funcionalidade PWA
* Registra um service worker para habilitar recursos offline e funcionalidades PWA
*/
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js')
.then(() => {
// Service Worker registered successfully
// Service Worker registrado com sucesso
})
.catch(() => {
// Service Worker registration failed
// Falha no registro do Service Worker
});
});
}
/**
* Header toggle menus
*/
document.addEventListener('DOMContentLoaded', function () {
const integration = document.querySelector('.integration');
const integrationToggle = document.querySelector('.integration__toggle');
const extension = document.querySelector('.extension');
const extensionToggle = document.querySelector('.extension__toggle');
// Function to close all menus
const closeAllMenus = () => {
integration.classList.remove('open');
extension.classList.remove('open');
};
// Function to close other menus except the one passed
const closeOtherMenus = (exceptMenu) => {
if (exceptMenu !== integration) {
integration.classList.remove('open');
}
if (exceptMenu !== extension) {
extension.classList.remove('open');
}
};
integrationToggle.addEventListener('click', (e) => {
e.stopPropagation(); // Prevent click from bubbling to document
closeOtherMenus(integration);
integration.classList.toggle('open');
});
extensionToggle.addEventListener('click', (e) => {
e.stopPropagation(); // Prevent click from bubbling to document
closeOtherMenus(extension);
extension.classList.toggle('open');
});
// Prevent clicks inside menus from closing them
integration.addEventListener('click', (e) => {
e.stopPropagation();
});
extension.addEventListener('click', (e) => {
e.stopPropagation();
});
// Close menus when clicking outside
document.addEventListener('click', () => {
closeAllMenus();
});
});

View file

@ -2,7 +2,7 @@
// Default
body {
font-family: var(--font-family-haffer);
font-family: var(--font-family-inter);
font-size: var(--font-size);
font-weight: var(--font-weight);
line-height: var(--line-height);

View file

@ -1,10 +1,10 @@
@font-face {
font-family: 'inter';
src: url('../fonts/inter-500.eot');
src: url('../dist/fonts/inter-500.eot');
src: local('Inter Medium'), local('Inter-Medium'),
url('../fonts/inter-500.woff2') format('woff2'),
url('../fonts/inter-500.woff') format('woff'),
url('../fonts/inter-500.ttf') format('truetype');
url('../dist/fonts/inter-500.woff2') format('woff2'),
url('../dist/fonts/inter-500.woff') format('woff'),
url('../dist/fonts/inter-500.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
@ -12,11 +12,11 @@
@font-face {
font-family: 'inter';
src: url('../fonts/inter-600.eot');
src: url('../dist/fonts/inter-600.eot');
src: local('Inter SemiBold'), local('Inter-SemiBold'),
url('../fonts/inter-600.woff2') format('woff2'),
url('../fonts/inter-600.woff') format('woff'),
url('../fonts/inter-600.ttf') format('truetype');
url('../dist/fonts/inter-600.woff2') format('woff2'),
url('../dist/fonts/inter-600.woff') format('woff'),
url('../dist/fonts/inter-600.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
@ -24,11 +24,11 @@
@font-face {
font-family: 'unna';
src: url('../fonts/unna-400.eot');
src: url('../dist/fonts/unna-400.eot');
src: local('Unna Regular'), local('Unna-Regular'),
url('../fonts/unna-400.woff2') format('woff2'),
url('../fonts/unna-400.woff') format('woff'),
url('../fonts/unna-400.ttf') format('truetype');
url('../dist/fonts/unna-400.woff2') format('woff2'),
url('../dist/fonts/unna-400.woff') format('woff'),
url('../dist/fonts/unna-400.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;

View file

@ -11,26 +11,28 @@
display: inline-block;
vertical-align: -0.125em;
fill: currentcolor;
width: 1em;
height: 1em;
width: 16px;
height: 16px;
background-repeat: no-repeat;
background-position: center center;
background-size: 100% auto;
&--bookmark {
background-size: auto 100% !important;
}
}
@include mixin.icon('marreta');
@include mixin.icon('android');
@include mixin.icon('apple');
@include mixin.icon('archive');
@include mixin.icon('bookmark');
@include mixin.icon('bsky');
@include mixin.icon('bypass');
@include mixin.icon('chrome');
@include mixin.icon('code');
@include mixin.icon('error');
@include mixin.icon('firefox');
@include mixin.icon('link');
@include mixin.icon('refresh');
@include mixin.icon('search');
@include mixin.icon('telegram');
@include mixin.icon('warning');
@include mixin.icon('marreta', 'invert(43%) sepia(74%) saturate(2288%) hue-rotate(201deg) brightness(98%) contrast(97%)');
@include mixin.icon('bookmark', 'invert(80%) sepia(46%) saturate(1512%) hue-rotate(340deg) brightness(106%) contrast(97%)');
@include mixin.icon('android', 'invert(72%) sepia(34%) saturate(778%) hue-rotate(32deg) brightness(97%) contrast(88%)');
@include mixin.icon('apple', 'invert(0%) sepia(21%) saturate(7425%) hue-rotate(12deg) brightness(96%) contrast(96%)');
@include mixin.icon('bsky', 'invert(47%) sepia(66%) saturate(4445%) hue-rotate(195deg) brightness(98%) contrast(104%)');
@include mixin.icon('telegram', 'invert(61%) sepia(86%) saturate(1341%) hue-rotate(166deg) brightness(96%) contrast(85%)');
@include mixin.icon('chrome', 'invert(40%) sepia(90%) saturate(1163%) hue-rotate(203deg) brightness(104%) contrast(92%)');
@include mixin.icon('firefox', 'invert(57%) sepia(43%) saturate(1854%) hue-rotate(360deg) brightness(102%) contrast(106%)');
@include mixin.icon('link', 'invert(53%) sepia(12%) saturate(17%) hue-rotate(39deg) brightness(94%) contrast(91%)');
@include mixin.icon('refresh', 'invert(100%) sepia(32%) saturate(8%) hue-rotate(23deg) brightness(102%) contrast(100%)');
@include mixin.icon('error', 'invert(30%) sepia(58%) saturate(3703%) hue-rotate(336deg) brightness(90%) contrast(91%)');
@include mixin.icon('warning', 'invert(89%) sepia(25%) saturate(5861%) hue-rotate(353deg) brightness(101%) contrast(101%)');

View file

@ -1,8 +1,10 @@
@use "sass:math";
@use "sass:color";
@mixin create-color($name, $color) {
--#{$name}: #{$color};
--#{$name}-lighten: color.scale($color, $lightness: -100%);
--#{$name}-darken: color.adjust($color, $lightness: -10%)
@mixin create-color($name, $hex) {
--#{$name}: #{$hex};
--#{$name}-lighten: #{color.adjust($hex, $lightness: 5%)};
--#{$name}-darken: #{color.adjust($hex, $lightness: -10%)};
}
@mixin devices($breakpoint) {
@ -13,12 +15,9 @@
}
}
@mixin background-image-svg($name) {
background-image: url("../images/icons/#{$name}.svg");
}
@mixin icon($name) {
@mixin icon($name, $filter) {
.icon--#{$name} {
@include background-image-svg($name);
background-image: url("../dist/icons/#{$name}.svg");
filter: #{$filter};
}
}

View file

@ -21,7 +21,8 @@
"Liberation Mono",
"Courier New",
monospace;
--font-family-haffer: "haffer";
--font-family-inter: "inter";
--font-family-unna: "unna";
//-- Styles
--font-size: 16px;
@ -29,18 +30,10 @@
--line-height: 160%;
// Colors
$hex-marreta: #fff;
$hex-text: #000;
$hex-textmuted: #000;
$hex-link: #000;
@include mixin.create-color('marreta', $hex-marreta);
@include mixin.create-color('text', $hex-text);
@include mixin.create-color('textmuted', $hex-textmuted);
@include mixin.create-color('link', $hex-link);
// Borders
--border-radius-default: 1rem;
@include mixin.create-color('marreta', #3B82F6);
@include mixin.create-color('text', #484848);
@include mixin.create-color('textmuted', #818181);
@include mixin.create-color('link', #3B82F6);
// Spacing
--container_spacing: 24px;

View file

@ -0,0 +1,374 @@
header {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
align-items: center;
padding: 42px 0;
.brand {
display: flex;
align-items: center;
.icon {
margin-right: 6px;
&--marreta {
width: 32px;
height: 32px;
}
}
h1 {
font-family: var(--font-family-unna);
color: #000;
}
}
nav {
display: flex;
justify-content: center;
gap: 48px;
a {
text-decoration: none;
color: #333;
&:hover {
color: #007bff;
}
}
.integration {
position: relative;
&__toggle {
background: none;
border: none;
cursor: pointer;
color: #333;
&:hover {
color: #007bff;
}
}
&__menu {
display: none;
position: absolute;
top: 110%;
left: 0;
border-radius: 16px;
background-color: #F4F4F5;
border: 4px solid #F4F4F5;
z-index: 10;
box-shadow: 0px 4px 6px 0px rgba(0, 0, 0, 0.05);
box-shadow: 0px 10px 15px 0px rgba(0, 0, 0, 0.1);
box-shadow: 0px 10px 10px 0px rgba(0, 0, 0, 0.04);
box-shadow: 0px 20px 25px 0px rgba(0, 0, 0, 0.1);
a {
margin-bottom: 4px;
&:first-child {
border-top-left-radius: 16px;
border-top-right-radius: 16px;
}
&:last-child {
margin-bottom: 0;
border-bottom-left-radius: 16px;
border-bottom-right-radius: 16px;
}
color: var(--text);
font-weight: 600;
display: block;
padding: 8px 16px;
background-color: #fff;
display: flex;
align-items: center;
&:hover {
color: var(--marreta);
}
span {
display: inline-block;
}
}
.name {
width: 140px;
}
}
&.open {
.integration__menu {
display: block;
}
.arrow {
top: 1px;
transform: rotate(-45deg);
}
}
.arrow {
position: relative;
top: -3px;
content: "";
display: inline-block;
width: 6px;
height: 6px;
border-right: 2px solid black;
border-top: 2px solid black;
transform: rotate(135deg);
margin-right: 0;
margin-left: 5px;
}
}
}
.extension {
display: flex;
justify-content: flex-end;
position: relative;
&__toggle {
background-color: var(--marreta);
border-radius: 40px;
border: 0;
cursor: pointer;
color: #FFF;
font-weight: 600;
padding: 12px 24px;
line-height: 1.3em;
&:hover {
background-color: var(--marreta-darken);
}
}
&__menu {
display: none;
position: absolute;
top: 110%;
right: 0;
border-radius: 16px;
background-color: #F4F4F5;
border: 4px solid #F4F4F5;
z-index: 10;
box-shadow: 0px 4px 6px 0px rgba(0, 0, 0, 0.05);
box-shadow: 0px 10px 15px 0px rgba(0, 0, 0, 0.1);
box-shadow: 0px 10px 10px 0px rgba(0, 0, 0, 0.04);
box-shadow: 0px 20px 25px 0px rgba(0, 0, 0, 0.1);
a {
margin-bottom: 4px;
&:first-child {
border-top-left-radius: 16px;
border-top-right-radius: 16px;
}
&:last-child {
margin-bottom: 0;
border-bottom-left-radius: 16px;
border-bottom-right-radius: 16px;
}
color: var(--text);
font-weight: 600;
display: block;
padding: 8px 16px;
background-color: #fff;
display: flex;
align-items: center;
&:hover {
color: var(--marreta);
}
span {
display: inline-block;
}
}
.name {
width: 140px;
}
}
&.open {
.extension__toggle {
background-color: #F4F4F5;
color: var(--textmuted);
}
.extension__menu {
display: block;
}
}
}
}
main {
.description {
position: relative;
z-index: 3;
font-family: var(--font-family-unna);
font-size: 64px;
line-height: 61.44px;
text-align: center;
color: #000;
max-width: 512px;
margin: 0 auto;
}
.walls_destroyed {
position: relative;
z-index: 3;
max-width: 512px;
margin: 22px auto;
text-align: center;
span {
color: var(--textmuted);
}
}
form {
z-index: 2;
position: relative;
.fields {
&::before {
content: '';
background-image: url(../assets/images/wall.png);
background-repeat: no-repeat;
background-size: 100% 100%;
width: 422px;
height: 306px;
position: absolute;
top: -110px;
right: -180px;
z-index: 1;
}
max-width: 470px;
margin: 0 auto;
position: relative;
.input {
position: relative;
z-index: 2;
padding-right: 28px;
padding-top: 2px;
.icon {
z-index: 2;
&--link {
position: absolute;
top: 50%;
left: 1rem;
margin-top: -6px;
}
}
input {
background-color: #F4F4F5;
padding: 16px 0 16px 44px;
border: 0;
border-radius: 8px;
width: 100%;
box-sizing: border-box;
position: relative;
line-height: 1.3em;
}
}
button {
position: relative;
background-color: var(--marreta);
border-radius: 50%;
height: 56px;
width: 56px;
border: 0;
z-index: 3;
position: absolute;
top: 0;
right: 0;
cursor: pointer;
&:hover {
background-color: var(--marreta-darken);
}
.icon {
width: 23px;
height: 23px;
&--refresh,
&--marreta {
filter: invert(100%) sepia(32%) saturate(8%) hue-rotate(23deg) brightness(102%) contrast(100%);
}
}
}
}
}
.adblock {
color: var(--textmuted);
font-size: 13px;
line-height: 1.2em;
text-align: center;
max-width: 470px;
position: relative;
z-index: 3;
margin: 22px auto 0 auto;
}
.plus {
z-index: 3;
position: relative;
display: grid;
grid-auto-columns: 1fr;
grid-template-columns: 1fr 1fr;
gap: 0px 28px;
align-items: start;
max-width: 960px;
margin: 62px auto 24px auto;
h2 {
font-size: 16px;
padding-bottom: 8px;
margin: 0;
.icon {
margin-right: 10px;
}
}
.text {
font-size: 14px;
color: var(--textmuted);
padding-left: 26px;
ol {
padding-left: 16px;
margin: 0;
}
p {
margin: 0;
}
strong {
font-weight: 600;
color: var(--text);
}
}
.bookmarklet {
a {
border: 2px solid var(--marreta);
color: var(--marreta);
border-radius: 40px;
padding: 8px 16px;
margin-top: 16px;
display: inline-block;
font-weight: 600;
&:hover {
border-color: var(--marreta-darken);
color: var(--marreta-darken);
}
}
}
}
}
footer {}

View file

@ -1,6 +1,3 @@
@use "sass:math";
@use "sass:color";
@forward "normalize.css/normalize";
@use "mixin";

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,13 +0,0 @@
@font-face {
font-family: "Inter 18pt Medium";
src: url("inter-500.eot"); /* IE9 */
src: url("inter-500.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
url("inter-500.woff2") format("woff2"), /* chrome 36+, firefox 39+,iOS 10+, Android 67+ */
url("inter-500.woff") format("woff"), /* chrome, firefox */
url("inter-500.ttf") format("truetype"), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url("inter-500.svg#Inter 18pt Medium") format("svg"); /* iOS 4.1- */
font-style: normal;
font-weight: normal;
}

Binary file not shown.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 389 KiB

Binary file not shown.

Binary file not shown.

BIN
app/dist/fonts/inter-500.woff2 vendored Normal file

Binary file not shown.

View file

@ -1,13 +0,0 @@
@font-face {
font-family: "Inter 18pt SemiBold";
src: url("inter-600.eot"); /* IE9 */
src: url("inter-600.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
url("inter-600.woff2") format("woff2"), /* chrome 36+, firefox 39+,iOS 10+, Android 67+ */
url("inter-600.woff") format("woff"), /* chrome, firefox */
url("inter-600.ttf") format("truetype"), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url("inter-600.svg#Inter 18pt SemiBold") format("svg"); /* iOS 4.1- */
font-style: normal;
font-weight: normal;
}

Binary file not shown.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 390 KiB

Binary file not shown.

Binary file not shown.

BIN
app/dist/fonts/inter-600.woff2 vendored Normal file

Binary file not shown.

View file

@ -1,13 +0,0 @@
@font-face {
font-family: "Unna";
src: url("unna-400.eot"); /* IE9 */
src: url("unna-400.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
url("unna-400.woff2") format("woff2"), /* chrome 36+, firefox 39+,iOS 10+, Android 67+ */
url("unna-400.woff") format("woff"), /* chrome, firefox */
url("unna-400.ttf") format("truetype"), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url("unna-400.svg#Unna") format("svg"); /* iOS 4.1- */
font-style: normal;
font-weight: normal;
}

Binary file not shown.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Binary file not shown.

BIN
app/dist/fonts/unna-400.woff2 vendored Normal file

Binary file not shown.

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M32 32h448c17.7 0 32 14.3 32 32v32c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32V64c0-17.7 14.3-32 32-32zm0 128h448v256c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V160zm128 80c0 8.8 7.2 16 16 16h160c8.8 0 16-7.2 16-16s-7.2-16-16-16H176c-8.8 0-16 7.2-16 16z"/></svg>

Before

Width:  |  Height:  |  Size: 338 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M240 32a32 32 0 1 1 64 0 32 32 0 1 1-64 0zm-48 16a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm-32 80c17.7 0 32 14.3 32 32h8c13.3 0 24 10.7 24 24v16c0 1.7-.2 3.4-.5 5.1C280.3 229.6 320 286.2 320 352c0 88.4-71.6 160-160 160S0 440.4 0 352c0-65.8 39.7-122.4 96.5-146.9-.4-1.6-.5-3.3-.5-5.1v-16c0-13.3 10.7-24 24-24h8c0-17.7 14.3-32 32-32zm0 320a96 96 0 1 0 0-192 96 96 0 1 0 0 192zm192-96c0-25.9-5.1-50.5-14.4-73.1 16.9-32.9 44.8-59.1 78.9-73.9-.4-1.6-.5-3.3-.5-5.1v-16c0-13.3 10.7-24 24-24h8c0-17.7 14.3-32 32-32s32 14.3 32 32h8c13.3 0 24 10.7 24 24v16c0 1.7-.2 3.4-.5 5.1 56.8 24.6 96.5 81.2 96.5 147 0 88.4-71.6 160-160 160-62 0-115.8-35.3-142.4-86.9 9.3-22.5 14.4-47.2 14.4-73.1zm224 0a96 96 0 1 0-192 0 96 96 0 1 0 192 0zM368 0a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm80 48a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>

Before

Width:  |  Height:  |  Size: 875 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M392.8 1.2c-17-4.9-34.7 5-39.6 22l-128 448c-4.9 17 5 34.7 22 39.6s34.7-5 39.6-22l128-448c4.9-17-5-34.7-22-39.6zm80.6 120.1c-12.5 12.5-12.5 32.8 0 45.3l89.3 89.4-89.4 89.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l112-112c12.5-12.5 12.5-32.8 0-45.3l-112-112c-12.5-12.5-32.8-12.5-45.3 0zm-306.7 0c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3l112 112c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256l89.4-89.4c12.5-12.5 12.5-32.8 0-45.3z"/></svg>

Before

Width:  |  Height:  |  Size: 541 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M416 208c0 45.9-14.9 88.3-40 122.7l126.6 126.7c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0s208 93.1 208 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"/></svg>

Before

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View file

@ -1,7 +0,0 @@
function validateForm(){var r=document.getElementById("url"),e=document.querySelector('button[type="submit"]'),t=r.value.trim();if(!t)return showError("Por favor, insira uma URL"),!1;if(!/^https?:\/\//i.test(t))return showError("A URL deve começar com http:// ou https://"),!1;try{new URL(t)}catch(r){return showError("Formato de URL inválido"),!1}return r.readonly=!0,e.disabled=!0,e.classList.add("cursor-wait","disabled:bg-blue-400"),e.classList.remove("hover:bg-blue-700"),r.classList.add("cursor-wait","disabled:bg-gray-50","focus:outline-none"),e.innerHTML=`
<img src="assets/svg/search.svg" class="w-6 h-6 mr-3" alt="Search">
Analisando...
`,!0}function showError(r){var e=document.getElementById("urlForm"),t=e.querySelector(".error-message"),t=(t&&t.remove(),document.createElement("div"));t.className="error-message mt-4 text-base text-red-600",t.innerHTML=`
<img src="assets/svgs/error.svg" class="inline-block w-5 h-5 mr-2" alt="Error icon">
`+r,e.appendChild(t)}"serviceWorker"in navigator&&window.addEventListener("load",()=>{navigator.serviceWorker.register("/service-worker.js").then(()=>{}).catch(()=>{})});
//# sourceMappingURL=script.js.map

File diff suppressed because one or more lines are too long

2
app/dist/js/scripts.js vendored Normal file
View file

@ -0,0 +1,2 @@
"serviceWorker"in navigator&&window.addEventListener("load",()=>{navigator.serviceWorker.register("/service-worker.js").then(()=>{}).catch(()=>{})}),document.addEventListener("DOMContentLoaded",function(){let t=document.querySelector(".integration");var e=document.querySelector(".integration__toggle");let o=document.querySelector(".extension");var n=document.querySelector(".extension__toggle");let r=e=>{e!==t&&t.classList.remove("open"),e!==o&&o.classList.remove("open")};e.addEventListener("click",e=>{e.stopPropagation(),r(t),t.classList.toggle("open")}),n.addEventListener("click",e=>{e.stopPropagation(),r(o),o.classList.toggle("open")}),t.addEventListener("click",e=>{e.stopPropagation()}),o.addEventListener("click",e=>{e.stopPropagation()}),document.addEventListener("click",()=>{t.classList.remove("open"),o.classList.remove("open")})});
//# sourceMappingURL=scripts.js.map

1
app/dist/js/scripts.js.map vendored Normal file
View file

@ -0,0 +1 @@
{"version":3,"sources":["scripts.js"],"names":["navigator","window","addEventListener","serviceWorker","register","then","catch","document","integration","querySelector","integrationToggle","extension","extensionToggle","closeOtherMenus","exceptMenu","classList","remove","e","stopPropagation","toggle"],"mappings":"AAIA,kBAAAA,WACAC,OAAAC,iBAAA,OAAA,KACAF,UAAAG,cAAAC,SAAA,oBAAA,EACAC,KAAA,MAEA,EACAC,MAAA,MAEA,CACA,CAAA,EAMAC,SAAAL,iBAAA,mBAAA,WACA,IAAAM,EAAAD,SAAAE,cAAA,cAAA,EACA,IAAAC,EAAAH,SAAAE,cAAA,sBAAA,EACA,IAAAE,EAAAJ,SAAAE,cAAA,YAAA,EACA,IAAAG,EAAAL,SAAAE,cAAA,oBAAA,EAGA,IAMAI,EAAA,IACAC,IAAAN,GACAA,EAAAO,UAAAC,OAAA,MAAA,EAEAF,IAAAH,GACAA,EAAAI,UAAAC,OAAA,MAAA,CAEA,EAEAN,EAAAR,iBAAA,QAAA,IACAe,EAAAC,gBAAA,EACAL,EAAAL,CAAA,EACAA,EAAAO,UAAAI,OAAA,MAAA,CACA,CAAA,EAEAP,EAAAV,iBAAA,QAAA,IACAe,EAAAC,gBAAA,EACAL,EAAAF,CAAA,EACAA,EAAAI,UAAAI,OAAA,MAAA,CACA,CAAA,EAGAX,EAAAN,iBAAA,QAAA,IACAe,EAAAC,gBAAA,CACA,CAAA,EAEAP,EAAAT,iBAAA,QAAA,IACAe,EAAAC,gBAAA,CACA,CAAA,EAGAX,SAAAL,iBAAA,QAAA,KApCAM,EAAAO,UAAAC,OAAA,MAAA,EACAL,EAAAI,UAAAC,OAAA,MAAA,CAqCA,CAAA,CACA,CAAA","file":"scripts.js","sourcesContent":["/**\r\n * Service Worker registration for PWA functionality\r\n * Registers a service worker to enable offline capabilities and PWA features\r\n */\r\nif ('serviceWorker' in navigator) {\r\n window.addEventListener('load', () => {\r\n navigator.serviceWorker.register('/service-worker.js')\r\n .then(() => {\r\n // Service Worker registered successfully\r\n })\r\n .catch(() => {\r\n // Service Worker registration failed\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Header toggle menus\r\n */\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n const integration = document.querySelector('.integration');\r\n const integrationToggle = document.querySelector('.integration__toggle');\r\n const extension = document.querySelector('.extension');\r\n const extensionToggle = document.querySelector('.extension__toggle');\r\n\r\n // Function to close all menus\r\n const closeAllMenus = () => {\r\n integration.classList.remove('open');\r\n extension.classList.remove('open');\r\n };\r\n\r\n // Function to close other menus except the one passed\r\n const closeOtherMenus = (exceptMenu) => {\r\n if (exceptMenu !== integration) {\r\n integration.classList.remove('open');\r\n }\r\n if (exceptMenu !== extension) {\r\n extension.classList.remove('open');\r\n }\r\n };\r\n\r\n integrationToggle.addEventListener('click', (e) => {\r\n e.stopPropagation(); // Prevent click from bubbling to document\r\n closeOtherMenus(integration);\r\n integration.classList.toggle('open');\r\n });\r\n\r\n extensionToggle.addEventListener('click', (e) => {\r\n e.stopPropagation(); // Prevent click from bubbling to document\r\n closeOtherMenus(extension);\r\n extension.classList.toggle('open');\r\n });\r\n\r\n // Prevent clicks inside menus from closing them\r\n integration.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n extension.addEventListener('click', (e) => {\r\n e.stopPropagation();\r\n });\r\n\r\n // Close menus when clicking outside\r\n document.addEventListener('click', () => {\r\n closeAllMenus();\r\n });\r\n});"]}

View file

@ -4,13 +4,13 @@ return [
'walls_destroyed' => 'Paywall überwunden',
'url_placeholder' => 'Adresse eingegeben (z.B., https://example.com)',
'analyze_button' => 'Analysiere',
'nav_integration' => 'Integrations',
'nav_extension' => 'Install the extension',
'bookmarklet_title' => 'Zu Lesezeichen hinzufügen',
'bookmarklet_description' => 'Ziehe Sie die Schaltfläche unten in Ihre Lesezeichenleiste, um schnell auf {site_name} zuzugreifen:',
'open_in' => 'Öffne {site_name}',
'open_source_description' => 'Das ist ein <a href="https://github.com/manualdousuario/marreta/" class="underline" target="_blank">Open Source</a> Projekt das mit ❤️ erstellt wurde!',
'adblocker_warning' => 'Bei Konflikten zwischen {site_name} und Werbeblockern kann ein weißer Bildschirm angezeigt werden. Verwenden Sie den Inkognito-Modus oder deaktivieren Sie die Erweiterung.',
'add_as_app' => 'Als app hinzufügen',
'add_as_app_description' => 'Installieren Sie {site_name} als App auf Android mit Chrome, um schnell Links zu teilen:',
'add_as_app_step1' => 'Klicken Sie in Ihrem Browser auf das Menüsymbol (drei Punkte)',
'add_as_app_step2' => 'Wählen Sie "App installieren" oder "Zum Startbildschirm hinzufügen"',
'add_as_app_step3' => 'Klicken Sie für den Schnellzugriff auf „Installieren"',

View file

@ -4,13 +4,13 @@ return [
'walls_destroyed' => 'walls destroyed!',
'url_placeholder' => 'Enter URL (e.g., https://example.com)',
'analyze_button' => 'Analyze',
'nav_integration' => 'Integrations',
'nav_extension' => 'Install the extension',
'bookmarklet_title' => 'Add to Bookmarks',
'bookmarklet_description' => 'Drag the button below to your bookmarks bar to quickly access {site_name} on any page:',
'open_in' => 'Open in {site_name}',
'open_source_description' => 'This is an <a href="https://github.com/manualdousuario/marreta/" class="underline" target="_blank">open source</a> project made with ❤️!',
'adblocker_warning' => 'Conflicts between {site_name} and ad blockers may cause a white screen. Use incognito mode or disable the extension.',
'add_as_app' => 'Add as app',
'add_as_app_description' => 'Install {site_name} as an app on Android with Chrome to quickly share links:',
'add_as_app_step1' => 'In your browser, click the menu icon (three dots)',
'add_as_app_step2' => 'Select "Install app" or "Add to home screen"',
'add_as_app_step3' => 'Click "Install" for quick access',

View file

@ -4,13 +4,13 @@ return [
'walls_destroyed' => '¡paredes destruidas!',
'url_placeholder' => 'Ingrese URL (ej: https://ejemplo.com)',
'analyze_button' => 'Analizar',
'nav_integration' => 'Integraciones',
'nav_extension' => 'Instalar la extensión',
'bookmarklet_title' => 'Agregar a Favoritos',
'bookmarklet_description' => 'Arrastra el botón a tu barra de favoritos para acceder rápidamente a {site_name} en cualquier página:',
'open_in' => 'Abrir en {site_name}',
'open_source_description' => '¡Este es un proyecto de <a href="https://github.com/manualdousuario/marreta/" class="underline" target="_blank">código abierto</a> hecho con ❤️!',
'adblocker_warning' => 'Los conflictos entre {site_name} y los bloqueadores de anuncios pueden causar una pantalla en blanco. Use el modo incógnito o desactive la extensión.',
'add_as_app' => 'Agregar como aplicación',
'add_as_app_description' => 'Instala {site_name} como una aplicación en Android con Chrome para compartir enlaces rápidamente:',
'add_as_app_step1' => 'En su navegador, haga clic en el icono de menú (tres puntos)',
'add_as_app_step2' => 'Seleccione "Instalar aplicación" o "Agregar a la pantalla de inicio"',
'add_as_app_step3' => 'Haga clic en "Instalar" para tener acceso rápido',

View file

@ -4,13 +4,13 @@ return [
'walls_destroyed' => 'paredes derrubadas!',
'url_placeholder' => 'Digite a URL (ex: https://exemplo.com)',
'analyze_button' => 'Analisar',
'nav_integration' => 'Integrações',
'nav_extension' => 'Instale a extensão',
'bookmarklet_title' => 'Adicione aos Favoritos',
'bookmarklet_description' => 'Arraste o botão abaixo para sua barra de favoritos para acessar o {site_name} rapidamente em qualquer página:',
'open_in' => 'Abrir no {site_name}',
'open_source_description' => 'Este é um projeto de <a href="https://github.com/manualdousuario/marreta/" class="underline" target="_blank">código aberto</a> feito com ❤️!',
'bookmarklet_description' => 'Adicione aos favoritos arrastando o botão abaixo <strong>para sua barra de favoritos</strong> para acessar o Marreta rapidamente em qualquer página!',
'open_in' => 'Me arrasta',
'adblocker_warning' => 'Conflitos entre o {site_name} e bloqueadores de anúncios podem causar tela branca. Use o modo anônimo ou desative a extensão.',
'add_as_app' => 'Adicionar como aplicativo',
'add_as_app_description' => 'Instale o {site_name} como um aplicativo no Android com Chrome para compartilhar links rapidamente:',
'add_as_app_step1' => 'No seu navegador, clique no ícone de menu (três pontos)',
'add_as_app_step2' => 'Selecione "Instalar aplicativo" ou "Adicionar à tela inicial"',
'add_as_app_step3' => 'Clique em "Instalar" para ter acesso rápido',

View file

@ -4,13 +4,13 @@ return [
'walls_destroyed' => 'стены разрушены!',
'url_placeholder' => 'Введите URL (например, https://example.com)',
'analyze_button' => 'Анализировать',
'nav_integration' => 'Integrations',
'nav_extension' => 'Install the extension',
'bookmarklet_title' => 'Добавить в закладки',
'bookmarklet_description' => 'Перетащите кнопку ниже на панель закладок, чтобы быстро получить доступ к {site_name} на любой странице:',
'open_in' => 'Открыть в {site_name}',
'open_source_description' => 'Это <a href="https://github.com/manualdousuario/marreta/" class="underline" target="_blank">проект с открытым исходным кодом</a>, созданный с ❤️!',
'adblocker_warning' => 'Конфликты между {site_name} и блокировщиками рекламы могут вызывать белый экран. Используйте режим инкогнито или отключите расширение.',
'add_as_app' => 'Добавить как приложение',
'add_as_app_description' => 'Установите {site_name} как приложение на Android с Chrome, чтобы быстро делиться ссылками:',
'add_as_app_step1' => 'В браузере нажмите на значок меню (три точки)',
'add_as_app_step2' => 'Выберите "Установить приложение" или "Добавить на главный экран".',
'add_as_app_step3' => 'Нажмите "Установить" для быстрого доступа.',

1098
app/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -10,14 +10,15 @@
"gulp-clean-css": "^4.3.0",
"gulp-concat": "^2.6.1",
"gulp-dart-sass": "^1.1.0",
"gulp-fontmin": "^0.7.4",
"gulp-imagemin": "^7.1.0",
"gulp-newer": "^1.4.0",
"gulp-rename": "^2.0.0",
"gulp-sass": "^5.1.0",
"gulp-sourcemaps": "^3.0.0",
"gulp-svgmin": "^4.1.0",
"ttf2eot": "^3.1.0",
"gulp-ttf2eot": "^1.1.2",
"gulp-ttf2woff": "^1.1.1",
"gulp-ttf2woff2": "^4.0.1",
"gulp-uglify": "^3.0.2",
"gulp-watch": "^5.0.1",
"gulp-webp": "^4.0.1",

View file

@ -5,104 +5,105 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title><?php echo SITE_NAME; ?></title>
<link rel="icon" href="<?php echo SITE_URL; ?>/assets/svg/marreta.svg" type="image/svg+xml">
<link rel="icon" href="<?php echo SITE_URL; ?>/dist/icons/marreta.svg" type="image/svg+xml">
<meta name="theme-color" content="#2563eb">
<link rel="manifest" href="<?php echo SITE_URL; ?>/manifest.json">
<!-- PWA meta tags -->
<meta name="mobile-web-app-capable" content="yes">
<meta name="application-name" content="<?php echo SITE_NAME; ?>">
<!-- Open Graph meta tags -->
<meta property="og:type" content="website" />
<meta property="og:url" content="<?php echo SITE_URL; ?>" />
<meta property="og:title" content="<?php echo SITE_NAME; ?>" />
<meta property="og:description" content="<?php echo htmlspecialchars(SITE_DESCRIPTION); ?>" />
<meta property="og:image" content="<?php echo SITE_URL; ?>/assets/opengraph.png" />
<script src="https://cdn.tailwindcss.com/3.4.15"></script>
<meta property="og:image" content="<?php echo SITE_URL; ?>/dist/images/opengraph.png" />
<style>
<?php
$css_file = 'dist/css/style.css';
if (file_exists($css_file)) {
echo file_get_contents($css_file);
}
?>
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<div class="container mx-auto px-4 py-8 max-w-4xl">
<!-- Cabeçalho da página / Page header -->
<div class="text-center mb-8">
<h1 class="text-4xl font-bold text-gray-800 mb-4">
<img src="assets/svg/marreta.svg" class="inline-block w-12 h-12 mb-2" alt="Marreta">
<?php echo SITE_NAME; ?>
</h1>
<p class="text-gray-600 text-lg"><?php echo SITE_DESCRIPTION; ?></p>
<p class="text-gray-600 text-lg">
<span class="font-bold text-blue-600">
<?php echo number_format($cache_folder, 0, ',', '.'); ?>
</span>
<span><?php echo Language::get('walls_destroyed'); ?></span>
<body>
<div class="container">
<header>
<div class="brand">
<span class="icon icon--marreta"></span>
<h1><?php echo SITE_NAME; ?></h1>
</div>
<nav>
<a target="_blank" href="https://github.com/manualdousuario/marreta/wiki/API-Rest">API Rest</a>
<a target="_blank" href="https://github.com/manualdousuario/marreta/">Github</a>
<div class="integration">
<button class="integration__toggle"><?php echo Language::get('nav_integration'); ?><span class="arrow"></span></button>
<div class="integration__menu">
<a target="_blank" href="https://bsky.app/profile/marreta.pcdomanual.com"><span class="name">Bsky</span><span class="icon icon--bsky"></span></a>
<a target="_blank" href="https://t.me/leissoai_bot"><span class="name">Telegram</span><span class="icon icon--telegram"></span></a>
<a target="_blank" href="https://www.icloud.com/shortcuts/3594074b69ee4707af52ed78922d624f"><span class="name">MacOS</span><span class="icon icon--apple"></span></a>
</div>
</div>
</nav>
<div class="extension">
<button class="extension__toggle"><?php echo Language::get('nav_extension'); ?></button>
<div class="extension__menu">
<a target="_blank" href="https://addons.mozilla.org/pt-BR/firefox/addon/marreta/"><span class="name">Firefox</span><span class="icon icon--firefox"></span></a>
<a target="_blank" href="#"><span class="name">Chrome</span><span class="icon icon--chrome"></span></a>
</div>
</div>
</header>
<main>
<h2 class="description"><?php echo SITE_DESCRIPTION; ?></h2>
<p class="walls_destroyed">
<strong><?php echo number_format($cache_folder, 0, ',', '.'); ?></strong> <span><?php echo Language::get('walls_destroyed'); ?></span>
</p>
</div>
<!-- Formulário principal de análise de URLs / Main URL analysis form -->
<div class="bg-white rounded-xl shadow-lg p-8 mb-8">
<form id="urlForm" method="POST" onsubmit="return validateForm()" class="space-y-6">
<div class="relative">
<div class="flex items-stretch">
<span class="inline-flex items-center px-5 rounded-l-lg border border-r-0 border-gray-300 bg-gray-50 text-gray-500">
<img src="assets/svg/link.svg" class="w-6 h-6" alt="Link">
</span>
<input type="url"
name="url"
id="url"
class="flex-1 block w-full rounded-none rounded-r-lg text-lg py-4 border border-l-0 border-gray-300 bg-gray-50 focus:border-blue-500 focus:ring-blue-500 shadow-sm bg-gray-50"
placeholder="<?php echo Language::get('url_placeholder'); ?>"
value="<?php echo htmlspecialchars($url); ?>"
required
pattern="https?://.+"
title="<?php echo Language::getMessage('INVALID_URL')['message']; ?>">
</div>
<button type="submit"
class="mt-4 w-full inline-flex justify-center items-center px-6 py-4 border border-transparent text-lg font-medium rounded-lg text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200">
<img src="assets/svg/search.svg" class="w-6 h-6 mr-3" alt="Search">
<?php echo Language::get('analyze_button'); ?>
</button>
</div>
</form>
<!-- Aviso sobre bloqueadores de anúncios / Ad blocker warning -->
<div class="mt-4 text-sm text-gray-600 flex items-start">
<p><?php echo str_replace('{site_name}', SITE_NAME, Language::get('adblocker_warning')); ?></p>
</div>
<!-- Área de mensagens de erro/alerta / Error/warning message area -->
<?php if ($message): ?>
<div class="mt-6 <?php echo $message_type === 'error' ? 'bg-red-50 border-red-400' : 'bg-yellow-50 border-yellow-400'; ?> border-l-4 p-4 rounded-r">
<div class="flex">
<div class="flex-shrink-0">
<div class="<?php echo $message_type === 'error' ? 'error' : 'warning'; ?>">
<div>
<div>
<?php if ($message_type === 'error'): ?>
<img src="assets/svg/error.svg" class="w-6 h-6" alt="Error">
<span class="icon icon--error"></span>
<?php else: ?>
<img src="assets/svg/warning.svg" class="w-6 h-6" alt="Warning">
<span class="icon icon--warning"></span>
<?php endif; ?>
</div>
<div class="ml-3">
<p class="text-base <?php echo $message_type === 'error' ? 'text-red-700' : 'text-yellow-700'; ?>">
<div>
<p class="<?php echo $message_type === 'error' ? 'error' : 'warning'; ?>">
<?php echo htmlspecialchars($message); ?>
</p>
</div>
</div>
</div>
<?php endif; ?>
<div class="fields">
<div class="input">
<span class="icon icon--link"></span>
<input type="url"
name="url"
id="url"
placeholder="<?php echo Language::get('url_placeholder'); ?>"
value="<?php echo htmlspecialchars($url); ?>"
required
pattern="https?://.+"
title="<?php echo Language::getMessage('INVALID_URL')['message']; ?>">
</div>
<button type="submit" alt="<?php echo Language::get('analyze_button'); ?>">
<span class="icon icon--marreta"></span>
</button>
</div>
<p class="adblock"><?php echo str_replace('{site_name}', SITE_NAME, Language::get('adblocker_warning')); ?></p>
</form>
<!-- Adicionar como aplicativo / Add as app (mobile only) -->
<div class="bg-white rounded-xl shadow-lg p-8 mt-8 mb-8 md:hidden">
<h2 class="text-xl font-semibold text-gray-800 mb-6 flex items-center">
<img src="assets/svg/marreta.svg" class="w-6 h-6 mr-3" alt="App">
<?php echo Language::get('add_as_app'); ?>
<div class="plus">
<div class="add_as_app">
<h2>
<span class="icon icon--android"></span><?php echo Language::get('add_as_app'); ?>
</h2>
<div class="space-y-4">
<p class="text-gray-600">
<?php echo str_replace('{site_name}', SITE_NAME, Language::get('add_as_app_description')); ?>
</p>
<div class="bg-gray-50 rounded-lg p-4">
<ol class="list-decimal list-inside space-y-2 text-gray-700">
<div class="text">
<div>
<ol>
<li><?php echo Language::get('add_as_app_step1'); ?></li>
<li><?php echo Language::get('add_as_app_step2'); ?></li>
<li><?php echo Language::get('add_as_app_step3'); ?></li>
@ -112,42 +113,30 @@
</div>
</div>
<!-- Seção de Bookmarklet / Bookmarklet section (desktop only) -->
<div class="bg-white rounded-xl shadow-lg p-8 mt-8 mb-8 hidden md:block">
<h2 class="text-xl font-semibold text-gray-800 mb-6 flex items-center">
<img src="assets/svg/bookmark.svg" class="w-6 h-6 mr-3" alt="Favoritos">
<?php echo Language::get('bookmarklet_title'); ?>
<div class="bookmarklet">
<h2>
<span class="icon icon--bookmark"></span><?php echo Language::get('bookmarklet_title'); ?>
</h2>
<div class="space-y-4">
<p class="text-gray-600">
<div class="text">
<p>
<?php echo str_replace('{site_name}', SITE_NAME, Language::get('bookmarklet_description')); ?>
</p>
<div class="flex justify-center">
<div>
<a href="javascript:(function(){let currentUrl=window.location.href;window.location.href='<?php echo SITE_URL; ?>/p/'+encodeURIComponent(currentUrl);})()"
class="inline-flex items-center px-6 py-3 border-2 border-blue-500 font-medium rounded-lg text-blue-600 bg-white hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200 cursor-move"
onclick="return false;">
<img src="assets/svg/marreta.svg" class="w-5 h-5 mr-2" alt="Marreta">
<?php echo str_replace('{site_name}', SITE_NAME, Language::get('open_in')); ?>
</a>
</div>
</div>
</div>
<div class="text-gray-600 text-center text-sm">
<p>
<?php echo Language::get('open_source_description'); ?>
</p>
<p class="mt-2">
<a href="https://github.com/manualdousuario/marreta/wiki/API-Rest" target="_blank" class="underline">API Rest</a> <a href="https://github.com/manualdousuario/marreta/" target="_blank" class="underline">Github</a>
</p>
</div>
</main>
</div>
<!-- Scripts JavaScript -->
<script>
<?php
$js_file = 'assets/js/scripts.js';
$js_file = 'dist/js/scripts.js';
if (file_exists($js_file)) {
echo file_get_contents($js_file);
}

View file

@ -28,13 +28,13 @@ $manifest = [
'orientation' => 'any',
'icons' => [
[
'src' => 'assets/pwa/192x192.png',
'src' => 'dist/images/pwa/192x192.png',
'sizes' => '192x192',
'type' => 'image/png',
'purpose' => 'any maskable'
],
[
'src' => 'assets/pwa/512x512.png',
'src' => 'dist/images/pwa/512x512.png',
'sizes' => '512x512',
'type' => 'image/png',
'purpose' => 'any maskable'