<!doctype html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">


  <!-- ==================================================

       SEO

       ================================================== -->

  <title>Iñaki Serna | Senior Product Designer — Growth, Fintech &amp; AI</title>


  <meta

    name="description"

    content="Senior Product Designer at Lidl with 10+ years of global experience in growth, strategy, data and AI. Previously ClearScore, Europcar and Badi."

  >

  <meta name="author" content="Iñaki Serna">

  <meta name="robots" content="index, follow, max-image-preview:large">

  <meta name="theme-color" content="#3D3DED">

  <link rel="canonical" href="https://portfolio.inakiserna.com/">


  <!-- Open Graph -->

  <meta property="og:type" content="profile">

  <meta property="og:site_name" content="Iñaki Serna — Portfolio">

  <meta property="og:title" content="Iñaki Serna | Senior Product Designer — Growth, Fintech &amp; AI">

  <meta

    property="og:description"

    content="Senior Product Designer at Lidl with 10+ years of global experience in growth, strategy, data and AI. Previously ClearScore, Europcar and Badi."

  >

  <meta property="og:url" content="https://portfolio.inakiserna.com/">

  <meta property="og:locale" content="en_GB">

  <meta property="profile:first_name" content="Iñaki">

  <meta property="profile:last_name" content="Serna">


  <!--

    Cuando tengas una imagen 1200 x 630 px en la misma carpeta que

    index.html (por ejemplo og-image.jpg), descomenta estas líneas:


    <meta property="og:image" content="https://portfolio.inakiserna.com/og-image.jpg">

    <meta property="og:image:width" content="1200">

    <meta property="og:image:height" content="630">

    <meta name="twitter:image" content="https://portfolio.inakiserna.com/og-image.jpg">

  -->


  <!-- Twitter / X -->

  <meta name="twitter:card" content="summary_large_image">

  <meta name="twitter:title" content="Iñaki Serna | Senior Product Designer — Growth, Fintech &amp; AI">

  <meta

    name="twitter:description"

    content="Senior Product Designer at Lidl with 10+ years of global experience in growth, strategy, data and AI."

  >


<!-- Structured data -->

<script type="application/ld+json">

{

  "@context": "https://schema.org",

  "@type": "ProfilePage",

  "url": "https://portfolio.inakiserna.com/",

  "name": "Iñaki Serna — Senior Product Designer",

  "description": "Portfolio of Iñaki Serna, Senior Product Designer with 10+ years of global experience in growth, strategy, data and AI.",

  "inLanguage": "en",

  "mainEntity": {

    "@type": "Person",

    "name": "Iñaki Serna",

    "givenName": "Iñaki",

    "familyName": "Serna",

    "url": "https://portfolio.inakiserna.com/",

    "sameAs": [

      "https://www.linkedin.com/in/inaki-serna/"

    ],

    "jobTitle": "Senior Product Designer",

    "description": "Senior Product Designer at SCRM Lidl with 10+ years of international experience in London and Spain across fintech, e-commerce, e-food, travel and real estate. Focused on growth, strategy, data and AI.",

    "worksFor": {

      "@type": "Organization",

      "name": "Lidl"

    },

    "knowsAbout": [

      "Product design",

      "UX design",

      "UI design",

      "Growth design",

      "Product strategy",

      "Data-informed design",

      "AI product design",

      "Fintech",

      "E-commerce",

      "Design mentoring"

    ]

  }

}

