// Carlota Rezola — Creative Direction & Strategy
// Core Interactivity Controller (Vanilla TypeScript / DOM Engine)

interface Project {
  id: string;
  title: string;
  category: string;
  tagline: string;
  overview: string;
  services: string[];
  year: number;
  imageUrl: string;
  featured: boolean;
  client: string;
  duration: string;
}

interface Capability {
  title: string;
  text: string;
  list: string[];
}

interface ChronicleItem {
  id: string;
  period: string;
  role: string;
  company: string;
  details: string[];
  highlight?: boolean;
}

interface Inquiry {
  id: string;
  name: string;
  email: string;
  service: string;
  budget: string;
  vision: string;
  timestamp: string;
}

// ----------------================ DATA SOURCE ================----------------

const projects: Project[] = [
  {
    id: "musee-noir",
    title: "Musee Noir",
    category: "BRANDING",
    tagline: "A dark contemporary luxury aesthetic.",
    overview: "A complete identity and brand philosophy for Musee Noir, an avant-garde boutique curated in Milan. Focused on raw textures, minimal geometry, and a high-contrast ink-on-stone look.",
    services: ["Creative Direction", "Brand Identity", "Typeface Curation", "Visual Guidelines"],
    year: 2024,
    imageUrl: "https://lh3.googleusercontent.com/aida-public/AB6AXuBUSihYma1jYaE-VDDjXHO8niBl7DgcBK-lIYCPyGgM_qYQN2uli464PgKM5mDoMmXr26PoF7iu9Tg2977geYqB6_AopsTqg3NCunxdFsGJtS95mTAkToE_a_5xcgMDwKWKQb4c41lkxpgyXfzm_fXF3EtnJ4pYZOblGrQJ5PbyP7H6IPk88OZeW9NlJ5rXaHU5RUN83IWiRFr8EWhJzPNIXVaPKYhZr8NT8JXhrdTdVA0KT1dzoS33uKiaiS2n0-9qJCdmfdDyaILu",
    featured: true,
    client: "Musee Noir Milan",
    duration: "4 Months"
  },
  {
    id: "silent-motion",
    title: "Silent Motion",
    category: "CONTENT CREATION",
    tagline: "Capturing human motion in serene spaces.",
    overview: "An artistic film and lookbook series developed to celebrate silent movement. Centered around architectural lines in Madrid's Brutalist structures, it merges haute couture garments with slow shadow play.",
    services: ["Art Direction", "Cinematography", "Digital Content Strategy", "Print Lookbook"],
    year: 2023,
    imageUrl: "/src/assets/images/regenerated_image_1782238515071.jpg",
    featured: true,
    client: "National Dance Ensemble Context",
    duration: "6 Months"
  },
  {
    id: "levis-campaign",
    title: "Built for Scape. Worn for Life.",
    category: "STRATEGY",
    tagline: "Strategic brand relaunch.",
    overview: "A high-impact campaign that repositions rigid denim inside fluid urban architecture. Developed to target metropolitan creators seeking durability without compromising aesthetic purity.",
    services: ["Campaign Strategy", "Layout Design", "Typography", "Copywriting"],
    year: 2023,
    imageUrl: "/src/assets/images/regenerated_image_1782239046026.png",
    featured: false,
    client: "Levi's Spain",
    duration: "3 Months"
  },
  {
    id: "tomorrowland",
    title: "High Energy. Low Impact.",
    category: "CONTENT CREATION",
    tagline: "Sustainable rave visuals.",
    overview: "A futuristic digital installation and scenic identity for Tomorrowland's new eco-conscious underground stage. The system links live energy metrics with raw aesthetic geometry.",
    services: ["Scenic Ideation", "Kinetic Visuals", "Environmental Design"],
    year: 2024,
    imageUrl: "/src/assets/images/regenerated_image_1782239047247.png",
    featured: false,
    client: "Tomorrowland Curation Group",
    duration: "5 Months"
  },
  {
    id: "id-magazine",
    title: "Mess is the new Chic",
    category: "EDITORIAL",
    tagline: "Unrefined editorial fashion layout.",
    overview: "An experimental typographic exploration violating standard layout grids to reflect raw youth culture. Standard alignment is broken down to unleash pure visual rebellion.",
    services: ["Editorial Design", "Experimental Layout", "Typographic Identity"],
    year: 2023,
    imageUrl: "/src/assets/images/regenerated_image_1782239047888.png",
    featured: false,
    client: "i-D Magazine Concept",
    duration: "2 Months"
  },
  {
    id: "crocs-shift",
    title: "Nice Run. Now Try a Shift.",
    category: "BRANDING",
    tagline: "Modern lifestyle lookbook.",
    overview: "A complete visual shift celebrating physical transition: from the rush of a daily run to the calm posture of recovery. High-contrast studio lighting underscores the unexpected sculptural form of the shoes.",
    services: ["Creative Direction", "Studio Lighting", "Campaign Execution"],
    year: 2024,
    imageUrl: "/src/assets/images/regenerated_image_1782239049116.png",
    featured: false,
    client: "Crocs Europe",
    duration: "3 Months"
  },
  {
    id: "magtag",
    title: "MAGTAG",
    category: "EDITORIAL",
    tagline: "Innovative magnetic lifestyle system.",
    overview: "An identity project that breaks out traditional accessories to show a clean magnetic lifestyle utility ecosystem. Minimal typography aligns with structured tactile layouts.",
    services: ["Brand Framework", "Packaging Architecture", "Visual Language"],
    year: 2024,
    imageUrl: "/src/assets/images/regenerated_image_1782239050654.jpg",
    featured: false,
    client: "MAGTAG Tech",
    duration: "4 Months"
  }
];

const capabilities: Record<string, Capability> = {
  strategy: {
    title: "Strategic Acumen & Intelligence",
    text: "My consulting relies strictly on qualitative analysis and modern consumer psychology rather than arbitrary styling templates. I build structural formulas that translate technical advantages into pristine messaging models and premium market authority.",
    list: [
      "Consumer Psychology Analytical Models",
      "Dynamic Brand Positioning Strategy",
      "Aesthetic Trend Forecasting Data",
      "Data-Informed Visual Narrative Design",
      "Bilingual Strategy Workshop Curation",
      "Multi-Channel Campaign Architecture"
    ]
  },
  design: {
    title: "Tactile & Digital Design Ecosystem",
    text: "Stripping down clutter is a technical challenge. I curate layouts, grid geometries, and contrast standards to guarantee that brand publications, books, and campaigns stand beautifully on modern and legacy screens alike.",
    list: [
      "Editorial Print Layouts & Publications",
      "Comprehensive Luxury Creative Direction",
      "High-Contrast Typography Systems",
      "Geometric Brand Identity Systems",
      "Aesthetic Grid Engineering Protocols",
      "Fine Luxury Packaging Architecture"
    ]
  },
  ecosystem: {
    title: "Tools & Multi-Disciplinary Frameworks",
    text: "A modern creative director must operate natively across both digital and physical spectrums. I leverage a custom tech stack of figma templates and local tailwind frameworks to accelerate the conceptual-to-market validation loop.",
    list: [
      "Figma / Adobe Creative Suite Custom Workflows",
      "HTML5 / CSS3 / Tailwind Layout Engineering",
      "Tactile Print Material & Stock Procurement",
      "Creative Portrait & Product Studio Lighting",
      "Cinematography Production Protocols",
      "High-Fidelity Interaction Prototyping"
    ]
  }
};

