Files
myAi/web/wwwroot/css/myai.css
claude 36759d8fee
Build and Push Docker Images Staging / build (push) Successful in 4m41s
refactor: Add strategic comments to organize CSS (Step 5 of 6)
Added inline comments throughout myai.css to:
- Clarify complex CSS selectors (input:not selectors, specificity explanations)
- Explain design patterns (.is-invalid error state pattern)
- Document focus and error states
- Describe layout decisions (sticky result panel, hamburger dropdown)
- Clarify responsive breakpoints and what changes at each
- Explain the relationship between CSS and JS (e.g., .is-open, .is-invalid)

Comments are strategic and concise—added to complex/non-obvious sections
without bloating the file. All CSS rules remain unchanged—purely additive
documentation.

Key sections now have better context:
- Form field selectors and state handling
- Hamburger menu responsive behavior
- Result panel sticky positioning strategy
- Responsive grid layout changes at 900px and 560px
- Cookie banner and loader overlay behavior

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-05-29 09:15:20 +03:00

1000 lines
21 KiB
CSS

/* ============================================================
DESIGN TOKENS
============================================================ */
:root {
--bg: #041120;
--bg-soft: #0a1c34;
--panel: rgba(10,22,42,.82);
--panel-border: rgba(255,255,255,.1);
--text: #eaf1ff;
--muted: #9bb0d0;
--primary: #5fa0ff;
--primary-strong: #8b6cff;
--card-radius: 28px;
--shadow: 0 18px 60px rgba(0,0,0,.28)
}
/* ============================================================
RESET / BASE
============================================================ */
* {
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
}
/* ============================================================
LAYOUT HELPERS
============================================================ */
.container {
width: 100%;
max-width: 1120px;
margin: 0 auto;
padding-left: 20px;
padding-right: 20px
}
.site-shell {
overflow: hidden
}
/* ============================================================
STATUS PAGE (job-search redirect result)
============================================================ */
.status-hero {
min-height: 100vh;
display: flex;
align-items: center;
padding: 48px 0
}
.status-card {
max-width: 720px;
margin: 0 auto;
padding: 40px;
border-radius: var(--card-radius);
background: var(--panel);
border: 1px solid var(--panel-border);
box-shadow: var(--shadow)
}
.status-brand {
margin-bottom: 28px
}
.status-note {
margin: 24px 0 0;
color: var(--muted);
line-height: 1.6
}
/* ============================================================
HEADER / NAVIGATION
============================================================ */
.header {
position: sticky;
top: 0;
z-index: 20;
background: rgba(3,11,23,.76);
backdrop-filter: blur(16px);
border-bottom: 1px solid rgba(255,255,255,.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
}
.brand-mark img {
width: 100%;
height: 100%;
object-fit: contain;
filter: drop-shadow(0 16px 26px rgba(95,160,255,.24))
}
.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: #fff
}
/* Hamburger menu button — hidden on desktop, shown in responsive via media query */
.menu-toggle {
display: none;
background: transparent;
border: 0;
padding: 8px
}
/* Three horizontal lines that make up the hamburger icon */
.menu-toggle span {
display: block;
width: 24px;
height: 2px;
background: #fff;
margin: 5px 0
}
/* Language selector (right side of header) */
.nav-actions {
display: flex;
align-items: center;
gap: 12px
}
.lang-switch {
display: flex;
align-items: center;
gap: 8px;
padding: 6px;
border-radius: 18px;
background: rgba(255,255,255,.04);
border: 1px solid rgba(255,255,255,.1)
}
.lang-flag {
width: 46px;
height: 32px;
padding: 3px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid transparent;
border-radius: 12px;
background: transparent;
cursor: pointer;
opacity: .78;
transition: transform .2s ease,border-color .2s ease,background-color .2s ease,opacity .2s ease
}
.lang-flag img {
width: 100%;
height: 100%;
display: block;
border-radius: 8px;
object-fit: cover;
box-shadow: 0 8px 18px rgba(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,.65);
background: rgba(95,160,255,.1)
}
/* ============================================================
HERO SECTION
============================================================ */
.hero {
padding: 72px 0 48px
}
.hero-grid {
display: grid;
grid-template-columns: 1.05fr .95fr;
gap: 42px;
align-items: center
}
.eyebrow {
display: inline-flex;
align-items: center;
gap: 8px;
margin-bottom: 14px;
color: #8fb8ff;
text-transform: uppercase;
letter-spacing: .18em;
font-size: .78rem;
font-weight: 800
}
.hero h1 {
font-size: clamp(2.3rem,5vw,4.8rem);
line-height: 1.02;
margin: 0 0 24px;
letter-spacing: -.05em
}
.hero-text {
font-size: 1.12rem;
line-height: 1.8;
color: var(--muted);
max-width: 650px
}
.hero-actions {
display: flex;
gap: 14px;
flex-wrap: wrap;
margin-top: 30px
}
/* Hero card / AI console */
.banner-card {
overflow: hidden
}
.showcase-banner {
width: 100%;
border-radius: 22px;
margin-bottom: 18px;
border: 1px solid rgba(255,255,255,.12);
box-shadow: 0 20px 55px rgba(0,0,0,.22)
}
.console-line {
display: flex;
gap: 16px;
align-items: center;
margin: 12px 0;
padding: 16px 18px;
border-radius: 18px;
background: rgba(255,255,255,.05);
color: #dce8ff
}
.console-line span {
min-width: 76px;
color: #8fb8ff;
font-weight: 900
}
.console-line b {
font-weight: 700;
color: #dce8ff
}
/* ============================================================
BUTTONS
============================================================ */
.btn {
border-radius: 999px;
padding: 13px 22px;
font-weight: 800;
border: 1px solid rgba(255,255,255,.12)
}
.btn-primary {
background: linear-gradient(135deg,var(--primary),var(--primary-strong));
border: 0;
color: #fff
}
.btn-secondary {
background: rgba(255,255,255,.06);
color: #fff
}
/* Bootstrap replacement utilities */
.btn-sm { padding: 5px 10px; font-size: .875rem }
.btn-dark { background: #1e2730; color: #fff; border-color: #1e2730 }
.btn-warning { background: #ffc107; color: #212529; border: 0 }
.shadow { box-shadow: 0 .5rem 1rem rgba(0,0,0,.15) !important }
/* ============================================================
SECTION / DEMO GRID
============================================================ */
.section {
padding: 76px 0
}
.section-heading {
max-width: 720px;
margin-bottom: 34px
}
.section-heading h2, .contact h2, .ai-panel h2 {
font-size: clamp(2rem,4vw,3.2rem);
line-height: 1.05;
letter-spacing: -.04em;
margin: 0 0 18px
}
.section-heading p, .contact p {
color: var(--muted);
font-size: 1.05rem;
line-height: 1.8
}
.demo-grid {
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 20px
}
.demo-card {
display: block;
padding: 26px;
min-height: 260px;
transition: transform .2s ease,border-color .2s ease
}
.demo-card:hover {
transform: translateY(-4px);
border-color: rgba(95,160,255,.45)
}
.demo-card h3 {
font-size: 1.55rem;
margin: 18px 0 12px
}
.demo-card p {
color: var(--muted);
line-height: 1.7
}
.muted-card {
opacity: .7
}
.product-tag {
display: inline-flex;
border-radius: 999px;
padding: 7px 12px;
background: rgba(95,160,255,.12);
color: #b9d4ff;
border: 1px solid rgba(95,160,255,.18);
font-weight: 800;
font-size: .82rem
}
/* ============================================================
SHARED CARD STYLES
============================================================ */
.ai-console-card, .ai-panel, .demo-card, .contact-form {
background: var(--panel);
border: 1px solid var(--panel-border);
border-radius: var(--card-radius);
box-shadow: var(--shadow)
}
.ai-console-card {
padding: 30px
}
/* ============================================================
CV MATCHER — INPUT / RESULT PANELS
============================================================ */
.matcher-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
align-items: start
}
.ai-panel {
padding: 28px
}
.ai-panel label, .contact-form label {
display: block;
margin-bottom: 18px
}
/* Label text styling */
.ai-panel label span, .contact-form label span {
display: block;
margin-bottom: 8px;
color: #c3d4f2;
font-weight: 700
}
/* Input fields: text, textarea, email. Excludes checkboxes and file inputs. */
.ai-panel input:not([type="checkbox"]):not([type="file"]),
.ai-panel textarea,
.contact-form input:not([type="checkbox"]):not([type="file"]),
.contact-form textarea,
.subscribe-form input[type="email"] {
width: 100%;
border: 1px solid #d9e1f0;
border-radius: 6px;
background: #fff;
color: #0e1e3a;
padding: 12px 14px;
outline: none;
font-family: inherit;
font-size: 1rem;
line-height: 1.4;
transition: border-color .15s ease, box-shadow .15s ease
}
/* Placeholder text color */
.ai-panel input:not([type="checkbox"]):not([type="file"])::placeholder,
.ai-panel textarea::placeholder,
.contact-form input:not([type="checkbox"]):not([type="file"])::placeholder,
.contact-form textarea::placeholder,
.subscribe-form input[type="email"]::placeholder {
color: #97a4b8
}
/* Focus state: blue border and glow */
.ai-panel input:not([type="checkbox"]):not([type="file"]):focus,
.ai-panel textarea:focus,
.contact-form input:not([type="checkbox"]):not([type="file"]):focus,
.contact-form textarea:focus,
.subscribe-form input[type="email"]:focus {
border-color: #5fa0ff;
box-shadow: 0 0 0 3px rgba(95,160,255,.18)
}
/* Error state (is-invalid): red border and red glow when parent has .is-invalid class */
.ai-panel label.is-invalid input:not([type="checkbox"]):not([type="file"]),
.ai-panel label.is-invalid textarea,
.contact-form label.is-invalid input:not([type="checkbox"]):not([type="file"]),
.contact-form label.is-invalid textarea,
.subscribe-form .subscribe-row.is-invalid input[type="email"] {
border-color: #ff8a8a;
box-shadow: 0 0 0 3px rgba(255,138,138,.18)
}
.field-error {
display: block;
margin-top: 6px;
color: #ff8a8a;
font-size: .85rem;
font-weight: 600;
line-height: 1.35
}
.field-error:empty {
display: none
}
.consent-inline.is-invalid label {
color: #ff8a8a
}
/* File upload drop zone */
.file-drop {
display: block;
border: 1px dashed rgba(143,184,255,.45);
border-radius: 6px;
background: rgba(95,160,255,.07);
padding: 22px;
cursor: pointer
}
/* File drop zone error state */
.file-drop.is-invalid {
border-color: #ff8a8a;
background: rgba(255,138,138,.06)
}
.file-drop input {
display: none
}
.file-drop strong {
display: block;
font-size: 1.1rem
}
.file-drop span {
color: var(--muted) !important;
margin-top: 8px
}
.consent-inline {
display: flex;
gap: 12px;
align-items: flex-start;
margin: 18px 0 22px;
color: #b7c7e4;
line-height: 1.6
}
.consent-inline input {
width: auto;
margin-top: 5px
}
.consent-inline label {
margin: 0
}
/* Match result panel — sticky positioning keeps it visible while scrolling the form */
.result-panel {
position: sticky;
top: 110px
}
/* Empty state message (before results generated) */
.empty-result {
color: var(--muted);
line-height: 1.8;
padding: 20px;
border-radius: 18px;
background: rgba(0,0,0,.25)
}
/* Large circular match score percentage badge */
.score-badge {
display: inline-flex;
align-items: center;
justify-content: center;
width: 104px;
height: 104px;
border-radius: 50%;
background: linear-gradient(135deg,var(--primary),var(--primary-strong));
font-size: 2rem;
font-weight: 900;
margin: 10px 0 20px
}
/* Bulleted lists for strengths, gaps, evidence */
.result-list {
padding-left: 18px;
color: #d7e3fb;
line-height: 1.8
}
/* ============================================================
CONTACT SECTION
============================================================ */
.contact {
background: rgba(255,255,255,.03)
}
.contact-grid {
display: grid;
grid-template-columns: .9fr 1.1fr;
gap: 32px;
align-items: start
}
.contact-list {
display: grid;
gap: 14px;
margin-top: 24px
}
.contact-list div {
padding: 18px;
border-radius: 20px;
background: rgba(255,255,255,.05);
border: 1px solid rgba(255,255,255,.08)
}
.contact-list span {
display: block;
color: var(--muted);
font-size: .88rem
}
.contact-form {
padding: 28px
}
/* ============================================================
FORM MESSAGES & FEEDBACK
============================================================ */
.form-message {
display: block;
margin-top: 14px
}
.form-message:empty {
display: none
}
.form-message:not(:empty) {
padding: 10px 14px;
border-radius: 12px;
border: 1px solid rgba(255,255,255,.08);
background: rgba(0,0,0,.18);
font-weight: 700;
line-height: 1.4
}
.form-message.text-success:not(:empty) {
background: rgba(126,242,167,.08);
border-color: rgba(126,242,167,.35)
}
.form-message.text-danger:not(:empty) {
background: rgba(255,138,138,.08);
border-color: rgba(255,138,138,.35)
}
.form-message.text-warning:not(:empty) {
background: rgba(247,212,136,.08);
border-color: rgba(247,212,136,.35)
}
.text-success {
color: #7ef2a7 !important
}
.text-danger {
color: #ff8a8a !important
}
.text-warning {
color: #f7d488 !important
}
/* ============================================================
SUBSCRIBE FORM
============================================================ */
.subscribe-form {
margin-top: 28px;
padding: 28px;
border-radius: 24px;
background: rgba(255,255,255,.03);
border: 1px solid rgba(255,255,255,.08)
}
.subscribe-form h3 {
margin: 0 0 6px;
font-size: 1.1rem
}
.subscribe-form p {
margin: 0 0 14px;
color: var(--muted);
font-size: .92rem
}
.subscribe-form .subscribe-row {
display: flex;
gap: 10px;
flex-wrap: wrap
}
.subscribe-form .subscribe-row input[type="email"] {
flex: 1 1 220px;
min-width: 0
}
.subscribe-form .consent-inline {
margin-top: 12px
}
/* ============================================================
FOOTER
============================================================ */
.footer {
padding: 26px 0;
border-top: 1px solid rgba(255,255,255,.08);
background: rgba(0,0,0,.18)
}
.footer-wrap {
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px;
flex-wrap: wrap;
color: var(--muted)
}
.footer-wrap p {
margin: 0
}
.footer-links {
display: flex;
gap: 18px;
flex-wrap: wrap
}
.app-version {
font-size: .7rem;
color: var(--muted);
opacity: .5;
font-family: monospace
}
/* ============================================================
COOKIE BANNER & MANAGE BUTTON
Initial display:none ensures they are hidden before JS runs;
JS calls .fadeIn() / .show() to reveal them.
============================================================ */
.cookie-overlay {
display: none;
position: fixed;
left: 0;
right: 0;
bottom: 20px;
z-index: 50;
padding: 0 20px
}
.cookie-box {
max-width: 980px;
margin: auto;
padding: 20px;
border-radius: 24px;
background: #071326;
border: 1px solid rgba(255,255,255,.16);
box-shadow: var(--shadow);
display: flex;
align-items: center;
justify-content: space-between;
gap: 20px
}
.cookie-text {
color: #dce8ff;
line-height: 1.6
}
.cookie-text a {
color: #9cc5ff;
text-decoration: underline
}
.cookie-actions {
display: flex;
gap: 10px;
flex-wrap: wrap
}
/* "Cookie settings" button — hidden until consent is given */
.cookie-manage {
display: none;
position: fixed;
bottom: 20px;
z-index: 40
}
/* ============================================================
LOADER OVERLAY
Hidden by default; JS adds .loader-visible to show it.
Two-class selector (0,2,0) wins over single-class (0,1,0)
so no !important is needed.
============================================================ */
.loader-overlay {
display: none;
position: fixed;
inset: 0;
z-index: 80;
background: rgba(0,0,0,.55);
align-items: center;
justify-content: center;
backdrop-filter: blur(2px)
}
.loader-overlay.loader-visible {
display: flex
}
.loader-box {
max-width: 360px;
padding: 22px 28px;
border-radius: 18px;
background: #071326;
border: 1px solid rgba(255,255,255,.16);
text-align: center;
box-shadow: var(--shadow)
}
.loader-box strong {
display: block;
font-weight: 800;
margin-bottom: 6px
}
.loader-box span {
display: block;
color: var(--muted);
font-weight: 500;
font-size: .92rem;
line-height: 1.5
}
.loader-spinner {
display: block;
width: 28px;
height: 28px;
margin: 0 auto 14px;
border-radius: 50%;
border: 3px solid rgba(255,255,255,.18);
border-top-color: #9cc5ff;
animation: loader-spin .8s linear infinite
}
/* ============================================================
ANIMATIONS
============================================================ */
@keyframes loader-spin {
to { transform: rotate(360deg) }
}
.shake {
animation: shake .35s
}
@keyframes shake {
25% { transform: translateX(-5px) }
50% { transform: translateX(5px) }
75% { transform: translateX(-3px) }
}
/* ============================================================
RESPONSIVE — tablets and below (≤900px)
Changes: Single-column layouts, hamburger nav, adjusted spacing
============================================================ */
@media (max-width:900px) {
/* All grids switch from multi-column to single column */
.hero-grid, .matcher-grid, .contact-grid, .demo-grid {
grid-template-columns: 1fr
}
/* Result panel no longer sticky on tablets (would interfere with form) */
.result-panel {
position: static
}
/* Navigation becomes a hidden dropdown, shown on hamburger click via .is-open class */
.nav {
position: absolute;
top: 84px;
left: 20px;
right: 20px;
display: none;
flex-direction: column;
align-items: flex-start;
background: #071326;
border: 1px solid rgba(255,255,255,.12);
border-radius: 20px;
padding: 20px;
z-index: 30
}
/* .is-open class added by JS on hamburger click */
.nav.is-open {
display: flex
}
/* Show hamburger button on tablets */
.menu-toggle {
display: block;
order: 4
}
.nav-actions {
margin-left: auto
}
.nav-wrap {
position: relative
}
/* Cookie banner stacks vertically on tablets */
.cookie-box {
align-items: flex-start;
flex-direction: column
}
/* Language flags get smaller */
.lang-switch {
padding: 4px
}
.lang-flag {
width: 42px;
height: 30px
}
}
/* ============================================================
RESPONSIVE — mobile (≤560px)
Changes: Reduced padding, smaller text, full-width buttons, hide subtitle
============================================================ */
@media (max-width:560px) {
/* Tighter padding on small screens */
.hero {
padding-top: 46px
}
.section {
padding: 56px 0
}
/* Footer goes vertical on mobile */
.footer-wrap {
align-items: flex-start;
flex-direction: column
}
/* Action buttons take full width */
.hero-actions .btn {
width: 100%;
text-align: center
}
/* Brand logo smaller, subtitle hidden */
.brand-text {
font-size: 1.35rem
}
.brand small {
display: none
}
.brand-mark {
width: 42px;
height: 42px
}
/* Tighter gaps in nav and language selector */
.nav-actions {
gap: 6px
}
.lang-switch {
gap: 4px
}
.lang-flag {
width: 36px;
height: 27px
}
/* Slightly smaller banner border radius on mobile */
.showcase-banner {
border-radius: 18px
}
}