@@ -0,0 +1,18 @@
|
||||
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
WORKDIR /src/web
|
||||
|
||||
COPY web.csproj ./
|
||||
RUN dotnet restore web.csproj
|
||||
|
||||
# Copy only the web project files to avoid bringing other projects into the build context
|
||||
COPY . ./
|
||||
RUN dotnet publish web.csproj -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS final
|
||||
WORKDIR /app
|
||||
EXPOSE 8080
|
||||
ENV ASPNETCORE_URLS=http://0.0.0.0:8080
|
||||
|
||||
COPY --from=build /app/publish .
|
||||
ENTRYPOINT ["dotnet", "web.dll"]
|
||||
@@ -0,0 +1,17 @@
|
||||
// Program.cs
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services.AddRouting();
|
||||
|
||||
builder.Services.AddReverseProxy()
|
||||
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Static site
|
||||
app.UseDefaultFiles();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.MapReverseProxy();
|
||||
|
||||
app.Run();
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Container (Dockerfile)": {
|
||||
"commandName": "Docker",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_HTTPS_PORTS": "8081",
|
||||
"ASPNETCORE_HTTP_PORTS": "8080"
|
||||
},
|
||||
"publishAllPorts": true,
|
||||
"useSSL": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"ReverseProxy": {
|
||||
"Routes": {
|
||||
"apiRoute": {
|
||||
"ClusterId": "apiCluster",
|
||||
"Match": { "Path": "/api/{**catch-all}" }
|
||||
}
|
||||
},
|
||||
"Clusters": {
|
||||
"apiCluster": {
|
||||
"Destinations": {
|
||||
"api": { "Address": "http://api:8080/" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
|
||||
"ReverseProxy": {
|
||||
"Routes": {
|
||||
"apiRoute": {
|
||||
"ClusterId": "apiCluster",
|
||||
"Match": { "Path": "/api/{**catch-all}" }
|
||||
}
|
||||
},
|
||||
"Clusters": {
|
||||
"apiCluster": {
|
||||
"Destinations": {
|
||||
"api": { "Address": "http://myai-api:8080/" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>e410da9c-f42f-43bd-86d7-47d051e2bad6</UserSecretsId>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />
|
||||
<PackageReference Include="Yarp.ReverseProxy" Version="2.3.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,99 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>MyAi.ro · AI CV Matcher</title>
|
||||
<meta name="description" content="Upload a CV PDF, provide a job link or description, and compare the job requirements against extracted CV context." />
|
||||
<meta name="author" content="Mihes Gelu" />
|
||||
<meta property="og:title" content="MyAi.ro · AI CV Matcher" />
|
||||
<meta property="og:description" content="AI-powered CV-to-job matching demo." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://myai.ro/cv-matcher/" />
|
||||
<meta name="theme-color" content="#071326" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="/css/myai.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="site-shell">
|
||||
<header class="header" id="top">
|
||||
<div class="container nav-wrap">
|
||||
<a class="brand" href="/" aria-label="MyAi.ro home"><span class="brand-mark ai-mark">AI</span><span><span class="brand-text">MyAi.ro</span><small>CV Matcher</small></span></a>
|
||||
<nav class="nav" id="mainNav" aria-label="Primary navigation"><a href="/">Navigator</a><a href="#matcher">Matcher</a><a href="#contact">Contact</a></nav>
|
||||
<button class="menu-toggle" id="menuToggle" aria-expanded="false" aria-controls="mainNav"><span></span><span></span><span></span></button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="hero matcher-hero">
|
||||
<div class="container hero-grid">
|
||||
<div class="hero-copy">
|
||||
<span class="eyebrow">AI CV Matcher</span>
|
||||
<h1>Upload your CV, add a job link, and see how well they match.</h1>
|
||||
<p class="hero-text">The backend should extract text from the PDF, create RAG context from your CV, retrieve relevant experience for the job, then score strengths, gaps and next actions.</p>
|
||||
<div class="hero-actions"><a class="btn btn-primary" href="#matcher">Try matcher</a><a class="btn btn-secondary" href="/">Back to navigator</a></div>
|
||||
</div>
|
||||
<div class="hero-card ai-console-card">
|
||||
<div class="console-line"><span>1</span> PDF text extraction</div>
|
||||
<div class="console-line"><span>2</span> CV chunking + embeddings</div>
|
||||
<div class="console-line"><span>3</span> Job URL/description parsing</div>
|
||||
<div class="console-line"><span>4</span> Match score + evidence</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="matcher">
|
||||
<div class="container matcher-grid">
|
||||
<form class="ai-panel" id="cvMatcherForm">
|
||||
<span class="eyebrow">Input</span>
|
||||
<h2>CV and job details</h2>
|
||||
<label class="file-drop" for="cvFile"><strong>Upload CV PDF</strong><span id="cvFileName">PDF only, max size handled by backend</span><input type="file" id="cvFile" accept="application/pdf" required /></label>
|
||||
<label><span>Job link</span><input type="url" id="jobUrl" placeholder="https://company.com/careers/job" /></label>
|
||||
<label><span>Or paste job description</span><textarea id="jobDescription" rows="8" placeholder="Paste the job description if the page cannot be crawled."></textarea></label>
|
||||
<div class="consent-inline"><input type="checkbox" id="gdprConsent" required /><label for="gdprConsent">I agree that my CV is processed for this matching demo. Do not upload sensitive documents unless you trust the deployment.</label></div>
|
||||
<button id="matchSubmit" type="submit" class="btn btn-primary">Extract CV and match job</button>
|
||||
<strong id="matcherMsg" class="form-message"></strong>
|
||||
</form>
|
||||
|
||||
<aside class="ai-panel result-panel">
|
||||
<span class="eyebrow">Result</span>
|
||||
<h2>Match analysis</h2>
|
||||
<div id="matchResult" class="empty-result">Upload a CV and provide a job link or description to generate a result.</div>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section contact" id="contact">
|
||||
<div class="container contact-grid">
|
||||
<div>
|
||||
<span class="eyebrow">Contact</span>
|
||||
<h2>Want this adapted for your workflow?</h2>
|
||||
<p>This form uses the existing template contact API endpoint.</p>
|
||||
<div class="contact-list"><div><span>Contact person</span><strong>Mihes Gelu</strong></div><div><span>Phone</span><strong><a href="tel:+40722523764">+40 722-523-764</a></strong></div></div>
|
||||
</div>
|
||||
<form class="contact-form" id="contactForm">
|
||||
<label><span>Name</span><input type="text" id="name" placeholder="Your name" required /></label>
|
||||
<label><span>Email</span><input type="email" id="email" placeholder="name@company.com" required /></label>
|
||||
<label><span>Message</span><textarea id="message" rows="6" placeholder="Tell me what you want to build." required></textarea></label>
|
||||
<button id="submit" type="submit" class="btn btn-primary">Send message</button>
|
||||
<strong id="msgSubmit" class="form-message"></strong>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="footer"><div class="container footer-wrap"><p>© <span id="year"></span> MyAi.ro · All rights reserved</p><div class="footer-links footer-legal"><a href="/legal/terms-en.html" target="_blank">Terms</a><a href="/legal/privacy-en.html" target="_blank">Privacy</a><a href="/legal/cookies-en.html" target="_blank">Cookies</a></div><a href="#top" class="back-to-top btn btn-dark btn-sm shadow">Back to top</a></div></footer>
|
||||
</div>
|
||||
|
||||
<div id="contactLoader" class="loader-overlay" style="display:none;"><div class="loader-box">Sending...</div></div>
|
||||
<div id="cookieBanner" class="cookie-overlay" style="display:none;"><div class="cookie-box"><div class="cookie-text"><strong>Cookies</strong><br>We use necessary cookies and, with your consent, analytics through Google Tag Manager. <a href="/legal/privacy-en.html" target="_blank">Privacy policy</a>.</div><div class="cookie-actions"><button id="cookieReject" class="btn btn-warning btn-sm">Reject</button><button id="cookieNecessary" class="btn btn-warning btn-sm">Necessary only</button><button id="cookieAccept" class="btn btn-primary btn-sm">Accept analytics</button></div></div></div>
|
||||
<a href="#" id="cookieManage" class="cookie-manage btn btn-dark btn-sm shadow" style="display:none;">Cookie settings</a>
|
||||
|
||||
<script src="/js/vendor/jquery-1.12.4.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/myai.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 252 KiB |
|
After Width: | Height: | Size: 147 KiB |
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="800" viewBox="0 0 1200 800" fill="none">
|
||||
<rect width="1200" height="800" rx="36" fill="#081120"/>
|
||||
<rect x="75" y="75" width="1050" height="650" rx="30" fill="#12213A" stroke="#56B6FF" stroke-opacity="0.25"/>
|
||||
<rect x="150" y="150" width="320" height="500" rx="28" fill="#173255"/>
|
||||
<rect x="540" y="170" width="470" height="70" rx="18" fill="#21406E"/>
|
||||
<rect x="540" y="280" width="400" height="30" rx="15" fill="#AFBDD4" fill-opacity="0.7"/>
|
||||
<rect x="540" y="340" width="430" height="30" rx="15" fill="#AFBDD4" fill-opacity="0.45"/>
|
||||
<rect x="540" y="430" width="250" height="130" rx="22" fill="#56B6FF" fill-opacity="0.9"/>
|
||||
<rect x="820" y="430" width="190" height="130" rx="22" fill="#7DF0C8" fill-opacity="0.85"/>
|
||||
<path d="M310 255C365.228 255 410 299.772 410 355V430H370V355C370 321.863 343.137 295 310 295C276.863 295 250 321.863 250 355V430H210V355C210 299.772 254.772 255 310 255Z" fill="#7DF0C8"/>
|
||||
<rect x="190" y="390" width="240" height="170" rx="24" fill="#0F1B31" stroke="#7DF0C8" stroke-width="10"/>
|
||||
<text x="145" y="690" fill="#EEF4FF" font-family="Arial, sans-serif" font-size="54" font-weight="700">easyBackup</text>
|
||||
<text x="145" y="740" fill="#AFBDD4" font-family="Arial, sans-serif" font-size="28">Replace with your real product screenshot</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 238 KiB |
|
After Width: | Height: | Size: 191 KiB |
|
After Width: | Height: | Size: 247 KiB |
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="800" viewBox="0 0 1200 800" fill="none">
|
||||
<rect width="1200" height="800" rx="36" fill="#0B172A"/>
|
||||
<rect x="80" y="80" width="1040" height="640" rx="30" fill="#13233F" stroke="#56B6FF" stroke-opacity="0.25"/>
|
||||
<rect x="140" y="150" width="380" height="420" rx="22" fill="#1B3155"/>
|
||||
<rect x="570" y="150" width="480" height="70" rx="18" fill="#21406E"/>
|
||||
<rect x="570" y="260" width="430" height="28" rx="14" fill="#7DF0C8" fill-opacity="0.7"/>
|
||||
<rect x="570" y="316" width="360" height="28" rx="14" fill="#7DF0C8" fill-opacity="0.5"/>
|
||||
<rect x="570" y="372" width="410" height="28" rx="14" fill="#7DF0C8" fill-opacity="0.35"/>
|
||||
<rect x="570" y="448" width="190" height="56" rx="18" fill="#56B6FF"/>
|
||||
<circle cx="330" cy="300" r="110" fill="#56B6FF" fill-opacity="0.18"/>
|
||||
<path d="M330 212C374.183 212 410 247.817 410 292C410 355 330 430 330 430C330 430 250 355 250 292C250 247.817 285.817 212 330 212Z" fill="#7DF0C8"/>
|
||||
<text x="140" y="645" fill="#EEF4FF" font-family="Arial, sans-serif" font-size="54" font-weight="700">easyDent</text>
|
||||
<text x="140" y="695" fill="#AFBDD4" font-family="Arial, sans-serif" font-size="28">Replace with your real product screenshot</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 205 KiB |
|
After Width: | Height: | Size: 263 KiB |
|
After Width: | Height: | Size: 164 KiB |
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="800" viewBox="0 0 1200 800" fill="none">
|
||||
<rect width="1200" height="800" rx="36" fill="#091423"/>
|
||||
<rect x="80" y="80" width="1040" height="640" rx="28" fill="#13233F" stroke="#7DF0C8" stroke-opacity="0.22"/>
|
||||
<rect x="130" y="145" width="250" height="470" rx="24" fill="#19304F"/>
|
||||
<rect x="420" y="145" width="630" height="110" rx="24" fill="#1D3C67"/>
|
||||
<rect x="420" y="290" width="300" height="145" rx="24" fill="#56B6FF" fill-opacity="0.9"/>
|
||||
<rect x="750" y="290" width="300" height="145" rx="24" fill="#7DF0C8" fill-opacity="0.85"/>
|
||||
<rect x="420" y="470" width="630" height="145" rx="24" fill="#1B3155"/>
|
||||
<rect x="170" y="195" width="170" height="16" rx="8" fill="#AFBDD4"/>
|
||||
<rect x="170" y="245" width="110" height="16" rx="8" fill="#AFBDD4" fill-opacity="0.75"/>
|
||||
<rect x="170" y="295" width="140" height="16" rx="8" fill="#AFBDD4" fill-opacity="0.55"/>
|
||||
<text x="130" y="678" fill="#EEF4FF" font-family="Arial, sans-serif" font-size="54" font-weight="700">easyERP</text>
|
||||
<text x="130" y="728" fill="#AFBDD4" font-family="Arial, sans-serif" font-size="28">Replace with your real product screenshot</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" viewBox="0 0 48 32">
|
||||
<clipPath id="a"><rect width="48" height="32" rx="2"/></clipPath>
|
||||
<g clip-path="url(#a)">
|
||||
<rect width="48" height="32" fill="#012169"/>
|
||||
<path d="M0 0l48 32M48 0L0 32" stroke="#fff" stroke-width="6"/>
|
||||
<path d="M0 0l48 32M48 0L0 32" stroke="#C8102E" stroke-width="3"/>
|
||||
<path d="M24 0v32M0 16h48" stroke="#fff" stroke-width="10"/>
|
||||
<path d="M24 0v32M0 16h48" stroke="#C8102E" stroke-width="6"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 513 B |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" viewBox="0 0 48 32">
|
||||
<rect width="16" height="32" fill="#002B7F"/>
|
||||
<rect x="16" width="16" height="32" fill="#FCD116"/>
|
||||
<rect x="32" width="16" height="32" fill="#CE1126"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 249 B |
@@ -0,0 +1,144 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>MyAi.ro · AI Engineering Showcase</title>
|
||||
<meta name="description" content="MyAi.ro showcases practical AI engineering demos, including a CV-to-job matcher powered by document extraction, retrieval and AI scoring." />
|
||||
<meta name="author" content="Mihes Gelu" />
|
||||
<meta property="og:title" content="MyAi.ro · AI Engineering Showcase" />
|
||||
<meta property="og:description" content="Practical AI demos built by a veteran software developer." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://myai.ro/" />
|
||||
<meta name="theme-color" content="#071326" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="css/myai.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="site-shell">
|
||||
<header class="header" id="top">
|
||||
<div class="container nav-wrap">
|
||||
<a class="brand" href="/" aria-label="MyAi.ro home">
|
||||
<span class="brand-mark ai-mark">AI</span>
|
||||
<span>
|
||||
<span class="brand-text">MyAi.ro</span>
|
||||
<small>AI engineering showcase</small>
|
||||
</span>
|
||||
</a>
|
||||
<nav class="nav" id="mainNav" aria-label="Primary navigation">
|
||||
<a href="#demos">Demos</a>
|
||||
<a href="#contact">Contact</a>
|
||||
</nav>
|
||||
<button class="menu-toggle" id="menuToggle" aria-expanded="false" aria-controls="mainNav">
|
||||
<span></span><span></span><span></span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="hero navigator-hero">
|
||||
<div class="container hero-grid">
|
||||
<div class="hero-copy">
|
||||
<span class="eyebrow">Applied AI lab</span>
|
||||
<h1>Production-minded AI demos, not generic chatbot wrappers.</h1>
|
||||
<p class="hero-text">MyAi.ro is a technical showcase for practical AI systems: document understanding, retrieval, matching, automation and decision support.</p>
|
||||
<div class="hero-actions">
|
||||
<a class="btn btn-primary" href="/cv-matcher/">Open CV Matcher</a>
|
||||
<a class="btn btn-secondary" href="#contact">Contact</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-card ai-console-card">
|
||||
<div class="console-line"><span>upload</span> CV.pdf</div>
|
||||
<div class="console-line"><span>extract</span> skills, projects, experience</div>
|
||||
<div class="console-line"><span>retrieve</span> relevant CV context</div>
|
||||
<div class="console-line"><span>score</span> job match + gaps</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="demos">
|
||||
<div class="container">
|
||||
<div class="section-heading">
|
||||
<span class="eyebrow">Navigator</span>
|
||||
<h2>Select an AI demo</h2>
|
||||
<p>Start with the CV Matcher. More demos can be added here without changing the site structure.</p>
|
||||
</div>
|
||||
<div class="demo-grid">
|
||||
<a class="demo-card active" href="/cv-matcher/">
|
||||
<span class="product-tag">Available</span>
|
||||
<h3>CV Matcher</h3>
|
||||
<p>Upload a CV PDF, provide a job link or description, extract RAG context and generate a match score with strengths and gaps.</p>
|
||||
<strong>Open demo →</strong>
|
||||
</a>
|
||||
<article class="demo-card muted-card">
|
||||
<span class="product-tag">Next</span>
|
||||
<h3>RAG Playground</h3>
|
||||
<p>Experiment with chunk size, retrieval count and source context transparency.</p>
|
||||
</article>
|
||||
<article class="demo-card muted-card">
|
||||
<span class="product-tag">Next</span>
|
||||
<h3>Agent Automation</h3>
|
||||
<p>Job discovery, filtering, ranking and notification workflows.</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section contact" id="contact">
|
||||
<div class="container contact-grid">
|
||||
<div>
|
||||
<span class="eyebrow">Contact</span>
|
||||
<h2>Discuss an AI integration or custom software project</h2>
|
||||
<p>Use the form and it will submit through the existing contact API endpoint from the template.</p>
|
||||
<div class="contact-list">
|
||||
<div><span>Contact person</span><strong>Mihes Gelu</strong></div>
|
||||
<div><span>Phone</span><strong><a href="tel:+40722523764">+40 722-523-764</a></strong></div>
|
||||
<div><span>WhatsApp</span><strong><a href="https://wa.me/40744564177" target="_blank" rel="noreferrer">+40 744-564-177</a></strong></div>
|
||||
</div>
|
||||
</div>
|
||||
<form class="contact-form" id="contactForm">
|
||||
<label><span>Name</span><input type="text" id="name" placeholder="Your name" required /></label>
|
||||
<label><span>Email</span><input type="email" id="email" placeholder="name@company.com" required /></label>
|
||||
<label><span>Message</span><textarea id="message" rows="6" placeholder="Tell me what you want to build." required></textarea></label>
|
||||
<button id="submit" type="submit" class="btn btn-primary">Send message</button>
|
||||
<strong id="msgSubmit" class="form-message"></strong>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="container footer-wrap">
|
||||
<p>© <span id="year"></span> MyAi.ro · All rights reserved</p>
|
||||
<div class="footer-links footer-legal">
|
||||
<a href="/legal/terms-en.html" target="_blank">Terms</a>
|
||||
<a href="/legal/privacy-en.html" target="_blank">Privacy</a>
|
||||
<a href="/legal/cookies-en.html" target="_blank">Cookies</a>
|
||||
</div>
|
||||
<a href="#top" class="back-to-top btn btn-dark btn-sm shadow">Back to top</a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<div id="contactLoader" class="loader-overlay" style="display:none;"><div class="loader-box">Sending...</div></div>
|
||||
|
||||
<div id="cookieBanner" class="cookie-overlay" style="display:none;">
|
||||
<div class="cookie-box">
|
||||
<div class="cookie-text"><strong>Cookies</strong><br>We use necessary cookies and, with your consent, analytics through Google Tag Manager. <a href="/legal/privacy-en.html" target="_blank">Privacy policy</a>.</div>
|
||||
<div class="cookie-actions">
|
||||
<button id="cookieReject" class="btn btn-warning btn-sm">Reject</button>
|
||||
<button id="cookieNecessary" class="btn btn-warning btn-sm">Necessary only</button>
|
||||
<button id="cookieAccept" class="btn btn-primary btn-sm">Accept analytics</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" id="cookieManage" class="cookie-manage btn btn-dark btn-sm shadow" style="display:none;">Cookie settings</a>
|
||||
|
||||
<script src="js/vendor/jquery-1.12.4.min.js"></script>
|
||||
<script src="js/bootstrap.min.js"></script>
|
||||
<script src="js/myai.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,490 @@
|
||||
var translations = {
|
||||
ro: {
|
||||
'brand.tagline': 'Romania dezvoltare applicatii',
|
||||
'nav.products': 'Produse', 'nav.services': 'Servicii', 'nav.contact': 'Contactati-ne',
|
||||
'hero.eyebrow': 'Portofoliu software easySoft',
|
||||
'hero.title': 'Software pentru cabinete dentare, gestiune de stocuri si salvare sigura a datelor.',
|
||||
'hero.text': 'Aplicatii practice construite pentru fluxuri reale de lucru: managementul pacientilor, contabilitate si gestiune, plus backup automatizat pentru fisiere importante.',
|
||||
'hero.ctaPrimary': 'Vezi produsele', 'hero.ctaSecondary': 'Contactati-ne',
|
||||
'hero.metric1': 'aplicații software', 'hero.metric2': 'ani experiență în dezvoltare', 'hero.metric3': 'instalări active',
|
||||
'hero.cardLabel': 'Portofoliu software', 'hero.badge1': 'cabinete dentare', 'hero.badge2': 'gestiune si contabilitate', 'hero.badge3': 'salvare automata',
|
||||
'products.eyebrow': 'Produse', 'products.title': 'Aplicatii software pentru activitati de zi cu zi', 'products.text': 'Portofoliul actual include aplicatii pentru cabinete stomatologice, operatiuni comerciale si protectia datelor.',
|
||||
'products.easydent.title': 'Soft pentru cabinete stomatologice',
|
||||
'products.easydent.desc': 'easyDent este un program destinat cabinetelor stomatologice si clinicilor dentare. Puteti urmari pacienti, plati, interventii, pacienti restantieri si profitul pe perioade de timp.',
|
||||
'products.easydent.feature1': 'Planificarea pacientilor intr-o sectiune simplu de utilizat', 'products.easydent.feature2': 'Imagini dentare, istoric pe dinte si poze atasate pacientilor', 'products.easydent.feature3': 'Raport lunar CNAS si configurare pe specializari',
|
||||
'products.easyerp.title': 'Soft de contabilitate si gestiunea stocurilor',
|
||||
'products.easyerp.desc': 'easyERP este un program client-server, bazat pe SQL, compus din module pentru diferite divizii ale companiei: gestiune, contabilitate, facturare, livrari, comenzi si promotii.',
|
||||
'products.easyerp.feature1': 'Receptie de marfa, inventar si cautare rapida in nomenclatoare', 'products.easyerp.feature2': 'Control pe roluri si drepturi de acces pe module', 'products.easyerp.feature3': 'Documente comerciale si rapoarte operationale',
|
||||
'products.easybackup.title': 'Utilitar pentru salvarea fisierelor',
|
||||
'products.easybackup.desc': 'easyBackup salveaza fisiere in directoare partajate sau pe servere FTP, cu job-uri recurente sau simple, monitorizare in timp si optiuni de compresie si notificare.',
|
||||
'products.easybackup.feature1': 'Definire job-uri recurente sau simple', 'products.easybackup.feature2': 'Scanare directoare cu excluderi si filtre', 'products.easybackup.feature3': 'Compresie, parola si notificari prin e-mail',
|
||||
'products.download': 'Descarca',
|
||||
'services.eyebrow': 'Servicii', 'services.title': 'Servicii software si consultanta IT',
|
||||
'services.db.title': 'Proiectare baze de date', 'services.db.text': 'Organizati mai bine informatiile si obtineti rapoartele de care aveti nevoie.',
|
||||
'services.it.title': 'Consultanta IT', 'services.it.text': 'Analizam ofertele disponibile si alegem sistemul informatic potrivit pentru activitatea dumneavoastra.',
|
||||
'services.dev.title': 'Dezvoltare software', 'services.dev.text': 'Construim aplicatii adaptate fluxului real de lucru, nu invers.',
|
||||
'about.eyebrow': 'easySoft', 'about.title': 'Solutii software construite pentru lucru real',
|
||||
'about.text1': 'Portofoliul easySoft acopera activitati esentiale pentru cabinete stomatologice, evidenta comerciala si protectia fisierelor importante.',
|
||||
'about.text2': 'Aplicatiile sunt gandite pentru utilizare practica, implementare rapida si acces clar la informatiile care conteaza in activitatea zilnica.',
|
||||
'about.point1Title': 'Implementare practica', 'about.point1Text': 'Produse software orientate spre utilizare zilnica.',
|
||||
'about.point2Title': 'Fluxuri clare', 'about.point2Text': 'Planificare, evidenta, facturare, rapoarte si backup in functii usor de urmarit.',
|
||||
'about.point3Title': 'Suport comercial direct', 'about.point3Text': 'Pentru prezentare, oferta sau implementare, puteti lua legatura direct cu easySoft.',
|
||||
'contact.eyebrow': 'Contactati-ne', 'contact.title': 'Discutam despre nevoile tale software',
|
||||
'contact.text': 'easySoft Romania dezvoltare applicatii. Pentru prezentari, detalii comerciale sau implementare, folositi datele de mai jos.',
|
||||
'contact.personLabel': 'Persoana de contact', 'contact.addressLabel': 'Adresa', 'contact.phoneLabel': 'Telefon', 'contact.webLabel': 'Website',
|
||||
'contact.form.name': 'Nume', 'contact.form.email': 'Email', 'contact.form.message': 'Mesaj', 'contact.form.send': 'Trimite mesaj',
|
||||
'contact.form.yourname': 'Numele dumneavoastra', 'contact.form.youremail': 'nume@companie.ro', 'contact.form.yourmessage': 'Spuneti-ne ce produs sau serviciu va intereseaza.',
|
||||
'contact.form.success': 'Va multumim pentru mesaj.', 'contact.form.submissionfailed': 'A aparut o eroare la transmiterea mesajului.', 'contact.form.verificationfailed': 'A aparut o eroare la verificare Captcha.',
|
||||
'footer.backToTop': 'Inapoi sus',
|
||||
'cookie.text': 'Folosim cookie-uri pentru a imbunatati experienta pe site, a analiza traficul si a personaliza continutul. Puteti accepta toate cookie-urile sau doar cele necesare.',
|
||||
'cookie.privacy': 'Politica de confidentialitate',
|
||||
'cookie.reject': 'Respinge',
|
||||
'cookie.necessary': 'Doar necesare',
|
||||
'cookie.accept': 'Accepta analitice',
|
||||
'footer.rights': 'Toate drepturile rezervate'
|
||||
},
|
||||
en: {
|
||||
'brand.tagline': 'Romania software development',
|
||||
'nav.products': 'Products', 'nav.services': 'Services', 'nav.contact': 'Contact us',
|
||||
'hero.eyebrow': 'easySoft software portfolio',
|
||||
'hero.title': 'Software for dental offices, stock management and secure data backup.',
|
||||
'hero.text': 'Practical applications built for real workflows: patient management, accounting and inventory, plus automated backup for critical files.',
|
||||
'hero.ctaPrimary': 'View products', 'hero.ctaSecondary': 'Contact us',
|
||||
'hero.metric1': 'software solutions', 'hero.metric2': 'years experience in software development', 'hero.metric3': 'active installations',
|
||||
'hero.cardLabel': 'Software portfolio', 'hero.badge1': 'dental offices', 'hero.badge2': 'inventory and accounting', 'hero.badge3': 'automatic backup',
|
||||
'products.eyebrow': 'Products', 'products.title': 'Software applications for daily operations', 'products.text': 'The current portfolio includes applications for dental offices, business operations and data protection.',
|
||||
'products.easydent.title': 'Software for dental offices',
|
||||
'products.easydent.desc': 'easyDent is built for dental offices and clinics. It helps track patients, payments, interventions, outstanding balances and profit over time.',
|
||||
'products.easydent.feature1': 'Simple patient scheduling section', 'products.easydent.feature2': 'Dental images, tooth history and attached patient photos', 'products.easydent.feature3': 'Monthly reports and specialization-based setup',
|
||||
'products.easyerp.title': 'Accounting and stock management software',
|
||||
'products.easyerp.desc': 'easyERP is a client-server SQL-based application with modules for company divisions: inventory, accounting, invoicing, deliveries, orders and promotions.',
|
||||
'products.easyerp.feature1': 'Receiving merchandise, inventory and fast search', 'products.easyerp.feature2': 'Role-based permissions for modules', 'products.easyerp.feature3': 'Commercial documents and operational reports',
|
||||
'products.easybackup.title': 'File backup utility',
|
||||
'products.easybackup.desc': 'easyBackup saves files to shared folders or FTP servers using recurring or one-time jobs, change tracking, compression and notifications.',
|
||||
'products.easybackup.feature1': 'Recurring or one-time backup jobs', 'products.easybackup.feature2': 'Directory scanning with exclusions and filters', 'products.easybackup.feature3': 'Compression, password protection and email alerts',
|
||||
'products.download': 'Download',
|
||||
'services.eyebrow': 'Services', 'services.title': 'Software services and IT consulting',
|
||||
'services.db.title': 'Database design', 'services.db.text': 'Organize information better and get the reports you actually need.',
|
||||
'services.it.title': 'IT consulting', 'services.it.text': 'We review available systems and help choose the right software solution.',
|
||||
'services.dev.title': 'Software development', 'services.dev.text': 'We build applications around the real workflow, not the other way around.',
|
||||
'about.eyebrow': 'easySoft', 'about.title': 'Software solutions built for real work',
|
||||
'about.text1': 'The easySoft portfolio covers essential workflows for dental offices, commercial operations and protection of important files.',
|
||||
'about.text2': 'The applications are built for practical use, fast implementation and clear access to the information that matters every day.',
|
||||
'about.point1Title': 'Practical implementation', 'about.point1Text': 'Software products focused on daily use.',
|
||||
'about.point2Title': 'Clear workflows', 'about.point2Text': 'Scheduling, records, invoicing, reports and backup in functions that are easy to follow.',
|
||||
'about.point3Title': 'Direct commercial support', 'about.point3Text': 'For presentation, pricing or implementation, you can contact easySoft directly.',
|
||||
'contact.eyebrow': 'Contact us', 'contact.title': 'Let’s discuss your software needs',
|
||||
'contact.text': 'easySoft Romania software development. For product presentations, commercial details or implementation, use the contact details below.',
|
||||
'contact.personLabel': 'Contact person', 'contact.addressLabel': 'Address', 'contact.phoneLabel': 'Phone', 'contact.webLabel': 'Website',
|
||||
'contact.form.name': 'Name', 'contact.form.email': 'Email', 'contact.form.message': 'Message', 'contact.form.send': 'Send message',
|
||||
'contact.form.yourname': 'Your name', 'contact.form.youremail': 'name@company.com', 'contact.form.yourmessage': 'Let us know how we can help you.',
|
||||
'contact.form.success': 'Thank you for your message.', 'contact.form.submissionfailed': 'Failed to send the message.', 'contact.form.verificationfailed': 'Captcha verification failed.',
|
||||
'footer.backToTop': 'Back to top',
|
||||
'cookie.text': 'We use cookies to enhance your experience, analyze traffic and personalize content. You can accept all cookies or just the necessary ones.',
|
||||
'cookie.privacy': 'Privacy policy',
|
||||
'cookie.reject': 'Reject',
|
||||
'cookie.necessary': 'Necessary only',
|
||||
'cookie.accept': 'Accept analytics',
|
||||
'footer.rights': 'All rights reserved'
|
||||
}
|
||||
};
|
||||
|
||||
function updateLegalLinks(lang) {
|
||||
$('.legal-link').each(function () {
|
||||
var $link = $(this);
|
||||
|
||||
if (lang === 'ro') {
|
||||
$link.attr('href', $link.attr('data-ro-href'));
|
||||
$link.text($link.attr('data-ro-text'));
|
||||
} else {
|
||||
$link.attr('href', $link.attr('data-en-href'));
|
||||
$link.text($link.attr('data-en-text'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function applyLanguage(lang) {
|
||||
var dict = translations[lang] || translations.en;
|
||||
|
||||
$('[data-i18n]').each(function () {
|
||||
var key = $(this).data('i18n');
|
||||
|
||||
if (!key) return;
|
||||
|
||||
// Handle special attributes like [placeholder]
|
||||
var match = key.match(/^\[(.*?)\](.*)$/);
|
||||
|
||||
if (match) {
|
||||
var attr = match[1]; // e.g. "placeholder"
|
||||
var realKey = match[2]; // e.g. "contact.form.message"
|
||||
|
||||
if (dict[realKey]) {
|
||||
$(this).attr(attr, dict[realKey]);
|
||||
}
|
||||
} else {
|
||||
if (dict[key]) {
|
||||
$(this).text(dict[key]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
updateLegalLinks(lang);
|
||||
|
||||
$('html').attr('lang', lang);
|
||||
localStorage.setItem('easysoft-language', lang);
|
||||
|
||||
$('.lang-flag').each(function () {
|
||||
var isActive = $(this).data('lang') === lang;
|
||||
$(this).attr('aria-pressed', isActive ? 'true' : 'false');
|
||||
$(this).toggleClass('is-active', isActive);
|
||||
});
|
||||
}
|
||||
|
||||
function detectLanguage() {
|
||||
var saved = localStorage.getItem('easysoft-language');
|
||||
if (saved && translations[saved]) {
|
||||
return saved;
|
||||
}
|
||||
|
||||
var browserLang = ((navigator.languages && navigator.languages[0]) || navigator.language || navigator.userLanguage || 'en').toLowerCase();
|
||||
if (browserLang.indexOf('ro') === 0) {
|
||||
return 'ro';
|
||||
}
|
||||
|
||||
return 'en';
|
||||
}
|
||||
|
||||
function closeMobileMenu() {
|
||||
$('#mainNav').removeClass('is-open');
|
||||
$('#menuToggle').attr('aria-expanded', 'false');
|
||||
}
|
||||
|
||||
function initCarousels() {
|
||||
$('[data-carousel]').each(function () {
|
||||
var $carousel = $(this);
|
||||
var $slides = $carousel.find('.carousel-slide');
|
||||
var $dotsWrap = $carousel.find('.carousel-dots');
|
||||
var index = 0;
|
||||
var timer = null;
|
||||
|
||||
function renderDots() {
|
||||
$dotsWrap.empty();
|
||||
$slides.each(function (i) {
|
||||
var $dot = $('<button>', {
|
||||
type: 'button',
|
||||
class: 'carousel-dot' + (i === index ? ' active' : ''),
|
||||
'aria-label': 'Go to slide ' + (i + 1)
|
||||
});
|
||||
$dot.on('click', function () {
|
||||
show(i);
|
||||
restartAutoPlay();
|
||||
});
|
||||
$dotsWrap.append($dot);
|
||||
});
|
||||
}
|
||||
|
||||
function show(i) {
|
||||
index = (i + $slides.length) % $slides.length;
|
||||
$slides.removeClass('active').eq(index).addClass('active');
|
||||
$dotsWrap.find('.carousel-dot').removeClass('active').eq(index).addClass('active');
|
||||
}
|
||||
|
||||
function restartAutoPlay() {
|
||||
if (timer) {
|
||||
window.clearInterval(timer);
|
||||
}
|
||||
timer = window.setInterval(function () {
|
||||
show(index + 1);
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
$carousel.find('.prev').on('click', function () {
|
||||
show(index - 1);
|
||||
restartAutoPlay();
|
||||
});
|
||||
|
||||
$carousel.find('.next').on('click', function () {
|
||||
show(index + 1);
|
||||
restartAutoPlay();
|
||||
});
|
||||
|
||||
renderDots();
|
||||
show(0);
|
||||
restartAutoPlay();
|
||||
});
|
||||
}
|
||||
|
||||
(function ($) {
|
||||
"use strict";
|
||||
var reCaptchaSiteKey; // To be initialized from the backend API
|
||||
var gTagManagerId; // Google Tag Manager ID from backend
|
||||
var gMapKey; // To be initialized from the backend API
|
||||
const CONSENT_KEY = "cookie_consent";
|
||||
|
||||
applyLanguage(detectLanguage());
|
||||
|
||||
$('.lang-flag').on('click', function () {
|
||||
applyLanguage($(this).data('lang'));
|
||||
});
|
||||
|
||||
$('#menuToggle').on('click', function () {
|
||||
var $nav = $('#mainNav');
|
||||
var open = !$nav.hasClass('is-open');
|
||||
$nav.toggleClass('is-open', open);
|
||||
$(this).attr('aria-expanded', open ? 'true' : 'false');
|
||||
});
|
||||
|
||||
$('.nav a').on('click', function () {
|
||||
closeMobileMenu();
|
||||
});
|
||||
|
||||
$('#year').text(new Date().getFullYear());
|
||||
|
||||
/*--------------------------
|
||||
API health check
|
||||
---------------------------- */
|
||||
// Checks the backend API live endpoint and updates #api-status if present.
|
||||
function checkApiLive() {
|
||||
var $statusEl = $('#api-status');
|
||||
return $.ajax({
|
||||
url: '/api/health/live',
|
||||
method: 'GET',
|
||||
dataType: 'json',
|
||||
timeout: 5000
|
||||
}).done(function (data) {
|
||||
var status = (data && data.status) ? data.status : 'unknown';
|
||||
if ($statusEl.length) {
|
||||
$statusEl.text('API: ' + status).removeClass('text-danger').addClass('text-success');
|
||||
} else {
|
||||
console.log('API live status:', status);
|
||||
}
|
||||
}).fail(function (jqXHR, textStatus, errorThrown) {
|
||||
if ($statusEl.length) {
|
||||
$statusEl.text('API: offline').removeClass('text-success').addClass('text-danger');
|
||||
}
|
||||
console.error('API health check failed:', textStatus, errorThrown);
|
||||
});
|
||||
}
|
||||
|
||||
/*--------------------------
|
||||
reCaptcha
|
||||
---------------------------- */
|
||||
function getRecaptchaWebKey() {
|
||||
return $.get("/api/contact", function (res) {
|
||||
reCaptchaSiteKey = res;
|
||||
if (reCaptchaSiteKey) {
|
||||
var script = document.createElement('script');
|
||||
script.setAttribute('src', "https://www.google.com/recaptcha/api.js?render=" + reCaptchaSiteKey);
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*--------------------------
|
||||
Google Tag Manager ID
|
||||
---------------------------- */
|
||||
function getGoogleTagManagerId() {
|
||||
return $.get("/api/google/tagmanager", function (res) {
|
||||
gTagManagerId = res;
|
||||
});
|
||||
}
|
||||
|
||||
/*--------------------------
|
||||
Google Maps Key
|
||||
---------------------------- */
|
||||
function getGMapKey() {
|
||||
return $.get("/api/google/maps", function (res) {
|
||||
gMapKey = res;
|
||||
if (gMapKey) {
|
||||
var script = document.createElement('script');
|
||||
script.setAttribute('src', "https://maps.googleapis.com/maps/api/js?key=" + gMapKey);
|
||||
document.body.appendChild(script);
|
||||
var script = document.createElement('script');
|
||||
script.setAttribute('src', "js/mapcode.js");
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*--------------------------
|
||||
Load Google Tag Manager script with the retrieved ID
|
||||
---------------------------- */
|
||||
function loadGoogleTagManager() {
|
||||
if (window.__gtm_loaded) return;
|
||||
|
||||
var script = document.createElement('script');
|
||||
script.async = true;
|
||||
script.src = "https://www.googletagmanager.com/gtm/js?id=" + gTagManagerId;
|
||||
document.head.appendChild(script);
|
||||
|
||||
// Initialize dataLayer
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
window.dataLayer.push({
|
||||
'gtm.start': new Date().getTime(),
|
||||
event: 'gtm.js'
|
||||
});
|
||||
}
|
||||
|
||||
/*--------------------------
|
||||
Load consent cookie data
|
||||
---------------------------- */
|
||||
function loadConsent() {
|
||||
var consent = getConsent();
|
||||
|
||||
if (!consent) {
|
||||
showBanner();
|
||||
} else {
|
||||
applyConsent(consent);
|
||||
showManage();
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------
|
||||
Preloader
|
||||
---------------------------- */
|
||||
$(window).on('load', async function () {
|
||||
var pre_loader = $('#preloader')
|
||||
try {
|
||||
await Promise.all([
|
||||
checkApiLive(),
|
||||
getRecaptchaWebKey(),
|
||||
getGoogleTagManagerId(),
|
||||
getGMapKey()
|
||||
]).then(loadConsent);
|
||||
|
||||
} catch (e) {
|
||||
console.error("Startup API error", e);
|
||||
}
|
||||
pre_loader.fadeOut('slow', function () {
|
||||
$(this).remove();
|
||||
});
|
||||
});
|
||||
|
||||
/*--------------------------
|
||||
contact-from
|
||||
---------------------------- */
|
||||
$("#contactForm").on("submit", function (event) {
|
||||
if (event.isDefaultPrevented()) {
|
||||
// handle the invalid form...
|
||||
formError();
|
||||
submitMSG(false, "Did you fill in the form properly?");
|
||||
} else {
|
||||
// everything looks good!
|
||||
event.preventDefault();
|
||||
submitForm();
|
||||
}
|
||||
});
|
||||
function submitForm() {
|
||||
var loader = $('#contactLoader')
|
||||
var button = $("#submit");
|
||||
|
||||
loader.css("display", "flex"); // show overlay
|
||||
button.prop("disabled", true);
|
||||
$("#msgSubmit").text("");
|
||||
grecaptcha.ready(function () {
|
||||
grecaptcha.execute(reCaptchaSiteKey, { action: 'contact' })
|
||||
.then(function (token) {
|
||||
// Initiate Variables With Form Content
|
||||
var message = {
|
||||
Name: $("#name").val(),
|
||||
Email: $("#email").val(),
|
||||
Subject: '[Contact request]',
|
||||
Message: $("#message").val(),
|
||||
CaptchaToken: token
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api/contact",
|
||||
data: JSON.stringify(message),
|
||||
contentType: "application/json; charset=utf-8",
|
||||
dataType: "json",
|
||||
success: function (resp) {
|
||||
if (resp && resp.ok === true) {
|
||||
formSuccess()
|
||||
} else {
|
||||
var dict = translations[detectLanguage()] || translations.en;
|
||||
submitMSG(false, dict['contact.form.verificationfailed']);
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
var dict = translations[detectLanguage()] || translations.en;
|
||||
submitMSG(false, dict['contact.form.submissionfailed']);
|
||||
}
|
||||
}).always(function () {
|
||||
loader.hide();
|
||||
button.prop("disabled", false);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function formSuccess() {
|
||||
$("#contactForm")[0].reset();
|
||||
var dict = translations[detectLanguage()] || translations.en;
|
||||
submitMSG(true, dict['contact.form.success'])
|
||||
}
|
||||
|
||||
function formError() {
|
||||
$("#contactForm").removeClass().addClass('shake animated').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
|
||||
$(this).removeClass();
|
||||
});
|
||||
}
|
||||
|
||||
function submitMSG(valid, msg) {
|
||||
if (valid) {
|
||||
var msgClasses = "text-center tada animated text-success";
|
||||
} else {
|
||||
var msgClasses = "text-center text-danger";
|
||||
}
|
||||
$("#msgSubmit").removeClass().addClass(msgClasses).text(msg);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------
|
||||
cookie consent
|
||||
---------------------------- */
|
||||
function getConsent() {
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem(CONSENT_KEY));
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function setConsent(consent) {
|
||||
localStorage.setItem(CONSENT_KEY, JSON.stringify(consent));
|
||||
}
|
||||
|
||||
function showBanner() { $("#cookieBanner").fadeIn(200); }
|
||||
function hideBanner() { $("#cookieBanner").fadeOut(200); }
|
||||
function showManage() { $("#cookieManage").show(); }
|
||||
function applyConsent(consent) {
|
||||
if (consent && consent.analytics === true) {
|
||||
loadGoogleTagManager();
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
$("#cookieReject, #cookieNecessary").on("click", function () {
|
||||
setConsent({ necessary: true, analytics: false, ts: new Date().toISOString() });
|
||||
hideBanner();
|
||||
showManage();
|
||||
location.reload(true);
|
||||
});
|
||||
|
||||
$("#cookieAccept").on("click", function () {
|
||||
setConsent({ necessary: true, analytics: true, ts: new Date().toISOString() });
|
||||
hideBanner();
|
||||
showManage();
|
||||
applyConsent(getConsent());
|
||||
location.reload(true);
|
||||
});
|
||||
|
||||
$("#cookieManage").on("click", function (e) {
|
||||
e.preventDefault();
|
||||
showBanner();
|
||||
});
|
||||
|
||||
initCarousels();
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,243 @@
|
||||
(function ($) {
|
||||
"use strict";
|
||||
|
||||
var reCaptchaSiteKey = null;
|
||||
var gTagManagerId = null;
|
||||
var CONSENT_KEY = "myai_cookie_consent";
|
||||
|
||||
$('#year').text(new Date().getFullYear());
|
||||
|
||||
$('#menuToggle').on('click', function () {
|
||||
var $nav = $('#mainNav');
|
||||
var open = !$nav.hasClass('is-open');
|
||||
$nav.toggleClass('is-open', open);
|
||||
$(this).attr('aria-expanded', open ? 'true' : 'false');
|
||||
});
|
||||
|
||||
$('.nav a').on('click', function () {
|
||||
$('#mainNav').removeClass('is-open');
|
||||
$('#menuToggle').attr('aria-expanded', 'false');
|
||||
});
|
||||
|
||||
function getRecaptchaWebKey() {
|
||||
return $.get('/api/contact').done(function (res) {
|
||||
reCaptchaSiteKey = res;
|
||||
if (reCaptchaSiteKey && !window.__recaptcha_loaded) {
|
||||
window.__recaptcha_loaded = true;
|
||||
var script = document.createElement('script');
|
||||
script.setAttribute('src', 'https://www.google.com/recaptcha/api.js?render=' + reCaptchaSiteKey);
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
}).fail(function () {
|
||||
console.warn('Could not load reCaptcha site key from /api/contact');
|
||||
});
|
||||
}
|
||||
|
||||
function getGoogleTagManagerId() {
|
||||
return $.get('/api/google/tagmanager').done(function (res) {
|
||||
gTagManagerId = res;
|
||||
}).fail(function () {
|
||||
console.warn('Could not load Google Tag Manager id from /api/google/tagmanager');
|
||||
});
|
||||
}
|
||||
|
||||
function loadGoogleTagManager() {
|
||||
if (window.__gtm_loaded || !gTagManagerId) return;
|
||||
window.__gtm_loaded = true;
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
window.dataLayer.push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
|
||||
var script = document.createElement('script');
|
||||
script.async = true;
|
||||
script.src = 'https://www.googletagmanager.com/gtm/js?id=' + gTagManagerId;
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
function getConsent() {
|
||||
try { return JSON.parse(localStorage.getItem(CONSENT_KEY)); } catch { return null; }
|
||||
}
|
||||
|
||||
function setConsent(consent) {
|
||||
localStorage.setItem(CONSENT_KEY, JSON.stringify(consent));
|
||||
}
|
||||
|
||||
function applyConsent(consent) {
|
||||
if (consent && consent.analytics === true) loadGoogleTagManager();
|
||||
}
|
||||
|
||||
function showBanner() { $('#cookieBanner').fadeIn(200); }
|
||||
function hideBanner() { $('#cookieBanner').fadeOut(200); }
|
||||
function showManage() { $('#cookieManage').show(); }
|
||||
|
||||
$('#cookieReject, #cookieNecessary').on('click', function () {
|
||||
setConsent({ necessary: true, analytics: false, ts: new Date().toISOString() });
|
||||
hideBanner();
|
||||
showManage();
|
||||
});
|
||||
|
||||
$('#cookieAccept').on('click', function () {
|
||||
var consent = { necessary: true, analytics: true, ts: new Date().toISOString() };
|
||||
setConsent(consent);
|
||||
applyConsent(consent);
|
||||
hideBanner();
|
||||
showManage();
|
||||
});
|
||||
|
||||
$('#cookieManage').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
showBanner();
|
||||
});
|
||||
|
||||
function initConsent() {
|
||||
var consent = getConsent();
|
||||
if (!consent) showBanner();
|
||||
else { applyConsent(consent); showManage(); }
|
||||
}
|
||||
|
||||
function submitMSG(valid, msg) {
|
||||
var msgClasses = valid ? 'form-message text-success' : 'form-message text-danger';
|
||||
$('#msgSubmit').removeClass().addClass(msgClasses).text(msg);
|
||||
}
|
||||
|
||||
function formSuccess() {
|
||||
$('#contactForm')[0].reset();
|
||||
submitMSG(true, 'Thank you for your message.');
|
||||
}
|
||||
|
||||
function formError() {
|
||||
$('#contactForm').removeClass().addClass('contact-form shake').one('animationend', function () {
|
||||
$(this).removeClass('shake');
|
||||
});
|
||||
}
|
||||
|
||||
$('#contactForm').on('submit', function (event) {
|
||||
event.preventDefault();
|
||||
var loader = $('#contactLoader');
|
||||
var button = $('#submit');
|
||||
loader.css('display', 'flex');
|
||||
button.prop('disabled', true);
|
||||
$('#msgSubmit').text('');
|
||||
|
||||
function postContact(token) {
|
||||
var message = {
|
||||
Name: $('#name').val(),
|
||||
Email: $('#email').val(),
|
||||
Subject: '[MyAi.ro contact request]',
|
||||
Message: $('#message').val(),
|
||||
CaptchaToken: token || ''
|
||||
};
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/api/contact',
|
||||
data: JSON.stringify(message),
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
dataType: 'json'
|
||||
}).done(function (resp) {
|
||||
if (resp && resp.ok === true) formSuccess();
|
||||
else submitMSG(false, 'Captcha verification failed.');
|
||||
}).fail(function () {
|
||||
submitMSG(false, 'Failed to send the message.');
|
||||
formError();
|
||||
}).always(function () {
|
||||
loader.hide();
|
||||
button.prop('disabled', false);
|
||||
});
|
||||
}
|
||||
|
||||
if (window.grecaptcha && reCaptchaSiteKey) {
|
||||
grecaptcha.ready(function () {
|
||||
grecaptcha.execute(reCaptchaSiteKey, { action: 'contact' }).then(postContact);
|
||||
});
|
||||
} else {
|
||||
postContact('');
|
||||
}
|
||||
});
|
||||
|
||||
$('#cvFile').on('change', function () {
|
||||
var file = this.files && this.files[0];
|
||||
$('#cvFileName').text(file ? file.name : 'PDF only, max size handled by backend');
|
||||
});
|
||||
|
||||
$('#cvMatcherForm').on('submit', async function (event) {
|
||||
event.preventDefault();
|
||||
var file = $('#cvFile')[0] && $('#cvFile')[0].files[0];
|
||||
var jobUrl = $('#jobUrl').val();
|
||||
var jobDescription = $('#jobDescription').val();
|
||||
var consent = $('#gdprConsent').is(':checked');
|
||||
var $msg = $('#matcherMsg');
|
||||
var $button = $('#matchSubmit');
|
||||
var $result = $('#matchResult');
|
||||
|
||||
if (!file) { $msg.removeClass().addClass('form-message text-danger').text('Please upload a CV PDF.'); return; }
|
||||
if (!jobUrl && !jobDescription) { $msg.removeClass().addClass('form-message text-danger').text('Add a job link or paste a job description.'); return; }
|
||||
if (!consent) { $msg.removeClass().addClass('form-message text-danger').text('GDPR consent is required.'); return; }
|
||||
|
||||
$button.prop('disabled', true).text('Processing...');
|
||||
$msg.removeClass().addClass('form-message').text('Extracting CV and matching job...');
|
||||
$result.html('<div class="empty-result">Processing CV PDF and job input. Backend endpoints must be available.</div>');
|
||||
|
||||
try {
|
||||
var formData = new FormData();
|
||||
formData.append('cv', file);
|
||||
formData.append('gdprConsent', String(consent));
|
||||
|
||||
var cvResponse = await fetch('/api/rag/cv', { method: 'POST', body: formData });
|
||||
if (!cvResponse.ok) throw new Error('CV extraction failed');
|
||||
var cvData = await cvResponse.json();
|
||||
|
||||
var matchResponse = await fetch('/api/rag/match-job', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
cvDocumentId: cvData.documentId || cvData.cvDocumentId,
|
||||
jobUrl: jobUrl,
|
||||
jobDescription: jobDescription,
|
||||
gdprConsent: consent
|
||||
})
|
||||
});
|
||||
if (!matchResponse.ok) throw new Error('Job matching failed');
|
||||
var match = await matchResponse.json();
|
||||
renderMatchResult(match);
|
||||
$msg.removeClass().addClass('form-message text-success').text('Match completed.');
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
$msg.removeClass().addClass('form-message text-danger').text(err.message || 'Failed to run the matcher.');
|
||||
$result.html('<div class="empty-result">The frontend is ready, but the backend endpoints /api/rag/cv and /api/rag/match-job must be implemented.</div>');
|
||||
} finally {
|
||||
$button.prop('disabled', false).text('Extract CV and match job');
|
||||
}
|
||||
});
|
||||
|
||||
function renderMatchResult(match) {
|
||||
var score = match.score || match.matchScore || 0;
|
||||
var summary = match.summary || 'No summary returned.';
|
||||
var strengths = match.strengths || [];
|
||||
var gaps = match.gaps || match.missingSkills || [];
|
||||
var evidence = match.evidence || match.retrievedChunks || [];
|
||||
|
||||
function list(items) {
|
||||
if (!items || !items.length) return '<p class="empty-result">No items returned.</p>';
|
||||
return '<ul class="result-list">' + items.map(function (x) {
|
||||
var text = typeof x === 'string' ? x : (x.text || x.title || JSON.stringify(x));
|
||||
return '<li>' + escapeHtml(text) + '</li>';
|
||||
}).join('') + '</ul>';
|
||||
}
|
||||
|
||||
$('#matchResult').html(
|
||||
'<div class="score-badge">' + Number(score).toFixed(0) + '%</div>' +
|
||||
'<p>' + escapeHtml(summary) + '</p>' +
|
||||
'<h3>Strengths</h3>' + list(strengths) +
|
||||
'<h3>Gaps</h3>' + list(gaps) +
|
||||
'<h3>Retrieved CV evidence</h3>' + list(evidence)
|
||||
);
|
||||
}
|
||||
|
||||
function escapeHtml(value) {
|
||||
return String(value).replace(/[&<>'"]/g, function (char) {
|
||||
return ({ '&': '&', '<': '<', '>': '>', "'": ''', '"': '"' })[char];
|
||||
});
|
||||
}
|
||||
|
||||
$(window).on('load', function () {
|
||||
$.when(getRecaptchaWebKey(), getGoogleTagManagerId()).always(initConsent);
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Cookies Policy - easySoft</title>
|
||||
<meta name="description" content="Information about how cookies are used on the easySoft website and how browser preferences can be managed.">
|
||||
<link rel="stylesheet" href="css/legal.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="easySoft home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="easySoft">
|
||||
</div>
|
||||
<div class="brand-copy">easySoft<small>Legal pages</small></div>
|
||||
</a>
|
||||
<div class="switcher">
|
||||
<a href="cookies-ro.html" class="lang-link " data-lang="ro" aria-label="Română">
|
||||
<img src="img/flags/ro.svg" alt="Română">
|
||||
</a>
|
||||
<a href="cookies-en.html" class="lang-link active" data-lang="en" aria-label="English">
|
||||
<img src="img/flags/en.svg" alt="English">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero">
|
||||
<div class="kicker">Cookies</div>
|
||||
<h1>Cookies Policy</h1>
|
||||
<p>Information about how cookies are used on the easySoft website and how browser preferences can be managed.</p>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
<div class="notice"><strong>Cookies Policy</strong> explains how easySoft uses cookies for website operation, analytics, and improving user experience.</div>
|
||||
|
||||
<h2>1. What cookies are</h2>
|
||||
<p>Cookies are small files stored on your device when you visit a website. They help the site function correctly and remember certain preferences.</p>
|
||||
|
||||
<h2>2. Types of cookies we may use</h2>
|
||||
<ul>
|
||||
<li><strong>Essential cookies</strong> – required for the basic operation of the website</li>
|
||||
<li><strong>Analytics cookies</strong> – used to understand how the website is used</li>
|
||||
<li><strong>Preference cookies</strong> – used to remember language or other selected options</li>
|
||||
<li><strong>Marketing cookies</strong> – only if explicitly enabled and used</li>
|
||||
</ul>
|
||||
|
||||
<h2>3. Why we use cookies</h2>
|
||||
<p>We use cookies for:</p>
|
||||
<ul>
|
||||
<li>ensuring technical operation of the website</li>
|
||||
<li>improving performance and usability</li>
|
||||
<li>remembering visitor settings</li>
|
||||
<li>aggregated statistical analysis</li>
|
||||
</ul>
|
||||
|
||||
<h2>4. Managing cookies</h2>
|
||||
<p>You can control or delete cookies from your browser settings. You can also block certain categories of cookies, but doing so may affect some parts of the website.</p>
|
||||
|
||||
<h2>5. Third-party cookies</h2>
|
||||
<p>Some services embedded on the website may set their own cookies, for example analytics services or external content. Those cookies are governed by the respective providers’ policies.</p>
|
||||
|
||||
<h2>6. Updates</h2>
|
||||
<p>This policy may be updated periodically. The current version will remain published on the website.</p>
|
||||
|
||||
<p class="meta">Last updated: 2026-03-26</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="footer">
|
||||
<small>©2026 easySoft. All rights reserved.</small>
|
||||
<div class="footer-links">
|
||||
<a href="terms-en.html">Terms and Conditions</a>
|
||||
<a href="privacy-en.html">Privacy Policy</a>
|
||||
<a href="cookies-en.html">Cookies Policy</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script src="js/legal.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ro">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Politica de COOKIES - easySoft</title>
|
||||
<meta name="description" content="Informații despre utilizarea cookies pe site-ul easySoft și despre gestionarea preferințelor browserului.">
|
||||
<link rel="stylesheet" href="css/legal.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="easySoft home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="easySoft">
|
||||
</div>
|
||||
<div class="brand-copy">easySoft<small>Pagini legale</small></div>
|
||||
</a>
|
||||
<div class="switcher">
|
||||
<a href="cookies-ro.html" class="lang-link active" data-lang="ro" aria-label="Română">
|
||||
<img src="img/flags/ro.svg" alt="Română">
|
||||
</a>
|
||||
<a href="cookies-en.html" class="lang-link " data-lang="en" aria-label="English">
|
||||
<img src="img/flags/en.svg" alt="English">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero">
|
||||
<div class="kicker">Cookies</div>
|
||||
<h1>Politica de COOKIES</h1>
|
||||
<p>Informații despre utilizarea cookies pe site-ul easySoft și despre gestionarea preferințelor browserului.</p>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
<div class="notice"><strong>Politica de COOKIES</strong> explică modul în care easySoft utilizează fișierele cookie pentru funcționarea site-ului, analiză și îmbunătățirea experienței utilizatorilor.</div>
|
||||
|
||||
<h2>1. Ce sunt cookies</h2>
|
||||
<p>Cookies sunt fișiere mici stocate pe dispozitivul dvs. atunci când vizitați un site. Acestea ajută la funcționarea corectă a site-ului și la memorarea anumitor preferințe.</p>
|
||||
|
||||
<h2>2. Ce tipuri de cookies putem folosi</h2>
|
||||
<ul>
|
||||
<li><strong>Cookies esențiale</strong> – necesare pentru funcționarea de bază a site-ului</li>
|
||||
<li><strong>Cookies de analiză</strong> – pentru a înțelege modul în care este utilizat site-ul</li>
|
||||
<li><strong>Cookies de preferințe</strong> – pentru memorarea limbii sau a altor opțiuni selectate</li>
|
||||
<li><strong>Cookies de marketing</strong> – doar dacă sunt activate și utilizate în mod expres</li>
|
||||
</ul>
|
||||
|
||||
<h2>3. Scopul utilizării</h2>
|
||||
<p>Folosim cookies pentru:</p>
|
||||
<ul>
|
||||
<li>asigurarea funcționării tehnice a site-ului</li>
|
||||
<li>îmbunătățirea performanței și utilizabilității</li>
|
||||
<li>memorarea setărilor vizitatorilor</li>
|
||||
<li>analiză statistică agregată</li>
|
||||
</ul>
|
||||
|
||||
<h2>4. Gestionarea cookies</h2>
|
||||
<p>Puteți controla sau șterge cookies din setările browserului. De asemenea, puteți bloca anumite categorii de cookies, însă acest lucru poate afecta funcționarea unor secțiuni ale site-ului.</p>
|
||||
|
||||
<h2>5. Cookies terțe părți</h2>
|
||||
<p>Unele servicii integrate în site pot seta propriile cookies, de exemplu servicii de analiză sau conținut extern. Acestea sunt guvernate de politicile respectivilor furnizori.</p>
|
||||
|
||||
<h2>6. Actualizări</h2>
|
||||
<p>Această politică poate fi actualizată periodic. Versiunea curentă va fi publicată permanent pe site.</p>
|
||||
|
||||
<p class="meta">Ultima actualizare: 2026-03-26</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="footer">
|
||||
<small>©2026 easySoft. Toate drepturile sunt rezervate.</small>
|
||||
<div class="footer-links">
|
||||
<a href="terms-ro.html">Termeni și condiții</a>
|
||||
<a href="privacy-ro.html">Politica de confidențialitate</a>
|
||||
<a href="cookies-ro.html">Politica de COOKIES</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script src="js/legal.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,86 @@
|
||||
|
||||
:root{
|
||||
--bg:#07192f;
|
||||
--bg2:#0a2441;
|
||||
--card:#0e1f37;
|
||||
--text:#eaf2ff;
|
||||
--muted:#b4c5dd;
|
||||
--line:rgba(255,255,255,.10);
|
||||
--accent:#7eb7ff;
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
body{
|
||||
margin:0;
|
||||
font-family:Arial,Helvetica,sans-serif;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(79,140,255,.18), transparent 28%),
|
||||
linear-gradient(180deg, var(--bg) 0%, #05111f 100%);
|
||||
color:var(--text);
|
||||
line-height:1.75;
|
||||
}
|
||||
a{color:var(--accent);text-decoration:none}
|
||||
a:hover{text-decoration:none}
|
||||
.wrap{max-width:1100px;margin:0 auto;padding:28px 20px 60px}
|
||||
.topbar{
|
||||
display:flex;justify-content:space-between;align-items:center;gap:16px;
|
||||
padding:10px 0 22px;margin-bottom:24px;border-bottom:1px solid var(--line);
|
||||
}
|
||||
.brand{display:flex;align-items:center;gap:14px;}
|
||||
.brand-badge {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.brand-badge img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.brand-copy small{display:block;color:var(--muted);font-weight:400}
|
||||
.switcher{display:flex;align-items:center;gap:10px}
|
||||
.switcher a{
|
||||
display:inline-flex;align-items:center;justify-content:center;
|
||||
width:44px;height:44px;border-radius:999px;border:1px solid var(--line);
|
||||
background:rgba(255,255,255,.04);transition:.2s ease;
|
||||
}
|
||||
.switcher a:hover{text-decoration:none;transform:translateY(-1px)}
|
||||
.switcher a.active{border-color:rgba(126,183,255,.65);box-shadow:0 0 0 3px rgba(126,183,255,.13)}
|
||||
.switcher img{width:24px;height:24px;display:block}
|
||||
.hero,.content,.footer{
|
||||
background:linear-gradient(180deg, rgba(255,255,255,.03), rgba(255,255,255,.02));
|
||||
border:1px solid var(--line);
|
||||
border-radius:22px;
|
||||
box-shadow:0 25px 60px rgba(0,0,0,.18);
|
||||
}
|
||||
.hero{padding:28px 30px;margin-bottom:18px}
|
||||
.kicker{
|
||||
display:inline-block;padding:8px 12px;border-radius:999px;
|
||||
background:rgba(255,255,255,.04);border:1px solid var(--line);color:var(--muted);
|
||||
font-size:13px;margin-bottom:12px
|
||||
}
|
||||
.hero h1{margin:0 0 8px;font-size:40px;line-height:1.08}
|
||||
.hero p{margin:0;color:var(--muted);max-width:780px}
|
||||
.content{padding:30px}
|
||||
.content h2{font-size:28px;line-height:1.15;margin:28px 0 10px}
|
||||
.content h2:first-child{margin-top:0}
|
||||
.content p{margin:0 0 14px;color:#deebff}
|
||||
.content ul{margin:0 0 18px 22px;padding:0}
|
||||
.content li{margin-bottom:8px;color:#deebff}
|
||||
.notice{
|
||||
margin:16px 0 18px;padding:16px 18px;border-radius:18px;
|
||||
background:rgba(126,183,255,.08);border:1px solid rgba(126,183,255,.18)
|
||||
}
|
||||
.footer{
|
||||
margin-top:18px;padding:22px 26px;display:flex;justify-content:space-between;gap:16px;align-items:center;flex-wrap:wrap
|
||||
}
|
||||
.footer-links{display:flex;gap:18px;flex-wrap:wrap}
|
||||
.footer small{color:var(--muted)}
|
||||
.meta{color:var(--muted);font-size:14px}
|
||||
@media (max-width:768px){
|
||||
.hero h1{font-size:32px}
|
||||
.content{padding:22px}
|
||||
.content h2{font-size:24px}
|
||||
.topbar{align-items:flex-start;flex-direction:column}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 30"><clipPath id="a"><path d="M0,0 v30 h60 v-30 z"/></clipPath><clipPath id="b"><path d="M30,15 h30 v15 z v15 h-30 z h-30 v-15 z v-15 h30 z"/></clipPath><g clip-path="url(#a)"><path d="M0,0 v30 h60 v-30 z" fill="#012169"/><path d="M0,0 60,30 M60,0 0,30" stroke="#fff" stroke-width="6"/><path d="M0,0 60,30 M60,0 0,30" clip-path="url(#b)" stroke="#C8102E" stroke-width="4"/><path d="M30,0 v30 M0,15 h60" stroke="#fff" stroke-width="10"/><path d="M30,0 v30 M0,15 h60" stroke="#C8102E" stroke-width="6"/></g></svg>
|
||||
|
After Width: | Height: | Size: 567 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3 2"><rect width="1" height="2" fill="#002B7F"/><rect x="1" width="1" height="2" fill="#FCD116"/><rect x="2" width="1" height="2" fill="#CE1126"/></svg>
|
||||
|
After Width: | Height: | Size: 205 B |
@@ -0,0 +1,23 @@
|
||||
|
||||
(function(){
|
||||
function browserLang(){
|
||||
var lang = (navigator.language || navigator.userLanguage || 'en').toLowerCase();
|
||||
return lang.indexOf('ro') === 0 ? 'ro' : 'en';
|
||||
}
|
||||
function targetPage(current, lang){
|
||||
if(current.indexOf('-ro.html') !== -1) return current.replace('-ro.html', '-' + lang + '.html');
|
||||
if(current.indexOf('-en.html') !== -1) return current.replace('-en.html', '-' + lang + '.html');
|
||||
return current;
|
||||
}
|
||||
var links = document.querySelectorAll('.lang-link');
|
||||
for(var i=0;i<links.length;i++){
|
||||
links[i].addEventListener('click', function(e){
|
||||
e.preventDefault();
|
||||
localStorage.setItem('legalLang', this.getAttribute('data-lang'));
|
||||
window.location.href = targetPage(window.location.pathname, this.getAttribute('data-lang'));
|
||||
});
|
||||
}
|
||||
if(!localStorage.getItem('legalLang')){
|
||||
localStorage.setItem('legalLang', browserLang());
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,123 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Privacy Policy - easySoft</title>
|
||||
<meta name="description" content="Information about the collection, use, and protection of personal data by easySoft.">
|
||||
<link rel="stylesheet" href="css/legal.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="easySoft home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="easySoft">
|
||||
</div>
|
||||
<div class="brand-copy">easySoft<small>Legal pages</small></div>
|
||||
</a>
|
||||
<div class="switcher">
|
||||
<a href="privacy-ro.html" class="lang-link " data-lang="ro" aria-label="Română">
|
||||
<img src="img/flags/ro.svg" alt="Română">
|
||||
</a>
|
||||
<a href="privacy-en.html" class="lang-link active" data-lang="en" aria-label="English">
|
||||
<img src="img/flags/en.svg" alt="English">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero">
|
||||
<div class="kicker">Data protection</div>
|
||||
<h1>Privacy Policy</h1>
|
||||
<p>Information about the collection, use, and protection of personal data by easySoft.</p>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
<div class="notice"><strong>easySoft</strong> respects the confidentiality of personal data and is committed to protecting the information of clients, partners, and website visitors.</div>
|
||||
|
||||
<h2>1. Who we are</h2>
|
||||
<p>easySoft</p>
|
||||
<p>Email: <a href="mailto:contact@easysoft.ro">contact@easysoft.ro</a><br>Website: <a href="https://easysoft.ro">easysoft.ro</a></p>
|
||||
<p>This document explains how we collect, use, and protect your personal data.</p>
|
||||
|
||||
<h2>2. What data we collect</h2>
|
||||
<p>We may collect the following types of data:</p>
|
||||
<ul>
|
||||
<li>Contact details such as name, email address, and phone number</li>
|
||||
<li>Data submitted voluntarily through forms, including messages, requests, and quote inquiries</li>
|
||||
<li>Technical data such as IP address, browser type, cookies, and visited pages</li>
|
||||
<li>Data needed in the contractual relationship, if you are a client</li>
|
||||
</ul>
|
||||
|
||||
<h2>3. Purpose of processing</h2>
|
||||
<p>Your data may be processed for:</p>
|
||||
<ul>
|
||||
<li>answering requests and direct communication</li>
|
||||
<li>providing our services</li>
|
||||
<li>improving website functionality</li>
|
||||
<li>marketing, only with consent</li>
|
||||
<li>meeting legal and accounting obligations</li>
|
||||
</ul>
|
||||
|
||||
<h2>4. Legal basis</h2>
|
||||
<p>We process data under Article 6 GDPR based on:</p>
|
||||
<ul>
|
||||
<li>the data subject’s consent</li>
|
||||
<li>performance of a contract</li>
|
||||
<li>legal obligation</li>
|
||||
<li>legitimate interest</li>
|
||||
</ul>
|
||||
|
||||
<h2>5. Data retention</h2>
|
||||
<p>We keep personal data only for as long as necessary for the purposes for which it was collected or as required by law.</p>
|
||||
|
||||
<h2>6. Data disclosure</h2>
|
||||
<p>Data may be disclosed only to:</p>
|
||||
<ul>
|
||||
<li>IT or hosting providers</li>
|
||||
<li>contractual partners involved in service delivery</li>
|
||||
<li>public authorities, only where required by law</li>
|
||||
</ul>
|
||||
<p>We do not sell or transfer data to third parties for commercial purposes.</p>
|
||||
|
||||
<h2>7. Your rights under GDPR</h2>
|
||||
<p>You have the right to:</p>
|
||||
<ul>
|
||||
<li>access</li>
|
||||
<li>rectification</li>
|
||||
<li>erasure (“right to be forgotten”)</li>
|
||||
<li>restriction</li>
|
||||
<li>objection</li>
|
||||
<li>data portability</li>
|
||||
<li>withdrawal of consent</li>
|
||||
</ul>
|
||||
<p>Requests can be sent to: <a href="mailto:contact@easysoft.ro">contact@easysoft.ro</a>.</p>
|
||||
|
||||
<h2>8. Data security</h2>
|
||||
<p>We implement appropriate technical and organizational measures to protect data against unauthorized access, loss, or disclosure.</p>
|
||||
|
||||
<h2>9. Transfers outside the EU</h2>
|
||||
<p>We normally do not transfer data outside the EU. If this becomes necessary, appropriate safeguards will be used, including Standard Contractual Clauses.</p>
|
||||
|
||||
<h2>10. Policy updates</h2>
|
||||
<p>We reserve the right to update this policy. The latest version will remain permanently available on the website.</p>
|
||||
|
||||
<p class="meta">Last updated: 2026-03-26</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="footer">
|
||||
<small>©2026 easySoft. All rights reserved.</small>
|
||||
<div class="footer-links">
|
||||
<a href="terms-en.html">Terms and Conditions</a>
|
||||
<a href="privacy-en.html">Privacy Policy</a>
|
||||
<a href="cookies-en.html">Cookies Policy</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script src="js/legal.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,123 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ro">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Politica de confidențialitate - easySoft</title>
|
||||
<meta name="description" content="Informații despre colectarea, utilizarea și protejarea datelor cu caracter personal de către easySoft.">
|
||||
<link rel="stylesheet" href="css/legal.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="easySoft home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="easySoft">
|
||||
</div>
|
||||
<div class="brand-copy">easySoft<small>Pagini legale</small></div>
|
||||
</a>
|
||||
<div class="switcher">
|
||||
<a href="privacy-ro.html" class="lang-link active" data-lang="ro" aria-label="Română">
|
||||
<img src="img/flags/ro.svg" alt="Română">
|
||||
</a>
|
||||
<a href="privacy-en.html" class="lang-link " data-lang="en" aria-label="English">
|
||||
<img src="img/flags/en.svg" alt="English">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero">
|
||||
<div class="kicker">Protecția datelor</div>
|
||||
<h1>Politica de confidențialitate</h1>
|
||||
<p>Informații despre colectarea, utilizarea și protejarea datelor cu caracter personal de către easySoft.</p>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
<div class="notice"><strong>easySoft</strong> respectă confidențialitatea datelor cu caracter personal și se angajează să protejeze informațiile clienților, partenerilor și vizitatorilor site-ului nostru.</div>
|
||||
|
||||
<h2>1. Cine suntem</h2>
|
||||
<p>easySoft</p>
|
||||
<p>Email: <a href="mailto:contact@easysoft.ro">contact@easysoft.ro</a><br>Website: <a href="https://easysoft.ro">easysoft.ro</a></p>
|
||||
<p>Acest document explică modul în care colectăm, utilizăm și protejăm datele dvs. personale.</p>
|
||||
|
||||
<h2>2. Ce date colectăm</h2>
|
||||
<p>Putem colecta următoarele tipuri de date:</p>
|
||||
<ul>
|
||||
<li>Date de contact (nume, email, telefon)</li>
|
||||
<li>Date furnizate voluntar prin formulare (mesaje, solicitări, cereri de ofertă)</li>
|
||||
<li>Date tehnice (IP, browser, cookies, pagini accesate)</li>
|
||||
<li>Date necesare în relația contractuală (doar dacă sunteți client)</li>
|
||||
</ul>
|
||||
|
||||
<h2>3. Scopurile procesării</h2>
|
||||
<p>Datele sunt prelucrate pentru:</p>
|
||||
<ul>
|
||||
<li>răspuns la solicitări și comunicare directă</li>
|
||||
<li>furnizarea serviciilor noastre</li>
|
||||
<li>îmbunătățirea funcționalității site-ului</li>
|
||||
<li>marketing (numai cu acord)</li>
|
||||
<li>respectarea obligațiilor legale și contabile</li>
|
||||
</ul>
|
||||
|
||||
<h2>4. Temeiul legal</h2>
|
||||
<p>Procesăm datele conform art. 6 GDPR:</p>
|
||||
<ul>
|
||||
<li>consimțământul persoanei vizate</li>
|
||||
<li>executarea unui contract</li>
|
||||
<li>obligație legală</li>
|
||||
<li>interes legitim</li>
|
||||
</ul>
|
||||
|
||||
<h2>5. Stocarea datelor</h2>
|
||||
<p>Păstrăm datele doar atât timp cât este necesar pentru scopurile pentru care au fost colectate sau conform obligațiilor legale.</p>
|
||||
|
||||
<h2>6. Dezvăluirea datelor</h2>
|
||||
<p>Datele pot fi transmise doar către:</p>
|
||||
<ul>
|
||||
<li>furnizori IT sau hosting</li>
|
||||
<li>parteneri contractuali implicați în furnizarea serviciilor</li>
|
||||
<li>autorități, numai dacă legea o impune</li>
|
||||
</ul>
|
||||
<p>Nu vindem și nu înstrăinăm datele către terți în scopuri comerciale.</p>
|
||||
|
||||
<h2>7. Drepturile dvs. (GDPR)</h2>
|
||||
<p>Aveți dreptul:</p>
|
||||
<ul>
|
||||
<li>de acces</li>
|
||||
<li>rectificare</li>
|
||||
<li>ștergere (“dreptul de a fi uitat”)</li>
|
||||
<li>restricționare</li>
|
||||
<li>opoziție</li>
|
||||
<li>portabilitate</li>
|
||||
<li>retragerea consimțământului</li>
|
||||
</ul>
|
||||
<p>Solicitările se trimit la: <a href="mailto:contact@easysoft.ro">contact@easysoft.ro</a>.</p>
|
||||
|
||||
<h2>8. Securitatea datelor</h2>
|
||||
<p>Implementăm măsuri tehnice și organizatorice adecvate pentru protejarea datelor împotriva accesului neautorizat, pierderii sau divulgării.</p>
|
||||
|
||||
<h2>9. Transferul datelor în afara UE</h2>
|
||||
<p>În mod normal nu transferăm date în afara UE. Dacă acest lucru devine necesar, vor fi folosite garanții adecvate (Clauze Contractuale Standard).</p>
|
||||
|
||||
<h2>10. Modificări ale politicii</h2>
|
||||
<p>Ne rezervăm dreptul de a actualiza această politică. Ultima versiune va fi afișată permanent pe site.</p>
|
||||
|
||||
<p class="meta">Ultima actualizare: 2026-03-26</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="footer">
|
||||
<small>©2026 easySoft. Toate drepturile sunt rezervate.</small>
|
||||
<div class="footer-links">
|
||||
<a href="terms-ro.html">Termeni și condiții</a>
|
||||
<a href="privacy-ro.html">Politica de confidențialitate</a>
|
||||
<a href="cookies-ro.html">Politica de COOKIES</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script src="js/legal.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Terms and Conditions - easySoft</title>
|
||||
<meta name="description" content="Rules for using the easySoft website and the general conditions applicable to the published content and materials.">
|
||||
<link rel="stylesheet" href="css/legal.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="easySoft home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="easySoft">
|
||||
</div>
|
||||
<div class="brand-copy">easySoft<small>Legal pages</small></div>
|
||||
</a>
|
||||
<div class="switcher">
|
||||
<a href="terms-ro.html" class="lang-link " data-lang="ro" aria-label="Română">
|
||||
<img src="img/flags/ro.svg" alt="Română">
|
||||
</a>
|
||||
<a href="terms-en.html" class="lang-link active" data-lang="en" aria-label="English">
|
||||
<img src="img/flags/en.svg" alt="English">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero">
|
||||
<div class="kicker">Terms of use</div>
|
||||
<h1>Terms and Conditions</h1>
|
||||
<p>Rules for using the easySoft website and the general conditions applicable to the published content and materials.</p>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
<div class="notice"><strong>Terms and Conditions</strong> govern the use of the easySoft website and the way users may access the information and materials published on it.</div>
|
||||
|
||||
<h2>1. General information</h2>
|
||||
<p>The easySoft website is operated to present the software products and services offered, including applications for dental offices, inventory management, and backup.</p>
|
||||
|
||||
<h2>2. Acceptance of terms</h2>
|
||||
<p>By accessing and using this website, you accept these terms of use. If you do not agree, please do not use the website.</p>
|
||||
|
||||
<h2>3. Use of content</h2>
|
||||
<p>The website content is provided for informational and commercial purposes only. Copying, distributing, modifying, or republishing content without prior approval is not permitted.</p>
|
||||
|
||||
<h2>4. Intellectual property</h2>
|
||||
<p>Texts, images, graphic elements, logos, and the website structure belong to easySoft or are used under lawful rights. All rights are reserved.</p>
|
||||
|
||||
<h2>5. Limitation of liability</h2>
|
||||
<p>We make efforts to keep information accurate and up to date, but we do not guarantee that the website is free of errors or interruptions. Use of the information is at your own risk.</p>
|
||||
|
||||
<h2>6. External links</h2>
|
||||
<p>The website may contain links to third-party websites. We are not responsible for the content or policies of those external websites.</p>
|
||||
|
||||
<h2>7. Data protection</h2>
|
||||
<p>Processing of personal data is described in the <a href="privacy-en.html">Privacy Policy</a>, and the use of cookies is explained in the <a href="cookies-en.html">Cookies Policy</a>.</p>
|
||||
|
||||
<h2>8. Changes</h2>
|
||||
<p>We reserve the right to modify these terms at any time. The updated version will be published on the website.</p>
|
||||
|
||||
<h2>9. Governing law</h2>
|
||||
<p>These terms are governed by the laws of Romania. Any disputes will be settled by the competent courts in Romania.</p>
|
||||
|
||||
<p class="meta">Last updated: 2026-03-26</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="footer">
|
||||
<small>©2026 easySoft. All rights reserved.</small>
|
||||
<div class="footer-links">
|
||||
<a href="terms-en.html">Terms and Conditions</a>
|
||||
<a href="privacy-en.html">Privacy Policy</a>
|
||||
<a href="cookies-en.html">Cookies Policy</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script src="js/legal.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ro">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Termeni și condiții - easySoft</title>
|
||||
<meta name="description" content="Regulile de utilizare a site-ului easySoft și condițiile generale aplicabile conținutului și materialelor publicate.">
|
||||
<link rel="stylesheet" href="css/legal.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="easySoft home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="easySoft">
|
||||
</div>
|
||||
<div class="brand-copy">easySoft<small>Pagini legale</small></div>
|
||||
</a>
|
||||
<div class="switcher">
|
||||
<a href="terms-ro.html" class="lang-link active" data-lang="ro" aria-label="Română">
|
||||
<img src="img/flags/ro.svg" alt="Română">
|
||||
</a>
|
||||
<a href="terms-en.html" class="lang-link " data-lang="en" aria-label="English">
|
||||
<img src="img/flags/en.svg" alt="English">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero">
|
||||
<div class="kicker">Condiții de utilizare</div>
|
||||
<h1>Termeni și condiții</h1>
|
||||
<p>Regulile de utilizare a site-ului easySoft și condițiile generale aplicabile conținutului și materialelor publicate.</p>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
|
||||
<div class="notice"><strong>Termenii și condițiile</strong> reglementează utilizarea site-ului easySoft și modul în care utilizatorii pot accesa informațiile și materialele publicate.</div>
|
||||
|
||||
<h2>1. Informații generale</h2>
|
||||
<p>Site-ul easySoft este operat pentru prezentarea produselor și serviciilor software oferite, inclusiv aplicații pentru cabinete dentare, gestiune și backup.</p>
|
||||
|
||||
<h2>2. Acceptarea termenilor</h2>
|
||||
<p>Prin accesarea și utilizarea acestui site, acceptați prezentele condiții de utilizare. Dacă nu sunteți de acord cu acestea, vă rugăm să nu utilizați site-ul.</p>
|
||||
|
||||
<h2>3. Utilizarea conținutului</h2>
|
||||
<p>Conținutul site-ului este furnizat exclusiv în scop informativ și comercial. Nu este permisă copierea, distribuirea, modificarea sau republicarea conținutului fără acordul prealabil al operatorului site-ului.</p>
|
||||
|
||||
<h2>4. Proprietate intelectuală</h2>
|
||||
<p>Textele, imaginile, elementele grafice, logo-urile și structura site-ului aparțin easySoft sau sunt utilizate în baza unor drepturi legale. Toate drepturile sunt rezervate.</p>
|
||||
|
||||
<h2>5. Limitarea răspunderii</h2>
|
||||
<p>Depunem eforturi pentru a menține informațiile corecte și actualizate, însă nu garantăm că site-ul este lipsit de erori sau întreruperi. Utilizarea informațiilor se face pe propria răspundere.</p>
|
||||
|
||||
<h2>6. Linkuri externe</h2>
|
||||
<p>Site-ul poate conține linkuri către site-uri terțe. Nu suntem responsabili pentru conținutul sau politicile acestor site-uri externe.</p>
|
||||
|
||||
<h2>7. Protecția datelor</h2>
|
||||
<p>Prelucrarea datelor cu caracter personal este descrisă în <a href="privacy-ro.html">Politica de confidențialitate</a>, iar utilizarea cookies este explicată în <a href="cookies-ro.html">Politica de COOKIES</a>.</p>
|
||||
|
||||
<h2>8. Modificări</h2>
|
||||
<p>Ne rezervăm dreptul de a modifica acești termeni în orice moment. Versiunea actualizată va fi publicată pe site.</p>
|
||||
|
||||
<h2>9. Legea aplicabilă</h2>
|
||||
<p>Acești termeni sunt guvernați de legislația din România. Eventualele litigii vor fi soluționate de instanțele competente din România.</p>
|
||||
|
||||
<p class="meta">Ultima actualizare: 2026-03-26</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="footer">
|
||||
<small>©2026 easySoft. Toate drepturile sunt rezervate.</small>
|
||||
<div class="footer-links">
|
||||
<a href="terms-ro.html">Termeni și condiții</a>
|
||||
<a href="privacy-ro.html">Politica de confidențialitate</a>
|
||||
<a href="cookies-ro.html">Politica de COOKIES</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script src="js/legal.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="bgGrad" x1="180" y1="120" x2="860" y2="900" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#FF7A7A"/>
|
||||
<stop offset="0.38" stop-color="#F04444"/>
|
||||
<stop offset="1" stop-color="#9F1239"/>
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="glassGrad" x1="250" y1="160" x2="610" y2="430" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#FFFFFF" stop-opacity="0.38"/>
|
||||
<stop offset="1" stop-color="#FFFFFF" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="shadowGrad" x1="280" y1="250" x2="760" y2="760" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#000000" stop-opacity="0"/>
|
||||
<stop offset="1" stop-color="#4A0417" stop-opacity="0.32"/>
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="letterGrad" x1="310" y1="330" x2="760" y2="710" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#FFFFFF"/>
|
||||
<stop offset="1" stop-color="#FDECEC"/>
|
||||
</linearGradient>
|
||||
|
||||
<filter id="outerShadow" x="120" y="120" width="784" height="784" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feDropShadow dx="0" dy="18" stdDeviation="28" flood-color="#4A0417" flood-opacity="0.28"/>
|
||||
</filter>
|
||||
|
||||
<filter id="letterShadow" x="220" y="220" width="584" height="584" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feDropShadow dx="0" dy="10" stdDeviation="12" flood-color="#5A1022" flood-opacity="0.18"/>
|
||||
</filter>
|
||||
|
||||
<clipPath id="rounded">
|
||||
<rect x="170" y="150" width="684" height="684" rx="170"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<g filter="url(#outerShadow)">
|
||||
<rect x="170" y="150" width="684" height="684" rx="170" fill="url(#bgGrad)"/>
|
||||
<rect x="171.5" y="151.5" width="681" height="681" rx="168.5" stroke="rgba(255,255,255,0.14)" stroke-opacity="0.18" />
|
||||
</g>
|
||||
|
||||
<g clip-path="url(#rounded)">
|
||||
<path d="M215 250C300 175 425 150 555 150H854V834H765C558 834 365 756 250 620C158 510 140 354 215 250Z" fill="url(#shadowGrad)"/>
|
||||
<path d="M230 208C315 148 430 130 560 130H800C725 232 605 300 465 300H220C217 267 219 236 230 208Z" fill="url(#glassGrad)"/>
|
||||
</g>
|
||||
|
||||
<g filter="url(#letterShadow)">
|
||||
<!-- Premium stylized E -->
|
||||
<path d="M382 328H713C732 328 741 351 726 365L679 410C668 420 654 425 640 425H453L382 328Z" fill="url(#letterGrad)"/>
|
||||
<path d="M331 430H657C676 430 685 452 671 467L626 512C615 523 601 529 586 529H403L331 430Z" fill="url(#letterGrad)"/>
|
||||
<path d="M298 575H618C638 575 646 599 632 613L590 654C579 665 564 671 549 671H370L298 575Z" fill="url(#letterGrad)"/>
|
||||
<!-- subtle base cuts -->
|
||||
<path d="M382 328L453 425H415L344 425L382 328Z" fill="#F3DADA" fill-opacity="0.7"/>
|
||||
<path d="M331 430L403 529H365L293 529L331 430Z" fill="#F3DADA" fill-opacity="0.7"/>
|
||||
<path d="M298 575L370 671H332L260 671L298 575Z" fill="#F3DADA" fill-opacity="0.7"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,784 @@
|
||||
:root {
|
||||
--bg: #041120;
|
||||
--bg-soft: #0a1c34;
|
||||
--panel: rgba(10, 22, 42, 0.82);
|
||||
--panel-border: rgba(255, 255, 255, 0.1);
|
||||
--text: #eaf1ff;
|
||||
--muted: #9bb0d0;
|
||||
--primary: #5fa0ff;
|
||||
--primary-strong: #8b6cff;
|
||||
--card-radius: 28px;
|
||||
--shadow: 0 18px 60px rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: radial-gradient(circle at top left, #12345d 0%, #071326 35%, #030915 100%);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 1120px;
|
||||
margin: 0 auto;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.site-shell {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 20;
|
||||
background: rgba(3, 11, 23, 0.76);
|
||||
backdrop-filter: blur(16px);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.nav-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
min-height: 84px;
|
||||
}
|
||||
|
||||
.brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.brand-mark {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.brand-mark img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.brand-text {
|
||||
display: block;
|
||||
font-size: 1.7rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.brand small {
|
||||
display: block;
|
||||
color: var(--muted);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.nav a {
|
||||
color: #d7e3fb;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.nav a:hover {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.nav-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.lang-switch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 6px;
|
||||
border-radius: 18px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.lang-flag {
|
||||
width: 48px;
|
||||
height: 34px;
|
||||
padding: 3px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 12px;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease, opacity 0.2s ease;
|
||||
opacity: 0.82;
|
||||
}
|
||||
|
||||
.lang-flag img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
.lang-flag:hover {
|
||||
opacity: 1;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.lang-flag[aria-pressed="true"] {
|
||||
opacity: 1;
|
||||
border-color: rgba(95, 160, 255, 0.65);
|
||||
background: rgba(95, 160, 255, 0.08);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 0 0 1px rgba(95, 160, 255, 0.12);
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
display: none;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.menu-toggle span {
|
||||
display: block;
|
||||
width: 24px;
|
||||
height: 2px;
|
||||
background: #ffffff;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.hero {
|
||||
padding: 72px 0 48px;
|
||||
}
|
||||
|
||||
.hero-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1.05fr 0.95fr;
|
||||
gap: 42px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
display: inline-flex;
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border-radius: 999px;
|
||||
padding: 8px 14px;
|
||||
color: #bfd1f0;
|
||||
font-size: 0.92rem;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: clamp(2.8rem, 6vw, 5.8rem);
|
||||
line-height: 0.95;
|
||||
margin: 0 0 20px;
|
||||
letter-spacing: -0.06em;
|
||||
}
|
||||
|
||||
.hero-text {
|
||||
font-size: 1.14rem;
|
||||
line-height: 1.7;
|
||||
color: var(--muted);
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
.hero-actions,
|
||||
.product-actions {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 28px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 999px;
|
||||
padding: 14px 22px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 700;
|
||||
transition: 0.2s ease;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, var(--primary), #7ac4ff);
|
||||
color: #071326;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.product-actions .btn {
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.hero-metrics {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 14px;
|
||||
margin-top: 28px;
|
||||
}
|
||||
|
||||
.hero-metrics div,
|
||||
.hero-badge,
|
||||
.service-card,
|
||||
.about-panel,
|
||||
.contact-form,
|
||||
.contact-list > div {
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--panel-border);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.hero-metrics div {
|
||||
border-radius: 22px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.hero-metrics strong {
|
||||
display: block;
|
||||
font-size: 1.7rem;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.hero-metrics span {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.hero-card-inner {
|
||||
position: relative;
|
||||
min-height: 640px;
|
||||
border-radius: 34px;
|
||||
padding: 28px;
|
||||
background: linear-gradient(180deg, rgba(18, 35, 66, 0.95), rgba(10, 20, 39, 0.9));
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.hero-card-label {
|
||||
margin: 0 0 14px;
|
||||
color: #d8e5ff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hero-main-shot {
|
||||
width: 78%;
|
||||
border-radius: 24px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.14);
|
||||
margin-top: 38px;
|
||||
box-shadow: 0 18px 50px rgba(0, 0, 0, 0.36);
|
||||
}
|
||||
|
||||
.hero-floating {
|
||||
position: absolute;
|
||||
width: 38%;
|
||||
border-radius: 24px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.14);
|
||||
box-shadow: 0 18px 50px rgba(0, 0, 0, 0.36);
|
||||
background: #d9e6ff;
|
||||
}
|
||||
|
||||
.hero-floating-top {
|
||||
top: 72px;
|
||||
right: -10px;
|
||||
transform: rotate(9deg);
|
||||
}
|
||||
|
||||
.hero-floating-bottom {
|
||||
right: 10px;
|
||||
bottom: 90px;
|
||||
transform: rotate(-8deg);
|
||||
}
|
||||
|
||||
.hero-badges {
|
||||
position: absolute;
|
||||
left: 18px;
|
||||
right: 18px;
|
||||
bottom: 18px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.hero-badge {
|
||||
border-radius: 20px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.hero-badge strong {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.hero-badge span {
|
||||
color: var(--muted);
|
||||
font-size: 0.96rem;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 42px 0 28px;
|
||||
}
|
||||
|
||||
.section-heading {
|
||||
max-width: 760px;
|
||||
margin-bottom: 26px;
|
||||
}
|
||||
|
||||
.section-heading h2 {
|
||||
font-size: clamp(2rem, 3.6vw, 3.2rem);
|
||||
margin: 0 0 14px;
|
||||
letter-spacing: -0.04em;
|
||||
}
|
||||
|
||||
.section-heading p {
|
||||
color: var(--muted);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.product-stack {
|
||||
display: grid;
|
||||
gap: 28px;
|
||||
}
|
||||
|
||||
.product-card {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 24px;
|
||||
align-items: center;
|
||||
background: rgba(7, 18, 36, 0.66);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: var(--card-radius);
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.product-card.reverse .product-carousel {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.product-tag {
|
||||
display: inline-flex;
|
||||
padding: 8px 12px;
|
||||
border-radius: 999px;
|
||||
background: rgba(95, 160, 255, 0.12);
|
||||
color: #cfe0ff;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.product-body h3 {
|
||||
font-size: 2rem;
|
||||
margin: 0 0 14px;
|
||||
}
|
||||
|
||||
.product-body p,
|
||||
.product-body li,
|
||||
.service-card p,
|
||||
.about-grid p,
|
||||
.contact-grid p {
|
||||
color: var(--muted);
|
||||
line-height: 1.72;
|
||||
}
|
||||
|
||||
.product-body ul {
|
||||
padding-left: 20px;
|
||||
margin: 18px 0 0;
|
||||
}
|
||||
|
||||
.product-carousel {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 24px;
|
||||
min-height: 380px;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.02));
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.carousel-track {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
min-height: 380px;
|
||||
}
|
||||
|
||||
.carousel-slide {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
opacity: 0;
|
||||
transition: opacity 0.35s ease;
|
||||
}
|
||||
|
||||
.carousel-slide.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.carousel-btn {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 2;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
background: rgba(4, 17, 32, 0.68);
|
||||
color: #ffffff;
|
||||
font-size: 1.6rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.carousel-btn.prev {
|
||||
left: 14px;
|
||||
}
|
||||
|
||||
.carousel-btn.next {
|
||||
right: 14px;
|
||||
}
|
||||
|
||||
.carousel-dots {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 16px;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.carousel-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.34);
|
||||
border: 0;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.carousel-dot.active {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.service-grid,
|
||||
.contact-grid,
|
||||
.about-grid {
|
||||
display: grid;
|
||||
gap: 22px;
|
||||
}
|
||||
|
||||
.service-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
.service-card {
|
||||
padding: 24px;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
.about-grid {
|
||||
grid-template-columns: 1.1fr 0.9fr;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.about-panel {
|
||||
border-radius: 28px;
|
||||
padding: 24px;
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.about-panel strong {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.contact-grid {
|
||||
grid-template-columns: 0.95fr 1.05fr;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.contact-list {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
margin-top: 22px;
|
||||
}
|
||||
|
||||
.contact-list > div {
|
||||
border-radius: 20px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.contact-list span {
|
||||
display: block;
|
||||
color: #bfd1f0;
|
||||
margin-bottom: 6px;
|
||||
font-size: 0.94rem;
|
||||
}
|
||||
|
||||
.contact-form {
|
||||
border-radius: 28px;
|
||||
padding: 24px;
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.contact-form label span {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.contact-form input,
|
||||
.contact-form textarea {
|
||||
width: 100%;
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
background: #0a1629;
|
||||
color: #ffffff;
|
||||
padding: 14px 16px;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.footer {
|
||||
padding: 28px 0 44px;
|
||||
}
|
||||
|
||||
.footer-wrap {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.08);
|
||||
padding-top: 24px;
|
||||
}
|
||||
|
||||
.footer-wrap p {
|
||||
margin: 0;
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.back-to-top {
|
||||
color: var(--muted);
|
||||
white-space: nowrap;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.back-to-top:hover {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.footer-links,
|
||||
.footer-legal {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.footer-links a,
|
||||
.footer-legal a {
|
||||
text-decoration: none;
|
||||
white-space: nowrap;
|
||||
color: var(--muted);
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.footer-links a:hover,
|
||||
.footer-legal a:hover {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
/*----------------------------------------*/
|
||||
/* 31. Cookie consent CSS
|
||||
/*----------------------------------------*/
|
||||
.cookie-overlay {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 99999;
|
||||
padding: 16px;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
backdrop-filter: blur(2px);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cookie-box {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
background: #212529;
|
||||
color: #ffffff;
|
||||
border-radius: 10px;
|
||||
padding: 14px 16px;
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.cookie-text a {
|
||||
color: #ffffff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.cookie-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cookie-manage {
|
||||
position: fixed;
|
||||
left: 16px;
|
||||
bottom: 16px;
|
||||
z-index: 99998;
|
||||
}
|
||||
|
||||
@media (max-width: 980px) {
|
||||
.hero-grid,
|
||||
.product-card,
|
||||
.about-grid,
|
||||
.contact-grid,
|
||||
.service-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.product-card.reverse .product-carousel {
|
||||
order: initial;
|
||||
}
|
||||
|
||||
.hero-card-inner {
|
||||
min-height: 560px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.lang-switch {
|
||||
order: -1;
|
||||
}
|
||||
|
||||
.nav {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
top: 84px;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 14px;
|
||||
padding: 18px;
|
||||
border-radius: 20px;
|
||||
background: #0a1629;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.nav.is-open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.menu-toggle {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.hero {
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
line-height: 1.02;
|
||||
}
|
||||
|
||||
.hero-metrics,
|
||||
.hero-badges {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.hero-card-inner {
|
||||
min-height: 660px;
|
||||
}
|
||||
|
||||
.hero-main-shot {
|
||||
width: 100%;
|
||||
margin-top: 56px;
|
||||
}
|
||||
|
||||
.hero-floating {
|
||||
width: 42%;
|
||||
}
|
||||
|
||||
.hero-floating-top {
|
||||
top: 88px;
|
||||
}
|
||||
|
||||
.hero-floating-bottom {
|
||||
bottom: 180px;
|
||||
}
|
||||
|
||||
.footer-wrap {
|
||||
grid-template-columns: 1fr;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.footer-wrap p {
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.footer-links,
|
||||
.footer-legal {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||