const chronicleItems: ChronicleItem[] = [
  {
    id: "roi-up",
    period: "2021 — PRESENT",
    role: "Senior Strategic Consultant & Team Lead",
    company: "ROI UP Group — Madrid, Spain",
    details: [
      "Orchestrate creative directions and positioning strategies for multi-national luxury and high-growth retail brands across Europe.",
      "Manage a multidisciplinary team of designers, copywriters, and performance strategists, resulting in 43% average increases in engagement.",
      "Lead client workshops to transform qualitative consumer psychology data into actionable, high-contrast visual brand guidelines.",
      "Successfully pitch and secure creative contracts worth over €1.2M annually."
    ],
    highlight: true
  },
  {
    id: "uc3m",
    period: "2018 — 2021",
    role: "Research Fellow & Lecturer in Brand Architecture",
    company: "Universidad Carlos III de Madrid — Spain",
    details: [
      "Lectured on Brand Strategy, Contemporary Typography, and Consumer Sociology to over 400 advanced undergraduate and graduate students.",
      "Published peer-reviewed research analyzing the semantic shift of minimalism in high-end brand packaging.",
      "Coordinated with industry leaders to introduce hands-on luxury brand identity simulation modules inside the master's curriculum.",
      "Received consecutive 'Excellent' teaching evaluations for bilingual (Spanish/English) studio classes."
    ]
  },
  {
    id: "freelance",
    period: "2015 — 2018",
    role: "Independent Creative Director & Designer",
    company: "Madrid / Milan (Remote)",
    details: [
      "Collaborated with niche fashion labels, architecture firms, and cultural publication studios to build striking print and digital identities.",
      "Designed and hand-bound custom portfolio lookbooks, leveraging deep tactile materiality.",
      "Refined high-contrast vector methodologies and digital grid system standards still in use by regional design studios."
    ]
  }
];

// Initial Dummy Inquiries (Pre-seeded in localStorage so the vault never feels blank on initial preview)
const initialDummyInquiries: Inquiry[] = [
  {
    id: "CR-839-WQ12",
    name: "Milano Fashion Syndicate",
    email: "coordination@milanofashion.it",
    service: "BRANDING",
    budget: "€10,000 — €25,000",
    vision: "We require a highly tactile print publication layout for our Fall Resort showcase. Focus on raw geometries and luxury stock choice.",
    timestamp: "2026-06-08T14:24:00Z"
  },
  {
    id: "CR-214-MN58",
    name: "Built Scape Spain",
    email: "contact@builtscape.es",
    service: "STRATEGY",
    budget: "€25,000+",
    vision: "Repositioning our residential eco-architectural grid as a minimalist high-ticket collectible lifestyle. Seeking sharp typography direction.",
    timestamp: "2026-06-09T09:12:30Z"
  }
];


// ----------------================ ACTIVE STATES ================----------------

let currentTab = "work";
let currentModalProjectIndex = 0;
let activeFilter = "ALL";
let activeCapSegment = "strategy";

// Form input state holders
let selectedService = "";
let selectedBudget = "";


// ----------------================ INITIALIZER ENGINE ================----------------

function runInitialization() {
  initClock();
  initVault();
  initTabTriggers();
  initWorkPage();
  initProfilePage();
  initChroniclePage();
  initContactPage();
  initModal();
  initDrawer();
  
  // Create icons on start
  if (typeof (window as any).lucide !== "undefined") {
    (window as any).lucide.createIcons();
  }
}

if (document.readyState === "complete" || document.readyState === "interactive") {
  runInitialization();
} else {
  document.addEventListener("DOMContentLoaded", runInitialization);
}


// ----------------================ CORE FUNCTION BLOCKS ================----------------

// Timezone Madrid ticker clock
function initClock() {
  const updateTimes = () => {
    const clockEl = document.getElementById("madrid-clock");
    const mobileClockEl = document.getElementById("mobile-madrid-clock");

    try {
      const formatter = new Intl.DateTimeFormat("en-US", {
        timeZone: "Europe/Madrid",
        hour12: false,
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit"
      });

      const timeStr = formatter.format(new Date());
      const displayStr = `MAD ESP ${timeStr}`;

      if (clockEl) clockEl.textContent = displayStr;
      if (mobileClockEl) mobileClockEl.textContent = displayStr;
    } catch (e) {
      const fallbackStr = `MAD ESP ${new Date().toLocaleTimeString()}`;
      if (clockEl) clockEl.textContent = fallbackStr;
      if (mobileClockEl) mobileClockEl.textContent = fallbackStr;
    }
  };

  updateTimes();
  setInterval(updateTimes, 1000);
}


// Client Vault (localStorage syncing)
function getVaultInquiries(): Inquiry[] {
  try {
    const data = localStorage.getItem("cr_vault_inquiries");
    if (!data) {
      // Seed with pre-loaded mock records
      localStorage.setItem("cr_vault_inquiries", JSON.stringify(initialDummyInquiries));
      return initialDummyInquiries;
    }
    return JSON.parse(data);
  } catch (e) {
    console.error("Error parsing vault inquiries, resetting:", e);
    localStorage.setItem("cr_vault_inquiries", JSON.stringify(initialDummyInquiries));
    return initialDummyInquiries;
  }
}

function saveVaultInquiry(inquiry: Inquiry) {
  const current = getVaultInquiries();
  current.unshift(inquiry);
  localStorage.setItem("cr_vault_inquiries", JSON.stringify(current));
  updateVaultUI();
}

function deleteVaultInquiry(id: string) {
  const current = getVaultInquiries();
  const updated = current.filter(item => item.id !== id);
  localStorage.setItem("cr_vault_inquiries", JSON.stringify(updated));
  updateVaultUI();
}

function purgeVault() {
  if (confirm("Are you absolutely sure you want to purge all client specifications in the local archive?")) {
    localStorage.setItem("cr_vault_inquiries", JSON.stringify([]));
    updateVaultUI();
  }
}

function initVault() {
  updateVaultUI();

  // Purge button trigger
  const purgeBtn = document.getElementById("purge-vault-btn");
  if (purgeBtn) {
    purgeBtn.addEventListener("click", purgeVault);
  }
}

