/* ============================================================================
   VOLTAGE — site-wide design layer
   ----------------------------------------------------------------------------
   Loaded after style.css and the Theme Manager's <style id="theme-vars">, so it
   restyles components without owning any colour: every hue still comes from
   --primary / --accent / --bg / --text… as set in Admin → Theme. Pick the
   "Voltage" preset there for the palette this layer was designed around
   (electric indigo + volt lime on near-black).

   Rules of the system
   • Display type (Space Grotesk) for headings and numbers, theme font for body,
     JetBrains Mono for eyebrows and metadata.
   • --accent is a FILL colour (buttons, highlights, markers) with --ink text on
     top. It is never used as text on --bg, because a bright accent such as volt
     lime is unreadable on a light background.
   • Hairline borders, solid surfaces, one hard offset shadow on hover. No
     gradients-on-gradients.
   • Everything animated is skipped under prefers-reduced-motion.
============================================================================ */

:root {
    --font-display: 'Space Grotesk', var(--font, 'Outfit'), system-ui, sans-serif;
    --font-mono:    'JetBrains Mono', ui-monospace, monospace;
    --ink:          #0a0b10;                       /* text on an --accent fill */
    --vx-radius:    var(--radius, 12px);
    --vx-ease:      cubic-bezier(.2, .8, .2, 1);
    --vx-line:      color-mix(in srgb, var(--text) 9%, transparent);
    --vx-grid:      color-mix(in srgb, var(--text) 4.5%, transparent);
    --vx-surface:   color-mix(in srgb, var(--bg) 70%, var(--bg3));
    --vx-shadow:    color-mix(in srgb, var(--text) 85%, transparent);
}
[data-theme="light"] {
    --vx-line:    color-mix(in srgb, var(--text) 12%, transparent);
    --vx-grid:    color-mix(in srgb, var(--text) 5.5%, transparent);
    --vx-surface: #ffffff;
}

/* Cross-document view transitions: page-to-page navigation cross-fades
   instead of flashing white. Browsers without support ignore the at-rule. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .22s; }

/* ── Base ─────────────────────────────────────────────────────────────────── */
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body { text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; }

/* Blueprint grid behind every page — fixed, masked so it fades out toward the
   bottom of the viewport and never fights with content. */
body::before {
    content: '';
    position: fixed; inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image:
        linear-gradient(var(--vx-grid) 1px, transparent 1px),
        linear-gradient(90deg, var(--vx-grid) 1px, transparent 1px);
    background-size: 56px 56px;
    background-position: -1px -1px;
    -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 30%, transparent 85%);
            mask-image: radial-gradient(ellipse 90% 70% at 50% 0%, #000 30%, transparent 85%);
}

::selection { background: var(--accent); color: var(--ink); }

h1, h2, h3, h4,
.section-title, .hero-name, .project-title, .blog-title, .service-title {
    font-family: var(--font-display);
    letter-spacing: -0.025em;
    text-wrap: balance;
}
p { text-wrap: pretty; }

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
}

#scroll-progress {
    height: 3px;
    background: var(--accent);
    animation: none;
    box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 60%, transparent);
}

/* ── Navbar: floating bar on desktop ─────────────────────────────────────── */
/* Desktop only. The mobile drawer is a position:fixed child of .navbar, and
   .navbar's backdrop-filter makes it the drawer's containing block — insetting
   the bar on mobile would drag the drawer with it. */
