<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="description" content="Kaladi Tamil — Tamil input tools across desktop and mobile platforms. Type in Tamil using Phonetic, Tamil99, or Old Typewriter layouts."><meta name="theme-color" content="#23272a" id="theme-color-meta"><link rel="icon" type="image/png" href="/icon.png"><title>Kaladi Tamil — Tamil Input Tools for Every Platform</title><script>
    (function() {
      const THEME_STORAGE_KEY = 'kaladi_theme';

      function getInitialTheme() {
        try {
          const storedTheme = localStorage.getItem(THEME_STORAGE_KEY);
          if (storedTheme === 'dark' || storedTheme === 'light') {
            return storedTheme;
          }
        } catch (_) {}

        if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) {
          return 'light';
        }

        return 'dark';
      }

      function applyTheme(theme, persist) {
        document.documentElement.setAttribute('data-theme', theme);
        document.documentElement.style.colorScheme = theme;

        const meta = document.getElementById('theme-color-meta');
        if (meta) {
          meta.setAttribute('content', theme === 'light' ? '#ffffff' : '#23272a');
        }

        if (persist) {
          try {
            localStorage.setItem(THEME_STORAGE_KEY, theme);
          } catch (_) {}
        }

        window.dispatchEvent(new CustomEvent('kaladi-theme-change', {
          detail: { theme }
        }));
      }

      window.getKaladiTheme = function() {
        return document.documentElement.getAttribute('data-theme') || 'dark';
      };

      window.updateThemeToggleIcon = function(theme) {
        const labelFor = (targetTheme) => {
          const t = window.getText || ((key) => {
            if (key === 'theme.aria.light') return 'Switch to light theme';
            if (key === 'theme.aria.dark') return 'Switch to dark theme';
            return 'Toggle theme';
          });
          return targetTheme === 'dark' ? t('theme.aria.dark') : t('theme.aria.light');
        };

        document.querySelectorAll('.theme-toggle').forEach((toggle) => {
          toggle.setAttribute('aria-label', labelFor(theme === 'dark' ? 'light' : 'dark'));
        });
      };

      window.toggleTheme = function() {
        const currentTheme = window.getKaladiTheme();
        const nextTheme = currentTheme === 'dark' ? 'light' : 'dark';
        applyTheme(nextTheme, true);
        window.updateThemeToggleIcon(nextTheme);
      };

      const initialTheme = getInitialTheme();
      applyTheme(initialTheme, false);

      if (window.matchMedia) {
        window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => {
          try {
            if (localStorage.getItem(THEME_STORAGE_KEY)) return;
          } catch (_) {}

          const nextTheme = event.matches ? 'dark' : 'light';
          applyTheme(nextTheme, false);
          window.updateThemeToggleIcon(nextTheme);
        });
      }

      document.addEventListener('DOMContentLoaded', () => {
        window.updateThemeToggleIcon(window.getKaladiTheme());
        document.querySelectorAll('.theme-toggle').forEach((toggle) => {
          toggle.addEventListener('click', window.toggleTheme);
        });
      });
    })();
  </script><!-- Google tag (gtag.js) --><script async src="https://www.googletagmanager.com/gtag/js?id=G-3QF5N8WED8"></script><script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', 'G-3QF5N8WED8');
  </script><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6162987305272220" crossorigin="anonymous"></script><link rel="stylesheet" href="/_astro/kaladi-tamil-next-edition.GIQ6PMHq.css">