function updateVaultUI() {
  const list = getVaultInquiries();
  const count = list.length;

  // Render badge counters
  const badgeEl = document.getElementById("vault-badge");
  const mobileBadgeEl = document.getElementById("mobile-vault-badge");

  if (badgeEl) {
    badgeEl.textContent = String(count);
    if (count > 0) {
      badgeEl.classList.remove("hidden");
    } else {
      badgeEl.classList.add("hidden");
    }
  }

  if (mobileBadgeEl) {
    mobileBadgeEl.textContent = String(count);
    if (count > 0) {
      mobileBadgeEl.classList.remove("hidden");
    } else {
      mobileBadgeEl.classList.add("hidden");
    }
  }

  // Update list total count string
  const countStatusEl = document.getElementById("inquiry-count-status");
  if (countStatusEl) {
    countStatusEl.textContent = `${count} INQUIRY RECORD(S) RETRIEVED`;
  }

  // Re-render drawers items list
  const container = document.getElementById("inquiries-list-container");
  if (!container) return;

  if (count === 0) {
    container.innerHTML = `
      <div class="text-center py-12 border border-dashed border-ink-deep/10 text-warm-gray space-y-3">
        <i data-lucide="folder-open" class="w-8 h-8 text-neutral-300 mx-auto"></i>
        <p class="font-mono text-[9px] tracking-widest uppercase">THE ARCHIVE SHELF IS EMPTY</p>
        <p class="font-serif text-xs italic">Submit a custom strategy brief to see dynamic payloads mapped here.</p>
      </div>
    `;
    if (typeof (window as any).lucide !== "undefined") {
      (window as any).lucide.createIcons();
    }
    return;
  }

  container.innerHTML = list.map(item => {
    const cleanDate = new Date(item.timestamp).toLocaleDateString("en-US", {
      month: "short",
      day: "numeric",
      hour: "2-digit",
      minute: "2-digit"
    });

    return `
      <div class="border border-ink-deep/15 bg-white p-5 space-y-4 shadow-sm relative group/card">
        <button data-delete-id="${item.id}" class="absolute top-4 right-4 text-neutral-400 hover:text-red-600 transition-colors p-1" title="Delete record">
          <i data-lucide="trash" class="w-3.5 h-3.5"></i>
        </button>

        <div class="space-y-1">
          <div class="flex items-center gap-2">
            <span class="font-mono text-[9px] text-accent-gold font-bold tracking-widest bg-accent-gold/5 px-2 py-0.5">${item.service}</span>
            <span class="font-mono text-[8px] text-neutral-400">ID: ${item.id}</span>
          </div>
          <h4 class="font-serif text-base font-bold text-ink-deep">${escapeHtml(item.name)}</h4>
          <span class="font-mono text-[9px] text-neutral-400 block">${escapeHtml(item.email)} — BUDBET: ${item.budget}</span>
        </div>

        <blockquote class="border-l-2 border-accent-gold pl-3 font-sans text-xs text-warm-gray py-0.5 italic max-h-24 overflow-y-auto">
          "${escapeHtml(item.vision)}"
        </blockquote>

        <div class="flex items-center justify-between font-mono text-[8px] text-neutral-400 pt-2 border-t border-ink-deep/5">
          <span>TX STAMP: ${cleanDate}</span>
          <button data-copy-json-id="${item.id}" class="text-ink-deep hover:underline flex items-center gap-1 font-bold">
            <i data-lucide="copy" class="w-2.5 h-2.5"></i> COPY RAW PAYLOAD
          </button>
        </div>
      </div>
    `;
  }).join("");

  // Attach button triggers for card operations inside the list inside the drawer
  const deleteButtons = container.querySelectorAll("[data-delete-id]");
  deleteButtons.forEach(btn => {
    btn.addEventListener("click", (e) => {
      const id = btn.getAttribute("data-delete-id");
      if (id) deleteVaultInquiry(id);
    });
  });

  const copyButtons = container.querySelectorAll("[data-copy-json-id]");
  copyButtons.forEach(btn => {
    btn.addEventListener("click", (e) => {
      const id = btn.getAttribute("data-copy-json-id");
      if (!id) return;
      
      const match = list.find(item => item.id === id);
      if (match) {
        navigator.clipboard.writeText(JSON.stringify(match, null, 2));
        alert("Inquiry specifications copied to clipboard as clean JSON metadata!");
      }
    });
  });

  // Re-run icons compiler
  if (typeof (window as any).lucide !== "undefined") {
    (window as any).lucide.createIcons();
  }
}


// ----------------================ NAV TAB SWITCHING ================----------------

function initTabTriggers() {
  const triggers = document.querySelectorAll("[data-tab-trigger]");
  const mobileDrawer = document.getElementById("mobile-drawer");

  triggers.forEach(trigger => {
    trigger.addEventListener("click", () => {
      const tabName = trigger.getAttribute("data-tab-trigger");
      if (tabName) {
        switchTab(tabName);

        // Close mobile drawer on link click
        if (mobileDrawer && !mobileDrawer.classList.contains("hidden")) {
          mobileDrawer.classList.add("hidden");
          const menuToggle = document.getElementById("mobile-menu-toggle");
          if (menuToggle) {
            menuToggle.innerHTML = `<i data-lucide="menu" class="w-5 h-5"></i>`;
            if (typeof (window as any).lucide !== "undefined") {
              (window as any).lucide.createIcons();
            }
          }
        }
      }
    });
  });

  // Logo trigger resets to work tab
  const logoBtn = document.getElementById("nav-logo");
  if (logoBtn) {
    logoBtn.addEventListener("click", () => {
      switchTab("work");
      if (mobileDrawer && !mobileDrawer.classList.contains("hidden")) {
        mobileDrawer.classList.add("hidden");
        const menuToggle = document.getElementById("mobile-menu-toggle");
        if (menuToggle) {
          menuToggle.innerHTML = `<i data-lucide="menu" class="w-5 h-5"></i>`;
          if (typeof (window as any).lucide !== "undefined") {
            (window as any).lucide.createIcons();
          }
        }
      }
    });
  }

  // Anchor transitions triggers
  const gotoTriggers = document.querySelectorAll("[data-goto-tab]");
  gotoTriggers.forEach(element => {
    element.addEventListener("click", () => {
      const targetTabName = element.getAttribute("data-goto-tab");
      if (targetTabName) {
        switchTab(targetTabName);

        const servicePreset = element.getAttribute("data-goto-service");
        if (targetTabName === "contact" && servicePreset) {
          renderInquiryForm();
          setTimeout(() => {
            const targetPill = document.querySelector(`[data-service-pill="${servicePreset}"]`) as HTMLButtonElement;
            if (targetPill) {
              targetPill.click();
            }
          }, 100);
        }
      }
    });
  });
}

function switchTab(tabName: string) {
  currentTab = tabName;

  // Pages ids mapping
  const pages = {
    work: "page-work",
    profile: "page-profile",
    chronicle: "page-chronicle",
    contact: "page-contact"
  };

  // Hide all sections, show the select one
  Object.entries(pages).forEach(([key, id]) => {
    const container = document.getElementById(id);
    if (container) {
      if (key === tabName) {
        container.classList.remove("hidden");
        container.classList.add("fade-in-up");
        window.scrollTo({ top: 0, behavior: "smooth" });
      } else {
        container.classList.add("hidden");
        container.classList.remove("fade-in-up");
      }
    }
  });

  // Update tabs style highlights class
  const allTriggers = document.querySelectorAll("[data-tab-trigger]");
  allTriggers.forEach(el => {
    const elTab = el.getAttribute("data-tab-trigger");
    if (elTab === tabName) {
      el.classList.add("active", "text-ink-deep", "font-bold");
      el.classList.remove("text-warm-gray");
      if (el.classList.contains("text-left")) {
        // Mobile highlight color
        el.classList.add("text-accent-gold");
        el.classList.remove("text-ink-deep");
      }
    } else {
      el.classList.remove("active", "text-ink-deep", "font-bold", "text-accent-gold");
      if (el.classList.contains("text-left")) {
        el.classList.add("text-ink-deep");
      } else {
        el.classList.add("text-warm-gray");
      }
    }
  });
}


