<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Benoit Meunier</title>
    <meta name="description" content="Benoit Meunier">
    <meta name="author" content="Benoit Meunier">
    <meta property="og:title" content="Benoit Meunier">
    <meta property="og:description" content="Benoit Meunier">
    <meta property="og:type" content="website">
    <link rel="icon" type="image/png" href="/favicon.png">
    <link rel="icon" type="image/svg+xml" href="/favicon.svg">
    <link href="https://fonts.cdnfonts.com/css/perfect-dos-vga-437" rel="stylesheet">
    <style>
        body {
            background-color: #121212;
            margin: 0;
            padding: 20px;
            font-family: 'Perfect DOS VGA 437', monospace;
            color: #a1a1a1;
        }
        pre {
            color: #f90;
            font-size: 1.5vw;
            line-height: 1.0;
            margin: 20px auto 20px auto;
            font-weight: normal;
            white-space: pre;
            overflow: hidden;
            display: block;
            width: fit-content;
        }
        .links {
            margin-top: 20px;
            margin-left: 4px;
        }
        .links a {
            color: #a1a1a1;
            text-decoration: none;
            font-size: clamp(12px, 2.5vw, 16px);
            display: block;
            margin-bottom: 8px;
        }
        .links a:hover, .links a:focus {
            outline: none;
        }
        .links a .hotkey {
            color: #f90;
            font-weight: bold;
        }
        .links a .bracket {
            color: #3a3a3a;
        }
        p {
            color: #a1a1a1;
            font-size: clamp(12px, 2.5vw, 16px);
            margin: 20px 0 0 4px;
            max-width: 80ch;
        }
        .cursor {
            animation: blink 1s infinite;
        }
        #typed-char {
            color: #f90;
        }
        .confirmation {
            display: none;
        }
        .hidden {
            visibility: hidden;
        }
        #loading {
            color: #a1a1a1;
            margin: 20px 0 0 4px;
        }
        @keyframes blink {
            0%, 50% { opacity: 1; }
            51%, 100% { opacity: 0; }
        }
    </style>
</head>
<body>
    <p id="loading">Connecting to benoitmeunier.info...</p>
    
    <pre id="logo" class="hidden">
 .-==============-------------------:::.                 .:------===:.    
 :#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*.           -%@@@@@@@@@@@@@@+ 
.*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%=         +@@@@@@@@@@@@@@@@#:
.*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%:       =@@@@@@@@@@@@@@@@@#:
 .*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*      :#@@@@@@@@@@@@@@@@@#:
    ........................:#@@@@@@@=:%@@@@@@%-     =@@@@@@@#..=@@@@@@@#:
                             *@@@@@@@= =@@@@@@@+.   :%@@@@@@@:  =%@@@@@@#:
                             *@@@@@@@=  %@@@@@@@-   =@@@@@@@+   =%@@@@@@#:
  .+%@@%@@%@@%@@%@@%@@%@@%@@@@@@@@@@#:  :@@@@@@@*. .@@@@@@@@.   =%@@@@@@#:
 =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@=    %@@@@@@@: *@@@@@@@=    -%@@@@@@#.
:#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*     .@@@@@@@@@@@@@@@@%.    -%@@@@@@#.
 +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@=     *@@@@@@@@@@@@@@@-     -%@@@@@@#.
  .*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*:    .@@@@@@@@@@@@@@*.     -%@@@@@@#.
                             *@@@@@@@=     =@@@@@@@@@@@@@-      -%@@@@@@#.
                             *@@@@@@@=     :%@@@@@@@@@@@+.      -%@@@@@@#.
                            .#@@@@@@@=      =@@@@@@@@@@%-       -%@@@@@@#.
  =@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*.      :#@@@@@@@@@*.       -%@@@@@@#.
