/* =============================================================================
   NODELYNC — Shared design tokens and component styles.
   Dark navy scheme. Linked by the homepage (EN + ES); other pages still carry
   inline copies until they are converted.
   ============================================================================= */

:root {
  /* Surfaces — deep navy base, lighter navy for cards and alternating bands */
  --surface: #050b18;
  --surface-soft: #0b1a33;
  --surface-raised: #13284a;
  --line: #1c2d4d;

  /* Text on dark. Ratios against --surface: 19.7, 13.4, 8.1 */
  --ink: #ffffff;
  --ink-soft: #c9d6ee;
  --ink-faint: #8fa7d1;

  /* Brand blue, sampled from the logo mark.
     --primary is a FILL colour: at 3.8:1 on navy it fails as small text.
     Use --primary-light (7.6:1) whenever blue needs to be readable text. */
  --primary: #005ffc;
  --primary-dark: #0043dc;
  --primary-light: #2ca8fc;

  --radius-card: 1.25rem;
  --radius-section: 2rem;

  /* Makes native form controls (checkbox, radio, select popup, scrollbars)
     render dark. Without this they are white boxes on navy. */
  color-scheme: dark;
}

@font-face {
  font-family: 'OCR A Extended';
  src: url('/fonts/OCRAEXT.TTF') format('truetype');
  font-display: swap;
}

/* --- Focus states --- */
:where(a, button, [tabindex]):focus-visible {
  outline: 3px solid var(--primary-light);
  outline-offset: 3px;
  border-radius: 4px;
}

/* --- Nav --- */
nav.scrolled { box-shadow: 0 8px 30px rgba(0, 0, 0, .5); }