// ----------------================ WORK MATRIX ================----------------

function initWorkPage() {
  const gridContainer = document.getElementById("projects-grid");
  if (!gridContainer) return;

  renderProjects();

  // Set up categories filter clicks
  const filters = document.querySelectorAll("#filter-controls [data-filter]");
  filters.forEach(btn => {
    btn.addEventListener("click", () => {
      const filterVal = btn.getAttribute("data-filter");
      if (!filterVal) return;

      activeFilter = filterVal;

      // Update styling buttons
      filters.forEach(f => {
        if (f.getAttribute("data-filter") === filterVal) {
          f.className = "font-mono text-[9px] sm:text-[10px] tracking-widest px-3 py-1.5 focus:outline-none transition-all bg-ink-deep text-cream-soft font-bold";
        } else {
          f.className = "font-mono text-[9px] sm:text-[10px] tracking-widest px-3 py-1.5 focus:outline-none transition-all border border-ink-deep/10 text-warm-gray hover:text-ink-deep hover:bg-ink-deep/5";
        }
      });

      renderProjects();
    });
  });

  // CTA button opens Musee Noir from Hero
  const exploreHeroBtn = document.getElementById("hero-featured-btn");
  if (exploreHeroBtn) {
    exploreHeroBtn.addEventListener("click", () => {
      openModalAtIndex(0); // Musee Noir is index 0
    });
  }
}

function renderProjects() {
  const gridContainer = document.getElementById("projects-grid");
  if (!gridContainer) return;

  // Filter project instances
  const listToRender = activeFilter === "ALL" 
    ? projects 
    : projects.filter(item => item.category === activeFilter);

  gridContainer.innerHTML = listToRender.map((proj, idx) => {
    // Map initial source index, so when they clicked a filtered card, we open the exact global index
    const globalIdx = projects.findIndex(p => p.id === proj.id);

    return `
      <article class="group/card border border-ink-deep/10 bg-white/40 overflow-hidden relative shadow-sm flex flex-col justify-between hover:shadow-md transition-all duration-300">
        <div class="h-[260px] sm:h-[300px] overflow-hidden relative bg-zinc-950 cursor-pointer" data-trigger-modal-idx="${globalIdx}">
          <img src="${proj.imageUrl}" alt="${escapeHtml(proj.title)}" class="w-full h-full object-cover img-zoom" referrerpolicy="no-referrer" />
          <div class="absolute top-4 left-4 bg-ink-deep text-cream-soft font-mono text-[8px] tracking-[0.25em] px-2.5 py-1.5 pointer-events-none">
            ${proj.year} — ${proj.category}
          </div>
        </div>

        <div class="p-6 flex-grow flex flex-col justify-between space-y-4">
          <div class="space-y-2">
            <h3 class="font-serif text-xl font-bold text-ink-deep tracking-tight hover:text-accent-gold transition-colors cursor-pointer" data-trigger-modal-idx="${globalIdx}">${escapeHtml(proj.title)}</h3>
            <p class="font-sans text-xs text-warm-gray leading-relaxed max-w-sm line-clamp-2">${escapeHtml(proj.tagline)}</p>
          </div>

          <div class="pt-4 border-t border-ink-deep/5 flex items-center justify-between">
            <span class="font-mono text-[9px] text-neutral-400">CLIENT: ${escapeHtml(proj.client)}</span>
            <button data-trigger-modal-idx="${globalIdx}" class="text-accent-gold hover:text-ink-deep font-mono text-[10px] font-bold tracking-widest flex items-center gap-1 transition-colors focus:outline-none group/btn cursor-pointer">
              <span style="color: #000000;">EXPLORE BRIEF</span>
              <i data-lucide="arrow-up-right" style="color: #000000;" class="w-3.5 h-3.5 group-hover/btn:translate-x-0.5 group-hover/btn:-translate-y-0.5 transition-transform"></i>
            </button>
          </div>
        </div>
      </article>
    `;
  }).join("");

  // Attach click modal triggers
  const cardsBtns = gridContainer.querySelectorAll("[data-trigger-modal-idx]");
  cardsBtns.forEach(btn => {
    btn.addEventListener("click", () => {
      const idxStr = btn.getAttribute("data-trigger-modal-idx");
      if (idxStr !== null) {
        openModalAtIndex(parseInt(idxStr, 10));
      }
    });
  });

  // Re-map lucide elements
  if (typeof (window as any).lucide !== "undefined") {
    (window as any).lucide.createIcons();
  }
}


// ----------------================ CAPABILITIES BENTO SLIDER ================----------------

function initProfilePage() {
  const container = document.getElementById("capabilities-buttons-container");
  if (!container) return;

  const btnTriggers = container.querySelectorAll("[data-cap-segment]");
  
  btnTriggers.forEach(btn => {
    btn.addEventListener("click", () => {
      const segName = btn.getAttribute("data-cap-segment");
      if (!segName) return;

      activeCapSegment = segName;

      // Swap active highlight styles
      btnTriggers.forEach(b => {
        if (b.getAttribute("data-cap-segment") === segName) {
          b.className = "text-left p-5 border transition-all cursor-pointer bg-white border-ink-deep shadow-sm border-l-4 border-l-accent-gold";
        } else {
          b.className = "text-left p-5 border transition-all cursor-pointer border-ink-deep/10 hover:bg-white/50";
        }
      });

      renderActiveCapability();
    });
  });

  // Initial render
  renderActiveCapability();
}

function renderActiveCapability() {
  const data = capabilities[activeCapSegment];
  if (!data) return;

  const tagEl = document.getElementById("capability-tag");
  const titleEl = document.getElementById("capability-title");
  const descEl = document.getElementById("capability-desc");
  const listEl = document.getElementById("capability-deliverables-list");

  if (tagEl) {
    tagEl.textContent = activeCapSegment === "strategy" 
      ? "BRAND VALUE & POSITIONING" 
      : activeCapSegment === "design" 
      ? "AESTHETIC ARCHITECTURE" 
      : "ECOSYSTEM TOOLS FRAMEWORK";
  }

  if (titleEl) titleEl.textContent = data.title;
  if (descEl) descEl.textContent = data.text;

  if (listEl) {
    listEl.innerHTML = data.list.map(item => `
      <div class="flex items-center gap-2.5 font-sans text-xs text-warm-gray">
        <i data-lucide="check-circle" class="w-3.5 h-3.5 text-accent-gold shrink-0"></i>
        <span>${escapeHtml(item)}</span>
      </div>
    `).join("");
  }

  if (typeof (window as any).lucide !== "undefined") {
    (window as any).lucide.createIcons();
  }
}


// ----------------================ CHRONOLOGY ACCORDIONS ================----------------