@media (min-width: 769px) {
    .navbar {
        top: 12px;
        left: 50%;
        right: auto;
        transform: translateX(-50%);
        width: min(1240px, calc(100% - 32px));
        height: calc(var(--nav-h) - 12px);
        border: 1px solid var(--vx-line);
        border-radius: calc(var(--vx-radius) + 6px);
        background: color-mix(in srgb, var(--bg) 78%, transparent);
        box-shadow: 0 10px 40px -18px var(--shadow2);
    }
    .navbar.scrolled { border-color: var(--border3); }
    .nav-container { height: 100%; padding-inline: 18px; }
    body { padding-top: calc(var(--nav-h) + 14px); }
}
.nav-logo span { font-family: var(--font-display); letter-spacing: -.03em; }
.nav-logo .accent { color: var(--accent); }
.nav-link { font-weight: 600; }
.nav-link.active {
    color: var(--text);
    background: color-mix(in srgb, var(--accent) 16%, transparent);
}
.nav-link.active i { color: var(--primary); }
.nav-dot { background: var(--accent) !important; }

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.btn,
body .hero-glass-btn-primary {
    background: var(--accent);
    color: var(--ink);
    border: 1.5px solid var(--accent);
    border-radius: var(--vx-radius);
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -.005em;
    box-shadow: 0 0 0 0 var(--vx-shadow);
    transition: transform .18s var(--vx-ease), box-shadow .18s var(--vx-ease), background .18s, color .18s, border-color .18s;
}
.btn:hover,
body .hero-glass-btn-primary:hover {
    background: var(--accent);
    color: var(--ink);
    filter: none;
    transform: translate(-3px, -3px);
    box-shadow: 4px 4px 0 0 var(--vx-shadow);
}
.btn:active, body .hero-glass-btn-primary:active { transform: translate(0, 0); box-shadow: 0 0 0 0 var(--vx-shadow); }

.btn.btn-outline,
.btn.btn-ghost,
body .hero-glass-btn-ghost {
    background: transparent;
    color: var(--text);
    border: 1.5px solid var(--vx-line);
}
.btn.btn-outline:hover,
.btn.btn-ghost:hover,
body .hero-glass-btn-ghost:hover {
    background: var(--vx-surface);
    color: var(--text);
    border-color: var(--text);
    transform: translate(-3px, -3px);
    box-shadow: 4px 4px 0 0 var(--vx-shadow);
}
body .hero-glass-btn-ghost { transition: transform .18s var(--vx-ease), box-shadow .18s var(--vx-ease), border-color .18s, background .18s; }

/* ── Section headers ──────────────────────────────────────────────────────── */
.section-header { margin-bottom: 56px; }
.section-tag {
    display: inline-flex; align-items: center; gap: 10px;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 0;
    color: var(--text2);
    font-family: var(--font-mono);
    font-size: .74rem;
    font-weight: 500;
    letter-spacing: .14em;
}
.section-tag::before {
    content: '';
    width: 9px; height: 9px;
    background: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
    border-radius: 2px;
    flex: none;
}
.section-title {
    font-size: clamp(2.2rem, 5.2vw, 3.6rem);
    font-weight: 700;
    line-height: 1.04;
    letter-spacing: -.035em;
}
.section-subtitle { font-size: 1.05rem; line-height: 1.75; }

/* ── Cards (shared) ───────────────────────────────────────────────────────── */
/* --mx/--my are set by enhance.js from the pointer position, giving each card a
   soft spotlight that follows the cursor. Without JS the spotlight sits at the
   top-left and is barely visible — the card still looks finished. */
.project-card, .blog-card, .service-card, .glass-card, .skill-chip,
.contact-info-item, .timeline-item {
    --mx: 0px; --my: 0px;
    background:
        radial-gradient(420px circle at var(--mx) var(--my), color-mix(in srgb, var(--primary) 9%, transparent), transparent 60%),
        var(--vx-surface);
    border: 1px solid var(--vx-line);
    border-radius: var(--vx-radius);
    box-shadow: none;
    transition: transform .22s var(--vx-ease), border-color .22s, box-shadow .22s var(--vx-ease);
}
.project-card:hover, .blog-card:hover, .service-card:hover, .glass-card:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--primary) 55%, transparent);
    box-shadow: 0 24px 48px -28px var(--shadow2);
}
.project-image img, .blog-image img { transition: transform .5s var(--vx-ease); }
.project-card:hover .project-image img,
.blog-card:hover .blog-image img { transform: scale(1.04); }