@keyframes navSlideDown {
  from { opacity: 0; transform: translateY(-10px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (max-width: 767px) {
  #navLinks { display: none !important; }
  #navLinks.open {
    display: flex !important;
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
    /* Anchored to the nav itself so the panel stays flush if nav height changes. */
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    /* Fully opaque: the panel sits over the video hero, and any translucency
       let high-contrast hero text ghost through. */
    background: var(--surface);
    padding: 28px 32px;
    border-bottom: 1px solid var(--line);
    z-index: 40;
    animation: navSlideDown .22s cubic-bezier(.16, 1, .3, 1) both;
  }
}

/* --- Panels and cards --- */
.card-soft {
  background: var(--surface-soft);
  border: 1px solid var(--line);
  box-shadow: 0 10px 30px -12px rgba(0, 0, 0, .6);
}

.card-glass {
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(120, 160, 255, .22);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

/* Brand gradient band — replaces the old light `ethereal-gradient`. */
.ethereal-gradient {
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
}

/* Blurred ambient background blobs. */
.orb-float {
  filter: blur(60px);
  opacity: .35;
  z-index: -1;
}

@keyframes gentleFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}
.gentle-float { animation: gentleFloat 3s ease-in-out infinite; }

/* Node/connection motif — echoes the "Nodelync" name without extra requests. */
.node-grid {
  background-image:
    radial-gradient(circle, rgba(44, 168, 252, .5) 1.5px, transparent 1.5px),
    linear-gradient(to right, rgba(80, 140, 255, .09) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(80, 140, 255, .09) 1px, transparent 1px);
  background-size: 72px 72px, 72px 72px, 72px 72px;
}

/* --- Sticky mobile WhatsApp --- */
.whatsapp-fab {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 60;
  box-shadow: 0 10px 30px -6px rgba(37, 211, 102, .55);
}
@media (min-width: 768px) { .whatsapp-fab { display: none; } }

/* --- Motion --- */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .65s cubic-bezier(.16, 1, .3, 1), transform .65s cubic-bezier(.16, 1, .3, 1);
}
.reveal.visible { opacity: 1; transform: none; }

@keyframes heroIn {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}
.hero-item { animation: heroIn .7s cubic-bezier(.16, 1, .3, 1) both; }
.hero-item-1 { animation-delay: 0ms; }
.hero-item-2 { animation-delay: 130ms; }
.hero-item-3 { animation-delay: 260ms; }
.hero-item-4 { animation-delay: 390ms; }

@keyframes statIn {
  from { opacity: 0; transform: translateY(24px) scale(.95); }
  to { opacity: 1; transform: none; }
}
.stat-reveal { opacity: 0; }
.stat-reveal.visible { animation: statIn .65s cubic-bezier(.16, 1, .3, 1) both; opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal.visible { opacity: 1; transform: none; transition: none; }
  .hero-item { animation: none; }
  .stat-reveal { opacity: 1; }
  .stat-reveal.visible { animation: none; }
  .review-card { transition: none; }
  .gentle-float { animation: none; }
}

/* =============================================================================
   FORMS
   One vocabulary for both questionnaires and both contact pages. The EN and ES
   questionnaires had diverged onto two different sets of class names; this is
   the union of the two, so either page's markup works against it.

   `.checkbox-item` is a main.js contract: it must stay on the <label>, with the
   <input> nested inside it. main.js calls input.closest('.checkbox-item') with
   no null guard.
   ============================================================================= */

.form-label {
  display: block;
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: .875rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: .5rem;
}

.form-hint {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: .75rem;
  color: var(--ink-faint);
  margin-bottom: .5rem;
}

/* Element-qualified on purpose. The Tailwind `forms` plugin publishes its own
   .form-input / .form-select / .form-textarea classes and is injected after
   this stylesheet, so a bare .form-input (0,1,0) loses the cascade and the
   fields render white-on-white. Adding the element bumps us to (0,1,1). */
input.form-input,
select.form-input,
textarea.form-input,
select.form-select,
textarea.form-textarea {
  width: 100%;
  padding: .75rem 1rem;
  border: 1px solid var(--line);
  border-radius: .75rem;
  background-color: rgba(255, 255, 255, .04);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: .9375rem;
  color: var(--ink);
  outline: none;
  transition: border-color .2s, box-shadow .2s;
}

input.form-input::placeholder,
textarea.form-input::placeholder,
textarea.form-textarea::placeholder { color: var(--ink-faint); }

input.form-input:focus,
select.form-input:focus,
textarea.form-input:focus,
select.form-select:focus,
textarea.form-textarea:focus {
  border-color: var(--primary-light);
  box-shadow: 0 0 0 3px rgba(44, 168, 252, .18);
}

textarea.form-input,
textarea.form-textarea { resize: vertical; min-height: 100px; }

/* Both questionnaires style selects, but EN uses .form-input for them. */
select.form-select,
select.form-input {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 2.5rem;
  /* Chevron tinted to --ink-soft (#c9d6ee); the old copy baked in a dark grey. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23c9d6ee' viewBox='0 0 16 16'%3E%3Cpath d='M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
}

/* The native option popup is OS-rendered, not styled by the rules above.
   `appearance: none` on the <select> makes Chromium stop reliably applying
   `color-scheme: dark` to that popup, so without this it can render white
   text with no guaranteed dark background underneath — illegible. Chromium
   (unlike most other custom <select> styling) DOES honor color/background
   set directly on <option>, so this is the fix rather than a workaround. */
select.form-select option,
select.form-input option {
  background-color: var(--surface-soft);
  color: var(--ink);
}

.form-section-title {
  font-family: 'OCR A Extended', ui-monospace, monospace;
  font-size: .9rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--primary-light);
  margin-bottom: .25rem;
  padding-bottom: .75rem;
  border-bottom: 1px solid var(--line);
}

.form-section-sub {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: .875rem;
  color: var(--ink-faint);
  margin-top: .25rem;
  margin-bottom: 1.5rem;
}

.form-divider {
  border: none;
  height: 1px;
  background: var(--line);
  margin: 2.5rem 0;
}

.checkbox-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
.checkbox-grid.budget-grid { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 768px) { .checkbox-grid.budget-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) { .checkbox-grid, .checkbox-grid.budget-grid { grid-template-columns: 1fr; } }

.checkbox-item {
  display: flex;
  align-items: center;
  gap: .625rem;
  padding: .75rem 1rem;
  border: 1px solid var(--line);
  border-radius: .75rem;
  background: rgba(255, 255, 255, .03);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: .875rem;
  color: var(--ink-soft);
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}

.checkbox-item:hover {
  border-color: var(--primary-light);
  background: rgba(44, 168, 252, .07);
}

/* main.js adds .checked. The ES questionnaire never defined this rule, so ES
   users got no selected-state feedback at all — sharing the CSS fixes that. */
.checkbox-item.checked {
  border-color: var(--primary-light);
  background: rgba(44, 168, 252, .12);
  color: var(--ink);
}

.checkbox-item input {
  accent-color: var(--primary-light);
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  cursor: pointer;
}

/* --- Reviews carousel (class names are a main.js contract) --- */
.review-card { transition: opacity .3s ease, transform .3s ease; }
.review-card.leaving { opacity: 0; transform: translateY(-20px); }
.review-card.entering-start { opacity: 0; transform: translateY(20px); }
.review-card.hidden-review { display: none; }

.review-dot {
  width: 8px;
  height: 8px;
  border-radius: 9999px;
  background: rgba(120, 160, 255, .3);
  transition: background .2s ease, width .2s ease;
  border: none;
  padding: 0;
  cursor: pointer;
}
.review-dot.active { background: var(--primary-light); width: 20px; }
