Home

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kairexa Software Solutions — Coming Soon</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<style>
  :root{
    --ink: #090C14;
    --panel: #10141F;
    --paper: #EDEFF5;
    --violet: #7C5CFC;
    --teal: #23E5C4;
    --muted: #7B8299;
  }
  *{ box-sizing:border-box; margin:0; padding:0; }
  html,body{ height:100%; }
  body{
    background: var(--ink);
    color: var(--paper);
    font-family: 'Inter', sans-serif;
    overflow-x: hidden;
    position: relative;
  }

  /* ambient light: slow-drifting glow fields */
  .aurora{
    position: fixed;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
  }
  .aurora span{
    position: absolute;
    border-radius: 50%;
    filter: blur(90px);
    will-change: transform;
  }
  .aurora .a1{
    width: 46vw; height: 46vw;
    left: -10vw; top: -12vw;
    background: radial-gradient(circle, rgba(124,92,252,0.32) 0%, rgba(124,92,252,0) 70%);
    animation: drift1 26s ease-in-out infinite;
  }
  .aurora .a2{
    width: 40vw; height: 40vw;
    right: -8vw; bottom: -10vw;
    background: radial-gradient(circle, rgba(35,229,196,0.24) 0%, rgba(35,229,196,0) 70%);
    animation: drift2 32s ease-in-out infinite;
  }
  .aurora .a3{
    width: 28vw; height: 28vw;
    left: 50%; top: 40%;
    background: radial-gradient(circle, rgba(237,239,245,0.06) 0%, rgba(237,239,245,0) 70%);
    animation: drift3 22s ease-in-out infinite;
  }
  @keyframes drift1{
    0%,100%{ transform: translate(0,0) scale(1); }
    50%{ transform: translate(6vw,8vw) scale(1.12); }
  }
  @keyframes drift2{
    0%,100%{ transform: translate(0,0) scale(1); }
    50%{ transform: translate(-7vw,-6vw) scale(1.08); }
  }
  @keyframes drift3{
    0%,100%{ transform: translate(-50%,-40%) scale(1); opacity: 0.7; }
    50%{ transform: translate(-46%,-44%) scale(1.2); opacity: 1; }
  }

  /* signature: falling grain + node lattice canvases */
  #lattice, #grains{
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
  }
  #lattice{ opacity: 0.45; }
  #grains{ opacity: 0.85; }

  .wrap{
    position: relative;
    z-index: 2;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 6vh 6vw;
    text-align: center;
  }

  .mark{
    display:flex;
    align-items:center;
    gap: 10px;
    margin-bottom: 3.2rem;
  }
  .mark-glyph{
    width: 34px;
    height: 34px;
    position: relative;
  }
  .mark-glyph svg{ width:100%; height:100%; display:block; }
  .mark-word{
    font-family: 'Space Grotesk', sans-serif;
    font-weight: 700;
    font-size: 1.3rem;
    letter-spacing: -0.01em;
    color: var(--paper);
  }

  .eyebrow{
    font-family: 'Inter', sans-serif;
    font-size: 0.78rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--teal);
    margin-bottom: 1.4rem;
  }

  h1{
    font-family: 'Space Grotesk', sans-serif;
    font-weight: 700;
    font-size: clamp(2.4rem, 7vw, 5.2rem);
    line-height: 1.02;
    letter-spacing: -0.02em;
    max-width: 16ch;
    background: linear-gradient(180deg, #FFFFFF 0%, #C7CBE0 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }

  h1 em{
    font-style: normal;
    background: linear-gradient(120deg, var(--violet), var(--teal));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }

  .sub{
    margin-top: 1.6rem;
    max-width: 46ch;
    font-size: clamp(0.98rem, 1.6vw, 1.15rem);
    color: var(--muted);
    line-height: 1.6;
  }

  form{
    margin-top: 3rem;
    display: flex;
    gap: 0.6rem;
    width: 100%;
    max-width: 440px;
    flex-wrap: wrap;
    justify-content: center;
  }
  .field{
    flex: 1 1 260px;
    display: flex;
    align-items: center;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 10px;
    padding: 0 0.4rem 0 1.1rem;
    transition: border-color 0.2s ease, background 0.2s ease;
  }
  .field:focus-within{
    border-color: var(--teal);
    background: rgba(35,229,196,0.06);
  }
  .field input{
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: var(--paper);
    font-family: 'Inter', sans-serif;
    font-size: 0.95rem;
    padding: 0.85rem 0.4rem;
  }
  .field input::placeholder{ color: rgba(237,239,245,0.35); }

  button{
    flex: 0 0 auto;
    background: var(--paper);
    color: var(--ink);
    border: none;
    border-radius: 8px;
    padding: 0.85rem 1.4rem;
    font-family: 'Inter', sans-serif;
    font-weight: 600;
    font-size: 0.92rem;
    cursor: pointer;
    transition: transform 0.15s ease, background 0.2s ease;
    margin: 3px;
  }
  button:hover{ background: var(--teal); }
  button:active{ transform: scale(0.97); }
  button:focus-visible, .field:focus-within, a:focus-visible{
    outline: 2px solid var(--teal);
    outline-offset: 2px;
  }

  .status{
    margin-top: 0.9rem;
    font-size: 0.85rem;
    color: var(--teal);
    height: 1.2rem;
  }

  .status.err{ color: #FF7A7A; }

  footer{
    position: relative;
    z-index: 2;
    padding: 1.6rem 6vw 2.2rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.78rem;
    color: var(--muted);
    letter-spacing: 0.02em;
    flex-wrap: wrap;
    gap: 0.6rem;
  }
  footer a{ color: var(--muted); text-decoration: none; }
  footer a:hover{ color: var(--paper); }

  @media (prefers-reduced-motion: reduce){
    #lattice{ opacity: 0.3; }
    .aurora span{ animation: none; }
  }
</style>
</head>
<body>

<div class="aurora">
  <span class="a1"></span>
  <span class="a2"></span>
  <span class="a3"></span>
</div>
<canvas id="lattice"></canvas>
<canvas id="grains"></canvas>

<div class="wrap">
  <div class="mark">
    <span class="mark-glyph">
      <svg viewBox="0 0 34 34" fill="none">
        <path d="M5 5H29L17 17L5 5Z" stroke="#F5F7FA" stroke-width="1.9" stroke-linejoin="round"/>
        <path d="M5 29H29L17 17L5 29Z" stroke="#F5F7FA" stroke-width="1.9" stroke-linejoin="round"/>
        <path d="M9.5 25.5L20 8" stroke="#23E5C4" stroke-width="2.1" stroke-linecap="round"/>
      </svg>
    </span>
    <span class="mark-word">kairexa</span>
  </div>

  <p class="eyebrow">Building something worth the wait</p>

  <h1>Software that fits the way your team actually <em>works</em>.</h1>

  <p class="sub">
    Kairexa is in final assembly. We're putting the last pieces of our platform together —
    leave your email and we'll let you know the moment the doors open.
  </p>

  <form id="notify-form">
    <label class="field">
      <input type="email" id="email-input" placeholder="you@company.com" required autocomplete="email">
    </label>
    <button type="submit">Notify me</button>
  </form>
  <div class="status" id="status"></div>
</div>

<footer>
  <span>© 2026 Kairexa Software Solutions</span>
  <span><a href="mailto:hello@kairexa.com">hello@kairexa.com</a></span>
</footer>

<script>
  // Node lattice signature animation
  const canvas = document.getElementById('lattice');
  const ctx = canvas.getContext('2d');
  let w, h, nodes = [];
  const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  function resize(){
    w = canvas.width = window.innerWidth;
    h = canvas.height = window.innerHeight;
    const count = Math.floor((w*h)/22000);
    nodes = Array.from({length: count}, () => ({
      x: Math.random()*w,
      y: Math.random()*h,
      vx: (Math.random()-0.5)*0.15,
      vy: (Math.random()-0.5)*0.15,
    }));
  }
  window.addEventListener('resize', resize);
  resize();

  function step(){
    ctx.clearRect(0,0,w,h);
    for(const n of nodes){
      if(!reduceMotion){
        n.x += n.vx; n.y += n.vy;
        if(n.x < 0 || n.x > w) n.vx *= -1;
        if(n.y < 0 || n.y > h) n.vy *= -1;
      }
    }
    for(let i=0;i<nodes.length;i++){
      for(let j=i+1;j<nodes.length;j++){
        const a = nodes[i], b = nodes[j];
        const dx = a.x-b.x, dy = a.y-b.y;
        const dist = Math.sqrt(dx*dx+dy*dy);
        if(dist < 140){
          ctx.strokeStyle = `rgba(124,92,252,${(1-dist/140)*0.18})`;
          ctx.lineWidth = 1;
          ctx.beginPath();
          ctx.moveTo(a.x,a.y);
          ctx.lineTo(b.x,b.y);
          ctx.stroke();
        }
      }
    }
    for(const n of nodes){
      ctx.beginPath();
      ctx.arc(n.x, n.y, 1.4, 0, Math.PI*2);
      ctx.fillStyle = 'rgba(35,229,196,0.5)';
      ctx.fill();
    }
    if(!reduceMotion) requestAnimationFrame(step);
  }
  step();

  // Falling grains — the hourglass motif, drifting past the whole page
  const gCanvas = document.getElementById('grains');
  const gCtx = gCanvas.getContext('2d');
  let gw, gh, grains = [];

  function resizeGrains(){
    gw = gCanvas.width = window.innerWidth;
    gh = gCanvas.height = window.innerHeight;
    const count = Math.floor((gw*gh)/16000);
    grains = Array.from({length: count}, () => spawnGrain(Math.random()*gh));
  }
  function spawnGrain(startY){
    return {
      x: Math.random()*gw,
      y: startY,
      r: Math.random()*1.6 + 0.5,
      speed: Math.random()*0.35 + 0.12,
      drift: (Math.random()-0.5)*0.3,
      phase: Math.random()*Math.PI*2,
      hue: Math.random() > 0.5 ? '35,229,196' : '124,92,252',
      alpha: Math.random()*0.5 + 0.25
    };
  }
  window.addEventListener('resize', resizeGrains);
  resizeGrains();

  function stepGrains(t){
    gCtx.clearRect(0,0,gw,gh);
    for(const g of grains){
      if(!reduceMotion){
        g.y += g.speed;
        g.x += g.drift + Math.sin(t*0.0006 + g.phase)*0.15;
        if(g.y > gh + 4){
          Object.assign(g, spawnGrain(-4));
        }
      }
      gCtx.beginPath();
      gCtx.arc(g.x, g.y, g.r, 0, Math.PI*2);
      gCtx.fillStyle = `rgba(${g.hue},${g.alpha})`;
      gCtx.fill();
    }
    if(!reduceMotion) requestAnimationFrame(stepGrains);
  }
  requestAnimationFrame(stepGrains);

  // Form handling (in-memory only, no backend)
  const form = document.getElementById('notify-form');
  const status = document.getElementById('status');
  form.addEventListener('submit', (e) => {
    e.preventDefault();
    const email = document.getElementById('email-input').value.trim();
    const valid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    if(!valid){
      status.textContent = 'Enter a valid email address.';
      status.classList.add('err');
      return;
    }
    status.classList.remove('err');
    status.textContent = "You're on the list — we'll be in touch.";
    form.reset();
  });
</script>

</body>
</html>
Scroll to Top