.project-tag, .blog-category {
    font-family: var(--font-mono);
    font-size: .68rem;
    letter-spacing: .04em;
}

.service-icon {
    background: var(--accent) !important;
    color: var(--ink) !important;
    border-radius: calc(var(--vx-radius) - 2px);
}

/* Skill chips: compact tiles with an icon square. */
.skill-chip { font-weight: 600; }
.skill-chip i { color: var(--primary); }
.skill-chip:hover { border-color: var(--accent); transform: translateY(-2px); }

/* ── Glass hero (default home hero) ───────────────────────────────────────── */
body .hero-glass { background: transparent; }
body .hero-glass-orb.a { background: var(--primary); opacity: .14; filter: blur(80px); }
body .hero-glass-orb.b { background: var(--accent);  opacity: .10; filter: blur(80px); }
body .hero-glass-card {
    background: transparent;
    border: 0;
    padding-inline: 0;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
@media (min-width: 768px) { body .hero-glass-card { padding: 0; backdrop-filter: none; -webkit-backdrop-filter: none; } }
body .hero-glass-badge {
    display: inline-flex; align-items: center; gap: 9px;
    background: var(--vx-surface);
    border: 1px solid var(--vx-line);
    color: var(--text);
    font-family: var(--font-mono);
    font-weight: 500;
    letter-spacing: .02em;
}
body .hero-glass-badge::before {
    content: '';
    width: 8px; height: 8px; border-radius: 50%;
    background: #22c55e;
    box-shadow: 0 0 0 0 rgba(34,197,94,.6);
    animation: vx-pulse 2s infinite;
}
body .hero-glass h1 {
    font-family: var(--font-display);
    font-size: clamp(2.6rem, 7.4vw, 5.6rem);
    font-weight: 700;
    line-height: .98;
    letter-spacing: -.045em;
    margin-bottom: 22px;
}
body .hero-glass h1 .grad {
    display: inline;
    background: none;
    -webkit-text-fill-color: currentColor;
    color: var(--text);
    /* Highlighter stroke behind the name — volt fill, ink-safe text on top. */
    background-image: linear-gradient(transparent 62%, color-mix(in srgb, var(--accent) 85%, transparent) 62%, color-mix(in srgb, var(--accent) 85%, transparent) 92%, transparent 92%);
    -webkit-box-decoration-break: clone;
            box-decoration-break: clone;
    padding-inline: .06em;
}
body .hero-glass-sub { font-size: clamp(1.02rem, 1.6vw, 1.2rem); max-width: 54ch; }
body .hero-glass-stats { border-top: 1px dashed var(--vx-line); gap: 18px; }
body .hero-glass-stat .num {
    font-family: var(--font-display);
    font-size: clamp(1.8rem, 5vw, 2.8rem);
    font-weight: 700;
    color: var(--text);
    letter-spacing: -.04em;
}
body .hero-glass-stat .lbl { font-family: var(--font-mono); letter-spacing: .1em; }
body .hero-glass-img { position: relative; }
body .hero-glass-img img {
    border-radius: calc(var(--vx-radius) + 8px);
    border: 1.5px solid var(--text);
    box-shadow: 12px 12px 0 0 var(--accent);
}
@media (min-width: 900px) {
    body .hero-glass-img::after {
        /* "spec tag" pinned to the portrait — reads the hero badge text via the
           data attribute enhance.js copies over; hidden when there isn't one. */
        content: attr(data-spec);
        position: absolute; left: -22px; bottom: 34px;
        padding: 8px 14px;
        background: var(--vx-surface);
        border: 1.5px solid var(--text);
        border-radius: 10px;
        font: 600 .78rem/1.2 var(--font-mono);
        color: var(--text);
        box-shadow: 4px 4px 0 0 var(--vx-shadow);
    }
    body .hero-glass-img:not([data-spec])::after { display: none; }
}

/* ── Page heroes (projects / blog / services headers) ─────────────────────── */
.page .section-header h1.section-title,
.page > .section-header .section-title { font-size: clamp(2.6rem, 6.4vw, 4.4rem); }

/* ── Forms ────────────────────────────────────────────────────────────────── */
.form-control {
    background: var(--vx-surface);
    border: 1.5px solid var(--vx-line);
    border-radius: var(--vx-radius);
    transition: border-color .18s, box-shadow .18s;
}
.form-control:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 18%, transparent);
    outline: none;
}