function initChroniclePage() {
  const spine = document.getElementById("chronicle-timeline-spine");
  if (!spine) return;

  // Render nodes list
  spine.innerHTML = chronicleItems.map((item, idx) => {
    // The senior role matches index 0 and starts pre-expanded
    const isExpanded = idx === 0;

    return `
      <div class="relative pb-2" id="chronicle-node-${item.id}">
        <!-- Spine bullet circle node -->
        <span class="absolute -left-[16px] sm:-left-[28px] top-1.5 w-3 h-3 rounded-full border-2 ${item.highlight ? 'bg-accent-gold border-ink-deep' : 'bg-cream-soft border-neutral-400'} z-10 transition-transform hover:scale-125 duration-300"></span>

        <button data-timeline-toggle="${item.id}" class="w-full text-left group focus:outline-none">
          <div class="flex items-center justify-between border-b border-ink-deep/5 pb-2 group-hover:border-accent-gold/50 transition-colors">
            <div class="space-y-1">
              <span class="font-mono text-[9px] text-accent-gold font-bold tracking-widest block">${item.period}</span>
              <h3 class="font-serif text-lg font-bold text-ink-deep leading-tight group-hover:underline">${escapeHtml(item.role)}</h3>
              <p class="font-sans text-xs text-neutral-500 font-medium">${escapeHtml(item.company)}</p>
            </div>
            
            <i data-lucide="${isExpanded ? 'minus' : 'plus'}" class="w-4 h-4 text-warm-gray group-hover:text-ink-deep transition-transform shrink-0"></i>
          </div>
        </button>

        <!-- Dynamic height accordion content -->
        <div data-accordion-content="${item.id}" class="accordion-content pt-4 space-y-3 pl-1 ${isExpanded ? 'expanded' : ''}">
          <ul class="space-y-2.5 font-sans text-xs text-warm-gray leading-relaxed pr-2">
            ${item.details.map(bullet => `
              <li class="flex gap-2 items-start">
                <span class="w-1.5 h-1.5 rounded-full bg-accent-gold mt-1.5 shrink-0"></span>
                <span>${escapeHtml(bullet)}</span>
              </li>
            `).join("")}
          </ul>
        </div>
      </div>
    `;
  }).join("");

  // Hook event clicks
  const toggleButtons = spine.querySelectorAll("[data-timeline-toggle]");
  toggleButtons.forEach(btn => {
    btn.addEventListener("click", () => {
      const nodeId = btn.getAttribute("data-timeline-toggle");
      if (!nodeId) return;

      const accContent = spine.querySelector(`[data-accordion-content="${nodeId}"]`);
      const iconEl = btn.querySelector("[data-lucide]");

      if (accContent) {
        if (accContent.classList.contains("expanded")) {
          // Collapse
          accContent.classList.remove("expanded");
          if (iconEl && typeof (window as any).lucide !== "undefined") {
            iconEl.outerHTML = `<i data-lucide="plus" class="w-4 h-4 text-warm-gray group-hover:text-ink-deep transition-transform shrink-0"></i>`;
          }
        } else {
          // Expand
          accContent.classList.add("expanded");
          if (iconEl && typeof (window as any).lucide !== "undefined") {
            iconEl.outerHTML = `<i data-lucide="minus" class="w-4 h-4 text-warm-gray group-hover:text-ink-deep transition-transform shrink-0"></i>`;
          }
        }
        
        if (typeof (window as any).lucide !== "undefined") {
          (window as any).lucide.createIcons();
        }
      }
    });
  });

  if (typeof (window as any).lucide !== "undefined") {
    (window as any).lucide.createIcons();
  }
}


// ----------------================ PROPOSAL BRIEF FORM ================----------------

function initContactPage() {
  renderInquiryForm();
}

