{"id":70,"date":"2026-03-16T06:22:22","date_gmt":"2026-03-16T06:22:22","guid":{"rendered":"https:\/\/tools.sanepo.com\/?post_type=tool&#038;p=70"},"modified":"2026-03-16T06:22:23","modified_gmt":"2026-03-16T06:22:23","slug":"online-case-converter","status":"publish","type":"tool","link":"https:\/\/tools.sanepo.com\/id\/features\/online-case-converter\/","title":{"rendered":"Free Online Case Converter \u2013 Change Text to Uppercase, Lowercase, &amp; Title Case"},"content":{"rendered":"\n<div id=\"wpnt-audio-compressor\"> <!-- Tetap menggunakan ID ini untuk konsistensi struktur CSS Anda -->\n    <div class=\"wpnt-header\">\n        <h3>Sanepo Case Converter<\/h3>\n        <p>Easily transform your text format, clean up spaces, and analyze your content.<\/p>\n        <div class=\"wpnt-privacy-badge\">\n            <svg style=\"width:14px;height:14px;margin-bottom:-2px;margin-right:4px;\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M12,1L3,5V11C3,16.55 6.84,21.74 12,23C17.16,21.74 21,16.55 21,11V5L12,1M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M17.13,17C15.92,18.85 14.11,20.24 12,20.92C9.89,20.24 8.08,18.85 6.87,17C6.53,16.5 6.24,16 6,15.47C6,13.82 8.71,12.47 12,12.47C15.29,12.47 18,13.82 18,15.47C17.76,16 17.47,16.5 17.13,17Z\" \/><\/svg>\n            100% Client-Side &#038; Secure\n        <\/div>\n    <\/div>\n\n    <!-- Text Input Area -->\n    <div class=\"wpnt-input-container\">\n        <textarea id=\"caseInput\" placeholder=\"Type or paste your text here... (Your text will be auto-saved)\" rows=\"10\" class=\"wpnt-textarea\"><\/textarea>\n    <\/div>\n\n    <!-- Live Stats -->\n    <div class=\"wpnt-stats-grid\">\n        <div class=\"wpnt-stat-item\">\n            <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M14,17H7V15H14M17,13H7V11H17M17,9H7V7H17M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z\" \/><\/svg>\n            Words: <span id=\"wordCount\">0<\/span>\n        <\/div>\n        <div class=\"wpnt-stat-item\">\n            <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M9.62,12L12,5.67L14.37,12M11,3L5.5,17H7.75L8.87,14H15.12L16.25,17H18.5L13,3H11Z\" \/><\/svg>\n            Characters: <span id=\"charCount\">0<\/span>\n        <\/div>\n        <div class=\"wpnt-stat-item\">\n            <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z\" \/><\/svg>\n            Reading Time: <span id=\"readTime\">0 min<\/span>\n        <\/div>\n    <\/div>\n\n    <!-- Conversion Actions -->\n    <div class=\"wpnt-settings\">\n        <button onclick=\"transformText('sentence')\" class=\"wpnt-btn-alt\">Sentence case<\/button>\n        <button onclick=\"transformText('lower')\" class=\"wpnt-btn-alt\">lower case<\/button>\n        <button onclick=\"transformText('upper')\" class=\"wpnt-btn-alt\">UPPER CASE<\/button>\n        <button onclick=\"transformText('capitalize')\" class=\"wpnt-btn-alt\">Capitalized Case<\/button>\n        <button onclick=\"transformText('title')\" class=\"wpnt-btn-alt\">Title Case<\/button>\n        <button onclick=\"transformText('alternating')\" class=\"wpnt-btn-alt\">aLtErNaTiNg cAsE<\/button>\n        <button onclick=\"transformText('inverse')\" class=\"wpnt-btn-alt\">iNVERSE cASE<\/button>\n    <\/div>\n\n    <!-- Advanced Actions -->\n    <div class=\"wpnt-settings-advanced\">\n        <button onclick=\"transformText('trim')\" class=\"wpnt-btn-action\">\n            <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M21,3H3V5H21V3M21,19H3V21H21V19M21,11H3V13H21V11M21,7H3V9H21V7M21,15H3V17H21V15Z\" \/><\/svg>\n            Trim Extra Spaces\n        <\/button>\n        <button onclick=\"transformText('nolinebreaks')\" class=\"wpnt-btn-action\">\n            <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M3,15H5V13H3V15M3,19H5V17H3V19M3,11H5V9H3V11M7,19H21V17H7V19M7,15H21V13H7V15M7,11H21V9H7V11M3,7H5V5H3V7M7,7H21V5H7V7Z\" \/><\/svg>\n            Remove Line Breaks\n        <\/button>\n        <button onclick=\"downloadText()\" class=\"wpnt-btn-action\">\n            <svg viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z\" \/><\/svg>\n            Download .txt\n        <\/button>\n    <\/div>\n\n    <!-- Utilities -->\n    <div class=\"wpnt-footer-actions\">\n        <button onclick=\"copyToClipboard()\" class=\"wpnt-btn\">\n            <svg style=\"width:20px;height:20px\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M19,21H8V7H19M19,5H8A2,2 0 0 0 6,7V21A2,2 0 0 0 8,23H19A2,2 0 0 0 21,21V7A2,2 0 0 0 19,5M16,1H4A2,2 0 0 0 2,3V17H4V3H16V1Z\" \/><\/svg>\n            Copy to Clipboard\n        <\/button>\n        <button onclick=\"clearText()\" class=\"wpnt-btn-danger\">\n            <svg style=\"width:20px;height:20px\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z\" \/><\/svg>\n            Clear\n        <\/button>\n    <\/div>\n\n    <div id=\"wpnt-toast\" class=\"wpnt-toast\">Action Completed!<\/div>\n<\/div>\n\n<style>\n    @import url('https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700&display=swap');\n\n    \/* CSS Variables Base (Light Mode Default) *\/\n    #wpnt-audio-compressor {\n        --bg-primary: #ffffff;\n        --bg-secondary: #f8fafc;\n        --border-color: #e2e8f0;\n        --accent-color: #4361ee;\n        --accent-hover: #3a56d4;\n        --glass-bg: rgba(255, 255, 255, 0.85);\n        --card-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05), 0 8px 10px -6px rgba(0, 0, 0, 0.05);\n        --transition: all 0.3s ease;\n        --wpnt-success: #10b981;\n        --wpnt-danger: #ef4444;\n        --wpnt-radius-lg: 16px;\n        --wpnt-radius-md: 12px;\n        --wpnt-radius-sm: 8px;\n        \n        font-family: 'Inter', sans-serif;\n        color: #1e293b;\n        width: 100%;\n        margin: 30px auto;\n        background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 100%);\n        border: 1px solid var(--border-color);\n        border-radius: var(--wpnt-radius-lg);\n        box-shadow: var(--card-shadow);\n        padding: 32px;\n        box-sizing: border-box;\n        line-height: 1.5;\n        backdrop-filter: blur(10px);\n        -webkit-backdrop-filter: blur(10px);\n    }\n\n    \/* * SMART DARK MODE LOGIC:\n     * 1. Jika website memiliki class \"dark\" di tag HTML\/BODY (Override Manual).\n     *\/\n    html.dark #wpnt-audio-compressor,\n    body.dark #wpnt-audio-compressor,\n    [data-theme=\"dark\"] #wpnt-audio-compressor {\n        --bg-primary: #0f172a;\n        --bg-secondary: #1e293b;\n        --border-color: #334155;\n        --glass-bg: rgba(15, 23, 42, 0.7);\n        color: #f1f5f9;\n        --card-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5);\n    }\n\n    \/* * 2. Fallback ke sistem OS HANYA JIKA website tidak secara eksplisit di-set ke \"light\" mode.\n     * Ini mencegah tool berubah gelap saat OS gelap tapi website sedang light mode.\n     *\/\n    @media (prefers-color-scheme: dark) {\n        html:not(.light):not([data-theme=\"light\"]) body:not(.light) #wpnt-audio-compressor {\n            --bg-primary: #0f172a;\n            --bg-secondary: #1e293b;\n            --border-color: #334155;\n            --glass-bg: rgba(15, 23, 42, 0.7);\n            color: #f1f5f9;\n            --card-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.5);\n        }\n    }\n\n    #wpnt-audio-compressor * { box-sizing: border-box; }\n\n    #wpnt-audio-compressor .wpnt-header { text-align: center; margin-bottom: 24px; }\n    #wpnt-audio-compressor h3 { margin: 0 0 8px 0; font-size: 1.75rem; font-weight: 700; }\n    #wpnt-audio-compressor p { margin: 0; font-size: 0.95rem; opacity: 0.8; }\n    \n    #wpnt-audio-compressor .wpnt-privacy-badge {\n        display: inline-flex;\n        align-items: center;\n        background: rgba(16, 185, 129, 0.1);\n        color: var(--wpnt-success);\n        border: 1px solid rgba(16, 185, 129, 0.2);\n        padding: 6px 14px;\n        border-radius: 20px;\n        font-size: 0.8rem;\n        font-weight: 600;\n        margin-top: 12px;\n    }\n\n    \/* Input Styling *\/\n    .wpnt-textarea {\n        width: 100%;\n        padding: 18px;\n        border-radius: var(--wpnt-radius-md);\n        border: 1px solid var(--border-color);\n        background: var(--glass-bg);\n        color: inherit;\n        font-family: inherit;\n        font-size: 1.05rem;\n        line-height: 1.6;\n        resize: vertical;\n        outline: none;\n        transition: var(--transition);\n        margin-bottom: 12px;\n        box-shadow: inset 0 2px 4px rgba(0,0,0,0.02);\n    }\n    .wpnt-textarea:focus {\n        border-color: var(--accent-color);\n        box-shadow: 0 0 0 4px rgba(67, 97, 238, 0.15), inset 0 2px 4px rgba(0,0,0,0.02);\n        background: var(--bg-primary);\n    }\n\n    \/* Stats Styling *\/\n    .wpnt-stats-grid {\n        display: flex;\n        flex-wrap: wrap;\n        gap: 16px;\n        margin-bottom: 24px;\n        font-size: 0.85rem;\n        font-weight: 600;\n        opacity: 0.8;\n    }\n    .wpnt-stat-item {\n        display: flex;\n        align-items: center;\n        gap: 6px;\n        background: var(--bg-secondary);\n        padding: 8px 12px;\n        border-radius: var(--wpnt-radius-sm);\n        border: 1px solid var(--border-color);\n    }\n    .wpnt-stat-item svg { width: 16px; height: 16px; opacity: 0.7; }\n    .wpnt-stat-item span { color: var(--accent-color); font-weight: 700; margin-left: 2px; }\n\n    \/* Grid Buttons *\/\n    .wpnt-settings {\n        display: grid;\n        grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n        gap: 12px;\n        margin-bottom: 20px;\n    }\n    .wpnt-btn-alt {\n        background: var(--bg-primary);\n        border: 1px solid var(--border-color);\n        padding: 12px 10px;\n        border-radius: var(--wpnt-radius-sm);\n        cursor: pointer;\n        font-weight: 500;\n        color: inherit;\n        transition: var(--transition);\n        box-shadow: 0 2px 4px rgba(0,0,0,0.02);\n    }\n    .wpnt-btn-alt:hover {\n        background: var(--accent-color);\n        color: #fff;\n        border-color: var(--accent-color);\n        transform: translateY(-2px);\n        box-shadow: 0 4px 8px rgba(67, 97, 238, 0.2);\n    }\n\n    \/* Advanced Buttons *\/\n    .wpnt-settings-advanced {\n        display: flex;\n        flex-wrap: wrap;\n        gap: 10px;\n        margin-bottom: 24px;\n        padding-top: 16px;\n        border-top: 1px dashed var(--border-color);\n    }\n    .wpnt-btn-action {\n        background: transparent;\n        border: 1px solid var(--border-color);\n        color: inherit;\n        padding: 8px 14px;\n        border-radius: 30px;\n        font-size: 0.85rem;\n        font-weight: 500;\n        cursor: pointer;\n        transition: var(--transition);\n        display: inline-flex;\n        align-items: center;\n        gap: 6px;\n    }\n    .wpnt-btn-action svg { width: 14px; height: 14px; opacity: 0.7; }\n    .wpnt-btn-action:hover {\n        background: var(--bg-secondary);\n        border-color: var(--accent-color);\n        color: var(--accent-color);\n    }\n    .wpnt-btn-action:hover svg { opacity: 1; }\n\n    \/* Footer Buttons *\/\n    .wpnt-footer-actions {\n        display: flex;\n        gap: 16px;\n    }\n    .wpnt-btn {\n        background: var(--accent-color);\n        color: #fff;\n        border: none;\n        padding: 14px 24px;\n        border-radius: var(--wpnt-radius-sm);\n        cursor: pointer;\n        font-weight: 600;\n        flex: 2;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        gap: 8px;\n        font-size: 1rem;\n        transition: var(--transition);\n    }\n    .wpnt-btn:hover { \n        background: var(--accent-hover); \n        transform: translateY(-2px); \n        box-shadow: 0 8px 16px rgba(67, 97, 238, 0.25);\n    }\n\n    .wpnt-btn-danger {\n        background: var(--bg-secondary);\n        color: var(--wpnt-danger);\n        border: 1px solid var(--border-color);\n        padding: 14px 24px;\n        border-radius: var(--wpnt-radius-sm);\n        cursor: pointer;\n        font-weight: 600;\n        flex: 1;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        gap: 8px;\n        font-size: 1rem;\n        transition: var(--transition);\n    }\n    .wpnt-btn-danger:hover { \n        background: var(--wpnt-danger); \n        color: #fff; \n        border-color: var(--wpnt-danger);\n        transform: translateY(-2px); \n        box-shadow: 0 8px 16px rgba(239, 68, 68, 0.25);\n    }\n\n    \/* Toast notification *\/\n    .wpnt-toast {\n        position: fixed;\n        bottom: 30px;\n        left: 50%;\n        transform: translateX(-50%) translateY(100px);\n        background: #1e293b;\n        color: white;\n        padding: 12px 28px;\n        border-radius: 30px;\n        font-weight: 600;\n        font-size: 0.95rem;\n        transition: transform 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);\n        z-index: 9999;\n        box-shadow: 0 10px 25px rgba(0,0,0,0.2);\n        border: 1px solid rgba(255,255,255,0.1);\n    }\n    .wpnt-toast.show { transform: translateX(-50%) translateY(0); }\n    .wpnt-toast.success { background: var(--wpnt-success); }\n\n    @media (max-width: 600px) {\n        #wpnt-audio-compressor { padding: 20px 16px; }\n        .wpnt-settings { grid-template-columns: 1fr 1fr; }\n        .wpnt-footer-actions { flex-direction: column; }\n        .wpnt-stats-grid { gap: 10px; }\n        .wpnt-stat-item { flex: 1; justify-content: center; font-size: 0.75rem; }\n    }\n<\/style>\n\n<script>\n(function() {\n    const textArea = document.getElementById('caseInput');\n    const wordCount = document.getElementById('wordCount');\n    const charCount = document.getElementById('charCount');\n    const readTime = document.getElementById('readTime');\n    const toast = document.getElementById('wpnt-toast');\n\n    \/\/ 1. Auto-Load from Local Storage\n    const savedText = localStorage.getItem('sanepo_case_converter_data');\n    if (savedText) {\n        textArea.value = savedText;\n    }\n\n    \/\/ Hitung Statistik Real-time\n    function updateStats() {\n        const text = textArea.value;\n        const chars = text.length;\n        \/\/ Hitung kata (abaikan spasi kosong)\n        const words = text.trim() ? text.trim().split(\/\\s+\/).length : 0;\n        \n        charCount.innerText = chars.toLocaleString();\n        wordCount.innerText = words.toLocaleString();\n\n        \/\/ Estimasi waktu baca (Rata-rata 200 kata per menit)\n        if (words > 0) {\n            const minutes = Math.floor(words \/ 200);\n            const seconds = Math.floor((words % 200) \/ (200 \/ 60));\n            if (minutes > 0) {\n                readTime.innerText = `${minutes}m ${seconds}s`;\n            } else {\n                readTime.innerText = `${seconds} sec`;\n            }\n        } else {\n            readTime.innerText = '0 min';\n        }\n\n        \/\/ Auto-save to Local Storage\n        localStorage.setItem('sanepo_case_converter_data', text);\n    }\n\n    \/\/ Inisiasi stats pada load pertama\n    updateStats();\n\n    \/\/ Listener saat mengetik\n    textArea.addEventListener('input', updateStats);\n\n    \/\/ Fungsi Notifikasi Toast\n    function showToast(message, isSuccess = false) {\n        toast.innerText = message;\n        if(isSuccess) {\n            toast.classList.add('success');\n        } else {\n            toast.classList.remove('success');\n        }\n        toast.classList.add('show');\n        setTimeout(() => toast.classList.remove('show'), 2500);\n    }\n\n    \/\/ Fungsi Utama Konversi Teks\n    window.transformText = function(type) {\n        let text = textArea.value;\n        if (!text) {\n            showToast('Please enter some text first!');\n            return;\n        }\n\n        switch(type) {\n            case 'upper':\n                text = text.toUpperCase();\n                break;\n            case 'lower':\n                text = text.toLowerCase();\n                break;\n            case 'capitalize':\n                text = text.toLowerCase().replace(\/\\b\\w\/g, c => c.toUpperCase());\n                break;\n            case 'sentence':\n                text = text.toLowerCase().replace(\/(^\\s*\\w|[\\.\\!\\?]\\s*\\w)\/g, c => c.toUpperCase());\n                break;\n            case 'title':\n                const minorWords = ['a', 'an', 'and', 'as', 'at', 'but', 'by', 'en', 'for', 'if', 'in', 'of', 'on', 'or', 'the', 'to', 'v', 'via', 'vs', 'with'];\n                text = text.toLowerCase().replace(\/\\b\\w+\/g, (word, index) => {\n                    if (index > 0 && minorWords.includes(word)) return word;\n                    return word.charAt(0).toUpperCase() + word.substring(1);\n                });\n                break;\n            case 'alternating':\n                text = text.split('').map((c, i) => i % 2 === 0 ? c.toLowerCase() : c.toUpperCase()).join('');\n                break;\n            case 'inverse':\n                text = text.split('').map(c => c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase()).join('');\n                break;\n            case 'trim':\n                text = text.replace(\/\\s+\/g, ' ').trim(); \/\/ Hapus spasi ganda\n                break;\n            case 'nolinebreaks':\n                text = text.replace(\/(\\r\\n|\\n|\\r)\/gm, \" \").replace(\/\\s+\/g, ' ').trim(); \/\/ Hapus baris baru\n                break;\n        }\n\n        textArea.value = text;\n        updateStats();\n        showToast('Text converted successfully!', true);\n    };\n\n    \/\/ Fungsi Download TXT\n    window.downloadText = function() {\n        if (!textArea.value) {\n            showToast('Nothing to download!');\n            return;\n        }\n        const blob = new Blob([textArea.value], { type: 'text\/plain' });\n        const url = URL.createObjectURL(blob);\n        const a = document.createElement('a');\n        a.href = url;\n        a.download = 'Sanepo-Text-Format.txt';\n        a.click();\n        URL.revokeObjectURL(url);\n        showToast('File downloaded!', true);\n    };\n\n    \/\/ Fungsi Copy\n    window.copyToClipboard = function() {\n        if (!textArea.value) {\n            showToast('Nothing to copy!');\n            return;\n        }\n        \n        textArea.select();\n        try {\n            document.execCommand('copy');\n            showToast('Copied to Clipboard!', true);\n        } catch (err) {\n            showToast('Failed to copy text.');\n        }\n        window.getSelection().removeAllRanges();\n    };\n\n    \/\/ Fungsi Hapus\n    window.clearText = function() {\n        if(confirm('Are you sure you want to clear all text?')) {\n            textArea.value = '';\n            updateStats();\n            textArea.focus();\n            showToast('Text cleared!');\n        }\n    };\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Sanepo Case Converter Easily transform your text format, clean up spaces, and analyze your content. 100% Client-Side &#038; Secure Words: 0 Characters: 0 Reading Time: 0 min Sentence case lower case UPPER CASE Capitalized Case Title Case aLtErNaTiNg cAsE iNVERSE cASE Trim Extra Spaces Remove Line Breaks Download .txt Copy to Clipboard Clear Action Completed!<\/p>\n","protected":false},"featured_media":0,"template":"","meta":[],"class_list":["post-70","tool","type-tool","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/tools.sanepo.com\/id\/wp-json\/wp\/v2\/tool\/70","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tools.sanepo.com\/id\/wp-json\/wp\/v2\/tool"}],"about":[{"href":"https:\/\/tools.sanepo.com\/id\/wp-json\/wp\/v2\/types\/tool"}],"wp:attachment":[{"href":"https:\/\/tools.sanepo.com\/id\/wp-json\/wp\/v2\/media?parent=70"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}