/* ── Pagination ───────────────────────────────────────────────────────────── */
.page-btn { font-family: var(--font-display); font-weight: 700; border-radius: 10px; }
.page-btn.active, .pagination .active { background: var(--accent) !important; color: var(--ink) !important; border-color: var(--accent) !important; }

/* ── Footer ───────────────────────────────────────────────────────────────── */
footer, .footer { position: relative; }
footer::before, .footer::before {
    content: '';
    position: absolute; top: 0; left: 0; right: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--accent) 0 18%, var(--primary) 18% 36%, transparent 36%);
}
.footer-logo { font-family: var(--font-display); letter-spacing: -.03em; }

#backToTop {
    background: var(--accent) !important;
    color: var(--ink) !important;
    border: 1.5px solid var(--text) !important;
    border-radius: 12px !important;
}

/* ============================================================================
   NEW COMPONENTS (rendered by enhance.js / footer.php)
============================================================================ */

/* ── Skills marquee (homepage) ────────────────────────────────────────────── */
.vx-marquee {
    position: relative;
    overflow: hidden;
    border-block: 1px solid var(--vx-line);
    padding: 18px 0;
    margin: 0 0 8px;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
            mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.vx-marquee-track {
    display: flex; gap: 44px;
    width: max-content;
    animation: vx-marquee 38s linear infinite;
}
.vx-marquee:hover .vx-marquee-track { animation-play-state: paused; }
.skills-grid.vx-replaced { display: none; }
.vx-marquee-item {
    display: inline-flex; align-items: center; gap: 12px;
    font: 700 clamp(1.1rem, 2.2vw, 1.5rem)/1 var(--font-display);
    letter-spacing: -.02em;
    color: var(--text);
    white-space: nowrap;
}
.vx-marquee-item i { color: var(--primary); font-size: .85em; }
.vx-marquee-item::after { content: '✦'; color: var(--accent); margin-left: 32px; font-size: .7em; -webkit-text-stroke: .5px var(--text); }

/* ── Blog: table of contents ──────────────────────────────────────────────── */
.vx-toc { font-size: .86rem; }
.vx-toc-title {
    display: flex; align-items: center; gap: 10px;
    margin: 0 0 12px;
    font: 800 .7rem/1 var(--font-mono);
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--primary);
}
.vx-toc-title::after { content: ''; flex: 1; height: 1px; background: var(--border); }
.vx-toc ol { list-style: none; margin: 0; padding: 0; border-left: 1px solid var(--vx-line); }
.vx-toc li { margin: 0; }
.vx-toc a {
    display: block;
    padding: 6px 0 6px 14px;
    margin-left: -1px;
    border-left: 2px solid transparent;
    color: var(--text3);
    text-decoration: none;
    line-height: 1.4;
    transition: color .15s, border-color .15s;
}
.vx-toc li.lvl-3 a { padding-left: 28px; font-size: .82rem; }
.vx-toc a:hover { color: var(--text); }
.vx-toc a.is-active { color: var(--text); border-left-color: var(--accent); font-weight: 600; }
/* Inline variant (templates without a side rail): a collapsible box above the
   article body. */
details.vx-toc-inline {
    margin: 0 0 28px;
    padding: 14px 18px;
    border: 1px solid var(--vx-line);
    border-radius: var(--vx-radius);
    background: var(--vx-surface);
}
details.vx-toc-inline summary {
    cursor: pointer;
    font: 700 .78rem/1.4 var(--font-mono);
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--primary);
    list-style: none;
}
details.vx-toc-inline summary::-webkit-details-marker { display: none; }
details.vx-toc-inline summary::before { content: '▸ '; display: inline-block; transition: transform .15s; }
details.vx-toc-inline[open] summary::before { transform: rotate(90deg); }
details.vx-toc-inline ol { margin-top: 12px; }