.*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%:        =@@@@@@@@%:        :%@@@@@@#.
.*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#.         .*@@@@@@@*         -%@@@@@@*.
 =%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%:            =@@@@@@%:         :%@@@@@@= 
   :======================---:.                :-----.            :===:   
 </pre>
    <p id="tagline" class="hidden">I am a maker of experiences, crafting with code and steel, where sparks transform into structures.</p>
    
    <div id="links" class="links hidden">
        <a href="/cdn-cgi/l/email-protection#eb8e889982998eab898e8584829f868e9e85828e99c582858d84" title="Email Benoit" data-hotkey="e"><span class="bracket">[</span><span class="hotkey">E</span><span class="bracket">]</span>mail</a>
        <a href="https://www.linkedin.com/in/benoitmeunier/" title="LinkedIn" data-hotkey="l"><span class="bracket">[</span><span class="hotkey">L</span><span class="bracket">]</span>inkedIn</a>
        <a href="https://www.x.com/bmeunier" title="X" data-hotkey="x"><span class="bracket">[</span><span class="hotkey">X</span><span class="bracket">]</span></a>
        <a href="https://www.youtube.com/@b_meunier" title="YouTube" data-hotkey="y"><span class="bracket">[</span><span class="hotkey">Y</span><span class="bracket">]</span>outube</a>
    </div>
    <p id="main-menu" class="hidden">Main Menu: <span id="typed-char"></span><span id="main-cursor" class="cursor">_</span></p>
    <p id="email-confirm" class="confirmation">Are you sure you want to email Benoit Meunier? [Y/n] <span id="email-char"></span><span class="cursor">_</span></p>
    <p id="linkedin-confirm" class="confirmation">Are you sure you want to see his LinkedIn profile? [Y/n] <span id="linkedin-char"></span><span class="cursor">_</span></p>
    <p id="x-confirm" class="confirmation">Are you sure you want to see his X profile? [Y/n] <span id="x-char"></span><span class="cursor">_</span></p>
    <p id="youtube-confirm" class="confirmation">Are you sure you want to see his YouTube channel? [Y/n] <span id="youtube-char"></span><span class="cursor">_</span></p>
    <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><script>
      // BBS Loading Sequence
      let keyboardEnabled = false;
      
      function typeText(element, text, speed = 12) {
        return new Promise(resolve => {
          element.innerHTML = '';
          element.style.visibility = 'visible';
          let i = 0;
          
          function type() {
            if (i < text.length) {
              element.innerHTML += text.charAt(i);
              i++;
              setTimeout(type, speed);
            } else {
              resolve();
            }
          }
          type();
        });
      }
      
      
      async function startBBSSequence() {
        const loading = document.getElementById('loading');
        const logo = document.getElementById('logo');
        const tagline = document.getElementById('tagline');
        const links = document.getElementById('links');
        const mainMenu = document.getElementById('main-menu');
        
        // Step 1: Connection message types out
        await typeText(loading, 'Connecting to benoitmeunier.info...');
        await new Promise(resolve => setTimeout(resolve, 500));
        
        loading.style.display = 'none';
        
        // Step 2: ASCII logo appears
        logo.style.visibility = 'visible';
        await new Promise(resolve => setTimeout(resolve, 250));
        
        // Step 3: Tagline types out
        await typeText(tagline, tagline.textContent);
        await new Promise(resolve => setTimeout(resolve, 200));
        
        // Step 4: Links appear one by one
        links.style.visibility = 'visible';
        const linkElements = links.querySelectorAll('a');
        linkElements.forEach(link => link.style.visibility = 'hidden');
        
        for (let link of linkElements) {
          link.style.visibility = 'visible';
          await new Promise(resolve => setTimeout(resolve, 200));
        }
        await new Promise(resolve => setTimeout(resolve, 125));
        
        // Step 5: Main menu appears
        mainMenu.style.visibility = 'visible';
        
        // Enable keyboard input
        keyboardEnabled = true;
      }
      
      // Start the sequence when page loads
      window.addEventListener('load', startBBSSequence);
      
      // BBS State Management
      const typedChar = document.getElementById('typed-char');
      const emailChar = document.getElementById('email-char');
      const linkedinChar = document.getElementById('linkedin-char');
      const xChar = document.getElementById('x-char');
      const youtubeChar = document.getElementById('youtube-char');
      const mainCursor = document.getElementById('main-cursor');
      const mainMenu = document.getElementById('main-menu');
      const emailConfirm = document.getElementById('email-confirm');
      const linkedinConfirm = document.getElementById('linkedin-confirm');
      const xConfirm = document.getElementById('x-confirm');
      const youtubeConfirm = document.getElementById('youtube-confirm');
      let currentState = 'main'; // 'main' or 'confirm-e' or 'confirm-l' or 'confirm-x' or 'confirm-y'
      let pendingAction = '';
      let activeConfirmChar = null;
      
      async function showConfirmation(type) {
        // Hide main cursor and keep main menu visible
        mainCursor.style.display = 'none';
        
        // Hide all confirmations first
        emailConfirm.style.display = 'none';
        linkedinConfirm.style.display = 'none';
        xConfirm.style.display = 'none';
        youtubeConfirm.style.display = 'none';
        
        let confirmElement;
        let confirmText;
        
        // Set up the right confirmation
        if (type === 'e') {
          confirmElement = emailConfirm;
          confirmText = 'Are you sure you want to email Benoit Meunier? [Y/n] ';
          pendingAction = 'mailto:ecrire@benoitmeunier.info';
          activeConfirmChar = emailChar;
        } else if (type === 'l') {
          confirmElement = linkedinConfirm;
          confirmText = 'Are you sure you want to see his LinkedIn profile? [Y/n] ';
          pendingAction = 'https://www.linkedin.com/in/benoitmeunier/';
          activeConfirmChar = linkedinChar;
        } else if (type === 'x') {
          confirmElement = xConfirm;
          confirmText = 'Are you sure you want to see his X profile? [Y/n] ';
          pendingAction = 'https://www.x.com/bmeunier';
          activeConfirmChar = xChar;
        } else if (type === 'y') {
          confirmElement = youtubeConfirm;
          confirmText = 'Are you sure you want to see his YouTube channel? [Y/n] ';
          pendingAction = 'https://www.youtube.com/@b_meunier';
          activeConfirmChar = youtubeChar;
        }
        
        // Show element and type the confirmation message
        confirmElement.style.display = 'block';
        confirmElement.innerHTML = '';
        await typeText(confirmElement, confirmText);
        
        // Add the input span and cursor with proper ID
        const charId = type + '-char';
        confirmElement.innerHTML += '<span id="' + charId + '"></span><span class="cursor">_</span>';
        
        // Update active char reference
        activeConfirmChar = document.getElementById(charId);
        
        currentState = 'confirm-' + type;
      }
      
      function showMainMenu() {
        // Show main cursor again and hide confirmations
        mainCursor.style.display = 'inline';
        emailConfirm.style.display = 'none';
        linkedinConfirm.style.display = 'none';
        xConfirm.style.display = 'none';
        youtubeConfirm.style.display = 'none';
        typedChar.textContent = '';
        
        // Clear all confirm chars
        emailChar.textContent = '';
        linkedinChar.textContent = '';
        xChar.textContent = '';
        youtubeChar.textContent = '';
        
        currentState = 'main';
        pendingAction = '';
        activeConfirmChar = null;
      }
      
      window.addEventListener('keydown', async function(evt) {
        if (evt.defaultPrevented || !keyboardEnabled) return;
        const tag = (evt.target && evt.target.tagName) ? evt.target.tagName.toLowerCase() : '';
        const isTyping = tag === 'input' || tag === 'textarea' || tag === 'select' || evt.isComposing;
        if (isTyping) return;
        
        const activeChar = currentState === 'main' ? typedChar : activeConfirmChar;
        
        // Safety check for activeChar
        if (!activeChar) return;
        
        // Handle backspace
        if (evt.key === 'Backspace') {
          activeChar.textContent = '';
          evt.preventDefault();
          return;
        }
        
        // Handle Enter key
        if (evt.key === 'Enter' && activeChar.textContent) {
          const key = activeChar.textContent.toLowerCase();
          
          if (currentState === 'main') {
            if (['e', 'l', 'x', 'y'].includes(key)) {
              await showConfirmation(key);
            }
          } else if (currentState.startsWith('confirm-')) {
            if (key === 'y') {
              window.location.assign(pendingAction);
            } else if (key === 'n') {
              location.reload();
            }
          }
          
          evt.preventDefault();
          return;
        }
        
        // Handle single character typing
        if (evt.key.length === 1 && !evt.metaKey && !evt.ctrlKey && !evt.altKey) {
          activeChar.textContent = evt.key.toUpperCase();
          evt.preventDefault();
          return;
        }
        
        // Direct hotkey functionality (only in main menu)
        if (currentState === 'main') {
          const key = (evt.key || '').toLowerCase();
          if (['e', 'l', 'x', 'y'].includes(key)) {
            await showConfirmation(key);
            evt.preventDefault();
          }
        }
      });
    </script>
</body>
</html>