+735
-1
File diff suppressed because one or more lines are too long
@@ -11,6 +11,8 @@
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://myai.ro/cv-matcher/" />
|
||||
<meta name="theme-color" content="#071326" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
<link rel="icon" type="image/png" href="/img/favicon-256.png" />
|
||||
<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">
|
||||
@@ -21,79 +23,177 @@
|
||||
<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>
|
||||
<a class="brand" href="/" aria-label="MyAi.ro home">
|
||||
<span class="brand-mark">
|
||||
<img src="/img/myai-logo.svg" alt="MyAi.ro">
|
||||
</span>
|
||||
<span>
|
||||
<span class="brand-text">MyAi.ro</span>
|
||||
<small data-i18n="cv.brand">CV Matcher</small>
|
||||
</span>
|
||||
</a>
|
||||
<nav class="nav" id="mainNav" aria-label="Primary navigation">
|
||||
<a href="/" data-i18n="nav.navigator">Navigator</a>
|
||||
<a href="#matcher" data-i18n="nav.matcher">Matcher</a>
|
||||
<a href="#contact" data-i18n="nav.contact">Contact</a>
|
||||
</nav>
|
||||
<div class="nav-actions">
|
||||
<div class="lang-switch" aria-label="Language selector">
|
||||
<button class="lang-flag" data-lang="ro" aria-label="Română">
|
||||
<img src="/img/flags/ro.svg" alt="RO">
|
||||
</button>
|
||||
<button class="lang-flag" data-lang="en" aria-label="English">
|
||||
<img src="/img/flags/en.svg" alt="EN">
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<span class="eyebrow" data-i18n="cv.eyebrow">AI CV Matcher</span>
|
||||
<h1 data-i18n="cv.title">Upload your CV, add a job link, and see how well they match.</h1>
|
||||
<p class="hero-text" data-i18n="cv.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" data-i18n="cv.try">Try matcher</a>
|
||||
<a class="btn btn-secondary" href="/" data-i18n="cv.back">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 class="hero-card ai-console-card banner-card">
|
||||
<img class="showcase-banner" src="/img/myai-banner.svg" alt="MyAi.ro AI engineering banner">
|
||||
<div class="console-line">
|
||||
<span>1</span>
|
||||
<b data-i18n="cv.step1">PDF text extraction</b>
|
||||
</div>
|
||||
<div class="console-line">
|
||||
<span>2</span>
|
||||
<b data-i18n="cv.step2">CV chunking + embeddings</b>
|
||||
</div>
|
||||
<div class="console-line">
|
||||
<span>3</span>
|
||||
<b data-i18n="cv.step3">Job URL/description parsing</b>
|
||||
</div>
|
||||
<div class="console-line">
|
||||
<span>4</span>
|
||||
<b data-i18n="cv.step4">Match score + evidence</b>
|
||||
</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>
|
||||
<span class="eyebrow" data-i18n="cv.input">Input</span>
|
||||
<h2 data-i18n="cv.details">CV and job details</h2>
|
||||
<label class="file-drop" for="cvFile">
|
||||
<strong data-i18n="cv.upload">Upload CV PDF</strong>
|
||||
<span id="cvFileName" data-i18n="cv.fileHint">PDF only, max size handled by backend</span>
|
||||
<input type="file" id="cvFile" accept="application/pdf" required />
|
||||
</label>
|
||||
<label>
|
||||
<span data-i18n="cv.jobLink">Job link</span>
|
||||
<input type="url" id="jobUrl" placeholder="https://company.com/careers/job" />
|
||||
</label>
|
||||
<label>
|
||||
<span data-i18n="cv.jobDescription">Or paste job description</span>
|
||||
<textarea id="jobDescription" rows="8" data-i18n-placeholder="cv.jobPlaceholder" 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" data-i18n="cv.gdpr">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" data-i18n="cv.submit">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>
|
||||
<span class="eyebrow" data-i18n="cv.result">Result</span>
|
||||
<h2 data-i18n="cv.analysis">Match analysis</h2>
|
||||
<div id="matchResult" class="empty-result" data-i18n="cv.empty">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>
|
||||
<span class="eyebrow" data-i18n="nav.contact">Contact</span>
|
||||
<h2 data-i18n="cv.contactTitle">Want this adapted for your workflow?</h2>
|
||||
<p data-i18n="cv.contactText">This form uses the existing template contact API endpoint.</p>
|
||||
<div class="contact-list">
|
||||
<div>
|
||||
<span data-i18n="contact.person">Contact person</span>
|
||||
<strong>Mihes Gelu</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span data-i18n="contact.phone">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>
|
||||
<label>
|
||||
<span data-i18n="form.name">Name</span>
|
||||
<input type="text" id="name" data-i18n-placeholder="form.namePlaceholder" placeholder="Your name" required />
|
||||
</label>
|
||||
<label>
|
||||
<span data-i18n="form.email">Email</span>
|
||||
<input type="email" id="email" data-i18n-placeholder="form.emailPlaceholder" placeholder="name@company.com" required />
|
||||
</label>
|
||||
<label>
|
||||
<span data-i18n="form.message">Message</span>
|
||||
<textarea id="message" rows="6" data-i18n-placeholder="form.messagePlaceholder" placeholder="Tell me what you want to build." required></textarea>
|
||||
</label>
|
||||
<button id="submit" type="submit" class="btn btn-primary" data-i18n="form.send">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>
|
||||
<footer class="footer">
|
||||
<div class="container footer-wrap">
|
||||
<p>
|
||||
©
|
||||
<span id="year"></span> MyAi.ro ·
|
||||
<span data-i18n="footer.rights">All rights reserved</span>
|
||||
</p>
|
||||
<div class="footer-links footer-legal">
|
||||
<a data-legal="terms" href="/legal/terms-en.html" target="_blank" data-i18n="legal.terms">Terms</a>
|
||||
<a data-legal="privacy" href="/legal/privacy-en.html" target="_blank" data-i18n="legal.privacy">Privacy</a>
|
||||
<a data-legal="cookies" href="/legal/cookies-en.html" target="_blank" data-i18n="legal.cookies">Cookies</a>
|
||||
</div>
|
||||
<a href="#top" class="back-to-top btn btn-dark btn-sm shadow" data-i18n="footer.top">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>
|
||||
|
||||
<div id="contactLoader" class="loader-overlay" style="display:none;">
|
||||
<div class="loader-box" data-i18n="status.sending">Sending...</div>
|
||||
</div>
|
||||
<div id="cookieBanner" class="cookie-overlay" style="display:none;">
|
||||
<div class="cookie-box">
|
||||
<div class="cookie-text">
|
||||
<strong data-i18n="cookies.title">Cookies</strong>
|
||||
<br>
|
||||
<span data-i18n="cookies.text">We use necessary cookies and, with your consent, analytics through Google Tag Manager.</span>
|
||||
<a data-legal="privacy" href="/legal/privacy-en.html" target="_blank" data-i18n="cookies.policy">Privacy policy</a>.
|
||||
</div>
|
||||
<div class="cookie-actions">
|
||||
<button id="cookieReject" class="btn btn-warning btn-sm" data-i18n="cookies.reject">Reject</button>
|
||||
<button id="cookieNecessary" class="btn btn-warning btn-sm" data-i18n="cookies.necessary">Necessary only</button>
|
||||
<button id="cookieAccept" class="btn btn-primary btn-sm" data-i18n="cookies.accept">Accept analytics</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" id="cookieManage" class="cookie-manage btn btn-dark btn-sm shadow" style="display:none;" data-i18n="cookies.settings">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>
|
||||
</html>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,17 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 360" role="img" aria-label="MyAi AI engineering banner">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0" x2="960" y1="0" y2="360" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#06152B"/><stop offset=".5" stop-color="#0A2B54"/><stop offset="1" stop-color="#2F1F74"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="line" x1="120" x2="850" y1="40" y2="320" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#20E3B2"/><stop offset=".5" stop-color="#5FA0FF"/><stop offset="1" stop-color="#8B6CFF"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="960" height="360" rx="42" fill="url(#bg)"/>
|
||||
<g opacity=".18" stroke="#fff"><path d="M0 70h960M0 140h960M0 210h960M0 280h960M140 0v360M280 0v360M420 0v360M560 0v360M700 0v360M840 0v360"/></g>
|
||||
<path d="M110 250 C240 100, 360 280, 500 142 S720 84, 850 205" fill="none" stroke="url(#line)" stroke-width="18" stroke-linecap="round"/>
|
||||
<g fill="#fff"><circle cx="110" cy="250" r="18"/><circle cx="500" cy="142" r="18"/><circle cx="850" cy="205" r="18"/></g>
|
||||
<text x="84" y="138" font-family="Inter, Arial, sans-serif" font-size="58" font-weight="800" fill="#fff">MyAi.ro</text>
|
||||
<text x="86" y="188" font-family="Inter, Arial, sans-serif" font-size="26" font-weight="600" fill="#BFD1F0">Applied AI engineering showcase</text>
|
||||
<g transform="translate(700 76)"><rect width="150" height="64" rx="22" fill="rgba(255,255,255,.08)" stroke="rgba(255,255,255,.18)"/><text x="30" y="42" font-family="Inter, Arial" font-size="25" font-weight="800" fill="#fff">RAG</text></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-label="MyAi logo">
|
||||
<defs>
|
||||
<linearGradient id="g" x1="80" x2="420" y1="80" y2="420" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#5FA0FF"/>
|
||||
<stop offset="0.55" stop-color="#8B6CFF"/>
|
||||
<stop offset="1" stop-color="#20E3B2"/>
|
||||
</linearGradient>
|
||||
<filter id="s" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="18" stdDeviation="22" flood-color="#2b6bff" flood-opacity=".32"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<rect x="44" y="44" width="424" height="424" rx="116" fill="#06152b"/>
|
||||
<path d="M126 327V185h31l55 80 55-80h31v142h-34v-88l-42 61h-21l-42-61v88h-33Z" fill="#fff"/>
|
||||
<path d="M318 327V217h34v110h-34Zm17-124c-11 0-20-8-20-19s9-19 20-19 20 8 20 19-9 19-20 19Z" fill="#fff" opacity=".92"/>
|
||||
<path d="M92 113c70-55 177-62 250-13 74 50 102 145 68 226" fill="none" stroke="url(#g)" stroke-width="24" stroke-linecap="round" filter="url(#s)"/>
|
||||
<circle cx="94" cy="113" r="18" fill="#20E3B2"/>
|
||||
<circle cx="410" cy="326" r="18" fill="#5FA0FF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
+117
-62
@@ -11,134 +11,189 @@
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://myai.ro/" />
|
||||
<meta name="theme-color" content="#071326" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
<link rel="icon" type="image/png" href="/img/favicon-256.png" />
|
||||
<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" />
|
||||
<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 class="brand-mark">
|
||||
<img src="/img/myai-logo.svg" alt="MyAi.ro">
|
||||
</span>
|
||||
<span>
|
||||
<span class="brand-text">MyAi.ro</span>
|
||||
<small>AI engineering showcase</small>
|
||||
<small data-i18n="brand.subtitle">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>
|
||||
<a href="#demos" data-i18n="nav.demos">Demos</a>
|
||||
<a href="#contact" data-i18n="nav.contact">Contact</a>
|
||||
</nav>
|
||||
<div class="nav-actions">
|
||||
<div class="lang-switch" aria-label="Language selector">
|
||||
<button class="lang-flag" data-lang="ro" aria-label="Română">
|
||||
<img src="/img/flags/ro.svg" alt="RO">
|
||||
</button>
|
||||
<button class="lang-flag" data-lang="en" aria-label="English">
|
||||
<img src="/img/flags/en.svg" alt="EN">
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="menu-toggle" id="menuToggle" aria-expanded="false" aria-controls="mainNav">
|
||||
<span></span><span></span><span></span>
|
||||
<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>
|
||||
<span class="eyebrow" data-i18n="home.eyebrow">Applied AI lab</span>
|
||||
<h1 data-i18n="home.title">Production-minded AI demos, not generic chatbot wrappers.</h1>
|
||||
<p class="hero-text" data-i18n="home.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>
|
||||
<a class="btn btn-primary" href="/cv-matcher/" data-i18n="home.openCv">Open CV Matcher</a>
|
||||
<a class="btn btn-secondary" href="#contact" data-i18n="nav.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 class="hero-card ai-console-card banner-card">
|
||||
<img class="showcase-banner" src="/img/myai-banner.svg" alt="MyAi.ro AI engineering banner">
|
||||
<div class="console-line">
|
||||
<span>upload</span>
|
||||
<b data-i18n="home.step1">CV.pdf</b>
|
||||
</div>
|
||||
<div class="console-line">
|
||||
<span>extract</span>
|
||||
<b data-i18n="home.step2">skills, projects, experience</b>
|
||||
</div>
|
||||
<div class="console-line">
|
||||
<span>retrieve</span>
|
||||
<b data-i18n="home.step3">relevant CV context</b>
|
||||
</div>
|
||||
<div class="console-line">
|
||||
<span>score</span>
|
||||
<b data-i18n="home.step4">job match + gaps</b>
|
||||
</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>
|
||||
<span class="eyebrow" data-i18n="home.navigator">Navigator</span>
|
||||
<h2 data-i18n="home.selectDemo">Select an AI demo</h2>
|
||||
<p data-i18n="home.selectText">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>
|
||||
<span class="product-tag" data-i18n="tag.available">Available</span>
|
||||
<h3 data-i18n="demo.cv.title">CV Matcher</h3>
|
||||
<p data-i18n="demo.cv.text">Upload a CV PDF, provide a job link or description, extract RAG context and generate a match score with strengths and gaps.</p>
|
||||
<strong data-i18n="demo.open">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>
|
||||
<span class="product-tag" data-i18n="tag.next">Next</span>
|
||||
<h3 data-i18n="demo.rag.title">RAG Playground</h3>
|
||||
<p data-i18n="demo.rag.text">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>
|
||||
<span class="product-tag" data-i18n="tag.next">Next</span>
|
||||
<h3 data-i18n="demo.agent.title">Agent Automation</h3>
|
||||
<p data-i18n="demo.agent.text">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>
|
||||
<span class="eyebrow" data-i18n="nav.contact">Contact</span>
|
||||
<h2 data-i18n="contact.title">Discuss an AI integration or custom software project</h2>
|
||||
<p data-i18n="contact.text">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>
|
||||
<span data-i18n="contact.person">Contact person</span>
|
||||
<strong>Mihes Gelu</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span data-i18n="contact.phone">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>
|
||||
<label>
|
||||
<span data-i18n="form.name">Name</span>
|
||||
<input type="text" id="name" data-i18n-placeholder="form.namePlaceholder" placeholder="Your name" required />
|
||||
</label>
|
||||
<label>
|
||||
<span data-i18n="form.email">Email</span>
|
||||
<input type="email" id="email" data-i18n-placeholder="form.emailPlaceholder" placeholder="name@company.com" required />
|
||||
</label>
|
||||
<label>
|
||||
<span data-i18n="form.message">Message</span>
|
||||
<textarea id="message" rows="6" data-i18n-placeholder="form.messagePlaceholder" placeholder="Tell me what you want to build." required></textarea>
|
||||
</label>
|
||||
<button id="submit" type="submit" class="btn btn-primary" data-i18n="form.send">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>
|
||||
<p>
|
||||
©
|
||||
<span id="year"></span> MyAi.ro ·
|
||||
<span data-i18n="footer.rights">All rights reserved</span>
|
||||
</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>
|
||||
<a data-legal="terms" href="/legal/terms-en.html" target="_blank" data-i18n="legal.terms">Terms</a>
|
||||
<a data-legal="privacy" href="/legal/privacy-en.html" target="_blank" data-i18n="legal.privacy">Privacy</a>
|
||||
<a data-legal="cookies" href="/legal/cookies-en.html" target="_blank" data-i18n="legal.cookies">Cookies</a>
|
||||
</div>
|
||||
<a href="#top" class="back-to-top btn btn-dark btn-sm shadow">Back to top</a>
|
||||
<a href="#top" class="back-to-top btn btn-dark btn-sm shadow" data-i18n="footer.top">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="contactLoader" class="loader-overlay" style="display:none;">
|
||||
<div class="loader-box" data-i18n="status.sending">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-text">
|
||||
<strong data-i18n="cookies.title">Cookies</strong>
|
||||
<br>
|
||||
<span data-i18n="cookies.text">We use necessary cookies and, with your consent, analytics through Google Tag Manager.</span>
|
||||
<a data-legal="privacy" href="/legal/privacy-en.html" target="_blank" data-i18n="cookies.policy">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>
|
||||
<button id="cookieReject" class="btn btn-warning btn-sm" data-i18n="cookies.reject">Reject</button>
|
||||
<button id="cookieNecessary" class="btn btn-warning btn-sm" data-i18n="cookies.necessary">Necessary only</button>
|
||||
<button id="cookieAccept" class="btn btn-primary btn-sm" data-i18n="cookies.accept">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>
|
||||
<a href="#" id="cookieManage" class="cookie-manage btn btn-dark btn-sm shadow" style="display:none;" data-i18n="cookies.settings">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>
|
||||
</html>
|
||||
+470
-214
@@ -1,243 +1,499 @@
|
||||
(function ($) {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
var reCaptchaSiteKey = null;
|
||||
var gTagManagerId = null;
|
||||
var CONSENT_KEY = "myai_cookie_consent";
|
||||
var reCaptchaSiteKey = null;
|
||||
var gTagManagerId = null;
|
||||
var CONSENT_KEY = "myai_cookie_consent";
|
||||
var LANG_KEY = "myai_lang";
|
||||
|
||||
$('#year').text(new Date().getFullYear());
|
||||
var i18n = {
|
||||
en: {
|
||||
"brand.subtitle": "AI engineering showcase",
|
||||
"nav.demos": "Demos",
|
||||
"nav.contact": "Contact",
|
||||
"nav.navigator": "Navigator",
|
||||
"nav.matcher": "Matcher",
|
||||
"home.eyebrow": "Applied AI lab",
|
||||
"home.title": "Production-minded AI demos, not generic chatbot wrappers.",
|
||||
"home.text": "MyAi.ro is a technical showcase for practical AI systems: document understanding, retrieval, matching, automation and decision support.",
|
||||
"home.openCv": "Open CV Matcher",
|
||||
"home.step1": "CV.pdf",
|
||||
"home.step2": "skills, projects, experience",
|
||||
"home.step3": "relevant CV context",
|
||||
"home.step4": "job match + gaps",
|
||||
"home.navigator": "Navigator",
|
||||
"home.selectDemo": "Select an AI demo",
|
||||
"home.selectText": "Our first steps in AI integrations.",
|
||||
"tag.available": "Available",
|
||||
"tag.next": "Next",
|
||||
"demo.cv.title": "CV Matcher",
|
||||
"demo.cv.text": "Upload a CV PDF, provide a job link or description, extract RAG context and generate a match score with strengths and gaps.",
|
||||
"demo.open": "Open demo →",
|
||||
"demo.rag.title": "RAG Playground",
|
||||
"demo.rag.text": "Experiment with chunk size, retrieval count and source context transparency.",
|
||||
"demo.agent.title": "Agent Automation",
|
||||
"demo.agent.text": "Job discovery, filtering, ranking and notification workflows.",
|
||||
"contact.title": "Discuss an AI integration or custom software project",
|
||||
"contact.text": "Fill in the form fields and will contact you.",
|
||||
"contact.person": "Contact person",
|
||||
"contact.phone": "Phone",
|
||||
"form.name": "Name",
|
||||
"form.namePlaceholder": "Your name",
|
||||
"form.email": "Email",
|
||||
"form.emailPlaceholder": "name@company.com",
|
||||
"form.message": "Message",
|
||||
"form.messagePlaceholder": "Tell me what you want to build.",
|
||||
"form.send": "Send message",
|
||||
"form.thanks": "Thank you for your message.",
|
||||
"form.captchaFailed": "Captcha verification failed.",
|
||||
"form.failed": "Failed to send the message.",
|
||||
"footer.rights": "All rights reserved",
|
||||
"footer.top": "Back to top",
|
||||
"legal.terms": "Terms",
|
||||
"legal.privacy": "Privacy",
|
||||
"legal.cookies": "Cookies",
|
||||
"status.sending": "Sending...",
|
||||
"cookies.title": "Cookies",
|
||||
"cookies.text": "We use necessary cookies and, with your consent, analytics through Google Tag Manager.",
|
||||
"cookies.policy": "Privacy policy",
|
||||
"cookies.reject": "Reject",
|
||||
"cookies.necessary": "Necessary only",
|
||||
"cookies.accept": "Accept analytics",
|
||||
"cookies.settings": "Cookie settings",
|
||||
"cv.brand": "CV Matcher",
|
||||
"cv.eyebrow": "AI CV Matcher",
|
||||
"cv.title": "Upload your CV, add a job link, and see how well they match.",
|
||||
"cv.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.",
|
||||
"cv.try": "Try matcher",
|
||||
"cv.back": "Back to navigator",
|
||||
"cv.step1": "PDF text extraction",
|
||||
"cv.step2": "CV chunking + embeddings",
|
||||
"cv.step3": "Job URL/description parsing",
|
||||
"cv.step4": "Match score + evidence",
|
||||
"cv.input": "Input",
|
||||
"cv.details": "CV and job details",
|
||||
"cv.upload": "Upload CV PDF",
|
||||
"cv.fileHint": "PDF only, max size handled by backend",
|
||||
"cv.jobLink": "Job link",
|
||||
"cv.jobDescription": "Or paste job description",
|
||||
"cv.jobPlaceholder": "Paste the job description if the page cannot be crawled.",
|
||||
"cv.gdpr": "I agree that my CV is processed for this matching demo. Do not upload sensitive documents unless you trust the deployment.",
|
||||
"cv.submit": "Extract CV and match job",
|
||||
"cv.result": "Result",
|
||||
"cv.analysis": "Match analysis",
|
||||
"cv.empty": "Upload a CV and provide a job link or description to generate a result.",
|
||||
"cv.contactTitle": "Want this adapted for your workflow?",
|
||||
"cv.contactText": "This form uses the existing template contact API endpoint.",
|
||||
"cv.noFile": "Please upload a CV PDF.",
|
||||
"cv.noJob": "Add a job link or paste a job description.",
|
||||
"cv.noConsent": "GDPR consent is required.",
|
||||
"cv.processing": "Processing...",
|
||||
"cv.extracting": "Extracting CV and matching job...",
|
||||
"cv.processingLong": "Processing CV PDF and job input. Backend endpoints must be available.",
|
||||
"cv.cvFailed": "CV extraction failed",
|
||||
"cv.matchFailed": "Job matching failed",
|
||||
"cv.completed": "Match completed.",
|
||||
"cv.backendMissing": "The frontend is ready, but the backend endpoints /api/rag/cv and /api/rag/match-job must be implemented.",
|
||||
"cv.noSummary": "No summary returned.",
|
||||
"cv.noItems": "No items returned.",
|
||||
"cv.strengths": "Strengths",
|
||||
"cv.gaps": "Gaps",
|
||||
"cv.evidence": "Retrieved CV evidence"
|
||||
},
|
||||
ro: {
|
||||
"brand.subtitle": "prezentare inginerie AI",
|
||||
"nav.demos": "Demo-uri",
|
||||
"nav.contact": "Contact",
|
||||
"nav.navigator": "Navigator",
|
||||
"nav.matcher": "Matcher",
|
||||
"home.eyebrow": "Laborator AI aplicat",
|
||||
"home.title": "Demo-uri AI orientate spre producție, nu simple wrapper-e de chatbot.",
|
||||
"home.text": "MyAi.ro este o prezentare tehnică pentru sisteme AI practice: înțelegere documente, retrieval, potrivire, automatizare și suport decizional.",
|
||||
"home.openCv": "Deschide CV Matcher",
|
||||
"home.step1": "CV.pdf",
|
||||
"home.step2": "competențe, proiecte, experiență",
|
||||
"home.step3": "context relevant din CV",
|
||||
"home.step4": "potrivire job + lipsuri",
|
||||
"home.navigator": "Navigator",
|
||||
"home.selectDemo": "Alege un demo AI",
|
||||
"home.selectText": "Primele noastre projecte",
|
||||
"tag.available": "Disponibil",
|
||||
"tag.next": "Urmează",
|
||||
"demo.cv.title": "CV Matcher",
|
||||
"demo.cv.text": "Încarcă un CV PDF, adaugă un link sau o descriere de job, extrage context RAG și generează un scor de potrivire cu puncte forte și lipsuri.",
|
||||
"demo.open": "Deschide demo →",
|
||||
"demo.rag.title": "RAG Playground",
|
||||
"demo.rag.text": "Experimentează cu dimensiunea chunk-urilor, numărul de rezultate și transparența surselor.",
|
||||
"demo.agent.title": "Automatizare cu agenți",
|
||||
"demo.agent.text": "Fluxuri pentru descoperire joburi, filtrare, ranking și notificări.",
|
||||
"contact.title": "Discută o integrare AI sau un proiect software custom",
|
||||
"contact.text": "Complecteaza formularul si te vom contacta.",
|
||||
"contact.person": "Persoană de contact",
|
||||
"contact.phone": "Telefon",
|
||||
"form.name": "Nume",
|
||||
"form.namePlaceholder": "Numele tău",
|
||||
"form.email": "Email",
|
||||
"form.emailPlaceholder": "nume@companie.ro",
|
||||
"form.message": "Mesaj",
|
||||
"form.messagePlaceholder": "Spune-mi ce vrei să construiești.",
|
||||
"form.send": "Trimite mesajul",
|
||||
"form.thanks": "Mulțumesc pentru mesaj.",
|
||||
"form.captchaFailed": "Verificarea Captcha a eșuat.",
|
||||
"form.failed": "Mesajul nu a putut fi trimis.",
|
||||
"footer.rights": "Toate drepturile rezervate",
|
||||
"footer.top": "Înapoi sus",
|
||||
"legal.terms": "Termeni",
|
||||
"legal.privacy": "Confidențialitate",
|
||||
"legal.cookies": "Cookies",
|
||||
"status.sending": "Se trimite...",
|
||||
"cookies.title": "Cookies",
|
||||
"cookies.text": "Folosim cookies necesare și, cu acordul tău, analytics prin Google Tag Manager.",
|
||||
"cookies.policy": "Politica de confidențialitate",
|
||||
"cookies.reject": "Respinge",
|
||||
"cookies.necessary": "Doar necesare",
|
||||
"cookies.accept": "Accept analytics",
|
||||
"cookies.settings": "Setări cookies",
|
||||
"cv.brand": "CV Matcher",
|
||||
"cv.eyebrow": "AI CV Matcher",
|
||||
"cv.title": "Încarcă CV-ul, adaugă un link de job și vezi cât de bine se potrivesc.",
|
||||
"cv.text": "Backend-ul ar trebui să extragă textul din PDF, să creeze context RAG din CV, să recupereze experiența relevantă pentru job, apoi să calculeze punctele forte, lipsurile și pașii următori.",
|
||||
"cv.try": "Încearcă matcherul",
|
||||
"cv.back": "Înapoi la navigator",
|
||||
"cv.step1": "Extragere text PDF",
|
||||
"cv.step2": "Chunking CV + embeddings",
|
||||
"cv.step3": "Parsare URL/descriere job",
|
||||
"cv.step4": "Scor potrivire + dovezi",
|
||||
"cv.input": "Date de intrare",
|
||||
"cv.details": "CV și detalii job",
|
||||
"cv.upload": "Încarcă CV PDF",
|
||||
"cv.fileHint": "Doar PDF, limita de mărime este gestionată de backend",
|
||||
"cv.jobLink": "Link job",
|
||||
"cv.jobDescription": "Sau lipește descrierea jobului",
|
||||
"cv.jobPlaceholder": "Lipește descrierea jobului dacă pagina nu poate fi citită automat.",
|
||||
"cv.gdpr": "Sunt de acord ca CV-ul meu să fie procesat pentru acest demo de matching. Nu încărca documente sensibile dacă nu ai încredere în deployment.",
|
||||
"cv.submit": "Extrage CV și compară jobul",
|
||||
"cv.result": "Rezultat",
|
||||
"cv.analysis": "Analiză potrivire",
|
||||
"cv.empty": "Încarcă un CV și adaugă un link sau o descriere de job pentru a genera rezultatul.",
|
||||
"cv.contactTitle": "Vrei să adaptezi asta pentru workflow-ul tău?",
|
||||
"cv.contactText": "Formularul folosește endpoint-ul existent de contact din template.",
|
||||
"cv.noFile": "Te rog încarcă un CV PDF.",
|
||||
"cv.noJob": "Adaugă un link de job sau lipește descrierea jobului.",
|
||||
"cv.noConsent": "Consimțământul GDPR este obligatoriu.",
|
||||
"cv.processing": "Se procesează...",
|
||||
"cv.extracting": "Se extrage CV-ul și se compară jobul...",
|
||||
"cv.processingLong": "Se procesează PDF-ul și informațiile despre job. Endpoint-urile backend trebuie să fie disponibile.",
|
||||
"cv.cvFailed": "Extragerea CV-ului a eșuat",
|
||||
"cv.matchFailed": "Matching-ul jobului a eșuat",
|
||||
"cv.completed": "Matching finalizat.",
|
||||
"cv.backendMissing": "Frontend-ul este pregătit, dar endpoint-urile backend /api/rag/cv și /api/rag/match-job trebuie implementate.",
|
||||
"cv.noSummary": "Nu a fost returnat niciun sumar.",
|
||||
"cv.noItems": "Nu au fost returnate elemente.",
|
||||
"cv.strengths": "Puncte forte",
|
||||
"cv.gaps": "Lipsuri",
|
||||
"cv.evidence": "Dovezi recuperate din CV"
|
||||
}
|
||||
};
|
||||
|
||||
$('#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');
|
||||
});
|
||||
function browserLang() {
|
||||
return ((navigator.language || navigator.userLanguage || 'en').toLowerCase().indexOf('ro') === 0) ? 'ro' : 'en';
|
||||
}
|
||||
|
||||
$('.nav a').on('click', function () {
|
||||
$('#mainNav').removeClass('is-open');
|
||||
$('#menuToggle').attr('aria-expanded', 'false');
|
||||
});
|
||||
function currentLang() {
|
||||
return localStorage.getItem(LANG_KEY) || browserLang();
|
||||
}
|
||||
|
||||
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 t(key) {
|
||||
var lang = currentLang();
|
||||
return (i18n[lang] && i18n[lang][key]) || i18n.en[key] || key;
|
||||
}
|
||||
|
||||
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 updateLegalLinks(lang) {
|
||||
$('[data-legal]').each(function () {
|
||||
var page = $(this).data('legal');
|
||||
$(this).attr('href', '/legal/' + page + '-' + lang + '.html');
|
||||
});
|
||||
}
|
||||
|
||||
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 applyLanguage(lang) {
|
||||
localStorage.setItem(LANG_KEY, lang);
|
||||
document.documentElement.lang = lang;
|
||||
updateLegalLinks(lang);
|
||||
$('[data-i18n]').each(function () {
|
||||
$(this).text(t($(this).data('i18n')));
|
||||
});
|
||||
$('[data-i18n-placeholder]').each(function () {
|
||||
$(this).attr('placeholder', t($(this).data('i18n-placeholder')));
|
||||
});
|
||||
$('.lang-flag').attr('aria-pressed', 'false');
|
||||
$('.lang-flag[data-lang="' + lang + '"]').attr('aria-pressed', 'true');
|
||||
}
|
||||
|
||||
function getConsent() {
|
||||
try { return JSON.parse(localStorage.getItem(CONSENT_KEY)); } catch { return null; }
|
||||
}
|
||||
$('#year').text(new Date().getFullYear());
|
||||
applyLanguage(currentLang());
|
||||
$('.lang-flag').on('click', function () {
|
||||
applyLanguage($(this).data('lang'));
|
||||
});
|
||||
|
||||
function setConsent(consent) {
|
||||
localStorage.setItem(CONSENT_KEY, JSON.stringify(consent));
|
||||
}
|
||||
$('#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 applyConsent(consent) {
|
||||
if (consent && consent.analytics === true) loadGoogleTagManager();
|
||||
}
|
||||
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 showBanner() { $('#cookieBanner').fadeIn(200); }
|
||||
function hideBanner() { $('#cookieBanner').fadeOut(200); }
|
||||
function showManage() { $('#cookieManage').show(); }
|
||||
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');
|
||||
});
|
||||
}
|
||||
|
||||
$('#cookieReject, #cookieNecessary').on('click', function () {
|
||||
setConsent({ necessary: true, analytics: false, ts: new Date().toISOString() });
|
||||
hideBanner();
|
||||
showManage();
|
||||
});
|
||||
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);
|
||||
}
|
||||
|
||||
$('#cookieAccept').on('click', function () {
|
||||
var consent = { necessary: true, analytics: true, ts: new Date().toISOString() };
|
||||
setConsent(consent);
|
||||
applyConsent(consent);
|
||||
hideBanner();
|
||||
showManage();
|
||||
});
|
||||
function getConsent() {
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem(CONSENT_KEY));
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$('#cookieManage').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
showBanner();
|
||||
});
|
||||
function setConsent(consent) {
|
||||
localStorage.setItem(CONSENT_KEY, JSON.stringify(consent));
|
||||
}
|
||||
|
||||
function initConsent() {
|
||||
var consent = getConsent();
|
||||
if (!consent) showBanner();
|
||||
else { applyConsent(consent); showManage(); }
|
||||
}
|
||||
function applyConsent(consent) {
|
||||
if (consent && consent.analytics === true) loadGoogleTagManager();
|
||||
}
|
||||
|
||||
function submitMSG(valid, msg) {
|
||||
var msgClasses = valid ? 'form-message text-success' : 'form-message text-danger';
|
||||
$('#msgSubmit').removeClass().addClass(msgClasses).text(msg);
|
||||
}
|
||||
function showBanner() {
|
||||
$('#cookieBanner').fadeIn(200);
|
||||
}
|
||||
|
||||
function formSuccess() {
|
||||
$('#contactForm')[0].reset();
|
||||
submitMSG(true, 'Thank you for your message.');
|
||||
}
|
||||
function hideBanner() {
|
||||
$('#cookieBanner').fadeOut(200);
|
||||
}
|
||||
|
||||
function formError() {
|
||||
$('#contactForm').removeClass().addClass('contact-form shake').one('animationend', function () {
|
||||
$(this).removeClass('shake');
|
||||
});
|
||||
}
|
||||
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();
|
||||
});
|
||||
|
||||
$('#contactForm').on('submit', function (event) {
|
||||
event.preventDefault();
|
||||
var loader = $('#contactLoader');
|
||||
var button = $('#submit');
|
||||
loader.css('display', 'flex');
|
||||
button.prop('disabled', true);
|
||||
$('#msgSubmit').text('');
|
||||
function initConsent() {
|
||||
var consent = getConsent();
|
||||
if (!consent) showBanner();
|
||||
else {
|
||||
applyConsent(consent);
|
||||
showManage();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
function submitMSG(valid, msg) {
|
||||
$('#msgSubmit').removeClass().addClass(valid ? 'form-message text-success' : 'form-message text-danger').text(msg);
|
||||
}
|
||||
|
||||
if (window.grecaptcha && reCaptchaSiteKey) {
|
||||
grecaptcha.ready(function () {
|
||||
grecaptcha.execute(reCaptchaSiteKey, { action: 'contact' }).then(postContact);
|
||||
});
|
||||
} else {
|
||||
postContact('');
|
||||
}
|
||||
});
|
||||
function formSuccess() {
|
||||
$('#contactForm')[0].reset();
|
||||
submitMSG(true, t('form.thanks'));
|
||||
}
|
||||
|
||||
$('#cvFile').on('change', function () {
|
||||
var file = this.files && this.files[0];
|
||||
$('#cvFileName').text(file ? file.name : 'PDF only, max size handled by backend');
|
||||
});
|
||||
function formError() {
|
||||
$('#contactForm').removeClass().addClass('contact-form shake').one('animationend', function () {
|
||||
$(this).removeClass('shake');
|
||||
});
|
||||
}
|
||||
|
||||
$('#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');
|
||||
$('#contactForm').on('submit', function (event) {
|
||||
event.preventDefault();
|
||||
var loader = $('#contactLoader'),
|
||||
button = $('#submit');
|
||||
loader.css('display', 'flex');
|
||||
button.prop('disabled', true);
|
||||
$('#msgSubmit').text('');
|
||||
|
||||
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; }
|
||||
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, t('form.captchaFailed'));
|
||||
}).fail(function () {
|
||||
submitMSG(false, t('form.failed'));
|
||||
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('');
|
||||
}
|
||||
});
|
||||
|
||||
$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>');
|
||||
$('#cvFile').on('change', function () {
|
||||
var file = this.files && this.files[0];
|
||||
$('#cvFileName').text(file ? file.name : t('cv.fileHint'));
|
||||
});
|
||||
$('#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'),
|
||||
$button = $('#matchSubmit'),
|
||||
$result = $('#matchResult');
|
||||
if (!file) {
|
||||
$msg.removeClass().addClass('form-message text-danger').text(t('cv.noFile'));
|
||||
return;
|
||||
}
|
||||
if (!jobUrl && !jobDescription) {
|
||||
$msg.removeClass().addClass('form-message text-danger').text(t('cv.noJob'));
|
||||
return;
|
||||
}
|
||||
if (!consent) {
|
||||
$msg.removeClass().addClass('form-message text-danger').text(t('cv.noConsent'));
|
||||
return;
|
||||
}
|
||||
$button.prop('disabled', true).text(t('cv.processing'));
|
||||
$msg.removeClass().addClass('form-message').text(t('cv.extracting'));
|
||||
$result.html('<div class="empty-result">' + escapeHtml(t('cv.processingLong')) + '</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(t('cv.cvFailed'));
|
||||
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(t('cv.matchFailed'));
|
||||
var match = await matchResponse.json();
|
||||
renderMatchResult(match);
|
||||
$msg.removeClass().addClass('form-message text-success').text(t('cv.completed'));
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
$msg.removeClass().addClass('form-message text-danger').text(err.message || t('cv.matchFailed'));
|
||||
$result.html('<div class="empty-result">' + escapeHtml(t('cv.backendMissing')) + '</div>');
|
||||
} finally {
|
||||
$button.prop('disabled', false).text(t('cv.submit'));
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
var formData = new FormData();
|
||||
formData.append('cv', file);
|
||||
formData.append('gdprConsent', String(consent));
|
||||
function renderMatchResult(match) {
|
||||
var score = match.score || match.matchScore || 0;
|
||||
var summary = match.summary || t('cv.noSummary');
|
||||
var strengths = match.strengths || [];
|
||||
var gaps = match.gaps || match.missingSkills || [];
|
||||
var evidence = match.evidence || match.retrievedChunks || [];
|
||||
|
||||
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();
|
||||
function list(items) {
|
||||
if (!items || !items.length) return '<p class="empty-result">' + escapeHtml(t('cv.noItems')) + '</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>' + t('cv.strengths') + '</h3>' + list(strengths) + '<h3>' + t('cv.gaps') + '</h3>' + list(gaps) + '<h3>' + t('cv.evidence') + '</h3>' + list(evidence));
|
||||
}
|
||||
|
||||
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);
|
||||
function escapeHtml(value) {
|
||||
return String(value).replace(/[&<>'"]/g, function (char) {
|
||||
return ({
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
"'": ''',
|
||||
'"': '"'
|
||||
})[char];
|
||||
});
|
||||
}
|
||||
$(window).on('load', function () {
|
||||
$.when(getRecaptchaWebKey(), getGoogleTagManagerId()).always(initConsent);
|
||||
});
|
||||
})(jQuery);
|
||||
@@ -9,22 +9,24 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="myAi home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="myAi">
|
||||
</div>
|
||||
<div class="brand-copy">myAi<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 class="topbar">
|
||||
<a class="brand" href="/" aria-label="Back">
|
||||
<span class="brand-mark">
|
||||
<img src="/img/myai-logo.svg" alt="MyAi.ro">
|
||||
</span>
|
||||
<span>
|
||||
<span class="brand-text">Back</span>
|
||||
</span>
|
||||
</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>
|
||||
|
||||
<div class="hero">
|
||||
<div class="kicker">Cookies</div>
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="myAi home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="myAi">
|
||||
</div>
|
||||
<div class="brand-copy">myAi<small>Pagini legale</small></div>
|
||||
<a class="brand" href="/" aria-label="Inapoi">
|
||||
<span class="brand-mark">
|
||||
<img src="/img/myai-logo.svg" alt="MyAi.ro">
|
||||
</span>
|
||||
<span>
|
||||
<span class="brand-text">Inapoi</span>
|
||||
</span>
|
||||
</a>
|
||||
<div class="switcher">
|
||||
<a href="cookies-ro.html" class="lang-link active" data-lang="ro" aria-label="Română">
|
||||
|
||||
+205
-75
@@ -1,86 +1,216 @@
|
||||
|
||||
: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;
|
||||
:root {
|
||||
--bg: #07192f;
|
||||
--bg2: #0a2441;
|
||||
--card: #0e1f37;
|
||||
--text: #eaf2ff;
|
||||
--muted: #b4c5dd;
|
||||
--line: rgba(255,255,255,.10);
|
||||
--accent: #7eb7ff;
|
||||
}
|
||||
|
||||
.brand-badge img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
* {
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
.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;
|
||||
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;
|
||||
}
|
||||
.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);
|
||||
|
||||
a {
|
||||
color: var(--accent);
|
||||
text-decoration: none
|
||||
}
|
||||
.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
|
||||
|
||||
a:hover {
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.wrap {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
padding: 28px 20px 60px
|
||||
}
|
||||
.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)
|
||||
|
||||
.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);
|
||||
}
|
||||
.footer{
|
||||
margin-top:18px;padding:22px 26px;display:flex;justify-content:space-between;gap:16px;align-items:center;flex-wrap:wrap
|
||||
|
||||
.brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
.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}
|
||||
|
||||
.brand-text {
|
||||
font-size: 1.35rem
|
||||
}
|
||||
|
||||
.brand small {
|
||||
display: none
|
||||
}
|
||||
|
||||
.brand-mark {
|
||||
width: 42px;
|
||||
height: 42px
|
||||
}
|
||||
|
||||
.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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,22 +9,24 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="myAi home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="myAi">
|
||||
</div>
|
||||
<div class="brand-copy">myAi<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 class="topbar">
|
||||
<a class="brand" href="/" aria-label="Back">
|
||||
<span class="brand-mark">
|
||||
<img src="/img/myai-logo.svg" alt="MyAi.ro">
|
||||
</span>
|
||||
<span>
|
||||
<span class="brand-text">Back</span>
|
||||
</span>
|
||||
</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>
|
||||
|
||||
<div class="hero">
|
||||
<div class="kicker">Data protection</div>
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="myAi home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="myAi">
|
||||
</div>
|
||||
<div class="brand-copy">myAi<small>Pagini legale</small></div>
|
||||
<a class="brand" href="/" aria-label="Inapoi">
|
||||
<span class="brand-mark">
|
||||
<img src="/img/myai-logo.svg" alt="MyAi.ro">
|
||||
</span>
|
||||
<span>
|
||||
<span class="brand-text">Inapoi</span>
|
||||
</span>
|
||||
</a>
|
||||
<div class="switcher">
|
||||
<a href="privacy-ro.html" class="lang-link active" data-lang="ro" aria-label="Română">
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="myAi home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="myAi">
|
||||
</div>
|
||||
<div class="brand-copy">myAi<small>Legal pages</small></div>
|
||||
<a class="brand" href="/" aria-label="Back">
|
||||
<span class="brand-mark">
|
||||
<img src="/img/myai-logo.svg" alt="MyAi.ro">
|
||||
</span>
|
||||
<span>
|
||||
<span class="brand-text">Back</span>
|
||||
</span>
|
||||
</a>
|
||||
<div class="switcher">
|
||||
<a href="terms-ro.html" class="lang-link " data-lang="ro" aria-label="Română">
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="topbar">
|
||||
<a class="brand" href="\" aria-label="myAi home">
|
||||
<div class="brand-badge">
|
||||
<img src="\logo.png" alt="myAi">
|
||||
</div>
|
||||
<div class="brand-copy">myAi<small>Pagini legale</small></div>
|
||||
<a class="brand" href="/" aria-label="Inapoi">
|
||||
<span class="brand-mark">
|
||||
<img src="/img/myai-logo.svg" alt="MyAi.ro">
|
||||
</span>
|
||||
<span>
|
||||
<span class="brand-text">Inapoi</span>
|
||||
</span>
|
||||
</a>
|
||||
<div class="switcher">
|
||||
<a href="terms-ro.html" class="lang-link active" data-lang="ro" aria-label="Română">
|
||||
|
||||
Reference in New Issue
Block a user