/* ── Blog: heading anchors and code copy ──────────────────────────────────── */
.vx-anchor {
    margin-left: .35em;
    color: var(--text3);
    opacity: 0;
    text-decoration: none;
    font-weight: 400;
    transition: opacity .15s;
}
:is(h2, h3):hover > .vx-anchor, .vx-anchor:focus-visible { opacity: 1; }
.vx-code-wrap { position: relative; }
.vx-copy {
    position: absolute; top: 8px; right: 8px;
    padding: 5px 10px;
    border: 1px solid var(--vx-line);
    border-radius: 8px;
    background: var(--vx-surface);
    color: var(--text2);
    font: 600 .72rem/1 var(--font-mono);
    cursor: pointer;
    opacity: .85;
    transition: opacity .15s, color .15s, border-color .15s;
}
.vx-copy:hover { opacity: 1; color: var(--text); border-color: var(--text); }
.vx-copy.is-done { background: var(--accent); color: var(--ink); border-color: var(--accent); }

/* ── Sticky mobile "hire" bar ─────────────────────────────────────────────── */
.vx-mobile-cta { display: none; }
@media (max-width: 768px) {
    .vx-mobile-cta {
        display: flex; align-items: center; gap: 10px;
        position: fixed; left: 12px; right: 12px;
        bottom: max(12px, env(safe-area-inset-bottom));
        z-index: 900;
        padding: 8px 8px 8px 16px;
        border: 1.5px solid var(--text);
        border-radius: 16px;
        background: var(--vx-surface);
        box-shadow: 4px 4px 0 0 var(--vx-shadow);
        transform: translateY(calc(100% + 24px));
        transition: transform .3s var(--vx-ease);
    }
    .vx-mobile-cta.is-visible { transform: none; }
    .vx-mobile-cta-text { flex: 1; min-width: 0; font: 600 .82rem/1.25 var(--font-display); color: var(--text); }
    .vx-mobile-cta-text small { display: block; font: 500 .68rem/1.3 var(--font-mono); color: var(--text3); }
    .vx-mobile-cta .btn { padding: 12px 16px; min-height: 44px; }
    /* Keep the back-to-top button clear of the bar while it is showing. */
    body.vx-cta-up #backToTop { bottom: 92px !important; }
}

/* ── Keyframes ────────────────────────────────────────────────────────────── */
@keyframes vx-marquee { to { transform: translateX(-50%); } }
@keyframes vx-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(34,197,94,.55); }
    70%  { box-shadow: 0 0 0 9px rgba(34,197,94,0); }
    100% { box-shadow: 0 0 0 0 rgba(34,197,94,0); }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    @view-transition { navigation: none; }
    /* No scrolling: show the list once, as a wrapped row of chips. */
    .vx-marquee { -webkit-mask-image: none; mask-image: none; border: 0; }
    .vx-marquee-track { animation: none; flex-wrap: wrap; width: auto; justify-content: center; gap: 10px; }
    .vx-marquee-item[aria-hidden="true"] { display: none; }
    .vx-marquee-item { font-size: 1rem; padding: 10px 16px; border: 1px solid var(--vx-line); border-radius: var(--vx-radius); background: var(--vx-surface); }
    .vx-marquee-item::after { display: none; }
    body .hero-glass-badge::before { animation: none; }
    .btn:hover, body .hero-glass-btn-primary:hover, body .hero-glass-btn-ghost:hover,
    .project-card:hover, .blog-card:hover, .service-card:hover, .glass-card:hover { transform: none; }
}

@media print {
    body::before, .vx-mobile-cta, .vx-copy, .vx-anchor { display: none !important; }
}
