
/* ========================================
   CSS RESET
======================================== */

*,
*::before,
*::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}


/* ========================================
   THEME TOKENS
   All colours live here. Components only use these variables, so a
   theme is just a different set of values on <html data-theme="…">.
   The initial theme is set by an inline script in <head> (no flash).
======================================== */

/* Palette: "Petróleo + Dorado". Petrol teal leads (links, active nav,
   progress, interactive details); muted gold supports it (secondary CTA,
   highlighted labels, small decorative accents). The two are never used
   together on large surfaces.
   Text tokens marked (AA) keep the palette hue but are adjusted slightly
   so small text / button labels reach WCAG AA 4.5:1. */

/* ---------- Dark theme (default) ---------- */

:root,
:root[data-theme="dark"] {
    color-scheme: dark;

    /* Brand accents */
    --primary: #3E9E94;          /* (AA) palette #3D9B91: 4.41:1 on cards */
    --primary-rgb: 61, 155, 145;
    --primary-fill: #3D9B91;
    --primary-fill-hover: #55B0A5;

    --secondary: #D6AD62;
    --secondary-rgb: 214, 173, 98;
    --secondary-fill: #D6AD62;
    --secondary-fill-hover: #E4BE7A;

    --on-accent: #101820;

    /* Text */
    --text-strong: #F5F7F8;
    --text-soft: #E5EBEF;
    --text: #CCD6DC;
    --text-muted: #A7B5BE;
    --text-subtle: #8797A2;
    --line-muted: #52616B;

    /* Backgrounds and surfaces */
    --bg: #17232D;
    --bg-deep: #101820;
    --surface-rgb: 16, 24, 32;
    --surface-2-rgb: 27, 42, 53;
    --field-bg: #101820;
    --track: rgba(167, 181, 190, 0.15);
    --hairline: rgba(255, 255, 255, 0.08);

    /* Glows */
    --cyan-glow: rgba(61, 155, 145, 0.12);
    --orange-glow: rgba(214, 173, 98, 0.12);

    /* Shadows */
    --shadow-color: rgba(0, 0, 0, 0.25);
    --card-shadow: none;

    /* Logo */
    --logo-plate: transparent;
}

/* ---------- Light theme ---------- */

:root[data-theme="light"] {
    color-scheme: light;

    /* Brand accents */
    --primary: #286F68;
    --primary-rgb: 61, 155, 145;
    --primary-fill: #3D9B91;
    --primary-fill-hover: #388E85; /* (AA) palette #327F77: 3.78:1 with --on-accent */

    --secondary: #87642C;        /* (AA) palette #8B672D: 4.38:1 on --bg-deep */
    --secondary-rgb: 214, 173, 98;
    --secondary-fill: #D6AD62;
    --secondary-fill-hover: #C69B4E;

    --on-accent: #101820;

    /* Text */
    --text-strong: #26343D;
    --text-soft: #354650;
    --text: #485963;
    --text-muted: #5E6C75;
    --text-subtle: #606C74;
    --line-muted: #B3BEC5;

    /* Backgrounds and surfaces */
    --bg: #F1F3F5;
    --bg-deep: #E9EDF0;
    --surface-rgb: 255, 255, 255;
    --surface-2-rgb: 246, 248, 249;
    --field-bg: #FFFFFF;
    --track: rgba(38, 52, 61, 0.1);
    --hairline: rgba(38, 52, 61, 0.1);

    /* Glows */
    --cyan-glow: rgba(61, 155, 145, 0.08);
    --orange-glow: rgba(139, 103, 45, 0.08);

    /* Shadows */
    --shadow-color: rgba(38, 52, 61, 0.06);
    --card-shadow:
        0 1px 2px rgba(38, 52, 61, 0.04),
        0 6px 20px rgba(38, 52, 61, 0.05);

    /* Logo */
    --logo-plate: #26343D;
}

/* ========================================
   NON-COLOUR VARIABLES
======================================== */

:root {
    /* Derived colour token (follows the active theme) */
    --border-color: rgba(var(--primary-rgb), 0.2);

    /* Typography */
    --font-display: 'Orbitron', 'Segoe UI', sans-serif;
    --font-body: 'Montserrat', 'Segoe UI', sans-serif;
    --font-tech: 'Rajdhani', 'Segoe UI', sans-serif;

    /* Layout: the container grows progressively from 1200px to 1440px
       on large screens (1846px+ viewports reach the maximum) */
    --container-width: clamp(1200px, 78vw, 1440px);
    --gutter: 1.5rem;
    --section-space: clamp(5rem, 2.5rem + 3.5vw, 7.5rem);
    --nav-height: 85px;

    /* Transitions */
    --transition-fast: 0.3s ease;
    --transition-normal: 0.5s ease;

    /* Motion ("signals travel"): short distances, soft deceleration */
    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --reveal-distance: 12px;
    --reveal-duration: 420ms;
}


/* ========================================
   GLOBAL ELEMENTS
======================================== */

html {
    min-height: 100%;
    scroll-behavior: smooth;
    scroll-padding-top: var(--nav-height);
    background: linear-gradient(135deg, var(--bg), var(--bg-deep));
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    min-height: 100vh;
    overflow-x: hidden;
    color: var(--text-strong);
}

/* Lock page scroll while the mobile menu is open */
body.menu-open {
    overflow: hidden;
}


/* ========================================
   MEDIA ELEMENTS
======================================== */

img,
svg,
video {
    display: block;
    max-width: 100%;
    height: auto;
}


/* ========================================
   LINKS, BUTTONS AND FORMS
======================================== */

a {
    color: inherit;
}

button {
    cursor: pointer;
    border: none;
    color: inherit;
}