</script>


  <style>

    :root {

      /* Todos los fondos de página usan este azul */

      --background: #3D3DED;

      --portfolio-blue: #3D3DED;


      --surface: #1a1a1a;

      --field: #262626;

      --border: #3a3a3a;

      --text: #ffffff;

      --muted: #c0c0c0;

      --error: #ff9b9b;

      --button: #ffffff;

      --button-text: #111111;

    }


    * {

      box-sizing: border-box;

    }


    html,

    body {

      width: 100%;

      min-height: 100%;

      margin: 0;

      padding: 0;

      background: var(--portfolio-blue);

      color: var(--text);

      font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

    }


    /* ==============================

       Password gate + SEO content

       ============================== */


    #access-gate {

      display: flex;

      flex-direction: column;

      align-items: center;

      justify-content: center;

      gap: 28px;

      min-height: 100vh;

      min-height: 100dvh;

      padding: 40px 24px;

      background: var(--portfolio-blue);

    }


    .seo-intro {

      width: min(100%, 400px);

    }


    .seo-intro h1 {

      margin: 0 0 6px;

      color: var(--text);

      font-size: clamp(1.25rem, 4.5vw, 1.5rem);

      line-height: 1.2;

      letter-spacing: -0.02em;

    }


    .seo-intro p {

      margin: 0;

      color: rgba(255, 255, 255, 0.9);

      font-size: 0.9375rem;

      line-height: 1.5;

    }


    .card {

      width: min(100%, 400px);

      padding: 32px;

      border: 1px solid var(--border);

      border-radius: 16px;

      background: var(--surface);

      box-shadow: 0 24px 64px rgba(0, 0, 0, 0.32);

    }


    .about {

      width: min(100%, 560px);

      color: rgba(255, 255, 255, 0.92);

      font-size: 0.9375rem;

      line-height: 1.6;

    }


    .about h2 {

      margin: 0 0 8px;

      color: var(--text);

      font-size: 1rem;

      letter-spacing: 0.02em;

    }


    .about p {

      margin: 0 0 22px;

    }


    .about ul {

      margin: 0 0 22px;

      padding-left: 18px;

    }


    .about li {

      margin-bottom: 6px;

    }


    .about strong {

      color: var(--text);

    }


    .language-switcher {

      display: flex;

      justify-content: flex-end;

      gap: 4px;

      margin-bottom: 28px;

    }


    .language-button {

      width: auto;

      margin: 0;

      padding: 5px 7px;

      border: 0;

      border-radius: 5px;

      background: transparent;

      color: var(--muted);

      cursor: pointer;

      font: inherit;

      font-size: 0.75rem;

      font-weight: 700;

      letter-spacing: 0.04em;

    }


    .language-button:hover,

    .language-button[aria-pressed="true"] {

      background: #2d2d2d;

      color: var(--text);

    }


    .eyebrow {

      margin: 0 0 10px;

      color: var(--muted);

      font-size: 0.875rem;

      font-weight: 600;

      letter-spacing: 0.02em;

    }


    .card h2 {

      margin: 0 0 12px;

      color: var(--text);

      font-size: clamp(1.75rem, 6vw, 2rem);

      line-height: 1.1;

      letter-spacing: -0.03em;

    }


    .intro {

      margin: 0;

      color: var(--muted);

      line-height: 1.5;

    }


    label {

      display: block;

      margin: 24px 0 8px;

      color: var(--text);

      font-size: 0.9rem;

      font-weight: 650;

    }


    input,

    button[type="submit"] {

      width: 100%;

      padding: 13px 14px;

      border-radius: 8px;

      font: inherit;

    }


    input {

      border: 1px solid #444444;

      outline: none;

      background: var(--field);

      color: var(--text);

    }


    input:focus {

      border-color: #ffffff;

      box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.12);

    }


    button[type="submit"] {

      margin-top: 16px;

      border: 0;

      background: var(--button);

      color: var(--button-text);

      cursor: pointer;

      font-weight: 700;

      transition: background 150ms ease, transform 150ms ease;

    }


    button[type="submit"]:hover {

      background: #e8e8e8;

    }


    button[type="submit"]:active {

      transform: translateY(1px);

    }


    #error-message {

      min-height: 1.5em;

      margin: 12px 0 0;

      color: var(--error);

      font-size: 0.9rem;

      line-height: 1.4;

    }


    .request-access {

      margin: 24px 0 0;

      color: var(--muted);

      font-size: 0.875rem;

      line-height: 1.5;

      text-align: center;

    }


    .request-access a {

      color: var(--text);

      text-decoration: underline;

      text-underline-offset: 3px;

    }


    /* ==============================

       Figma portfolio

       ============================== */


    #portfolio {

      position: relative;

      isolation: isolate;

      display: none;

      width: 100%;

      min-height: 100vh;

      min-height: 100dvh;

      overflow: hidden;

      background: var(--portfolio-blue);

    }


    #portfolio.is-visible {

      display: flex;

      justify-content: center;

      align-items: flex-start;

    }


    #portfolio iframe {

      position: relative;

      z-index: 1;

      display: block;

      width: 100%;

      height: 100vh;

      height: 100dvh;

      border: 0;

      background: transparent;

      color-scheme: auto;

      opacity: 0;

      transition: opacity 400ms ease;

    }


    #portfolio iframe.is-loaded {

      opacity: 1;

    }


    #portfolio.device-desktop iframe {

      max-width: 1440px;

    }


    #portfolio.device-tablet iframe {

      max-width: 834px;

    }


    /* Cambia 430px si tu frame móvil usa otro ancho */

    #portfolio.device-mobile iframe {

      max-width: 430px;

    }


    .portfolio-message {

      position: relative;

      z-index: 1;

      display: grid;

      width: 100%;

      min-height: 100vh;

      min-height: 100dvh;

      place-items: center;

      padding: 24px;

      color: #ffffff;

      background: var(--portfolio-blue);

      text-align: center;

    }


    /* ==============================

       Loading overlay

       ============================== */


    .portfolio-loader {

      position: fixed;

      z-index: 1000;

      inset: 0;

      display: grid;

      place-items: center;

      overflow: hidden;

      background: var(--portfolio-blue);

      color: #ffffff;

      opacity: 0;

      visibility: hidden;

      pointer-events: none;

      transition:

        opacity 500ms cubic-bezier(0.22, 1, 0.36, 1),

        visibility 0s linear 500ms;

    }


    .portfolio-loader.is-active {

      opacity: 1;

      visibility: visible;

      pointer-events: auto;

      transition:

        opacity 150ms ease,

        visibility 0s linear 0s;

    }


    .portfolio-loader::after {

      content: "";

      position: absolute;

      inset: -20%;

      pointer-events: none;

      background:

        radial-gradient(

          circle at 50% 50%,

          rgba(255, 255, 255, 0.22) 0,

          rgba(255, 255, 255, 0.08) 18%,

          transparent 48%

        );

      transform: scale(0.55);

      animation: loading-pulse 1700ms cubic-bezier(0.22, 1, 0.36, 1) infinite;

    }


    .loader-content {

      position: relative;

      z-index: 1;

      display: grid;

      justify-items: center;

      gap: 18px;

    }


    .loader-mark {

      display: flex;

      align-items: flex-end;

      gap: 7px;

      height: 48px;

    }


    .loader-mark span {

      display: block;

      width: 7px;

      height: 18px;

      border-radius: 999px;

      background: #ffffff;

      transform-origin: bottom;

      animation: loading-bars 900ms cubic-bezier(0.4, 0, 0.2, 1) infinite;

    }


    .loader-mark span:nth-child(2) {

      animation-delay: 120ms;

    }


    .loader-mark span:nth-child(3) {

      animation-delay: 240ms;

    }


    #loader-text {

      margin: 0;

      color: rgba(255, 255, 255, 0.9);

      font-size: 0.8125rem;

      font-weight: 700;

      letter-spacing: 0.1em;

      text-transform: uppercase;

    }


    @keyframes loading-bars {

      0%, 100% {

        transform: scaleY(0.55);

        opacity: 0.5;

      }

      50% {

        transform: scaleY(2.35);

        opacity: 1;

      }

    }


    @keyframes loading-pulse {

      0% {

        opacity: 0;

        transform: scale(0.45);

      }

      35% {

        opacity: 1;

      }

      100% {

        opacity: 0;

        transform: scale(1.6);

      }

    }


    @media (prefers-reduced-motion: reduce) {

      .portfolio-loader::after,

      .loader-mark span {

        animation: none;

      }


      .portfolio-loader,

      .portfolio-loader.is-active,

      #portfolio iframe {

        transition: none;

      }

    }

  </style>