function renderInquiryForm() {
  const panel = document.getElementById("contact-panel-content");
  if (!panel) return;

  panel.innerHTML = `
    <div class="space-y-8">
      <div class="border-b border-ink-deep/10 pb-4">
        <h3 class="font-serif text-xl font-bold text-ink-deep">TRANSMIT BRIEF DETAILS</h3>
        <p class="font-mono text-[9px] text-warm-gray uppercase tracking-wider">
          Specifications will index securely to the creative vault.
        </p>
      </div>

      <form id="proposal-brief-form" class="space-y-6">
        <!-- Identity input -->
        <div class="space-y-1.5">
          <label class="font-mono text-[9px] font-bold text-ink-deep uppercase tracking-wider block">
            INDIVIDUAL IDENTITY OR ORGANIZTION BRANDING NAME
          </label>
          <input type="text" id="brief-name" required placeholder="e.g. Brera Design Studio, Milan" 
            class="w-full bg-cream-soft border border-ink-deep/15 py-3 px-4 text-xs focus:ring-1 focus:ring-accent-gold focus:border-accent-gold focus:outline-none focus:bg-white rounded-none transition-all placeholder:text-neutral-400 text-ink-deep" />
        </div>

        <!-- Email input -->
        <div class="space-y-1.5">
          <label class="font-mono text-[9px] font-bold text-ink-deep uppercase tracking-wider block">
            SECURE DIRECT TELEMETRY MAIL
          </label>
          <input type="email" id="brief-email" required placeholder="coordination@domain.com" 
            class="w-full bg-cream-soft border border-ink-deep/15 py-3 px-4 text-xs focus:ring-1 focus:ring-accent-gold focus:border-accent-gold focus:outline-none focus:bg-white rounded-none transition-all placeholder:text-neutral-400 text-ink-deep" />
        </div>

        <!-- Service archetypes -->
        <div class="space-y-2">
          <label class="font-mono text-[9px] font-bold text-ink-deep uppercase tracking-wider block">
            SERVICE TYPE ARCHETYPE REQUIRED
          </label>
          <div class="flex flex-wrap gap-2">
            <button type="button" data-service-pill="BRANDING" class="font-mono text-[9px] tracking-wider px-3.5 py-2.5 border border-ink-deep/15 text-warm-gray hover:text-ink-deep hover:bg-ink-deep/5 transition-all focus:outline-none cursor-pointer">
              BRANDING
            </button>
            <button type="button" data-service-pill="EDITORIAL" class="font-mono text-[9px] tracking-wider px-3.5 py-2.5 border border-ink-deep/15 text-warm-gray hover:text-ink-deep hover:bg-ink-deep/5 transition-all focus:outline-none cursor-pointer">
              EDITORIAL
            </button>
            <button type="button" data-service-pill="STRATEGY" class="font-mono text-[9px] tracking-wider px-3.5 py-2.5 border border-ink-deep/15 text-warm-gray hover:text-ink-deep hover:bg-ink-deep/5 transition-all focus:outline-none cursor-pointer">
              STRATEGY
            </button>
            <button type="button" data-service-pill="CONTENT CREATION" class="font-mono text-[9px] tracking-wider px-3.5 py-2.5 border border-ink-deep/15 text-warm-gray hover:text-ink-deep hover:bg-ink-deep/5 transition-all focus:outline-none cursor-pointer">
              CONTENT CREATION
            </button>
          </div>
        </div>

        <!-- Budget archetypes -->
        <div class="space-y-2">
          <label class="font-mono text-[9px] font-bold text-ink-deep uppercase tracking-wider block">
            ESTIMATED INVESTMENT BUDGET PROTOCOL
          </label>
          <div class="grid grid-cols-2 gap-2">
            <button type="button" data-budget-pill="Under €5,000" class="font-mono text-[9px] tracking-wider py-2.5 border border-ink-deep/15 text-warm-gray hover:text-ink-deep hover:bg-ink-deep/5 transition-all focus:outline-none cursor-pointer">
              UNDER €5,000
            </button>
            <button type="button" data-budget-pill="€5,000 — €10,000" class="font-mono text-[9px] tracking-wider py-2.5 border border-ink-deep/15 text-warm-gray hover:text-ink-deep hover:bg-ink-deep/5 transition-all focus:outline-none cursor-pointer">
              €5,000 — €10,000
            </button>
            <button type="button" data-budget-pill="€10,000 — €25,000" class="font-mono text-[9px] tracking-wider py-2.5 border border-ink-deep/15 text-warm-gray hover:text-ink-deep hover:bg-ink-deep/5 transition-all focus:outline-none cursor-pointer">
              €10,000 — €25,000
            </button>
            <button type="button" data-budget-pill="€25,000+" class="font-mono text-[9px] tracking-wider py-2.5 border border-ink-deep/15 text-warm-gray hover:text-ink-deep hover:bg-ink-deep/5 transition-all focus:outline-none cursor-pointer">
              €25,000+
            </button>
          </div>
        </div>

        <!-- Vision statement -->
        <div class="space-y-1.5">
          <label class="font-mono text-[9px] font-bold text-ink-deep uppercase tracking-wider block">
            STATEMENT & AESTHETIC REBELLION VISION
          </label>
          <textarea id="brief-vision" rows="4" required placeholder="What are we stripping down? Describe your core visual direction objectives..." 
            class="w-full bg-cream-soft border border-ink-deep/15 py-3 px-4 text-xs focus:ring-1 focus:ring-accent-gold focus:border-accent-gold focus:outline-none focus:bg-white rounded-none transition-all placeholder:text-neutral-400 text-ink-deep leading-relaxed"></textarea>
        </div>

        <!-- Submit btn -->
        <button type="submit" class="w-full bg-ink-deep text-cream-soft hover:bg-accent-gold transition-colors font-mono text-xs tracking-[0.2em] py-4 flex items-center justify-center gap-2 group/btn cursor-pointer focus:outline-none">
          <i data-lucide="shield-check" class="w-3.5 h-3.5 text-accent-gold group-hover/btn:rotate-12 transition-transform"></i>
          <span>TRANSMIT SPECIFICATIONS TO VAULT</span>
        </button>
      </form>
    </div>
  `;

  // Restore dynamic pill settings if populated
  selectedService = "";
  selectedBudget = "";

  // Set up pills toggle logic
  const servicePills = panel.querySelectorAll("[data-service-pill]");
  servicePills.forEach(pill => {
    pill.addEventListener("click", () => {
      const val = pill.getAttribute("data-service-pill") || "";
      selectedService = val;

      servicePills.forEach(p => {
        if (p.getAttribute("data-service-pill") === val) {
          p.className = "font-mono text-[9px] tracking-wider px-3.5 py-2.5 bg-accent-gold text-ink-deep font-bold border border-accent-gold focus:outline-none cursor-pointer";
        } else {
          p.className = "font-mono text-[9px] tracking-wider px-3.5 py-2.5 border border-ink-deep/15 text-warm-gray hover:text-ink-deep hover:bg-ink-deep/5 transition-all focus:outline-none cursor-pointer";
        }
      });
    });
  });

  const budgetPills = panel.querySelectorAll("[data-budget-pill]");
  budgetPills.forEach(pill => {
    pill.addEventListener("click", () => {
      const val = pill.getAttribute("data-budget-pill") || "";
      selectedBudget = val;

      budgetPills.forEach(p => {
        if (p.getAttribute("data-budget-pill") === val) {
          p.className = "font-mono text-[9px] tracking-wider py-2.5 bg-accent-gold text-ink-deep font-bold border border-accent-gold focus:outline-none cursor-pointer text-center";
        } else {
          p.className = "font-mono text-[9px] tracking-wider py-2.5 border border-ink-deep/15 text-warm-gray hover:text-ink-deep hover:bg-ink-deep/5 transition-all focus:outline-none cursor-pointer text-center";
        }
      });
    });
  });

  // Handle Form submit
  const form = document.getElementById("proposal-brief-form");
  if (form) {
    form.addEventListener("submit", (e) => {
      e.preventDefault();

      if (!selectedService) {
        alert("Please select a target Service Type first.");
        return;
      }

      if (!selectedBudget) {
        alert("Please select your budget Investment Range preference.");
        return;
      }

      const nameInput = document.getElementById("brief-name") as HTMLInputElement;
      const emailInput = document.getElementById("brief-email") as HTMLInputElement;
      const visionInput = document.getElementById("brief-vision") as HTMLTextAreaElement;

      // Enter loading state
      renderLoadingState();

      setTimeout(() => {
        // Secure random payload tx ID
        const randomHex = Math.floor(Math.random() * 900) + 100;
        const randomSuffix = Math.random().toString(36).substring(2, 6).toUpperCase();
        const txID = `CR-${randomHex}-${randomSuffix}`;

        const payload: Inquiry = {
          id: txID,
          name: nameInput.value,
          email: emailInput.value,
          service: selectedService,
          budget: selectedBudget,
          vision: visionInput.value,
          timestamp: new Date().toISOString()
        };

        // Sync to cloud persistence simulation (localStorage logs)
        saveVaultInquiry(payload);

        // Render success invoice ticket
        renderSuccessTicket(payload);
      }, 1500);
    });
  }

  if (typeof (window as any).lucide !== "undefined") {
    (window as any).lucide.createIcons();
  }
}

// Interactive Loading animation logic
function renderLoadingState() {
  const panel = document.getElementById("contact-panel-content");
  if (!panel) return;

  panel.innerHTML = `
    <div class="py-24 flex flex-col items-center justify-center text-center space-y-6">
      <div class="relative w-16 h-16 flex items-center justify-center">
        <!-- Modern spinning vector nodes -->
        <div class="absolute inset-0 border-t-2 border-accent-gold rounded-full animate-spin"></div>
        <div class="absolute inset-2 border-b-2 border-ink-deep rounded-full animate-spin [animation-duration:1.5s]"></div>
        <i data-lucide="shield" class="w-5 h-5 text-accent-gold"></i>
      </div>
      
      <div class="space-y-1">
        <h3 class="font-serif text-lg font-bold text-ink-deep">TRANSMITTING PROTOCOLS</h3>
        <p class="font-mono text-[9px] text-warm-gray tracking-widest uppercase animate-pulse">
          SECURING LOCAL TRANSMISSION TUNNEL...
        </p>
      </div>
    </div>
  `;

  if (typeof (window as any).lucide !== "undefined") {
    (window as any).lucide.createIcons();
  }
}