input,
textarea,
button {
    font: inherit;
}


/* ========================================
   FOCUS STATES
======================================== */

:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 3px;
}

/* Scroll containers receive focus for keyboard scrolling */
[tabindex="0"]:focus-visible {
    outline-offset: 4px;
}


/* ========================================
   UTILITIES
======================================== */

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: fixed;
    display: inline-block;
    top: 0.75rem;
    left: 0.75rem;
    z-index: 2000;
    padding: 0.75rem 1rem;
    background: var(--primary-fill);
    color: var(--on-accent);
    font-weight: 700;
    text-decoration: none;
    transform: translateY(-200%);
    transition: transform var(--transition-fast);
}

.skip-link:focus {
    transform: translateY(0);
}


/* ========================================
   SELECTION
======================================== */

::selection {
    background: var(--primary-fill);
    color: var(--on-accent);
}


/* ========================================
   RESPONSIVE VARIABLES
======================================== */

@media (max-width: 850px) {
    :root {
        --nav-height: 70px;
    }
}

@media (max-width: 768px) {
    :root {
        --gutter: 1rem;
        --section-space: 4rem;
    }
}

@media (max-width: 480px) {
    :root {
        --section-space: 3.5rem;
    }
}


/* ========================================
   THEME TRANSITION
   theme.js adds .theme-transition to <html> only while switching,
   so colours never animate on page load (and not at all with
   prefers-reduced-motion).
======================================== */

html.theme-transition,
html.theme-transition *,
html.theme-transition *::before,
html.theme-transition *::after {
    transition:
        background-color 0.35s ease,
        color 0.35s ease,
        border-color 0.35s ease,
        box-shadow 0.35s ease,
        fill 0.35s ease !important;
    transition-delay: 0s !important;
}


/* ========================================
   SPINNER (reusable)
   <span class="spinner" aria-hidden="true"></span>
   Size follows the font size; colour follows currentColor.
======================================== */

.spinner {
    display: inline-block;
    flex-shrink: 0;
    width: 1.1em;
    height: 1.1em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spinner-rotate 0.75s linear infinite;
}

@keyframes spinner-rotate {
    to {
        transform: rotate(360deg);
    }
}

@keyframes spinner-pulse {
    0%, 100% {
        opacity: 1;
    }

    50% {
        opacity: 0.35;
    }
}


/* ========================================
   SCROLL REVEAL ("signals travel")
   - The inline script in <head> adds .motion to <html> only when
     motion is allowed and IntersectionObserver exists. Without it
     (no JS, reduced motion, old browser) nothing is ever hidden.
   - reveal.js adds .is-visible once per element; it never repeats.
   - Only opacity/transform/scale are animated: no layout shift.
   Variants (data-reveal="…"):
     rise (default) · fade · line (draws from the left) · trace (draws down)
   Stagger: elements inside [data-reveal-group] get --reveal-delay.
======================================== */

.motion [data-reveal] {
    transition:
        opacity var(--reveal-duration) var(--ease-out),
        transform var(--reveal-duration) var(--ease-out);
    transition-delay: var(--reveal-delay, 0ms);
}

.motion [data-reveal]:not(.is-visible) {
    opacity: 0;
    transform: translateY(var(--reveal-distance));
}

.motion [data-reveal="fade"]:not(.is-visible) {
    transform: none;
}

.motion [data-reveal="line"] {
    transform-origin: left center;
    transition-duration: 700ms;
}

.motion [data-reveal="line"]:not(.is-visible) {
    opacity: 1;
    transform: scaleX(0);
}

/* Vertical variant: a trace drawn from the top (Skillset signal bus) */
.motion [data-reveal="trace"] {
    transform-origin: top center;
    transition-duration: 1100ms;
}

.motion [data-reveal="trace"]:not(.is-visible) {
    opacity: 1;
    transform: scaleY(0);
}

/* After the reveal finishes, reveal.js removes [data-reveal] so each
   component gets its own hover/focus transitions back. */


/* ========================================
   HERO ENTRANCE (CSS only, runs once on load)
======================================== */

@keyframes hero-in {
    from {
        opacity: 0;
        transform: translateY(var(--reveal-distance));
    }
}

/* Text that can be the LCP element (headline, subtitle, description)
   only moves: it is painted at full opacity from the first frame, so the
   entrance never delays Largest Contentful Paint. */
@keyframes hero-in-text {
    from {
        transform: translateY(var(--reveal-distance));
    }
}

.motion [data-hero] {
    animation: hero-in 480ms var(--ease-out) both;
    animation-delay: calc(var(--hero-step, 0) * 70ms);
}

.motion [data-hero="text"] {
    animation-name: hero-in-text;
    animation-delay: 0ms;
}


/* ========================================
   VIEW TRANSITIONS (progressive enhancement)
   - Theme switch: theme.js wraps the change in
     document.startViewTransition() when supported → soft cross-fade.
   - Language switch (/ ↔ /en/): cross-document transition.
   Unsupported browsers simply switch instantly.
======================================== */

@media (prefers-reduced-motion: no-preference) {
    @view-transition {
        navigation: auto;
    }
}

::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 320ms;
    animation-timing-function: ease;
}

/* The fixed navbar stays in place during transitions */
#navbar {
    view-transition-name: site-navbar;
}


/* ========================================
   REDUCED MOTION
======================================== */

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    /* Keep a loading cue without rotation: a gentle opacity pulse */
    .spinner {
        animation-name: spinner-pulse !important;
        animation-duration: 1.6s !important;
        animation-timing-function: ease-in-out !important;
        animation-iteration-count: infinite !important;
        border-right-color: currentColor;
        border-style: dotted;
    }
}