<link rel="stylesheet" href="/_astro/index.DxhBhJK7.css"></head> <body>  <div class="page-wrapper" id="main-content"> <header> <div class="container"> <div class="logo-section"> <img src="/kaladi-wordmark.png" alt="Kaladi Tamil" class="nav-wordmark"> </div> <nav> <a href="/about" data-i18n="nav.about">About Us</a> <a href="/blog/kaladi-tamil-next-edition" data-i18n="nav.blog">Blog</a> <a href="/welcome" data-i18n="nav.help">Help</a> <a href="/privacy" data-i18n="nav.privacy">Privacy</a> <div class="lang-toggle" role="group" aria-label="Language"> <button id="lang-en" type="button" class="lang-btn active">EN</button> <button id="lang-ta" type="button" class="lang-btn">தமிழ்</button> </div> <button id="theme-toggle" class="theme-toggle" aria-label="Toggle theme"> <svg class="sun-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> <svg class="moon-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path> </svg> </button> </nav> </div> </header> <main> <!-- NHM Writer → Kaladi Tamil Migration Section --> <section class="migration-section"> <div class="container"> <div class="migration-card"> <div class="migration-logos"> <div class="migration-from"> <img src="/nhmwriter-logo.gif" alt="NHM Writer" class="migration-logo-nhm"> </div> <div class="migration-arrow"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="5" y1="12" x2="19" y2="12"></line> <polyline points="12 5 19 12 12 19"></polyline> </svg> </div> <div class="migration-to"> <img src="/icon.png" alt="Kaladi Tamil" class="migration-logo"> <span class="migration-name" data-i18n="migration.name">Kaladi Tamil</span> </div> </div> <div class="migration-body"> <p class="migration-desc" data-i18n="migration.desc">
Kaladi Tamil is the next edition of NHM Writer, redeveloped for current Windows and macOS systems with native platform frameworks, signed releases, and transparent security checks.
</p> <a href="/blog/kaladi-tamil-next-edition" class="migration-link" data-i18n="migration.cta">Read the full post</a> <div class="migration-highlighter"> <span class="badge badge-free" data-i18n="migration.free">Free</span> </div> </div> </div> <p class="migration-coming-soon" data-i18n="migration.comingSoon">
Android & iOS coming soon
</p> </div> </section> <!-- Hero Section --> <section class="hero"> <div class="hero-bg-pattern"></div> <div class="container"> <div class="hero-top"> <div class="hero-content"> <p class="hero-announcement" data-i18n="hero.announcement">
Old Typewriter, Bamini, Inscript issues will be resolved in 0.1.89 release (Windows) before 1st week of June
</p> <img src="/icon.png" alt="Kaladi Tamil" class="hero-logo"> <h1 class="hero-title"> <span data-i18n="hero.titleLine1">TYPE TAMIL,</span><br> <span class="gradient-text" data-i18n="hero.titleLine2">YOUR WAY</span> </h1> <p class="hero-subtitle" data-i18n="hero.subtitle">
The most powerful Tamil input tool across desktop and mobile platforms. Free, fast, and works everywhere.
</p> </div> <div class="hero-visual"> <!-- Tamil script decorative background --> <div class="tamil-bg-text">தமிழ்</div> <!-- Keymap Carousel --> <div class="keymap-carousel"> <div class="keymap-tabs"> <button class="keymap-tab active" data-keymap="phonetic" data-i18n="keymaps.phonetic">Phonetic</button> <button class="keymap-tab" data-keymap="tamil99" data-i18n="keymaps.tamil99">Tamil99</button> <button class="keymap-tab" data-keymap="typewriter" data-i18n="keymaps.typewriter">Old Typewriter</button> <button class="keymap-tab" data-keymap="bamini" data-i18n="keymaps.bamini">Bamini</button> <button class="keymap-tab" data-keymap="inscript" data-i18n="keymaps.inscript">Inscript</button> </div> <div class="keymap-slides"> <!-- Phonetic --> <div class="keymap-slide active" data-keymap="phonetic"> <div class="word-examples"> <div class="example"> <span class="input-text">indhiyaa</span> <span class="arrow">→</span> <span class="tamil-text">இந்தியா</span> </div> <div class="example"> <span class="input-text">thamiz</span> <span class="arrow">→</span> <span class="tamil-text">தமிழ்</span> </div> <div class="example"> <span class="input-text">ammaa</span> <span class="arrow">→</span> <span class="tamil-text">அம்மா</span> </div> <div class="example"> <span class="input-text">iLaiyaraajaa</span> <span class="arrow">→</span> <span class="tamil-text">இளையராஜா</span> </div> <div class="example"> <span class="input-text">mazai</span> <span class="arrow">→</span> <span class="tamil-text">மழை</span> </div> </div> </div> <!-- Tamil99 --> <div class="keymap-slide" data-keymap="tamil99"> <div class="word-examples"> <div class="example"> <span class="input-text">s;ls'q</span> <span class="arrow">→</span> <span class="tamil-text">இந்தியா</span> </div> <div class="example"> <span class="input-text">lks/f</span> <span class="arrow">→</span> <span class="tamil-text">தமிழ்</span> </div> <div class="example"> <span class="input-text">akkq</span> <span class="arrow">→</span> <span class="tamil-text">அம்மா</span> </div> <div class="example"> <span class="input-text">syr'mqEq</span> <span class="arrow">→</span> <span class="tamil-text">இளையராஜா</span> </div> <div class="example"> <span class="input-text">k/r</span> <span class="arrow">→</span> <span class="tamil-text">மழை</span> </div> </div> </div> <!-- Typewriter --> <div class="keymap-slide" data-keymap="typewriter"> <div class="word-examples"> <div class="example"> <span class="input-text">,;epjah</span> <span class="arrow">→</span> <span class="tamil-text">இந்தியா</span> </div> <div class="example"> <span class="input-text">jpk;H</span> <span class="arrow">→</span> <span class="tamil-text">தமிழ்</span> </div> <div class="example"> <span class="input-text">m;kkh</span> <span class="arrow">→</span> <span class="tamil-text">அம்மா</span> </div> <div class="example"> <span class="input-text">,isauh$h</span> <span class="arrow">→</span> <span class="tamil-text">இளையராஜா</span> </div> <div class="example"> <span class="input-text">kiH</span> <span class="arrow">→</span> <span class="tamil-text">மழை</span> </div> </div> </div> <!-- Bamini --> <div class="keymap-slide" data-keymap="bamini"> <div class="word-examples"> <div class="example"> <span class="input-text">,e;jpah</span> <span class="arrow">→</span> <span class="tamil-text">இந்தியா</span> </div> <div class="example"> <span class="input-text">jkpo;</span> <span class="arrow">→</span> <span class="tamil-text">தமிழ்</span> </div> <div class="example"> <span class="input-text">mk;kh</span> <span class="arrow">→</span> <span class="tamil-text">அம்மா</span> </div> <div class="example"> <span class="input-text">,isauh[h</span> <span class="arrow">→</span> <span class="tamil-text">இளையராஜா</span> </div> <div class="example"> <span class="input-text">kio</span> <span class="arrow">→</span> <span class="tamil-text">மழை</span> </div> </div> </div> <!-- Inscript --> <div class="keymap-slide" data-keymap="inscript"> <div class="word-examples"> <div class="example"> <span class="input-text">Fvdlf/e</span> <span class="arrow">→</span> <span class="tamil-text">இந்தியா</span> </div> <div class="example"> <span class="input-text">lcfBd</span> <span class="arrow">→</span> <span class="tamil-text">தமிழ்</span> </div> <div class="example"> <span class="input-text">Dcdce</span> <span class="arrow">→</span> <span class="tamil-text">அம்மா</span> </div> <div class="example"> <span class="input-text">FNw/jepe</span> <span class="arrow">→</span> <span class="tamil-text">இளையராஜா</span> </div> <div class="example"> <span class="input-text">cBw</span> <span class="arrow">→</span> <span class="tamil-text">மழை</span> </div> </div> </div> </div> </div> </div> </div> <!-- Platform Selection — full width --> <div id="download" class="download-anchor" aria-hidden="true"></div> <div class="hero-download-section" id="hero-download-section"> <div class="download-heading"> <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg> <span data-i18n="download.heading">Download</span> </div> <div class="platform-selection"> <div class="platform-row" id="platform-grid"> <!-- Platforms will be rendered here --> </div> </div> <div id="hero-downloads" class="hero-downloads"></div> <div id="turnstile-container" style="display: none; margin: 1.5rem 0;"></div> <div id="file-details" class="file-details" style="display: none;"> <table class="file-details-table"> <tbody> <tr> <td class="file-details-label">SHA256:</td> <td class="file-details-value" id="file-sha256"></td> </tr> <tr> <td class="file-details-label" data-i18n="file.size">File size:</td> <td class="file-details-value" id="file-size"></td> </tr> <tr> <td class="file-details-label" data-i18n="file.name">File name:</td> <td class="file-details-value" id="file-name"></td> </tr> </tbody> </table> </div> <!-- Security & Trust Section --> <div id="security-trust" class="security-trust" style="display: none;"> <div class="trust-header"> <svg class="trust-shield-icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path> <path d="M9 12l2 2 4-4"></path> </svg> <span data-i18n="trust.title">Security & Trust</span> </div> <div id="vt-badge" class="trust-row" style="display: none;"> <span class="trust-label">VirusTotal:</span> <span class="trust-value"> <span id="vt-result" class="vt-result"></span> <a id="vt-link" href="#" target="_blank" rel="noopener" class="vt-report-link">View full report</a> </span> </div> <div class="trust-row signed-row"> <span class="trust-label" data-i18n="trust.signedBy">Signed by:</span> <span class="trust-value signed-badge"> <svg class="signed-check-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path> <path d="M9 12l2 2 4-4"></path> </svg> <span class="signed-org">Kaladi Atma Intelligence Pvt Ltd</span> </span> </div> <div class="trust-row signed-meta-row"> <span class="trust-label"></span> <span class="trust-value signed-meta">
DigiCert Code Signing &middot; SHA-256 &middot; Timestamped
</span> </div> <details class="checksums-details"> <summary data-i18n="trust.checksums">Checksums</summary> <table class="checksums-table"> <tbody> <tr> <td class="checksum-label">SHA-256:</td> <td class="checksum-value" id="trust-sha256"></td> </tr> <tr id="trust-sha1-row" style="display: none;"> <td class="checksum-label">SHA-1:</td> <td class="checksum-value" id="trust-sha1"></td> </tr> <tr id="trust-md5-row" style="display: none;"> <td class="checksum-label">MD5:</td> <td class="checksum-value" id="trust-md5"></td> </tr> </tbody> </table> </details> <div id="vt-scan-date" class="trust-row trust-meta" style="display: none;"> <span class="trust-label" data-i18n="trust.scanned">Scanned:</span> <span class="trust-value" id="vt-date-value"></span> </div> </div> <p class="version-badge" id="version-badge-bar" style="display: none;"> <span class="badge-label" id="version-badge">Latest Version</span> <span class="badge-separator">•</span> <span class="badge-label" data-i18n="hero.badgePlatform">Multi-platform support</span> <span class="badge-separator">•</span> <span class="badge-label" data-i18n="hero.badgeFree">Free Forever</span> </p> </div> </div> </section> <section class="compatibility-section"> <div class="container"> <div class="section-headline"> <h2 class="compatibility-title" data-i18n="compatibility.title">Compatibility</h2> <p id="compatibility-active-os" class="compatibility-active-os">macOS Universal</p> </div> <p id="compatibility-subtitle" class="compatibility-subtitle">
Kaladi Tamil ships as a single <strong>universal installer</strong> (<code>x86_64 + arm64</code>), so you do not need separate downloads.
</p> <div id="compatibility-table-block" class="compatibility-table-wrapper"> <table class="compatibility-table"> <thead> <tr> <th data-i18n="compatibility.table.version">macOS Version</th> <th data-i18n="compatibility.table.intel">Intel Mac (x86_64)</th> <th data-i18n="compatibility.table.silicon">Apple Silicon Mac (arm64)</th> <th data-i18n="compatibility.table.notes">Notes</th> </tr> </thead> <tbody> <tr> <td data-i18n="compatibility.rows.catalina.version">10.15 Catalina</td> <td data-i18n="compatibility.rows.catalina.intel">Supported</td> <td data-i18n="compatibility.rows.catalina.silicon">Not supported</td> <td data-i18n="compatibility.rows.catalina.notes">Apple Silicon Macs did not exist on Catalina</td> </tr> <tr> <td data-i18n="compatibility.rows.bigsur.version">11 Big Sur</td> <td data-i18n="compatibility.rows.bigsur.intel">Supported</td> <td data-i18n="compatibility.rows.bigsur.silicon">Supported</td> <td data-i18n="compatibility.rows.bigsur.notes">Universal build</td> </tr> <tr> <td data-i18n="compatibility.rows.monterey.version">12 Monterey and later (including Tahoe and newer)</td> <td data-i18n="compatibility.rows.monterey.intel">Supported</td> <td data-i18n="compatibility.rows.monterey.silicon">Supported</td> <td data-i18n="compatibility.rows.monterey.notes">Universal build</td> </tr> </tbody> </table> </div> <p id="compatibility-empty" class="compatibility-empty" hidden></p> </div> </section> <section class="release-notes-section"> <div class="container"> <div class="section-headline release-headline"> <h2 class="release-title" data-i18n="release.title">Release Notes</h2> <p id="release-platform" class="release-platform">macOS Universal</p> </div> <p id="release-version" class="release-version"></p> <ul id="release-list" class="release-list"></ul> </div> </section> <!-- Features Wave Section --> <section class="features-section"> <div class="wave-divider"> <svg viewBox="0 0 1200 120" preserveAspectRatio="none"> <path d="M0,0 C150,100 350,0 600,50 C850,100 1050,0 1200,50 L1200,120 L0,120 Z"></path> </svg> </div> <div class="container features-container"> <div class="feature-block"> <div class="feature-visual"> <div class="visual-demo demo-apps"> <div class="demo-window"> <div class="demo-title" data-i18n="features.demoTitle">🚀 Works everywhere</div> <div class="app-icons-wrapper"> <div class="app-icons"> <div class="app-icon word-icon"> <div class="icon-badge">W</div> <span>Word</span> </div> <div class="app-icon excel-icon"> <div class="icon-badge">X</div> <span>Excel</span> </div> <div class="app-icon chrome-icon"> <div class="icon-badge">C</div> <span>Chrome</span> </div> <div class="app-icon vscode-icon"> <div class="icon-badge">VS</div> <span>Code</span> </div> <div class="app-icon notepad-icon"> <div class="icon-badge">N</div> <span>Notepad</span> </div> <div class="app-icon email-icon"> <div class="icon-badge">@</div> <span>Email</span> </div> </div> <!-- Connection lines illustration --> <div class="connection-lines"> <svg viewBox="0 0 200 200"> <circle cx="100" cy="100" r="40" fill="#C4ED41" opacity="0.2"></circle> <circle cx="100" cy="100" r="60" fill="none" stroke="#064734" stroke-width="2" opacity="0.3" stroke-dasharray="4 4"></circle> <circle cx="100" cy="100" r="80" fill="none" stroke="#C4ED41" stroke-width="2" opacity="0.2" stroke-dasharray="4 4"></circle> </svg> </div> </div> </div> </div> </div> <div class="feature-text"> <h2 data-i18n="features.title">System-level integration</h2> <p data-i18n="features.subtitle" data-i18n-html="true">
Built with native system-level input integration, Kaladi works seamlessly in your everyday apps.
                No browser extensions, no copy-paste — just type Tamil anywhere.
</p> <ul class="feature-list"> <li data-i18n="features.points.0">✓ Productivity apps (Pages, Numbers, Keynote)</li> <li data-i18n="features.points.1">✓ Browsers (Safari, Chrome, Firefox)</li> <li data-i18n="features.points.2">✓ Developer tools (VS Code, Terminal, JetBrains IDEs)</li> <li data-i18n="features.points.3">✓ Communication apps (Mail, Messages, Slack, Discord)</li> </ul> </div> </div> </div> </section> <!-- Keymap Matrix --> <section class="matrix-section"> <div class="container"> <h2 class="matrix-title" data-i18n="matrix.title">41 Tamil Keymaps</h2> <p class="matrix-subtitle" data-i18n="matrix.subtitle">One language, 11 font encodings, 5 keyboard layouts</p> <div class="matrix-table-wrapper"> <table class="matrix-table"> <thead> <tr> <th data-i18n="matrix.encoding">Encoding</th> <th>Phonetic</th> <th>Tamil99</th> <th>Bamini</th> <th data-i18n="matrix.typewriter">Typewriter</th> <th>Inscript</th> </tr> </thead> <tbody> <tr> <td class="encoding-name">Unicode</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> </tr> <tr> <td class="encoding-name">Bamini</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-dash">&mdash;</td> </tr> <tr> <td class="encoding-name">Shrilipi</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-dash">&mdash;</td> </tr> <tr> <td class="encoding-name">TSCII</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-dash">&mdash;</td> </tr> <tr> <td class="encoding-name">TAB</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-dash">&mdash;</td> </tr> <tr> <td class="encoding-name">TAM</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-dash">&mdash;</td> </tr> <tr> <td class="encoding-name">Vanavil</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-dash">&mdash;</td> </tr> <tr> <td class="encoding-name">Softview</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-dash">&mdash;</td> </tr> <tr> <td class="encoding-name">Diacritic</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-dash">&mdash;</td> </tr> <tr> <td class="encoding-name">TACE</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-dash">&mdash;</td> <td class="matrix-dash">&mdash;</td> <td class="matrix-dash">&mdash;</td> </tr> <tr> <td class="encoding-name">Brahmi</td> <td class="matrix-check">&#10003;</td> <td class="matrix-check">&#10003;</td> <td class="matrix-dash">&mdash;</td> <td class="matrix-dash">&mdash;</td> <td class="matrix-dash">&mdash;</td> </tr> </tbody> </table> </div> </div> </section> <!-- Key Features --> <section class="key-features-section"> <div class="container"> <h2 class="key-features-title" data-i18n="keyFeatures.title">For All Types of Users</h2> <div class="key-features-grid"> <div class="key-feature-card"> <div class="key-feature-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"></rect><path d="M6 8h.01M10 8h.01M14 8h.01M18 8h.01M8 12h.01M12 12h.01M16 12h.01M7 16h10"></path></svg> </div> <h3 id="feature-tsf-title" data-i18n="keyFeatures.tsf.title.windows">Native TSF Integration</h3> <p id="feature-tsf-desc" data-i18n="keyFeatures.tsf.desc.windows">Built on the Windows Text Services Framework for true OS-level input — works in every app, not just browsers.</p> </div> <div class="key-feature-card"> <div class="key-feature-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z"></path></svg> </div> <h3 data-i18n="keyFeatures.hotkeys.title">Hotkey Switching</h3> <p id="feature-hotkeys-desc" data-i18n="keyFeatures.hotkeys.desc.windows">Press Alt+1 for Tamil99, Alt+2 for Phonetic, Alt+0 for English — switch keymaps instantly without touching the mouse.</p> </div> <div class="key-feature-card"> <div class="key-feature-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect><line x1="8" y1="21" x2="16" y2="21"></line><line x1="12" y1="17" x2="12" y2="21"></line></svg> </div> <h3 id="feature-perwindow-title" data-i18n="keyFeatures.perWindow.title.windows">Per-Window Keymap</h3> <p id="feature-perwindow-desc" data-i18n="keyFeatures.perWindow.desc.windows">Each window remembers its own keymap. Type Tamil in Word and English in Chrome — no manual switching needed.</p> </div> <div class="key-feature-card"> <div class="key-feature-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 4H8l-7 8 7 8h13a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z"></path><line x1="18" y1="9" x2="12" y2="15"></line><line x1="12" y1="9" x2="18" y2="15"></line></svg> </div> <h3 data-i18n="keyFeatures.backspace.title">Smart Backspace</h3> <p data-i18n="keyFeatures.backspace.desc">Removes the last logical Tamil character, not individual code points. One press undoes the last typing step cleanly.</p> </div> </div> </div> </section> <!-- Quick Stats --> <section class="stats-section"> <div class="container"> <div class="stats-grid"> <div class="stat-card"> <div class="stat-number">41</div> <div class="stat-label" data-i18n="stats.keymaps">Tamil Keymaps</div> </div> <div class="stat-card"> <div class="stat-number">11</div> <div class="stat-label" data-i18n="stats.encodings">Font Encodings</div> </div> <div class="stat-card"> <div class="stat-number">5</div> <div class="stat-label" data-i18n="stats.layouts">Keyboard Layouts</div> </div> <div class="stat-card"> <div class="stat-number">100%</div> <div class="stat-label" data-i18n="stats.free">Free Forever</div> </div> </div> </div> </section> </main> <footer> <div class="container"> <p>kāladi  ātma intelligence</p> <p class="footer-links"> <a href="/about" data-i18n="nav.about">About Us</a> <span>•</span> <a href="/welcome" data-i18n="nav.help">Help</a> <span>•</span> <a href="/privacy" data-i18n="nav.privacy">Privacy</a> </p> <div class="footer-feedback"> <p class="footer-feedback-label" data-i18n="footer.feedback">Feedback email</p> <canvas id="footer-feedback-email" class="footer-feedback-email" width="180" height="24" role="img" aria-label="Feedback email address"></canvas> </div> <p class="build-timestamp"><span data-i18n="footer.built">Built:</span> 24 May 2026, 1:13:45 pm IST</p> </div> </footer> </div> <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script> <script>
    (function() {
      const LANG_STORAGE_KEY = 'kaladi_lang';
      const translations = {
        en: {
          'brand.name': 'Kaladi Tamil',
          'nav.about': 'About Us',
          'nav.blog': 'Blog',
          'nav.help': 'Help',
          'nav.privacy': 'Privacy',
          'hero.titleLine1': 'TYPE TAMIL,',
          'hero.titleLine2': 'YOUR WAY',
          'hero.announcement': 'Old Typewriter, Bamini, Inscript issues will be resolved in 0.1.89 release (Windows) before 1st week of June',
          'hero.subtitle': 'The most powerful Tamil input tool across desktop and mobile platforms. Free, fast, and works everywhere.',
          'hero.badgePlatform': 'Multi-platform support',
          'hero.badgeFree': 'Free Forever',
          'file.size': 'File size:',
          'file.name': 'File name:',
          'trust.title': 'Security & Trust',
          'trust.signedBy': 'Signed by:',
          'trust.checksums': 'Checksums',
          'trust.scanned': 'Scanned:',
          'migration.desc': 'Kaladi Tamil is the next edition of NHM Writer, redeveloped for current Windows and macOS systems with native platform frameworks, signed releases, and transparent security checks.',
          'migration.cta': 'Read the full post',
          'migration.name': 'Kaladi Tamil',
          'migration.free': 'Free',
          'migration.comingSoon': 'Android & iOS coming soon',
          'keymaps.phonetic': 'Phonetic',
          'keymaps.tamil99': 'Tamil99',
          'keymaps.typewriter': 'Old Typewriter',
          'keymaps.bamini': 'Bamini',
          'keymaps.inscript': 'Inscript',
          'compatibility.title': 'Compatibility',
          'compatibility.table.version': 'macOS Version',
          'compatibility.table.intel': 'Intel Mac (x86_64)',
          'compatibility.table.silicon': 'Apple Silicon Mac (arm64)',
          'compatibility.table.notes': 'Notes',
          'compatibility.rows.catalina.version': '10.15 Catalina',
          'compatibility.rows.catalina.intel': 'Supported',
          'compatibility.rows.catalina.silicon': 'Not supported',
          'compatibility.rows.catalina.notes': 'Apple Silicon Macs did not exist on Catalina',
          'compatibility.rows.bigsur.version': '11 Big Sur',
          'compatibility.rows.bigsur.intel': 'Supported',
          'compatibility.rows.bigsur.silicon': 'Supported',
          'compatibility.rows.bigsur.notes': 'Universal build',
          'compatibility.rows.monterey.version': '12 Monterey and later (including Tahoe and newer)',
          'compatibility.rows.monterey.intel': 'Supported',
          'compatibility.rows.monterey.silicon': 'Supported',
          'compatibility.rows.monterey.notes': 'Universal build',
          'compatibility.subtitle.mac': 'Kaladi Tamil ships as a single <strong>universal installer</strong> (<code>x86_64 + arm64</code>), so you do not need separate downloads.',
          'compatibility.subtitle.windows': 'Windows uses separate installers for x64 and ARM64. Pick the one that matches your device.',
          'compatibility.subtitle.generic': '{platform} compatibility details will be published with that release.',
          'compatibility.empty.windows.x64': 'Windows x64 is supported on Windows 10 64-bit and newer (Windows 11 recommended).',
          'compatibility.empty.windows.arm64': 'Windows ARM64 is supported on Windows 11 ARM64 devices (Surface Pro, Snapdragon X Elite, and similar).',
          'compatibility.empty.windows.default': 'Windows uses architecture-specific installers. Use x64 for Intel/AMD PCs and ARM64 for ARM-based PCs.',
          'compatibility.empty.macDisabled': 'macOS downloads are temporarily unavailable while we sort out the current installer issue.',
          'compatibility.empty.generic': 'Detailed compatibility notes for {platform} will be added with that release.',
          'release.title': 'Release Notes',
          'release.version.mac': 'v0.1.2',
          'release.version.windows': 'v0.1.88',
          'release.version.comingSoon': 'Coming soon',
          'release.version.temporarilyUnavailable': 'Temporarily unavailable',
          'release.notes.mac.1': '41 Tamil keymaps — 11 font encodings (Unicode, Bamini, Shrilipi, TSCII, and more) across 5 keyboard layouts (Phonetic, Tamil99, Bamini, Old Typewriter, Inscript).',
          'release.notes.mac.2': 'Hotkey switching — press configurable hotkeys to switch keymaps instantly from the menu bar.',
          'release.notes.mac.3': 'Real-time Tamil input across all layouts (for example, "thamizh" → "தமிழ்", "ammaa" → "அம்மா" in Phonetic mode).',
          'release.notes.mac.4': 'Smart backspace restores the previous input step instead of removing just one character.',
          'release.notes.mac.5': 'Native macOS input source — works seamlessly in Pages, Numbers, Safari, Chrome, VS Code, and more.',
          'release.notes.mac.6': 'Fixes delayed keymap activation after install by making the IME re-sync from shared state if it misses the first helper notification.',
          'release.notes.mac.7': 'New macOS downloads now follow a dedicated update channel, so existing installs stay on the older path until we intentionally migrate them.',
          'release.notes.windows.x64.1': '41 Tamil keymaps — 11 font encodings (Unicode, Bamini, Shrilipi, TSCII, and more) across 5 keyboard layouts (Phonetic, Tamil99, Bamini, Old Typewriter, Inscript).',
          'release.notes.windows.x64.2': 'Hotkey switching — press Alt+1, Alt+2, etc. to switch keymaps instantly. Customizable from Settings.',
          'release.notes.windows.x64.3': 'Per-window keymap memory — each window remembers its own active keymap automatically.',
          'release.notes.windows.x64.4': 'Smart backspace restores the previous input step instead of removing just one character.',
          'release.notes.windows.x64.5': 'Native TSF (Text Services Framework) integration — works in Notepad, Word, Excel, VS Code, Chrome, Edge, and more.',
          'release.notes.windows.x64.6': 'Lightweight tray app (~3 MB), starts on login, one-click MSI installer with clean uninstall.',
          'release.notes.windows.arm64.1': '41 Tamil keymaps — 11 font encodings (Unicode, Bamini, Shrilipi, TSCII, and more) across 5 keyboard layouts (Phonetic, Tamil99, Bamini, Old Typewriter, Inscript).',
          'release.notes.windows.arm64.2': 'Hotkey switching — press Alt+1, Alt+2, etc. to switch keymaps instantly. Customizable from Settings.',
          'release.notes.windows.arm64.3': 'Per-window keymap memory — each window remembers its own active keymap automatically.',
          'release.notes.windows.arm64.4': 'Smart backspace restores the previous input step instead of removing just one character.',
          'release.notes.windows.arm64.5': 'Native TSF (Text Services Framework) integration — works in Notepad, Word, Excel, VS Code, Chrome, Edge, and more.',
          'release.notes.windows.arm64.6': 'Lightweight tray app (~3 MB), starts on login, one-click MSI installer with clean uninstall.',
          'release.notes.ios.1': 'iOS release notes will be published when iOS support is available.',
          'release.notes.android.1': 'Android release notes will be published when Android support is available.',
          'features.demoTitle': '🚀 Works everywhere',
          'features.title': 'System-level integration',
          'features.subtitle': 'Built with native system-level input integration, Kaladi works seamlessly in your everyday apps. No browser extensions, no copy-paste — just type Tamil anywhere.',
          'features.points.0': '✓ Productivity apps (Pages, Numbers, Keynote)',
          'features.points.1': '✓ Browsers (Safari, Chrome, Firefox)',
          'features.points.2': '✓ Developer tools (VS Code, Terminal, JetBrains IDEs)',
          'features.points.3': '✓ Communication apps (Mail, Messages, Slack, Discord)',
          'stats.keymaps': 'Tamil Keymaps',
          'stats.encodings': 'Font Encodings',
          'stats.layouts': 'Keyboard Layouts',
          'stats.free': 'Free Forever',
          'matrix.title': '41 Tamil Keymaps',
          'matrix.subtitle': 'One language, 11 font encodings, 5 keyboard layouts',
          'matrix.encoding': 'Encoding',
          'matrix.typewriter': 'Typewriter',
          'keyFeatures.title': 'For All Types of Users',
          'keyFeatures.tsf.title.windows': 'Native TSF Integration',
          'keyFeatures.tsf.desc.windows': 'Built on the Windows Text Services Framework for true OS-level input — works in every app, not just browsers.',
          'keyFeatures.tsf.title.mac': 'Native Input Method',
          'keyFeatures.tsf.desc.mac': 'Built on Apple\'s Input Method Kit for true OS-level input — works in Pages, Safari, Chrome, VS Code, and every app.',
          'keyFeatures.hotkeys.title': 'Hotkey Switching',
          'keyFeatures.hotkeys.desc.windows': 'Press Alt+1 for Tamil99, Alt+2 for Phonetic, Alt+0 for English — switch keymaps instantly without touching the mouse.',
          'keyFeatures.hotkeys.desc.mac': 'Configurable hotkeys to switch keymaps instantly — toggle between Tamil and English without touching the mouse.',
          'keyFeatures.perWindow.title.windows': 'Per-Window Keymap',
          'keyFeatures.perWindow.desc.windows': 'Each window remembers its own keymap. Type Tamil in Word and English in Chrome — no manual switching needed.',
          'keyFeatures.perWindow.title.mac': 'Menu Bar Control',
          'keyFeatures.perWindow.desc.mac': 'Switch between 41 keymaps from the menu bar. See your active layout at a glance and change it with one click.',
          'keyFeatures.backspace.title': 'Smart Backspace',
          'keyFeatures.backspace.desc': 'Removes the last logical Tamil character, not individual code points. One press undoes the last typing step cleanly.',
          'footer.feedback': 'Feedback email',
          'footer.built': 'Built:',
          'theme.aria.light': 'Switch to light theme',
          'theme.aria.dark': 'Switch to dark theme',
          'platform.labels.mac': 'macOS',
          'platform.labels.windows': 'Windows',
          'platform.labels.ios': 'iOS',
          'platform.labels.android': 'Android',
          'platform.sublabels.universal': 'Universal',
          'platform.sublabels.x64': 'x64',
          'platform.sublabels.arm64': 'ARM64',
          'platform.badges.detected': 'detected',
          'platform.badges.soon': 'soon',
          'platform.comingSoon': '{platform} build is coming soon.',
          'download.heading': 'Download',
          'download.button': 'Download for {platform}',
          'download.size.universal': '~3 MB universal installer',
          'download.size.windows': '~3 MB Windows installer',
          'download.size.default': '~3 MB installer'
        },
        ta: {
          'brand.name': 'காலடி தமிழ்',
          'nav.about': 'எம்மைப் பற்றி',
          'nav.blog': 'Blog',
          'nav.help': 'உதவி',
          'nav.privacy': 'தனியுரிமை',
          'hero.titleLine1': 'தமிழில் டைப் செய்யுங்கள்,',
          'hero.titleLine2': 'உங்கள் முறையில்',
          'hero.announcement': 'Old Typewriter, Bamini, Inscript பிழைகள் Windows-க்கான 0.1.89 வெளியீட்டில் ஜூன் முதல் வாரத்திற்குள் தீர்க்கப்படும்',
          'hero.subtitle': 'டெஸ்க்டாப் மற்றும் மொபைல் தளங்களில் செயல்படும் மிக சக்திவாய்ந்த தமிழ் உள்ளீட்டு கருவி. இலவசம், வேகம், எங்கும் செயல்படும்.',
          'hero.badgePlatform': 'பல தள ஆதரவு',
          'hero.badgeFree': 'எப்போதும் இலவசம்',
          'file.size': 'கோப்பு அளவு:',
          'file.name': 'கோப்பு பெயர்:',
          'trust.title': 'பாதுகாப்பு & நம்பகத்தன்மை',
          'trust.signedBy': 'கையொப்பமிட்டது:',
          'trust.checksums': 'சரிபார்ப்பு எண்கள்',
          'trust.scanned': 'ஸ்கேன் செய்யப்பட்டது:',
          'migration.desc': 'Kaladi Tamil is the next edition of NHM Writer, redeveloped for current Windows and macOS systems with native platform frameworks, signed releases, and transparent security checks.',
          'migration.cta': 'Read the full post',
          'migration.name': 'காலடி தமிழ்',
          'migration.free': 'இலவசம்',
          'migration.comingSoon': 'Android & iOS விரைவில்',
          'keymaps.phonetic': 'Phonetic',
          'keymaps.tamil99': 'Tamil99',
          'keymaps.typewriter': 'Old Typewriter',
          'keymaps.bamini': 'Bamini',
          'keymaps.inscript': 'Inscript',
          'compatibility.title': 'இணக்கத்தன்மை',
          'compatibility.table.version': 'macOS பதிப்பு',
          'compatibility.table.intel': 'Intel Mac (x86_64)',
          'compatibility.table.silicon': 'Apple Silicon Mac (arm64)',
          'compatibility.table.notes': 'குறிப்புகள்',
          'compatibility.rows.catalina.version': '10.15 Catalina',
          'compatibility.rows.catalina.intel': 'ஆதரவு உள்ளது',
          'compatibility.rows.catalina.silicon': 'ஆதரவு இல்லை',
          'compatibility.rows.catalina.notes': 'Catalina-வில் Apple Silicon Mac-கள் இல்லை',
          'compatibility.rows.bigsur.version': '11 Big Sur',
          'compatibility.rows.bigsur.intel': 'ஆதரவு உள்ளது',
          'compatibility.rows.bigsur.silicon': 'ஆதரவு உள்ளது',
          'compatibility.rows.bigsur.notes': 'யுனிவர்சல் பில்ட்',
          'compatibility.rows.monterey.version': '12 Monterey மற்றும் பிந்தையவை (Tahoe மற்றும் புதியவை உட்பட)',
          'compatibility.rows.monterey.intel': 'ஆதரவு உள்ளது',
          'compatibility.rows.monterey.silicon': 'ஆதரவு உள்ளது',
          'compatibility.rows.monterey.notes': 'யுனிவர்சல் பில்ட்',
          'compatibility.subtitle.mac': 'Kaladi Tamil ஒரு <strong>யுனிவர்சல் இன்ஸ்டாலராக</strong> (<code>x86_64 + arm64</code>) வருகிறது. தனி பதிவிறக்கங்கள் தேவையில்லை.',
          'compatibility.subtitle.windows': 'Windows-க்கு x64 மற்றும் ARM64 தனித்தனி installers வழங்கப்படும். உங்கள் சாதனத்துக்கு பொருத்தமானதைத் தேர்ந்தெடுக்கவும்.',
          'compatibility.subtitle.generic': '{platform} இணக்கத்தன்மை விவரங்கள் அந்த வெளியீட்டில் வழங்கப்படும்.',
          'compatibility.empty.windows.x64': 'Windows x64, Windows 10 64-bit மற்றும் அதற்கு பிந்தைய பதிப்புகளில் ஆதரிக்கப்படுகிறது (Windows 11 பரிந்துரைக்கப்படுகிறது).',
          'compatibility.empty.windows.arm64': 'Windows ARM64, Windows 11 ARM64 சாதனங்களில் ஆதரிக்கப்படுகிறது (Surface Pro, Snapdragon X Elite போன்றவை).',
          'compatibility.empty.windows.default': 'Windows-இல் architecture-அடிப்படையிலான installers வழங்கப்படும்: Intel/AMD PC க்கு x64, ARM சாதனங்களுக்கு ARM64.',
          'compatibility.empty.macDisabled': 'தற்போதைய installer பிரச்சினையை சரி செய்யும் வரை macOS பதிவிறக்கங்கள் தற்காலிகமாக நிறுத்தப்பட்டுள்ளன.',
          'compatibility.empty.generic': '{platform}க்கான விரிவான இணக்கத்தன்மை குறிப்புகள் அந்த வெளியீட்டில் சேர்க்கப்படும்.',
          'release.title': 'வெளியீட்டு குறிப்புகள்',
          'release.version.mac': 'v0.1.2',
          'release.version.windows': 'v0.1.88',
          'release.version.comingSoon': 'விரைவில்',
          'release.version.temporarilyUnavailable': 'தற்காலிகமாக இல்லை',
          'release.notes.mac.1': '41 தமிழ் keymaps — 11 எழுத்துரு குறியீடுகள் (Unicode, Bamini, Shrilipi, TSCII மற்றும் பல) 5 விசைப்பலகை அமைப்புகளில் (Phonetic, Tamil99, Bamini, Old Typewriter, Inscript).',
          'release.notes.mac.2': 'Hotkey மாற்றம் — menu bar-இல் இருந்து keymaps-ஐ உடனே மாற்ற configurable hotkeys அழுத்தவும்.',
          'release.notes.mac.3': 'அனைத்து layout-களிலும் உடனடி தமிழ் உள்ளீடு (உதா: Phonetic mode-ல் "thamizh" → "தமிழ்", "ammaa" → "அம்மா").',
          'release.notes.mac.4': 'Smart backspace மூலம் ஒரு எழுத்தை அல்ல, கடைசி உள்ளீட்டு படியைத்தான் மீட்டெடுக்கலாம்.',
          'release.notes.mac.5': 'Native macOS input source — Pages, Numbers, Safari, Chrome, VS Code உள்ளிட்ட apps-ல் தடையின்றி செயல்படும்.',
          'release.notes.mac.6': 'Install ஆன பின் keymap தாமதமாக செயல்படும் பிரச்சினை சரிசெய்யப்பட்டுள்ளது; helper notification முதல் முறையில் தவறினாலும் IME shared state-இல் இருந்து மீண்டும் sync ஆகும்.',
          'release.notes.mac.7': 'புதிய macOS download-கள் தனி update channel-ஐ பயன்படுத்தும்; அதனால் பழைய install-கள் நாம் நினைத்தே migrate செய்யும் வரை பழைய பாதையிலேயே இருக்கும்.',
          'release.notes.windows.x64.1': '41 தமிழ் keymaps — 11 எழுத்துரு குறியீடுகள் (Unicode, Bamini, Shrilipi, TSCII மற்றும் பல) 5 விசைப்பலகை அமைப்புகளில் (Phonetic, Tamil99, Bamini, Old Typewriter, Inscript).',
          'release.notes.windows.x64.2': 'Hotkey மாற்றம் — Alt+1, Alt+2 போன்ற keyboard shortcuts மூலம் keymaps-ஐ உடனே மாற்றலாம். Settings-ல் customize செய்யலாம்.',
          'release.notes.windows.x64.3': 'சாளர வாரியான keymap நினைவகம் — ஒவ்வொரு சாளரமும் அதன் சொந்த active keymap-ஐ தானாக நினைவில் கொள்கிறது.',
          'release.notes.windows.x64.4': 'Smart backspace மூலம் ஒரு எழுத்தை அல்ல, கடைசி உள்ளீட்டு படியைத்தான் மீட்டெடுக்கலாம்.',
          'release.notes.windows.x64.5': 'Native TSF (Text Services Framework) ஒருங்கிணைப்பு — Notepad, Word, Excel, VS Code, Chrome, Edge உள்ளிட்ட apps-ல் செயல்படும்.',
          'release.notes.windows.x64.6': 'எளிய tray app (~3 MB), login ஆனவுடன் தொடங்கும், one-click MSI installer, clean uninstall.',
          'release.notes.windows.arm64.1': '41 தமிழ் keymaps — 11 எழுத்துரு குறியீடுகள் (Unicode, Bamini, Shrilipi, TSCII மற்றும் பல) 5 விசைப்பலகை அமைப்புகளில் (Phonetic, Tamil99, Bamini, Old Typewriter, Inscript).',
          'release.notes.windows.arm64.2': 'Hotkey மாற்றம் — Alt+1, Alt+2 போன்ற keyboard shortcuts மூலம் keymaps-ஐ உடனே மாற்றலாம். Settings-ல் customize செய்யலாம்.',
          'release.notes.windows.arm64.3': 'சாளர வாரியான keymap நினைவகம் — ஒவ்வொரு சாளரமும் அதன் சொந்த active keymap-ஐ தானாக நினைவில் கொள்கிறது.',
          'release.notes.windows.arm64.4': 'Smart backspace மூலம் ஒரு எழுத்தை அல்ல, கடைசி உள்ளீட்டு படியைத்தான் மீட்டெடுக்கலாம்.',
          'release.notes.windows.arm64.5': 'Native TSF (Text Services Framework) ஒருங்கிணைப்பு — Notepad, Word, Excel, VS Code, Chrome, Edge உள்ளிட்ட apps-ல் செயல்படும்.',
          'release.notes.windows.arm64.6': 'எளிய tray app (~3 MB), login ஆனவுடன் தொடங்கும், one-click MSI installer, clean uninstall.',
          'release.notes.ios.1': 'iOS ஆதரவு கிடைக்கும் போது iOS வெளியீட்டு குறிப்புகள் இங்கே வெளியிடப்படும்.',
          'release.notes.android.1': 'Android ஆதரவு கிடைக்கும் போது Android வெளியீட்டு குறிப்புகள் இங்கே வெளியிடப்படும்.',
          'features.demoTitle': '🚀 எங்கும் வேலை செய்கிறது',
          'features.title': 'அமைப்பு நிலை ஒருங்கிணைப்பு',
          'features.subtitle': 'Native system-level input integration மூலம் உருவாக்கப்பட்ட "காலடி தமிழ்”,&nbsp;நீங்கள் தினமும் பயன்படுத்தும் மென்பொருள்களில் சீராக வேலை செய்கிறது; Browser extension அல்லது copy-paste தேவையில்லை, எங்கும் தமிழில் நேரடியாக தட்டச்சு செய்யலாம்.',
          'features.points.0': '✓ உற்பத்தித் திறன் பயன்பாடுகள் (Pages, Numbers, Keynote)',
          'features.points.1': '✓ உலாவிகள் (Safari, Chrome, Firefox)',
          'features.points.2': '✓ டெவலப்பர் கருவிகள் (VS Code, Terminal, JetBrains IDEs)',
          'features.points.3': '✓ தொடர்பு பயன்பாடுகள் (Mail, Messages, Slack, Discord)',
          'stats.keymaps': 'தமிழ் Keymaps',
          'stats.encodings': 'எழுத்துரு குறியீடுகள்',
          'stats.layouts': 'விசைப்பலகை அமைப்புகள்',
          'stats.free': 'எப்போதும் இலவசம்',
          'matrix.title': '41 தமிழ் Keymaps',
          'matrix.subtitle': 'ஒரு மொழி, 11 எழுத்துரு குறியீடுகள், 5 விசைப்பலகை அமைப்புகள்',
          'matrix.encoding': 'குறியீடு',
          'matrix.typewriter': 'Typewriter',
          'keyFeatures.title': 'அனைத்து வகை பயனர்களுக்கும்',
          'keyFeatures.tsf.title.windows': 'Native TSF ஒருங்கிணைப்பு',
          'keyFeatures.tsf.desc.windows': 'Windows Text Services Framework மீது கட்டப்பட்டது — browsers மட்டுமல்ல, அனைத்து apps-லும் உண்மையான OS-நிலை உள்ளீடு.',
          'keyFeatures.tsf.title.mac': 'Native Input Method',
          'keyFeatures.tsf.desc.mac': 'Apple Input Method Kit மீது கட்டப்பட்டது — Pages, Safari, Chrome, VS Code உள்ளிட்ட அனைத்து apps-லும் செயல்படும்.',
          'keyFeatures.hotkeys.title': 'Hotkey மாற்றம்',
          'keyFeatures.hotkeys.desc.windows': 'Tamil99-க்கு Alt+1, Phonetic-க்கு Alt+2, English-க்கு Alt+0 — mouse தொடாமல் keymaps-ஐ உடனே மாற்றலாம்.',
          'keyFeatures.hotkeys.desc.mac': 'Configurable hotkeys மூலம் keymaps-ஐ உடனே மாற்றலாம் — mouse தொடாமல் தமிழுக்கும் English-க்கும் மாறலாம்.',
          'keyFeatures.perWindow.title.windows': 'சாளர வாரியான Keymap',
          'keyFeatures.perWindow.desc.windows': 'ஒவ்வொரு சாளரமும் அதன் சொந்த keymap-ஐ நினைவில் கொள்கிறது. Word-ல் தமிழ், Chrome-ல் English — கையால் மாற்ற வேண்டியதில்லை.',
          'keyFeatures.perWindow.title.mac': 'Menu Bar கட்டுப்பாடு',
          'keyFeatures.perWindow.desc.mac': 'Menu bar-இல் இருந்து 41 keymaps-க்கு மாறலாம். Active layout-ஐ ஒரே பார்வையில் காணலாம், ஒரே click-ல் மாற்றலாம்.',
          'keyFeatures.backspace.title': 'Smart Backspace',
          'keyFeatures.backspace.desc': 'தனிப்பட்ட code points அல்ல, கடைசி தமிழ் எழுத்தை நீக்குகிறது. ஒரு அழுத்தம் கடைசி உள்ளீட்டு படியை சுத்தமாக மீட்டெடுக்கிறது.',
          'footer.feedback': 'பின்னூட்ட மின்னஞ்சல்',
          'footer.source': 'மூலக் குறியீடு',
          'footer.built': 'உருவாக்கம்:',
          'theme.aria.light': 'ஒளி தோற்றத்துக்கு மாற்றவும்',
          'theme.aria.dark': 'இருள் தோற்றத்துக்கு மாற்றவும்',
          'platform.labels.mac': 'macOS',
          'platform.labels.windows': 'Windows',
          'platform.labels.ios': 'iOS',
          'platform.labels.android': 'Android',
          'platform.sublabels.universal': 'Universal',
          'platform.sublabels.x64': 'x64',
          'platform.sublabels.arm64': 'ARM64',
          'platform.badges.detected': 'கண்டறியப்பட்டது',
          'platform.badges.soon': 'விரைவில்',
          'platform.comingSoon': '{platform} பதிப்பு விரைவில் வருகிறது.',
          'download.heading': 'பதிவிறக்கம்',
          'download.button': '{platform} க்கு பதிவிறக்கு',
          'download.size.universal': '~3 MB யுனிவர்சல் installer',
          'download.size.windows': '~3 MB Windows installer',
          'download.size.default': '~3 MB installer'
        }
      };

      let currentLang = 'ta';

      function interpolate(message, vars = {}) {
        return message.replace(/\{(\w+)\}/g, (_, key) => vars[key] ?? `{${key}}`);
      }

      function getText(key, vars = {}) {
        const dictionary = translations[currentLang] || translations.en;
        const fallback = translations.en[key] || key;
        const value = dictionary[key] || fallback;
        return interpolate(value, vars);
      }

      function getInitialLanguage() {
        const stored = localStorage.getItem(LANG_STORAGE_KEY);
        if (stored === 'en' || stored === 'ta') return stored;
        return 'en';
      }

      function applyStaticTranslations() {
        document.querySelectorAll('[data-i18n]').forEach(element => {
          const key = element.getAttribute('data-i18n');
          if (!key) return;
          const translated = getText(key);
          if (element.hasAttribute('data-i18n-html')) {
            element.innerHTML = translated;
          } else {
            element.textContent = translated;
          }
        });

        document.querySelectorAll('[data-i18n-placeholder]').forEach(element => {
          const key = element.getAttribute('data-i18n-placeholder');
          if (!key) return;
          element.setAttribute('placeholder', getText(key));
        });
      }

      function updateLanguageToggle() {
        const enBtn = document.getElementById('lang-en');
        const taBtn = document.getElementById('lang-ta');
        if (enBtn) enBtn.classList.toggle('active', currentLang === 'en');
        if (taBtn) taBtn.classList.toggle('active', currentLang === 'ta');
      }

      function setLanguage(lang, persist = true) {
        currentLang = lang === 'ta' ? 'ta' : 'en';
        if (persist) {
          localStorage.setItem(LANG_STORAGE_KEY, currentLang);
        }
        document.documentElement.setAttribute('lang', currentLang);
        document.documentElement.setAttribute('data-lang', currentLang);
        applyStaticTranslations();
        updateLanguageToggle();
        if (typeof window.updateThemeToggleIcon === 'function') {
          window.updateThemeToggleIcon(document.documentElement.getAttribute('data-theme') || 'dark');
        }
        if (typeof window.refreshDynamicContent === 'function') {
          window.refreshDynamicContent();
        }
      }

      window.getText = getText;
      window.getCurrentLanguage = () => currentLang;
      window.setLanguage = setLanguage;

      window.addEventListener('DOMContentLoaded', () => {
        setLanguage(getInitialLanguage(), false);
        const enBtn = document.getElementById('lang-en');
        const taBtn = document.getElementById('lang-ta');
        if (enBtn) {
          enBtn.addEventListener('click', () => setLanguage('en'));
        }
        if (taBtn) {
          taBtn.addEventListener('click', () => setLanguage('ta'));
        }
      });
    })();
  </script> <script>
    const TURNSTILE_SITE_KEY = '0x4AAAAAACdMWG78105ZNIiT';
    const DIRECT_DOWNLOAD_URL = 'https://downloads.tamil.kaladi.ai';
    const t = (key, vars = {}) => window.getText ? window.getText(key, vars) : key;

    let currentDownloadFile = null;
    let turnstileToken = null;
    let detectedPlatform = null;
    let selectedPlatform = null;
    let releaseInfo = null;

    // Fetch current release info from Worker API (version, filenames, sizes)
    fetch(DIRECT_DOWNLOAD_URL + '/api/release-info')
      .then(function(r) { return r.json(); })
      .then(function(info) {
        releaseInfo = info;
        // Update version badges
        var ver = info.version;
        if (ver) {
          var badge = document.getElementById('version-badge');
          if (badge) badge.textContent = 'Version ' + ver;
          var relVer = document.getElementById('release-version');
          if (relVer) relVer.textContent = 'v' + ver;
        }
        // Update platform download files from API
        platforms.forEach(function(p) {
          var platData = info.platforms && info.platforms[p.os] && info.platforms[p.os][p.arch];
          if (platData) {
            p.downloadFile = platData.filename;
            p.available = true;
            if (platData.sizeLabel) p.downloadSize = platData.sizeLabel + ' installer';
          } else if (p.os === 'mac') {
            p.available = false;
          }
        });
        // Re-detect platform with updated filenames
        if (detectedPlatform && detectedPlatform.os) {
          var platData = info.platforms && info.platforms[detectedPlatform.os] && info.platforms[detectedPlatform.os][detectedPlatform.arch];
          if (platData) {
            detectedPlatform.downloadFile = platData.filename;
            detectedPlatform.available = true;
            if (platData.sizeLabel) detectedPlatform.downloadSize = platData.sizeLabel + ' installer';
          } else if (detectedPlatform.os === 'mac') {
            detectedPlatform.available = false;
          }
        }
        // Refresh UI
        if (window.refreshDynamicContent) window.refreshDynamicContent();
      })
      .catch(function() {}); // fail silently, defaults still work

    // Helper: get download filename from API data or platform defaults
    function getDownloadFile(os, arch) {
      if (releaseInfo && releaseInfo.platforms && releaseInfo.platforms[os] && releaseInfo.platforms[os][arch]) {
        return releaseInfo.platforms[os][arch].filename;
      }
      return null;
    }

    const platforms = [
      {
        os: 'windows',
        arch: 'x64',
        label: 'Windows',
        sublabel: 'x64',
        icon: 'windows',
        color: '#0078D4',
        available: true,
        downloadFile: null,
        downloadSize: 'Windows installer'
      },
      {
        os: 'windows',
        arch: 'arm64',
        label: 'Windows',
        sublabel: 'ARM64',
        icon: 'windows',
        color: '#0078D4',
        available: true,
        downloadFile: null,
        downloadSize: 'Windows installer'
      },
      {
        os: 'mac',
        arch: 'universal',
        label: 'macOS',
        sublabel: 'Universal',
        icon: 'mac',
        color: '#A2AAAD',
        available: false
      },
      {
        os: 'ios',
        arch: 'arm64',
        label: 'iOS',
        sublabel: '',
        icon: 'ios',
        color: '#A2AAAD',
        available: false
      },
      {
        os: 'android',
        arch: 'arm64',
        label: 'Android',
        sublabel: '',
        icon: 'android',
        color: '#3DDC84',
        available: false
      }
    ];

    const releaseNotesByPlatform = {
      'mac-universal': {
        versionKey: 'release.version.mac',
        items: [
          'release.notes.mac.1',
          'release.notes.mac.2',
          'release.notes.mac.3',
          'release.notes.mac.4',
          'release.notes.mac.5',
          'release.notes.mac.6',
          'release.notes.mac.7'
        ]
      },
      'windows-x64': {
        versionKey: 'release.version.windows',
        items: [
          'release.notes.windows.x64.1',
          'release.notes.windows.x64.2',
          'release.notes.windows.x64.3',
          'release.notes.windows.x64.4',
          'release.notes.windows.x64.5',
          'release.notes.windows.x64.6'
        ]
      },
      'windows-arm64': {
        versionKey: 'release.version.windows',
        items: [
          'release.notes.windows.arm64.1',
          'release.notes.windows.arm64.2',
          'release.notes.windows.arm64.3',
          'release.notes.windows.arm64.4',
          'release.notes.windows.arm64.5',
          'release.notes.windows.arm64.6'
        ]
      },
      'ios-arm64': {
        versionKey: 'release.version.comingSoon',
        items: [
          'release.notes.ios.1'
        ]
      },
      'android-arm64': {
        versionKey: 'release.version.comingSoon',
        items: [
          'release.notes.android.1'
        ]
      }
    };

    function getActivePlatform() {
      if (selectedPlatform) return selectedPlatform;
      if (detectedPlatform && detectedPlatform.available) return detectedPlatform;
      return platforms.find(p => p.available) ||
        platforms.find(p => p.os === 'windows' && p.arch === 'x64') ||
        platforms[0];
    }

    function getPlatformDisplayName(platform) {
      if (!platform) return `${t('platform.labels.mac')} ${t('platform.sublabels.universal')}`;
      const label = getPlatformLabel(platform);
      const sublabel = getPlatformSublabel(platform);
      return sublabel ? `${label} ${sublabel}` : label;
    }

    function getPlatformLabel(platform) {
      if (!platform) return t('platform.labels.mac');
      if (platform.os === 'mac') return t('platform.labels.mac');
      if (platform.os === 'windows') return t('platform.labels.windows');
      if (platform.os === 'ios') return t('platform.labels.ios');
      if (platform.os === 'android') return t('platform.labels.android');
      return platform.label || platform.os;
    }

    function getPlatformSublabel(platform) {
      if (!platform) return t('platform.sublabels.universal');
      if (platform.os === 'mac' && platform.arch === 'universal') return t('platform.sublabels.universal');
      if (platform.os === 'windows' && platform.arch === 'x64') return t('platform.sublabels.x64');
      if (platform.os === 'windows' && platform.arch === 'arm64') return t('platform.sublabels.arm64');
      return platform.sublabel || '';
    }

    function getPlatformDownloadSize(platform) {
      if (!platform) return t('download.size.default');
      if (platform.os === 'mac') return t('download.size.universal');
      if (platform.os === 'windows') return t('download.size.windows');
      return t('download.size.default');
    }

    function getPlatformKey(platform) {
      if (!platform) return 'mac-universal';
      return `${platform.os}-${platform.arch}`;
    }

    // Platform detection - improved algorithm
    async function detectPlatform() {
      const ua = navigator.userAgent;
      let detectedOS = null;
      let detectedArch = null;

      console.log('User Agent:', ua);
      console.log('Platform:', navigator.platform);

      // Try User-Agent Client Hints API first (Chrome/Edge)
      if (navigator.userAgentData) {
        try {
          const hints = await navigator.userAgentData.getHighEntropyValues(['platform', 'architecture', 'bitness']);
          console.log('UA Client Hints:', hints);

          if (hints.platform) {
            const platform = hints.platform.toLowerCase();
            if (platform.includes('mac')) {
              detectedOS = 'mac';
              detectedArch = 'universal';
            } else if (platform.includes('win')) {
              detectedOS = 'windows';
              detectedArch = 'x64';
            }
          }
        } catch (e) {
          console.log('UA Client Hints not available:', e);
        }
      }

      // Fallback to User-Agent string parsing
      // Check mobile platforms first (iOS UA contains "Mac OS X")
      if (!detectedOS) {
        if (/iPhone|iPad|iPod/.test(ua)) {
          detectedOS = 'ios';
          detectedArch = 'arm64';
        } else if (/Android/.test(ua)) {
          detectedOS = 'android';
          detectedArch = 'arm64';
        } else if (ua.includes('Mac OS X') || ua.includes('Macintosh')) {
          detectedOS = 'mac';
          detectedArch = 'universal';
        } else if (ua.includes('Windows') || ua.includes('Win64') || ua.includes('Win32')) {
          detectedOS = 'windows';
          detectedArch = 'x64';
        }
      }

      // Check navigator.platform as additional hint
      const platform = navigator.platform;
      if (platform) {
        if (platform.includes('Mac')) {
          detectedOS = 'mac';
          detectedArch = 'universal';
        } else if (platform.includes('Win')) {
          detectedOS = 'windows';
          detectedArch = 'x64';
        }
      }

      console.log('Detected OS:', detectedOS, 'Arch:', detectedArch);

      if (!detectedOS) return null;

      if (detectedOS === 'mac') {
        return {
          os: 'mac',
          arch: detectedArch || 'universal',
          label: 'macOS',
          sublabel: 'Universal',
          icon: 'mac',
          available: false
        };
      } else if (detectedOS === 'windows') {
        return {
          os: 'windows',
          arch: detectedArch || 'x64',
          label: 'Windows',
          sublabel: (detectedArch || 'x64') === 'arm64' ? 'ARM64' : 'x64',
          icon: 'windows',
          available: true,
          downloadFile: getDownloadFile('windows', detectedArch || 'x64'),
          downloadSize: 'Windows installer'
        };
      } else if (detectedOS === 'ios') {
        return {
          os: 'ios',
          arch: 'arm64',
          label: 'iOS',
          icon: 'ios',
          available: false
        };
      } else if (detectedOS === 'android') {
        return {
          os: 'android',
          arch: 'arm64',
          label: 'Android',
          icon: 'android',
          available: false
        };
      }

      return null;
    }

    // Run async detection
    detectPlatform().then(result => {
      detectedPlatform = result;
      console.log('Final detected platform:', detectedPlatform);
      window.refreshDynamicContent();
    });

    function renderPlatformSelection() {
      const grid = document.getElementById('platform-grid');
      if (!grid) return;

      grid.innerHTML = '';

      platforms.forEach(platform => {
        const card = document.createElement('button');
        const activePlatform = getActivePlatform();
        const isSelected = activePlatform && activePlatform.os === platform.os && activePlatform.arch === platform.arch;
        const isDetected = detectedPlatform && detectedPlatform.os === platform.os && detectedPlatform.arch === platform.arch;

        card.className = 'platform-card' + (isSelected ? ' selected' : '') + (!platform.available ? ' unavailable' : '');

        let iconSVG = '';
        if (platform.icon === 'windows') {
          iconSVG = `<svg viewBox="0 0 24 24" class="card-icon"><path fill="#F25022" d="M1 4.8l9.7-1.3v9.4l-9.7.1z"/><path fill="#7FBA00" d="M1 13.3l9.7.1v9.4L1 21.5z"/><path fill="#00A4EF" d="M11.9 3.3L23.8 1.5v11.3l-11.9.1z"/><path fill="#FFB900" d="M11.9 13.1l11.9.1v11.3l-11.9-1.8z"/></svg>`;
        } else if (platform.icon === 'mac' || platform.icon === 'ios') {
          iconSVG = `<svg viewBox="0 0 24 24" class="card-icon"><path fill="currentColor" d="M18.71 19.5C17.88 20.74 17 21.95 15.66 21.97C14.32 22 13.89 21.18 12.37 21.18C10.84 21.18 10.37 21.95 9.1 22C7.79 22.05 6.8 20.68 5.96 19.47C4.25 17 2.94 12.45 4.7 9.39C5.57 7.87 7.13 6.91 8.82 6.88C10.1 6.86 11.32 7.75 12.11 7.75C12.89 7.75 14.37 6.68 15.92 6.84C16.57 6.87 18.39 7.1 19.56 8.82C19.47 8.88 17.39 10.1 17.41 12.63C17.44 15.65 20.06 16.66 20.09 16.67C20.06 16.74 19.67 18.11 18.71 19.5M13 3.5C13.73 2.67 14.94 2.04 15.94 2C16.07 3.17 15.6 4.35 14.9 5.19C14.21 6.04 13.07 6.7 11.95 6.61C11.8 5.46 12.36 4.26 13 3.5Z"/></svg>`;
        } else if (platform.icon === 'android') {
          iconSVG = `<svg viewBox="0 0 24 24" class="card-icon"><path fill="#3DDC84" d="M6 18c0 .55.45 1 1 1h1v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h2v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h1c.55 0 1-.45 1-1V8H6v10zM3.5 8C2.67 8 2 8.67 2 9.5v7c0 .83.67 1.5 1.5 1.5S5 17.33 5 16.5v-7C5 8.67 4.33 8 3.5 8zm17 0c-.83 0-1.5.67-1.5 1.5v7c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5v-7c0-.83-.67-1.5-1.5-1.5zm-4.97-5.84l1.3-1.3c.2-.2.2-.51 0-.71-.2-.2-.51-.2-.71 0l-1.48 1.48C13.85 1.23 12.95 1 12 1c-.96 0-1.86.23-2.66.63L7.85.15c-.2-.2-.51-.2-.71 0-.2.2-.2.51 0 .71l1.31 1.31C6.97 3.26 6 5.01 6 7h12c0-1.99-.97-3.75-2.47-4.84zM10 5H9V4h1v1zm5 0h-1V4h1v1z"/></svg>`;
        }

        const detectedTag = isDetected ? `<span class="detected-tag">${t('platform.badges.detected')}</span>` : '';
        const comingSoonTag = !platform.available ? `<span class="soon-tag">${t('platform.badges.soon')}</span>` : '';
        const labelText = getPlatformDisplayName(platform);

        card.innerHTML = `${iconSVG}<span class="card-label">${labelText}</span><div class="card-badges">${detectedTag}${comingSoonTag}</div>`;

        card.onclick = function() {
          selectPlatform(platform);
        };

        grid.appendChild(card);
      });
    }

    function selectPlatform(platform) {
      selectedPlatform = platform;
      renderPlatformSelection();
      renderDownloads();
      renderCompatibility();
      renderReleaseNotes();
      renderKeyFeatures();
    }

    function renderKeyFeatures() {
      const platform = getActivePlatform();
      if (!platform) return;
      const os = platform.os === 'mac' ? 'mac' : 'windows';

      const tsfTitle = document.getElementById('feature-tsf-title');
      const tsfDesc = document.getElementById('feature-tsf-desc');
      const hotkeysDesc = document.getElementById('feature-hotkeys-desc');
      const perWindowTitle = document.getElementById('feature-perwindow-title');
      const perWindowDesc = document.getElementById('feature-perwindow-desc');

      if (tsfTitle) tsfTitle.textContent = t('keyFeatures.tsf.title.' + os);
      if (tsfDesc) tsfDesc.textContent = t('keyFeatures.tsf.desc.' + os);
      if (hotkeysDesc) hotkeysDesc.textContent = t('keyFeatures.hotkeys.desc.' + os);
      if (perWindowTitle) perWindowTitle.textContent = t('keyFeatures.perWindow.title.' + os);
      if (perWindowDesc) perWindowDesc.textContent = t('keyFeatures.perWindow.desc.' + os);
    }

    function createDownloadButton(platform, isPrimary = false) {
      const btn = document.createElement('button');
      btn.className = isPrimary ? 'download-btn primary' : 'download-btn secondary';
      const downloadLabel = getPlatformDisplayName(platform);
      const installerSize = getPlatformDownloadSize(platform);

      btn.innerHTML = `
        <span class="btn-text">
          <span class="btn-label">${t('download.button', { platform: downloadLabel })}</span>
          <span class="btn-sublabel">${installerSize}</span>
        </span>
        <span class="btn-arrow">↓</span>
      `;
      btn.onclick = () => initiateDownload(platform);

      return btn;
    }

    function renderDownloads() {
      const heroContainer = document.getElementById('hero-downloads');
      const fileDetails = document.getElementById('file-details');

      // Clear existing content
      if (heroContainer) heroContainer.innerHTML = '';

      // Use selected platform or detected platform
      const platformToShow = getActivePlatform();

      if (!platformToShow || !platformToShow.available) {
        // Show "coming soon" message
        const platformName = getPlatformDisplayName(platformToShow);
        if (heroContainer) {
          heroContainer.innerHTML = `<p class="coming-soon-message">${t('platform.comingSoon', { platform: platformName })}</p>`;
        }
        if (fileDetails) fileDetails.style.display = 'none';
        var trustHideCS = document.getElementById('security-trust');
        if (trustHideCS) trustHideCS.style.display = 'none';
        var vbHide = document.getElementById('version-badge-bar');
        if (vbHide) vbHide.style.display = 'none';
        return;
      }

      // Hero section
      if (heroContainer) {
        const primaryBtn = createDownloadButton(platformToShow, true);
        heroContainer.appendChild(primaryBtn);
      }

      // File details table (SHA256, size, filename)
      if (fileDetails) {
        var platInfo = releaseInfo && releaseInfo.platforms && releaseInfo.platforms[platformToShow.os] && releaseInfo.platforms[platformToShow.os][platformToShow.arch];
        if (platInfo && platInfo.sha256) {
          document.getElementById('file-sha256').textContent = platInfo.sha256;
          var sizeStr = platInfo.sizeLabel || '';
          if (platInfo.size) {
            sizeStr += ' (' + platInfo.size.toLocaleString() + ' bytes)';
          }
          document.getElementById('file-size').textContent = sizeStr;
          document.getElementById('file-name').textContent = platInfo.filename || '';
          fileDetails.style.display = 'block';
          var vbShow = document.getElementById('version-badge-bar');
          if (vbShow) vbShow.style.display = '';

          // Populate Security & Trust section
          var trustSection = document.getElementById('security-trust');
          if (trustSection) {
            trustSection.style.display = 'block';

            // SHA-256 in trust section
            var trustSha256 = document.getElementById('trust-sha256');
            if (trustSha256) trustSha256.textContent = platInfo.sha256;

            // SHA-1 and MD5 (from VT-enriched release-info)
            if (platInfo.sha1) {
              document.getElementById('trust-sha1').textContent = platInfo.sha1;
              document.getElementById('trust-sha1-row').style.display = '';
            }
            if (platInfo.md5) {
              document.getElementById('trust-md5').textContent = platInfo.md5;
              document.getElementById('trust-md5-row').style.display = '';
            }

            // VirusTotal badge
            var vt = platInfo.virusTotal;
            if (vt) {
              document.getElementById('vt-badge').style.display = '';
              var vtResult = document.getElementById('vt-result');
              vtResult.textContent = vt.detections + '/' + vt.totalEngines + ' engines detected threats';
              vtResult.className = 'vt-result ' + (vt.detections === 0 ? 'vt-clean' : 'vt-warning');
              document.getElementById('vt-link').href = vt.permalink;

              if (vt.scanDate) {
                document.getElementById('vt-scan-date').style.display = '';
                var d = new Date(vt.scanDate);
                document.getElementById('vt-date-value').textContent = d.toLocaleDateString(undefined, {
                  year: 'numeric', month: 'short', day: 'numeric'
                });
              }
            }
          }
        } else {
          fileDetails.style.display = 'none';
          var trustHide = document.getElementById('security-trust');
          if (trustHide) trustHide.style.display = 'none';
          var vbHide2 = document.getElementById('version-badge-bar');
          if (vbHide2) vbHide2.style.display = 'none';
        }
      }
    }

    function renderCompatibility() {
      const platform = getActivePlatform();
      const activeOsLabel = document.getElementById('compatibility-active-os');
      const subtitle = document.getElementById('compatibility-subtitle');
      const tableBlock = document.getElementById('compatibility-table-block');
      const emptyState = document.getElementById('compatibility-empty');

      if (!activeOsLabel || !subtitle || !tableBlock || !emptyState || !platform) return;

      const platformName = getPlatformDisplayName(platform);
      activeOsLabel.textContent = platformName;

      if (platform.os === 'mac' && platform.available) {
        subtitle.innerHTML = t('compatibility.subtitle.mac');
        tableBlock.hidden = false;
        emptyState.hidden = true;
      } else if (platform.os === 'windows' && platform.available) {
        subtitle.textContent = t('compatibility.subtitle.windows');
        tableBlock.hidden = true;
        emptyState.hidden = false;
        if (platform.arch === 'x64') {
          emptyState.textContent = t('compatibility.empty.windows.x64', { platform: platformName });
        } else if (platform.arch === 'arm64') {
          emptyState.textContent = t('compatibility.empty.windows.arm64', { platform: platformName });
        } else {
          emptyState.textContent = t('compatibility.empty.windows.default', { platform: platformName });
        }
      } else {
        subtitle.textContent = t('compatibility.subtitle.generic', { platform: platformName });
        tableBlock.hidden = true;
        emptyState.hidden = false;
        emptyState.textContent = platform.os === 'mac'
          ? t('compatibility.empty.macDisabled')
          : t('compatibility.empty.generic', { platform: platformName });
      }
    }

    function renderReleaseNotes() {
      const platform = getActivePlatform();
      const platformBadge = document.getElementById('release-platform');
      const version = document.getElementById('release-version');
      const list = document.getElementById('release-list');
      if (!platformBadge || !version || !list || !platform) return;

      platformBadge.textContent = getPlatformDisplayName(platform);

      if (!platform.available) {
        if (platform.os === 'mac') {
          version.textContent = t('release.version.temporarilyUnavailable');
          list.innerHTML = `<li>${t('compatibility.empty.macDisabled')}</li>`;
        } else {
          version.textContent = t('release.version.comingSoon');
          const platformLabel = getPlatformLabel(platform);
          list.innerHTML = `<li>${platformLabel} release notes will be published when ${platformLabel} support is available.</li>`;
        }
        return;
      }

      const notes = releaseNotesByPlatform[getPlatformKey(platform)] || releaseNotesByPlatform['windows-x64'];
      version.textContent = t(notes.versionKey);
      list.innerHTML = notes.items.map(itemKey => `<li>${t(itemKey)}</li>`).join('');
    }

    function initiateDownload(platform) {
      currentDownloadFile = platform.downloadFile || null;
      const container = document.getElementById('turnstile-container');
      container.style.display = 'block';
      container.innerHTML = '';

      turnstile.render(container, {
        sitekey: TURNSTILE_SITE_KEY,
        callback: (token) => {
          turnstileToken = token;
          startDownload();
        }
      });
    }

    function startDownload() {
      if (!turnstileToken || !currentDownloadFile) return;

      const filename = currentDownloadFile;
      const downloadUrl = DIRECT_DOWNLOAD_URL + '/api/download/' + encodeURIComponent(filename) + '?token=' + encodeURIComponent(turnstileToken);

      // Navigate to the Worker download API — it verifies the token,
      // increments counters, and streams the file back
      window.location.href = downloadUrl;

      document.getElementById('turnstile-container').style.display = 'none';
      turnstileToken = null;
      currentDownloadFile = null;
    }

    window.refreshDynamicContent = function() {
      renderPlatformSelection();
      renderDownloads();
      renderCompatibility();
      renderReleaseNotes();
      renderKeyFeatures();
      if (typeof window.updateThemeToggleIcon === 'function') {
        const currentTheme = document.documentElement.getAttribute('data-theme');
        window.updateThemeToggleIcon(currentTheme);
      }
    };

    // Initial render happens after detectPlatform() completes

    // Keymap carousel functionality
    document.querySelectorAll('.keymap-tab').forEach(tab => {
      tab.addEventListener('click', function() {
        const keymap = this.getAttribute('data-keymap');

        // Update active tab
        document.querySelectorAll('.keymap-tab').forEach(t => t.classList.remove('active'));
        this.classList.add('active');

        // Update active slide
        document.querySelectorAll('.keymap-slide').forEach(s => s.classList.remove('active'));
        document.querySelector(`.keymap-slide[data-keymap="${keymap}"]`).classList.add('active');
      });
    });

    const footerEmailCanvas = document.getElementById('footer-feedback-email');
    if (footerEmailCanvas instanceof HTMLCanvasElement) {
      const footerEmail = 'nags@kaladi.ai';

      function renderFooterEmail() {
        const ctx = footerEmailCanvas.getContext('2d');
        if (!ctx) return;

        const dpr = window.devicePixelRatio || 1;
        const cssWidth = 180;
        const cssHeight = 24;

        footerEmailCanvas.width = cssWidth * dpr;
        footerEmailCanvas.height = cssHeight * dpr;
        footerEmailCanvas.style.width = `${cssWidth}px`;
        footerEmailCanvas.style.height = `${cssHeight}px`;

        ctx.scale(dpr, dpr);
        ctx.clearRect(0, 0, cssWidth, cssHeight);
        ctx.font = '700 16px "Source Sans 3", "Segoe UI", sans-serif';
        ctx.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--text-heading').trim() || '#ffffff';
        ctx.textBaseline = 'middle';
        ctx.textAlign = 'center';
        ctx.fillText(footerEmail, cssWidth / 2, cssHeight / 2);
      }

      renderFooterEmail();
      window.addEventListener('kaladi-theme-change', renderFooterEmail);
    }
  </script>   <script defer src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon="{&quot;token&quot;: &quot;2706304501524d9b8dc91e322040d741&quot;}"></script> </body> </html>