// Success ticket generator receipt
function renderSuccessTicket(inquiry: Inquiry) {
  const panel = document.getElementById("contact-panel-content");
  if (!panel) return;

  const fmtDate = new Date(inquiry.timestamp).toLocaleString("en-US", {
    month: "short",
    day: "numeric",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit"
  });

  const mailSubject = encodeURIComponent(`Creative Brief Authorization [${inquiry.id}]`);
  const mailBody = encodeURIComponent(
    `Hello Carlota Rezola,\n\n` +
    `I have transmitted my creative specification brief through your Strategic Portal.\n\n` +
    `Here is my unique transmission key: ${inquiry.id}\n` +
    `Service Requested: ${inquiry.service}\n` +
    `Investment Category: ${inquiry.budget}\n` +
    `Identity/Brand: ${inquiry.name}\n\n` +
    `Creative Vision Outline:\n"${inquiry.vision}"\n\n` +
    `Let's schedule a session to iterate.\n\n` +
    `Best regards,\n${inquiry.name}\n${inquiry.email}`
  );

  panel.innerHTML = `
    <div class="p-4 sm:p-6 border-2 border-dashed border-ink-deep bg-cream-soft space-y-6 text-ink-deep relative select-none">
      
      <!-- Top receipt serrated stub indicator aesthetics -->
      <div class="absolute -top-1.5 left-0 right-0 h-1 bg-[radial-gradient(ellipse_at_top,transparent_3px,#0D0D0C_4px)] bg-[length:12px_6px] bg-repeat-x pointer-events-none"></div>

      <div class="flex flex-col sm:flex-row items-start sm:items-center justify-between border-b border-ink-deep pb-4 gap-4">
        <div>
          <span class="font-mono text-[9px] bg-ink-deep text-cream-soft px-2 py-0.5 uppercase tracking-widest font-bold">
            SECURE TRANSACTION SLIP
          </span>
          <h2 class="font-serif text-2xl font-bold tracking-tight mt-1">TRANSMISSION VERIFIED</h2>
        </div>
        <div class="font-mono text-right text-[10px] shrink-0">
          <p class="font-bold text-accent-gold">${inquiry.id}</p>
          <p class="text-[8px] text-neutral-400">TX VERIFIED STATUS</p>
        </div>
      </div>

      <div class="space-y-4 font-mono text-[10px] sm:text-[11px] text-warm-gray leading-relaxed">
        <div class="grid grid-cols-12 gap-1 border-b border-ink-deep/5 pb-2">
          <div class="col-span-4 text-neutral-400">TIMESTAMP</div>
          <div class="col-span-8 text-ink-deep font-bold font-mono">${fmtDate}</div>
        </div>

        <div class="grid grid-cols-12 gap-1 border-b border-ink-deep/5 pb-2">
          <div class="col-span-4 text-neutral-400">IDENTITY BRAND</div>
          <div class="col-span-8 text-ink-deep font-bold font-serif text-xs">${escapeHtml(inquiry.name)}</div>
        </div>

        <div class="grid grid-cols-12 gap-1 border-b border-ink-deep/5 pb-2">
          <div class="col-span-4 text-neutral-400">TARGET MAIL</div>
          <div class="col-span-8 text-ink-deep font-bold">${escapeHtml(inquiry.email)}</div>
        </div>

        <div class="grid grid-cols-12 gap-1 border-b border-ink-deep/5 pb-2">
          <div class="col-span-4 text-neutral-400">SERVICE LEVEL</div>
          <div class="col-span-8 text-ink-deep font-bold text-accent-gold">${inquiry.service}</div>
        </div>

        <div class="grid grid-cols-12 gap-1 border-b border-ink-deep/5 pb-2">
          <div class="col-span-4 text-neutral-400">INVEST PROFILE</div>
          <div class="col-span-8 text-ink-deep font-bold">${inquiry.budget}</div>
        </div>

        <div class="space-y-2 pt-2">
          <span class="text-neutral-400 uppercase tracking-widest block text-[9px]">RAW BRIEF EXTRACT STATEMENT:</span>
          <blockquote class="border-l-2 border-ink-deep pl-3 italic font-sans text-xs text-warm-gray py-0.5">
            "${escapeHtml(inquiry.vision)}"
          </blockquote>
        </div>
      </div>

      <div class="pt-4 border-t border-ink-deep space-y-3">
        <div class="flex flex-col sm:flex-row items-stretch gap-2.5">
          <button id="success-copy-json-btn" class="flex-1 border border-ink-deep/15 hover:border-ink-deep hover:bg-ink-deep/5 py-3 transition-all font-mono text-[10px] font-bold tracking-widest flex items-center justify-center gap-1.5 focus:outline-none cursor-pointer">
            <i data-lucide="copy" class="w-3.5 h-3.5"></i>
            <span>COPY PAYLOAD (JSON)</span>
          </button>
          <a href="mailto:hello@carlotarezola.com?subject=${mailSubject}&body=${mailBody}" class="flex-1 bg-ink-deep text-cream-soft hover:bg-accent-gold py-3 transition-all font-mono text-[10px] font-bold tracking-widest flex items-center justify-center gap-1.5 text-center focus:outline-none">
            <i data-lucide="mail-check" class="w-3.5 h-3.5 text-accent-gold"></i>
            <span>SEAMLESS MAIL DEPLOY</span>
          </a>
        </div>

        <button id="success-reset-btn" class="w-full text-center py-2 font-mono text-[9px] text-neutral-400 hover:text-ink-deep hover:underline focus:outline-none cursor-pointer">
          [ TRANSMIT ANOTHER PORTFOLIO BRIEF PROTOCOL ]
        </button>
      </div>

    </div>
  `;

  // Bind actions inside ticket receipt
  const copyBtn = document.getElementById("success-copy-json-btn");
  if (copyBtn) {
    copyBtn.addEventListener("click", () => {
      navigator.clipboard.writeText(JSON.stringify(inquiry, null, 2));
      alert("Inquiry metadata synced copied to clipboard perfectly!");
    });
  }

  const resetBtn = document.getElementById("success-reset-btn");
  if (resetBtn) {
    resetBtn.addEventListener("click", () => {
      renderInquiryForm();
    });
  }

  if (typeof (window as any).lucide !== "undefined") {
    (window as any).lucide.createIcons();
  }
}


// ----------------================ CASES DOSSIER MODAL ================----------------