</head>


<body>

  <!-- ==================================================

       Password gate + crawlable profile content

       ================================================== -->

  <div id="access-gate">


    <header class="seo-intro">

      <h1>Iñaki Serna — Senior Product Designer</h1>

      <p data-i18n="tagline">Growth, strategy, data and AI for digital products.</p>

    </header>


    <main class="card" aria-labelledby="page-title">

      <div class="language-switcher" aria-label="Language selector">

        <button class="language-button" type="button" data-language="en" aria-pressed="false">EN</button>

        <button class="language-button" type="button" data-language="es" aria-pressed="false">ES</button>

      </div>


      <p id="eyebrow" class="eyebrow">Iñaki Serna · Portfolio</p>


      <h2 id="page-title">Private access</h2>


      <p id="intro" class="intro">

        Enter the password shared with you to view this portfolio.

      </p>


      <form id="access-form">

        <label id="password-label" for="password">Password</label>


        <input

          id="password"

          name="password"

          type="password"

          autocomplete="current-password"

          required

          autofocus

        >


        <button id="submit-button" type="submit">

          View portfolio

        </button>


        <p id="error-message" aria-live="polite"></p>

      </form>


      <p id="request-access" class="request-access"></p>

    </main>


    <section class="about" aria-labelledby="about-title">

      <h2 id="about-title" data-i18n="aboutTitle">About</h2>

      <p data-i18n="aboutText">

        Senior Product Designer at SCRM Lidl with 10+ years of international experience across London and Spain. I design growth-focused digital products, improving the registration rate (18%) and designing for 130M Lidl users, while shaping design and product culture and mentoring UX/UI designers.

      </p>


      <h2 data-i18n="experienceTitle">Selected experience</h2>

      <ul>

        <li><strong>Lidl</strong> — <span data-i18n="expLidl">SCRM, e-commerce and e-food.</span></li>

        <li><strong>ClearScore</strong> — <span data-i18n="expClearScore">fintech, London.</span></li>

        <li><strong>Europcar</strong> — <span data-i18n="expEuropcar">Volkswagen, travel sector.</span></li>

        <li><strong>Badi</strong> — <span data-i18n="expBadi">real estate app.</span></li>

      </ul>


      <h2 data-i18n="focusTitle">Focus</h2>

      <p data-i18n="focusText">

        Open to growth companies in fintech, AI, renewables and robotics.

      </p>

    </section>


  </div>


  <!-- Figma iframe is injected here -->

  <main id="portfolio" aria-label="Iñaki Serna portfolio"></main>


  <!-- Loading overlay -->

  <div

    id="portfolio-loader"

    class="portfolio-loader"

    role="status"

    aria-live="polite"

  >

    <div class="loader-content">

      <div class="loader-mark" aria-hidden="true">

        <span></span>

        <span></span>

        <span></span>

      </div>

      <p id="loader-text">Loading portfolio</p>

    </div>

  </div>


  <script>

    /*

      ==================================================

      CONFIGURATION: CHANGE ONLY THESE TWO VALUES

      ==================================================

    */


    const ACCESS_PASSWORD = “serna”;


    const REQUEST_ACCESS_EMAIL = “[email protected]”;


    /*

      ==================================================

      FIGMA SETTINGS (template azul)

      ==================================================

    */


    const FIGMA_BASE_URL =

      "https://embed.figma.com/proto/mUhlf6ntiFnXWSXqSyZRWH/Website-2026";


    const FIGMA_PAGE_ID = "0:1";


    const FIGMA_NODES = {

      desktop: { node: "2-71798", start: "2:71798" },

      tablet:  { node: "2-75728", start: "2:75728" },

      mobile:  { node: "2-75267", start: "2:75267" }

    };


    const FIGMA_PARAMS = {

      "embed-host": "share",

      "scaling": "scale-down-width",

      "content-scaling": "fixed",

      "show-proto-sidebar": "0",

      "footer": "false",

      "viewport-controls": "false",

      "hotspot-hints": "false",

      "device-frame": "false",

      "disable-default-keyboard-nav": "true",

      "hide-ui": "1"

    };


    const DEVICE_BREAKPOINTS = {

      mobileMax: 767,

      tabletMax: 1023

    };


    /*

      LOADER TIMING (milliseconds)

      Increase LOADER_AFTER_LOAD_DELAY if you still see a blank

      or white frame when the loader disappears.

    */

    const LOADER_MIN_VISIBLE = 1400;

    const LOADER_AFTER_LOAD_DELAY = 4000;

    const LOADER_MAX_WAIT = 30000;


    function buildFigmaUrl(device) {

      const config = FIGMA_NODES[device];


      if (!config) {

        return "";

      }


      const params = new URLSearchParams();


      params.set("page-id", FIGMA_PAGE_ID);

      params.set("node-id", config.node);

      params.set("starting-point-node-id", config.start);


      Object.keys(FIGMA_PARAMS).forEach(function (key) {

        params.set(key, FIGMA_PARAMS[key]);

      });


      return FIGMA_BASE_URL + "?" + params.toString();

    }


    /*

      ==================================================

      TRANSLATIONS

      ==================================================

    */


    const translations = {

      en: {

        pageTitle: "Iñaki Serna | Senior Product Designer — Growth, Fintech & AI",

        eyebrow: "Iñaki Serna · Portfolio",

        heading: "Private access",

        intro: "Enter the password shared with you to view this portfolio.",

        passwordLabel: "Password",

        button: "View portfolio",

        checking: "Opening portfolio...",

        loading: "Loading portfolio",

        incorrectPassword: "Incorrect password. Please try again.",

        requestText: "Don't have access?",

        requestLink: "Request access",

        requestSubject: "Portfolio access request",

        missingEmbed: "Portfolio unlocked, but the Figma URL for this screen size is not configured.",


        tagline: "Growth, strategy, data and AI for digital products.",

        aboutTitle: "About",

        aboutText: "Senior Product Designer at SCRM Lidl with 10+ years of international experience across London and Spain. I design growth-focused digital products, improving the registration rate (18%) and designing for 130M Lidl users, while shaping design and product culture and mentoring UX/UI designers.",

        experienceTitle: "Selected experience",

        expLidl: "SCRM, e-commerce and e-food.",

        expClearScore: "fintech, London.",

        expEuropcar: "Volkswagen, travel sector.",

        expBadi: "real estate app.",

        focusTitle: "Focus",

        focusText: "Open to growth companies in fintech, AI, renewables and robotics."

      },


      es: {

        pageTitle: "Iñaki Serna | Senior Product Designer — Growth, Fintech e IA",

        eyebrow: "Iñaki Serna · Portfolio",

        heading: "Acceso privado",

        intro: "Introduce la contraseña que se ha compartido contigo para ver este portfolio.",

        passwordLabel: "Contraseña",

        button: "Ver portfolio",

        checking: "Abriendo portfolio...",

        loading: "Cargando portfolio",

        incorrectPassword: "La contraseña no es correcta. Inténtalo de nuevo.",

        requestText: "¿No tienes acceso?",

        requestLink: "Solicitar acceso",

        requestSubject: "Solicitud de acceso al portfolio",

        missingEmbed: "El portfolio se ha desbloqueado, pero falta la URL de Figma para este tamaño de pantalla.",


        tagline: "Growth, estrategia, datos e IA para productos digitales.",

        aboutTitle: "Sobre mí",

        aboutText: "Senior Product Designer en SCRM Lidl con más de 10 años de experiencia internacional en Londres y España. Diseño productos digitales orientados a growth, mejorando la tasa de registro (18%) y diseñando para 130M de usuarios de Lidl, mientras impulso la cultura de diseño y producto y mentorizo a diseñadores UX/UI.",

        experienceTitle: "Experiencia destacada",

        expLidl: "SCRM, e-commerce y e-food.",

        expClearScore: "fintech, Londres.",

        expEuropcar: "Volkswagen, sector travel.",

        expBadi: "app de real estate.",

        focusTitle: "Enfoque",

        focusText: "Abierto a empresas en crecimiento en fintech, IA, renovables y robótica."

      }

    };


    /*

      ==================================================

      DOM ELEMENTS

      ==================================================

    */


    const form = document.getElementById("access-form");

    const input = document.getElementById("password");

    const error = document.getElementById("error-message");

    const gate = document.getElementById("access-gate");

    const portfolio = document.getElementById("portfolio");

    const loader = document.getElementById("portfolio-loader");

    const loaderText = document.getElementById("loader-text");


    const ui = {

      eyebrow: document.getElementById("eyebrow"),

      heading: document.getElementById("page-title"),

      intro: document.getElementById("intro"),

      label: document.getElementById("password-label"),

      button: document.getElementById("submit-button"),

      requestAccess: document.getElementById("request-access"),

      languageButtons: document.querySelectorAll("[data-language]"),

      i18nElements: document.querySelectorAll("[data-i18n]")

    };


    let language = "en";

    let iframe = null;

    let activeDevice = null;

    let loaderStartedAt = 0;

    let loaderMaxTimer = null;

    let loaderHideTimer = null;


    /*

      ==================================================

      LANGUAGE

      ==================================================

    */


    function detectBrowserLanguage() {

      const browserLanguage = (navigator.language || "en").toLowerCase();

      return browserLanguage.startsWith("es") ? "es" : "en";

    }


    function setLanguage(nextLanguage) {

      language = nextLanguage;


      const copy = translations[language];


      document.documentElement.lang = language;

      document.title = copy.pageTitle;


      ui.eyebrow.textContent = copy.eyebrow;

      ui.heading.textContent = copy.heading;

      ui.intro.textContent = copy.intro;

      ui.label.textContent = copy.passwordLabel;

      loaderText.textContent = copy.loading;


      ui.i18nElements.forEach(function (element) {

        const key = element.dataset.i18n;


        if (copy[key]) {

          element.textContent = copy[key];

        }

      });


      if (!portfolio.classList.contains("is-visible")) {

        ui.button.textContent = copy.button;

      }


      const requestUrl = REQUEST_ACCESS_EMAIL

        ? "mailto:" +

          encodeURIComponent(REQUEST_ACCESS_EMAIL) +

          "?subject=" +

          encodeURIComponent(copy.requestSubject)

        : "#";


      ui.requestAccess.innerHTML =

        copy.requestText +

        ' <a href="' + requestUrl + '">' +

        copy.requestLink +

        "</a>";


      ui.languageButtons.forEach(function (button) {

        const isSelected = button.dataset.language === language;

        button.setAttribute("aria-pressed", String(isSelected));

      });

    }


    ui.languageButtons.forEach(function (button) {

      button.addEventListener("click", function () {

        setLanguage(button.dataset.language);

      });

    });


    /*

      ==================================================

      LOADER

      ==================================================

    */


    function showLoader() {

      window.clearTimeout(loaderHideTimer);

      window.clearTimeout(loaderMaxTimer);


      loaderStartedAt = Date.now();

      loaderText.textContent = translations[language].loading;

      loader.classList.add("is-active");


      if (iframe) {

        iframe.classList.remove("is-loaded");

      }


      loaderMaxTimer = window.setTimeout(finishLoading, LOADER_MAX_WAIT);

    }


    function finishLoading() {

      window.clearTimeout(loaderMaxTimer);

      window.clearTimeout(loaderHideTimer);


      loader.classList.remove("is-active");


      if (iframe) {

        iframe.classList.add("is-loaded");

      }

    }


    function scheduleFinish(delay) {

      window.clearTimeout(loaderHideTimer);


      const elapsed = Date.now() - loaderStartedAt;

      const remainingMin = Math.max(0, LOADER_MIN_VISIBLE - elapsed);

      const wait = Math.max(remainingMin, delay);


      loaderHideTimer = window.setTimeout(finishLoading, wait);

    }


    function handleIframeLoaded() {

      scheduleFinish(LOADER_AFTER_LOAD_DELAY);

    }


    window.addEventListener("message", function (event) {

      if (!iframe || event.source !== iframe.contentWindow) {

        return;

      }


      if (event.data && event.data.type === "INITIAL_LOAD") {

        scheduleFinish(0);

      }

    });


    /*

      ==================================================

      RESPONSIVE DEVICE

      ==================================================

    */


    const mobileQuery = window.matchMedia(

      "(max-width: " + DEVICE_BREAKPOINTS.mobileMax + "px)"

    );


    const tabletQuery = window.matchMedia(

      "(min-width: " +

        (DEVICE_BREAKPOINTS.mobileMax + 1) +

        "px) and (max-width: " +

        DEVICE_BREAKPOINTS.tabletMax +

        "px)"

    );


    function getDeviceType() {

      if (mobileQuery.matches) {

        return "mobile";

      }


      if (tabletQuery.matches) {

        return "tablet";

      }


      return "desktop";

    }


    function setPortfolioDeviceClass(device) {

      portfolio.classList.remove(

        "device-desktop",

        "device-tablet",

        "device-mobile"

      );


      portfolio.classList.add("device-" + device);

    }


    /*

      ==================================================

      FIGMA

      ==================================================

    */


    function showPortfolioMessage(message) {

      portfolio.replaceChildren();


      const container = document.createElement("div");

      container.className = "portfolio-message";


      const paragraph = document.createElement("p");

      paragraph.textContent = message;


      container.appendChild(paragraph);

      portfolio.appendChild(container);


      iframe = null;

      activeDevice = null;

    }


    function loadFigma() {

      const device = getDeviceType();

      const url = buildFigmaUrl(device);


      setPortfolioDeviceClass(device);


      if (!url) {

        showPortfolioMessage(translations[language].missingEmbed);

        finishLoading();

        return;

      }


      if (iframe && activeDevice === device) {

        return;

      }


      activeDevice = device;


      if (iframe) {

        showLoader();

        iframe.src = url;

        return;

      }


      showLoader();


      iframe = document.createElement("iframe");

      iframe.title = "Iñaki Serna portfolio";

      iframe.setAttribute("allowfullscreen", "");

      iframe.setAttribute("allowtransparency", "true");

      iframe.setAttribute("loading", "eager");


      iframe.addEventListener("load", handleIframeLoaded);


      /* Set src BEFORE inserting in the DOM to avoid an early about:blank "load". */

      iframe.src = url;


      portfolio.replaceChildren(iframe);

    }


    mobileQuery.addEventListener("change", function () {

      if (portfolio.classList.contains("is-visible")) {

        loadFigma();

      }

    });


    tabletQuery.addEventListener("change", function () {

      if (portfolio.classList.contains("is-visible")) {

        loadFigma();

      }

    });


    /*

      ==================================================

      PASSWORD

      ==================================================

    */


    function hasSessionAccess() {

      try {

        return sessionStorage.getItem("inaki-portfolio-access") === "granted";

      } catch (storageError) {

        return false;

      }

    }


    function saveSessionAccess() {

      try {

        sessionStorage.setItem("inaki-portfolio-access", "granted");

      } catch (storageError) {

        /* Session storage not available: continue without it */

      }

    }


    function openPortfolio() {

      gate.style.display = "none";

      portfolio.classList.add("is-visible");


      loadFigma();

    }


    form.addEventListener("submit", function (event) {

      event.preventDefault();


      const enteredPassword = input.value;


      ui.button.textContent = translations[language].checking;


      if (ACCESS_PASSWORD !== "" && enteredPassword === ACCESS_PASSWORD) {

        error.textContent = "";

        saveSessionAccess();

        openPortfolio();

        return;

      }


      error.textContent = translations[language].incorrectPassword;

      input.value = "";

      input.focus();

      ui.button.textContent = translations[language].button;

    });


    /*

      ==================================================

      INITIALIZATION

      ==================================================

    */


    setLanguage(detectBrowserLanguage());


    if (hasSessionAccess()) {

      openPortfolio();

    }

  </script>

</body>

</html>