function initModal() {
  const modal = document.getElementById("project-modal");
  const closeBtn = document.getElementById("modal-close-btn");
  const backdrop = document.getElementById("modal-backdrop");
  
  const prevBtn = document.getElementById("modal-prev-btn");
  const nextBtn = document.getElementById("modal-next-btn");
  const inquireCta = document.getElementById("modal-inquire-cta");

  if (!modal) return;

  const closeModal = () => {
    modal.classList.add("hidden");
    document.body.style.overflow = "auto";
  };

  if (closeBtn) closeBtn.addEventListener("click", closeModal);
  if (backdrop) backdrop.addEventListener("click", closeModal);

  // Keyboard navigation
  document.addEventListener("keydown", (e) => {
    if (modal.classList.contains("hidden")) return;
    if (e.key === "Escape") closeModal();
    if (e.key === "ArrowLeft") handlePrevProject();
    if (e.key === "ArrowRight") handleNextProject();
  });

  if (prevBtn) prevBtn.addEventListener("click", handlePrevProject);
  if (nextBtn) nextBtn.addEventListener("click", handleNextProject);

  if (inquireCta) {
    inquireCta.addEventListener("click", () => {
      closeModal();
      
      // Go to contact tab and populate brief service with modal category
      switchTab("contact");

      // Auto pill preset select
      const proj = projects[currentModalProjectIndex];
      renderInquiryForm(); // Re-render first

      setTimeout(() => {
        const targetPill = document.querySelector(`[data-service-pill="${proj.category}"]`) as HTMLButtonElement;
        if (targetPill) {
          targetPill.click();
          
          // Focus identity input
          const nameInput = document.getElementById("brief-name");
          if (nameInput) nameInput.focus();
        }
      }, 100);
    });
  }
}

function openModalAtIndex(idx: number) {
  const modal = document.getElementById("project-modal");
  if (!modal) return;

  currentModalProjectIndex = idx;
  const proj = projects[idx];

  const imgEl = document.getElementById("modal-image") as HTMLImageElement;
  const titleEl = document.getElementById("modal-title");
  const taglineEl = document.getElementById("modal-tagline");
  const categoryEl = document.getElementById("modal-category");
  const clientEl = document.getElementById("modal-client");
  const yearEl = document.getElementById("modal-year");
  const durationEl = document.getElementById("modal-duration");
  const overviewEl = document.getElementById("modal-overview");
  const servicesContainer = document.getElementById("modal-services");

  if (imgEl) imgEl.src = proj.imageUrl;
  if (titleEl) titleEl.textContent = proj.title;
  if (taglineEl) taglineEl.textContent = `"${proj.tagline}"`;
  if (categoryEl) categoryEl.textContent = proj.category;
  if (clientEl) clientEl.textContent = proj.client;
  if (yearEl) yearEl.textContent = String(proj.year);
  if (durationEl) durationEl.textContent = proj.duration;
  if (overviewEl) overviewEl.textContent = proj.overview;

  if (servicesContainer) {
    servicesContainer.innerHTML = proj.services.map(srv => `
      <span class="font-mono text-[8px] bg-ink-deep/5 text-warm-gray border border-ink-deep/10 px-2.5 py-1 uppercase rounded-none">
        ${escapeHtml(srv)}
      </span>
    `).join("");
  }

  modal.classList.remove("hidden");
  document.body.style.overflow = "hidden";

  if (typeof (window as any).lucide !== "undefined") {
    (window as any).lucide.createIcons();
  }
}

function handlePrevProject() {
  const total = projects.length;
  const prevIdx = (currentModalProjectIndex - 1 + total) % total;
  openModalAtIndex(prevIdx);
}

function handleNextProject() {
  const total = projects.length;
  const nextIdx = (currentModalProjectIndex + 1) % total;
  openModalAtIndex(nextIdx);
}


// ----------------================ CLIENT DB CONSOLE DRAWER ================----------------

function initDrawer() {
  const drawer = document.getElementById("inquiry-drawer");
  const openBtns = [
    document.getElementById("open-vault-btn"),
    document.getElementById("mobile-vault-btn"),
    document.getElementById("mobile-drawer-vault-btn")
  ];
  const closeBtn = document.getElementById("inquiry-drawer-close-btn");
  const backdrop = document.getElementById("inquiry-drawer-backdrop");

  const openDrawer = () => {
    if (drawer) {
      drawer.classList.remove("hidden");
      document.body.style.overflow = "hidden";
      updateVaultUI();

      // Also close mobile menu drawer if open
      const mobileDrawer = document.getElementById("mobile-drawer");
      if (mobileDrawer && !mobileDrawer.classList.contains("hidden")) {
        mobileDrawer.classList.add("hidden");
        const menuToggle = document.getElementById("mobile-menu-toggle");
        if (menuToggle) {
          menuToggle.innerHTML = `<i data-lucide="menu" class="w-5 h-5"></i>`;
          if (typeof (window as any).lucide !== "undefined") {
            (window as any).lucide.createIcons();
          }
        }
      }
    }
  };

  const closeDrawer = () => {
    if (drawer) {
      drawer.classList.add("hidden");
      document.body.style.overflow = "auto";
    }
  };

  openBtns.forEach(btn => {
    if (btn) btn.addEventListener("click", openDrawer);
  });

  if (closeBtn) closeBtn.addEventListener("click", closeDrawer);
  if (backdrop) backdrop.addEventListener("click", closeDrawer);

  // Mobile hamburger toggling logic
  const menuToggle = document.getElementById("mobile-menu-toggle");
  const mobileDrawer = document.getElementById("mobile-drawer");
  if (menuToggle && mobileDrawer) {
    menuToggle.addEventListener("click", () => {
      if (mobileDrawer.classList.contains("hidden")) {
        mobileDrawer.classList.remove("hidden");
        // Swap menu icon to x
        menuToggle.innerHTML = `<i data-lucide="x" class="w-5 h-5"></i>`;
      } else {
        mobileDrawer.classList.add("hidden");
        menuToggle.innerHTML = `<i data-lucide="menu" class="w-5 h-5"></i>`;
      }
      
      if (typeof (window as any).lucide !== "undefined") {
        (window as any).lucide.createIcons();
      }
    });
  }

  // Footer copy direct mail click trigger
  const copyMailBtn = document.getElementById("footer-copy-email-btn");
  const mailDisplayEl = document.getElementById("footer-email-text");
  const copyMailIcon = document.getElementById("footer-copy-icon");

  if (copyMailBtn && mailDisplayEl) {
    copyMailBtn.addEventListener("click", () => {
      navigator.clipboard.writeText("hello@carlotarezola.com");
      
      const prevString = mailDisplayEl.textContent;
      mailDisplayEl.textContent = "COPIED TO CLIPBOARD!";
      mailDisplayEl.classList.add("text-accent-gold");

      if (copyMailIcon && typeof (window as any).lucide !== "undefined") {
        copyMailIcon.outerHTML = `<i data-lucide="check" id="footer-copy-icon" class="w-3.5 h-3.5 text-accent-gold ml-1"></i>`;
        (window as any).lucide.createIcons();
      }

      setTimeout(() => {
        mailDisplayEl.textContent = prevString;
        mailDisplayEl.classList.remove("text-accent-gold");

        const reMappedIcon = document.getElementById("footer-copy-icon");
        if (reMappedIcon && typeof (window as any).lucide !== "undefined") {
          reMappedIcon.outerHTML = `<i data-lucide="copy" id="footer-copy-icon" class="w-3 h-3 opacity-40 group-hover:opacity-100 transition-opacity ml-1"></i>`;
          (window as any).lucide.createIcons();
        }
      }, 2000);
    });
  }
}


// ----------------================ EXTRA UTILS ================----------------

function escapeHtml(str: string): string {
  if (!str) return "";
  return str
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#039;");
}
